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