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