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