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