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