Home | History | Annotate | Download | only in btm
      1 /******************************************************************************
      2  *
      3  *  Copyright 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 #include <base/bind.h>
     19 #include <stddef.h>
     20 #include <stdio.h>
     21 #include <string.h>
     22 #include <vector>
     23 #include "bt_target.h"
     24 
     25 #include "bt_types.h"
     26 #include "bt_utils.h"
     27 #include "btm_ble_api.h"
     28 #include "btm_int.h"
     29 #include "btu.h"
     30 #include "device/include/controller.h"
     31 #include "hcimsgs.h"
     32 
     33 using base::Bind;
     34 using base::Callback;
     35 using hci_cmd_cb = base::Callback<void(uint8_t* /* return_parameters */,
     36                                        uint16_t /* return_parameters_length*/)>;
     37 
     38 tBTM_BLE_BATCH_SCAN_CB ble_batchscan_cb;
     39 tBTM_BLE_ADV_TRACK_CB ble_advtrack_cb;
     40 
     41 /* length of each batch scan command */
     42 #define BTM_BLE_BATCH_SCAN_STORAGE_CFG_LEN 4
     43 #define BTM_BLE_BATCH_SCAN_PARAM_CONFIG_LEN 12
     44 #define BTM_BLE_BATCH_SCAN_ENB_DISB_LEN 2
     45 #define BTM_BLE_BATCH_SCAN_READ_RESULTS_LEN 2
     46 
     47 namespace {
     48 
     49 bool can_do_batch_scan() {
     50   if (!controller_get_interface()->supports_ble()) return false;
     51 
     52   tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
     53   BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
     54 
     55   if (cmn_ble_vsc_cb.tot_scan_results_strg == 0) return false;
     56 
     57   return true;
     58 }
     59 
     60 /* VSE callback for batch scan, filter, and tracking events */
     61 void btm_ble_batchscan_filter_track_adv_vse_cback(uint8_t len, uint8_t* p) {
     62   tBTM_BLE_TRACK_ADV_DATA adv_data;
     63 
     64   uint8_t sub_event = 0;
     65   tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
     66   STREAM_TO_UINT8(sub_event, p);
     67 
     68   BTM_TRACE_EVENT(
     69       "btm_ble_batchscan_filter_track_adv_vse_cback called with event:%x",
     70       sub_event);
     71   if (HCI_VSE_SUBCODE_BLE_THRESHOLD_SUB_EVT == sub_event &&
     72       NULL != ble_batchscan_cb.p_thres_cback) {
     73     ble_batchscan_cb.p_thres_cback(ble_batchscan_cb.ref_value);
     74     return;
     75   }
     76 
     77   if (HCI_VSE_SUBCODE_BLE_TRACKING_SUB_EVT == sub_event &&
     78       NULL != ble_advtrack_cb.p_track_cback) {
     79     if (len < 10) return;
     80 
     81     memset(&adv_data, 0, sizeof(tBTM_BLE_TRACK_ADV_DATA));
     82     BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
     83     adv_data.client_if = (uint8_t)ble_advtrack_cb.ref_value;
     84     if (cmn_ble_vsc_cb.version_supported > BTM_VSC_CHIP_CAPABILITY_L_VERSION) {
     85       STREAM_TO_UINT8(adv_data.filt_index, p);
     86       STREAM_TO_UINT8(adv_data.advertiser_state, p);
     87       STREAM_TO_UINT8(adv_data.advertiser_info_present, p);
     88       STREAM_TO_BDADDR(adv_data.bd_addr, p);
     89       STREAM_TO_UINT8(adv_data.addr_type, p);
     90 
     91       /* Extract the adv info details */
     92       if (ADV_INFO_PRESENT == adv_data.advertiser_info_present) {
     93         STREAM_TO_UINT8(adv_data.tx_power, p);
     94         STREAM_TO_UINT8(adv_data.rssi_value, p);
     95         STREAM_TO_UINT16(adv_data.time_stamp, p);
     96 
     97         STREAM_TO_UINT8(adv_data.adv_pkt_len, p);
     98         if (adv_data.adv_pkt_len > 0) {
     99           adv_data.p_adv_pkt_data =
    100               static_cast<uint8_t*>(osi_malloc(adv_data.adv_pkt_len));
    101           memcpy(adv_data.p_adv_pkt_data, p, adv_data.adv_pkt_len);
    102         }
    103 
    104         STREAM_TO_UINT8(adv_data.scan_rsp_len, p);
    105         if (adv_data.scan_rsp_len > 0) {
    106           adv_data.p_scan_rsp_data =
    107               static_cast<uint8_t*>(osi_malloc(adv_data.scan_rsp_len));
    108           memcpy(adv_data.p_scan_rsp_data, p, adv_data.scan_rsp_len);
    109         }
    110       }
    111     } else {
    112       /* Based on L-release version */
    113       STREAM_TO_UINT8(adv_data.filt_index, p);
    114       STREAM_TO_UINT8(adv_data.addr_type, p);
    115       STREAM_TO_BDADDR(adv_data.bd_addr, p);
    116       STREAM_TO_UINT8(adv_data.advertiser_state, p);
    117     }
    118 
    119     BTM_TRACE_EVENT("track_adv_vse_cback called: %d, %d, %d",
    120                     adv_data.filt_index, adv_data.addr_type,
    121                     adv_data.advertiser_state);
    122 
    123     // Make sure the device is known
    124     BTM_SecAddBleDevice(adv_data.bd_addr, NULL, BT_DEVICE_TYPE_BLE,
    125                         adv_data.addr_type);
    126 
    127     ble_advtrack_cb.p_track_cback(&adv_data);
    128     return;
    129   }
    130 }
    131 
    132 void feat_enable_cb(uint8_t* p, uint16_t len) {
    133   if (len < 2) {
    134     BTM_TRACE_ERROR("%s: wrong length", __func__);
    135     return;
    136   }
    137 
    138   uint8_t status, subcode;
    139   STREAM_TO_UINT8(status, p);
    140   STREAM_TO_UINT8(subcode, p);
    141 
    142   uint8_t expected_opcode = BTM_BLE_BATCH_SCAN_ENB_DISAB_CUST_FEATURE;
    143   if (subcode != expected_opcode) {
    144     BTM_TRACE_ERROR("%s: bad subcode, expected: %d got: %d", __func__,
    145                     expected_opcode, subcode);
    146     return;
    147   }
    148 
    149   if (ble_batchscan_cb.cur_state != BTM_BLE_SCAN_ENABLE_CALLED)
    150     BTM_TRACE_ERROR("%s: state should be ENABLE_CALLED", __func__);
    151 
    152   ble_batchscan_cb.cur_state = BTM_BLE_SCAN_ENABLED_STATE;
    153 }
    154 
    155 void storage_config_cb(Callback<void(uint8_t /* status */)> cb, uint8_t* p,
    156                        uint16_t len) {
    157   if (len < 2) {
    158     BTM_TRACE_ERROR("%s: wrong length", __func__);
    159     return;
    160   }
    161 
    162   uint8_t status, subcode;
    163   STREAM_TO_UINT8(status, p);
    164   STREAM_TO_UINT8(subcode, p);
    165 
    166   uint8_t expected_opcode = BTM_BLE_BATCH_SCAN_SET_STORAGE_PARAM;
    167   if (subcode != expected_opcode) {
    168     BTM_TRACE_ERROR("%s: bad subcode, expected: %d got: %d", __func__,
    169                     expected_opcode, subcode);
    170     return;
    171   }
    172 
    173   cb.Run(status);
    174 }
    175 
    176 void param_enable_cb(Callback<void(uint8_t /* status */)> cb, uint8_t* p,
    177                      uint16_t len) {
    178   if (len < 2) {
    179     BTM_TRACE_ERROR("%s: wrong length", __func__);
    180     return;
    181   }
    182 
    183   uint8_t status, subcode;
    184   STREAM_TO_UINT8(status, p);
    185   STREAM_TO_UINT8(subcode, p);
    186 
    187   uint8_t expected_opcode = BTM_BLE_BATCH_SCAN_SET_PARAMS;
    188   if (subcode != expected_opcode) {
    189     BTM_TRACE_ERROR("%s: bad subcode: 0x%02x 0x%02x", __func__, expected_opcode,
    190                     subcode);
    191     return;
    192   }
    193 
    194   cb.Run(status);
    195 }
    196 
    197 void disable_cb(base::Callback<void(uint8_t /* status */)> cb, uint8_t* p,
    198                 uint16_t len) {
    199   if (len < 2) {
    200     BTM_TRACE_ERROR("%s: wrong length", __func__);
    201     return;
    202   }
    203 
    204   uint8_t status, subcode;
    205   STREAM_TO_UINT8(status, p);
    206   STREAM_TO_UINT8(subcode, p);
    207 
    208   uint8_t expected_opcode = BTM_BLE_BATCH_SCAN_SET_PARAMS;
    209   if (subcode != expected_opcode) {
    210     BTM_TRACE_ERROR("%s: bad subcode: 0x%02x 0x%02x", __func__, expected_opcode,
    211                     subcode);
    212     return;
    213   }
    214 
    215   if (ble_batchscan_cb.cur_state != BTM_BLE_SCAN_DISABLE_CALLED) {
    216     BTM_TRACE_ERROR("%s: state should be DISABLE_CALLED", __func__);
    217   }
    218 
    219   if (BTM_SUCCESS == status) {
    220     ble_batchscan_cb.cur_state = BTM_BLE_SCAN_DISABLED_STATE;
    221   } else {
    222     BTM_TRACE_ERROR("%s: Invalid state after disabled", __func__);
    223     ble_batchscan_cb.cur_state = BTM_BLE_SCAN_INVALID_STATE;
    224   }
    225 
    226   cb.Run(status);
    227 }
    228 
    229 /**
    230  * This function reads the reports from controller. |scan_mode| is the mode for
    231  * which the reports are to be read
    232  */
    233 void btm_ble_read_batchscan_reports(tBTM_BLE_BATCH_SCAN_MODE scan_mode,
    234                                     hci_cmd_cb cb) {
    235   uint8_t len = BTM_BLE_BATCH_SCAN_READ_RESULTS_LEN;
    236   uint8_t param[len];
    237   memset(param, 0, len);
    238 
    239   uint8_t* pp = param;
    240   UINT8_TO_STREAM(pp, BTM_BLE_BATCH_SCAN_READ_RESULTS);
    241   UINT8_TO_STREAM(pp, scan_mode);
    242 
    243   btu_hcif_send_cmd_with_cb(FROM_HERE, HCI_BLE_BATCH_SCAN_OCF, param, len, cb);
    244 }
    245 
    246 /* read reports. data is accumulated in |data_all|, number of records is
    247  * accumulated in |num_records_all| */
    248 void read_reports_cb(std::vector<uint8_t> data_all, uint8_t num_records_all,
    249                      tBTM_BLE_SCAN_REP_CBACK cb, uint8_t* p, uint16_t len) {
    250   if (len < 2) {
    251     BTM_TRACE_ERROR("%s: wrong length", __func__);
    252     return;
    253   }
    254 
    255   uint8_t status, subcode;
    256   STREAM_TO_UINT8(status, p);
    257   STREAM_TO_UINT8(subcode, p);
    258 
    259   uint8_t expected_opcode = BTM_BLE_BATCH_SCAN_READ_RESULTS;
    260   if (subcode != expected_opcode) {
    261     BTM_TRACE_ERROR("%s: bad subcode, expected: %d got: %d", __func__,
    262                     expected_opcode, subcode);
    263     return;
    264   }
    265 
    266   uint8_t report_format, num_records;
    267   STREAM_TO_UINT8(report_format, p);
    268   STREAM_TO_UINT8(num_records, p);
    269 
    270   BTM_TRACE_DEBUG("%s: status=%d,len=%d,rec=%d", __func__, status, len - 4,
    271                   num_records);
    272 
    273   if (num_records == 0) {
    274     cb.Run(status, report_format, num_records_all, data_all);
    275     return;
    276   }
    277 
    278   if (len > 4) {
    279     data_all.insert(data_all.end(), p, p + len - 4);
    280     num_records_all += num_records;
    281 
    282     /* More records could be in the buffer and needs to be pulled out */
    283     btm_ble_read_batchscan_reports(
    284         report_format, base::Bind(&read_reports_cb, std::move(data_all),
    285                                   num_records_all, std::move(cb)));
    286   }
    287 }
    288 
    289 /**
    290  * This function writes the storage configuration in controller
    291  *
    292  * Parameters       batch_scan_full_max - Max storage space (in %) allocated to
    293  *                                        full scanning
    294  *                  batch_scan_trunc_max - Max storage space (in %) allocated to
    295  *                                         truncated scanning
    296  *                  batch_scan_notify_threshold - Set up notification level
    297  *                                                based on total space
    298  *
    299  **/
    300 void btm_ble_set_storage_config(uint8_t batch_scan_full_max,
    301                                 uint8_t batch_scan_trunc_max,
    302                                 uint8_t batch_scan_notify_threshold,
    303                                 hci_cmd_cb cb) {
    304   uint8_t len = BTM_BLE_BATCH_SCAN_STORAGE_CFG_LEN;
    305   uint8_t param[len];
    306   memset(param, 0, len);
    307 
    308   uint8_t* pp = param;
    309   UINT8_TO_STREAM(pp, BTM_BLE_BATCH_SCAN_SET_STORAGE_PARAM);
    310   UINT8_TO_STREAM(pp, batch_scan_full_max);
    311   UINT8_TO_STREAM(pp, batch_scan_trunc_max);
    312   UINT8_TO_STREAM(pp, batch_scan_notify_threshold);
    313 
    314   btu_hcif_send_cmd_with_cb(FROM_HERE, HCI_BLE_BATCH_SCAN_OCF, param, len, cb);
    315 }
    316 
    317 /* This function writes the batch scan params in controller */
    318 void btm_ble_set_batchscan_param(tBTM_BLE_BATCH_SCAN_MODE scan_mode,
    319                                  uint32_t scan_interval, uint32_t scan_window,
    320                                  tBLE_ADDR_TYPE addr_type,
    321                                  tBTM_BLE_DISCARD_RULE discard_rule,
    322                                  hci_cmd_cb cb) {
    323   // Override param and decide addr_type based on own addr type
    324   // TODO: Remove upper layer parameter?
    325   addr_type = btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type;
    326 
    327   uint8_t len = BTM_BLE_BATCH_SCAN_PARAM_CONFIG_LEN;
    328   uint8_t param[len];
    329   memset(param, 0, len);
    330 
    331   uint8_t* p = param;
    332   UINT8_TO_STREAM(p, BTM_BLE_BATCH_SCAN_SET_PARAMS);
    333   UINT8_TO_STREAM(p, scan_mode);
    334   UINT32_TO_STREAM(p, scan_window);
    335   UINT32_TO_STREAM(p, scan_interval);
    336   UINT8_TO_STREAM(p, addr_type);
    337   UINT8_TO_STREAM(p, discard_rule);
    338 
    339   btu_hcif_send_cmd_with_cb(FROM_HERE, HCI_BLE_BATCH_SCAN_OCF, param, len, cb);
    340 }
    341 
    342 /* This function enables the customer specific feature in controller */
    343 void btm_ble_enable_batchscan(hci_cmd_cb cb) {
    344   uint8_t len = BTM_BLE_BATCH_SCAN_ENB_DISB_LEN;
    345   uint8_t param[len];
    346   memset(param, 0, len);
    347 
    348   uint8_t* p = param;
    349   UINT8_TO_STREAM(p, BTM_BLE_BATCH_SCAN_ENB_DISAB_CUST_FEATURE);
    350   UINT8_TO_STREAM(p, 0x01 /* enable */);
    351 
    352   btu_hcif_send_cmd_with_cb(FROM_HERE, HCI_BLE_BATCH_SCAN_OCF, param, len, cb);
    353 }
    354 
    355 }  // namespace
    356 
    357 /*******************************************************************************
    358  *
    359  * Description      This function is called to write storage config params.
    360  *
    361  * Parameters:      batch_scan_full_max - Max storage space (in %) allocated to
    362  *                                        full style
    363  *                  batch_scan_trunc_max - Max storage space (in %) allocated to
    364  *                                         trunc style
    365  *                  batch_scan_notify_threshold - Setup notification level based
    366  *                                                on total space
    367  *                  cb - Setup callback pointer
    368  *                  p_thres_cback - Threshold callback pointer
    369  *                  ref_value - Reference value
    370  *
    371  ******************************************************************************/
    372 void BTM_BleSetStorageConfig(uint8_t batch_scan_full_max,
    373                              uint8_t batch_scan_trunc_max,
    374                              uint8_t batch_scan_notify_threshold,
    375                              Callback<void(uint8_t /* status */)> cb,
    376                              tBTM_BLE_SCAN_THRESHOLD_CBACK* p_thres_cback,
    377                              tBTM_BLE_REF_VALUE ref_value) {
    378   if (!can_do_batch_scan()) {
    379     cb.Run(BTM_ERR_PROCESSING);
    380     return;
    381   }
    382 
    383   BTM_TRACE_EVENT("%s: %d, %d, %d, %d, %d", __func__,
    384                   ble_batchscan_cb.cur_state, ref_value, batch_scan_full_max,
    385                   batch_scan_trunc_max, batch_scan_notify_threshold);
    386 
    387   ble_batchscan_cb.p_thres_cback = p_thres_cback;
    388   ble_batchscan_cb.ref_value = ref_value;
    389 
    390   if (batch_scan_full_max > BTM_BLE_ADV_SCAN_FULL_MAX ||
    391       batch_scan_trunc_max > BTM_BLE_ADV_SCAN_TRUNC_MAX ||
    392       batch_scan_notify_threshold > BTM_BLE_ADV_SCAN_THR_MAX) {
    393     BTM_TRACE_ERROR("Illegal set storage config params");
    394     cb.Run(BTM_ILLEGAL_VALUE);
    395     return;
    396   }
    397 
    398   if (BTM_BLE_SCAN_INVALID_STATE == ble_batchscan_cb.cur_state ||
    399       BTM_BLE_SCAN_DISABLED_STATE == ble_batchscan_cb.cur_state ||
    400       BTM_BLE_SCAN_DISABLE_CALLED == ble_batchscan_cb.cur_state) {
    401     btm_ble_enable_batchscan(Bind(&feat_enable_cb));
    402     ble_batchscan_cb.cur_state = BTM_BLE_SCAN_ENABLE_CALLED;
    403   }
    404 
    405   btm_ble_set_storage_config(batch_scan_full_max, batch_scan_trunc_max,
    406                              batch_scan_notify_threshold,
    407                              Bind(&storage_config_cb, cb));
    408   return;
    409 }
    410 
    411 /* This function is called to configure and enable batch scanning */
    412 void BTM_BleEnableBatchScan(tBTM_BLE_BATCH_SCAN_MODE scan_mode,
    413                             uint32_t scan_interval, uint32_t scan_window,
    414                             tBLE_ADDR_TYPE addr_type,
    415                             tBTM_BLE_DISCARD_RULE discard_rule,
    416                             Callback<void(uint8_t /* status */)> cb) {
    417   BTM_TRACE_EVENT("%s: %d, %d, %d, %d, %d, %d", __func__, scan_mode,
    418                   scan_interval, scan_window, addr_type, discard_rule);
    419 
    420   if (!can_do_batch_scan()) {
    421     cb.Run(BTM_ERR_PROCESSING);
    422     return;
    423   }
    424 
    425   BTM_TRACE_DEBUG("%s: %d, %x, %x, %d, %d", __func__, scan_mode, scan_interval,
    426                   scan_window, discard_rule, ble_batchscan_cb.cur_state);
    427 
    428   /* Only 16 bits will be used for scan interval and scan window as per
    429    * agreement with Google */
    430   /* So the standard LE range would suffice for scan interval and scan window */
    431   if ((BTM_BLE_ISVALID_PARAM(scan_interval, BTM_BLE_SCAN_INT_MIN,
    432                              BTM_BLE_SCAN_INT_MAX) ||
    433        BTM_BLE_ISVALID_PARAM(scan_window, BTM_BLE_SCAN_WIN_MIN,
    434                              BTM_BLE_SCAN_WIN_MAX)) &&
    435       (BTM_BLE_BATCH_SCAN_MODE_PASS == scan_mode ||
    436        BTM_BLE_BATCH_SCAN_MODE_ACTI == scan_mode ||
    437        BTM_BLE_BATCH_SCAN_MODE_PASS_ACTI == scan_mode) &&
    438       (BTM_BLE_DISCARD_OLD_ITEMS == discard_rule ||
    439        BTM_BLE_DISCARD_LOWER_RSSI_ITEMS == discard_rule)) {
    440   } else {
    441     BTM_TRACE_ERROR("%s: Illegal enable scan params", __func__);
    442     cb.Run(BTM_ILLEGAL_VALUE);
    443     return;
    444   }
    445 
    446   if (BTM_BLE_SCAN_INVALID_STATE == ble_batchscan_cb.cur_state ||
    447       BTM_BLE_SCAN_DISABLED_STATE == ble_batchscan_cb.cur_state ||
    448       BTM_BLE_SCAN_DISABLE_CALLED == ble_batchscan_cb.cur_state) {
    449     btm_ble_enable_batchscan(Bind(&feat_enable_cb));
    450     ble_batchscan_cb.cur_state = BTM_BLE_SCAN_ENABLE_CALLED;
    451   }
    452 
    453   ble_batchscan_cb.scan_mode = scan_mode;
    454   ble_batchscan_cb.scan_interval = scan_interval;
    455   ble_batchscan_cb.scan_window = scan_window;
    456   ble_batchscan_cb.addr_type = addr_type;
    457   ble_batchscan_cb.discard_rule = discard_rule;
    458   /* This command starts batch scanning, if enabled */
    459   btm_ble_set_batchscan_param(scan_mode, scan_interval, scan_window, addr_type,
    460                               discard_rule, Bind(&param_enable_cb, cb));
    461 }
    462 
    463 /* This function is called to disable batch scanning */
    464 void BTM_BleDisableBatchScan(base::Callback<void(uint8_t /* status */)> cb) {
    465   BTM_TRACE_EVENT(" BTM_BleDisableBatchScan");
    466 
    467   if (!can_do_batch_scan()) {
    468     cb.Run(BTM_ERR_PROCESSING);
    469     return;
    470   }
    471 
    472   btm_ble_set_batchscan_param(
    473       BTM_BLE_BATCH_SCAN_MODE_DISABLE, ble_batchscan_cb.scan_interval,
    474       ble_batchscan_cb.scan_window, ble_batchscan_cb.addr_type,
    475       ble_batchscan_cb.discard_rule, Bind(&disable_cb, cb));
    476   ble_batchscan_cb.cur_state = BTM_BLE_SCAN_DISABLE_CALLED;
    477 }
    478 
    479 /* This function is called to start reading batch scan reports */
    480 void BTM_BleReadScanReports(tBTM_BLE_BATCH_SCAN_MODE scan_mode,
    481                             tBTM_BLE_SCAN_REP_CBACK cb) {
    482   uint8_t read_scan_mode = 0;
    483 
    484   BTM_TRACE_EVENT("%s; %d", __func__, scan_mode);
    485 
    486   if (!can_do_batch_scan()) {
    487     BTM_TRACE_ERROR("Controller does not support batch scan");
    488     cb.Run(BTM_ERR_PROCESSING, 0, 0, {});
    489     return;
    490   }
    491 
    492   /*  Check if the requested scan mode has already been setup by the user */
    493   read_scan_mode = ble_batchscan_cb.scan_mode & BTM_BLE_BATCH_SCAN_MODE_ACTI;
    494   if (0 == read_scan_mode)
    495     read_scan_mode = ble_batchscan_cb.scan_mode & BTM_BLE_BATCH_SCAN_MODE_PASS;
    496 
    497   /* Check only for modes, as scan reports can be called after disabling batch
    498    * scan */
    499   if (scan_mode != BTM_BLE_BATCH_SCAN_MODE_PASS &&
    500       scan_mode != BTM_BLE_BATCH_SCAN_MODE_ACTI) {
    501     BTM_TRACE_ERROR("Illegal read scan params: %d, %d, %d", read_scan_mode,
    502                     scan_mode, ble_batchscan_cb.cur_state);
    503     cb.Run(BTM_ILLEGAL_VALUE, 0, 0, {});
    504     return;
    505   }
    506 
    507   btm_ble_read_batchscan_reports(
    508       scan_mode, base::Bind(&read_reports_cb, std::vector<uint8_t>(), 0, cb));
    509   return;
    510 }
    511 
    512 /* This function is called to setup the callback for tracking */
    513 void BTM_BleTrackAdvertiser(tBTM_BLE_TRACK_ADV_CBACK* p_track_cback,
    514                             tBTM_BLE_REF_VALUE ref_value) {
    515   BTM_TRACE_EVENT("%s:", __func__);
    516 
    517   if (!can_do_batch_scan()) {
    518     BTM_TRACE_ERROR("Controller does not support batch scan");
    519 
    520     tBTM_BLE_TRACK_ADV_DATA track_adv_data;
    521     memset(&track_adv_data, 0, sizeof(tBTM_BLE_TRACK_ADV_DATA));
    522     track_adv_data.advertiser_info_present =
    523         NO_ADV_INFO_PRESENT; /* Indicates failure */
    524     track_adv_data.client_if = (uint8_t)ref_value;
    525     p_track_cback(&track_adv_data);
    526     return;
    527   }
    528 
    529   ble_advtrack_cb.p_track_cback = p_track_cback;
    530   ble_advtrack_cb.ref_value = ref_value;
    531   return;
    532 }
    533 
    534 /**
    535  * This function initialize the batch scan control block.
    536  **/
    537 void btm_ble_batchscan_init(void) {
    538   BTM_TRACE_EVENT(" btm_ble_batchscan_init");
    539   memset(&ble_batchscan_cb, 0, sizeof(tBTM_BLE_BATCH_SCAN_CB));
    540   memset(&ble_advtrack_cb, 0, sizeof(tBTM_BLE_ADV_TRACK_CB));
    541   BTM_RegisterForVSEvents(btm_ble_batchscan_filter_track_adv_vse_cback, true);
    542 }
    543 
    544 /**
    545  * This function cleans the batch scan control block.
    546  **/
    547 void btm_ble_batchscan_cleanup(void) {
    548   BTM_TRACE_EVENT("%s", __func__);
    549 
    550   memset(&ble_batchscan_cb, 0, sizeof(tBTM_BLE_BATCH_SCAN_CB));
    551   memset(&ble_advtrack_cb, 0, sizeof(tBTM_BLE_ADV_TRACK_CB));
    552 }
    553