Home | History | Annotate | Download | only in btm
      1 /******************************************************************************
      2  *
      3  *  Copyright 1999-2012 Broadcom Corporation
      4  *
      5  *  Licensed under the Apache License, Version 2.0 (the "License");
      6  *  you may not use this file except in compliance with the License.
      7  *  You may obtain a copy of the License at:
      8  *
      9  *  http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  *
     17  ******************************************************************************/
     18 
     19 /******************************************************************************
     20  *
     21  *  This file contains functions for BLE whitelist operation.
     22  *
     23  ******************************************************************************/
     24 
     25 #include <base/logging.h>
     26 #include <string.h>
     27 #include <unordered_map>
     28 
     29 #include "bt_types.h"
     30 #include "bt_utils.h"
     31 #include "btm_int.h"
     32 #include "btu.h"
     33 #include "device/include/controller.h"
     34 #include "hcimsgs.h"
     35 #include "l2c_int.h"
     36 #include "osi/include/allocator.h"
     37 #include "osi/include/osi.h"
     38 
     39 #ifndef BTM_BLE_SCAN_PARAM_TOUT
     40 #define BTM_BLE_SCAN_PARAM_TOUT 50 /* 50 seconds */
     41 #endif
     42 
     43 static void btm_suspend_wl_activity(tBTM_BLE_WL_STATE wl_state);
     44 static void btm_resume_wl_activity(tBTM_BLE_WL_STATE wl_state);
     45 
     46 // Unfortunately (for now?) we have to maintain a copy of the device whitelist
     47 // on the host to determine if a device is pending to be connected or not. This
     48 // controls whether the host should keep trying to scan for whitelisted
     49 // peripherals or not.
     50 // TODO: Move all of this to controller/le/background_list or similar?
     51 typedef struct background_connection_t {
     52   RawAddress address;
     53   uint8_t addr_type;
     54 
     55   bool in_controller_wl;
     56   uint8_t addr_type_in_wl;
     57 
     58   bool pending_removal;
     59 } background_connection_t;
     60 
     61 struct BgConnHash {
     62   bool operator()(const RawAddress& x) const {
     63     const uint8_t* a = x.address;
     64     return a[0] ^ (a[1] << 8) ^ (a[2] << 16) ^ (a[3] << 24) ^ a[4] ^
     65            (a[5] << 8);
     66   }
     67 };
     68 
     69 static std::unordered_map<RawAddress, background_connection_t, BgConnHash>
     70     background_connections;
     71 
     72 static void background_connection_add(uint8_t addr_type,
     73                                       const RawAddress& address) {
     74   auto map_iter = background_connections.find(address);
     75   if (map_iter == background_connections.end()) {
     76     background_connections[address] =
     77         background_connection_t{address, addr_type, false, 0, false};
     78   } else {
     79     background_connection_t* connection = &map_iter->second;
     80     connection->addr_type = addr_type;
     81     connection->pending_removal = false;
     82   }
     83 }
     84 
     85 static void background_connection_remove(const RawAddress& address) {
     86   auto map_iter = background_connections.find(address);
     87   if (map_iter != background_connections.end()) {
     88     if (map_iter->second.in_controller_wl) {
     89       map_iter->second.pending_removal = true;
     90     } else {
     91       background_connections.erase(map_iter);
     92     }
     93   }
     94 }
     95 
     96 static void background_connections_clear() { background_connections.clear(); }
     97 
     98 static bool background_connections_pending() {
     99   for (auto& map_el : background_connections) {
    100     background_connection_t* connection = &map_el.second;
    101     if (connection->pending_removal) continue;
    102     const bool connected =
    103         BTM_IsAclConnectionUp(connection->address, BT_TRANSPORT_LE);
    104     if (!connected) {
    105       return true;
    106     }
    107   }
    108   return false;
    109 }
    110 
    111 static int background_connections_count() {
    112   int count = 0;
    113   for (auto& map_el : background_connections) {
    114     if (!map_el.second.pending_removal) ++count;
    115   }
    116   return count;
    117 }
    118 
    119 /*******************************************************************************
    120  *
    121  * Function         btm_update_scanner_filter_policy
    122  *
    123  * Description      This function updates the filter policy of scanner
    124  ******************************************************************************/
    125 void btm_update_scanner_filter_policy(tBTM_BLE_SFP scan_policy) {
    126   tBTM_BLE_INQ_CB* p_inq = &btm_cb.ble_ctr_cb.inq_var;
    127 
    128   uint32_t scan_interval =
    129       !p_inq->scan_interval ? BTM_BLE_GAP_DISC_SCAN_INT : p_inq->scan_interval;
    130   uint32_t scan_window =
    131       !p_inq->scan_window ? BTM_BLE_GAP_DISC_SCAN_WIN : p_inq->scan_window;
    132 
    133   BTM_TRACE_EVENT("%s", __func__);
    134 
    135   p_inq->sfp = scan_policy;
    136   p_inq->scan_type = p_inq->scan_type == BTM_BLE_SCAN_MODE_NONE
    137                          ? BTM_BLE_SCAN_MODE_ACTI
    138                          : p_inq->scan_type;
    139 
    140   btm_send_hci_set_scan_params(
    141       p_inq->scan_type, (uint16_t)scan_interval, (uint16_t)scan_window,
    142       btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type, scan_policy);
    143 }
    144 
    145 /*******************************************************************************
    146  *
    147  * Function         btm_ble_bgconn_cancel_if_disconnected
    148  *
    149  * Description      If a device has been disconnected, it must be re-added to
    150  *                  the white list. If needed, this function cancels a pending
    151  *                  initiate command in order to trigger restart of the initiate
    152  *                  command which in turn updates the white list.
    153  *
    154  * Parameters       bd_addr: updated device
    155  *
    156  ******************************************************************************/
    157 void btm_ble_bgconn_cancel_if_disconnected(const RawAddress& bd_addr) {
    158   if (btm_cb.ble_ctr_cb.conn_state != BLE_BG_CONN) return;
    159 
    160   auto map_it = background_connections.find(bd_addr);
    161   if (map_it != background_connections.end()) {
    162     background_connection_t* connection = &map_it->second;
    163     if (!connection->in_controller_wl && !connection->pending_removal &&
    164         !BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_LE)) {
    165       btm_ble_start_auto_conn(false);
    166     }
    167   }
    168 }
    169 
    170 /*******************************************************************************
    171  *
    172  * Function         btm_add_dev_to_controller
    173  *
    174  * Description      This function load the device into controller white list
    175  ******************************************************************************/
    176 bool btm_add_dev_to_controller(bool to_add, const RawAddress& bd_addr) {
    177   tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr);
    178   bool started = false;
    179 
    180   if (p_dev_rec != NULL && p_dev_rec->device_type & BT_DEVICE_TYPE_BLE) {
    181     if (to_add) {
    182       if (p_dev_rec->ble.ble_addr_type == BLE_ADDR_PUBLIC ||
    183           !BTM_BLE_IS_RESOLVE_BDA(bd_addr)) {
    184         background_connection_add(p_dev_rec->ble.ble_addr_type, bd_addr);
    185         started = true;
    186         p_dev_rec->ble.in_controller_list |= BTM_WHITE_LIST_BIT;
    187       } else if (p_dev_rec->ble.static_addr != bd_addr &&
    188                  !p_dev_rec->ble.static_addr.IsEmpty()) {
    189         background_connection_add(p_dev_rec->ble.static_addr_type,
    190                                   p_dev_rec->ble.static_addr);
    191         started = true;
    192         p_dev_rec->ble.in_controller_list |= BTM_WHITE_LIST_BIT;
    193       }
    194     } else {
    195       if (p_dev_rec->ble.ble_addr_type == BLE_ADDR_PUBLIC ||
    196           !BTM_BLE_IS_RESOLVE_BDA(bd_addr)) {
    197         background_connection_remove(bd_addr);
    198         started = true;
    199       }
    200 
    201       if (!p_dev_rec->ble.static_addr.IsEmpty() &&
    202           p_dev_rec->ble.static_addr != bd_addr) {
    203         background_connection_remove(p_dev_rec->ble.static_addr);
    204         started = true;
    205       }
    206 
    207       p_dev_rec->ble.in_controller_list &= ~BTM_WHITE_LIST_BIT;
    208     }
    209   } else {
    210     /* not a known device, i.e. attempt to connect to device never seen before
    211      */
    212     started = true;
    213     if (to_add)
    214       background_connection_add(BLE_ADDR_PUBLIC, bd_addr);
    215     else
    216       background_connection_remove(bd_addr);
    217   }
    218 
    219   return started;
    220 }
    221 /*******************************************************************************
    222  *
    223  * Function         btm_execute_wl_dev_operation
    224  *
    225  * Description      execute the pending whitelist device operation (loading or
    226  *                                                                  removing)
    227  ******************************************************************************/
    228 bool btm_execute_wl_dev_operation(void) {
    229   // handle removals first to avoid filling up controller's white list
    230   for (auto map_it = background_connections.begin();
    231        map_it != background_connections.end();) {
    232     background_connection_t* connection = &map_it->second;
    233     if (connection->pending_removal) {
    234       btsnd_hcic_ble_remove_from_white_list(connection->addr_type_in_wl,
    235                                             connection->address);
    236       map_it = background_connections.erase(map_it);
    237     } else
    238       ++map_it;
    239   }
    240   for (auto& map_el : background_connections) {
    241     background_connection_t* connection = &map_el.second;
    242     const bool connected =
    243         BTM_IsAclConnectionUp(connection->address, BT_TRANSPORT_LE);
    244     if (!connection->in_controller_wl && !connected) {
    245       btsnd_hcic_ble_add_white_list(connection->addr_type, connection->address);
    246       connection->in_controller_wl = true;
    247       connection->addr_type_in_wl = connection->addr_type;
    248     } else if (connection->in_controller_wl && connected) {
    249       /* Bluetooth Core 4.2 as well as ESR08 disallows more than one
    250          connection between two LE addresses. Not all controllers handle this
    251          correctly, therefore we must make sure connected devices are not in
    252          the white list when bg connection attempt is active. */
    253       btsnd_hcic_ble_remove_from_white_list(connection->addr_type_in_wl,
    254                                             connection->address);
    255       connection->in_controller_wl = false;
    256     }
    257   }
    258   return true;
    259 }
    260 
    261 /*******************************************************************************
    262  *
    263  * Function         btm_update_dev_to_white_list
    264  *
    265  * Description      This function adds or removes a device into/from
    266  *                  the white list.
    267  *
    268  ******************************************************************************/
    269 bool btm_update_dev_to_white_list(bool to_add, const RawAddress& bd_addr) {
    270   tBTM_BLE_CB* p_cb = &btm_cb.ble_ctr_cb;
    271 
    272   if (to_add &&
    273       background_connections_count() ==
    274           controller_get_interface()->get_ble_white_list_size()) {
    275     BTM_TRACE_ERROR("%s Whitelist full, unable to add device", __func__);
    276     return false;
    277   }
    278 
    279   btm_suspend_wl_activity(p_cb->wl_state);
    280   btm_add_dev_to_controller(to_add, bd_addr);
    281   btm_resume_wl_activity(p_cb->wl_state);
    282   return true;
    283 }
    284 
    285 /*******************************************************************************
    286  *
    287  * Function         btm_ble_clear_white_list
    288  *
    289  * Description      This function clears the white list.
    290  *
    291  ******************************************************************************/
    292 void btm_ble_clear_white_list(void) {
    293   BTM_TRACE_EVENT("btm_ble_clear_white_list");
    294   btsnd_hcic_ble_clear_white_list();
    295   background_connections_clear();
    296 }
    297 
    298 /*******************************************************************************
    299  *
    300  * Function         btm_ble_clear_white_list_complete
    301  *
    302  * Description      Indicates white list cleared.
    303  *
    304  ******************************************************************************/
    305 void btm_ble_clear_white_list_complete(uint8_t* p_data,
    306                                        UNUSED_ATTR uint16_t evt_len) {
    307   uint8_t status;
    308 
    309   STREAM_TO_UINT8(status, p_data);
    310   BTM_TRACE_EVENT("%s status=%d", __func__, status);
    311 }
    312 
    313 /*******************************************************************************
    314  *
    315  * Function         btm_ble_white_list_init
    316  *
    317  * Description      Initialize white list size
    318  *
    319  ******************************************************************************/
    320 void btm_ble_white_list_init(uint8_t white_list_size) {
    321   BTM_TRACE_DEBUG("%s white_list_size = %d", __func__, white_list_size);
    322 }
    323 
    324 /*******************************************************************************
    325  *
    326  * Function         btm_ble_add_2_white_list_complete
    327  *
    328  * Description      White list element added
    329  *
    330  ******************************************************************************/
    331 void btm_ble_add_2_white_list_complete(uint8_t status) {
    332   BTM_TRACE_EVENT("%s status=%d", __func__, status);
    333 }
    334 
    335 /*******************************************************************************
    336  *
    337  * Function         btm_ble_remove_from_white_list_complete
    338  *
    339  * Description      White list element removal complete
    340  *
    341  ******************************************************************************/
    342 void btm_ble_remove_from_white_list_complete(uint8_t* p,
    343                                              UNUSED_ATTR uint16_t evt_len) {
    344   BTM_TRACE_EVENT("%s status=%d", __func__, *p);
    345 }
    346 
    347 void btm_ble_create_conn_cancel_complete(uint8_t* p) {
    348   uint8_t status;
    349   STREAM_TO_UINT8(status, p);
    350 
    351   if (status == HCI_ERR_COMMAND_DISALLOWED) {
    352     /* This is a sign that logic around keeping connection state is broken */
    353     LOG(ERROR)
    354         << "Attempt to cancel LE connection, when no connection is pending.";
    355     if (btm_ble_get_conn_st() == BLE_CONN_CANCEL) {
    356       btm_ble_set_conn_st(BLE_CONN_IDLE);
    357       btm_ble_update_mode_operation(HCI_ROLE_UNKNOWN, nullptr, status);
    358     }
    359   }
    360 }
    361 
    362 void btm_send_hci_create_connection(
    363     uint16_t scan_int, uint16_t scan_win, uint8_t init_filter_policy,
    364     uint8_t addr_type_peer, const RawAddress& bda_peer, uint8_t addr_type_own,
    365     uint16_t conn_int_min, uint16_t conn_int_max, uint16_t conn_latency,
    366     uint16_t conn_timeout, uint16_t min_ce_len, uint16_t max_ce_len,
    367     uint8_t initiating_phys) {
    368   if (controller_get_interface()->supports_ble_extended_advertising()) {
    369     EXT_CONN_PHY_CFG phy_cfg[3];  // maximum three phys
    370 
    371     int phy_cnt =
    372         std::bitset<std::numeric_limits<uint8_t>::digits>(initiating_phys)
    373             .count();
    374 
    375     LOG_ASSERT(phy_cnt < 3) << "More than three phys provided";
    376     // TODO(jpawlowski): tune parameters for different transports
    377     for (int i = 0; i < phy_cnt; i++) {
    378       phy_cfg[i].scan_int = scan_int;
    379       phy_cfg[i].scan_win = scan_win;
    380       phy_cfg[i].conn_int_min = conn_int_min;
    381       phy_cfg[i].conn_int_max = conn_int_max;
    382       phy_cfg[i].conn_latency = conn_latency;
    383       phy_cfg[i].sup_timeout = conn_timeout;
    384       phy_cfg[i].min_ce_len = min_ce_len;
    385       phy_cfg[i].max_ce_len = max_ce_len;
    386     }
    387 
    388     addr_type_peer &= ~BLE_ADDR_TYPE_ID_BIT;
    389     btsnd_hcic_ble_ext_create_conn(init_filter_policy, addr_type_own,
    390                                    addr_type_peer, bda_peer, initiating_phys,
    391                                    phy_cfg);
    392   } else {
    393     btsnd_hcic_ble_create_ll_conn(scan_int, scan_win, init_filter_policy,
    394                                   addr_type_peer, bda_peer, addr_type_own,
    395                                   conn_int_min, conn_int_max, conn_latency,
    396                                   conn_timeout, min_ce_len, max_ce_len);
    397   }
    398 }
    399 
    400 /*******************************************************************************
    401  *
    402  * Function         btm_ble_start_auto_conn
    403  *
    404  * Description      This function is to start/stop auto connection procedure.
    405  *
    406  * Parameters       start: true to start; false to stop.
    407  *
    408  * Returns          void
    409  *
    410  ******************************************************************************/
    411 bool btm_ble_start_auto_conn(bool start) {
    412   tBTM_BLE_CB* p_cb = &btm_cb.ble_ctr_cb;
    413   bool exec = true;
    414   uint16_t scan_int;
    415   uint16_t scan_win;
    416   uint8_t own_addr_type = p_cb->addr_mgnt_cb.own_addr_type;
    417   uint8_t peer_addr_type = BLE_ADDR_PUBLIC;
    418 
    419   uint8_t phy = PHY_LE_1M;
    420   if (controller_get_interface()->supports_ble_2m_phy()) phy |= PHY_LE_2M;
    421   if (controller_get_interface()->supports_ble_coded_phy()) phy |= PHY_LE_CODED;
    422 
    423   BTM_TRACE_EVENT("%s start=%d", __func__, start);
    424 
    425   if (start) {
    426     if (p_cb->conn_state == BLE_CONN_IDLE && background_connections_pending() &&
    427         btm_ble_topology_check(BTM_BLE_STATE_INIT) && l2cu_can_allocate_lcb()) {
    428       p_cb->wl_state |= BTM_BLE_WL_INIT;
    429 
    430       btm_execute_wl_dev_operation();
    431 
    432 #if (BLE_PRIVACY_SPT == TRUE)
    433       btm_ble_enable_resolving_list_for_platform(BTM_BLE_RL_INIT);
    434 #endif
    435       scan_int = (p_cb->scan_int == BTM_BLE_SCAN_PARAM_UNDEF)
    436                      ? BTM_BLE_SCAN_SLOW_INT_1
    437                      : p_cb->scan_int;
    438       scan_win = (p_cb->scan_win == BTM_BLE_SCAN_PARAM_UNDEF)
    439                      ? BTM_BLE_SCAN_SLOW_WIN_1
    440                      : p_cb->scan_win;
    441 
    442 #if (BLE_PRIVACY_SPT == TRUE)
    443       if (btm_cb.ble_ctr_cb.rl_state != BTM_BLE_RL_IDLE &&
    444           controller_get_interface()->supports_ble_privacy()) {
    445         own_addr_type |= BLE_ADDR_TYPE_ID_BIT;
    446         peer_addr_type |= BLE_ADDR_TYPE_ID_BIT;
    447       }
    448 #endif
    449 
    450       btm_send_hci_create_connection(
    451           scan_int,                       /* uint16_t scan_int      */
    452           scan_win,                       /* uint16_t scan_win      */
    453           0x01,                           /* uint8_t white_list     */
    454           peer_addr_type,                 /* uint8_t addr_type_peer */
    455           RawAddress::kEmpty,             /* BD_ADDR bda_peer     */
    456           own_addr_type,                  /* uint8_t addr_type_own */
    457           BTM_BLE_CONN_INT_MIN_DEF,       /* uint16_t conn_int_min  */
    458           BTM_BLE_CONN_INT_MAX_DEF,       /* uint16_t conn_int_max  */
    459           BTM_BLE_CONN_SLAVE_LATENCY_DEF, /* uint16_t conn_latency  */
    460           BTM_BLE_CONN_TIMEOUT_DEF,       /* uint16_t conn_timeout  */
    461           0,                              /* uint16_t min_len       */
    462           0,                              /* uint16_t max_len       */
    463           phy);
    464       btm_ble_set_conn_st(BLE_BG_CONN);
    465     } else {
    466       exec = false;
    467     }
    468   } else {
    469     if (p_cb->conn_state == BLE_BG_CONN) {
    470       btsnd_hcic_ble_create_conn_cancel();
    471       btm_ble_set_conn_st(BLE_CONN_CANCEL);
    472       p_cb->wl_state &= ~BTM_BLE_WL_INIT;
    473     } else {
    474       BTM_TRACE_DEBUG("conn_st = %d, not in auto conn state, cannot stop",
    475                       p_cb->conn_state);
    476       exec = false;
    477     }
    478   }
    479   return exec;
    480 }
    481 
    482 /*******************************************************************************
    483  *
    484  * Function         btm_ble_suspend_bg_conn
    485  *
    486  * Description      This function is to suspend an active background connection
    487  *                  procedure.
    488  *
    489  * Parameters       none.
    490  *
    491  * Returns          none.
    492  *
    493  ******************************************************************************/
    494 bool btm_ble_suspend_bg_conn(void) {
    495   BTM_TRACE_EVENT("%s", __func__);
    496 
    497   if (btm_cb.ble_ctr_cb.bg_conn_type == BTM_BLE_CONN_AUTO)
    498     return btm_ble_start_auto_conn(false);
    499 
    500   return false;
    501 }
    502 /*******************************************************************************
    503  *
    504  * Function         btm_suspend_wl_activity
    505  *
    506  * Description      This function is to suspend white list related activity
    507  *
    508  * Returns          none.
    509  *
    510  ******************************************************************************/
    511 static void btm_suspend_wl_activity(tBTM_BLE_WL_STATE wl_state) {
    512   if (wl_state & BTM_BLE_WL_INIT) {
    513     btm_ble_start_auto_conn(false);
    514   }
    515 }
    516 /*******************************************************************************
    517  *
    518  * Function         btm_resume_wl_activity
    519  *
    520  * Description      This function is to resume white list related activity
    521  *
    522  * Returns          none.
    523  *
    524  ******************************************************************************/
    525 static void btm_resume_wl_activity(tBTM_BLE_WL_STATE wl_state) {
    526   btm_ble_resume_bg_conn();
    527 }
    528 /*******************************************************************************
    529  *
    530  * Function         btm_ble_resume_bg_conn
    531  *
    532  * Description      This function is to resume a background auto connection
    533  *                  procedure.
    534  *
    535  * Parameters       none.
    536  *
    537  * Returns          none.
    538  *
    539  ******************************************************************************/
    540 bool btm_ble_resume_bg_conn(void) {
    541   tBTM_BLE_CB* p_cb = &btm_cb.ble_ctr_cb;
    542   if (p_cb->bg_conn_type == BTM_BLE_CONN_AUTO) {
    543     return btm_ble_start_auto_conn(true);
    544   }
    545 
    546   return false;
    547 }
    548 /*******************************************************************************
    549  *
    550  * Function         btm_ble_get_conn_st
    551  *
    552  * Description      This function get BLE connection state
    553  *
    554  * Returns          connection state
    555  *
    556  ******************************************************************************/
    557 tBTM_BLE_CONN_ST btm_ble_get_conn_st(void) {
    558   return btm_cb.ble_ctr_cb.conn_state;
    559 }
    560 /*******************************************************************************
    561  *
    562  * Function         btm_ble_set_conn_st
    563  *
    564  * Description      This function set BLE connection state
    565  *
    566  * Returns          None.
    567  *
    568  ******************************************************************************/
    569 void btm_ble_set_conn_st(tBTM_BLE_CONN_ST new_st) {
    570   btm_cb.ble_ctr_cb.conn_state = new_st;
    571 
    572   if (new_st == BLE_BG_CONN || new_st == BLE_DIR_CONN)
    573     btm_ble_set_topology_mask(BTM_BLE_STATE_INIT_BIT);
    574   else
    575     btm_ble_clear_topology_mask(BTM_BLE_STATE_INIT_BIT);
    576 }
    577 
    578 /*******************************************************************************
    579  *
    580  * Function         btm_ble_enqueue_direct_conn_req
    581  *
    582  * Description      This function enqueue the direct connection request
    583  *
    584  * Returns          None.
    585  *
    586  ******************************************************************************/
    587 void btm_ble_enqueue_direct_conn_req(void* p_param) {
    588   tBTM_BLE_CONN_REQ* p =
    589       (tBTM_BLE_CONN_REQ*)osi_malloc(sizeof(tBTM_BLE_CONN_REQ));
    590 
    591   p->p_param = p_param;
    592 
    593   fixed_queue_enqueue(btm_cb.ble_ctr_cb.conn_pending_q, p);
    594 }
    595 /*******************************************************************************
    596  *
    597  * Function         btm_ble_dequeue_direct_conn_req
    598  *
    599  * Description      This function dequeues the direct connection request
    600  *
    601  * Returns          None.
    602  *
    603  ******************************************************************************/
    604 void btm_ble_dequeue_direct_conn_req(const RawAddress& rem_bda) {
    605   if (fixed_queue_is_empty(btm_cb.ble_ctr_cb.conn_pending_q)) return;
    606 
    607   list_t* list = fixed_queue_get_list(btm_cb.ble_ctr_cb.conn_pending_q);
    608   for (const list_node_t* node = list_begin(list); node != list_end(list);
    609        node = list_next(node)) {
    610     tBTM_BLE_CONN_REQ* p_req = (tBTM_BLE_CONN_REQ*)list_node(node);
    611     tL2C_LCB* p_lcb = (tL2C_LCB*)p_req->p_param;
    612     if ((p_lcb == NULL) || (!p_lcb->in_use)) {
    613       continue;
    614     }
    615     // If BD address matches
    616     if (rem_bda == p_lcb->remote_bd_addr) {
    617       fixed_queue_try_remove_from_queue(btm_cb.ble_ctr_cb.conn_pending_q,
    618                                         p_req);
    619       l2cu_release_lcb((tL2C_LCB*)p_req->p_param);
    620       osi_free((void*)p_req);
    621       break;
    622     }
    623   }
    624 }
    625 /*******************************************************************************
    626  *
    627  * Function         btm_send_pending_direct_conn
    628  *
    629  * Description      This function send the pending direct connection request in
    630  *                  queue
    631  *
    632  * Returns          true if started, false otherwise
    633  *
    634  ******************************************************************************/
    635 bool btm_send_pending_direct_conn(void) {
    636   tBTM_BLE_CONN_REQ* p_req;
    637   bool rt = false;
    638 
    639   p_req = (tBTM_BLE_CONN_REQ*)fixed_queue_try_dequeue(
    640       btm_cb.ble_ctr_cb.conn_pending_q);
    641   if (p_req != NULL) {
    642     tL2C_LCB* p_lcb = (tL2C_LCB*)(p_req->p_param);
    643     /* Ignore entries that might have been released while queued. */
    644     if (p_lcb->in_use) rt = l2cble_init_direct_conn(p_lcb);
    645     osi_free(p_req);
    646   }
    647 
    648   return rt;
    649 }
    650