1 /******************************************************************************
2 *
3 * Copyright 1999-2014 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 inquiries. These include
22 * setting discoverable mode, controlling the mode of the Baseband, and
23 * maintaining a small database of inquiry responses, with API for people
24 * to browse it.
25 *
26 ******************************************************************************/
27
28 #define LOG_TAG "bluetooth"
29
30 #include <base/logging.h>
31 #include <stddef.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35
36 #include <mutex>
37
38 #include "advertise_data_parser.h"
39 #include "common/time_util.h"
40 #include "device/include/controller.h"
41 #include "main/shim/btm_api.h"
42 #include "main/shim/shim.h"
43 #include "osi/include/allocator.h"
44 #include "osi/include/log.h"
45 #include "osi/include/osi.h"
46 #include "osi/include/properties.h"
47 #include "stack/btm/btm_ble_int.h"
48 #include "stack/btm/btm_dev.h"
49 #include "stack/btm/btm_int_types.h"
50 #include "stack/include/acl_api.h"
51 #include "stack/include/bt_hdr.h"
52 #include "stack/include/btm_api.h"
53 #include "stack/include/btm_ble_api.h"
54 #include "stack/include/inq_hci_link_interface.h"
55 #include "types/bluetooth/uuid.h"
56 #include "types/raw_address.h"
57
58 namespace {
59 constexpr char kBtmLogTag[] = "SCAN";
60
btm_log_history_scan_mode(uint8_t scan_mode)61 void btm_log_history_scan_mode(uint8_t scan_mode) {
62 static uint8_t scan_mode_cached_ = 0xff;
63 if (scan_mode_cached_ == scan_mode) return;
64
65 BTM_LogHistory(
66 kBtmLogTag, RawAddress::kEmpty, "Classic updated",
67 base::StringPrintf("inquiry_scan_enable:%c page_scan_enable:%c",
68 (scan_mode & HCI_INQUIRY_SCAN_ENABLED) ? 'T' : 'F',
69 (scan_mode & HCI_PAGE_SCAN_ENABLED) ? 'T' : 'F'));
70 scan_mode_cached_ = scan_mode;
71 }
72
73 // Inquiry database lock
74 std::mutex inq_db_lock_;
75 // Inquiry database
76 tINQ_DB_ENT inq_db_[BTM_INQ_DB_SIZE];
77
78 // Inquiry bluetooth device database lock
79 std::mutex bd_db_lock_;
80 tINQ_BDADDR* p_bd_db_; /* Pointer to memory that holds bdaddrs */
81 uint16_t num_bd_entries_; /* Number of entries in database */
82 uint16_t max_bd_entries_; /* Maximum number of entries that can be stored */
83
84 } // namespace
85
86 extern tBTM_CB btm_cb;
87
88 void btm_inq_remote_name_timer_timeout(void* data);
89 tBTM_STATUS btm_ble_read_remote_name(const RawAddress& remote_bda,
90 tBTM_NAME_CMPL_CB* p_cb);
91 bool btm_ble_cancel_remote_name(const RawAddress& remote_bda);
92 tBTM_STATUS btm_ble_set_discoverability(uint16_t combined_mode);
93 tBTM_STATUS btm_ble_set_connectability(uint16_t combined_mode);
94
95 tBTM_STATUS btm_ble_start_inquiry(uint8_t duration);
96 void btm_ble_stop_inquiry(void);
97
98 using bluetooth::Uuid;
99
100 /* 3 second timeout waiting for responses */
101 #define BTM_INQ_REPLY_TIMEOUT_MS (3 * 1000)
102
103 /* TRUE to enable DEBUG traces for btm_inq */
104 #ifndef BTM_INQ_DEBUG
105 #define BTM_INQ_DEBUG FALSE
106 #endif
107
108 #ifndef PROPERTY_PAGE_SCAN_TYPE
109 #define PROPERTY_PAGE_SCAN_TYPE "bluetooth.core.classic.page_scan_type"
110 #endif
111
112 #ifndef PROPERTY_PAGE_SCAN_INTERVAL
113 #define PROPERTY_PAGE_SCAN_INTERVAL "bluetooth.core.classic.page_scan_interval"
114 #endif
115
116 #ifndef PROPERTY_PAGE_SCAN_WINDOW
117 #define PROPERTY_PAGE_SCAN_WINDOW "bluetooth.core.classic.page_scan_window"
118 #endif
119
120 #ifndef PROPERTY_INQ_SCAN_TYPE
121 #define PROPERTY_INQ_SCAN_TYPE "bluetooth.core.classic.inq_scan_type"
122 #endif
123
124 #ifndef PROPERTY_INQ_SCAN_INTERVAL
125 #define PROPERTY_INQ_SCAN_INTERVAL "bluetooth.core.classic.inq_scan_interval"
126 #endif
127
128 #ifndef PROPERTY_INQ_SCAN_WINDOW
129 #define PROPERTY_INQ_SCAN_WINDOW "bluetooth.core.classic.inq_scan_window"
130 #endif
131
132 #define BTIF_DM_DEFAULT_INQ_MAX_DURATION 10
133
134 /******************************************************************************/
135 /* L O C A L D A T A D E F I N I T I O N S */
136 /******************************************************************************/
137 static const LAP general_inq_lap = {0x9e, 0x8b, 0x33};
138 static const LAP limited_inq_lap = {0x9e, 0x8b, 0x00};
139
140 const uint16_t BTM_EIR_UUID_LKUP_TBL[BTM_EIR_MAX_SERVICES] = {
141 UUID_SERVCLASS_SERVICE_DISCOVERY_SERVER,
142 /* UUID_SERVCLASS_BROWSE_GROUP_DESCRIPTOR, */
143 /* UUID_SERVCLASS_PUBLIC_BROWSE_GROUP, */
144 UUID_SERVCLASS_SERIAL_PORT, UUID_SERVCLASS_LAN_ACCESS_USING_PPP,
145 UUID_SERVCLASS_DIALUP_NETWORKING, UUID_SERVCLASS_IRMC_SYNC,
146 UUID_SERVCLASS_OBEX_OBJECT_PUSH, UUID_SERVCLASS_OBEX_FILE_TRANSFER,
147 UUID_SERVCLASS_IRMC_SYNC_COMMAND, UUID_SERVCLASS_HEADSET,
148 UUID_SERVCLASS_CORDLESS_TELEPHONY, UUID_SERVCLASS_AUDIO_SOURCE,
149 UUID_SERVCLASS_AUDIO_SINK, UUID_SERVCLASS_AV_REM_CTRL_TARGET,
150 /* UUID_SERVCLASS_ADV_AUDIO_DISTRIBUTION, */
151 UUID_SERVCLASS_AV_REMOTE_CONTROL,
152 /* UUID_SERVCLASS_VIDEO_CONFERENCING, */
153 UUID_SERVCLASS_INTERCOM, UUID_SERVCLASS_FAX,
154 UUID_SERVCLASS_HEADSET_AUDIO_GATEWAY,
155 /* UUID_SERVCLASS_WAP, */
156 /* UUID_SERVCLASS_WAP_CLIENT, */
157 UUID_SERVCLASS_PANU, UUID_SERVCLASS_NAP, UUID_SERVCLASS_GN,
158 UUID_SERVCLASS_DIRECT_PRINTING,
159 /* UUID_SERVCLASS_REFERENCE_PRINTING, */
160 UUID_SERVCLASS_IMAGING, UUID_SERVCLASS_IMAGING_RESPONDER,
161 UUID_SERVCLASS_IMAGING_AUTO_ARCHIVE, UUID_SERVCLASS_IMAGING_REF_OBJECTS,
162 UUID_SERVCLASS_HF_HANDSFREE, UUID_SERVCLASS_AG_HANDSFREE,
163 UUID_SERVCLASS_DIR_PRT_REF_OBJ_SERVICE,
164 /* UUID_SERVCLASS_REFLECTED_UI, */
165 UUID_SERVCLASS_BASIC_PRINTING, UUID_SERVCLASS_PRINTING_STATUS,
166 UUID_SERVCLASS_HUMAN_INTERFACE, UUID_SERVCLASS_CABLE_REPLACEMENT,
167 UUID_SERVCLASS_HCRP_PRINT, UUID_SERVCLASS_HCRP_SCAN,
168 /* UUID_SERVCLASS_COMMON_ISDN_ACCESS, */
169 /* UUID_SERVCLASS_VIDEO_CONFERENCING_GW, */
170 /* UUID_SERVCLASS_UDI_MT, */
171 /* UUID_SERVCLASS_UDI_TA, */
172 /* UUID_SERVCLASS_VCP, */
173 UUID_SERVCLASS_SAP, UUID_SERVCLASS_PBAP_PCE, UUID_SERVCLASS_PBAP_PSE,
174 UUID_SERVCLASS_PHONE_ACCESS, UUID_SERVCLASS_HEADSET_HS,
175 UUID_SERVCLASS_PNP_INFORMATION,
176 /* UUID_SERVCLASS_GENERIC_NETWORKING, */
177 /* UUID_SERVCLASS_GENERIC_FILETRANSFER, */
178 /* UUID_SERVCLASS_GENERIC_AUDIO, */
179 /* UUID_SERVCLASS_GENERIC_TELEPHONY, */
180 /* UUID_SERVCLASS_UPNP_SERVICE, */
181 /* UUID_SERVCLASS_UPNP_IP_SERVICE, */
182 /* UUID_SERVCLASS_ESDP_UPNP_IP_PAN, */
183 /* UUID_SERVCLASS_ESDP_UPNP_IP_LAP, */
184 /* UUID_SERVCLASS_ESDP_UPNP_IP_L2CAP, */
185 UUID_SERVCLASS_VIDEO_SOURCE, UUID_SERVCLASS_VIDEO_SINK,
186 /* UUID_SERVCLASS_VIDEO_DISTRIBUTION */
187 UUID_SERVCLASS_MESSAGE_ACCESS, UUID_SERVCLASS_MESSAGE_NOTIFICATION,
188 UUID_SERVCLASS_HDP_SOURCE, UUID_SERVCLASS_HDP_SINK};
189
190 /******************************************************************************/
191 /* L O C A L F U N C T I O N P R O T O T Y P E S */
192 /******************************************************************************/
193 static void btm_clr_inq_db(const RawAddress* p_bda);
194 static void btm_init_inq_result_flt(void);
195 void btm_clr_inq_result_flt(void);
196 static void btm_inq_rmt_name_failed_cancelled(void);
197 static tBTM_STATUS btm_initiate_rem_name(const RawAddress& remote_bda,
198 uint8_t origin, uint64_t timeout_ms,
199 tBTM_NAME_CMPL_CB* p_cb);
200
201 static uint8_t btm_convert_uuid_to_eir_service(uint16_t uuid16);
202 void btm_set_eir_uuid(const uint8_t* p_eir, tBTM_INQ_RESULTS* p_results);
203 static const uint8_t* btm_eir_get_uuid_list(const uint8_t* p_eir,
204 size_t eir_len, uint8_t uuid_size,
205 uint8_t* p_num_uuid,
206 uint8_t* p_uuid_list_type);
207
SendRemoteNameRequest(const RawAddress & raw_address)208 void SendRemoteNameRequest(const RawAddress& raw_address) {
209 btsnd_hcic_rmt_name_req(raw_address, HCI_PAGE_SCAN_REP_MODE_R1,
210 HCI_MANDATARY_PAGE_SCAN_MODE, 0);
211 }
212 /*******************************************************************************
213 *
214 * Function BTM_SetDiscoverability
215 *
216 * Description This function is called to set the device into or out of
217 * discoverable mode. Discoverable mode means inquiry
218 * scans are enabled. If a value of '0' is entered for window
219 * or interval, the default values are used.
220 *
221 * Returns BTM_SUCCESS if successful
222 * BTM_BUSY if a setting of the filter is already in progress
223 * BTM_NO_RESOURCES if couldn't get a memory pool buffer
224 * BTM_ILLEGAL_VALUE if a bad parameter was detected
225 * BTM_WRONG_MODE if the device is not up.
226 *
227 ******************************************************************************/
BTM_SetDiscoverability(uint16_t inq_mode)228 tBTM_STATUS BTM_SetDiscoverability(uint16_t inq_mode) {
229 uint8_t scan_mode = 0;
230 uint16_t service_class;
231 uint8_t* p_cod;
232 uint8_t major, minor;
233 DEV_CLASS cod;
234 LAP temp_lap[2];
235 bool is_limited;
236 bool cod_limited;
237 uint16_t window = BTM_DEFAULT_DISC_WINDOW;
238 uint16_t interval = BTM_DEFAULT_DISC_INTERVAL;
239
240 BTM_TRACE_API("BTM_SetDiscoverability");
241 if (controller_get_interface()->supports_ble()) {
242 if (btm_ble_set_discoverability((uint16_t)(inq_mode)) == BTM_SUCCESS) {
243 btm_cb.btm_inq_vars.discoverable_mode &= (~BTM_BLE_DISCOVERABLE_MASK);
244 btm_cb.btm_inq_vars.discoverable_mode |=
245 (inq_mode & BTM_BLE_DISCOVERABLE_MASK);
246 }
247 }
248 inq_mode &= ~BTM_BLE_DISCOVERABLE_MASK;
249
250 /*** Check mode parameter ***/
251 if (inq_mode > BTM_MAX_DISCOVERABLE) return (BTM_ILLEGAL_VALUE);
252
253 /* Make sure the controller is active */
254 if (!controller_get_interface()->get_is_ready()) return (BTM_DEV_RESET);
255
256 /* If the window and/or interval is '0', set to default values */
257 BTM_TRACE_API("BTM_SetDiscoverability: mode %d [NonDisc-0, Lim-1, Gen-2]",
258 inq_mode);
259
260 /* Set the IAC if needed */
261 if (inq_mode != BTM_NON_DISCOVERABLE) {
262 if (inq_mode & BTM_LIMITED_DISCOVERABLE) {
263 /* Use the GIAC and LIAC codes for limited discoverable mode */
264 memcpy(temp_lap[0], limited_inq_lap, LAP_LEN);
265 memcpy(temp_lap[1], general_inq_lap, LAP_LEN);
266
267 btsnd_hcic_write_cur_iac_lap(2, (LAP * const)temp_lap);
268 } else {
269 btsnd_hcic_write_cur_iac_lap(1, (LAP * const) & general_inq_lap);
270 }
271
272 scan_mode |= HCI_INQUIRY_SCAN_ENABLED;
273 }
274
275 window =
276 osi_property_get_int32(PROPERTY_INQ_SCAN_WINDOW, BTM_DEFAULT_DISC_WINDOW);
277 interval = osi_property_get_int32(PROPERTY_INQ_SCAN_INTERVAL,
278 BTM_DEFAULT_DISC_INTERVAL);
279
280 /* Send down the inquiry scan window and period if changed */
281 if ((window != btm_cb.btm_inq_vars.inq_scan_window) ||
282 (interval != btm_cb.btm_inq_vars.inq_scan_period)) {
283 btsnd_hcic_write_inqscan_cfg(interval, window);
284 btm_cb.btm_inq_vars.inq_scan_window = window;
285 btm_cb.btm_inq_vars.inq_scan_period = interval;
286 }
287
288 if (btm_cb.btm_inq_vars.connectable_mode & BTM_CONNECTABLE_MASK)
289 scan_mode |= HCI_PAGE_SCAN_ENABLED;
290
291 btm_log_history_scan_mode(scan_mode);
292 btsnd_hcic_write_scan_enable(scan_mode);
293 btm_cb.btm_inq_vars.discoverable_mode &= (~BTM_DISCOVERABLE_MASK);
294 btm_cb.btm_inq_vars.discoverable_mode |= inq_mode;
295
296 /* Change the service class bit if mode has changed */
297 p_cod = BTM_ReadDeviceClass();
298 BTM_COD_SERVICE_CLASS(service_class, p_cod);
299 is_limited = (inq_mode & BTM_LIMITED_DISCOVERABLE) ? true : false;
300 cod_limited = (service_class & BTM_COD_SERVICE_LMTD_DISCOVER) ? true : false;
301 if (is_limited ^ cod_limited) {
302 BTM_COD_MINOR_CLASS(minor, p_cod);
303 BTM_COD_MAJOR_CLASS(major, p_cod);
304 if (is_limited)
305 service_class |= BTM_COD_SERVICE_LMTD_DISCOVER;
306 else
307 service_class &= ~BTM_COD_SERVICE_LMTD_DISCOVER;
308
309 FIELDS_TO_COD(cod, minor, major, service_class);
310 (void)BTM_SetDeviceClass(cod);
311 }
312
313 return (BTM_SUCCESS);
314 }
315
BTM_EnableInterlacedInquiryScan()316 void BTM_EnableInterlacedInquiryScan() {
317 BTM_TRACE_API("BTM_EnableInterlacedInquiryScan");
318
319 uint16_t inq_scan_type =
320 osi_property_get_int32(PROPERTY_INQ_SCAN_TYPE, BTM_SCAN_TYPE_INTERLACED);
321
322 if (!controller_get_interface()->supports_interlaced_inquiry_scan() ||
323 inq_scan_type != BTM_SCAN_TYPE_INTERLACED ||
324 btm_cb.btm_inq_vars.inq_scan_type == BTM_SCAN_TYPE_INTERLACED) {
325 return;
326 }
327
328 btsnd_hcic_write_inqscan_type(BTM_SCAN_TYPE_INTERLACED);
329 btm_cb.btm_inq_vars.inq_scan_type = BTM_SCAN_TYPE_INTERLACED;
330 }
331
BTM_EnableInterlacedPageScan()332 void BTM_EnableInterlacedPageScan() {
333 BTM_TRACE_API("BTM_EnableInterlacedPageScan");
334
335 uint16_t page_scan_type =
336 osi_property_get_int32(PROPERTY_PAGE_SCAN_TYPE, BTM_SCAN_TYPE_INTERLACED);
337
338 if (!controller_get_interface()->supports_interlaced_inquiry_scan() ||
339 page_scan_type != BTM_SCAN_TYPE_INTERLACED ||
340 btm_cb.btm_inq_vars.page_scan_type == BTM_SCAN_TYPE_INTERLACED) {
341 return;
342 }
343
344 btsnd_hcic_write_pagescan_type(BTM_SCAN_TYPE_INTERLACED);
345 btm_cb.btm_inq_vars.page_scan_type = BTM_SCAN_TYPE_INTERLACED;
346 }
347
348 /*******************************************************************************
349 *
350 * Function BTM_SetInquiryMode
351 *
352 * Description This function is called to set standard or with RSSI
353 * mode of the inquiry for local device.
354 *
355 * Output Params: mode - standard, with RSSI, extended
356 *
357 * Returns BTM_SUCCESS if successful
358 * BTM_NO_RESOURCES if couldn't get a memory pool buffer
359 * BTM_ILLEGAL_VALUE if a bad parameter was detected
360 * BTM_WRONG_MODE if the device is not up.
361 *
362 ******************************************************************************/
BTM_SetInquiryMode(uint8_t mode)363 tBTM_STATUS BTM_SetInquiryMode(uint8_t mode) {
364 const controller_t* controller = controller_get_interface();
365 BTM_TRACE_API("BTM_SetInquiryMode");
366 if (mode == BTM_INQ_RESULT_STANDARD) {
367 /* mandatory mode */
368 } else if (mode == BTM_INQ_RESULT_WITH_RSSI) {
369 if (!controller->supports_rssi_with_inquiry_results())
370 return (BTM_MODE_UNSUPPORTED);
371 } else if (mode == BTM_INQ_RESULT_EXTENDED) {
372 if (!controller->supports_extended_inquiry_response())
373 return (BTM_MODE_UNSUPPORTED);
374 } else
375 return (BTM_ILLEGAL_VALUE);
376
377 if (!BTM_IsDeviceUp()) return (BTM_WRONG_MODE);
378
379 btsnd_hcic_write_inquiry_mode(mode);
380
381 return (BTM_SUCCESS);
382 }
383
384 /*******************************************************************************
385 *
386 * Function BTM_SetConnectability
387 *
388 * Description This function is called to set the device into or out of
389 * connectable mode. Discoverable mode means page scans are
390 * enabled.
391 *
392 * Returns BTM_SUCCESS if successful
393 * BTM_ILLEGAL_VALUE if a bad parameter is detected
394 * BTM_NO_RESOURCES if could not allocate a message buffer
395 * BTM_WRONG_MODE if the device is not up.
396 *
397 ******************************************************************************/
BTM_SetConnectability(uint16_t page_mode)398 tBTM_STATUS BTM_SetConnectability(uint16_t page_mode) {
399 uint8_t scan_mode = 0;
400 uint16_t window = BTM_DEFAULT_CONN_WINDOW;
401 uint16_t interval = (uint16_t)osi_property_get_int32(
402 BTM_PAGE_SCAN_INTERVAL_PROPERTY, BTM_DEFAULT_CONN_INTERVAL);
403
404 tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
405
406 BTM_TRACE_API("BTM_SetConnectability page scan interval = (%d * 0.625)ms",
407 interval);
408
409 if (controller_get_interface()->supports_ble()) {
410 if (btm_ble_set_connectability(page_mode) != BTM_SUCCESS) {
411 return BTM_NO_RESOURCES;
412 }
413 p_inq->connectable_mode &= (~BTM_BLE_CONNECTABLE_MASK);
414 p_inq->connectable_mode |= (page_mode & BTM_BLE_CONNECTABLE_MASK);
415 }
416 page_mode &= ~BTM_BLE_CONNECTABLE_MASK;
417
418 /*** Check mode parameter ***/
419 if (page_mode != BTM_NON_CONNECTABLE && page_mode != BTM_CONNECTABLE)
420 return (BTM_ILLEGAL_VALUE);
421
422 /* Make sure the controller is active */
423 if (!controller_get_interface()->get_is_ready()) return (BTM_DEV_RESET);
424
425 BTM_TRACE_API("BTM_SetConnectability: mode %d [NonConn-0, Conn-1]",
426 page_mode);
427
428 /*** Only check window and duration if mode is connectable ***/
429 if (page_mode == BTM_CONNECTABLE) {
430 scan_mode |= HCI_PAGE_SCAN_ENABLED;
431 }
432
433 window = osi_property_get_int32(PROPERTY_PAGE_SCAN_WINDOW,
434 BTM_DEFAULT_CONN_WINDOW);
435 interval = osi_property_get_int32(PROPERTY_PAGE_SCAN_INTERVAL,
436 BTM_DEFAULT_CONN_INTERVAL);
437
438 if ((window != p_inq->page_scan_window) ||
439 (interval != p_inq->page_scan_period)) {
440 p_inq->page_scan_window = window;
441 p_inq->page_scan_period = interval;
442 btsnd_hcic_write_pagescan_cfg(interval, window);
443 }
444
445 /* Keep the inquiry scan as previouosly set */
446 if (p_inq->discoverable_mode & BTM_DISCOVERABLE_MASK)
447 scan_mode |= HCI_INQUIRY_SCAN_ENABLED;
448
449 btm_log_history_scan_mode(scan_mode);
450 btsnd_hcic_write_scan_enable(scan_mode);
451 p_inq->connectable_mode &= (~BTM_CONNECTABLE_MASK);
452 p_inq->connectable_mode |= page_mode;
453 return (BTM_SUCCESS);
454 }
455
456 /*******************************************************************************
457 *
458 * Function BTM_IsInquiryActive
459 *
460 * Description This function returns a bit mask of the current inquiry
461 * state
462 *
463 * Returns BTM_INQUIRY_INACTIVE if inactive (0)
464 * BTM_GENERAL_INQUIRY_ACTIVE if a general inquiry is active
465 *
466 ******************************************************************************/
BTM_IsInquiryActive(void)467 uint16_t BTM_IsInquiryActive(void) {
468 BTM_TRACE_API("BTM_IsInquiryActive");
469
470 return (btm_cb.btm_inq_vars.inq_active);
471 }
472
473 /*******************************************************************************
474 *
475 * Function BTM_CancelInquiry
476 *
477 * Description This function cancels an inquiry if active
478 *
479 ******************************************************************************/
BTM_CancelInquiry(void)480 void BTM_CancelInquiry(void) {
481 tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
482 BTM_TRACE_API("BTM_CancelInquiry called");
483
484 CHECK(BTM_IsDeviceUp());
485
486 btm_cb.neighbor.inquiry_history_->Push({
487 .status = tBTM_INQUIRY_CMPL::CANCELED,
488 .num_resp = btm_cb.btm_inq_vars.inq_cmpl_info.num_resp,
489 .resp_type =
490 {
491 btm_cb.btm_inq_vars.inq_cmpl_info
492 .resp_type[BTM_INQ_RESULT_STANDARD],
493 btm_cb.btm_inq_vars.inq_cmpl_info
494 .resp_type[BTM_INQ_RESULT_WITH_RSSI],
495 btm_cb.btm_inq_vars.inq_cmpl_info
496 .resp_type[BTM_INQ_RESULT_EXTENDED],
497 },
498 .start_time_ms = btm_cb.neighbor.classic_inquiry.start_time_ms,
499 });
500
501 const auto end_time_ms = timestamper_in_milliseconds.GetTimestamp();
502 BTM_LogHistory(
503 kBtmLogTag, RawAddress::kEmpty, "Classic inquiry canceled",
504 base::StringPrintf(
505 "duration_s:%6.3f results:%lu std:%u rssi:%u ext:%u",
506 (end_time_ms - btm_cb.neighbor.classic_inquiry.start_time_ms) /
507 1000.0,
508 btm_cb.neighbor.classic_inquiry.results,
509 p_inq->inq_cmpl_info.resp_type[BTM_INQ_RESULT_STANDARD],
510 p_inq->inq_cmpl_info.resp_type[BTM_INQ_RESULT_WITH_RSSI],
511 p_inq->inq_cmpl_info.resp_type[BTM_INQ_RESULT_EXTENDED]));
512 btm_cb.neighbor.classic_inquiry = {};
513
514 /* Only cancel if not in periodic mode, otherwise the caller should call
515 * BTM_CancelPeriodicMode */
516 if ((p_inq->inq_active & BTM_INQUIRY_ACTIVE_MASK) != 0) {
517 p_inq->inq_active = BTM_INQUIRY_INACTIVE;
518 p_inq->state = BTM_INQ_INACTIVE_STATE;
519 p_inq->p_inq_results_cb = NULL; /* Do not notify caller anymore */
520 p_inq->p_inq_cmpl_cb = NULL; /* Do not notify caller anymore */
521
522 if ((p_inq->inqparms.mode & BTM_BR_INQUIRY_MASK) != 0) {
523 bluetooth::legacy::hci::GetInterface().InquiryCancel();
524 }
525
526 if (!bluetooth::shim::is_classic_discovery_only_enabled()) {
527 if ((p_inq->inqparms.mode & BTM_BLE_INQUIRY_MASK) != 0)
528 btm_ble_stop_inquiry();
529 }
530
531 p_inq->inq_counter++;
532 btm_clr_inq_result_flt();
533 }
534 }
535
btm_classic_inquiry_timeout(UNUSED_ATTR void * data)536 static void btm_classic_inquiry_timeout(UNUSED_ATTR void* data) {
537 // When the Inquiry Complete event is received, the classic inquiry
538 // will be marked as completed. Therefore, we only need to mark
539 // the BLE inquiry as completed here to stop processing BLE results
540 // as inquiry results.
541 btm_process_inq_complete(HCI_SUCCESS, BTM_BLE_INQUIRY_MASK);
542 }
543
544 /*******************************************************************************
545 *
546 * Function BTM_StartInquiry
547 *
548 * Description This function is called to start an inquiry.
549 *
550 * Parameters: p_inqparms - pointer to the inquiry information
551 * mode - GENERAL or LIMITED inquiry, BR/LE bit mask
552 * seperately
553 * duration - length in 1.28 sec intervals (If '0', the
554 * inquiry is CANCELLED)
555 * filter_cond_type - BTM_CLR_INQUIRY_FILTER,
556 * BTM_FILTER_COND_DEVICE_CLASS, or
557 * BTM_FILTER_COND_BD_ADDR
558 * filter_cond - value for the filter (based on
559 * filter_cond_type)
560 *
561 * p_results_cb - Pointer to the callback routine which gets
562 * called upon receipt of an inquiry result. If
563 * this field is NULL, the application is not
564 * notified.
565 *
566 * p_cmpl_cb - Pointer to the callback routine which gets
567 * called upon completion. If this field is
568 * NULL, the application is not notified when
569 * completed.
570 * Returns tBTM_STATUS
571 * BTM_CMD_STARTED if successfully initiated
572 * BTM_BUSY if already in progress
573 * BTM_ILLEGAL_VALUE if parameter(s) are out of range
574 * BTM_NO_RESOURCES if could not allocate resources to start
575 * the command
576 * BTM_WRONG_MODE if the device is not up.
577 *
578 ******************************************************************************/
BTM_StartInquiry(tBTM_INQ_RESULTS_CB * p_results_cb,tBTM_CMPL_CB * p_cmpl_cb)579 tBTM_STATUS BTM_StartInquiry(tBTM_INQ_RESULTS_CB* p_results_cb,
580 tBTM_CMPL_CB* p_cmpl_cb) {
581 /* Only one active inquiry is allowed in this implementation.
582 Also do not allow an inquiry if the inquiry filter is being updated */
583 if (btm_cb.btm_inq_vars.inq_active) {
584 LOG_WARN(
585 "Active device discovery already in progress inq_active:0x%02x"
586 " state:%hhu counter:%u",
587 btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state,
588 btm_cb.btm_inq_vars.inq_counter);
589 btm_cb.neighbor.inquiry_history_->Push({
590 .status = tBTM_INQUIRY_CMPL::NOT_STARTED,
591 });
592 return BTM_BUSY;
593 }
594
595 /*** Make sure the device is ready ***/
596 if (!BTM_IsDeviceUp()) {
597 LOG(ERROR) << __func__ << ": adapter is not up";
598 btm_cb.neighbor.inquiry_history_->Push({
599 .status = tBTM_INQUIRY_CMPL::NOT_STARTED,
600 });
601 return BTM_WRONG_MODE;
602 }
603
604 BTM_LogHistory(kBtmLogTag, RawAddress::kEmpty, "Classic inquiry started",
605 base::StringPrintf(
606 "%s", (btm_cb.neighbor.classic_inquiry.start_time_ms == 0)
607 ? ""
608 : "ERROR Already in progress"));
609
610 /* Save the inquiry parameters to be used upon the completion of
611 * setting/clearing the inquiry filter */
612 btm_cb.btm_inq_vars.inqparms = {
613 // tBTM_INQ_PARMS
614 .mode = BTM_GENERAL_INQUIRY | BTM_BLE_GENERAL_INQUIRY,
615 .duration = BTIF_DM_DEFAULT_INQ_MAX_DURATION,
616 };
617
618 /* Initialize the inquiry variables */
619 btm_cb.btm_inq_vars.state = BTM_INQ_ACTIVE_STATE;
620 btm_cb.btm_inq_vars.p_inq_cmpl_cb = p_cmpl_cb;
621 btm_cb.btm_inq_vars.p_inq_results_cb = p_results_cb;
622 btm_cb.btm_inq_vars.inq_cmpl_info = {}; /* Clear the results counter */
623 btm_cb.btm_inq_vars.inq_active = btm_cb.btm_inq_vars.inqparms.mode;
624 btm_cb.neighbor.classic_inquiry = {
625 .start_time_ms = timestamper_in_milliseconds.GetTimestamp(),
626 .results = 0,
627 };
628
629 LOG_DEBUG("Starting device discovery inq_active:0x%02x",
630 btm_cb.btm_inq_vars.inq_active);
631
632 // Also do BLE scanning here if we aren't limiting discovery to classic only.
633 // This path does not play nicely with GD BLE scanning and may cause issues
634 // with other scanners.
635 if (!bluetooth::shim::is_classic_discovery_only_enabled()) {
636 if (controller_get_interface()->supports_ble()) {
637 btm_ble_start_inquiry(btm_cb.btm_inq_vars.inqparms.duration);
638 } else {
639 LOG_WARN("Trying to do LE scan on a non-LE adapter");
640 btm_cb.btm_inq_vars.inqparms.mode &= ~BTM_BLE_INQUIRY_MASK;
641 }
642 }
643
644 btm_acl_update_inquiry_status(BTM_INQUIRY_STARTED);
645
646 if (btm_cb.btm_inq_vars.inq_active & BTM_SSP_INQUIRY_ACTIVE) {
647 LOG_INFO("Not starting inquiry as SSP is in progress");
648 btm_process_inq_complete(HCI_ERR_MAX_NUM_OF_CONNECTIONS,
649 BTM_GENERAL_INQUIRY);
650 return BTM_CMD_STARTED;
651 }
652
653 btm_clr_inq_result_flt();
654
655 btm_init_inq_result_flt();
656
657 bluetooth::legacy::hci::GetInterface().StartInquiry(
658 general_inq_lap, btm_cb.btm_inq_vars.inqparms.duration, 0);
659
660 // If we are only doing classic discovery, we should also set a timeout for
661 // the inquiry if a duration is set.
662 if (bluetooth::shim::is_classic_discovery_only_enabled() &&
663 btm_cb.btm_inq_vars.inqparms.duration != 0) {
664 /* start inquiry timer */
665 uint64_t duration_ms = btm_cb.btm_inq_vars.inqparms.duration * 1280;
666 alarm_set_on_mloop(btm_cb.btm_inq_vars.classic_inquiry_timer, duration_ms,
667 btm_classic_inquiry_timeout, NULL);
668 }
669
670 return BTM_CMD_STARTED;
671 }
672
673 /*******************************************************************************
674 *
675 * Function BTM_ReadRemoteDeviceName
676 *
677 * Description This function initiates a remote device HCI command to the
678 * controller and calls the callback when the process has
679 * completed.
680 *
681 * Input Params: remote_bda - device address of name to retrieve
682 * p_cb - callback function called when
683 * BTM_CMD_STARTED is returned.
684 * A pointer to tBTM_REMOTE_DEV_NAME is
685 * passed to the callback.
686 *
687 * Returns
688 * BTM_CMD_STARTED is returned if the request was successfully
689 * sent to HCI.
690 * BTM_BUSY if already in progress
691 * BTM_UNKNOWN_ADDR if device address is bad
692 * BTM_NO_RESOURCES if could not allocate resources to start
693 * the command
694 * BTM_WRONG_MODE if the device is not up.
695 *
696 ******************************************************************************/
BTM_ReadRemoteDeviceName(const RawAddress & remote_bda,tBTM_NAME_CMPL_CB * p_cb,tBT_TRANSPORT transport)697 tBTM_STATUS BTM_ReadRemoteDeviceName(const RawAddress& remote_bda,
698 tBTM_NAME_CMPL_CB* p_cb,
699 tBT_TRANSPORT transport) {
700 VLOG(1) << __func__ << ": bd addr " << remote_bda;
701 /* Use LE transport when LE is the only available option */
702 if (transport == BT_TRANSPORT_LE) {
703 return btm_ble_read_remote_name(remote_bda, p_cb);
704 }
705 /* Use classic transport for BR/EDR and Dual Mode devices */
706 return btm_initiate_rem_name(remote_bda, BTM_RMT_NAME_EXT,
707 BTM_EXT_RMT_NAME_TIMEOUT_MS, p_cb);
708 }
709
710 /*******************************************************************************
711 *
712 * Function BTM_CancelRemoteDeviceName
713 *
714 * Description This function initiates the cancel request for the specified
715 * remote device.
716 *
717 * Input Params: None
718 *
719 * Returns
720 * BTM_CMD_STARTED is returned if the request was successfully
721 * sent to HCI.
722 * BTM_NO_RESOURCES if could not allocate resources to start
723 * the command
724 * BTM_WRONG_MODE if there is not an active remote name
725 * request.
726 *
727 ******************************************************************************/
BTM_CancelRemoteDeviceName(void)728 tBTM_STATUS BTM_CancelRemoteDeviceName(void) {
729 tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
730
731 BTM_TRACE_API("BTM_CancelRemoteDeviceName()");
732
733 /* Make sure there is not already one in progress */
734 if (p_inq->remname_active) {
735 if (BTM_UseLeLink(p_inq->remname_bda)) {
736 /* Cancel remote name request for LE device, and process remote name
737 * callback. */
738 btm_inq_rmt_name_failed_cancelled();
739 } else
740 btsnd_hcic_rmt_name_req_cancel(p_inq->remname_bda);
741 return (BTM_CMD_STARTED);
742 } else
743 return (BTM_WRONG_MODE);
744 }
745
BTM_IsRemoteNameKnown(const RawAddress & bd_addr,tBT_TRANSPORT transport)746 bool BTM_IsRemoteNameKnown(const RawAddress& bd_addr, tBT_TRANSPORT transport) {
747 tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(bd_addr);
748 return (p_dev_rec == nullptr) ? false : p_dev_rec->is_name_known();
749 }
750
751 /*******************************************************************************
752 *
753 * Function BTM_InqDbRead
754 *
755 * Description This function looks through the inquiry database for a match
756 * based on Bluetooth Device Address. This is the application's
757 * interface to get the inquiry details of a specific BD
758 * address.
759 *
760 * Returns pointer to entry, or NULL if not found
761 *
762 ******************************************************************************/
BTM_InqDbRead(const RawAddress & p_bda)763 tBTM_INQ_INFO* BTM_InqDbRead(const RawAddress& p_bda) {
764 tINQ_DB_ENT* p_ent = btm_inq_db_find(p_bda);
765 return (p_ent == nullptr) ? nullptr : &p_ent->inq_info;
766 }
767
768 /*******************************************************************************
769 *
770 * Function BTM_InqDbFirst
771 *
772 * Description This function looks through the inquiry database for the
773 * first used entry, and returns that. This is used in
774 * conjunction with
775 * BTM_InqDbNext by applications as a way to walk through the
776 * inquiry database.
777 *
778 * Returns pointer to first in-use entry, or NULL if DB is empty
779 *
780 ******************************************************************************/
BTM_InqDbFirst(void)781 tBTM_INQ_INFO* BTM_InqDbFirst(void) {
782 uint16_t xx;
783
784 std::lock_guard<std::mutex> lock(inq_db_lock_);
785 tINQ_DB_ENT* p_ent = inq_db_;
786 for (xx = 0; xx < BTM_INQ_DB_SIZE; xx++, p_ent++) {
787 if (p_ent->in_use) return (&p_ent->inq_info);
788 }
789
790 /* If here, no used entry found */
791 return ((tBTM_INQ_INFO*)NULL);
792 }
793
794 /*******************************************************************************
795 *
796 * Function BTM_InqDbNext
797 *
798 * Description This function looks through the inquiry database for the
799 * next used entry, and returns that. If the input parameter
800 * is NULL, the first entry is returned.
801 *
802 * Returns pointer to next in-use entry, or NULL if no more found.
803 *
804 ******************************************************************************/
BTM_InqDbNext(tBTM_INQ_INFO * p_cur)805 tBTM_INQ_INFO* BTM_InqDbNext(tBTM_INQ_INFO* p_cur) {
806 uint16_t inx;
807
808 std::lock_guard<std::mutex> lock(inq_db_lock_);
809
810 if (p_cur) {
811 tINQ_DB_ENT* p_ent =
812 (tINQ_DB_ENT*)((uint8_t*)p_cur - offsetof(tINQ_DB_ENT, inq_info));
813 inx = (uint16_t)((p_ent - inq_db_) + 1);
814
815 for (p_ent = &inq_db_[inx]; inx < BTM_INQ_DB_SIZE; inx++, p_ent++) {
816 if (p_ent->in_use) return (&p_ent->inq_info);
817 }
818
819 /* If here, more entries found */
820 return ((tBTM_INQ_INFO*)NULL);
821 } else
822 return (BTM_InqDbFirst());
823 }
824
825 /*******************************************************************************
826 *
827 * Function BTM_ClearInqDb
828 *
829 * Description This function is called to clear out a device or all devices
830 * from the inquiry database.
831 *
832 * Parameter p_bda - (input) BD_ADDR -> Address of device to clear
833 * (NULL clears all entries)
834 *
835 * Returns BTM_BUSY if an inquiry, get remote name, or event filter
836 * is active, otherwise BTM_SUCCESS
837 *
838 ******************************************************************************/
BTM_ClearInqDb(const RawAddress * p_bda)839 tBTM_STATUS BTM_ClearInqDb(const RawAddress* p_bda) {
840 tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
841
842 /* If an inquiry or remote name is in progress return busy */
843 if (p_inq->inq_active != BTM_INQUIRY_INACTIVE) return (BTM_BUSY);
844
845 btm_clr_inq_db(p_bda);
846
847 return (BTM_SUCCESS);
848 }
849
850 /*******************************************************************************
851 *
852 * Function btm_clear_all_pending_le_entry
853 *
854 * Description This function is called to clear all LE pending entry in
855 * inquiry database.
856 *
857 * Returns void
858 *
859 ******************************************************************************/
btm_clear_all_pending_le_entry(void)860 void btm_clear_all_pending_le_entry(void) {
861 uint16_t xx;
862 std::lock_guard<std::mutex> lock(inq_db_lock_);
863 tINQ_DB_ENT* p_ent = inq_db_;
864
865 for (xx = 0; xx < BTM_INQ_DB_SIZE; xx++, p_ent++) {
866 /* mark all pending LE entry as unused if an LE only device has scan
867 * response outstanding */
868 if ((p_ent->in_use) &&
869 (p_ent->inq_info.results.device_type == BT_DEVICE_TYPE_BLE) &&
870 !p_ent->scan_rsp)
871 p_ent->in_use = false;
872 }
873 }
874
875 /*******************************************************************************
876 *******************************************************************************
877 * **
878 * BTM Internal Inquiry Functions **
879 * **
880 *******************************************************************************
881 ******************************************************************************/
882 /*******************************************************************************
883 *
884 * Function btm_inq_db_reset
885 *
886 * Description This function is called at at reset to clear the inquiry
887 * database & pending callback.
888 *
889 * Returns void
890 *
891 ******************************************************************************/
btm_inq_db_reset(void)892 void btm_inq_db_reset(void) {
893 tBTM_REMOTE_DEV_NAME rem_name = {};
894 tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
895 uint8_t num_responses;
896 uint8_t temp_inq_active;
897
898 LOG_DEBUG("Resetting inquiry database");
899
900 /* If an inquiry or periodic inquiry is active, reset the mode to inactive */
901 if (p_inq->inq_active != BTM_INQUIRY_INACTIVE) {
902 temp_inq_active = p_inq->inq_active; /* Save so state can change BEFORE
903 callback is called */
904 p_inq->inq_active = BTM_INQUIRY_INACTIVE;
905
906 /* If not a periodic inquiry, the complete callback must be called to notify
907 * caller */
908 if (temp_inq_active == BTM_GENERAL_INQUIRY_ACTIVE) {
909 if (p_inq->p_inq_cmpl_cb) {
910 num_responses = 0;
911 (*p_inq->p_inq_cmpl_cb)(&num_responses);
912 }
913 }
914 }
915
916 /* Cancel a remote name request if active, and notify the caller (if waiting)
917 */
918 if (p_inq->remname_active) {
919 alarm_cancel(p_inq->remote_name_timer);
920 p_inq->remname_active = false;
921 p_inq->remname_bda = RawAddress::kEmpty;
922
923 if (p_inq->p_remname_cmpl_cb) {
924 rem_name.status = BTM_DEV_RESET;
925 rem_name.hci_status = HCI_SUCCESS;
926
927 (*p_inq->p_remname_cmpl_cb)(&rem_name);
928 p_inq->p_remname_cmpl_cb = NULL;
929 }
930 }
931
932 p_inq->state = BTM_INQ_INACTIVE_STATE;
933 p_inq->p_inq_results_cb = NULL;
934 btm_clr_inq_db(NULL); /* Clear out all the entries in the database */
935 btm_clr_inq_result_flt();
936
937 p_inq->discoverable_mode = BTM_NON_DISCOVERABLE;
938 p_inq->connectable_mode = BTM_NON_CONNECTABLE;
939 p_inq->page_scan_type = BTM_SCAN_TYPE_STANDARD;
940 p_inq->inq_scan_type = BTM_SCAN_TYPE_STANDARD;
941
942 p_inq->discoverable_mode |= BTM_BLE_NON_DISCOVERABLE;
943 p_inq->connectable_mode |= BTM_BLE_NON_CONNECTABLE;
944 return;
945 }
946
947 /*******************************************************************************
948 *
949 * Function btm_inq_db_init
950 *
951 * Description This function is called at startup to initialize the inquiry
952 * database.
953 *
954 * Returns void
955 *
956 ******************************************************************************/
btm_inq_db_init(void)957 void btm_inq_db_init(void) {
958 alarm_free(btm_cb.btm_inq_vars.remote_name_timer);
959 btm_cb.btm_inq_vars.remote_name_timer =
960 alarm_new("btm_inq.remote_name_timer");
961 btm_cb.btm_inq_vars.no_inc_ssp = BTM_NO_SSP_ON_INQUIRY;
962 }
963
btm_inq_db_free(void)964 void btm_inq_db_free(void) {
965 alarm_free(btm_cb.btm_inq_vars.remote_name_timer);
966 }
967
968 /*******************************************************************************
969 *
970 * Function btm_inq_stop_on_ssp
971 *
972 * Description This function is called on incoming SSP
973 *
974 * Returns void
975 *
976 ******************************************************************************/
btm_inq_stop_on_ssp(void)977 void btm_inq_stop_on_ssp(void) {
978 uint8_t normal_active = (BTM_GENERAL_INQUIRY_ACTIVE);
979
980 #if (BTM_INQ_DEBUG == TRUE)
981 BTM_TRACE_DEBUG(
982 "btm_inq_stop_on_ssp: no_inc_ssp=%d inq_active:0x%x state:%d ",
983 btm_cb.btm_inq_vars.no_inc_ssp, btm_cb.btm_inq_vars.inq_active,
984 btm_cb.btm_inq_vars.state);
985 #endif
986 if (btm_cb.btm_inq_vars.no_inc_ssp) {
987 if (btm_cb.btm_inq_vars.state == BTM_INQ_ACTIVE_STATE) {
988 if (btm_cb.btm_inq_vars.inq_active & normal_active) {
989 /* can not call BTM_CancelInquiry() here. We need to report inquiry
990 * complete evt */
991 bluetooth::legacy::hci::GetInterface().InquiryCancel();
992 }
993 }
994 /* do not allow inquiry to start */
995 btm_cb.btm_inq_vars.inq_active |= BTM_SSP_INQUIRY_ACTIVE;
996 }
997 }
998
999 /*******************************************************************************
1000 *
1001 * Function btm_inq_clear_ssp
1002 *
1003 * Description This function is called when pairing_state becomes idle
1004 *
1005 * Returns void
1006 *
1007 ******************************************************************************/
btm_inq_clear_ssp(void)1008 void btm_inq_clear_ssp(void) {
1009 btm_cb.btm_inq_vars.inq_active &= ~BTM_SSP_INQUIRY_ACTIVE;
1010 }
1011
1012 /*******************************************************************************
1013 *
1014 * Function btm_clr_inq_db
1015 *
1016 * Description This function is called to clear out a device or all devices
1017 * from the inquiry database.
1018 *
1019 * Parameter p_bda - (input) BD_ADDR -> Address of device to clear
1020 * (NULL clears all entries)
1021 *
1022 * Returns void
1023 *
1024 ******************************************************************************/
btm_clr_inq_db(const RawAddress * p_bda)1025 void btm_clr_inq_db(const RawAddress* p_bda) {
1026 uint16_t xx;
1027
1028 #if (BTM_INQ_DEBUG == TRUE)
1029 BTM_TRACE_DEBUG("btm_clr_inq_db: inq_active:0x%x state:%d",
1030 btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state);
1031 #endif
1032 std::lock_guard<std::mutex> lock(inq_db_lock_);
1033 tINQ_DB_ENT* p_ent = inq_db_;
1034 for (xx = 0; xx < BTM_INQ_DB_SIZE; xx++, p_ent++) {
1035 if (p_ent->in_use) {
1036 /* If this is the specified BD_ADDR or clearing all devices */
1037 if (p_bda == NULL || (p_ent->inq_info.results.remote_bd_addr == *p_bda)) {
1038 p_ent->in_use = false;
1039 }
1040 }
1041 }
1042 #if (BTM_INQ_DEBUG == TRUE)
1043 BTM_TRACE_DEBUG("inq_active:0x%x state:%d", btm_cb.btm_inq_vars.inq_active,
1044 btm_cb.btm_inq_vars.state);
1045 #endif
1046 }
1047
1048 /*******************************************************************************
1049 *
1050 * Function btm_[init|clr]_inq_result_flt
1051 *
1052 * Description These functions initialize and clear the bdaddr
1053 * database for a match based on Bluetooth Device Address
1054 *
1055 * Returns None
1056 *
1057 ******************************************************************************/
btm_init_inq_result_flt(void)1058 static void btm_init_inq_result_flt(void) {
1059 std::lock_guard<std::mutex> lock(bd_db_lock_);
1060
1061 if (p_bd_db_ != nullptr) {
1062 LOG_ERROR("Memory leak with bluetooth device database");
1063 }
1064
1065 /* Allocate memory to hold bd_addrs responding */
1066 p_bd_db_ = (tINQ_BDADDR*)osi_calloc(BT_DEFAULT_BUFFER_SIZE);
1067 max_bd_entries_ = (uint16_t)(BT_DEFAULT_BUFFER_SIZE / sizeof(tINQ_BDADDR));
1068 }
1069
btm_clr_inq_result_flt(void)1070 void btm_clr_inq_result_flt(void) {
1071 std::lock_guard<std::mutex> lock(bd_db_lock_);
1072 if (p_bd_db_ == nullptr) {
1073 LOG_WARN("Memory being reset multiple times");
1074 }
1075
1076 osi_free_and_reset((void**)&p_bd_db_);
1077 num_bd_entries_ = 0;
1078 max_bd_entries_ = 0;
1079 }
1080
1081 /*******************************************************************************
1082 *
1083 * Function btm_inq_find_bdaddr
1084 *
1085 * Description This function looks through the bdaddr database for a match
1086 * based on Bluetooth Device Address
1087 *
1088 * Returns true if found, else false (new entry)
1089 *
1090 ******************************************************************************/
btm_inq_find_bdaddr(const RawAddress & p_bda)1091 bool btm_inq_find_bdaddr(const RawAddress& p_bda) {
1092 std::lock_guard<std::mutex> lock(bd_db_lock_);
1093 tINQ_BDADDR* p_db = p_bd_db_;
1094 uint16_t xx;
1095
1096 /* Don't bother searching, database doesn't exist or periodic mode */
1097 if (!p_db) return (false);
1098
1099 for (xx = 0; xx < num_bd_entries_; xx++, p_db++) {
1100 if (p_db->bd_addr == p_bda &&
1101 p_db->inq_count == btm_cb.btm_inq_vars.inq_counter)
1102 return (true);
1103 }
1104
1105 if (xx < max_bd_entries_) {
1106 p_db->inq_count = btm_cb.btm_inq_vars.inq_counter;
1107 p_db->bd_addr = p_bda;
1108 num_bd_entries_++;
1109 }
1110
1111 /* If here, New Entry */
1112 return (false);
1113 }
1114
1115 /*******************************************************************************
1116 *
1117 * Function btm_inq_db_find
1118 *
1119 * Description This function looks through the inquiry database for a match
1120 * based on Bluetooth Device Address
1121 *
1122 * Returns pointer to entry, or NULL if not found
1123 *
1124 ******************************************************************************/
btm_inq_db_find(const RawAddress & p_bda)1125 tINQ_DB_ENT* btm_inq_db_find(const RawAddress& p_bda) {
1126 uint16_t xx;
1127 std::lock_guard<std::mutex> lock(inq_db_lock_);
1128 tINQ_DB_ENT* p_ent = inq_db_;
1129
1130 for (xx = 0; xx < BTM_INQ_DB_SIZE; xx++, p_ent++) {
1131 if (p_ent->in_use && p_ent->inq_info.results.remote_bd_addr == p_bda)
1132 return (p_ent);
1133 }
1134
1135 /* If here, not found */
1136 return (NULL);
1137 }
1138
1139 /*******************************************************************************
1140 *
1141 * Function btm_inq_db_new
1142 *
1143 * Description This function looks through the inquiry database for an
1144 * unused entry. If no entry is free, it allocates the oldest
1145 * entry.
1146 *
1147 * Returns pointer to entry
1148 *
1149 ******************************************************************************/
btm_inq_db_new(const RawAddress & p_bda)1150 tINQ_DB_ENT* btm_inq_db_new(const RawAddress& p_bda) {
1151 uint16_t xx;
1152 uint64_t ot = UINT64_MAX;
1153
1154 std::lock_guard<std::mutex> lock(inq_db_lock_);
1155 tINQ_DB_ENT* p_ent = inq_db_;
1156 tINQ_DB_ENT* p_old = inq_db_;
1157
1158 for (xx = 0; xx < BTM_INQ_DB_SIZE; xx++, p_ent++) {
1159 if (!p_ent->in_use) {
1160 memset(p_ent, 0, sizeof(tINQ_DB_ENT));
1161 p_ent->inq_info.results.remote_bd_addr = p_bda;
1162 p_ent->in_use = true;
1163
1164 return (p_ent);
1165 }
1166
1167 if (p_ent->time_of_resp < ot) {
1168 p_old = p_ent;
1169 ot = p_ent->time_of_resp;
1170 }
1171 }
1172
1173 /* If here, no free entry found. Return the oldest. */
1174
1175 memset(p_old, 0, sizeof(tINQ_DB_ENT));
1176 p_old->inq_info.results.remote_bd_addr = p_bda;
1177 p_old->in_use = true;
1178
1179 return (p_old);
1180 }
1181
1182 /*******************************************************************************
1183 *
1184 * Function btm_process_inq_results
1185 *
1186 * Description This function is called when inquiry results are received
1187 * from the device. It updates the inquiry database. If the
1188 * inquiry database is full, the oldest entry is discarded.
1189 *
1190 * Parameters inq_res_mode - BTM_INQ_RESULT_STANDARD
1191 * BTM_INQ_RESULT_WITH_RSSI
1192 * BTM_INQ_RESULT_EXTENDED
1193 *
1194 * Returns void
1195 *
1196 ******************************************************************************/
btm_process_inq_results(const uint8_t * p,uint8_t hci_evt_len,uint8_t inq_res_mode)1197 void btm_process_inq_results(const uint8_t* p, uint8_t hci_evt_len,
1198 uint8_t inq_res_mode) {
1199 uint8_t num_resp, xx;
1200 RawAddress bda;
1201 tINQ_DB_ENT* p_i;
1202 tBTM_INQ_RESULTS* p_cur = NULL;
1203 bool is_new = true;
1204 bool update = false;
1205 int8_t i_rssi;
1206 tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
1207 tBTM_INQ_RESULTS_CB* p_inq_results_cb = p_inq->p_inq_results_cb;
1208 uint8_t page_scan_rep_mode = 0;
1209 uint8_t page_scan_per_mode = 0;
1210 uint8_t page_scan_mode = 0;
1211 uint8_t rssi = 0;
1212 DEV_CLASS dc;
1213 uint16_t clock_offset;
1214 const uint8_t* p_eir_data = NULL;
1215
1216 LOG_DEBUG("Received inquiry result inq_active:0x%x state:%d",
1217 btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state);
1218
1219 /* Only process the results if the BR inquiry is still active */
1220 if (!(p_inq->inq_active & BTM_BR_INQ_ACTIVE_MASK)) {
1221 LOG_INFO("Inquiry is inactive so dropping inquiry result");
1222 return;
1223 }
1224
1225 STREAM_TO_UINT8(num_resp, p);
1226
1227 if (inq_res_mode == BTM_INQ_RESULT_EXTENDED) {
1228 if (num_resp > 1) {
1229 BTM_TRACE_ERROR("btm_process_inq_results() extended results (%d) > 1",
1230 num_resp);
1231 return;
1232 }
1233
1234 constexpr uint16_t extended_inquiry_result_size = 254;
1235 if (hci_evt_len - 1 != extended_inquiry_result_size) {
1236 BTM_TRACE_ERROR("%s: can't fit %d results in %d bytes", __func__,
1237 num_resp, hci_evt_len);
1238 return;
1239 }
1240 } else if (inq_res_mode == BTM_INQ_RESULT_STANDARD ||
1241 inq_res_mode == BTM_INQ_RESULT_WITH_RSSI) {
1242 constexpr uint16_t inquiry_result_size = 14;
1243 if (hci_evt_len < num_resp * inquiry_result_size) {
1244 BTM_TRACE_ERROR("%s: can't fit %d results in %d bytes", __func__,
1245 num_resp, hci_evt_len);
1246 return;
1247 }
1248 }
1249
1250 btm_cb.neighbor.classic_inquiry.results += num_resp;
1251 for (xx = 0; xx < num_resp; xx++) {
1252 update = false;
1253 /* Extract inquiry results */
1254 STREAM_TO_BDADDR(bda, p);
1255 STREAM_TO_UINT8(page_scan_rep_mode, p);
1256 STREAM_TO_UINT8(page_scan_per_mode, p);
1257
1258 if (inq_res_mode == BTM_INQ_RESULT_STANDARD) {
1259 STREAM_TO_UINT8(page_scan_mode, p);
1260 }
1261
1262 STREAM_TO_DEVCLASS(dc, p);
1263 STREAM_TO_UINT16(clock_offset, p);
1264 if (inq_res_mode != BTM_INQ_RESULT_STANDARD) {
1265 STREAM_TO_UINT8(rssi, p);
1266 }
1267
1268 p_i = btm_inq_db_find(bda);
1269
1270 /* Check if this address has already been processed for this inquiry */
1271 if (btm_inq_find_bdaddr(bda)) {
1272 /* BTM_TRACE_DEBUG("BDA seen before %s", ADDRESS_TO_LOGGABLE_CSTR(bda));
1273 */
1274
1275 /* By default suppose no update needed */
1276 i_rssi = (int8_t)rssi;
1277
1278 /* If this new RSSI is higher than the last one */
1279 if ((rssi != 0) && p_i &&
1280 (i_rssi > p_i->inq_info.results.rssi ||
1281 p_i->inq_info.results.rssi == 0
1282 /* BR/EDR inquiry information update */
1283 ||
1284 (p_i->inq_info.results.device_type & BT_DEVICE_TYPE_BREDR) != 0)) {
1285 p_cur = &p_i->inq_info.results;
1286 BTM_TRACE_DEBUG("update RSSI new:%d, old:%d", i_rssi, p_cur->rssi);
1287 p_cur->rssi = i_rssi;
1288 update = true;
1289 }
1290 /* If we received a second Extended Inq Event for an already */
1291 /* discovered device, this is because for the first one EIR was not
1292 received */
1293 else if ((inq_res_mode == BTM_INQ_RESULT_EXTENDED) && (p_i)) {
1294 p_cur = &p_i->inq_info.results;
1295 update = true;
1296 }
1297 /* If no update needed continue with next response (if any) */
1298 else
1299 continue;
1300 }
1301
1302 /* If existing entry, use that, else get a new one (possibly reusing the
1303 * oldest) */
1304 if (p_i == NULL) {
1305 p_i = btm_inq_db_new(bda);
1306 is_new = true;
1307 }
1308
1309 /* If an entry for the device already exists, overwrite it ONLY if it is
1310 from
1311 a previous inquiry. (Ignore it if it is a duplicate response from the
1312 same
1313 inquiry.
1314 */
1315 else if (p_i->inq_count == p_inq->inq_counter &&
1316 (p_i->inq_info.results.device_type == BT_DEVICE_TYPE_BREDR))
1317 is_new = false;
1318
1319 /* keep updating RSSI to have latest value */
1320 if (inq_res_mode != BTM_INQ_RESULT_STANDARD)
1321 p_i->inq_info.results.rssi = (int8_t)rssi;
1322 else
1323 p_i->inq_info.results.rssi = BTM_INQ_RES_IGNORE_RSSI;
1324
1325 if (is_new) {
1326 /* Save the info */
1327 p_cur = &p_i->inq_info.results;
1328 p_cur->page_scan_rep_mode = page_scan_rep_mode;
1329 p_cur->page_scan_per_mode = page_scan_per_mode;
1330 p_cur->page_scan_mode = page_scan_mode;
1331 p_cur->dev_class[0] = dc[0];
1332 p_cur->dev_class[1] = dc[1];
1333 p_cur->dev_class[2] = dc[2];
1334 p_cur->clock_offset = clock_offset | BTM_CLOCK_OFFSET_VALID;
1335
1336 p_i->time_of_resp = bluetooth::common::time_get_os_boottime_ms();
1337
1338 if (p_i->inq_count != p_inq->inq_counter) {
1339 /* A new response was found */
1340 btm_cb.btm_inq_vars.inq_cmpl_info.num_resp++;
1341 switch (static_cast<tBTM_INQ_RESULT>(inq_res_mode)) {
1342 case BTM_INQ_RESULT_STANDARD:
1343 case BTM_INQ_RESULT_WITH_RSSI:
1344 case BTM_INQ_RESULT_EXTENDED:
1345 btm_cb.btm_inq_vars.inq_cmpl_info.resp_type[inq_res_mode]++;
1346 break;
1347 case BTM_INQ_RES_IGNORE_RSSI:
1348 btm_cb.btm_inq_vars.inq_cmpl_info
1349 .resp_type[BTM_INQ_RESULT_STANDARD]++;
1350 break;
1351 }
1352 }
1353
1354 p_cur->inq_result_type |= BTM_INQ_RESULT_BR;
1355 if (p_i->inq_count != p_inq->inq_counter) {
1356 p_cur->device_type = BT_DEVICE_TYPE_BREDR;
1357 p_i->scan_rsp = false;
1358 } else
1359 p_cur->device_type |= BT_DEVICE_TYPE_BREDR;
1360 p_i->inq_count = p_inq->inq_counter; /* Mark entry for current inquiry */
1361
1362 /* Initialize flag to false. This flag is set/used by application */
1363 p_i->inq_info.appl_knows_rem_name = false;
1364 }
1365
1366 if (is_new || update) {
1367 if (inq_res_mode == BTM_INQ_RESULT_EXTENDED) {
1368 memset(p_cur->eir_uuid, 0,
1369 BTM_EIR_SERVICE_ARRAY_SIZE * (BTM_EIR_ARRAY_BITS / 8));
1370 /* set bit map of UUID list from received EIR */
1371 btm_set_eir_uuid(p, p_cur);
1372 p_eir_data = p;
1373 } else
1374 p_eir_data = NULL;
1375
1376 /* If a callback is registered, call it with the results */
1377 if (p_inq_results_cb) {
1378 (p_inq_results_cb)((tBTM_INQ_RESULTS*)p_cur, p_eir_data,
1379 HCI_EXT_INQ_RESPONSE_LEN);
1380 } else {
1381 LOG_WARN("No callback is registered for inquiry result");
1382 }
1383 }
1384 }
1385 }
1386
1387 /*******************************************************************************
1388 *
1389 * Function btm_sort_inq_result
1390 *
1391 * Description This function is called when inquiry complete is received
1392 * from the device to sort inquiry results based on rssi.
1393 *
1394 * Returns void
1395 *
1396 ******************************************************************************/
btm_sort_inq_result(void)1397 void btm_sort_inq_result(void) {
1398 uint8_t xx, yy, num_resp;
1399 std::lock_guard<std::mutex> lock(inq_db_lock_);
1400 tINQ_DB_ENT* p_ent = inq_db_;
1401 tINQ_DB_ENT* p_next = inq_db_ + 1;
1402 int size;
1403 tINQ_DB_ENT* p_tmp = (tINQ_DB_ENT*)osi_malloc(sizeof(tINQ_DB_ENT));
1404
1405 num_resp = (btm_cb.btm_inq_vars.inq_cmpl_info.num_resp < BTM_INQ_DB_SIZE)
1406 ? btm_cb.btm_inq_vars.inq_cmpl_info.num_resp
1407 : BTM_INQ_DB_SIZE;
1408
1409 size = sizeof(tINQ_DB_ENT);
1410 for (xx = 0; xx < num_resp - 1; xx++, p_ent++) {
1411 for (yy = xx + 1, p_next = p_ent + 1; yy < num_resp; yy++, p_next++) {
1412 if (p_ent->inq_info.results.rssi < p_next->inq_info.results.rssi) {
1413 memcpy(p_tmp, p_next, size);
1414 memcpy(p_next, p_ent, size);
1415 memcpy(p_ent, p_tmp, size);
1416 }
1417 }
1418 }
1419
1420 osi_free(p_tmp);
1421 }
1422
1423 /*******************************************************************************
1424 *
1425 * Function btm_process_inq_complete
1426 *
1427 * Description This function is called when inquiry complete is received
1428 * from the device. Call the callback if not in periodic
1429 * inquiry mode AND it is not NULL
1430 * (The caller wants the event).
1431 *
1432 * The callback pass back the status and the number of
1433 * responses
1434 *
1435 * Returns void
1436 *
1437 ******************************************************************************/
btm_process_inq_complete(tHCI_STATUS status,uint8_t mode)1438 void btm_process_inq_complete(tHCI_STATUS status, uint8_t mode) {
1439 tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
1440
1441 p_inq->inqparms.mode &= ~(mode);
1442 const auto inq_active = p_inq->inq_active;
1443
1444 btm_acl_update_inquiry_status(BTM_INQUIRY_COMPLETE);
1445
1446 if (status != HCI_SUCCESS) {
1447 LOG_WARN("Received unexpected hci status:%s",
1448 hci_error_code_text(status).c_str());
1449 }
1450
1451 /* Ignore any stray or late complete messages if the inquiry is not active */
1452 if (p_inq->inq_active) {
1453 p_inq->inq_cmpl_info.hci_status = status;
1454
1455 /* Notify caller that the inquiry has completed; (periodic inquiries do not
1456 * send completion events */
1457 if (p_inq->inqparms.mode == 0) {
1458 btm_clear_all_pending_le_entry();
1459 p_inq->state = BTM_INQ_INACTIVE_STATE;
1460
1461 /* Increment so the start of a next inquiry has a new count */
1462 p_inq->inq_counter++;
1463
1464 btm_clr_inq_result_flt();
1465
1466 if ((status == HCI_SUCCESS) &&
1467 controller_get_interface()->supports_rssi_with_inquiry_results()) {
1468 btm_sort_inq_result();
1469 }
1470
1471 if (btm_cb.btm_inq_vars.p_inq_cmpl_cb) {
1472 (btm_cb.btm_inq_vars.p_inq_cmpl_cb)(
1473 (tBTM_INQUIRY_CMPL*)&p_inq->inq_cmpl_info);
1474 } else {
1475 LOG_WARN("No callback to return inquiry result");
1476 }
1477
1478 btm_cb.neighbor.inquiry_history_->Push({
1479 .status = tBTM_INQUIRY_CMPL::TIMER_POPPED,
1480 .num_resp = btm_cb.btm_inq_vars.inq_cmpl_info.num_resp,
1481 .resp_type =
1482 {
1483 btm_cb.btm_inq_vars.inq_cmpl_info
1484 .resp_type[BTM_INQ_RESULT_STANDARD],
1485 btm_cb.btm_inq_vars.inq_cmpl_info
1486 .resp_type[BTM_INQ_RESULT_WITH_RSSI],
1487 btm_cb.btm_inq_vars.inq_cmpl_info
1488 .resp_type[BTM_INQ_RESULT_EXTENDED],
1489 },
1490 .start_time_ms = btm_cb.neighbor.classic_inquiry.start_time_ms,
1491 });
1492 const auto end_time_ms = timestamper_in_milliseconds.GetTimestamp();
1493 BTM_LogHistory(
1494 kBtmLogTag, RawAddress::kEmpty, "Classic inquiry complete",
1495 base::StringPrintf(
1496 "duration_s:%6.3f results:%lu inq_active:0x%02x std:%u rssi:%u "
1497 "ext:%u status:%s",
1498 (end_time_ms - btm_cb.neighbor.classic_inquiry.start_time_ms) /
1499 1000.0,
1500 btm_cb.neighbor.classic_inquiry.results, inq_active,
1501 p_inq->inq_cmpl_info.resp_type[BTM_INQ_RESULT_STANDARD],
1502 p_inq->inq_cmpl_info.resp_type[BTM_INQ_RESULT_WITH_RSSI],
1503 p_inq->inq_cmpl_info.resp_type[BTM_INQ_RESULT_EXTENDED],
1504 hci_error_code_text(status).c_str()));
1505
1506 btm_cb.neighbor.classic_inquiry.start_time_ms = 0;
1507 /* Clear the results callback if set */
1508 p_inq->p_inq_results_cb = NULL;
1509 p_inq->inq_active = BTM_INQUIRY_INACTIVE;
1510 p_inq->p_inq_cmpl_cb = NULL;
1511
1512 } else {
1513 LOG_INFO(
1514 "Inquiry params is not clear so not sending callback inq_parms:%u",
1515 btm_cb.btm_inq_vars.inqparms.mode);
1516 }
1517 } else {
1518 LOG_ERROR("Received inquiry complete when no inquiry was active");
1519 }
1520 }
1521
1522 /*******************************************************************************
1523 *
1524 * Function btm_process_cancel_complete
1525 *
1526 * Description This function is called when inquiry cancel complete is
1527 * received from the device. This function will also call the
1528 * btm_process_inq_complete. This function is needed to
1529 * differentiate a cancel_cmpl_evt from the inq_cmpl_evt.
1530 *
1531 * Returns void
1532 *
1533 ******************************************************************************/
btm_process_cancel_complete(tHCI_STATUS status,uint8_t mode)1534 void btm_process_cancel_complete(tHCI_STATUS status, uint8_t mode) {
1535 btm_acl_update_inquiry_status(BTM_INQUIRY_CANCELLED);
1536 btm_process_inq_complete(status, mode);
1537 }
1538 /*******************************************************************************
1539 *
1540 * Function btm_initiate_rem_name
1541 *
1542 * Description This function looks initiates a remote name request. It is
1543 * called either by GAP or by the API call
1544 * BTM_ReadRemoteDeviceName.
1545 *
1546 * Input Params: p_cb - callback function called when
1547 * BTM_CMD_STARTED is returned.
1548 * A pointer to tBTM_REMOTE_DEV_NAME is
1549 * passed to the callback.
1550 *
1551 * Returns
1552 * BTM_CMD_STARTED is returned if the request was sent to HCI.
1553 * BTM_BUSY if already in progress
1554 * BTM_NO_RESOURCES if could not allocate resources to start
1555 * the command
1556 * BTM_WRONG_MODE if the device is not up.
1557 *
1558 ******************************************************************************/
btm_initiate_rem_name(const RawAddress & remote_bda,uint8_t origin,uint64_t timeout_ms,tBTM_NAME_CMPL_CB * p_cb)1559 tBTM_STATUS btm_initiate_rem_name(const RawAddress& remote_bda, uint8_t origin,
1560 uint64_t timeout_ms,
1561 tBTM_NAME_CMPL_CB* p_cb) {
1562 tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
1563
1564 /*** Make sure the device is ready ***/
1565 if (!BTM_IsDeviceUp()) return (BTM_WRONG_MODE);
1566 if (origin == BTM_RMT_NAME_EXT) {
1567 if (p_inq->remname_active) {
1568 return (BTM_BUSY);
1569 } else {
1570 /* If there is no remote name request running,call the callback function
1571 * and start timer */
1572 p_inq->p_remname_cmpl_cb = p_cb;
1573 p_inq->remname_bda = remote_bda;
1574
1575 alarm_set_on_mloop(p_inq->remote_name_timer, timeout_ms,
1576 btm_inq_remote_name_timer_timeout, NULL);
1577
1578 /* If the database entry exists for the device, use its clock offset */
1579 tINQ_DB_ENT* p_i = btm_inq_db_find(remote_bda);
1580 if (p_i && (p_i->inq_info.results.inq_result_type & BTM_INQ_RESULT_BR)) {
1581 tBTM_INQ_INFO* p_cur = &p_i->inq_info;
1582 btsnd_hcic_rmt_name_req(
1583 remote_bda, p_cur->results.page_scan_rep_mode,
1584 p_cur->results.page_scan_mode,
1585 (uint16_t)(p_cur->results.clock_offset | BTM_CLOCK_OFFSET_VALID));
1586 } else {
1587 /* Otherwise use defaults and mark the clock offset as invalid */
1588 btsnd_hcic_rmt_name_req(remote_bda, HCI_PAGE_SCAN_REP_MODE_R1,
1589 HCI_MANDATARY_PAGE_SCAN_MODE, 0);
1590 }
1591
1592 p_inq->remname_active = true;
1593 return BTM_CMD_STARTED;
1594 }
1595 } else {
1596 return BTM_ILLEGAL_VALUE;
1597 }
1598 }
1599
1600 /*******************************************************************************
1601 *
1602 * Function btm_process_remote_name
1603 *
1604 * Description This function is called when a remote name is received from
1605 * the device. If remote names are cached, it updates the
1606 * inquiry database.
1607 *
1608 * Returns void
1609 *
1610 ******************************************************************************/
btm_process_remote_name(const RawAddress * bda,const BD_NAME bdn,uint16_t evt_len,tHCI_STATUS hci_status)1611 void btm_process_remote_name(const RawAddress* bda, const BD_NAME bdn,
1612 uint16_t evt_len, tHCI_STATUS hci_status) {
1613 tBTM_REMOTE_DEV_NAME rem_name;
1614 tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
1615 tBTM_NAME_CMPL_CB* p_cb = p_inq->p_remname_cmpl_cb;
1616 uint8_t* p_n1;
1617
1618 uint16_t temp_evt_len;
1619
1620 if (bda) {
1621 rem_name.bd_addr = *bda;
1622 } else {
1623 rem_name.bd_addr = RawAddress::kEmpty;
1624 }
1625
1626 LOG_INFO("btm_process_remote_name for %s",
1627 ADDRESS_TO_LOGGABLE_CSTR(rem_name.bd_addr));
1628
1629 VLOG(2) << "Inquire BDA " << p_inq->remname_bda;
1630
1631 /* If the inquire BDA and remote DBA are the same, then stop the timer and set
1632 * the active to false */
1633 if ((p_inq->remname_active) && (!bda || (*bda == p_inq->remname_bda))) {
1634 if (BTM_UseLeLink(p_inq->remname_bda)) {
1635 if (hci_status == HCI_ERR_UNSPECIFIED)
1636 btm_ble_cancel_remote_name(p_inq->remname_bda);
1637 }
1638 alarm_cancel(p_inq->remote_name_timer);
1639 p_inq->remname_active = false;
1640 /* Clean up and return the status if the command was not successful */
1641 /* Note: If part of the inquiry, the name is not stored, and the */
1642 /* inquiry complete callback is called. */
1643
1644 if (hci_status == HCI_SUCCESS) {
1645 /* Copy the name from the data stream into the return structure */
1646 /* Note that even if it is not being returned, it is used as a */
1647 /* temporary buffer. */
1648 p_n1 = (uint8_t*)rem_name.remote_bd_name;
1649 rem_name.length = (evt_len < BD_NAME_LEN) ? evt_len : BD_NAME_LEN;
1650 rem_name.remote_bd_name[rem_name.length] = 0;
1651 rem_name.status = BTM_SUCCESS;
1652 rem_name.hci_status = hci_status;
1653 temp_evt_len = rem_name.length;
1654
1655 while (temp_evt_len > 0) {
1656 *p_n1++ = *bdn++;
1657 temp_evt_len--;
1658 }
1659 rem_name.remote_bd_name[rem_name.length] = 0;
1660 } else {
1661 /* If processing a stand alone remote name then report the error in the
1662 callback */
1663 rem_name.status = BTM_BAD_VALUE_RET;
1664 rem_name.hci_status = hci_status;
1665 rem_name.length = 0;
1666 rem_name.remote_bd_name[0] = 0;
1667 }
1668 /* Reset the remote BAD to zero and call callback if possible */
1669 p_inq->remname_bda = RawAddress::kEmpty;
1670
1671 p_inq->p_remname_cmpl_cb = NULL;
1672 if (p_cb) (p_cb)(&rem_name);
1673 }
1674 }
1675
btm_inq_remote_name_timer_timeout(UNUSED_ATTR void * data)1676 void btm_inq_remote_name_timer_timeout(UNUSED_ATTR void* data) {
1677 btm_inq_rmt_name_failed_cancelled();
1678 }
1679
1680 /*******************************************************************************
1681 *
1682 * Function btm_inq_rmt_name_failed_cancelled
1683 *
1684 * Description This function is if timeout expires or request is cancelled
1685 * while getting remote name. This is done for devices that
1686 * incorrectly do not report operation failure
1687 *
1688 * Returns void
1689 *
1690 ******************************************************************************/
btm_inq_rmt_name_failed_cancelled(void)1691 void btm_inq_rmt_name_failed_cancelled(void) {
1692 BTM_TRACE_ERROR("btm_inq_rmt_name_failed_cancelled() remname_active=%d",
1693 btm_cb.btm_inq_vars.remname_active);
1694
1695 if (btm_cb.btm_inq_vars.remname_active) {
1696 btm_process_remote_name(&btm_cb.btm_inq_vars.remname_bda, NULL, 0,
1697 HCI_ERR_UNSPECIFIED);
1698 }
1699
1700 btm_sec_rmt_name_request_complete(NULL, NULL, HCI_ERR_UNSPECIFIED);
1701 }
1702
1703 /*******************************************************************************
1704 *
1705 * Function BTM_WriteEIR
1706 *
1707 * Description This function is called to write EIR data to controller.
1708 *
1709 * Parameters p_buff - allocated HCI command buffer including extended
1710 * inquriry response
1711 *
1712 * Returns BTM_SUCCESS - if successful
1713 * BTM_MODE_UNSUPPORTED - if local device cannot support it
1714 *
1715 ******************************************************************************/
BTM_WriteEIR(BT_HDR * p_buff)1716 tBTM_STATUS BTM_WriteEIR(BT_HDR* p_buff) {
1717 if (controller_get_interface()->supports_extended_inquiry_response()) {
1718 BTM_TRACE_API("Write Extended Inquiry Response to controller");
1719 btsnd_hcic_write_ext_inquiry_response(p_buff, BTM_EIR_DEFAULT_FEC_REQUIRED);
1720 return BTM_SUCCESS;
1721 } else {
1722 osi_free(p_buff);
1723 return BTM_MODE_UNSUPPORTED;
1724 }
1725 }
1726
1727 /*******************************************************************************
1728 *
1729 * Function btm_convert_uuid_to_eir_service
1730 *
1731 * Description This function is called to get the bit position of UUID.
1732 *
1733 * Parameters uuid16 - UUID 16-bit
1734 *
1735 * Returns BTM EIR service ID if found
1736 * BTM_EIR_MAX_SERVICES - if not found
1737 *
1738 ******************************************************************************/
btm_convert_uuid_to_eir_service(uint16_t uuid16)1739 static uint8_t btm_convert_uuid_to_eir_service(uint16_t uuid16) {
1740 uint8_t xx;
1741
1742 for (xx = 0; xx < BTM_EIR_MAX_SERVICES; xx++) {
1743 if (uuid16 == BTM_EIR_UUID_LKUP_TBL[xx]) {
1744 return xx;
1745 }
1746 }
1747 return BTM_EIR_MAX_SERVICES;
1748 }
1749
1750 /*******************************************************************************
1751 *
1752 * Function BTM_HasEirService
1753 *
1754 * Description This function is called to know if UUID in bit map of UUID.
1755 *
1756 * Parameters p_eir_uuid - bit map of UUID list
1757 * uuid16 - UUID 16-bit
1758 *
1759 * Returns true - if found
1760 * false - if not found
1761 *
1762 ******************************************************************************/
BTM_HasEirService(const uint32_t * p_eir_uuid,uint16_t uuid16)1763 bool BTM_HasEirService(const uint32_t* p_eir_uuid, uint16_t uuid16) {
1764 uint8_t service_id;
1765
1766 service_id = btm_convert_uuid_to_eir_service(uuid16);
1767 if (service_id < BTM_EIR_MAX_SERVICES)
1768 return (BTM_EIR_HAS_SERVICE(p_eir_uuid, service_id));
1769 else
1770 return (false);
1771 }
1772
1773 /*******************************************************************************
1774 *
1775 * Function BTM_HasInquiryEirService
1776 *
1777 * Description This function is called to know if UUID in bit map of UUID
1778 * list.
1779 *
1780 * Parameters p_results - inquiry results
1781 * uuid16 - UUID 16-bit
1782 *
1783 * Returns BTM_EIR_FOUND - if found
1784 * BTM_EIR_NOT_FOUND - if not found and it is complete list
1785 * BTM_EIR_UNKNOWN - if not found and it is not complete list
1786 *
1787 ******************************************************************************/
BTM_HasInquiryEirService(tBTM_INQ_RESULTS * p_results,uint16_t uuid16)1788 tBTM_EIR_SEARCH_RESULT BTM_HasInquiryEirService(tBTM_INQ_RESULTS* p_results,
1789 uint16_t uuid16) {
1790 if (BTM_HasEirService(p_results->eir_uuid, uuid16)) {
1791 return BTM_EIR_FOUND;
1792 } else if (p_results->eir_complete_list) {
1793 return BTM_EIR_NOT_FOUND;
1794 } else
1795 return BTM_EIR_UNKNOWN;
1796 }
1797
1798 /*******************************************************************************
1799 *
1800 * Function BTM_AddEirService
1801 *
1802 * Description This function is called to add a service in bit map of UUID
1803 * list.
1804 *
1805 * Parameters p_eir_uuid - bit mask of UUID list for EIR
1806 * uuid16 - UUID 16-bit
1807 *
1808 * Returns None
1809 *
1810 ******************************************************************************/
BTM_AddEirService(uint32_t * p_eir_uuid,uint16_t uuid16)1811 void BTM_AddEirService(uint32_t* p_eir_uuid, uint16_t uuid16) {
1812 uint8_t service_id;
1813
1814 service_id = btm_convert_uuid_to_eir_service(uuid16);
1815 if (service_id < BTM_EIR_MAX_SERVICES)
1816 BTM_EIR_SET_SERVICE(p_eir_uuid, service_id);
1817 }
1818
1819 /*******************************************************************************
1820 *
1821 * Function BTM_RemoveEirService
1822 *
1823 * Description This function is called to remove a service in bit map of
1824 * UUID list.
1825 *
1826 * Parameters p_eir_uuid - bit mask of UUID list for EIR
1827 * uuid16 - UUID 16-bit
1828 *
1829 * Returns None
1830 *
1831 ******************************************************************************/
BTM_RemoveEirService(uint32_t * p_eir_uuid,uint16_t uuid16)1832 void BTM_RemoveEirService(uint32_t* p_eir_uuid, uint16_t uuid16) {
1833 uint8_t service_id;
1834
1835 service_id = btm_convert_uuid_to_eir_service(uuid16);
1836 if (service_id < BTM_EIR_MAX_SERVICES)
1837 BTM_EIR_CLR_SERVICE(p_eir_uuid, service_id);
1838 }
1839
1840 /*******************************************************************************
1841 *
1842 * Function BTM_GetEirSupportedServices
1843 *
1844 * Description This function is called to get UUID list from bit map of
1845 * UUID list.
1846 *
1847 * Parameters p_eir_uuid - bit mask of UUID list for EIR
1848 * p - reference of current pointer of EIR
1849 * max_num_uuid16 - max number of UUID can be written in EIR
1850 * num_uuid16 - number of UUID have been written in EIR
1851 *
1852 * Returns HCI_EIR_MORE_16BITS_UUID_TYPE, if it has more than max
1853 * HCI_EIR_COMPLETE_16BITS_UUID_TYPE, otherwise
1854 *
1855 ******************************************************************************/
BTM_GetEirSupportedServices(uint32_t * p_eir_uuid,uint8_t ** p,uint8_t max_num_uuid16,uint8_t * p_num_uuid16)1856 uint8_t BTM_GetEirSupportedServices(uint32_t* p_eir_uuid, uint8_t** p,
1857 uint8_t max_num_uuid16,
1858 uint8_t* p_num_uuid16) {
1859 uint8_t service_index;
1860
1861 *p_num_uuid16 = 0;
1862
1863 for (service_index = 0; service_index < BTM_EIR_MAX_SERVICES;
1864 service_index++) {
1865 if (BTM_EIR_HAS_SERVICE(p_eir_uuid, service_index)) {
1866 if (*p_num_uuid16 < max_num_uuid16) {
1867 UINT16_TO_STREAM(*p, BTM_EIR_UUID_LKUP_TBL[service_index]);
1868 (*p_num_uuid16)++;
1869 }
1870 /* if max number of UUIDs are stored and found one more */
1871 else {
1872 return HCI_EIR_MORE_16BITS_UUID_TYPE;
1873 }
1874 }
1875 }
1876 return HCI_EIR_COMPLETE_16BITS_UUID_TYPE;
1877 }
1878
1879 /*******************************************************************************
1880 *
1881 * Function BTM_GetEirUuidList
1882 *
1883 * Description This function parses EIR and returns UUID list.
1884 *
1885 * Parameters p_eir - EIR
1886 * eir_len - EIR len
1887 * uuid_size - Uuid::kNumBytes16, Uuid::kNumBytes32,
1888 * Uuid::kNumBytes128
1889 * p_num_uuid - return number of UUID in found list
1890 * p_uuid_list - return UUID list
1891 * max_num_uuid - maximum number of UUID to be returned
1892 *
1893 * Returns 0 - if not found
1894 * HCI_EIR_COMPLETE_16BITS_UUID_TYPE
1895 * HCI_EIR_MORE_16BITS_UUID_TYPE
1896 * HCI_EIR_COMPLETE_32BITS_UUID_TYPE
1897 * HCI_EIR_MORE_32BITS_UUID_TYPE
1898 * HCI_EIR_COMPLETE_128BITS_UUID_TYPE
1899 * HCI_EIR_MORE_128BITS_UUID_TYPE
1900 *
1901 ******************************************************************************/
BTM_GetEirUuidList(const uint8_t * p_eir,size_t eir_len,uint8_t uuid_size,uint8_t * p_num_uuid,uint8_t * p_uuid_list,uint8_t max_num_uuid)1902 uint8_t BTM_GetEirUuidList(const uint8_t* p_eir, size_t eir_len,
1903 uint8_t uuid_size, uint8_t* p_num_uuid,
1904 uint8_t* p_uuid_list, uint8_t max_num_uuid) {
1905 const uint8_t* p_uuid_data;
1906 uint8_t type;
1907 uint8_t yy, xx;
1908 uint16_t* p_uuid16 = (uint16_t*)p_uuid_list;
1909 uint32_t* p_uuid32 = (uint32_t*)p_uuid_list;
1910 char buff[Uuid::kNumBytes128 * 2 + 1];
1911
1912 p_uuid_data =
1913 btm_eir_get_uuid_list(p_eir, eir_len, uuid_size, p_num_uuid, &type);
1914 if (p_uuid_data == NULL) {
1915 return 0x00;
1916 }
1917
1918 if (*p_num_uuid > max_num_uuid) {
1919 BTM_TRACE_WARNING("%s: number of uuid in EIR = %d, size of uuid list = %d",
1920 __func__, *p_num_uuid, max_num_uuid);
1921 *p_num_uuid = max_num_uuid;
1922 }
1923
1924 BTM_TRACE_DEBUG("%s: type = %02X, number of uuid = %d", __func__, type,
1925 *p_num_uuid);
1926
1927 if (uuid_size == Uuid::kNumBytes16) {
1928 for (yy = 0; yy < *p_num_uuid; yy++) {
1929 STREAM_TO_UINT16(*(p_uuid16 + yy), p_uuid_data);
1930 BTM_TRACE_DEBUG(" 0x%04X", *(p_uuid16 + yy));
1931 }
1932 } else if (uuid_size == Uuid::kNumBytes32) {
1933 for (yy = 0; yy < *p_num_uuid; yy++) {
1934 STREAM_TO_UINT32(*(p_uuid32 + yy), p_uuid_data);
1935 BTM_TRACE_DEBUG(" 0x%08X", *(p_uuid32 + yy));
1936 }
1937 } else if (uuid_size == Uuid::kNumBytes128) {
1938 for (yy = 0; yy < *p_num_uuid; yy++) {
1939 STREAM_TO_ARRAY16(p_uuid_list + yy * Uuid::kNumBytes128, p_uuid_data);
1940 for (xx = 0; xx < Uuid::kNumBytes128; xx++)
1941 snprintf(buff + xx * 2, sizeof(buff) - xx * 2, "%02X",
1942 *(p_uuid_list + yy * Uuid::kNumBytes128 + xx));
1943 BTM_TRACE_DEBUG(" 0x%s", buff);
1944 }
1945 }
1946
1947 return type;
1948 }
1949
1950 /*******************************************************************************
1951 *
1952 * Function btm_eir_get_uuid_list
1953 *
1954 * Description This function searches UUID list in EIR.
1955 *
1956 * Parameters p_eir - address of EIR
1957 * eir_len - EIR length
1958 * uuid_size - size of UUID to find
1959 * p_num_uuid - number of UUIDs found
1960 * p_uuid_list_type - EIR data type
1961 *
1962 * Returns NULL - if UUID list with uuid_size is not found
1963 * beginning of UUID list in EIR - otherwise
1964 *
1965 ******************************************************************************/
btm_eir_get_uuid_list(const uint8_t * p_eir,size_t eir_len,uint8_t uuid_size,uint8_t * p_num_uuid,uint8_t * p_uuid_list_type)1966 static const uint8_t* btm_eir_get_uuid_list(const uint8_t* p_eir,
1967 size_t eir_len, uint8_t uuid_size,
1968 uint8_t* p_num_uuid,
1969 uint8_t* p_uuid_list_type) {
1970 const uint8_t* p_uuid_data;
1971 uint8_t complete_type, more_type;
1972 uint8_t uuid_len;
1973
1974 switch (uuid_size) {
1975 case Uuid::kNumBytes16:
1976 complete_type = HCI_EIR_COMPLETE_16BITS_UUID_TYPE;
1977 more_type = HCI_EIR_MORE_16BITS_UUID_TYPE;
1978 break;
1979 case Uuid::kNumBytes32:
1980 complete_type = HCI_EIR_COMPLETE_32BITS_UUID_TYPE;
1981 more_type = HCI_EIR_MORE_32BITS_UUID_TYPE;
1982 break;
1983 case Uuid::kNumBytes128:
1984 complete_type = HCI_EIR_COMPLETE_128BITS_UUID_TYPE;
1985 more_type = HCI_EIR_MORE_128BITS_UUID_TYPE;
1986 break;
1987 default:
1988 *p_num_uuid = 0;
1989 return NULL;
1990 break;
1991 }
1992
1993 p_uuid_data = AdvertiseDataParser::GetFieldByType(p_eir, eir_len,
1994 complete_type, &uuid_len);
1995 if (p_uuid_data == NULL) {
1996 p_uuid_data = AdvertiseDataParser::GetFieldByType(p_eir, eir_len, more_type,
1997 &uuid_len);
1998 *p_uuid_list_type = more_type;
1999 } else {
2000 *p_uuid_list_type = complete_type;
2001 }
2002
2003 *p_num_uuid = uuid_len / uuid_size;
2004 return p_uuid_data;
2005 }
2006
2007 /*******************************************************************************
2008 *
2009 * Function btm_convert_uuid_to_uuid16
2010 *
2011 * Description This function converts UUID to UUID 16-bit.
2012 *
2013 * Parameters p_uuid - address of UUID
2014 * uuid_size - size of UUID
2015 *
2016 * Returns 0 - if UUID cannot be converted to UUID 16-bit
2017 * UUID 16-bit - otherwise
2018 *
2019 ******************************************************************************/
btm_convert_uuid_to_uuid16(const uint8_t * p_uuid,uint8_t uuid_size)2020 static uint16_t btm_convert_uuid_to_uuid16(const uint8_t* p_uuid,
2021 uint8_t uuid_size) {
2022 static const uint8_t base_uuid[Uuid::kNumBytes128] = {
2023 0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80,
2024 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
2025 uint16_t uuid16 = 0;
2026 uint32_t uuid32;
2027 bool is_base_uuid;
2028 uint8_t xx;
2029
2030 switch (uuid_size) {
2031 case Uuid::kNumBytes16:
2032 STREAM_TO_UINT16(uuid16, p_uuid);
2033 break;
2034 case Uuid::kNumBytes32:
2035 STREAM_TO_UINT32(uuid32, p_uuid);
2036 if (uuid32 < 0x10000) uuid16 = (uint16_t)uuid32;
2037 break;
2038 case Uuid::kNumBytes128:
2039 /* See if we can compress the UUID down to 16 or 32bit UUIDs */
2040 is_base_uuid = true;
2041 for (xx = 0; xx < Uuid::kNumBytes128 - 4; xx++) {
2042 if (p_uuid[xx] != base_uuid[xx]) {
2043 is_base_uuid = false;
2044 break;
2045 }
2046 }
2047 if (is_base_uuid) {
2048 if ((p_uuid[Uuid::kNumBytes128 - 1] == 0) &&
2049 (p_uuid[Uuid::kNumBytes128 - 2] == 0)) {
2050 p_uuid += (Uuid::kNumBytes128 - 4);
2051 STREAM_TO_UINT16(uuid16, p_uuid);
2052 }
2053 }
2054 break;
2055 default:
2056 BTM_TRACE_WARNING("btm_convert_uuid_to_uuid16 invalid uuid size");
2057 break;
2058 }
2059
2060 return (uuid16);
2061 }
2062
2063 /*******************************************************************************
2064 *
2065 * Function btm_set_eir_uuid
2066 *
2067 * Description This function is called to store received UUID into inquiry
2068 * result.
2069 *
2070 * Parameters p_eir - pointer of EIR significant part
2071 * p_results - pointer of inquiry result
2072 *
2073 * Returns None
2074 *
2075 ******************************************************************************/
btm_set_eir_uuid(const uint8_t * p_eir,tBTM_INQ_RESULTS * p_results)2076 void btm_set_eir_uuid(const uint8_t* p_eir, tBTM_INQ_RESULTS* p_results) {
2077 const uint8_t* p_uuid_data;
2078 uint8_t num_uuid;
2079 uint16_t uuid16;
2080 uint8_t yy;
2081 uint8_t type = HCI_EIR_MORE_16BITS_UUID_TYPE;
2082
2083 p_uuid_data = btm_eir_get_uuid_list(p_eir, HCI_EXT_INQ_RESPONSE_LEN,
2084 Uuid::kNumBytes16, &num_uuid, &type);
2085
2086 if (type == HCI_EIR_COMPLETE_16BITS_UUID_TYPE) {
2087 p_results->eir_complete_list = true;
2088 } else {
2089 p_results->eir_complete_list = false;
2090 }
2091
2092 BTM_TRACE_API("btm_set_eir_uuid eir_complete_list=0x%02X",
2093 p_results->eir_complete_list);
2094
2095 if (p_uuid_data) {
2096 for (yy = 0; yy < num_uuid; yy++) {
2097 STREAM_TO_UINT16(uuid16, p_uuid_data);
2098 BTM_AddEirService(p_results->eir_uuid, uuid16);
2099 }
2100 }
2101
2102 p_uuid_data = btm_eir_get_uuid_list(p_eir, HCI_EXT_INQ_RESPONSE_LEN,
2103 Uuid::kNumBytes32, &num_uuid, &type);
2104 if (p_uuid_data) {
2105 for (yy = 0; yy < num_uuid; yy++) {
2106 uuid16 = btm_convert_uuid_to_uuid16(p_uuid_data, Uuid::kNumBytes32);
2107 p_uuid_data += Uuid::kNumBytes32;
2108 if (uuid16) BTM_AddEirService(p_results->eir_uuid, uuid16);
2109 }
2110 }
2111
2112 p_uuid_data = btm_eir_get_uuid_list(p_eir, HCI_EXT_INQ_RESPONSE_LEN,
2113 Uuid::kNumBytes128, &num_uuid, &type);
2114 if (p_uuid_data) {
2115 for (yy = 0; yy < num_uuid; yy++) {
2116 uuid16 = btm_convert_uuid_to_uuid16(p_uuid_data, Uuid::kNumBytes128);
2117 p_uuid_data += Uuid::kNumBytes128;
2118 if (uuid16) BTM_AddEirService(p_results->eir_uuid, uuid16);
2119 }
2120 }
2121 }
2122