1 /****************************************************************************** 2 * 3 * Copyright (C) 1999-2012 Broadcom Corporation 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19 /****************************************************************************** 20 * 21 * This file contains functions that handle BTM interface functions for the 22 * Bluetooth device including Rest, HCI buffer size and others 23 * 24 ******************************************************************************/ 25 26 #include <base/logging.h> 27 #include <stddef.h> 28 #include <stdio.h> 29 #include <stdlib.h> 30 #include <string.h> 31 32 #include "bt_types.h" 33 #include "bt_utils.h" 34 #include "btcore/include/module.h" 35 #include "btm_int.h" 36 #include "btu.h" 37 #include "device/include/controller.h" 38 #include "hci_layer.h" 39 #include "hcimsgs.h" 40 #include "l2c_int.h" 41 #include "osi/include/osi.h" 42 #include "osi/include/thread.h" 43 44 #include "gatt_int.h" 45 46 extern thread_t* bt_workqueue_thread; 47 48 /******************************************************************************/ 49 /* L O C A L D A T A D E F I N I T I O N S */ 50 /******************************************************************************/ 51 52 #ifndef BTM_DEV_RESET_TIMEOUT 53 #define BTM_DEV_RESET_TIMEOUT 4 54 #endif 55 56 // TODO: Reevaluate this value in the context of timers with ms granularity 57 #define BTM_DEV_NAME_REPLY_TIMEOUT_MS \ 58 (2 * 1000) /* 2 seconds for name reply \ 59 */ 60 61 #define BTM_INFO_TIMEOUT 5 /* 5 seconds for info response */ 62 63 /******************************************************************************/ 64 /* L O C A L F U N C T I O N P R O T O T Y P E S */ 65 /******************************************************************************/ 66 67 static void btm_decode_ext_features_page(uint8_t page_number, 68 const BD_FEATURES p_features); 69 70 /******************************************************************************* 71 * 72 * Function btm_dev_init 73 * 74 * Description This function is on the BTM startup 75 * 76 * Returns void 77 * 78 ******************************************************************************/ 79 void btm_dev_init(void) { 80 /* Initialize nonzero defaults */ 81 memset(btm_cb.cfg.bd_name, 0, sizeof(tBTM_LOC_BD_NAME)); 82 83 btm_cb.devcb.read_local_name_timer = alarm_new("btm.read_local_name_timer"); 84 btm_cb.devcb.read_rssi_timer = alarm_new("btm.read_rssi_timer"); 85 btm_cb.devcb.read_failed_contact_counter_timer = 86 alarm_new("btm.read_failed_contact_counter_timer"); 87 btm_cb.devcb.read_automatic_flush_timeout_timer = 88 alarm_new("btm.read_automatic_flush_timeout_timer"); 89 btm_cb.devcb.read_link_quality_timer = 90 alarm_new("btm.read_link_quality_timer"); 91 btm_cb.devcb.read_inq_tx_power_timer = 92 alarm_new("btm.read_inq_tx_power_timer"); 93 btm_cb.devcb.qos_setup_timer = alarm_new("btm.qos_setup_timer"); 94 btm_cb.devcb.read_tx_power_timer = alarm_new("btm.read_tx_power_timer"); 95 96 btm_cb.btm_acl_pkt_types_supported = 97 BTM_ACL_PKT_TYPES_MASK_DH1 + BTM_ACL_PKT_TYPES_MASK_DM1 + 98 BTM_ACL_PKT_TYPES_MASK_DH3 + BTM_ACL_PKT_TYPES_MASK_DM3 + 99 BTM_ACL_PKT_TYPES_MASK_DH5 + BTM_ACL_PKT_TYPES_MASK_DM5; 100 101 btm_cb.btm_sco_pkt_types_supported = 102 ESCO_PKT_TYPES_MASK_HV1 + ESCO_PKT_TYPES_MASK_HV2 + 103 ESCO_PKT_TYPES_MASK_HV3 + ESCO_PKT_TYPES_MASK_EV3 + 104 ESCO_PKT_TYPES_MASK_EV4 + ESCO_PKT_TYPES_MASK_EV5; 105 } 106 107 /******************************************************************************* 108 * 109 * Function btm_db_reset 110 * 111 * Description This function is called by BTM_DeviceReset and clears out 112 * any pending callbacks for inquiries, discoveries, other 113 * pending functions that may be in progress. 114 * 115 * Returns void 116 * 117 ******************************************************************************/ 118 static void btm_db_reset(void) { 119 tBTM_CMPL_CB* p_cb; 120 tBTM_STATUS status = BTM_DEV_RESET; 121 122 btm_inq_db_reset(); 123 124 if (btm_cb.devcb.p_rln_cmpl_cb) { 125 p_cb = btm_cb.devcb.p_rln_cmpl_cb; 126 btm_cb.devcb.p_rln_cmpl_cb = NULL; 127 128 if (p_cb) (*p_cb)((void*)NULL); 129 } 130 131 if (btm_cb.devcb.p_rssi_cmpl_cb) { 132 p_cb = btm_cb.devcb.p_rssi_cmpl_cb; 133 btm_cb.devcb.p_rssi_cmpl_cb = NULL; 134 135 if (p_cb) (*p_cb)((tBTM_RSSI_RESULT*)&status); 136 } 137 138 if (btm_cb.devcb.p_failed_contact_counter_cmpl_cb) { 139 p_cb = btm_cb.devcb.p_failed_contact_counter_cmpl_cb; 140 btm_cb.devcb.p_failed_contact_counter_cmpl_cb = NULL; 141 142 if (p_cb) (*p_cb)((tBTM_FAILED_CONTACT_COUNTER_RESULT*)&status); 143 } 144 145 if (btm_cb.devcb.p_automatic_flush_timeout_cmpl_cb) { 146 p_cb = btm_cb.devcb.p_automatic_flush_timeout_cmpl_cb; 147 btm_cb.devcb.p_automatic_flush_timeout_cmpl_cb = NULL; 148 149 if (p_cb) (*p_cb)((tBTM_AUTOMATIC_FLUSH_TIMEOUT_RESULT*)&status); 150 } 151 } 152 153 bool set_sec_state_idle(void* data, void* context) { 154 tBTM_SEC_DEV_REC* p_dev_rec = static_cast<tBTM_SEC_DEV_REC*>(data); 155 p_dev_rec->sec_state = BTM_SEC_STATE_IDLE; 156 return true; 157 } 158 159 static void reset_complete(void* result) { 160 CHECK(result == FUTURE_SUCCESS); 161 const controller_t* controller = controller_get_interface(); 162 163 /* Tell L2CAP that all connections are gone */ 164 l2cu_device_reset(); 165 166 /* Clear current security state */ 167 list_foreach(btm_cb.sec_dev_rec, set_sec_state_idle, NULL); 168 169 /* After the reset controller should restore all parameters to defaults. */ 170 btm_cb.btm_inq_vars.inq_counter = 1; 171 btm_cb.btm_inq_vars.inq_scan_window = HCI_DEF_INQUIRYSCAN_WINDOW; 172 btm_cb.btm_inq_vars.inq_scan_period = HCI_DEF_INQUIRYSCAN_INTERVAL; 173 btm_cb.btm_inq_vars.inq_scan_type = HCI_DEF_SCAN_TYPE; 174 175 btm_cb.btm_inq_vars.page_scan_window = HCI_DEF_PAGESCAN_WINDOW; 176 btm_cb.btm_inq_vars.page_scan_period = HCI_DEF_PAGESCAN_INTERVAL; 177 btm_cb.btm_inq_vars.page_scan_type = HCI_DEF_SCAN_TYPE; 178 179 btm_cb.ble_ctr_cb.conn_state = BLE_CONN_IDLE; 180 btm_cb.ble_ctr_cb.bg_conn_type = BTM_BLE_CONN_NONE; 181 gatt_reset_bgdev_list(); 182 183 btm_pm_reset(); 184 185 l2c_link_processs_num_bufs(controller->get_acl_buffer_count_classic()); 186 187 #if (BLE_PRIVACY_SPT == TRUE) 188 /* Set up the BLE privacy settings */ 189 if (controller->supports_ble() && controller->supports_ble_privacy() && 190 controller->get_ble_resolving_list_max_size() > 0) { 191 btm_ble_resolving_list_init(controller->get_ble_resolving_list_max_size()); 192 /* set the default random private address timeout */ 193 btsnd_hcic_ble_set_rand_priv_addr_timeout(BTM_BLE_PRIVATE_ADDR_INT_MS / 194 1000); 195 } 196 #endif 197 198 if (controller->supports_ble()) { 199 btm_ble_white_list_init(controller->get_ble_white_list_size()); 200 l2c_link_processs_ble_num_bufs(controller->get_acl_buffer_count_ble()); 201 } 202 203 BTM_SetPinType(btm_cb.cfg.pin_type, btm_cb.cfg.pin_code, 204 btm_cb.cfg.pin_code_len); 205 206 for (int i = 0; i <= controller->get_last_features_classic_index(); i++) { 207 btm_decode_ext_features_page(i, 208 controller->get_features_classic(i)->as_array); 209 } 210 211 btm_report_device_status(BTM_DEV_STATUS_UP); 212 } 213 214 // TODO(zachoverflow): remove this function 215 void BTM_DeviceReset(UNUSED_ATTR tBTM_CMPL_CB* p_cb) { 216 /* Flush all ACL connections */ 217 btm_acl_device_down(); 218 219 /* Clear the callback, so application would not hang on reset */ 220 btm_db_reset(); 221 222 module_start_up_callbacked_wrapper(get_module(CONTROLLER_MODULE), 223 bt_workqueue_thread, reset_complete); 224 } 225 226 /******************************************************************************* 227 * 228 * Function BTM_IsDeviceUp 229 * 230 * Description This function is called to check if the device is up. 231 * 232 * Returns true if device is up, else false 233 * 234 ******************************************************************************/ 235 bool BTM_IsDeviceUp(void) { return controller_get_interface()->get_is_ready(); } 236 237 /******************************************************************************* 238 * 239 * Function btm_read_local_name_timeout 240 * 241 * Description Callback when reading the local name times out. 242 * 243 * Returns void 244 * 245 ******************************************************************************/ 246 void btm_read_local_name_timeout(UNUSED_ATTR void* data) { 247 tBTM_CMPL_CB* p_cb = btm_cb.devcb.p_rln_cmpl_cb; 248 btm_cb.devcb.p_rln_cmpl_cb = NULL; 249 if (p_cb) (*p_cb)((void*)NULL); 250 } 251 252 /******************************************************************************* 253 * 254 * Function btm_decode_ext_features_page 255 * 256 * Description This function is decodes a features page. 257 * 258 * Returns void 259 * 260 ******************************************************************************/ 261 static void btm_decode_ext_features_page(uint8_t page_number, 262 const uint8_t* p_features) { 263 BTM_TRACE_DEBUG("btm_decode_ext_features_page page: %d", page_number); 264 switch (page_number) { 265 /* Extended (Legacy) Page 0 */ 266 case 0: 267 268 /* Create ACL supported packet types mask */ 269 btm_cb.btm_acl_pkt_types_supported = 270 (BTM_ACL_PKT_TYPES_MASK_DH1 + BTM_ACL_PKT_TYPES_MASK_DM1); 271 272 if (HCI_3_SLOT_PACKETS_SUPPORTED(p_features)) 273 btm_cb.btm_acl_pkt_types_supported |= 274 (BTM_ACL_PKT_TYPES_MASK_DH3 + BTM_ACL_PKT_TYPES_MASK_DM3); 275 276 if (HCI_5_SLOT_PACKETS_SUPPORTED(p_features)) 277 btm_cb.btm_acl_pkt_types_supported |= 278 (BTM_ACL_PKT_TYPES_MASK_DH5 + BTM_ACL_PKT_TYPES_MASK_DM5); 279 280 /* Add in EDR related ACL types */ 281 if (!HCI_EDR_ACL_2MPS_SUPPORTED(p_features)) { 282 btm_cb.btm_acl_pkt_types_supported |= 283 (BTM_ACL_PKT_TYPES_MASK_NO_2_DH1 + BTM_ACL_PKT_TYPES_MASK_NO_2_DH3 + 284 BTM_ACL_PKT_TYPES_MASK_NO_2_DH5); 285 } 286 287 if (!HCI_EDR_ACL_3MPS_SUPPORTED(p_features)) { 288 btm_cb.btm_acl_pkt_types_supported |= 289 (BTM_ACL_PKT_TYPES_MASK_NO_3_DH1 + BTM_ACL_PKT_TYPES_MASK_NO_3_DH3 + 290 BTM_ACL_PKT_TYPES_MASK_NO_3_DH5); 291 } 292 293 /* Check to see if 3 and 5 slot packets are available */ 294 if (HCI_EDR_ACL_2MPS_SUPPORTED(p_features) || 295 HCI_EDR_ACL_3MPS_SUPPORTED(p_features)) { 296 if (!HCI_3_SLOT_EDR_ACL_SUPPORTED(p_features)) 297 btm_cb.btm_acl_pkt_types_supported |= 298 (BTM_ACL_PKT_TYPES_MASK_NO_2_DH3 + 299 BTM_ACL_PKT_TYPES_MASK_NO_3_DH3); 300 301 if (!HCI_5_SLOT_EDR_ACL_SUPPORTED(p_features)) 302 btm_cb.btm_acl_pkt_types_supported |= 303 (BTM_ACL_PKT_TYPES_MASK_NO_2_DH5 + 304 BTM_ACL_PKT_TYPES_MASK_NO_3_DH5); 305 } 306 307 BTM_TRACE_DEBUG("Local supported ACL packet types: 0x%04x", 308 btm_cb.btm_acl_pkt_types_supported); 309 310 /* Create (e)SCO supported packet types mask */ 311 btm_cb.btm_sco_pkt_types_supported = 0; 312 #if (BTM_SCO_INCLUDED == TRUE) 313 btm_cb.sco_cb.esco_supported = false; 314 #endif 315 if (HCI_SCO_LINK_SUPPORTED(p_features)) { 316 btm_cb.btm_sco_pkt_types_supported = ESCO_PKT_TYPES_MASK_HV1; 317 318 if (HCI_HV2_PACKETS_SUPPORTED(p_features)) 319 btm_cb.btm_sco_pkt_types_supported |= ESCO_PKT_TYPES_MASK_HV2; 320 321 if (HCI_HV3_PACKETS_SUPPORTED(p_features)) 322 btm_cb.btm_sco_pkt_types_supported |= ESCO_PKT_TYPES_MASK_HV3; 323 } 324 325 if (HCI_ESCO_EV3_SUPPORTED(p_features)) 326 btm_cb.btm_sco_pkt_types_supported |= ESCO_PKT_TYPES_MASK_EV3; 327 328 if (HCI_ESCO_EV4_SUPPORTED(p_features)) 329 btm_cb.btm_sco_pkt_types_supported |= ESCO_PKT_TYPES_MASK_EV4; 330 331 if (HCI_ESCO_EV5_SUPPORTED(p_features)) 332 btm_cb.btm_sco_pkt_types_supported |= ESCO_PKT_TYPES_MASK_EV5; 333 if (btm_cb.btm_sco_pkt_types_supported & BTM_ESCO_LINK_ONLY_MASK) { 334 btm_cb.sco_cb.esco_supported = true; 335 336 /* Add in EDR related eSCO types */ 337 if (HCI_EDR_ESCO_2MPS_SUPPORTED(p_features)) { 338 if (!HCI_3_SLOT_EDR_ESCO_SUPPORTED(p_features)) 339 btm_cb.btm_sco_pkt_types_supported |= ESCO_PKT_TYPES_MASK_NO_2_EV5; 340 } else { 341 btm_cb.btm_sco_pkt_types_supported |= 342 (ESCO_PKT_TYPES_MASK_NO_2_EV3 + ESCO_PKT_TYPES_MASK_NO_2_EV5); 343 } 344 345 if (HCI_EDR_ESCO_3MPS_SUPPORTED(p_features)) { 346 if (!HCI_3_SLOT_EDR_ESCO_SUPPORTED(p_features)) 347 btm_cb.btm_sco_pkt_types_supported |= ESCO_PKT_TYPES_MASK_NO_3_EV5; 348 } else { 349 btm_cb.btm_sco_pkt_types_supported |= 350 (ESCO_PKT_TYPES_MASK_NO_3_EV3 + ESCO_PKT_TYPES_MASK_NO_3_EV5); 351 } 352 } 353 354 BTM_TRACE_DEBUG("Local supported SCO packet types: 0x%04x", 355 btm_cb.btm_sco_pkt_types_supported); 356 357 /* Create Default Policy Settings */ 358 if (HCI_SWITCH_SUPPORTED(p_features)) 359 btm_cb.btm_def_link_policy |= HCI_ENABLE_MASTER_SLAVE_SWITCH; 360 else 361 btm_cb.btm_def_link_policy &= ~HCI_ENABLE_MASTER_SLAVE_SWITCH; 362 363 if (HCI_HOLD_MODE_SUPPORTED(p_features)) 364 btm_cb.btm_def_link_policy |= HCI_ENABLE_HOLD_MODE; 365 else 366 btm_cb.btm_def_link_policy &= ~HCI_ENABLE_HOLD_MODE; 367 368 if (HCI_SNIFF_MODE_SUPPORTED(p_features)) 369 btm_cb.btm_def_link_policy |= HCI_ENABLE_SNIFF_MODE; 370 else 371 btm_cb.btm_def_link_policy &= ~HCI_ENABLE_SNIFF_MODE; 372 373 if (HCI_PARK_MODE_SUPPORTED(p_features)) 374 btm_cb.btm_def_link_policy |= HCI_ENABLE_PARK_MODE; 375 else 376 btm_cb.btm_def_link_policy &= ~HCI_ENABLE_PARK_MODE; 377 378 btm_sec_dev_reset(); 379 380 if (HCI_LMP_INQ_RSSI_SUPPORTED(p_features)) { 381 if (HCI_EXT_INQ_RSP_SUPPORTED(p_features)) 382 BTM_SetInquiryMode(BTM_INQ_RESULT_EXTENDED); 383 else 384 BTM_SetInquiryMode(BTM_INQ_RESULT_WITH_RSSI); 385 } 386 387 #if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE) 388 if (HCI_NON_FLUSHABLE_PB_SUPPORTED(p_features)) 389 l2cu_set_non_flushable_pbf(true); 390 else 391 l2cu_set_non_flushable_pbf(false); 392 #endif 393 BTM_SetPageScanType(BTM_DEFAULT_SCAN_TYPE); 394 BTM_SetInquiryScanType(BTM_DEFAULT_SCAN_TYPE); 395 396 break; 397 398 default: 399 BTM_TRACE_WARNING("%s: feature page %d ignored", __func__, page_number); 400 break; 401 } 402 } 403 404 /******************************************************************************* 405 * 406 * Function BTM_SetLocalDeviceName 407 * 408 * Description This function is called to set the local device name. 409 * 410 * Returns status of the operation 411 * 412 ******************************************************************************/ 413 tBTM_STATUS BTM_SetLocalDeviceName(char* p_name) { 414 uint8_t* p; 415 416 if (!p_name || !p_name[0] || (strlen((char*)p_name) > BD_NAME_LEN)) 417 return (BTM_ILLEGAL_VALUE); 418 419 if (!controller_get_interface()->get_is_ready()) return (BTM_DEV_RESET); 420 /* Save the device name if local storage is enabled */ 421 p = (uint8_t*)btm_cb.cfg.bd_name; 422 if (p != (uint8_t*)p_name) 423 strlcpy(btm_cb.cfg.bd_name, p_name, BTM_MAX_LOC_BD_NAME_LEN); 424 425 btsnd_hcic_change_name(p); 426 return (BTM_CMD_STARTED); 427 } 428 429 /******************************************************************************* 430 * 431 * Function BTM_ReadLocalDeviceName 432 * 433 * Description This function is called to read the local device name. 434 * 435 * Returns status of the operation 436 * If success, BTM_SUCCESS is returned and p_name points stored 437 * local device name 438 * If BTM doesn't store local device name, BTM_NO_RESOURCES is 439 * is returned and p_name is set to NULL 440 * 441 ******************************************************************************/ 442 tBTM_STATUS BTM_ReadLocalDeviceName(char** p_name) { 443 *p_name = btm_cb.cfg.bd_name; 444 return (BTM_SUCCESS); 445 } 446 447 /******************************************************************************* 448 * 449 * Function BTM_ReadLocalDeviceNameFromController 450 * 451 * Description Get local device name from controller. Do not use cached 452 * name (used to get chip-id prior to btm reset complete). 453 * 454 * Returns BTM_CMD_STARTED if successful, otherwise an error 455 * 456 ******************************************************************************/ 457 tBTM_STATUS BTM_ReadLocalDeviceNameFromController( 458 tBTM_CMPL_CB* p_rln_cmpl_cback) { 459 /* Check if rln already in progress */ 460 if (btm_cb.devcb.p_rln_cmpl_cb) return (BTM_NO_RESOURCES); 461 462 /* Save callback */ 463 btm_cb.devcb.p_rln_cmpl_cb = p_rln_cmpl_cback; 464 465 btsnd_hcic_read_name(); 466 alarm_set_on_mloop(btm_cb.devcb.read_local_name_timer, 467 BTM_DEV_NAME_REPLY_TIMEOUT_MS, btm_read_local_name_timeout, 468 NULL); 469 470 return BTM_CMD_STARTED; 471 } 472 473 /******************************************************************************* 474 * 475 * Function btm_read_local_name_complete 476 * 477 * Description This function is called when local name read complete. 478 * message is received from the HCI. 479 * 480 * Returns void 481 * 482 ******************************************************************************/ 483 void btm_read_local_name_complete(uint8_t* p, UNUSED_ATTR uint16_t evt_len) { 484 tBTM_CMPL_CB* p_cb = btm_cb.devcb.p_rln_cmpl_cb; 485 uint8_t status; 486 487 alarm_cancel(btm_cb.devcb.read_local_name_timer); 488 489 /* If there was a callback address for read local name, call it */ 490 btm_cb.devcb.p_rln_cmpl_cb = NULL; 491 492 if (p_cb) { 493 STREAM_TO_UINT8(status, p); 494 495 if (status == HCI_SUCCESS) 496 (*p_cb)(p); 497 else 498 (*p_cb)(NULL); 499 } 500 } 501 502 /******************************************************************************* 503 * 504 * Function BTM_SetDeviceClass 505 * 506 * Description This function is called to set the local device class 507 * 508 * Returns status of the operation 509 * 510 ******************************************************************************/ 511 tBTM_STATUS BTM_SetDeviceClass(DEV_CLASS dev_class) { 512 if (!memcmp(btm_cb.devcb.dev_class, dev_class, DEV_CLASS_LEN)) 513 return (BTM_SUCCESS); 514 515 memcpy(btm_cb.devcb.dev_class, dev_class, DEV_CLASS_LEN); 516 517 if (!controller_get_interface()->get_is_ready()) return (BTM_DEV_RESET); 518 519 btsnd_hcic_write_dev_class(dev_class); 520 521 return (BTM_SUCCESS); 522 } 523 524 /******************************************************************************* 525 * 526 * Function BTM_ReadDeviceClass 527 * 528 * Description This function is called to read the local device class 529 * 530 * Returns pointer to the device class 531 * 532 ******************************************************************************/ 533 uint8_t* BTM_ReadDeviceClass(void) { 534 return ((uint8_t*)btm_cb.devcb.dev_class); 535 } 536 537 /******************************************************************************* 538 * 539 * Function BTM_ReadLocalFeatures 540 * 541 * Description This function is called to read the local features 542 * 543 * Returns pointer to the local features string 544 * 545 ******************************************************************************/ 546 // TODO(zachoverflow): get rid of this function 547 uint8_t* BTM_ReadLocalFeatures(void) { 548 // Discarding const modifier for now, until this function dies 549 return (uint8_t*)controller_get_interface() 550 ->get_features_classic(0) 551 ->as_array; 552 } 553 554 /******************************************************************************* 555 * 556 * Function BTM_RegisterForDeviceStatusNotif 557 * 558 * Description This function is called to register for device status 559 * change notifications. 560 * 561 * If one registration is already there calling function should 562 * save the pointer to the function that is return and 563 * call it when processing of the event is complete 564 * 565 * Returns status of the operation 566 * 567 ******************************************************************************/ 568 tBTM_DEV_STATUS_CB* BTM_RegisterForDeviceStatusNotif(tBTM_DEV_STATUS_CB* p_cb) { 569 tBTM_DEV_STATUS_CB* p_prev = btm_cb.devcb.p_dev_status_cb; 570 571 btm_cb.devcb.p_dev_status_cb = p_cb; 572 return (p_prev); 573 } 574 575 /******************************************************************************* 576 * 577 * Function BTM_VendorSpecificCommand 578 * 579 * Description Send a vendor specific HCI command to the controller. 580 * 581 * Notes 582 * Opcode will be OR'd with HCI_GRP_VENDOR_SPECIFIC. 583 * 584 ******************************************************************************/ 585 void BTM_VendorSpecificCommand(uint16_t opcode, uint8_t param_len, 586 uint8_t* p_param_buf, tBTM_VSC_CMPL_CB* p_cb) { 587 /* Allocate a buffer to hold HCI command plus the callback function */ 588 void* p_buf = osi_malloc(sizeof(BT_HDR) + sizeof(tBTM_CMPL_CB*) + param_len + 589 HCIC_PREAMBLE_SIZE); 590 591 BTM_TRACE_EVENT("BTM: %s: Opcode: 0x%04X, ParamLen: %i.", __func__, opcode, 592 param_len); 593 594 /* Send the HCI command (opcode will be OR'd with HCI_GRP_VENDOR_SPECIFIC) */ 595 btsnd_hcic_vendor_spec_cmd(p_buf, opcode, param_len, p_param_buf, 596 (void*)p_cb); 597 } 598 599 /******************************************************************************* 600 * 601 * Function btm_vsc_complete 602 * 603 * Description This function is called when local HCI Vendor Specific 604 * Command complete message is received from the HCI. 605 * 606 * Returns void 607 * 608 ******************************************************************************/ 609 void btm_vsc_complete(uint8_t* p, uint16_t opcode, uint16_t evt_len, 610 tBTM_CMPL_CB* p_vsc_cplt_cback) { 611 tBTM_VSC_CMPL vcs_cplt_params; 612 613 /* If there was a callback address for vcs complete, call it */ 614 if (p_vsc_cplt_cback) { 615 /* Pass paramters to the callback function */ 616 vcs_cplt_params.opcode = opcode; /* Number of bytes in return info */ 617 vcs_cplt_params.param_len = evt_len; /* Number of bytes in return info */ 618 vcs_cplt_params.p_param_buf = p; 619 (*p_vsc_cplt_cback)( 620 &vcs_cplt_params); /* Call the VSC complete callback function */ 621 } 622 } 623 624 /******************************************************************************* 625 * 626 * Function BTM_RegisterForVSEvents 627 * 628 * Description This function is called to register/deregister for vendor 629 * specific HCI events. 630 * 631 * If is_register=true, then the function will be registered; 632 * otherwise, the the function will be deregistered. 633 * 634 * Returns BTM_SUCCESS if successful, 635 * BTM_BUSY if maximum number of callbacks have already been 636 * registered. 637 * 638 ******************************************************************************/ 639 tBTM_STATUS BTM_RegisterForVSEvents(tBTM_VS_EVT_CB* p_cb, bool is_register) { 640 tBTM_STATUS retval = BTM_SUCCESS; 641 uint8_t i, free_idx = BTM_MAX_VSE_CALLBACKS; 642 643 /* See if callback is already registered */ 644 for (i = 0; i < BTM_MAX_VSE_CALLBACKS; i++) { 645 if (btm_cb.devcb.p_vend_spec_cb[i] == NULL) { 646 /* Found a free slot. Store index */ 647 free_idx = i; 648 } else if (btm_cb.devcb.p_vend_spec_cb[i] == p_cb) { 649 /* Found callback in lookup table. If deregistering, clear the entry. */ 650 if (is_register == false) { 651 btm_cb.devcb.p_vend_spec_cb[i] = NULL; 652 BTM_TRACE_EVENT("BTM Deregister For VSEvents is successfully"); 653 } 654 return (BTM_SUCCESS); 655 } 656 } 657 658 /* Didn't find callback. Add callback to free slot if registering */ 659 if (is_register) { 660 if (free_idx < BTM_MAX_VSE_CALLBACKS) { 661 btm_cb.devcb.p_vend_spec_cb[free_idx] = p_cb; 662 BTM_TRACE_EVENT("BTM Register For VSEvents is successfully"); 663 } else { 664 /* No free entries available */ 665 BTM_TRACE_ERROR("BTM_RegisterForVSEvents: too many callbacks registered"); 666 667 retval = BTM_NO_RESOURCES; 668 } 669 } 670 671 return (retval); 672 } 673 674 /******************************************************************************* 675 * 676 * Function btm_vendor_specific_evt 677 * 678 * Description Process event HCI_VENDOR_SPECIFIC_EVT 679 * 680 * Note: Some controllers do not send command complete, so 681 * the callback and busy flag are cleared here also. 682 * 683 * Returns void 684 * 685 ******************************************************************************/ 686 void btm_vendor_specific_evt(uint8_t* p, uint8_t evt_len) { 687 uint8_t i; 688 689 BTM_TRACE_DEBUG("BTM Event: Vendor Specific event from controller"); 690 691 for (i = 0; i < BTM_MAX_VSE_CALLBACKS; i++) { 692 if (btm_cb.devcb.p_vend_spec_cb[i]) 693 (*btm_cb.devcb.p_vend_spec_cb[i])(evt_len, p); 694 } 695 } 696 697 /******************************************************************************* 698 * 699 * Function BTM_WritePageTimeout 700 * 701 * Description Send HCI Write Page Timeout. 702 * 703 ******************************************************************************/ 704 void BTM_WritePageTimeout(uint16_t timeout) { 705 BTM_TRACE_EVENT("BTM: BTM_WritePageTimeout: Timeout: %d.", timeout); 706 707 /* Send the HCI command */ 708 btsnd_hcic_write_page_tout(timeout); 709 } 710 711 /******************************************************************************* 712 * 713 * Function BTM_WriteVoiceSettings 714 * 715 * Description Send HCI Write Voice Settings command. 716 * See hcidefs.h for settings bitmask values. 717 * 718 ******************************************************************************/ 719 void BTM_WriteVoiceSettings(uint16_t settings) { 720 BTM_TRACE_EVENT("BTM: BTM_WriteVoiceSettings: Settings: 0x%04x.", settings); 721 722 /* Send the HCI command */ 723 btsnd_hcic_write_voice_settings((uint16_t)(settings & 0x03ff)); 724 } 725 726 /******************************************************************************* 727 * 728 * Function BTM_EnableTestMode 729 * 730 * Description Send HCI the enable device under test command. 731 * 732 * Note: Controller can only be taken out of this mode by 733 * resetting the controller. 734 * 735 * Returns 736 * BTM_SUCCESS Command sent. 737 * BTM_NO_RESOURCES If out of resources to send the command. 738 * 739 * 740 ******************************************************************************/ 741 tBTM_STATUS BTM_EnableTestMode(void) { 742 uint8_t cond; 743 744 BTM_TRACE_EVENT("BTM: BTM_EnableTestMode"); 745 746 /* set auto accept connection as this is needed during test mode */ 747 /* Allocate a buffer to hold HCI command */ 748 cond = HCI_DO_AUTO_ACCEPT_CONNECT; 749 btsnd_hcic_set_event_filter(HCI_FILTER_CONNECTION_SETUP, 750 HCI_FILTER_COND_NEW_DEVICE, &cond, sizeof(cond)); 751 752 /* put device to connectable mode */ 753 if (BTM_SetConnectability(BTM_CONNECTABLE, BTM_DEFAULT_CONN_WINDOW, 754 BTM_DEFAULT_CONN_INTERVAL) != BTM_SUCCESS) { 755 return BTM_NO_RESOURCES; 756 } 757 758 /* put device to discoverable mode */ 759 if (BTM_SetDiscoverability(BTM_GENERAL_DISCOVERABLE, BTM_DEFAULT_DISC_WINDOW, 760 BTM_DEFAULT_DISC_INTERVAL) != BTM_SUCCESS) { 761 return BTM_NO_RESOURCES; 762 } 763 764 /* mask off all of event from controller */ 765 hci_layer_get_interface()->transmit_command( 766 hci_packet_factory_get_interface()->make_set_event_mask( 767 (const bt_event_mask_t*)("\x00\x00\x00\x00\x00\x00\x00\x00")), 768 NULL, NULL, NULL); 769 770 /* Send the HCI command */ 771 btsnd_hcic_enable_test_mode(); 772 return (BTM_SUCCESS); 773 } 774 775 /******************************************************************************* 776 * 777 * Function BTM_DeleteStoredLinkKey 778 * 779 * Description This function is called to delete link key for the specified 780 * device addresses from the NVRAM storage attached to the 781 * Bluetooth controller. 782 * 783 * Parameters: bd_addr - Addresses of the devices 784 * p_cb - Call back function to be called to return 785 * the results 786 * 787 ******************************************************************************/ 788 tBTM_STATUS BTM_DeleteStoredLinkKey(const RawAddress* bd_addr, 789 tBTM_CMPL_CB* p_cb) { 790 /* Check if the previous command is completed */ 791 if (btm_cb.devcb.p_stored_link_key_cmpl_cb) return (BTM_BUSY); 792 793 bool delete_all_flag = !bd_addr; 794 795 BTM_TRACE_EVENT("BTM: BTM_DeleteStoredLinkKey: delete_all_flag: %s", 796 delete_all_flag ? "true" : "false"); 797 798 btm_cb.devcb.p_stored_link_key_cmpl_cb = p_cb; 799 if (!bd_addr) { 800 /* This is to delete all link keys */ 801 /* We don't care the BD address. Just pass a non zero pointer */ 802 RawAddress local_bd_addr = RawAddress::kEmpty; 803 btsnd_hcic_delete_stored_key(local_bd_addr, delete_all_flag); 804 } else { 805 btsnd_hcic_delete_stored_key(*bd_addr, delete_all_flag); 806 } 807 808 return (BTM_SUCCESS); 809 } 810 811 /******************************************************************************* 812 * 813 * Function btm_delete_stored_link_key_complete 814 * 815 * Description This function is called when the command complete message 816 * is received from the HCI for the delete stored link key 817 * command. 818 * 819 * Returns void 820 * 821 ******************************************************************************/ 822 void btm_delete_stored_link_key_complete(uint8_t* p) { 823 tBTM_CMPL_CB* p_cb = btm_cb.devcb.p_stored_link_key_cmpl_cb; 824 tBTM_DELETE_STORED_LINK_KEY_COMPLETE result; 825 826 /* If there was a callback registered for read stored link key, call it */ 827 btm_cb.devcb.p_stored_link_key_cmpl_cb = NULL; 828 829 if (p_cb) { 830 /* Set the call back event to indicate command complete */ 831 result.event = BTM_CB_EVT_DELETE_STORED_LINK_KEYS; 832 833 /* Extract the result fields from the HCI event */ 834 STREAM_TO_UINT8(result.status, p); 835 STREAM_TO_UINT16(result.num_keys, p); 836 837 /* Call the call back and pass the result */ 838 (*p_cb)(&result); 839 } 840 } 841 842 /******************************************************************************* 843 * 844 * Function btm_report_device_status 845 * 846 * Description This function is called when there is a change in the device 847 * status. This function will report the new device status to 848 * the application 849 * 850 * Returns void 851 * 852 ******************************************************************************/ 853 void btm_report_device_status(tBTM_DEV_STATUS status) { 854 tBTM_DEV_STATUS_CB* p_cb = btm_cb.devcb.p_dev_status_cb; 855 856 /* Call the call back to pass the device status to application */ 857 if (p_cb) (*p_cb)(status); 858 } 859