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