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