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