Skip to content

Commit

Permalink
Merge branch 'feature/dynamic_services_v5.1' into 'release/v5.1'
Browse files Browse the repository at this point in the history
Nimble: Add support for dynamic service addition / deletion (v5.1)

See merge request espressif/esp-idf!25742
  • Loading branch information
rahult-github committed Sep 6, 2023
2 parents 8ff8486 + 1520984 commit 94ad8f1
Show file tree
Hide file tree
Showing 12 changed files with 1,008 additions and 1 deletion.
6 changes: 6 additions & 0 deletions components/bt/host/nimble/Kconfig.in
Expand Up @@ -208,6 +208,12 @@ config BT_NIMBLE_DEBUG
help
This enables extra runtime asserts and host debugging

config BT_NIMBLE_DYNAMIC_SERVICE
bool "Enable dynamic services"
depends on BT_NIMBLE_ENABLED
help
This enables user to add/remove Gatt services at runtime

config BT_NIMBLE_SVC_GAP_DEVICE_NAME
string "BLE GAP default device name"
depends on BT_NIMBLE_ENABLED
Expand Down
5 changes: 5 additions & 0 deletions components/bt/host/nimble/port/include/esp_nimble_cfg.h
Expand Up @@ -475,6 +475,11 @@
#endif

/*** @apache-mynewt-nimble/nimble/host */

#ifndef MYNEWT_VAL_BLE_DYNAMIC_SERVICE
#define MYNEWT_VAL_BLE_DYNAMIC_SERVICE CONFIG_BT_NIMBLE_DYNAMIC_SERVICE
#endif

#ifndef MYNEWT_VAL_BLE_ATT_PREFERRED_MTU
#define MYNEWT_VAL_BLE_ATT_PREFERRED_MTU CONFIG_BT_NIMBLE_ATT_PREFERRED_MTU
#endif
Expand Down
6 changes: 6 additions & 0 deletions examples/bluetooth/.build-test-rules.yml
Expand Up @@ -142,6 +142,12 @@ examples/bluetooth/nimble:
temporary: true
reason: The runner doesn't support yet

examples/bluetooth/nimble/ble_dynamic_service:
enable:
- if: IDF_TARGET in ["esp32", "esp32c2", "esp32c3", "esp32c6", "esp32h2", "esp32h4", "esp32s3"]
temporary: true
reason: the other targets are not tested yet

examples/bluetooth/nimble/ble_enc_adv_data:
enable:
- if: IDF_TARGET in ["esp32c2", "esp32c6", "esp32h2"]
Expand Down
8 changes: 8 additions & 0 deletions examples/bluetooth/nimble/ble_dynamic_service/CMakeLists.txt
@@ -0,0 +1,8 @@
# The following lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)

set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/bluetooth/nimble/common/nimble_peripheral_utils)

include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(ble_dynamic_service)
167 changes: 167 additions & 0 deletions examples/bluetooth/nimble/ble_dynamic_service/README.md
@@ -0,0 +1,167 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |

# BLE Dyanamic Service Example

(See the README.md file in the upper level 'examples' directory for more information about examples.)

This example creates GATT server and then starts advertising, waiting to be connected to a GATT client.
In the main thread it keeps on adding and deleting one custom service in the gatt server.

It uses ESP32's Bluetooth controller and NimBLE stack based BLE host.

This example aims at understanding addition and deletion of services at runtime.
Note : Services can be added at the time of init. This example focuses on adding services after stack init. There may be active connections at the time the new service is added/deleted.

To test this demo, any BLE scanner app can be used.

## How to Use Example

Before project configuration and build, be sure to set the correct chip target using:

```bash
idf.py set-target <chip_name>
```

### Configure the project

Open the project configuration menu:

```bash
idf.py menuconfig
```
### Build and Flash

Run `idf.py -p PORT flash monitor` to build, flash and monitor the project.

(To exit the serial monitor, type ``Ctrl-]``.)

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 ble_dynamic_service is connected to ble scanner:

