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 <string.h>
26
27 #include "bt_types.h"
28 #include "btu.h"
29 #include "btm_int.h"
30 #include "l2c_int.h"
31 #include "hcimsgs.h"
32
33
34 #ifndef BTM_BLE_SCAN_PARAM_TOUT
35 #define BTM_BLE_SCAN_PARAM_TOUT 50 /* 50 seconds */
36 #endif
37
38 #if (BLE_INCLUDED == TRUE)
39
40 static void btm_suspend_wl_activity(tBTM_BLE_WL_STATE wl_state);
41 static void btm_resume_wl_activity(tBTM_BLE_WL_STATE wl_state);
42
43 /*******************************************************************************
44 **
45 ** Function btm_update_scanner_filter_policy
46 **
47 ** Description This function update the filter policy of scnner or advertiser.
48 *******************************************************************************/
btm_update_scanner_filter_policy(tBTM_BLE_SFP scan_policy)49 void btm_update_scanner_filter_policy(tBTM_BLE_SFP scan_policy)
50 {
51 tBTM_BLE_INQ_CB *p_inq = &btm_cb.ble_ctr_cb.inq_var;
52 BTM_TRACE_EVENT0 ("btm_update_scanner_filter_policy");
53
54 p_inq->sfp = scan_policy;
55 p_inq->scan_type = (p_inq->scan_type == BTM_BLE_SCAN_MODE_NONE) ? BTM_BLE_SCAN_MODE_ACTI: p_inq->scan_type;
56
57 btsnd_hcic_ble_set_scan_params (p_inq->scan_type,
58 (UINT16)(!p_inq->scan_interval ? BTM_BLE_GAP_DISC_SCAN_INT : p_inq->scan_interval),
59 (UINT16)(!p_inq->scan_window ? BTM_BLE_GAP_DISC_SCAN_WIN : p_inq->scan_window),
60 BLE_ADDR_PUBLIC,
61 scan_policy);
62 }
63 /*******************************************************************************
64 **
65 ** Function btm_update_dev_to_white_list
66 **
67 ** Description This function adds a device into white list.
68 *******************************************************************************/
btm_update_dev_to_white_list(BOOLEAN to_add,BD_ADDR bd_addr,UINT8 attr)69 BOOLEAN btm_update_dev_to_white_list(BOOLEAN to_add, BD_ADDR bd_addr, UINT8 attr)
70 {
71 /* look up the sec device record, and find the address */
72 tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb;
73 tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev (bd_addr);
74 BD_ADDR dummy_bda = {0};
75 BOOLEAN started = FALSE;
76 UINT8 wl_state = p_cb->wl_state;
77 tBT_DEVICE_TYPE dev_type;
78 tBLE_ADDR_TYPE addr_type = BLE_ADDR_PUBLIC;
79
80 if ((to_add && p_cb->num_empty_filter == 0) ||
81 (!to_add && p_cb->num_empty_filter == p_cb->max_filter_entries))
82 {
83 BTM_TRACE_ERROR1("WL full or empty, unable to update to WL. num_entry available: %d", p_cb->num_empty_filter);
84 return started;
85 }
86
87 btm_suspend_wl_activity(wl_state);
88
89 if (p_dev_rec != NULL &&
90 p_dev_rec->device_type == BT_DEVICE_TYPE_BLE)
91 {
92
93 if (to_add)
94 {
95 if (!BTM_BLE_IS_RESOLVE_BDA(bd_addr))
96 {
97 started = btsnd_hcic_ble_add_white_list (p_dev_rec->ble.ble_addr_type, bd_addr);
98 }
99 if (memcmp(p_dev_rec->ble.static_addr, bd_addr, BD_ADDR_LEN) != 0 &&
100 memcmp(p_dev_rec->ble.static_addr, dummy_bda, BD_ADDR_LEN) != 0)
101 {
102 started = btsnd_hcic_ble_add_white_list (p_dev_rec->ble.static_addr_type, p_dev_rec->ble.static_addr);
103 }
104 }
105 else
106 {
107 if (!BTM_BLE_IS_RESOLVE_BDA(bd_addr))
108 {
109 started = btsnd_hcic_ble_remove_from_white_list (p_dev_rec->ble.ble_addr_type, bd_addr);
110 }
111 if (memcmp(p_dev_rec->ble.static_addr, dummy_bda, BD_ADDR_LEN) != 0)
112 {
113 started = btsnd_hcic_ble_remove_from_white_list (p_dev_rec->ble.static_addr_type, p_dev_rec->ble.static_addr);
114 }
115 }
116 } /* if not a known device, shall we add it? */
117 else
118 {
119 BTM_ReadDevInfo(bd_addr, &dev_type, &addr_type);
120 if (to_add)
121 started = btsnd_hcic_ble_add_white_list (addr_type, bd_addr);
122 else
123 started = btsnd_hcic_ble_remove_from_white_list (addr_type, bd_addr);
124 }
125
126 btm_resume_wl_activity(wl_state);
127
128 return started;
129 }
130 /*******************************************************************************
131 **
132 ** Function btm_ble_clear_white_list
133 **
134 ** Description This function clears the white list.
135 *******************************************************************************/
btm_ble_clear_white_list(void)136 void btm_ble_clear_white_list (void)
137 {
138 BTM_TRACE_EVENT0 ("btm_ble_clear_white_list");
139 btsnd_hcic_ble_clear_white_list();
140 }
141
142 /*******************************************************************************
143 **
144 ** Function btm_ble_clear_white_list_complete
145 **
146 ** Description This function clears the white list complete.
147 *******************************************************************************/
btm_ble_clear_white_list_complete(UINT8 * p_data,UINT16 evt_len)148 void btm_ble_clear_white_list_complete(UINT8 *p_data, UINT16 evt_len)
149 {
150 tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb;
151 UINT8 status;
152 BTM_TRACE_EVENT0 ("btm_ble_clear_white_list_complete");
153 STREAM_TO_UINT8 (status, p_data);
154
155 if (status == HCI_SUCCESS)
156 p_cb->num_empty_filter = p_cb->max_filter_entries;
157
158 }
159 /*******************************************************************************
160 **
161 ** Function btm_ble_add_2_white_list_complete
162 **
163 ** Description This function read the current white list size.
164 *******************************************************************************/
btm_ble_add_2_white_list_complete(UINT8 status)165 void btm_ble_add_2_white_list_complete(UINT8 status)
166 {
167 tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb;
168 BTM_TRACE_EVENT0 ("btm_ble_add_2_white_list_complete");
169
170 if (status == HCI_SUCCESS)
171 {
172 p_cb->num_empty_filter --;
173 }
174 }
175 /*******************************************************************************
176 **
177 ** Function btm_ble_add_2_white_list_complete
178 **
179 ** Description This function read the current white list size.
180 *******************************************************************************/
btm_ble_remove_from_white_list_complete(UINT8 * p,UINT16 evt_len)181 void btm_ble_remove_from_white_list_complete(UINT8 *p, UINT16 evt_len)
182 {
183 tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb;
184 BTM_TRACE_EVENT0 ("btm_ble_remove_from_white_list_complete");
185 if (*p == HCI_SUCCESS)
186 {
187 p_cb->num_empty_filter ++;
188 }
189 }
190 /*******************************************************************************
191 **
192 ** Function btm_ble_count_unconn_dev_in_whitelist
193 **
194 ** Description This function find the number of un-connected background device
195 *******************************************************************************/
btm_ble_count_unconn_dev_in_whitelist(void)196 UINT8 btm_ble_count_unconn_dev_in_whitelist(void)
197 {
198 tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb;
199 UINT8 i, count = 0;
200
201 for (i = 0; i < BTM_BLE_MAX_BG_CONN_DEV_NUM; i ++)
202 {
203 if (p_cb->bg_dev_list[i].in_use &&
204 !BTM_IsAclConnectionUp(p_cb->bg_dev_list[i].bd_addr))
205 {
206 count ++;
207 }
208 }
209 return count;
210
211 }
212 /*******************************************************************************
213 **
214 ** Function btm_update_bg_conn_list
215 **
216 ** Description This function update the local background connection device list.
217 *******************************************************************************/
btm_update_bg_conn_list(BOOLEAN to_add,BD_ADDR bd_addr,UINT8 * p_attr_tag)218 BOOLEAN btm_update_bg_conn_list(BOOLEAN to_add, BD_ADDR bd_addr, UINT8 *p_attr_tag)
219 {
220 UINT8 white_list_type = *p_attr_tag;
221 tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb;
222 tBTM_LE_BG_CONN_DEV *p_bg_dev = &p_cb->bg_dev_list[0], *p_next, *p_cur;
223 UINT8 i, j;
224 BOOLEAN ret = FALSE;
225
226 BTM_TRACE_EVENT0 ("btm_update_bg_conn_list");
227
228 if ((to_add && (p_cb->bg_dev_num == BTM_BLE_MAX_BG_CONN_DEV_NUM || p_cb->num_empty_filter == 0)))
229 {
230 BTM_TRACE_DEBUG1("num_empty_filter = %d", p_cb->num_empty_filter);
231 return ret;
232 }
233
234 for (i = 0; i < BTM_BLE_MAX_BG_CONN_DEV_NUM; i ++, p_bg_dev ++)
235 {
236 if (p_bg_dev->in_use && memcmp(p_bg_dev->bd_addr, bd_addr, BD_ADDR_LEN) == 0)
237 {
238 if (to_add)
239 p_bg_dev->attr |= white_list_type;
240 else
241 p_bg_dev->attr &= ~white_list_type;
242
243 if (p_bg_dev->attr == 0)
244 {
245 memset(p_bg_dev, 0, sizeof(tBTM_LE_BG_CONN_DEV));
246 p_cb->bg_dev_num --;
247 p_cur = p_bg_dev;
248 p_next = p_bg_dev + 1;
249 for (j = i + 1 ;j < BTM_BLE_MAX_BG_CONN_DEV_NUM && p_next->in_use ; j ++, p_cur ++, p_next ++ )
250 memcpy(p_cur, p_next, sizeof(tBTM_LE_BG_CONN_DEV));
251 }
252 ret = TRUE;
253 break;
254 }
255 else if (!p_bg_dev->in_use && to_add)
256 {
257 BTM_TRACE_DEBUG0("add new WL entry in bg_dev_list");
258
259 memcpy(p_bg_dev->bd_addr, bd_addr, BD_ADDR_LEN);
260 p_bg_dev->in_use = TRUE;
261 p_bg_dev->attr |= white_list_type;
262 p_cb->bg_dev_num ++;
263
264 ret = TRUE;
265 break;
266 }
267 }
268
269 if (i != BTM_BLE_MAX_BG_CONN_DEV_NUM)
270 *p_attr_tag = p_bg_dev->attr;
271
272 return ret;
273 }
274
275 /*******************************************************************************
276 **
277 ** Function btm_ble_start_auto_conn
278 **
279 ** Description This function is to start/stop auto connection procedure.
280 **
281 ** Parameters start: TRUE to start; FALSE to stop.
282 **
283 ** Returns void
284 **
285 *******************************************************************************/
btm_ble_start_auto_conn(BOOLEAN start)286 BOOLEAN btm_ble_start_auto_conn(BOOLEAN start)
287 {
288 tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb;
289 BD_ADDR dummy_bda = {0};
290 BOOLEAN exec = TRUE;
291 UINT8 own_addr_type = BLE_ADDR_PUBLIC;
292 UINT16 scan_int, scan_win;
293
294 if (start)
295 {
296 if (p_cb->conn_state == BLE_CONN_IDLE && btm_ble_count_unconn_dev_in_whitelist() > 0)
297 {
298
299 scan_int = (p_cb->scan_int == BTM_BLE_CONN_PARAM_UNDEF) ? BTM_BLE_SCAN_SLOW_INT_1 : p_cb->scan_int;
300 scan_win = (p_cb->scan_win == BTM_BLE_CONN_PARAM_UNDEF) ? BTM_BLE_SCAN_SLOW_WIN_1 : p_cb->scan_win;
301
302 if (!btsnd_hcic_ble_create_ll_conn (scan_int, /* UINT16 scan_int */
303 scan_win, /* UINT16 scan_win */
304 0x01, /* UINT8 white_list */
305 BLE_ADDR_PUBLIC, /* UINT8 addr_type_peer */
306 dummy_bda, /* BD_ADDR bda_peer */
307 own_addr_type, /* UINT8 addr_type_own, not allow random address for central */
308 BTM_BLE_CONN_INT_MIN_DEF, /* UINT16 conn_int_min */
309 BTM_BLE_CONN_INT_MAX_DEF, /* UINT16 conn_int_max */
310 BTM_BLE_CONN_SLAVE_LATENCY_DEF, /* UINT16 conn_latency */
311 BTM_BLE_CONN_TIMEOUT_DEF, /* UINT16 conn_timeout */
312 0, /* UINT16 min_len */
313 0)) /* UINT16 max_len */
314 {
315 /* start auto connection failed */
316 exec = FALSE;
317 }
318 else
319 {
320 p_cb->conn_state = BLE_BG_CONN;
321
322 }
323 }
324 else
325 {
326 exec = FALSE;
327 }
328 }
329 else
330 {
331 if (p_cb->conn_state == BLE_BG_CONN)
332 {
333 btsnd_hcic_ble_create_conn_cancel();
334 p_cb->conn_state = BLE_CONN_IDLE;
335
336 }
337 else
338 {
339 #if 0
340 BTM_TRACE_ERROR1("conn_st = %d, not in auto conn state, can not stop.", p_cb->conn_state);
341 exec = FALSE;
342 #endif
343 }
344 }
345 return exec;
346 }
347
348 /*******************************************************************************
349 **
350 ** Function btm_ble_start_select_conn
351 **
352 ** Description This function is to start/stop selective connection procedure.
353 **
354 ** Parameters start: TRUE to start; FALSE to stop.
355 ** p_select_cback: callback function to return application
356 ** selection.
357 **
358 ** Returns BOOLEAN: selective connectino procedure is started.
359 **
360 *******************************************************************************/
btm_ble_start_select_conn(BOOLEAN start,tBTM_BLE_SEL_CBACK * p_select_cback)361 BOOLEAN btm_ble_start_select_conn(BOOLEAN start,tBTM_BLE_SEL_CBACK *p_select_cback)
362 {
363 tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb;
364 UINT16 scan_int, scan_win;
365
366 BTM_TRACE_EVENT0 ("btm_ble_start_select_conn");
367
368 scan_int = (p_cb->scan_int == BTM_BLE_CONN_PARAM_UNDEF) ? BTM_BLE_SCAN_FAST_INT : p_cb->scan_int;
369 scan_win = (p_cb->scan_win == BTM_BLE_CONN_PARAM_UNDEF) ? BTM_BLE_SCAN_FAST_WIN : p_cb->scan_win;
370
371 if (start)
372 {
373 if (btm_cb.btm_inq_vars.inq_active == BTM_INQUIRY_INACTIVE)
374 {
375 if (p_select_cback != NULL)
376 btm_cb.ble_ctr_cb.p_select_cback = p_select_cback;
377
378 btm_update_scanner_filter_policy(SP_ADV_WL);
379 btm_cb.ble_ctr_cb.inq_var.scan_type = BTM_BLE_SCAN_MODE_PASS;
380
381 if (!btsnd_hcic_ble_set_scan_params(BTM_BLE_SCAN_MODE_PASS, /* use passive scan by default */
382 scan_int, /* scan interval */
383 scan_win, /* scan window */
384 BLE_ADDR_PUBLIC, /* own device, DUMO always use public */
385 SP_ADV_WL) /* process advertising packets only from devices in the White List */
386 )
387 return FALSE;
388
389 if (p_cb->inq_var.adv_mode == BTM_BLE_ADV_ENABLE
390 )
391 {
392 BTM_TRACE_ERROR0("peripheral device cannot initiate a selective connection");
393 return FALSE;
394 }
395 else if (p_cb->bg_dev_num > 0 && btm_ble_count_unconn_dev_in_whitelist() > 0 )
396 {
397
398 if (!btsnd_hcic_ble_set_scan_enable(TRUE, TRUE)) /* duplicate filtering enabled */
399 return FALSE;
400
401 /* mark up inquiry status flag */
402 btm_cb.btm_inq_vars.inq_active |= BTM_LE_SELECT_CONN_ACTIVE;
403 p_cb->inq_var.proc_mode = BTM_BLE_SELECT_SCAN;
404 p_cb->conn_state = BLE_BG_CONN;
405 }
406 }
407 else
408 {
409 BTM_TRACE_ERROR0("scan active, can not start selective connection procedure");
410 return FALSE;
411 }
412 }
413 else /* disable selective connection mode */
414 {
415 btm_cb.btm_inq_vars.inq_active &= ~BTM_LE_SELECT_CONN_ACTIVE;
416 btm_cb.ble_ctr_cb.inq_var.proc_mode = BTM_BLE_INQUIRY_NONE;
417
418 btm_update_scanner_filter_policy(SP_ADV_ALL);
419 /* stop scanning */
420 if (p_cb->bg_dev_num > 0)
421 {
422 if (!btsnd_hcic_ble_set_scan_enable(FALSE, TRUE)) /* duplicate filtering enabled */
423 return FALSE;
424 }
425 }
426 return TRUE;
427 }
428 /*******************************************************************************
429 **
430 ** Function btm_ble_initiate_select_conn
431 **
432 ** Description This function is to start/stop selective connection procedure.
433 **
434 ** Parameters start: TRUE to start; FALSE to stop.
435 ** p_select_cback: callback function to return application
436 ** selection.
437 **
438 ** Returns BOOLEAN: selective connectino procedure is started.
439 **
440 *******************************************************************************/
btm_ble_initiate_select_conn(BD_ADDR bda)441 void btm_ble_initiate_select_conn(BD_ADDR bda)
442 {
443 BTM_TRACE_EVENT0 ("btm_ble_initiate_select_conn");
444
445 /* use direct connection procedure to initiate connection */
446 if (!L2CA_ConnectFixedChnl(L2CAP_ATT_CID, bda))
447 {
448 BTM_TRACE_ERROR0("btm_ble_initiate_select_conn failed");
449 }
450 }
451 /*******************************************************************************
452 **
453 ** Function btm_ble_suspend_bg_conn
454 **
455 ** Description This function is to suspend an active background connection
456 ** procedure.
457 **
458 ** Parameters none.
459 **
460 ** Returns none.
461 **
462 *******************************************************************************/
btm_ble_suspend_bg_conn(void)463 void btm_ble_suspend_bg_conn(void)
464 {
465 tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb;
466 BTM_TRACE_EVENT0 ("btm_ble_suspend_bg_conn");
467
468 if (p_cb->bg_conn_type == BTM_BLE_CONN_AUTO)
469 {
470 btm_ble_start_auto_conn(FALSE);
471 }
472 else if (p_cb->bg_conn_type == BTM_BLE_CONN_SELECTIVE)
473 {
474 btm_ble_start_select_conn(FALSE, NULL);
475 }
476 }
477 /*******************************************************************************
478 **
479 ** Function btm_suspend_wl_activity
480 **
481 ** Description This function is to suspend white list related activity
482 **
483 ** Returns none.
484 **
485 *******************************************************************************/
btm_suspend_wl_activity(tBTM_BLE_WL_STATE wl_state)486 static void btm_suspend_wl_activity(tBTM_BLE_WL_STATE wl_state)
487 {
488 if (wl_state & BTM_BLE_WL_INIT)
489 {
490 btm_ble_start_auto_conn(FALSE);
491 }
492 if (wl_state & BTM_BLE_WL_SCAN)
493 {
494 btm_ble_start_select_conn(FALSE, NULL);
495 }
496 if (wl_state & BTM_BLE_WL_ADV)
497 {
498 btsnd_hcic_ble_set_adv_enable(BTM_BLE_ADV_DISABLE);
499 }
500
501 }
502 /*******************************************************************************
503 **
504 ** Function btm_resume_wl_activity
505 **
506 ** Description This function is to resume white list related activity
507 **
508 ** Returns none.
509 **
510 *******************************************************************************/
btm_resume_wl_activity(tBTM_BLE_WL_STATE wl_state)511 static void btm_resume_wl_activity(tBTM_BLE_WL_STATE wl_state)
512 {
513 btm_ble_resume_bg_conn();
514
515 if (wl_state & BTM_BLE_WL_ADV)
516 {
517 btsnd_hcic_ble_set_adv_enable(BTM_BLE_ADV_ENABLE);
518 }
519
520 }
521 /*******************************************************************************
522 **
523 ** Function btm_ble_resume_bg_conn
524 **
525 ** Description This function is to resume a background auto connection
526 ** procedure.
527 **
528 ** Parameters none.
529 **
530 ** Returns none.
531 **
532 *******************************************************************************/
btm_ble_resume_bg_conn(void)533 BOOLEAN btm_ble_resume_bg_conn(void)
534 {
535 tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb;
536 BOOLEAN ret = FALSE;
537
538 if (p_cb->bg_conn_type != BTM_BLE_CONN_NONE)
539 {
540 if (p_cb->bg_conn_type == BTM_BLE_CONN_AUTO)
541 ret = btm_ble_start_auto_conn(TRUE);
542
543 if (p_cb->bg_conn_type == BTM_BLE_CONN_SELECTIVE)
544 ret = btm_ble_start_select_conn(TRUE, btm_cb.ble_ctr_cb.p_select_cback);
545 }
546
547 return ret;
548 }
549 /*******************************************************************************
550 **
551 ** Function btm_ble_get_conn_st
552 **
553 ** Description This function get BLE connection state
554 **
555 ** Returns connection state
556 **
557 *******************************************************************************/
btm_ble_get_conn_st(void)558 tBTM_BLE_CONN_ST btm_ble_get_conn_st(void)
559 {
560 return btm_cb.ble_ctr_cb.conn_state;
561 }
562 /*******************************************************************************
563 **
564 ** Function btm_ble_set_conn_st
565 **
566 ** Description This function set BLE connection state
567 **
568 ** Returns None.
569 **
570 *******************************************************************************/
btm_ble_set_conn_st(tBTM_BLE_CONN_ST new_st)571 void btm_ble_set_conn_st(tBTM_BLE_CONN_ST new_st)
572 {
573 btm_cb.ble_ctr_cb.conn_state = new_st;
574 }
575
576 /*******************************************************************************
577 **
578 ** Function btm_ble_enqueue_direct_conn_req
579 **
580 ** Description This function enqueue the direct connection request
581 **
582 ** Returns None.
583 **
584 *******************************************************************************/
btm_ble_enqueue_direct_conn_req(void * p_param)585 void btm_ble_enqueue_direct_conn_req(void *p_param)
586 {
587 tBTM_BLE_CONN_REQ *p = (tBTM_BLE_CONN_REQ *)GKI_getbuf(sizeof(tBTM_BLE_CONN_REQ));
588
589 p->p_param = p_param;
590
591 GKI_enqueue (&btm_cb.ble_ctr_cb.conn_pending_q, p);
592 }
593 /*******************************************************************************
594 **
595 ** Function btm_send_pending_direct_conn
596 **
597 ** Description This function send the pending direct connection request in queue
598 **
599 ** Returns TRUE if started, FALSE otherwise
600 **
601 *******************************************************************************/
btm_send_pending_direct_conn(void)602 BOOLEAN btm_send_pending_direct_conn(void )
603 {
604 tBTM_BLE_CONN_REQ *p_req;
605 BOOLEAN rt = FALSE;
606
607 if ( btm_cb.ble_ctr_cb.conn_pending_q.count )
608 {
609 p_req = (tBTM_BLE_CONN_REQ*)GKI_dequeue (&btm_cb.ble_ctr_cb.conn_pending_q);
610
611 rt = l2cble_init_direct_conn((tL2C_LCB *)(p_req->p_param));
612
613 GKI_freebuf((void *)p_req);
614 }
615
616 return rt;
617 }
618 #endif
619
620
621