From b1bf55bcbef82be70917af322b45662ad9b2ebce Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Wed, 25 Mar 2026 10:27:44 +0800 Subject: [PATCH] fix(ble/bluedroid): fix parameter handling and deep copy in BTC layer - Fix CS and CTE callback deep copy errors in btc_gap_ble - Fix incorrect parameter check in btc_gattc_prepare_write_char_descr - Fix conn_handle length error and malloc failure handling - Fix memcpy error and reset params if malloc failed - Fix spelling: BROCASTER to BROADCASTER - Delete unused ISO functions in btc_iso_ble (cherry picked from commit 1fea299dc96570b004e7f36685708d72728c2577) Co-authored-by: zhiweijian --- .../host/bluedroid/btc/core/btc_ble_storage.c | 3 +- .../bt/host/bluedroid/btc/core/btc_config.c | 8 +++- .../bt/host/bluedroid/btc/core/btc_storage.c | 36 ++++++++++------ .../btc/profile/std/cte/btc_ble_cte.c | 36 ++++++++++++++-- .../btc/profile/std/gap/btc_gap_ble.c | 43 ++++++++++++++----- .../btc/profile/std/gatt/btc_gatt_util.c | 10 ++--- .../btc/profile/std/gatt/btc_gattc.c | 23 +++++++--- .../btc/profile/std/gatt/btc_gatts.c | 32 +++++++++++--- .../btc/profile/std/include/btc_ble_cte.h | 2 +- .../btc/profile/std/include/btc_gap_ble.h | 8 ++-- .../btc/profile/std/include/btc_iso_ble.h | 8 ++-- .../btc/profile/std/iso/btc_iso_ble.c | 10 +++-- 12 files changed, 159 insertions(+), 60 deletions(-) diff --git a/components/bt/host/bluedroid/btc/core/btc_ble_storage.c b/components/bt/host/bluedroid/btc/core/btc_ble_storage.c index aef3863111f..2c7c87ef7a5 100644 --- a/components/bt/host/bluedroid/btc/core/btc_ble_storage.c +++ b/components/bt/host/bluedroid/btc/core/btc_ble_storage.c @@ -1045,9 +1045,10 @@ bt_status_t btc_storage_set_gatt_cl_supp_feat(bt_bdaddr_t *remote_bd_addr, uint8 { int ret; bdstr_t bdstr; - + btc_config_lock(); bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr_t)); ret = btc_config_set_bin(bdstr, BTC_BLE_STORAGE_GATT_CL_SUPP_FEAT_STR, value, (size_t)len); + btc_config_unlock(); if (ret == false) { return BT_STATUS_FAIL; } diff --git a/components/bt/host/bluedroid/btc/core/btc_config.c b/components/bt/host/bluedroid/btc/core/btc_config.c index e2cce6da73f..966c33b5229 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-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -85,7 +85,11 @@ static void btc_key_value_to_string(uint8_t *key_value, char *value_str, int key bool btc_config_init(void) { - osi_mutex_new(&lock); + if (osi_mutex_new(&lock) != 0) { + BTC_TRACE_ERROR("%s unable to create lock.\n", __func__); + return false; + } + config = config_new(CONFIG_FILE_PATH); if (!config) { BTC_TRACE_WARNING("%s unable to load config file; starting unconfigured.\n", __func__); diff --git a/components/bt/host/bluedroid/btc/core/btc_storage.c b/components/bt/host/bluedroid/btc/core/btc_storage.c index bee44e18d38..9b197e3b060 100644 --- a/components/bt/host/bluedroid/btc/core/btc_storage.c +++ b/components/bt/host/bluedroid/btc/core/btc_storage.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -42,23 +42,33 @@ bt_status_t btc_storage_add_bonded_device(bt_bdaddr_t *remote_bd_addr, /* device not in bond list and exceed the maximum number of bonded devices, delete the inactive bonded device */ if (btc_storage_get_num_all_bond_devices() >= BTM_SEC_MAX_BONDS && !btc_config_has_section(bdstr)) { const btc_config_section_iter_t *iter = btc_config_section_begin(); - const btc_config_section_iter_t *remove_iter = iter; - /* find the first device(the last node) */ + const btc_config_section_iter_t *remove_iter = NULL; + /* find the last bdaddr-formatted device section */ while (iter != btc_config_section_end()) { - remove_iter = iter; + const char *name = btc_config_section_name(iter); + if (name && string_is_bdaddr(name)) { + remove_iter = iter; + } iter = btc_config_section_next(iter); } - const char *remove_section = btc_config_section_name(remove_iter); - // delete device info - string_to_bdaddr(remove_section, &bd_addr); - BTA_DmRemoveDevice(bd_addr.address, BT_TRANSPORT_BR_EDR); - BTA_DmRemoveDevice(bd_addr.address, BT_TRANSPORT_LE); + if (remove_iter != NULL) { + const char *remove_section = btc_config_section_name(remove_iter); + if (string_to_bdaddr(remove_section, &bd_addr)) { + // delete device info + BTA_DmRemoveDevice(bd_addr.address, BT_TRANSPORT_BR_EDR); + BTA_DmRemoveDevice(bd_addr.address, BT_TRANSPORT_LE); - // delete config info - if (btc_config_remove_section(remove_section)) { - BTC_TRACE_WARNING("exceeded the maximum number of bonded devices, delete the first device info : %02x:%02x:%02x:%02x:%02x:%02x", - bd_addr.address[0], bd_addr.address[1], bd_addr.address[2], bd_addr.address[3], bd_addr.address[4], bd_addr.address[5]); + // delete config info + if (btc_config_remove_section(remove_section)) { + BTC_TRACE_WARNING("exceeded the maximum number of bonded devices, delete the first device info : %02x:%02x:%02x:%02x:%02x:%02x", + bd_addr.address[0], bd_addr.address[1], bd_addr.address[2], bd_addr.address[3], bd_addr.address[4], bd_addr.address[5]); + } + } else { + BTC_TRACE_ERROR("Failed to convert section name to bdaddr: %s", remove_section); + } + } else { + BTC_TRACE_WARNING("No bdaddr-formatted section found to remove"); } } diff --git a/components/bt/host/bluedroid/btc/profile/std/cte/btc_ble_cte.c b/components/bt/host/bluedroid/btc/profile/std/cte/btc_ble_cte.c index b4534bba985..546c3c71fe2 100644 --- a/components/bt/host/bluedroid/btc/profile/std/cte/btc_ble_cte.c +++ b/components/bt/host/bluedroid/btc/profile/std/cte/btc_ble_cte.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -159,6 +159,8 @@ void btc_ble_cte_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) memcpy(dst->cte_trans_params.antenna_ids, src->cte_trans_params.antenna_ids, src->cte_trans_params.switching_pattern_len); } else { BTC_TRACE_ERROR("%s %d no mem\n",__func__, msg->act); + dst->cte_trans_params.switching_pattern_len = 0; + dst->cte_trans_params.antenna_ids = NULL; } } break; @@ -168,6 +170,8 @@ void btc_ble_cte_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) if (dst->cte_iq_sampling_en.antenna_ids) { memcpy(dst->cte_iq_sampling_en.antenna_ids, src->cte_iq_sampling_en.antenna_ids, src->cte_iq_sampling_en.switching_pattern_len); } else { + dst->cte_iq_sampling_en.switching_pattern_len = 0; + dst->cte_iq_sampling_en.antenna_ids = NULL; BTC_TRACE_ERROR("%s %d no mem\n",__func__, msg->act); } } @@ -181,6 +185,8 @@ void btc_ble_cte_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) if (dst->cte_recv_params.antenna_ids) { memcpy(dst->cte_recv_params.antenna_ids, src->cte_recv_params.antenna_ids, src->cte_recv_params.switching_pattern_len); } else { + dst->cte_recv_params.switching_pattern_len = 0; + dst->cte_recv_params.antenna_ids = NULL; BTC_TRACE_ERROR("%s %d no mem\n",__func__, msg->act); } } @@ -191,6 +197,8 @@ void btc_ble_cte_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) if (dst->cte_conn_trans_params.antenna_ids) { memcpy(dst->cte_conn_trans_params.antenna_ids, src->cte_conn_trans_params.antenna_ids, src->cte_conn_trans_params.switching_pattern_len); } else { + dst->cte_conn_trans_params.switching_pattern_len = 0; + dst->cte_conn_trans_params.antenna_ids = NULL; BTC_TRACE_ERROR("%s %d no mem\n",__func__, msg->act); } } @@ -258,7 +266,11 @@ void btc_ble_cte_cb_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) memcpy(dst->connless_iq_rpt.i_sample, &(src->connless_iq_rpt.i_sample[0]), src->connless_iq_rpt.sample_count); } else { + dst->connless_iq_rpt.sample_count = 0; + dst->connless_iq_rpt.i_sample = NULL; + dst->connless_iq_rpt.q_sample = NULL; BTC_TRACE_ERROR("%s, i_sample malloc failed\n", __func__); + break; } dst->connless_iq_rpt.q_sample = osi_malloc(src->connless_iq_rpt.sample_count); if (dst->connless_iq_rpt.q_sample) { @@ -266,7 +278,14 @@ void btc_ble_cte_cb_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) src->connless_iq_rpt.sample_count); } else { BTC_TRACE_ERROR("%s, q_sample malloc failed\n", __func__); + osi_free(dst->connless_iq_rpt.i_sample); + dst->connless_iq_rpt.sample_count = 0; + dst->connless_iq_rpt.i_sample = NULL; + dst->connless_iq_rpt.q_sample = NULL; } + } else { + dst->connless_iq_rpt.i_sample = NULL; + dst->connless_iq_rpt.q_sample = NULL; } break; #endif // #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) @@ -278,15 +297,26 @@ void btc_ble_cte_cb_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) memcpy(dst->conn_iq_rpt.i_sample, src->conn_iq_rpt.i_sample, src->conn_iq_rpt.sample_count); } else { + dst->conn_iq_rpt.i_sample = NULL; + dst->conn_iq_rpt.q_sample = NULL; + dst->conn_iq_rpt.sample_count = 0; BTC_TRACE_ERROR("%s, i_sample malloc failed\n", __func__); + break; } dst->conn_iq_rpt.q_sample = osi_malloc(src->conn_iq_rpt.sample_count); if (dst->conn_iq_rpt.q_sample) { memcpy(dst->conn_iq_rpt.q_sample, src->conn_iq_rpt.q_sample, src->conn_iq_rpt.sample_count); } else { + osi_free(dst->conn_iq_rpt.i_sample); + dst->conn_iq_rpt.i_sample = NULL; + dst->conn_iq_rpt.q_sample = NULL; + dst->conn_iq_rpt.sample_count = 0; BTC_TRACE_ERROR("%s, q_sample malloc failed\n", __func__); } + } else { + dst->conn_iq_rpt.i_sample = NULL; + dst->conn_iq_rpt.q_sample = NULL; } break; #endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) @@ -303,8 +333,8 @@ void btc_ble_cte_cb_deep_free(btc_msg_t *msg) #if (BLE_FEAT_CTE_CONNECTIONLESS_EN == TRUE) case ESP_BLE_CTE_CONNLESS_IQ_REPORT_EVT: { esp_ble_cte_cb_param_t *params = (esp_ble_cte_cb_param_t *)msg->arg; - uint8_t *i_sample = &(params->connless_iq_rpt.i_sample[0]); - uint8_t *q_sample = &(params->connless_iq_rpt.q_sample[0]); + uint8_t *i_sample = params->connless_iq_rpt.i_sample; + uint8_t *q_sample = params->connless_iq_rpt.q_sample; if (i_sample) { osi_free(i_sample); } 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 a606852bc67..de3c5e68f4b 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 @@ -88,6 +88,10 @@ static void btc_gap_ble_get_dev_name_callback(UINT8 status, char *name) ret = btc_transfer_context(&msg, ¶m, sizeof(esp_ble_gap_cb_param_t), NULL, NULL); if (ret != BT_STATUS_SUCCESS) { + if (param.get_dev_name_cmpl.name) { + osi_free(param.get_dev_name_cmpl.name); + } + BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__); } } @@ -213,6 +217,9 @@ static void btc_to_bta_adv_data(esp_ble_adv_data_t *p_adv_data, tBTA_BLE_ADV_DAT mask |= BTM_BLE_AD_BIT_MANU; bta_adv_data->p_manu->len = p_adv_data->manufacturer_len; memcpy(bta_adv_data->p_manu->p_val, p_adv_data->p_manufacturer_data, p_adv_data->manufacturer_len); + } else { + osi_free(bta_adv_data->p_manu); + bta_adv_data->p_manu = NULL; } } } @@ -246,6 +253,11 @@ static void btc_to_bta_adv_data(esp_ble_adv_data_t *p_adv_data, tBTA_BLE_ADV_DAT p_elem = p_prop->p_elem; if (NULL != p_elem) { memcpy(p_elem++, p_elem_service_data, sizeof(tBTA_BLE_PROP_ELEM)); + } else { + osi_free(p_elem_service_data->p_val); + osi_free(bta_adv_data->p_proprietary); + bta_adv_data->p_proprietary = NULL; + mask &= ~BTM_BLE_AD_BIT_PROPRIETARY; } } osi_free(p_elem_service_data); @@ -274,6 +286,10 @@ static void btc_to_bta_adv_data(esp_ble_adv_data_t *p_adv_data, tBTA_BLE_ADV_DAT mask |= BTM_BLE_AD_BIT_SERVICE; ++bta_adv_data->p_services->num_service; *p_uuid_out16++ = bt_uuid.uu.uuid16; + } else { + osi_free(bta_adv_data->p_services); + bta_adv_data->p_services = NULL; + BTC_TRACE_ERROR("%s - memory malloc failed", __FUNCTION__); } break; } @@ -2117,6 +2133,9 @@ void btc_gap_ble_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) } else { BTC_TRACE_ERROR("%s %d no mem\n",__func__, msg->act); } + } else { + dst->periodic_adv_cfg_data.data = NULL; + dst->periodic_adv_cfg_data.len = 0; } break; } @@ -2205,6 +2224,7 @@ void btc_gap_ble_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) case BTC_GAP_BLE_SET_PA_RSP_DATA: { btc_ble_5_gap_args_t *src = (btc_ble_5_gap_args_t *)p_src; btc_ble_5_gap_args_t *dst = (btc_ble_5_gap_args_t *)p_dest; + dst->per_adv_response_data_params.response_data = NULL; if (src->per_adv_response_data_params.response_data && src->per_adv_response_data_params.response_data_len) { dst->per_adv_response_data_params.response_data = osi_malloc(src->per_adv_response_data_params.response_data_len); if (dst->per_adv_response_data_params.response_data) { @@ -2218,6 +2238,7 @@ void btc_gap_ble_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) case BTC_GAP_BLE_SET_PA_SYNC_SUBEVT: { btc_ble_5_gap_args_t *src = (btc_ble_5_gap_args_t *)p_src; btc_ble_5_gap_args_t *dst = (btc_ble_5_gap_args_t *)p_dest; + dst->per_sync_subevent_params.subevent = NULL; if (src->per_sync_subevent_params.subevent && src->per_sync_subevent_params.num_subevents_to_sync) { dst->per_sync_subevent_params.subevent = osi_malloc(src->per_sync_subevent_params.num_subevents_to_sync); if (dst->per_sync_subevent_params.subevent) { @@ -2301,9 +2322,9 @@ void btc_gap_ble_cb_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) break; #endif // (BT_BLE_FEAT_PAWR_EN == TRUE) #if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) - case BTA_BLE_GAP_CS_SUBEVENT_RESULT_EVT: + case ESP_GAP_BLE_CS_SUBEVENT_RESULT_EVT: if (src->cs_subevt_result.step_info) { - dst->cs_subevt_result.step_info = osi_malloc(src->cs_subevt_result.num_steps_reported * sizeof(esp_ble_cs_step_info)); + dst->cs_subevt_result.step_info = osi_calloc(src->cs_subevt_result.num_steps_reported * sizeof(esp_ble_cs_step_info)); if (dst->cs_subevt_result.step_info) { for (UINT8 i = 0; i < src->cs_subevt_result.num_steps_reported; i++) { @@ -2324,9 +2345,9 @@ void btc_gap_ble_cb_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) } } break; - case BTA_BLE_GAP_CS_SUBEVENT_RESULT_CONTINUE_EVT: + case ESP_GAP_BLE_CS_SUBEVENT_RESULT_CONTINUE_EVT: if (src->cs_subevt_result_continue.step_info) { - dst->cs_subevt_result_continue.step_info = osi_malloc(src->cs_subevt_result_continue.num_steps_reported * sizeof(esp_ble_cs_step_info)); + dst->cs_subevt_result_continue.step_info = osi_calloc(src->cs_subevt_result_continue.num_steps_reported * sizeof(esp_ble_cs_step_info)); if (dst->cs_subevt_result_continue.step_info) { for (UINT8 i = 0; i < src->cs_subevt_result_continue.num_steps_reported; i++) { @@ -2336,7 +2357,7 @@ void btc_gap_ble_cb_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) if (src->cs_subevt_result_continue.step_info[i].step_data_len) { dst->cs_subevt_result_continue.step_info[i].data = osi_malloc(src->cs_subevt_result_continue.step_info[i].step_data_len); if (dst->cs_subevt_result_continue.step_info[i].data) { - memcpy(dst->cs_subevt_result_continue.step_info[i].data, src->cs_subevt_result_continue.step_info[i].data, src->cs_subevt_result.step_info[i].step_data_len); + memcpy(dst->cs_subevt_result_continue.step_info[i].data, src->cs_subevt_result_continue.step_info[i].data, src->cs_subevt_result_continue.step_info[i].step_data_len); } else { BTC_TRACE_ERROR("%s, data, no enough memory.", __func__); } @@ -2545,7 +2566,7 @@ void btc_gap_ble_cb_deep_free(btc_msg_t *msg) break; #endif // (BT_BLE_FEAT_PAWR_EN == TRUE) #if (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) - case BTA_BLE_GAP_CS_SUBEVENT_RESULT_EVT: + case ESP_GAP_BLE_CS_SUBEVENT_RESULT_EVT: { esp_ble_cs_step_info *step_info = ((esp_ble_gap_cb_param_t *)msg->arg)->cs_subevt_result.step_info; if (step_info) { @@ -2560,7 +2581,7 @@ void btc_gap_ble_cb_deep_free(btc_msg_t *msg) } } break; - case BTA_BLE_GAP_CS_SUBEVENT_RESULT_CONTINUE_EVT: + case ESP_GAP_BLE_CS_SUBEVENT_RESULT_CONTINUE_EVT: { esp_ble_cs_step_info *step_info = ((esp_ble_gap_cb_param_t *)msg->arg)->cs_subevt_result_continue.step_info; if (step_info) { @@ -2797,14 +2818,14 @@ void btc_gap_ble_call_handler(btc_msg_t *msg) } case BTC_GAP_BLE_PASSKEY_REPLY_EVT: { BD_ADDR bd_addr; - memcpy(bd_addr, arg->enc_passkey_replay.bd_addr, sizeof(BD_ADDR)); - BTA_DmBlePasskeyReply(bd_addr, arg->enc_passkey_replay.accept, arg->enc_passkey_replay.passkey); + memcpy(bd_addr, arg->enc_passkey_reply.bd_addr, sizeof(BD_ADDR)); + BTA_DmBlePasskeyReply(bd_addr, arg->enc_passkey_reply.accept, arg->enc_passkey_reply.passkey); break; } case BTC_GAP_BLE_CONFIRM_REPLY_EVT: { BD_ADDR bd_addr; - memcpy(bd_addr, arg->enc_comfirm_replay.bd_addr, sizeof(BD_ADDR)); - BTA_DmBleConfirmReply(bd_addr, arg->enc_comfirm_replay.accept); + memcpy(bd_addr, arg->enc_confirm_reply.bd_addr, sizeof(BD_ADDR)); + BTA_DmBleConfirmReply(bd_addr, arg->enc_confirm_reply.accept); break; } case BTC_GAP_BLE_REMOVE_BOND_DEV_EVT: { diff --git a/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gatt_util.c b/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gatt_util.c index 9d4d108bef6..4d0a7b272f7 100644 --- a/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gatt_util.c +++ b/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gatt_util.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -27,6 +27,10 @@ int uuidType(unsigned char *p_uuid) int all_zero = 1; for (i = 0; i != 16; ++i) { + /* Check if bytes 12-13 are non-zero for all_zero detection */ + if (p_uuid[i] != 0) { + all_zero = 0; + } if (i == 12 || i == 13) { continue; } @@ -34,10 +38,6 @@ int uuidType(unsigned char *p_uuid) if (p_uuid[i] == BASE_UUID[i]) { ++match; } - - if (p_uuid[i] != 0) { - all_zero = 0; - } } if (all_zero) { return 0; diff --git a/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gattc.c b/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gattc.c index 07e5fd1b82e..4882584baa4 100644 --- a/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gattc.c +++ b/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gattc.c @@ -40,6 +40,7 @@ void btc_gattc_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) memcpy(dst->write_char.value, src->write_char.value, src->write_char.value_len); } else { BTC_TRACE_ERROR("%s %d no mem\n", __func__, msg->act); + dst->write_char.value_len = 0; } break; } @@ -49,6 +50,7 @@ void btc_gattc_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) memcpy(dst->write_descr.value, src->write_descr.value, src->write_descr.value_len); } else { BTC_TRACE_ERROR("%s %d no mem\n", __func__, msg->act); + dst->write_descr.value_len = 0; } break; } @@ -58,6 +60,7 @@ void btc_gattc_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) memcpy(dst->prep_write.value, src->prep_write.value, src->prep_write.value_len); } else { BTC_TRACE_ERROR("%s %d no mem\n", __func__, msg->act); + dst->prep_write.value_len = 0; } break; } @@ -67,6 +70,7 @@ void btc_gattc_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) memcpy(dst->prep_write_descr.value, src->prep_write_descr.value, src->prep_write_descr.value_len); } else { BTC_TRACE_ERROR("%s %d no mem\n", __func__, msg->act); + dst->prep_write_descr.value_len = 0; } break; } @@ -337,6 +341,11 @@ esp_gatt_status_t btc_ble_gattc_get_service(uint16_t conn_id, esp_bt_uuid_t *svc tBT_UUID *bta_uuid = NULL; if (svc_uuid) { bta_uuid = osi_malloc(sizeof(tBT_UUID)); + if (bta_uuid == NULL) { + *count = 0; + return ESP_GATT_NO_RESOURCES; + } + btc_to_bta_uuid(bta_uuid, svc_uuid); } @@ -621,16 +630,16 @@ static void btc_gattc_read_char(btc_ble_gattc_args_t *arg) static void btc_gattc_read_multiple_char(btc_ble_gattc_args_t *arg) { tBTA_GATTC_MULTI bta_multi; - bta_multi.num_attr = arg->read_multiple.num_attr; - memcpy(bta_multi.handles, arg->read_multiple.handles, BTA_GATTC_MULTI_MAX); + bta_multi.num_attr = (arg->read_multiple.num_attr > BTA_GATTC_MULTI_MAX) ? BTA_GATTC_MULTI_MAX : arg->read_multiple.num_attr; + memcpy(bta_multi.handles, arg->read_multiple.handles, sizeof(uint16_t) * bta_multi.num_attr); BTA_GATTC_ReadMultiple(arg->read_multiple.conn_id, &bta_multi, arg->read_multiple.auth_req); } static void btc_gattc_read_multiple_variable_char(btc_ble_gattc_args_t *arg) { tBTA_GATTC_MULTI bta_multi; - bta_multi.num_attr = arg->read_multiple.num_attr; - memcpy(bta_multi.handles, arg->read_multiple.handles, BTA_GATTC_MULTI_MAX); + bta_multi.num_attr = (arg->read_multiple.num_attr > BTA_GATTC_MULTI_MAX) ? BTA_GATTC_MULTI_MAX : arg->read_multiple.num_attr; + memcpy(bta_multi.handles, arg->read_multiple.handles, sizeof(uint16_t) * bta_multi.num_attr); BTA_GATTC_ReadMultipleVariable(arg->read_multiple.conn_id, &bta_multi, arg->read_multiple.auth_req); } @@ -681,7 +690,11 @@ static void btc_gattc_prepare_write(btc_ble_gattc_args_t *arg) static void btc_gattc_prepare_write_char_descr(btc_ble_gattc_args_t *arg) { tBTA_GATT_UNFMT descr_val; - + /* + According to the Bluetooth Core Specification, a Prepare Write Request can have a zero-length value. + The underlying BTA layer function BTA_GATTC_PrepareWriteCharDescr is implemented to handle zero-length data correctly by skipping the memory copy + but still sending the message to the stack. + */ descr_val.len = arg->prep_write_descr.value_len; descr_val.p_value = arg->prep_write_descr.value; BTA_GATTC_PrepareWriteCharDescr(arg->prep_write_descr.conn_id, diff --git a/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gatts.c b/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gatts.c index e1b06cffbae..893e29e1739 100644 --- a/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gatts.c +++ b/components/bt/host/bluedroid/btc/profile/std/gatt/btc_gatts.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -74,9 +74,11 @@ void btc_gatts_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) memcpy(dst->send_ind.value, src->send_ind.value, src->send_ind.value_len); } else { BTC_TRACE_ERROR("%s %d no mem\n", __func__, msg->act); + dst->send_ind.value_len = 0; } } else { dst->send_ind.value = NULL; + dst->send_ind.value_len = 0; if (src->send_ind.value) { BTC_TRACE_ERROR("%s %d, invalid length", __func__, msg->act); } @@ -103,9 +105,11 @@ void btc_gatts_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) src->add_char.char_val.attr_len); } else { BTC_TRACE_ERROR("%s %d no mem\n", __func__, msg->act); + dst->add_char.char_val.attr_len = 0; } } else { dst->add_char.char_val.attr_value = NULL; + dst->add_char.char_val.attr_len = 0; if (src->add_char.char_val.attr_value) { BTC_TRACE_ERROR("%s %d, invalid length", __func__, msg->act); } @@ -120,9 +124,11 @@ void btc_gatts_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) src->add_descr.descr_val.attr_len); } else { BTC_TRACE_ERROR("%s %d no mem\n", __func__, msg->act); + dst->add_descr.descr_val.attr_len = 0; } } else { dst->add_descr.descr_val.attr_value = NULL; + dst->add_descr.descr_val.attr_len = 0; if (src->add_descr.descr_val.attr_value) { BTC_TRACE_ERROR("%s %d, invalid length", __func__, msg->act); } @@ -138,8 +144,11 @@ void btc_gatts_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) sizeof(esp_gatts_attr_db_t) * num_attr); } else { BTC_TRACE_ERROR("%s %d no mem\n",__func__, msg->act); + dst->create_attr_tab.max_nb_attr = 0; } } else { + dst->create_attr_tab.gatts_attr_db = NULL; + dst->create_attr_tab.max_nb_attr = 0; BTC_TRACE_ERROR("%s %d, NULL data", __func__, msg->act); } break; @@ -151,9 +160,11 @@ void btc_gatts_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) memcpy(dst->set_attr_val.value, src->set_attr_val.value, src->set_attr_val.length); } else { BTC_TRACE_ERROR("%s %d no mem\n",__func__, msg->act); + dst->set_attr_val.length = 0; } } else { dst->set_attr_val.value = NULL; + dst->set_attr_val.length = 0; if (src->set_attr_val.value) { BTC_TRACE_ERROR("%s %d, invalid length", __func__, msg->act); } else { @@ -462,8 +473,8 @@ static esp_gatt_status_t btc_gatts_check_valid_attr_tab(esp_gatts_attr_db_t *gat break; } case ESP_GATT_UUID_CHAR_DECLARE: - if((gatts_attr_db[i].att_desc.value) == NULL) { - BTC_TRACE_ERROR("%s, Characteristic declaration should not be NULL.", __func__); + if((gatts_attr_db[i].att_desc.value) == NULL || ((i + 1) >= max_nb_attr)) { + BTC_TRACE_ERROR("%s, att_desc.value is NULL or (%d + 1) >= %d", __func__, i, max_nb_attr); return ESP_GATT_INVALID_PDU; } @@ -788,6 +799,10 @@ void btc_gatts_cb_handler(btc_msg_t *msg) param.read.conn_id = BTC_GATT_GET_CONN_ID(p_data->req_data.conn_id); param.read.trans_id = p_data->req_data.trans_id; memcpy(param.read.bda, p_data->req_data.remote_bda, ESP_BD_ADDR_LEN); + if (p_data->req_data.p_data == NULL) { + BTC_TRACE_ERROR("%s READ_EVT p_data NULL", __func__); + break; + } param.read.handle = p_data->req_data.p_data->read_req.handle; param.read.offset = p_data->req_data.p_data->read_req.offset; param.read.is_long = p_data->req_data.p_data->read_req.is_long; @@ -816,23 +831,26 @@ void btc_gatts_cb_handler(btc_msg_t *msg) break; } case BTA_GATTS_EXEC_WRITE_EVT: { + if (p_data->req_data.p_data == NULL) { + break; + } gatts_if = BTC_GATT_GET_GATT_IF(p_data->req_data.conn_id); param.exec_write.conn_id = BTC_GATT_GET_CONN_ID(p_data->req_data.conn_id); param.exec_write.trans_id = p_data->req_data.trans_id; memcpy(param.exec_write.bda, p_data->req_data.remote_bda, ESP_BD_ADDR_LEN); - if (p_data->req_data.p_data == NULL) { - break; - } param.exec_write.exec_write_flag = p_data->req_data.p_data->exec_write; btc_gatts_cb_to_app(ESP_GATTS_EXEC_WRITE_EVT, gatts_if, ¶m); break; } case BTA_GATTS_MTU_EVT: + if (p_data->req_data.p_data == NULL) { + BTC_TRACE_ERROR("%s MTU_EVT p_data NULL", __func__); + break; + } gatts_if = BTC_GATT_GET_GATT_IF(p_data->req_data.conn_id); param.mtu.conn_id = BTC_GATT_GET_CONN_ID(p_data->req_data.conn_id); param.mtu.mtu = p_data->req_data.p_data->mtu; - btc_gatts_cb_to_app(ESP_GATTS_MTU_EVT, gatts_if, ¶m); break; case BTA_GATTS_CONF_EVT: diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_ble_cte.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_ble_cte.h index 659bfb31993..161955ac77e 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_ble_cte.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_ble_cte.h @@ -76,12 +76,12 @@ typedef union { uint8_t req_cte_len; uint8_t req_cte_Type; } cte_req_en; -#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) struct cte_rsp_en_arg { uint16_t conn_handle; uint8_t enable; } cte_rsp_en; +#endif // #if (BLE_FEAT_CTE_CONNECTION_EN == TRUE) } btc_ble_cte_args_t; 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 a429751293b..37bd4771b63 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 @@ -287,12 +287,12 @@ typedef union { esp_bd_addr_t bd_addr; bool accept; uint32_t passkey; - } enc_passkey_replay; + } enc_passkey_reply; //BTC_GAP_BLE_CONFIRM_REPLY_EVT struct enc_comfirm_reply_args { esp_bd_addr_t bd_addr; bool accept; - } enc_comfirm_replay; + } enc_confirm_reply; //BTC_GAP_BLE_OOB_DATA_REPLY_EVT struct oob_req_reply_args { esp_bd_addr_t bd_addr; @@ -513,12 +513,12 @@ typedef union { #if (BLE_FEAT_POWER_CONTROL_EN == TRUE) // BTC_GAP_BLE_ENH_READ_TRANS_POWER_LEVEL struct enh_read_trans_pwr_level_args { - uint8_t conn_handle; + uint16_t conn_handle; uint8_t phy; } enh_read_trans_pwr_level; // BTC_GAP_BLE_READ_REM_TRANS_POWER_LEVEL struct read_rem_trans_pwr_level_args { - uint8_t conn_handle; + uint16_t conn_handle; uint8_t phy; } read_rem_trans_pwr_level; // BTC_GAP_BLE_SET_PATH_LOSS_REPORT_PARAMS diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_iso_ble.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_iso_ble.h index 4e734b12026..6b51941c480 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_iso_ble.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_iso_ble.h @@ -41,11 +41,11 @@ struct btc_iso_cis_hdls { }__attribute__((packed)); typedef enum { -#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) +#if (BLE_FEAT_ISO_BIG_BROADCASTER_EN == TRUE) BTC_ISO_ACT_BIG_CREATE, BTC_ISO_ACT_BIG_CREATE_TEST, BTC_ISO_ACT_BIG_TERMINATE, -#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) +#endif // #if (BLE_FEAT_ISO_BIG_BROADCASTER_EN == TRUE) #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE) BTC_ISO_ACT_BIG_SYNC_CREATE, BTC_ISO_ACT_BIG_SYNC_TERMINATE, @@ -71,7 +71,7 @@ typedef enum { /* btc_ble_iso_args_t */ typedef union { -#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) +#if (BLE_FEAT_ISO_BIG_BROADCASTER_EN == TRUE) struct iso_big_create_args { uint8_t big_handle; uint8_t adv_handle; @@ -110,7 +110,7 @@ typedef union { uint8_t big_handle; uint8_t reason; } iso_big_terminate_params; -#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) +#endif // #if (BLE_FEAT_ISO_BIG_BROADCASTER_EN == TRUE) #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE) struct iso_big_sync_creat_arg { diff --git a/components/bt/host/bluedroid/btc/profile/std/iso/btc_iso_ble.c b/components/bt/host/bluedroid/btc/profile/std/iso/btc_iso_ble.c index 2f0381501b7..ec25805cffe 100644 --- a/components/bt/host/bluedroid/btc/profile/std/iso/btc_iso_ble.c +++ b/components/bt/host/bluedroid/btc/profile/std/iso/btc_iso_ble.c @@ -34,7 +34,7 @@ static void btc_ble_iso_callback(tBTM_BLE_ISO_EVENT event, msg.pid = BTC_PID_ISO_BLE; switch(event) { -#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) +#if (BLE_FEAT_ISO_BIG_BROADCASTER_EN == TRUE) case BTA_BLE_ISO_BIG_CREATE_COMPLETE_EVT: msg.act = ESP_BLE_ISO_BIG_CREATE_CMPL_EVT; param.create_big_cmpl.status = btc_btm_status_to_esp_status(params->btm_big_cmpl.status); @@ -60,7 +60,7 @@ static void btc_ble_iso_callback(tBTM_BLE_ISO_EVENT event, param.term_big_cmpl.big_handle = params->btm_big_term.big_handle; param.term_big_cmpl.reason = params->btm_big_term.reason; break; -#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) +#endif // #if (BLE_FEAT_ISO_BIG_BROADCASTER_EN == TRUE) #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE) case BTA_BLE_ISO_BIG_SYNC_ESTABLISHED_EVT: msg.act = ESP_BLE_ISO_BIG_SYNC_ESTABLISHED_EVT; @@ -244,6 +244,7 @@ void btc_iso_ble_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src) memcpy(dst->iso_set_data_path_params.codec_cfg, src->iso_set_data_path_params.codec_cfg, src->iso_set_data_path_params.codec_cfg_len); } else { BTC_TRACE_ERROR("%s %d no mem\n",__func__, msg->act); + dst->iso_set_data_path_params.codec_cfg_len = 0; } } break; @@ -300,7 +301,7 @@ void btc_iso_ble_call_handler(btc_msg_t *msg) BTC_TRACE_DEBUG("%s act %d", __func__, msg->act); switch (msg->act) { -#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) +#if (BLE_FEAT_ISO_BIG_BROADCASTER_EN == TRUE) case BTC_ISO_ACT_BIG_CREATE: BTA_DmBleGapIsoBigCreate((tBTA_DM_BLE_BIG_CREATE_PARAMS *)&arg->iso_big_creat_params); break; @@ -310,7 +311,7 @@ void btc_iso_ble_call_handler(btc_msg_t *msg) case BTC_ISO_ACT_BIG_TERMINATE: BTA_DmBleGapIsoBigTerminate((tBTA_DM_BLE_BIG_TERMINATE_PARAMS *)&arg->iso_big_terminate_params); break; -#endif // #if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) +#endif // #if (BLE_FEAT_ISO_BIG_BROADCASTER_EN == TRUE) #if (BLE_FEAT_ISO_BIG_SYNCER_EN == TRUE) case BTC_ISO_ACT_BIG_SYNC_CREATE: BTA_DmBleGapIsoBigSyncCreate((tBTA_DM_BLE_BIG_SYNC_CREATE_PARAMS *)&arg->iso_big_sync_creat_params); @@ -329,6 +330,7 @@ void btc_iso_ble_call_handler(btc_msg_t *msg) BTA_DmBleGapIsoReadTxSync(arg->iso_read_tx_sync_params.iso_handle); break; case BTC_ISO_ACT_READ_ISO_LINK_QUALITY: + BTA_DmBleGapIsoReadLinkQuality(arg->iso_read_link_quality_params.iso_handle); break; #if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE) case BTC_ISO_ACT_SET_CIG_PARAMS: {