```
I (354) BLE_INIT: BT controller compile version [80abacd]
I (354) phy_init: phy_version 950,f732b06,Feb 15 2023,18:57:12
I (404) BLE_INIT: Bluetooth MAC: 58:cf:79:e9:c1:9e
I (404) NimBLE_BLE_DYNAMIC_SERVER: BLE Host Task Started
I (404) NimBLE: GAP procedure initiated: stop advertising.
I (414) NimBLE: Failed to restore IRKs from store; status=8
I (414) NimBLE: Device Address:
I (424) NimBLE: 58:cf:79:e9:c1:9e
I (424) NimBLE:
I (424) NimBLE: GAP procedure initiated: advertise;
I (434) NimBLE: disc_mode=2
I (434) NimBLE: adv_channel_map=0 own_addr_type=0 adv_filter_policy=0 adv_itvl_min=0 adv_itvl_max=0
I (444) NimBLE:
I (15444) NimBLE: Adding Dynamic service
I (30444) NimBLE: Deleting service
I (45444) NimBLE: Adding Dynamic service
I (60444) NimBLE: Deleting service
I (75444) NimBLE: Adding Dynamic service
I (90444) NimBLE: Deleting service
I (101654) NimBLE: connection established; status=0
I (101654) NimBLE: handle=1 our_ota_addr_type=0 our_ota_addr=
I (101654) NimBLE: 58:cf:79:e9:c1:9e
I (101664) NimBLE: our_id_addr_type=0 our_id_addr=
I (101664) NimBLE: 58:cf:79:e9:c1:9e
I (101674) NimBLE: peer_ota_addr_type=1 peer_ota_addr=
I (101674) NimBLE: 41:c7:05:e9:d9:ce
I (101684) NimBLE: peer_id_addr_type=1 peer_id_addr=
I (101684) NimBLE: 41:c7:05:e9:d9:ce
I (101694) NimBLE: conn_itvl=39 conn_latency=0 supervision_timeout=500 encrypted=0 authenticated=0 bonded=0
I (101704) NimBLE:
I (102284) NimBLE: connection updated; status=0
I (102284) NimBLE: handle=1 our_ota_addr_type=0 our_ota_addr=
I (102284) NimBLE: 58:cf:79:e9:c1:9e
I (102294) NimBLE: our_id_addr_type=0 our_id_addr=
I (102294) NimBLE: 58:cf:79:e9:c1:9e
I (102304) NimBLE: peer_ota_addr_type=1 peer_ota_addr=
I (102304) NimBLE: 41:c7:05:e9:d9:ce
I (102314) NimBLE: peer_id_addr_type=1 peer_id_addr=
I (102314) NimBLE: 41:c7:05:e9:d9:ce
I (102324) NimBLE: conn_itvl=6 conn_latency=0 supervision_timeout=500 encrypted=0 authenticated=0 bonded=0
I (102334) NimBLE:
I (102584) NimBLE: connection updated; status=0
I (102584) NimBLE: handle=1 our_ota_addr_type=0 our_ota_addr=
I (102584) NimBLE: 58:cf:79:e9:c1:9e
I (102584) NimBLE: our_id_addr_type=0 our_id_addr=
I (102594) NimBLE: 58:cf:79:e9:c1:9e
I (102594) NimBLE: peer_ota_addr_type=1 peer_ota_addr=
I (102604) NimBLE: 41:c7:05:e9:d9:ce
I (102604) NimBLE: peer_id_addr_type=1 peer_id_addr=
I (102614) NimBLE: 41:c7:05:e9:d9:ce
I (102614) NimBLE: conn_itvl=39 conn_latency=0 supervision_timeout=500 encrypted=0 authenticated=0 bonded=0
I (102624) NimBLE:
I (104974) NimBLE: subscribe event; conn_handle=1 attr_handle=8 reason=1 prevn=0 curn=0 previ=0 curi=1
I (105444) NimBLE: Adding Dynamic service
I (105444) NimBLE: GATT procedure initiated: indicate;
I (105444) NimBLE: att_handle=8
I (105444) NimBLE: notify_tx event; conn_handle=1 attr_handle=8 status=0 is_indication=1
I (105554) NimBLE: notify_tx event; conn_handle=1 attr_handle=8 status=14 is_indication=1
I (105554) NimBLE: GATT procedure initiated: indicate;
I (105564) NimBLE: att_handle=8
I (105564) NimBLE: notify_tx event; conn_handle=1 attr_handle=8 status=0 is_indication=1
I (105654) NimBLE: notify_tx event; conn_handle=1 attr_handle=8 status=14 is_indication=1
I (105904) NimBLE: connection updated; status=0
I (105904) NimBLE: handle=1 our_ota_addr_type=0 our_ota_addr=
I (105904) NimBLE: 58:cf:79:e9:c1:9e
I (105904) NimBLE: our_id_addr_type=0 our_id_addr=
I (105914) NimBLE: 58:cf:79:e9:c1:9e
I (105914) NimBLE: peer_ota_addr_type=1 peer_ota_addr=
I (105924) NimBLE: 41:c7:05:e9:d9:ce
I (105924) NimBLE: peer_id_addr_type=1 peer_id_addr=
I (105934) NimBLE: 41:c7:05:e9:d9:ce
I (105934) NimBLE: conn_itvl=6 conn_latency=0 supervision_timeout=500 encrypted=0 authenticated=0 bonded=0
I (105944) NimBLE:
I (106334) NimBLE: connection updated; status=0
I (106334) NimBLE: handle=1 our_ota_addr_type=0 our_ota_addr=
I (106334) NimBLE: 58:cf:79:e9:c1:9e
I (106344) NimBLE: our_id_addr_type=0 our_id_addr=
I (106344) NimBLE: 58:cf:79:e9:c1:9e
I (106354) NimBLE: peer_ota_addr_type=1 peer_ota_addr=
I (106354) NimBLE: 41:c7:05:e9:d9:ce
I (106364) NimBLE: peer_id_addr_type=1 peer_id_addr=
I (106364) NimBLE: 41:c7:05:e9:d9:ce
I (106374) NimBLE: conn_itvl=39 conn_latency=0 supervision_timeout=500 encrypted=0 authenticated=0 bonded=0
I (106384) NimBLE:
I (109604) NimBLE: subscribe event; conn_handle=1 attr_handle=40 reason=1 prevn=0 curn=1 previ=0 curi=0
I (110484) NimBLE: subscribe event; conn_handle=1 attr_handle=40 reason=1 prevn=1 curn=0 previ=0 curi=0
I (112484) NimBLE: Characteristic read; conn_handle=1 attr_handle=40
I (120454) NimBLE: Deleting service
I (120454) NimBLE: GATT procedure initiated: indicate;
I (120454) NimBLE: att_handle=8
I (120454) NimBLE: notify_tx event; conn_handle=1 attr_handle=8 status=0 is_indication=1
I (120574) NimBLE: notify_tx event; conn_handle=1 attr_handle=8 status=14 is_indication=1
I (120574) NimBLE: GATT procedure initiated: indicate;
I (120574) NimBLE: att_handle=8
```

