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