mirror of
https://github.com/espressif/esp-idf.git
synced 2026-09-22 13:01:16 +03:00
fix(ble/bluedroid): clean up LE CoC connect on CCB alloc failure
(cherry picked from commit 4fd1ebb4a9)
Co-authored-by: zhiweijian <zhiweijian@espressif.com>
This commit is contained in:
@@ -842,6 +842,8 @@ extern void l2c_fcr_free_timer (tL2C_CCB *p_ccb);
|
||||
*/
|
||||
#if (BLE_INCLUDED == TRUE)
|
||||
extern BOOLEAN l2cble_create_conn (tL2C_LCB *p_lcb);
|
||||
extern void l2cble_remove_pending_direct_conn (tL2C_LCB *p_lcb);
|
||||
extern void l2cble_cleanup_alloc_ccb_failed_conn (tL2C_LCB *p_lcb);
|
||||
extern void l2cble_process_sig_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len);
|
||||
extern void l2cble_conn_comp (UINT16 handle, UINT8 role, BD_ADDR bda, tBLE_ADDR_TYPE type,
|
||||
UINT16 conn_interval, UINT16 conn_latency, UINT16 conn_timeout);
|
||||
|
||||
@@ -1476,17 +1476,22 @@ UINT16 L2CA_ConnectLECocReq(UINT16 psm, BD_ADDR p_bd_addr, tL2CAP_LE_CFG_INFO *p
|
||||
}
|
||||
|
||||
/* First, see if we already have a le link to the remote */
|
||||
BOOLEAN lcb_allocated = FALSE;
|
||||
tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr(p_bd_addr, BT_TRANSPORT_LE);
|
||||
if (p_lcb == NULL)
|
||||
{
|
||||
/* No link. Get an LCB and start link establishment */
|
||||
p_lcb = l2cu_allocate_lcb(p_bd_addr, FALSE, BT_TRANSPORT_LE);
|
||||
if ((p_lcb == NULL)
|
||||
/* currently use BR/EDR for ERTM mode l2cap connection */
|
||||
|| (l2cu_create_conn(p_lcb, BT_TRANSPORT_LE) == FALSE) )
|
||||
{
|
||||
L2CAP_TRACE_WARNING("%s conn not started for PSM: 0x%04x p_lcb: 0x%p",
|
||||
if (p_lcb == NULL) {
|
||||
L2CAP_TRACE_WARNING("%s conn not started for PSM: 0x%04x p_lcb: NULL",
|
||||
__func__, psm);
|
||||
return 0;
|
||||
}
|
||||
lcb_allocated = TRUE;
|
||||
if (l2cu_create_conn(p_lcb, BT_TRANSPORT_LE) == FALSE) {
|
||||
L2CAP_TRACE_WARNING("%s conn not started for PSM: 0x%04x p_lcb: %p",
|
||||
__func__, psm, p_lcb);
|
||||
l2cu_release_lcb(p_lcb);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1496,6 +1501,9 @@ UINT16 L2CA_ConnectLECocReq(UINT16 psm, BD_ADDR p_bd_addr, tL2CAP_LE_CFG_INFO *p
|
||||
if (p_ccb == NULL)
|
||||
{
|
||||
L2CAP_TRACE_WARNING("%s no CCB, PSM: 0x%04x", __func__, psm);
|
||||
if (lcb_allocated) {
|
||||
l2cble_cleanup_alloc_ccb_failed_conn(p_lcb);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -891,6 +891,11 @@ void l2cble_process_sig_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
|
||||
STREAM_TO_UINT16(credits, p);
|
||||
L2CAP_TRACE_DEBUG("%s spsm %x, scid %x", __func__, spsm, scid);
|
||||
|
||||
if (mtu < L2CAP_LE_MIN_MTU || mps < L2CAP_LE_MIN_MPS || mps > L2CAP_LE_MAX_MPS) {
|
||||
l2cu_reject_ble_connection(p_lcb, id, L2CAP_LE_RESULT_INVALID_PARAMETERS);
|
||||
break;
|
||||
}
|
||||
|
||||
p_ccb = l2cu_find_ccb_by_remote_cid(p_lcb, scid);
|
||||
if (p_ccb) {
|
||||
l2cu_reject_ble_connection(p_lcb, id, L2CAP_LE_RESULT_SOURCE_CID_ALREADY_ALLOCATED);
|
||||
@@ -912,12 +917,14 @@ void l2cble_process_sig_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
|
||||
p_ccb->remote_id = id;
|
||||
p_ccb->p_rcb = p_rcb;
|
||||
p_ccb->remote_cid = scid;
|
||||
p_ccb->local_conn_cfg.mtu = mtu;
|
||||
p_ccb->local_conn_cfg.mps = controller_get_interface()->get_acl_data_size_ble();
|
||||
p_ccb->local_conn_cfg.credits = credits;
|
||||
/* Peer request fields describe peer receive capability */
|
||||
p_ccb->peer_conn_cfg.mtu = mtu;
|
||||
p_ccb->peer_conn_cfg.mps = mps;
|
||||
p_ccb->peer_conn_cfg.credits = credits;
|
||||
/* Response must advertise our receive capability, not peer's */
|
||||
p_ccb->local_conn_cfg.mtu = L2CAP_LE_DEFAULT_MTU;
|
||||
p_ccb->local_conn_cfg.mps = controller_get_interface()->get_acl_data_size_ble();
|
||||
p_ccb->local_conn_cfg.credits = L2CAP_LE_DEFAULT_CREDIT;
|
||||
|
||||
l2cu_send_peer_ble_credit_based_conn_res(p_ccb, L2CAP_LE_RESULT_CONN_OK);
|
||||
#else
|
||||
@@ -1052,6 +1059,17 @@ void l2cble_process_sig_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
|
||||
}
|
||||
}
|
||||
|
||||
#if (BLE_50_FEATURE_SUPPORT == TRUE)
|
||||
static void l2cble_abort_direct_conn_init(tL2C_LCB *p_lcb)
|
||||
{
|
||||
btu_stop_timer(&p_lcb->timer_entry);
|
||||
l2cb.is_ble_connecting = FALSE;
|
||||
memset(l2cb.ble_connecting_bda, 0, BD_ADDR_LEN);
|
||||
btm_ble_set_conn_st(BLE_CONN_IDLE);
|
||||
p_lcb->link_state = LST_DISCONNECTED;
|
||||
}
|
||||
#endif // (BLE_50_FEATURE_SUPPORT == TRUE)
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function l2cble_init_direct_conn
|
||||
@@ -1060,6 +1078,9 @@ void l2cble_process_sig_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
|
||||
**
|
||||
** Returns TRUE connection initiated, FALSE otherwise.
|
||||
**
|
||||
** Note On failure the LCB is not released; the caller must call
|
||||
** l2cu_release_lcb (see l2cu_create_conn contract in l2c_link.c).
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb)
|
||||
{
|
||||
@@ -1147,7 +1168,6 @@ BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb)
|
||||
|
||||
#if (BLE_TOPOLOGY_CHECK == TRUE)
|
||||
if (!btm_ble_topology_check(BTM_BLE_STATE_INIT)) {
|
||||
l2cu_release_lcb (p_lcb);
|
||||
L2CAP_TRACE_ERROR("initiate direct connection fail, topology limitation");
|
||||
return FALSE;
|
||||
}
|
||||
@@ -1212,7 +1232,6 @@ BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb)
|
||||
p_dev_rec->conn_params.min_ce_len : BLE_CE_LEN_MIN), /* UINT16 min_ce_len */
|
||||
(UINT16) ((p_dev_rec->conn_params.max_ce_len != BTM_BLE_CONN_PARAM_UNDEF) ?
|
||||
p_dev_rec->conn_params.max_ce_len : BLE_CE_LEN_MIN) /* UINT16 max_ce_len */)) {
|
||||
l2cu_release_lcb (p_lcb);
|
||||
L2CAP_TRACE_ERROR("initiate direct connection fail, no resources");
|
||||
return (FALSE);
|
||||
} else {
|
||||
@@ -1270,10 +1289,7 @@ 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);
|
||||
l2cble_abort_direct_conn_init(p_lcb);
|
||||
L2CAP_TRACE_ERROR("initiate pawr sync connection failed, no resources");
|
||||
return (FALSE);
|
||||
}
|
||||
@@ -1281,16 +1297,12 @@ BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb)
|
||||
#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);
|
||||
l2cble_abort_direct_conn_init(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)
|
||||
@@ -1329,6 +1341,50 @@ BOOLEAN l2cble_create_conn (tL2C_LCB *p_lcb)
|
||||
return rt;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function l2cble_cleanup_alloc_ccb_failed_conn
|
||||
**
|
||||
** Description Clean up after LE CoC setup fails to allocate a CCB. If a
|
||||
** direct HCI connection is in progress, cancel it and update
|
||||
** BTM state; otherwise drop a queued direct-connect request.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void l2cble_cleanup_alloc_ccb_failed_conn (tL2C_LCB *p_lcb)
|
||||
{
|
||||
if (p_lcb == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (p_lcb->link_state == LST_CONNECTING) {
|
||||
if (!L2CA_CancelBleConnectReq(p_lcb->remote_bd_addr)) {
|
||||
L2CAP_TRACE_ERROR("%s: cancel direct connect failed", __func__);
|
||||
l2cu_release_lcb(p_lcb);
|
||||
memset(l2cb.ble_connecting_bda, 0, BD_ADDR_LEN);
|
||||
btm_ble_set_conn_st(BLE_CONN_IDLE);
|
||||
}
|
||||
} else {
|
||||
l2cble_remove_pending_direct_conn(p_lcb);
|
||||
l2cu_release_lcb(p_lcb);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function l2cble_remove_pending_direct_conn
|
||||
**
|
||||
** Description Drop a queued direct-connection attempt for this LCB.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void l2cble_remove_pending_direct_conn (tL2C_LCB *p_lcb)
|
||||
{
|
||||
btm_ble_remove_direct_conn_req(p_lcb);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function l2c_link_processs_ble_num_bufs
|
||||
|
||||
Reference in New Issue
Block a user