btm_inq.c revision ff2c6ae048d59e2be29339a7c88cf6c97b818358
1/******************************************************************************
2 *
3 *  Copyright (C) 1999-2014 Broadcom Corporation
4 *
5 *  Licensed under the Apache License, Version 2.0 (the "License");
6 *  you may not use this file except in compliance with the License.
7 *  You may obtain a copy of the License at:
8 *
9 *  http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 *
17 ******************************************************************************/
18
19/******************************************************************************
20 *
21 *  This file contains functions that handle inquiries. These include
22 *  setting discoverable mode, controlling the mode of the Baseband, and
23 *  maintaining a small database of inquiry responses, with API for people
24 *  to browse it.
25 *
26 ******************************************************************************/
27
28#include <stdlib.h>
29#include <string.h>
30#include <stdio.h>
31#include <stddef.h>
32
33#include "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_API ("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_DISCOVERABLE_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_API ("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_API ("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_API ("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_API ("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_API ("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_API ("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_WARNING("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_API ("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_API ("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_API ("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_API ("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_API ("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_API ("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_BLE_INQ_ACTIVE_MASK)
800#endif
801            )
802                btm_ble_stop_inquiry();
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_API ("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_API("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            btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_DISABLE, BTM_BLE_DUPLICATE_ENABLE);
873        }
874        else
875#endif
876        {
877            return (BTM_BUSY);
878            BTM_TRACE_API("BTM_StartInquiry: return BUSY");
879        }
880    }
881    else
882        p_inq->scan_type = INQ_GENERAL;
883
884        /*** Make sure the device is ready ***/
885    if (!BTM_IsDeviceUp())
886        return (BTM_WRONG_MODE);
887
888    if ((p_inqparms->mode & BTM_BR_INQUIRY_MASK)!= BTM_GENERAL_INQUIRY &&
889        (p_inqparms->mode & BTM_BR_INQUIRY_MASK)!= BTM_LIMITED_INQUIRY
890#if (BLE_INCLUDED == TRUE)
891        && (p_inqparms->mode & BTM_BLE_INQUIRY_MASK)!= BTM_BLE_GENERAL_INQUIRY
892        && (p_inqparms->mode & BTM_BLE_INQUIRY_MASK)!= BTM_BLE_LIMITED_INQUIRY
893#endif
894        )
895        return (BTM_ILLEGAL_VALUE);
896
897#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE)
898        if(p_inq->next_state==BTM_FINISH)
899            return BTM_ILLEGAL_VALUE;
900#endif
901
902
903    /* Save the inquiry parameters to be used upon the completion of setting/clearing the inquiry filter */
904    p_inq->inqparms = *p_inqparms;
905
906    /* Initialize the inquiry variables */
907    p_inq->state = BTM_INQ_ACTIVE_STATE;
908    p_inq->p_inq_cmpl_cb = p_cmpl_cb;
909    p_inq->p_inq_results_cb = p_results_cb;
910    p_inq->inq_cmpl_info.num_resp = 0;         /* Clear the results counter */
911    p_inq->inq_active = p_inqparms->mode;
912
913    BTM_TRACE_DEBUG("BTM_StartInquiry: p_inq->inq_active = 0x%02x", p_inq->inq_active);
914
915/* interleave scan minimal conditions */
916#if (BLE_INCLUDED==TRUE && (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE))
917
918    /* check if both modes are present */
919    if((p_inqparms->mode & BTM_BLE_INQUIRY_MASK) && (p_inqparms->mode & BTM_BR_INQUIRY_MASK))
920    {
921        BTM_TRACE_API("BTM:Interleave Inquiry Mode Set");
922        p_inqparms->duration=p_inqparms->intl_duration[p_inq->next_state];
923        p_inq->inqparms.duration=p_inqparms->duration;
924    }
925    else
926    {
927        BTM_TRACE_API("BTM:Single Mode: No interleaving, Mode:0x%02x", p_inqparms->mode);
928        p_inq->next_state=BTM_NO_INTERLEAVING;
929    }
930#endif
931
932
933
934/* start LE inquiry here if requested */
935#if BLE_INCLUDED == TRUE
936    if ((p_inqparms->mode & BTM_BLE_INQUIRY_MASK)
937#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE)
938        &&(p_inq->next_state==BTM_BLE_ONE || p_inq->next_state==BTM_BLE_TWO ||
939           p_inq->next_state==BTM_NO_INTERLEAVING)
940#endif
941        )
942
943    {
944#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE)
945        p_inq->inq_active = (p_inqparms->mode & BTM_BLE_INQUIRY_MASK);
946        BTM_TRACE_API("BTM:Starting LE Scan with duration %d and activeMode:0x%02x",
947                       p_inqparms->duration, (p_inqparms->mode & BTM_BLE_INQUIRY_MASK));
948#endif
949        if (!HCI_LE_HOST_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_1]))
950        {
951            p_inq->inqparms.mode &= ~ BTM_BLE_INQUIRY_MASK;
952            status = BTM_ILLEGAL_VALUE;
953        }
954        /* BLE for now does not support filter condition for inquiry */
955        else if ((status = btm_ble_start_inquiry((UINT8)(p_inqparms->mode & BTM_BLE_INQUIRY_MASK),
956                                            p_inqparms->duration)) != BTM_CMD_STARTED)
957        {
958            BTM_TRACE_ERROR("Err Starting LE Inquiry.");
959            p_inq->inqparms.mode &= ~ BTM_BLE_INQUIRY_MASK;
960        }
961#if (!defined(BTA_HOST_INTERLEAVE_SEARCH) || BTA_HOST_INTERLEAVE_SEARCH == FALSE)
962        p_inqparms->mode &= ~BTM_BLE_INQUIRY_MASK;
963#endif
964
965#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE)
966        if(p_inq->next_state==BTM_NO_INTERLEAVING)
967        {
968            p_inq->next_state=BTM_FINISH;
969        }
970        else
971        {
972            BTM_TRACE_API("BTM:Interleaving: started LE scan, Advancing to next state: %d",
973                           p_inq->next_state+1);
974            p_inq->next_state+=1;
975        }
976        /* reset next_state if status <> BTM_Started */
977        if(status!=BTM_CMD_STARTED)
978            p_inq->next_state=BTM_BR_ONE;
979
980        /* if interleave scan..return here */
981        return status;
982#endif
983
984
985        BTM_TRACE_DEBUG("BTM_StartInquiry: mode = %02x", p_inqparms->mode);
986    }
987#endif /* end of BLE_INCLUDED */
988
989    /* we're done with this routine if BR/EDR inquiry is not desired. */
990    if ((p_inqparms->mode & BTM_BR_INQUIRY_MASK) == BTM_INQUIRY_NONE)
991        return status;
992
993    /* BR/EDR inquiry portion */
994#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE)
995    if((p_inq->next_state==BTM_BR_ONE || p_inq->next_state==BTM_BR_TWO ||
996        p_inq->next_state==BTM_NO_INTERLEAVING ))
997    {
998        p_inq->inq_active = (p_inqparms->mode & BTM_BR_INQUIRY_MASK);
999#endif
1000#if (defined(BTM_BYPASS_EVENT_FILTERING) && BTM_BYPASS_EVENT_FILTERING == TRUE)
1001    BTM_TRACE_WARNING("BTM: Bypassing event filtering...");
1002    p_inq->inqfilt_active = FALSE;
1003    btm_initiate_inquiry (p_inq);
1004    status = BTM_CMD_STARTED;
1005#else
1006    /* If a filter is specified, then save it for later and clear the current filter.
1007       The setting of the filter is done upon completion of clearing of the previous
1008       filter.
1009    */
1010    switch (p_inqparms->filter_cond_type)
1011    {
1012    case BTM_CLR_INQUIRY_FILTER:
1013        p_inq->state = BTM_INQ_SET_FILT_STATE;
1014        break;
1015
1016    case BTM_FILTER_COND_DEVICE_CLASS:
1017    case BTM_FILTER_COND_BD_ADDR:
1018        /* The filter is not being used so simply clear it;
1019            the inquiry can start after this operation */
1020        p_inq->state = BTM_INQ_CLR_FILT_STATE;
1021        p_inqparms->filter_cond_type = BTM_CLR_INQUIRY_FILTER;
1022        /* =============>>>> adding LE filtering here ????? */
1023        break;
1024
1025    default:
1026        return (BTM_ILLEGAL_VALUE);
1027    }
1028
1029    /* Before beginning the inquiry the current filter must be cleared, so initiate the command */
1030    if ((status = btm_set_inq_event_filter (p_inqparms->filter_cond_type,
1031                                            &p_inqparms->filter_cond)) != BTM_CMD_STARTED)
1032        p_inq->state = BTM_INQ_INACTIVE_STATE;
1033#endif
1034
1035#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE)
1036        if (p_inq->next_state==BTM_NO_INTERLEAVING)
1037            p_inq->next_state=BTM_FINISH;
1038        else
1039        {
1040            BTM_TRACE_API("BTM:Interleaving: Started BTM inq, Advancing to next state: %d",
1041                           p_inq->next_state+1);
1042            p_inq->next_state+=1;
1043        }
1044     }
1045     if (status!=BTM_CMD_STARTED)
1046     {
1047         /* Some error beginning the scan process.
1048            Reset the next_state parameter.. Do we need to reset the inq_active also?
1049         */
1050        BTM_TRACE_API("BTM:Interleaving: Error in Starting inquiry, status: 0x%02x", status);
1051        p_inq->next_state=BTM_BR_ONE;
1052     }
1053#endif
1054
1055
1056    return (status);
1057}
1058
1059
1060/*******************************************************************************
1061**
1062** Function         BTM_ReadRemoteDeviceName
1063**
1064** Description      This function initiates a remote device HCI command to the
1065**                  controller and calls the callback when the process has completed.
1066**
1067** Input Params:    remote_bda      - device address of name to retrieve
1068**                  p_cb            - callback function called when BTM_CMD_STARTED
1069**                                    is returned.
1070**                                    A pointer to tBTM_REMOTE_DEV_NAME is passed to the
1071**                                    callback.
1072**
1073** Returns
1074**                  BTM_CMD_STARTED is returned if the request was successfully sent
1075**                                  to HCI.
1076**                  BTM_BUSY if already in progress
1077**                  BTM_UNKNOWN_ADDR if device address is bad
1078**                  BTM_NO_RESOURCES if could not allocate resources to start the command
1079**                  BTM_WRONG_MODE if the device is not up.
1080**
1081*******************************************************************************/
1082tBTM_STATUS  BTM_ReadRemoteDeviceName (BD_ADDR remote_bda, tBTM_CMPL_CB *p_cb
1083                                                ,tBT_TRANSPORT transport)
1084{
1085    tBTM_INQ_INFO   *p_cur = NULL;
1086    tINQ_DB_ENT     *p_i;
1087
1088    BTM_TRACE_API ("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    BTM_TRACE_API ("no device found in inquiry db");
1098
1099#if (BLE_INCLUDED == TRUE)
1100    if (transport == BT_TRANSPORT_LE)
1101    {
1102        return btm_ble_read_remote_name(remote_bda, p_cur, p_cb);
1103    }
1104    else
1105#endif
1106
1107    return (btm_initiate_rem_name (remote_bda, p_cur, BTM_RMT_NAME_EXT,
1108                                   BTM_EXT_RMT_NAME_TIMEOUT, p_cb));
1109}
1110
1111/*******************************************************************************
1112**
1113** Function         BTM_CancelRemoteDeviceName
1114**
1115** Description      This function initiates the cancel request for the specified
1116**                  remote device.
1117**
1118** Input Params:    None
1119**
1120** Returns
1121**                  BTM_CMD_STARTED is returned if the request was successfully sent
1122**                                  to HCI.
1123**                  BTM_NO_RESOURCES if could not allocate resources to start the command
1124**                  BTM_WRONG_MODE if there is not an active remote name request.
1125**
1126*******************************************************************************/
1127tBTM_STATUS  BTM_CancelRemoteDeviceName (void)
1128{
1129    tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
1130
1131    BTM_TRACE_API ("BTM_CancelRemoteDeviceName()");
1132
1133    /* Make sure there is not already one in progress */
1134    if (p_inq->remname_active)
1135    {
1136#if BLE_INCLUDED == TRUE
1137        if (BTM_UseLeLink(p_inq->remname_bda))
1138        {
1139            if (btm_ble_cancel_remote_name(p_inq->remname_bda))
1140                return (BTM_CMD_STARTED);
1141            else
1142                return (BTM_UNKNOWN_ADDR);
1143        }
1144        else
1145#endif
1146        if (btsnd_hcic_rmt_name_req_cancel (p_inq->remname_bda))
1147            return (BTM_CMD_STARTED);
1148        else
1149            return (BTM_NO_RESOURCES);
1150    }
1151    else
1152        return (BTM_WRONG_MODE);
1153}
1154
1155/*******************************************************************************
1156**
1157** Function         BTM_InqFirstResult
1158**
1159** Description      This function looks through the inquiry database for the first
1160**                  used entrysince the LAST inquiry. This is used in conjunction
1161**                  with BTM_InqNext by applications as a way to walk through the
1162**                  inquiry results database.
1163**
1164** Returns          pointer to first in-use entry, or NULL if DB is empty
1165**
1166*******************************************************************************/
1167tBTM_INQ_INFO *BTM_InqFirstResult (void)
1168{
1169    UINT16       xx;
1170    tINQ_DB_ENT  *p_ent = btm_cb.btm_inq_vars.inq_db;
1171    UINT32       cur_inq_count = btm_cb.btm_inq_vars.inq_counter - 1;
1172
1173    for (xx = 0; xx < BTM_INQ_DB_SIZE; xx++, p_ent++)
1174    {
1175        if (p_ent->in_use && p_ent->inq_count == cur_inq_count)
1176            return (&p_ent->inq_info);
1177    }
1178
1179    /* If here, no used entry found */
1180    return ((tBTM_INQ_INFO *)NULL);
1181}
1182
1183
1184/*******************************************************************************
1185**
1186** Function         BTM_InqNextResult
1187**
1188** Description      This function looks through the inquiry database for the next
1189**                  used entrysince the LAST inquiry. If the input parameter is NULL,
1190**                  the first entry is returned.
1191**
1192** Returns          pointer to next in-use entry, or NULL if no more found.
1193**
1194*******************************************************************************/
1195tBTM_INQ_INFO *BTM_InqNextResult (tBTM_INQ_INFO *p_cur)
1196{
1197    tINQ_DB_ENT  *p_ent;
1198    UINT16        inx;
1199    UINT32        cur_inq_count = btm_cb.btm_inq_vars.inq_counter - 1;
1200
1201    if (p_cur)
1202    {
1203        p_ent = (tINQ_DB_ENT *) ((UINT8 *)p_cur - offsetof (tINQ_DB_ENT, inq_info));
1204        inx = (UINT16)((p_ent - btm_cb.btm_inq_vars.inq_db) + 1);
1205
1206        for (p_ent = &btm_cb.btm_inq_vars.inq_db[inx]; inx < BTM_INQ_DB_SIZE; inx++, p_ent++)
1207        {
1208            if (p_ent->in_use && p_ent->inq_count == cur_inq_count)
1209                return (&p_ent->inq_info);
1210        }
1211
1212        /* If here, more entries found */
1213        return ((tBTM_INQ_INFO *)NULL);
1214    }
1215    else
1216        return (BTM_InqDbFirst());
1217}
1218
1219
1220/*******************************************************************************
1221**
1222** Function         BTM_InqDbRead
1223**
1224** Description      This function looks through the inquiry database for a match
1225**                  based on Bluetooth Device Address. This is the application's
1226**                  interface to get the inquiry details of a specific BD address.
1227**
1228** Returns          pointer to entry, or NULL if not found
1229**
1230*******************************************************************************/
1231tBTM_INQ_INFO *BTM_InqDbRead (BD_ADDR p_bda)
1232{
1233    UINT16       xx;
1234    tINQ_DB_ENT  *p_ent = btm_cb.btm_inq_vars.inq_db;
1235
1236    BTM_TRACE_API ("BTM_InqDbRead: bd addr [%02x%02x%02x%02x%02x%02x]",
1237               p_bda[0], p_bda[1], p_bda[2], p_bda[3], p_bda[4], p_bda[5]);
1238
1239    for (xx = 0; xx < BTM_INQ_DB_SIZE; xx++, p_ent++)
1240    {
1241        if ((p_ent->in_use) && (!memcmp (p_ent->inq_info.results.remote_bd_addr, p_bda, BD_ADDR_LEN)))
1242            return (&p_ent->inq_info);
1243    }
1244
1245    /* If here, not found */
1246    return ((tBTM_INQ_INFO *)NULL);
1247}
1248
1249
1250/*******************************************************************************
1251**
1252** Function         BTM_InqDbFirst
1253**
1254** Description      This function looks through the inquiry database for the first
1255**                  used entry, and returns that. This is used in conjunction with
1256**                  BTM_InqDbNext by applications as a way to walk through the
1257**                  inquiry database.
1258**
1259** Returns          pointer to first in-use entry, or NULL if DB is empty
1260**
1261*******************************************************************************/
1262tBTM_INQ_INFO *BTM_InqDbFirst (void)
1263{
1264    UINT16       xx;
1265    tINQ_DB_ENT  *p_ent = btm_cb.btm_inq_vars.inq_db;
1266
1267    for (xx = 0; xx < BTM_INQ_DB_SIZE; xx++, p_ent++)
1268    {
1269        if (p_ent->in_use)
1270            return (&p_ent->inq_info);
1271    }
1272
1273    /* If here, no used entry found */
1274    return ((tBTM_INQ_INFO *)NULL);
1275}
1276
1277
1278/*******************************************************************************
1279**
1280** Function         BTM_InqDbNext
1281**
1282** Description      This function looks through the inquiry database for the next
1283**                  used entry, and returns that.  If the input parameter is NULL,
1284**                  the first entry is returned.
1285**
1286** Returns          pointer to next in-use entry, or NULL if no more found.
1287**
1288*******************************************************************************/
1289tBTM_INQ_INFO *BTM_InqDbNext (tBTM_INQ_INFO *p_cur)
1290{
1291    tINQ_DB_ENT  *p_ent;
1292    UINT16        inx;
1293
1294    if (p_cur)
1295    {
1296        p_ent = (tINQ_DB_ENT *) ((UINT8 *)p_cur - offsetof (tINQ_DB_ENT, inq_info));
1297        inx = (UINT16)((p_ent - btm_cb.btm_inq_vars.inq_db) + 1);
1298
1299        for (p_ent = &btm_cb.btm_inq_vars.inq_db[inx]; inx < BTM_INQ_DB_SIZE; inx++, p_ent++)
1300        {
1301            if (p_ent->in_use)
1302                return (&p_ent->inq_info);
1303        }
1304
1305        /* If here, more entries found */
1306        return ((tBTM_INQ_INFO *)NULL);
1307    }
1308    else
1309        return (BTM_InqDbFirst());
1310}
1311
1312
1313/*******************************************************************************
1314**
1315** Function         BTM_ClearInqDb
1316**
1317** Description      This function is called to clear out a device or all devices
1318**                  from the inquiry database.
1319**
1320** Parameter        p_bda - (input) BD_ADDR ->  Address of device to clear
1321**                                              (NULL clears all entries)
1322**
1323** Returns          BTM_BUSY if an inquiry, get remote name, or event filter
1324**                          is active, otherwise BTM_SUCCESS
1325**
1326*******************************************************************************/
1327tBTM_STATUS BTM_ClearInqDb (BD_ADDR p_bda)
1328{
1329    tBTM_INQUIRY_VAR_ST     *p_inq = &btm_cb.btm_inq_vars;
1330
1331    /* If an inquiry or remote name is in progress return busy */
1332    if (p_inq->inq_active != BTM_INQUIRY_INACTIVE ||
1333        p_inq->inqfilt_active)
1334        return (BTM_BUSY);
1335
1336    btm_clr_inq_db(p_bda);
1337
1338    return (BTM_SUCCESS);
1339}
1340
1341
1342/*******************************************************************************
1343**
1344** Function         BTM_ReadNumInqDbEntries
1345**
1346** Returns          This function returns the number of entries in the inquiry database.
1347**
1348*******************************************************************************/
1349UINT8 BTM_ReadNumInqDbEntries (void)
1350{
1351    UINT8         num_entries;
1352    UINT8         num_results;
1353    tINQ_DB_ENT  *p_ent = btm_cb.btm_inq_vars.inq_db;
1354
1355    for (num_entries = 0, num_results = 0; num_entries < BTM_INQ_DB_SIZE; num_entries++, p_ent++)
1356    {
1357        if (p_ent->in_use)
1358            num_results++;
1359    }
1360
1361    return (num_results);
1362}
1363
1364/*******************************************************************************
1365**
1366** Function         BTM_SetInquiryFilterCallback
1367**
1368** Description      Host can register to be asked whenever an inquiry result
1369**                  is received.  If host does not like the device no name
1370**                  request is issued for the device
1371**
1372** Returns          void
1373**
1374*******************************************************************************/
1375void BTM_SetInquiryFilterCallback (tBTM_FILTER_CB *p_callback)
1376{
1377    btm_cb.p_inq_filter_cb = p_callback;
1378}
1379
1380/*******************************************************************************
1381**
1382** Function         BTM_ReadInquiryRspTxPower
1383**
1384** Description      This command will read the inquiry Transmit Power level used
1385**                  to transmit the FHS and EIR data packets.
1386**                  This can be used directly in the Tx Power Level EIR data type.
1387**
1388** Returns          BTM_SUCCESS if successful
1389**
1390*******************************************************************************/
1391tBTM_STATUS BTM_ReadInquiryRspTxPower (tBTM_CMPL_CB *p_cb)
1392{
1393    if (btm_cb.devcb.p_txpwer_cmpl_cb)
1394        return (BTM_BUSY);
1395
1396     btu_start_timer (&btm_cb.devcb.txpwer_timer, BTU_TTYPE_BTM_ACL, BTM_INQ_REPLY_TIMEOUT );
1397
1398
1399    btm_cb.devcb.p_txpwer_cmpl_cb = p_cb;
1400
1401    if (!btsnd_hcic_read_inq_tx_power ())
1402    {
1403        btm_cb.devcb.p_txpwer_cmpl_cb = NULL;
1404        btu_stop_timer (&btm_cb.devcb.txpwer_timer);
1405        return (BTM_NO_RESOURCES);
1406    }
1407    else
1408        return (BTM_CMD_STARTED);
1409}
1410/*******************************************************************************
1411**
1412** Function         BTM_WriteInquiryTxPower
1413**
1414** Description      This command is used to write the inquiry transmit power level
1415**                  used to transmit the inquiry (ID) data packets. The Controller
1416**                  should use the supported TX power level closest to the Tx_Power
1417**                  parameter.
1418**
1419** Returns          BTM_SUCCESS if successful
1420**
1421*******************************************************************************/
1422tBTM_STATUS  BTM_WriteInquiryTxPower (INT8 tx_power)
1423{
1424    tBTM_STATUS status = BTM_SUCCESS;
1425
1426    if (tx_power < BTM_MIN_INQ_TX_POWER || tx_power > BTM_MAX_INQ_TX_POWER)
1427    {
1428        status = BTM_ILLEGAL_VALUE;
1429    }
1430    else if (!btsnd_hcic_write_inq_tx_power(tx_power))
1431        status = BTM_NO_RESOURCES;
1432
1433    return status;
1434}
1435/*********************************************************************************
1436**********************************************************************************
1437**                                                                              **
1438**                      BTM Internal Inquiry Functions                          **
1439**                                                                              **
1440**********************************************************************************
1441*********************************************************************************/
1442/*******************************************************************************
1443**
1444** Function         btm_inq_db_reset
1445**
1446** Description      This function is called at at reset to clear the inquiry
1447**                  database & pending callback.
1448**
1449** Returns          void
1450**
1451*******************************************************************************/
1452void btm_inq_db_reset (void)
1453{
1454    tBTM_REMOTE_DEV_NAME     rem_name;
1455    tBTM_INQUIRY_VAR_ST     *p_inq = &btm_cb.btm_inq_vars;
1456    UINT8                    num_responses;
1457    UINT8                    temp_inq_active;
1458    tBTM_STATUS              status;
1459
1460    btu_stop_timer (&p_inq->inq_timer_ent);
1461
1462    /* If an inquiry or periodic inquiry is active, reset the mode to inactive */
1463    if (p_inq->inq_active != BTM_INQUIRY_INACTIVE)
1464    {
1465        temp_inq_active = p_inq->inq_active;    /* Save so state can change BEFORE
1466                                                       callback is called */
1467        p_inq->inq_active = BTM_INQUIRY_INACTIVE;
1468
1469        /* If not a periodic inquiry, the complete callback must be called to notify caller */
1470        if (temp_inq_active == BTM_LIMITED_INQUIRY_ACTIVE ||
1471            temp_inq_active == BTM_GENERAL_INQUIRY_ACTIVE)
1472        {
1473            if (p_inq->p_inq_cmpl_cb)
1474            {
1475                num_responses = 0;
1476                (*p_inq->p_inq_cmpl_cb)(&num_responses);
1477            }
1478        }
1479    }
1480
1481    /* Cancel a remote name request if active, and notify the caller (if waiting) */
1482    if (p_inq->remname_active )
1483    {
1484        btu_stop_timer (&p_inq->rmt_name_timer_ent);
1485        p_inq->remname_active = FALSE;
1486        memset(p_inq->remname_bda, 0, BD_ADDR_LEN);
1487
1488        if (p_inq->p_remname_cmpl_cb)
1489        {
1490            rem_name.status = BTM_DEV_RESET;
1491
1492            (*p_inq->p_remname_cmpl_cb)(&rem_name);
1493            p_inq->p_remname_cmpl_cb = NULL;
1494        }
1495    }
1496
1497    /* Cancel an inquiry filter request if active, and notify the caller (if waiting) */
1498    if (p_inq->inqfilt_active)
1499    {
1500        p_inq->inqfilt_active = FALSE;
1501
1502        if (p_inq->p_inqfilter_cmpl_cb)
1503        {
1504            status = BTM_DEV_RESET;
1505            (*p_inq->p_inqfilter_cmpl_cb)(&status);
1506        }
1507    }
1508
1509    p_inq->state = BTM_INQ_INACTIVE_STATE;
1510    p_inq->pending_filt_complete_event = 0;
1511    p_inq->p_inq_results_cb = NULL;
1512    btm_clr_inq_db(NULL);   /* Clear out all the entries in the database */
1513    btm_clr_inq_result_flt();
1514
1515    p_inq->discoverable_mode = BTM_NON_DISCOVERABLE;
1516    p_inq->connectable_mode  = BTM_NON_CONNECTABLE;
1517    p_inq->page_scan_type    = BTM_SCAN_TYPE_STANDARD;
1518    p_inq->inq_scan_type     = BTM_SCAN_TYPE_STANDARD;
1519
1520#if BLE_INCLUDED == TRUE
1521    p_inq->discoverable_mode |= BTM_BLE_NON_DISCOVERABLE;
1522    p_inq->connectable_mode  |= BTM_BLE_NON_CONNECTABLE;
1523#endif
1524    return;
1525}
1526
1527
1528/*********************************************************************************
1529**
1530** Function         btm_inq_db_init
1531**
1532** Description      This function is called at startup to initialize the inquiry
1533**                  database.
1534**
1535** Returns          void
1536**
1537*******************************************************************************/
1538void btm_inq_db_init (void)
1539{
1540#if 0  /* cleared in btm_init; put back in if called from anywhere else! */
1541    memset (&btm_cb.btm_inq_vars, 0, sizeof (tBTM_INQUIRY_VAR_ST));
1542#endif
1543    btm_cb.btm_inq_vars.no_inc_ssp = BTM_NO_SSP_ON_INQUIRY;
1544}
1545
1546/*********************************************************************************
1547**
1548** Function         btm_inq_stop_on_ssp
1549**
1550** Description      This function is called on incoming SSP
1551**
1552** Returns          void
1553**
1554*******************************************************************************/
1555void btm_inq_stop_on_ssp(void)
1556{
1557    UINT8 normal_active = (BTM_GENERAL_INQUIRY_ACTIVE|BTM_LIMITED_INQUIRY_ACTIVE);
1558
1559#if (BTM_INQ_DEBUG == TRUE)
1560    BTM_TRACE_DEBUG ("btm_inq_stop_on_ssp: no_inc_ssp=%d inq_active:0x%x state:%d inqfilt_active:%d",
1561        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);
1562#endif
1563    if (btm_cb.btm_inq_vars.no_inc_ssp)
1564    {
1565        if (btm_cb.btm_inq_vars.state == BTM_INQ_ACTIVE_STATE)
1566        {
1567            if (btm_cb.btm_inq_vars.inq_active & BTM_PERIODIC_INQUIRY_ACTIVE)
1568            {
1569                BTM_CancelPeriodicInquiry();
1570            }
1571            else if (btm_cb.btm_inq_vars.inq_active & normal_active)
1572            {
1573                /* can not call BTM_CancelInquiry() here. We need to report inquiry complete evt */
1574                btsnd_hcic_inq_cancel();
1575            }
1576        }
1577        /* do not allow inquiry to start */
1578        btm_cb.btm_inq_vars.inq_active |= BTM_SSP_INQUIRY_ACTIVE;
1579    }
1580}
1581
1582/*********************************************************************************
1583**
1584** Function         btm_inq_clear_ssp
1585**
1586** Description      This function is called when pairing_state becomes idle
1587**
1588** Returns          void
1589**
1590*******************************************************************************/
1591void btm_inq_clear_ssp(void)
1592{
1593    btm_cb.btm_inq_vars.inq_active &= ~BTM_SSP_INQUIRY_ACTIVE;
1594}
1595
1596/*********************************************************************************
1597**
1598** Function         btm_clr_inq_db
1599**
1600** Description      This function is called to clear out a device or all devices
1601**                  from the inquiry database.
1602**
1603** Parameter        p_bda - (input) BD_ADDR ->  Address of device to clear
1604**                                              (NULL clears all entries)
1605**
1606** Returns          void
1607**
1608*******************************************************************************/
1609void btm_clr_inq_db (BD_ADDR p_bda)
1610{
1611    tBTM_INQUIRY_VAR_ST     *p_inq = &btm_cb.btm_inq_vars;
1612    tINQ_DB_ENT             *p_ent = p_inq->inq_db;
1613    UINT16                   xx;
1614
1615#if (BTM_INQ_DEBUG == TRUE)
1616    BTM_TRACE_DEBUG ("btm_clr_inq_db: inq_active:0x%x state:%d",
1617        btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state);
1618#endif
1619    for (xx = 0; xx < BTM_INQ_DB_SIZE; xx++, p_ent++)
1620    {
1621        if (p_ent->in_use)
1622        {
1623            /* If this is the specified BD_ADDR or clearing all devices */
1624            if (p_bda == NULL ||
1625                (!memcmp (p_ent->inq_info.results.remote_bd_addr, p_bda, BD_ADDR_LEN)))
1626            {
1627                p_ent->in_use = FALSE;
1628            }
1629        }
1630    }
1631#if (BTM_INQ_DEBUG == TRUE)
1632    BTM_TRACE_DEBUG ("inq_active:0x%x state:%d",
1633        btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state);
1634#endif
1635}
1636
1637
1638/*******************************************************************************
1639**
1640** Function         btm_clr_inq_result_flt
1641**
1642** Description      This function looks through the bdaddr database for a match
1643**                  based on Bluetooth Device Address
1644**
1645** Returns          TRUE if found, else FALSE (new entry)
1646**
1647*******************************************************************************/
1648static void btm_clr_inq_result_flt (void)
1649{
1650#if BTM_USE_INQ_RESULTS_FILTER == TRUE
1651    tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
1652
1653    if (p_inq->p_bd_db)
1654    {
1655        GKI_freebuf(p_inq->p_bd_db);
1656        p_inq->p_bd_db = NULL;
1657    }
1658    p_inq->num_bd_entries = 0;
1659    p_inq->max_bd_entries = 0;
1660#endif
1661}
1662
1663/*******************************************************************************
1664**
1665** Function         btm_inq_find_bdaddr
1666**
1667** Description      This function looks through the bdaddr database for a match
1668**                  based on Bluetooth Device Address
1669**
1670** Returns          TRUE if found, else FALSE (new entry)
1671**
1672*******************************************************************************/
1673BOOLEAN btm_inq_find_bdaddr (BD_ADDR p_bda)
1674{
1675#if BTM_USE_INQ_RESULTS_FILTER == TRUE
1676    tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
1677    tINQ_BDADDR         *p_db = &p_inq->p_bd_db[0];
1678    UINT16       xx;
1679
1680    /* Don't bother searching, database doesn't exist or periodic mode */
1681    if ((p_inq->inq_active & BTM_PERIODIC_INQUIRY_ACTIVE) || !p_db)
1682        return (FALSE);
1683
1684    for (xx = 0; xx < p_inq->num_bd_entries; xx++, p_db++)
1685    {
1686        if (!memcmp(p_db->bd_addr, p_bda, BD_ADDR_LEN)
1687            && p_db->inq_count == p_inq->inq_counter)
1688            return (TRUE);
1689    }
1690
1691    if (xx < p_inq->max_bd_entries)
1692    {
1693        p_db->inq_count = p_inq->inq_counter;
1694        memcpy(p_db->bd_addr, p_bda, BD_ADDR_LEN);
1695        p_inq->num_bd_entries++;
1696    }
1697
1698#endif
1699    /* If here, New Entry */
1700    return (FALSE);
1701}
1702
1703/*******************************************************************************
1704**
1705** Function         btm_inq_db_find
1706**
1707** Description      This function looks through the inquiry database for a match
1708**                  based on Bluetooth Device Address
1709**
1710** Returns          pointer to entry, or NULL if not found
1711**
1712*******************************************************************************/
1713tINQ_DB_ENT *btm_inq_db_find (BD_ADDR p_bda)
1714{
1715    UINT16       xx;
1716    tINQ_DB_ENT  *p_ent = btm_cb.btm_inq_vars.inq_db;
1717
1718    for (xx = 0; xx < BTM_INQ_DB_SIZE; xx++, p_ent++)
1719    {
1720        if ((p_ent->in_use) && (!memcmp (p_ent->inq_info.results.remote_bd_addr, p_bda, BD_ADDR_LEN)))
1721            return (p_ent);
1722    }
1723
1724    /* If here, not found */
1725    return (NULL);
1726}
1727
1728
1729/*******************************************************************************
1730**
1731** Function         btm_inq_db_new
1732**
1733** Description      This function looks through the inquiry database for an unused
1734**                  entry. If no entry is free, it allocates the oldest entry.
1735**
1736** Returns          pointer to entry
1737**
1738*******************************************************************************/
1739tINQ_DB_ENT *btm_inq_db_new (BD_ADDR p_bda)
1740{
1741    UINT16       xx;
1742    tINQ_DB_ENT  *p_ent = btm_cb.btm_inq_vars.inq_db;
1743    tINQ_DB_ENT  *p_old = btm_cb.btm_inq_vars.inq_db;
1744    UINT32       ot = 0xFFFFFFFF;
1745
1746    for (xx = 0; xx < BTM_INQ_DB_SIZE; xx++, p_ent++)
1747    {
1748        if (!p_ent->in_use)
1749        {
1750            memset (p_ent, 0, sizeof (tINQ_DB_ENT));
1751            memcpy (p_ent->inq_info.results.remote_bd_addr, p_bda, BD_ADDR_LEN);
1752            p_ent->in_use = TRUE;
1753
1754            return (p_ent);
1755        }
1756
1757        if (p_ent->time_of_resp < ot)
1758        {
1759            p_old = p_ent;
1760            ot    = p_ent->time_of_resp;
1761        }
1762    }
1763
1764    /* If here, no free entry found. Return the oldest. */
1765
1766    memset (p_old, 0, sizeof (tINQ_DB_ENT));
1767    memcpy (p_old->inq_info.results.remote_bd_addr, p_bda, BD_ADDR_LEN);
1768    p_old->in_use = TRUE;
1769
1770    return (p_old);
1771}
1772
1773
1774/*******************************************************************************
1775**
1776** Function         btm_set_inq_event_filter
1777**
1778** Description      This function is called to set the inquiry event filter.
1779**                  It is called by either internally, or by the external API function
1780**                  (BTM_SetInqEventFilter).  It is used internally as part of the
1781**                  inquiry processing.
1782**
1783** Input Params:
1784**                  filter_cond_type - this is the type of inquiry filter to apply:
1785**                          BTM_FILTER_COND_DEVICE_CLASS,
1786**                          BTM_FILTER_COND_BD_ADDR, or
1787**                          BTM_CLR_INQUIRY_FILTER
1788**
1789**                  p_filt_cond - this is either a BD_ADDR or DEV_CLASS depending on the
1790**                          filter_cond_type  (See section 4.7.3 of Core Spec 1.0b).
1791**
1792** Returns          BTM_CMD_STARTED if successfully initiated
1793**                  BTM_NO_RESOURCES if couldn't get a memory pool buffer
1794**                  BTM_ILLEGAL_VALUE if a bad parameter was detected
1795**
1796*******************************************************************************/
1797static tBTM_STATUS btm_set_inq_event_filter (UINT8 filter_cond_type,
1798                                             tBTM_INQ_FILT_COND *p_filt_cond)
1799{
1800    UINT8    condition_length = DEV_CLASS_LEN * 2;
1801    UINT8    condition_buf[DEV_CLASS_LEN * 2];
1802    UINT8   *p_cond = condition_buf;                    /* points to the condition to pass to HCI */
1803
1804#if (BTM_INQ_DEBUG == TRUE)
1805    BTM_TRACE_DEBUG ("btm_set_inq_event_filter: filter type %d [Clear-0, COD-1, BDADDR-2]",
1806        filter_cond_type);
1807    BTM_TRACE_DEBUG ("                       condition [%02x%02x%02x %02x%02x%02x]",
1808               p_filt_cond->bdaddr_cond[0], p_filt_cond->bdaddr_cond[1], p_filt_cond->bdaddr_cond[2],
1809               p_filt_cond->bdaddr_cond[3], p_filt_cond->bdaddr_cond[4], p_filt_cond->bdaddr_cond[5]);
1810#endif
1811
1812    /* Load the correct filter condition to pass to the lower layer */
1813    switch (filter_cond_type)
1814    {
1815    case BTM_FILTER_COND_DEVICE_CLASS:
1816        /* copy the device class and device class fields into contiguous memory to send to HCI */
1817        memcpy (condition_buf, p_filt_cond->cod_cond.dev_class, DEV_CLASS_LEN);
1818        memcpy (&condition_buf[DEV_CLASS_LEN],
1819                p_filt_cond->cod_cond.dev_class_mask, DEV_CLASS_LEN);
1820
1821        /* condition length should already be set as the default */
1822        break;
1823
1824    case BTM_FILTER_COND_BD_ADDR:
1825        p_cond = p_filt_cond->bdaddr_cond;
1826
1827        /* condition length should already be set as the default */
1828        break;
1829
1830    case BTM_CLR_INQUIRY_FILTER:
1831        condition_length = 0;
1832        break;
1833
1834    default:
1835        return (BTM_ILLEGAL_VALUE);     /* Bad parameter was passed in */
1836    }
1837
1838    btm_cb.btm_inq_vars.inqfilt_active = TRUE;
1839
1840    /* Filter the inquiry results for the specified condition type and value */
1841    if (btsnd_hcic_set_event_filter(HCI_FILTER_INQUIRY_RESULT, filter_cond_type,
1842                                    p_cond, condition_length))
1843
1844        return (BTM_CMD_STARTED);
1845    else
1846        return (BTM_NO_RESOURCES);
1847}
1848
1849
1850/*******************************************************************************
1851**
1852** Function         btm_event_filter_complete
1853**
1854** Description      This function is called when a set event filter has completed.
1855**                  Note: This routine currently only handles inquiry filters.
1856**                      Connection filters are ignored for now.
1857**
1858** Returns          void
1859**
1860*******************************************************************************/
1861void btm_event_filter_complete (UINT8 *p)
1862{
1863    UINT8            hci_status;
1864    tBTM_STATUS      status;
1865    tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
1866    tBTM_CMPL_CB   *p_cb = p_inq->p_inqfilter_cmpl_cb;
1867
1868#if (BTM_INQ_DEBUG == TRUE)
1869    BTM_TRACE_DEBUG ("btm_event_filter_complete: inq_active:0x%x state:%d inqfilt_active:%d",
1870        btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state, btm_cb.btm_inq_vars.inqfilt_active);
1871#endif
1872    /* If the filter complete event is from an old or cancelled request, ignore it */
1873    if(p_inq->pending_filt_complete_event)
1874    {
1875        p_inq->pending_filt_complete_event--;
1876        return;
1877    }
1878
1879    /* Only process the inquiry filter; Ignore the connection filter until it
1880       is used by the upper layers */
1881    if (p_inq->inqfilt_active == TRUE )
1882    {
1883        /* Extract the returned status from the buffer */
1884        STREAM_TO_UINT8 (hci_status, p);
1885        if (hci_status != HCI_SUCCESS)
1886        {
1887            /* If standalone operation, return the error status; if embedded in the inquiry, continue the inquiry */
1888            BTM_TRACE_WARNING ("BTM Warning: Set Event Filter Failed (HCI returned 0x%x)", hci_status);
1889            status = BTM_ERR_PROCESSING;
1890        }
1891        else
1892            status = BTM_SUCCESS;
1893
1894        /* If the set filter was initiated externally (via BTM_SetInqEventFilter), call the
1895           callback function to notify the initiator that it has completed */
1896        if (p_inq->state == BTM_INQ_INACTIVE_STATE)
1897        {
1898            p_inq->inqfilt_active = FALSE;
1899            if (p_cb)
1900                (*p_cb) (&status);
1901        }
1902        else    /* An inquiry is active (the set filter command was internally generated),
1903                   process the next state of the process (Set a new filter or start the inquiry). */
1904        {
1905            if(status != BTM_SUCCESS)
1906            {
1907                /* Process the inquiry complete (Error Status) */
1908                btm_process_inq_complete (BTM_ERR_PROCESSING, (UINT8)(p_inq->inqparms.mode & BTM_BR_INQUIRY_MASK));
1909
1910                /* btm_process_inq_complete() does not restore the following settings on periodic inquiry */
1911                p_inq->inqfilt_active = FALSE;
1912                p_inq->inq_active = BTM_INQUIRY_INACTIVE;
1913                p_inq->state = BTM_INQ_INACTIVE_STATE;
1914
1915                return;
1916            }
1917
1918            /* Check to see if a new filter needs to be set up */
1919            if (p_inq->state == BTM_INQ_CLR_FILT_STATE)
1920            {
1921                if ((status = btm_set_inq_event_filter (p_inq->inqparms.filter_cond_type, &p_inq->inqparms.filter_cond)) == BTM_CMD_STARTED)
1922                {
1923                    p_inq->state = BTM_INQ_SET_FILT_STATE;
1924                }
1925                else    /* Error setting the filter: Call the initiator's callback function to indicate a failure */
1926                {
1927                    p_inq->inqfilt_active = FALSE;
1928
1929                    /* Process the inquiry complete (Error Status) */
1930                    btm_process_inq_complete (BTM_ERR_PROCESSING, (UINT8)(p_inq->inqparms.mode & BTM_BR_INQUIRY_MASK));
1931                }
1932            }
1933            else    /* Initiate the Inquiry or Periodic Inquiry */
1934            {
1935                p_inq->state = BTM_INQ_ACTIVE_STATE;
1936                p_inq->inqfilt_active = FALSE;
1937                btm_initiate_inquiry (p_inq);
1938            }
1939        }
1940    }
1941}
1942
1943
1944/*******************************************************************************
1945**
1946** Function         btm_initiate_inquiry
1947**
1948** Description      This function is called to start an inquiry or periodic inquiry
1949**                  upon completion of the setting and/or clearing of the inquiry filter.
1950**
1951** Inputs:          p_inq (btm_cb.btm_inq_vars) - pointer to saved inquiry information
1952**                      mode - GENERAL or LIMITED inquiry
1953**                      duration - length in 1.28 sec intervals (If '0', the inquiry is CANCELLED)
1954**                      max_resps - maximum amount of devices to search for before ending the inquiry
1955**                      filter_cond_type - BTM_CLR_INQUIRY_FILTER, BTM_FILTER_COND_DEVICE_CLASS, or
1956**                                         BTM_FILTER_COND_BD_ADDR
1957**                      filter_cond - value for the filter (based on filter_cond_type)
1958**
1959** Returns          If an error occurs the initiator's callback is called with the error status.
1960**
1961*******************************************************************************/
1962static void btm_initiate_inquiry (tBTM_INQUIRY_VAR_ST *p_inq)
1963{
1964    const LAP       *lap;
1965    tBTM_INQ_PARMS  *p_inqparms = &p_inq->inqparms;
1966
1967#if (BTM_INQ_DEBUG == TRUE)
1968    BTM_TRACE_DEBUG ("btm_initiate_inquiry: inq_active:0x%x state:%d inqfilt_active:%d",
1969        btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state, btm_cb.btm_inq_vars.inqfilt_active);
1970#endif
1971#if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE)
1972    btm_acl_update_busy_level (BTM_BLI_INQ_EVT);
1973#endif
1974
1975    if (p_inq->inq_active & BTM_SSP_INQUIRY_ACTIVE)
1976    {
1977        btm_process_inq_complete (BTM_NO_RESOURCES, (UINT8)(p_inqparms->mode & BTM_BR_INQUIRY_MASK));
1978        return;
1979    }
1980
1981    /* Make sure the number of responses doesn't overflow the database configuration */
1982    p_inqparms->max_resps = (UINT8)((p_inqparms->max_resps <= BTM_INQ_DB_SIZE) ? p_inqparms->max_resps : BTM_INQ_DB_SIZE);
1983
1984    lap = (p_inq->inq_active & BTM_LIMITED_INQUIRY_ACTIVE) ? &limited_inq_lap : &general_inq_lap;
1985
1986    if (p_inq->inq_active & BTM_PERIODIC_INQUIRY_ACTIVE)
1987    {
1988        if (!btsnd_hcic_per_inq_mode (p_inq->per_max_delay,
1989                                      p_inq->per_min_delay,
1990                                      *lap, p_inqparms->duration,
1991                                      p_inqparms->max_resps))
1992            btm_process_inq_complete (BTM_NO_RESOURCES, (UINT8)(p_inqparms->mode & BTM_BR_INQUIRY_MASK));
1993    }
1994    else
1995    {
1996#if BTM_USE_INQ_RESULTS_FILTER == TRUE
1997        btm_clr_inq_result_flt();
1998
1999        /* Allocate memory to hold bd_addrs responding */
2000        if ((p_inq->p_bd_db = (tINQ_BDADDR *)GKI_getbuf(GKI_MAX_BUF_SIZE)) != NULL)
2001        {
2002            p_inq->max_bd_entries = (UINT16)(GKI_MAX_BUF_SIZE / sizeof(tINQ_BDADDR));
2003            memset(p_inq->p_bd_db, 0, GKI_MAX_BUF_SIZE);
2004/*            BTM_TRACE_DEBUG("btm_initiate_inquiry: memory allocated for %d bdaddrs",
2005                              p_inq->max_bd_entries); */
2006        }
2007
2008        if (!btsnd_hcic_inquiry(*lap, p_inqparms->duration, 0))
2009#else
2010        if (!btsnd_hcic_inquiry(*lap, p_inqparms->duration, p_inqparms->max_resps))
2011#endif /* BTM_USE_INQ_RESULTS_FILTER */
2012            btm_process_inq_complete (BTM_NO_RESOURCES, (UINT8)(p_inqparms->mode & BTM_BR_INQUIRY_MASK));
2013    }
2014}
2015
2016/*******************************************************************************
2017**
2018** Function         btm_process_inq_results
2019**
2020** Description      This function is called when inquiry results are received from
2021**                  the device. It updates the inquiry database. If the inquiry
2022**                  database is full, the oldest entry is discarded.
2023**
2024** Parameters       inq_res_mode - BTM_INQ_RESULT_STANDARD
2025**                                 BTM_INQ_RESULT_WITH_RSSI
2026**                                 BTM_INQ_RESULT_EXTENDED
2027**
2028** Returns          void
2029**
2030*******************************************************************************/
2031void btm_process_inq_results (UINT8 *p, UINT8 inq_res_mode)
2032{
2033    UINT8            num_resp, xx;
2034    BD_ADDR          bda;
2035    tINQ_DB_ENT     *p_i;
2036    tBTM_INQ_RESULTS *p_cur=NULL;
2037    BOOLEAN          is_new = TRUE;
2038    BOOLEAN          update = FALSE;
2039    INT8             i_rssi;
2040    tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
2041    tBTM_INQ_RESULTS_CB *p_inq_results_cb = p_inq->p_inq_results_cb;
2042    UINT8            page_scan_rep_mode = 0;
2043    UINT8            page_scan_per_mode = 0;
2044    UINT8            page_scan_mode = 0;
2045    UINT8            rssi = 0;
2046    DEV_CLASS        dc;
2047    UINT16           clock_offset;
2048#if (BTM_EIR_CLIENT_INCLUDED == TRUE)
2049    UINT8            *p_eir_data = NULL;
2050#endif
2051
2052#if (BTM_INQ_DEBUG == TRUE)
2053    BTM_TRACE_DEBUG ("btm_process_inq_results inq_active:0x%x state:%d inqfilt_active:%d",
2054        btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state, btm_cb.btm_inq_vars.inqfilt_active);
2055#endif
2056    /* Only process the results if the BR inquiry is still active */
2057    if (!(p_inq->inq_active & BTM_BR_INQ_ACTIVE_MASK))
2058        return;
2059
2060    STREAM_TO_UINT8 (num_resp, p);
2061
2062    for (xx = 0; xx < num_resp; xx++)
2063    {
2064        update = FALSE;
2065        /* Extract inquiry results */
2066        STREAM_TO_BDADDR   (bda, p);
2067        STREAM_TO_UINT8    (page_scan_rep_mode, p);
2068        STREAM_TO_UINT8    (page_scan_per_mode, p);
2069
2070        if (inq_res_mode == BTM_INQ_RESULT_STANDARD)
2071        {
2072            STREAM_TO_UINT8(page_scan_mode, p);
2073        }
2074
2075        STREAM_TO_DEVCLASS (dc, p);
2076        STREAM_TO_UINT16   (clock_offset, p);
2077        if (inq_res_mode != BTM_INQ_RESULT_STANDARD)
2078        {
2079            STREAM_TO_UINT8(rssi, p);
2080        }
2081
2082        p_i = btm_inq_db_find (bda);
2083
2084#if BTM_USE_INQ_RESULTS_FILTER == TRUE
2085        /* Only process the num_resp is smaller than max_resps.
2086           If results are queued to BTU task while canceling inquiry,
2087           or when more than one result is in this response, > max_resp
2088           responses could be processed which can confuse some apps
2089        */
2090        if (p_inq->inqparms.max_resps &&
2091            p_inq->inq_cmpl_info.num_resp >= p_inq->inqparms.max_resps
2092#if BLE_INCLUDED == TRUE
2093            /* new device response */
2094            && ( p_i == NULL ||
2095                /* exisiting device with BR/EDR info */
2096                (p_i && (p_i->inq_info.results.device_type & BT_DEVICE_TYPE_BREDR) != 0)
2097               )
2098#endif
2099
2100            )
2101        {
2102/*            BTM_TRACE_WARNING("INQ RES: Extra Response Received...ignoring"); */
2103            return;
2104        }
2105#endif
2106
2107        /* Check if this address has already been processed for this inquiry */
2108        if (btm_inq_find_bdaddr(bda))
2109        {
2110/*             BTM_TRACE_DEBUG("BDA seen before [%02x%02x %02x%02x %02x%02x]",
2111                             bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);*/
2112             /* By default suppose no update needed */
2113            i_rssi = (INT8)rssi;
2114
2115            /* If this new RSSI is higher than the last one */
2116            if(p_inq->inqparms.report_dup && (rssi != 0) &&
2117               p_i && (i_rssi > p_i->inq_info.results.rssi || p_i->inq_info.results.rssi == 0
2118#if BLE_INCLUDED == TRUE
2119               /* BR/EDR inquiry information update */
2120                       || (p_i->inq_info.results.device_type & BT_DEVICE_TYPE_BREDR) != 0
2121#endif
2122                       ))
2123            {
2124                p_cur = &p_i->inq_info.results;
2125                BTM_TRACE_DEBUG("update RSSI new:%d, old:%d", i_rssi, p_cur->rssi);
2126                p_cur->rssi = i_rssi;
2127                update = TRUE;
2128            }
2129            /* If we received a second Extended Inq Event for an already */
2130            /* discovered device, this is because for the first one EIR was not received */
2131            else if ((inq_res_mode == BTM_INQ_RESULT_EXTENDED) && (p_i))
2132            {
2133                p_cur = &p_i->inq_info.results;
2134                update = TRUE;
2135            }
2136            /* If no update needed continue with next response (if any) */
2137            else
2138                continue;
2139        }
2140
2141        /* Host can be registered to verify comming BDA or DC */
2142        if (btm_cb.p_inq_filter_cb)
2143        {
2144            if (!(* btm_cb.p_inq_filter_cb) (bda, dc))
2145            {
2146                continue;
2147            }
2148        }
2149
2150        /* If existing entry, use that, else get a new one (possibly reusing the oldest) */
2151        if (p_i == NULL)
2152        {
2153            p_i = btm_inq_db_new (bda);
2154            is_new = TRUE;
2155        }
2156
2157        /* If an entry for the device already exists, overwrite it ONLY if it is from
2158           a previous inquiry. (Ignore it if it is a duplicate response from the same
2159           inquiry.
2160        */
2161        else if (p_i->inq_count == p_inq->inq_counter
2162#if (BLE_INCLUDED == TRUE )
2163            && (p_i->inq_info.results.device_type & BT_DEVICE_TYPE_BREDR)
2164#endif
2165            )
2166            is_new = FALSE;
2167
2168        /* keep updating RSSI to have latest value */
2169        if( inq_res_mode != BTM_INQ_RESULT_STANDARD )
2170            p_i->inq_info.results.rssi = (INT8)rssi;
2171        else
2172            p_i->inq_info.results.rssi = BTM_INQ_RES_IGNORE_RSSI;
2173
2174        if (is_new == TRUE)
2175        {
2176            /* Save the info */
2177            p_cur = &p_i->inq_info.results;
2178            p_cur->page_scan_rep_mode = page_scan_rep_mode;
2179            p_cur->page_scan_per_mode = page_scan_per_mode;
2180            p_cur->page_scan_mode     = page_scan_mode;
2181            p_cur->dev_class[0]       = dc[0];
2182            p_cur->dev_class[1]       = dc[1];
2183            p_cur->dev_class[2]       = dc[2];
2184            p_cur->clock_offset       = clock_offset  | BTM_CLOCK_OFFSET_VALID;
2185
2186            p_i->time_of_resp = GKI_get_tick_count ();
2187
2188            if (p_i->inq_count != p_inq->inq_counter)
2189                p_inq->inq_cmpl_info.num_resp++;       /* A new response was found */
2190
2191#if (defined BLE_INCLUDED && BLE_INCLUDED == TRUE)
2192            p_cur->inq_result_type    = BTM_INQ_RESULT_BR;
2193            if (p_i->inq_count != p_inq->inq_counter)
2194            {
2195                p_cur->device_type  = BT_DEVICE_TYPE_BREDR;
2196                p_i->scan_rsp       = FALSE;
2197            }
2198            else
2199                p_cur->device_type    |= BT_DEVICE_TYPE_BREDR;
2200#endif
2201                p_i->inq_count = p_inq->inq_counter;   /* Mark entry for current inquiry */
2202
2203#if BTM_USE_INQ_RESULTS_FILTER == TRUE
2204            /* If the number of responses found and not unlimited, issue a cancel inquiry */
2205            if (!(p_inq->inq_active & BTM_PERIODIC_INQUIRY_ACTIVE) &&
2206                p_inq->inqparms.max_resps &&
2207                p_inq->inq_cmpl_info.num_resp == p_inq->inqparms.max_resps
2208#if BLE_INCLUDED == TRUE
2209                /* BLE scanning is active and received adv */
2210                && ((((p_inq->inqparms.mode & BTM_BLE_INQUIRY_MASK) != 0) &&
2211                     p_cur->device_type == BT_DEVICE_TYPE_DUMO && p_i->scan_rsp) ||
2212                    (p_inq->inqparms.mode & BTM_BLE_INQUIRY_MASK) == 0)
2213#endif
2214                )
2215            {
2216/*                BTM_TRACE_DEBUG("BTMINQ: Found devices, cancelling inquiry..."); */
2217                btsnd_hcic_inq_cancel();
2218
2219#if BLE_INCLUDED == TRUE
2220                if ((p_inq->inqparms.mode & BTM_BLE_INQUIRY_MASK) != 0)
2221                    btm_ble_stop_inquiry();
2222#endif
2223
2224
2225#if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE)
2226                btm_acl_update_busy_level (BTM_BLI_INQ_DONE_EVT);
2227#endif
2228            }
2229#endif
2230            /* Initialize flag to FALSE. This flag is set/used by application */
2231            p_i->inq_info.appl_knows_rem_name = FALSE;
2232        }
2233
2234        if (is_new || update)
2235        {
2236#if (BTM_EIR_CLIENT_INCLUDED == TRUE)
2237            if( inq_res_mode == BTM_INQ_RESULT_EXTENDED )
2238            {
2239                memset( p_cur->eir_uuid, 0,
2240                        BTM_EIR_SERVICE_ARRAY_SIZE * (BTM_EIR_ARRAY_BITS/8));
2241                /* set bit map of UUID list from received EIR */
2242                btm_set_eir_uuid( p, p_cur );
2243                p_eir_data = p;
2244            }
2245            else
2246                p_eir_data = NULL;
2247#endif
2248
2249            /* If a callback is registered, call it with the results */
2250            if (p_inq_results_cb)
2251#if (BTM_EIR_CLIENT_INCLUDED == TRUE)
2252                (p_inq_results_cb)((tBTM_INQ_RESULTS *) p_cur, p_eir_data);
2253#else
2254                (p_inq_results_cb)((tBTM_INQ_RESULTS *) p_cur, NULL);
2255#endif
2256        }
2257    }
2258}
2259
2260/*******************************************************************************
2261**
2262** Function         btm_sort_inq_result
2263**
2264** Description      This function is called when inquiry complete is received
2265**                  from the device to sort inquiry results based on rssi.
2266**
2267** Returns          void
2268**
2269*******************************************************************************/
2270void btm_sort_inq_result(void)
2271{
2272    UINT8               xx, yy, num_resp;
2273    tINQ_DB_ENT         *p_tmp  = NULL;
2274    tINQ_DB_ENT         *p_ent  = btm_cb.btm_inq_vars.inq_db;
2275    tINQ_DB_ENT         *p_next = btm_cb.btm_inq_vars.inq_db+1;
2276    int                 size;
2277
2278    num_resp = (btm_cb.btm_inq_vars.inq_cmpl_info.num_resp<BTM_INQ_DB_SIZE)?
2279                btm_cb.btm_inq_vars.inq_cmpl_info.num_resp: BTM_INQ_DB_SIZE;
2280
2281    if((p_tmp = (tINQ_DB_ENT *)GKI_getbuf(sizeof(tINQ_DB_ENT))) != NULL)
2282    {
2283        size = sizeof(tINQ_DB_ENT);
2284        for(xx = 0; xx < num_resp-1; xx++, p_ent++)
2285        {
2286            for(yy = xx+1, p_next = p_ent+1; yy < num_resp; yy++, p_next++)
2287            {
2288                if(p_ent->inq_info.results.rssi < p_next->inq_info.results.rssi)
2289                {
2290                    memcpy (p_tmp,  p_next, size);
2291                    memcpy (p_next, p_ent,  size);
2292                    memcpy (p_ent,  p_tmp,  size);
2293                }
2294            }
2295        }
2296
2297        GKI_freebuf(p_tmp);
2298    }
2299}
2300
2301/*******************************************************************************
2302**
2303** Function         btm_process_inq_complete
2304**
2305** Description      This function is called when inquiry complete is received
2306**                  from the device.  Call the callback if not in periodic inquiry
2307**                  mode AND it is not NULL (The caller wants the event).
2308**
2309**                  The callback pass back the status and the number of responses
2310**
2311** Returns          void
2312**
2313*******************************************************************************/
2314void btm_process_inq_complete (UINT8 status, UINT8 mode)
2315{
2316    tBTM_CMPL_CB        *p_inq_cb = btm_cb.btm_inq_vars.p_inq_cmpl_cb;
2317    tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
2318
2319#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE)
2320    /* inquiry inactive case happens when inquiry is cancelled.
2321       Make mode 0 for no further inquiries from the current inquiry process
2322    */
2323    if(status!=HCI_SUCCESS || p_inq->next_state==BTM_FINISH || !p_inq->inq_active)
2324    {
2325        /* re-initialize for next inquiry request */
2326        p_inq->next_state=BTM_BR_ONE;
2327        /* make the mode 0 here */
2328        p_inq->inqparms.mode &= ~(p_inq->inqparms.mode);
2329
2330    }
2331#endif
2332
2333#if (!defined(BTA_HOST_INTERLEAVE_SEARCH) || BTA_HOST_INTERLEAVE_SEARCH == FALSE)
2334    p_inq->inqparms.mode &= ~(mode);
2335#endif
2336
2337    if(p_inq->scan_type == INQ_LE_OBSERVE && !p_inq->inq_active)
2338    {
2339        /*end of LE observe*/
2340        p_inq->p_inq_ble_results_cb = (tBTM_INQ_RESULTS_CB *) NULL;
2341        p_inq->p_inq_ble_cmpl_cb = (tBTM_CMPL_CB *) NULL;
2342        p_inq->scan_type=INQ_NONE;
2343    }
2344
2345
2346#if (BTM_INQ_DEBUG == TRUE)
2347    BTM_TRACE_DEBUG ("btm_process_inq_complete inq_active:0x%x state:%d inqfilt_active:%d",
2348        btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state, btm_cb.btm_inq_vars.inqfilt_active);
2349#endif
2350#if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE)
2351    btm_acl_update_busy_level (BTM_BLI_INQ_DONE_EVT);
2352#endif
2353    /* Ignore any stray or late complete messages if the inquiry is not active */
2354    if (p_inq->inq_active)
2355    {
2356        p_inq->inq_cmpl_info.status = (tBTM_STATUS)((status == HCI_SUCCESS) ? BTM_SUCCESS : BTM_ERR_PROCESSING);
2357
2358        /* Notify caller that the inquiry has completed; (periodic inquiries do not send completion events */
2359        if (!(p_inq->inq_active & BTM_PERIODIC_INQUIRY_ACTIVE) && p_inq->inqparms.mode == 0)
2360        {
2361            p_inq->state = BTM_INQ_INACTIVE_STATE;
2362
2363            /* Increment so the start of a next inquiry has a new count */
2364            p_inq->inq_counter++;
2365
2366            btm_clr_inq_result_flt();
2367
2368            if((p_inq->inq_cmpl_info.status == BTM_SUCCESS) &&
2369                HCI_LMP_INQ_RSSI_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_0]))
2370            {
2371                btm_sort_inq_result();
2372            }
2373
2374            /* Clear the results callback if set */
2375            p_inq->p_inq_results_cb = (tBTM_INQ_RESULTS_CB *) NULL;
2376            p_inq->inq_active = BTM_INQUIRY_INACTIVE;
2377            p_inq->p_inq_cmpl_cb = (tBTM_CMPL_CB *) NULL;
2378
2379            /* If we have a callback registered for inquiry complete, call it */
2380            BTM_TRACE_DEBUG ("BTM Inq Compl Callback: status 0x%02x, num results %d",
2381                        p_inq->inq_cmpl_info.status, p_inq->inq_cmpl_info.num_resp);
2382
2383            if (p_inq_cb)
2384                (p_inq_cb)((tBTM_INQUIRY_CMPL *) &p_inq->inq_cmpl_info);
2385        }
2386#if (defined(BTA_HOST_INTERLEAVE_SEARCH) && BTA_HOST_INTERLEAVE_SEARCH == TRUE)
2387        if(p_inq->inqparms.mode != 0 && !(p_inq->inq_active & BTM_PERIODIC_INQUIRY_ACTIVE))
2388        {
2389            /* make inquiry inactive for next iteration */
2390            p_inq->inq_active = BTM_INQUIRY_INACTIVE;
2391            /* call the inquiry again */
2392            BTM_StartInquiry(&p_inq->inqparms,p_inq->p_inq_results_cb,p_inq->p_inq_cmpl_cb);
2393        }
2394#endif
2395    }
2396    if(p_inq->inqparms.mode == 0 && p_inq->scan_type == INQ_GENERAL)//this inquiry is complete
2397    {
2398        p_inq->scan_type = INQ_NONE;
2399#if (defined BLE_INCLUDED && BLE_INCLUDED == TRUE)
2400        /* check if the LE observe is pending */
2401        if(p_inq->p_inq_ble_results_cb != NULL)
2402        {
2403            BTM_TRACE_DEBUG("BTM Inq Compl: resuming a pending LE scan");
2404            BTM_BleObserve(1,0, p_inq->p_inq_ble_results_cb, p_inq->p_inq_ble_cmpl_cb);
2405        }
2406#endif
2407    }
2408#if (BTM_INQ_DEBUG == TRUE)
2409    BTM_TRACE_DEBUG ("inq_active:0x%x state:%d inqfilt_active:%d",
2410        btm_cb.btm_inq_vars.inq_active, btm_cb.btm_inq_vars.state, btm_cb.btm_inq_vars.inqfilt_active);
2411#endif
2412}
2413
2414/*******************************************************************************
2415**
2416** Function         btm_process_cancel_complete
2417**
2418** Description      This function is called when inquiry cancel complete is received
2419**                  from the device.This function will also call the btm_process_inq_complete
2420**                  This function is needed to differentiate a cancel_cmpl_evt from the
2421**                  inq_cmpl_evt
2422**
2423** Returns          void
2424**
2425*******************************************************************************/
2426void btm_process_cancel_complete(UINT8 status, UINT8 mode)
2427{
2428#if (defined(BTM_BUSY_LEVEL_CHANGE_INCLUDED) && BTM_BUSY_LEVEL_CHANGE_INCLUDED == TRUE)
2429     btm_acl_update_busy_level (BTM_BLI_INQ_CANCEL_EVT);
2430#endif
2431     btm_process_inq_complete(status, mode);
2432}
2433/*******************************************************************************
2434**
2435** Function         btm_initiate_rem_name
2436**
2437** Description      This function looks initiates a remote name request.  It is called
2438**                  either by GAP or by the API call BTM_ReadRemoteDeviceName.
2439**
2440** Input Params:    p_cur         - pointer to an inquiry result structure (NULL if nonexistent)
2441**                  p_cb            - callback function called when BTM_CMD_STARTED
2442**                                    is returned.
2443**                                    A pointer to tBTM_REMOTE_DEV_NAME is passed to the
2444**                                    callback.
2445**
2446** Returns
2447**                  BTM_CMD_STARTED is returned if the request was sent to HCI.
2448**                  BTM_BUSY if already in progress
2449**                  BTM_NO_RESOURCES if could not allocate resources to start the command
2450**                  BTM_WRONG_MODE if the device is not up.
2451**
2452*******************************************************************************/
2453tBTM_STATUS  btm_initiate_rem_name (BD_ADDR remote_bda, tBTM_INQ_INFO *p_cur,
2454                                    UINT8 origin, UINT32 timeout, tBTM_CMPL_CB *p_cb)
2455{
2456    tBTM_INQUIRY_VAR_ST *p_inq = &btm_cb.btm_inq_vars;
2457    BOOLEAN              cmd_ok;
2458
2459
2460    /*** Make sure the device is ready ***/
2461    if (!BTM_IsDeviceUp())
2462        return (BTM_WRONG_MODE);
2463
2464
2465    if (origin == BTM_RMT_NAME_SEC)
2466    {
2467        cmd_ok = btsnd_hcic_rmt_name_req (remote_bda, HCI_PAGE_SCAN_REP_MODE_R1,
2468                                         HCI_MANDATARY_PAGE_SCAN_MODE, 0);
2469        if (cmd_ok)
2470            return BTM_CMD_STARTED;
2471        else
2472            return BTM_NO_RESOURCES;
2473    }
2474    /* Make sure there are no two remote name requests from external API in progress */
2475    else if (origin == BTM_RMT_NAME_EXT)
2476    {
2477        if (p_inq->remname_active)
2478        {
2479            return (BTM_BUSY);
2480        }
2481        else
2482        {
2483            /* If there is no remote name request running,call the callback function and start timer */
2484            p_inq->p_remname_cmpl_cb = p_cb;
2485            memcpy(p_inq->remname_bda, remote_bda, BD_ADDR_LEN);
2486            btu_start_timer (&p_inq->rmt_name_timer_ent,
2487                             BTU_TTYPE_BTM_RMT_NAME,
2488                             timeout);
2489
2490            /* If the database entry exists for the device, use its clock offset */
2491            if (p_cur)
2492            {
2493                cmd_ok = btsnd_hcic_rmt_name_req (remote_bda,
2494                                         p_cur->results.page_scan_rep_mode,
2495                                         p_cur->results.page_scan_mode,
2496                                         (UINT16)(p_cur->results.clock_offset |
2497                                                  BTM_CLOCK_OFFSET_VALID));
2498            }
2499            else /* Otherwise use defaults and mark the clock offset as invalid */
2500            {
2501                cmd_ok = btsnd_hcic_rmt_name_req (remote_bda, HCI_PAGE_SCAN_REP_MODE_R1,
2502                                         HCI_MANDATARY_PAGE_SCAN_MODE, 0);
2503            }
2504            if (cmd_ok)
2505            {
2506                p_inq->remname_active = TRUE;
2507                return BTM_CMD_STARTED;
2508            }
2509            else
2510                return BTM_NO_RESOURCES;
2511        }
2512    }
2513    else
2514    {
2515        return BTM_ILLEGAL_VALUE;
2516    }
2517}
2518
2519/*******************************************************************************
2520**
2521** Function         btm_process_remote_name
2522**
2523** Description      This function is called when a remote name is received from
2524**                  the device. If remote names are cached, it updates the inquiry
2525**                  database.
2526**
2527** Returns          void
2528**
2529*******************************************************************************/
2530void btm_process_remote_name (BD_ADDR bda, BD_NAME bdn, UINT16 evt_len, UINT8 hci_status)
2531{
2532    tBTM_REMOTE_DEV_NAME    rem_name;
2533    tBTM_INQUIRY_VAR_ST    *p_inq = &btm_cb.btm_inq_vars;
2534    tBTM_CMPL_CB           *p_cb = p_inq->p_remname_cmpl_cb;
2535    UINT8                  *p_n1;
2536
2537    UINT16                 temp_evt_len;
2538
2539    if (bda != NULL)
2540    {
2541        BTM_TRACE_EVENT("BDA %02x:%02x:%02x:%02x:%02x:%02x",bda[0], bda[1],
2542                 bda[2], bda[3],
2543                 bda[4], bda[5]);
2544    }
2545
2546    BTM_TRACE_EVENT("Inquire BDA %02x:%02x:%02x:%02x:%02x:%02x",p_inq->remname_bda[0], p_inq->remname_bda[1],
2547             p_inq->remname_bda[2], p_inq->remname_bda[3],
2548             p_inq->remname_bda[4], p_inq->remname_bda[5]);
2549
2550
2551
2552    /* If the inquire BDA and remote DBA are the same, then stop the timer and set the active to false */
2553    if ((p_inq->remname_active ==TRUE)&&
2554        (((bda != NULL) &&
2555        (memcmp(bda, p_inq->remname_bda,BD_ADDR_LEN)==0)) || bda == NULL))
2556
2557    {
2558#if BLE_INCLUDED == TRUE
2559        if (BTM_UseLeLink(p_inq->remname_bda))
2560        {
2561            if (hci_status == HCI_ERR_UNSPECIFIED)
2562                btm_ble_cancel_remote_name(p_inq->remname_bda);
2563        }
2564#endif
2565        btu_stop_timer (&p_inq->rmt_name_timer_ent);
2566        p_inq->remname_active = FALSE;
2567         /* Clean up and return the status if the command was not successful */
2568         /* Note: If part of the inquiry, the name is not stored, and the    */
2569         /*       inquiry complete callback is called.                       */
2570
2571        if ((hci_status == HCI_SUCCESS))
2572        {
2573            /* Copy the name from the data stream into the return structure */
2574            /* Note that even if it is not being returned, it is used as a  */
2575            /*      temporary buffer.                                       */
2576            p_n1 = (UINT8 *)rem_name.remote_bd_name;
2577            rem_name.length = (evt_len < BD_NAME_LEN) ? evt_len : BD_NAME_LEN;
2578            rem_name.remote_bd_name[rem_name.length] = 0;
2579            rem_name.status = BTM_SUCCESS;
2580            temp_evt_len = rem_name.length;
2581
2582            while (temp_evt_len > 0)
2583            {
2584                *p_n1++ = *bdn++;
2585                temp_evt_len--;
2586            }
2587            rem_name.remote_bd_name[rem_name.length] = 0;
2588        }
2589
2590
2591        /* If processing a stand alone remote name then report the error in the callback */
2592        else
2593        {
2594            rem_name.status = BTM_BAD_VALUE_RET;
2595            rem_name.length = 0;
2596            rem_name.remote_bd_name[0] = 0;
2597        }
2598        /* Reset the remote BAD to zero and call callback if possible */
2599        memset(p_inq->remname_bda, 0, BD_ADDR_LEN);
2600
2601        p_inq->p_remname_cmpl_cb = NULL;
2602        if (p_cb)
2603            (p_cb)((tBTM_REMOTE_DEV_NAME *)&rem_name);
2604    }
2605}
2606
2607/*******************************************************************************
2608**
2609** Function         btm_inq_rmt_name_failed
2610**
2611** Description      This function is if timeout expires while getting remote
2612**                  name.  This is done for devices that incorrectly do not
2613**                  report operation failure
2614**
2615** Returns          void
2616**
2617*******************************************************************************/
2618void btm_inq_rmt_name_failed (void)
2619{
2620    BTM_TRACE_ERROR ("btm_inq_rmt_name_failed()  remname_active=%d", btm_cb.btm_inq_vars.remname_active);
2621
2622    if (btm_cb.btm_inq_vars.remname_active)
2623        btm_process_remote_name (btm_cb.btm_inq_vars.remname_bda, NULL, 0, HCI_ERR_UNSPECIFIED);
2624    else
2625        btm_process_remote_name (NULL, NULL, 0, HCI_ERR_UNSPECIFIED);
2626
2627    btm_sec_rmt_name_request_complete (NULL, NULL, HCI_ERR_UNSPECIFIED);
2628}
2629/*******************************************************************************
2630**
2631** Function         btm_read_linq_tx_power_complete
2632**
2633** Description      read inquiry tx power level complete callback function.
2634**
2635** Returns          void
2636**
2637*******************************************************************************/
2638void btm_read_linq_tx_power_complete(UINT8 *p)
2639{
2640    tBTM_CMPL_CB                *p_cb = btm_cb.devcb.p_txpwer_cmpl_cb;
2641    tBTM_INQ_TXPWR_RESULTS        results;
2642
2643    btu_stop_timer (&btm_cb.devcb.txpwer_timer);
2644    /* If there was a callback registered for read inq tx power, call it */
2645    btm_cb.devcb.p_txpwer_cmpl_cb = NULL;
2646
2647    if (p_cb)
2648    {
2649        STREAM_TO_UINT8  (results.hci_status, p);
2650
2651        if (results.hci_status == HCI_SUCCESS)
2652        {
2653            results.status = BTM_SUCCESS;
2654
2655            STREAM_TO_UINT8 (results.tx_power, p);
2656            BTM_TRACE_EVENT ("BTM INQ TX POWER Complete: tx_power %d, hci status 0x%02x",
2657                              results.tx_power, results.hci_status);
2658        }
2659        else
2660            results.status = BTM_ERR_PROCESSING;
2661
2662        (*p_cb)(&results);
2663    }
2664
2665}
2666/*******************************************************************************
2667**
2668** Function         BTM_WriteEIR
2669**
2670** Description      This function is called to write EIR data to controller.
2671**
2672** Parameters       p_buff - allocated HCI command buffer including extended
2673**                           inquriry response
2674**
2675** Returns          BTM_SUCCESS  - if successful
2676**                  BTM_MODE_UNSUPPORTED - if local device cannot support it
2677**
2678*******************************************************************************/
2679tBTM_STATUS BTM_WriteEIR( BT_HDR *p_buff )
2680{
2681#if (BTM_EIR_SERVER_INCLUDED == TRUE)
2682    if (HCI_EXT_INQ_RSP_SUPPORTED(btm_cb.devcb.local_lmp_features[HCI_EXT_FEATURES_PAGE_0]))
2683    {
2684        BTM_TRACE_API("Write Extended Inquiry Response to controller");
2685        btsnd_hcic_write_ext_inquiry_response (p_buff, BTM_EIR_DEFAULT_FEC_REQUIRED);
2686        return BTM_SUCCESS;
2687    }
2688    else
2689    {
2690        GKI_freebuf(p_buff);
2691        return BTM_MODE_UNSUPPORTED;
2692    }
2693#else
2694    GKI_freebuf(p_buff);
2695    return BTM_SUCCESS;
2696#endif
2697}
2698
2699/*******************************************************************************
2700**
2701** Function         BTM_CheckEirData
2702**
2703** Description      This function is called to get EIR data from significant part.
2704**
2705** Parameters       p_eir - pointer of EIR significant part
2706**                  type   - finding EIR data type
2707**                  p_length - return the length of EIR data not including type
2708**
2709** Returns          pointer of EIR data
2710**
2711*******************************************************************************/
2712UINT8 *BTM_CheckEirData( UINT8 *p_eir, UINT8 type, UINT8 *p_length )
2713{
2714#if (BTM_EIR_CLIENT_INCLUDED == TRUE)
2715    UINT8 *p = p_eir;
2716    UINT8 length;
2717    UINT8 eir_type;
2718    BTM_TRACE_API("BTM_CheckEirData type=0x%02X", type);
2719
2720    STREAM_TO_UINT8(length, p);
2721    while( length && (p - p_eir <= HCI_EXT_INQ_RESPONSE_LEN))
2722    {
2723        STREAM_TO_UINT8(eir_type, p);
2724        if( eir_type == type )
2725        {
2726            /* length doesn't include itself */
2727            *p_length = length - 1; /* minus the length of type */
2728            return p;
2729        }
2730        p += length - 1; /* skip the length of data */
2731        STREAM_TO_UINT8(length, p);
2732    }
2733
2734    *p_length = 0;
2735    return NULL;
2736#else
2737    return NULL;
2738#endif
2739}
2740
2741/*******************************************************************************
2742**
2743** Function         btm_convert_uuid_to_eir_service
2744**
2745** Description      This function is called to get the bit position of UUID.
2746**
2747** Parameters       uuid16 - UUID 16-bit
2748**
2749** Returns          BTM EIR service ID if found
2750**                  BTM_EIR_MAX_SERVICES - if not found
2751**
2752*******************************************************************************/
2753#if (( BTM_EIR_CLIENT_INCLUDED == TRUE )||( BTM_EIR_SERVER_INCLUDED == TRUE ))
2754static UINT8 btm_convert_uuid_to_eir_service( UINT16 uuid16 )
2755{
2756    UINT8 xx;
2757
2758    for( xx = 0; xx < BTM_EIR_MAX_SERVICES; xx++ )
2759    {
2760        if( uuid16 == BTM_EIR_UUID_LKUP_TBL[xx])
2761        {
2762            return xx;
2763        }
2764    }
2765    return BTM_EIR_MAX_SERVICES;
2766}
2767#endif
2768
2769/*******************************************************************************
2770**
2771** Function         BTM_HasEirService
2772**
2773** Description      This function is called to know if UUID in bit map of UUID.
2774**
2775** Parameters       p_eir_uuid - bit map of UUID list
2776**                  uuid16 - UUID 16-bit
2777**
2778** Returns          TRUE - if found
2779**                  FALSE - if not found
2780**
2781*******************************************************************************/
2782BOOLEAN BTM_HasEirService( UINT32 *p_eir_uuid, UINT16 uuid16 )
2783{
2784#if ((BTM_EIR_SERVER_INCLUDED == TRUE)||(BTM_EIR_CLIENT_INCLUDED == TRUE))
2785    UINT8 service_id;
2786
2787    service_id = btm_convert_uuid_to_eir_service(uuid16);
2788    if( service_id < BTM_EIR_MAX_SERVICES )
2789        return( BTM_EIR_HAS_SERVICE( p_eir_uuid, service_id ));
2790    else
2791        return( FALSE );
2792#else
2793    return( FALSE );
2794#endif
2795}
2796
2797/*******************************************************************************
2798**
2799** Function         BTM_HasInquiryEirService
2800**
2801** Description      This function is called to know if UUID in bit map of UUID list.
2802**
2803** Parameters       p_results - inquiry results
2804**                  uuid16 - UUID 16-bit
2805**
2806** Returns          BTM_EIR_FOUND - if found
2807**                  BTM_EIR_NOT_FOUND - if not found and it is complete list
2808**                  BTM_EIR_UNKNOWN - if not found and it is not complete list
2809**
2810*******************************************************************************/
2811tBTM_EIR_SEARCH_RESULT BTM_HasInquiryEirService( tBTM_INQ_RESULTS *p_results, UINT16 uuid16 )
2812{
2813#if ((BTM_EIR_SERVER_INCLUDED == TRUE)||(BTM_EIR_CLIENT_INCLUDED == TRUE))
2814    if( BTM_HasEirService( p_results->eir_uuid, uuid16 ))
2815    {
2816        return BTM_EIR_FOUND;
2817    }
2818    else if( p_results->eir_complete_list )
2819    {
2820        return BTM_EIR_NOT_FOUND;
2821    }
2822    else
2823        return BTM_EIR_UNKNOWN;
2824#else
2825    return BTM_EIR_UNKNOWN;
2826#endif
2827}
2828
2829/*******************************************************************************
2830**
2831** Function         BTM_AddEirService
2832**
2833** Description      This function is called to add a service in bit map of UUID list.
2834**
2835** Parameters       p_eir_uuid - bit mask of UUID list for EIR
2836**                  uuid16 - UUID 16-bit
2837**
2838** Returns          None
2839**
2840*******************************************************************************/
2841void BTM_AddEirService( UINT32 *p_eir_uuid, UINT16 uuid16 )
2842{
2843#if ((BTM_EIR_SERVER_INCLUDED == TRUE)||(BTM_EIR_CLIENT_INCLUDED == TRUE))
2844    UINT8 service_id;
2845
2846    service_id = btm_convert_uuid_to_eir_service(uuid16);
2847    if( service_id < BTM_EIR_MAX_SERVICES )
2848        BTM_EIR_SET_SERVICE( p_eir_uuid, service_id );
2849#endif
2850}
2851
2852/*******************************************************************************
2853**
2854** Function         BTM_RemoveEirService
2855**
2856** Description      This function is called to remove a service in bit map of UUID list.
2857**
2858** Parameters       p_eir_uuid - bit mask of UUID list for EIR
2859**                  uuid16 - UUID 16-bit
2860**
2861** Returns          None
2862**
2863*******************************************************************************/
2864void BTM_RemoveEirService( UINT32 *p_eir_uuid, UINT16 uuid16 )
2865{
2866#if (BTM_EIR_SERVER_INCLUDED == TRUE)
2867    UINT8 service_id;
2868
2869    service_id = btm_convert_uuid_to_eir_service(uuid16);
2870    if( service_id < BTM_EIR_MAX_SERVICES )
2871        BTM_EIR_CLR_SERVICE( p_eir_uuid, service_id );
2872#endif
2873}
2874
2875/*******************************************************************************
2876**
2877** Function         BTM_GetEirSupportedServices
2878**
2879** Description      This function is called to get UUID list from bit map of UUID list.
2880**
2881** Parameters       p_eir_uuid - bit mask of UUID list for EIR
2882**                  p - reference of current pointer of EIR
2883**                  max_num_uuid16 - max number of UUID can be written in EIR
2884**                  num_uuid16 - number of UUID have been written in EIR
2885**
2886** Returns          BTM_EIR_MORE_16BITS_UUID_TYPE, if it has more than max
2887**                  BTM_EIR_COMPLETE_16BITS_UUID_TYPE, otherwise
2888**
2889*******************************************************************************/
2890UINT8 BTM_GetEirSupportedServices( UINT32 *p_eir_uuid,    UINT8 **p,
2891                                   UINT8  max_num_uuid16, UINT8 *p_num_uuid16)
2892{
2893#if (BTM_EIR_SERVER_INCLUDED == TRUE)
2894    UINT8 service_index;
2895
2896    *p_num_uuid16 = 0;
2897
2898    for(service_index = 0; service_index < BTM_EIR_MAX_SERVICES; service_index++)
2899    {
2900        if( BTM_EIR_HAS_SERVICE( p_eir_uuid, service_index ))
2901        {
2902            if( *p_num_uuid16 < max_num_uuid16 )
2903            {
2904                UINT16_TO_STREAM(*p, BTM_EIR_UUID_LKUP_TBL[service_index]);
2905                (*p_num_uuid16)++;
2906            }
2907            /* if max number of UUIDs are stored and found one more */
2908            else
2909            {
2910                return BTM_EIR_MORE_16BITS_UUID_TYPE;
2911            }
2912        }
2913    }
2914    return BTM_EIR_COMPLETE_16BITS_UUID_TYPE;
2915#else
2916    return BTM_EIR_COMPLETE_16BITS_UUID_TYPE;
2917#endif
2918}
2919
2920/*******************************************************************************
2921**
2922** Function         BTM_GetEirUuidList
2923**
2924** Description      This function parses EIR and returns UUID list.
2925**
2926** Parameters       p_eir - EIR
2927**                  uuid_size - LEN_UUID_16, LEN_UUID_32, LEN_UUID_128
2928**                  p_num_uuid - return number of UUID in found list
2929**                  p_uuid_list - return UUID list
2930**                  max_num_uuid - maximum number of UUID to be returned
2931**
2932** Returns          0 - if not found
2933**                  BTM_EIR_COMPLETE_16BITS_UUID_TYPE
2934**                  BTM_EIR_MORE_16BITS_UUID_TYPE
2935**                  BTM_EIR_COMPLETE_32BITS_UUID_TYPE
2936**                  BTM_EIR_MORE_32BITS_UUID_TYPE
2937**                  BTM_EIR_COMPLETE_128BITS_UUID_TYPE
2938**                  BTM_EIR_MORE_128BITS_UUID_TYPE
2939**
2940*******************************************************************************/
2941UINT8 BTM_GetEirUuidList( UINT8 *p_eir, UINT8 uuid_size, UINT8 *p_num_uuid,
2942                            UINT8 *p_uuid_list, UINT8 max_num_uuid)
2943{
2944#if (BTM_EIR_CLIENT_INCLUDED == TRUE)
2945    UINT8   *p_uuid_data;
2946    UINT8   type;
2947    UINT8   yy, xx;
2948    UINT16  *p_uuid16 = (UINT16 *)p_uuid_list;
2949    UINT32  *p_uuid32 = (UINT32 *)p_uuid_list;
2950    char    buff[LEN_UUID_128 * 2 + 1];
2951
2952    p_uuid_data = btm_eir_get_uuid_list( p_eir, uuid_size, p_num_uuid, &type );
2953    if( p_uuid_data == NULL )
2954    {
2955        return 0x00;
2956    }
2957
2958    if( *p_num_uuid > max_num_uuid )
2959    {
2960        BTM_TRACE_WARNING("BTM_GetEirUuidList number of uuid in EIR = %d, size of uuid list = %d",
2961                           *p_num_uuid, max_num_uuid );
2962        *p_num_uuid = max_num_uuid;
2963    }
2964
2965    BTM_TRACE_DEBUG("BTM_GetEirUuidList type = %02X, number of uuid = %d", type, *p_num_uuid );
2966
2967    if( uuid_size == LEN_UUID_16 )
2968    {
2969        for( yy = 0; yy < *p_num_uuid; yy++ )
2970        {
2971            STREAM_TO_UINT16(*(p_uuid16 + yy), p_uuid_data);
2972            BTM_TRACE_DEBUG("                     0x%04X", *(p_uuid16 + yy));
2973        }
2974    }
2975    else if( uuid_size == LEN_UUID_32 )
2976    {
2977        for( yy = 0; yy < *p_num_uuid; yy++ )
2978        {
2979            STREAM_TO_UINT32(*(p_uuid32 + yy), p_uuid_data);
2980            BTM_TRACE_DEBUG("                     0x%08X", *(p_uuid32 + yy));
2981        }
2982    }
2983    else if( uuid_size == LEN_UUID_128 )
2984    {
2985        for( yy = 0; yy < *p_num_uuid; yy++ )
2986        {
2987            STREAM_TO_ARRAY16(p_uuid_list + yy * LEN_UUID_128, p_uuid_data);
2988            for( xx = 0; xx < LEN_UUID_128; xx++ )
2989                sprintf(buff + xx*2, "%02X", *(p_uuid_list + yy * LEN_UUID_128 + xx));
2990            BTM_TRACE_DEBUG("                     0x%s", buff);
2991        }
2992    }
2993
2994    return type;
2995#else
2996    *p_num_uuid = 0;
2997    return 0x00;
2998#endif
2999}
3000
3001
3002#if (BTM_EIR_CLIENT_INCLUDED == TRUE)
3003/*******************************************************************************
3004**
3005** Function         btm_eir_get_uuid_list
3006**
3007** Description      This function searches UUID list in EIR.
3008**
3009** Parameters       p_eir - address of EIR
3010**                  uuid_size - size of UUID to find
3011**                  p_num_uuid - number of UUIDs found
3012**                  p_uuid_list_type - EIR data type
3013**
3014** Returns          NULL - if UUID list with uuid_size is not found
3015**                  beginning of UUID list in EIR - otherwise
3016**
3017*******************************************************************************/
3018static UINT8 *btm_eir_get_uuid_list( UINT8 *p_eir, UINT8 uuid_size,
3019                                     UINT8 *p_num_uuid, UINT8 *p_uuid_list_type )
3020{
3021    UINT8   *p_uuid_data;
3022    UINT8   complete_type, more_type;
3023    UINT8   uuid_len;
3024
3025    switch( uuid_size )
3026    {
3027    case LEN_UUID_16:
3028        complete_type = BTM_EIR_COMPLETE_16BITS_UUID_TYPE;
3029        more_type     = BTM_EIR_MORE_16BITS_UUID_TYPE;
3030        break;
3031    case LEN_UUID_32:
3032        complete_type = BTM_EIR_COMPLETE_32BITS_UUID_TYPE;
3033        more_type     = BTM_EIR_MORE_32BITS_UUID_TYPE;
3034        break;
3035    case LEN_UUID_128:
3036        complete_type = BTM_EIR_COMPLETE_128BITS_UUID_TYPE;
3037        more_type     = BTM_EIR_MORE_128BITS_UUID_TYPE;
3038        break;
3039    default:
3040        *p_num_uuid = 0;
3041        return NULL;
3042        break;
3043    }
3044
3045    p_uuid_data = BTM_CheckEirData( p_eir, complete_type, &uuid_len );
3046    if(p_uuid_data == NULL)
3047    {
3048        p_uuid_data = BTM_CheckEirData( p_eir, more_type, &uuid_len );
3049        *p_uuid_list_type = more_type;
3050    }
3051    else
3052    {
3053        *p_uuid_list_type = complete_type;
3054    }
3055
3056    *p_num_uuid = uuid_len / uuid_size;
3057    return p_uuid_data;
3058}
3059
3060/*******************************************************************************
3061**
3062** Function         btm_convert_uuid_to_uuid16
3063**
3064** Description      This function converts UUID to UUID 16-bit.
3065**
3066** Parameters       p_uuid - address of UUID
3067**                  uuid_size - size of UUID
3068**
3069** Returns          0 - if UUID cannot be converted to UUID 16-bit
3070**                  UUID 16-bit - otherwise
3071**
3072*******************************************************************************/
3073static UINT16 btm_convert_uuid_to_uuid16( UINT8 *p_uuid, UINT8 uuid_size )
3074{
3075    static const UINT8  base_uuid[LEN_UUID_128] = {0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80,
3076                                                   0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3077    UINT16 uuid16 = 0;
3078    UINT32 uuid32;
3079    BOOLEAN is_base_uuid;
3080    UINT8  xx;
3081
3082    switch (uuid_size)
3083    {
3084    case LEN_UUID_16:
3085        STREAM_TO_UINT16 (uuid16, p_uuid);
3086        break;
3087    case LEN_UUID_32:
3088        STREAM_TO_UINT32 (uuid32, p_uuid);
3089        if (uuid32 < 0x10000)
3090            uuid16 = (UINT16) uuid32;
3091        break;
3092    case LEN_UUID_128:
3093        /* See if we can compress his UUID down to 16 or 32bit UUIDs */
3094        is_base_uuid = TRUE;
3095        for (xx = 0; xx < LEN_UUID_128 - 4; xx++)
3096        {
3097            if (p_uuid[xx] != base_uuid[xx])
3098            {
3099                is_base_uuid = FALSE;
3100                break;
3101            }
3102        }
3103        if (is_base_uuid)
3104        {
3105            if ((p_uuid[LEN_UUID_128 - 1] == 0) && (p_uuid[LEN_UUID_128 - 2] == 0))
3106            {
3107                p_uuid += (LEN_UUID_128 - 4);
3108                STREAM_TO_UINT16(uuid16, p_uuid);
3109            }
3110        }
3111        break;
3112    default:
3113        BTM_TRACE_WARNING("btm_convert_uuid_to_uuid16 invalid uuid size");
3114        break;
3115    }
3116
3117    return( uuid16);
3118}
3119
3120/*******************************************************************************
3121**
3122** Function         btm_set_eir_uuid
3123**
3124** Description      This function is called to store received UUID into inquiry result.
3125**
3126** Parameters       p_eir - pointer of EIR significant part
3127**                  p_results - pointer of inquiry result
3128**
3129** Returns          None
3130**
3131*******************************************************************************/
3132void btm_set_eir_uuid( UINT8 *p_eir, tBTM_INQ_RESULTS *p_results )
3133{
3134    UINT8   *p_uuid_data;
3135    UINT8   num_uuid;
3136    UINT16  uuid16;
3137    UINT8   yy;
3138    UINT8   type = BTM_EIR_MORE_16BITS_UUID_TYPE;
3139
3140    p_uuid_data = btm_eir_get_uuid_list( p_eir, LEN_UUID_16, &num_uuid, &type );
3141
3142    if(type == BTM_EIR_COMPLETE_16BITS_UUID_TYPE)
3143    {
3144        p_results->eir_complete_list = TRUE;
3145    }
3146    else
3147    {
3148        p_results->eir_complete_list = FALSE;
3149    }
3150
3151    BTM_TRACE_API("btm_set_eir_uuid eir_complete_list=0x%02X", p_results->eir_complete_list);
3152
3153    if( p_uuid_data )
3154    {
3155        for( yy = 0; yy < num_uuid; yy++ )
3156        {
3157            STREAM_TO_UINT16(uuid16, p_uuid_data);
3158            BTM_AddEirService( p_results->eir_uuid, uuid16 );
3159        }
3160    }
3161
3162    p_uuid_data = btm_eir_get_uuid_list( p_eir, LEN_UUID_32, &num_uuid, &type );
3163    if( p_uuid_data )
3164    {
3165        for( yy = 0; yy < num_uuid; yy++ )
3166        {
3167            uuid16 = btm_convert_uuid_to_uuid16( p_uuid_data, LEN_UUID_32 );
3168            p_uuid_data += LEN_UUID_32;
3169            if( uuid16 )
3170                BTM_AddEirService( p_results->eir_uuid, uuid16 );
3171        }
3172    }
3173
3174    p_uuid_data = btm_eir_get_uuid_list( p_eir, LEN_UUID_128, &num_uuid, &type );
3175    if( p_uuid_data )
3176    {
3177        for( yy = 0; yy < num_uuid; yy++ )
3178        {
3179            uuid16 = btm_convert_uuid_to_uuid16( p_uuid_data, LEN_UUID_128 );
3180            p_uuid_data += LEN_UUID_128;
3181            if( uuid16 )
3182                BTM_AddEirService( p_results->eir_uuid, uuid16 );
3183        }
3184    }
3185}
3186#endif
3187
3188