Commit 7ae25156 authored by Prerepa Viswanadham's avatar Prerepa Viswanadham
Browse files

Avoid premature LE connection notifaction to app

To avoid premature connection notification to app, always wait for
LE read remote feature complete with success before the connection
event is sent to application.

This patch also deprecates the BTA_SKIP_BLE_READ_REMOTE_FEAT flag.
Since the remote feature request is now serialized and start encryption
won't be called until the connection is up, this flag is no longer
necessary and interferes with the new behaviour.

This is an extension of previous CL

Bug: 17326529
Change-Id: Icfd4c5dfdd9f89d1318ef429e132eb005abb1f64
parent 976990f8
......@@ -947,15 +947,14 @@ tBTA_GATTC_CLCB * bta_gattc_find_int_disconn_clcb(tBTA_GATTC_DATA *p_msg)
tGATT_DISCONN_REASON reason = p_msg->int_conn.reason;
bta_gattc_conn_dealloc(p_msg->int_conn.remote_bda);
/* connection attempt timeout, send connection callback event */
if (reason == GATT_CONN_CANCEL || reason == GATT_CONN_L2C_FAILURE
|| reason == GATT_CONN_FAIL_ESTABLISH)
if ((p_clcb = bta_gattc_find_clcb_by_conn_id(p_msg->int_conn.hdr.layer_specific)) == NULL)
{
/* connection attempt failed, send connection callback event */
p_clcb = bta_gattc_find_clcb_by_cif(p_msg->int_conn.client_if,
p_msg->int_conn.remote_bda,
p_msg->int_conn.transport);
}
else if ((p_clcb = bta_gattc_find_clcb_by_conn_id(p_msg->int_conn.hdr.layer_specific)) == NULL)
if (p_clcb == NULL)
{
APPL_TRACE_DEBUG(" disconnection ID: [%d] not used by BTA",
p_msg->int_conn.hdr.layer_specific);
......
......@@ -260,11 +260,6 @@
#define BTA_HOST_INTERLEAVE_SEARCH FALSE
#endif
/* This feature is used to skip query of ble read remote features*/
#ifndef BTA_SKIP_BLE_READ_REMOTE_FEAT
#define BTA_SKIP_BLE_READ_REMOTE_FEAT FALSE
#endif
#ifndef BT_TRACE_PROTOCOL
#define BT_TRACE_PROTOCOL TRUE
#endif
......
......@@ -374,15 +374,15 @@ void btm_acl_created (BD_ADDR bda, DEV_CLASS dc, BD_NAME bdn,
&p->active_remote_addr_type);
#endif
#if (!defined(BTA_SKIP_BLE_READ_REMOTE_FEAT) || BTA_SKIP_BLE_READ_REMOTE_FEAT == FALSE)
if (HCI_LE_SLAVE_INIT_FEAT_EXC_SUPPORTED(btm_cb.devcb.local_le_features)
|| link_role == HCI_ROLE_MASTER)
{
btsnd_hcic_ble_read_remote_feat(p->hci_handle);
}
else
#endif
btm_establish_continue(p);
{
btm_establish_continue(p);
}
}
else
#endif
......
......@@ -3009,8 +3009,7 @@ void btm_ble_read_remote_features_complete(UINT8 *p)
if ((p_acl_cb->in_use) && (p_acl_cb->hci_handle == handle))
{
STREAM_TO_ARRAY(p_acl_cb->peer_le_features, p, BD_FEATURES_LEN);
/* notify link up here */
btm_establish_continue(p_acl_cb);
/*notify link up here */
l2cble_notify_le_connection (p_acl_cb->remote_addr);
break;
}
......
......@@ -280,9 +280,16 @@ UINT16 L2CA_GetDisconnectReason (BD_ADDR remote_bda, tBT_TRANSPORT transport)
void l2cble_notify_le_connection (BD_ADDR bda)
{
tL2C_LCB *p_lcb = l2cu_find_lcb_by_bd_addr (bda, BT_TRANSPORT_LE);
tACL_CONN *p_acl = btm_bda_to_acl(bda, BT_TRANSPORT_LE) ;
if (p_lcb != NULL)
if (p_lcb != NULL && p_acl != NULL && p_lcb->link_state != LST_CONNECTED)
{
/* update link status */
btm_establish_continue(p_acl);
/* update l2cap link status and send callback */
p_lcb->link_state = LST_CONNECTED;
l2cu_process_fixed_chnl_resp (p_lcb);
}
}
/*******************************************************************************
......@@ -340,7 +347,6 @@ void l2cble_scanner_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE type,
p_lcb->handle = handle;
/* Connected OK. Change state to connected, we were scanning so we are master */
p_lcb->link_state = LST_CONNECTED;
p_lcb->link_role = HCI_ROLE_MASTER;
p_lcb->transport = BT_TRANSPORT_LE;
......@@ -373,15 +379,8 @@ void l2cble_scanner_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE type,
/* Tell BTM Acl management about the link */
btm_acl_created (bda, NULL, p_dev_rec->sec_bd_name, handle, p_lcb->link_role, BT_TRANSPORT_LE);
#if(defined(BTA_SKIP_BLE_READ_REMOTE_FEAT) && BTA_SKIP_BLE_READ_REMOTE_FEAT == TRUE)
{
l2cu_process_fixed_chnl_resp (p_lcb);
}
#endif
p_lcb->peer_chnl_mask[0] = L2CAP_FIXED_CHNL_ATT_BIT | L2CAP_FIXED_CHNL_BLE_SIG_BIT | L2CAP_FIXED_CHNL_SMP_BIT;
btm_ble_set_conn_st(BLE_CONN_IDLE);
}
......@@ -434,7 +433,6 @@ void l2cble_advertiser_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE typ
p_lcb->handle = handle;
/* Connected OK. Change state to connected, we were advertising, so we are slave */
p_lcb->link_state = LST_CONNECTED;
p_lcb->link_role = HCI_ROLE_SLAVE;
p_lcb->transport = BT_TRANSPORT_LE;
......@@ -445,16 +443,11 @@ void l2cble_advertiser_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE typ
p_lcb->peer_chnl_mask[0] = L2CAP_FIXED_CHNL_ATT_BIT | L2CAP_FIXED_CHNL_BLE_SIG_BIT | L2CAP_FIXED_CHNL_SMP_BIT;
#if (defined(BTA_SKIP_BLE_READ_REMOTE_FEAT) && BTA_SKIP_BLE_READ_REMOTE_FEAT == TRUE)
{
l2cu_process_fixed_chnl_resp (p_lcb);
}
#else
if (!HCI_LE_SLAVE_INIT_FEAT_EXC_SUPPORTED(btm_cb.devcb.local_le_features))
{
p_lcb->link_state = LST_CONNECTED;
l2cu_process_fixed_chnl_resp (p_lcb);
}
#endif
/* when adv and initiating are both active, cancel the direct connection */
if (l2cb.is_ble_connecting && memcmp(bda, l2cb.ble_connecting_bda, BD_ADDR_LEN) == 0)
......
......@@ -418,38 +418,40 @@ BOOLEAN l2c_link_hci_disc_comp (UINT16 handle, UINT8 reason)
*/
if (p_lcb->ccb_queue.p_first_ccb != NULL || p_lcb->p_pending_ccb)
{
#if (L2CAP_NUM_FIXED_CHNLS > 0)
/* If we are going to re-use the LCB without dropping it, release all fixed channels here */
int xx;
for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++)
L2CAP_TRACE_DEBUG("l2c_link_hci_disc_comp: Restarting pending ACL request");
#if BLE_INCLUDED == TRUE
/* for LE link, always drop and re-open to ensure to get LE remote feature */
if (p_lcb->transport == BT_TRANSPORT_LE)
{
if (p_lcb->p_fixed_ccbs[xx] && p_lcb->p_fixed_ccbs[xx] != p_lcb->p_pending_ccb)
{
l2cu_release_lcb (p_lcb);
p_lcb->in_use = TRUE;
transport = BT_TRANSPORT_LE;
}
else
#endif
{
#if (L2CAP_NUM_FIXED_CHNLS > 0)
/* If we are going to re-use the LCB without dropping it, release all fixed channels
here */
int xx;
for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++)
{
if (p_lcb->p_fixed_ccbs[xx] && p_lcb->p_fixed_ccbs[xx] != p_lcb->p_pending_ccb)
{
#if BLE_INCLUDED == TRUE
(*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE,
p_lcb->disc_reason, p_lcb->transport);
(*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE,
p_lcb->disc_reason, p_lcb->transport);
#else
(*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE,
p_lcb->disc_reason, BT_TRANSPORT_BR_EDR);
(*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE,
p_lcb->disc_reason, BT_TRANSPORT_BR_EDR);
#endif
l2cu_release_ccb (p_lcb->p_fixed_ccbs[xx]);
p_lcb->p_fixed_ccbs[xx] = NULL;
}
#if BLE_INCLUDED == TRUE
else if (p_lcb->p_fixed_ccbs[xx] && p_lcb->p_fixed_ccbs[xx] ==
p_lcb->p_pending_ccb)
{
if (p_lcb->p_fixed_ccbs[xx]->local_cid >= L2CAP_ATT_CID &&
p_lcb->p_fixed_ccbs[xx]->local_cid <= L2CAP_SMP_CID)
transport = BT_TRANSPORT_LE;
}
#endif
}
}
}
#endif
L2CAP_TRACE_DEBUG("l2c_link_hci_disc_comp: Restarting pending ACL request");
}
if (l2cu_create_conn(p_lcb, transport))
lcb_is_free = FALSE; /* still using this lcb */
}
......
......@@ -267,8 +267,12 @@ void l2c_rcv_acl_data (BT_HDR *p_msg)
(l2cb.fixed_reg[rcv_cid - L2CAP_FIRST_FIXED_CHNL].pL2CA_FixedData_Cb != NULL) )
{
/* If no CCB for this channel, allocate one */
if (l2cu_initialize_fixed_ccb (p_lcb, rcv_cid, &l2cb.fixed_reg[rcv_cid - L2CAP_FIRST_FIXED_CHNL].fixed_chnl_opts))
if (p_lcb && l2cu_initialize_fixed_ccb (p_lcb, rcv_cid,
&l2cb.fixed_reg[rcv_cid - L2CAP_FIRST_FIXED_CHNL].fixed_chnl_opts))
{
#if(defined BLE_INCLUDED && (BLE_INCLUDED == TRUE))
l2cble_notify_le_connection(p_lcb->remote_bd_addr);
#endif
p_ccb = p_lcb->p_fixed_ccbs[rcv_cid - L2CAP_FIRST_FIXED_CHNL];
if (p_ccb->peer_cfg.fcr.mode != L2CAP_FCR_BASIC_MODE)
......
......@@ -132,6 +132,9 @@ void l2cu_release_lcb (tL2C_LCB *p_lcb)
p_lcb->in_use = FALSE;
p_lcb->is_bonding = FALSE;
#if (BLE_INCLUDED == TRUE)
btu_stop_timer(&p_lcb->conn_param_enb);
#endif
/* Stop timers */
btu_stop_timer (&p_lcb->timer_entry);
btu_stop_timer (&p_lcb->info_timer_entry);
......@@ -2899,13 +2902,16 @@ void l2cu_process_fixed_disc_cback (tL2C_LCB *p_lcb)
{
if (p_lcb->p_fixed_ccbs[xx])
{
l2cu_release_ccb (p_lcb->p_fixed_ccbs[xx]);
p_lcb->p_fixed_ccbs[xx] = NULL;
if (p_lcb->p_fixed_ccbs[xx] != p_lcb->p_pending_ccb)
{
l2cu_release_ccb (p_lcb->p_fixed_ccbs[xx]);
p_lcb->p_fixed_ccbs[xx] = NULL;
#if BLE_INCLUDED == TRUE
(*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, p_lcb->transport);
#else
(*l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb)(p_lcb->remote_bd_addr, FALSE, p_lcb->disc_reason, BT_TRANSPORT_BR_EDR);
#endif
}
}
else if ( (p_lcb->peer_chnl_mask[0] & (1 << (xx + L2CAP_FIRST_FIXED_CHNL)))
&& (l2cb.fixed_reg[xx].pL2CA_FixedConn_Cb != NULL) )
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment