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