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