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