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