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