diff --git a/components/bt/common/btc/core/btc_manage.c b/components/bt/common/btc/core/btc_manage.c index 52aa837b99..e65e107988 100644 --- a/components/bt/common/btc/core/btc_manage.c +++ b/components/bt/common/btc/core/btc_manage.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -16,6 +16,12 @@ void **btc_profile_cb_tab; void esp_profile_cb_reset(void) { + #if BTC_DYNAMIC_MEMORY == TRUE + if (btc_profile_cb_tab == NULL) { + return; + } + #endif + int i; for (i = 0; i < BTC_PID_NUM; i++) { @@ -25,6 +31,12 @@ void esp_profile_cb_reset(void) int btc_profile_cb_set(btc_pid_t profile_id, void *cb) { + #if BTC_DYNAMIC_MEMORY == TRUE + if (btc_profile_cb_tab == NULL) { + return -1; + } + #endif + if (profile_id < 0 || profile_id >= BTC_PID_NUM) { return -1; } @@ -36,6 +48,12 @@ int btc_profile_cb_set(btc_pid_t profile_id, void *cb) void *btc_profile_cb_get(btc_pid_t profile_id) { + #if BTC_DYNAMIC_MEMORY == TRUE + if (btc_profile_cb_tab == NULL) { + return NULL; + } + #endif + if (profile_id < 0 || profile_id >= BTC_PID_NUM) { return NULL; } diff --git a/components/bt/host/bluedroid/api/esp_bt_device.c b/components/bt/host/bluedroid/api/esp_bt_device.c index ae4ff8ec93..d3229e5f5c 100644 --- a/components/bt/host/bluedroid/api/esp_bt_device.c +++ b/components/bt/host/bluedroid/api/esp_bt_device.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -95,6 +95,11 @@ esp_err_t esp_bt_dev_coex_status_config(esp_bt_dev_coex_type_t type, esp_bt_dev_ } #endif +esp_err_t esp_bt_config_file_path_get(char *file_path) +{ + return btc_config_file_path_get(file_path); +} + esp_err_t esp_bt_config_file_path_update(const char *file_path) { ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_UNINITIALIZED); diff --git a/components/bt/host/bluedroid/api/esp_gap_ble_api.c b/components/bt/host/bluedroid/api/esp_gap_ble_api.c index 1897e05ceb..57ead58af8 100644 --- a/components/bt/host/bluedroid/api/esp_gap_ble_api.c +++ b/components/bt/host/bluedroid/api/esp_gap_ble_api.c @@ -581,6 +581,7 @@ esp_err_t esp_ble_gap_read_rssi(esp_bd_addr_t remote_addr) return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); } + #if (BLE_42_FEATURE_SUPPORT == TRUE) esp_err_t esp_ble_gap_config_scan_rsp_data_raw(uint8_t *raw_data, uint32_t raw_data_len) { @@ -929,6 +930,26 @@ esp_err_t esp_gap_ble_set_channels(esp_gap_ble_channels channels) return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); } +esp_err_t esp_ble_gap_read_channel_map(esp_bd_addr_t bd_addr) +{ + if (!bd_addr) { + return ESP_ERR_INVALID_ARG; + } + + btc_msg_t msg; + btc_ble_gap_args_t arg; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_READ_CHANNEL_MAP; + + memcpy(arg.read_channel_map.bd_addr, bd_addr, ESP_BD_ADDR_LEN); + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) + == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + esp_err_t esp_gap_ble_set_authorization(esp_bd_addr_t bd_addr, bool authorize) { if (!bd_addr) { diff --git a/components/bt/host/bluedroid/api/include/api/esp_bt_device.h b/components/bt/host/bluedroid/api/include/api/esp_bt_device.h index 6e12765ce8..60758f1e59 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_bt_device.h +++ b/components/bt/host/bluedroid/api/include/api/esp_bt_device.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -128,6 +128,17 @@ esp_err_t esp_bt_dev_get_device_name(void) __attribute__((deprecated("Please use */ esp_err_t esp_bt_dev_coex_status_config(esp_bt_dev_coex_type_t type, esp_bt_dev_coex_op_t op, uint8_t status); +/** + * @brief This function is used to get the path name of the Bluetooth bond keys + * saved in the NVS module. + * @param[out] file_path: buffer to store the config file path, max length NVS_KEY_NAME_MAX_SIZE + * + * @return + * - ESP_OK: success + * + */ +esp_err_t esp_bt_config_file_path_get(char *file_path); + /** * @brief This function is used to update the path name of bluetooth bond keys saved in the NVS module * and need to be called before esp_bluedroid_init(). diff --git a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h index 90864bd69b..1a072bf933 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h @@ -245,6 +245,7 @@ typedef enum { ESP_GAP_BLE_SUBRATE_REQUEST_COMPLETE_EVT, /*!< when subrate request command complete, the event comes */ ESP_GAP_BLE_SUBRATE_CHANGE_EVT, /*!< when Connection Subrate Update procedure has completed and some parameters of the specified connection have changed, the event comes */ ESP_GAP_BLE_SET_HOST_FEATURE_CMPL_EVT, /*!< When host feature set complete, the event comes */ + ESP_GAP_BLE_READ_CHANNEL_MAP_COMPLETE_EVT, /*!< When BLE channel map result is received, the event comes */ ESP_GAP_BLE_EVT_MAX, /*!< when maximum advertising event complete, the event comes */ } esp_gap_ble_cb_event_t; @@ -1331,6 +1332,14 @@ typedef union { if the RSSI cannot be read, the RSSI metric shall be set to 127. */ esp_bd_addr_t remote_addr; /*!< The remote device address */ } read_rssi_cmpl; /*!< Event parameter of ESP_GAP_BLE_READ_RSSI_COMPLETE_EVT */ + /** + * @brief ESP_GAP_BLE_READ_CHANNEL_MAP_COMPLETE_EVT + */ + struct ble_read_ble_channel_map_cmpl_evt_param { + esp_bt_status_t status; /*!< Status of the read channel map operation */ + uint8_t channel_map[ESP_GAP_BLE_CHANNELS_LEN]; /*!< The BLE channel map, represented as a 5-byte array */ + esp_bd_addr_t remote_addr; /*!< The remote device address */ + } read_ble_channel_map_cmpl; /*!< Event parameter of ESP_GAP_BLE_READ_CHANNEL_MAP_COMPLETE_EVT */ /** * @brief ESP_GAP_BLE_UPDATE_WHITELIST_COMPLETE_EVT */ @@ -1857,7 +1866,8 @@ esp_err_t esp_ble_gap_set_scan_params(esp_ble_scan_params_t *scan_params); /** * @brief This procedure keep the device scanning the peer device which advertising on the air * - * @param[in] duration: Keeping the scanning time, the unit is second. + * @param[in] duration: The scanning duration in seconds. + * Set to 0 for continuous scanning until explicitly stopped. * * @return * - ESP_OK : success @@ -2200,6 +2210,7 @@ esp_err_t esp_ble_gap_config_scan_rsp_data_raw(uint8_t *raw_data, uint32_t raw_d * - other : failed */ esp_err_t esp_ble_gap_read_rssi(esp_bd_addr_t remote_addr); + #if (BLE_42_FEATURE_SUPPORT == TRUE) /** * @brief This function is called to add a device info into the duplicate scan exceptional list. @@ -2447,6 +2458,18 @@ esp_err_t esp_ble_get_current_conn_params(esp_bd_addr_t bd_addr, esp_gap_conn_pa */ esp_err_t esp_gap_ble_set_channels(esp_gap_ble_channels channels); +/** +* @brief This function is used to read the current channel map +* for the connection identified by remote address. +* +* @param[in] bd_addr : BD address of the peer device +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_gap_read_channel_map(esp_bd_addr_t bd_addr); + /** * @brief This function is called to authorized a link after Authentication(MITM protection) * diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index 2aef794871..2439ad5a69 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -5865,6 +5865,13 @@ void bta_dm_ble_gap_set_vendor_evt_mask(tBTA_DM_MSG *p_data) BTM_BleSetVendorEventMask(p_data->ble_set_vendor_evt_mask.evt_mask, p_data->ble_set_vendor_evt_mask.p_cback); } +void bta_dm_read_ble_channel_map(tBTA_DM_MSG *p_data) +{ + if (p_data && p_data->ch_map.read_ch_map_cb) { + BTM_ReadChannelMap(p_data->ch_map.remote_addr, p_data->ch_map.read_ch_map_cb); + } +} + #if (BLE_50_DTM_TEST_EN == TRUE) void bta_dm_ble_gap_dtm_enhance_tx_start(tBTA_DM_MSG *p_data) { diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c index e4b8029dd2..7b8a0d9a16 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -500,6 +500,20 @@ void BTA_DmBleReadAdvTxPower(tBTA_CMPL_CB *cmpl_cb) } #endif // BLE_HOST_READ_TX_POWER_EN +void BTA_DmBleReadChannelMap(BD_ADDR remote_device, tBTA_CMPL_CB *p_callback) +{ + if (!remote_device || !p_callback) { + return; + } + tBTA_DM_API_READ_CH_MAP *p_msg; + + if ((p_msg = (tBTA_DM_API_READ_CH_MAP *)osi_malloc(sizeof(tBTA_DM_API_READ_CH_MAP))) != NULL) { + p_msg->hdr.event = BTA_DM_API_BLE_READ_CH_MAP_EVT; + memcpy(p_msg->remote_addr, remote_device, sizeof(BD_ADDR)); + p_msg->read_ch_map_cb = p_callback; + bta_sys_sendmsg(p_msg); + } +} #endif ///BLE_INCLUDED == TRUE void BTA_DmReadRSSI(BD_ADDR remote_addr, tBTA_TRANSPORT transport, tBTA_CMPL_CB *cmpl_cb) diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c index 86283b4e52..3aaf6b49ea 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c @@ -286,6 +286,7 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = { bta_dm_ble_gap_set_privacy_mode, /* BTA_DM_API_SET_PRIVACY_MODE_EVT */ bta_dm_ble_gap_set_csa_support, /* BTA_DM_API_BLE_SET_CSA_SUPPORT_EVT */ bta_dm_ble_gap_set_vendor_evt_mask, /* BTA_DM_API_BLE_SET_VENDOR_EVT_MASK_EVT */ + bta_dm_read_ble_channel_map, /* BTA_DM_API_BLE_READ_CH_MAP_EVT */ #endif #if (BLE_FEAT_ISO_EN == TRUE) #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) diff --git a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h index 3d6dcacc0a..4de7e01f15 100644 --- a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h +++ b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h @@ -277,6 +277,7 @@ enum { BTA_DM_API_SET_PRIVACY_MODE_EVT, BTA_DM_API_BLE_SET_CSA_SUPPORT_EVT, BTA_DM_API_BLE_SET_VENDOR_EVT_MASK_EVT, + BTA_DM_API_BLE_READ_CH_MAP_EVT, #endif #if (BLE_FEAT_ISO_EN == TRUE) #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) @@ -490,6 +491,12 @@ typedef struct { tBTA_CMPL_CB *read_rssi_cb; }tBTA_DM_API_READ_RSSI; +typedef struct { + BT_HDR hdr; + BD_ADDR remote_addr; + tBTA_CMPL_CB *read_ch_map_cb; +} tBTA_DM_API_READ_CH_MAP; + /* data type for BTA_DM_API_SET_VISIBILITY_EVT */ typedef struct { BT_HDR hdr; @@ -1639,6 +1646,8 @@ typedef union { #endif ///BLE_INCLUDED == TRUE tBTA_DM_API_READ_RSSI rssi; + tBTA_DM_API_READ_CH_MAP ch_map; + tBTA_DM_API_SET_VISIBILITY set_visibility; tBTA_DM_API_ADD_DEVICE add_dev; @@ -2250,6 +2259,7 @@ extern void bta_dm_update_white_list(tBTA_DM_MSG *p_data); extern void bta_dm_clear_white_list(tBTA_DM_MSG *p_data); extern void bta_dm_ble_read_adv_tx_power(tBTA_DM_MSG *p_data); extern void bta_dm_read_rssi(tBTA_DM_MSG *p_data); +extern void bta_dm_read_ble_channel_map(tBTA_DM_MSG *p_data); #if (CLASSIC_BT_INCLUDED == TRUE) extern void bta_dm_set_visibility (tBTA_DM_MSG *p_data); #endif // #if (CLASSIC_BT_INCLUDED == TRUE) diff --git a/components/bt/host/bluedroid/bta/include/bta/bta_api.h b/components/bt/host/bluedroid/bta/include/bta/bta_api.h index 91f060035e..b66fb2295f 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_api.h @@ -451,6 +451,8 @@ typedef tBTM_TX_POWER_RESULTS tBTA_TX_POWER_RESULTS; typedef tBTM_RSSI_RESULTS tBTA_RSSI_RESULTS; +typedef tBTM_BLE_CH_MAP_RESULTS tBTA_BLE_CH_MAP_RESULTS; + typedef tBTM_SET_AFH_CHANNELS_RESULTS tBTA_SET_AFH_CHANNELS_RESULTS; typedef tBTM_BLE_SET_CHANNELS_RESULTS tBTA_BLE_SET_CHANNELS_RESULTS; @@ -2067,6 +2069,7 @@ extern void BTA_DmBleReadAdvTxPower(tBTA_CMPL_CB *cmpl_cb); #endif ///BLE_INCLUDED == TRUE extern void BTA_DmReadRSSI(BD_ADDR remote_addr, tBTA_TRANSPORT transport, tBTA_CMPL_CB *cmpl_cb); +extern void BTA_DmBleReadChannelMap(BD_ADDR remote_device, tBTA_CMPL_CB *p_callback); /******************************************************************************* ** diff --git a/components/bt/host/bluedroid/btc/core/btc_config.c b/components/bt/host/bluedroid/btc/core/btc_config.c index f46aef89b0..e2cce6da73 100644 --- a/components/bt/host/bluedroid/btc/core/btc_config.c +++ b/components/bt/host/bluedroid/btc/core/btc_config.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -29,6 +29,17 @@ static void btc_key_value_to_string(uint8_t *key_value, char *value_str, int key static osi_mutex_t lock; // protects operations on |config|. static config_t *config; + +int btc_config_file_path_get(char *file_path) +{ + if (file_path == NULL) { + return -1; + } + + strcpy(file_path, CONFIG_FILE_PATH); + return 0; +} + int btc_config_file_path_update(const char *file_path) { if (file_path != NULL && strlen(file_path) < NVS_NS_NAME_MAX_SIZE) { diff --git a/components/bt/host/bluedroid/btc/include/btc/btc_config.h b/components/bt/host/bluedroid/btc/include/btc/btc_config.h index 8467ced83c..6727c0caea 100644 --- a/components/bt/host/bluedroid/btc/include/btc/btc_config.h +++ b/components/bt/host/bluedroid/btc/include/btc/btc_config.h @@ -49,4 +49,6 @@ void btc_config_lock(void); void btc_config_unlock(void); int btc_config_file_path_update(const char *file_path); + +int btc_config_file_path_get(char *file_path); #endif diff --git a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c index 1a80df50b1..c28971c1df 100644 --- a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c +++ b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c @@ -935,6 +935,29 @@ static void btc_read_ble_rssi_cmpl_callback(void *p_data) } } +static void btc_ble_read_channel_map_callback(void *p_data) +{ + tBTA_BLE_CH_MAP_RESULTS *result = (tBTA_BLE_CH_MAP_RESULTS *)p_data; + esp_ble_gap_cb_param_t param; + bt_status_t ret; + btc_msg_t msg = {0}; + + msg.sig = BTC_SIG_API_CB; + msg.pid = BTC_PID_GAP_BLE; + msg.act = ESP_GAP_BLE_READ_CHANNEL_MAP_COMPLETE_EVT; + + param.read_ble_channel_map_cmpl.status = btc_btm_status_to_esp_status(result->status); + memcpy(param.read_ble_channel_map_cmpl.channel_map, result->channel_map, 5); + memcpy(param.read_ble_channel_map_cmpl.remote_addr, result->rem_bda, sizeof(BD_ADDR)); + + ret = btc_transfer_context(&msg, ¶m, sizeof(esp_ble_gap_cb_param_t), NULL, NULL); + + if (ret != BT_STATUS_SUCCESS) { + BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__); + } +} + + #if (BLE_50_FEATURE_SUPPORT == TRUE) static void btc_ble_5_gap_callback(tBTA_DM_BLE_5_GAP_EVENT event, tBTA_DM_BLE_5_GAP_CB_PARAMS *params) @@ -2184,6 +2207,9 @@ void btc_gap_ble_call_handler(btc_msg_t *msg) case BTC_GAP_BLE_ACT_READ_RSSI: BTA_DmReadRSSI(arg->read_rssi.remote_addr, BTA_TRANSPORT_LE, btc_read_ble_rssi_cmpl_callback); break; + case BTC_GAP_BLE_READ_CHANNEL_MAP: + BTA_DmBleReadChannelMap(arg->read_channel_map.bd_addr, btc_ble_read_channel_map_callback); + break; #if (BLE_42_FEATURE_SUPPORT == TRUE) case BTC_GAP_BLE_ACT_SET_CONN_PARAMS: BTA_DmSetBlePrefConnParams(arg->set_conn_params.bd_addr, arg->set_conn_params.min_conn_int, diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h index c672125181..43d44343ac 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h @@ -136,6 +136,7 @@ typedef enum { #if (BLE_50_FEATURE_SUPPORT == TRUE) BTC_GAP_ACT_SET_HOST_FEATURE, #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) + BTC_GAP_BLE_READ_CHANNEL_MAP, } btc_gap_ble_act_t; /* btc_ble_gap_args_t */ @@ -314,6 +315,9 @@ typedef union { struct set_vendor_evt_mask_args { uint32_t evt_mask; } set_vendor_evt_mask; + struct read_channel_map_args { + esp_bd_addr_t bd_addr; + } read_channel_map; } btc_ble_gap_args_t; #if (BLE_50_FEATURE_SUPPORT == TRUE) diff --git a/components/bt/host/bluedroid/device/controller.c b/components/bt/host/bluedroid/device/controller.c index 817838fe61..537e0e5030 100644 --- a/components/bt/host/bluedroid/device/controller.c +++ b/components/bt/host/bluedroid/device/controller.c @@ -101,6 +101,7 @@ static controller_local_param_t *controller_param_ptr; #define AWAIT_COMMAND(command) future_await(controller_param.hci->transmit_command_futured(command)) +static bool loaded = false; // Module lifecycle functions static void start_up(void) @@ -348,6 +349,17 @@ static void shut_down(void) controller_param.readable = false; } +#if (BT_BLE_DYNAMIC_ENV_MEMORY == TRUE) +void free_controller_param(void) +{ + if (controller_param_ptr) { + osi_free(controller_param_ptr); + controller_param_ptr = NULL; + loaded = false; + } +} +#endif + static bool get_is_ready(void) { return controller_param.readable; @@ -632,7 +644,6 @@ static const controller_t interface = { const controller_t *controller_get_interface(void) { - static bool loaded = false; if (!loaded) { loaded = true; #if (BT_BLE_DYNAMIC_ENV_MEMORY == TRUE) diff --git a/components/bt/host/bluedroid/main/bte_main.c b/components/bt/host/bluedroid/main/bte_main.c index c47bdc15f9..c974037ef9 100644 --- a/components/bt/host/bluedroid/main/bte_main.c +++ b/components/bt/host/bluedroid/main/bte_main.c @@ -64,6 +64,9 @@ static void bte_main_enable(void); bluedroid_init_done_cb_t bluedroid_init_done_cb; extern void osi_mem_dbg_init(void); +#if (BT_BLE_DYNAMIC_ENV_MEMORY == TRUE) +extern void free_controller_param(void); +#endif /****************************************************************************** ** ** Function bte_main_boot_entry @@ -85,7 +88,7 @@ int bte_main_boot_entry(bluedroid_init_done_cb_t cb) osi_init(); - //Enbale HCI + //Enable HCI bte_main_enable(); return 0; @@ -105,6 +108,11 @@ void bte_main_shutdown(void) #if (BLE_INCLUDED == TRUE) BTA_VendorCleanup(); #endif + +#if (BT_BLE_DYNAMIC_ENV_MEMORY == TRUE) + free_controller_param(); +#endif + bte_main_disable(); osi_deinit(); diff --git a/components/bt/host/bluedroid/stack/btm/btm_acl.c b/components/bt/host/bluedroid/stack/btm/btm_acl.c index 2e9f602692..9050678589 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_acl.c +++ b/components/bt/host/bluedroid/stack/btm/btm_acl.c @@ -2189,6 +2189,54 @@ void btm_acl_pkt_types_changed(UINT8 status, UINT16 handle, UINT16 pkt_types) } #if (BLE_INCLUDED == TRUE) + +/******************************************************************************* +** +** Function BTM_ReadChannelMap +** +** Description This function is called to read the current channel map +** for the given connection. The results are returned via +** the callback (tBTM_BLE_CH_MAP_RESULTS). +** +** Returns BTM_CMD_STARTED if successfully initiated or error code +** +*******************************************************************************/ +tBTM_STATUS BTM_ReadChannelMap(BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb) +{ + tACL_CONN *p; + tBTM_BLE_CH_MAP_RESULTS result; + + BTM_TRACE_DEBUG("BTM_ReadChannelMap: RemBdAddr: %02x%02x%02x%02x%02x%02x\n", + remote_bda[0], remote_bda[1], remote_bda[2], + remote_bda[3], remote_bda[4], remote_bda[5]); + + memset(result.channel_map, 0, sizeof(result.channel_map)); // Clear channel map data + /* If someone already waiting for the channel map, do not allow another */ + if (btm_cb.devcb.p_ble_ch_map_cmpl_cb) { + result.status = BTM_BUSY; + (*p_cb)(&result); + return BTM_BUSY; + } + p = btm_bda_to_acl(remote_bda, BT_TRANSPORT_LE); + if (p != NULL) { + btm_cb.devcb.p_ble_ch_map_cmpl_cb = p_cb; + + if (!btsnd_hcic_ble_read_chnl_map(p->hci_handle)) { + btm_cb.devcb.p_ble_ch_map_cmpl_cb = NULL; + result.status = BTM_NO_RESOURCES; + (*p_cb)(&result); + return BTM_NO_RESOURCES; + } else { + return BTM_CMD_STARTED; + } + } + + /* If here, no BD Addr found */ + result.status = BTM_UNKNOWN_ADDR; + (*p_cb)(&result); + return BTM_UNKNOWN_ADDR; +} + #if (BLE_HOST_READ_TX_POWER_EN == TRUE) tBTM_STATUS BTM_BleReadAdvTxPower(tBTM_CMPL_CB *p_cb) { @@ -2297,6 +2345,62 @@ void btm_read_tx_power_complete (UINT8 *p, BOOLEAN is_ble) } #endif // #if (BLE_HOST_READ_TX_POWER_EN == TRUE) +/******************************************************************************* +** +** Function btm_read_channel_map_complete +** +** Description This function is called when the command complete message +** is received from the HCI for the read channel map request. +** It processes the received channel map data and invokes the +** registered callback function with the results. +** +** Returns void +** +*******************************************************************************/ +void btm_read_channel_map_complete(UINT8 *p) +{ + tBTM_CMPL_CB *p_cb = btm_cb.devcb.p_ble_ch_map_cmpl_cb; + tBTM_BLE_CH_MAP_RESULTS results; + UINT16 handle; + tACL_CONN *p_acl_cb = NULL; + + BTM_TRACE_DEBUG("btm_read_channel_map_complete\n"); + + /* Reset the callback pointer to prevent duplicate calls */ + btm_cb.devcb.p_ble_ch_map_cmpl_cb = NULL; + + if (p_cb) { + /* Extract HCI status from the response */ + STREAM_TO_UINT8(results.hci_status, p); + + if (results.hci_status == HCI_SUCCESS) { + results.status = BTM_SUCCESS; + + /* Extract the connection handle and channel map */ + STREAM_TO_UINT16(handle, p); + STREAM_TO_ARRAY(results.channel_map, p, 5); + + BTM_TRACE_DEBUG("BTM Channel Map Complete: handle 0x%04x, hci status 0x%02x", handle, results.hci_status); + BTM_TRACE_DEBUG("Channel Map: %02x %02x %02x %02x %02x", + results.channel_map[0], results.channel_map[1], results.channel_map[2], + results.channel_map[3], results.channel_map[4]); + + /* Retrieve the remote BD address using the connection handle */ + p_acl_cb = btm_handle_to_acl(handle); + if (p_acl_cb) { + memcpy(results.rem_bda, p_acl_cb->remote_addr, BD_ADDR_LEN); + } + } else { + results.status = BTM_ERR_PROCESSING; + BTM_TRACE_ERROR("BTM Channel Map Read Failed: hci status 0x%02x", results.hci_status); + } + + /* Invoke the registered callback with the results */ + (*p_cb)(&results); + } +} + + /******************************************************************************* ** ** Function btm_read_rssi_complete diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble.c b/components/bt/host/bluedroid/stack/btm/btm_ble.c index b2bc1bd574..c24a111ee4 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble.c @@ -2294,17 +2294,16 @@ UINT8 btm_proc_smp_cback(tSMP_EVT event, BD_ADDR bd_addr, tSMP_EVT_DATA *p_data) } - } else { - if (event == SMP_SC_LOC_OOB_DATA_UP_EVT) { - tBTM_LE_EVT_DATA evt_data; - memcpy(&evt_data.local_oob_data, &p_data->loc_oob_data, sizeof(tSMP_LOC_OOB_DATA)); - if (btm_cb.api.p_le_callback) { - (*btm_cb.api.p_le_callback)(event, bd_addr, &evt_data); - } - } else { - BTM_TRACE_ERROR("btm_proc_smp_cback received for unknown device"); + } + + if (event == SMP_SC_LOC_OOB_DATA_UP_EVT) { + tBTM_LE_EVT_DATA evt_data; + memcpy(&evt_data.local_oob_data, &p_data->loc_oob_data, sizeof(tSMP_LOC_OOB_DATA)); + if (btm_cb.api.p_le_callback) { + (*btm_cb.api.p_le_callback)(event, bd_addr, &evt_data); } } + return 0; } #endif ///SMP_INCLUDED == TRUE diff --git a/components/bt/host/bluedroid/stack/btm/include/btm_int.h b/components/bt/host/bluedroid/stack/btm/include/btm_int.h index 81244e87bf..d5b69c6818 100644 --- a/components/bt/host/bluedroid/stack/btm/include/btm_int.h +++ b/components/bt/host/bluedroid/stack/btm/include/btm_int.h @@ -191,6 +191,10 @@ tBTM_CMPL_CB *p_rln_cmpl_cb; /* Callback function to be called when TIMER_LIST_ENT rssi_timer; tBTM_CMPL_CB *p_rssi_cmpl_cb; /* Callback function to be called when */ /* read rssi function completes */ + +tBTM_CMPL_CB *p_ble_ch_map_cmpl_cb; /* Callback function to be called when */ +/* read channel map function completes */ + TIMER_LIST_ENT lnk_quality_timer; tBTM_CMPL_CB *p_lnk_qual_cmpl_cb;/* Callback function to be called when */ /* read link quality function completes */ @@ -1068,6 +1072,7 @@ void btm_cont_rswitch (tACL_CONN *p, tACL_CONN *btm_handle_to_acl (UINT16 hci_handle); void btm_read_link_policy_complete (UINT8 *p); void btm_read_rssi_complete (UINT8 *p); +void btm_read_channel_map_complete (UINT8 *p); void btm_read_tx_power_complete (UINT8 *p, BOOLEAN is_ble); void btm_acl_pkt_types_changed(UINT8 status, UINT16 handle, UINT16 pkt_types); void btm_read_link_quality_complete (UINT8 *p); diff --git a/components/bt/host/bluedroid/stack/btu/btu_hcif.c b/components/bt/host/bluedroid/stack/btu/btu_hcif.c index 0a45729abb..eb2995b958 100644 --- a/components/bt/host/bluedroid/stack/btu/btu_hcif.c +++ b/components/bt/host/bluedroid/stack/btu/btu_hcif.c @@ -1153,7 +1153,9 @@ static void btu_hcif_hdl_command_complete (UINT16 opcode, UINT8 *p, UINT16 evt_l case HCI_READ_RSSI: btm_read_rssi_complete (p); break; - + case HCI_BLE_READ_CHNL_MAP: + btm_read_channel_map_complete (p); + break; case HCI_READ_TRANSMIT_POWER_LEVEL: #if (BLE_HOST_READ_TX_POWER_EN == TRUE) btm_read_tx_power_complete(p, FALSE); diff --git a/components/bt/host/bluedroid/stack/btu/btu_task.c b/components/bt/host/bluedroid/stack/btu/btu_task.c index df3a4aa3eb..bffa6837b0 100644 --- a/components/bt/host/bluedroid/stack/btu/btu_task.c +++ b/components/bt/host/bluedroid/stack/btu/btu_task.c @@ -453,7 +453,7 @@ void btu_start_timer(TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout_sec) // NOTE: This value is in seconds but stored in a ticks field. p_tle->ticks = timeout_sec; p_tle->in_use = TRUE; - osi_alarm_set(alarm, (period_ms_t)(timeout_sec * 1000)); + osi_alarm_set(alarm, (period_ms_t)((period_ms_t)timeout_sec * 1000)); } diff --git a/components/bt/host/bluedroid/stack/include/stack/btm_api.h b/components/bt/host/bluedroid/stack/include/stack/btm_api.h index c501fafd70..3415df5de3 100644 --- a/components/bt/host/bluedroid/stack/include/stack/btm_api.h +++ b/components/bt/host/bluedroid/stack/include/stack/btm_api.h @@ -811,6 +811,16 @@ typedef struct { BD_ADDR rem_bda; } tBTM_RSSI_RESULTS; +/* Structure returned with read channel map event (in tBTM_CMPL_CB callback function) +** in response to BTM_ReadChannelMap call. +*/ +typedef struct { + tBTM_STATUS status; /* BTM operation status */ + UINT8 hci_status; /* HCI command complete status */ + UINT8 channel_map[5]; /* Channel map (5 bytes) */ + BD_ADDR rem_bda; /* Remote device Bluetooth address */ +} tBTM_BLE_CH_MAP_RESULTS; + /* Structure returned with read current TX power event (in tBTM_CMPL_CB callback function) ** in response to BTM_ReadTxPower call. */ @@ -3024,6 +3034,18 @@ tBTM_STATUS BTM_SwitchRole (BD_ADDR remote_bd_addr, //extern tBTM_STATUS BTM_ReadRSSI (BD_ADDR remote_bda, tBT_TRANSPORT transport, tBTM_CMPL_CB *p_cb); +/******************************************************************************* +** +** Function BTM_ReadChannelMap +** +** Description This function is called to read the current channel map +** for the given connection. The results are returned via +** the callback (tBTM_BLE_CH_MAP_RESULTS). +** +** Returns BTM_CMD_STARTED if successfully initiated or error code +** +*******************************************************************************/ +tBTM_STATUS BTM_ReadChannelMap(BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb); #if (BLE_HOST_READ_TX_POWER_EN == TRUE) /******************************************************************************* ** diff --git a/examples/bluetooth/bluedroid/ble/ble_eddystone/main/esp_eddystone_demo.c b/examples/bluetooth/bluedroid/ble/ble_eddystone/main/esp_eddystone_demo.c index 33fa93c2f1..f4849f8b7b 100644 --- a/examples/bluetooth/bluedroid/ble/ble_eddystone/main/esp_eddystone_demo.c +++ b/examples/bluetooth/bluedroid/ble/ble_eddystone/main/esp_eddystone_demo.c @@ -84,6 +84,7 @@ static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t* par switch(event) { case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT: { + // the unit of the duration is second, 0 means scan permanently uint32_t duration = 0; esp_ble_gap_start_scanning(duration); break; diff --git a/examples/bluetooth/bluedroid/ble/ble_ibeacon/main/ibeacon_demo.c b/examples/bluetooth/bluedroid/ble/ble_ibeacon/main/ibeacon_demo.c index 7d55039171..846f7fea31 100644 --- a/examples/bluetooth/bluedroid/ble/ble_ibeacon/main/ibeacon_demo.c +++ b/examples/bluetooth/bluedroid/ble/ble_ibeacon/main/ibeacon_demo.c @@ -73,7 +73,7 @@ static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *par } case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT: { #if (IBEACON_MODE == IBEACON_RECEIVER) - //the unit of the duration is second, 0 means scan permanently + // the unit of the duration is second, 0 means scan permanently uint32_t duration = 0; esp_ble_gap_start_scanning(duration); #endif diff --git a/examples/bluetooth/bluedroid/ble/ble_spp_client/main/spp_client_demo.c b/examples/bluetooth/bluedroid/ble/ble_spp_client/main/spp_client_demo.c index 306a5834eb..72070dbab8 100644 --- a/examples/bluetooth/bluedroid/ble/ble_spp_client/main/spp_client_demo.c +++ b/examples/bluetooth/bluedroid/ble/ble_spp_client/main/spp_client_demo.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 */ @@ -216,9 +216,8 @@ static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *par ESP_LOGE(GATTC_TAG, "Scan param set failed: %s", esp_err_to_name(err)); break; } - //the unit of the duration is second - uint32_t duration = 0xFFFF; - ESP_LOGI(GATTC_TAG, "Enable Ble Scan:during time %04" PRIx32 " minutes.",duration); + // the unit of the duration is second, 0 means scan permanently + uint32_t duration = 0; esp_ble_gap_start_scanning(duration); break; } diff --git a/examples/bluetooth/bluedroid/ble/gatt_client/main/gattc_demo.c b/examples/bluetooth/bluedroid/ble/gatt_client/main/gattc_demo.c index 302f9bf66d..0e81f0040d 100644 --- a/examples/bluetooth/bluedroid/ble/gatt_client/main/gattc_demo.c +++ b/examples/bluetooth/bluedroid/ble/gatt_client/main/gattc_demo.c @@ -325,7 +325,9 @@ static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *par uint8_t adv_name_len = 0; switch (event) { case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT: { - //the unit of the duration is second + // The unit of duration is seconds. + // If duration is set to 0, scanning will continue indefinitely + // until esp_ble_gap_stop_scanning is explicitly called. uint32_t duration = 30; esp_ble_gap_start_scanning(duration); break; diff --git a/examples/bluetooth/bluedroid/ble/gatt_security_client/main/example_ble_sec_gattc_demo.c b/examples/bluetooth/bluedroid/ble/gatt_security_client/main/example_ble_sec_gattc_demo.c index 7f6fda129a..7955da0c71 100644 --- a/examples/bluetooth/bluedroid/ble/gatt_security_client/main/example_ble_sec_gattc_demo.c +++ b/examples/bluetooth/bluedroid/ble/gatt_security_client/main/example_ble_sec_gattc_demo.c @@ -385,7 +385,7 @@ static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *par } break; case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT: { - //the unit of the duration is second + // the unit of the duration is second, 0 means scan permanently uint32_t duration = 30; esp_ble_gap_start_scanning(duration); break; diff --git a/examples/bluetooth/bluedroid/ble/gattc_multi_connect/main/gattc_multi_connect.c b/examples/bluetooth/bluedroid/ble/gattc_multi_connect/main/gattc_multi_connect.c index f455aaadb7..0908e5e4ee 100644 --- a/examples/bluetooth/bluedroid/ble/gattc_multi_connect/main/gattc_multi_connect.c +++ b/examples/bluetooth/bluedroid/ble/gattc_multi_connect/main/gattc_multi_connect.c @@ -775,7 +775,7 @@ static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *par param->update_conn_params.timeout); break; case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT: { - //the unit of the duration is second + // the unit of the duration is second, 0 means scan permanently uint32_t duration = 30; esp_ble_gap_start_scanning(duration); break; diff --git a/examples/bluetooth/bluedroid/coex/gattc_gatts_coex/main/gattc_gatts_coex.c b/examples/bluetooth/bluedroid/coex/gattc_gatts_coex/main/gattc_gatts_coex.c index 28d63ff75b..6d9627337b 100644 --- a/examples/bluetooth/bluedroid/coex/gattc_gatts_coex/main/gattc_gatts_coex.c +++ b/examples/bluetooth/bluedroid/coex/gattc_gatts_coex/main/gattc_gatts_coex.c @@ -278,7 +278,7 @@ static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param break; case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT: { ESP_LOGI(COEX_TAG, "ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT, set scan sparameters complete"); - //the unit of the duration is second + // the unit of the duration is second, 0 means scan permanently uint32_t duration = 120; esp_ble_gap_start_scanning(duration); break;