diff --git a/components/bt/host/nimble/Kconfig.in b/components/bt/host/nimble/Kconfig.in index d8ff62e96f..6c0ef3238c 100644 --- a/components/bt/host/nimble/Kconfig.in +++ b/components/bt/host/nimble/Kconfig.in @@ -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 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/bt/host/nimble/port/include/esp_nimble_cfg.h b/components/bt/host/nimble/port/include/esp_nimble_cfg.h index cf36dec256..eea72da7b5 100644 --- a/components/bt/host/nimble/port/include/esp_nimble_cfg.h +++ b/components/bt/host/nimble/port/include/esp_nimble_cfg.h @@ -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 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/components/esp_hid/src/nimble_hidh.c b/components/esp_hid/src/nimble_hidh.c index 22b08cbc37..bfbed8eca2 100644 --- a/components/esp_hid/src/nimble_hidh.c +++ b/components/esp_hid/src/nimble_hidh.c @@ -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); 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);