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