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