1 /****************************************************************************** 2 * 3 * Copyright (C) 2008-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 GAP. 22 * 23 ******************************************************************************/ 24 25 #include <string.h> 26 #include <stdio.h> 27 #include <stddef.h> 28 29 #include "bt_types.h" 30 #include "btu.h" 31 #include "btm_int.h" 32 #include "hcimsgs.h" 33 #if (GAP_INCLUDED == TRUE) 34 #include "gap_api.h" 35 #endif 36 #if (BLE_INCLUDED == TRUE) 37 #include "gattdefs.h" 38 39 #define BTM_BLE_NAME_SHORT 0x01 40 #define BTM_BLE_NAME_CMPL 0x02 41 42 #define BTM_BLE_FILTER_TARGET_UNKNOWN 0xff 43 #define BTM_BLE_POLICY_UNKNOWN 0xff 44 45 #define BTM_EXT_BLE_RMT_NAME_TIMEOUT 30 46 47 /******************************************************************************* 48 ** Local functions 49 *******************************************************************************/ 50 static void btm_ble_update_adv_flag(UINT8 flag); 51 static void btm_ble_process_adv_pkt_cont(BD_ADDR bda, UINT8 addr_type, UINT8 evt_type, UINT8 *p); 52 static UINT8 *btm_ble_build_adv_data(tBTM_BLE_AD_MASK *p_data_mask, UINT8 **p_dst, tBTM_BLE_ADV_DATA *p_data); 53 static UINT8 btm_set_conn_mode_adv_init_addr(tBTM_BLE_INQ_CB *p_cb, 54 BD_ADDR_PTR p_addr_ptr, 55 tBLE_ADDR_TYPE *p_init_addr_type, 56 tBLE_ADDR_TYPE *p_own_addr_type); 57 static BOOLEAN btm_ble_start_adv(void); 58 static tBTM_STATUS btm_ble_stop_adv(void); 59 60 61 62 /******************************************************************************* 63 ** 64 ** Function BTM_BleReset 65 ** 66 ** Description This function is called to reset ULP controller. 67 ** 68 ** Parameters None. 69 ** 70 ** Returns void 71 ** 72 *******************************************************************************/ 73 void BTM_BleReset(void) 74 { 75 btsnd_hcic_ble_reset(); 76 } 77 /******************************************************************************* 78 ** 79 ** Function BTM_BleUpdateAdvWhitelist 80 ** 81 ** Description Add or remove device from advertising white list 82 ** 83 ** Returns void 84 ** 85 *******************************************************************************/ 86 BOOLEAN BTM_BleUpdateAdvWhitelist(BOOLEAN add_remove, BD_ADDR remote_bda) 87 { 88 return FALSE; 89 } 90 91 /******************************************************************************* 92 ** 93 ** Function BTM_BleUpdateAdvFilterPolicy 94 ** 95 ** Description This function update the filter policy of advertiser. 96 ** 97 ** Parameter adv_policy: advertising filter policy 98 ** 99 ** Return void 100 *******************************************************************************/ 101 void BTM_BleUpdateAdvFilterPolicy(tBTM_BLE_AFP adv_policy) 102 { 103 tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var; 104 tBLE_ADDR_TYPE init_addr_type = BLE_ADDR_PUBLIC; 105 BD_ADDR p_addr_ptr= {0}; 106 UINT8 adv_mode = p_cb->adv_mode; 107 108 BTM_TRACE_EVENT0 ("BTM_BleUpdateAdvFilterPolicy"); 109 110 if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1])) 111 return; 112 113 if (p_cb->afp != adv_policy) 114 { 115 p_cb->afp = adv_policy; 116 117 /* if adv active, stop and restart */ 118 btm_ble_stop_adv (); 119 120 if (p_cb->connectable_mode & BTM_BLE_CONNECTABLE) 121 p_cb->evt_type = btm_set_conn_mode_adv_init_addr(p_cb, p_addr_ptr, &init_addr_type, &p_cb->adv_addr_type); 122 123 btsnd_hcic_ble_write_adv_params (p_cb->adv_interval_min, 124 p_cb->adv_interval_max, 125 p_cb->evt_type, 126 p_cb->adv_addr_type, 127 init_addr_type, 128 p_addr_ptr, 129 p_cb->adv_chnl_map, 130 p_cb->afp); 131 132 if (adv_mode == BTM_BLE_ADV_ENABLE) 133 btm_ble_start_adv (); 134 135 } 136 } 137 /******************************************************************************* 138 ** 139 ** Function BTM_BleObserve 140 ** 141 ** Description This procedure keep the device listening for advertising 142 ** events from a broadcast device. 143 ** 144 ** Parameters start: start or stop observe. 145 ** white_list: use white list in observer mode or not. 146 ** 147 ** Returns void 148 ** 149 *******************************************************************************/ 150 tBTM_STATUS BTM_BleObserve(BOOLEAN start, UINT8 duration, 151 tBTM_INQ_RESULTS_CB *p_results_cb, tBTM_CMPL_CB *p_cmpl_cb) 152 { 153 tBTM_BLE_INQ_CB *p_inq = &btm_cb.ble_ctr_cb.inq_var; 154 tBTM_STATUS status = BTM_NO_RESOURCES; 155 156 BTM_TRACE_EVENT0 ("BTM_BleObserve "); 157 158 if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1])) 159 return BTM_ILLEGAL_VALUE; 160 161 if (start) 162 { 163 /* shared inquiry database, do not allow observe if any inquiry is active */ 164 if (btm_cb.btm_inq_vars.inq_active || p_inq->proc_mode != BTM_BLE_INQUIRY_NONE) 165 return BTM_BUSY; 166 167 btm_cb.btm_inq_vars.p_inq_results_cb = p_results_cb; 168 btm_cb.btm_inq_vars.p_inq_cmpl_cb = p_cmpl_cb; 169 p_inq->scan_type = (p_inq->scan_type == BTM_BLE_SCAN_MODE_NONE) ? BTM_BLE_SCAN_MODE_ACTI: p_inq->scan_type; 170 171 /* allow config scanning type */ 172 if (btsnd_hcic_ble_set_scan_params (p_inq->scan_type, 173 (UINT16)(!p_inq->scan_interval ? BTM_BLE_GAP_DISC_SCAN_INT : p_inq->scan_interval), 174 (UINT16)(!p_inq->scan_window ? BTM_BLE_GAP_DISC_SCAN_WIN : p_inq->scan_window), 175 BLE_ADDR_PUBLIC, 176 BTM_BLE_DEFAULT_SFP)) /* assume observe always not using white list */ 177 { 178 /* start scan, disable duplicate filtering */ 179 if (btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_ENABLE, BTM_BLE_DUPLICATE_DISABLE)) 180 { 181 status = BTM_SUCCESS; 182 p_inq->proc_mode = BTM_BLE_OBSERVE; 183 btm_cb.btm_inq_vars.inq_active |= BTM_LE_OBSERVE_ACTIVE; 184 185 if (duration != 0) 186 { 187 /* start inquiry timer */ 188 btu_start_timer (&p_inq->inq_timer_ent, BTU_TTYPE_BLE_INQUIRY, duration); 189 } 190 } 191 } 192 } 193 else if (p_inq->proc_mode == BTM_BLE_OBSERVE) 194 { 195 btm_cb.btm_inq_vars.inq_active &= ~BTM_LE_OBSERVE_ACTIVE; 196 btm_ble_stop_scan(); 197 } 198 199 return status; 200 } 201 202 /******************************************************************************* 203 ** 204 ** Function BTM_BleBroadcast 205 ** 206 ** Description This function is to start or stop broadcasting. 207 ** 208 ** Parameters start: start or stop broadcasting. 209 ** 210 ** Returns status. 211 ** 212 *******************************************************************************/ 213 tBTM_STATUS BTM_BleBroadcast(BOOLEAN start) 214 { 215 tBTM_STATUS status = BTM_NO_RESOURCES; 216 tBTM_LE_RANDOM_CB *p_addr_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb; 217 tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var; 218 UINT8 evt_type = p_cb->scan_rsp ? BTM_BLE_DISCOVER_EVT: BTM_BLE_NON_CONNECT_EVT; 219 220 if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1])) 221 return BTM_ILLEGAL_VALUE; 222 223 #ifdef BTM_BLE_PC_ADV_TEST_MODE 224 if (BTM_BLE_PC_ADV_TEST_MODE) 225 { 226 evt_type = p_cb->scan_rsp ? BTM_BLE_CONNECT_EVT: BTM_BLE_NON_CONNECT_EVT; 227 } 228 #endif 229 230 if (start && p_cb->adv_mode == BTM_BLE_ADV_DISABLE) 231 { 232 /* update adv params */ 233 if (!btsnd_hcic_ble_write_adv_params ((UINT16)(p_cb->adv_interval_min ? p_cb->adv_interval_min : BTM_BLE_GAP_ADV_INT), 234 (UINT16)(p_cb->adv_interval_max ? p_cb->adv_interval_max : BTM_BLE_GAP_ADV_INT), 235 evt_type, 236 p_addr_cb->own_addr_type, 237 p_cb->direct_bda.type, 238 p_cb->direct_bda.bda, 239 p_cb->adv_chnl_map, 240 p_cb->afp)) 241 242 status = BTM_NO_RESOURCES; 243 else 244 p_cb->evt_type = evt_type; 245 246 status = btm_ble_start_adv (); 247 } 248 else if (!start && p_cb->adv_mode == BTM_BLE_ADV_ENABLE) 249 { 250 status = btm_ble_stop_adv(); 251 } 252 else 253 { 254 status = BTM_WRONG_MODE; 255 BTM_TRACE_ERROR2("Can not %s Broadcast, device %s in Broadcast mode", 256 (start ? "Start" : "Stop"), (start ? "alerady" :"not")); 257 } 258 return status; 259 } 260 261 /******************************************************************************* 262 ** 263 ** Function BTM_RegisterScanReqEvt 264 ** 265 ** Description This function is called to register a scan request callback 266 ** on the advertiser. 267 ** 268 ** Parameters p_scan_req_cback: scan request callback. If NULL, remove the 269 ** registration. 270 ** 271 ** Returns void 272 ** 273 *******************************************************************************/ 274 void BTM_RegisterScanReqEvt(tBTM_BLE_SCAN_REQ_CBACK *p_scan_req_cback) 275 { 276 #ifdef BTM_BLE_PC_ADV_TEST_MODE /* For general stack code (e.g. BTInsight testing), we simply do not define it to exclude or set it to TRUE to include */ 277 if (BTM_BLE_PC_ADV_TEST_MODE) /* For stack component, it is always defined and maps to a global variable g_bDraculaAdvertisingMode */ 278 { 279 tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb; 280 p_cb->p_scan_req_cback = p_scan_req_cback; 281 } 282 #endif 283 } 284 285 /******************************************************************************* 286 ** 287 ** Function BTM_BleSetBgConnType 288 ** 289 ** Description This function is called to set BLE connectable mode for a 290 ** peripheral device. 291 ** 292 ** Parameters bg_conn_type: it can be auto connection, or selective connection. 293 ** p_select_cback: callback function when selective connection procedure 294 ** is being used. 295 ** 296 ** Returns void 297 ** 298 *******************************************************************************/ 299 BOOLEAN BTM_BleSetBgConnType(tBTM_BLE_CONN_TYPE bg_conn_type, 300 tBTM_BLE_SEL_CBACK *p_select_cback) 301 { 302 BOOLEAN started = TRUE; 303 304 BTM_TRACE_EVENT0 ("BTM_BleSetBgConnType "); 305 if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1])) 306 return FALSE; 307 308 if (btm_cb.ble_ctr_cb.bg_conn_type != bg_conn_type) 309 { 310 switch (bg_conn_type) 311 { 312 case BTM_BLE_CONN_AUTO: 313 btm_ble_start_auto_conn(TRUE); 314 break; 315 316 case BTM_BLE_CONN_SELECTIVE: 317 if (btm_cb.ble_ctr_cb.bg_conn_type == BTM_BLE_CONN_AUTO) 318 { 319 btm_ble_start_auto_conn(FALSE); 320 } 321 started = btm_ble_start_select_conn(TRUE, p_select_cback); 322 break; 323 324 case BTM_BLE_CONN_NONE: 325 if (btm_cb.ble_ctr_cb.bg_conn_type == BTM_BLE_CONN_AUTO) 326 { 327 btm_ble_start_auto_conn(FALSE); 328 } 329 else if (btm_cb.ble_ctr_cb.bg_conn_type == BTM_BLE_CONN_SELECTIVE) 330 { 331 btm_ble_start_select_conn(FALSE, NULL); 332 } 333 started = TRUE; 334 break; 335 336 default: 337 BTM_TRACE_ERROR1("invalid bg connection type : %d ", bg_conn_type); 338 started = FALSE; 339 break; 340 } 341 342 if (started) 343 btm_cb.ble_ctr_cb.bg_conn_type = bg_conn_type; 344 } 345 return started; 346 } 347 348 /******************************************************************************* 349 ** 350 ** Function BTM_BleUpdateBgConnDev 351 ** 352 ** Description This function is called to add or remove a device into/from 353 ** background connection procedure. The background connection 354 * procedure is decided by the background connection type, it can be 355 * auto connection, or selective connection. 356 ** 357 ** Parameters add_remove: TRUE to add; FALSE to remove. 358 ** remote_bda: device address to add/remove. 359 ** 360 ** Returns void 361 ** 362 *******************************************************************************/ 363 BOOLEAN BTM_BleUpdateBgConnDev(BOOLEAN add_remove, BD_ADDR remote_bda) 364 { 365 BOOLEAN ret = TRUE; 366 UINT8 dev_wl_type = BTM_BLE_WL_INIT; 367 368 BTM_TRACE_EVENT0 (" BTM_BleUpdateBgConnDev"); 369 370 /* update white list */ 371 ret = btm_update_bg_conn_list(add_remove, remote_bda, &dev_wl_type); 372 373 btm_update_dev_to_white_list(add_remove, remote_bda, dev_wl_type); 374 375 return ret; 376 } 377 378 /******************************************************************************* 379 ** 380 ** Function BTM_BleSetConnMode 381 ** 382 ** Description This function is called to set BLE connectable mode for a 383 ** peripheral device. 384 ** 385 ** Parameters directed: is directed connectable mode, or non-directed. 386 ** p_dir_bda: connectable direct initiator's LE device address 387 ** 388 ** Returns void 389 ** 390 *******************************************************************************/ 391 tBTM_STATUS BTM_BleSetConnMode(BOOLEAN is_directed) 392 { 393 tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var; 394 395 BTM_TRACE_EVENT1 ("BTM_BleSetConnMode is_directed = %d ", is_directed); 396 if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1])) 397 return BTM_ILLEGAL_VALUE; 398 399 p_cb->directed_conn = is_directed; 400 return btm_ble_set_connectability( p_cb->connectable_mode); 401 402 } 403 404 /******************************************************************************* 405 ** 406 ** Function btm_set_conn_mode_adv_init_addr 407 ** 408 ** Description set initator address type and local address type based on adv 409 ** mode. 410 ** 411 ** 412 *******************************************************************************/ 413 static UINT8 btm_set_conn_mode_adv_init_addr(tBTM_BLE_INQ_CB *p_cb, 414 BD_ADDR_PTR p_addr_ptr, 415 tBLE_ADDR_TYPE *p_init_addr_type, 416 tBLE_ADDR_TYPE *p_own_addr_type) 417 { 418 UINT8 evt_type; 419 420 if ( p_cb->directed_conn) 421 { 422 /* direct adv mode does not have privacy if privacy 423 is not enabled or no reconn addr config */ 424 *p_own_addr_type = BLE_ADDR_PUBLIC; 425 *p_init_addr_type = p_cb->direct_bda.type; 426 memcpy(p_addr_ptr, p_cb->direct_bda.bda, BD_ADDR_LEN); 427 evt_type = BTM_BLE_CONNECT_DIR_EVT; 428 } 429 else /* undirect adv mode */ 430 { 431 evt_type = BTM_BLE_CONNECT_EVT; 432 } 433 434 return evt_type; 435 436 } 437 438 /******************************************************************************* 439 ** 440 ** Function BTM_BleSetAdvParams 441 ** 442 ** Description This function is called to set advertising parameters. 443 ** 444 ** Parameters adv_int_min: minimum advertising interval 445 ** adv_int_max: maximum advertising interval 446 ** p_dir_bda: connectable direct initiator's LE device address 447 ** chnl_map: advertising channel map. 448 ** 449 ** Returns void 450 ** 451 *******************************************************************************/ 452 tBTM_STATUS BTM_BleSetAdvParams(UINT16 adv_int_min, UINT16 adv_int_max, 453 tBLE_BD_ADDR *p_dir_bda, 454 tBTM_BLE_ADV_CHNL_MAP chnl_map) 455 { 456 tBTM_LE_RANDOM_CB *p_addr_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb; 457 tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var; 458 tBTM_STATUS status = BTM_SUCCESS; 459 BD_ADDR p_addr_ptr = {0}; 460 tBLE_ADDR_TYPE init_addr_type = BLE_ADDR_PUBLIC; 461 tBLE_ADDR_TYPE own_addr_type = p_addr_cb->own_addr_type; 462 UINT8 adv_mode = p_cb->adv_mode; 463 464 BTM_TRACE_EVENT0 ("BTM_BleSetAdvParams"); 465 466 if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1])) 467 return BTM_ILLEGAL_VALUE; 468 469 if (!BTM_BLE_VALID_PRAM(adv_int_min, BTM_BLE_ADV_INT_MIN, BTM_BLE_ADV_INT_MAX) || 470 !BTM_BLE_VALID_PRAM(adv_int_max, BTM_BLE_ADV_INT_MIN, BTM_BLE_ADV_INT_MAX)) 471 { 472 return BTM_ILLEGAL_VALUE; 473 } 474 475 p_cb->adv_interval_min = adv_int_min; 476 p_cb->adv_interval_max = adv_int_max; 477 p_cb->adv_chnl_map = chnl_map; 478 479 if (p_dir_bda) 480 { 481 memcpy(&p_cb->direct_bda, p_dir_bda, sizeof(tBLE_BD_ADDR)); 482 } 483 484 BTM_TRACE_EVENT0 ("update params for an active adv"); 485 486 btm_ble_stop_adv(); 487 488 if (p_cb->connectable_mode & BTM_BLE_CONNECTABLE) 489 p_cb->evt_type = btm_set_conn_mode_adv_init_addr(p_cb, p_addr_ptr, &init_addr_type, &own_addr_type); 490 491 /* update adv params */ 492 btsnd_hcic_ble_write_adv_params (p_cb->adv_interval_min, 493 p_cb->adv_interval_max, 494 p_cb->evt_type, 495 own_addr_type, 496 init_addr_type, 497 p_addr_ptr, 498 p_cb->adv_chnl_map, 499 p_cb->afp); 500 501 if (adv_mode == BTM_BLE_ADV_ENABLE) 502 btm_ble_start_adv(); 503 504 return status; 505 } 506 507 /******************************************************************************* 508 ** 509 ** Function BTM_BleReadAdvParams 510 ** 511 ** Description This function is called to set advertising parameters. 512 ** 513 ** Parameters adv_int_min: minimum advertising interval 514 ** adv_int_max: maximum advertising interval 515 ** p_dir_bda: connectable direct initiator's LE device address 516 ** chnl_map: advertising channel map. 517 ** 518 ** Returns void 519 ** 520 *******************************************************************************/ 521 void BTM_BleReadAdvParams (UINT16 *adv_int_min, UINT16 *adv_int_max, 522 tBLE_BD_ADDR *p_dir_bda, tBTM_BLE_ADV_CHNL_MAP *p_chnl_map) 523 { 524 tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var; 525 526 BTM_TRACE_EVENT0 ("BTM_BleReadAdvParams "); 527 if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1])) 528 return ; 529 530 *adv_int_min = p_cb->adv_interval_min; 531 *adv_int_max = p_cb->adv_interval_max; 532 *p_chnl_map = p_cb->adv_chnl_map; 533 534 if (p_dir_bda != NULL) 535 { 536 memcpy(p_dir_bda, &p_cb->direct_bda, sizeof(tBLE_BD_ADDR)); 537 } 538 } 539 540 /******************************************************************************* 541 ** 542 ** Function BTM_BleSetScanParams 543 ** 544 ** Description This function is called to set Scan parameters. 545 ** 546 ** Parameters adv_int_min: minimum advertising interval 547 ** adv_int_max: maximum advertising interval 548 ** p_dir_bda: connectable direct initiator's LE device address 549 ** chnl_map: advertising channel map. 550 ** scan_type: active scan or passive scan 551 ** 552 ** Returns void 553 ** 554 *******************************************************************************/ 555 void BTM_BleSetScanParams(UINT16 scan_interval, UINT16 scan_window, tBTM_BLE_SCAN_MODE scan_mode) 556 { 557 tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var; 558 559 BTM_TRACE_EVENT0 (" BTM_BleSetScanParams"); 560 if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1])) 561 return ; 562 563 if (BTM_BLE_VALID_PRAM(scan_interval, BTM_BLE_SCAN_INT_MIN, BTM_BLE_SCAN_INT_MAX) && 564 BTM_BLE_VALID_PRAM(scan_window, BTM_BLE_SCAN_WIN_MIN, BTM_BLE_SCAN_WIN_MAX) && 565 (scan_mode == BTM_BLE_SCAN_MODE_ACTI || scan_mode == BTM_BLE_SCAN_MODE_PASS)) 566 { 567 p_cb->scan_type = scan_mode; 568 569 if (BTM_BLE_CONN_PARAM_UNDEF != scan_interval) 570 p_cb->scan_interval = scan_interval; 571 572 if (BTM_BLE_CONN_PARAM_UNDEF != scan_window) 573 p_cb->scan_window = scan_window; 574 } 575 else 576 { 577 BTM_TRACE_ERROR2("Illegal params: scan_interval = %d scan_window = %d", 578 scan_interval, scan_window); 579 } 580 581 } 582 583 /******************************************************************************* 584 ** 585 ** Function BTM_BleWriteScanRsp 586 ** 587 ** Description This function is called to write LE scan response. 588 ** 589 ** Parameters: p_scan_rsp: scan response information. 590 ** 591 ** Returns void 592 ** 593 *******************************************************************************/ 594 tBTM_STATUS BTM_BleWriteScanRsp(tBTM_BLE_AD_MASK data_mask, tBTM_BLE_ADV_DATA *p_data) 595 { 596 tBTM_STATUS status = BTM_NO_RESOURCES; 597 UINT8 rsp_data[BTM_BLE_AD_DATA_LEN], 598 *p = rsp_data; 599 600 BTM_TRACE_EVENT0 (" BTM_BleWriteScanRsp"); 601 602 if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1])) 603 return BTM_ILLEGAL_VALUE; 604 605 memset(rsp_data, 0, BTM_BLE_AD_DATA_LEN); 606 btm_ble_build_adv_data(&data_mask, &p, p_data); 607 608 if (btsnd_hcic_ble_set_scan_rsp_data((UINT8)(p - rsp_data), rsp_data)) 609 { 610 status = BTM_SUCCESS; 611 612 if (data_mask != 0) 613 btm_cb.ble_ctr_cb.inq_var.scan_rsp = TRUE; 614 else 615 btm_cb.ble_ctr_cb.inq_var.scan_rsp = FALSE; 616 } 617 else 618 status = BTM_ILLEGAL_VALUE; 619 620 return status; 621 } 622 623 /******************************************************************************* 624 ** 625 ** Function BTM_BleWriteAdvData 626 ** 627 ** Description This function is called to write advertising data. 628 ** 629 ** Parameters: None. 630 ** 631 ** Returns void 632 ** 633 *******************************************************************************/ 634 tBTM_STATUS BTM_BleWriteAdvData(tBTM_BLE_AD_MASK data_mask, tBTM_BLE_ADV_DATA *p_data) 635 { 636 tBTM_BLE_LOCAL_ADV_DATA *p_cb_data = &btm_cb.ble_ctr_cb.inq_var.adv_data; 637 UINT8 *p; 638 UINT16 mask = data_mask; 639 640 BTM_TRACE_EVENT0 ("BTM_BleWriteAdvData "); 641 642 if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1])) 643 return BTM_ILLEGAL_VALUE; 644 645 memset(p_cb_data, 0, sizeof(tBTM_BLE_LOCAL_ADV_DATA)); 646 p = p_cb_data->ad_data; 647 p_cb_data->data_mask = data_mask; 648 649 p_cb_data->p_flags = btm_ble_build_adv_data(&mask, &p, p_data); 650 651 p_cb_data->p_pad = p; 652 653 if (data_mask != 0) 654 { 655 BTM_TRACE_ERROR0("Partial data write into ADV"); 656 } 657 658 p_cb_data->data_mask &= ~mask; 659 660 if (btsnd_hcic_ble_set_adv_data((UINT8)(p_cb_data->p_pad - p_cb_data->ad_data), 661 p_cb_data->ad_data)) 662 return BTM_SUCCESS; 663 else 664 return BTM_NO_RESOURCES; 665 666 } 667 668 /******************************************************************************* 669 ** 670 ** Function BTM_CheckAdvData 671 ** 672 ** Description This function is called to get ADV data for a specific type. 673 ** 674 ** Parameters p_adv - pointer of ADV data 675 ** type - finding ADV data type 676 ** p_length - return the length of ADV data not including type 677 ** 678 ** Returns pointer of ADV data 679 ** 680 *******************************************************************************/ 681 UINT8 *BTM_CheckAdvData( UINT8 *p_adv, UINT8 type, UINT8 *p_length) 682 { 683 UINT8 *p = p_adv; 684 UINT8 length; 685 UINT8 adv_type; 686 BTM_TRACE_API1("BTM_CheckAdvData type=0x%02X", type); 687 688 STREAM_TO_UINT8(length, p); 689 690 while ( length && (p - p_adv <= BTM_BLE_CACHE_ADV_DATA_MAX)) 691 { 692 STREAM_TO_UINT8(adv_type, p); 693 694 if ( adv_type == type ) 695 { 696 /* length doesn't include itself */ 697 *p_length = length - 1; /* minus the length of type */ 698 return p; 699 } 700 p += length - 1; /* skip the length of data */ 701 STREAM_TO_UINT8(length, p); 702 } 703 704 *p_length = 0; 705 return NULL; 706 } 707 708 /******************************************************************************* 709 ** 710 ** Function btm_ble_build_adv_data 711 ** 712 ** Description This function is called build the adv data and rsp data. 713 *******************************************************************************/ 714 static UINT8 *btm_ble_build_adv_data(tBTM_BLE_AD_MASK *p_data_mask, UINT8 **p_dst, tBTM_BLE_ADV_DATA *p_data) 715 { 716 UINT16 data_mask = *p_data_mask; 717 UINT8 *p = *p_dst, 718 *p_flag = NULL; 719 UINT16 len = BTM_BLE_AD_DATA_LEN, cp_len = 0; 720 UINT8 i = 0; 721 tBTM_BLE_PROP_ELEM *p_elem; 722 723 BTM_TRACE_EVENT0 (" btm_ble_build_adv_data"); 724 725 /* build the adv data structure and build the data string */ 726 if (data_mask) 727 { 728 /* flags */ 729 if (data_mask & BTM_BLE_AD_BIT_FLAGS) 730 { 731 *p++ = 2; 732 *p++ = BTM_BLE_AD_TYPE_FLAG; 733 p_flag = p; 734 if (p_data) 735 *p++ = p_data->flag; 736 else 737 *p++ = 0; 738 739 len -= 3; 740 741 data_mask &= ~BTM_BLE_AD_BIT_FLAGS; 742 } 743 /* appearance data */ 744 if (len > 3 && data_mask & BTM_BLE_AD_BIT_APPEARANCE) 745 { 746 *p++ = 3; /* length */ 747 *p++ = BTM_BLE_AD_TYPE_APPEARANCE; 748 UINT16_TO_STREAM(p, p_data->appearance); 749 len -= 4; 750 751 data_mask &= ~BTM_BLE_AD_BIT_APPEARANCE; 752 } 753 /* device name */ 754 #if BTM_MAX_LOC_BD_NAME_LEN > 0 755 if (len > 2 && data_mask & BTM_BLE_AD_BIT_DEV_NAME) 756 { 757 if (strlen(btm_cb.cfg.bd_name) > (UINT16)(len - 2)) 758 { 759 *p++ = len - 2 + 1; 760 *p++ = BTM_BLE_AD_TYPE_NAME_SHORT; 761 ARRAY_TO_STREAM(p, btm_cb.cfg.bd_name, len - 2); 762 } 763 else 764 { 765 cp_len = (UINT16)strlen(btm_cb.cfg.bd_name); 766 *p++ = cp_len + 1; 767 *p++ = BTM_BLE_AD_TYPE_NAME_CMPL; 768 ARRAY_TO_STREAM(p, btm_cb.cfg.bd_name, cp_len); 769 } 770 len -= (cp_len + 2); 771 data_mask &= ~BTM_BLE_AD_BIT_DEV_NAME; 772 } 773 #endif 774 /* manufacturer data */ 775 if (len > 2 && data_mask & BTM_BLE_AD_BIT_MANU && 776 p_data && p_data->manu.len != 0 && p_data->manu.p_val) 777 { 778 if (p_data->manu.len > (len - 2)) 779 cp_len = len - 2; 780 else 781 cp_len = p_data->manu.len; 782 783 *p++ = cp_len + 1; 784 *p++ = BTM_BLE_AD_TYPE_MANU; 785 ARRAY_TO_STREAM(p, p_data->manu.p_val, cp_len); 786 787 len -= (cp_len + 2); 788 data_mask &= ~BTM_BLE_AD_BIT_MANU; 789 } 790 /* TX power */ 791 if (len > 2 && data_mask & BTM_BLE_AD_BIT_TX_PWR) 792 { 793 *p++ = 2; 794 *p++ = BTM_BLE_AD_TYPE_TX_PWR; 795 *p++ = btm_cb.ble_ctr_cb.inq_var.tx_power; 796 len -= 3; 797 798 data_mask &= ~BTM_BLE_AD_BIT_TX_PWR; 799 } 800 /* services */ 801 if (len > 2 && data_mask & BTM_BLE_AD_BIT_SERVICE && 802 p_data && p_data->services.num_service != 0 && 803 p_data->services.p_uuid) 804 { 805 if (p_data->services.num_service * 2 > (len - 2)) 806 { 807 cp_len = (len - 2)/2; 808 *p ++ = 1 + cp_len * 2; 809 *p++ = BTM_BLE_AD_TYPE_16SRV_PART; 810 } 811 else 812 { 813 cp_len = p_data->services.num_service; 814 *p++ = 1 + cp_len * 2; 815 *p++ = BTM_BLE_AD_TYPE_16SRV_CMPL; 816 } 817 for (i = 0; i < cp_len; i ++) 818 { 819 UINT16_TO_STREAM(p, *(p_data->services.p_uuid + i)); 820 } 821 822 len -= (cp_len * 2 + 2); 823 data_mask &= ~BTM_BLE_AD_BIT_SERVICE; 824 } 825 if (len >= 6 && data_mask & BTM_BLE_AD_BIT_INT_RANGE && 826 p_data) 827 { 828 *p++ = 5; 829 *p++ = BTM_BLE_AD_TYPE_INT_RANGE; 830 UINT16_TO_STREAM(p, p_data->int_range.low); 831 UINT16_TO_STREAM(p, p_data->int_range.hi); 832 len -= 6; 833 data_mask &= ~BTM_BLE_AD_BIT_INT_RANGE; 834 } 835 if (data_mask & BTM_BLE_AD_BIT_PROPRIETARY && p_data && p_data->p_proprietary) 836 { 837 for (i = 0; i < p_data->p_proprietary->num_elem ; i ++) 838 { 839 p_elem = p_data->p_proprietary->p_elem + i; 840 841 if (len >= (2 + p_elem->len))/* len byte(1) + ATTR type(1) + Uuid len(2) + value length */ 842 { 843 *p ++ = p_elem->len + 1; /* Uuid len + value length */ 844 *p ++ = p_elem->adv_type; 845 ARRAY_TO_STREAM(p, p_elem->p_val, p_elem->len); 846 847 len -= (2 + p_elem->len); 848 } 849 else 850 { 851 BTM_TRACE_WARNING0("data exceed max adv packet length"); 852 break; 853 } 854 } 855 data_mask &= ~BTM_BLE_AD_BIT_PROPRIETARY; 856 } 857 } 858 859 *p_data_mask = data_mask; 860 *p_dst = p; 861 862 return p_flag; 863 } 864 865 /******************************************************************************* 866 ** 867 ** Function btm_ble_set_discoverability 868 ** 869 ** Description This function is called to set BLE discoverable mode. 870 ** 871 ** Parameters: mode: discoverability mode. 872 ** 873 ** Returns void 874 ** 875 *******************************************************************************/ 876 tBTM_STATUS btm_ble_set_discoverability(UINT16 combined_mode) 877 { 878 tBTM_LE_RANDOM_CB *p_addr_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb; 879 tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var; 880 UINT16 mode = (combined_mode & BTM_BLE_DISCOVERABLE_MASK); 881 UINT8 flag = 0; 882 UINT8 new_mode = BTM_BLE_ADV_ENABLE; 883 UINT8 evt_type = (p_cb->connectable_mode == BTM_BLE_NON_CONNECTABLE) ? \ 884 ((p_cb->scan_rsp) ? BTM_BLE_DISCOVER_EVT : BTM_BLE_NON_CONNECT_EVT )\ 885 : BTM_BLE_CONNECT_EVT; 886 tBTM_STATUS status = BTM_SUCCESS; 887 BD_ADDR p_addr_ptr= {0}; 888 tBLE_ADDR_TYPE init_addr_type = BLE_ADDR_PUBLIC, 889 own_addr_type = p_addr_cb->own_addr_type;; 890 891 BTM_TRACE_EVENT2 ("btm_ble_set_discoverability mode=0x%0x combined_mode=0x%x", mode, combined_mode); 892 893 /*** Check mode parameter ***/ 894 if (mode > BTM_BLE_MAX_DISCOVERABLE) 895 return(BTM_ILLEGAL_VALUE); 896 897 p_cb->br_edr_supported_flag |= (combined_mode & BTM_DISCOVERABLE_MASK); 898 p_cb->discoverable_mode = mode; 899 900 if (!p_cb->br_edr_supported_flag) 901 { 902 flag = BTM_BLE_BREDR_NOT_SPT; 903 BTM_TRACE_DEBUG1("btm_ble_set_discoverability (BREDR not sup)flag=0x%x",flag); 904 } 905 906 BTM_TRACE_DEBUG1 ("br_edr_supported=0x%x", p_cb->br_edr_supported_flag); 907 908 if (mode == BTM_BLE_LIMITED_DISCOVERABLE || mode == BTM_BLE_GENERAL_DISCOVERABLE) 909 { 910 BTM_TRACE_EVENT0 ("mode == BTM_BLE_LIMITED_DISCOVERABLE "); 911 /* write ADV data with limited disc flag */ 912 if (mode == BTM_BLE_LIMITED_DISCOVERABLE) 913 flag |= BTM_BLE_LIMIT_DISC_FLAG ; 914 else 915 flag |= BTM_BLE_GEN_DISC_FLAG; 916 } 917 else /* non-discoverable */ 918 { 919 BTM_TRACE_EVENT0 ("mode == BTM_BLE_NON_DISCOVERABLE "); 920 921 if (p_cb->connectable_mode == BTM_BLE_NON_CONNECTABLE) 922 { 923 p_cb->br_edr_supported_flag = 0; 924 925 BTM_TRACE_EVENT0 ("always disable adv in non-discoverable non-connectable mode if no scan rsp "); 926 if (!p_cb->scan_rsp ) 927 new_mode = BTM_BLE_ADV_DISABLE; 928 929 } 930 else 931 { 932 p_cb->evt_type = btm_set_conn_mode_adv_init_addr(p_cb, p_addr_ptr, &init_addr_type, &own_addr_type); 933 } 934 } 935 btm_ble_update_adv_flag(flag); 936 937 /* update adv params if start advertising */ 938 BTM_TRACE_EVENT2 ("evt_type=0x%x p-cb->evt_type=0x%x ", evt_type, p_cb->evt_type); 939 if (new_mode == BTM_BLE_ADV_ENABLE && 940 (evt_type != p_cb->evt_type ||p_cb->adv_addr_type != own_addr_type)) 941 { 942 btm_ble_stop_adv(); 943 944 /* update adv params */ 945 if (!btsnd_hcic_ble_write_adv_params ((UINT16)(p_cb->adv_interval_min ? p_cb->adv_interval_min : BTM_BLE_GAP_ADV_INT), 946 (UINT16)(p_cb->adv_interval_max ? p_cb->adv_interval_max : BTM_BLE_GAP_ADV_INT), 947 evt_type, 948 own_addr_type, 949 init_addr_type, 950 p_addr_ptr, 951 p_cb->adv_chnl_map, 952 p_cb->afp)) 953 954 status = BTM_NO_RESOURCES; 955 else 956 { 957 p_cb->evt_type = evt_type; 958 p_cb->adv_addr_type = own_addr_type; 959 } 960 961 } 962 963 if (status == BTM_SUCCESS && p_cb->adv_mode != new_mode) 964 { 965 if (new_mode == BTM_BLE_ADV_ENABLE) 966 status = btm_ble_start_adv(); 967 else 968 status = btm_ble_stop_adv(); 969 } 970 971 /* set up stop advertising timer */ 972 if (status == BTM_SUCCESS && mode == BTM_BLE_LIMITED_DISCOVERABLE) 973 { 974 BTM_TRACE_EVENT1 ("start timer for limited disc mode duration=%d (30 secs)", BTM_BLE_GAP_LIM_TOUT); 975 /* start Tgap(lim_timeout) */ 976 btu_start_timer (&p_cb->inq_timer_ent, BTU_TTYPE_BLE_GAP_LIM_DISC, 977 BTM_BLE_GAP_LIM_TOUT); 978 } 979 return status; 980 } 981 982 /******************************************************************************* 983 ** 984 ** Function btm_ble_set_connectability 985 ** 986 ** Description This function is called to set BLE connectability mode. 987 ** 988 ** Parameters: mode: connectability mode. 989 ** 990 ** Returns void 991 ** 992 *******************************************************************************/ 993 tBTM_STATUS btm_ble_set_connectability(UINT16 combined_mode) 994 { 995 tBTM_LE_RANDOM_CB *p_addr_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb; 996 tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var; 997 UINT16 mode = (combined_mode & BTM_BLE_CONNECTABLE_MASK); 998 UINT8 cur_flag = 0; 999 UINT8 cur_br_edr_not_sup_flag; 1000 UINT8 new_flag; 1001 UINT8 new_mode = BTM_BLE_ADV_ENABLE; 1002 UINT8 evt_type = (p_cb->scan_rsp) ? BTM_BLE_DISCOVER_EVT: BTM_BLE_NON_CONNECT_EVT; 1003 tBTM_STATUS status = BTM_SUCCESS; 1004 BD_ADDR p_addr_ptr = {0}; 1005 tBLE_ADDR_TYPE init_addr_type = BLE_ADDR_PUBLIC, 1006 own_addr_type = p_addr_cb->own_addr_type; 1007 1008 BTM_TRACE_EVENT2 ("btm_ble_set_connectability mode=0x%0x combined_mode=0x%x", mode, combined_mode); 1009 /*** Check mode parameter ***/ 1010 if (mode > BTM_BLE_MAX_CONNECTABLE) 1011 return(BTM_ILLEGAL_VALUE); 1012 if (btm_cb.ble_ctr_cb.inq_var.adv_data.p_flags) 1013 cur_flag = *btm_cb.ble_ctr_cb.inq_var.adv_data.p_flags ; 1014 cur_br_edr_not_sup_flag = (cur_flag & ((UINT8) BTM_BLE_BREDR_NOT_SPT)); 1015 1016 p_cb->br_edr_supported_flag |= ((combined_mode & BTM_CONNECTABLE_MASK) << 4); 1017 if (p_cb->br_edr_supported_flag && cur_br_edr_not_sup_flag) 1018 { 1019 new_flag = cur_flag & ((UINT8) (~BTM_BLE_BREDR_NOT_SPT)); 1020 BTM_TRACE_EVENT2 ("new flag=0x%x cur flag=0x%x",new_flag, cur_flag); 1021 btm_ble_update_adv_flag(new_flag); 1022 } 1023 p_cb->connectable_mode = mode; 1024 1025 if (mode == BTM_BLE_NON_CONNECTABLE) 1026 { 1027 if (p_cb->discoverable_mode == BTM_BLE_NON_DISCOVERABLE) 1028 { 1029 p_cb->br_edr_supported_flag = 0; 1030 BTM_TRACE_EVENT0 ("always disable adv in non-discoverable non-connectable mode with no scan rsp"); 1031 if(!p_cb->scan_rsp) 1032 new_mode = BTM_BLE_ADV_DISABLE; 1033 1034 } 1035 } 1036 else /* connectable */ 1037 { 1038 evt_type = btm_set_conn_mode_adv_init_addr(p_cb, p_addr_ptr, &init_addr_type, &own_addr_type); 1039 } 1040 1041 /* update adv params if needed */ 1042 if ((p_cb->evt_type != evt_type || p_cb->adv_addr_type != p_addr_cb->own_addr_type) 1043 && new_mode == BTM_BLE_ADV_ENABLE) 1044 { 1045 btm_ble_stop_adv(); 1046 1047 if (!btsnd_hcic_ble_write_adv_params ((UINT16)(p_cb->adv_interval_min ? p_cb->adv_interval_min : BTM_BLE_GAP_ADV_INT), 1048 (UINT16)(p_cb->adv_interval_max ? p_cb->adv_interval_max : BTM_BLE_GAP_ADV_INT), 1049 evt_type, 1050 own_addr_type, 1051 init_addr_type, 1052 p_addr_ptr, 1053 p_cb->adv_chnl_map, 1054 p_cb->afp)) 1055 status = BTM_NO_RESOURCES; 1056 else 1057 { 1058 p_cb->evt_type = evt_type; 1059 p_cb->adv_addr_type = own_addr_type; 1060 } 1061 } 1062 1063 /* update advertising mode */ 1064 if (status == BTM_SUCCESS && new_mode != p_cb->adv_mode) 1065 { 1066 if (btsnd_hcic_ble_set_adv_enable (new_mode)) 1067 { 1068 status = BTM_SUCCESS; 1069 1070 p_cb->adv_mode = new_mode; 1071 1072 if (p_cb->adv_mode == BTM_BLE_ADV_ENABLE && 1073 p_cb->afp != AP_SCAN_CONN_ALL) 1074 btm_cb.ble_ctr_cb.wl_state |= BTM_BLE_WL_ADV; 1075 else 1076 btm_cb.ble_ctr_cb.wl_state &= ~BTM_BLE_WL_ADV; 1077 1078 } 1079 } 1080 1081 return status; 1082 } 1083 1084 /******************************************************************************* 1085 ** 1086 ** Function btm_ble_start_inquiry 1087 ** 1088 ** Description This function is called to start BLE inquiry procedure. 1089 ** If the duration is zero, the periodic inquiry mode is cancelled. 1090 ** 1091 ** Parameters: mode - GENERAL or LIMITED inquiry 1092 ** p_inq_params - pointer to the BLE inquiry parameter. 1093 ** p_results_cb - callback returning pointer to results (tBTM_INQ_RESULTS) 1094 ** p_cmpl_cb - callback indicating the end of an inquiry 1095 ** 1096 ** 1097 ** 1098 ** Returns BTM_CMD_STARTED if successfully started 1099 ** BTM_NO_RESOURCES if could not allocate a message buffer 1100 ** BTM_BUSY - if an inquiry is already active 1101 ** 1102 *******************************************************************************/ 1103 tBTM_STATUS btm_ble_start_inquiry (UINT8 mode, UINT8 duration) 1104 { 1105 tBTM_STATUS status = BTM_NO_RESOURCES; 1106 tBTM_BLE_INQ_CB *p_inq = &btm_cb.ble_ctr_cb.inq_var; 1107 1108 BTM_TRACE_DEBUG2("btm_ble_start_inquiry: mode = %02x inq_active = %d", mode, btm_cb.btm_inq_vars.inq_active); 1109 1110 if (p_inq->proc_mode != BTM_BLE_INQUIRY_NONE) 1111 { 1112 BTM_TRACE_ERROR0("LE scan is active, can not start inquiry"); 1113 return(BTM_BUSY); 1114 } 1115 1116 btm_update_scanner_filter_policy(SP_ADV_ALL); 1117 1118 /* start scan, already enable duplicate filtering */ 1119 if (btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_ENABLE, BTM_BLE_DUPLICATE_DISABLE)) 1120 { 1121 status = BTM_CMD_STARTED; 1122 p_inq->proc_mode = mode; 1123 1124 if (duration != 0) 1125 { 1126 /* start inquiry timer */ 1127 btu_start_timer (&p_inq->inq_timer_ent, BTU_TTYPE_BLE_INQUIRY, duration); 1128 } 1129 } 1130 1131 return status; 1132 } 1133 1134 /******************************************************************************* 1135 ** 1136 ** Function btm_ble_read_remote_name_cmpl 1137 ** 1138 ** Description This function is called when BLE remote name is received. 1139 ** 1140 ** Returns void 1141 ** 1142 *******************************************************************************/ 1143 void btm_ble_read_remote_name_cmpl(BOOLEAN status, BD_ADDR bda, UINT16 length, char *p_name) 1144 { 1145 UINT8 hci_status = HCI_SUCCESS; 1146 BD_NAME bd_name; 1147 1148 memset(bd_name, 0, (BD_NAME_LEN + 1)); 1149 memcpy((UINT8*)bd_name, p_name, length); 1150 1151 if ((!status) || (length==0)) 1152 { 1153 hci_status = HCI_ERR_HOST_TIMEOUT; 1154 } 1155 1156 btm_process_remote_name(bda, bd_name, length +1, hci_status); 1157 btm_sec_rmt_name_request_complete (bda, (UINT8 *)p_name, hci_status); 1158 } 1159 1160 /******************************************************************************* 1161 ** 1162 ** Function btm_ble_read_remote_name 1163 ** 1164 ** Description This function read remote LE device name using GATT read 1165 ** procedure. 1166 ** 1167 ** Parameters: None. 1168 ** 1169 ** Returns void 1170 ** 1171 *******************************************************************************/ 1172 tBTM_STATUS btm_ble_read_remote_name(BD_ADDR remote_bda, tBTM_INQ_INFO *p_cur, tBTM_CMPL_CB *p_cb) 1173 { 1174 tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars; 1175 1176 if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1])) 1177 return BTM_ERR_PROCESSING; 1178 1179 if (p_cur && 1180 p_cur->results.ble_evt_type != BTM_BLE_EVT_CONN_ADV && 1181 p_cur->results.ble_evt_type != BTM_BLE_EVT_CONN_DIR_ADV) 1182 { 1183 BTM_TRACE_DEBUG0("name request to non-connectable device failed."); 1184 return BTM_ERR_PROCESSING; 1185 } 1186 1187 /* read remote device name using GATT procedure */ 1188 if (p_inq->remname_active) 1189 return BTM_BUSY; 1190 1191 if (!GAP_BleReadPeerDevName(remote_bda, btm_ble_read_remote_name_cmpl)) 1192 return BTM_BUSY; 1193 1194 p_inq->p_remname_cmpl_cb = p_cb; 1195 p_inq->remname_active = TRUE; 1196 1197 memcpy(p_inq->remname_bda, remote_bda, BD_ADDR_LEN); 1198 1199 btu_start_timer (&p_inq->rmt_name_timer_ent, 1200 BTU_TTYPE_BTM_RMT_NAME, 1201 BTM_EXT_BLE_RMT_NAME_TIMEOUT); 1202 1203 return BTM_CMD_STARTED; 1204 } 1205 1206 /******************************************************************************* 1207 ** 1208 ** Function btm_ble_cancel_remote_name 1209 ** 1210 ** Description This function cancel read remote LE device name. 1211 ** 1212 ** Parameters: None. 1213 ** 1214 ** Returns void 1215 ** 1216 *******************************************************************************/ 1217 BOOLEAN btm_ble_cancel_remote_name(BD_ADDR remote_bda) 1218 { 1219 tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars; 1220 BOOLEAN status; 1221 1222 status = GAP_BleCancelReadPeerDevName(remote_bda); 1223 1224 p_inq->remname_active = FALSE; 1225 memset(p_inq->remname_bda, 0, BD_ADDR_LEN); 1226 btu_stop_timer(&p_inq->rmt_name_timer_ent); 1227 1228 return status; 1229 } 1230 1231 /******************************************************************************* 1232 ** 1233 ** Function btm_ble_update_adv_flag 1234 ** 1235 ** Description This function update the limited discoverable flag in the adv 1236 ** data. 1237 ** 1238 ** Parameters: None. 1239 ** 1240 ** Returns void 1241 ** 1242 *******************************************************************************/ 1243 static void btm_ble_update_adv_flag(UINT8 flag) 1244 { 1245 tBTM_BLE_LOCAL_ADV_DATA *p_adv_data = &btm_cb.ble_ctr_cb.inq_var.adv_data; 1246 UINT8 *p; 1247 1248 BTM_TRACE_DEBUG1 ("btm_ble_update_adv_flag new=0x%x", flag); 1249 1250 if (p_adv_data->p_flags != NULL) 1251 { 1252 BTM_TRACE_DEBUG1 ("btm_ble_update_adv_flag old=0x%x", *p_adv_data->p_flags); 1253 *p_adv_data->p_flags = flag; 1254 } 1255 else /* no FLAGS in ADV data*/ 1256 { 1257 p = (p_adv_data->p_pad == NULL) ? p_adv_data->ad_data : p_adv_data->p_pad; 1258 /* need 3 bytes space to stuff in the flags, if not */ 1259 /* erase all written data, just for flags */ 1260 if ((BTM_BLE_AD_DATA_LEN - (p - p_adv_data->ad_data)) < 3) 1261 { 1262 p = p_adv_data->p_pad = p_adv_data->ad_data; 1263 memset(p_adv_data->ad_data, 0, BTM_BLE_AD_DATA_LEN); 1264 } 1265 1266 *p++ = 2; 1267 *p++ = BTM_BLE_AD_TYPE_FLAG; 1268 p_adv_data->p_flags = p; 1269 *p++ = flag; 1270 p_adv_data->p_pad = p; 1271 } 1272 1273 if (btsnd_hcic_ble_set_adv_data((UINT8)(p_adv_data->p_pad - p_adv_data->ad_data), 1274 p_adv_data->ad_data)) 1275 p_adv_data->data_mask |= BTM_BLE_AD_BIT_FLAGS; 1276 1277 } 1278 1279 #if 0 1280 /******************************************************************************* 1281 ** 1282 ** Function btm_ble_parse_adv_data 1283 ** 1284 ** Description This function parse the adv data into a structure. 1285 ** 1286 ** Returns pointer to entry, or NULL if not found 1287 ** 1288 *******************************************************************************/ 1289 static void btm_ble_parse_adv_data(tBTM_INQ_INFO *p_info, UINT8 *p_data, 1290 UINT8 len, tBTM_BLE_INQ_DATA *p_adv_data, UINT8 *p_buf) 1291 { 1292 UINT8 *p_cur = p_data; 1293 UINT8 ad_len, ad_type, ad_flag; 1294 1295 BTM_TRACE_EVENT0 (" btm_ble_parse_adv_data"); 1296 1297 while (len > 0) 1298 { 1299 BTM_TRACE_DEBUG1("btm_ble_parse_adv_data: len = %d", len); 1300 if ((ad_len = *p_cur ++) == 0) 1301 break; 1302 1303 ad_type = *p_cur ++; 1304 1305 BTM_TRACE_DEBUG2(" ad_type = %02x ad_len = %d", ad_type, ad_len); 1306 1307 switch (ad_type) 1308 { 1309 case BTM_BLE_AD_TYPE_NAME_SHORT: 1310 1311 case BTM_BLE_AD_TYPE_NAME_CMPL: 1312 p_adv_data->ad_mask |= BTM_BLE_AD_BIT_DEV_NAME; 1313 if (p_info) 1314 { 1315 p_info->remote_name_type =(ad_type == BTM_BLE_AD_TYPE_NAME_SHORT) ? 1316 BTM_BLE_NAME_SHORT: BTM_BLE_NAME_CMPL; 1317 memcpy(p_info->remote_name, p_cur, ad_len -1); 1318 p_info->remote_name[ad_len] = 0; 1319 p_adv_data->p_remote_name = p_info->remote_name; 1320 p_info->remote_name_len = p_adv_data->remote_name_len = ad_len - 1; 1321 BTM_TRACE_DEBUG1("BTM_BLE_AD_TYPE_NAME name = %s",p_adv_data->p_remote_name); 1322 } 1323 p_cur += (ad_len -1); 1324 1325 break; 1326 1327 case BTM_BLE_AD_TYPE_FLAG: 1328 p_adv_data->ad_mask |= BTM_BLE_AD_BIT_FLAGS; 1329 ad_flag = *p_cur ++; 1330 p_adv_data->flag = (UINT8)(ad_flag & BTM_BLE_ADV_FLAG_MASK) ; 1331 BTM_TRACE_DEBUG3("BTM_BLE_AD_TYPE_FLAG flag = %s | %s | %s", 1332 (p_adv_data->flag & BTM_BLE_LIMIT_DISC_FLAG)? "LE_LIMIT_DISC" : "", 1333 (p_adv_data->flag & BTM_BLE_GEN_DISC_FLAG)? "LE_GENERAL_DISC" : "", 1334 (p_adv_data->flag & BTM_BLE_BREDR_NOT_SPT)? "LE Only device" : ""); 1335 break; 1336 1337 case BTM_BLE_AD_TYPE_TX_PWR: 1338 p_adv_data->ad_mask |= BTM_BLE_AD_BIT_TX_PWR; 1339 p_adv_data->tx_power_level = (INT8)*p_cur ++; 1340 BTM_TRACE_DEBUG1("BTM_BLE_AD_TYPE_TX_PWR tx_level = %d", p_adv_data->tx_power_level); 1341 break; 1342 1343 case BTM_BLE_AD_TYPE_MANU: 1344 1345 case BTM_BLE_AD_TYPE_16SRV_PART: 1346 case BTM_BLE_AD_TYPE_16SRV_CMPL: 1347 p_adv_data->ad_mask |= BTM_BLE_AD_BIT_SERVICE; 1348 /* need allocate memory to store UUID list */ 1349 p_adv_data->service.num_service = (ad_len - 1)/2; 1350 BTM_TRACE_DEBUG1("service UUID list, num = %d", p_adv_data->service.num_service); 1351 p_cur += (ad_len - 1); 1352 break; 1353 1354 case BTM_BLE_AD_TYPE_SOL_SRV_UUID: 1355 p_adv_data->ad_mask |= BTM_BLE_AD_BIT_SERVICE_SOL; 1356 /* need allocate memory to store UUID list */ 1357 p_adv_data->service.num_service = (ad_len - 1)/2; 1358 BTM_TRACE_DEBUG1("service UUID list, num = %d", p_adv_data->service.num_service); 1359 p_cur += (ad_len - 1); 1360 break; 1361 1362 case BTM_BLE_AD_TYPE_128SOL_SRV_UUID: 1363 p_adv_data->ad_mask |= BTM_BLE_AD_BIT_SERVICE_128SOL; 1364 /* need allocate memory to store UUID list */ 1365 p_adv_data->service.num_service = (ad_len - 1)/16; 1366 BTM_TRACE_DEBUG1("service UUID list, num = %d", p_adv_data->service.num_service); 1367 p_cur += (ad_len - 1); 1368 break; 1369 1370 case BTM_BLE_AD_TYPE_APPEARANCE: 1371 case BTM_BLE_AD_TYPE_PUBLIC_TARGET: 1372 case BTM_BLE_AD_TYPE_RANDOM_TARGET: 1373 default: 1374 break; 1375 } 1376 len -= (ad_len + 1); 1377 } 1378 } 1379 #endif 1380 1381 /******************************************************************************* 1382 ** 1383 ** Function btm_ble_cache_adv_data 1384 ** 1385 ** Description Update advertising cache data. 1386 ** 1387 ** Returns void 1388 ** 1389 *******************************************************************************/ 1390 void btm_ble_cache_adv_data(tBTM_INQ_RESULTS *p_cur, UINT8 data_len, UINT8 *p, UINT8 evt_type) 1391 { 1392 tBTM_BLE_INQ_CB *p_le_inq_cb = &btm_cb.ble_ctr_cb.inq_var; 1393 UINT8 *p_cache; 1394 UINT8 length; 1395 1396 /* cache adv report/scan response data */ 1397 if (evt_type != BTM_BLE_SCAN_RSP_EVT) 1398 { 1399 p_le_inq_cb->adv_len = 0; 1400 memset(p_le_inq_cb->adv_data_cache, 0, BTM_BLE_CACHE_ADV_DATA_MAX); 1401 } 1402 1403 if (data_len > 0) 1404 { 1405 p_cache = &p_le_inq_cb->adv_data_cache[p_le_inq_cb->adv_len]; 1406 STREAM_TO_UINT8(length, p); 1407 while ( length && ((p_le_inq_cb->adv_len + length + 1) <= BTM_BLE_CACHE_ADV_DATA_MAX)) 1408 { 1409 /* copy from the length byte & data into cache */ 1410 memcpy(p_cache, p-1, length+1); 1411 /* advance the cache pointer past data */ 1412 p_cache += length+1; 1413 /* increment cache length */ 1414 p_le_inq_cb->adv_len += length+1; 1415 /* skip the length of data */ 1416 p += length; 1417 STREAM_TO_UINT8(length, p); 1418 } 1419 } 1420 1421 /* parse service UUID from adv packet and save it in inq db eir_uuid */ 1422 /* TODO */ 1423 } 1424 1425 /******************************************************************************* 1426 ** 1427 ** Function btm_ble_is_discoverable 1428 ** 1429 ** Description check ADV flag to make sure device is discoverable and match 1430 ** the search condition 1431 ** 1432 ** Parameters 1433 ** 1434 ** Returns void 1435 ** 1436 *******************************************************************************/ 1437 BOOLEAN btm_ble_is_discoverable(BD_ADDR bda, UINT8 evt_type, UINT8 *p) 1438 { 1439 BOOLEAN is_discoverable = FALSE; 1440 UINT8 *p_flag, flag = 0; 1441 UINT8 data_len; 1442 tBTM_INQ_PARMS *p_cond = &btm_cb.btm_inq_vars.inqparms; 1443 1444 STREAM_TO_UINT8 (data_len, p); 1445 1446 /* for observer, always "discoverable */ 1447 if (btm_cb.ble_ctr_cb.inq_var.proc_mode == BTM_BLE_OBSERVE || 1448 (btm_cb.ble_ctr_cb.inq_var.proc_mode == BTM_BLE_SELECT_SCAN && 1449 btm_cb.ble_ctr_cb.bg_conn_type == BTM_BLE_CONN_SELECTIVE)) 1450 return TRUE; 1451 1452 /* does not match filter condition */ 1453 if (p_cond->filter_cond_type == BTM_FILTER_COND_BD_ADDR && 1454 memcmp(bda, p_cond->filter_cond.bdaddr_cond, BD_ADDR_LEN) != 0) 1455 { 1456 BTM_TRACE_DEBUG0("BD ADDR does not meet filter condition"); 1457 return FALSE; 1458 } 1459 1460 /* scan response does not include the flag */ 1461 if (evt_type == BTM_BLE_SCAN_RSP_EVT) 1462 return FALSE; 1463 1464 if (data_len > BTM_BLE_ADV_DATA_LEN_MAX) 1465 { 1466 BTM_TRACE_WARNING1("ADV data too long %d. discard", data_len); 1467 return FALSE; 1468 } 1469 1470 if (data_len != 0) 1471 { 1472 if ((p_flag = BTM_CheckAdvData(p, BTM_BLE_AD_TYPE_FLAG, &data_len)) != NULL) 1473 { 1474 flag = * p_flag; 1475 1476 if ((btm_cb.ble_ctr_cb.inq_var.proc_mode == BTM_BLE_GENERAL_INQUIRY) && 1477 (flag & (BTM_BLE_LIMIT_DISC_FLAG|BTM_BLE_GEN_DISC_FLAG)) != 0) 1478 { 1479 BTM_TRACE_DEBUG0("Find Generable Discoverable device"); 1480 is_discoverable = TRUE; 1481 } 1482 1483 else if (btm_cb.ble_ctr_cb.inq_var.proc_mode == BTM_BLE_LIMITED_INQUIRY && 1484 (flag & BTM_BLE_LIMIT_DISC_FLAG) != 0) 1485 { 1486 BTM_TRACE_DEBUG0("Find limited discoverable device"); 1487 is_discoverable = TRUE; 1488 } 1489 1490 } 1491 } 1492 1493 if (!is_discoverable) 1494 { 1495 BTM_TRACE_ERROR1("discoverable flag not desired: %d", flag); 1496 } 1497 1498 return is_discoverable; 1499 } 1500 1501 /******************************************************************************* 1502 ** 1503 ** Function btm_ble_update_inq_result 1504 ** 1505 ** Description Update adv packet information into inquiry result. 1506 ** 1507 ** Parameters 1508 ** 1509 ** Returns void 1510 ** 1511 *******************************************************************************/ 1512 BOOLEAN btm_ble_update_inq_result(tINQ_DB_ENT *p_i, UINT8 addr_type, UINT8 evt_type, UINT8 *p) 1513 { 1514 BOOLEAN to_report = TRUE; 1515 tBTM_INQ_RESULTS *p_cur = &p_i->inq_info.results; 1516 UINT8 len; 1517 UINT8 *p_flag; 1518 tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars; 1519 UINT8 data_len, rssi; 1520 tBTM_BLE_INQ_CB *p_le_inq_cb = &btm_cb.ble_ctr_cb.inq_var; 1521 UINT8 *p1; 1522 1523 STREAM_TO_UINT8 (data_len, p); 1524 1525 if (data_len > BTM_BLE_ADV_DATA_LEN_MAX) 1526 { 1527 BTM_TRACE_WARNING1("EIR data too long %d. discard", data_len); 1528 return FALSE; 1529 } 1530 btm_ble_cache_adv_data(p_cur, data_len, p, evt_type); 1531 1532 p1 = (p + data_len); 1533 STREAM_TO_UINT8 (rssi, p1); 1534 1535 /* Save the info */ 1536 p_cur->inq_result_type = BTM_INQ_RESULT_BLE; 1537 p_cur->ble_addr_type = addr_type; 1538 p_cur->rssi = rssi; 1539 1540 /* active scan, always wait until get scan_rsp to report the result */ 1541 if ((btm_cb.ble_ctr_cb.inq_var.scan_type == BTM_BLE_SCAN_MODE_ACTI && 1542 (evt_type == BTM_BLE_CONNECT_EVT || evt_type == BTM_BLE_DISCOVER_EVT))) 1543 { 1544 p_i->scan_rsp = FALSE; 1545 to_report = FALSE; 1546 } 1547 else 1548 p_i->scan_rsp = TRUE; 1549 1550 if (p_i->inq_count != p_inq->inq_counter) 1551 p_cur->device_type = BT_DEVICE_TYPE_BLE; 1552 else 1553 p_cur->device_type |= BT_DEVICE_TYPE_BLE; 1554 1555 if (evt_type != BTM_BLE_SCAN_RSP_EVT) 1556 p_cur->ble_evt_type = evt_type; 1557 1558 p_i->inq_count = p_inq->inq_counter; /* Mark entry for current inquiry */ 1559 1560 if (p_le_inq_cb->adv_len != 0) 1561 { 1562 if ((p_flag = BTM_CheckAdvData(p_le_inq_cb->adv_data_cache, BTM_BLE_AD_TYPE_FLAG, &len)) != NULL) 1563 p_cur->flag = * p_flag; 1564 } 1565 1566 /* if BR/EDR not supported is not set, assume is a DUMO device */ 1567 if ((p_cur->flag & BTM_BLE_BREDR_NOT_SPT) == 0 && 1568 evt_type != BTM_BLE_CONNECT_DIR_EVT) 1569 { 1570 BTM_TRACE_DEBUG0("BR/EDR NOT support bit not set, treat as DUMO"); 1571 p_cur->device_type |= BT_DEVICE_TYPE_DUMO; 1572 } 1573 else 1574 { 1575 BTM_TRACE_DEBUG0("BR/EDR NOT SUPPORT bit set, LE only device"); 1576 } 1577 1578 return to_report; 1579 1580 } 1581 1582 /******************************************************************************* 1583 ** 1584 ** Function btm_send_sel_conn_callback 1585 ** 1586 ** Description send selection connection request callback. 1587 ** 1588 ** Parameters 1589 ** 1590 ** Returns void 1591 ** 1592 *******************************************************************************/ 1593 void btm_send_sel_conn_callback(BD_ADDR remote_bda, UINT8 evt_type, UINT8 *p_data, UINT8 addr_type) 1594 { 1595 UINT8 data_len, len; 1596 UINT8 *p_dev_name, remname[31] = {0}; 1597 1598 if (btm_cb.ble_ctr_cb.p_select_cback == NULL || 1599 /* non-connectable device */ 1600 (evt_type != BTM_BLE_EVT_CONN_ADV && evt_type != BTM_BLE_EVT_CONN_DIR_ADV)) 1601 return; 1602 1603 STREAM_TO_UINT8 (data_len, p_data); 1604 1605 /* get the device name if exist in ADV data */ 1606 if (data_len != 0) 1607 { 1608 p_dev_name = BTM_CheckAdvData(p_data, BTM_BLE_AD_TYPE_NAME_CMPL, &len); 1609 1610 if (p_dev_name == NULL) 1611 p_dev_name = BTM_CheckAdvData(p_data, BTM_BLE_AD_TYPE_NAME_SHORT, &len); 1612 1613 if (p_dev_name) 1614 memcpy(remname, p_dev_name, len); 1615 } 1616 /* allow connection */ 1617 if ((* btm_cb.ble_ctr_cb.p_select_cback)(remote_bda, remname)) 1618 { 1619 /* terminate selective connection, initiate connection */ 1620 btm_ble_initiate_select_conn(remote_bda); 1621 } 1622 } 1623 1624 /******************************************************************************* 1625 ** 1626 ** Function btm_ble_process_adv_pkt 1627 ** 1628 ** Description This function is called when adv packet report events are 1629 ** received from the device. It updates the inquiry database. 1630 ** If the inquiry database is full, the oldest entry is discarded. 1631 ** 1632 ** Parameters 1633 ** 1634 ** Returns void 1635 ** 1636 *******************************************************************************/ 1637 void btm_ble_process_adv_pkt (UINT8 *p_data) 1638 { 1639 BD_ADDR bda; 1640 UINT8 evt_type = 0, *p = p_data; 1641 UINT8 addr_type = 0; 1642 1643 /* always get one device at a time */ 1644 p ++; 1645 1646 /* Extract inquiry results */ 1647 STREAM_TO_UINT8 (evt_type, p); 1648 STREAM_TO_UINT8 (addr_type, p); 1649 STREAM_TO_BDADDR (bda, p); 1650 1651 #ifdef BTM_BLE_PC_ADV_TEST_MODE /* For general stack code (e.g. BTInsight testing), we simply do not define it to exclude or set it to TRUE to include */ 1652 if (BTM_BLE_PC_ADV_TEST_MODE) /* For stack component, it is always defined and maps to a global variable g_bDraculaAdvertisingMode */ 1653 { 1654 if (btm_cb.ble_ctr_cb.p_scan_req_cback) 1655 (*btm_cb.ble_ctr_cb.p_scan_req_cback)(bda, addr_type, evt_type); 1656 } 1657 #endif 1658 1659 1660 1661 /* Only process the results if the inquiry is still active */ 1662 if ((btm_cb.btm_inq_vars.inq_active & BTM_LE_SCAN_ACTIVE_MASK) == 0 && 1663 (btm_cb.ble_ctr_cb.bg_conn_type != BTM_BLE_CONN_SELECTIVE || 1664 /* or selective auto connection is active */ 1665 btm_cb.ble_ctr_cb.p_select_cback == NULL)) 1666 return; 1667 1668 btm_ble_process_adv_pkt_cont(bda, addr_type, evt_type, p); 1669 } 1670 1671 /******************************************************************************* 1672 ** 1673 ** Function btm_ble_process_adv_pkt_cont 1674 ** 1675 ** Description This function is called after random address resolution is 1676 ** done, and proceed to process adv packet. 1677 ** 1678 ** Parameters 1679 ** 1680 ** Returns void 1681 ** 1682 *******************************************************************************/ 1683 static void btm_ble_process_adv_pkt_cont(BD_ADDR bda, UINT8 addr_type, UINT8 evt_type, UINT8 *p) 1684 { 1685 tINQ_DB_ENT *p_i; 1686 BOOLEAN to_report = FALSE; 1687 tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars; 1688 tBTM_INQ_RESULTS_CB *p_inq_results_cb = p_inq->p_inq_results_cb; 1689 tBTM_BLE_INQ_CB *p_le_inq_cb = &btm_cb.ble_ctr_cb.inq_var; 1690 1691 p_i = btm_inq_db_find (bda); 1692 1693 /* Check if this address has already been processed for this inquiry */ 1694 if (btm_inq_find_bdaddr(bda)) 1695 { 1696 /* never been report as an LE device */ 1697 if ((p_i && 1698 (!(p_i->inq_info.results.device_type & BT_DEVICE_TYPE_BLE) || 1699 /* scan repsonse to be updated */ 1700 (!p_i->scan_rsp))) 1701 || 1702 btm_cb.ble_ctr_cb.inq_var.proc_mode == BTM_BLE_OBSERVE) 1703 { 1704 BTM_TRACE_DEBUG0("update new BLE information "); 1705 to_report = TRUE; 1706 } 1707 else 1708 { 1709 /* if yes, skip it */ 1710 return; /* assumption: one result per event */ 1711 } 1712 } 1713 else /* not been processed int his round */ 1714 { 1715 to_report = TRUE; 1716 } 1717 1718 /* If existing entry, use that, else get a new one (possibly reusing the oldest) */ 1719 if (p_i == NULL) 1720 { 1721 if (btm_ble_is_discoverable(bda, evt_type, p)) 1722 { 1723 if ((p_i = btm_inq_db_new (bda)) != NULL) 1724 { 1725 p_inq->inq_cmpl_info.num_resp++; 1726 to_report = TRUE; 1727 } 1728 else 1729 return; 1730 } 1731 else 1732 { 1733 BTM_TRACE_ERROR0("discard adv pkt"); 1734 return; 1735 } 1736 } 1737 else if (p_i->inq_count != p_inq->inq_counter) /* first time seen in this inquiry */ 1738 { 1739 p_inq->inq_cmpl_info.num_resp++; 1740 } 1741 1742 /* update the LE device information in inquiry database */ 1743 if (to_report) 1744 { 1745 to_report = btm_ble_update_inq_result(p_i, addr_type, evt_type, p); 1746 } 1747 1748 #if BTM_USE_INQ_RESULTS_FILTER == TRUE 1749 /* If the number of responses found and limited, issue a cancel inquiry */ 1750 if (p_inq->inqparms.max_resps && 1751 p_inq->inq_cmpl_info.num_resp == p_inq->inqparms.max_resps) 1752 { 1753 /* new device */ 1754 if (p_i == NULL || 1755 (/* assume a DUMO device, BR/EDR inquiry is always active */ 1756 p_i && p_i->inq_info.results.device_type == BT_DEVICE_TYPE_BLE && p_i->scan_rsp)) 1757 { 1758 BTM_TRACE_WARNING0("INQ RES: Extra Response Received...cancelling inquiry.."); 1759 1760 /* if is non-periodic inquiry active, cancel now */ 1761 if ((p_inq->inq_active & BTM_BR_INQ_ACTIVE_MASK) != 0 && 1762 (p_inq->inq_active & BTM_PERIODIC_INQUIRY_ACTIVE) == 0) 1763 btsnd_hcic_inq_cancel(); 1764 1765 /* stop LE scan now */ 1766 btm_ble_stop_scan(); 1767 1768 #if BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE 1769 btm_acl_update_busy_level (BTM_BLI_INQ_DONE_EVT); 1770 #endif 1771 } 1772 } 1773 #endif 1774 1775 /* background connection in selective connection mode */ 1776 if (btm_cb.ble_ctr_cb.bg_conn_type == BTM_BLE_CONN_SELECTIVE) 1777 { 1778 if (p_i->inq_info.results.device_type == BT_DEVICE_TYPE_BLE && 1779 (evt_type == BTM_BLE_CONNECT_EVT || evt_type == BTM_BLE_CONNECT_DIR_EVT)) 1780 btm_send_sel_conn_callback(bda, evt_type, p, addr_type); 1781 else 1782 { 1783 BTM_TRACE_DEBUG0("None LE device, can not initiate selective connection"); 1784 } 1785 } 1786 else if (p_inq_results_cb && to_report) 1787 { 1788 (p_inq_results_cb)((tBTM_INQ_RESULTS *) &p_i->inq_info.results, p_le_inq_cb->adv_data_cache); 1789 } 1790 } 1791 1792 /******************************************************************************* 1793 ** 1794 ** Function btm_ble_stop_scan 1795 ** 1796 ** Description Stop the BLE scan. 1797 ** 1798 ** Returns void 1799 ** 1800 *******************************************************************************/ 1801 void btm_ble_stop_scan(void) 1802 { 1803 tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var; 1804 tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars; 1805 1806 BTM_TRACE_EVENT0 ("btm_ble_stop_scan "); 1807 1808 btu_stop_timer (&p_cb->inq_timer_ent); 1809 1810 /* Clear the inquiry callback if set */ 1811 p_cb->scan_type = BTM_BLE_SCAN_MODE_NONE; 1812 p_cb->proc_mode = BTM_BLE_INQUIRY_NONE; 1813 1814 /* stop discovery now */ 1815 btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_DISABLE, BTM_BLE_DUPLICATE_ENABLE); 1816 1817 /* If we have a callback registered for inquiry complete, call it */ 1818 BTM_TRACE_DEBUG2 ("BTM Inq Compl Callback: status 0x%02x, num results %d", 1819 p_inq->inq_cmpl_info.status, p_inq->inq_cmpl_info.num_resp); 1820 1821 btm_update_scanner_filter_policy(SP_ADV_ALL); 1822 1823 btm_process_inq_complete(HCI_SUCCESS, (UINT8)(p_inq->inqparms.mode & BTM_BLE_INQUIRY_MASK)); 1824 1825 } 1826 1827 /******************************************************************************* 1828 ** 1829 ** Function btm_ble_start_adv 1830 ** 1831 ** Description Stop the BLE advertising. 1832 ** 1833 ** Returns void 1834 ** 1835 *******************************************************************************/ 1836 static tBTM_STATUS btm_ble_start_adv(void) 1837 { 1838 tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var; 1839 tBTM_STATUS rt = BTM_NO_RESOURCES; 1840 1841 if (btsnd_hcic_ble_set_adv_enable (BTM_BLE_ADV_ENABLE)) 1842 { 1843 if (p_cb->afp != AP_SCAN_CONN_ALL) 1844 btm_cb.ble_ctr_cb.wl_state |= BTM_BLE_WL_ADV; 1845 1846 p_cb->adv_mode = BTM_BLE_ADV_ENABLE; 1847 1848 rt = BTM_SUCCESS; 1849 } 1850 else 1851 { 1852 p_cb->adv_mode = BTM_BLE_ADV_DISABLE; 1853 btm_cb.ble_ctr_cb.wl_state &= ~BTM_BLE_WL_ADV; 1854 } 1855 return rt; 1856 } 1857 /******************************************************************************* 1858 ** 1859 ** Function btm_ble_stop_adv 1860 ** 1861 ** Description Stop the BLE advertising. 1862 ** 1863 ** Returns void 1864 ** 1865 *******************************************************************************/ 1866 static tBTM_STATUS btm_ble_stop_adv(void) 1867 { 1868 tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var; 1869 tBTM_STATUS rt = BTM_SUCCESS; 1870 1871 if (p_cb->adv_mode == BTM_BLE_ADV_ENABLE) 1872 { 1873 if (btsnd_hcic_ble_set_adv_enable (BTM_BLE_ADV_DISABLE)) 1874 { 1875 p_cb->adv_mode = BTM_BLE_ADV_DISABLE; 1876 btm_cb.ble_ctr_cb.wl_state &= ~BTM_BLE_WL_ADV; 1877 } 1878 else 1879 rt = BTM_NO_RESOURCES; 1880 } 1881 return rt; 1882 1883 } 1884 1885 /******************************************************************************* 1886 ** 1887 ** Function btm_ble_timeout 1888 ** 1889 ** Description Called when BTM BLE inquiry timer expires 1890 ** 1891 ** Returns void 1892 ** 1893 *******************************************************************************/ 1894 void btm_ble_timeout(TIMER_LIST_ENT *p_tle) 1895 { 1896 switch (p_tle->event) 1897 { 1898 case BTU_TTYPE_BLE_INQUIRY: 1899 btm_ble_stop_scan(); 1900 break; 1901 1902 case BTU_TTYPE_BLE_GAP_LIM_DISC: 1903 /* lim_timeout expiried, limited discovery should exit now */ 1904 btm_ble_update_adv_flag(BTM_BLE_NON_LIMIT_DISC_FLAG); 1905 1906 btm_ble_stop_adv(); 1907 break; 1908 1909 case BTU_TTYPE_BLE_RANDOM_ADDR: 1910 if (btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type == BLE_ADDR_RANDOM) 1911 { 1912 /* refresh the random addr */ 1913 btm_gen_resolvable_private_addr(); 1914 } 1915 break; 1916 1917 } 1918 } 1919 1920 1921 /******************************************************************************* 1922 ** 1923 ** Function btm_ble_read_remote_features_complete 1924 ** 1925 ** Description This function is called when the command complete message 1926 ** is received from the HCI for the read LE remote feature supported 1927 ** complete event. 1928 ** 1929 ** Returns void 1930 ** 1931 *******************************************************************************/ 1932 void btm_ble_read_remote_features_complete(UINT8 *p) 1933 { 1934 tACL_CONN *p_acl_cb = &btm_cb.acl_db[0]; 1935 UINT8 status; 1936 UINT16 handle; 1937 int xx; 1938 1939 BTM_TRACE_EVENT0 ("btm_ble_read_remote_features_complete "); 1940 1941 STREAM_TO_UINT8 (status, p); 1942 STREAM_TO_UINT16 (handle, p); 1943 1944 /* Look up the connection by handle and copy features */ 1945 for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_acl_cb++) 1946 { 1947 if ((p_acl_cb->in_use) && (p_acl_cb->hci_handle == handle)) 1948 { 1949 STREAM_TO_ARRAY(p_acl_cb->peer_le_features, p, BD_FEATURES_LEN); 1950 break; 1951 } 1952 } 1953 } 1954 1955 /******************************************************************************* 1956 ** 1957 ** Function btm_ble_write_adv_enable_complete 1958 ** 1959 ** Description This function process the write adv enable command complete. 1960 ** 1961 ** Returns void 1962 ** 1963 *******************************************************************************/ 1964 void btm_ble_write_adv_enable_complete(UINT8 * p) 1965 { 1966 tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var; 1967 1968 /* if write adv enable/disbale not succeed */ 1969 if (*p != HCI_SUCCESS) 1970 { 1971 /* toggle back the adv mode */ 1972 p_cb->adv_mode = !p_cb->adv_mode; 1973 } 1974 1975 1976 } 1977 1978 /******************************************************************************* 1979 ** 1980 ** Function btm_ble_dir_adv_tout 1981 ** 1982 ** Description when directed adv time out 1983 ** 1984 ** Returns void 1985 ** 1986 *******************************************************************************/ 1987 void btm_ble_dir_adv_tout(void) 1988 { 1989 btm_cb.ble_ctr_cb.inq_var.adv_mode = BTM_BLE_ADV_DISABLE; 1990 1991 /* make device fall back into undirected adv mode by default */ 1992 btm_cb.ble_ctr_cb.inq_var.directed_conn = FALSE; 1993 } 1994 1995 /******************************************************************************* 1996 ** 1997 ** Function btm_ble_update_mode_operation 1998 ** 1999 ** Description This function update the GAP role operation when a link status 2000 ** is updated. 2001 ** 2002 ** Returns void 2003 ** 2004 *******************************************************************************/ 2005 void btm_ble_update_mode_operation(UINT8 link_role, BD_ADDR bd_addr, BOOLEAN conn_cancel) 2006 { 2007 tACL_CONN *pa = &btm_cb.acl_db[0]; 2008 UINT16 xx; 2009 UINT8 dev_role = link_role; 2010 2011 BTM_TRACE_DEBUG1("btm_ble_update_mode_operation adv_mode = %d", btm_cb.ble_ctr_cb.inq_var.adv_mode ); 2012 2013 /* update periphera role operation */ 2014 /* If we are LE connectable, check if we need to start advertising again */ 2015 if (link_role == HCI_ROLE_UNKNOWN) 2016 /* && btm_cb.ble_ctr_cb.inq_var.connectable_mode != BTM_BLE_NON_CONNECTABLE) */ 2017 { 2018 for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, pa++) 2019 { 2020 /* If any other LE link is up, we are still not connectable */ 2021 if (pa->in_use && pa->is_le_link) 2022 { 2023 dev_role = pa->link_role; 2024 break; 2025 } 2026 } 2027 } 2028 2029 if (btm_cb.ble_ctr_cb.inq_var.connectable_mode == BTM_BLE_CONNECTABLE && 2030 (dev_role == HCI_ROLE_UNKNOWN )) /* when device has no connection, update adv here */ 2031 /* if already in connection, no connectable adv is allowed unless scatternet is enabled */ 2032 { 2033 btm_ble_set_connectability ( btm_cb.ble_ctr_cb.inq_var.connectable_mode ); 2034 } 2035 2036 /* if connection complete */ 2037 if (conn_cancel || link_role != HCI_ROLE_UNKNOWN) 2038 btm_ble_set_conn_st(BLE_CONN_IDLE); 2039 2040 if (btm_ble_get_conn_st() == BLE_CONN_IDLE) 2041 { 2042 if (!btm_send_pending_direct_conn()) 2043 { 2044 btm_ble_resume_bg_conn(); 2045 } 2046 } 2047 } 2048 2049 /******************************************************************************* 2050 ** 2051 ** Function btm_ble_init 2052 ** 2053 ** Description Initialize the control block variable values. 2054 ** 2055 ** Returns void 2056 ** 2057 *******************************************************************************/ 2058 void btm_ble_init (void) 2059 { 2060 tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb; 2061 2062 BTM_TRACE_EVENT0 ("btm_ble_init "); 2063 2064 memset(p_cb, 0, sizeof(tBTM_BLE_CB)); 2065 2066 p_cb->inq_var.adv_mode = BTM_BLE_ADV_DISABLE; 2067 p_cb->inq_var.scan_type = BTM_BLE_SCAN_MODE_NONE; 2068 p_cb->inq_var.adv_chnl_map = BTM_BLE_DEFAULT_ADV_CHNL_MAP; 2069 p_cb->inq_var.afp = BTM_BLE_DEFAULT_AFP; 2070 p_cb->inq_var.sfp = BTM_BLE_DEFAULT_SFP; 2071 p_cb->inq_var.connectable_mode = BTM_BLE_NON_CONNECTABLE; 2072 p_cb->inq_var.discoverable_mode = BTM_BLE_NON_DISCOVERABLE; 2073 2074 /* for background connection, reset connection params to be undefined */ 2075 p_cb->scan_int = p_cb->scan_win = BTM_BLE_CONN_PARAM_UNDEF; 2076 2077 p_cb->inq_var.evt_type = BTM_BLE_UNKNOWN_EVT; 2078 } 2079 2080 #endif /* BLE_INCLUDED */ 2081