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