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