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