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