1 /******************************************************************************
2  *
3  *  Copyright (C) 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 
can_do_batch_scan()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 */
btm_ble_batchscan_filter_track_adv_vse_cback(uint8_t len,uint8_t * p)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.address, 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.address, 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.address, 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 
feat_enable_cb(uint8_t * p,uint16_t len)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 
storage_config_cb(Callback<void (uint8_t)> cb,uint8_t * p,uint16_t len)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 
param_enable_cb(Callback<void (uint8_t)> cb,uint8_t * p,uint16_t len)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 
disable_cb(base::Callback<void (uint8_t)> cb,uint8_t * p,uint16_t len)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  */
btm_ble_read_batchscan_reports(tBTM_BLE_BATCH_SCAN_MODE scan_mode,hci_cmd_cb cb)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| */
read_reports_cb(std::vector<uint8_t> data_all,uint8_t num_records_all,tBTM_BLE_SCAN_REP_CBACK cb,uint8_t * p,uint16_t len)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  **/
btm_ble_set_storage_config(uint8_t batch_scan_full_max,uint8_t batch_scan_trunc_max,uint8_t batch_scan_notify_threshold,hci_cmd_cb cb)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 */
btm_ble_set_batchscan_param(tBTM_BLE_BATCH_SCAN_MODE scan_mode,uint32_t scan_interval,uint32_t scan_window,tBLE_ADDR_TYPE addr_type,tBTM_BLE_DISCARD_RULE discard_rule,hci_cmd_cb cb)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 */
btm_ble_enable_batchscan(hci_cmd_cb cb)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  ******************************************************************************/
BTM_BleSetStorageConfig(uint8_t batch_scan_full_max,uint8_t batch_scan_trunc_max,uint8_t batch_scan_notify_threshold,Callback<void (uint8_t)> cb,tBTM_BLE_SCAN_THRESHOLD_CBACK * p_thres_cback,tBTM_BLE_REF_VALUE ref_value)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 */
BTM_BleEnableBatchScan(tBTM_BLE_BATCH_SCAN_MODE scan_mode,uint32_t scan_interval,uint32_t scan_window,tBLE_ADDR_TYPE addr_type,tBTM_BLE_DISCARD_RULE discard_rule,Callback<void (uint8_t)> cb)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 */
BTM_BleDisableBatchScan(base::Callback<void (uint8_t)> cb)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 */
BTM_BleReadScanReports(tBTM_BLE_BATCH_SCAN_MODE scan_mode,tBTM_BLE_SCAN_REP_CBACK cb)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 (read_scan_mode < 0 || (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 */
BTM_BleTrackAdvertiser(tBTM_BLE_TRACK_ADV_CBACK * p_track_cback,tBTM_BLE_REF_VALUE ref_value)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  **/
btm_ble_batchscan_init(void)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  **/
btm_ble_batchscan_cleanup(void)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