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