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