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