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