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