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