fix(nimble): Added CS service support

This commit is contained in:
Rahul Tank
2025-09-14 19:25:57 +05:30
parent d709f10701
commit fa6bb99bb0
30 changed files with 1070 additions and 4793 deletions

View File

@@ -754,6 +754,7 @@ if(CONFIG_BT_ENABLED)
"host/nimble/nimble/nimble/host/services/hid/src/ble_svc_hid.c"
"host/nimble/nimble/nimble/host/services/sps/src/ble_svc_sps.c"
"host/nimble/nimble/nimble/host/services/cte/src/ble_svc_cte.c"
"host/nimble/nimble/nimble/host/services/ras/src/ble_svc_ras.c"
"host/nimble/nimble/nimble/host/src/ble_cs.c"
"host/nimble/nimble/nimble/host/src/ble_hs_conn.c"
"host/nimble/nimble/nimble/host/src/ble_store_util.c"

View File

@@ -618,6 +618,27 @@ menu "BLE 5.x Features"
endif
endmenu #BLE5.x
menu "BLE 6.x Features"
depends on (SOC_BLE_60_SUPPORTED || BT_CONTROLLER_DISABLED)
menuconfig BT_NIMBLE_60_FEATURE_SUPPORT
bool "Enable BLE 6 feature"
depends on BT_NIMBLE_ENABLED && (SOC_BLE_60_SUPPORTED || BT_CONTROLLER_DISABLED)
default n
help
Enable BLE 6 feature
if BT_NIMBLE_60_FEATURE_SUPPORT
config BT_NIMBLE_CHANNEL_SOUNDING
bool "ble channel souding feature"
depends on BT_NIMBLE_ENABLED
default n
help
Used to enable/disable the channel sounding feature
endif
endmenu #BLE6.x
menu "Services"
depends on BT_NIMBLE_GATT_SERVER

View File

@@ -2097,7 +2097,7 @@
#ifdef CONFIG_BT_NIMBLE_CHANNEL_SOUNDING
#define MYNEWT_VAL_BLE_CHANNEL_SOUNDING (CONFIG_BT_NIMBLE_CHANNEL_SOUNDING)
#else
#define MYNEWT_VAL_BLE_CHANNEL_SOUNDING (1)
#define MYNEWT_VAL_BLE_CHANNEL_SOUNDING (0)
#endif
#endif

View File

@@ -172,6 +172,25 @@ examples/bluetooth/hci/controller_hci_uart_esp32c3_and_esp32s3:
depends_filepatterns:
- components/driver/uart/**/*
examples/bluetooth/nimble/ble_chan_sound_initiator:
<<: *bt_default_depends
enable:
- if: SOC_BLE_SUPPORTED == 1 and IDF_TARGET == "esp32c6"
temporary: true
reason: Channel Sounding example only supported on ESP32-C6
depends_filepatterns:
- examples/bluetooth/nimble/ble_chan_sound_initiator/**/*
- examples/bluetooth/nimble/common/**/*
examples/bluetooth/nimble/ble_chan_sound_reflector:
<<: *bt_default_depends
enable:
- if: SOC_BLE_SUPPORTED == 1 and IDF_TARGET == "esp32c6"
temporary: true
reason: Channel Sounding example only supported on ESP32-C6
depends_filepatterns:
- examples/bluetooth/nimble/ble_chan_sound_reflector/**/*
- examples/bluetooth/nimble/common/**/*
# config BT_NIMBLE_ENABLED does not depends on any soc cap
examples/bluetooth/nimble/ble_cte:

View File

@@ -5,4 +5,4 @@ cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
# "Trim" the build. Include the minimal set of components, main, and anything it depends on.
idf_build_set_property(MINIMAL_BUILD ON)
project(blecent)
project(ble_chan_sound_initiator)

View File

