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