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