• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright 1999-2014 Broadcom Corporation
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 
19 /******************************************************************************
20  *
21  *  This file contains functions that handle inquiries. These include
22  *  setting discoverable mode, controlling the mode of the Baseband, and
23  *  maintaining a small database of inquiry responses, with API for people
24  *  to browse it.
25  *
26  ******************************************************************************/
27 
28 #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 
130 /*******************************************************************************
131  *
132  * Function         BTM_SetDiscoverability
133  *
134  * Description      This function is called to set the device into or out of
135  *                  discoverable mode. Discoverable mode means inquiry
136  *                  scans are enabled.  If a value of '0' is entered for window
137  *                  or interval, the default values are used.
138  *
139  * Returns          BTM_SUCCESS if successful
140  *                  BTM_BUSY if a setting of the filter is already in progress
141  *                  BTM_NO_RESOURCES if couldn't get a memory pool buffer
142  *                  BTM_ILLEGAL_VALUE if a bad parameter was detected
143  *                  BTM_WRONG_MODE if the device is not up.
144  *
145  ******************************************************************************/
BTM_SetDiscoverability(uint16_t inq_mode,uint16_t window,uint16_t interval)146 tBTM_STATUS BTM_SetDiscoverability(uint16_t inq_mode, uint16_t window,
147                                    uint16_t interval) {
148   if (bluetooth::shim::is_gd_shim_enabled()) {
149     return bluetooth::shim::BTM_SetDiscoverability(inq_mode, window, interval);
150   }
151 
152   uint8_t scan_mode = 0;
153   uint16_t service_class;
154   uint8_t* p_cod;
155   uint8_t major, minor;
156   DEV_CLASS cod;
157   LAP temp_lap[2];
158   bool is_limited;
159   bool cod_limited;
160 
161   BTM_TRACE_API("BTM_SetDiscoverability");
162   if (controller_get_interface()->supports_ble()) {
163     if (btm_ble_set_discoverability((uint16_t)(inq_mode)) == BTM_SUCCESS) {
164       btm_cb.btm_inq_vars.discoverable_mode &= (~BTM_BLE_DISCOVERABLE_MASK);
165       btm_cb.btm_inq_vars.discoverable_mode |=
166           (inq_mode & BTM_BLE_DISCOVERABLE_MASK);
167     }
168   }
169   inq_mode &= ~BTM_BLE_DISCOVERABLE_MASK;
170 
171   /*** Check mode parameter ***/
172   if (inq_mode > BTM_MAX_DISCOVERABLE) return (BTM_ILLEGAL_VALUE);
173 
174   /* Make sure the controller is active */
175   if (!controller_get_interface()->get_is_ready()) return (BTM_DEV_RESET);
176 
177   /* If the window and/or interval is '0', set to default values */
178   if (!window) window = BTM_DEFAULT_DISC_WINDOW;
179 
180   if (!interval) interval = BTM_DEFAULT_DISC_INTERVAL;
181 
182   BTM_TRACE_API(
183       "BTM_SetDiscoverability: mode %d [NonDisc-0, Lim-1, Gen-2], window "
184       "0x%04x, interval 0x%04x",
185       inq_mode, window, interval);
186 
187   /*** Check for valid window and interval parameters ***/
188   /*** Only check window and duration if mode is connectable ***/
189   if (inq_mode != BTM_NON_DISCOVERABLE) {
190     /* window must be less than or equal to interval */
191     if (window < HCI_MIN_INQUIRYSCAN_WINDOW ||
192         window > HCI_MAX_INQUIRYSCAN_WINDOW ||
193         interval < HCI_MIN_INQUIRYSCAN_INTERVAL ||
194         interval > HCI_MAX_INQUIRYSCAN_INTERVAL || window > interval) {
195       return (BTM_ILLEGAL_VALUE);
196     }
197   }
198 
199   /* Set the IAC if needed */
200   if (inq_mode != BTM_NON_DISCOVERABLE) {
201     if (inq_mode & BTM_LIMITED_DISCOVERABLE) {
202       /* Use the GIAC and LIAC codes for limited discoverable mode */
203       memcpy(temp_lap[0], limited_inq_lap, LAP_LEN);
204       memcpy(temp_lap[1], general_inq_lap, LAP_LEN);
205 
206       btsnd_hcic_write_cur_iac_lap(2, (LAP * const)temp_lap);
207     } else {
208       btsnd_hcic_write_cur_iac_lap(1, (LAP * const) & general_inq_lap);
209     }
210 
211     scan_mode |= HCI_INQUIRY_SCAN_ENABLED;
212   }
213 
214   /* Send down the inquiry scan window and period if changed */
215   if ((window != btm_cb.btm_inq_vars.inq_scan_window) ||
216       (interval != btm_cb.btm_inq_vars.inq_scan_period)) {
217     btsnd_hcic_write_inqscan_cfg(interval, window);
218     btm_cb.btm_inq_vars.inq_scan_window = window;
219     btm_cb.btm_inq_vars.inq_scan_period = interval;
220   }
221 
222   if (btm_cb.btm_inq_vars.connectable_mode & BTM_CONNECTABLE_MASK)
223     scan_mode |= HCI_PAGE_SCAN_ENABLED;
224 
225   btsnd_hcic_write_scan_enable(scan_mode);
226   btm_cb.btm_inq_vars.discoverable_mode &= (~BTM_DISCOVERABLE_MASK);
227   btm_cb.btm_inq_vars.discoverable_mode |= inq_mode;
228 
229   /* Change the service class bit if mode has changed */
230   p_cod = BTM_ReadDeviceClass();
231   BTM_COD_SERVICE_CLASS(service_class, p_cod);
232   is_limited = (inq_mode & BTM_LIMITED_DISCOVERABLE) ? true : false;
233   cod_limited = (service_class & BTM_COD_SERVICE_LMTD_DISCOVER) ? true : false;
234   if (is_limited ^ cod_limited) {
235     BTM_COD_MINOR_CLASS(minor, p_cod);
236     BTM_COD_MAJOR_CLASS(major, p_cod);
237     if (is_limited)
238       service_class |= BTM_COD_SERVICE_LMTD_DISCOVER;
239     else
240       service_class &= ~BTM_COD_SERVICE_LMTD_DISCOVER;
241 
242     FIELDS_TO_COD(cod, minor, major, service_class);
243     (void)BTM_SetDeviceClass(cod);
244   }
245 
246   return (BTM_SUCCESS);
247 }
248 
249 /*******************************************************************************
250  *
251  * Function         BTM_SetInquiryScanType
252  *
253  * Description      This function is called to set the iquiry scan-type to
254  *                  standard or interlaced.
255  *
256  * Returns          BTM_SUCCESS if successful
257  *                  BTM_MODE_UNSUPPORTED if not a 1.2 device
258  *                  BTM_WRONG_MODE if the device is not up.
259  *
260  ******************************************************************************/
BTM_SetInquiryScanType(uint16_t scan_type)261 tBTM_STATUS BTM_SetInquiryScanType(uint16_t scan_type) {
262   if (bluetooth::shim::is_gd_shim_enabled()) {
263     return bluetooth::shim::BTM_SetInquiryScanType(scan_type);
264   }
265 
266   BTM_TRACE_API("BTM_SetInquiryScanType");
267   if (scan_type != BTM_SCAN_TYPE_STANDARD &&
268       scan_type != BTM_SCAN_TYPE_INTERLACED)
269     return (BTM_ILLEGAL_VALUE);
270 
271   /* whatever app wants if device is not 1.2 scan type should be STANDARD */
272   if (!controller_get_interface()->supports_interlaced_inquiry_scan())
273     return (BTM_MODE_UNSUPPORTED);
274 
275   /* Check for scan type if configuration has been changed */
276   if (scan_type != btm_cb.btm_inq_vars.inq_scan_type) {
277     if (BTM_IsDeviceUp()) {
278       btsnd_hcic_write_inqscan_type((uint8_t)scan_type);
279       btm_cb.btm_inq_vars.inq_scan_type = scan_type;
280     } else
281       return (BTM_WRONG_MODE);
282   }
283   return (BTM_SUCCESS);
284 }
285 
286 /*******************************************************************************
287  *
288  * Function         BTM_SetPageScanType
289  *
290  * Description      This function is called to set the page scan-type to
291  *                  standard or interlaced.
292  *
293  * Returns          BTM_SUCCESS if successful
294  *                  BTM_MODE_UNSUPPORTED if not a 1.2 device
295  *                  BTM_WRONG_MODE if the device is not up.
296  *
297  ******************************************************************************/
BTM_SetPageScanType(uint16_t scan_type)298 tBTM_STATUS BTM_SetPageScanType(uint16_t scan_type) {
299   if (bluetooth::shim::is_gd_shim_enabled()) {
300     return bluetooth::shim::BTM_SetPageScanType(scan_type);
301   }
302 
303   BTM_TRACE_API("BTM_SetPageScanType");
304   if (scan_type != BTM_SCAN_TYPE_STANDARD &&
305       scan_type != BTM_SCAN_TYPE_INTERLACED)
306     return (BTM_ILLEGAL_VALUE);
307 
308   /* whatever app wants if device is not 1.2 scan type should be STANDARD */
309   if (!controller_get_interface()->supports_interlaced_inquiry_scan())
310     return (BTM_MODE_UNSUPPORTED);
311 
312   /* Check for scan type if configuration has been changed */
313   if (scan_type != btm_cb.btm_inq_vars.page_scan_type) {
314     if (BTM_IsDeviceUp()) {
315       btsnd_hcic_write_pagescan_type((uint8_t)scan_type);
316       btm_cb.btm_inq_vars.page_scan_type = scan_type;
317     } else
318       return (BTM_WRONG_MODE);
319   }
320   return (BTM_SUCCESS);
321 }
322 
323 /*******************************************************************************
324  *
325  * Function         BTM_SetInquiryMode
326  *
327  * Description      This function is called to set standard or with RSSI
328  *                  mode of the inquiry for local device.
329  *
330  * Output Params:   mode - standard, with RSSI, extended
331  *
332  * Returns          BTM_SUCCESS if successful
333  *                  BTM_NO_RESOURCES if couldn't get a memory pool buffer
334  *                  BTM_ILLEGAL_VALUE if a bad parameter was detected
335  *                  BTM_WRONG_MODE if the device is not up.
336  *
337  ******************************************************************************/
BTM_SetInquiryMode(uint8_t mode)338 tBTM_STATUS BTM_SetInquiryMode(uint8_t mode) {
339   if (bluetooth::shim::is_gd_shim_enabled()) {
340     return bluetooth::shim::BTM_SetInquiryMode(mode);
341   }
342 
343   const controller_t* controller = controller_get_interface();
344   BTM_TRACE_API("BTM_SetInquiryMode");
345   if (mode == BTM_INQ_RESULT_STANDARD) {
346     /* mandatory mode */
347   } else if (mode == BTM_INQ_RESULT_WITH_RSSI) {
348     if (!controller->supports_rssi_with_inquiry_results())
349       return (BTM_MODE_UNSUPPORTED);
350   } else if (mode == BTM_INQ_RESULT_EXTENDED) {
351     if (!controller->supports_extended_inquiry_response())
352       return (BTM_MODE_UNSUPPORTED);
353   } else
354     return (BTM_ILLEGAL_VALUE);
355 
356   if (!BTM_IsDeviceUp()) return (BTM_WRONG_MODE);
357 
358   btsnd_hcic_write_inquiry_mode(mode);
359 
360   return (BTM_SUCCESS);
361 }
362 
363 /*******************************************************************************
364  *
365  * Function         BTM_ReadDiscoverability
366  *
367  * Description      This function is called to read the current discoverability
368  *                  mode of the device.
369  *
370  * Output Params:   p_window - current inquiry scan duration
371  *                  p_interval - current inquiry scan interval
372  *
373  * Returns          BTM_NON_DISCOVERABLE, BTM_LIMITED_DISCOVERABLE, or
374  *                  BTM_GENERAL_DISCOVERABLE
375  *
376  ******************************************************************************/
BTM_ReadDiscoverability(uint16_t * p_window,uint16_t * p_interval)377 uint16_t BTM_ReadDiscoverability(uint16_t* p_window, uint16_t* p_interval) {
378   if (bluetooth::shim::is_gd_shim_enabled()) {
379     return bluetooth::shim::BTM_ReadDiscoverability(p_window, p_interval);
380   }
381 
382   BTM_TRACE_API("BTM_ReadDiscoverability");
383   if (p_window) *p_window = btm_cb.btm_inq_vars.inq_scan_window;
384 
385   if (p_interval) *p_interval = btm_cb.btm_inq_vars.inq_scan_period;
386 
387   return (btm_cb.btm_inq_vars.discoverable_mode);
388 }
389 
390 /*******************************************************************************
391  *
392  * Function         BTM_CancelPeriodicInquiry
393  *
394  * Description      This function cancels a periodic inquiry
395  *
396  * Returns
397  *                  BTM_NO_RESOURCES if could not allocate a message buffer
398  *                  BTM_SUCCESS - if cancelling the periodic inquiry
399  *                  BTM_WRONG_MODE if the device is not up.
400  *
401  ******************************************************************************/
BTM_CancelPeriodicInquiry(void)402 tBTM_STATUS BTM_CancelPeriodicInquiry(void) {
403   if (bluetooth::shim::is_gd_shim_enabled()) {
404     return bluetooth::shim::BTM_CancelPeriodicInquiry();
405   }
406 
407   tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
408   tBTM_STATUS status = BTM_SUCCESS;
409   BTM_TRACE_API("BTM_CancelPeriodicInquiry called");
410 
411   /*** Make sure the device is ready ***/
412   if (!BTM_IsDeviceUp()) return (BTM_WRONG_MODE);
413 
414   /* Only cancel if one is active */
415   if (btm_cb.btm_inq_vars.inq_active & BTM_PERIODIC_INQUIRY_ACTIVE) {
416     btm_cb.btm_inq_vars.inq_active = BTM_INQUIRY_INACTIVE;
417     btm_cb.btm_inq_vars.p_inq_results_cb = NULL;
418 
419     btsnd_hcic_exit_per_inq();
420 
421     /* If the event filter is in progress, mark it so that the processing of the
422        return
423        event will be ignored */
424     if (p_inq->inqfilt_active) p_inq->pending_filt_complete_event++;
425 
426     p_inq->inqfilt_active = false;
427     p_inq->inq_counter++;
428   }
429 
430   return (status);
431 }
432 
433 /*******************************************************************************
434  *
435  * Function         BTM_SetConnectability
436  *
437  * Description      This function is called to set the device into or out of
438  *                  connectable mode. Discoverable mode means page scans are
439  *                  enabled.
440  *
441  * Returns          BTM_SUCCESS if successful
442  *                  BTM_ILLEGAL_VALUE if a bad parameter is detected
443  *                  BTM_NO_RESOURCES if could not allocate a message buffer
444  *                  BTM_WRONG_MODE if the device is not up.
445  *
446  ******************************************************************************/
BTM_SetConnectability(uint16_t page_mode,uint16_t window,uint16_t interval)447 tBTM_STATUS BTM_SetConnectability(uint16_t page_mode, uint16_t window,
448                                   uint16_t interval) {
449   if (bluetooth::shim::is_gd_shim_enabled()) {
450     return bluetooth::shim::BTM_SetConnectability(page_mode, window, interval);
451   }
452 
453   uint8_t scan_mode = 0;
454   tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
455 
456   BTM_TRACE_API("BTM_SetConnectability");
457 
458   if (controller_get_interface()->supports_ble()) {
459     if (btm_ble_set_connectability(page_mode) != BTM_SUCCESS) {
460       return BTM_NO_RESOURCES;
461     }
462     p_inq->connectable_mode &= (~BTM_BLE_CONNECTABLE_MASK);
463     p_inq->connectable_mode |= (page_mode & BTM_BLE_CONNECTABLE_MASK);
464   }
465   page_mode &= ~BTM_BLE_CONNECTABLE_MASK;
466 
467   /*** Check mode parameter ***/
468   if (page_mode != BTM_NON_CONNECTABLE && page_mode != BTM_CONNECTABLE)
469     return (BTM_ILLEGAL_VALUE);
470 
471   /* Make sure the controller is active */
472   if (!controller_get_interface()->get_is_ready()) return (BTM_DEV_RESET);
473 
474   /* If the window and/or interval is '0', set to default values */
475   if (!window) window = BTM_DEFAULT_CONN_WINDOW;
476 
477   if (!interval) interval = BTM_DEFAULT_CONN_INTERVAL;
478 
479   BTM_TRACE_API(
480       "BTM_SetConnectability: mode %d [NonConn-0, Conn-1], window 0x%04x, "
481       "interval 0x%04x",
482       page_mode, window, interval);
483 
484   /*** Check for valid window and interval parameters ***/
485   /*** Only check window and duration if mode is connectable ***/
486   if (page_mode == BTM_CONNECTABLE) {
487     /* window must be less than or equal to interval */
488     if (window < HCI_MIN_PAGESCAN_WINDOW || window > HCI_MAX_PAGESCAN_WINDOW ||
489         interval < HCI_MIN_PAGESCAN_INTERVAL ||
490         interval > HCI_MAX_PAGESCAN_INTERVAL || window > interval) {
491       return (BTM_ILLEGAL_VALUE);
492     }
493 
494     scan_mode |= HCI_PAGE_SCAN_ENABLED;
495   }
496 
497   if ((window != p_inq->page_scan_window) ||
498       (interval != p_inq->page_scan_period)) {
499     p_inq->page_scan_window = window;
500     p_inq->page_scan_period = interval;
501     btsnd_hcic_write_pagescan_cfg(interval, window);
502   }
503 
504   /* Keep the inquiry scan as previouosly set */
505   if (p_inq->discoverable_mode & BTM_DISCOVERABLE_MASK)
506     scan_mode |= HCI_INQUIRY_SCAN_ENABLED;
507 
508   btsnd_hcic_write_scan_enable(scan_mode);
509   p_inq->connectable_mode &= (~BTM_CONNECTABLE_MASK);
510   p_inq->connectable_mode |= page_mode;
511   return (BTM_SUCCESS);
512 }
513 
514 /*******************************************************************************
515  *
516  * Function         BTM_ReadConnectability
517  *
518  * Description      This function is called to read the current discoverability
519  *                  mode of the device.
520  * Output Params    p_window - current page scan duration
521  *                  p_interval - current time between page scans
522  *
523  * Returns          BTM_NON_CONNECTABLE or BTM_CONNECTABLE
524  *
525  ******************************************************************************/
BTM_ReadConnectability(uint16_t * p_window,uint16_t * p_interval)526 uint16_t BTM_ReadConnectability(uint16_t* p_window, uint16_t* p_interval) {
527   if (bluetooth::shim::is_gd_shim_enabled()) {
528     return bluetooth::shim::BTM_ReadConnectability(p_window, p_interval);
529   }
530 
531   BTM_TRACE_API("BTM_ReadConnectability");
532   if (p_window) *p_window = btm_cb.btm_inq_vars.page_scan_window;
533 
534   if (p_interval) *p_interval = btm_cb.btm_inq_vars.page_scan_period;
535 
536   return (btm_cb.btm_inq_vars.connectable_mode);
537 }
538 
539 /*******************************************************************************
540  *
541  * Function         BTM_IsInquiryActive
542  *
543  * Description      This function returns a bit mask of the current inquiry
544  *                  state
545  *
546  * Returns          BTM_INQUIRY_INACTIVE if inactive (0)
547  *                  BTM_LIMITED_INQUIRY_ACTIVE if a limted inquiry is active
548  *                  BTM_GENERAL_INQUIRY_ACTIVE if a general inquiry is active
549  *                  BTM_PERIODIC_INQUIRY_ACTIVE if a periodic inquiry is active
550  *
551  ******************************************************************************/
BTM_IsInquiryActive(void)552 uint16_t BTM_IsInquiryActive(void) {
553   if (bluetooth::shim::is_gd_shim_enabled()) {
554     return bluetooth::shim::BTM_IsInquiryActive();
555   }
556 
557   BTM_TRACE_API("BTM_IsInquiryActive");
558 
559   return (btm_cb.btm_inq_vars.inq_active);
560 }
561 
562 /*******************************************************************************
563  *
564  * Function         BTM_CancelInquiry
565  *
566  * Description      This function cancels an inquiry if active
567  *
568  * Returns          BTM_SUCCESS if successful
569  *                  BTM_NO_RESOURCES if could not allocate a message buffer
570  *                  BTM_WRONG_MODE if the device is not up.
571  *
572  ******************************************************************************/
BTM_CancelInquiry(void)573 tBTM_STATUS BTM_CancelInquiry(void) {
574   if (bluetooth::shim::is_gd_shim_enabled()) {
575     return bluetooth::shim::BTM_CancelInquiry();
576   }
577 
578   tBTM_STATUS status = BTM_SUCCESS;
579   tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
580   BTM_TRACE_API("BTM_CancelInquiry called");
581 
582   /*** Make sure the device is ready ***/
583   if (!BTM_IsDeviceUp()) return (BTM_WRONG_MODE);
584 
585   /* Only cancel if not in periodic mode, otherwise the caller should call
586    * BTM_CancelPeriodicMode */
587   if ((p_inq->inq_active & BTM_INQUIRY_ACTIVE_MASK) != 0 &&
588       (!(p_inq->inq_active & BTM_PERIODIC_INQUIRY_ACTIVE))) {
589     p_inq->inq_active = BTM_INQUIRY_INACTIVE;
590     p_inq->state = BTM_INQ_INACTIVE_STATE;
591     p_inq->p_inq_results_cb = NULL; /* Do not notify caller anymore */
592     p_inq->p_inq_cmpl_cb = NULL;    /* Do not notify caller anymore */
593 
594     /* If the event filter is in progress, mark it so that the processing of the
595        return
596         event will be ignored */
597     if (p_inq->inqfilt_active) {
598       p_inq->inqfilt_active = false;
599       p_inq->pending_filt_complete_event++;
600     }
601     /* Initiate the cancel inquiry */
602     else {
603       if ((p_inq->inqparms.mode & BTM_BR_INQUIRY_MASK) != 0) {
604         btsnd_hcic_inq_cancel();
605       }
606       if ((p_inq->inqparms.mode & BTM_BLE_INQUIRY_MASK) != 0)
607         btm_ble_stop_inquiry();
608     }
609 
610     /* Do not send the BUSY_LEVEL event yet. Wait for the cancel_complete event
611      * and then send the BUSY_LEVEL event
612      * btm_acl_update_busy_level (BTM_BLI_INQ_DONE_EVT);
613      */
614 
615     p_inq->inq_counter++;
616     btm_clr_inq_result_flt();
617   }
618 
619   return (status);
620 }
621 
622 /*******************************************************************************
623  *
624  * Function         BTM_StartInquiry
625  *
626  * Description      This function is called to start an inquiry.
627  *
628  * Parameters:      p_inqparms - pointer to the inquiry information
629  *                      mode - GENERAL or LIMITED inquiry, BR/LE bit mask
630  *                             seperately
631  *                      duration - length in 1.28 sec intervals (If '0', the
632  *                                 inquiry is CANCELLED)
633  *                      max_resps - maximum amount of devices to search for
634  *                                  before ending the inquiry
635  *                      filter_cond_type - BTM_CLR_INQUIRY_FILTER,
636  *                                         BTM_FILTER_COND_DEVICE_CLASS, or
637  *                                         BTM_FILTER_COND_BD_ADDR
638  *                      filter_cond - value for the filter (based on
639  *                                                          filter_cond_type)
640  *
641  *                  p_results_cb   - Pointer to the callback routine which gets
642  *                                called upon receipt of an inquiry result. If
643  *                                this field is NULL, the application is not
644  *                                notified.
645  *
646  *                  p_cmpl_cb   - Pointer to the callback routine which gets
647  *                                called upon completion.  If this field is
648  *                                NULL, the application is not notified when
649  *                                completed.
650  * Returns          tBTM_STATUS
651  *                  BTM_CMD_STARTED if successfully initiated
652  *                  BTM_BUSY if already in progress
653  *                  BTM_ILLEGAL_VALUE if parameter(s) are out of range
654  *                  BTM_NO_RESOURCES if could not allocate resources to start
655  *                                   the command
656  *                  BTM_WRONG_MODE if the device is not up.
657  *
658  ******************************************************************************/
BTM_StartInquiry(tBTM_INQ_PARMS * p_inqparms,tBTM_INQ_RESULTS_CB * p_results_cb,tBTM_CMPL_CB * p_cmpl_cb)659 tBTM_STATUS BTM_StartInquiry(tBTM_INQ_PARMS* p_inqparms,
660                              tBTM_INQ_RESULTS_CB* p_results_cb,
661                              tBTM_CMPL_CB* p_cmpl_cb) {
662   tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
663 
664   if (bluetooth::shim::is_gd_shim_enabled()) {
665     return bluetooth::shim::BTM_StartInquiry(p_inqparms, p_results_cb,
666                                              p_cmpl_cb);
667   }
668 
669   BTM_TRACE_API("BTM_StartInquiry: mode: %d, dur: %d, rsps: %d, flt: %d",
670                 p_inqparms->mode, p_inqparms->duration, p_inqparms->max_resps,
671                 p_inqparms->filter_cond_type);
672 
673   /* Only one active inquiry is allowed in this implementation.
674      Also do not allow an inquiry if the inquiry filter is being updated */
675   if (p_inq->inq_active || p_inq->inqfilt_active) {
676     LOG(ERROR) << __func__ << ": BTM_BUSY";
677     return (BTM_BUSY);
678   } else {
679     p_inq->scan_type = INQ_GENERAL;
680   }
681 
682   /*** Make sure the device is ready ***/
683   if (!BTM_IsDeviceUp()) {
684     LOG(ERROR) << __func__ << ": adapter is not up";
685     return BTM_WRONG_MODE;
686   }
687 
688   if ((p_inqparms->mode & BTM_BR_INQUIRY_MASK) != BTM_GENERAL_INQUIRY &&
689       (p_inqparms->mode & BTM_BR_INQUIRY_MASK) != BTM_LIMITED_INQUIRY &&
690       (p_inqparms->mode & BTM_BLE_INQUIRY_MASK) != BTM_BLE_GENERAL_INQUIRY &&
691       (p_inqparms->mode & BTM_BLE_INQUIRY_MASK) != BTM_BLE_LIMITED_INQUIRY) {
692     LOG(ERROR) << __func__ << ": illegal inquiry mode "
693                << std::to_string(p_inqparms->mode);
694     return (BTM_ILLEGAL_VALUE);
695   }
696 
697   /* Save the inquiry parameters to be used upon the completion of
698    * setting/clearing the inquiry filter */
699   p_inq->inqparms = *p_inqparms;
700 
701   /* Initialize the inquiry variables */
702   p_inq->state = BTM_INQ_ACTIVE_STATE;
703   p_inq->p_inq_cmpl_cb = p_cmpl_cb;
704   p_inq->p_inq_results_cb = p_results_cb;
705   p_inq->inq_cmpl_info.num_resp = 0; /* Clear the results counter */
706   p_inq->inq_active = p_inqparms->mode;
707 
708   BTM_TRACE_DEBUG("BTM_StartInquiry: p_inq->inq_active = 0x%02x",
709                   p_inq->inq_active);
710 
711   tBTM_STATUS status = BTM_CMD_STARTED;
712   /* start LE inquiry here if requested */
713   if ((p_inqparms->mode & BTM_BLE_INQUIRY_MASK)) {
714     if (!controller_get_interface()->supports_ble()) {
715       LOG(ERROR) << __func__ << ": trying to do LE scan on a non-LE adapter";
716       p_inq->inqparms.mode &= ~BTM_BLE_INQUIRY_MASK;
717       status = BTM_ILLEGAL_VALUE;
718     } else {
719       /* BLE for now does not support filter condition for inquiry */
720       status = btm_ble_start_inquiry(
721           (uint8_t)(p_inqparms->mode & BTM_BLE_INQUIRY_MASK),
722           p_inqparms->duration);
723       if (status != BTM_CMD_STARTED) {
724         LOG(ERROR) << __func__ << ": Error Starting LE Inquiry";
725         p_inq->inqparms.mode &= ~BTM_BLE_INQUIRY_MASK;
726       }
727     }
728     p_inqparms->mode &= ~BTM_BLE_INQUIRY_MASK;
729 
730     BTM_TRACE_DEBUG("BTM_StartInquiry: mode = %02x", p_inqparms->mode);
731   }
732 
733   /* we're done with this routine if BR/EDR inquiry is not desired. */
734   if ((p_inqparms->mode & BTM_BR_INQUIRY_MASK) == BTM_INQUIRY_NONE) {
735     return status;
736   }
737 
738   /* BR/EDR inquiry portion */
739   /* If a filter is specified, then save it for later and clear the current
740      filter.
741      The setting of the filter is done upon completion of clearing of the
742      previous
743      filter.
744   */
745   switch (p_inqparms->filter_cond_type) {
746     case BTM_CLR_INQUIRY_FILTER:
747       p_inq->state = BTM_INQ_SET_FILT_STATE;
748       break;
749 
750     case BTM_FILTER_COND_DEVICE_CLASS:
751     case BTM_FILTER_COND_BD_ADDR:
752       /* The filter is not being used so simply clear it;
753           the inquiry can start after this operation */
754       p_inq->state = BTM_INQ_CLR_FILT_STATE;
755       p_inqparms->filter_cond_type = BTM_CLR_INQUIRY_FILTER;
756       /* =============>>>> adding LE filtering here ????? */
757       break;
758 
759     default:
760       LOG(ERROR) << __func__ << ": invalid filter condition type "
761                  << std::to_string(p_inqparms->filter_cond_type);
762       return (BTM_ILLEGAL_VALUE);
763     }
764 
765     /* Before beginning the inquiry the current filter must be cleared, so
766      * initiate the command */
767     status = btm_set_inq_event_filter(p_inqparms->filter_cond_type,
768                                       &p_inqparms->filter_cond);
769     if (status != BTM_CMD_STARTED) {
770       LOG(ERROR) << __func__ << ": failed to set inquiry event filter";
771       p_inq->state = BTM_INQ_INACTIVE_STATE;
772     }
773 
774     return (status);
775 }
776 
777 /*******************************************************************************
778  *
779  * Function         BTM_ReadRemoteDeviceName
780  *
781  * Description      This function initiates a remote device HCI command to the
782  *                  controller and calls the callback when the process has
783  *                  completed.
784  *
785  * Input Params:    remote_bda      - device address of name to retrieve
786  *                  p_cb            - callback function called when
787  *                                    BTM_CMD_STARTED is returned.
788  *                                    A pointer to tBTM_REMOTE_DEV_NAME is
789  *                                    passed to the callback.
790  *
791  * Returns
792  *                  BTM_CMD_STARTED is returned if the request was successfully
793  *                                  sent to HCI.
794  *                  BTM_BUSY if already in progress
795  *                  BTM_UNKNOWN_ADDR if device address is bad
796  *                  BTM_NO_RESOURCES if could not allocate resources to start
797  *                                   the command
798  *                  BTM_WRONG_MODE if the device is not up.
799  *
800  ******************************************************************************/
BTM_ReadRemoteDeviceName(const RawAddress & remote_bda,tBTM_CMPL_CB * p_cb,tBT_TRANSPORT transport)801 tBTM_STATUS BTM_ReadRemoteDeviceName(const RawAddress& remote_bda,
802                                      tBTM_CMPL_CB* p_cb,
803                                      tBT_TRANSPORT transport) {
804   if (bluetooth::shim::is_gd_shim_enabled()) {
805     return bluetooth::shim::BTM_ReadRemoteDeviceName(remote_bda, p_cb,
806                                                      transport);
807   }
808 
809   VLOG(1) << __func__ << ": bd addr " << remote_bda;
810   /* Use LE transport when LE is the only available option */
811   if (transport == BT_TRANSPORT_LE) {
812     return btm_ble_read_remote_name(remote_bda, p_cb);
813   }
814   /* Use classic transport for BR/EDR and Dual Mode devices */
815   return btm_initiate_rem_name(remote_bda, BTM_RMT_NAME_EXT,
816                                BTM_EXT_RMT_NAME_TIMEOUT_MS, p_cb);
817 }
818 
819 /*******************************************************************************
820  *
821  * Function         BTM_CancelRemoteDeviceName
822  *
823  * Description      This function initiates the cancel request for the specified
824  *                  remote device.
825  *
826  * Input Params:    None
827  *
828  * Returns
829  *                  BTM_CMD_STARTED is returned if the request was successfully
830  *                                  sent to HCI.
831  *                  BTM_NO_RESOURCES if could not allocate resources to start
832  *                                   the command
833  *                  BTM_WRONG_MODE if there is not an active remote name
834  *                                 request.
835  *
836  ******************************************************************************/
BTM_CancelRemoteDeviceName(void)837 tBTM_STATUS BTM_CancelRemoteDeviceName(void) {
838   tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
839 
840   BTM_TRACE_API("BTM_CancelRemoteDeviceName()");
841 
842   /* Make sure there is not already one in progress */
843   if (p_inq->remname_active) {
844     if (BTM_UseLeLink(p_inq->remname_bda)) {
845       /* Cancel remote name request for LE device, and process remote name
846        * callback. */
847       btm_inq_rmt_name_failed_cancelled();
848     } else
849       btsnd_hcic_rmt_name_req_cancel(p_inq->remname_bda);
850     return (BTM_CMD_STARTED);
851   } else
852     return (BTM_WRONG_MODE);
853 }
854 
855 /*******************************************************************************
856  *
857  * Function         BTM_InqDbRead
858  *
859  * Description      This function looks through the inquiry database for a match
860  *                  based on Bluetooth Device Address. This is the application's
861  *                  interface to get the inquiry details of a specific BD
862  *                  address.
863  *
864  * Returns          pointer to entry, or NULL if not found
865  *
866  ******************************************************************************/
BTM_InqDbRead(const RawAddress & p_bda)867 tBTM_INQ_INFO* BTM_InqDbRead(const RawAddress& p_bda) {
868   VLOG(1) << __func__ << ": bd addr " << p_bda;
869 
870   tINQ_DB_ENT* p_ent = btm_inq_db_find(p_bda);
871   if (!p_ent) return NULL;
872 
873   return &p_ent->inq_info;
874 }
875 
876 /*******************************************************************************
877  *
878  * Function         BTM_InqDbFirst
879  *
880  * Description      This function looks through the inquiry database for the
881  *                  first used entry, and returns that. This is used in
882  *                  conjunction with
883  *                  BTM_InqDbNext by applications as a way to walk through the
884  *                  inquiry database.
885  *
886  * Returns          pointer to first in-use entry, or NULL if DB is empty
887  *
888  ******************************************************************************/
BTM_InqDbFirst(void)889 tBTM_INQ_INFO* BTM_InqDbFirst(void) {
890   uint16_t xx;
891   tINQ_DB_ENT* p_ent = btm_cb.btm_inq_vars.inq_db;
892 
893   for (xx = 0; xx < BTM_INQ_DB_SIZE; xx++, p_ent++) {
894     if (p_ent->in_use) return (&p_ent->inq_info);
895   }
896 
897   /* If here, no used entry found */
898   return ((tBTM_INQ_INFO*)NULL);
899 }
900 
901 /*******************************************************************************
902  *
903  * Function         BTM_InqDbNext
904  *
905  * Description      This function looks through the inquiry database for the
906  *                  next used entry, and returns that.  If the input parameter
907  *                  is NULL, the first entry is returned.
908  *
909  * Returns          pointer to next in-use entry, or NULL if no more found.
910  *
911  ******************************************************************************/
BTM_InqDbNext(tBTM_INQ_INFO * p_cur)912 tBTM_INQ_INFO* BTM_InqDbNext(tBTM_INQ_INFO* p_cur) {
913   tINQ_DB_ENT* p_ent;
914   uint16_t inx;
915 
916   if (p_cur) {
917     p_ent = (tINQ_DB_ENT*)((uint8_t*)p_cur - offsetof(tINQ_DB_ENT, inq_info));
918     inx = (uint16_t)((p_ent - btm_cb.btm_inq_vars.inq_db) + 1);
919 
920     for (p_ent = &btm_cb.btm_inq_vars.inq_db[inx]; inx < BTM_INQ_DB_SIZE;
921          inx++, p_ent++) {
922       if (p_ent->in_use) return (&p_ent->inq_info);
923     }
924 
925     /* If here, more entries found */
926     return ((tBTM_INQ_INFO*)NULL);
927   } else
928     return (BTM_InqDbFirst());
929 }
930 
931 /*******************************************************************************
932  *
933  * Function         BTM_ClearInqDb
934  *
935  * Description      This function is called to clear out a device or all devices
936  *                  from the inquiry database.
937  *
938  * Parameter        p_bda - (input) BD_ADDR ->  Address of device to clear
939  *                                              (NULL clears all entries)
940  *
941  * Returns          BTM_BUSY if an inquiry, get remote name, or event filter
942  *                          is active, otherwise BTM_SUCCESS
943  *
944  ******************************************************************************/
BTM_ClearInqDb(const RawAddress * p_bda)945 tBTM_STATUS BTM_ClearInqDb(const RawAddress* p_bda) {
946   tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
947 
948   /* If an inquiry or remote name is in progress return busy */
949   if (p_inq->inq_active != BTM_INQUIRY_INACTIVE || p_inq->inqfilt_active)
950     return (BTM_BUSY);
951 
952   btm_clr_inq_db(p_bda);
953 
954   return (BTM_SUCCESS);
955 }
956 
957 /*******************************************************************************
958  *******************************************************************************
959  *                                                                            **
960  *                    BTM Internal Inquiry Functions                          **
961  *                                                                            **
962  *******************************************************************************
963  ******************************************************************************/
964 /*******************************************************************************
965  *
966  * Function         btm_inq_db_reset
967  *
968  * Description      This function is called at at reset to clear the inquiry
969  *                  database & pending callback.
970  *
971  * Returns          void
972  *
973  ******************************************************************************/
btm_inq_db_reset(void)974 void btm_inq_db_reset(void) {
975   tBTM_REMOTE_DEV_NAME rem_name;
976   tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
977   uint8_t num_responses;
978   uint8_t temp_inq_active;
979   tBTM_STATUS status;
980 
981   /* If an inquiry or periodic inquiry is active, reset the mode to inactive */
982   if (p_inq->inq_active != BTM_INQUIRY_INACTIVE) {
983     temp_inq_active = p_inq->inq_active; /* Save so state can change BEFORE
984                                                 callback is called */
985     p_inq->inq_active = BTM_INQUIRY_INACTIVE;
986 
987     /* If not a periodic inquiry, the complete callback must be called to notify
988      * caller */
989     if (temp_inq_active == BTM_LIMITED_INQUIRY_ACTIVE ||
990         temp_inq_active == BTM_GENERAL_INQUIRY_ACTIVE) {
991       if (p_inq->p_inq_cmpl_cb) {
992         num_responses = 0;
993         (*p_inq->p_inq_cmpl_cb)(&num_responses);
994       }
995     }
996   }
997 
998   /* Cancel a remote name request if active, and notify the caller (if waiting)
999    */
1000   if (p_inq->remname_active) {
1001     alarm_cancel(p_inq->remote_name_timer);
1002     p_inq->remname_active = false;
1003     p_inq->remname_bda = RawAddress::kEmpty;
1004 
1005     if (p_inq->p_remname_cmpl_cb) {
1006       rem_name.status = BTM_DEV_RESET;
1007 
1008       (*p_inq->p_remname_cmpl_cb)(&rem_name);
1009       p_inq->p_remname_cmpl_cb = NULL;
1010     }
1011   }
1012 
1013   /* Cancel an inquiry filter request if active, and notify the caller (if
1014    * waiting) */
1015   if (p_inq->inqfilt_active) {
1016     p_inq->inqfilt_active = false;
1017 
1018     if (p_inq->p_inqfilter_cmpl_cb) {
1019       status = BTM_DEV_RESET;
1020       (*p_inq->p_inqfilter_cmpl_cb)(&status);
1021     }
1022   }
1023 
1024   p_inq->state = BTM_INQ_INACTIVE_STATE;
1025   p_inq->pending_filt_complete_event = 0;
1026   p_inq->p_inq_results_cb = NULL;
1027   btm_clr_inq_db(NULL); /* Clear out all the entries in the database */
1028   btm_clr_inq_result_flt();
1029 
1030   p_inq->discoverable_mode = BTM_NON_DISCOVERABLE;
1031   p_inq->connectable_mode = BTM_NON_CONNECTABLE;
1032   p_inq->page_scan_type = BTM_SCAN_TYPE_STANDARD;
1033   p_inq->inq_scan_type = BTM_SCAN_TYPE_STANDARD;
1034 
1035   p_inq->discoverable_mode |= BTM_BLE_NON_DISCOVERABLE;
1036   p_inq->connectable_mode |= BTM_BLE_NON_CONNECTABLE;
1037   return;
1038 }
1039 
1040 /*******************************************************************************
1041  *
1042  * Function         btm_inq_db_init
1043  *
1044  * Description      This function is called at startup to initialize the inquiry
1045  *                  database.
1046  *
1047  * Returns          void
1048  *
1049  ******************************************************************************/
btm_inq_db_init(void)1050 void btm_inq_db_init(void) {
1051   alarm_free(btm_cb.btm_inq_vars.remote_name_timer);
1052   btm_cb.btm_inq_vars.remote_name_timer =
1053       alarm_new("btm_inq.remote_name_timer");
1054   btm_cb.btm_inq_vars.no_inc_ssp = BTM_NO_SSP_ON_INQUIRY;
1055 }
1056 
1057 /*******************************************************************************
1058  *
1059  * Function         btm_inq_stop_on_ssp
1060  *
1061  * Description      This function is called on incoming SSP
1062  *
1063  * Returns          void
1064  *
1065  ******************************************************************************/
btm_inq_stop_on_ssp(void)1066 void btm_inq_stop_on_ssp(void) {
1067   uint8_t normal_active =
1068       (BTM_GENERAL_INQUIRY_ACTIVE | BTM_LIMITED_INQUIRY_ACTIVE);
1069 
1070 #if (BTM_INQ_DEBUG == TRUE)
1071   BTM_TRACE_DEBUG(
1072       "btm_inq_stop_on_ssp: no_inc_ssp=%d inq_active:0x%x state:%d "
1073       "inqfilt_active:%d",
1074       btm_cb.btm_inq_vars.no_inc_ssp, btm_cb.btm_inq_vars.inq_active,
1075       btm_cb.btm_inq_vars.state, btm_cb.btm_inq_vars.inqfilt_active);
1076 #endif
1077   if (btm_cb.btm_inq_vars.no_inc_ssp) {
1078     if (btm_cb.btm_inq_vars.state == BTM_INQ_ACTIVE_STATE) {
1079       if (btm_cb.btm_inq_vars.inq_active & BTM_PERIODIC_INQUIRY_ACTIVE) {
1080         BTM_CancelPeriodicInquiry();
1081       } else if (btm_cb.btm_inq_vars.inq_active & normal_active) {
1082         /* can not call BTM_CancelInquiry() here. We need to report inquiry
1083          * complete evt */
1084         btsnd_hcic_inq_cancel();
1085       }
1086     }
1087     /* do not allow inquiry to start */
1088     btm_cb.btm_inq_vars.inq_active |= BTM_SSP_INQUIRY_ACTIVE;
1089   }
1090 }
1091 
1092 /*******************************************************************************
1093  *
1094  * Function         btm_inq_clear_ssp
1095  *
1096  * Description      This function is called when pairing_state becomes idle
1097  *
1098  * Returns          void
1099  *
1100  ******************************************************************************/
btm_inq_clear_ssp(void)1101 void btm_inq_clear_ssp(void) {
1102   btm_cb.btm_inq_vars.inq_active &= ~BTM_SSP_INQUIRY_ACTIVE;
1103 }
1104 
1105 /*******************************************************************************
1106  *
1107  * Function         btm_clr_inq_db
1108  *
1109  * Description      This function is called to clear out a device or all devices
1110  *                  from the inquiry database.
1111  *
1112  * Parameter        p_bda - (input) BD_ADDR ->  Address of device to clear
1113  *                                              (NULL clears all entries)
1114  *
1115  * Returns          void
1116  *
1117  ******************************************************************************/
btm_clr_inq_db(const RawAddress * p_bda)1118 void btm_clr_inq_db(const RawAddress* p_bda) {
1119   tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
1120   tINQ_DB_ENT* p_ent = p_inq->inq_db;
1121   uint16_t xx;
1122 
1123 #if (BTM_INQ_DEBUG == TRUE)
1124   BTM_TRACE_DEBUG("btm_clr_inq_db: inq_active:0x%x state:%d",
1125                   btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state);
1126 #endif
1127   for (xx = 0; xx < BTM_INQ_DB_SIZE; xx++, p_ent++) {
1128     if (p_ent->in_use) {
1129       /* If this is the specified BD_ADDR or clearing all devices */
1130       if (p_bda == NULL || (p_ent->inq_info.results.remote_bd_addr == *p_bda)) {
1131         p_ent->in_use = false;
1132       }
1133     }
1134   }
1135 #if (BTM_INQ_DEBUG == TRUE)
1136   BTM_TRACE_DEBUG("inq_active:0x%x state:%d", btm_cb.btm_inq_vars.inq_active,
1137                   btm_cb.btm_inq_vars.state);
1138 #endif
1139 }
1140 
1141 /*******************************************************************************
1142  *
1143  * Function         btm_clr_inq_result_flt
1144  *
1145  * Description      This function looks through the bdaddr database for a match
1146  *                  based on Bluetooth Device Address
1147  *
1148  * Returns          true if found, else false (new entry)
1149  *
1150  ******************************************************************************/
btm_clr_inq_result_flt(void)1151 void btm_clr_inq_result_flt(void) {
1152   tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
1153 
1154   osi_free_and_reset((void**)&p_inq->p_bd_db);
1155   p_inq->num_bd_entries = 0;
1156   p_inq->max_bd_entries = 0;
1157 }
1158 
1159 /*******************************************************************************
1160  *
1161  * Function         btm_inq_find_bdaddr
1162  *
1163  * Description      This function looks through the bdaddr database for a match
1164  *                  based on Bluetooth Device Address
1165  *
1166  * Returns          true if found, else false (new entry)
1167  *
1168  ******************************************************************************/
btm_inq_find_bdaddr(const RawAddress & p_bda)1169 bool btm_inq_find_bdaddr(const RawAddress& p_bda) {
1170   tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
1171   tINQ_BDADDR* p_db = &p_inq->p_bd_db[0];
1172   uint16_t xx;
1173 
1174   /* Don't bother searching, database doesn't exist or periodic mode */
1175   if ((p_inq->inq_active & BTM_PERIODIC_INQUIRY_ACTIVE) || !p_db)
1176     return (false);
1177 
1178   for (xx = 0; xx < p_inq->num_bd_entries; xx++, p_db++) {
1179     if (p_db->bd_addr == p_bda && p_db->inq_count == p_inq->inq_counter)
1180       return (true);
1181   }
1182 
1183   if (xx < p_inq->max_bd_entries) {
1184     p_db->inq_count = p_inq->inq_counter;
1185     p_db->bd_addr = p_bda;
1186     p_inq->num_bd_entries++;
1187   }
1188 
1189   /* If here, New Entry */
1190   return (false);
1191 }
1192 
1193 /*******************************************************************************
1194  *
1195  * Function         btm_inq_db_find
1196  *
1197  * Description      This function looks through the inquiry database for a match
1198  *                  based on Bluetooth Device Address
1199  *
1200  * Returns          pointer to entry, or NULL if not found
1201  *
1202  ******************************************************************************/
btm_inq_db_find(const RawAddress & p_bda)1203 tINQ_DB_ENT* btm_inq_db_find(const RawAddress& p_bda) {
1204   uint16_t xx;
1205   tINQ_DB_ENT* p_ent = btm_cb.btm_inq_vars.inq_db;
1206 
1207   for (xx = 0; xx < BTM_INQ_DB_SIZE; xx++, p_ent++) {
1208     if (p_ent->in_use && p_ent->inq_info.results.remote_bd_addr == p_bda)
1209       return (p_ent);
1210   }
1211 
1212   /* If here, not found */
1213   return (NULL);
1214 }
1215 
1216 /*******************************************************************************
1217  *
1218  * Function         btm_inq_db_new
1219  *
1220  * Description      This function looks through the inquiry database for an
1221  *                  unused entry. If no entry is free, it allocates the oldest
1222  *                  entry.
1223  *
1224  * Returns          pointer to entry
1225  *
1226  ******************************************************************************/
btm_inq_db_new(const RawAddress & p_bda)1227 tINQ_DB_ENT* btm_inq_db_new(const RawAddress& p_bda) {
1228   uint16_t xx;
1229   tINQ_DB_ENT* p_ent = btm_cb.btm_inq_vars.inq_db;
1230   tINQ_DB_ENT* p_old = btm_cb.btm_inq_vars.inq_db;
1231   uint64_t ot = UINT64_MAX;
1232 
1233   for (xx = 0; xx < BTM_INQ_DB_SIZE; xx++, p_ent++) {
1234     if (!p_ent->in_use) {
1235       memset(p_ent, 0, sizeof(tINQ_DB_ENT));
1236       p_ent->inq_info.results.remote_bd_addr = p_bda;
1237       p_ent->in_use = true;
1238 
1239       return (p_ent);
1240     }
1241 
1242     if (p_ent->time_of_resp < ot) {
1243       p_old = p_ent;
1244       ot = p_ent->time_of_resp;
1245     }
1246   }
1247 
1248   /* If here, no free entry found. Return the oldest. */
1249 
1250   memset(p_old, 0, sizeof(tINQ_DB_ENT));
1251   p_old->inq_info.results.remote_bd_addr = p_bda;
1252   p_old->in_use = true;
1253 
1254   return (p_old);
1255 }
1256 
1257 /*******************************************************************************
1258  *
1259  * Function         btm_set_inq_event_filter
1260  *
1261  * Description      This function is called to set the inquiry event filter.
1262  *                  It is called by either internally, or by the external API
1263  *                  function (BTM_SetInqEventFilter).  It is used internally as
1264  *                  part of the inquiry processing.
1265  *
1266  * Input Params:
1267  *                  filter_cond_type - this is the type of inquiry filter to
1268  *                                     apply:
1269  *                          BTM_FILTER_COND_DEVICE_CLASS,
1270  *                          BTM_FILTER_COND_BD_ADDR, or
1271  *                          BTM_CLR_INQUIRY_FILTER
1272  *
1273  *                  p_filt_cond - this is either a BD_ADDR or DEV_CLASS
1274  *                                depending on the filter_cond_type
1275  *                                (See section 4.7.3 of Core Spec 1.0b).
1276  *
1277  * Returns          BTM_CMD_STARTED if successfully initiated
1278  *                  BTM_NO_RESOURCES if couldn't get a memory pool buffer
1279  *                  BTM_ILLEGAL_VALUE if a bad parameter was detected
1280  *
1281  ******************************************************************************/
btm_set_inq_event_filter(uint8_t filter_cond_type,tBTM_INQ_FILT_COND * p_filt_cond)1282 static tBTM_STATUS btm_set_inq_event_filter(uint8_t filter_cond_type,
1283                                             tBTM_INQ_FILT_COND* p_filt_cond) {
1284   uint8_t condition_length = DEV_CLASS_LEN * 2;
1285   uint8_t condition_buf[DEV_CLASS_LEN * 2];
1286   uint8_t* p_cond = condition_buf; /* points to the condition to pass to HCI */
1287 
1288 #if (BTM_INQ_DEBUG == TRUE)
1289   BTM_TRACE_DEBUG(
1290       "btm_set_inq_event_filter: filter type %d [Clear-0, COD-1, BDADDR-2]",
1291       filter_cond_type);
1292   VLOG(2) << "condition " << p_filt_cond->bdaddr_cond;
1293 #endif
1294 
1295   /* Load the correct filter condition to pass to the lower layer */
1296   switch (filter_cond_type) {
1297     case BTM_FILTER_COND_DEVICE_CLASS:
1298       /* copy the device class and device class fields into contiguous memory to
1299        * send to HCI */
1300       memcpy(condition_buf, p_filt_cond->cod_cond.dev_class, DEV_CLASS_LEN);
1301       memcpy(&condition_buf[DEV_CLASS_LEN],
1302              p_filt_cond->cod_cond.dev_class_mask, DEV_CLASS_LEN);
1303 
1304       /* condition length should already be set as the default */
1305       break;
1306 
1307     case BTM_FILTER_COND_BD_ADDR:
1308       p_cond = (uint8_t*)&p_filt_cond->bdaddr_cond;
1309 
1310       /* condition length should already be set as the default */
1311       break;
1312 
1313     case BTM_CLR_INQUIRY_FILTER:
1314       condition_length = 0;
1315       break;
1316 
1317     default:
1318       return (BTM_ILLEGAL_VALUE); /* Bad parameter was passed in */
1319   }
1320 
1321   btm_cb.btm_inq_vars.inqfilt_active = true;
1322 
1323   /* Filter the inquiry results for the specified condition type and value */
1324   btsnd_hcic_set_event_filter(HCI_FILTER_INQUIRY_RESULT, filter_cond_type,
1325                               p_cond, condition_length);
1326   return (BTM_CMD_STARTED);
1327 }
1328 
1329 /*******************************************************************************
1330  *
1331  * Function         btm_event_filter_complete
1332  *
1333  * Description      This function is called when a set event filter has
1334  *                  completed.
1335  *                  Note: This routine currently only handles inquiry filters.
1336  *                      Connection filters are ignored for now.
1337  *
1338  * Returns          void
1339  *
1340  ******************************************************************************/
btm_event_filter_complete(uint8_t * p)1341 void btm_event_filter_complete(uint8_t* p) {
1342   uint8_t hci_status;
1343   tBTM_STATUS status;
1344   tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
1345   tBTM_CMPL_CB* p_cb = p_inq->p_inqfilter_cmpl_cb;
1346 
1347 #if (BTM_INQ_DEBUG == TRUE)
1348   BTM_TRACE_DEBUG(
1349       "btm_event_filter_complete: inq_active:0x%x state:%d inqfilt_active:%d",
1350       btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state,
1351       btm_cb.btm_inq_vars.inqfilt_active);
1352 #endif
1353   /* If the filter complete event is from an old or cancelled request, ignore it
1354    */
1355   if (p_inq->pending_filt_complete_event) {
1356     p_inq->pending_filt_complete_event--;
1357     return;
1358   }
1359 
1360   /* Only process the inquiry filter; Ignore the connection filter until it
1361      is used by the upper layers */
1362   if (p_inq->inqfilt_active) {
1363     /* Extract the returned status from the buffer */
1364     STREAM_TO_UINT8(hci_status, p);
1365     if (hci_status != HCI_SUCCESS) {
1366       /* If standalone operation, return the error status; if embedded in the
1367        * inquiry, continue the inquiry */
1368       BTM_TRACE_WARNING(
1369           "BTM Warning: Set Event Filter Failed (HCI returned 0x%x)",
1370           hci_status);
1371       status = BTM_ERR_PROCESSING;
1372     } else
1373       status = BTM_SUCCESS;
1374 
1375     /* If the set filter was initiated externally (via BTM_SetInqEventFilter),
1376        call the
1377        callback function to notify the initiator that it has completed */
1378     if (p_inq->state == BTM_INQ_INACTIVE_STATE) {
1379       p_inq->inqfilt_active = false;
1380       if (p_cb) (*p_cb)(&status);
1381     } else /* An inquiry is active (the set filter command was internally
1382               generated),
1383               process the next state of the process (Set a new filter or start
1384               the inquiry). */
1385     {
1386       if (status != BTM_SUCCESS) {
1387         /* Process the inquiry complete (Error Status) */
1388         btm_process_inq_complete(
1389             BTM_ERR_PROCESSING,
1390             (uint8_t)(p_inq->inqparms.mode & BTM_BR_INQUIRY_MASK));
1391 
1392         /* btm_process_inq_complete() does not restore the following settings on
1393          * periodic inquiry */
1394         p_inq->inqfilt_active = false;
1395         p_inq->inq_active = BTM_INQUIRY_INACTIVE;
1396         p_inq->state = BTM_INQ_INACTIVE_STATE;
1397 
1398         return;
1399       }
1400 
1401       /* Check to see if a new filter needs to be set up */
1402       if (p_inq->state == BTM_INQ_CLR_FILT_STATE) {
1403         status = btm_set_inq_event_filter(p_inq->inqparms.filter_cond_type,
1404                                           &p_inq->inqparms.filter_cond);
1405         if (status == BTM_CMD_STARTED) {
1406           p_inq->state = BTM_INQ_SET_FILT_STATE;
1407         } else /* Error setting the filter: Call the initiator's callback
1408                   function to indicate a failure */
1409         {
1410           p_inq->inqfilt_active = false;
1411 
1412           /* Process the inquiry complete (Error Status) */
1413           btm_process_inq_complete(
1414               BTM_ERR_PROCESSING,
1415               (uint8_t)(p_inq->inqparms.mode & BTM_BR_INQUIRY_MASK));
1416         }
1417       } else /* Initiate the Inquiry or Periodic Inquiry */
1418       {
1419         p_inq->state = BTM_INQ_ACTIVE_STATE;
1420         p_inq->inqfilt_active = false;
1421         btm_initiate_inquiry(p_inq);
1422       }
1423     }
1424   }
1425 }
1426 
1427 /*******************************************************************************
1428  *
1429  * Function         btm_initiate_inquiry
1430  *
1431  * Description      This function is called to start an inquiry or periodic
1432  *                  inquiry upon completion of the setting and/or clearing of
1433  *                  the inquiry filter.
1434  *
1435  * Inputs:          p_inq (btm_cb.btm_inq_vars) - pointer to saved inquiry
1436  *                                                information
1437  *                      mode - GENERAL or LIMITED inquiry
1438  *                      duration - length in 1.28 sec intervals
1439  *                                 (If '0', the inquiry is CANCELLED)
1440  *                      max_resps - maximum amount of devices to search for
1441  *                                  before ending the inquiry
1442  *                      filter_cond_type - BTM_CLR_INQUIRY_FILTER,
1443  *                                         BTM_FILTER_COND_DEVICE_CLASS, or
1444  *                                         BTM_FILTER_COND_BD_ADDR
1445  *                      filter_cond - value for the filter
1446  *                                   (based on filter_cond_type)
1447  *
1448  * Returns          If an error occurs the initiator's callback is called with
1449  *                  the error status.
1450  *
1451  ******************************************************************************/
btm_initiate_inquiry(tBTM_INQUIRY_VAR_ST * p_inq)1452 static void btm_initiate_inquiry(tBTM_INQUIRY_VAR_ST* p_inq) {
1453   const LAP* lap;
1454   tBTM_INQ_PARMS* p_inqparms = &p_inq->inqparms;
1455 
1456 #if (BTM_INQ_DEBUG == TRUE)
1457   BTM_TRACE_DEBUG(
1458       "btm_initiate_inquiry: inq_active:0x%x state:%d inqfilt_active:%d",
1459       btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state,
1460       btm_cb.btm_inq_vars.inqfilt_active);
1461 #endif
1462   btm_acl_update_busy_level(BTM_BLI_INQ_EVT);
1463 
1464   if (p_inq->inq_active & BTM_SSP_INQUIRY_ACTIVE) {
1465     btm_process_inq_complete(BTM_NO_RESOURCES,
1466                              (uint8_t)(p_inqparms->mode & BTM_BR_INQUIRY_MASK));
1467     return;
1468   }
1469 
1470   /* Make sure the number of responses doesn't overflow the database
1471    * configuration */
1472   p_inqparms->max_resps = (uint8_t)((p_inqparms->max_resps <= BTM_INQ_DB_SIZE)
1473                                         ? p_inqparms->max_resps
1474                                         : BTM_INQ_DB_SIZE);
1475 
1476   lap = (p_inq->inq_active & BTM_LIMITED_INQUIRY_ACTIVE) ? &limited_inq_lap
1477                                                          : &general_inq_lap;
1478 
1479   if (p_inq->inq_active & BTM_PERIODIC_INQUIRY_ACTIVE) {
1480     btsnd_hcic_per_inq_mode(p_inq->per_max_delay, p_inq->per_min_delay, *lap,
1481                             p_inqparms->duration, p_inqparms->max_resps);
1482   } else {
1483     btm_clr_inq_result_flt();
1484 
1485     /* Allocate memory to hold bd_addrs responding */
1486     p_inq->p_bd_db = (tINQ_BDADDR*)osi_calloc(BT_DEFAULT_BUFFER_SIZE);
1487     p_inq->max_bd_entries =
1488         (uint16_t)(BT_DEFAULT_BUFFER_SIZE / sizeof(tINQ_BDADDR));
1489 
1490     btsnd_hcic_inquiry(*lap, p_inqparms->duration, 0);
1491   }
1492 }
1493 
1494 /*******************************************************************************
1495  *
1496  * Function         btm_process_inq_results
1497  *
1498  * Description      This function is called when inquiry results are received
1499  *                  from the device. It updates the inquiry database. If the
1500  *                  inquiry database is full, the oldest entry is discarded.
1501  *
1502  * Parameters       inq_res_mode - BTM_INQ_RESULT_STANDARD
1503  *                                 BTM_INQ_RESULT_WITH_RSSI
1504  *                                 BTM_INQ_RESULT_EXTENDED
1505  *
1506  * Returns          void
1507  *
1508  ******************************************************************************/
btm_process_inq_results(uint8_t * p,uint8_t hci_evt_len,uint8_t inq_res_mode)1509 void btm_process_inq_results(uint8_t* p, uint8_t hci_evt_len,
1510                              uint8_t inq_res_mode) {
1511   uint8_t num_resp, xx;
1512   RawAddress bda;
1513   tINQ_DB_ENT* p_i;
1514   tBTM_INQ_RESULTS* p_cur = NULL;
1515   bool is_new = true;
1516   bool update = false;
1517   int8_t i_rssi;
1518   tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
1519   tBTM_INQ_RESULTS_CB* p_inq_results_cb = p_inq->p_inq_results_cb;
1520   uint8_t page_scan_rep_mode = 0;
1521   uint8_t page_scan_per_mode = 0;
1522   uint8_t page_scan_mode = 0;
1523   uint8_t rssi = 0;
1524   DEV_CLASS dc;
1525   uint16_t clock_offset;
1526   uint8_t* p_eir_data = NULL;
1527 
1528 #if (BTM_INQ_DEBUG == TRUE)
1529   BTM_TRACE_DEBUG(
1530       "btm_process_inq_results inq_active:0x%x state:%d inqfilt_active:%d",
1531       btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state,
1532       btm_cb.btm_inq_vars.inqfilt_active);
1533 #endif
1534   /* Only process the results if the BR inquiry is still active */
1535   if (!(p_inq->inq_active & BTM_BR_INQ_ACTIVE_MASK)) return;
1536 
1537   STREAM_TO_UINT8(num_resp, p);
1538 
1539   if (inq_res_mode == BTM_INQ_RESULT_EXTENDED) {
1540     if (num_resp > 1) {
1541       BTM_TRACE_ERROR("btm_process_inq_results() extended results (%d) > 1",
1542                       num_resp);
1543       return;
1544     }
1545 
1546     constexpr uint16_t extended_inquiry_result_size = 254;
1547     if (hci_evt_len - 1 != extended_inquiry_result_size) {
1548       android_errorWriteLog(0x534e4554, "141620271");
1549       BTM_TRACE_ERROR("%s: can't fit %d results in %d bytes", __func__,
1550                       num_resp, hci_evt_len);
1551       return;
1552     }
1553   } else if (inq_res_mode == BTM_INQ_RESULT_STANDARD ||
1554              inq_res_mode == BTM_INQ_RESULT_WITH_RSSI) {
1555     constexpr uint16_t inquiry_result_size = 14;
1556     if (hci_evt_len < num_resp * inquiry_result_size) {
1557       android_errorWriteLog(0x534e4554, "141620271");
1558       BTM_TRACE_ERROR("%s: can't fit %d results in %d bytes", __func__,
1559                       num_resp, hci_evt_len);
1560       return;
1561     }
1562   }
1563 
1564   for (xx = 0; xx < num_resp; xx++) {
1565     update = false;
1566     /* Extract inquiry results */
1567     STREAM_TO_BDADDR(bda, p);
1568     STREAM_TO_UINT8(page_scan_rep_mode, p);
1569     STREAM_TO_UINT8(page_scan_per_mode, p);
1570 
1571     if (inq_res_mode == BTM_INQ_RESULT_STANDARD) {
1572       STREAM_TO_UINT8(page_scan_mode, p);
1573     }
1574 
1575     STREAM_TO_DEVCLASS(dc, p);
1576     STREAM_TO_UINT16(clock_offset, p);
1577     if (inq_res_mode != BTM_INQ_RESULT_STANDARD) {
1578       STREAM_TO_UINT8(rssi, p);
1579     }
1580 
1581     p_i = btm_inq_db_find(bda);
1582     /* Only process the num_resp is smaller than max_resps.
1583        If results are queued to BTU task while canceling inquiry,
1584        or when more than one result is in this response, > max_resp
1585        responses could be processed which can confuse some apps
1586     */
1587     if (p_inq->inqparms.max_resps &&
1588         p_inq->inq_cmpl_info.num_resp >= p_inq->inqparms.max_resps
1589         /* new device response */
1590         &&
1591         (p_i == NULL ||
1592          /* exisiting device with BR/EDR info */
1593          (p_i &&
1594           (p_i->inq_info.results.device_type & BT_DEVICE_TYPE_BREDR) != 0))) {
1595       /* BTM_TRACE_WARNING("INQ RES: Extra Response Received...ignoring"); */
1596       return;
1597     }
1598 
1599     /* Check if this address has already been processed for this inquiry */
1600     if (btm_inq_find_bdaddr(bda)) {
1601       /* BTM_TRACE_DEBUG("BDA seen before %s", bda.ToString().c_str()); */
1602 
1603       /* By default suppose no update needed */
1604       i_rssi = (int8_t)rssi;
1605 
1606       /* If this new RSSI is higher than the last one */
1607       if (p_inq->inqparms.report_dup && (rssi != 0) && p_i &&
1608           (i_rssi > p_i->inq_info.results.rssi ||
1609            p_i->inq_info.results.rssi == 0
1610            /* BR/EDR inquiry information update */
1611            ||
1612            (p_i->inq_info.results.device_type & BT_DEVICE_TYPE_BREDR) != 0)) {
1613         p_cur = &p_i->inq_info.results;
1614         BTM_TRACE_DEBUG("update RSSI new:%d, old:%d", i_rssi, p_cur->rssi);
1615         p_cur->rssi = i_rssi;
1616         update = true;
1617       }
1618       /* If we received a second Extended Inq Event for an already */
1619       /* discovered device, this is because for the first one EIR was not
1620          received */
1621       else if ((inq_res_mode == BTM_INQ_RESULT_EXTENDED) && (p_i)) {
1622         p_cur = &p_i->inq_info.results;
1623         update = true;
1624       }
1625       /* If no update needed continue with next response (if any) */
1626       else
1627         continue;
1628     }
1629 
1630     /* If existing entry, use that, else get a new one (possibly reusing the
1631      * oldest) */
1632     if (p_i == NULL) {
1633       p_i = btm_inq_db_new(bda);
1634       is_new = true;
1635     }
1636 
1637     /* If an entry for the device already exists, overwrite it ONLY if it is
1638        from
1639        a previous inquiry. (Ignore it if it is a duplicate response from the
1640        same
1641        inquiry.
1642     */
1643     else if (p_i->inq_count == p_inq->inq_counter &&
1644              (p_i->inq_info.results.device_type == BT_DEVICE_TYPE_BREDR))
1645       is_new = false;
1646 
1647     /* keep updating RSSI to have latest value */
1648     if (inq_res_mode != BTM_INQ_RESULT_STANDARD)
1649       p_i->inq_info.results.rssi = (int8_t)rssi;
1650     else
1651       p_i->inq_info.results.rssi = BTM_INQ_RES_IGNORE_RSSI;
1652 
1653     if (is_new) {
1654       /* Save the info */
1655       p_cur = &p_i->inq_info.results;
1656       p_cur->page_scan_rep_mode = page_scan_rep_mode;
1657       p_cur->page_scan_per_mode = page_scan_per_mode;
1658       p_cur->page_scan_mode = page_scan_mode;
1659       p_cur->dev_class[0] = dc[0];
1660       p_cur->dev_class[1] = dc[1];
1661       p_cur->dev_class[2] = dc[2];
1662       p_cur->clock_offset = clock_offset | BTM_CLOCK_OFFSET_VALID;
1663 
1664       p_i->time_of_resp = bluetooth::common::time_get_os_boottime_ms();
1665 
1666       if (p_i->inq_count != p_inq->inq_counter)
1667         p_inq->inq_cmpl_info.num_resp++; /* A new response was found */
1668 
1669       p_cur->inq_result_type |= BTM_INQ_RESULT_BR;
1670       if (p_i->inq_count != p_inq->inq_counter) {
1671         p_cur->device_type = BT_DEVICE_TYPE_BREDR;
1672         p_i->scan_rsp = false;
1673       } else
1674         p_cur->device_type |= BT_DEVICE_TYPE_BREDR;
1675       p_i->inq_count = p_inq->inq_counter; /* Mark entry for current inquiry */
1676 
1677       /* If the number of responses found and not unlimited, issue a cancel
1678        * inquiry */
1679       if (!(p_inq->inq_active & BTM_PERIODIC_INQUIRY_ACTIVE) &&
1680           p_inq->inqparms.max_resps &&
1681           p_inq->inq_cmpl_info.num_resp == p_inq->inqparms.max_resps &&
1682           /* BLE scanning is active and received adv */
1683           ((((p_inq->inqparms.mode & BTM_BLE_INQUIRY_MASK) != 0) &&
1684             p_cur->device_type == BT_DEVICE_TYPE_DUMO && p_i->scan_rsp) ||
1685            (p_inq->inqparms.mode & BTM_BLE_INQUIRY_MASK) == 0)) {
1686         /*                BTM_TRACE_DEBUG("BTMINQ: Found devices, cancelling
1687          * inquiry..."); */
1688         btsnd_hcic_inq_cancel();
1689 
1690         if ((p_inq->inqparms.mode & BTM_BLE_INQUIRY_MASK) != 0)
1691           btm_ble_stop_inquiry();
1692         btm_acl_update_busy_level(BTM_BLI_INQ_DONE_EVT);
1693       }
1694       /* Initialize flag to false. This flag is set/used by application */
1695       p_i->inq_info.appl_knows_rem_name = false;
1696     }
1697 
1698     if (is_new || update) {
1699       if (inq_res_mode == BTM_INQ_RESULT_EXTENDED) {
1700         memset(p_cur->eir_uuid, 0,
1701                BTM_EIR_SERVICE_ARRAY_SIZE * (BTM_EIR_ARRAY_BITS / 8));
1702         /* set bit map of UUID list from received EIR */
1703         btm_set_eir_uuid(p, p_cur);
1704         p_eir_data = p;
1705       } else
1706         p_eir_data = NULL;
1707 
1708       /* If a callback is registered, call it with the results */
1709       if (p_inq_results_cb) {
1710         (p_inq_results_cb)((tBTM_INQ_RESULTS*)p_cur, p_eir_data,
1711                            HCI_EXT_INQ_RESPONSE_LEN);
1712       } else {
1713         BTM_TRACE_DEBUG("No callback is registered");
1714       }
1715     }
1716   }
1717 }
1718 
1719 /*******************************************************************************
1720  *
1721  * Function         btm_sort_inq_result
1722  *
1723  * Description      This function is called when inquiry complete is received
1724  *                  from the device to sort inquiry results based on rssi.
1725  *
1726  * Returns          void
1727  *
1728  ******************************************************************************/
btm_sort_inq_result(void)1729 void btm_sort_inq_result(void) {
1730   uint8_t xx, yy, num_resp;
1731   tINQ_DB_ENT* p_ent = btm_cb.btm_inq_vars.inq_db;
1732   tINQ_DB_ENT* p_next = btm_cb.btm_inq_vars.inq_db + 1;
1733   int size;
1734   tINQ_DB_ENT* p_tmp = (tINQ_DB_ENT*)osi_malloc(sizeof(tINQ_DB_ENT));
1735 
1736   num_resp = (btm_cb.btm_inq_vars.inq_cmpl_info.num_resp < BTM_INQ_DB_SIZE)
1737                  ? btm_cb.btm_inq_vars.inq_cmpl_info.num_resp
1738                  : BTM_INQ_DB_SIZE;
1739 
1740   size = sizeof(tINQ_DB_ENT);
1741   for (xx = 0; xx < num_resp - 1; xx++, p_ent++) {
1742     for (yy = xx + 1, p_next = p_ent + 1; yy < num_resp; yy++, p_next++) {
1743       if (p_ent->inq_info.results.rssi < p_next->inq_info.results.rssi) {
1744         memcpy(p_tmp, p_next, size);
1745         memcpy(p_next, p_ent, size);
1746         memcpy(p_ent, p_tmp, size);
1747       }
1748     }
1749   }
1750 
1751   osi_free(p_tmp);
1752 }
1753 
1754 /*******************************************************************************
1755  *
1756  * Function         btm_process_inq_complete
1757  *
1758  * Description      This function is called when inquiry complete is received
1759  *                  from the device.  Call the callback if not in periodic
1760  *                  inquiry mode AND it is not NULL
1761  *                  (The caller wants the event).
1762  *
1763  *                  The callback pass back the status and the number of
1764  *                  responses
1765  *
1766  * Returns          void
1767  *
1768  ******************************************************************************/
btm_process_inq_complete(uint8_t status,uint8_t mode)1769 void btm_process_inq_complete(uint8_t status, uint8_t mode) {
1770   tBTM_CMPL_CB* p_inq_cb = btm_cb.btm_inq_vars.p_inq_cmpl_cb;
1771   tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
1772 
1773   p_inq->inqparms.mode &= ~(mode);
1774 
1775 #if (BTM_INQ_DEBUG == TRUE)
1776   BTM_TRACE_DEBUG(
1777       "btm_process_inq_complete inq_active:0x%x state:%d inqfilt_active:%d",
1778       btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state,
1779       btm_cb.btm_inq_vars.inqfilt_active);
1780 #endif
1781   btm_acl_update_busy_level(BTM_BLI_INQ_DONE_EVT);
1782   /* Ignore any stray or late complete messages if the inquiry is not active */
1783   if (p_inq->inq_active) {
1784     p_inq->inq_cmpl_info.status = (tBTM_STATUS)(
1785         (status == HCI_SUCCESS) ? BTM_SUCCESS : BTM_ERR_PROCESSING);
1786 
1787     /* Notify caller that the inquiry has completed; (periodic inquiries do not
1788      * send completion events */
1789     if (!(p_inq->inq_active & BTM_PERIODIC_INQUIRY_ACTIVE) &&
1790         p_inq->inqparms.mode == 0) {
1791       btm_clear_all_pending_le_entry();
1792       p_inq->state = BTM_INQ_INACTIVE_STATE;
1793 
1794       /* Increment so the start of a next inquiry has a new count */
1795       p_inq->inq_counter++;
1796 
1797       btm_clr_inq_result_flt();
1798 
1799       if ((p_inq->inq_cmpl_info.status == BTM_SUCCESS) &&
1800           controller_get_interface()->supports_rssi_with_inquiry_results()) {
1801         btm_sort_inq_result();
1802       }
1803 
1804       /* Clear the results callback if set */
1805       p_inq->p_inq_results_cb = NULL;
1806       p_inq->inq_active = BTM_INQUIRY_INACTIVE;
1807       p_inq->p_inq_cmpl_cb = NULL;
1808 
1809       /* If we have a callback registered for inquiry complete, call it */
1810       BTM_TRACE_DEBUG("BTM Inq Compl Callback: status 0x%02x, num results %d",
1811                       p_inq->inq_cmpl_info.status,
1812                       p_inq->inq_cmpl_info.num_resp);
1813 
1814       if (p_inq_cb) (p_inq_cb)((tBTM_INQUIRY_CMPL*)&p_inq->inq_cmpl_info);
1815     }
1816   }
1817   if (p_inq->inqparms.mode == 0 &&
1818       p_inq->scan_type == INQ_GENERAL)  // this inquiry is complete
1819   {
1820     p_inq->scan_type = INQ_NONE;
1821   }
1822 #if (BTM_INQ_DEBUG == TRUE)
1823   BTM_TRACE_DEBUG("inq_active:0x%x state:%d inqfilt_active:%d",
1824                   btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state,
1825                   btm_cb.btm_inq_vars.inqfilt_active);
1826 #endif
1827 }
1828 
1829 /*******************************************************************************
1830  *
1831  * Function         btm_process_cancel_complete
1832  *
1833  * Description      This function is called when inquiry cancel complete is
1834  *                  received from the device. This function will also call the
1835  *                  btm_process_inq_complete. This function is needed to
1836  *                  differentiate a cancel_cmpl_evt from the inq_cmpl_evt.
1837  *
1838  * Returns          void
1839  *
1840  ******************************************************************************/
btm_process_cancel_complete(uint8_t status,uint8_t mode)1841 void btm_process_cancel_complete(uint8_t status, uint8_t mode) {
1842   btm_acl_update_busy_level(BTM_BLI_INQ_CANCEL_EVT);
1843   btm_process_inq_complete(status, mode);
1844 }
1845 /*******************************************************************************
1846  *
1847  * Function         btm_initiate_rem_name
1848  *
1849  * Description      This function looks initiates a remote name request.  It is
1850  *                  called either by GAP or by the API call
1851  *                  BTM_ReadRemoteDeviceName.
1852  *
1853  * Input Params:    p_cb            - callback function called when
1854  *                                    BTM_CMD_STARTED is returned.
1855  *                                    A pointer to tBTM_REMOTE_DEV_NAME is
1856  *                                    passed to the callback.
1857  *
1858  * Returns
1859  *                  BTM_CMD_STARTED is returned if the request was sent to HCI.
1860  *                  BTM_BUSY if already in progress
1861  *                  BTM_NO_RESOURCES if could not allocate resources to start
1862  *                                   the command
1863  *                  BTM_WRONG_MODE if the device is not up.
1864  *
1865  ******************************************************************************/
btm_initiate_rem_name(const RawAddress & remote_bda,uint8_t origin,uint64_t timeout_ms,tBTM_CMPL_CB * p_cb)1866 tBTM_STATUS btm_initiate_rem_name(const RawAddress& remote_bda, uint8_t origin,
1867                                   uint64_t timeout_ms, tBTM_CMPL_CB* p_cb) {
1868   tBTM_INQUIRY_VAR_ST* p_inq = &btm_cb.btm_inq_vars;
1869 
1870   /*** Make sure the device is ready ***/
1871   if (!BTM_IsDeviceUp()) return (BTM_WRONG_MODE);
1872 
1873   if (origin == BTM_RMT_NAME_SEC) {
1874     btsnd_hcic_rmt_name_req(remote_bda, HCI_PAGE_SCAN_REP_MODE_R1,
1875                             HCI_MANDATARY_PAGE_SCAN_MODE, 0);
1876     return BTM_CMD_STARTED;
1877   }
1878   /* Make sure there are no two remote name requests from external API in
1879      progress */
1880   else 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 his 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