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