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