From 2a08c85677869d55a6df3f336ca2eaf4e38697a0 Mon Sep 17 00:00:00 2001 From: Astha Verma Date: Mon, 8 Sep 2025 15:37:45 +0530 Subject: [PATCH] fix(nimble): Reset HID service during deinit --- components/bt/host/nimble/nimble | 2 +- components/esp_hid/src/nimble_hidd.c | 22 +++-- .../esp_hid_device/main/esp_hid_gap.c | 84 ++++++++++++++++++- .../esp_hid_device/main/esp_hid_gap.h | 1 + .../bluetooth/esp_hid_host/main/esp_hid_gap.h | 2 + 5 files changed, 103 insertions(+), 8 deletions(-) diff --git a/components/bt/host/nimble/nimble b/components/bt/host/nimble/nimble index 883c9ebed0..039d2d62ed 160000 --- a/components/bt/host/nimble/nimble +++ b/components/bt/host/nimble/nimble @@ -1 +1 @@ -Subproject commit 883c9ebed02e937fc3756a3d9fc1e3008500bb69 +Subproject commit 039d2d62ed97fed632827fd51294f04068b2ca60 diff --git a/components/esp_hid/src/nimble_hidd.c b/components/esp_hid/src/nimble_hidd.c index 6c4904160c..6bb00bd525 100644 --- a/components/esp_hid/src/nimble_hidd.c +++ b/components/esp_hid/src/nimble_hidd.c @@ -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]; diff --git a/examples/bluetooth/esp_hid_device/main/esp_hid_gap.c b/examples/bluetooth/esp_hid_device/main/esp_hid_gap.c index 9c87942f88..005966f249 100644 --- a/examples/bluetooth/esp_hid_device/main/esp_hid_gap.c +++ b/examples/bluetooth/esp_hid_device/main/esp_hid_gap.c @@ -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; diff --git a/examples/bluetooth/esp_hid_device/main/esp_hid_gap.h b/examples/bluetooth/esp_hid_device/main/esp_hid_gap.h index 5211c90c83..fe01fc77ee 100644 --- a/examples/bluetooth/esp_hid_device/main/esp_hid_gap.h +++ b/examples/bluetooth/esp_hid_device/main/esp_hid_gap.h @@ -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); diff --git a/examples/bluetooth/esp_hid_host/main/esp_hid_gap.h b/examples/bluetooth/esp_hid_host/main/esp_hid_gap.h index 33bad93103..758de01dff 100644 --- a/examples/bluetooth/esp_hid_host/main/esp_hid_gap.h +++ b/examples/bluetooth/esp_hid_host/main/esp_hid_gap.h @@ -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);