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