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