From e08609e451a4bf26a0c9f0002f591f061ab2d304 Mon Sep 17 00:00:00 2001 From: Rahul Tank Date: Sat, 25 Jul 2026 18:45:47 +0530 Subject: [PATCH] fix(nimble): Migrate to NimBLE 1.9.0 --- .../profile/esp/blufi/nimble_host/esp_blufi.c | 4 + components/bt/host/nimble/CMakeLists.txt | 24 ++- components/bt/host/nimble/Kconfig.in | 8 + .../host/nimble/esp-hci/src/esp_nimble_hci.c | 1 + components/bt/host/nimble/nimble | 2 +- .../host/nimble/port/include/esp_nimble_cfg.h | 70 ++++++- .../host/nimble/port/include/esp_nimble_mem.h | 9 +- .../bt/host/nimble/port/src/esp_nimble_mem.c | 88 ++++++++- components/bt/porting/CMakeLists.txt | 11 +- components/bt/porting/include/bt_osi_mem.h | 8 +- components/bt/porting/include/os/os_mempool.h | 18 +- components/bt/porting/mem/bt_osi_mem.c | 177 +++++++++++++++--- .../controller/ble/include/os/os_mempool.h | 17 +- components/esp_hid/src/nimble_hidd.c | 4 +- .../src/transports/protocomm_nimble.c | 2 + .../nimble/NimBLE_Beacon/main/src/gap.c | 8 +- .../nimble/NimBLE_Connection/main/src/gap.c | 7 +- .../nimble/NimBLE_GATT_Server/main/src/gap.c | 7 +- .../nimble/NimBLE_Security/main/src/gap.c | 6 + .../common/ble_uart/ble_uart_nimble.c | 6 +- .../onoff_server/sdkconfig.defaults | 5 + .../bluetooth/nimble/ble_ancs/main/main.c | 2 + .../ble_chan_sound_initiator/main/main.c | 2 + .../ble_chan_sound_reflector/main/main.c | 23 ++- .../nimble/ble_cts/cts_prph/main/main.c | 2 + .../nimble/ble_dynamic_service/main/main.c | 6 + .../enc_adv_data_prph/main/main.c | 2 + .../nimble/ble_gattc_gatts_coex/main/main.c | 4 + .../nimble/ble_htp/htp_prph/main/main.c | 2 + .../ble_l2cap_coc/coc_bleprph/main/main.c | 4 + .../ble_multi_conn_prph/main/main.c | 2 + .../nimble/ble_spp/spp_server/main/main.c | 4 + examples/bluetooth/nimble/blehr/main/main.c | 2 + .../nimble/bleprph_host_only/main/main.c | 2 + .../nimble/bleprph_wifi_coex/main/main.c | 4 + .../gatt/bleprph_throughput/main/main.c | 2 + .../main/ble_helper/nimble_gatts.c | 4 + 37 files changed, 484 insertions(+), 65 deletions(-) diff --git a/components/bt/common/btc/profile/esp/blufi/nimble_host/esp_blufi.c b/components/bt/common/btc/profile/esp/blufi/nimble_host/esp_blufi.c index 6f1ef2b2b7d..a57ff873a75 100644 --- a/components/bt/common/btc/profile/esp/blufi/nimble_host/esp_blufi.c +++ b/components/bt/common/btc/profile/esp/blufi/nimble_host/esp_blufi.c @@ -570,7 +570,9 @@ void esp_blufi_adv_start(void) /* Begin advertising. */ struct ble_gap_adv_params adv_params; struct ble_hs_adv_fields fields; +#if CONFIG_BT_NIMBLE_GAP_SERVICE const char *name; +#endif /** * Set the advertisement data included in our advertisements: @@ -596,12 +598,14 @@ void esp_blufi_adv_start(void) fields.tx_pwr_lvl_is_present = 1; fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO; +#if CONFIG_BT_NIMBLE_GAP_SERVICE name = ble_svc_gap_device_name(); if (name != NULL) { fields.name = (uint8_t *)name; fields.name_len = strlen(name); fields.name_is_complete = 1; } +#endif fields.uuids16 = (ble_uuid16_t[]) { BLE_UUID16_INIT(BLUFI_APP_UUID) diff --git a/components/bt/host/nimble/CMakeLists.txt b/components/bt/host/nimble/CMakeLists.txt index 74c10a6e816..362a9a4165e 100644 --- a/components/bt/host/nimble/CMakeLists.txt +++ b/components/bt/host/nimble/CMakeLists.txt @@ -170,6 +170,12 @@ else() endif() endif() +if(CONFIG_BT_DUAL_MODE_ARCH AND CONFIG_BT_CONTROLLER_ENABLED) + list(APPEND nimble_host_srcs + "${CMAKE_CURRENT_LIST_DIR}/../../porting/mem/bt_osi_mem.c" + ) +endif() + # Reuse the code from the controller to reduce flash usage if(CONFIG_BT_CONTROLLER_DISABLED OR NOT CONFIG_SOC_ESP_NIMBLE_CONTROLLER) list(APPEND nimble_host_srcs @@ -179,10 +185,17 @@ if(CONFIG_BT_CONTROLLER_DISABLED OR NOT CONFIG_SOC_ESP_NIMBLE_CONTROLLER) "${CMAKE_CURRENT_LIST_DIR}/nimble/porting/nimble/src/mem.c" "${CMAKE_CURRENT_LIST_DIR}/nimble/porting/nimble/src/os_mbuf.c" "${CMAKE_CURRENT_LIST_DIR}/nimble/porting/nimble/src/os_msys_init.c" - "${CMAKE_CURRENT_LIST_DIR}/nimble/porting/npl/freertos/src/npl_os_freertos.c" + "${CMAKE_CURRENT_LIST_DIR}/../../porting/mem/bt_osi_mem.c" ) + if(NOT CONFIG_BT_DUAL_MODE_ARCH) + list(APPEND nimble_host_srcs + "${CMAKE_CURRENT_LIST_DIR}/nimble/porting/npl/freertos/src/npl_os_freertos.c" + ) + endif() endif() +list(REMOVE_DUPLICATES nimble_host_srcs) + list(APPEND nimble_host_include_dirs ${CMAKE_CURRENT_LIST_DIR}/nimble/nimble/host/include ${CMAKE_CURRENT_LIST_DIR}/nimble/nimble/include @@ -209,6 +222,7 @@ list(APPEND nimble_host_include_dirs ${CMAKE_CURRENT_LIST_DIR}/nimble/porting/nimble/include ${CMAKE_CURRENT_LIST_DIR}/port/include + ${CMAKE_CURRENT_LIST_DIR}/../../porting/include ${CMAKE_CURRENT_LIST_DIR}/nimble/nimble/transport/include ) @@ -218,13 +232,17 @@ if(CONFIG_BT_CONTROLLER_DISABLED) ) endif() -if(CONFIG_BT_CONTROLLER_DISABLED OR NOT CONFIG_SOC_ESP_NIMBLE_CONTROLLER) +# Add NPL include directories based on which NPL implementation is being used +if(CONFIG_BT_DUAL_MODE_ARCH) + # esp-idf NPL include already added above +else() + # freertos NPL include needed for non-dual-mode targets list(APPEND nimble_host_include_dirs - ${CMAKE_CURRENT_LIST_DIR}/../../porting/include ${CMAKE_CURRENT_LIST_DIR}/nimble/porting/npl/freertos/include ) endif() + # BLE NIMBLE MESH (Deprecated) if(CONFIG_BT_NIMBLE_MESH) list(APPEND nimble_host_srcs diff --git a/components/bt/host/nimble/Kconfig.in b/components/bt/host/nimble/Kconfig.in index 73469c6de9b..0df815dd384 100644 --- a/components/bt/host/nimble/Kconfig.in +++ b/components/bt/host/nimble/Kconfig.in @@ -359,6 +359,14 @@ menu "GAP" Required when the host delays CONNECT so applications never receive other events before CONNECT event. + config BT_NIMBLE_UNHANDLED_HCI_EVENT + bool "Post unhandled HCI events to GAP" + depends on BT_NIMBLE_ENABLED + default n + help + For events that are not handled by stack, they would be directly posted to application + Application is responsible for handling such events. + endmenu #GAP menu "GATT / ATT" diff --git a/components/bt/host/nimble/esp-hci/src/esp_nimble_hci.c b/components/bt/host/nimble/esp-hci/src/esp_nimble_hci.c index 125486965d9..de0af66c5b8 100644 --- a/components/bt/host/nimble/esp-hci/src/esp_nimble_hci.c +++ b/components/bt/host/nimble/esp-hci/src/esp_nimble_hci.c @@ -215,6 +215,7 @@ static void ble_hci_rx_acl(uint8_t *data, uint16_t len) os_mbuf_free_chain(m); return; } + /* Host path may block on the NimBLE event queue; must not run inside OS critical. */ ble_transport_to_hs_acl(m); } #endif diff --git a/components/bt/host/nimble/nimble b/components/bt/host/nimble/nimble index 5311c952a53..920a1e0b753 160000 --- a/components/bt/host/nimble/nimble +++ b/components/bt/host/nimble/nimble @@ -1 +1 @@ -Subproject commit 5311c952a537a609347725b90059ae43fcf9021d +Subproject commit 920a1e0b75323508564e711061a786e3d2d3c1bd diff --git a/components/bt/host/nimble/port/include/esp_nimble_cfg.h b/components/bt/host/nimble/port/include/esp_nimble_cfg.h index 14f7d687152..dce3abb43fa 100644 --- a/components/bt/host/nimble/port/include/esp_nimble_cfg.h +++ b/components/bt/host/nimble/port/include/esp_nimble_cfg.h @@ -102,6 +102,10 @@ #define MYNEWT_VAL_BLE_EXT_ADV (CONFIG_BT_NIMBLE_EXT_ADV) #endif +#ifndef MYNEWT_VAL_BLE_HS_EXT_ADV_LEGACY_INSTANCE +#define MYNEWT_VAL_BLE_HS_EXT_ADV_LEGACY_INSTANCE (0) +#endif + #ifndef MYNEWT_VAL_BLE_EXT_ADV_V2 #ifdef CONFIG_BT_NIMBLE_EXT_ADV_V2 #define MYNEWT_VAL_BLE_EXT_ADV_V2 (CONFIG_BT_NIMBLE_EXT_ADV_V2) @@ -228,6 +232,18 @@ #define MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES (CONFIG_BT_NIMBLE_MAX_EXT_ADV_INSTANCES) #endif +#ifndef MYNEWT_VAL_BLE_HS_16_COMPAT +#define MYNEWT_VAL_BLE_HS_16_COMPAT (1) +#endif + +#ifndef MYNEWT_VAL_BLE_HS_GAP_UNHANDLED_HCI_EVENT +#ifdef CONFIG_BT_NIMBLE_UNHANDLED_HCI_EVENT +#define MYNEWT_VAL_BLE_HS_GAP_UNHANDLED_HCI_EVENT CONFIG_BT_NIMBLE_UNHANDLED_HCI_EVENT +#else +#define MYNEWT_VAL_BLE_HS_GAP_UNHANDLED_HCI_EVENT (0) +#endif +#endif + #ifndef CONFIG_BT_NIMBLE_ENABLE_PERIODIC_ADV #define MYNEWT_VAL_BLE_PERIODIC_ADV (0) #else @@ -601,8 +617,13 @@ #endif #ifndef MYNEWT_VAL_BLE_ATT_PREFERRED_MTU +#ifdef CONFIG_BT_NIMBLE_ATT_PREFERRED_MTU #define MYNEWT_VAL_BLE_ATT_PREFERRED_MTU CONFIG_BT_NIMBLE_ATT_PREFERRED_MTU +#else +#define MYNEWT_VAL_BLE_ATT_PREFERRED_MTU (23) #endif +#endif + #ifndef MYNEWT_VAL_BLE_ATT_SVR_FIND_INFO #define MYNEWT_VAL_BLE_ATT_SVR_FIND_INFO (1) @@ -2025,10 +2046,14 @@ #endif #ifndef MYNEWT_VAL_BLE_HCI_VS +#ifdef CONFIG_BT_NIMBLE_VS_SUPPORT #define MYNEWT_VAL_BLE_HCI_VS CONFIG_BT_NIMBLE_VS_SUPPORT -#define MYNEWT_VAL_BLE_HCI_VS_OCF_OFFSET (0) #else -#define MYNEWT_VAL_BLE_HCI_VS (0) +#define MYNEWT_VAL_BLE_HCI_VS (0) +#endif +#endif +#ifndef MYNEWT_VAL_BLE_HCI_VS_OCF_OFFSET +#define MYNEWT_VAL_BLE_HCI_VS_OCF_OFFSET (0) #endif #ifndef MYNEWT_VAL_OPTIMIZE_MULTI_CONN @@ -2119,6 +2144,14 @@ #endif #endif +#ifndef MYNEWT_VAL_BLE_ISO_MAX_BISES +#ifdef CONFIG_BT_NIMBLE_ISO_MAX_BISES +#define MYNEWT_VAL_BLE_ISO_MAX_BISES CONFIG_BT_NIMBLE_ISO_MAX_BISES +#else +#define MYNEWT_VAL_BLE_ISO_MAX_BISES (4) +#endif +#endif + #ifndef MYNEWT_VAL_BLE_ISO_BIS_PER_BIG #ifdef CONFIG_BT_NIMBLE_ISO_BIS_PER_BIG #define MYNEWT_VAL_BLE_ISO_BIS_PER_BIG CONFIG_BT_NIMBLE_ISO_BIS_PER_BIG @@ -2223,6 +2256,39 @@ #ifndef MYNEWT_VAL_BLE_TRANSPORT_UART_STOP_BITS #define MYNEWT_VAL_BLE_TRANSPORT_UART_STOP_BITS (1) #endif + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_UART_LL_PORT +#define MYNEWT_VAL_BLE_TRANSPORT_UART_LL_PORT MYNEWT_VAL_BLE_TRANSPORT_UART_PORT +#endif + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_UART_LL_PARITY__none +#define MYNEWT_VAL_BLE_TRANSPORT_UART_LL_PARITY__none MYNEWT_VAL_BLE_TRANSPORT_UART_PARITY__none +#endif + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_UART_LL_PARITY__odd +#define MYNEWT_VAL_BLE_TRANSPORT_UART_LL_PARITY__odd MYNEWT_VAL_BLE_TRANSPORT_UART_PARITY__odd +#endif + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_UART_LL_PARITY__even +#define MYNEWT_VAL_BLE_TRANSPORT_UART_LL_PARITY__even MYNEWT_VAL_BLE_TRANSPORT_UART_PARITY__even +#endif + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_UART_LL_FLOW_CONTROL__rtscts +#define MYNEWT_VAL_BLE_TRANSPORT_UART_LL_FLOW_CONTROL__rtscts \ + MYNEWT_VAL_BLE_TRANSPORT_UART_FLOW_CONTROL__rtscts +#endif + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_UART_LL_BAUDRATE +#define MYNEWT_VAL_BLE_TRANSPORT_UART_LL_BAUDRATE MYNEWT_VAL_BLE_TRANSPORT_UART_BAUDRATE +#endif + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_UART_LL_DATA_BITS +#define MYNEWT_VAL_BLE_TRANSPORT_UART_LL_DATA_BITS MYNEWT_VAL_BLE_TRANSPORT_UART_DATA_BITS +#endif + +#ifndef MYNEWT_VAL_BLE_TRANSPORT_UART_LL_STOP_BITS +#define MYNEWT_VAL_BLE_TRANSPORT_UART_LL_STOP_BITS MYNEWT_VAL_BLE_TRANSPORT_UART_STOP_BITS +#endif #endif #ifndef MYNEWT_VAL_BLE_PERIODIC_ADV_WITH_RESPONSES diff --git a/components/bt/host/nimble/port/include/esp_nimble_mem.h b/components/bt/host/nimble/port/include/esp_nimble_mem.h index bc57004da8e..8d19cdecd98 100644 --- a/components/bt/host/nimble/port/include/esp_nimble_mem.h +++ b/components/bt/host/nimble/port/include/esp_nimble_mem.h @@ -8,6 +8,7 @@ #define __ESP_NIMBLE_MEM_H__ #include +#include "bt_osi_mem.h" #ifdef __cplusplus extern "C" { @@ -101,7 +102,9 @@ uint32_t nimble_mem_dbg_get_max_size_section(uint8_t index); void *p; \ do { \ p = nimble_mem_malloc(size); \ - nimble_mem_dbg_record(p, size, __func__, __LINE__); \ + if (p) { \ + nimble_mem_dbg_record(p, size, __func__, __LINE__); \ + } \ } while (0); \ p; \ }) @@ -111,7 +114,9 @@ uint32_t nimble_mem_dbg_get_max_size_section(uint8_t index); void *p; \ do { \ p = nimble_mem_calloc(count, size); \ - nimble_mem_dbg_record(p, (count) * (size), __func__, __LINE__); \ + if (p) { \ + nimble_mem_dbg_record(p, (count) * (size), __func__, __LINE__); \ + } \ } while (0); \ p; \ }) diff --git a/components/bt/host/nimble/port/src/esp_nimble_mem.c b/components/bt/host/nimble/port/src/esp_nimble_mem.c index 05d96c9a80e..5a3e1e98a1c 100644 --- a/components/bt/host/nimble/port/src/esp_nimble_mem.c +++ b/components/bt/host/nimble/port/src/esp_nimble_mem.c @@ -12,12 +12,14 @@ static uint8_t log_count; #if CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED -static size_t host_mem_used_size = 0; +static _Atomic size_t host_mem_used_size = 0; #endif // CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED +void *nimble_mem_realloc(void *ptr, size_t size); + #if CONFIG_BT_NIMBLE_MEM_DEBUG -#define NIMBLE_MEM_DBG_INFO_MAX (1024*3) +#define NIMBLE_MEM_DBG_INFO_MAX (1024 * 3) typedef struct { void *p; int size; @@ -118,7 +120,7 @@ void nimble_mem_dbg_clean(void *p, const char *func, int line) } if (i >= NIMBLE_MEM_DBG_INFO_MAX) { - ESP_LOGE("BT_NIMBLE_MEM", "%s full %s %d !!\n", __func__, func, line); + ESP_LOGE("BT_NIMBLE_MEM", "%s pointer %s %d not found!!\n", __func__, func, line); } } @@ -191,6 +193,67 @@ uint32_t nimble_mem_dbg_get_max_size_section(uint8_t index) return nimble_mem_dbg_max_size_section[index].max_size; } +void *nimble_mem_dbg_realloc(void *ptr, size_t new_size, const char *func, int line) +{ + size_t old_size = 0; + int i; + + void *new_ptr = nimble_mem_realloc(ptr, new_size); + if (new_ptr == NULL && new_size > 0) { + // realloc failed, keep old ptr record + return NULL; + } + + // Find and clean old record if ptr is not NULL + if (ptr != NULL) { + for (i = 0; i < NIMBLE_MEM_DBG_INFO_MAX; i++) { + if (nimble_mem_dbg_info[i].p == ptr) { + old_size = nimble_mem_dbg_info[i].size; + nimble_mem_dbg_current_size -= old_size; + + nimble_mem_dbg_info[i].p = NULL; + nimble_mem_dbg_info[i].size = 0; + nimble_mem_dbg_info[i].func = NULL; + nimble_mem_dbg_info[i].line = 0; + nimble_mem_dbg_count--; + break; + } + } + } + + // Record the new allocation if new_size > 0 + if (new_ptr != NULL && new_size > 0) { + for (i = 0; i < NIMBLE_MEM_DBG_INFO_MAX; i++) { + if (nimble_mem_dbg_info[i].p == NULL) { + nimble_mem_dbg_info[i].p = new_ptr; + nimble_mem_dbg_info[i].size = new_size; + nimble_mem_dbg_info[i].func = func; + nimble_mem_dbg_info[i].line = line; + nimble_mem_dbg_count++; + break; + } + } + + if (i >= NIMBLE_MEM_DBG_INFO_MAX) { + ESP_LOGE("BT_NIMBLE_MEM", "%s full %s %d !!\n", __func__, func, line); + return new_ptr; + } + + nimble_mem_dbg_current_size += new_size; + if (nimble_mem_dbg_max_size < nimble_mem_dbg_current_size) { + nimble_mem_dbg_max_size = nimble_mem_dbg_current_size; + } + + for (i = 0; i < NIMBLE_MEM_DBG_MAX_SECTION_NUM; i++) { + if (nimble_mem_dbg_max_size_section[i].used && + nimble_mem_dbg_max_size_section[i].max_size < nimble_mem_dbg_current_size) { + nimble_mem_dbg_max_size_section[i].max_size = nimble_mem_dbg_current_size; + } + } + } + + return new_ptr; +} #endif // CONFIG_BT_NIMBLE_MEM_DEBUG #if !CONFIG_BT_NIMBLE_LOW_SPEED_MODE @@ -218,7 +281,8 @@ void *nimble_mem_malloc(size_t size) } #if CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED if(mem) { - host_mem_used_size += heap_caps_get_allocated_size(mem); + size_t alloc_size = heap_caps_get_allocated_size(mem); + __atomic_fetch_add(&host_mem_used_size, alloc_size, __ATOMIC_RELAXED); } #endif // CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED return mem; @@ -241,7 +305,8 @@ void *nimble_mem_calloc(size_t n, size_t size) #endif #if CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED if(mem) { - host_mem_used_size += heap_caps_get_allocated_size(mem); + size_t alloc_size = heap_caps_get_allocated_size(mem); + __atomic_fetch_add(&host_mem_used_size, alloc_size, __ATOMIC_RELAXED); } #endif // CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED return mem; @@ -274,17 +339,21 @@ void *nimble_mem_realloc(void *ptr, size_t size) #if CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED if (mem) { + /* Successful realloc: replace old_size contribution with new block size. */ size_t new_size = heap_caps_get_allocated_size(mem); - host_mem_used_size = host_mem_used_size - old_size + new_size; + __atomic_fetch_sub(&host_mem_used_size, old_size, __ATOMIC_RELAXED); + __atomic_fetch_add(&host_mem_used_size, new_size, __ATOMIC_RELAXED); } else if (ptr && size == 0) { - host_mem_used_size -= old_size; + /* realloc(ptr, 0) freed the block and returned NULL; deduct old_size. */ + __atomic_fetch_sub(&host_mem_used_size, old_size, __ATOMIC_RELAXED); } + /* If mem == NULL and size != 0, realloc failed; ptr is still valid and + * host_mem_used_size remains unchanged, which is the correct state. */ #endif // CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED return mem; } - #if !CONFIG_BT_NIMBLE_LOW_SPEED_MODE IRAM_ATTR #endif @@ -293,8 +362,7 @@ void nimble_mem_free(void *ptr) #if CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED if (ptr) { size_t alloc_size = heap_caps_get_allocated_size(ptr); - // assert(host_mem_used_size >= alloc_size); - host_mem_used_size -= alloc_size; + __atomic_fetch_sub(&host_mem_used_size, alloc_size, __ATOMIC_RELAXED); } #endif // CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED if (ptr) { diff --git a/components/bt/porting/CMakeLists.txt b/components/bt/porting/CMakeLists.txt index b8b0ff0097f..ecf073ece0b 100644 --- a/components/bt/porting/CMakeLists.txt +++ b/components/bt/porting/CMakeLists.txt @@ -11,14 +11,21 @@ list(APPEND porting_priv_include_dirs ${CMAKE_CURRENT_SOURCE_DIR}/include ) +# Memory functions are needed for all NIMBLE builds list(APPEND porting_srcs "${CMAKE_CURRENT_SOURCE_DIR}/mem/bt_osi_mem.c" "${CMAKE_CURRENT_SOURCE_DIR}/mem/os_msys_init.c" "${CMAKE_CURRENT_SOURCE_DIR}/mem/os_mempool.c" - "${CMAKE_CURRENT_SOURCE_DIR}/npl/freertos/src/npl_os_freertos.c" - "${CMAKE_CURRENT_SOURCE_DIR}/transport/src/hci_transport.c" ) +# NPL and transport are only for ESP NIMBLE controller targets +if(CONFIG_SOC_ESP_NIMBLE_CONTROLLER) + list(APPEND porting_srcs + "${CMAKE_CURRENT_SOURCE_DIR}/npl/freertos/src/npl_os_freertos.c" + "${CMAKE_CURRENT_SOURCE_DIR}/transport/src/hci_transport.c" + ) +endif() + if(CONFIG_BT_LE_HCI_INTERFACE_USE_RAM) if(CONFIG_BT_NIMBLE_ENABLED) list(APPEND porting_srcs diff --git a/components/bt/porting/include/bt_osi_mem.h b/components/bt/porting/include/bt_osi_mem.h index c0aa125a40c..d3a77d97de2 100644 --- a/components/bt/porting/include/bt_osi_mem.h +++ b/components/bt/porting/include/bt_osi_mem.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -13,8 +13,12 @@ void *bt_osi_mem_malloc(size_t size); +void *bt_osi_mem_calloc(size_t n, size_t size); + void bt_osi_mem_free(void *ptr); +void *bt_osi_mem_realloc(void *ptr, size_t size); + void *bt_osi_mem_malloc_internal(size_t size); void *bt_osi_mem_calloc_internal(size_t n, size_t size); @@ -27,6 +31,4 @@ void bt_osi_mem_count_limit_set(uint16_t count_limit); #if CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED size_t bt_osi_mem_internal_used_size_get(void); -// TODO: Remove it. bt_osi_mem_used_size_get has been defined in esp_nimble_mem.h. -size_t bt_osi_mem_used_size_get(void); #endif // CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED diff --git a/components/bt/porting/include/os/os_mempool.h b/components/bt/porting/include/os/os_mempool.h index 4363d7474c4..312efa9b26d 100644 --- a/components/bt/porting/include/os/os_mempool.h +++ b/components/bt/porting/include/os/os_mempool.h @@ -195,9 +195,25 @@ typedef __uint128_t os_membuf_t; #endif /* OS_ALIGNMENT == * */ #define OS_MEMPOOL_SIZE(n,blksize) ((((blksize) + ((OS_ALIGNMENT)-1)) / (OS_ALIGNMENT)) * (n)) -/** Calculates the number of bytes required to initialize a memory pool. */ +/** + * Calculates the number of bytes required to initialize a memory pool. + * When OS_MEMPOOL_GUARD is enabled, one extra os_membuf_t word per block is + * included for the guard pattern written by os_mempool_init; the buffer passed + * to os_mempool_init must be at least this size. + */ +#if CONFIG_BT_NIMBLE_ENABLED +#if MYNEWT_VAL(OS_MEMPOOL_GUARD) +#define OS_MEMPOOL_BYTES(n,blksize) \ + (sizeof (os_membuf_t) * (OS_MEMPOOL_SIZE((n), (blksize)) + (n))) +#else #define OS_MEMPOOL_BYTES(n,blksize) \ (sizeof (os_membuf_t) * OS_MEMPOOL_SIZE((n), (blksize))) +#endif +#else +/* When NimBLE is disabled, provide basic macro without guard support */ +#define OS_MEMPOOL_BYTES(n,blksize) \ + (sizeof (os_membuf_t) * OS_MEMPOOL_SIZE((n), (blksize))) +#endif /** * Initialize a memory pool. diff --git a/components/bt/porting/mem/bt_osi_mem.c b/components/bt/porting/mem/bt_osi_mem.c index 537dc8def1e..18ed356bed9 100644 --- a/components/bt/porting/mem/bt_osi_mem.c +++ b/components/bt/porting/mem/bt_osi_mem.c @@ -9,6 +9,7 @@ #include "sdkconfig.h" #include "esp_log.h" #include +#include #if CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED static size_t controller_mem_used_size = 0; @@ -18,9 +19,149 @@ static size_t controller_mem_used_size = 0; static uint16_t mem_count_limit = 0; static uint16_t curr_mem_count; #endif // CONFIG_BT_LE_MEM_CHECK_ENABLED +/* Updated with GCC atomic builtins since allocation failures can race. + * DRAM_ATTR ensures the variable is reachable when flash cache is disabled. */ +static DRAM_ATTR uint32_t log_count = 0; -void * -bt_osi_mem_malloc_internal(size_t size) +/* Both helpers are placed in IRAM (matching their callers) so the compiler + * cannot emit them into flash even if it decides not to inline them. + * ESP_DRAM_LOGI places the format string in DRAM, keeping the whole log path + * flash-cache-safe. */ +#if !CONFIG_BT_NIMBLE_LOW_SPEED_MODE +IRAM_ATTR +#endif +static void bt_osi_log_alloc_failure(size_t bytes) +{ + uint32_t count = __atomic_add_fetch(&log_count, 1, __ATOMIC_RELAXED); + if (count == 1 || (count % 100) == 0) { + ESP_DRAM_LOGI("BT_OSI_MEM", "alloc failed (size %zu)", bytes); + } +} + + +#if !CONFIG_BT_NIMBLE_LOW_SPEED_MODE +IRAM_ATTR +#endif +void *bt_osi_mem_malloc(size_t size) +{ + void *mem = NULL; +#if CONFIG_BT_LE_MEM_CHECK_ENABLED + if (mem_count_limit) { + if (curr_mem_count > mem_count_limit) { + return NULL; + } + curr_mem_count++; + } +#endif // CONFIG_BT_LE_MEM_CHECK_ENABLED +#ifdef CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_INTERNAL + mem = heap_caps_malloc(size, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT); +#elif CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_EXTERNAL + mem = heap_caps_malloc(size, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT); +#elif CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_IRAM_8BIT + mem = heap_caps_malloc_prefer(size, 2, MALLOC_CAP_INTERNAL|MALLOC_CAP_IRAM_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT); +#elif CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_DEFAULT + mem = malloc(size); +#else + /* Bluedroid / controller-only: NimBLE mem-mode Kconfig not present. + * Preserve historical INTERNAL alloc used by msys and controller paths. */ + mem = heap_caps_malloc(size, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT); +#endif + if (!mem) { + bt_osi_log_alloc_failure(size); + } +#if CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED + if(mem) { + controller_mem_used_size += heap_caps_get_allocated_size(mem); + } +#endif // CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED + return mem; +} + +#if !CONFIG_BT_NIMBLE_LOW_SPEED_MODE +IRAM_ATTR +#endif +void *bt_osi_mem_calloc(size_t n, size_t size) +{ + void *mem = NULL; +#if CONFIG_BT_LE_MEM_CHECK_ENABLED + if (mem_count_limit) { + if (curr_mem_count > mem_count_limit) { + return NULL; + } + curr_mem_count++; + } +#endif // CONFIG_BT_LE_MEM_CHECK_ENABLED +#ifdef CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_INTERNAL + mem = heap_caps_calloc(n, size, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT); +#elif CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_EXTERNAL + mem = heap_caps_calloc(n, size, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT); +#elif CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_IRAM_8BIT + mem = heap_caps_calloc_prefer(n, size, 2, MALLOC_CAP_INTERNAL|MALLOC_CAP_IRAM_8BIT, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT); +#elif CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_DEFAULT + mem = calloc(n, size); +#else + /* Bluedroid / controller-only: keep INTERNAL (see bt_osi_mem_malloc). */ + mem = heap_caps_calloc(n, size, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT); +#endif + if (!mem) { + size_t total = (size && n > SIZE_MAX / size) ? SIZE_MAX : n * size; + bt_osi_log_alloc_failure(total); + } +#if CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED + if(mem) { + controller_mem_used_size += heap_caps_get_allocated_size(mem); + } +#endif // CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED + return mem; +} + +#if !CONFIG_BT_NIMBLE_LOW_SPEED_MODE +IRAM_ATTR +#endif +void *bt_osi_mem_realloc(void *ptr, size_t size) +{ + void *mem = NULL; +#if CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED + size_t old_size = 0; + if (ptr) { + old_size = heap_caps_get_allocated_size(ptr); + } +#endif + +#ifdef CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_INTERNAL + mem = heap_caps_realloc(ptr, size, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT); +#elif CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_EXTERNAL + mem = heap_caps_realloc(ptr, size, MALLOC_CAP_SPIRAM|MALLOC_CAP_8BIT); +#elif CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_IRAM_8BIT + mem = heap_caps_realloc_prefer(ptr, size, 2, + MALLOC_CAP_INTERNAL|MALLOC_CAP_IRAM_8BIT, + MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT); +#elif CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_DEFAULT + mem = realloc(ptr, size); +#else + /* Bluedroid / controller-only: keep INTERNAL (see bt_osi_mem_malloc). */ + mem = heap_caps_realloc(ptr, size, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT); +#endif + if (!mem && size != 0) { + bt_osi_log_alloc_failure(size); + } + +#if CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED + if (mem) { + size_t new_size = heap_caps_get_allocated_size(mem); + controller_mem_used_size = controller_mem_used_size - old_size + new_size; + } else if (ptr && size == 0) { + controller_mem_used_size -= old_size; + } +#endif + + return mem; +} + +#if !CONFIG_BT_NIMBLE_LOW_SPEED_MODE +IRAM_ATTR +#endif +void *bt_osi_mem_malloc_internal(size_t size) { void *mem_ptr; #if CONFIG_BT_LE_MEM_CHECK_ENABLED @@ -32,6 +173,9 @@ bt_osi_mem_malloc_internal(size_t size) } #endif // CONFIG_BT_LE_MEM_CHECK_ENABLED mem_ptr = heap_caps_malloc(size, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT|MALLOC_CAP_DMA); + if (!mem_ptr) { + bt_osi_log_alloc_failure(size); + } #if CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED if (mem_ptr) { controller_mem_used_size += heap_caps_get_allocated_size(mem_ptr); @@ -54,6 +198,10 @@ bt_osi_mem_calloc_internal(size_t n, size_t size) } #endif // CONFIG_BT_LE_MEM_CHECK_ENABLED mem_ptr = heap_caps_calloc(n, size, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT|MALLOC_CAP_DMA); + if (!mem_ptr) { + size_t total = (size && n > SIZE_MAX / size) ? SIZE_MAX : n * size; + bt_osi_log_alloc_failure(total); + } #if CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED if (mem_ptr) { controller_mem_used_size += heap_caps_get_allocated_size(mem_ptr); @@ -77,31 +225,6 @@ bt_osi_mem_free_internal(void *ptr) } } -void * -bt_osi_mem_malloc(size_t size) -{ - void *mem_ptr; - -#if CONFIG_BT_LE_MEM_CHECK_ENABLED - if (mem_count_limit) { - if (curr_mem_count > mem_count_limit) { - return NULL; - } - curr_mem_count ++; - } -#endif // CONFIG_BT_LE_MEM_CHECK_ENABLED - - mem_ptr = heap_caps_malloc(size, MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT); - -#if CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED - if (mem_ptr) { - controller_mem_used_size += heap_caps_get_allocated_size(mem_ptr); - } -#endif // CONFIG_BT_LE_USED_MEM_STATISTICS_ENABLED - - return mem_ptr; -} - void bt_osi_mem_free(void *ptr) { diff --git a/components/bt/porting_btdm/controller/ble/include/os/os_mempool.h b/components/bt/porting_btdm/controller/ble/include/os/os_mempool.h index 491bf8bb97d..56f5c81a6e7 100644 --- a/components/bt/porting_btdm/controller/ble/include/os/os_mempool.h +++ b/components/bt/porting_btdm/controller/ble/include/os/os_mempool.h @@ -180,9 +180,24 @@ typedef __uint128_t os_membuf_t; #endif /* OS_ALIGNMENT == * */ #define OS_MEMPOOL_SIZE(n,blksize) ((((blksize) + ((OS_ALIGNMENT)-1)) / (OS_ALIGNMENT)) * (n)) -/** Calculates the number of bytes required to initialize a memory pool. */ +/** + * Calculates the number of bytes required to initialize a memory pool. + * When OS_MEMPOOL_GUARD is enabled, one extra os_membuf_t word per block is + * included for the guard pattern written by os_mempool_init; the buffer passed + * to os_mempool_init must be at least this size. + */ +#if CONFIG_BT_NIMBLE_ENABLED +#if MYNEWT_VAL(OS_MEMPOOL_GUARD) +#define OS_MEMPOOL_BYTES(n,blksize) \ + (sizeof (os_membuf_t) * (OS_MEMPOOL_SIZE((n), (blksize)) + (n))) +#else #define OS_MEMPOOL_BYTES(n,blksize) \ (sizeof (os_membuf_t) * OS_MEMPOOL_SIZE((n), (blksize))) +#endif +#else +#define OS_MEMPOOL_BYTES(n,blksize) \ + (sizeof (os_membuf_t) * OS_MEMPOOL_SIZE((n), (blksize))) +#endif #if SOC_ESP_NIMBLE_CONTROLLER && CONFIG_BT_CONTROLLER_ENABLED /** diff --git a/components/esp_hid/src/nimble_hidd.c b/components/esp_hid/src/nimble_hidd.c index 747677ff460..7300f95f606 100644 --- a/components/esp_hid/src/nimble_hidd.c +++ b/components/esp_hid/src/nimble_hidd.c @@ -28,6 +28,9 @@ #include "services/dis/ble_svc_dis.h" #include "services/sps/ble_svc_sps.h" +void ble_hs_lock(void); +void ble_hs_unlock(void); + #if CONFIG_BT_NIMBLE_HID_SERVICE static const char *TAG = "NIMBLE_HIDD"; @@ -231,7 +234,6 @@ static int nimble_hid_stop_gatts(esp_ble_hidd_dev_t *dev) ble_gatts_stop(); ble_svc_hid_deinit(); - ble_svc_hid_reset(); ble_svc_dis_deinit(); ble_svc_bas_deinit(); ble_svc_sps_deinit(); diff --git a/components/protocomm/src/transports/protocomm_nimble.c b/components/protocomm/src/transports/protocomm_nimble.c index 2f46b6d01a5..6a31ec3a6dd 100644 --- a/components/protocomm/src/transports/protocomm_nimble.c +++ b/components/protocomm/src/transports/protocomm_nimble.c @@ -650,6 +650,7 @@ static int simple_ble_start(const simple_ble_cfg_t *cfg) goto err_deinit_port; } +#if CONFIG_BT_NIMBLE_GAP_SERVICE /* Set device name, configure response data to be sent while advertising */ rc = ble_svc_gap_device_name_set(cfg->device_name); if (rc != 0) { @@ -663,6 +664,7 @@ static int simple_ble_start(const simple_ble_cfg_t *cfg) resp_data.name_len = strlen(ble_svc_gap_device_name()); resp_data.name_is_complete = 1; } +#endif #endif /* Set manufacturer data if protocomm_ble_mfg_data points to valid data */ diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Beacon/main/src/gap.c b/examples/bluetooth/ble_get_started/nimble/NimBLE_Beacon/main/src/gap.c index acb8bc50759..4a27c646a51 100644 --- a/examples/bluetooth/ble_get_started/nimble/NimBLE_Beacon/main/src/gap.c +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Beacon/main/src/gap.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -25,7 +25,9 @@ inline static void format_addr(char *addr_str, uint8_t addr[]) { static void start_advertising(void) { /* Local variables */ int rc = 0; +#if CONFIG_BT_NIMBLE_GAP_SERVICE const char *name; +#endif struct ble_hs_adv_fields adv_fields = {0}; struct ble_hs_adv_fields rsp_fields = {0}; struct ble_gap_adv_params adv_params = {0}; @@ -33,6 +35,7 @@ static void start_advertising(void) { /* Set advertising flags */ adv_fields.flags = BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP; +#if CONFIG_BT_NIMBLE_GAP_SERVICE /* Set device name */ name = ble_svc_gap_device_name(); if (name == NULL) { @@ -41,6 +44,7 @@ static void start_advertising(void) { adv_fields.name = (uint8_t *)name; adv_fields.name_len = strlen(name); adv_fields.name_is_complete = 1; +#endif /* Set device tx power */ adv_fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO; @@ -128,6 +132,7 @@ int gap_init(void) { /* Local variables */ int rc = 0; +#if CONFIG_BT_NIMBLE_GAP_SERVICE /* Initialize GAP service */ ble_svc_gap_init(); @@ -145,5 +150,6 @@ int gap_init(void) { ESP_LOGE(TAG, "failed to set device appearance, error code: %d", rc); return rc; } +#endif return rc; } diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/main/src/gap.c b/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/main/src/gap.c index 1c591becf4e..dea9663a010 100644 --- a/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/main/src/gap.c +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Connection/main/src/gap.c @@ -54,7 +54,9 @@ static void print_conn_desc(struct ble_gap_conn_desc *desc) { static void start_advertising(void) { /* Local variables */ int rc = 0; +#if CONFIG_BT_NIMBLE_GAP_SERVICE const char *name; +#endif struct ble_hs_adv_fields adv_fields = {0}; struct ble_hs_adv_fields rsp_fields = {0}; struct ble_gap_adv_params adv_params = {0}; @@ -62,6 +64,7 @@ static void start_advertising(void) { /* Set advertising flags */ adv_fields.flags = BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP; +#if CONFIG_BT_NIMBLE_GAP_SERVICE /* Set device name */ name = ble_svc_gap_device_name(); if (name == NULL) { @@ -70,6 +73,7 @@ static void start_advertising(void) { adv_fields.name = (uint8_t *)name; adv_fields.name_len = strlen(name); adv_fields.name_is_complete = 1; +#endif /* Set device tx power */ adv_fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO; @@ -257,7 +261,7 @@ int gap_init(void) { /* Local variables */ int rc = 0; - +#if CONFIG_BT_NIMBLE_GAP_SERVICE /* Initialize GAP service */ ble_svc_gap_init(); @@ -275,5 +279,6 @@ int gap_init(void) { ESP_LOGE(TAG, "failed to set device appearance, error code: %d", rc); return rc; } +#endif return rc; } diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/main/src/gap.c b/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/main/src/gap.c index d707f881369..067925ad197 100644 --- a/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/main/src/gap.c +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_GATT_Server/main/src/gap.c @@ -54,7 +54,9 @@ static void print_conn_desc(struct ble_gap_conn_desc *desc) { static void start_advertising(void) { /* Local variables */ int rc = 0; +#if CONFIG_BT_NIMBLE_GAP_SERVICE const char *name; +#endif struct ble_hs_adv_fields adv_fields = {0}; struct ble_hs_adv_fields rsp_fields = {0}; struct ble_gap_adv_params adv_params = {0}; @@ -62,6 +64,7 @@ static void start_advertising(void) { /* Set advertising flags */ adv_fields.flags = BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP; +#if CONFIG_BT_NIMBLE_GAP_SERVICE /* Set device name */ name = ble_svc_gap_device_name(); if (name == NULL) { @@ -70,6 +73,7 @@ static void start_advertising(void) { adv_fields.name = (uint8_t *)name; adv_fields.name_len = strlen(name); adv_fields.name_is_complete = 1; +#endif /* Set device tx power */ adv_fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO; @@ -300,7 +304,7 @@ void adv_init(void) { int gap_init(void) { /* Local variables */ int rc = 0; - +#if CONFIG_BT_NIMBLE_GAP_SERVICE /* Call NimBLE GAP initialization API */ ble_svc_gap_init(); @@ -311,5 +315,6 @@ int gap_init(void) { DEVICE_NAME, rc); return rc; } +#endif return rc; } diff --git a/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/main/src/gap.c b/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/main/src/gap.c index 5a9f174c939..e5bc66dc59e 100644 --- a/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/main/src/gap.c +++ b/examples/bluetooth/ble_get_started/nimble/NimBLE_Security/main/src/gap.c @@ -54,7 +54,9 @@ static void print_conn_desc(struct ble_gap_conn_desc *desc) { static void start_advertising(void) { /* Local variables */ int rc = 0; +#if CONFIG_BT_NIMBLE_GAP_SERVICE const char *name; +#endif struct ble_hs_adv_fields adv_fields = {0}; struct ble_hs_adv_fields rsp_fields = {0}; struct ble_gap_adv_params adv_params = {0}; @@ -62,6 +64,7 @@ static void start_advertising(void) { /* Set advertising flags */ adv_fields.flags = BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP; +#if CONFIG_BT_NIMBLE_GAP_SERVICE /* Set device name */ name = ble_svc_gap_device_name(); if (name == NULL) { @@ -70,6 +73,7 @@ static void start_advertising(void) { adv_fields.name = (uint8_t *)name; adv_fields.name_len = strlen(name); adv_fields.name_is_complete = 1; +#endif /* Set device tx power */ adv_fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO; @@ -364,6 +368,7 @@ int gap_init(void) { /* Local variables */ int rc = 0; +#if CONFIG_BT_NIMBLE_GAP_SERVICE /* Call NimBLE GAP initialization API */ ble_svc_gap_init(); @@ -374,5 +379,6 @@ int gap_init(void) { DEVICE_NAME, rc); return rc; } +#endif return rc; } diff --git a/examples/bluetooth/common/ble_uart/ble_uart_nimble.c b/examples/bluetooth/common/ble_uart/ble_uart_nimble.c index 9887240c517..f316753b833 100644 --- a/examples/bluetooth/common/ble_uart/ble_uart_nimble.c +++ b/examples/bluetooth/common/ble_uart/ble_uart_nimble.c @@ -1002,7 +1002,7 @@ int ble_uart_install(const ble_uart_config_t *cfg) ble_hs_cfg.sm_mitm = 0; } -#if NIMBLE_BLE_CONNECT +#if CONFIG_BT_NIMBLE_GAP_SERVICE ble_svc_gap_init(); #endif ble_svc_gatt_init(); @@ -1018,12 +1018,14 @@ int ble_uart_install(const ble_uart_config_t *cfg) /* Best-effort: also set in the GAP service for peer reads. * Returns -1 on the stub path — fine, we already cached locally. */ - rc = ble_svc_gap_device_name_set(s_dev_name); +#if CONFIG_BT_NIMBLE_GAP_SERVICE + rc = ble_svc_gap_device_name_set(s_dev_name); if (rc != 0) { ESP_LOGI(TAG, "ble_svc_gap_device_name_set rc=%d (GAP service stubbed?)", rc); rc = 0; } +#endif } else { s_dev_name[0] = '\0'; } diff --git a/examples/bluetooth/esp_ble_mesh/onoff_models/onoff_server/sdkconfig.defaults b/examples/bluetooth/esp_ble_mesh/onoff_models/onoff_server/sdkconfig.defaults index 5dea3935ab1..ddf9c1304cc 100644 --- a/examples/bluetooth/esp_ble_mesh/onoff_models/onoff_server/sdkconfig.defaults +++ b/examples/bluetooth/esp_ble_mesh/onoff_models/onoff_server/sdkconfig.defaults @@ -16,3 +16,8 @@ CONFIG_BLE_MESH_PB_GATT=y CONFIG_BLE_MESH_TX_SEG_MSG_COUNT=10 CONFIG_BLE_MESH_RX_SEG_MSG_COUNT=10 CONFIG_BLE_MESH_GENERIC_SERVER=y + +# NimBLE host (optional overlay; same as sdkconfig.ci.nimble) +CONFIG_BT_NIMBLE_ENABLED=y +CONFIG_BLE_MESH_LOW_POWER=y +CONFIG_BLE_MESH_SETTINGS=y diff --git a/examples/bluetooth/nimble/ble_ancs/main/main.c b/examples/bluetooth/nimble/ble_ancs/main/main.c index da0c70b3b91..686fcd265b4 100644 --- a/examples/bluetooth/nimble/ble_ancs/main/main.c +++ b/examples/bluetooth/nimble/ble_ancs/main/main.c @@ -779,9 +779,11 @@ app_main(void) ble_hs_cfg.sm_their_key_dist |= BLE_SM_PAIR_KEY_DIST_ENC; ble_hs_cfg.sm_sc = 0; +#if CONFIG_BT_NIMBLE_GAP_SERVICE /* Set the default device name. */ rc = ble_svc_gap_device_name_set("nimble-ancs"); assert(rc == 0); +#endif /* XXX Need to have template for store */ ble_store_config_init(); diff --git a/examples/bluetooth/nimble/ble_chan_sound_initiator/main/main.c b/examples/bluetooth/nimble/ble_chan_sound_initiator/main/main.c index 56a5cfddba9..b2b0fcde039 100644 --- a/examples/bluetooth/nimble/ble_chan_sound_initiator/main/main.c +++ b/examples/bluetooth/nimble/ble_chan_sound_initiator/main/main.c @@ -750,9 +750,11 @@ app_main(void) rc = peer_init(MYNEWT_VAL(BLE_MAX_CONNECTIONS), 64, 64, 64); assert(rc == 0); +#if CONFIG_BT_NIMBLE_GAP_SERVICE /* Set the default device name. */ rc = ble_svc_gap_device_name_set("nimble_ble_channel_sounding"); assert(rc == 0); +#endif /* XXX Need to have template for store */ ble_store_config_init(); diff --git a/examples/bluetooth/nimble/ble_chan_sound_reflector/main/main.c b/examples/bluetooth/nimble/ble_chan_sound_reflector/main/main.c index a037201294b..62f6891848a 100644 --- a/examples/bluetooth/nimble/ble_chan_sound_reflector/main/main.c +++ b/examples/bluetooth/nimble/ble_chan_sound_reflector/main/main.c @@ -150,13 +150,15 @@ static int blecs_gap_event(struct ble_cs_event *event, void *arg) */ ind ++; if (ind==1) { - struct ble_cs_event continue_event; - continue_event.type = BLE_CS_EVENT_SUBEVET_RESULT_CONTINUE; - continue_event.subev_result_continue = event->subev_result_continue; - ble_gatts_store_ranging_data(continue_event); - ble_gatts_indicate_ranging_data_ready(most_recent_local_ranging_counter); - idx = 0; - ind = 0; +#if MYNEWT_VAL(BLE_GATTS) && CONFIG_BT_NIMBLE_RAS_SERVICE + struct ble_cs_event continue_event; + continue_event.type = BLE_CS_EVENT_SUBEVET_RESULT_CONTINUE; + continue_event.subev_result_continue = event->subev_result_continue; + ble_gatts_store_ranging_data(continue_event); + ble_gatts_indicate_ranging_data_ready(most_recent_local_ranging_counter); + idx = 0; + ind = 0; +#endif } } @@ -253,7 +255,9 @@ bleprph_advertise(void) { struct ble_gap_adv_params adv_params; struct ble_hs_adv_fields fields; +#if CONFIG_BT_NIMBLE_GAP_SERVICE const char *name; +#endif int rc; /** * Set the advertisement data included in our advertisements: @@ -400,7 +404,10 @@ bleprph_gap_event(struct ble_gap_event *event, void *arg) event->notify_tx.indication); if (event->notify_tx.status == BLE_HS_EDONE) { +#if MYNEWT_VAL(BLE_GATTS) && CONFIG_BT_NIMBLE_RAS_SERVICE + vTaskDelay(4000 / portTICK_PERIOD_MS); ble_gatts_indicate_control_point_response(event->notify_tx.attr_handle,most_recent_local_ranging_counter); +#endif } return 0; case BLE_GAP_EVENT_SUBSCRIBE: @@ -489,7 +496,9 @@ app_main(void) /* Initialize the NimBLE host configuration. */ ble_hs_cfg.reset_cb = bleprph_on_reset; ble_hs_cfg.sync_cb = bleprph_on_sync; +#if MYNEWT_VAL(BLE_GATTS) && CONFIG_BT_NIMBLE_RAS_SERVICE ble_hs_cfg.gatts_register_cb = custom_gatt_svr_register_cb; +#endif ble_hs_cfg.store_status_cb = ble_store_util_status_rr; ble_hs_cfg.sm_io_cap = 0x03; #ifdef CONFIG_EXAMPLE_BONDING diff --git a/examples/bluetooth/nimble/ble_cts/cts_prph/main/main.c b/examples/bluetooth/nimble/ble_cts/cts_prph/main/main.c index 35968b02a6c..2658a45df18 100644 --- a/examples/bluetooth/nimble/ble_cts/cts_prph/main/main.c +++ b/examples/bluetooth/nimble/ble_cts/cts_prph/main/main.c @@ -305,9 +305,11 @@ void app_main(void) rc = gatt_svr_init(); assert(rc == 0); +#if CONFIG_BT_NIMBLE_GAP_SERVICE /* Set the default device name */ rc = ble_svc_gap_device_name_set(device_name); assert(rc == 0); +#endif #endif /* Start the task */ diff --git a/examples/bluetooth/nimble/ble_dynamic_service/main/main.c b/examples/bluetooth/nimble/ble_dynamic_service/main/main.c index aea975194b5..242c231e4dc 100644 --- a/examples/bluetooth/nimble/ble_dynamic_service/main/main.c +++ b/examples/bluetooth/nimble/ble_dynamic_service/main/main.c @@ -58,7 +58,9 @@ dynamic_service_advertise(void) { struct ble_gap_adv_params adv_params; struct ble_hs_adv_fields fields; +#if CONFIG_BT_NIMBLE_GAP_SERVICE const char *name; +#endif int rc; /** @@ -85,10 +87,12 @@ dynamic_service_advertise(void) fields.tx_pwr_lvl_is_present = 1; fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO; +#if CONFIG_BT_NIMBLE_GAP_SERVICE name = ble_svc_gap_device_name(); fields.name = (uint8_t *)name; fields.name_len = strlen(name); fields.name_is_complete = 1; +#endif /* Must be static: ble_gap_adv_set_fields stores the pointer, not the data. * A stack compound literal becomes dangling after this function returns, @@ -293,6 +297,7 @@ app_main(void) return; } +#if CONFIG_BT_NIMBLE_GAP_SERVICE /* Set the default device name. */ rc = ble_svc_gap_device_name_set("ble-dynamic-service"); if (rc != 0) { @@ -300,6 +305,7 @@ app_main(void) nimble_port_deinit(); return; } +#endif #endif nimble_port_freertos_init(dynamic_service_host_task); diff --git a/examples/bluetooth/nimble/ble_enc_adv_data/enc_adv_data_prph/main/main.c b/examples/bluetooth/nimble/ble_enc_adv_data/enc_adv_data_prph/main/main.c index 10a1737cf56..fb70f71d7f3 100644 --- a/examples/bluetooth/nimble/ble_enc_adv_data/enc_adv_data_prph/main/main.c +++ b/examples/bluetooth/nimble/ble_enc_adv_data/enc_adv_data_prph/main/main.c @@ -523,9 +523,11 @@ app_main(void) rc = gatt_svr_init(); assert(rc == 0); +#if CONFIG_BT_NIMBLE_GAP_SERVICE /* Set the default device name. */ rc = ble_svc_gap_device_name_set("enc_adv_data_prph"); assert(rc == 0); +#endif #endif /* Set the session key and initialization vector */ diff --git a/examples/bluetooth/nimble/ble_gattc_gatts_coex/main/main.c b/examples/bluetooth/nimble/ble_gattc_gatts_coex/main/main.c index a69617bc2db..ff349fd1226 100644 --- a/examples/bluetooth/nimble/ble_gattc_gatts_coex/main/main.c +++ b/examples/bluetooth/nimble/ble_gattc_gatts_coex/main/main.c @@ -489,7 +489,9 @@ ble_coex_advertise(void) { struct ble_gap_adv_params adv_params; struct ble_hs_adv_fields fields; +#if CONFIG_BT_NIMBLE_GAP_SERVICE const char *name; +#endif int rc; /** @@ -516,12 +518,14 @@ ble_coex_advertise(void) fields.tx_pwr_lvl_is_present = 1; fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO; +#if CONFIG_BT_NIMBLE_GAP_SERVICE name = ble_svc_gap_device_name(); if (name) { fields.name = (uint8_t *)name; fields.name_len = strlen(name); fields.name_is_complete = 1; } +#endif static const ble_uuid16_t adv_uuids16[] = { BLE_UUID16_INIT(BLECOEX_SVC_ALERT_UUID) diff --git a/examples/bluetooth/nimble/ble_htp/htp_prph/main/main.c b/examples/bluetooth/nimble/ble_htp/htp_prph/main/main.c index 47abc4d490f..9849775cf20 100644 --- a/examples/bluetooth/nimble/ble_htp/htp_prph/main/main.c +++ b/examples/bluetooth/nimble/ble_htp/htp_prph/main/main.c @@ -377,9 +377,11 @@ void app_main(void) rc = gatt_svr_init(); assert(rc == 0); +#if CONFIG_BT_NIMBLE_GAP_SERVICE /* Set the default device name */ rc = ble_svc_gap_device_name_set(device_name); assert(rc == 0); +#endif #endif /* Start the task */ diff --git a/examples/bluetooth/nimble/ble_l2cap_coc/coc_bleprph/main/main.c b/examples/bluetooth/nimble/ble_l2cap_coc/coc_bleprph/main/main.c index 94198f6ffcc..d4f6a81f159 100644 --- a/examples/bluetooth/nimble/ble_l2cap_coc/coc_bleprph/main/main.c +++ b/examples/bluetooth/nimble/ble_l2cap_coc/coc_bleprph/main/main.c @@ -158,11 +158,13 @@ bleprph_advertise(void) fields.tx_pwr_lvl_is_present = 1; fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO; +#if CONFIG_BT_NIMBLE_GAP_SERVICE const char *name; name = ble_svc_gap_device_name(); fields.name = (uint8_t *)name; fields.name_len = strlen(name); fields.name_is_complete = 1; +#endif static const ble_uuid16_t adv_uuids16[] = { BLE_UUID16_INIT(L2CAP_COC_UUID) @@ -475,9 +477,11 @@ app_main(void) bleprph_l2cap_coc_mem_init(); #endif +#if CONFIG_BT_NIMBLE_GAP_SERVICE /* Set the default device name. */ rc = ble_svc_gap_device_name_set("bleprph-l2coc"); assert(rc == 0); +#endif /* XXX Need to have template for store */ ble_store_config_init(); diff --git a/examples/bluetooth/nimble/ble_multi_conn/ble_multi_conn_prph/main/main.c b/examples/bluetooth/nimble/ble_multi_conn/ble_multi_conn_prph/main/main.c index c9b18309047..6d5b3ef6820 100644 --- a/examples/bluetooth/nimble/ble_multi_conn/ble_multi_conn_prph/main/main.c +++ b/examples/bluetooth/nimble/ble_multi_conn/ble_multi_conn_prph/main/main.c @@ -94,7 +94,9 @@ ble_prph_advertise(void) #else struct ble_gap_adv_params adv_params; struct ble_hs_adv_fields fields; +#if CONFIG_BT_NIMBLE_GAP_SERVICE const char *name; +#endif if (ble_gap_adv_active()) { return; diff --git a/examples/bluetooth/nimble/ble_spp/spp_server/main/main.c b/examples/bluetooth/nimble/ble_spp/spp_server/main/main.c index d4cd20e20a8..20ba388fece 100644 --- a/examples/bluetooth/nimble/ble_spp/spp_server/main/main.c +++ b/examples/bluetooth/nimble/ble_spp/spp_server/main/main.c @@ -89,11 +89,13 @@ ble_spp_server_advertise(void) fields.tx_pwr_lvl_is_present = 1; fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO; +#if CONFIG_BT_NIMBLE_GAP_SERVICE const char *name; name = ble_svc_gap_device_name(); fields.name = (uint8_t *)name; fields.name_len = strlen(name); fields.name_is_complete = 1; +#endif fields.uuids16 = (ble_uuid16_t[]) { BLE_UUID16_INIT(BLE_SVC_SPP_UUID16) @@ -478,9 +480,11 @@ app_main(void) rc = gatt_svr_init(); assert(rc == 0); +#if CONFIG_BT_NIMBLE_GAP_SERVICE /* Set the default device name. */ rc = ble_svc_gap_device_name_set("nimble-ble-spp-svr"); assert(rc == 0); +#endif #endif /* XXX Need to have template for store */ diff --git a/examples/bluetooth/nimble/blehr/main/main.c b/examples/bluetooth/nimble/blehr/main/main.c index 662f178b578..8647f09f673 100644 --- a/examples/bluetooth/nimble/blehr/main/main.c +++ b/examples/bluetooth/nimble/blehr/main/main.c @@ -289,9 +289,11 @@ void app_main(void) rc = gatt_svr_init(); assert(rc == 0); +#if CONFIG_BT_NIMBLE_GAP_SERVICE /* Set the default device name */ rc = ble_svc_gap_device_name_set(device_name); assert(rc == 0); +#endif #endif /* Start the task */ diff --git a/examples/bluetooth/nimble/bleprph_host_only/main/main.c b/examples/bluetooth/nimble/bleprph_host_only/main/main.c index 0e45a58c360..d4859925ba6 100644 --- a/examples/bluetooth/nimble/bleprph_host_only/main/main.c +++ b/examples/bluetooth/nimble/bleprph_host_only/main/main.c @@ -546,7 +546,9 @@ app_main(void) #if MYNEWT_VAL(BLE_GATTS) rc = gatt_svr_init(); assert(rc == 0); +#endif +#if CONFIG_BT_NIMBLE_GAP_SERVICE /* Set the default device name. */ rc = ble_svc_gap_device_name_set("nimble-bleprph"); assert(rc == 0); diff --git a/examples/bluetooth/nimble/bleprph_wifi_coex/main/main.c b/examples/bluetooth/nimble/bleprph_wifi_coex/main/main.c index a631d22e514..a6b966c331a 100644 --- a/examples/bluetooth/nimble/bleprph_wifi_coex/main/main.c +++ b/examples/bluetooth/nimble/bleprph_wifi_coex/main/main.c @@ -345,11 +345,13 @@ bleprph_advertise(void) fields.tx_pwr_lvl_is_present = 1; fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO; +#if CONFIG_BT_NIMBLE_GAP_SERVICE const char *name; name = ble_svc_gap_device_name(); fields.name = (uint8_t *)name; fields.name_len = strlen(name); fields.name_is_complete = 1; +#endif static const ble_uuid16_t adv_uuids16[] = { BLE_UUID16_INIT(GATT_SVR_SVC_ALERT_UUID) @@ -562,9 +564,11 @@ app_main(void) rc = gatt_svr_init(); assert(rc == 0); +#if CONFIG_BT_NIMBLE_GAP_SERVICE /* Set the default device name. */ rc = ble_svc_gap_device_name_set("nimble-bleprph"); assert(rc == 0); +#endif #endif /* XXX Need to have template for store */ diff --git a/examples/bluetooth/nimble/throughput_app/gatt/bleprph_throughput/main/main.c b/examples/bluetooth/nimble/throughput_app/gatt/bleprph_throughput/main/main.c index 032336a1837..ba8f5d32874 100644 --- a/examples/bluetooth/nimble/throughput_app/gatt/bleprph_throughput/main/main.c +++ b/examples/bluetooth/nimble/throughput_app/gatt/bleprph_throughput/main/main.c @@ -561,9 +561,11 @@ void app_main(void) rc = gatt_svr_init(); assert(rc == 0); +#if CONFIG_BT_NIMBLE_GAP_SERVICE /* Set the default device name */ rc = ble_svc_gap_device_name_set(device_name); assert(rc == 0); +#endif #endif /* Start the task */ diff --git a/examples/system/ota/advanced_https_ota/main/ble_helper/nimble_gatts.c b/examples/system/ota/advanced_https_ota/main/ble_helper/nimble_gatts.c index 9045cb4f18c..17be9454d5c 100644 --- a/examples/system/ota/advanced_https_ota/main/ble_helper/nimble_gatts.c +++ b/examples/system/ota/advanced_https_ota/main/ble_helper/nimble_gatts.c @@ -149,7 +149,9 @@ bleprph_advertise(void) { struct ble_gap_adv_params adv_params; struct ble_hs_adv_fields fields; +#if CONFIG_BT_NIMBLE_GAP_SERVICE const char *name; +#endif int rc; /** @@ -176,10 +178,12 @@ bleprph_advertise(void) fields.tx_pwr_lvl_is_present = 1; fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO; +#if CONFIG_BT_NIMBLE_GAP_SERVICE name = ble_svc_gap_device_name(); fields.name = (uint8_t *)name; fields.name_len = strlen(name); fields.name_is_complete = 1; +#endif fields.uuids16 = (ble_uuid16_t[]) { BLE_UUID16_INIT(GATT_SVR_SVC_ALERT_UUID)