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