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