fix(ble/bluedroid): fix L2CAP, SMP and HCI command issues

- Fix active_count check in l2cu_ble_plcb_active_count
- Restore previous state if connection command fails
- Fix HCI cmd buffer size off-by-one errors
- Fix connect handle length errors
- Fix channel sounding event status handling
- Fix SMP param_len check in smp_rand_back
- Fix spelling: BROCASTER to BROADCASTER in definitions
This commit is contained in:
zhiweijian
2026-02-27 17:59:59 +08:00
parent e0ccc644a8
commit e118d053b3
13 changed files with 183 additions and 65 deletions
@@ -192,12 +192,12 @@ static void btu_ble_periodic_adv_sync_trans_recv(UINT8 *p);
#if (BLE_FEAT_ISO_EN == TRUE)
#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
#if (BLE_FEAT_ISO_BIG_BROADCASTER_EN == TRUE)
void btu_ble_create_big_cmd_status(UINT8 status);
static void btu_ble_big_create_complete_evt(UINT8 *p);
void btu_ble_big_terminate_cmd_status(UINT8 status);
static void btu_ble_big_terminate_complete_evt(UINT8 *p);
#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)
static void btu_ble_create_big_sync_cmd_status(UINT8 status);
@@ -570,14 +570,14 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg)
btu_ble_cis_request_evt(p);
break;
#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)
case HCI_BLE_BIG_CREATE_COMPLETE_EVT:
btu_ble_big_create_complete_evt(p);
break;
case HCI_BLE_BIG_TERMINATE_COMPLETE_EVT:
btu_ble_big_terminate_complete_evt(p);
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 HCI_BLE_BIG_SYNC_ESTABLISHED_EVT:
btu_ble_big_sync_establish_evt(p);
@@ -1633,7 +1633,7 @@ static void btu_hcif_hdl_command_status (UINT16 opcode, UINT8 status, UINT8 *p_c
}
#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
#if (BLE_FEAT_ISO_EN == TRUE)
#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
#if (BLE_FEAT_ISO_BIG_BROADCASTER_EN == TRUE)
case HCI_BLE_CREATE_BIG:
case HCI_BLE_CREATE_BIG_TEST:
btu_ble_create_big_cmd_status(status);
@@ -1641,7 +1641,7 @@ static void btu_hcif_hdl_command_status (UINT16 opcode, UINT8 status, UINT8 *p_c
case HCI_BLE_TERMINATE_BIG:
btu_ble_big_terminate_cmd_status(status);
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 HCI_BLE_BIG_CREATE_SYNC:
btu_ble_create_big_sync_cmd_status(status);
@@ -2538,9 +2538,9 @@ static void btm_ble_resolve_random_addr_adv_ext(void *p_rec, void *p)
{
tBTM_SEC_DEV_REC *match_rec = (tBTM_SEC_DEV_REC *) p_rec;
BD_ADDR bda;
UINT8 *pp = (UINT8 *)p+4; //jump to the location of bd addr
UINT8 *pp = (UINT8 *)p+2; //jump to the location of addr_type
if (match_rec) {
// Assign the original address to be the current report address
UINT8_TO_STREAM(pp, match_rec->ble.ble_addr_type);
memcpy(bda, match_rec->ble.pseudo_addr, BD_ADDR_LEN);
BDADDR_TO_STREAM(pp,bda);
}
@@ -2554,15 +2554,13 @@ static void btu_ble_ext_adv_report_evt(UINT8 *p, UINT16 evt_len)
tBTM_BLE_EXT_ADV_REPORT ext_adv_report = {0};
UINT8 num_reports = {0};
#if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE)
UINT8 *pp = p;
UINT8 *pp;
BOOLEAN match = FALSE;
#endif
//UINT8 legacy_event_type = 0;
UINT16 evt_type = 0;
uint8_t addr_type;
BD_ADDR bda;
#if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE)
BOOLEAN match = FALSE;
#endif
if (!p) {
HCI_TRACE_ERROR("%s, Invalid params.", __func__);
@@ -2576,6 +2574,10 @@ static void btu_ble_ext_adv_report_evt(UINT8 *p, UINT16 evt_len)
}
while (num_reports--) {
#if (defined BLE_PRIVACY_SPT && BLE_PRIVACY_SPT == TRUE)
/* Save current report start position for address resolution callback */
pp = p;
#endif
STREAM_TO_UINT16(evt_type, p);
ext_adv_report.event_type = evt_type & 0x1F;
if(ext_adv_report.event_type & BTM_BLE_ADV_LEGACY_MASK) {
@@ -2601,8 +2603,9 @@ static void btu_ble_ext_adv_report_evt(UINT8 *p, UINT16 evt_len)
match = btm_identity_addr_to_random_pseudo(bda, &addr_type, FALSE);
if (!match && BTM_BLE_IS_RESOLVE_BDA(bda)) {
btm_ble_resolve_random_addr(bda, btm_ble_resolve_random_addr_adv_ext, pp);
//the BDADDR may be updated, so read it again
p = p - sizeof(bda);
//the addr_type and BDADDR may be updated, so read them again
p = p - sizeof(bda) - 1;
STREAM_TO_UINT8(addr_type, p);
STREAM_TO_BDADDR(bda, p);
}
}
@@ -2656,6 +2659,13 @@ static void btu_ble_periodic_adv_sync_establish_evt(UINT8 *p, bool v2_evt)
STREAM_TO_UINT8(sync_estab.rsp_slot_delay, p);
STREAM_TO_UINT8(sync_estab.rsp_slot_spacing, p);
}
#else
if (v2_evt) {
STREAM_SKIP_UINT8(p);
STREAM_SKIP_UINT8(p);
STREAM_SKIP_UINT8(p);
STREAM_SKIP_UINT8(p);
}
#endif // (BT_BLE_FEAT_PAWR_EN == TRUE)
btm_ble_periodic_adv_sync_establish_evt(&sync_estab);
@@ -2666,15 +2676,15 @@ static void btu_ble_periodic_adv_report_evt(UINT8 *p, UINT8 evt_len, bool v2_evt
tBTM_PERIOD_ADV_REPORT adv_report = {0};
/* This parameter is intended to be used in a future feature. */
UINT8 unused = 0;
UINT8 min_len = MIN_BLE_PERIODIC_ADV_REPORT_LEN;
UINT8 min_len = v2_evt ? (MIN_BLE_PERIODIC_ADV_REPORT_LEN + 3) : MIN_BLE_PERIODIC_ADV_REPORT_LEN;
if (!p) {
HCI_TRACE_ERROR("%s, Invalid params.", __func__);
return;
}
if (evt_len < MIN_BLE_PERIODIC_ADV_REPORT_LEN) {
HCI_TRACE_ERROR("%s, Invalid params, the adv len is too short.", __func__);
if (evt_len < min_len) {
HCI_TRACE_ERROR("%s, Invalid params, the adv len %d is too short.", __func__, evt_len);
return;
}
@@ -2686,7 +2696,11 @@ static void btu_ble_periodic_adv_report_evt(UINT8 *p, UINT8 evt_len, bool v2_evt
if (v2_evt) {
STREAM_TO_UINT16(adv_report.periodic_evt_cnt, p);
STREAM_TO_UINT8(adv_report.subevt, p);
min_len += 3;
}
#else
if (v2_evt) {
STREAM_SKIP_UINT16(p);
STREAM_SKIP_UINT8(p);
}
#endif // (BT_BLE_FEAT_PAWR_EN == TRUE)
STREAM_TO_UINT8(adv_report.data_status, p);
@@ -2885,6 +2899,15 @@ static void btu_ble_cis_established_evt(UINT8 *p, bool v2_evt)
STREAM_TO_UINT24(cis_estab_evt.sdu_int_p_to_c, p);
STREAM_TO_UINT8(cis_estab_evt.framing, p);
}
#else
if (v2_evt) {
STREAM_SKIP_UINT24(p);
STREAM_SKIP_UINT16(p);
STREAM_SKIP_UINT16(p);
STREAM_SKIP_UINT24(p);
STREAM_SKIP_UINT24(p);
STREAM_SKIP_UINT8(p);
}
#endif // #if (BLE_FEAT_ISO_60_EN == TRUE)
btm_ble_cis_established_evt(&cis_estab_evt);
@@ -2912,7 +2935,7 @@ static void btu_ble_cis_request_evt(UINT8 *p)
}
#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 btu_ble_create_big_cmd_status(UINT8 status)
{
if (status != HCI_SUCCESS) {
@@ -2987,7 +3010,7 @@ static void btu_ble_big_terminate_complete_evt(UINT8 *p)
btm_ble_big_terminate_cmpl_evt(&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)
void btu_ble_create_big_sync_cmd_status(UINT8 status)
@@ -3534,6 +3557,8 @@ static void btu_ble_cs_subevt_result_continue_evt(UINT8 *p)
HCI_TRACE_ERROR("%s, no memory.", __func__);
}
}
} else {
HCI_TRACE_ERROR("%s, no memory for step_info.", __func__);
}
btm_ble_cs_subevt_continue_result_evt(&subevt_continue_result);
@@ -559,6 +559,12 @@ void btu_start_quick_timer(TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout_ti
osi_mutex_lock(&btu_l2cap_alarm_lock, OSI_MUTEX_MAX_TIMEOUT);
if (!hash_map_has_key(btu_l2cap_alarm_hash_map, p_tle)) {
alarm = osi_alarm_new("btu_l2cap", btu_l2cap_alarm_cb, (void *)p_tle, 0);
if (alarm == NULL) {
HCI_TRACE_ERROR("%s Unable to create alarm", __func__);
osi_mutex_unlock(&btu_l2cap_alarm_lock);
return;
}
hash_map_set(btu_l2cap_alarm_hash_map, p_tle, (void *)alarm);
}
osi_mutex_unlock(&btu_l2cap_alarm_lock);
@@ -1419,7 +1419,7 @@ UINT8 btsnd_hcic_ble_read_max_adv_len(void)
UINT8 *pp;
HCI_TRACE_EVENT("%s", __func__);
HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_READ_MAX_ADV_SIZE + 1);
HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_READ_MAX_ADV_SIZE);
UINT16_TO_STREAM(pp, HCI_BLE_RD_MAX_ADV_DATA_LEN);
UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_READ_MAX_ADV_SIZE);
@@ -1433,7 +1433,7 @@ UINT8 btsnd_hcic_ble_read_num_support_adv_set(void)
UINT8 *pp;
HCI_TRACE_EVENT("%s", __func__);
HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_NUM_SUPPORT_ADV_SET + 1);
HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_NUM_SUPPORT_ADV_SET);
UINT16_TO_STREAM(pp, HCI_BLE_RD_NUM_OF_ADV_SETS);
UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_NUM_SUPPORT_ADV_SET);
@@ -1447,7 +1447,7 @@ UINT8 btsnd_hcic_ble_remove_adv_set(UINT8 adv_handle)
UINT8 *pp;
HCI_TRACE_EVENT("%s, adv_handle = %d", __func__, adv_handle);
HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_REMOVE_ADV_SET + 1);
HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_REMOVE_ADV_SET);
UINT16_TO_STREAM(pp, HCI_BLE_REMOVE_ADV_SET);
UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_REMOVE_ADV_SET);
@@ -1462,7 +1462,7 @@ UINT8 btsnd_hcic_ble_clear_adv_set(void)
UINT8 *pp;
HCI_TRACE_EVENT("%s", __func__);
HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_CLEAR_ADV_SET + 1);
HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_CLEAR_ADV_SET);
UINT16_TO_STREAM(pp, HCI_BLE_CLEAR_ADV_SETS);
UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_CLEAR_ADV_SET);
@@ -1781,15 +1781,16 @@ BOOLEAN btsnd_hcic_ble_create_ext_conn_v2(tHCI_CreatExtConn *p_conn)
#if (BLE_50_EXTEND_SYNC_EN == TRUE)
BOOLEAN btsnd_hcic_ble_periodic_adv_create_sync(UINT8 option, UINT8 adv_sid,
UINT8 adv_addr_type, BD_ADDR adv_addr,
UINT16 skip,
UINT16 sync_timeout, UINT8 sync_cte_type)
{
BT_HDR *p;
UINT8 *pp;
HCI_TRACE_EVENT("%s, option = %d, adv_sid = %d, adv_addr_type = %d, sync_timeout = %d, sync_cte_type = %d",
__func__, option, adv_sid, adv_addr_type, sync_timeout, sync_cte_type);
HCI_TRACE_EVENT("%s, option = %d, adv_sid = %d, adv_addr_type = %d, skip = %d, sync_timeout = %d, sync_cte_type = %d",
__func__, option, adv_sid, adv_addr_type, skip, sync_timeout, sync_cte_type);
HCI_TRACE_EVENT("addr %02x %02x %02x %02x %02x %02x", adv_addr[0], adv_addr[1], adv_addr[2], adv_addr[3], adv_addr[4], adv_addr[5]);
uint16_t skip = 0;
HCIC_BLE_CMD_CREATED(p, pp, HCIC_PARAM_SIZE_PERIODIC_ADV_CREATE_SYNC + 2);
UINT16_TO_STREAM(pp, HCI_BLE_PERIOD_ADV_CREATE_SYNC);
@@ -1949,7 +1950,7 @@ UINT8 btsnd_hcic_ble_write_rf_path_compensation(UINT16 rf_tx_path, UINT16 rf_rx_
UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_WRITE_RF_PATH_COMPENSATION);
UINT16_TO_STREAM(pp, rf_tx_path);
UINT16_TO_STREAM(pp, rf_tx_path);
UINT16_TO_STREAM(pp, rf_rx_path);
return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p);
}
@@ -2157,7 +2158,7 @@ BOOLEAN btsnd_hcic_ble_set_vendor_evt_mask (UINT32 evt_mask)
#if (BLE_FEAT_ISO_EN == TRUE)
#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
#if (BLE_FEAT_ISO_BIG_BROADCASTER_EN == TRUE)
UINT8 btsnd_hcic_ble_big_create(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,
@@ -2255,7 +2256,7 @@ UINT8 btsnd_hcic_ble_big_terminate(uint8_t big_handle, uint8_t reason)
btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
return TRUE;
}
#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)
UINT8 btsnd_hcic_ble_big_sync_create(uint8_t big_handle, uint16_t sync_handle,
uint8_t encryption, uint8_t *bc_code,
@@ -3395,7 +3396,7 @@ UINT8 btsnd_hcic_ble_cs_procedure_enable(UINT16 conn_handle, UINT8 config_id, UI
UINT8_TO_STREAM(pp, config_id);
UINT8_TO_STREAM(pp, enable);
btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p);
btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
return TRUE;
}
@@ -260,6 +260,7 @@ typedef struct {
#define STREAM_SKIP_UINT8(p) do { (p) += 1; } while (0)
#define STREAM_SKIP_UINT16(p) do { (p) += 2; } while (0)
#define STREAM_SKIP_UINT24(p) do { (p) += 3; } while (0)
/********************************************************************************
** Macros to get and put bytes to and from a field (Little Endian format).
@@ -914,10 +914,10 @@
#if (BLE_FEAT_ISO_EN == TRUE)
#define HCI_BLE_CIS_ESTABLISHED_V1_EVT 0x19
#define HCI_BLE_CIS_REQUEST_EVT 0x1A
#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
#if (BLE_FEAT_ISO_BIG_BROADCASTER_EN == TRUE)
#define HCI_BLE_BIG_CREATE_COMPLETE_EVT 0x1B
#define HCI_BLE_BIG_TERMINATE_COMPLETE_EVT 0x1C
#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 HCI_BLE_BIG_SYNC_ESTABLISHED_EVT 0x1D
#define HCI_BLE_BIG_SYNC_LOST_EVT 0x1E
@@ -1042,6 +1042,7 @@ BOOLEAN btsnd_hcic_ble_create_ext_conn_v2(tHCI_CreatExtConn *p_conn);
BOOLEAN btsnd_hcic_ble_periodic_adv_create_sync(UINT8 filter_policy, UINT8 adv_sid,
UINT8 adv_addr_type, BD_ADDR adv_addr,
UINT16 skip,
UINT16 sync_timeout, UINT8 sync_cte_type);
UINT8 btsnd_hcic_ble_periodic_adv_create_sync_cancel(void);
@@ -1100,11 +1101,11 @@ UINT8 btsnd_hcic_ble_set_default_periodic_adv_sync_trans_params(UINT8 mode, UINT
#define HCIC_PARAM_SIZE_ISO_ACCEPT_CIS_REQ_PARAMS 2
#define HCIC_PARAM_SIZE_ISO_REJECT_CIS_REQ_PARAMS 3
#define HCIC_PARAM_SIZE_ISO_READ_LINK_QUALITY_PARAMS 2
#if (BLE_FEAT_ISO_BIG_BROCASTER_EN == TRUE)
#if (BLE_FEAT_ISO_BIG_BROADCASTER_EN == TRUE)
#define HCIC_PARAM_SIZE_BIG_CREATE_PARAMS 31
#define HCIC_PARAM_SIZE_BIG_CREATE_TEST_PARAMS 36
#define HCIC_PARAM_SIZE_BIG_TERMINATE_PARAMS 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 HCIC_PARAM_SIZE_BIG_SYNC_CREATE_PARAMS 55
#define HCIC_PARAM_SIZE_BIG_SYNC_TERMINATE_PARAMS 1
@@ -1155,7 +1156,7 @@ UINT8 btsnd_hcic_ble_iso_accept_cis_req(uint16_t cis_handle);
UINT8 btsnd_hcic_ble_iso_reject_cis_req(uint16_t cis_handle, uint8_t reason);
#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)
UINT8 btsnd_hcic_ble_big_create(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,
@@ -1168,7 +1169,7 @@ UINT8 btsnd_hcic_ble_big_create_test(uint8_t big_handle, uint8_t adv_handle, uin
uint8_t pto, uint8_t encryption, uint8_t *broadcast_code);
UINT8 btsnd_hcic_ble_big_terminate(uint8_t big_handle, uint8_t 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)
UINT8 btsnd_hcic_ble_big_sync_create(uint8_t big_handle, uint16_t sync_handle,
@@ -234,6 +234,7 @@ BOOLEAN L2CA_EnableUpdateBleConnParams (BD_ADDR rem_bda, BOOLEAN enable)
return (FALSE);
}
bool is_disable = (p_lcb->conn_update_mask & L2C_BLE_CONN_UPDATE_DISABLE);
// for multiple links, actively updating the parameters to 7.5ms may degrade multi-connection performance
if(l2cu_ble_plcb_active_count() >1 && !(enable && is_disable)) {
return FALSE;
}
@@ -875,10 +876,11 @@ void l2cble_process_sig_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
p_ccb = l2cu_find_ccb_by_cid(p_lcb, lcid);
if (p_ccb) {
p_ccb->remote_id = id;
// TODO
l2cu_send_peer_disc_rsp(p_lcb, id, lcid, rcid);
} else {
L2CAP_TRACE_WARNING ("L2CAP - LE - disc req with invalid lcid, send cmd reject");
l2cu_send_peer_cmd_reject(p_lcb, L2CAP_CMD_REJ_INVALID_CID, id, rcid, lcid);
}
l2cu_send_peer_disc_rsp(p_lcb, id, lcid, rcid);
break;
}
default:
@@ -1073,19 +1075,29 @@ BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb)
#if (BT_BLE_FEAT_PAWR_EN == TRUE)
if (p_lcb->is_pawr_synced) {
if(!btsnd_hcic_ble_create_ext_conn_v2(&aux_conn)) {
l2cb.is_ble_connecting = FALSE;
memset(l2cb.ble_connecting_bda, 0, BD_ADDR_LEN);
btm_ble_set_conn_st (BLE_CONN_IDLE);
l2cu_release_lcb (p_lcb);
L2CAP_TRACE_ERROR("initiate pawr sync connection failed, no resources");
return (FALSE);
}
} else
#endif // (BT_BLE_FEAT_PAWR_EN == TRUE)
{
if(!btsnd_hcic_ble_create_ext_conn(&aux_conn)) {
l2cb.is_ble_connecting = FALSE;
memset(l2cb.ble_connecting_bda, 0, BD_ADDR_LEN);
btm_ble_set_conn_st (BLE_CONN_IDLE);
l2cu_release_lcb (p_lcb);
L2CAP_TRACE_ERROR("initiate Aux connection failed, no resources");
return (FALSE);
}
}
#else
l2cu_release_lcb (p_lcb);
L2CAP_TRACE_ERROR("BLE 5.0 not support!\n");
return (FALSE);
#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
return (TRUE);
}
@@ -1293,7 +1305,7 @@ void l2cble_process_rc_param_request_evt(UINT16 handle, UINT16 int_min, UINT16 i
btsnd_hcic_ble_rc_param_req_reply(handle, int_min, int_max, latency, timeout, BLE_CE_LEN_MIN, BLE_CE_LEN_MIN);
}else {
L2CAP_TRACE_EVENT ("L2CAP - LE - update currently disabled");
p_lcb->conn_update_mask |= L2C_BLE_NEW_CONN_PARAM;
// p_lcb->conn_update_mask |= L2C_BLE_NEW_CONN_PARAM;
btsnd_hcic_ble_rc_param_req_neg_reply (handle, HCI_ERR_UNACCEPT_CONN_INTERVAL);
}
}
@@ -43,7 +43,7 @@
static BOOLEAN l2c_link_send_to_lower (tL2C_LCB *p_lcb, BT_HDR *p_buf);
#if (BLE_50_FEATURE_SUPPORT == TRUE)
extern tBTM_STATUS BTM_BleStartExtAdvRestart(uint8_t handle);
extern tBTM_STATUS BTM_BleStartExtAdvRestart(uint16_t handle);
#endif// #if (BLE_50_FEATURE_SUPPORT == TRUE)
extern bool btm_ble_inter_get(void);
@@ -909,7 +909,7 @@ void l2c_init (void)
l2cb.l2c_ble_fixed_chnls_mask =
L2CAP_FIXED_CHNL_ATT_BIT | L2CAP_FIXED_CHNL_BLE_SIG_BIT | L2CAP_FIXED_CHNL_SMP_BIT;
#endif
// Free callback must be NULL
l2cb.rcv_pending_q = list_new(NULL);
if (l2cb.rcv_pending_q == NULL) {
L2CAP_TRACE_ERROR("%s unable to allocate memory for link layer control block", __func__);
@@ -948,6 +948,10 @@ void l2c_free_p_ccb_pool(void)
void l2c_free(void)
{
// check again
if (l2cb.rcv_pending_q && list_length(l2cb.rcv_pending_q) > 0) {
assert(0);
}
list_free(l2cb.rcv_pending_q);
l2cb.rcv_pending_q = NULL;
l2c_free_p_lcb_pool();
@@ -170,6 +170,10 @@ void l2cu_release_lcb (tL2C_LCB *p_lcb)
p_lcb->start_time_s = 0;
#endif // #if (BLE_INCLUDED == TRUE)
#if (BT_BLE_FEAT_PAWR_EN == TRUE)
p_lcb->is_pawr_synced = FALSE;
#endif
/* Stop and release timers */
btu_free_timer (&p_lcb->timer_entry);
memset(&p_lcb->timer_entry, 0, sizeof(TIMER_LIST_ENT));
@@ -364,10 +368,7 @@ uint8_t l2cu_ble_plcb_active_count(void)
active_count ++;
}
}
if (active_count >= MAX_L2CAP_CHANNELS) {
L2CAP_TRACE_ERROR("error active count");
active_count = 0;
}
L2CAP_TRACE_DEBUG("plcb active count %d", active_count);
return active_count;
@@ -3286,7 +3287,7 @@ tL2C_LCB *l2cu_find_lcb_by_handle (UINT16 handle)
bool l2cu_find_ccb_in_list(void *p_ccb_node, void *p_local_cid)
{
tL2C_CCB *p_ccb = (tL2C_CCB *)p_ccb_node;
uint8_t local_cid = *((uint8_t *)p_local_cid);
uint16_t local_cid = *((uint16_t *)p_local_cid);
if (p_ccb->local_cid == local_cid && p_ccb->in_use) {
return FALSE;
@@ -177,9 +177,16 @@ static void ECC_NAF(uint8_t *naf, uint32_t *NumNAF, DWORD *k, uint32_t keyLength
k[0] = k[0] + 1;
if (k[0] == 0) { //overflow
j = 1;
do {
while (j < keyLength && k[j] == 0xFFFFFFFF) {
k[j] = 0;
j++;
}
if (j < keyLength) {
k[j]++;
} while (k[j++] == 0); //overflow
}
// If j >= keyLength, the entire key is 0xFFFFFFFF,
// which should not happen for a valid private key.
// In this case, we stop the propagation to prevent buffer overflow.
}
}
} else {
@@ -621,10 +621,10 @@ void smp_concatenate_peer( tSMP_CB *p_cb, UINT8 **p_data, UINT8 op_code)
** Description Generate Confirm/Compare Step1:
** p1 = press || preq || rat' || iat'
**
** Returns void
** Returns BOOLEAN
**
*******************************************************************************/
void smp_gen_p1_4_confirm( tSMP_CB *p_cb, BT_OCTET16 p1)
BOOLEAN smp_gen_p1_4_confirm( tSMP_CB *p_cb, BT_OCTET16 p1)
{
UINT8 *p = (UINT8 *)p1;
tBLE_ADDR_TYPE addr_type = 0;
@@ -634,7 +634,7 @@ void smp_gen_p1_4_confirm( tSMP_CB *p_cb, BT_OCTET16 p1)
if (!BTM_ReadRemoteConnectionAddr(p_cb->pairing_bda, remote_bda, &addr_type)) {
SMP_TRACE_ERROR("can not generate confirm for unknown device\n");
return;
return FALSE;
}
BTM_ReadConnectionAddr( p_cb->pairing_bda, p_cb->local_bda, &p_cb->addr_type);
@@ -662,6 +662,7 @@ void smp_gen_p1_4_confirm( tSMP_CB *p_cb, BT_OCTET16 p1)
SMP_TRACE_DEBUG("p1 = press || preq || rat' || iat'\n");
smp_debug_print_nbyte_little_endian ((UINT8 *)p1, (const UINT8 *)"P1", 16);
#endif
return TRUE;
}
/*******************************************************************************
@@ -725,7 +726,11 @@ void smp_calculate_comfirm (tSMP_CB *p_cb, BT_OCTET16 rand, BD_ADDR bda)
SMP_TRACE_DEBUG ("smp_calculate_comfirm \n");
/* generate p1 = press || preq || rat' || iat' */
smp_gen_p1_4_confirm(p_cb, p1);
if (!smp_gen_p1_4_confirm(p_cb, p1)) {
smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &status);
return ;
}
/* p1 = rand XOR p1 */
smp_xor_128(p1, rand);
@@ -1138,6 +1143,12 @@ void smp_continue_private_key_creation (tSMP_CB *p_cb, tBTM_RAND_ENC *p)
UINT8 state = p_cb->rand_enc_proc_state & ~0x80;
SMP_TRACE_DEBUG ("%s state=0x%x\n", __func__, state);
/* Validate param_len to prevent buffer overflow/underflow */
if (p == NULL || p->param_len != BT_OCTET8_LEN) {
SMP_TRACE_ERROR("invalid param_len: %d, expected %d\n", p ? p->param_len : 0, BT_OCTET8_LEN);
return;
}
switch (state) {
case SMP_GENERATE_PRIVATE_KEY_0_7:
memcpy((void *)p_cb->private_key, p->param_buf, p->param_len);
@@ -1543,6 +1554,9 @@ void smp_calculate_peer_commitment(tSMP_CB *p_cb, BT_OCTET16 output_buf)
**
** Note The LSB is the first octet, the MSB is the last octet of
** the AES-CMAC input/output stream.
** In little-endian implementation, the message is constructed
** as Z||V||U (reversed parameter order) to compensate for
** byte order differences with the big-endian specification.
**
*******************************************************************************/
void smp_calculate_f4(UINT8 *u, UINT8 *v, UINT8 *x, UINT8 z, UINT8 *c)
@@ -2041,11 +2055,16 @@ BOOLEAN smp_calculate_f5_key(UINT8 *w, UINT8 *t)
*******************************************************************************/
void smp_calculate_local_dhkey_check(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
{
UINT8 iocap[3], a[7], b[7];
UINT8 iocap[3], a[7] = {0}, b[7] = {0};
SMP_TRACE_DEBUG ("%s", __FUNCTION__);
smp_calculate_f5_mackey_and_long_term_key(p_cb);
if (!smp_calculate_f5_mackey_and_long_term_key(p_cb)) {
UINT8 reason = SMP_PAIR_FAIL_UNKNOWN;
p_cb->failure = reason;
smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
return;
}
smp_collect_local_io_capabilities(iocap, p_cb);
@@ -2068,7 +2087,7 @@ void smp_calculate_local_dhkey_check(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
*******************************************************************************/
void smp_calculate_peer_dhkey_check(tSMP_CB *p_cb, tSMP_INT_DATA *p_data)
{
UINT8 iocap[3], a[7], b[7];
UINT8 iocap[3], a[7] = {0}, b[7] = {0};
BT_OCTET16 param_buf;
BOOLEAN ret;
tSMP_KEY key;
@@ -2482,37 +2501,62 @@ static void smp_rand_back(tBTM_RAND_ENC *p)
UINT8 *pp = NULL;
UINT8 failure = SMP_PAIR_FAIL_UNKNOWN;
UINT8 state = p_cb->rand_enc_proc_state & ~0x80;
BOOLEAN check_failed = FALSE;
SMP_TRACE_DEBUG ("%s state=0x%x", __FUNCTION__, state);
if (p && p->status == HCI_SUCCESS) {
switch (state) {
case SMP_GEN_SRAND_MRAND:
if (p->param_len != BT_OCTET8_LEN) {
check_failed = TRUE;
break;
}
memcpy((void *)p_cb->rand, p->param_buf, p->param_len);
smp_generate_rand_cont(p_cb, NULL);
break;
case SMP_GEN_SRAND_MRAND_CONT:
if (p->param_len != BT_OCTET8_LEN) {
check_failed = TRUE;
break;
}
memcpy((void *)&p_cb->rand[8], p->param_buf, p->param_len);
smp_generate_confirm(p_cb, NULL);
break;
case SMP_GEN_DIV_LTK:
if (p->param_len < 2) {
check_failed = TRUE;
break;
}
pp = p->param_buf;
STREAM_TO_UINT16(p_cb->div, pp);
smp_generate_ltk_cont(p_cb, NULL);
break;
case SMP_GEN_DIV_CSRK:
if (p->param_len < 2) {
check_failed = TRUE;
break;
}
pp = p->param_buf;
STREAM_TO_UINT16(p_cb->div, pp);
smp_compute_csrk(p_cb, NULL);
break;
case SMP_GEN_TK:
if (p->param_len < 4) {
check_failed = TRUE;
break;
}
smp_proc_passkey(p_cb, p);
break;
case SMP_GEN_RAND_V:
if (p->param_len != BT_OCTET8_LEN) {
check_failed = TRUE;
break;
}
memcpy(p_cb->enc_rand, p->param_buf, BT_OCTET8_LEN);
smp_generate_y(p_cb, NULL);
break;
@@ -2521,21 +2565,34 @@ static void smp_rand_back(tBTM_RAND_ENC *p)
case SMP_GENERATE_PRIVATE_KEY_8_15:
case SMP_GENERATE_PRIVATE_KEY_16_23:
case SMP_GENERATE_PRIVATE_KEY_24_31:
if (p->param_len != BT_OCTET8_LEN) {
check_failed = TRUE;
break;
}
smp_continue_private_key_creation(p_cb, p);
break;
case SMP_GEN_NONCE_0_7:
if (p->param_len != BT_OCTET8_LEN) {
check_failed = TRUE;
break;
}
memcpy((void *)p_cb->rand, p->param_buf, p->param_len);
smp_finish_nonce_generation(p_cb);
break;
case SMP_GEN_NONCE_8_15:
if (p->param_len != BT_OCTET8_LEN) {
check_failed = TRUE;
break;
}
memcpy((void *)&p_cb->rand[8], p->param_buf, p->param_len);
smp_process_new_nonce(p_cb);
break;
}
return;
if (!check_failed) {
return;
}
}
SMP_TRACE_ERROR("%s key generation failed: (%d)", __FUNCTION__, p_cb->rand_enc_proc_state);
@@ -749,11 +749,14 @@ static BT_HDR *smp_build_pairing_commitment_cmd(UINT8 cmd_code, tSMP_CB *p_cb)
UINT8 *p;
UNUSED(cmd_code);
SMP_TRACE_EVENT("%s\n", __func__);
if ((p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR) + SMP_PAIR_COMMITM_SIZE + L2CAP_MIN_OFFSET))
!= NULL) {
p = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
/* The transmitter sends 0x03 universally.
The receiver performs automatic conversion according to its capabilities to ensure backward compatibility.
The state machine operates using the translated opcode. please refer to smp_data_received() in smp_l2c.c
Please note that using SMP OPCODE to CONFIRM is not an error.
*/
UINT8_TO_STREAM (p, SMP_OPCODE_CONFIRM);
ARRAY_TO_STREAM (p, p_cb->commitment, BT_OCTET16_LEN);
@@ -1462,7 +1465,7 @@ void smp_collect_peer_io_capabilities(UINT8 *iocap, tSMP_CB *p_cb)
void smp_collect_local_ble_address(UINT8 *le_addr, tSMP_CB *p_cb)
{
tBLE_ADDR_TYPE addr_type = 0;
BD_ADDR bda;
BD_ADDR bda = {0};
UINT8 *p = le_addr;
SMP_TRACE_DEBUG("%s\n", __func__);
@@ -1485,7 +1488,7 @@ void smp_collect_local_ble_address(UINT8 *le_addr, tSMP_CB *p_cb)
void smp_collect_peer_ble_address(UINT8 *le_addr, tSMP_CB *p_cb)
{
tBLE_ADDR_TYPE addr_type = 0;
BD_ADDR bda;
BD_ADDR bda = {0};
UINT8 *p = le_addr;
SMP_TRACE_DEBUG("%s\n", __func__);
@@ -1574,8 +1577,8 @@ void smp_save_secure_connections_long_term_key(tSMP_CB *p_cb)
*******************************************************************************/
BOOLEAN smp_calculate_f5_mackey_and_long_term_key(tSMP_CB *p_cb)
{
UINT8 a[7];
UINT8 b[7];
UINT8 a[7] = {0};
UINT8 b[7] = {0};
UINT8 *p_na;
UINT8 *p_nb;