@@ -1,37 +1,32 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- |
| Supported Targets | ESP32-C6 |
| ----------------- | -------- |
# BLE Central Example
# BLE Channel sounding example
(See the README.md file in the upper-level 'examples' directory for more information about examples.)
* This example demonstrates the capability of the CS procedure to be executed on the ESP host + external controller.
* It is important to note that the current example does not provide support for distance calculation, and it is currently under development.
(See the README.md file in the upper level 'examples' directory for more information about examples.)
## Example output
This example creates GATT client and performs passive scan, it then connects to peripheral device if the device advertises connectability and the device advertises support for the Alert Notification service (0x1811) as primary service UUID.
I (372) hal_uart: set baud_rate:115200.
After connection it enables bonding and link encryprion if the `Enable Link Encryption` flag is set in the example config.
I (382) NimBLE_RAS_INITIATOR: BLE Host Task Started
I (382) main_task: Returned from app_main()
It performs six GATT operations against the specified peer:
I (432) NimBLE: GAP procedure initiated: extended discovery;
* Reads the ANS Supported New Alert Category characteristic.
I (157332) NimBLE: GAP procedure initiated: extended connect;
I (157552) NimBLE: Connection established
I (157562) NimBLE: Connection secured
I (162222) NimBLE: encryption change event; status=0
* After the read operation is completed, writes the ANS Alert Notification Control Point characteristic.
I (162372) NimBLE: CS capabilities exchanged
I (162372) NimBLE: Set default CS settings
I (162392) NimBLE: create CS config
I (162392) NimBLE: Setup phase completed
* After the write operation is completed, subscribes to notifications for the ANS Unread Alert Status characteristic.
* After the subscribe operation is completed, it subscribes to notifications for a user defined characteristic.
* After this subscribe operation is completed, it writes to the user defined characteristic.
* After the write operation is completed, it reads from the user defined characteristic.
If the peer does not support a required service, characteristic, or descriptor, then the peer lied when it claimed support for the alert notification service! When this happens, or if a GATT procedure fails, this function immediately terminates the connection.
It uses ESP32's Bluetooth controller and NimBLE stack based BLE host.
This example aims at understanding BLE service discovery, connection, encryption and characteristic operations.
To test this demo, use any BLE GATT server app that advertises support for the Alert Notification service (0x1811) and includes it in the GATT database.
Note :
## Note:
* This example currently requires an external Bluetooth controller supporting BLE Channel sounding functionality,as the ESP chips listed above do not have native controller support for BLE channel sounding feature and is under development phase
* To install the dependency packages needed, please refer to the top level [README file](../../../README.md#running-test-python-script-pytest).
@@ -45,7 +40,7 @@ idf.py set-target <chip_name>
### Hardware Required
* A development board with ESP32/ESP32-C2/ESP32-C3/ESP32-S3 SoC (e.g., ESP32-DevKitC, ESP-WROVER-KIT, etc.)
* A development board with ESP32/ESP32-C2/ESP32-C3/ESP32-S3/ESP32-C6 SoC (e.g., ESP32-DevKitC, ESP-WROVER-KIT, etc.)
* A USB cable for Power supply and programming
See [Development Boards](https://www.espressif.com/en/products/devkits) for more information about it.
@@ -70,68 +65,6 @@ Run `idf.py -p PORT flash monitor` to build, flash and monitor the project.
See the [Getting Started Guide](https://idf.espressif.com/) for full steps to configure and use ESP-IDF to build projects.
## Example Output
This is the console output on successful connection:
```
I (202) BTDM_INIT: BT controller compile version [0b60040]
I (202) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
W (212) phy_init: failed to load RF calibration data (0xffffffff), falling back to full calibration
I (422) phy: phy_version: 4007, 9c6b43b, Jan 11 2019, 16:45:07, 0, 2
I (722) NimBLE_BLE_CENT: BLE Host Task Started
GAP procedure initiated: stop advertising.
GAP procedure initiated: discovery; own_addr_type=0 filter_policy=0 passive=1 limited=0 filter_duplicates=1 duration=forever
GAP procedure initiated: connect; peer_addr_type=1 peer_addr=xx:xx:xx:xx:xx:xx scan_itvl=16 scan_window=16 itvl_min=24 itvl_max=40 latency=0 supervision_timeout=256 min_ce_len=16 max_ce_len=768 own_addr_type=0
Connection established
Connection secured
encryption change event; status=0
GATT procedure initiated: discover all services
GATT procedure initiated: discover all characteristics; start_handle=1 end_handle=3
GATT procedure initiated: discover all characteristics; start_handle=20 end_handle=26
GATT procedure initiated: discover all characteristics; start_handle=40 end_handle=65535
GATT procedure initiated: discover all descriptors; chr_val_handle=42 end_handle=43
GATT procedure initiated: discover all descriptors; chr_val_handle=49 end_handle=65535
Service discovery complete; status=0 conn_handle=0
GATT procedure initiated: read; att_handle=45
GATT procedure initiated: write; att_handle=47 len=2
GATT procedure initiated: write; att_handle=43 len=2
Read complete; status=0 conn_handle=0 attr_handle=45 value=0x02
Write complete; status=0 conn_handle=0 attr_handle=47
Subscribe complete; status=0 conn_handle=0 attr_handle=43
GATT procedure initiated: write; att_handle=26 len=2
GATT procedure initiated: write; att_handle=25 len=1
GATT procedure initiated: read; att_handle=25
Subscribe to the custom subscribable characteristic complete; status=0 conn_handle=1 attr_handle=26 value=
Write to the custom subscribable characteristic complete; status=0 conn_handle=1 attr_handle=25
received notification; conn_handle=1 attr_handle=25 attr_len=4
Read complete for the subscribable characteristic; status=0 conn_handle=1 attr_handle=25 value=0x19
```
This is the console output on failure (or peripheral does not support New Alert Service category):
```
I (180) BTDM_INIT: BT controller compile version [8e87ec7]
I (180) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
I (250) phy: phy_version: 4000, b6198fa, Sep 3 2018, 15:11:06, 0, 0
I (480) NimBLE_BLE_CENT: BLE Host Task Started
GAP procedure initiated: stop advertising.
GAP procedure initiated: discovery; own_addr_type=0 filter_policy=0 passive=1 limited=0 filter_duplicates=1 duration=forever
GAP procedure initiated: connect; peer_addr_type=1 peer_addr=xx:xx:xx:xx:xx:xx scan_itvl=16 scan_window=16 itvl_min=24 itvl_max=40 latency=0 supervision_timeout=256 min_ce_len=16 max_ce_len=768 own_addr_type=0
Connection established
GATT procedure initiated: discover all services
GATT procedure initiated: discover all characteristics; start_handle=1 end_handle=3
GATT procedure initiated: discover all characteristics; start_handle=20 end_handle=26
GATT procedure initiated: discover all characteristics; start_handle=40 end_handle=65535
GATT procedure initiated: discover all descriptors; chr_val_handle=42 end_handle=43
GATT procedure initiated: discover all descriptors; chr_val_handle=47 end_handle=65535
Service discovery complete; status=0 conn_handle=0
Error: Peer doesn't support the Supported New Alert Category characteristic
GAP procedure initiated: terminate connection; conn_handle=0 hci_reason=19
disconnect; reason=534
```
## Troubleshooting
For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon.

View File

@@ -1,39 +1,14 @@
menu "Example Configuration"
config EXAMPLE_PEER_ADDR
string "Peer Address"
default "ADDR_ANY"
help
Enter the peer address in aa:bb:cc:dd:ee:ff form to connect to a specific peripheral
config EXAMPLE_EXTENDED_ADV
bool
depends on SOC_BLE_50_SUPPORTED && BT_NIMBLE_50_FEATURE_SUPPORT
default y if SOC_ESP_NIMBLE_CONTROLLER
default y
select BT_NIMBLE_EXT_ADV
prompt "Enable Extended Adv"
help
Use this option to enable extended advertising in the example.
If this option is disabled, ensure config BT_NIMBLE_EXT_ADV is
also disabled from Nimble stack menuconfig
config EXAMPLE_INIT_DEINIT_LOOP
bool
prompt "Perform init deinit of nimble stack in a loop"
help
Enable this flag, to perform only stack Init and Deinit in a loop.
config EXAMPLE_ENCRYPTION
bool
prompt "Enable Link Encryption"
help
This enables bonding and encryption after connection has been established.
config EXAMPLE_USE_CI_ADDRESS
bool
default n
prompt "Advertise using Test address(Internal Test ONLY)"
help
Used for internal test ONLY.
Use this option to advertise in a specific random address.
endmenu

View File

@@ -0,0 +1,59 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#ifndef H_BLE_CHAN_INITIATOR_
#define H_BLE_CHAN_INITIATOR_
#include "modlog/modlog.h"
#include "esp_central.h"
#ifdef __cplusplus
extern "C" {
#endif
struct ble_hs_adv_fields;
struct ble_gap_conn_desc;
struct ble_hs_cfg;
union ble_store_value;
union ble_store_key;
#define BLE_HCI_LE_CS_SUBEVENT_DONE_STATUS_COMPLETE 0x0
#define BLE_HCI_LE_CS_SUBEVENT_DONE_STATUS_PARTIAL 0x1
#define BLE_HCI_LE_CS_SUBEVENT_DONE_STATUS_ABORTED 0xF
#define LOCAL_PROCEDURE_MEM 1024 // Replace with an appropriate constant value
struct ble_hs_cfg;
struct ble_gatt_register_ctxt;
/** GATT server. */
#define BLE_UUID_RANGING_SERVICE_VAL (0x185B)
/** @brief UUID of the RAS Features Characteristic. **/
#define BLE_UUID_RAS_FEATURES_VAL (0x2C14)
/** @brief UUID of the Real-time Ranging Data Characteristic. **/
#define BLE_UUID_RAS_REALTIME_RD_VAL (0x2C15)
/** @brief UUID of the On-demand Ranging Data Characteristic. **/
#define BLE_UUID_RAS_ONDEMAND_RD_VAL (0x2C16)
/** @brief UUID of the RAS Control Point Characteristic. **/
#define BLE_UUID_RAS_CP_VAL (0x2C17)
/** @brief UUID of the Ranging Data Ready Characteristic. **/
#define BLE_UUID_RAS_RD_READY_VAL (0x2C18)
/** @brief UUID of the Ranging Data Overwritten Characteristic. **/
#define BLE_UUID_RAS_RD_OVERWRITTEN_VAL (0x2C19)
void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg);
int gatt_svr_init(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,46 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#ifndef H_BLECENT_
#define H_BLECENT_
#include "modlog/modlog.h"
#include "esp_central.h"
#ifdef __cplusplus
extern "C" {
#endif
struct ble_hs_adv_fields;
struct ble_gap_conn_desc;
struct ble_hs_cfg;
union ble_store_value;
union ble_store_key;
#define BLECENT_SVC_ALERT_UUID 0x1811
#define BLECENT_CHR_SUP_NEW_ALERT_CAT_UUID 0x2A47
#define BLECENT_CHR_NEW_ALERT 0x2A46
#define BLECENT_CHR_SUP_UNR_ALERT_CAT_UUID 0x2A48
#define BLECENT_CHR_UNR_ALERT_STAT_UUID 0x2A45
#define BLECENT_CHR_ALERT_NOT_CTRL_PT 0x2A44
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,72 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#ifndef H_BLEHR_SENSOR_
#define H_BLEHR_SENSOR_
#include "nimble/ble.h"
#include "modlog/modlog.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Heart-rate configuration */
#define GATT_HRS_UUID 0x180D
#define GATT_HRS_MEASUREMENT_UUID 0x2A37
#define GATT_HRS_BODY_SENSOR_LOC_UUID 0x2A38
#define GATT_DEVICE_INFO_UUID 0x180A
#define GATT_MANUFACTURER_NAME_UUID 0x2A29
#define GATT_MODEL_NUMBER_UUID 0x2A24
#define BLE_UUID_RANGING_SERVICE_VAL (0x185B)
/** @brief UUID of the RAS Features Characteristic. **/
#define BLE_UUID_RAS_FEATURES_VAL (0x2C14)
/** @brief UUID of the Real-time Ranging Data Characteristic. **/
#define BLE_UUID_RAS_REALTIME_RD_VAL (0x2C15)
/** @brief UUID of the On-demand Ranging Data Characteristic. **/
#define BLE_UUID_RAS_ONDEMAND_RD_VAL (0x2C16)
/** @brief UUID of the RAS Control Point Characteristic. **/
#define BLE_UUID_RAS_CP_VAL (0x2C17)
/** @brief UUID of the Ranging Data Ready Characteristic. **/
#define BLE_UUID_RAS_RD_READY_VAL (0x2C18)
/** @brief UUID of the Ranging Data Overwritten Characteristic. **/
#define BLE_UUID_RAS_RD_OVERWRITTEN_VAL (0x2C19)
extern uint16_t hrs_hrm_handle;
struct ble_hs_cfg;
struct ble_gatt_register_ctxt;
void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg);
int gatt_svr_init(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -17,167 +17,17 @@
* under the License.
*/
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include "host/ble_hs.h"
#include "host/ble_uuid.h"
#include "services/gap/ble_svc_gap.h"
#include "services/gatt/ble_svc_gatt.h"
#include "blehr_sens.h"
static const char *manuf_name = "Apache Mynewt ESP32 devkitC";
static const char *model_num = "Mynewt RAS Service";
static uint8_t ras_feat_val;
static uint16_t ras_feat_val_handle;
static int
gatt_svr_chr_access_ras_val(uint16_t conn_handle, uint16_t attr_handle,
struct ble_gatt_access_ctxt *ctxt, void *arg);
static const struct ble_gatt_svc_def gatt_svr_svcs[] = {
{
/* Service: Ranging Data Service */
.type = BLE_GATT_SVC_TYPE_PRIMARY,
.uuid = BLE_UUID16_DECLARE(BLE_UUID_RANGING_SERVICE_VAL),
.characteristics = (struct ble_gatt_chr_def[])
{ {
/* Characteristic: Feature Value */
.uuid = BLE_UUID16_DECLARE(BLE_UUID_RAS_FEATURES_VAL),
.access_cb = gatt_svr_chr_access_ras_val,
.val_handle = &ras_feat_val_handle,
.flags = BLE_GATT_CHR_F_READ|BLE_GATT_CHR_F_READ_ENC,
},{
/* Characteristic: On demand ranging data */
.uuid = BLE_UUID16_DECLARE(BLE_UUID_RAS_ONDEMAND_RD_VAL),
.access_cb = gatt_svr_chr_access_ras_val,
.flags = BLE_GATT_CHR_F_NOTIFY | BLE_GATT_CHR_F_INDICATE |BLE_GATT_CHR_F_READ_ENC
,
},{
/* Characteristic: RAS Control Point */
.uuid = BLE_UUID16_DECLARE(BLE_UUID_RAS_CP_VAL),
.access_cb = gatt_svr_chr_access_ras_val,
.flags = BLE_GATT_CHR_F_WRITE_NO_RSP | BLE_GATT_CHR_F_INDICATE |BLE_GATT_CHR_F_READ_ENC ,
},{
/* Characteristic: RAS Data Ready */
.uuid = BLE_UUID16_DECLARE(BLE_UUID_RAS_RD_READY_VAL),
.access_cb = gatt_svr_chr_access_ras_val,
.flags = BLE_GATT_CHR_F_INDICATE | BLE_GATT_CHR_F_READ_ENC,
},{
/* Characteristic: RAS data overwritten */
.uuid = BLE_UUID16_DECLARE(BLE_UUID_RAS_RD_OVERWRITTEN_VAL),
.access_cb = gatt_svr_chr_access_ras_val,
.flags = BLE_GATT_CHR_F_INDICATE | BLE_GATT_CHR_F_READ_ENC,
},{
0, /* No more characteristics in this service */
},
}
},
{
0, /* No more services */
},
};
static int
gatt_svr_chr_access_ras_val(uint16_t conn_handle, uint16_t attr_handle,
struct ble_gatt_access_ctxt *ctxt, void *arg)
{
const ble_uuid_t *uuid;
int rc;
switch (ctxt->op) {
case BLE_GATT_ACCESS_OP_READ_CHR:
if (conn_handle != BLE_HS_CONN_HANDLE_NONE) {
MODLOG_DFLT(INFO, "Characteristic read; conn_handle=%d attr_handle=%d\n",
conn_handle, attr_handle);
} else {
MODLOG_DFLT(INFO, "Characteristic read by NimBLE stack; attr_handle=%d\n",
attr_handle);
}
uuid = ctxt->chr->uuid;
if(uuid == BLE_UUID_RAS_FEATURES_VAL){
if (attr_handle == ras_feat_val_handle) {
rc = os_mbuf_append(ctxt->om,
&ras_feat_val,
sizeof(ras_feat_val));
return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
}
}
goto unknown;
case BLE_GATT_ACCESS_OP_WRITE_CHR:
if (conn_handle != BLE_HS_CONN_HANDLE_NONE) {
MODLOG_DFLT(INFO, "Characteristic write; conn_handle=%d attr_handle=%d",
conn_handle, attr_handle);
} else {
MODLOG_DFLT(INFO, "Characteristic write by NimBLE stack; attr_handle=%d",
attr_handle);
}
return 0;
default:
goto unknown;
}
unknown:
/* Unknown characteristic/descriptor;
* The NimBLE host should not have called this function;
*/
assert(0);
return BLE_ATT_ERR_UNLIKELY;
}
void
gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg)
{
char buf[BLE_UUID_STR_LEN];
switch (ctxt->op) {
case BLE_GATT_REGISTER_OP_SVC:
MODLOG_DFLT(DEBUG, "registered service %s with handle=%d\n",
ble_uuid_to_str(ctxt->svc.svc_def->uuid, buf),
ctxt->svc.handle);
break;
case BLE_GATT_REGISTER_OP_CHR:
MODLOG_DFLT(DEBUG, "registering characteristic %s with "
"def_handle=%d val_handle=%d\n",
ble_uuid_to_str(ctxt->chr.chr_def->uuid, buf),
ctxt->chr.def_handle,
ctxt->chr.val_handle);
break;
case BLE_GATT_REGISTER_OP_DSC:
MODLOG_DFLT(DEBUG, "registering descriptor %s with handle=%d\n",
ble_uuid_to_str(ctxt->dsc.dsc_def->uuid, buf),
ctxt->dsc.handle);
break;
default:
assert(0);
break;
}
}
#include "services/ans/ble_svc_ans.h"
#include "services/ras/ble_svc_ras.h"
int
gatt_svr_init(void)
{
int rc;
ble_svc_gap_init();
ble_svc_gatt_init();
rc = ble_gatts_count_cfg(gatt_svr_svcs);
if (rc != 0) {
return rc;
}
rc = ble_gatts_add_svcs(gatt_svr_svcs);
if (rc != 0) {
return rc;
}
ble_svc_ras_init();
return 0;
}

View File

@@ -1,2 +0,0 @@
CONFIG_EXAMPLE_USE_CI_ADDRESS=y
CONFIG_EXAMPLE_PEER_ADDR="${CI_PIPELINE_ID}"

View File

@@ -1,4 +1,2 @@
CONFIG_IDF_TARGET="esp32c2"
CONFIG_XTAL_FREQ_26=y
CONFIG_EXAMPLE_USE_CI_ADDRESS=y
CONFIG_EXAMPLE_PEER_ADDR="${CI_PIPELINE_ID}"

View File

@@ -9,5 +9,11 @@ CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
CONFIG_BT_BLUEDROID_ENABLED=n
CONFIG_BT_CONTROLLER_DISABLED=y
CONFIG_BT_NIMBLE_60_FEATURE_SUPPORT=y
CONFIG_BT_NIMBLE_ENABLED=y
CONFIG_BT_NIMBLE_EXT_ADV=y
CONFIG_BT_NIMBLE_CHANNEL_SOUNDING=y
CONFIG_BT_NIMBLE_TRANSPORT_EVT_SIZE=78
CONFIG_BT_NIMBLE_ATT_PREFERRED_MTU=498
CONFIG_BT_NIMBLE_GATT_MAX_PROCS=6

View File

@@ -765,7 +765,7 @@ blecent_custom_gatt_operations(const struct peer* peer)
remote_chr_uuid,
BLE_UUID16_DECLARE(BLE_GATT_DSC_CLT_CFG_UUID16));
if (dsc == NULL) {
MODLOG_DFLT(ERROR, "Error: Peer lacks a CCCD for the subscribable characterstic\n");
MODLOG_DFLT(ERROR, "Error: Peer lacks a CCCD for the subscribable characteristic\n");
goto err;
}

View File

@@ -1,23 +1,33 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- |
| Supported Targets | ESP32-C6 |
| ----------------- | -------- |
# BLE Peripheral Example
# BLE Channel Sounding reflector Example
(See the README.md file in the upper level 'examples' directory for more information about examples.)
(See the README.md file in the upper-level 'examples' directory for more information about examples.)
* This example demonstrates the capability of the CS procedure to be executed on the ESP host + external controller.
* It is important to note that the current example does not provide support for distance calculation, and it is currently under development.
* Ble channel sounding reflector example uses the RAS service defined in [ble_svc_ras.c](../../../../components/bt/host/nimble/nimble/nimble/host/services/ras/src/ble_svc_ras.c)
This example creates GATT server and then starts advertising, waiting to be connected to a GATT client.
I (372) hal_uart: set baud_rate:115200.
It uses ESP32's Bluetooth controller and NimBLE stack based BLE host.
I (382) NimBLE_RAS_INITIATOR: BLE Host Task Started
I (382) main_task: Returned from app_main()
This example aims at understanding GATT database configuration, handling GATT reads and writes, handling subscribe events, understanding advertisement and SMP related NimBLE APIs.
I (157562) NimBLE: GAP procedure initiated: extended advertise; instance=0
It also demonstrates security features of NimBLE stack. SMP parameters like I/O capabilities of device, Bonding flag, MITM protection flag and Secure Connection only mode, Enabling Link Encryption etc., can be configured through menuconfig options.
I (157562) NimBLE: Connection secured
I (162222) NimBLE: encryption change event; status=0
For RPA feature (currently Host based privacy feature is supported), use API `ble_hs_pvcy_rpa_config` to enable/disable host based privacy, `own_addr_type` needs to be set to `BLE_ADDR_RANDOM` to use this feature. Please include `ble_hs_pvcy.h` while using this API. As `ble_hs_pvcy_rpa_config` configures host privacy and sets address in controller, it is necessary to call this API after host-controller are synced (e.g. in `bleprph_on_sync` callback).
I (162372) NimBLE: CS capabilities exchanged
I (162372) NimBLE: Set default CS settings
To test this demo, any BLE scanner app can be used.
I (162392) NimBLE: Setup phase completed
Note :
To test this demo, any BLE channel sounding initiator app can be used.
## Note
* This example currently requires an external Bluetooth controller supporting BLE Channel sounding functionality, as the ESP chips listed above do not have native controller support for BLE channel sounding feature and is under development phase
* To install the dependency packages needed, please refer to the top level [README file](../../../README.md#running-test-python-script-pytest).
@@ -50,47 +60,6 @@ Run `idf.py -p PORT flash monitor` to build, flash and monitor the project.
See the [Getting Started Guide](https://idf.espressif.com/) for full steps to configure and use ESP-IDF to build projects.
## Example Output
There is this console output when bleprph is connected and characteristic is read:
```
I (118) BTDM_INIT: BT controller compile version [fe7ced0]
I (118) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
W (128) phy_init: failed to load RF calibration data (0xffffffff), falling back to full calibration
I (268) phy: phy_version: 4100, 6fa5e27, Jan 25 2019, 17:02:06, 0, 2
I (508) NimBLE_BLE_PRPH: BLE Host Task Started
I (508) uart: queue free spaces: 8
GAP procedure initiated: stop advertising.
Device Address: xx:xx:xx:xx:xx:xx
GAP procedure initiated: advertise; disc_mode=2 adv_channel_map=0 own_addr_type=0 adv_filter_policy=0 adv_itvl_min=0 adv_itvl_max=0
connection established; status=0 handle=0 our_ota_addr_type=0 our_ota_addr=xx:xx:xx:xx:xx:xx our_id_addr_type=0 our_id_addr=xx:xx:xx:xx:xx:xx peer_ota_addr_type=1 peer_ota_addr=xx:xx:xx:xx:xx:xx peer_id_addr_type=1 peer_id_addr=xx:xx:xx:xx:xx:xx conn_itvl=39 conn_latency=0 supervision_timeout=500 encrypted=0 authenticated=0 bonded=0
connection updated; status=0 handle=0 our_ota_addr_type=0 our_ota_addr=xx:xx:xx:xx:xx:xx our_id_addr_type=0 our_id_addr=xx:xx:xx:xx:xx:xx peer_ota_addr_type=1 peer_ota_addr=xx:xx:xx:xx:xx:xx peer_id_addr_type=1 peer_id_addr=xx:xx:xx:xx:xx:xx conn_itvl=6 conn_latency=0 supervision_timeout=500 encrypted=0 authenticated=0 bonded=0
I (50888) NimBLE_BLE_PRPH: PASSKEY_ACTION_EVENT started
I (50888) NimBLE_BLE_PRPH: Passkey on device's display: xxxxxx
I (50888) NimBLE_BLE_PRPH: Accept or reject the passkey through console in this format -> key Y or key N
key Y
I (50898) NimBLE_BLE_PRPH: ble_sm_inject_io result: 0
encryption change event; status=0 handle=0 our_ota_addr_type=0 our_ota_addr=xx:xx:xx:xx:xx:xx our_id_addr_type=0 our_id_addr=xx:xx:xx:xx:xx:xx peer_ota_addr_type=1 peer_ota_addr=xx:xx:xx:xx:xx:xx peer_id_addr_type=1
peer_id_addr=xx:xx:xx:xx:xx:xx conn_itvl=6 conn_latency=0 supervision_timeout=500 encrypted=1 authenticated=1 bonded=1
connection updated; status=0 handle=0 our_ota_addr_type=0 our_ota_addr=xx:xx:xx:xx:xx:xx our_id_addr_type=0 our_id_addr=xx:xx:xx:xx:xx:xx
peer_ota_addr_type=1 peer_ota_addr=xx:xx:xx:xx:xx:xx peer_id_addr_type=1 peer_id_addr=xx:xx:xx:xx:xx:xx conn_itvl=39 conn_latency=0 supervision_timeout=500 encrypted=1 authenticated=1 bonded=1
subscribe event; conn_handle=1 attr_handle=19 reason=1 prevn=0 curn=1 previ=0 curi=0
Subscribe to attribute (19) successful
subscribe event; conn_handle=1 attr_handle=25 reason=1 prevn=0 curn=1 previ=0 curi=0
Subscribe to attribute (25) successful
GATT procedure initiated: notify; att_handle=25
Notification sent successfully
```
## Note
* NVS support is not yet integrated to bonding. So, for now, bonding is not persistent across reboot.
## Troubleshooting

View File

@@ -1,80 +1,14 @@
menu "Example Configuration"
choice EXAMPLE_USE_IO_TYPE
prompt "I/O Capability"
default BLE_SM_IO_CAP_NO_IO
help
I/O capability of device.
config BLE_SM_IO_CAP_DISP_ONLY
bool "DISPLAY ONLY"
config BLE_SM_IO_CAP_DISP_YES_NO
bool "DISPLAY YESNO"
config BLE_SM_IO_CAP_KEYBOARD_ONLY
bool "KEYBOARD ONLY"
config BLE_SM_IO_CAP_NO_IO
bool "Just works"
config BLE_SM_IO_CAP_KEYBOARD_DISP
bool "Both KEYBOARD & DISPLAY"
endchoice
config EXAMPLE_IO_TYPE
int
default 0 if BLE_SM_IO_CAP_DISP_ONLY
default 1 if BLE_SM_IO_CAP_DISP_YES_NO
default 2 if BLE_SM_IO_CAP_KEYBOARD_ONLY
default 3 if BLE_SM_IO_CAP_NO_IO
default 4 if BLE_SM_IO_CAP_KEYBOARD_DISP
config EXAMPLE_BONDING
bool
default n
prompt "Use Bonding"
help
Use this option to enable/disable bonding.
config EXAMPLE_MITM
bool
default n
prompt "MITM security"
help
Use this option to enable/disable MITM security.
config EXAMPLE_USE_SC
bool
depends on BT_NIMBLE_SM_SC
default n
prompt "Use Secure Connection feature"
help
Use this option to enable/disable Security Manager Secure Connection 4.2 feature.
config EXAMPLE_EXTENDED_ADV
bool
depends on SOC_BLE_50_SUPPORTED && BT_NIMBLE_50_FEATURE_SUPPORT
default y if SOC_ESP_NIMBLE_CONTROLLER
default y
select BT_NIMBLE_EXT_ADV
prompt "Enable Extended Adv"
help
Use this option to enable extended advertising in the example.
If this option is disabled, ensure config BT_NIMBLE_EXT_ADV is
also disabled from Nimble stack menuconfig
config EXAMPLE_RANDOM_ADDR
bool
prompt "Advertise RANDOM Address"
help
Use this option to advertise a random address instead of public address
config EXAMPLE_ENCRYPTION
bool
prompt "Enable Link Encryption"
help
This adds Encrypted Read and Write permissions in the custom GATT server.
config EXAMPLE_RESOLVE_PEER_ADDR
bool
prompt "Enable resolving peer address"
help
Use this option to enable resolving peer's address.
endmenu

View File

@@ -17,8 +17,8 @@
* under the License.
*/
#ifndef H_BLEPRPH_
#define H_BLEPRPH_
#ifndef H_BLE_CHAN_REFLECTOR_
#define H_BLE_CHAN_REFLECTOR_
#include <stdbool.h>
#include "nimble/ble.h"
@@ -28,6 +28,12 @@
extern "C" {
#endif
#define BLE_HCI_LE_CS_SUBEVENT_DONE_STATUS_COMPLETE 0x0
#define BLE_HCI_LE_CS_SUBEVENT_DONE_STATUS_PARTIAL 0x1
#define BLE_HCI_LE_CS_SUBEVENT_DONE_STATUS_ABORTED 0xF
#define LOCAL_PROCEDURE_MEM 1024 // Replace with an appropriate constant value
struct ble_hs_cfg;
struct ble_gatt_register_ctxt;
@@ -53,12 +59,8 @@ struct ble_gatt_register_ctxt;
/** @brief UUID of the Ranging Data Overwritten Characteristic. **/
#define BLE_UUID_RAS_RD_OVERWRITTEN_VAL (0x2C19)
extern uint16_t hrs_hrm_handle;
void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg);
int gatt_svr_init(void);
void custom_gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg);
int custom_gatt_svr_init(void);
#ifdef __cplusplus
}

View File

@@ -17,179 +17,17 @@
* under the License.
*/
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include "host/ble_hs.h"
#include "host/ble_uuid.h"
#include "services/gap/ble_svc_gap.h"
#include "services/gatt/ble_svc_gatt.h"
#include "bleprph.h"
#include "services/ans/ble_svc_ans.h"
#include "services/gap/ble_svc_gap.h"
#include "services/gatt/ble_svc_gatt.h"
#include "services/ans/ble_svc_ans.h"
#include "services/ras/ble_svc_ras.h"
static uint8_t ras_feat_val;
static uint16_t ras_feat_val_handle;
int
custom_gatt_svr_init(void)
{
ble_svc_gap_init();
ble_svc_gatt_init();
ble_svc_ras_init();
static int
gatt_svr_chr_access_ras_val(uint16_t conn_handle, uint16_t attr_handle,
struct ble_gatt_access_ctxt *ctxt, void *arg);
static const struct ble_gatt_svc_def gatt_svr_svcs[] = {
{
/* Service: Ranging Data Service */
.type = BLE_GATT_SVC_TYPE_PRIMARY,
.uuid = BLE_UUID16_DECLARE(BLE_UUID_RANGING_SERVICE_VAL),
.characteristics = (struct ble_gatt_chr_def[])
{ {
/* Characteristic: Feature Value */
.uuid = BLE_UUID16_DECLARE(BLE_UUID_RAS_FEATURES_VAL),
.access_cb = gatt_svr_chr_access_ras_val,
.val_handle = &ras_feat_val_handle,
.flags = BLE_GATT_CHR_F_READ|BLE_GATT_CHR_F_READ_ENC,
}, {
/* Characteristic: On demand ranging data */
.uuid = BLE_UUID16_DECLARE(BLE_UUID_RAS_ONDEMAND_RD_VAL),
.access_cb = gatt_svr_chr_access_ras_val,
.flags = BLE_GATT_CHR_F_NOTIFY | BLE_GATT_CHR_F_INDICATE |BLE_GATT_CHR_F_READ_ENC |BLE_GATT_CHR_F_READ,
},{
/* Characteristic: RAS Control Point */
.uuid = BLE_UUID16_DECLARE(BLE_UUID_RAS_CP_VAL),
.access_cb = gatt_svr_chr_access_ras_val,
.flags = BLE_GATT_CHR_F_WRITE_NO_RSP | BLE_GATT_CHR_F_INDICATE |BLE_GATT_CHR_F_READ_ENC | BLE_GATT_CHR_F_READ ,
},{
/* Characteristic: RAS Data Ready */
.uuid = BLE_UUID16_DECLARE(BLE_UUID_RAS_RD_READY_VAL),
.access_cb = gatt_svr_chr_access_ras_val,
.flags = BLE_GATT_CHR_F_INDICATE | BLE_GATT_CHR_F_READ_ENC|BLE_GATT_CHR_F_READ,
},{
/* Characteristic: RAS data overwritten */
.uuid = BLE_UUID16_DECLARE(BLE_UUID_RAS_RD_OVERWRITTEN_VAL),
.access_cb = gatt_svr_chr_access_ras_val,
.flags = BLE_GATT_CHR_F_INDICATE | BLE_GATT_CHR_F_READ_ENC|BLE_GATT_CHR_F_READ,
}, {
0, /* No more characteristics in this service */
},
}
},
{
0, /* No more services */
},
};
static int
gatt_svr_chr_access_ras_val(uint16_t conn_handle, uint16_t attr_handle,
struct ble_gatt_access_ctxt *ctxt, void *arg)
{
const ble_uuid_t *uuid;
int rc;
printf("ctxt->op = %d\n",ctxt->op);
switch (ctxt->op) {
case BLE_GATT_ACCESS_OP_READ_CHR:
printf("reading call back \n");
if (conn_handle != BLE_HS_CONN_HANDLE_NONE) {
MODLOG_DFLT(INFO, "Characteristic read; conn_handle=%d attr_handle=%d\n",
conn_handle, attr_handle);
} else {
MODLOG_DFLT(INFO, "Characteristic read by NimBLE stack; attr_handle=%d\n",
attr_handle);
}
uuid = ctxt->chr->uuid;
if(uuid == BLE_UUID_RAS_FEATURES_VAL){
if (attr_handle == ras_feat_val_handle) {
rc = os_mbuf_append(ctxt->om,
&ras_feat_val,
sizeof(ras_feat_val));
return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
}
}
case BLE_GATT_ACCESS_OP_WRITE_CHR:
if (conn_handle != BLE_HS_CONN_HANDLE_NONE) {
MODLOG_DFLT(INFO, "Characteristic write; conn_handle=%d attr_handle=%d",
conn_handle, attr_handle);
} else {
MODLOG_DFLT(INFO, "Characteristic write by NimBLE stack; attr_handle=%d",
attr_handle);
}
uuid = ctxt->chr->uuid;
// if (attr_handle == ras_feat_val_handle) {
// rc = gatt_svr_write(ctxt->om,
// sizeof(ras_feat_val),
// sizeof(ras_feat_val),
// &ras_feat_val, NULL);
// ble_gatts_chr_updated(attr_handle);
// MODLOG_DFLT(INFO, "Notification/Indication scheduled for "
// "all subscribed peers.\n");
// return rc;
// }
return 0;
default:
goto unknown;
}
unknown:
/* Unknown characteristic/descriptor;
* The NimBLE host should not have called this function;
*/
//assert(0);
return BLE_ATT_ERR_UNLIKELY;
}
void
gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg)
{
char buf[BLE_UUID_STR_LEN];
switch (ctxt->op) {
case BLE_GATT_REGISTER_OP_SVC:
MODLOG_DFLT(DEBUG, "registered service %s with handle=%d\n",
ble_uuid_to_str(ctxt->svc.svc_def->uuid, buf),
ctxt->svc.handle);
break;
case BLE_GATT_REGISTER_OP_CHR:
MODLOG_DFLT(DEBUG, "registering characteristic %s with "
"def_handle=%d val_handle=%d\n",
ble_uuid_to_str(ctxt->chr.chr_def->uuid, buf),
ctxt->chr.def_handle,
ctxt->chr.val_handle);
break;
case BLE_GATT_REGISTER_OP_DSC:
MODLOG_DFLT(DEBUG, "registering descriptor %s with handle=%d\n",
ble_uuid_to_str(ctxt->dsc.dsc_def->uuid, buf),
ctxt->dsc.handle);
break;
default:
assert(0);
break;
}
}
int
gatt_svr_init(void)
{
int rc;
ble_svc_gap_init();
ble_svc_gatt_init();
rc = ble_gatts_count_cfg(gatt_svr_svcs);
if (rc != 0) {
return rc;
}
rc = ble_gatts_add_svcs(gatt_svr_svcs);
if (rc != 0) {
return rc;
}
return 0;
}
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@@ -9,4 +9,9 @@ CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
CONFIG_BT_BLUEDROID_ENABLED=n
CONFIG_BT_CONTROLLER_DISABLED=y
CONFIG_BT_NIMBLE_60_FEATURE_SUPPORT=y
CONFIG_BT_NIMBLE_ENABLED=y
CONFIG_BT_NIMBLE_EXT_ADV=y
CONFIG_BT_NIMBLE_CHANNEL_SOUNDING=y
CONFIG_BT_NIMBLE_ATT_PREFERRED_MTU=498

View File

@@ -4,5 +4,5 @@
CONFIG_IDF_TARGET="esp32c2"
CONFIG_BT_ENABLED=y
CONFIG_BT_NIMBLE_ENABLED=y
CONFIG_BT_NIMBLE_HCI_EVT_BUF_SIZE=70
CONFIG_BT_NIMBLE_TRANSPORT_EVT_SIZE=70
CONFIG_BT_NIMBLE_EXT_ADV=y

View File

@@ -3,5 +3,5 @@
#
CONFIG_BT_ENABLED=y
CONFIG_BT_NIMBLE_ENABLED=y
CONFIG_BT_NIMBLE_HCI_EVT_BUF_SIZE=70
CONFIG_BT_NIMBLE_TRANSPORT_EVT_SIZE=70
CONFIG_BT_NIMBLE_EXT_ADV=y

File diff suppressed because it is too large Load Diff

View File

@@ -39,27 +39,6 @@ struct ble_gatt_register_ctxt;
#define GATT_SVR_CHR_UNR_ALERT_STAT_UUID 0x2A45
#define GATT_SVR_CHR_ALERT_NOT_CTRL_PT 0x2A44
#define BLE_UUID_RANGING_SERVICE_VAL (0x185B)
/** @brief UUID of the RAS Features Characteristic. **/
#define BLE_UUID_RAS_FEATURES_VAL (0x2C14)
/** @brief UUID of the Real-time Ranging Data Characteristic. **/
#define BLE_UUID_RAS_REALTIME_RD_VAL (0x2C15)
/** @brief UUID of the On-demand Ranging Data Characteristic. **/
#define BLE_UUID_RAS_ONDEMAND_RD_VAL (0x2C16)
/** @brief UUID of the RAS Control Point Characteristic. **/
#define BLE_UUID_RAS_CP_VAL (0x2C17)
/** @brief UUID of the Ranging Data Ready Characteristic. **/
#define BLE_UUID_RAS_RD_READY_VAL (0x2C18)
/** @brief UUID of the Ranging Data Overwritten Characteristic. **/
#define BLE_UUID_RAS_RD_OVERWRITTEN_VAL (0x2C19)
void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg);
int gatt_svr_init(void);

View File

@@ -27,300 +27,113 @@
#include "bleprph.h"
#include "services/ans/ble_svc_ans.h"
// /*** Maximum number of characteristics with the notify flag ***/
// #define MAX_NOTIFY 5
/*** Maximum number of characteristics with the notify flag ***/
#define MAX_NOTIFY 5
// static const ble_uuid128_t gatt_svr_svc_uuid =
// BLE_UUID128_INIT(0x2d, 0x71, 0xa2, 0x59, 0xb4, 0x58, 0xc8, 0x12,
// 0x99, 0x99, 0x43, 0x95, 0x12, 0x2f, 0x46, 0x59);
static const ble_uuid128_t gatt_svr_svc_uuid =
BLE_UUID128_INIT(0x2d, 0x71, 0xa2, 0x59, 0xb4, 0x58, 0xc8, 0x12,
0x99, 0x99, 0x43, 0x95, 0x12, 0x2f, 0x46, 0x59);
// /* A characteristic that can be subscribed to */
// static uint8_t gatt_svr_chr_val;
// static uint16_t gatt_svr_chr_val_handle;
// static const ble_uuid128_t gatt_svr_chr_uuid =
// BLE_UUID128_INIT(0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11,
// 0x22, 0x22, 0x22, 0x22, 0x33, 0x33, 0x33, 0x33);
/* A characteristic that can be subscribed to */
static uint8_t gatt_svr_chr_val;
static uint16_t gatt_svr_chr_val_handle;
static const ble_uuid128_t gatt_svr_chr_uuid =
BLE_UUID128_INIT(0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11,
0x22, 0x22, 0x22, 0x22, 0x33, 0x33, 0x33, 0x33);
// /* A custom descriptor */
// static uint8_t gatt_svr_dsc_val;
// static const ble_uuid128_t gatt_svr_dsc_uuid =
// BLE_UUID128_INIT(0x01, 0x01, 0x01, 0x01, 0x12, 0x12, 0x12, 0x12,
// 0x23, 0x23, 0x23, 0x23, 0x34, 0x34, 0x34, 0x34);
/* A custom descriptor */
static uint8_t gatt_svr_dsc_val;
static const ble_uuid128_t gatt_svr_dsc_uuid =
BLE_UUID128_INIT(0x01, 0x01, 0x01, 0x01, 0x12, 0x12, 0x12, 0x12,
0x23, 0x23, 0x23, 0x23, 0x34, 0x34, 0x34, 0x34);
// static int
// gatt_svc_access(uint16_t conn_handle, uint16_t attr_handle,
// struct ble_gatt_access_ctxt *ctxt,
// void *arg);
static int
gatt_svc_access(uint16_t conn_handle, uint16_t attr_handle,
struct ble_gatt_access_ctxt *ctxt,
void *arg);
// static const struct ble_gatt_svc_def gatt_svr_svcs[] = {
// {
// /*** Service ***/
// .type = BLE_GATT_SVC_TYPE_PRIMARY,
// .uuid = &gatt_svr_svc_uuid.u,
// .characteristics = (struct ble_gatt_chr_def[])
// { {
// /*** This characteristic can be subscribed to by writing 0x00 and 0x01 to the CCCD ***/
// .uuid = &gatt_svr_chr_uuid.u,
// .access_cb = gatt_svc_access,
// #if CONFIG_EXAMPLE_ENCRYPTION
// .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE |
// BLE_GATT_CHR_F_READ_ENC | BLE_GATT_CHR_F_WRITE_ENC |
// BLE_GATT_CHR_F_NOTIFY | BLE_GATT_CHR_F_INDICATE,
// #else
// .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_NOTIFY | BLE_GATT_CHR_F_INDICATE,
// #endif
// .val_handle = &gatt_svr_chr_val_handle,
// .descriptors = (struct ble_gatt_dsc_def[])
// { {
// .uuid = &gatt_svr_dsc_uuid.u,
// #if CONFIG_EXAMPLE_ENCRYPTION
// .att_flags = BLE_ATT_F_READ | BLE_ATT_F_READ_ENC,
// #else
// .att_flags = BLE_ATT_F_READ,
// #endif
// .access_cb = gatt_svc_access,
// }, {
// 0, /* No more descriptors in this characteristic */
// }
// },
// }, {
// 0, /* No more characteristics in this service. */
// }
// },
// },
// {
// 0, /* No more services. */
// },
// };
// static int
// gatt_svr_write(struct os_mbuf *om, uint16_t min_len, uint16_t max_len,
// void *dst, uint16_t *len)
// {
// uint16_t om_len;
// int rc;
// om_len = OS_MBUF_PKTLEN(om);
// if (om_len < min_len || om_len > max_len) {
// return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
// }
// rc = ble_hs_mbuf_to_flat(om, dst, max_len, len);
// if (rc != 0) {
// return BLE_ATT_ERR_UNLIKELY;
// }
// return 0;
// }
// /**
// * Access callback whenever a characteristic/descriptor is read or written to.
// * Here reads and writes need to be handled.
// * ctxt->op tells weather the operation is read or write and
// * weather it is on a characteristic or descriptor,
// * ctxt->dsc->uuid tells which characteristic/descriptor is accessed.
// * attr_handle give the value handle of the attribute being accessed.
// * Accordingly do:
// * Append the value to ctxt->om if the operation is READ
// * Write ctxt->om to the value if the operation is WRITE
// **/
// static int
// gatt_svc_access(uint16_t conn_handle, uint16_t attr_handle,
// struct ble_gatt_access_ctxt *ctxt, void *arg)
// {
// const ble_uuid_t *uuid;
// int rc;
// switch (ctxt->op) {
// case BLE_GATT_ACCESS_OP_READ_CHR:
// if (conn_handle != BLE_HS_CONN_HANDLE_NONE) {
// MODLOG_DFLT(INFO, "Characteristic read; conn_handle=%d attr_handle=%d\n",
// conn_handle, attr_handle);
// } else {
// MODLOG_DFLT(INFO, "Characteristic read by NimBLE stack; attr_handle=%d\n",
// attr_handle);
// }
// uuid = ctxt->chr->uuid;
// if (attr_handle == gatt_svr_chr_val_handle) {
// rc = os_mbuf_append(ctxt->om,
// &gatt_svr_chr_val,
// sizeof(gatt_svr_chr_val));
// return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
// }
// goto unknown;
// case BLE_GATT_ACCESS_OP_WRITE_CHR:
// if (conn_handle != BLE_HS_CONN_HANDLE_NONE) {
// MODLOG_DFLT(INFO, "Characteristic write; conn_handle=%d attr_handle=%d",
// conn_handle, attr_handle);
// } else {
// MODLOG_DFLT(INFO, "Characteristic write by NimBLE stack; attr_handle=%d",
// attr_handle);
// }
// uuid = ctxt->chr->uuid;
// if (attr_handle == gatt_svr_chr_val_handle) {
// rc = gatt_svr_write(ctxt->om,
// sizeof(gatt_svr_chr_val),
// sizeof(gatt_svr_chr_val),
// &gatt_svr_chr_val, NULL);
// ble_gatts_chr_updated(attr_handle);
// MODLOG_DFLT(INFO, "Notification/Indication scheduled for "
// "all subscribed peers.\n");
// return rc;
// }
// goto unknown;
// case BLE_GATT_ACCESS_OP_READ_DSC:
// if (conn_handle != BLE_HS_CONN_HANDLE_NONE) {
// MODLOG_DFLT(INFO, "Descriptor read; conn_handle=%d attr_handle=%d\n",
// conn_handle, attr_handle);
// } else {
// MODLOG_DFLT(INFO, "Descriptor read by NimBLE stack; attr_handle=%d\n",
// attr_handle);
// }
// uuid = ctxt->dsc->uuid;
// if (ble_uuid_cmp(uuid, &gatt_svr_dsc_uuid.u) == 0) {
// rc = os_mbuf_append(ctxt->om,
// &gatt_svr_dsc_val,
// sizeof(gatt_svr_chr_val));
// return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
// }
// goto unknown;
// case BLE_GATT_ACCESS_OP_WRITE_DSC:
// goto unknown;
// default:
// goto unknown;
// }
// unknown:
// /* Unknown characteristic/descriptor;
// * The NimBLE host should not have called this function;
// */
// assert(0);
// return BLE_ATT_ERR_UNLIKELY;
// }
// void
// gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg)
// {
// char buf[BLE_UUID_STR_LEN];
// switch (ctxt->op) {
// case BLE_GATT_REGISTER_OP_SVC:
// MODLOG_DFLT(DEBUG, "registered service %s with handle=%d\n",
// ble_uuid_to_str(ctxt->svc.svc_def->uuid, buf),
// ctxt->svc.handle);
// break;
// case BLE_GATT_REGISTER_OP_CHR:
// MODLOG_DFLT(DEBUG, "registering characteristic %s with "
// "def_handle=%d val_handle=%d\n",
// ble_uuid_to_str(ctxt->chr.chr_def->uuid, buf),
// ctxt->chr.def_handle,
// ctxt->chr.val_handle);
// break;
// case BLE_GATT_REGISTER_OP_DSC:
// MODLOG_DFLT(DEBUG, "registering descriptor %s with handle=%d\n",
// ble_uuid_to_str(ctxt->dsc.dsc_def->uuid, buf),
// ctxt->dsc.handle);
// break;
// default:
// assert(0);
// break;
// }
// }
// int
// gatt_svr_init(void)
// {
// int rc;
// ble_svc_gap_init();
// ble_svc_gatt_init();
// ble_svc_ans_init();
// rc = ble_gatts_count_cfg(gatt_svr_svcs);
// if (rc != 0) {
// return rc;
// }
// rc = ble_gatts_add_svcs(gatt_svr_svcs);
// if (rc != 0) {
// return rc;
// }
// /* Setting a value for the read-only descriptor */
// gatt_svr_dsc_val = 0x99;
// return 0;
// }
static uint8_t ras_feat_val;
static uint16_t ras_feat_val_handle;
static int
gatt_svr_chr_access_ras_val(uint16_t conn_handle, uint16_t attr_handle,
struct ble_gatt_access_ctxt *ctxt, void *arg);
static const struct ble_gatt_svc_def gatt_svr_svcs[] = {
{
/* Service: Ranging Data Service */
.type = BLE_GATT_SVC_TYPE_PRIMARY,
.uuid = BLE_UUID16_DECLARE(BLE_UUID_RANGING_SERVICE_VAL),
.characteristics = (struct ble_gatt_chr_def[])
{ {
/* Characteristic: Feature Value */
.uuid = BLE_UUID16_DECLARE(BLE_UUID_RAS_FEATURES_VAL),
.access_cb = gatt_svr_chr_access_ras_val,
.val_handle = &ras_feat_val_handle,
.flags = BLE_GATT_CHR_F_READ|BLE_GATT_CHR_F_READ_ENC,
}, {
/* Characteristic: On demand ranging data */
.uuid = BLE_UUID16_DECLARE(BLE_UUID_RAS_ONDEMAND_RD_VAL),
.access_cb = gatt_svr_chr_access_ras_val,
.flags = BLE_GATT_CHR_F_NOTIFY | BLE_GATT_CHR_F_INDICATE |BLE_GATT_CHR_F_READ_ENC ,
},{
/* Characteristic: RAS Control Point */
.uuid = BLE_UUID16_DECLARE(BLE_UUID_RAS_CP_VAL),
.access_cb = gatt_svr_chr_access_ras_val,
.flags = BLE_GATT_CHR_F_WRITE_NO_RSP | BLE_GATT_CHR_F_INDICATE |BLE_GATT_CHR_F_READ_ENC ,
},{
/* Characteristic: RAS Data Ready */
.uuid = BLE_UUID16_DECLARE(BLE_UUID_RAS_RD_READY_VAL),
.access_cb = gatt_svr_chr_access_ras_val,
.flags = BLE_GATT_CHR_F_INDICATE | BLE_GATT_CHR_F_READ_ENC,
},{
/* Characteristic: RAS data overwritten */
.uuid = BLE_UUID16_DECLARE(BLE_UUID_RAS_RD_OVERWRITTEN_VAL),
.access_cb = gatt_svr_chr_access_ras_val,
.flags = BLE_GATT_CHR_F_INDICATE | BLE_GATT_CHR_F_READ_ENC,
static const struct ble_gatt_svc_def gatt_svr_svcs[] = {
{
/*** Service ***/
.type = BLE_GATT_SVC_TYPE_PRIMARY,
.uuid = &gatt_svr_svc_uuid.u,
.characteristics = (struct ble_gatt_chr_def[])
{ {
/*** This characteristic can be subscribed to by writing 0x00 and 0x01 to the CCCD ***/
.uuid = &gatt_svr_chr_uuid.u,
.access_cb = gatt_svc_access,
#if CONFIG_EXAMPLE_ENCRYPTION
.flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE |
BLE_GATT_CHR_F_READ_ENC | BLE_GATT_CHR_F_WRITE_ENC |
BLE_GATT_CHR_F_NOTIFY | BLE_GATT_CHR_F_INDICATE,
#else
.flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_NOTIFY | BLE_GATT_CHR_F_INDICATE,
#endif
.val_handle = &gatt_svr_chr_val_handle,
.descriptors = (struct ble_gatt_dsc_def[])
{ {
.uuid = &gatt_svr_dsc_uuid.u,
#if CONFIG_EXAMPLE_ENCRYPTION
.att_flags = BLE_ATT_F_READ | BLE_ATT_F_READ_ENC,
#else
.att_flags = BLE_ATT_F_READ,
#endif
.access_cb = gatt_svc_access,
}, {
0, /* No more descriptors in this characteristic */
}
},
}, {
0, /* No more characteristics in this service */
},
}
},
{
0, /* No more services */
},
};
0, /* No more characteristics in this service. */
}
},
},
{
0, /* No more services. */
},
};
static int
gatt_svr_chr_access_ras_val(uint16_t conn_handle, uint16_t attr_handle,
struct ble_gatt_access_ctxt *ctxt, void *arg)
{
static int
gatt_svr_write(struct os_mbuf *om, uint16_t min_len, uint16_t max_len,
void *dst, uint16_t *len)
{
uint16_t om_len;
int rc;
om_len = OS_MBUF_PKTLEN(om);
if (om_len < min_len || om_len > max_len) {
return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
}
rc = ble_hs_mbuf_to_flat(om, dst, max_len, len);
if (rc != 0) {
return BLE_ATT_ERR_UNLIKELY;
}
return 0;
}
/**
* Access callback whenever a characteristic/descriptor is read or written to.
* Here reads and writes need to be handled.
* ctxt->op tells weather the operation is read or write and
* weather it is on a characteristic or descriptor,
* ctxt->dsc->uuid tells which characteristic/descriptor is accessed.
* attr_handle give the value handle of the attribute being accessed.
* Accordingly do:
* Append the value to ctxt->om if the operation is READ
* Write ctxt->om to the value if the operation is WRITE
**/
static int
gatt_svc_access(uint16_t conn_handle, uint16_t attr_handle,
struct ble_gatt_access_ctxt *ctxt, void *arg)
{
const ble_uuid_t *uuid;
int rc;
switch (ctxt->op) {
case BLE_GATT_ACCESS_OP_READ_CHR:
printf("reading call back \n");
if (conn_handle != BLE_HS_CONN_HANDLE_NONE) {
MODLOG_DFLT(INFO, "Characteristic read; conn_handle=%d attr_handle=%d\n",
conn_handle, attr_handle);
@@ -328,16 +141,13 @@ static uint16_t ras_feat_val_handle;
MODLOG_DFLT(INFO, "Characteristic read by NimBLE stack; attr_handle=%d\n",
attr_handle);
}
// uuid = ctxt->chr->uuid;
// if(uuid == BLE_UUID_RAS_FEATURES_VAL){
// if (attr_handle == ras_feat_val_handle) {
// rc = os_mbuf_append(ctxt->om,
// &ras_feat_val,
// sizeof(ras_feat_val));
// return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
// }
// }
uuid = ctxt->chr->uuid;
if (attr_handle == gatt_svr_chr_val_handle) {
rc = os_mbuf_append(ctxt->om,
&gatt_svr_chr_val,
sizeof(gatt_svr_chr_val));
return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
}
goto unknown;
case BLE_GATT_ACCESS_OP_WRITE_CHR:
@@ -349,18 +159,39 @@ static uint16_t ras_feat_val_handle;
attr_handle);
}
uuid = ctxt->chr->uuid;
// if (attr_handle == ras_feat_val_handle) {
// rc = gatt_svr_write(ctxt->om,
// sizeof(ras_feat_val),
// sizeof(ras_feat_val),
// &ras_feat_val, NULL);
// ble_gatts_chr_updated(attr_handle);
// MODLOG_DFLT(INFO, "Notification/Indication scheduled for "
// "all subscribed peers.\n");
// return rc;
// }
if (attr_handle == gatt_svr_chr_val_handle) {
rc = gatt_svr_write(ctxt->om,
sizeof(gatt_svr_chr_val),
sizeof(gatt_svr_chr_val),
&gatt_svr_chr_val, NULL);
ble_gatts_chr_updated(attr_handle);
MODLOG_DFLT(INFO, "Notification/Indication scheduled for "
"all subscribed peers.\n");
return rc;
}
goto unknown;
default:
case BLE_GATT_ACCESS_OP_READ_DSC:
if (conn_handle != BLE_HS_CONN_HANDLE_NONE) {
MODLOG_DFLT(INFO, "Descriptor read; conn_handle=%d attr_handle=%d\n",
conn_handle, attr_handle);
} else {
MODLOG_DFLT(INFO, "Descriptor read by NimBLE stack; attr_handle=%d\n",
attr_handle);
}
uuid = ctxt->dsc->uuid;
if (ble_uuid_cmp(uuid, &gatt_svr_dsc_uuid.u) == 0) {
rc = os_mbuf_append(ctxt->om,
&gatt_svr_dsc_val,
sizeof(gatt_svr_chr_val));
return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
}
goto unknown;
case BLE_GATT_ACCESS_OP_WRITE_DSC:
goto unknown;
default:
goto unknown;
}
@@ -370,58 +201,61 @@ unknown:
*/
assert(0);
return BLE_ATT_ERR_UNLIKELY;
}
}
void
gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg)
{
char buf[BLE_UUID_STR_LEN];
void
gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg)
{
char buf[BLE_UUID_STR_LEN];
switch (ctxt->op) {
case BLE_GATT_REGISTER_OP_SVC:
MODLOG_DFLT(DEBUG, "registered service %s with handle=%d\n",
ble_uuid_to_str(ctxt->svc.svc_def->uuid, buf),
ctxt->svc.handle);
break;
switch (ctxt->op) {
case BLE_GATT_REGISTER_OP_SVC:
MODLOG_DFLT(DEBUG, "registered service %s with handle=%d\n",
ble_uuid_to_str(ctxt->svc.svc_def->uuid, buf),
ctxt->svc.handle);
break;
case BLE_GATT_REGISTER_OP_CHR:
MODLOG_DFLT(DEBUG, "registering characteristic %s with "
"def_handle=%d val_handle=%d\n",
ble_uuid_to_str(ctxt->chr.chr_def->uuid, buf),
ctxt->chr.def_handle,
ctxt->chr.val_handle);
break;
case BLE_GATT_REGISTER_OP_CHR:
MODLOG_DFLT(DEBUG, "registering characteristic %s with "
"def_handle=%d val_handle=%d\n",
ble_uuid_to_str(ctxt->chr.chr_def->uuid, buf),
ctxt->chr.def_handle,
ctxt->chr.val_handle);
break;
case BLE_GATT_REGISTER_OP_DSC:
MODLOG_DFLT(DEBUG, "registering descriptor %s with handle=%d\n",
ble_uuid_to_str(ctxt->dsc.dsc_def->uuid, buf),
ctxt->dsc.handle);
break;
case BLE_GATT_REGISTER_OP_DSC:
MODLOG_DFLT(DEBUG, "registering descriptor %s with handle=%d\n",
ble_uuid_to_str(ctxt->dsc.dsc_def->uuid, buf),
ctxt->dsc.handle);
break;
default:
assert(0);
break;
}
}
default:
assert(0);
break;
}
}
int
gatt_svr_init(void)
{
int rc;
int
gatt_svr_init(void)
{
int rc;
ble_svc_gap_init();
ble_svc_gatt_init();
ble_svc_ans_init();
ble_svc_gap_init();
ble_svc_gatt_init();
rc = ble_gatts_count_cfg(gatt_svr_svcs);
if (rc != 0) {
return rc;
}
rc = ble_gatts_count_cfg(gatt_svr_svcs);
if (rc != 0) {
return rc;
}
rc = ble_gatts_add_svcs(gatt_svr_svcs);
if (rc != 0) {
return rc;
}
rc = ble_gatts_add_svcs(gatt_svr_svcs);
if (rc != 0) {
return rc;
}
/* Setting a value for the read-only descriptor */
gatt_svr_dsc_val = 0x99;
return 0;
}
return 0;
}

