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