## 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.
@@ -0,0 +1,5 @@
set(srcs "main.c"
"gatt_svr.c")

idf_component_register(SRCS "${srcs}"
INCLUDE_DIRS ".")
@@ -0,0 +1,36 @@
/*
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/

#ifndef H_BLE_DYNAMIC_SERVICE_
#define H_BLE_DYNAMIC_SERVICE_

#include <stdbool.h>
#include "nimble/ble.h"
#include "modlog/modlog.h"
#include "esp_peripheral.h"
#ifdef __cplusplus
extern "C" {
#endif

struct ble_hs_cfg;
struct ble_gatt_register_ctxt;

/** GATT server. */
#define GATT_SVR_SVC_ALERT_UUID 0x1811
#define GATT_SVR_CHR_SUP_NEW_ALERT_CAT_UUID 0x2A47
#define GATT_SVR_CHR_NEW_ALERT 0x2A46
#define GATT_SVR_CHR_SUP_UNR_ALERT_CAT_UUID 0x2A48
#define GATT_SVR_CHR_UNR_ALERT_STAT_UUID 0x2A45
#define GATT_SVR_CHR_ALERT_NOT_CTRL_PT 0x2A44

void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg);
int gatt_svr_init(void);
int dynamic_service(const uint8_t operation, const struct ble_gatt_svc_def *svcs, const ble_uuid_t *uuid);
#ifdef __cplusplus
}
#endif

#endif

0 comments on commit 94ad8f1

Please sign in to comment.