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