]> granicus.if.org Git - esp-idf/blob - components/bt/bluedroid/stack/btm/btm_ble_bgconn.c
Merge branch 'bugfix/spiram_malloc_reserve_internal_fragments' into 'master'
[esp-idf] / components / bt / bluedroid / stack / btm / btm_ble_bgconn.c
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 #include "common/bt_trace.h"
27 #include "device/controller.h"
28 #include "osi/allocator.h"
29 #include "osi/hash_map.h"
30 #include "stack/bt_types.h"
31 #include "stack/btu.h"
32 #include "btm_int.h"
33 #include "l2c_int.h"
34 #include "stack/hcimsgs.h"
35 //#include "bt_utils.h"
36
37 #ifndef BTM_BLE_SCAN_PARAM_TOUT
38 #define BTM_BLE_SCAN_PARAM_TOUT      50    /* 50 seconds */
39 #endif
40
41 #if (BLE_INCLUDED == TRUE)
42
43 static void btm_suspend_wl_activity(tBTM_BLE_WL_STATE wl_state);
44 static void btm_wl_update_to_controller(void);
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 static const size_t background_connection_buckets = 42;
52 static hash_map_t *background_connections = NULL;
53
54 typedef struct background_connection_t {
55     bt_bdaddr_t address;
56 } background_connection_t;
57
58 static bool bdaddr_equality_fn(const void *x, const void *y)
59 {
60     return bdaddr_equals((bt_bdaddr_t *)x, (bt_bdaddr_t *)y);
61 }
62
63 static void background_connections_lazy_init()
64 {
65     if (!background_connections) {
66         background_connections = hash_map_new(background_connection_buckets,
67                                       hash_function_bdaddr, NULL, osi_free_func, bdaddr_equality_fn);
68         assert(background_connections);
69     }
70 }
71
72 static BOOLEAN background_connection_add(bt_bdaddr_t *address)
73 {
74     assert(address);
75     background_connections_lazy_init();
76     background_connection_t *connection = hash_map_get(background_connections, address);
77     if (!connection) {
78         connection = osi_calloc(sizeof(background_connection_t));
79         connection->address = *address;
80         hash_map_set(background_connections, &(connection->address), connection);
81         return TRUE;
82     }
83     return FALSE;
84 }
85
86 static BOOLEAN background_connection_remove(bt_bdaddr_t *address)
87 {
88     if (address && background_connections) {
89         return hash_map_erase(background_connections, address);
90     }
91     return FALSE;
92 }
93
94 static void background_connections_clear()
95 {
96     if (background_connections) {
97         hash_map_clear(background_connections);
98     }
99 }
100
101 static bool background_connections_pending_cb(hash_map_entry_t *hash_entry, void *context)
102 {
103     bool *pending_connections = context;
104     background_connection_t *connection = hash_entry->data;
105     const bool connected = BTM_IsAclConnectionUp(connection->address.address, BT_TRANSPORT_LE);
106     if (!connected) {
107         *pending_connections = true;
108         return false;
109     }
110     return true;
111 }
112
113 static bool background_connections_pending()
114 {
115     bool pending_connections = false;
116     if (background_connections) {
117         hash_map_foreach(background_connections, background_connections_pending_cb, &pending_connections);
118     }
119     return pending_connections;
120 }
121
122 /*******************************************************************************
123 **
124 ** Function         btm_update_scanner_filter_policy
125 **
126 ** Description      This function updates the filter policy of scanner
127 *******************************************************************************/
128 void btm_update_scanner_filter_policy(tBTM_BLE_SFP scan_policy)
129 {
130     tBTM_BLE_INQ_CB *p_inq = &btm_cb.ble_ctr_cb.inq_var;
131
132     UINT32 scan_interval = !p_inq->scan_interval ? BTM_BLE_GAP_DISC_SCAN_INT : p_inq->scan_interval;
133     UINT32 scan_window = !p_inq->scan_window ? BTM_BLE_GAP_DISC_SCAN_WIN : p_inq->scan_window;
134
135     BTM_TRACE_EVENT ("%s\n", __func__);
136
137     p_inq->sfp = scan_policy;
138     p_inq->scan_type = p_inq->scan_type == BTM_BLE_SCAN_MODE_NONE ? BTM_BLE_SCAN_MODE_ACTI : p_inq->scan_type;
139
140     if (btm_cb.cmn_ble_vsc_cb.extended_scan_support == 0) {
141         btsnd_hcic_ble_set_scan_params(p_inq->scan_type, (UINT16)scan_interval,
142                                        (UINT16)scan_window,
143                                        btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type,
144                                        scan_policy);
145     } else {
146         btm_ble_send_extended_scan_params(p_inq->scan_type, scan_interval, scan_window,
147                                           btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type,
148                                           scan_policy);
149     }
150 }
151 /*******************************************************************************
152 **
153 ** Function         btm_add_dev_to_controller
154 **
155 ** Description      This function load the device into controller white list
156 *******************************************************************************/
157 BOOLEAN btm_add_dev_to_controller (BOOLEAN to_add, BD_ADDR bd_addr)
158 {
159     tBTM_SEC_DEV_REC    *p_dev_rec = btm_find_dev (bd_addr);
160     tBLE_ADDR_TYPE  addr_type = BLE_ADDR_PUBLIC;
161     BOOLEAN             started = FALSE;
162     BD_ADDR             dummy_bda = {0};
163     tBT_DEVICE_TYPE dev_type;
164
165     if (p_dev_rec != NULL &&
166             p_dev_rec->device_type & BT_DEVICE_TYPE_BLE) {
167         if (to_add) {
168             if (p_dev_rec->ble.ble_addr_type == BLE_ADDR_PUBLIC || !BTM_BLE_IS_RESOLVE_BDA(bd_addr)) {
169                 started = btsnd_hcic_ble_add_white_list (p_dev_rec->ble.ble_addr_type, bd_addr);
170                 p_dev_rec->ble.in_controller_list |= BTM_WHITE_LIST_BIT;
171             } else if (memcmp(p_dev_rec->ble.static_addr, bd_addr, BD_ADDR_LEN) != 0 &&
172                        memcmp(p_dev_rec->ble.static_addr, dummy_bda, BD_ADDR_LEN) != 0) {
173                 started = btsnd_hcic_ble_add_white_list (p_dev_rec->ble.static_addr_type,
174                           p_dev_rec->ble.static_addr);
175                 p_dev_rec->ble.in_controller_list |= BTM_WHITE_LIST_BIT;
176             }
177         } else {
178             if (p_dev_rec->ble.ble_addr_type == BLE_ADDR_PUBLIC || !BTM_BLE_IS_RESOLVE_BDA(bd_addr)) {
179                 started = btsnd_hcic_ble_remove_from_white_list (p_dev_rec->ble.ble_addr_type, bd_addr);
180             }
181             if (memcmp(p_dev_rec->ble.static_addr, dummy_bda, BD_ADDR_LEN) != 0 &&
182                     memcmp(p_dev_rec->ble.static_addr, bd_addr, BD_ADDR_LEN) != 0) {
183                 started = btsnd_hcic_ble_remove_from_white_list (p_dev_rec->ble.static_addr_type, p_dev_rec->ble.static_addr);
184             }
185             p_dev_rec->ble.in_controller_list &= ~BTM_WHITE_LIST_BIT;
186         }
187     }    /* if not a known device, shall we add it? */
188     else {
189         BTM_ReadDevInfo(bd_addr, &dev_type, &addr_type);
190
191         if (to_add) {
192             started = btsnd_hcic_ble_add_white_list (addr_type, bd_addr);
193         }else{
194             started = btsnd_hcic_ble_remove_from_white_list (addr_type, bd_addr);
195         }
196     }
197
198     return started;
199
200 }
201 /*******************************************************************************
202 **
203 ** Function         btm_execute_wl_dev_operation
204 **
205 ** Description      execute the pending whitelist device operation(loading or removing)
206 *******************************************************************************/
207 BOOLEAN btm_execute_wl_dev_operation(void)
208 {
209     tBTM_BLE_WL_OP *p_dev_op = btm_cb.ble_ctr_cb.wl_op_q;
210     UINT8   i = 0;
211     BOOLEAN rt = TRUE;
212
213     for (i = 0; i < BTM_BLE_MAX_BG_CONN_DEV_NUM && rt; i ++, p_dev_op ++) {
214         if (p_dev_op->in_use) {
215             rt = btm_add_dev_to_controller(p_dev_op->to_add, p_dev_op->bd_addr);
216             memset(p_dev_op, 0, sizeof(tBTM_BLE_WL_OP));
217         } else {
218             break;
219         }
220     }
221     return rt;
222 }
223 /*******************************************************************************
224 **
225 ** Function         btm_enq_wl_dev_operation
226 **
227 ** Description      enqueue the pending whitelist device operation(loading or removing).
228 *******************************************************************************/
229 void btm_enq_wl_dev_operation(BOOLEAN to_add, BD_ADDR bd_addr)
230 {
231     tBTM_BLE_WL_OP *p_dev_op = btm_cb.ble_ctr_cb.wl_op_q;
232     UINT8   i = 0;
233
234     for (i = 0; i < BTM_BLE_MAX_BG_CONN_DEV_NUM; i ++, p_dev_op ++) {
235         if (p_dev_op->in_use && !memcmp(p_dev_op->bd_addr, bd_addr, BD_ADDR_LEN)) {
236             p_dev_op->to_add = to_add;
237             return;
238         } else if (!p_dev_op->in_use) {
239             break;
240         }
241     }
242     if (i != BTM_BLE_MAX_BG_CONN_DEV_NUM) {
243         p_dev_op->in_use = TRUE;
244         p_dev_op->to_add = to_add;
245         memcpy(p_dev_op->bd_addr, bd_addr, BD_ADDR_LEN);
246     } else {
247         BTM_TRACE_ERROR("max pending WL operation reached, discard");
248     }
249     return;
250 }
251
252 /*******************************************************************************
253 **
254 ** Function         btm_update_dev_to_white_list
255 **
256 ** Description      This function adds or removes a device into/from
257 **                  the white list.
258 **
259 *******************************************************************************/
260 BOOLEAN btm_update_dev_to_white_list(BOOLEAN to_add, BD_ADDR bd_addr, tBTM_ADD_WHITELIST_CBACK *add_wl_cb)
261 {
262     tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb;
263
264     if (to_add && p_cb->white_list_avail_size == 0) {
265         BTM_TRACE_ERROR("%s Whitelist full, unable to add device", __func__);
266         if (add_wl_cb){
267             add_wl_cb(HCI_ERR_MEMORY_FULL,to_add);
268         }
269         return FALSE;
270     }
271
272     if (to_add) {
273         /* added the bd_addr to the connection hash map queue */
274         if(!background_connection_add((bt_bdaddr_t *)bd_addr)) {
275             /* if the bd_addr already exist in whitelist, just callback return TRUE */
276             if (add_wl_cb){
277                 add_wl_cb(HCI_SUCCESS,to_add);
278             }
279             return TRUE;
280         }
281     } else {
282         /* remove the bd_addr to the connection hash map queue */
283         if(!background_connection_remove((bt_bdaddr_t *)bd_addr)){
284             /* if the bd_addr don't exist in whitelist, just callback return TRUE */
285             if (add_wl_cb){
286                 add_wl_cb(HCI_SUCCESS,to_add);
287             }
288             return TRUE;
289         }
290     }
291
292     if (add_wl_cb){
293         //save add whitelist complete callback
294         p_cb->add_wl_cb = add_wl_cb;
295     }
296     /* stop the auto connect */
297     btm_suspend_wl_activity(p_cb->wl_state);
298     /* save the bd_addr to the btm_cb env */
299     btm_enq_wl_dev_operation(to_add, bd_addr);
300     /* save the ba_addr to the controller white list */
301     btm_wl_update_to_controller();
302     return TRUE;
303 }
304
305 /*******************************************************************************
306 **
307 ** Function         btm_ble_clear_white_list
308 **
309 ** Description      This function clears the white list.
310 **
311 *******************************************************************************/
312 void btm_ble_clear_white_list (void)
313 {
314     BTM_TRACE_EVENT ("btm_ble_clear_white_list");
315     btsnd_hcic_ble_clear_white_list();
316     background_connections_clear();
317 }
318
319 /*******************************************************************************
320 **
321 ** Function         btm_ble_clear_white_list_complete
322 **
323 ** Description      Indicates white list cleared.
324 **
325 *******************************************************************************/
326 void btm_ble_clear_white_list_complete(UINT8 *p_data, UINT16 evt_len)
327 {
328     tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb;
329     UINT8       status;
330     UNUSED(evt_len);
331
332     BTM_TRACE_EVENT ("btm_ble_clear_white_list_complete");
333     STREAM_TO_UINT8  (status, p_data);
334
335     if (status == HCI_SUCCESS) {
336         p_cb->white_list_avail_size = controller_get_interface()->get_ble_white_list_size();
337     }
338 }
339
340 /*******************************************************************************
341 **
342 ** Function         btm_ble_white_list_init
343 **
344 ** Description      Initialize white list size
345 **
346 *******************************************************************************/
347 void btm_ble_white_list_init(UINT8 white_list_size)
348 {
349     BTM_TRACE_DEBUG("%s white_list_size = %d", __func__, white_list_size);
350     btm_cb.ble_ctr_cb.white_list_avail_size = white_list_size;
351 }
352
353 /*******************************************************************************
354 **
355 ** Function         btm_ble_add_2_white_list_complete
356 **
357 ** Description      White list element added
358 **
359 *******************************************************************************/
360 void btm_ble_add_2_white_list_complete(UINT8 status)
361 {
362     BTM_TRACE_EVENT("%s status=%d", __func__, status);
363     tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb;
364     if (status == HCI_SUCCESS) {
365         --btm_cb.ble_ctr_cb.white_list_avail_size;
366     }
367     // add whitelist complete callback
368     if (p_cb->add_wl_cb)
369     {
370         (*p_cb->add_wl_cb)(status, BTM_WHITELIST_ADD);
371     }
372
373 }
374
375 /*******************************************************************************
376 **
377 ** Function         btm_ble_remove_from_white_list_complete
378 **
379 ** Description      White list element removal complete
380 **
381 *******************************************************************************/
382 void btm_ble_remove_from_white_list_complete(UINT8 *p, UINT16 evt_len)
383 {
384     tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb;
385     UNUSED(evt_len);
386     BTM_TRACE_EVENT ("%s status=%d", __func__, *p);
387     if (*p == HCI_SUCCESS) {
388         ++btm_cb.ble_ctr_cb.white_list_avail_size;
389     }
390     if (p_cb->add_wl_cb)
391     {
392         (*p_cb->add_wl_cb)(*p, BTM_WHITELIST_REMOVE);
393     }
394 }
395
396 /*******************************************************************************
397 **
398 ** Function         btm_ble_start_auto_conn
399 **
400 ** Description      This function is to start/stop auto connection procedure.
401 **
402 ** Parameters       start: TRUE to start; FALSE to stop.
403 **
404 ** Returns          void
405 **
406 *******************************************************************************/
407 BOOLEAN btm_ble_start_auto_conn(BOOLEAN start)
408 {
409     tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb;
410     BD_ADDR dummy_bda = {0};
411     BOOLEAN exec = TRUE;
412     UINT16 scan_int;
413     UINT16 scan_win;
414     UINT8 own_addr_type = p_cb->addr_mgnt_cb.own_addr_type;
415     UINT8 peer_addr_type = BLE_ADDR_PUBLIC;
416
417     if (start) {
418         if (p_cb->conn_state == BLE_CONN_IDLE && background_connections_pending()
419                 && btm_ble_topology_check(BTM_BLE_STATE_INIT)) {
420             p_cb->wl_state  |= BTM_BLE_WL_INIT;
421
422             btm_execute_wl_dev_operation();
423
424 #if BLE_PRIVACY_SPT == TRUE
425             btm_ble_enable_resolving_list_for_platform(BTM_BLE_RL_INIT);
426 #endif
427             scan_int = (p_cb->scan_int == BTM_BLE_SCAN_PARAM_UNDEF) ?
428                        BTM_BLE_SCAN_SLOW_INT_1 : p_cb->scan_int;
429             scan_win = (p_cb->scan_win == BTM_BLE_SCAN_PARAM_UNDEF) ?
430                        BTM_BLE_SCAN_SLOW_WIN_1 : p_cb->scan_win;
431
432 #if BLE_PRIVACY_SPT == TRUE
433             if (btm_cb.ble_ctr_cb.rl_state != BTM_BLE_RL_IDLE
434                     && controller_get_interface()->supports_ble_privacy()) {
435                 own_addr_type |= BLE_ADDR_TYPE_ID_BIT;
436                 peer_addr_type |= BLE_ADDR_TYPE_ID_BIT;
437             }
438 #endif
439
440             if (!btsnd_hcic_ble_create_ll_conn (scan_int,  /* UINT16 scan_int      */
441                                                 scan_win,    /* UINT16 scan_win      */
442                                                 0x01,                   /* UINT8 white_list     */
443                                                 peer_addr_type,        /* UINT8 addr_type_peer */
444                                                 dummy_bda,              /* BD_ADDR bda_peer     */
445                                                 own_addr_type,          /* UINT8 addr_type_own */
446                                                 BTM_BLE_CONN_INT_MIN_DEF,   /* UINT16 conn_int_min  */
447                                                 BTM_BLE_CONN_INT_MAX_DEF,   /* UINT16 conn_int_max  */
448                                                 BTM_BLE_CONN_SLAVE_LATENCY_DEF,  /* UINT16 conn_latency  */
449                                                 BTM_BLE_CONN_TIMEOUT_DEF,        /* UINT16 conn_timeout  */
450                                                 0,                       /* UINT16 min_len       */
451                                                 0)) {                    /* UINT16 max_len       */
452                 /* start auto connection failed */
453                 exec =  FALSE;
454                 p_cb->wl_state &= ~BTM_BLE_WL_INIT;
455             } else {
456                 btm_ble_set_conn_st (BLE_BG_CONN);
457             }
458         } else {
459             exec = FALSE;
460         }
461     } else {
462         if (p_cb->conn_state == BLE_BG_CONN) {
463             btsnd_hcic_ble_create_conn_cancel();
464             btm_ble_set_conn_st (BLE_CONN_CANCEL);
465             p_cb->wl_state &= ~BTM_BLE_WL_INIT;
466         } else {
467             BTM_TRACE_DEBUG("conn_st = %d, not in auto conn state, cannot stop", p_cb->conn_state);
468             exec = FALSE;
469         }
470     }
471     return exec;
472 }
473
474 /*******************************************************************************
475 **
476 ** Function         btm_ble_start_select_conn
477 **
478 ** Description      This function is to start/stop selective connection procedure.
479 **
480 ** Parameters       start: TRUE to start; FALSE to stop.
481 **                  p_select_cback: callback function to return application
482 **                                  selection.
483 **
484 ** Returns          BOOLEAN: selective connection procedure is started.
485 **
486 *******************************************************************************/
487 BOOLEAN btm_ble_start_select_conn(BOOLEAN start, tBTM_BLE_SEL_CBACK *p_select_cback)
488 {
489     tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb;
490     UINT32 scan_int = p_cb->scan_int == BTM_BLE_SCAN_PARAM_UNDEF ? BTM_BLE_SCAN_FAST_INT : p_cb->scan_int;
491     UINT32 scan_win = p_cb->scan_win == BTM_BLE_SCAN_PARAM_UNDEF ? BTM_BLE_SCAN_FAST_WIN : p_cb->scan_win;
492
493     BTM_TRACE_EVENT ("%s", __func__);
494
495     if (start) {
496         if (!BTM_BLE_IS_SCAN_ACTIVE(p_cb->scan_activity)) {
497             if (p_select_cback != NULL) {
498                 btm_cb.ble_ctr_cb.p_select_cback = p_select_cback;
499             }
500
501             btm_execute_wl_dev_operation();
502
503             btm_update_scanner_filter_policy(SP_ADV_WL);
504             btm_cb.ble_ctr_cb.inq_var.scan_type = BTM_BLE_SCAN_MODE_PASS;
505
506             /* Process advertising packets only from devices in the white list */
507             if (btm_cb.cmn_ble_vsc_cb.extended_scan_support == 0) {
508                 /* use passive scan by default */
509                 if (!btsnd_hcic_ble_set_scan_params(BTM_BLE_SCAN_MODE_PASS,
510                                                     scan_int,
511                                                     scan_win,
512                                                     p_cb->addr_mgnt_cb.own_addr_type,
513                                                     SP_ADV_WL)) {
514                     return FALSE;
515                 }
516             } else {
517                 if (!btm_ble_send_extended_scan_params(BTM_BLE_SCAN_MODE_PASS,
518                                                        scan_int,
519                                                        scan_win,
520                                                        p_cb->addr_mgnt_cb.own_addr_type,
521                                                        SP_ADV_WL)) {
522                     return FALSE;
523                 }
524             }
525
526             if (!btm_ble_topology_check(BTM_BLE_STATE_PASSIVE_SCAN)) {
527                 BTM_TRACE_ERROR("peripheral device cannot initiate passive scan for a selective connection");
528                 return FALSE;
529             } else if (background_connections_pending()) {
530 #if BLE_PRIVACY_SPT == TRUE
531                 btm_ble_enable_resolving_list_for_platform(BTM_BLE_RL_SCAN);
532 #endif
533                 if (!btsnd_hcic_ble_set_scan_enable(TRUE, TRUE)) { /* duplicate filtering enabled */
534                     return FALSE;
535                 }
536                 /* mark up inquiry status flag */
537                 p_cb->scan_activity |= BTM_LE_SELECT_CONN_ACTIVE;
538                 p_cb->wl_state |= BTM_BLE_WL_SCAN;
539             }
540         } else {
541             BTM_TRACE_ERROR("scan active, can not start selective connection procedure");
542             return FALSE;
543         }
544     } else { /* disable selective connection mode */
545         p_cb->scan_activity &= ~BTM_LE_SELECT_CONN_ACTIVE;
546         p_cb->p_select_cback = NULL;
547         p_cb->wl_state &= ~BTM_BLE_WL_SCAN;
548
549         /* stop scanning */
550         if (!BTM_BLE_IS_SCAN_ACTIVE(p_cb->scan_activity)) {
551             btm_ble_stop_scan();    /* duplicate filtering enabled */
552         }
553     }
554     return TRUE;
555 }
556 /*******************************************************************************
557 **
558 ** Function         btm_ble_initiate_select_conn
559 **
560 ** Description      This function is to start/stop selective connection procedure.
561 **
562 ** Parameters       start: TRUE to start; FALSE to stop.
563 **                  p_select_cback: callback function to return application
564 **                                  selection.
565 **
566 ** Returns          BOOLEAN: selective connection procedure is started.
567 **
568 *******************************************************************************/
569 void btm_ble_initiate_select_conn(BD_ADDR bda)
570 {
571     BTM_TRACE_EVENT ("btm_ble_initiate_select_conn");
572
573     /* use direct connection procedure to initiate connection */
574     if (!L2CA_ConnectFixedChnl(L2CAP_ATT_CID, bda, BLE_ADDR_UNKNOWN_TYPE)) {
575         BTM_TRACE_ERROR("btm_ble_initiate_select_conn failed");
576     }
577 }
578 /*******************************************************************************
579 **
580 ** Function         btm_ble_suspend_bg_conn
581 **
582 ** Description      This function is to suspend an active background connection
583 **                  procedure.
584 **
585 ** Parameters       none.
586 **
587 ** Returns          none.
588 **
589 *******************************************************************************/
590 BOOLEAN btm_ble_suspend_bg_conn(void)
591 {
592     BTM_TRACE_EVENT ("%s\n", __func__);
593
594     if (btm_cb.ble_ctr_cb.bg_conn_type == BTM_BLE_CONN_AUTO) {
595         return btm_ble_start_auto_conn(FALSE);
596     } else if (btm_cb.ble_ctr_cb.bg_conn_type == BTM_BLE_CONN_SELECTIVE) {
597         return btm_ble_start_select_conn(FALSE, NULL);
598     }
599
600     return FALSE;
601 }
602 /*******************************************************************************
603 **
604 ** Function         btm_suspend_wl_activity
605 **
606 ** Description      This function is to suspend white list related activity
607 **
608 ** Returns          none.
609 **
610 *******************************************************************************/
611 static void btm_suspend_wl_activity(tBTM_BLE_WL_STATE wl_state)
612 {
613     if (wl_state & BTM_BLE_WL_INIT) {
614         btm_ble_start_auto_conn(FALSE);
615     }
616     if (wl_state & BTM_BLE_WL_SCAN) {
617         btm_ble_start_select_conn(FALSE, NULL);
618     }
619     if (wl_state & BTM_BLE_WL_ADV) {
620         btm_ble_stop_adv();
621     }
622
623 }
624 /*******************************************************************************
625 **
626 ** Function         btm_resume_wl_activity
627 **
628 ** Description      This function is to resume white list related activity
629 **
630 ** Returns          none.
631 **
632 *******************************************************************************/
633 void btm_resume_wl_activity(tBTM_BLE_WL_STATE wl_state)
634 {
635     btm_ble_resume_bg_conn();
636     if (wl_state & BTM_BLE_WL_ADV) {
637         btm_ble_start_adv();
638     }
639
640 }
641
642 /*******************************************************************************
643 **
644 ** Function         btm_wl_update_to_controller
645 **
646 ** Description      This function is to update white list to controller
647 **
648 ** Returns          none.
649 **
650 *******************************************************************************/
651 static void btm_wl_update_to_controller(void)
652 {
653     /* whitelist will be added in the btm_ble_resume_bg_conn(), we do not
654        support background connection now, so we nedd to use btm_execute_wl_dev_operation
655        to add whitelist directly ,if we support background connection in the future,
656        please delete btm_execute_wl_dev_operation(). */
657     btm_execute_wl_dev_operation();
658
659 }
660 /*******************************************************************************
661 **
662 ** Function         btm_ble_resume_bg_conn
663 **
664 ** Description      This function is to resume a background auto connection
665 **                  procedure.
666 **
667 ** Parameters       none.
668 **
669 ** Returns          none.
670 **
671 *******************************************************************************/
672 BOOLEAN btm_ble_resume_bg_conn(void)
673 {
674     tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb;
675     BOOLEAN ret = FALSE;
676
677     if (p_cb->bg_conn_type != BTM_BLE_CONN_NONE) {
678         if (p_cb->bg_conn_type == BTM_BLE_CONN_AUTO) {
679             ret = btm_ble_start_auto_conn(TRUE);
680         }
681
682         if (p_cb->bg_conn_type == BTM_BLE_CONN_SELECTIVE) {
683             ret = btm_ble_start_select_conn(TRUE, btm_cb.ble_ctr_cb.p_select_cback);
684         }
685     }
686
687     return ret;
688 }
689 /*******************************************************************************
690 **
691 ** Function         btm_ble_get_conn_st
692 **
693 ** Description      This function get BLE connection state
694 **
695 ** Returns          connection state
696 **
697 *******************************************************************************/
698 tBTM_BLE_CONN_ST btm_ble_get_conn_st(void)
699 {
700     return btm_cb.ble_ctr_cb.conn_state;
701 }
702 /*******************************************************************************
703 **
704 ** Function         btm_ble_set_conn_st
705 **
706 ** Description      This function set BLE connection state
707 **
708 ** Returns          None.
709 **
710 *******************************************************************************/
711 void btm_ble_set_conn_st(tBTM_BLE_CONN_ST new_st)
712 {
713     btm_cb.ble_ctr_cb.conn_state = new_st;
714
715     if (new_st == BLE_BG_CONN || new_st == BLE_DIR_CONN) {
716         btm_ble_set_topology_mask(BTM_BLE_STATE_INIT_BIT);
717     } else {
718         btm_ble_clear_topology_mask(BTM_BLE_STATE_INIT_BIT);
719     }
720 }
721
722 /*******************************************************************************
723 **
724 ** Function         btm_ble_enqueue_direct_conn_req
725 **
726 ** Description      This function enqueue the direct connection request
727 **
728 ** Returns          None.
729 **
730 *******************************************************************************/
731 void btm_ble_enqueue_direct_conn_req(void *p_param)
732 {
733     tBTM_BLE_CONN_REQ   *p = (tBTM_BLE_CONN_REQ *)osi_malloc(sizeof(tBTM_BLE_CONN_REQ));
734
735     p->p_param = p_param;
736
737     fixed_queue_enqueue(btm_cb.ble_ctr_cb.conn_pending_q, p);
738 }
739 /*******************************************************************************
740 **
741 ** Function         btm_send_pending_direct_conn
742 **
743 ** Description      This function send the pending direct connection request in queue
744 **
745 ** Returns          TRUE if started, FALSE otherwise
746 **
747 *******************************************************************************/
748 BOOLEAN btm_send_pending_direct_conn(void)
749 {
750     tBTM_BLE_CONN_REQ *p_req;
751     BOOLEAN     rt = FALSE;
752
753     p_req = (tBTM_BLE_CONN_REQ*)fixed_queue_try_dequeue(btm_cb.ble_ctr_cb.conn_pending_q);
754     if (p_req != NULL) {
755         rt = l2cble_init_direct_conn((tL2C_LCB *)(p_req->p_param));
756
757         osi_free((void *)p_req);
758     }
759
760     return rt;
761 }
762
763 #endif
764
765