From fc17a5d782eb72899d7d21ba98b08a72d722665d Mon Sep 17 00:00:00 2001 From: Astha Verma Date: Sat, 22 Aug 2026 03:27:20 +0530 Subject: [PATCH 1/9] fix(nimble): Fixed gatt caching crash on disconnect --- components/bt/host/nimble/Kconfig.in | 8 ++++---- components/bt/host/nimble/nimble | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/components/bt/host/nimble/Kconfig.in b/components/bt/host/nimble/Kconfig.in index 3e5e7a76b89..a395040a545 100644 --- a/components/bt/host/nimble/Kconfig.in +++ b/components/bt/host/nimble/Kconfig.in @@ -426,28 +426,28 @@ menu "GATT / ATT" config BT_NIMBLE_GATT_CACHING_MAX_SVCS int "Maximum number of services per connection" depends on BT_NIMBLE_GATT_CACHING - default 64 + default 8 help Set this option to set the upper limit on number of services per connection to be cached. config BT_NIMBLE_GATT_CACHING_MAX_INCL_SVCS int "Maximum number of included services per connection" depends on BT_NIMBLE_GATT_CACHING - default 64 + default 8 help Set this option to set the upper limit on number of included services per connection to be cached. config BT_NIMBLE_GATT_CACHING_MAX_CHRS int "Maximum number of characteristics per connection" depends on BT_NIMBLE_GATT_CACHING - default 64 + default 58 help Set this option to set the upper limit on number of characteristics per connection to be cached. config BT_NIMBLE_GATT_CACHING_MAX_DSCS int "Maximum number of descriptors per connection" depends on BT_NIMBLE_GATT_CACHING - default 64 + default 58 help Set this option to set the upper limit on number of descriptors per connection to be cached. diff --git a/components/bt/host/nimble/nimble b/components/bt/host/nimble/nimble index 83794b7c5fc..6ad55ca0aa7 160000 --- a/components/bt/host/nimble/nimble +++ b/components/bt/host/nimble/nimble @@ -1 +1 @@ -Subproject commit 83794b7c5fcdb1fab972c1ebbc35cd47abaef8f0 +Subproject commit 6ad55ca0aa7f0db03b6301e2f4a8d03309427f7b From 4665b93c663e1000d0f8930d83a6d9aaa247a8d0 Mon Sep 17 00:00:00 2001 From: Rahul Tank Date: Fri, 21 Aug 2026 12:21:04 +0530 Subject: [PATCH 2/9] fix(nimble): bound PAwR synced connect retries in the example --- components/bt/host/nimble/nimble | 2 +- .../nimble/ble_pawr_adv_conn/ble_pawr_adv_conn/main/main.c | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/components/bt/host/nimble/nimble b/components/bt/host/nimble/nimble index 6ad55ca0aa7..96ab0e4d864 160000 --- a/components/bt/host/nimble/nimble +++ b/components/bt/host/nimble/nimble @@ -1 +1 @@ -Subproject commit 6ad55ca0aa7f0db03b6301e2f4a8d03309427f7b +Subproject commit 96ab0e4d864090777512cddbb4aa8609d598c000 diff --git a/examples/bluetooth/nimble/ble_pawr_adv_conn/ble_pawr_adv_conn/main/main.c b/examples/bluetooth/nimble/ble_pawr_adv_conn/ble_pawr_adv_conn/main/main.c index f5145169cc4..533f168d3c8 100644 --- a/examples/bluetooth/nimble/ble_pawr_adv_conn/ble_pawr_adv_conn/main/main.c +++ b/examples/bluetooth/nimble/ble_pawr_adv_conn/ble_pawr_adv_conn/main/main.c @@ -18,6 +18,10 @@ #define BLE_PAWR_RSP_SLOT_SPACING (10) /*!< Time between response slots (N * 0.125 ms) */ #define BLE_PAWR_NUM_RSP_SLOTS (25) /*!< Number of subevent response slots */ #define BLE_PAWR_SUB_DATA_LEN (20) +/* Give the controller a few periodic intervals to report the outcome of a + * synchronized connection attempt before retrying from another subevent. + */ +#define BLE_PAWR_CONN_TIMEOUT_MS (3 * BLE_PAWR_EVENT_PERIODIC_INTERVAL_MS) #define TAG "NimBLE_BLE_PAwR_CONN" @@ -162,7 +166,7 @@ gap_event_cb(struct ble_gap_event *event, void *arg) phy_mask = 0x01; if (conn == 0) { - rc = ble_gap_connect_with_synced(own_addr_type,adv_handle,subevent,&peer_addr,30000,phy_mask,NULL,NULL,NULL,gap_event_cb,NULL); + rc = ble_gap_connect_with_synced(own_addr_type,adv_handle,subevent,&peer_addr,BLE_PAWR_CONN_TIMEOUT_MS,phy_mask,NULL,NULL,NULL,gap_event_cb,NULL); if (rc != 0 ) { ESP_LOGI(TAG,"Error: Failed to connect to device , rc = %d\n",rc); } else { From 66558f8c466e9fe5afa188613fae1a6ae932065b Mon Sep 17 00:00:00 2001 From: ShenWeilong Date: Wed, 26 Aug 2026 11:41:51 +0800 Subject: [PATCH 3/9] fix(bt): fixed mempool deinit crash issue --- components/bt/controller/CMakeLists.txt | 2 +- components/bt/host/nimble/nimble | 2 +- components/bt/porting/include/os/os_mempool.h | 23 +++++++++++++++++++ components/bt/porting/mem/os_mempool.c | 23 ++++++++++++++++++- 4 files changed, 47 insertions(+), 3 deletions(-) diff --git a/components/bt/controller/CMakeLists.txt b/components/bt/controller/CMakeLists.txt index a035fd7586e..1da8ffb796b 100644 --- a/components/bt/controller/CMakeLists.txt +++ b/components/bt/controller/CMakeLists.txt @@ -34,7 +34,7 @@ function(register_bt_ctrl_libs) set(lib_path "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/lib_${TARGET_SRC_NAME}/${TARGET_SRC_NAME}-bt-lib") # BLE controller library if(NOT CONFIG_BT_DUAL_MODE_ARCH OR CONFIG_BT_CTRL_BLE_ENABLE) - if(EXISTS "${lib_path}/libble_app.a") + if(NOT EXISTS "${lib_path}/${idf_target}") if(CONFIG_BT_CTRL_RUN_IN_FLASH_ONLY AND EXISTS "${lib_path}/libble_app_flash.a") add_prebuilt_library(libble_app "${lib_path}/libble_app_flash.a" REQUIRES esp_phy bt) else() diff --git a/components/bt/host/nimble/nimble b/components/bt/host/nimble/nimble index 96ab0e4d864..8d18f6d4ac8 160000 --- a/components/bt/host/nimble/nimble +++ b/components/bt/host/nimble/nimble @@ -1 +1 @@ -Subproject commit 96ab0e4d864090777512cddbb4aa8609d598c000 +Subproject commit 8d18f6d4ac821e139bb0ffa72f3eddde9edac42f diff --git a/components/bt/porting/include/os/os_mempool.h b/components/bt/porting/include/os/os_mempool.h index 4363d7474c4..825018a7160 100644 --- a/components/bt/porting/include/os/os_mempool.h +++ b/components/bt/porting/include/os/os_mempool.h @@ -358,6 +358,29 @@ void os_mempool_flags_set(struct os_mempool *mp, uint8_t flags); */ void os_mempool_flags_clear(struct os_mempool *mp, uint8_t flags); +/** + * @brief Deinitialize a memory pool. + * + * @param mp Pointer to memory pool + */ +void os_mempool_deinit(struct os_mempool *mp); + + /** + * @brief Deinitialize all of memory pools. + * + * @param is_controller Whether called from controller. + * + * @return OS_OK on success; OS_INVALID_PARM if not found corresponding memory pools. + */ +os_error_t os_mempool_deinit_all(bool is_controller); + +/** + * @brief Check if there are any live memory pools. + * + * @return true if there are any live memory pools; false otherwise. + */ +bool os_mempool_has_live_pool(void); + #ifdef __cplusplus } #endif diff --git a/components/bt/porting/mem/os_mempool.c b/components/bt/porting/mem/os_mempool.c index 6f8314c69dc..03b2e599d0a 100644 --- a/components/bt/porting/mem/os_mempool.c +++ b/components/bt/porting/mem/os_mempool.c @@ -735,6 +735,11 @@ os_mempool_module_init(void) static os_error_t os_mempool_mem_free(struct os_mempool *mp) { + /* Extended mempool has its own free logic */ + if (mp->mp_flags & OS_MEMPOOL_F_EXT) { + return OS_OK; + } + /* For runtime allocation mode, check whether all blocks have been freed */ if (!(mp->mp_flags & OS_MEMPOOL_F_RUNTIME)) { return OS_EINVAL; @@ -767,8 +772,15 @@ os_mempool_mem_free(struct os_mempool *mp) #endif void -os_mempool_deinit(bool is_controller) +os_mempool_deinit(struct os_mempool *mp) { + os_mempool_unregister(mp); +} + +os_error_t +os_mempool_deinit_all(bool is_controller) +{ + os_error_t err = OS_INVALID_PARM; struct os_mempool *mp = NULL; struct os_mempool *next = NULL; @@ -780,8 +792,17 @@ os_mempool_deinit(bool is_controller) next = STAILQ_NEXT(mp, mp_list); os_mempool_unregister(mp); mp = next; + err = OS_OK; } else { mp = STAILQ_NEXT(mp, mp_list); } } + + return err; +} + +bool +os_mempool_has_live_pool(void) +{ + return !STAILQ_EMPTY(&g_os_mempool_list); } From 2070731aee0ca47bba332c558487864ddaf0d3ce Mon Sep 17 00:00:00 2001 From: Rahul Tank Date: Wed, 19 Aug 2026 10:17:17 +0530 Subject: [PATCH 4/9] fix(nimble): fix crash on disconnect due to stale per-connection CCCD pool --- components/bt/host/nimble/nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/bt/host/nimble/nimble b/components/bt/host/nimble/nimble index 8d18f6d4ac8..05e03d6ab1f 160000 --- a/components/bt/host/nimble/nimble +++ b/components/bt/host/nimble/nimble @@ -1 +1 @@ -Subproject commit 8d18f6d4ac821e139bb0ffa72f3eddde9edac42f +Subproject commit 05e03d6ab1f502486a3aaf1e15e580847168b8b1 From 42e7cd35f71b2858990480bfd54bd333bc02e29a Mon Sep 17 00:00:00 2001 From: Rahul Tank Date: Mon, 31 Aug 2026 10:53:25 +0530 Subject: [PATCH 5/9] fix(nimble): Avoid NULL proc dereference in GATT client procedures --- components/bt/host/nimble/nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/bt/host/nimble/nimble b/components/bt/host/nimble/nimble index 05e03d6ab1f..233e0651420 160000 --- a/components/bt/host/nimble/nimble +++ b/components/bt/host/nimble/nimble @@ -1 +1 @@ -Subproject commit 05e03d6ab1f502486a3aaf1e15e580847168b8b1 +Subproject commit 233e065142036d8e3949f9f107d2a2851e4cfdab From 595448c891b1d7b635cb963297b32c45dbb74afa Mon Sep 17 00:00:00 2001 From: Rahul Tank Date: Wed, 2 Sep 2026 21:18:18 +0530 Subject: [PATCH 6/9] fix(nimble): Fix for BLERP attack --- components/bt/host/nimble/Kconfig.in | 65 +++++++++++++++++++ components/bt/host/nimble/nimble | 2 +- .../host/nimble/port/include/esp_nimble_cfg.h | 45 +++++++++++++ 3 files changed, 111 insertions(+), 1 deletion(-) diff --git a/components/bt/host/nimble/Kconfig.in b/components/bt/host/nimble/Kconfig.in index a395040a545..594269836af 100644 --- a/components/bt/host/nimble/Kconfig.in +++ b/components/bt/host/nimble/Kconfig.in @@ -202,6 +202,71 @@ menu "Security (SMP)" Enabling this option will delete the pairing of the device and stack will NOT post any event to application. If this option is disabled, application will get BLE_GAP_EVENT_REPEAT_PAIRING event. + + config BT_NIMBLE_SMP_HARDENED_REPAIRING + bool "Reject re-pairing that weakens an existing bond" + default y + help + When a bond already exists, refuse a new pairing that would lower MITM + protection, drop Secure Connections, or shorten the encryption key. + Also enforce that a Pairing Response keeps the MITM/SC bits announced + in a preceding Security Request. + + Same-level re-pairing (peer deleted its own bond and pairs again at the + same strength) is still allowed. A peer that must legitimately re-pair at + a lower level has to be unpaired first (ble_gap_unpair / NVS clear). + + Disable only if a peer must downgrade and the application cannot unbond + it beforehand. + + config BT_NIMBLE_SMP_REQUIRE_ENC_BEFORE_REPAIR + bool "Require encryption before re-pairing with a bonded peer" + default n + help + When enabled, a bonded peer cannot start SMP pairing on an unencrypted + link. The stack replies with Pairing Failed and disconnects. + This blocks same-level recovery when the peer deleted its bond and sends a + Pairing Request before encryption. + + Default is disabled so existing apps and one-sided bond-deletion + recovery keep working. Enable for maximum hardening against + unauthenticated re-pairing. + + config BT_NIMBLE_SMP_REMOVE_BOND_ON_PAIR_FAIL_AS_CENTRAL + bool "Remove the stored bond when pairing fails as Central" + default y + help + Erase NVS bonding keys when pairing or encryption fails while the local + device is Central (link-layer master). Historical Central behaviour and + the default: recovers when the peer deleted the bond and answers + encryption with Key Missing. + + A downgrade refused by BT_NIMBLE_SMP_HARDENED_REPAIRING never erases + the bond, regardless of this option. + + config BT_NIMBLE_SMP_REMOVE_BOND_ON_PAIR_FAIL_AS_PRPH + bool "Remove the stored bond when pairing fails as Peripheral" + default n + help + Erase NVS bonding keys when pairing or encryption fails while the local + device is Peripheral (link-layer slave). Default is disabled so a failed + pairing does not drop the bond; unbond explicitly from the app if needed. + + A downgrade refused by BT_NIMBLE_SMP_HARDENED_REPAIRING never erases + the bond, regardless of this option. + + config BT_NIMBLE_SMP_UNBOND_ON_KEY_MISSING + bool "Drop the local LE keys when the peer reports it has no key" + default n + help + As Central, an encryption attempt using the stored LTK can fail with + "PIN or Key Missing" when the peer deleted the bond. When enabled, the + local keys are discarded so re-pairing can proceed on the same link. + + Default is disabled: the bond is kept and the link is dropped, so a peer + cannot strip the stored security level by refusing to encrypt. With the + default, BT_NIMBLE_SMP_REMOVE_BOND_ON_PAIR_FAIL_AS_CENTRAL still recovers + Central-side Key Missing by erasing on the failure path. endif endmenu #SMP diff --git a/components/bt/host/nimble/nimble b/components/bt/host/nimble/nimble index 233e0651420..1cfacb92c43 160000 --- a/components/bt/host/nimble/nimble +++ b/components/bt/host/nimble/nimble @@ -1 +1 @@ -Subproject commit 233e065142036d8e3949f9f107d2a2851e4cfdab +Subproject commit 1cfacb92c43304fc90a06978bfcd0c89060085af 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 e6b1e2d12c9..0a1de86ac8a 100644 --- a/components/bt/host/nimble/port/include/esp_nimble_cfg.h +++ b/components/bt/host/nimble/port/include/esp_nimble_cfg.h @@ -2241,6 +2241,51 @@ #endif #endif +/* Bool Kconfig: defined=1 when y, absent when n. Non-ESP builds keep syscfg defaults. */ +#ifndef MYNEWT_VAL_BLE_SMP_HARDENED_REPAIRING +#if defined(CONFIG_BT_NIMBLE_SMP_HARDENED_REPAIRING) +#define MYNEWT_VAL_BLE_SMP_HARDENED_REPAIRING (1) +#elif defined(CONFIG_BT_NIMBLE_ENABLED) +#define MYNEWT_VAL_BLE_SMP_HARDENED_REPAIRING (0) +#else +#define MYNEWT_VAL_BLE_SMP_HARDENED_REPAIRING (1) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_SMP_REQUIRE_ENC_BEFORE_REPAIR +#if defined(CONFIG_BT_NIMBLE_SMP_REQUIRE_ENC_BEFORE_REPAIR) +#define MYNEWT_VAL_BLE_SMP_REQUIRE_ENC_BEFORE_REPAIR (1) +#else +#define MYNEWT_VAL_BLE_SMP_REQUIRE_ENC_BEFORE_REPAIR (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_SMP_REMOVE_BOND_ON_PAIR_FAIL_AS_CENTRAL +#if defined(CONFIG_BT_NIMBLE_SMP_REMOVE_BOND_ON_PAIR_FAIL_AS_CENTRAL) +#define MYNEWT_VAL_BLE_SMP_REMOVE_BOND_ON_PAIR_FAIL_AS_CENTRAL (1) +#elif defined(CONFIG_BT_NIMBLE_ENABLED) +#define MYNEWT_VAL_BLE_SMP_REMOVE_BOND_ON_PAIR_FAIL_AS_CENTRAL (0) +#else +#define MYNEWT_VAL_BLE_SMP_REMOVE_BOND_ON_PAIR_FAIL_AS_CENTRAL (1) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_SMP_REMOVE_BOND_ON_PAIR_FAIL_AS_PERIPHERAL +#if defined(CONFIG_BT_NIMBLE_SMP_REMOVE_BOND_ON_PAIR_FAIL_AS_PRPH) +#define MYNEWT_VAL_BLE_SMP_REMOVE_BOND_ON_PAIR_FAIL_AS_PERIPHERAL (1) +#else +#define MYNEWT_VAL_BLE_SMP_REMOVE_BOND_ON_PAIR_FAIL_AS_PERIPHERAL (0) +#endif +#endif + +#ifndef MYNEWT_VAL_BLE_SMP_UNBOND_ON_KEY_MISSING +#if defined(CONFIG_BT_NIMBLE_SMP_UNBOND_ON_KEY_MISSING) +#define MYNEWT_VAL_BLE_SMP_UNBOND_ON_KEY_MISSING (1) +#else +#define MYNEWT_VAL_BLE_SMP_UNBOND_ON_KEY_MISSING (0) +#endif +#endif + #ifndef MYNEWT_VAL_BT_NIMBLE_MEM_OPTIMIZATION #ifdef CONFIG_BT_NIMBLE_MEM_OPTIMIZATION #define MYNEWT_VAL_BT_NIMBLE_MEM_OPTIMIZATION CONFIG_BT_NIMBLE_MEM_OPTIMIZATION From 060d49ec5e023d81ff0f677892cce77d6ef7d6dc Mon Sep 17 00:00:00 2001 From: Rahul Tank Date: Fri, 21 Aug 2026 10:14:35 +0530 Subject: [PATCH 7/9] fix(nimble): Prevent crash in deinit when host init was not completed --- components/bt/host/nimble/nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/bt/host/nimble/nimble b/components/bt/host/nimble/nimble index 1cfacb92c43..d3e5eff797e 160000 --- a/components/bt/host/nimble/nimble +++ b/components/bt/host/nimble/nimble @@ -1 +1 @@ -Subproject commit 1cfacb92c43304fc90a06978bfcd0c89060085af +Subproject commit d3e5eff797e9bdfb51bfe0864d7762da310d8774 From 254d11666f35799ec2feafec0b4d6609d98ab30c Mon Sep 17 00:00:00 2001 From: Astha Verma Date: Tue, 25 Aug 2026 15:03:12 +0530 Subject: [PATCH 8/9] fix(nimble): Fix nimble HID service discovery --- components/bt/host/nimble/nimble | 2 +- components/esp_hid/src/nimble_hidh.c | 98 +++++++++++++++------------- 2 files changed, 52 insertions(+), 48 deletions(-) diff --git a/components/bt/host/nimble/nimble b/components/bt/host/nimble/nimble index d3e5eff797e..c409049a82f 160000 --- a/components/bt/host/nimble/nimble +++ b/components/bt/host/nimble/nimble @@ -1 +1 @@ -Subproject commit d3e5eff797e9bdfb51bfe0864d7762da310d8774 +Subproject commit c409049a82f316ccac19d555abcdacca286943f3 diff --git a/components/esp_hid/src/nimble_hidh.c b/components/esp_hid/src/nimble_hidh.c index a062ebd0b2f..f5ea694daea 100644 --- a/components/esp_hid/src/nimble_hidh.c +++ b/components/esp_hid/src/nimble_hidh.c @@ -428,6 +428,9 @@ static void read_device_services(esp_hidh_dev_t *dev) dev->config.report_maps = NULL; goto done; } + /* HOGP defaults to Report Protocol Mode; the Protocol Mode + * characteristic is often write-only, so it cannot be read back. */ + memset(dev->protocol_mode, ESP_HID_PROTOCOL_MODE_REPORT, dev->config.report_maps_len); } for (uint16_t s = 0; s < svc_count; s++) { @@ -467,6 +470,7 @@ static void read_device_services(esp_hidh_dev_t *dev) for (uint16_t c = 0; c < ccount; c++) { cuuid = ble_uuid_u16(&char_result[c].uuid.u); chandle = char_result[c].val_handle; + report = NULL; ESP_LOGD(TAG, " CHAR:(%d), handle: %d, perm: 0x%02x, uuid: 0x%04x", c + 1, chandle, char_result[c].properties, cuuid); if (suuid == BLE_SVC_GAP_UUID16) { @@ -514,21 +518,22 @@ static void read_device_services(esp_hidh_dev_t *dev) } } } - continue; - } else { - if (cuuid == BLE_SVC_HID_CHR_UUID16_PROTOCOL_MODE) { - if (char_result[c].properties & BLE_GATT_CHR_PROP_READ) { - if (read_char(dev->ble.conn_id, chandle, &rdata, &rlen) == 0 && rlen) { - dev->protocol_mode[hidindex] = *((uint8_t *)rdata); - free(rdata); - rdata = NULL; - } + } + continue; + } else if (suuid == BLE_SVC_HID_UUID16) { + if (cuuid == BLE_SVC_HID_CHR_UUID16_PROTOCOL_MODE) { + if ((char_result[c].properties & BLE_GATT_CHR_PROP_READ) != 0 + && dev->protocol_mode != NULL && hidindex < dev->config.report_maps_len) { + if (read_char(dev->ble.conn_id, chandle, &rdata, &rlen) == 0 && rlen) { + dev->protocol_mode[hidindex] = *((uint8_t *)rdata); } + free(rdata); + rdata = NULL; } continue; - } - if (cuuid == BLE_SVC_HID_CHR_UUID16_REPORT_MAP) { - if (char_result[c].properties & BLE_GATT_CHR_PROP_READ) { + } else if (cuuid == BLE_SVC_HID_CHR_UUID16_REPORT_MAP) { + if ((char_result[c].properties & BLE_GATT_CHR_PROP_READ) != 0 + && dev->config.report_maps != NULL && hidindex < dev->config.report_maps_len) { if (read_char(dev->ble.conn_id, chandle, &rdata, &rlen) == 0 && rlen) { uint8_t *copy = nimble_hidh_dup_bytes(rdata, rlen); if (copy) { @@ -537,41 +542,38 @@ static void read_device_services(esp_hidh_dev_t *dev) dev->config.report_maps[hidindex].len = rlen; } } - continue; - } else if (cuuid == BLE_SVC_HID_CHR_UUID16_BOOT_KBD_INP || cuuid == BLE_SVC_HID_CHR_UUID16_BOOT_KBD_OUT - || cuuid == BLE_SVC_HID_CHR_UUID16_BOOT_MOUSE_INP || cuuid == BLE_SVC_HID_CHR_UUID16_RPT) { - report = (esp_hidh_dev_report_t *)malloc(sizeof(esp_hidh_dev_report_t)); - if (report == NULL) { - ESP_LOGE(TAG, "malloc esp_hidh_dev_report_t failed"); - goto done; - } - report->next = NULL; - report->permissions = char_result[c].properties; - report->handle = chandle; - report->ccc_handle = 0; - report->report_id = 0; - report->map_index = hidindex; - if (cuuid == BLE_SVC_HID_CHR_UUID16_BOOT_KBD_INP) { - report->protocol_mode = ESP_HID_PROTOCOL_MODE_BOOT; - report->report_type = ESP_HID_REPORT_TYPE_INPUT; - report->usage = ESP_HID_USAGE_KEYBOARD; - report->value_len = 8; - } else if (cuuid == BLE_SVC_HID_CHR_UUID16_BOOT_KBD_OUT) { - report->protocol_mode = ESP_HID_PROTOCOL_MODE_BOOT; - report->report_type = ESP_HID_REPORT_TYPE_OUTPUT; - report->usage = ESP_HID_USAGE_KEYBOARD; - report->value_len = 8; - } else if (cuuid == BLE_SVC_HID_CHR_UUID16_BOOT_MOUSE_INP) { - report->protocol_mode = ESP_HID_PROTOCOL_MODE_BOOT; - report->report_type = ESP_HID_REPORT_TYPE_INPUT; - report->usage = ESP_HID_USAGE_MOUSE; - report->value_len = 8; - } else { - report->protocol_mode = ESP_HID_PROTOCOL_MODE_REPORT; - report->report_type = 0; - report->usage = ESP_HID_USAGE_GENERIC; - report->value_len = 0; - } + free(rdata); + rdata = NULL; + } + continue; + } else if (cuuid == BLE_SVC_HID_CHR_UUID16_BOOT_KBD_INP || cuuid == BLE_SVC_HID_CHR_UUID16_BOOT_KBD_OUT + || cuuid == BLE_SVC_HID_CHR_UUID16_BOOT_MOUSE_INP || cuuid == BLE_SVC_HID_CHR_UUID16_RPT) { + report = (esp_hidh_dev_report_t *)malloc(sizeof(esp_hidh_dev_report_t)); + if (report == NULL) { + ESP_LOGE(TAG, "malloc esp_hidh_dev_report_t failed"); + goto done; + } + report->next = NULL; + report->permissions = char_result[c].properties; + report->handle = chandle; + report->ccc_handle = 0; + report->report_id = 0; + report->map_index = hidindex; + if (cuuid == BLE_SVC_HID_CHR_UUID16_BOOT_KBD_INP) { + report->protocol_mode = ESP_HID_PROTOCOL_MODE_BOOT; + report->report_type = ESP_HID_REPORT_TYPE_INPUT; + report->usage = ESP_HID_USAGE_KEYBOARD; + report->value_len = 8; + } else if (cuuid == BLE_SVC_HID_CHR_UUID16_BOOT_KBD_OUT) { + report->protocol_mode = ESP_HID_PROTOCOL_MODE_BOOT; + report->report_type = ESP_HID_REPORT_TYPE_OUTPUT; + report->usage = ESP_HID_USAGE_KEYBOARD; + report->value_len = 8; + } else if (cuuid == BLE_SVC_HID_CHR_UUID16_BOOT_MOUSE_INP) { + report->protocol_mode = ESP_HID_PROTOCOL_MODE_BOOT; + report->report_type = ESP_HID_REPORT_TYPE_INPUT; + report->usage = ESP_HID_USAGE_MOUSE; + report->value_len = 8; } else { report->protocol_mode = ESP_HID_PROTOCOL_MODE_REPORT; report->report_type = 0; @@ -581,6 +583,8 @@ static void read_device_services(esp_hidh_dev_t *dev) } else { continue; } + } else { + continue; } struct ble_gatt_dsc descr_result[HIDH_MAX_DSCS]; uint16_t num_dsc = HIDH_MAX_DSCS; From 7cfa8f909d8590b7d1edeec3b8f8a139605a4298 Mon Sep 17 00:00:00 2001 From: Shreeyash Bhakare Date: Wed, 17 Jun 2026 15:45:50 +0530 Subject: [PATCH 9/9] fix(nimble): Send Prepare Write Request before Execute Write with zero-length data --- components/bt/host/nimble/nimble | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/bt/host/nimble/nimble b/components/bt/host/nimble/nimble index c409049a82f..71a1fd7bfd0 160000 --- a/components/bt/host/nimble/nimble +++ b/components/bt/host/nimble/nimble @@ -1 +1 @@ -Subproject commit c409049a82f316ccac19d555abcdacca286943f3 +Subproject commit 71a1fd7bfd0654c6d174cc3f9cb007864f767cbc