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 tBLE_ADDR_TYPE addr_type = BLE_ADDR_PUBLIC; 153 BOOLEAN started = FALSE; 154 BD_ADDR dummy_bda = {0}; 155 tBT_DEVICE_TYPE dev_type; 156 157 if (p_dev_rec != NULL && 158 p_dev_rec->device_type & BT_DEVICE_TYPE_BLE) 159 { 160 if (to_add) 161 { 162 if (p_dev_rec->ble.ble_addr_type == BLE_ADDR_PUBLIC || !BTM_BLE_IS_RESOLVE_BDA(bd_addr)) 163 { 164 started = btsnd_hcic_ble_add_white_list (p_dev_rec->ble.ble_addr_type, bd_addr); 165 p_dev_rec->ble.in_controller_list |= BTM_WHITE_LIST_BIT; 166 } 167 else if (memcmp(p_dev_rec->ble.static_addr, bd_addr, BD_ADDR_LEN) != 0 && 168 memcmp(p_dev_rec->ble.static_addr, dummy_bda, BD_ADDR_LEN) != 0) 169 { 170 started = btsnd_hcic_ble_add_white_list (p_dev_rec->ble.static_addr_type, 171 p_dev_rec->ble.static_addr); 172 p_dev_rec->ble.in_controller_list |= BTM_WHITE_LIST_BIT; 173 } 174 } 175 else 176 { 177 if (p_dev_rec->ble.ble_addr_type == BLE_ADDR_PUBLIC || !BTM_BLE_IS_RESOLVE_BDA(bd_addr)) 178 { 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 { 184 started = btsnd_hcic_ble_remove_from_white_list (p_dev_rec->ble.static_addr_type, p_dev_rec->ble.static_addr); 185 } 186 p_dev_rec->ble.in_controller_list &= ~BTM_WHITE_LIST_BIT; 187 } 188 } /* if not a known device, shall we add it? */ 189 else 190 { 191 BTM_ReadDevInfo(bd_addr, &dev_type, &addr_type); 192 193 started = btsnd_hcic_ble_remove_from_white_list (addr_type, bd_addr); 194 if (to_add) 195 started = btsnd_hcic_ble_add_white_list (addr_type, bd_addr); 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 { 215 if (p_dev_op->in_use) 216 { 217 rt = btm_add_dev_to_controller(p_dev_op->to_add, p_dev_op->bd_addr); 218 memset(p_dev_op, 0, sizeof(tBTM_BLE_WL_OP)); 219 } 220 else 221 break; 222 } 223 return rt; 224 } 225 /******************************************************************************* 226 ** 227 ** Function btm_enq_wl_dev_operation 228 ** 229 ** Description enqueue the pending whitelist device operation(loading or removing). 230 *******************************************************************************/ 231 void btm_enq_wl_dev_operation(BOOLEAN to_add, BD_ADDR bd_addr) 232 { 233 tBTM_BLE_WL_OP *p_dev_op = btm_cb.ble_ctr_cb.wl_op_q; 234 UINT8 i = 0; 235 236 for (i = 0; i < BTM_BLE_MAX_BG_CONN_DEV_NUM; i ++, p_dev_op ++) 237 { 238 if (p_dev_op->in_use && !memcmp(p_dev_op->bd_addr, bd_addr, BD_ADDR_LEN)) 239 { 240 p_dev_op->to_add = to_add; 241 return; 242 } 243 else if (!p_dev_op->in_use) 244 break; 245 } 246 if (i != BTM_BLE_MAX_BG_CONN_DEV_NUM) 247 { 248 p_dev_op->in_use = TRUE; 249 p_dev_op->to_add = to_add; 250 memcpy(p_dev_op->bd_addr, bd_addr, BD_ADDR_LEN); 251 } 252 else 253 { 254 BTM_TRACE_ERROR("max pending WL operation reached, discard"); 255 } 256 return; 257 } 258 259 /******************************************************************************* 260 ** 261 ** Function btm_update_dev_to_white_list 262 ** 263 ** Description This function adds or removes a device into/from 264 ** the white list. 265 ** 266 *******************************************************************************/ 267 BOOLEAN btm_update_dev_to_white_list(BOOLEAN to_add, BD_ADDR bd_addr) 268 { 269 tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb; 270 271 if (to_add && p_cb->white_list_avail_size == 0) 272 { 273 BTM_TRACE_ERROR("%s Whitelist full, unable to add device", __func__); 274 return FALSE; 275 } 276 277 if (to_add) 278 background_connection_add((bt_bdaddr_t*)bd_addr); 279 else 280 background_connection_remove((bt_bdaddr_t*)bd_addr); 281 282 btm_suspend_wl_activity(p_cb->wl_state); 283 btm_enq_wl_dev_operation(to_add, bd_addr); 284 btm_resume_wl_activity(p_cb->wl_state); 285 return TRUE; 286 } 287 288 /******************************************************************************* 289 ** 290 ** Function btm_ble_clear_white_list 291 ** 292 ** Description This function clears the white list. 293 ** 294 *******************************************************************************/ 295 void btm_ble_clear_white_list (void) 296 { 297 BTM_TRACE_EVENT ("btm_ble_clear_white_list"); 298 btsnd_hcic_ble_clear_white_list(); 299 background_connections_clear(); 300 } 301 302 /******************************************************************************* 303 ** 304 ** Function btm_ble_clear_white_list_complete 305 ** 306 ** Description Indicates white list cleared. 307 ** 308 *******************************************************************************/ 309 void btm_ble_clear_white_list_complete(UINT8 *p_data, UINT16 evt_len) 310 { 311 tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb; 312 UINT8 status; 313 UNUSED(evt_len); 314 315 BTM_TRACE_EVENT ("btm_ble_clear_white_list_complete"); 316 STREAM_TO_UINT8 (status, p_data); 317 318 if (status == HCI_SUCCESS) 319 p_cb->white_list_avail_size = controller_get_interface()->get_ble_white_list_size(); 320 } 321 322 /******************************************************************************* 323 ** 324 ** Function btm_ble_white_list_init 325 ** 326 ** Description Initialize white list size 327 ** 328 *******************************************************************************/ 329 void btm_ble_white_list_init(UINT8 white_list_size) 330 { 331 BTM_TRACE_DEBUG("%s white_list_size = %d", __func__, white_list_size); 332 btm_cb.ble_ctr_cb.white_list_avail_size = white_list_size; 333 } 334 335 /******************************************************************************* 336 ** 337 ** Function btm_ble_add_2_white_list_complete 338 ** 339 ** Description White list element added 340 ** 341 *******************************************************************************/ 342 void btm_ble_add_2_white_list_complete(UINT8 status) 343 { 344 BTM_TRACE_EVENT("%s status=%d", __func__, status); 345 if (status == HCI_SUCCESS) 346 --btm_cb.ble_ctr_cb.white_list_avail_size; 347 } 348 349 /******************************************************************************* 350 ** 351 ** Function btm_ble_remove_from_white_list_complete 352 ** 353 ** Description White list element removal complete 354 ** 355 *******************************************************************************/ 356 void btm_ble_remove_from_white_list_complete(UINT8 *p, UINT16 evt_len) 357 { 358 UNUSED(evt_len); 359 BTM_TRACE_EVENT ("%s status=%d", __func__, *p); 360 if (*p == HCI_SUCCESS) 361 ++btm_cb.ble_ctr_cb.white_list_avail_size; 362 } 363 364 /******************************************************************************* 365 ** 366 ** Function btm_ble_start_auto_conn 367 ** 368 ** Description This function is to start/stop auto connection procedure. 369 ** 370 ** Parameters start: TRUE to start; FALSE to stop. 371 ** 372 ** Returns void 373 ** 374 *******************************************************************************/ 375 BOOLEAN btm_ble_start_auto_conn(BOOLEAN start) 376 { 377 tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb; 378 BD_ADDR dummy_bda = {0}; 379 BOOLEAN exec = TRUE; 380 UINT16 scan_int; 381 UINT16 scan_win; 382 UINT8 own_addr_type = p_cb->addr_mgnt_cb.own_addr_type; 383 UINT8 peer_addr_type = BLE_ADDR_PUBLIC; 384 385 if (start) 386 { 387 if (p_cb->conn_state == BLE_CONN_IDLE && background_connections_pending() 388 && btm_ble_topology_check(BTM_BLE_STATE_INIT)) 389 { 390 p_cb->wl_state |= BTM_BLE_WL_INIT; 391 392 btm_execute_wl_dev_operation(); 393 394 #if BLE_PRIVACY_SPT == TRUE 395 btm_ble_enable_resolving_list_for_platform(BTM_BLE_RL_INIT); 396 #endif 397 scan_int = (p_cb->scan_int == BTM_BLE_SCAN_PARAM_UNDEF) ? 398 BTM_BLE_SCAN_SLOW_INT_1 : p_cb->scan_int; 399 scan_win = (p_cb->scan_win == BTM_BLE_SCAN_PARAM_UNDEF) ? 400 BTM_BLE_SCAN_SLOW_WIN_1 : p_cb->scan_win; 401 402 #if BLE_PRIVACY_SPT == TRUE 403 if (btm_cb.ble_ctr_cb.rl_state != BTM_BLE_RL_IDLE 404 && controller_get_interface()->supports_ble_privacy()) 405 { 406 own_addr_type |= BLE_ADDR_TYPE_ID_BIT; 407 peer_addr_type |= BLE_ADDR_TYPE_ID_BIT; 408 } 409 #endif 410 411 if (!btsnd_hcic_ble_create_ll_conn (scan_int, /* UINT16 scan_int */ 412 scan_win, /* UINT16 scan_win */ 413 0x01, /* UINT8 white_list */ 414 peer_addr_type, /* UINT8 addr_type_peer */ 415 dummy_bda, /* BD_ADDR bda_peer */ 416 own_addr_type, /* UINT8 addr_type_own */ 417 BTM_BLE_CONN_INT_MIN_DEF, /* UINT16 conn_int_min */ 418 BTM_BLE_CONN_INT_MAX_DEF, /* UINT16 conn_int_max */ 419 BTM_BLE_CONN_SLAVE_LATENCY_DEF, /* UINT16 conn_latency */ 420 BTM_BLE_CONN_TIMEOUT_DEF, /* UINT16 conn_timeout */ 421 0, /* UINT16 min_len */ 422 0)) /* UINT16 max_len */ 423 { 424 /* start auto connection failed */ 425 exec = FALSE; 426 p_cb->wl_state &= ~BTM_BLE_WL_INIT; 427 } 428 else 429 { 430 btm_ble_set_conn_st (BLE_BG_CONN); 431 } 432 } 433 else 434 { 435 exec = FALSE; 436 } 437 } 438 else 439 { 440 if (p_cb->conn_state == BLE_BG_CONN) 441 { 442 btsnd_hcic_ble_create_conn_cancel(); 443 btm_ble_set_conn_st (BLE_CONN_CANCEL); 444 p_cb->wl_state &= ~BTM_BLE_WL_INIT; 445 } 446 else 447 { 448 BTM_TRACE_DEBUG("conn_st = %d, not in auto conn state, cannot stop", p_cb->conn_state); 449 exec = FALSE; 450 } 451 } 452 return exec; 453 } 454 455 /******************************************************************************* 456 ** 457 ** Function btm_ble_start_select_conn 458 ** 459 ** Description This function is to start/stop selective connection procedure. 460 ** 461 ** Parameters start: TRUE to start; FALSE to stop. 462 ** p_select_cback: callback function to return application 463 ** selection. 464 ** 465 ** Returns BOOLEAN: selective connectino procedure is started. 466 ** 467 *******************************************************************************/ 468 BOOLEAN btm_ble_start_select_conn(BOOLEAN start, tBTM_BLE_SEL_CBACK *p_select_cback) 469 { 470 tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb; 471 UINT32 scan_int = p_cb->scan_int == BTM_BLE_SCAN_PARAM_UNDEF ? BTM_BLE_SCAN_FAST_INT : p_cb->scan_int; 472 UINT32 scan_win = p_cb->scan_win == BTM_BLE_SCAN_PARAM_UNDEF ? BTM_BLE_SCAN_FAST_WIN : p_cb->scan_win; 473 474 BTM_TRACE_EVENT ("%s", __func__); 475 476 if (start) 477 { 478 if (!BTM_BLE_IS_SCAN_ACTIVE(p_cb->scan_activity)) 479 { 480 if (p_select_cback != NULL) 481 btm_cb.ble_ctr_cb.p_select_cback = p_select_cback; 482 483 btm_execute_wl_dev_operation(); 484 485 btm_update_scanner_filter_policy(SP_ADV_WL); 486 btm_cb.ble_ctr_cb.inq_var.scan_type = BTM_BLE_SCAN_MODE_PASS; 487 488 /* Process advertising packets only from devices in the white list */ 489 if (btm_cb.cmn_ble_vsc_cb.extended_scan_support == 0) 490 { 491 /* use passive scan by default */ 492 if (!btsnd_hcic_ble_set_scan_params(BTM_BLE_SCAN_MODE_PASS, 493 scan_int, 494 scan_win, 495 p_cb->addr_mgnt_cb.own_addr_type, 496 SP_ADV_WL)) 497 { 498 return FALSE; 499 } 500 } 501 else 502 { 503 if (!btm_ble_send_extended_scan_params(BTM_BLE_SCAN_MODE_PASS, 504 scan_int, 505 scan_win, 506 p_cb->addr_mgnt_cb.own_addr_type, 507 SP_ADV_WL)) 508 { 509 return FALSE; 510 } 511 } 512 513 if (!btm_ble_topology_check(BTM_BLE_STATE_PASSIVE_SCAN)) 514 { 515 BTM_TRACE_ERROR("peripheral device cannot initiate passive scan for a selective connection"); 516 return FALSE; 517 } 518 else if (background_connections_pending()) 519 { 520 #if BLE_PRIVACY_SPT == TRUE 521 btm_ble_enable_resolving_list_for_platform(BTM_BLE_RL_SCAN); 522 #endif 523 if (!btsnd_hcic_ble_set_scan_enable(TRUE, TRUE)) /* duplicate filtering enabled */ 524 return FALSE; 525 /* mark up inquiry status flag */ 526 p_cb->scan_activity |= BTM_LE_SELECT_CONN_ACTIVE; 527 p_cb->wl_state |= BTM_BLE_WL_SCAN; 528 } 529 } 530 else 531 { 532 BTM_TRACE_ERROR("scan active, can not start selective connection procedure"); 533 return FALSE; 534 } 535 } 536 else /* disable selective connection mode */ 537 { 538 p_cb->scan_activity &= ~BTM_LE_SELECT_CONN_ACTIVE; 539 p_cb->p_select_cback = NULL; 540 p_cb->wl_state &= ~BTM_BLE_WL_SCAN; 541 542 /* stop scanning */ 543 if (!BTM_BLE_IS_SCAN_ACTIVE(p_cb->scan_activity)) 544 btm_ble_stop_scan(); /* duplicate filtering enabled */ 545 } 546 return TRUE; 547 } 548 /******************************************************************************* 549 ** 550 ** Function btm_ble_initiate_select_conn 551 ** 552 ** Description This function is to start/stop selective connection procedure. 553 ** 554 ** Parameters start: TRUE to start; FALSE to stop. 555 ** p_select_cback: callback function to return application 556 ** selection. 557 ** 558 ** Returns BOOLEAN: selective connectino procedure is started. 559 ** 560 *******************************************************************************/ 561 void btm_ble_initiate_select_conn(BD_ADDR bda) 562 { 563 BTM_TRACE_EVENT ("btm_ble_initiate_select_conn"); 564 565 /* use direct connection procedure to initiate connection */ 566 if (!L2CA_ConnectFixedChnl(L2CAP_ATT_CID, bda)) 567 { 568 BTM_TRACE_ERROR("btm_ble_initiate_select_conn failed"); 569 } 570 } 571 /******************************************************************************* 572 ** 573 ** Function btm_ble_suspend_bg_conn 574 ** 575 ** Description This function is to suspend an active background connection 576 ** procedure. 577 ** 578 ** Parameters none. 579 ** 580 ** Returns none. 581 ** 582 *******************************************************************************/ 583 BOOLEAN btm_ble_suspend_bg_conn(void) 584 { 585 BTM_TRACE_EVENT ("%s", __func__); 586 587 if (btm_cb.ble_ctr_cb.bg_conn_type == BTM_BLE_CONN_AUTO) 588 return btm_ble_start_auto_conn(FALSE); 589 else if (btm_cb.ble_ctr_cb.bg_conn_type == BTM_BLE_CONN_SELECTIVE) 590 return btm_ble_start_select_conn(FALSE, NULL); 591 592 return FALSE; 593 } 594 /******************************************************************************* 595 ** 596 ** Function btm_suspend_wl_activity 597 ** 598 ** Description This function is to suspend white list related activity 599 ** 600 ** Returns none. 601 ** 602 *******************************************************************************/ 603 static void btm_suspend_wl_activity(tBTM_BLE_WL_STATE wl_state) 604 { 605 if (wl_state & BTM_BLE_WL_INIT) 606 { 607 btm_ble_start_auto_conn(FALSE); 608 } 609 if (wl_state & BTM_BLE_WL_SCAN) 610 { 611 btm_ble_start_select_conn(FALSE, NULL); 612 } 613 if (wl_state & BTM_BLE_WL_ADV) 614 { 615 btm_ble_stop_adv(); 616 } 617 618 } 619 /******************************************************************************* 620 ** 621 ** Function btm_resume_wl_activity 622 ** 623 ** Description This function is to resume white list related activity 624 ** 625 ** Returns none. 626 ** 627 *******************************************************************************/ 628 static void btm_resume_wl_activity(tBTM_BLE_WL_STATE wl_state) 629 { 630 btm_ble_resume_bg_conn(); 631 632 if (wl_state & BTM_BLE_WL_ADV) 633 { 634 btm_ble_start_adv(); 635 } 636 637 } 638 /******************************************************************************* 639 ** 640 ** Function btm_ble_resume_bg_conn 641 ** 642 ** Description This function is to resume a background auto connection 643 ** procedure. 644 ** 645 ** Parameters none. 646 ** 647 ** Returns none. 648 ** 649 *******************************************************************************/ 650 BOOLEAN btm_ble_resume_bg_conn(void) 651 { 652 tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb; 653 BOOLEAN ret = FALSE; 654 655 if (p_cb->bg_conn_type != BTM_BLE_CONN_NONE) 656 { 657 if (p_cb->bg_conn_type == BTM_BLE_CONN_AUTO) 658 ret = btm_ble_start_auto_conn(TRUE); 659 660 if (p_cb->bg_conn_type == BTM_BLE_CONN_SELECTIVE) 661 ret = btm_ble_start_select_conn(TRUE, btm_cb.ble_ctr_cb.p_select_cback); 662 } 663 664 return ret; 665 } 666 /******************************************************************************* 667 ** 668 ** Function btm_ble_get_conn_st 669 ** 670 ** Description This function get BLE connection state 671 ** 672 ** Returns connection state 673 ** 674 *******************************************************************************/ 675 tBTM_BLE_CONN_ST btm_ble_get_conn_st(void) 676 { 677 return btm_cb.ble_ctr_cb.conn_state; 678 } 679 /******************************************************************************* 680 ** 681 ** Function btm_ble_set_conn_st 682 ** 683 ** Description This function set BLE connection state 684 ** 685 ** Returns None. 686 ** 687 *******************************************************************************/ 688 void btm_ble_set_conn_st(tBTM_BLE_CONN_ST new_st) 689 { 690 btm_cb.ble_ctr_cb.conn_state = new_st; 691 692 if (new_st == BLE_BG_CONN || new_st == BLE_DIR_CONN) 693 btm_ble_set_topology_mask(BTM_BLE_STATE_INIT_BIT); 694 else 695 btm_ble_clear_topology_mask(BTM_BLE_STATE_INIT_BIT); 696 } 697 698 /******************************************************************************* 699 ** 700 ** Function btm_ble_enqueue_direct_conn_req 701 ** 702 ** Description This function enqueue the direct connection request 703 ** 704 ** Returns None. 705 ** 706 *******************************************************************************/ 707 void btm_ble_enqueue_direct_conn_req(void *p_param) 708 { 709 tBTM_BLE_CONN_REQ *p = (tBTM_BLE_CONN_REQ *)GKI_getbuf(sizeof(tBTM_BLE_CONN_REQ)); 710 711 p->p_param = p_param; 712 713 GKI_enqueue (&btm_cb.ble_ctr_cb.conn_pending_q, p); 714 } 715 /******************************************************************************* 716 ** 717 ** Function btm_send_pending_direct_conn 718 ** 719 ** Description This function send the pending direct connection request in queue 720 ** 721 ** Returns TRUE if started, FALSE otherwise 722 ** 723 *******************************************************************************/ 724 BOOLEAN btm_send_pending_direct_conn(void) 725 { 726 tBTM_BLE_CONN_REQ *p_req; 727 BOOLEAN rt = FALSE; 728 729 if (!GKI_queue_is_empty(&btm_cb.ble_ctr_cb.conn_pending_q)) 730 { 731 p_req = (tBTM_BLE_CONN_REQ*)GKI_dequeue (&btm_cb.ble_ctr_cb.conn_pending_q); 732 733 rt = l2cble_init_direct_conn((tL2C_LCB *)(p_req->p_param)); 734 735 GKI_freebuf((void *)p_req); 736 } 737 738 return rt; 739 } 740 741 #endif 742 743 744