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 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 66static 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*******************************************************************************/ 77void 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*******************************************************************************/ 115static 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 141static 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 202void 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*******************************************************************************/ 225BOOLEAN 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*******************************************************************************/ 239void 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*******************************************************************************/ 263static 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*******************************************************************************/ 441tBTM_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*******************************************************************************/ 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 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*******************************************************************************/ 531void 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*******************************************************************************/ 562tBTM_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*******************************************************************************/ 588UINT8 *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 604UINT8 *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*******************************************************************************/ 624tBTM_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*******************************************************************************/ 647tBTM_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*******************************************************************************/ 684void 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*******************************************************************************/ 715tBTM_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*******************************************************************************/ 772void 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*******************************************************************************/ 798tBTM_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*******************************************************************************/ 822tBTM_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*******************************************************************************/ 848tBTM_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*******************************************************************************/ 905tBTM_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*******************************************************************************/ 946void 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*******************************************************************************/ 979void 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