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