1 /****************************************************************************** 2 * 3 * Copyright (C) 2014 The Android Open Source Project 4 * Copyright (C) 2009-2012 Broadcom Corporation 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at: 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 * 18 ******************************************************************************/ 19 20 /************************************************************************************ 21 * 22 * Filename: btif_core.c 23 * 24 * Description: Contains core functionality related to interfacing between 25 * Bluetooth HAL and BTE core stack. 26 * 27 ***********************************************************************************/ 28 29 #define LOG_TAG "bt_btif_core" 30 31 #include <ctype.h> 32 #include <dirent.h> 33 #include <fcntl.h> 34 #include <hardware/bluetooth.h> 35 #include <stdlib.h> 36 #include <string.h> 37 #include <sys/stat.h> 38 #include <sys/types.h> 39 #include <unistd.h> 40 41 #include "bdaddr.h" 42 #include "bt_utils.h" 43 #include "bta_api.h" 44 #include "bte.h" 45 #include "btif_api.h" 46 #include "btif_av.h" 47 #include "btif_config.h" 48 #include "btif_config.h" 49 #include "btif_pan.h" 50 #include "btif_profile_queue.h" 51 #include "btif_sock.h" 52 #include "btif_storage.h" 53 #include "btif_uid.h" 54 #include "btif_util.h" 55 #include "btu.h" 56 #include "device/include/controller.h" 57 #include "bt_common.h" 58 #include "osi/include/fixed_queue.h" 59 #include "osi/include/future.h" 60 #include "osi/include/log.h" 61 #include "osi/include/osi.h" 62 #include "osi/include/properties.h" 63 #include "osi/include/thread.h" 64 #include "stack_manager.h" 65 66 /************************************************************************************ 67 ** Constants & Macros 68 ************************************************************************************/ 69 70 #ifndef BTE_DID_CONF_FILE 71 // TODO(armansito): Find a better way than searching by a hardcoded path. 72 #if defined(OS_GENERIC) 73 #define BTE_DID_CONF_FILE "bt_did.conf" 74 #else // !defined(OS_GENERIC) 75 #define BTE_DID_CONF_FILE "/etc/bluetooth/bt_did.conf" 76 #endif // defined(OS_GENERIC) 77 #endif // BTE_DID_CONF_FILE 78 79 /************************************************************************************ 80 ** Local type definitions 81 ************************************************************************************/ 82 83 /* These type definitions are used when passing data from the HAL to BTIF context 84 * in the downstream path for the adapter and remote_device property APIs */ 85 86 typedef struct { 87 bt_bdaddr_t bd_addr; 88 bt_property_type_t type; 89 } btif_storage_read_t; 90 91 typedef struct { 92 bt_bdaddr_t bd_addr; 93 bt_property_t prop; 94 } btif_storage_write_t; 95 96 typedef union { 97 btif_storage_read_t read_req; 98 btif_storage_write_t write_req; 99 } btif_storage_req_t; 100 101 typedef enum { 102 BTIF_CORE_STATE_DISABLED = 0, 103 BTIF_CORE_STATE_ENABLING, 104 BTIF_CORE_STATE_ENABLED, 105 BTIF_CORE_STATE_DISABLING 106 } btif_core_state_t; 107 108 /************************************************************************************ 109 ** Static variables 110 ************************************************************************************/ 111 112 bt_bdaddr_t btif_local_bd_addr; 113 114 static tBTA_SERVICE_MASK btif_enabled_services = 0; 115 116 /* 117 * This variable should be set to 1, if the Bluedroid+BTIF libraries are to 118 * function in DUT mode. 119 * 120 * To set this, the btif_init_bluetooth needs to be called with argument as 1 121 */ 122 static UINT8 btif_dut_mode = 0; 123 124 static thread_t *bt_jni_workqueue_thread; 125 static const char *BT_JNI_WORKQUEUE_NAME = "bt_jni_workqueue"; 126 static uid_set_t* uid_set = NULL; 127 128 /************************************************************************************ 129 ** Static functions 130 ************************************************************************************/ 131 static void btif_jni_associate(UNUSED_ATTR uint16_t event, UNUSED_ATTR char *p_param); 132 static void btif_jni_disassociate(); 133 static bool btif_fetch_property(const char *key, bt_bdaddr_t *addr); 134 135 /* sends message to btif task */ 136 static void btif_sendmsg(void *p_msg); 137 138 /************************************************************************************ 139 ** Externs 140 ************************************************************************************/ 141 extern fixed_queue_t *btu_hci_msg_queue; 142 143 extern void bte_load_did_conf(const char *p_path); 144 145 /** TODO: Move these to _common.h */ 146 void bte_main_boot_entry(void); 147 void bte_main_disable(void); 148 void bte_main_cleanup(void); 149 #if (defined(HCILP_INCLUDED) && HCILP_INCLUDED == TRUE) 150 void bte_main_enable_lpm(BOOLEAN enable); 151 #endif 152 void bte_main_postload_cfg(void); 153 void btif_dm_execute_service_request(UINT16 event, char *p_param); 154 #ifdef BTIF_DM_OOB_TEST 155 void btif_dm_load_local_oob(void); 156 #endif 157 void bte_main_config_hci_logging(BOOLEAN enable, BOOLEAN bt_disabled); 158 159 /******************************************************************************* 160 ** 161 ** Function btif_context_switched 162 ** 163 ** Description Callback used to execute transferred context callback 164 ** 165 ** p_msg : message to be executed in btif context 166 ** 167 ** Returns void 168 ** 169 *******************************************************************************/ 170 171 static void btif_context_switched(void *p_msg) 172 { 173 174 BTIF_TRACE_VERBOSE("btif_context_switched"); 175 176 tBTIF_CONTEXT_SWITCH_CBACK *p = (tBTIF_CONTEXT_SWITCH_CBACK *) p_msg; 177 178 /* each callback knows how to parse the data */ 179 if (p->p_cb) 180 p->p_cb(p->event, p->p_param); 181 } 182 183 184 /******************************************************************************* 185 ** 186 ** Function btif_transfer_context 187 ** 188 ** Description This function switches context to btif task 189 ** 190 ** p_cback : callback used to process message in btif context 191 ** event : event id of message 192 ** p_params : parameter area passed to callback (copied) 193 ** param_len : length of parameter area 194 ** p_copy_cback : If set this function will be invoked for deep copy 195 ** 196 ** Returns void 197 ** 198 *******************************************************************************/ 199 200 bt_status_t btif_transfer_context (tBTIF_CBACK *p_cback, UINT16 event, char* p_params, int param_len, tBTIF_COPY_CBACK *p_copy_cback) 201 { 202 tBTIF_CONTEXT_SWITCH_CBACK *p_msg = 203 (tBTIF_CONTEXT_SWITCH_CBACK *)osi_malloc(sizeof(tBTIF_CONTEXT_SWITCH_CBACK) + param_len); 204 205 BTIF_TRACE_VERBOSE("btif_transfer_context event %d, len %d", event, param_len); 206 207 /* allocate and send message that will be executed in btif context */ 208 p_msg->hdr.event = BT_EVT_CONTEXT_SWITCH_EVT; /* internal event */ 209 p_msg->p_cb = p_cback; 210 211 p_msg->event = event; /* callback event */ 212 213 /* check if caller has provided a copy callback to do the deep copy */ 214 if (p_copy_cback) { 215 p_copy_cback(event, p_msg->p_param, p_params); 216 } else if (p_params) { 217 memcpy(p_msg->p_param, p_params, param_len); /* callback parameter data */ 218 } 219 220 btif_sendmsg(p_msg); 221 222 return BT_STATUS_SUCCESS; 223 } 224 225 /******************************************************************************* 226 ** 227 ** Function btif_is_dut_mode 228 ** 229 ** Description checks if BTIF is currently in DUT mode 230 ** 231 ** Returns 1 if test mode, otherwize 0 232 ** 233 *******************************************************************************/ 234 235 UINT8 btif_is_dut_mode(void) 236 { 237 return (btif_dut_mode == 1); 238 } 239 240 /******************************************************************************* 241 ** 242 ** Function btif_is_enabled 243 ** 244 ** Description checks if main adapter is fully enabled 245 ** 246 ** Returns 1 if fully enabled, otherwize 0 247 ** 248 *******************************************************************************/ 249 250 int btif_is_enabled(void) 251 { 252 return ((!btif_is_dut_mode()) && (stack_manager_get_interface()->get_stack_is_running())); 253 } 254 255 void btif_init_ok(UNUSED_ATTR uint16_t event, UNUSED_ATTR char *p_param) { 256 BTIF_TRACE_DEBUG("btif_task: received trigger stack init event"); 257 #if (BLE_INCLUDED == TRUE) 258 btif_dm_load_ble_local_keys(); 259 #endif 260 BTA_EnableBluetooth(bte_dm_evt); 261 } 262 263 /******************************************************************************* 264 ** 265 ** Function btif_task 266 ** 267 ** Description BTIF task handler managing all messages being passed 268 ** Bluetooth HAL and BTA. 269 ** 270 ** Returns void 271 ** 272 *******************************************************************************/ 273 static void bt_jni_msg_ready(void *context) { 274 BT_HDR *p_msg = (BT_HDR *)context; 275 276 BTIF_TRACE_VERBOSE("btif task fetched event %x", p_msg->event); 277 278 switch (p_msg->event) { 279 case BT_EVT_CONTEXT_SWITCH_EVT: 280 btif_context_switched(p_msg); 281 break; 282 default: 283 BTIF_TRACE_ERROR("unhandled btif event (%d)", p_msg->event & BT_EVT_MASK); 284 break; 285 } 286 osi_free(p_msg); 287 } 288 289 /******************************************************************************* 290 ** 291 ** Function btif_sendmsg 292 ** 293 ** Description Sends msg to BTIF task 294 ** 295 ** Returns void 296 ** 297 *******************************************************************************/ 298 299 void btif_sendmsg(void *p_msg) 300 { 301 if (!bt_jni_workqueue_thread) { 302 BTIF_TRACE_ERROR("%s: message dropped, queue not initialized or gone", __func__); 303 osi_free(p_msg); 304 return; 305 } 306 307 thread_post(bt_jni_workqueue_thread, bt_jni_msg_ready, p_msg); 308 } 309 310 void btif_thread_post(thread_fn func, void *context) { 311 if (!bt_jni_workqueue_thread) { 312 BTIF_TRACE_ERROR("%s: call dropped, queue not initialized or gone", __func__); 313 return; 314 } 315 316 thread_post(bt_jni_workqueue_thread, func, context); 317 } 318 319 static bool btif_fetch_property(const char *key, bt_bdaddr_t *addr) { 320 char val[PROPERTY_VALUE_MAX] = {0}; 321 322 if (osi_property_get(key, val, NULL)) { 323 if (string_to_bdaddr(val, addr)) { 324 BTIF_TRACE_DEBUG("%s: Got BDA %s", __func__, val); 325 return TRUE; 326 } 327 BTIF_TRACE_DEBUG("%s: System Property did not contain valid bdaddr", __func__); 328 } 329 return FALSE; 330 } 331 332 static void btif_fetch_local_bdaddr(bt_bdaddr_t *local_addr) 333 { 334 char val[PROPERTY_VALUE_MAX] = {0}; 335 uint8_t valid_bda = FALSE; 336 int val_size = 0; 337 338 const uint8_t null_bdaddr[BD_ADDR_LEN] = {0,0,0,0,0,0}; 339 340 /* Get local bdaddr storage path from property */ 341 if (osi_property_get(PROPERTY_BT_BDADDR_PATH, val, NULL)) 342 { 343 int addr_fd; 344 345 BTIF_TRACE_DEBUG("%s, local bdaddr is stored in %s", __func__, val); 346 347 if ((addr_fd = open(val, O_RDONLY)) != -1) 348 { 349 memset(val, 0, sizeof(val)); 350 read(addr_fd, val, FACTORY_BT_BDADDR_STORAGE_LEN); 351 /* If this is not a reserved/special bda, then use it */ 352 if ((string_to_bdaddr(val, local_addr)) && 353 (memcmp(local_addr->address, null_bdaddr, BD_ADDR_LEN) != 0)) 354 { 355 valid_bda = TRUE; 356 BTIF_TRACE_DEBUG("%s: Got Factory BDA %s", __func__, val); 357 } 358 close(addr_fd); 359 } 360 } 361 362 if(!valid_bda) 363 { 364 val_size = sizeof(val); 365 if(btif_config_get_str("Adapter", "Address", val, &val_size)) 366 { 367 string_to_bdaddr(val, local_addr); 368 BTIF_TRACE_DEBUG("local bdaddr from bt_config.xml is %s", val); 369 return; 370 } 371 } 372 373 /* No factory BDADDR found. Look for previously generated random BDA */ 374 if (!valid_bda) { 375 valid_bda = btif_fetch_property(PERSIST_BDADDR_PROPERTY, local_addr); 376 } 377 378 /* No BDADDR found in file. Look for BDA in factory property */ 379 if (!valid_bda) { 380 valid_bda = btif_fetch_property(FACTORY_BT_ADDR_PROPERTY, local_addr); 381 } 382 383 /* Generate new BDA if necessary */ 384 if (!valid_bda) 385 { 386 bdstr_t bdstr; 387 388 /* No autogen BDA. Generate one now. */ 389 local_addr->address[0] = 0x22; 390 local_addr->address[1] = 0x22; 391 local_addr->address[2] = (uint8_t) osi_rand(); 392 local_addr->address[3] = (uint8_t) osi_rand(); 393 local_addr->address[4] = (uint8_t) osi_rand(); 394 local_addr->address[5] = (uint8_t) osi_rand(); 395 396 /* Convert to ascii, and store as a persistent property */ 397 bdaddr_to_string(local_addr, bdstr, sizeof(bdstr)); 398 399 BTIF_TRACE_DEBUG("No preset BDA. Generating BDA: %s for prop %s", 400 (char*)bdstr, PERSIST_BDADDR_PROPERTY); 401 402 if (osi_property_set(PERSIST_BDADDR_PROPERTY, (char*)bdstr) < 0) 403 BTIF_TRACE_ERROR("Failed to set random BDA in prop %s",PERSIST_BDADDR_PROPERTY); 404 } 405 406 //save the bd address to config file 407 bdstr_t bdstr; 408 bdaddr_to_string(local_addr, bdstr, sizeof(bdstr)); 409 val_size = sizeof(val); 410 if (btif_config_get_str("Adapter", "Address", val, &val_size)) 411 { 412 if (strcmp(bdstr, val) ==0) 413 { 414 // BDA is already present in the config file. 415 return; 416 } 417 } 418 btif_config_set_str("Adapter", "Address", bdstr); 419 } 420 421 /******************************************************************************* 422 ** 423 ** Function btif_init_bluetooth 424 ** 425 ** Description Creates BTIF task and prepares BT scheduler for startup 426 ** 427 ** Returns bt_status_t 428 ** 429 *******************************************************************************/ 430 bt_status_t btif_init_bluetooth() { 431 bte_main_boot_entry(); 432 433 /* As part of the init, fetch the local BD ADDR */ 434 memset(&btif_local_bd_addr, 0, sizeof(bt_bdaddr_t)); 435 btif_fetch_local_bdaddr(&btif_local_bd_addr); 436 437 bt_jni_workqueue_thread = thread_new(BT_JNI_WORKQUEUE_NAME); 438 if (bt_jni_workqueue_thread == NULL) { 439 LOG_ERROR(LOG_TAG, "%s Unable to create thread %s", __func__, BT_JNI_WORKQUEUE_NAME); 440 goto error_exit; 441 } 442 443 // Associate this workqueue thread with jni. 444 btif_transfer_context(btif_jni_associate, 0, NULL, 0, NULL); 445 446 return BT_STATUS_SUCCESS; 447 448 error_exit:; 449 thread_free(bt_jni_workqueue_thread); 450 451 bt_jni_workqueue_thread = NULL; 452 453 return BT_STATUS_FAIL; 454 } 455 456 /******************************************************************************* 457 ** 458 ** Function btif_enable_bluetooth_evt 459 ** 460 ** Description Event indicating bluetooth enable is completed 461 ** Notifies HAL user with updated adapter state 462 ** 463 ** Returns void 464 ** 465 *******************************************************************************/ 466 467 void btif_enable_bluetooth_evt(tBTA_STATUS status) 468 { 469 const controller_t *controller = controller_get_interface(); 470 bdstr_t bdstr; 471 bdaddr_to_string(controller->get_address(), bdstr, sizeof(bdstr)); 472 473 BTIF_TRACE_DEBUG("%s: status %d, local bd [%s]", __FUNCTION__, status, bdstr); 474 475 if (bdcmp(btif_local_bd_addr.address, controller->get_address()->address)) 476 { 477 // TODO(zachoverflow): this whole code path seems like a bad time waiting to happen 478 // We open the vendor library using the old address. 479 bdstr_t old_address; 480 bt_property_t prop; 481 482 bdaddr_to_string(&btif_local_bd_addr, old_address, sizeof(old_address)); 483 484 /** 485 * The Controller's BDADDR does not match to the BTIF's initial BDADDR! 486 * This could be because the factory BDADDR was stored separately in 487 * the Controller's non-volatile memory rather than in device's file 488 * system. 489 **/ 490 BTIF_TRACE_WARNING("***********************************************"); 491 BTIF_TRACE_WARNING("BTIF init BDA was %s", old_address); 492 BTIF_TRACE_WARNING("Controller BDA is %s", bdstr); 493 BTIF_TRACE_WARNING("***********************************************"); 494 495 btif_local_bd_addr = *controller->get_address(); 496 497 //save the bd address to config file 498 btif_config_set_str("Adapter", "Address", bdstr); 499 btif_config_save(); 500 501 //fire HAL callback for property change 502 prop.type = BT_PROPERTY_BDADDR; 503 prop.val = (void*)&btif_local_bd_addr; 504 prop.len = sizeof(bt_bdaddr_t); 505 HAL_CBACK(bt_hal_cbacks, adapter_properties_cb, BT_STATUS_SUCCESS, 1, &prop); 506 } 507 508 bte_main_postload_cfg(); 509 #if (defined(HCILP_INCLUDED) && HCILP_INCLUDED == TRUE) 510 bte_main_enable_lpm(TRUE); 511 #endif 512 /* add passing up bd address as well ? */ 513 514 /* callback to HAL */ 515 if (status == BTA_SUCCESS) 516 { 517 uid_set = uid_set_create(); 518 519 btif_dm_init(uid_set); 520 521 /* init rfcomm & l2cap api */ 522 btif_sock_init(uid_set); 523 524 /* init pan */ 525 btif_pan_init(); 526 527 /* load did configuration */ 528 bte_load_did_conf(BTE_DID_CONF_FILE); 529 530 #ifdef BTIF_DM_OOB_TEST 531 btif_dm_load_local_oob(); 532 #endif 533 534 future_ready(stack_manager_get_hack_future(), FUTURE_SUCCESS); 535 } 536 else 537 { 538 /* cleanup rfcomm & l2cap api */ 539 btif_sock_cleanup(); 540 541 btif_pan_cleanup(); 542 543 future_ready(stack_manager_get_hack_future(), FUTURE_FAIL); 544 } 545 } 546 547 /******************************************************************************* 548 ** 549 ** Function btif_disable_bluetooth 550 ** 551 ** Description Inititates shutdown of Bluetooth system. 552 ** Any active links will be dropped and device entering 553 ** non connectable/discoverable mode 554 ** 555 ** Returns void 556 ** 557 *******************************************************************************/ 558 bt_status_t btif_disable_bluetooth(void) 559 { 560 BTIF_TRACE_DEBUG("BTIF DISABLE BLUETOOTH"); 561 562 btif_dm_on_disable(); 563 /* cleanup rfcomm & l2cap api */ 564 btif_sock_cleanup(); 565 btif_pan_cleanup(); 566 BTA_DisableBluetooth(); 567 568 return BT_STATUS_SUCCESS; 569 } 570 571 /******************************************************************************* 572 ** 573 ** Function btif_disable_bluetooth_evt 574 ** 575 ** Description Event notifying BT disable is now complete. 576 ** Terminates main stack tasks and notifies HAL 577 ** user with updated BT state. 578 ** 579 ** Returns void 580 ** 581 *******************************************************************************/ 582 583 void btif_disable_bluetooth_evt(void) 584 { 585 BTIF_TRACE_DEBUG("%s", __FUNCTION__); 586 587 #if (defined(HCILP_INCLUDED) && HCILP_INCLUDED == TRUE) 588 bte_main_enable_lpm(FALSE); 589 #endif 590 591 bte_main_disable(); 592 593 /* callback to HAL */ 594 future_ready(stack_manager_get_hack_future(), FUTURE_SUCCESS); 595 } 596 597 /******************************************************************************* 598 ** 599 ** Function btif_cleanup_bluetooth 600 ** 601 ** Description Cleanup BTIF state. 602 ** 603 ** Returns void 604 ** 605 *******************************************************************************/ 606 607 bt_status_t btif_cleanup_bluetooth(void) 608 { 609 BTIF_TRACE_DEBUG("%s", __FUNCTION__); 610 611 #if (BLE_INCLUDED == TRUE) 612 BTA_VendorCleanup(); 613 #endif 614 615 btif_dm_cleanup(); 616 btif_jni_disassociate(); 617 btif_queue_release(); 618 619 thread_free(bt_jni_workqueue_thread); 620 bt_jni_workqueue_thread = NULL; 621 622 bte_main_cleanup(); 623 624 btif_dut_mode = 0; 625 626 BTIF_TRACE_DEBUG("%s done", __FUNCTION__); 627 628 return BT_STATUS_SUCCESS; 629 } 630 631 /******************************************************************************* 632 ** 633 ** Function btif_dut_mode_cback 634 ** 635 ** Description Callback invoked on completion of vendor specific test mode command 636 ** 637 ** Returns None 638 ** 639 *******************************************************************************/ 640 static void btif_dut_mode_cback( tBTM_VSC_CMPL *p ) 641 { 642 UNUSED(p); 643 /* For now nothing to be done. */ 644 } 645 646 /******************************************************************************* 647 ** 648 ** Function btif_dut_mode_configure 649 ** 650 ** Description Configure Test Mode - 'enable' to 1 puts the device in test mode and 0 exits 651 ** test mode 652 ** 653 ** Returns BT_STATUS_SUCCESS on success 654 ** 655 *******************************************************************************/ 656 bt_status_t btif_dut_mode_configure(uint8_t enable) 657 { 658 BTIF_TRACE_DEBUG("%s", __FUNCTION__); 659 660 if (!stack_manager_get_interface()->get_stack_is_running()) { 661 BTIF_TRACE_ERROR("btif_dut_mode_configure : Bluetooth not enabled"); 662 return BT_STATUS_NOT_READY; 663 } 664 665 btif_dut_mode = enable; 666 if (enable == 1) { 667 BTA_EnableTestMode(); 668 } else { 669 BTA_DisableTestMode(); 670 } 671 return BT_STATUS_SUCCESS; 672 } 673 674 /******************************************************************************* 675 ** 676 ** Function btif_dut_mode_send 677 ** 678 ** Description Sends a HCI Vendor specific command to the controller 679 ** 680 ** Returns BT_STATUS_SUCCESS on success 681 ** 682 *******************************************************************************/ 683 bt_status_t btif_dut_mode_send(uint16_t opcode, uint8_t *buf, uint8_t len) 684 { 685 /* TODO: Check that opcode is a vendor command group */ 686 BTIF_TRACE_DEBUG("%s", __FUNCTION__); 687 if (!btif_is_dut_mode()) { 688 BTIF_TRACE_ERROR("Bluedroid HAL needs to be init with test_mode set to 1."); 689 return BT_STATUS_FAIL; 690 } 691 BTM_VendorSpecificCommand(opcode, len, buf, btif_dut_mode_cback); 692 return BT_STATUS_SUCCESS; 693 } 694 695 /***************************************************************************** 696 ** 697 ** btif api adapter property functions 698 ** 699 *****************************************************************************/ 700 701 static bt_status_t btif_in_get_adapter_properties(void) 702 { 703 bt_property_t properties[6]; 704 uint32_t num_props; 705 706 bt_bdaddr_t addr; 707 bt_bdname_t name; 708 bt_scan_mode_t mode; 709 uint32_t disc_timeout; 710 bt_bdaddr_t bonded_devices[BTM_SEC_MAX_DEVICE_RECORDS]; 711 bt_uuid_t local_uuids[BT_MAX_NUM_UUIDS]; 712 num_props = 0; 713 714 /* BD_ADDR */ 715 BTIF_STORAGE_FILL_PROPERTY(&properties[num_props], BT_PROPERTY_BDADDR, 716 sizeof(addr), &addr); 717 btif_storage_get_adapter_property(&properties[num_props]); 718 num_props++; 719 720 /* BD_NAME */ 721 BTIF_STORAGE_FILL_PROPERTY(&properties[num_props], BT_PROPERTY_BDNAME, 722 sizeof(name), &name); 723 btif_storage_get_adapter_property(&properties[num_props]); 724 num_props++; 725 726 /* SCAN_MODE */ 727 BTIF_STORAGE_FILL_PROPERTY(&properties[num_props], BT_PROPERTY_ADAPTER_SCAN_MODE, 728 sizeof(mode), &mode); 729 btif_storage_get_adapter_property(&properties[num_props]); 730 num_props++; 731 732 /* DISC_TIMEOUT */ 733 BTIF_STORAGE_FILL_PROPERTY(&properties[num_props], BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT, 734 sizeof(disc_timeout), &disc_timeout); 735 btif_storage_get_adapter_property(&properties[num_props]); 736 num_props++; 737 738 /* BONDED_DEVICES */ 739 BTIF_STORAGE_FILL_PROPERTY(&properties[num_props], BT_PROPERTY_ADAPTER_BONDED_DEVICES, 740 sizeof(bonded_devices), bonded_devices); 741 btif_storage_get_adapter_property(&properties[num_props]); 742 num_props++; 743 744 /* LOCAL UUIDs */ 745 BTIF_STORAGE_FILL_PROPERTY(&properties[num_props], BT_PROPERTY_UUIDS, 746 sizeof(local_uuids), local_uuids); 747 btif_storage_get_adapter_property(&properties[num_props]); 748 num_props++; 749 750 HAL_CBACK(bt_hal_cbacks, adapter_properties_cb, 751 BT_STATUS_SUCCESS, num_props, properties); 752 753 return BT_STATUS_SUCCESS; 754 } 755 756 static bt_status_t btif_in_get_remote_device_properties(bt_bdaddr_t *bd_addr) 757 { 758 bt_property_t remote_properties[8]; 759 uint32_t num_props = 0; 760 761 bt_bdname_t name, alias; 762 uint32_t cod, devtype; 763 bt_uuid_t remote_uuids[BT_MAX_NUM_UUIDS]; 764 765 memset(remote_properties, 0, sizeof(remote_properties)); 766 BTIF_STORAGE_FILL_PROPERTY(&remote_properties[num_props], BT_PROPERTY_BDNAME, 767 sizeof(name), &name); 768 btif_storage_get_remote_device_property(bd_addr, 769 &remote_properties[num_props]); 770 num_props++; 771 772 BTIF_STORAGE_FILL_PROPERTY(&remote_properties[num_props], BT_PROPERTY_REMOTE_FRIENDLY_NAME, 773 sizeof(alias), &alias); 774 btif_storage_get_remote_device_property(bd_addr, 775 &remote_properties[num_props]); 776 num_props++; 777 778 BTIF_STORAGE_FILL_PROPERTY(&remote_properties[num_props], BT_PROPERTY_CLASS_OF_DEVICE, 779 sizeof(cod), &cod); 780 btif_storage_get_remote_device_property(bd_addr, 781 &remote_properties[num_props]); 782 num_props++; 783 784 BTIF_STORAGE_FILL_PROPERTY(&remote_properties[num_props], BT_PROPERTY_TYPE_OF_DEVICE, 785 sizeof(devtype), &devtype); 786 btif_storage_get_remote_device_property(bd_addr, 787 &remote_properties[num_props]); 788 num_props++; 789 790 BTIF_STORAGE_FILL_PROPERTY(&remote_properties[num_props], BT_PROPERTY_UUIDS, 791 sizeof(remote_uuids), remote_uuids); 792 btif_storage_get_remote_device_property(bd_addr, 793 &remote_properties[num_props]); 794 num_props++; 795 796 HAL_CBACK(bt_hal_cbacks, remote_device_properties_cb, 797 BT_STATUS_SUCCESS, bd_addr, num_props, remote_properties); 798 799 return BT_STATUS_SUCCESS; 800 } 801 802 803 /******************************************************************************* 804 ** 805 ** Function execute_storage_request 806 ** 807 ** Description Executes adapter storage request in BTIF context 808 ** 809 ** Returns bt_status_t 810 ** 811 *******************************************************************************/ 812 813 static void execute_storage_request(UINT16 event, char *p_param) 814 { 815 bt_status_t status = BT_STATUS_SUCCESS; 816 817 BTIF_TRACE_EVENT("execute storage request event : %d", event); 818 819 switch(event) 820 { 821 case BTIF_CORE_STORAGE_ADAPTER_WRITE: 822 { 823 btif_storage_req_t *p_req = (btif_storage_req_t*)p_param; 824 bt_property_t *p_prop = &(p_req->write_req.prop); 825 BTIF_TRACE_EVENT("type: %d, len %d, 0x%x", p_prop->type, 826 p_prop->len, p_prop->val); 827 828 status = btif_storage_set_adapter_property(p_prop); 829 HAL_CBACK(bt_hal_cbacks, adapter_properties_cb, status, 1, p_prop); 830 } break; 831 832 case BTIF_CORE_STORAGE_ADAPTER_READ: 833 { 834 btif_storage_req_t *p_req = (btif_storage_req_t*)p_param; 835 char buf[512]; 836 bt_property_t prop; 837 prop.type = p_req->read_req.type; 838 prop.val = (void*)buf; 839 prop.len = sizeof(buf); 840 if (prop.type == BT_PROPERTY_LOCAL_LE_FEATURES) 841 { 842 #if (BLE_INCLUDED == TRUE) 843 tBTM_BLE_VSC_CB cmn_vsc_cb; 844 bt_local_le_features_t local_le_features; 845 846 /* LE features are not stored in storage. Should be retrived from stack */ 847 BTM_BleGetVendorCapabilities(&cmn_vsc_cb); 848 local_le_features.local_privacy_enabled = BTM_BleLocalPrivacyEnabled(); 849 850 prop.len = sizeof (bt_local_le_features_t); 851 if (cmn_vsc_cb.filter_support == 1) 852 local_le_features.max_adv_filter_supported = cmn_vsc_cb.max_filter; 853 else 854 local_le_features.max_adv_filter_supported = 0; 855 local_le_features.max_adv_instance = cmn_vsc_cb.adv_inst_max; 856 local_le_features.max_irk_list_size = cmn_vsc_cb.max_irk_list_sz; 857 local_le_features.rpa_offload_supported = cmn_vsc_cb.rpa_offloading; 858 local_le_features.scan_result_storage_size = cmn_vsc_cb.tot_scan_results_strg; 859 local_le_features.activity_energy_info_supported = cmn_vsc_cb.energy_support; 860 local_le_features.version_supported = cmn_vsc_cb.version_supported; 861 local_le_features.total_trackable_advertisers = 862 cmn_vsc_cb.total_trackable_advertisers; 863 864 local_le_features.extended_scan_support = cmn_vsc_cb.extended_scan_support > 0; 865 local_le_features.debug_logging_supported = cmn_vsc_cb.debug_logging_supported > 0; 866 memcpy(prop.val, &local_le_features, prop.len); 867 #endif 868 } 869 else 870 { 871 status = btif_storage_get_adapter_property(&prop); 872 } 873 HAL_CBACK(bt_hal_cbacks, adapter_properties_cb, status, 1, &prop); 874 } break; 875 876 case BTIF_CORE_STORAGE_ADAPTER_READ_ALL: 877 { 878 status = btif_in_get_adapter_properties(); 879 } break; 880 881 case BTIF_CORE_STORAGE_NOTIFY_STATUS: 882 { 883 HAL_CBACK(bt_hal_cbacks, adapter_properties_cb, status, 0, NULL); 884 } break; 885 886 default: 887 BTIF_TRACE_ERROR("%s invalid event id (%d)", __FUNCTION__, event); 888 break; 889 } 890 } 891 892 static void execute_storage_remote_request(UINT16 event, char *p_param) 893 { 894 bt_status_t status = BT_STATUS_FAIL; 895 bt_property_t prop; 896 897 BTIF_TRACE_EVENT("execute storage remote request event : %d", event); 898 899 switch (event) 900 { 901 case BTIF_CORE_STORAGE_REMOTE_READ: 902 { 903 char buf[1024]; 904 btif_storage_req_t *p_req = (btif_storage_req_t*)p_param; 905 prop.type = p_req->read_req.type; 906 prop.val = (void*) buf; 907 prop.len = sizeof(buf); 908 909 status = btif_storage_get_remote_device_property(&(p_req->read_req.bd_addr), 910 &prop); 911 HAL_CBACK(bt_hal_cbacks, remote_device_properties_cb, 912 status, &(p_req->read_req.bd_addr), 1, &prop); 913 }break; 914 case BTIF_CORE_STORAGE_REMOTE_WRITE: 915 { 916 btif_storage_req_t *p_req = (btif_storage_req_t*)p_param; 917 status = btif_storage_set_remote_device_property(&(p_req->write_req.bd_addr), 918 &(p_req->write_req.prop)); 919 }break; 920 case BTIF_CORE_STORAGE_REMOTE_READ_ALL: 921 { 922 btif_storage_req_t *p_req = (btif_storage_req_t*)p_param; 923 btif_in_get_remote_device_properties(&p_req->read_req.bd_addr); 924 }break; 925 } 926 } 927 928 void btif_adapter_properties_evt(bt_status_t status, uint32_t num_props, 929 bt_property_t *p_props) 930 { 931 HAL_CBACK(bt_hal_cbacks, adapter_properties_cb, 932 status, num_props, p_props); 933 934 } 935 void btif_remote_properties_evt(bt_status_t status, bt_bdaddr_t *remote_addr, 936 uint32_t num_props, bt_property_t *p_props) 937 { 938 HAL_CBACK(bt_hal_cbacks, remote_device_properties_cb, 939 status, remote_addr, num_props, p_props); 940 } 941 942 /******************************************************************************* 943 ** 944 ** Function btif_in_storage_request_copy_cb 945 ** 946 ** Description Switch context callback function to perform the deep copy for 947 ** both the adapter and remote_device property API 948 ** 949 ** Returns None 950 ** 951 *******************************************************************************/ 952 static void btif_in_storage_request_copy_cb(UINT16 event, 953 char *p_new_buf, char *p_old_buf) 954 { 955 btif_storage_req_t *new_req = (btif_storage_req_t*)p_new_buf; 956 btif_storage_req_t *old_req = (btif_storage_req_t*)p_old_buf; 957 958 BTIF_TRACE_EVENT("%s", __FUNCTION__); 959 switch (event) 960 { 961 case BTIF_CORE_STORAGE_REMOTE_WRITE: 962 case BTIF_CORE_STORAGE_ADAPTER_WRITE: 963 { 964 bdcpy(new_req->write_req.bd_addr.address, old_req->write_req.bd_addr.address); 965 /* Copy the member variables one at a time */ 966 new_req->write_req.prop.type = old_req->write_req.prop.type; 967 new_req->write_req.prop.len = old_req->write_req.prop.len; 968 969 new_req->write_req.prop.val = (UINT8 *)(p_new_buf + sizeof(btif_storage_req_t)); 970 memcpy(new_req->write_req.prop.val, old_req->write_req.prop.val, 971 old_req->write_req.prop.len); 972 }break; 973 } 974 } 975 976 /******************************************************************************* 977 ** 978 ** Function btif_get_adapter_properties 979 ** 980 ** Description Fetch all available properties (local & remote) 981 ** 982 ** Returns bt_status_t 983 ** 984 *******************************************************************************/ 985 986 bt_status_t btif_get_adapter_properties(void) 987 { 988 BTIF_TRACE_EVENT("%s", __FUNCTION__); 989 990 if (!btif_is_enabled()) 991 return BT_STATUS_NOT_READY; 992 993 return btif_transfer_context(execute_storage_request, 994 BTIF_CORE_STORAGE_ADAPTER_READ_ALL, 995 NULL, 0, NULL); 996 } 997 998 /******************************************************************************* 999 ** 1000 ** Function btif_get_adapter_property 1001 ** 1002 ** Description Fetches property value from local cache 1003 ** 1004 ** Returns bt_status_t 1005 ** 1006 *******************************************************************************/ 1007 1008 bt_status_t btif_get_adapter_property(bt_property_type_t type) 1009 { 1010 btif_storage_req_t req; 1011 1012 BTIF_TRACE_EVENT("%s %d", __FUNCTION__, type); 1013 1014 /* Allow get_adapter_property only for BDADDR and BDNAME if BT is disabled */ 1015 if (!btif_is_enabled() && (type != BT_PROPERTY_BDADDR) && (type != BT_PROPERTY_BDNAME)) 1016 return BT_STATUS_NOT_READY; 1017 1018 memset(&(req.read_req.bd_addr), 0, sizeof(bt_bdaddr_t)); 1019 req.read_req.type = type; 1020 1021 return btif_transfer_context(execute_storage_request, 1022 BTIF_CORE_STORAGE_ADAPTER_READ, 1023 (char*)&req, sizeof(btif_storage_req_t), NULL); 1024 } 1025 1026 /******************************************************************************* 1027 ** 1028 ** Function btif_set_adapter_property 1029 ** 1030 ** Description Updates core stack with property value and stores it in 1031 ** local cache 1032 ** 1033 ** Returns bt_status_t 1034 ** 1035 *******************************************************************************/ 1036 1037 bt_status_t btif_set_adapter_property(const bt_property_t *property) 1038 { 1039 btif_storage_req_t req; 1040 bt_status_t status = BT_STATUS_SUCCESS; 1041 int storage_req_id = BTIF_CORE_STORAGE_NOTIFY_STATUS; /* default */ 1042 char bd_name[BTM_MAX_LOC_BD_NAME_LEN +1]; 1043 UINT16 name_len = 0; 1044 1045 BTIF_TRACE_EVENT("btif_set_adapter_property type: %d, len %d, 0x%x", 1046 property->type, property->len, property->val); 1047 1048 if (!btif_is_enabled()) 1049 return BT_STATUS_NOT_READY; 1050 1051 switch(property->type) 1052 { 1053 case BT_PROPERTY_BDNAME: 1054 { 1055 name_len = property->len > BTM_MAX_LOC_BD_NAME_LEN ? BTM_MAX_LOC_BD_NAME_LEN: 1056 property->len; 1057 memcpy(bd_name,property->val, name_len); 1058 bd_name[name_len] = '\0'; 1059 1060 BTIF_TRACE_EVENT("set property name : %s", (char *)bd_name); 1061 1062 BTA_DmSetDeviceName((char *)bd_name); 1063 1064 storage_req_id = BTIF_CORE_STORAGE_ADAPTER_WRITE; 1065 } 1066 break; 1067 1068 case BT_PROPERTY_ADAPTER_SCAN_MODE: 1069 { 1070 bt_scan_mode_t mode = *(bt_scan_mode_t*)property->val; 1071 tBTA_DM_DISC disc_mode; 1072 tBTA_DM_CONN conn_mode; 1073 1074 switch(mode) 1075 { 1076 case BT_SCAN_MODE_NONE: 1077 disc_mode = BTA_DM_NON_DISC; 1078 conn_mode = BTA_DM_NON_CONN; 1079 break; 1080 1081 case BT_SCAN_MODE_CONNECTABLE: 1082 disc_mode = BTA_DM_NON_DISC; 1083 conn_mode = BTA_DM_CONN; 1084 break; 1085 1086 case BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE: 1087 disc_mode = BTA_DM_GENERAL_DISC; 1088 conn_mode = BTA_DM_CONN; 1089 break; 1090 1091 default: 1092 BTIF_TRACE_ERROR("invalid scan mode (0x%x)", mode); 1093 return BT_STATUS_PARM_INVALID; 1094 } 1095 1096 BTIF_TRACE_EVENT("set property scan mode : %x", mode); 1097 1098 BTA_DmSetVisibility(disc_mode, conn_mode, BTA_DM_IGNORE, BTA_DM_IGNORE); 1099 1100 storage_req_id = BTIF_CORE_STORAGE_ADAPTER_WRITE; 1101 } 1102 break; 1103 case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT: 1104 { 1105 /* Nothing to do beside store the value in NV. Java 1106 will change the SCAN_MODE property after setting timeout, 1107 if required */ 1108 storage_req_id = BTIF_CORE_STORAGE_ADAPTER_WRITE; 1109 } 1110 break; 1111 case BT_PROPERTY_BDADDR: 1112 case BT_PROPERTY_UUIDS: 1113 case BT_PROPERTY_ADAPTER_BONDED_DEVICES: 1114 case BT_PROPERTY_REMOTE_FRIENDLY_NAME: 1115 /* no write support through HAL, these properties are only populated from BTA events */ 1116 status = BT_STATUS_FAIL; 1117 break; 1118 default: 1119 BTIF_TRACE_ERROR("btif_get_adapter_property : invalid type %d", 1120 property->type); 1121 status = BT_STATUS_FAIL; 1122 break; 1123 } 1124 1125 if (storage_req_id != BTIF_CORE_STORAGE_NO_ACTION) 1126 { 1127 /* pass on to storage for updating local database */ 1128 1129 memset(&(req.write_req.bd_addr), 0, sizeof(bt_bdaddr_t)); 1130 memcpy(&(req.write_req.prop), property, sizeof(bt_property_t)); 1131 1132 return btif_transfer_context(execute_storage_request, 1133 storage_req_id, 1134 (char*)&req, 1135 sizeof(btif_storage_req_t)+property->len, 1136 btif_in_storage_request_copy_cb); 1137 } 1138 1139 return status; 1140 1141 } 1142 1143 /******************************************************************************* 1144 ** 1145 ** Function btif_get_remote_device_property 1146 ** 1147 ** Description Fetches the remote device property from the NVRAM 1148 ** 1149 ** Returns bt_status_t 1150 ** 1151 *******************************************************************************/ 1152 bt_status_t btif_get_remote_device_property(bt_bdaddr_t *remote_addr, 1153 bt_property_type_t type) 1154 { 1155 btif_storage_req_t req; 1156 1157 if (!btif_is_enabled()) 1158 return BT_STATUS_NOT_READY; 1159 1160 memcpy(&(req.read_req.bd_addr), remote_addr, sizeof(bt_bdaddr_t)); 1161 req.read_req.type = type; 1162 return btif_transfer_context(execute_storage_remote_request, 1163 BTIF_CORE_STORAGE_REMOTE_READ, 1164 (char*)&req, sizeof(btif_storage_req_t), 1165 NULL); 1166 } 1167 1168 /******************************************************************************* 1169 ** 1170 ** Function btif_get_remote_device_properties 1171 ** 1172 ** Description Fetches all the remote device properties from NVRAM 1173 ** 1174 ** Returns bt_status_t 1175 ** 1176 *******************************************************************************/ 1177 bt_status_t btif_get_remote_device_properties(bt_bdaddr_t *remote_addr) 1178 { 1179 btif_storage_req_t req; 1180 1181 if (!btif_is_enabled()) 1182 return BT_STATUS_NOT_READY; 1183 1184 memcpy(&(req.read_req.bd_addr), remote_addr, sizeof(bt_bdaddr_t)); 1185 return btif_transfer_context(execute_storage_remote_request, 1186 BTIF_CORE_STORAGE_REMOTE_READ_ALL, 1187 (char*)&req, sizeof(btif_storage_req_t), 1188 NULL); 1189 } 1190 1191 /******************************************************************************* 1192 ** 1193 ** Function btif_set_remote_device_property 1194 ** 1195 ** Description Writes the remote device property to NVRAM. 1196 ** Currently, BT_PROPERTY_REMOTE_FRIENDLY_NAME is the only 1197 ** remote device property that can be set 1198 ** 1199 ** Returns bt_status_t 1200 ** 1201 *******************************************************************************/ 1202 bt_status_t btif_set_remote_device_property(bt_bdaddr_t *remote_addr, 1203 const bt_property_t *property) 1204 { 1205 btif_storage_req_t req; 1206 1207 if (!btif_is_enabled()) 1208 return BT_STATUS_NOT_READY; 1209 1210 memcpy(&(req.write_req.bd_addr), remote_addr, sizeof(bt_bdaddr_t)); 1211 memcpy(&(req.write_req.prop), property, sizeof(bt_property_t)); 1212 1213 return btif_transfer_context(execute_storage_remote_request, 1214 BTIF_CORE_STORAGE_REMOTE_WRITE, 1215 (char*)&req, 1216 sizeof(btif_storage_req_t)+property->len, 1217 btif_in_storage_request_copy_cb); 1218 } 1219 1220 1221 /******************************************************************************* 1222 ** 1223 ** Function btif_get_remote_service_record 1224 ** 1225 ** Description Looks up the service matching uuid on the remote device 1226 ** and fetches the SCN and service_name if the UUID is found 1227 ** 1228 ** Returns bt_status_t 1229 ** 1230 *******************************************************************************/ 1231 bt_status_t btif_get_remote_service_record(bt_bdaddr_t *remote_addr, 1232 bt_uuid_t *uuid) 1233 { 1234 if (!btif_is_enabled()) 1235 return BT_STATUS_NOT_READY; 1236 1237 return btif_dm_get_remote_service_record(remote_addr, uuid); 1238 } 1239 1240 1241 /******************************************************************************* 1242 ** 1243 ** Function btif_get_enabled_services_mask 1244 ** 1245 ** Description Fetches currently enabled services 1246 ** 1247 ** Returns tBTA_SERVICE_MASK 1248 ** 1249 *******************************************************************************/ 1250 1251 tBTA_SERVICE_MASK btif_get_enabled_services_mask(void) 1252 { 1253 return btif_enabled_services; 1254 } 1255 1256 /******************************************************************************* 1257 ** 1258 ** Function btif_enable_service 1259 ** 1260 ** Description Enables the service 'service_ID' to the service_mask. 1261 ** Upon BT enable, BTIF core shall invoke the BTA APIs to 1262 ** enable the profiles 1263 ** 1264 ** Returns bt_status_t 1265 ** 1266 *******************************************************************************/ 1267 bt_status_t btif_enable_service(tBTA_SERVICE_ID service_id) 1268 { 1269 tBTA_SERVICE_ID *p_id = &service_id; 1270 1271 /* If BT is enabled, we need to switch to BTIF context and trigger the 1272 * enable for that profile 1273 * 1274 * Otherwise, we just set the flag. On BT_Enable, the DM will trigger 1275 * enable for the profiles that have been enabled */ 1276 1277 btif_enabled_services |= (1 << service_id); 1278 1279 BTIF_TRACE_DEBUG("%s: current services:0x%x", __FUNCTION__, btif_enabled_services); 1280 1281 if (btif_is_enabled()) 1282 { 1283 btif_transfer_context(btif_dm_execute_service_request, 1284 BTIF_DM_ENABLE_SERVICE, 1285 (char*)p_id, sizeof(tBTA_SERVICE_ID), NULL); 1286 } 1287 1288 return BT_STATUS_SUCCESS; 1289 } 1290 /******************************************************************************* 1291 ** 1292 ** Function btif_disable_service 1293 ** 1294 ** Description Disables the service 'service_ID' to the service_mask. 1295 ** Upon BT disable, BTIF core shall invoke the BTA APIs to 1296 ** disable the profiles 1297 ** 1298 ** Returns bt_status_t 1299 ** 1300 *******************************************************************************/ 1301 bt_status_t btif_disable_service(tBTA_SERVICE_ID service_id) 1302 { 1303 tBTA_SERVICE_ID *p_id = &service_id; 1304 1305 /* If BT is enabled, we need to switch to BTIF context and trigger the 1306 * disable for that profile so that the appropriate uuid_property_changed will 1307 * be triggerred. Otherwise, we just need to clear the service_id in the mask 1308 */ 1309 1310 btif_enabled_services &= (tBTA_SERVICE_MASK)(~(1<<service_id)); 1311 1312 BTIF_TRACE_DEBUG("%s: Current Services:0x%x", __FUNCTION__, btif_enabled_services); 1313 1314 if (btif_is_enabled()) 1315 { 1316 btif_transfer_context(btif_dm_execute_service_request, 1317 BTIF_DM_DISABLE_SERVICE, 1318 (char*)p_id, sizeof(tBTA_SERVICE_ID), NULL); 1319 } 1320 1321 return BT_STATUS_SUCCESS; 1322 } 1323 1324 static void btif_jni_associate(UNUSED_ATTR uint16_t event, UNUSED_ATTR char *p_param) { 1325 BTIF_TRACE_DEBUG("%s Associating thread to JVM", __func__); 1326 HAL_CBACK(bt_hal_cbacks, thread_evt_cb, ASSOCIATE_JVM); 1327 } 1328 1329 static void btif_jni_disassociate() { 1330 BTIF_TRACE_DEBUG("%s Disassociating thread from JVM", __func__); 1331 HAL_CBACK(bt_hal_cbacks, thread_evt_cb, DISASSOCIATE_JVM); 1332 bt_hal_cbacks = NULL; 1333 } 1334