View File

@@ -137,7 +137,7 @@ ext_bleprph_advertise(void)
/* start advertising */
rc = ble_gap_ext_adv_start(instance, 0, 0);
// assert (rc == 0);
assert (rc == 0);
}
#else
/**
@@ -507,7 +507,7 @@ static void
bleprph_on_sync(void)
{
int rc;
rc = ble_gap_set_host_feat(47,0x01);
#if CONFIG_EXAMPLE_RANDOM_ADDR
/* Generate a non-resolvable private address. */
ble_app_set_addr();

View File

@@ -1068,6 +1068,10 @@ examples/bluetooth/esp_ble_mesh/aligenie_demo/components/vendor_model/include/ge
examples/bluetooth/esp_ble_mesh/aligenie_demo/components/vendor_model/include/genie_slist.h
examples/bluetooth/esp_ble_mesh/aligenie_demo/components/vendor_model/include/genie_timer.h
examples/bluetooth/esp_ble_mesh/aligenie_demo/components/vendor_model/include/genie_util.h
examples/bluetooth/nimble/ble_chan_sound_initiator/main/gatt_svr.c
examples/bluetooth/nimble/ble_chan_sound_reflector/main/ble_chan_reflector.h
examples/bluetooth/nimble/ble_chan_sound_reflector/main/gatt_svr.c
examples/bluetooth/nimble/ble_chan_sound_reflector/main/main.c
examples/bluetooth/nimble/blecent/main/blecent.h
examples/bluetooth/nimble/blecent/main/main.c
examples/bluetooth/nimble/blehr/main/blehr_sens.h