• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright (C) 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 {
operator ()BgConnHash62   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 
background_connection_add(uint8_t addr_type,const RawAddress & address)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 
background_connection_remove(const RawAddress & address)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 
background_connections_clear()96 static void background_connections_clear() { background_connections.clear(); }
97 
background_connections_pending()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 
background_connections_count()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  ******************************************************************************/
btm_update_scanner_filter_policy(tBTM_BLE_SFP scan_policy)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  ******************************************************************************/
btm_ble_bgconn_cancel_if_disconnected(const RawAddress & bd_addr)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  ******************************************************************************/
btm_add_dev_to_controller(bool to_add,const RawAddress & bd_addr)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     uint8_t addr_type =
213         BTM_IS_PUBLIC_BDA(bd_addr) ? BLE_ADDR_PUBLIC : BLE_ADDR_RANDOM;
214     started = true;
215     if (to_add)
216       background_connection_add(addr_type, bd_addr);
217     else
218       background_connection_remove(bd_addr);
219   }
220 
221   return started;
222 }
223 /*******************************************************************************
224  *
225  * Function         btm_execute_wl_dev_operation
226  *
227  * Description      execute the pending whitelist device operation (loading or
228  *                                                                  removing)
229  ******************************************************************************/
btm_execute_wl_dev_operation(void)230 bool btm_execute_wl_dev_operation(void) {
231   // handle removals first to avoid filling up controller's white list
232   for (auto map_it = background_connections.begin();
233        map_it != background_connections.end();) {
234     background_connection_t* connection = &map_it->second;
235     if (connection->pending_removal) {
236       btsnd_hcic_ble_remove_from_white_list(connection->addr_type_in_wl,
237                                             connection->address);
238       map_it = background_connections.erase(map_it);
239     } else
240       ++map_it;
241   }
242   for (auto& map_el : background_connections) {
243     background_connection_t* connection = &map_el.second;
244     const bool connected =
245         BTM_IsAclConnectionUp(connection->address, BT_TRANSPORT_LE);
246     if (!connection->in_controller_wl && !connected) {
247       btsnd_hcic_ble_add_white_list(connection->addr_type, connection->address);
248       connection->in_controller_wl = true;
249       connection->addr_type_in_wl = connection->addr_type;
250     } else if (connection->in_controller_wl && connected) {
251       /* Bluetooth Core 4.2 as well as ESR08 disallows more than one
252          connection between two LE addresses. Not all controllers handle this
253          correctly, therefore we must make sure connected devices are not in
254          the white list when bg connection attempt is active. */
255       btsnd_hcic_ble_remove_from_white_list(connection->addr_type_in_wl,
256                                             connection->address);
257       connection->in_controller_wl = false;
258     }
259   }
260   return true;
261 }
262 
263 /*******************************************************************************
264  *
265  * Function         btm_update_dev_to_white_list
266  *
267  * Description      This function adds or removes a device into/from
268  *                  the white list.
269  *
270  ******************************************************************************/
btm_update_dev_to_white_list(bool to_add,const RawAddress & bd_addr)271 bool btm_update_dev_to_white_list(bool to_add, const RawAddress& bd_addr) {
272   tBTM_BLE_CB* p_cb = &btm_cb.ble_ctr_cb;
273 
274   if (to_add &&
275       background_connections_count() ==
276           controller_get_interface()->get_ble_white_list_size()) {
277     BTM_TRACE_ERROR("%s Whitelist full, unable to add device", __func__);
278     return false;
279   }
280 
281   btm_suspend_wl_activity(p_cb->wl_state);
282   btm_add_dev_to_controller(to_add, bd_addr);
283   btm_resume_wl_activity(p_cb->wl_state);
284   return true;
285 }
286 
287 /*******************************************************************************
288  *
289  * Function         btm_ble_clear_white_list
290  *
291  * Description      This function clears the white list.
292  *
293  ******************************************************************************/
btm_ble_clear_white_list(void)294 void btm_ble_clear_white_list(void) {
295   BTM_TRACE_EVENT("btm_ble_clear_white_list");
296   btsnd_hcic_ble_clear_white_list();
297   background_connections_clear();
298 }
299 
300 /*******************************************************************************
301  *
302  * Function         btm_ble_clear_white_list_complete
303  *
304  * Description      Indicates white list cleared.
305  *
306  ******************************************************************************/
btm_ble_clear_white_list_complete(uint8_t * p_data,UNUSED_ATTR uint16_t evt_len)307 void btm_ble_clear_white_list_complete(uint8_t* p_data,
308                                        UNUSED_ATTR uint16_t evt_len) {
309   uint8_t status;
310 
311   STREAM_TO_UINT8(status, p_data);
312   BTM_TRACE_EVENT("%s status=%d", __func__, status);
313 }
314 
315 /*******************************************************************************
316  *
317  * Function         btm_ble_white_list_init
318  *
319  * Description      Initialize white list size
320  *
321  ******************************************************************************/
btm_ble_white_list_init(uint8_t white_list_size)322 void btm_ble_white_list_init(uint8_t white_list_size) {
323   BTM_TRACE_DEBUG("%s white_list_size = %d", __func__, white_list_size);
324 }
325 
326 /*******************************************************************************
327  *
328  * Function         btm_ble_add_2_white_list_complete
329  *
330  * Description      White list element added
331  *
332  ******************************************************************************/
btm_ble_add_2_white_list_complete(uint8_t status)333 void btm_ble_add_2_white_list_complete(uint8_t status) {
334   BTM_TRACE_EVENT("%s status=%d", __func__, status);
335 }
336 
337 /*******************************************************************************
338  *
339  * Function         btm_ble_remove_from_white_list_complete
340  *
341  * Description      White list element removal complete
342  *
343  ******************************************************************************/
btm_ble_remove_from_white_list_complete(uint8_t * p,UNUSED_ATTR uint16_t evt_len)344 void btm_ble_remove_from_white_list_complete(uint8_t* p,
345                                              UNUSED_ATTR uint16_t evt_len) {
346   BTM_TRACE_EVENT("%s status=%d", __func__, *p);
347 }
348 
btm_send_hci_create_connection(uint16_t scan_int,uint16_t scan_win,uint8_t init_filter_policy,uint8_t addr_type_peer,const RawAddress & bda_peer,uint8_t addr_type_own,uint16_t conn_int_min,uint16_t conn_int_max,uint16_t conn_latency,uint16_t conn_timeout,uint16_t min_ce_len,uint16_t max_ce_len,uint8_t initiating_phys)349 void btm_send_hci_create_connection(
350     uint16_t scan_int, uint16_t scan_win, uint8_t init_filter_policy,
351     uint8_t addr_type_peer, const RawAddress& bda_peer, uint8_t addr_type_own,
352     uint16_t conn_int_min, uint16_t conn_int_max, uint16_t conn_latency,
353     uint16_t conn_timeout, uint16_t min_ce_len, uint16_t max_ce_len,
354     uint8_t initiating_phys) {
355   if (controller_get_interface()->supports_ble_extended_advertising()) {
356     EXT_CONN_PHY_CFG phy_cfg[3];  // maximum three phys
357 
358     int phy_cnt =
359         std::bitset<std::numeric_limits<uint8_t>::digits>(initiating_phys)
360             .count();
361 
362     LOG_ASSERT(phy_cnt < 3) << "More than three phys provided";
363     // TODO(jpawlowski): tune parameters for different transports
364     for (int i = 0; i < phy_cnt; i++) {
365       phy_cfg[i].scan_int = scan_int;
366       phy_cfg[i].scan_win = scan_win;
367       phy_cfg[i].conn_int_min = conn_int_min;
368       phy_cfg[i].conn_int_max = conn_int_max;
369       phy_cfg[i].conn_latency = conn_latency;
370       phy_cfg[i].sup_timeout = conn_timeout;
371       phy_cfg[i].min_ce_len = min_ce_len;
372       phy_cfg[i].max_ce_len = max_ce_len;
373     }
374 
375     addr_type_peer &= ~BLE_ADDR_TYPE_ID_BIT;
376     btsnd_hcic_ble_ext_create_conn(init_filter_policy, addr_type_own,
377                                    addr_type_peer, bda_peer, initiating_phys,
378                                    phy_cfg);
379   } else {
380     btsnd_hcic_ble_create_ll_conn(scan_int, scan_win, init_filter_policy,
381                                   addr_type_peer, bda_peer, addr_type_own,
382                                   conn_int_min, conn_int_max, conn_latency,
383                                   conn_timeout, min_ce_len, max_ce_len);
384   }
385 }
386 
387 /*******************************************************************************
388  *
389  * Function         btm_ble_start_auto_conn
390  *
391  * Description      This function is to start/stop auto connection procedure.
392  *
393  * Parameters       start: true to start; false to stop.
394  *
395  * Returns          void
396  *
397  ******************************************************************************/
btm_ble_start_auto_conn(bool start)398 bool btm_ble_start_auto_conn(bool start) {
399   tBTM_BLE_CB* p_cb = &btm_cb.ble_ctr_cb;
400   bool exec = true;
401   uint16_t scan_int;
402   uint16_t scan_win;
403   uint8_t own_addr_type = p_cb->addr_mgnt_cb.own_addr_type;
404   uint8_t peer_addr_type = BLE_ADDR_PUBLIC;
405 
406   uint8_t phy = PHY_LE_1M;
407   if (controller_get_interface()->supports_ble_2m_phy()) phy |= PHY_LE_2M;
408   if (controller_get_interface()->supports_ble_coded_phy()) phy |= PHY_LE_CODED;
409 
410   BTM_TRACE_EVENT("%s start=%d", __func__, start);
411 
412   if (start) {
413     if (p_cb->conn_state == BLE_CONN_IDLE && background_connections_pending() &&
414         btm_ble_topology_check(BTM_BLE_STATE_INIT) && l2cu_can_allocate_lcb()) {
415       p_cb->wl_state |= BTM_BLE_WL_INIT;
416 
417       btm_execute_wl_dev_operation();
418 
419 #if (BLE_PRIVACY_SPT == TRUE)
420       btm_ble_enable_resolving_list_for_platform(BTM_BLE_RL_INIT);
421 #endif
422       scan_int = (p_cb->scan_int == BTM_BLE_SCAN_PARAM_UNDEF)
423                      ? BTM_BLE_SCAN_SLOW_INT_1
424                      : p_cb->scan_int;
425       scan_win = (p_cb->scan_win == BTM_BLE_SCAN_PARAM_UNDEF)
426                      ? BTM_BLE_SCAN_SLOW_WIN_1
427                      : p_cb->scan_win;
428 
429 #if (BLE_PRIVACY_SPT == TRUE)
430       if (btm_cb.ble_ctr_cb.rl_state != BTM_BLE_RL_IDLE &&
431           controller_get_interface()->supports_ble_privacy()) {
432         own_addr_type |= BLE_ADDR_TYPE_ID_BIT;
433         peer_addr_type |= BLE_ADDR_TYPE_ID_BIT;
434       }
435 #endif
436 
437       btm_send_hci_create_connection(
438           scan_int,                       /* uint16_t scan_int      */
439           scan_win,                       /* uint16_t scan_win      */
440           0x01,                           /* uint8_t white_list     */
441           peer_addr_type,                 /* uint8_t addr_type_peer */
442           RawAddress::kEmpty,             /* BD_ADDR bda_peer     */
443           own_addr_type,                  /* uint8_t addr_type_own */
444           BTM_BLE_CONN_INT_MIN_DEF,       /* uint16_t conn_int_min  */
445           BTM_BLE_CONN_INT_MAX_DEF,       /* uint16_t conn_int_max  */
446           BTM_BLE_CONN_SLAVE_LATENCY_DEF, /* uint16_t conn_latency  */
447           BTM_BLE_CONN_TIMEOUT_DEF,       /* uint16_t conn_timeout  */
448           0,                              /* uint16_t min_len       */
449           0,                              /* uint16_t max_len       */
450           phy);
451       btm_ble_set_conn_st(BLE_BG_CONN);
452     } else {
453       exec = false;
454     }
455   } else {
456     if (p_cb->conn_state == BLE_BG_CONN) {
457       btsnd_hcic_ble_create_conn_cancel();
458       btm_ble_set_conn_st(BLE_CONN_CANCEL);
459       p_cb->wl_state &= ~BTM_BLE_WL_INIT;
460     } else {
461       BTM_TRACE_DEBUG("conn_st = %d, not in auto conn state, cannot stop",
462                       p_cb->conn_state);
463       exec = false;
464     }
465   }
466   return exec;
467 }
468 
469 /*******************************************************************************
470  *
471  * Function         btm_ble_suspend_bg_conn
472  *
473  * Description      This function is to suspend an active background connection
474  *                  procedure.
475  *
476  * Parameters       none.
477  *
478  * Returns          none.
479  *
480  ******************************************************************************/
btm_ble_suspend_bg_conn(void)481 bool btm_ble_suspend_bg_conn(void) {
482   BTM_TRACE_EVENT("%s", __func__);
483 
484   if (btm_cb.ble_ctr_cb.bg_conn_type == BTM_BLE_CONN_AUTO)
485     return btm_ble_start_auto_conn(false);
486 
487   return false;
488 }
489 /*******************************************************************************
490  *
491  * Function         btm_suspend_wl_activity
492  *
493  * Description      This function is to suspend white list related activity
494  *
495  * Returns          none.
496  *
497  ******************************************************************************/
btm_suspend_wl_activity(tBTM_BLE_WL_STATE wl_state)498 static void btm_suspend_wl_activity(tBTM_BLE_WL_STATE wl_state) {
499   if (wl_state & BTM_BLE_WL_INIT) {
500     btm_ble_start_auto_conn(false);
501   }
502 }
503 /*******************************************************************************
504  *
505  * Function         btm_resume_wl_activity
506  *
507  * Description      This function is to resume white list related activity
508  *
509  * Returns          none.
510  *
511  ******************************************************************************/
btm_resume_wl_activity(tBTM_BLE_WL_STATE wl_state)512 static void btm_resume_wl_activity(tBTM_BLE_WL_STATE wl_state) {
513   btm_ble_resume_bg_conn();
514 }
515 /*******************************************************************************
516  *
517  * Function         btm_ble_resume_bg_conn
518  *
519  * Description      This function is to resume a background auto connection
520  *                  procedure.
521  *
522  * Parameters       none.
523  *
524  * Returns          none.
525  *
526  ******************************************************************************/
btm_ble_resume_bg_conn(void)527 bool btm_ble_resume_bg_conn(void) {
528   tBTM_BLE_CB* p_cb = &btm_cb.ble_ctr_cb;
529   if (p_cb->bg_conn_type == BTM_BLE_CONN_AUTO) {
530     return btm_ble_start_auto_conn(true);
531   }
532 
533   return false;
534 }
535 /*******************************************************************************
536  *
537  * Function         btm_ble_get_conn_st
538  *
539  * Description      This function get BLE connection state
540  *
541  * Returns          connection state
542  *
543  ******************************************************************************/
btm_ble_get_conn_st(void)544 tBTM_BLE_CONN_ST btm_ble_get_conn_st(void) {
545   return btm_cb.ble_ctr_cb.conn_state;
546 }
547 /*******************************************************************************
548  *
549  * Function         btm_ble_set_conn_st
550  *
551  * Description      This function set BLE connection state
552  *
553  * Returns          None.
554  *
555  ******************************************************************************/
btm_ble_set_conn_st(tBTM_BLE_CONN_ST new_st)556 void btm_ble_set_conn_st(tBTM_BLE_CONN_ST new_st) {
557   btm_cb.ble_ctr_cb.conn_state = new_st;
558 
559   if (new_st == BLE_BG_CONN || new_st == BLE_DIR_CONN)
560     btm_ble_set_topology_mask(BTM_BLE_STATE_INIT_BIT);
561   else
562     btm_ble_clear_topology_mask(BTM_BLE_STATE_INIT_BIT);
563 }
564 
565 /*******************************************************************************
566  *
567  * Function         btm_ble_enqueue_direct_conn_req
568  *
569  * Description      This function enqueue the direct connection request
570  *
571  * Returns          None.
572  *
573  ******************************************************************************/
btm_ble_enqueue_direct_conn_req(void * p_param)574 void btm_ble_enqueue_direct_conn_req(void* p_param) {
575   tBTM_BLE_CONN_REQ* p =
576       (tBTM_BLE_CONN_REQ*)osi_malloc(sizeof(tBTM_BLE_CONN_REQ));
577 
578   p->p_param = p_param;
579 
580   fixed_queue_enqueue(btm_cb.ble_ctr_cb.conn_pending_q, p);
581 }
582 /*******************************************************************************
583  *
584  * Function         btm_ble_dequeue_direct_conn_req
585  *
586  * Description      This function dequeues the direct connection request
587  *
588  * Returns          None.
589  *
590  ******************************************************************************/
btm_ble_dequeue_direct_conn_req(const RawAddress & rem_bda)591 void btm_ble_dequeue_direct_conn_req(const RawAddress& rem_bda) {
592   if (fixed_queue_is_empty(btm_cb.ble_ctr_cb.conn_pending_q)) return;
593 
594   list_t* list = fixed_queue_get_list(btm_cb.ble_ctr_cb.conn_pending_q);
595   for (const list_node_t* node = list_begin(list); node != list_end(list);
596        node = list_next(node)) {
597     tBTM_BLE_CONN_REQ* p_req = (tBTM_BLE_CONN_REQ*)list_node(node);
598     tL2C_LCB* p_lcb = (tL2C_LCB*)p_req->p_param;
599     if ((p_lcb == NULL) || (!p_lcb->in_use)) {
600       continue;
601     }
602     // If BD address matches
603     if (rem_bda == p_lcb->remote_bd_addr) {
604       fixed_queue_try_remove_from_queue(btm_cb.ble_ctr_cb.conn_pending_q,
605                                         p_req);
606       l2cu_release_lcb((tL2C_LCB*)p_req->p_param);
607       osi_free((void*)p_req);
608       break;
609     }
610   }
611 }
612 /*******************************************************************************
613  *
614  * Function         btm_send_pending_direct_conn
615  *
616  * Description      This function send the pending direct connection request in
617  *                  queue
618  *
619  * Returns          true if started, false otherwise
620  *
621  ******************************************************************************/
btm_send_pending_direct_conn(void)622 bool btm_send_pending_direct_conn(void) {
623   tBTM_BLE_CONN_REQ* p_req;
624   bool rt = false;
625 
626   p_req = (tBTM_BLE_CONN_REQ*)fixed_queue_try_dequeue(
627       btm_cb.ble_ctr_cb.conn_pending_q);
628   if (p_req != NULL) {
629     tL2C_LCB* p_lcb = (tL2C_LCB*)(p_req->p_param);
630     /* Ignore entries that might have been released while queued. */
631     if (p_lcb->in_use) rt = l2cble_init_direct_conn(p_lcb);
632     osi_free(p_req);
633   }
634 
635   return rt;
636 }
637