From d0831229cdd5b7dc6bdb327fcedf0f276457ca76 Mon Sep 17 00:00:00 2001 From: Zhi Wei Jian Date: Wed, 25 Mar 2026 10:27:29 +0800 Subject: [PATCH] fix(ble/bluedroid): fix GAP, advertising and security issues in BTM layer - Fix adv state restore and reset if start/stop failed - Fix periodic adv v2 event without PAWR feature enabled - Fix periodic adv sync establish skip handling - Fix resolving list max_size validation - Fix RPA addr_type update after host-side resolution - Fix pairing_state reset if p_dev_rec alloc failed - Fix ISO cis_cnt limit and ext adv parameter check - Try to delete smp keys even if not in device list (cherry picked from commit e0ccc644a81eec6de417b80b8a0224c5fb285071) Co-authored-by: zhiweijian --- .../bt/host/bluedroid/stack/btm/btm_acl.c | 18 +++-- .../bt/host/bluedroid/stack/btm/btm_ble.c | 11 ++-- .../host/bluedroid/stack/btm/btm_ble_5_gap.c | 45 ++++++++----- .../host/bluedroid/stack/btm/btm_ble_addr.c | 6 +- .../bt/host/bluedroid/stack/btm/btm_ble_gap.c | 45 +++++++------ .../bt/host/bluedroid/stack/btm/btm_ble_iso.c | 46 +++++++------ .../bluedroid/stack/btm/btm_ble_privacy.c | 44 +++++++++++-- .../bt/host/bluedroid/stack/btm/btm_sec.c | 65 ++++++++++--------- .../bluedroid/stack/btm/include/btm_ble_int.h | 4 +- .../bluedroid/stack/btm/include/btm_int.h | 1 - .../bluedroid/stack/include/stack/btm_api.h | 10 --- .../stack/include/stack/btm_ble_api.h | 18 ++--- 12 files changed, 186 insertions(+), 127 deletions(-) diff --git a/components/bt/host/bluedroid/stack/btm/btm_acl.c b/components/bt/host/bluedroid/stack/btm/btm_acl.c index 9949c5585e..6187d3cb8f 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_acl.c +++ b/components/bt/host/bluedroid/stack/btm/btm_acl.c @@ -362,8 +362,12 @@ void btm_acl_created (BD_ADDR bda, DEV_CLASS dc, UINT8 bdn[BTM_MAX_REM_BD_NAME_L } else { p = (tACL_CONN *)osi_malloc(sizeof(tACL_CONN)); - if (p && list_append(btm_cb.p_acl_db_list, p)) { - memset(p, 0, sizeof(tACL_CONN)); + if (p && !list_append(btm_cb.p_acl_db_list, p)) { + osi_free(p); + return; + } + if (p) { + memset(p, 0, sizeof(tACL_CONN)); p->in_use = TRUE; p->hci_handle = hci_handle; p->link_role = link_role; @@ -2399,7 +2403,7 @@ void btm_read_channel_map_complete(UINT8 *p) void btm_read_rssi_complete (UINT8 *p, UINT16 evt_len) { tBTM_CMPL_CB *p_cb = btm_cb.devcb.p_rssi_cmpl_cb; - tBTM_RSSI_RESULTS results; + tBTM_RSSI_RESULTS results = {0}; UINT16 handle; tACL_CONN *p_acl_cb = NULL; BTM_TRACE_DEBUG ("btm_read_rssi_complete\n"); @@ -2431,10 +2435,12 @@ void btm_read_rssi_complete (UINT8 *p, UINT16 evt_len) results.rssi, results.hci_status); /* Search through the list of active channels for the correct BD Addr */ - p_acl_cb = btm_handle_to_acl(handle); - if (p_acl_cb) { + 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_UNKNOWN_ADDR; + } } else { results.status = BTM_ERR_PROCESSING; } diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble.c b/components/bt/host/bluedroid/stack/btm/btm_ble.c index 60601893da..7ea143e756 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble.c @@ -407,8 +407,9 @@ void BTM_BlePasskeyReply (BD_ADDR bd_addr, UINT8 res, UINT32 passkey) BTM_TRACE_ERROR("Passkey reply to Unknown device"); return; } - - p_dev_rec->sec_flags |= BTM_SEC_LE_AUTHENTICATED; + if (res_smp == SMP_SUCCESS) { + p_dev_rec->sec_flags |= BTM_SEC_LE_AUTHENTICATED; + } BTM_TRACE_DEBUG ("BTM_BlePasskeyReply"); SMP_PasskeyReply(bd_addr, res_smp, passkey); #endif @@ -487,8 +488,9 @@ void BTM_BleOobDataReply(BD_ADDR bd_addr, UINT8 res, UINT8 len, UINT8 *p_data) BTM_TRACE_ERROR("BTM_BleOobDataReply() to Unknown device"); return; } - - p_dev_rec->sec_flags |= BTM_SEC_LE_AUTHENTICATED; + if (res_smp == SMP_SUCCESS) { + p_dev_rec->sec_flags |= BTM_SEC_LE_AUTHENTICATED; + } SMP_OobDataReply(bd_addr, res_smp, len, p_data); #endif } @@ -1431,6 +1433,7 @@ void btm_ble_link_sec_check(BD_ADDR bd_addr, tBTM_LE_AUTH_REQ auth_req, tBTM_BLE if (p_dev_rec == NULL) { BTM_TRACE_ERROR ("btm_ble_link_sec_check received for unknown device"); + *p_sec_req_act = BTM_BLE_SEC_REQ_ACT_NONE; return; } diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c index 46f0eadbeb..3ecfe99c69 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c @@ -16,7 +16,9 @@ tBTM_BLE_EXTENDED_CB extend_adv_cb; tBTM_BLE_5_HCI_CBACK ble_5_hci_cb; -#define INVALID_VALUE 0XFF +#define INVALID_VALUE_8BIT 0XFF +#define INVALID_VALUE_16BIT 0XFFFF +#define INVALID_VALUE_32BIT 0XFFFFFFFF extern BOOLEAN BTM_GetLocalResolvablePrivateAddr(BD_ADDR bda); extern void BTM_UpdateAddrInfor(uint8_t addr_type, BD_ADDR bda); @@ -529,13 +531,21 @@ tBTM_STATUS BTM_BleStartExtAdv(BOOLEAN enable, UINT8 num, tBTM_BLE_EXT_ADV *ext_ UINT8 *max_events = NULL; // when enable = true, ext_adv = NULL or num = 0, goto end - if ((!ext_adv || num == 0) && enable) { + if (num > MAX_BLE_ADV_INSTANCE || (num > 0 && !ext_adv) || (enable && num == 0)) { status = BTM_ILLEGAL_VALUE; BTM_TRACE_ERROR("%s invalid parameters", __func__); goto end; } if (num != 0 && ext_adv != NULL) { + for (int i = 0; i < num; i++) { + if (ext_adv[i].instance >= MAX_BLE_ADV_INSTANCE) { + status = BTM_ILLEGAL_VALUE; + BTM_TRACE_ERROR("%s instance ID %d out of range", __func__, ext_adv[i].instance); + goto end; + } + } + instance = osi_malloc(num); duration = osi_malloc(num*sizeof(UINT16)); max_events = osi_malloc(num*sizeof(UINT8)); @@ -583,9 +593,9 @@ end: { adv_record[i].invalid = false; adv_record[i].enabled = false; - adv_record[i].instance = INVALID_VALUE; - adv_record[i].duration = INVALID_VALUE; - adv_record[i].max_events = INVALID_VALUE; + adv_record[i].instance = INVALID_VALUE_8BIT; + adv_record[i].duration = INVALID_VALUE_32BIT; + adv_record[i].max_events = INVALID_VALUE_32BIT; adv_record[i].retry_count = 0; } } else { @@ -594,9 +604,9 @@ end: uint8_t index = ext_adv[i].instance; adv_record[index].invalid = false; adv_record[index].enabled = false; - adv_record[index].instance = INVALID_VALUE; - adv_record[index].duration = INVALID_VALUE; - adv_record[index].max_events = INVALID_VALUE; + adv_record[index].instance = INVALID_VALUE_8BIT; + adv_record[index].duration = INVALID_VALUE_32BIT; + adv_record[index].max_events = INVALID_VALUE_32BIT; adv_record[index].retry_count = 0; } } @@ -616,9 +626,12 @@ end: } cb_params.adv_start.status = status; + num = (num > MAX_BLE_ADV_INSTANCE) ? MAX_BLE_ADV_INSTANCE : num; cb_params.adv_start.instance_num = num; - for (uint8_t i = 0; i < num; i++) { - cb_params.adv_start.instance[i] = ext_adv[i].instance; + if (ext_adv) { + for (uint8_t i = 0; i < num; i++) { + cb_params.adv_start.instance[i] = ext_adv[i].instance; + } } BTM_ExtBleCallbackTrigger(enable ? BTM_BLE_5_GAP_EXT_ADV_START_COMPLETE_EVT : BTM_BLE_5_GAP_EXT_ADV_STOP_COMPLETE_EVT, &cb_params); @@ -626,10 +639,10 @@ end: return status; } -tBTM_STATUS BTM_BleStartExtAdvRestart(uint8_t con_handle) +tBTM_STATUS BTM_BleStartExtAdvRestart(uint16_t con_handle) { tBTM_BLE_EXT_ADV ext_adv; - uint8_t index = INVALID_VALUE; + uint8_t index = INVALID_VALUE_8BIT; for (uint8_t i = 0; i < MAX_BLE_ADV_INSTANCE; i++) { if(adv_record[i].ter_con_handle == con_handle) { @@ -798,7 +811,7 @@ tBTM_STATUS BTM_BlePeriodicAdvCfgDataRaw(UINT8 instance, UINT16 len, UINT8 *data } } - if ((err = btsnd_hcic_ble_set_periodic_adv_data(instance, operation, send_data_len, &data[data_offset])) != HCI_SUCCESS) { + if ((err = btsnd_hcic_ble_set_periodic_adv_data(instance, operation, send_data_len, (data == NULL)? NULL : &data[data_offset])) != HCI_SUCCESS) { BTM_TRACE_ERROR("LE PA SetData: cmd err=0x%x", err); status = BTM_HCI_ERROR | err; break; @@ -900,7 +913,7 @@ tBTM_STATUS BTM_BlePeriodicAdvCreateSync(tBTM_BLE_Periodic_Sync_Params *params) sync_retry_cb.in_use = true; #endif // #if (BLE_FEAT_CREATE_SYNC_RETRY_MAX > 0) if (!btsnd_hcic_ble_periodic_adv_create_sync(option, params->sid, params->addr_type, - params->addr, params->sync_timeout, params->sync_cte_type)) { + params->addr, params->skip, params->sync_timeout, params->sync_cte_type)) { BTM_TRACE_ERROR("LE PA CreateSync cmd failed"); status = BTM_ILLEGAL_VALUE; #if (BLE_FEAT_CREATE_SYNC_RETRY_MAX > 0) @@ -1310,7 +1323,7 @@ void btm_ble_adv_set_terminated_evt(tBTM_BLE_ADV_TERMINAT *params) if(params->status == 0x00) { adv_record[params->adv_handle].ter_con_handle = params->conn_handle; } else { - adv_record[params->adv_handle].ter_con_handle = INVALID_VALUE; + adv_record[params->adv_handle].ter_con_handle = INVALID_VALUE_16BIT; adv_record[params->adv_handle].invalid = false; } adv_record[params->adv_handle].enabled = false; @@ -1454,6 +1467,7 @@ void btm_ble_periodic_adv_sync_establish_evt(tBTM_BLE_PERIOD_ADV_SYNC_ESTAB *par sync_retry_cb.params.sid, sync_retry_cb.params.addr_type, sync_retry_cb.params.addr, + sync_retry_cb.params.skip, sync_retry_cb.params.sync_timeout, sync_retry_cb.params.sync_cte_type)) { /* Retry command sent successfully, wait for next event */ @@ -1991,6 +2005,7 @@ void btm_ble_cs_security_enable_cmd_status(UINT8 status) tBTM_BLE_CS_SEC_ENABLE_CMPL_EVT cs_security_enable = {0}; if (status != HCI_SUCCESS) { cs_security_enable.status = (status | BTM_HCI_ERROR); + cs_security_enable.conn_handle = 0xFFFF; // Invalid handle BTM_ExtBleCallbackTrigger(BTM_BLE_GAP_CS_SECURITY_ENABLE_CMPL_EVT, (tBTM_BLE_5_GAP_CB_PARAMS *)&cs_security_enable); } } diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_addr.c b/components/bt/host/bluedroid/stack/btm/btm_ble_addr.c index 60548a76ba..291b1effc3 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_addr.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_addr.c @@ -221,7 +221,7 @@ static void btm_ble_resolve_address_cmpl(void) { tBTM_LE_RANDOM_CB *p_mgnt_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb; - BTM_TRACE_EVENT ("btm_ble_resolve_address_cmpl p_mgnt_cb->p_dev_rec = 0x%08x", (uint32_t)p_mgnt_cb->p_dev_rec); + BTM_TRACE_EVENT ("btm_ble_resolve_address_cmpl p_mgnt_cb->p_dev_rec = 0x%08x", p_mgnt_cb->p_dev_rec ? (uint32_t)p_mgnt_cb->p_dev_rec : 0); p_mgnt_cb->busy = FALSE; @@ -405,7 +405,9 @@ void btm_ble_resolve_random_addr(BD_ADDR random_bda, tBTM_BLE_RESOLVE_CBACK *p_c p_dev_rec = list_node(p_node); p_mgnt_cb->p_dev_rec = p_dev_rec; if (btm_ble_match_random_bda(p_dev_rec)) { - break; + // if matched, btm_ble_match_random_bda->btm_ble_proc_resolve_x->btm_ble_resolve_address_cmpl + p_mgnt_cb->p_dev_rec = NULL; + return; } p_mgnt_cb->p_dev_rec = NULL; } diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c index 831dbf7c0a..90461db35c 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c @@ -917,7 +917,7 @@ static void btm_ble_resolve_random_addr_on_adv(void *p_rec, void *p) tBTM_SEC_DEV_REC *match_rec = (tBTM_SEC_DEV_REC *) p_rec; UINT8 addr_type = BLE_ADDR_RANDOM; BD_ADDR bda; - UINT8 *pp = (UINT8 *)p + 1; + UINT8 *pp = (UINT8 *)p; UINT8 evt_type; BTM_TRACE_EVENT ("btm_ble_resolve_random_addr_on_adv "); @@ -937,6 +937,7 @@ static void btm_ble_resolve_random_addr_on_adv(void *p_rec, void *p) // Assign the original address to be the current report address memcpy(bda, match_rec->ble.pseudo_addr, BD_ADDR_LEN); } + addr_type = match_rec->ble.ble_addr_type; } btm_ble_process_adv_pkt_cont(bda, addr_type, evt_type, pp); @@ -1112,7 +1113,6 @@ static UINT8 btm_set_conn_mode_adv_init_addr(tBTM_BLE_INQ_CB *p_cb, { UINT8 evt_type; #if BLE_PRIVACY_SPT == TRUE - UINT8 i = BTM_SEC_MAX_DEVICE_RECORDS; tBTM_SEC_DEV_REC *p_dev_rec; list_node_t *p_node = NULL; #endif ///BLE_PRIVACY_SPT == TRUE @@ -1165,14 +1165,12 @@ static UINT8 btm_set_conn_mode_adv_init_addr(tBTM_BLE_INQ_CB *p_cb, memcpy(p_peer_addr_ptr, p_dev_rec->ble.static_addr, BD_ADDR_LEN); *p_peer_addr_type = p_dev_rec->ble.static_addr_type; break; - } - } + } + } - if (i != BTM_SEC_MAX_DEVICE_RECORDS) { + if (p_node) { *p_own_addr_type = BLE_ADDR_RANDOM_ID; - } else - /* resolving list is empty, not enabled */ - { + } else { *p_own_addr_type = BLE_ADDR_RANDOM; } } @@ -3125,6 +3123,10 @@ void btm_ble_process_adv_pkt (UINT8 *p_data) STREAM_TO_UINT8(num_reports, p); while (num_reports--) { +#if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE) + /* Save current report start position for address resolution callback */ + UINT8 *pp = p; +#endif /* Extract inquiry results */ STREAM_TO_UINT8 (evt_type, p); STREAM_TO_UINT8 (addr_type, p); @@ -3145,7 +3147,7 @@ void btm_ble_process_adv_pkt (UINT8 *p_data) // bda[0],bda[1],bda[2],bda[3],bda[4],bda[5]); /* always do RRA resolution on host */ if (!match && BTM_BLE_IS_RESOLVE_BDA(bda)) { - btm_ble_resolve_random_addr(bda, btm_ble_resolve_random_addr_on_adv, p_data); + btm_ble_resolve_random_addr(bda, btm_ble_resolve_random_addr_on_adv, pp); } else #endif btm_ble_process_adv_pkt_cont(bda, addr_type, evt_type, p); @@ -3539,6 +3541,7 @@ tBTM_STATUS btm_ble_start_adv(void) //btm_ble_enable_resolving_list_for_platform(BTM_BLE_RL_ADV); } #endif + UINT8 wl_state = btm_cb.ble_ctr_cb.wl_state; if (p_cb->afp != AP_SCAN_CONN_ALL) { //find the device in the btm dev buffer and write it to the controller white list btm_execute_wl_dev_operation(); @@ -3558,17 +3561,19 @@ tBTM_STATUS btm_ble_start_adv(void) rt = adv_enable_status; BTM_TRACE_EVENT ("BTM_SUCCESS\n"); } else { - p_cb->adv_mode = BTM_BLE_ADV_DISABLE; + rt = BTM_NO_RESOURCES; + // reinit adv_enable_status + // There is no suitable value, temporarily changed to 0xff + adv_enable_status = 0xff; + } + + if(adv_enable_status != HCI_SUCCESS) { p_cb->state = temp_state; p_cb->adv_mode = adv_mode; #if (BLE_TOPOLOGY_CHECK == TRUE) btm_ble_adv_states_operation(btm_ble_clear_topology_mask, p_cb->evt_type); #endif // (BLE_TOPOLOGY_CHECK == TRUE) - btm_cb.ble_ctr_cb.wl_state &= ~BTM_BLE_WL_ADV; - } - - if(adv_enable_status != HCI_SUCCESS) { - p_cb->adv_mode = adv_mode; + btm_cb.ble_ctr_cb.wl_state = wl_state; } osi_mutex_unlock(&adv_enable_lock); return rt; @@ -3609,6 +3614,12 @@ tBTM_STATUS btm_ble_stop_adv(void) osi_sem_take(&adv_enable_sem, OSI_SEM_MAX_TIMEOUT); rt = adv_enable_status; } else { + rt = BTM_NO_RESOURCES; + // reinit adv_enable_status + // There is no suitable value, temporarily changed to 0xff + adv_enable_status = 0xff; + } + if(adv_enable_status != HCI_SUCCESS) { // reset state p_cb->fast_adv_on = temp_fast_adv_on; p_cb->adv_mode = temp_adv_mode; @@ -3617,10 +3628,6 @@ tBTM_STATUS btm_ble_stop_adv(void) #if (BLE_TOPOLOGY_CHECK == TRUE) btm_ble_set_topology_mask (temp_mask); #endif // (BLE_TOPOLOGY_CHECK == TRUE) - rt = BTM_NO_RESOURCES; - } - if(adv_enable_status != HCI_SUCCESS) { - p_cb->adv_mode = temp_adv_mode; } osi_mutex_unlock(&adv_enable_lock); } diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_iso.c b/components/bt/host/bluedroid/stack/btm/btm_ble_iso.c index f0aa7ca56c..49483702a8 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_iso.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_iso.c @@ -162,7 +162,7 @@ void btm_ble_cis_request_evt(tBTM_BLE_CIS_REQUEST_CMPL *params) } #endif // #if (BLE_FEAT_ISO_CIG_PERIPHERAL_EN == TRUE) -#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) +#if (BLE_FEAT_ISO_BIG_BROADCASTER_EN == TRUE) void btm_ble_big_create_cmpl_evt(tBTM_BLE_BIG_CREATE_CMPL *params) { BTM_TRACE_DEBUG("%s", __func__); @@ -217,7 +217,7 @@ void btm_ble_big_terminate_cmpl_evt(tBTM_BLE_BIG_TERMINATE_CMPL *params) BTM_IsoBleCallbackTrigger(BTM_BLE_ISO_BIG_TERMINATE_COMPLETE_EVT, &cb_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) void btm_ble_big_sync_estab_evt(tBTM_BLE_BIG_SYNC_ESTAB_CMPL *params) @@ -315,7 +315,7 @@ void btm_ble_iso_data_path_update_complete(UINT16 opcode, UINT8 hci_status, UINT BTM_IsoBleCallbackTrigger(BTM_BLE_ISO_DATA_PATH_UPFATE_EVT, &cb_params); } -#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) +#if (BLE_FEAT_ISO_BIG_BROADCASTER_EN == TRUE) tBTM_STATUS BTM_BleBigCreate(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis, uint32_t sdu_interval, uint16_t max_sdu, uint16_t max_transport_latency, uint8_t rtn, uint8_t phy, uint8_t packing, uint8_t framing, @@ -356,23 +356,11 @@ tBTM_STATUS BTM_BleBigCreateTest(uint8_t big_handle, uint8_t adv_handle, uint8_t tBTM_STATUS BTM_BleBigTerminate(UINT8 big_handle, UINT8 reason) { - tHCI_STATUS err = HCI_SUCCESS; - tBTM_STATUS status = BTM_SUCCESS; - tBTM_BLE_ISO_CB_PARAMS cb_params = {0}; - - if ((err = btsnd_hcic_ble_big_terminate(big_handle, reason)) != TRUE) { - BTM_TRACE_ERROR("LE PA SyncCancel, cmd err=0x%x", err); - status = BTM_HCI_ERROR | err; - } - - if (status != BTM_SUCCESS) { - cb_params.status = status; - BTM_IsoBleCallbackTrigger(BTM_BLE_ISO_BIG_TERMINATE_COMPLETE_EVT, &cb_params); - } - - return status; + // event will be triggered in command status and complete event + btsnd_hcic_ble_big_terminate(big_handle, reason); + return BTM_SUCCESS; } -#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) tBTM_STATUS BTM_BleBigSyncCreate(uint8_t big_handle, uint16_t sync_handle, @@ -488,6 +476,11 @@ tBTM_STATUS BTM_BleSetCigParams(uint8_t cig_id, uint32_t sdu_int_c_to_p, uint32_ BTM_TRACE_ERROR("%s, cis_cnt %d exceeds BLE_ISO_CIS_MAX_COUNT %d", __func__, cis_cnt, BLE_ISO_CIS_MAX_COUNT); return BTM_ILLEGAL_VALUE; } + // HCI_LE_Set_CIG_Parameters param length = 15 + 9*cis_cnt (UINT8). Max 255 => cis_cnt <= 26. + if (cis_cnt > 26) { + BTM_TRACE_ERROR("%s, cis_cnt %d exceeds HCI transport limit", __func__, cis_cnt); + return BTM_ILLEGAL_VALUE; + } if ((err = btsnd_hcic_ble_iso_set_cig_params(cig_id, sdu_int_c_to_p, sdu_int_p_to_c, worse_case_SCA, packing, framing, mtl_c_to_p, mtl_p_to_c, cis_cnt, (struct ble_hci_le_cis_params *)cis_params)) != HCI_SUCCESS) { @@ -508,6 +501,11 @@ tBTM_STATUS BTM_BleSetCigParamsTest(uint8_t cig_id, uint32_t sdu_int_c_to_p, uin BTM_TRACE_ERROR("%s, cis_cnt %d exceeds BLE_ISO_CIS_MAX_COUNT %d", __func__, cis_cnt, BLE_ISO_CIS_MAX_COUNT); return BTM_ILLEGAL_VALUE; } + // HCI_LE_Set_CIG_Parameters_Test param length = 15 + 14*cis_cnt (UINT8). Max 255 => cis_cnt <= 17. + if (cis_cnt > 17) { + BTM_TRACE_ERROR("%s, cis_cnt %d exceeds HCI transport limit", __func__, cis_cnt); + return BTM_ILLEGAL_VALUE; + } if ((err = btsnd_hcic_ble_iso_set_cig_params_test(cig_id, sdu_int_c_to_p, sdu_int_p_to_c,ft_c_to_p, ft_p_to_c, iso_interval, worse_case_SCA, packing, framing, cis_cnt, (struct ble_hci_le_cis_params_test *)cis_params)) != HCI_SUCCESS) { @@ -562,8 +560,14 @@ void btm_ble_accept_cis_req_cmd_status(tBTM_BLE_ISO_CB_PARAMS *cb_params) tBTM_STATUS BTM_BleAcceptCisReq(uint16_t cis_handle) { - btsnd_hcic_ble_iso_accept_cis_req(cis_handle); - return BTM_SUCCESS; + if (btsnd_hcic_ble_iso_accept_cis_req(cis_handle)) { + return BTM_SUCCESS; + } + // failed to send command + tBTM_BLE_ISO_CB_PARAMS cb_params = {0}; + cb_params.status = BTM_NO_RESOURCES; + btm_ble_accept_cis_req_cmd_status(&cb_params); + return BTM_NO_RESOURCES; } tBTM_STATUS BTM_BleRejectCisReq(uint16_t cis_handle, uint8_t reason) diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_privacy.c b/components/bt/host/bluedroid/stack/btm/btm_ble_privacy.c index 633d15e253..09a0835f6a 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_privacy.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_privacy.c @@ -71,7 +71,14 @@ static bool is_deleting_zero_addr; void btm_ble_enq_resolving_list_pending(BD_ADDR pseudo_bda, UINT8 op_code) { tBTM_BLE_RESOLVE_Q *p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q; - + UINT8 max_size = controller_get_interface()->get_ble_resolving_list_max_size(); + if (max_size <= 1) { + return; + } + if (((p_q->q_next + 1) % max_size) == p_q->q_pending) { + BTM_TRACE_ERROR("%s, resolving pending queue full\n", __func__); + return; + } memcpy(p_q->resolve_q_random_pseudo[p_q->q_next], pseudo_bda, BD_ADDR_LEN); p_q->resolve_q_action[p_q->q_next] = op_code; p_q->q_next ++; @@ -244,10 +251,11 @@ void btm_ble_clear_resolving_list_complete(UINT8 *p, UINT16 evt_len) if (controller_get_interface()->get_ble_resolving_list_max_size() == 0) { btm_ble_resolving_list_init(irk_list_sz_max); } - - uint8_t irk_mask_size = (irk_list_sz_max % 8) ? + if (btm_cb.ble_ctr_cb.irk_list_mask != NULL) { + uint8_t irk_mask_size = (irk_list_sz_max % 8) ? (irk_list_sz_max / 8 + 1) : (irk_list_sz_max / 8); - memset(btm_cb.ble_ctr_cb.irk_list_mask, 0, irk_mask_size); + memset(btm_cb.ble_ctr_cb.irk_list_mask, 0, irk_mask_size); + } } btm_cb.ble_ctr_cb.resolving_list_avail_size = @@ -709,8 +717,9 @@ BOOLEAN btm_ble_suspend_resolving_list_activity(void) #if (BLE_42_ADV_EN == TRUE) if (p_ble_cb->inq_var.adv_mode == BTM_BLE_ADV_ENABLE) { - btm_ble_stop_adv(); - p_ble_cb->suspended_rl_state |= BTM_BLE_RL_ADV; + if (btm_ble_stop_adv() == BTM_SUCCESS) { + p_ble_cb->suspended_rl_state |= BTM_BLE_RL_ADV; + } } #endif // #if (BLE_42_ADV_EN == TRUE) @@ -1124,14 +1133,31 @@ void btm_ble_resolving_list_init(UINT8 max_irk_list_sz) tBTM_BLE_RESOLVE_Q *p_q = &btm_cb.ble_ctr_cb.resolving_list_pend_q; UINT8 irk_mask_size = (max_irk_list_sz % 8) ? (max_irk_list_sz / 8 + 1) : (max_irk_list_sz / 8); + // free them if they are already allocated. + btm_ble_resolving_list_cleanup(); + + p_q->q_next = 0; + p_q->q_pending = 0; if (max_irk_list_sz > 0) { p_q->resolve_q_random_pseudo = (BD_ADDR *)osi_malloc(sizeof(BD_ADDR) * max_irk_list_sz); + if (p_q->resolve_q_random_pseudo == NULL) { + BTM_TRACE_ERROR("%s - Out of memory for random pseudo address", __FUNCTION__); + goto _mem_error; + } p_q->resolve_q_action = (UINT8 *)osi_malloc(max_irk_list_sz); + if (p_q->resolve_q_action == NULL) { + BTM_TRACE_ERROR("%s - Out of memory for resolve action", __FUNCTION__); + goto _mem_error; + } /* RPA offloading feature */ if (btm_cb.ble_ctr_cb.irk_list_mask == NULL) { btm_cb.ble_ctr_cb.irk_list_mask = (UINT8 *)osi_malloc(irk_mask_size); + if (btm_cb.ble_ctr_cb.irk_list_mask == NULL) { + BTM_TRACE_ERROR("%s - Out of memory for IRK list mask", __FUNCTION__); + goto _mem_error; + } } BTM_TRACE_DEBUG ("%s max_irk_list_sz = %d", __func__, max_irk_list_sz); @@ -1140,6 +1166,12 @@ void btm_ble_resolving_list_init(UINT8 max_irk_list_sz) controller_get_interface()->set_ble_resolving_list_max_size(max_irk_list_sz); btm_ble_clear_resolving_list(); btm_cb.ble_ctr_cb.resolving_list_avail_size = max_irk_list_sz; + + return; + +_mem_error: + btm_ble_resolving_list_cleanup(); + btm_cb.ble_ctr_cb.resolving_list_avail_size = 0; } /******************************************************************************* diff --git a/components/bt/host/bluedroid/stack/btm/btm_sec.c b/components/bt/host/bluedroid/stack/btm/btm_sec.c index 4dcfaffe52..a744bc3032 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_sec.c +++ b/components/bt/host/bluedroid/stack/btm/btm_sec.c @@ -3491,6 +3491,12 @@ void btm_io_capabilities_rsp (UINT8 *p) /* Allocate a new device record or reuse the oldest one */ p_dev_rec = btm_find_or_alloc_dev (evt_data.bd_addr); + if (p_dev_rec == NULL) { + BTM_TRACE_ERROR ("%s: no device record available\n", __FUNCTION__); + return; + } + + /* If no security is in progress, this indicates incoming security */ if (btm_cb.pairing_state == BTM_PAIR_STATE_IDLE) { memcpy (btm_cb.pairing_bda, evt_data.bd_addr, BD_ADDR_LEN); @@ -4337,6 +4343,16 @@ void btm_sec_connected (UINT8 *bda, UINT16 handle, UINT8 status, UINT8 enc_mode) /* There is no device record for new connection. Allocate one */ if (status == HCI_SUCCESS) { p_dev_rec = btm_sec_alloc_dev (bda); + // no memory to allocate device record + if (p_dev_rec == NULL) { + if ((btm_cb.pairing_state != BTM_PAIR_STATE_IDLE) && + (memcmp (btm_cb.pairing_bda, bda, BD_ADDR_LEN) == 0)) { + btm_sec_change_pairing_state(BTM_PAIR_STATE_IDLE); + } + BTM_TRACE_ERROR ("%s: no device record available\n", __FUNCTION__); + return; + } + } else { /* If the device matches with stored paring address * reset the paring state to idle */ @@ -4899,6 +4915,12 @@ void btm_sec_link_key_notification (UINT8 *p_bda, UINT8 *p_link_key, UINT8 key_t void btm_sec_link_key_request (UINT8 *p_bda) { tBTM_SEC_DEV_REC *p_dev_rec = btm_find_or_alloc_dev (p_bda); + // no memory to allocate device record + if (p_dev_rec == NULL) { + btsnd_hcic_link_key_neg_reply (p_bda); + BTM_TRACE_ERROR ("%s: no device record available\n", __FUNCTION__); + return; + } BTM_TRACE_EVENT ("btm_sec_link_key_request() BDA: %02x:%02x:%02x:%02x:%02x:%02x\n", p_bda[0], p_bda[1], p_bda[2], p_bda[3], p_bda[4], p_bda[5]); @@ -6011,13 +6033,22 @@ static BOOLEAN btm_sec_queue_encrypt_request (BD_ADDR bd_addr, tBT_TRANSPORT tra tBTM_SEC_CALLBACK *p_callback, void *p_ref_data) { tBTM_SEC_QUEUE_ENTRY *p_e; + if (bd_addr == NULL) { + BTM_TRACE_ERROR("%s: bd_addr is NULL\n", __func__); + return FALSE; + } + p_e = (tBTM_SEC_QUEUE_ENTRY *)osi_malloc(sizeof(tBTM_SEC_QUEUE_ENTRY) + 1); if (p_e) { p_e->psm = 0; /* if PSM 0, encryption request */ p_e->p_callback = p_callback; - p_e->p_ref_data = (void *)(p_e + 1); - *(UINT8 *)p_e->p_ref_data = *(UINT8 *)(p_ref_data); + if (p_ref_data != NULL) { + p_e->p_ref_data = (void *)(p_e + 1); + *(UINT8 *)p_e->p_ref_data = *(UINT8 *)p_ref_data; + } else { + p_e->p_ref_data = NULL; + } p_e->transport = transport; memcpy(p_e->bd_addr, bd_addr, BD_ADDR_LEN); fixed_queue_enqueue(btm_cb.sec_pending_q, p_e, FIXED_QUEUE_MAX_TIMEOUT); @@ -6256,36 +6287,6 @@ BOOLEAN btm_sec_is_le_capable_dev (BD_ADDR bda) return le_capable; } -/******************************************************************************* -** -** Function btm_sec_find_bonded_dev -** -** Description Find a bonded device starting from the specified index -** -** Returns TRUE - found a bonded device -** -*******************************************************************************/ -#if (BLE_INCLUDED == TRUE) -BOOLEAN btm_sec_find_bonded_dev (UINT8 start_idx, UINT16 *p_found_handle, tBTM_SEC_DEV_REC **p_rec) -{ - BOOLEAN found = FALSE; - -#if (SMP_INCLUDED== TRUE) - tBTM_SEC_DEV_REC *p_dev_rec; - list_node_t *p_node = NULL; - for (p_node = list_begin(btm_cb.p_sec_dev_rec_list); p_node; p_node = list_next(p_node)) { - p_dev_rec = list_node(p_node); - if (p_dev_rec->ble.key_type || (p_dev_rec->sec_flags & BTM_SEC_LINK_KEY_KNOWN)) { - *p_found_handle = p_dev_rec->hci_handle; - *p_rec = p_dev_rec; - break; - } - } - BTM_TRACE_DEBUG ("%s() found=%d\n", __func__, found); -#endif - return (found); -} -#endif ///BLE_INCLUDED == TRUE /******************************************************************************* ** ** Function btm_sec_use_smp_br_chnl diff --git a/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h b/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h index 76b34bcefe..06a2023599 100644 --- a/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h +++ b/components/bt/host/bluedroid/stack/btm/include/btm_ble_int.h @@ -574,10 +574,10 @@ void btm_ble_accept_cis_req_cmd_status(tBTM_BLE_ISO_CB_PARAMS *cb_params); void btm_ble_create_cis_cmd_status(tBTM_BLE_ISO_CB_PARAMS *cb_params); void btm_ble_iso_set_cig_params_complete(UINT8 *p); #endif // #if (BLE_FEAT_ISO_CIG_CENTRAL_EN == TRUE) -#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) +#if (BLE_FEAT_ISO_BIG_BROADCASTER_EN == TRUE) void btm_ble_big_create_cmpl_evt(tBTM_BLE_BIG_CREATE_CMPL *param); void btm_ble_big_terminate_cmpl_evt(tBTM_BLE_BIG_TERMINATE_CMPL *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) void btm_ble_big_sync_estab_evt(tBTM_BLE_BIG_SYNC_ESTAB_CMPL *params); void btm_ble_big_sync_lost_evt(tBTM_BLE_BIG_SYNC_LOST_EVT *params); 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 2f1ae39414..e3e8c816bd 100644 --- a/components/bt/host/bluedroid/stack/btm/include/btm_int.h +++ b/components/bt/host/bluedroid/stack/btm/include/btm_int.h @@ -1337,7 +1337,6 @@ void btm_sec_set_peer_sec_caps (tACL_CONN *p_acl_cb, tBTM_SEC_DEV_REC *p_dev_rec #if BLE_INCLUDED == TRUE void btm_sec_clear_ble_keys (tBTM_SEC_DEV_REC *p_dev_rec); -BOOLEAN btm_sec_find_bonded_dev (UINT8 start_idx, UINT16 *p_found_handle, tBTM_SEC_DEV_REC **p_rec); BOOLEAN btm_sec_is_a_bonded_dev (BD_ADDR bda); void btm_consolidate_dev(tBTM_SEC_DEV_REC *p_target_rec); BOOLEAN btm_sec_is_le_capable_dev (BD_ADDR bda); 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 69ed5e27bb..0cd4302d5c 100644 --- a/components/bt/host/bluedroid/stack/include/stack/btm_api.h +++ b/components/bt/host/bluedroid/stack/include/stack/btm_api.h @@ -865,16 +865,6 @@ typedef struct { 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. -*/ -typedef struct { - tBTM_STATUS status; - UINT8 hci_status; - INT8 tx_power; - BD_ADDR rem_bda; -} tBTM_TX_POWER_RESULTS; - /* Structure returned with read link quality event (in tBTM_CMPL_CB callback function) ** in response to BTM_ReadLinkQuality call. */ diff --git a/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h b/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h index e331a39bf2..57c4660bc6 100644 --- a/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h +++ b/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h @@ -978,10 +978,10 @@ typedef void (tBTM_SET_VENDOR_EVT_MASK_CBACK) (tBTM_STATUS status); typedef UINT8 tBTM_BLE_5_GAP_EVENT; #if (BLE_FEAT_ISO_EN == TRUE) -#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) +#if (BLE_FEAT_ISO_BIG_BROADCASTER_EN == TRUE) #define BTM_BLE_ISO_BIG_CREATE_COMPLETE_EVT 1 #define BTM_BLE_ISO_BIG_TERMINATE_COMPLETE_EVT 2 -#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) #define BTM_BLE_ISO_BIG_SYNC_ESTABLISHED_EVT 3 #define BTM_BLE_ISO_BIG_SYNC_LOST_EVT 4 @@ -1099,7 +1099,7 @@ typedef struct { typedef struct { UINT8 status; UINT8 instance_num; - UINT8 instance[10]; + UINT8 instance[MAX_BLE_ADV_INSTANCE]; } tBTM_BLE_EXT_ADV_START_CMPL; typedef struct { @@ -1537,7 +1537,7 @@ typedef struct { #endif // (BT_BLE_FEAT_CHANNEL_SOUNDING == TRUE) #if (BLE_FEAT_ISO_EN == TRUE) -#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) +#if (BLE_FEAT_ISO_BIG_BROADCASTER_EN == TRUE) typedef struct { UINT8 status; UINT8 big_handle; @@ -1559,7 +1559,7 @@ typedef struct { UINT8 big_handle; UINT8 reason; } tBTM_BLE_BIG_TERMINATE_CMPL; -#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) typedef struct { @@ -1704,10 +1704,10 @@ typedef struct { typedef union { UINT8 status; -#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) +#if (BLE_FEAT_ISO_BIG_BROADCASTER_EN == TRUE) tBTM_BLE_BIG_CREATE_CMPL btm_big_cmpl; tBTM_BLE_BIG_TERMINATE_CMPL btm_big_term; -#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) tBTM_BLE_BIG_SYNC_ESTAB_CMPL btm_big_sync_estab; tBTM_BLE_BIG_SYNC_LOST_EVT btm_big_sync_lost; @@ -3107,7 +3107,7 @@ void BTM_BleSetPeriodicAdvSyncTransParams(BD_ADDR bd_addr, UINT8 mode, UINT16 sk #if (BLE_FEAT_ISO_EN == TRUE) void BTM_BleIsoRegisterCallback(tBTM_BLE_ISO_CBACK cb); -#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE) +#if (BLE_FEAT_ISO_BIG_BROADCASTER_EN == TRUE) tBTM_STATUS BTM_BleBigCreate(uint8_t big_handle, uint8_t adv_handle, uint8_t num_bis, uint32_t sdu_interval, uint16_t max_sdu, uint16_t max_transport_latency, uint8_t rtn, uint8_t phy, uint8_t packing, uint8_t framing, @@ -3120,7 +3120,7 @@ tBTM_STATUS BTM_BleBigCreateTest(uint8_t big_handle, uint8_t adv_handle, uint8_t uint8_t pto, uint8_t encryption, uint8_t *broadcast_code); tBTM_STATUS BTM_BleBigTerminate(UINT8 big_handle, UINT8 reason); -#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) tBTM_STATUS BTM_BleBigSyncCreate(uint8_t big_handle, uint16_t sync_handle, uint8_t encryption, uint8_t *bc_code,