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 1fea299dc9)

Co-authored-by: zhiweijian <zhiweijian@espressif.com>
This commit is contained in:
Zhi Wei Jian
2026-04-24 15:12:53 +08:00
committed by zhiweijian
parent 87da89a087
commit b1bf55bcbe
12 changed files with 159 additions and 60 deletions
@@ -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;
}
@@ -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__);
@@ -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");
}
}
@@ -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);
}
@@ -88,6 +88,10 @@ static void btc_gap_ble_get_dev_name_callback(UINT8 status, char *name)
ret = btc_transfer_context(&msg, &param, 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: {
@@ -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;
@@ -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,
@@ -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, &param);
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, &param);
break;
case BTA_GATTS_CONF_EVT:
@@ -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;
@@ -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
@@ -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 {
@@ -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: {