Merge branch 'fix/esp_hid_device_deint_reset' into 'master'

fix(nimble): Reset HID service during deinit

Closes BLERP-2229, BLERP-2521, and BLERP-2541

See merge request espressif/esp-idf!41695
This commit is contained in:
Rahul Tank
2026-01-27 12:13:55 +05:30
8 changed files with 120 additions and 9 deletions
+10 -1
View File
@@ -290,7 +290,7 @@ menu "GAP"
config BT_NIMBLE_MAX_CCCDS
int "Maximum number of CCC descriptors to save across reboots"
default 8
depends on BT_NIMBLE_ENABLED && BT_NIMBLE_NVS_PERSIST
depends on BT_NIMBLE_ENABLED
help
Defines maximum number of CCC descriptors to save
@@ -1217,6 +1217,15 @@ menu "Extra Features"
help
This option is used to enable encrypted advertising data.
config BT_NIMBLE_ADV_UUID_CONCAT
bool "concatenate uuids while parsing advertising data"
default n
depends on BT_NIMBLE_ENABLED
help
Enables concatenation of multiple UUIDs of the same type while parsing
advertising data on the central device. When disabled, only the last
parsed UUID of a given type is retained.
config BT_NIMBLE_MAX_EADS
int "Maximum number of EAD devices to save across reboots"
default 10
@@ -118,6 +118,12 @@
#define MYNEWT_VAL_ENC_ADV_DATA (CONFIG_BT_NIMBLE_ENC_ADV_DATA)
#endif
#ifndef CONFIG_BT_NIMBLE_ADV_UUID_CONCAT
#define MYNEWT_VAL_BLE_ADV_UUID_CONCAT (0)
#else
#define MYNEWT_VAL_BLE_ADV_UUID_CONCAT (CONFIG_BT_NIMBLE_ADV_UUID_CONCAT)
#endif
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
#define BLE_SCAN_RSP_DATA_MAX_LEN_N (1650)
#else
+16 -6
View File
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -35,6 +35,11 @@ static const char *TAG = "NIMBLE_HIDD";
typedef struct esp_ble_hidd_dev_s esp_ble_hidd_dev_t;
// there can be only one BLE HID device
static esp_ble_hidd_dev_t *s_dev = NULL;
/** service index is used to identify the hid service instance
of the registered characteristic.
Assuming the first instance of the hid service is registered first.
Increment service index as the hid services get registered */
static int service_index = -1;
typedef hidd_report_item_t hidd_le_report_item_t;
@@ -183,6 +188,15 @@ static int nimble_hid_stop_gatts(esp_ble_hidd_dev_t *dev)
/* stop gatt database */
ble_gatts_stop();
ble_svc_hid_deinit();
ble_svc_hid_reset();
ble_svc_dis_deinit();
ble_svc_bas_deinit();
ble_svc_sps_deinit();
ble_svc_gatt_deinit();
ble_svc_gap_deinit();
return rc;
}
@@ -283,6 +297,7 @@ static int nimble_hidd_dev_deinit(void *devp)
return ESP_FAIL;
}
s_dev = NULL;
service_index = -1; // resetting the value
nimble_hid_stop_gatts(dev);
esp_event_post_to(dev->event_loop_handle, ESP_HIDD_EVENTS, ESP_HIDD_STOP_EVENT, NULL, 0, portMAX_DELAY);
@@ -521,11 +536,6 @@ static int nimble_hid_gap_event(struct ble_gap_event *event, void *arg)
return 0;
}
/** service index is used to identify the hid service instance
of the registered characteristic.
Assuming the first instance of the hid service is registered first.
Increment service index as the hid services get registered */
static int service_index = -1;
static void nimble_gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg)
{
char buf[BLE_UUID_STR_LEN];
+1
View File
@@ -957,6 +957,7 @@ esp_hidh_dev_t *esp_ble_hidh_dev_open(uint8_t *bda, uint8_t address_type)
dev->report_write = esp_ble_hidh_dev_report_write;
dev->report_read = esp_ble_hidh_dev_report_read;
dev->dump = esp_ble_hidh_dev_dump;
dev->connected = true;
/* perform service discovery and fill the report maps */
read_device_services(dev);
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@@ -1021,6 +1021,44 @@ static esp_err_t init_low_level(uint8_t mode)
#endif /* CONFIG_BT_BLE_ENABLED */
return ret;
}
static esp_err_t deinit_low_level(void)
{
esp_err_t ret;
if (bt_scan_results) {
esp_hid_scan_results_free(bt_scan_results);
bt_scan_results = NULL;
num_bt_scan_results = 0;
}
if (ble_scan_results) {
esp_hid_scan_results_free(ble_scan_results);
ble_scan_results = NULL;
num_ble_scan_results = 0;
}
ret = esp_bluedroid_disable();
if (ret != ESP_OK) {
ESP_LOGE(TAG, "esp_bluedroid_disable failed: %d", ret);
}
ret = esp_bluedroid_deinit();
if (ret != ESP_OK) {
ESP_LOGE(TAG, "esp_bluedroid_deinit failed: %d", ret);
}
ret = esp_bt_controller_disable();
if (ret != ESP_OK) {
ESP_LOGE(TAG, "esp_bt_controller_disable failed: %d", ret);
}
ret = esp_bt_controller_deinit();
if (ret != ESP_OK) {
ESP_LOGE(TAG, "esp_bt_controller_deinit failed: %d", ret);
}
return ret;
}
#endif
#if CONFIG_BT_NIMBLE_ENABLED
@@ -1055,10 +1093,54 @@ static esp_err_t init_low_level(uint8_t mode)
}
return ret;
}
static esp_err_t deinit_low_level(void)
{
esp_err_t ret;
ret = esp_nimble_deinit();
if (ret != ESP_OK) {
ESP_LOGE(TAG, "esp_nimble_deinit failed: %d", ret);
}
ret = esp_bt_controller_disable();
if (ret != ESP_OK) {
ESP_LOGE(TAG, "esp_bt_controller_disable failed: %d", ret);
}
ret = esp_bt_controller_deinit();
if (ret != ESP_OK) {
ESP_LOGE(TAG, "esp_bt_controller_deinit failed: %d", ret);
}
return ret;
}
#endif
esp_err_t esp_hid_gap_deinit(void)
{
esp_err_t ret;
ret = deinit_low_level();
if (ret != ESP_OK) {
ESP_LOGE(TAG, "deinit_low_level failed: %d", ret);
}
if (bt_hidh_cb_semaphore != NULL) {
vSemaphoreDelete(bt_hidh_cb_semaphore);
bt_hidh_cb_semaphore = NULL;
}
if (ble_hidh_cb_semaphore != NULL) {
vSemaphoreDelete(ble_hidh_cb_semaphore);
ble_hidh_cb_semaphore = NULL;
}
return ESP_OK;
}
esp_err_t esp_hid_gap_init(uint8_t mode)
{
esp_err_t ret;
@@ -74,6 +74,7 @@ void print_uuid(esp_bt_uuid_t *uuid);
#endif
esp_err_t esp_hid_gap_init(uint8_t mode);
esp_err_t esp_hid_gap_deinit(void);
esp_err_t esp_hid_ble_gap_adv_init(uint16_t appearance, const char *device_name);
esp_err_t esp_hid_ble_gap_adv_start(void);
@@ -83,6 +83,8 @@ typedef struct esp_hidh_scan_result_s {
} esp_hid_scan_result_t;
esp_err_t esp_hid_gap_init(uint8_t mode);
esp_err_t esp_hid_gap_deinit(void);
esp_err_t esp_hid_scan(uint32_t seconds, size_t *num_results, esp_hid_scan_result_t **results);
void esp_hid_scan_results_free(esp_hid_scan_result_t *results);