From 2739813bf0fc85ff8de7687cc558484bad34ce19 Mon Sep 17 00:00:00 2001 From: Rahul Tank Date: Wed, 11 Feb 2026 11:39:32 +0530 Subject: [PATCH] fix(nimble): Fix ble_multi_adv example to show correct UUIDs information --- .../bluetooth/nimble/ble_multi_adv/README.md | 7 ++ .../nimble/ble_multi_adv/main/gatt_svr.c | 36 +++++++++- .../nimble/ble_multi_adv/main/main.c | 65 ++++++++++++++----- .../nimble/ble_multi_adv/main/multi_adv.h | 2 + 4 files changed, 92 insertions(+), 18 deletions(-) diff --git a/examples/bluetooth/nimble/ble_multi_adv/README.md b/examples/bluetooth/nimble/ble_multi_adv/README.md index 5ad62ee2f8..9a4ac9e07c 100644 --- a/examples/bluetooth/nimble/ble_multi_adv/README.md +++ b/examples/bluetooth/nimble/ble_multi_adv/README.md @@ -13,6 +13,13 @@ It starts 4 types of advertising: * Scannable legacy * Legacy withe specified duration(5 sec) +## Service UUID Notes + +* The example registers two 16-bit GATT services and one custom 128-bit GATT service. +* All advertising instances include the two 16-bit service UUIDs. +* The connectable advertiser also includes the 128-bit service UUID. +* UUID values in advertising payloads are populated from the same UUID definitions used in the GATT server. + ## How to Use Example Before project configuration and build, be sure to set the correct chip target using: diff --git a/examples/bluetooth/nimble/ble_multi_adv/main/gatt_svr.c b/examples/bluetooth/nimble/ble_multi_adv/main/gatt_svr.c index a3a0564255..0529f010a4 100644 --- a/examples/bluetooth/nimble/ble_multi_adv/main/gatt_svr.c +++ b/examples/bluetooth/nimble/ble_multi_adv/main/gatt_svr.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,6 +15,16 @@ static uint8_t gatt_svr_chr_val = 0x01; /* Example characteristic value */ +#define GATT_SVR_UUID16_1 (0xCDAB) +#define GATT_SVR_UUID16_2 (0x1118) + +static const uint16_t gatt_svr_adv_uuids16[] = { + GATT_SVR_UUID16_1, + GATT_SVR_UUID16_2, +}; +static const ble_uuid16_t gatt_svr_svc16_uuid_1 = BLE_UUID16_INIT(GATT_SVR_UUID16_1); +static const ble_uuid16_t gatt_svr_svc16_uuid_2 = BLE_UUID16_INIT(GATT_SVR_UUID16_2); + 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); @@ -37,6 +47,14 @@ gatt_svc_access(uint16_t conn_handle, uint16_t attr_handle, void *arg); static const struct ble_gatt_svc_def gatt_svr_svcs[] = { + { + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = &gatt_svr_svc16_uuid_1.u, + }, + { + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = &gatt_svr_svc16_uuid_2.u, + }, { /*** Service ***/ .type = BLE_GATT_SVC_TYPE_PRIMARY, @@ -184,3 +202,19 @@ gatt_svr_init(void) return 0; } + +const uint8_t * +gatt_svr_service_uuid128(void) +{ + return gatt_svr_svc_uuid.value; +} + +const uint16_t * +gatt_svr_service_uuids16(size_t *count) +{ + if (count) { + *count = sizeof(gatt_svr_adv_uuids16) / sizeof(gatt_svr_adv_uuids16[0]); + } + + return gatt_svr_adv_uuids16; +} diff --git a/examples/bluetooth/nimble/ble_multi_adv/main/main.c b/examples/bluetooth/nimble/ble_multi_adv/main/main.c index 03f93210fd..a0da020f89 100644 --- a/examples/bluetooth/nimble/ble_multi_adv/main/main.c +++ b/examples/bluetooth/nimble/ble_multi_adv/main/main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2017-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -27,38 +27,66 @@ static int ble_scannable_legacy_ext_cb(uint16_t instance); static int ble_legacy_duration_cb(uint16_t instance); static int ble_non_conn_ext_cb(uint16_t instance); static void ble_multi_advertise(ble_addr_t addr); +#define ADV_UUID16_OFFSET (5) +#define CONNECTABLE_ADV_UUID128_OFFSET (11) /* Advertising patterns */ static uint8_t legacy_dur_adv_pattern[] = { - 0x02, 0x01, 0x06, - 0x03, 0x03, 0xab, 0xcd, - 0x03, 0x03, 0x18, 0x11, - 0x12, 0X09, 'n', 'i', 'm', 'b', 'l', 'e', '-', 'l', 'e', 'g', 'a', 'c', 'y', '-', 'd', 'u', + 0x02, BLE_HS_ADV_TYPE_FLAGS, 0x06, + 0x05, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0x00, 0x00, 0x00, 0x00, + 0x12, BLE_HS_ADV_TYPE_COMP_NAME, 'n', 'i', 'm', 'b', 'l', 'e', '-', 'l', 'e', 'g', 'a', 'c', 'y', '-', 'd', 'u', 'r' }; static uint8_t scannable_legacy_adv_pattern[] = { - 0x02, 0x01, 0x06, - 0x03, 0x03, 0xab, 0xcd, - 0x03, 0x03, 0x18, 0x11, - 0x13, 0X09, 'n', 'i', 'm', 'b', 'l', 'e', '-', 's', 'c', 'a', 'n', '-', 'l', 'e', 'g', 'a', + 0x02, BLE_HS_ADV_TYPE_FLAGS, 0x06, + 0x05, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0x00, 0x00, 0x00, 0x00, + 0x13, BLE_HS_ADV_TYPE_COMP_NAME, 'n', 'i', 'm', 'b', 'l', 'e', '-', 's', 'c', 'a', 'n', '-', 'l', 'e', 'g', 'a', 'c', 'y' }; static uint8_t connectable_adv_pattern[] = { - 0x02, 0x01, 0x06, - 0x03, 0x03, 0xab, 0xcd, - 0x03, 0x03, 0x18, 0x11, - 0x12, 0X09, 'n', 'i', 'm', 'b', 'l', 'e', '-', 'c', 'o', 'n', 'n', 'e', 't', 'a', 'b', 'l', 'e' + 0x02, BLE_HS_ADV_TYPE_FLAGS, 0x06, + 0x05, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0x00, 0x00, 0x00, 0x00, + 0x11, BLE_HS_ADV_TYPE_COMP_UUIDS128, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x12, BLE_HS_ADV_TYPE_COMP_NAME, 'n', 'i', 'm', 'b', 'l', 'e', '-', 'c', 'o', 'n', 'n', 'e', 't', 'a', 'b', 'l', 'e' }; static uint8_t non_conn_adv_pattern[] = { - 0x02, 0x01, 0x06, - 0x03, 0x03, 0xab, 0xcd, - 0x03, 0x03, 0x18, 0x11, - 0x10, 0X09, 'n', 'i', 'm', 'b', 'l', 'e', '-', 'n', 'o', 'n', '-', 'c', 'o', 'n', 'n' + 0x02, BLE_HS_ADV_TYPE_FLAGS, 0x06, + 0x05, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0x00, 0x00, 0x00, 0x00, + 0x10, BLE_HS_ADV_TYPE_COMP_NAME, 'n', 'i', 'm', 'b', 'l', 'e', '-', 'n', 'o', 'n', '-', 'c', 'o', 'n', 'n' }; +static void +ble_multi_adv_set_uuid16_field(uint8_t *adv_pattern, uint8_t uuid_offset) +{ + size_t uuids16_count; + const uint16_t *uuids16 = gatt_svr_service_uuids16(&uuids16_count); + + /* Pattern reserves room for 2 x 16-bit UUIDs. */ + assert(uuids16_count >= 2); + + adv_pattern[uuid_offset] = uuids16[0] & 0xFF; + adv_pattern[uuid_offset + 1] = (uuids16[0] >> 8) & 0xFF; + adv_pattern[uuid_offset + 2] = uuids16[1] & 0xFF; + adv_pattern[uuid_offset + 3] = (uuids16[1] >> 8) & 0xFF; +} + +static void +ble_multi_adv_set_service_uuids(void) +{ + ble_multi_adv_set_uuid16_field(legacy_dur_adv_pattern, ADV_UUID16_OFFSET); + ble_multi_adv_set_uuid16_field(scannable_legacy_adv_pattern, ADV_UUID16_OFFSET); + ble_multi_adv_set_uuid16_field(connectable_adv_pattern, ADV_UUID16_OFFSET); + ble_multi_adv_set_uuid16_field(non_conn_adv_pattern, ADV_UUID16_OFFSET); + + memcpy(&connectable_adv_pattern[CONNECTABLE_ADV_UUID128_OFFSET], + gatt_svr_service_uuid128(), 16); +} + /** * Logs information about a connection to the console. */ @@ -207,6 +235,7 @@ start_connectable_ext(void) { uint8_t instance = 1; struct ble_gap_ext_adv_params params; + int size_pattern = sizeof(connectable_adv_pattern) / sizeof(connectable_adv_pattern[0]); memset (¶ms, 0, sizeof(params)); @@ -438,6 +467,8 @@ ble_multi_adv_on_sync(void) return; } + ble_multi_adv_set_service_uuids(); + start_non_connectable_ext(); start_connectable_ext(); diff --git a/examples/bluetooth/nimble/ble_multi_adv/main/multi_adv.h b/examples/bluetooth/nimble/ble_multi_adv/main/multi_adv.h index 4d8dce4474..39b28f9d0e 100644 --- a/examples/bluetooth/nimble/ble_multi_adv/main/multi_adv.h +++ b/examples/bluetooth/nimble/ble_multi_adv/main/multi_adv.h @@ -27,6 +27,8 @@ struct ble_instance_cb_register { void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg); int gatt_svr_init(void); +const uint16_t *gatt_svr_service_uuids16(size_t *count); +const uint8_t *gatt_svr_service_uuid128(void); #ifdef __cplusplus }