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 *******************************************************************************/
btm_dev_init(void)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 *******************************************************************************/
btm_db_reset(void)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 
reset_complete(void * result)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
BTM_DeviceReset(UNUSED_ATTR tBTM_CMPL_CB * p_cb)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 *******************************************************************************/
BTM_IsDeviceUp(void)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 *******************************************************************************/
btm_dev_timeout(TIMER_LIST_ENT * p_tle)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 *******************************************************************************/
btm_decode_ext_features_page(UINT8 page_number,const UINT8 * p_features)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 *******************************************************************************/
BTM_SetLocalDeviceName(char * p_name)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 *******************************************************************************/
BTM_ReadLocalDeviceName(char ** p_name)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 *******************************************************************************/
BTM_ReadLocalDeviceNameFromController(tBTM_CMPL_CB * p_rln_cmpl_cback)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 *******************************************************************************/
btm_read_local_name_complete(UINT8 * p,UINT16 evt_len)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 *******************************************************************************/
BTM_SetDeviceClass(DEV_CLASS dev_class)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 *******************************************************************************/
BTM_ReadDeviceClass(void)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
BTM_ReadLocalFeatures(void)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 *******************************************************************************/
BTM_RegisterForDeviceStatusNotif(tBTM_DEV_STATUS_CB * p_cb)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 *******************************************************************************/
BTM_VendorSpecificCommand(UINT16 opcode,UINT8 param_len,UINT8 * p_param_buf,tBTM_VSC_CMPL_CB * p_cb)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 *******************************************************************************/
btm_vsc_complete(UINT8 * p,UINT16 opcode,UINT16 evt_len,tBTM_CMPL_CB * p_vsc_cplt_cback)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 *******************************************************************************/
BTM_RegisterForVSEvents(tBTM_VS_EVT_CB * p_cb,BOOLEAN is_register)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 *******************************************************************************/
btm_vendor_specific_evt(UINT8 * p,UINT8 evt_len)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 *******************************************************************************/
BTM_WritePageTimeout(UINT16 timeout)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 *******************************************************************************/
BTM_WriteVoiceSettings(UINT16 settings)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 *******************************************************************************/
BTM_EnableTestMode(void)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 *******************************************************************************/
BTM_DeleteStoredLinkKey(BD_ADDR bd_addr,tBTM_CMPL_CB * p_cb)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 *******************************************************************************/
btm_delete_stored_link_key_complete(UINT8 * p)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 *******************************************************************************/
btm_report_device_status(tBTM_DEV_STATUS status)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