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