summaryrefslogtreecommitdiffstats
path: root/stack/l2cap
diff options
context:
space:
mode:
authorSatya Calloji <satyac@broadcom.com>2015-03-06 10:38:22 -0800
committerAndre Eisenbach <eisenbach@google.com>2015-04-13 00:09:06 -0700
commit444a8da807abaf5f9e813ce70c56a79160495fb3 (patch)
tree20a35a257203d1a87f34d887ffba13672af4288a /stack/l2cap
parent8372aa5fa535ee4f09c09981b6125b54ace31fe2 (diff)
downloadandroid_system_bt-444a8da807abaf5f9e813ce70c56a79160495fb3.tar.gz
android_system_bt-444a8da807abaf5f9e813ce70c56a79160495fb3.tar.bz2
android_system_bt-444a8da807abaf5f9e813ce70c56a79160495fb3.zip
LE Privacy 1.2 and LE secure connections
Bug: 19816438 Original author: Chaojing Sun <cjsun@broadcom.com> Change-Id: I5951f4d4e038f8348a62aa6d19b2111bae0b3ecc
Diffstat (limited to 'stack/l2cap')
-rw-r--r--stack/l2cap/l2c_api.c30
-rw-r--r--stack/l2cap/l2c_ble.c49
-rw-r--r--stack/l2cap/l2c_link.c26
-rw-r--r--stack/l2cap/l2c_utils.c22
4 files changed, 65 insertions, 62 deletions
diff --git a/stack/l2cap/l2c_api.c b/stack/l2cap/l2c_api.c
index 839ad1b5e..3a8d5de48 100644
--- a/stack/l2cap/l2c_api.c
+++ b/stack/l2cap/l2c_api.c
@@ -833,17 +833,22 @@ BOOLEAN L2CA_SetIdleTimeout (UINT16 cid, UINT16 timeout, BOOLEAN is_global)
** NOTE This timeout applies to all logical channels active on the
** ACL link.
*******************************************************************************/
-BOOLEAN L2CA_SetIdleTimeoutByBdAddr(BD_ADDR bd_addr, UINT16 timeout)
+BOOLEAN L2CA_SetIdleTimeoutByBdAddr(BD_ADDR bd_addr, UINT16 timeout, tBT_TRANSPORT transport)
{
tL2C_LCB *p_lcb;
if (memcmp (BT_BD_ANY, bd_addr, BD_ADDR_LEN))
{
- p_lcb = l2cu_find_lcb_by_bd_addr( bd_addr, BT_TRANSPORT_BR_EDR);
+ p_lcb = l2cu_find_lcb_by_bd_addr( bd_addr, transport);
if ((p_lcb) && (p_lcb->in_use) && (p_lcb->link_state == LST_CONNECTED))
+ {
p_lcb->idle_timeout = timeout;
+
+ if (!p_lcb->ccb_queue.p_first_ccb)
+ l2cu_no_dynamic_ccbs (p_lcb);
+ }
else
- return (FALSE);
+ return FALSE;
}
else
{
@@ -855,11 +860,14 @@ BOOLEAN L2CA_SetIdleTimeoutByBdAddr(BD_ADDR bd_addr, UINT16 timeout)
if ((p_lcb->in_use) && (p_lcb->link_state == LST_CONNECTED))
{
p_lcb->idle_timeout = timeout;
+
+ if (!p_lcb->ccb_queue.p_first_ccb)
+ l2cu_no_dynamic_ccbs (p_lcb);
}
}
}
- return (TRUE);
+ return TRUE;
}
/*******************************************************************************
@@ -1639,18 +1647,6 @@ BOOLEAN L2CA_RemoveFixedChnl (UINT16 fixed_cid, BD_ADDR rem_bda)
p_lcb->p_fixed_ccbs[fixed_cid - L2CAP_FIRST_FIXED_CHNL] = NULL;
p_lcb->disc_reason = HCI_ERR_CONN_CAUSE_LOCAL_HOST;
-#if BLE_INCLUDED == TRUE
- /* retain the link for a few more seconds after SMP pairing is done, since Android
- platformalways do service discovery after pairing complete. This way would avoid
- the link down (pairing is complete) and an immediate reconnection for service
- discovery. Some devices do not do auto advertising when link is dropped, thus fail
- the second connection and service discovery.
- BEFORE :if ((fixed_cid == L2CAP_ATT_CID || fixed_cid == L2CAP_SMP_CID)
- && !p_lcb->ccb_queue.p_first_ccb)*/
- if ((fixed_cid == L2CAP_ATT_CID ) && !p_lcb->ccb_queue.p_first_ccb)
- p_lcb->idle_timeout = 0;
-#endif
-
l2cu_release_ccb (p_ccb);
return (TRUE);
@@ -1700,7 +1696,7 @@ BOOLEAN L2CA_SetFixedChannelTout (BD_ADDR rem_bda, UINT16 fixed_cid, UINT16 idle
l2cu_no_dynamic_ccbs (p_lcb);
}
- return (TRUE);
+ return TRUE;
}
#endif /* #if (L2CAP_NUM_FIXED_CHNLS > 0) */
diff --git a/stack/l2cap/l2c_ble.c b/stack/l2cap/l2c_ble.c
index a2b0a75c9..94ddf4268 100644
--- a/stack/l2cap/l2c_ble.c
+++ b/stack/l2cap/l2c_ble.c
@@ -35,7 +35,6 @@
#if (BLE_INCLUDED == TRUE)
static void l2cble_start_conn_update (tL2C_LCB *p_lcb);
-#include "vendor_ble.h"
/*******************************************************************************
**
** Function L2CA_CancelBleConnectReq
@@ -463,6 +462,8 @@ void l2cble_advertiser_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE typ
void l2cble_conn_comp(UINT16 handle, UINT8 role, BD_ADDR bda, tBLE_ADDR_TYPE type,
UINT16 conn_interval, UINT16 conn_latency, UINT16 conn_timeout)
{
+ btm_ble_update_link_topology_mask(role, TRUE);
+
if (role == HCI_ROLE_MASTER)
{
l2cble_scanner_conn_comp(handle, bda, type, conn_interval, conn_latency, conn_timeout);
@@ -688,12 +689,13 @@ void l2cble_process_sig_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len)
*******************************************************************************/
BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb)
{
- tBTM_SEC_DEV_REC *p_dev_rec = btm_find_or_alloc_dev (p_lcb->remote_bd_addr);
- tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb;
- UINT16 scan_int, scan_win;
- BD_ADDR init_addr;
- UINT8 init_addr_type = BLE_ADDR_PUBLIC,
- own_addr_type = BLE_ADDR_PUBLIC;
+ tBTM_SEC_DEV_REC *p_dev_rec = btm_find_or_alloc_dev (p_lcb->remote_bd_addr);
+ tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb;
+ UINT16 scan_int;
+ UINT16 scan_win;
+ BD_ADDR peer_addr;
+ UINT8 peer_addr_type = BLE_ADDR_PUBLIC;
+ UINT8 own_addr_type = BLE_ADDR_PUBLIC;
/* There can be only one BLE connection request outstanding at a time */
if (p_dev_rec == NULL)
@@ -705,22 +707,21 @@ BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb)
scan_int = (p_cb->scan_int == BTM_BLE_CONN_PARAM_UNDEF) ? BTM_BLE_SCAN_FAST_INT : p_cb->scan_int;
scan_win = (p_cb->scan_win == BTM_BLE_CONN_PARAM_UNDEF) ? BTM_BLE_SCAN_FAST_WIN : p_cb->scan_win;
- init_addr_type = p_lcb->ble_addr_type;
- memcpy(init_addr, p_lcb->remote_bd_addr, BD_ADDR_LEN);
+ peer_addr_type = p_lcb->ble_addr_type;
+ memcpy(peer_addr, p_lcb->remote_bd_addr, BD_ADDR_LEN);
-#if BLE_PRIVACY_SPT == TRUE
- /* if RPA offloading supported */
- if (btm_ble_vendor_irk_list_load_dev(p_dev_rec))
- btm_random_pseudo_to_public(init_addr, &init_addr_type);
- /* otherwise, if remote is RPA enabled, use latest RPA */
- else if (p_dev_rec->ble.active_addr_type == BTM_BLE_ADDR_RRA)
+#if ( (defined BLE_PRIVACY_SPT) && (BLE_PRIVACY_SPT == TRUE))
+ own_addr_type = btm_cb.ble_ctr_cb.privacy_mode ? BLE_ADDR_RANDOM : BLE_ADDR_PUBLIC;
+ if (p_dev_rec->ble.in_controller_list & BTM_RESOLVING_LIST_BIT)
{
- init_addr_type = BLE_ADDR_RANDOM;
- memcpy(init_addr, p_dev_rec->ble.cur_rand_addr, BD_ADDR_LEN);
+ if (btm_cb.ble_ctr_cb.privacy_mode >= BTM_PRIVACY_1_2)
+ own_addr_type |= BLE_ADDR_TYPE_ID_BIT;
+
+ btm_ble_enable_resolving_list();
+ btm_random_pseudo_to_identity_addr(peer_addr, &peer_addr_type);
}
- /* if privacy is on and current do not consider using reconnection address */
- if (btm_cb.ble_ctr_cb.privacy ) /* && p_dev_rec->ble.use_reconn_addr */
- own_addr_type = BLE_ADDR_RANDOM;
+ else
+ btm_ble_disable_resolving_list();
#endif
if (!btm_ble_topology_check(BTM_BLE_STATE_INIT))
@@ -733,8 +734,8 @@ BOOLEAN l2cble_init_direct_conn (tL2C_LCB *p_lcb)
if (!btsnd_hcic_ble_create_ll_conn (scan_int,/* UINT16 scan_int */
scan_win, /* UINT16 scan_win */
FALSE, /* UINT8 white_list */
- init_addr_type, /* UINT8 addr_type_peer */
- init_addr, /* BD_ADDR bda_peer */
+ peer_addr_type, /* UINT8 addr_type_peer */
+ peer_addr, /* BD_ADDR bda_peer */
own_addr_type, /* UINT8 addr_type_own */
(UINT16) ((p_dev_rec->conn_params.min_conn_int != BTM_BLE_CONN_PARAM_UNDEF) ?
p_dev_rec->conn_params.min_conn_int : BTM_BLE_CONN_INT_MIN_DEF), /* UINT16 conn_int_min */
@@ -879,7 +880,7 @@ void l2c_ble_link_adjust_allocation (void)
if (num_lowpri_links > low_quota)
{
l2cb.ble_round_robin_quota = low_quota;
- qq = qq_remainder = 1;
+ qq = qq_remainder = 0;
}
/* If each low priority link can have at least one buffer */
else if (num_lowpri_links > 0)
@@ -894,7 +895,7 @@ void l2c_ble_link_adjust_allocation (void)
{
l2cb.ble_round_robin_quota = 0;
l2cb.ble_round_robin_unacked = 0;
- qq = qq_remainder = 1;
+ qq = qq_remainder = 0;
}
L2CAP_TRACE_EVENT ("l2c_ble_link_adjust_allocation num_hipri: %u num_lowpri: %u low_quota: %u round_robin_quota: %u qq: %u",
num_hipri_links, num_lowpri_links, low_quota,
diff --git a/stack/l2cap/l2c_link.c b/stack/l2cap/l2c_link.c
index 836f4ba54..fa2fcce52 100644
--- a/stack/l2cap/l2c_link.c
+++ b/stack/l2cap/l2c_link.c
@@ -385,6 +385,11 @@ BOOLEAN l2c_link_hci_disc_comp (UINT16 handle, UINT8 reason)
/* Just in case app decides to try again in the callback context */
p_lcb->link_state = LST_DISCONNECTING;
+#if (BLE_INCLUDED == TRUE)
+ /* Check for BLE and handle that differently */
+ if (p_lcb->transport == BT_TRANSPORT_LE)
+ btm_ble_update_link_topology_mask(p_lcb->link_role, FALSE);
+#endif
/* Link is disconnected. For all channels, send the event through */
/* their FSMs. The CCBs should remove themselves from the LCB */
for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; )
@@ -1142,20 +1147,17 @@ void l2c_link_check_send_pkts (tL2C_LCB *p_lcb, tL2C_CCB *p_ccb, BT_HDR *p_buf)
for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++)
{
/* If controller window is full, nothing to do */
+ if (((l2cb.controller_xmit_window == 0 ||
+ (l2cb.round_robin_unacked >= l2cb.round_robin_quota))
#if (BLE_INCLUDED == TRUE)
- if ( (l2cb.controller_xmit_window == 0
- && (p_lcb->transport == BT_TRANSPORT_BR_EDR))
- || (p_lcb->transport == BT_TRANSPORT_LE
- && l2cb.controller_le_xmit_window == 0 )
- || (l2cb.round_robin_unacked >= l2cb.round_robin_quota
- && (p_lcb->transport == BT_TRANSPORT_BR_EDR))
- || ((p_lcb->transport == BT_TRANSPORT_LE)
- && (l2cb.ble_round_robin_unacked >= l2cb.ble_round_robin_quota)))
-#else
- if ((l2cb.controller_xmit_window == 0)
- || (l2cb.round_robin_unacked >= l2cb.round_robin_quota))
+ && (p_lcb->transport == BT_TRANSPORT_BR_EDR)
#endif
- break;
+ )
+ || (p_lcb->transport == BT_TRANSPORT_LE &&
+ (l2cb.ble_round_robin_unacked >= l2cb.ble_round_robin_quota ||
+ l2cb.controller_le_xmit_window == 0 )))
+ break;
+
/* Check for wraparound */
if (p_lcb == &l2cb.lcb_pool[MAX_L2CAP_LINKS])
diff --git a/stack/l2cap/l2c_utils.c b/stack/l2cap/l2c_utils.c
index 00ff2e7b5..d3ee908f2 100644
--- a/stack/l2cap/l2c_utils.c
+++ b/stack/l2cap/l2c_utils.c
@@ -2815,13 +2815,15 @@ void l2cu_no_dynamic_ccbs (tL2C_LCB *p_lcb)
void l2cu_process_fixed_chnl_resp (tL2C_LCB *p_lcb)
{
#if (BLE_INCLUDED == TRUE)
- /* always exclude LE fixed channel on BR/EDR fix channel capability */
- if (p_lcb->transport == BT_TRANSPORT_BR_EDR)
- p_lcb->peer_chnl_mask[0] &= ~(L2CAP_FIXED_CHNL_ATT_BIT| \
- L2CAP_FIXED_CHNL_BLE_SIG_BIT| \
- L2CAP_FIXED_CHNL_SMP_BIT);
- else
- p_lcb->peer_chnl_mask[0] = l2cb.l2c_ble_fixed_chnls_mask;
+ if (p_lcb->transport == BT_TRANSPORT_BR_EDR)
+ {
+ /* ignore all not assigned BR/EDR channels */
+ p_lcb->peer_chnl_mask[0] &= (L2CAP_FIXED_CHNL_SIG_BIT| \
+ L2CAP_FIXED_CHNL_CNCTLESS_BIT| \
+ L2CAP_FIXED_CHNL_SMP_BR_BIT);
+ }
+ else
+ p_lcb->peer_chnl_mask[0] = l2cb.l2c_ble_fixed_chnls_mask;
#endif
/* Tell all registered fixed channels about the connection */
@@ -3305,6 +3307,10 @@ BT_HDR *l2cu_get_next_buffer_to_send (tL2C_LCB *p_lcb)
L2CAP_TRACE_ERROR("l2cu_get_buffer_to_send: No data to be sent");
return (NULL);
}
+ /* send tx complete */
+ if (l2cb.fixed_reg[xx].pL2CA_FixedTxComplete_Cb)
+ (*l2cb.fixed_reg[xx].pL2CA_FixedTxComplete_Cb)(p_ccb->local_cid, 1);
+
l2cu_check_channel_congestion (p_ccb);
l2cu_set_acl_hci_header (p_buf, p_ccb);
return (p_buf);
@@ -3433,9 +3439,7 @@ void l2cu_check_channel_congestion (tL2C_CCB *p_ccb)
q_count += p_ccb->p_lcb->ucd_out_sec_pending_q.count;
}
#endif
-
/* If the CCB queue limit is subject to a quota, check for congestion */
-
/* if this channel has outgoing traffic */
if (p_ccb->buff_quota != 0)
{