diff options
author | Satya Calloji <satyac@broadcom.com> | 2015-03-06 10:38:22 -0800 |
---|---|---|
committer | Andre Eisenbach <eisenbach@google.com> | 2015-04-13 00:09:06 -0700 |
commit | 444a8da807abaf5f9e813ce70c56a79160495fb3 (patch) | |
tree | 20a35a257203d1a87f34d887ffba13672af4288a /stack/l2cap | |
parent | 8372aa5fa535ee4f09c09981b6125b54ace31fe2 (diff) | |
download | android_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.c | 30 | ||||
-rw-r--r-- | stack/l2cap/l2c_ble.c | 49 | ||||
-rw-r--r-- | stack/l2cap/l2c_link.c | 26 | ||||
-rw-r--r-- | stack/l2cap/l2c_utils.c | 22 |
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) { |