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