1c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji/******************************************************************************
2c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji *
3c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji *  Copyright (C) 2014 Broadcom Corporation
4c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji *
5c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji *  Licensed under the Apache License, Version 2.0 (the "License");
6c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji *  you may not use this file except in compliance with the License.
7c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji *  You may obtain a copy of the License at:
8c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji *
9c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji *  http://www.apache.org/licenses/LICENSE-2.0
10c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji *
11c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji *  Unless required by applicable law or agreed to in writing, software
12c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji *  distributed under the License is distributed on an "AS IS" BASIS,
13c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji *  See the License for the specific language governing permissions and
15c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji *  limitations under the License.
16c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji *
17c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji ******************************************************************************/
18eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski#include <base/bind.h>
19c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji#include <stddef.h>
20911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#include <stdio.h>
21911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#include <string.h>
22eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski#include <vector>
23c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji#include "bt_target.h"
24c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji
25c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji#include "bt_types.h"
26c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji#include "bt_utils.h"
27911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#include "btm_ble_api.h"
28c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji#include "btm_int.h"
29911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#include "btu.h"
3079ecab5d0418fde77e9afcdd451bd713af73e180Chris Manton#include "device/include/controller.h"
31c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji#include "hcimsgs.h"
32c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji
33eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowskiusing base::Bind;
34eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowskiusing base::Callback;
35eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowskiusing hci_cmd_cb = base::Callback<void(uint8_t* /* return_parameters */,
36eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski                                       uint16_t /* return_parameters_length*/)>;
37eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski
38c4e2596a112a0dd63ac681b1226548c0f95e828cSatya CallojitBTM_BLE_BATCH_SCAN_CB ble_batchscan_cb;
391acb61ce065053f91a0f8d43e8328c9eeec4b5edSatya CallojitBTM_BLE_ADV_TRACK_CB ble_advtrack_cb;
40c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji
41c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji/* length of each batch scan command */
42911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#define BTM_BLE_BATCH_SCAN_STORAGE_CFG_LEN 4
43911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#define BTM_BLE_BATCH_SCAN_PARAM_CONFIG_LEN 12
44911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#define BTM_BLE_BATCH_SCAN_ENB_DISB_LEN 2
45911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson#define BTM_BLE_BATCH_SCAN_READ_RESULTS_LEN 2
46c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji
47eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowskinamespace {
48c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji
49eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowskibool can_do_batch_scan() {
50eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  if (!controller_get_interface()->supports_ble()) return false;
51c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji
52eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
53eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
54eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski
55eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  if (cmn_ble_vsc_cb.tot_scan_results_strg == 0) return false;
56eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski
57eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  return true;
58eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski}
59eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski
60eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski/* VSE callback for batch scan, filter, and tracking events */
61911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid btm_ble_batchscan_filter_track_adv_vse_cback(uint8_t len, uint8_t* p) {
62911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tBTM_BLE_TRACK_ADV_DATA adv_data;
63911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
64911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t sub_event = 0;
65911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  tBTM_BLE_VSC_CB cmn_ble_vsc_cb;
66911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  STREAM_TO_UINT8(sub_event, p);
67911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
68911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BTM_TRACE_EVENT(
69911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      "btm_ble_batchscan_filter_track_adv_vse_cback called with event:%x",
70911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      sub_event);
71911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (HCI_VSE_SUBCODE_BLE_THRESHOLD_SUB_EVT == sub_event &&
72911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      NULL != ble_batchscan_cb.p_thres_cback) {
73911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    ble_batchscan_cb.p_thres_cback(ble_batchscan_cb.ref_value);
74911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
75911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
76911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
77911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (HCI_VSE_SUBCODE_BLE_TRACKING_SUB_EVT == sub_event &&
78911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      NULL != ble_advtrack_cb.p_track_cback) {
79911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (len < 10) return;
801acb61ce065053f91a0f8d43e8328c9eeec4b5edSatya Calloji
81911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    memset(&adv_data, 0, sizeof(tBTM_BLE_TRACK_ADV_DATA));
82911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
83911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    adv_data.client_if = (uint8_t)ble_advtrack_cb.ref_value;
84911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (cmn_ble_vsc_cb.version_supported > BTM_VSC_CHIP_CAPABILITY_L_VERSION) {
85911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      STREAM_TO_UINT8(adv_data.filt_index, p);
86911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      STREAM_TO_UINT8(adv_data.advertiser_state, p);
87911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      STREAM_TO_UINT8(adv_data.advertiser_info_present, p);
88b8a477e9ac51898b05cb328eda897d95f1ef3d02Jakub Pawlowski      STREAM_TO_BDADDR(adv_data.bd_addr, p);
89911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      STREAM_TO_UINT8(adv_data.addr_type, p);
90911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
91911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      /* Extract the adv info details */
92911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      if (ADV_INFO_PRESENT == adv_data.advertiser_info_present) {
93911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        STREAM_TO_UINT8(adv_data.tx_power, p);
94911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        STREAM_TO_UINT8(adv_data.rssi_value, p);
95911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        STREAM_TO_UINT16(adv_data.time_stamp, p);
96911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
97911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        STREAM_TO_UINT8(adv_data.adv_pkt_len, p);
98911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        if (adv_data.adv_pkt_len > 0) {
99911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          adv_data.p_adv_pkt_data =
100911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson              static_cast<uint8_t*>(osi_malloc(adv_data.adv_pkt_len));
101911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          memcpy(adv_data.p_adv_pkt_data, p, adv_data.adv_pkt_len);
102f538707fe64c62b1dbb8e4210e4a1bfa0bab2b56Satya Calloji        }
103911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
104911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        STREAM_TO_UINT8(adv_data.scan_rsp_len, p);
105911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson        if (adv_data.scan_rsp_len > 0) {
106911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          adv_data.p_scan_rsp_data =
107911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson              static_cast<uint8_t*>(osi_malloc(adv_data.scan_rsp_len));
108911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson          memcpy(adv_data.p_scan_rsp_data, p, adv_data.scan_rsp_len);
109f538707fe64c62b1dbb8e4210e4a1bfa0bab2b56Satya Calloji        }
110911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      }
111911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    } else {
112911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      /* Based on L-release version */
113911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      STREAM_TO_UINT8(adv_data.filt_index, p);
114911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      STREAM_TO_UINT8(adv_data.addr_type, p);
115b8a477e9ac51898b05cb328eda897d95f1ef3d02Jakub Pawlowski      STREAM_TO_BDADDR(adv_data.bd_addr, p);
116911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      STREAM_TO_UINT8(adv_data.advertiser_state, p);
117911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    }
118f538707fe64c62b1dbb8e4210e4a1bfa0bab2b56Satya Calloji
119911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BTM_TRACE_EVENT("track_adv_vse_cback called: %d, %d, %d",
120911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                    adv_data.filt_index, adv_data.addr_type,
121911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                    adv_data.advertiser_state);
122e0295e2c2eb7cc6eb331d581ed8455d6b30b3bc6Andre Eisenbach
123911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    // Make sure the device is known
124b8a477e9ac51898b05cb328eda897d95f1ef3d02Jakub Pawlowski    BTM_SecAddBleDevice(adv_data.bd_addr, NULL, BT_DEVICE_TYPE_BLE,
125b8a477e9ac51898b05cb328eda897d95f1ef3d02Jakub Pawlowski                        adv_data.addr_type);
126e0295e2c2eb7cc6eb331d581ed8455d6b30b3bc6Andre Eisenbach
127911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    ble_advtrack_cb.p_track_cback(&adv_data);
128911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
129911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
130c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji}
131c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji
132eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowskivoid feat_enable_cb(uint8_t* p, uint16_t len) {
133eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  if (len < 2) {
134eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    BTM_TRACE_ERROR("%s: wrong length", __func__);
135eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    return;
136eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  }
137c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji
138eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  uint8_t status, subcode;
139eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  STREAM_TO_UINT8(status, p);
140eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  STREAM_TO_UINT8(subcode, p);
141eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski
142eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  uint8_t expected_opcode = BTM_BLE_BATCH_SCAN_ENB_DISAB_CUST_FEATURE;
143eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  if (subcode != expected_opcode) {
144eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    BTM_TRACE_ERROR("%s: bad subcode, expected: %d got: %d", __func__,
145eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski                    expected_opcode, subcode);
146eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    return;
147911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
148911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
149eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  if (ble_batchscan_cb.cur_state != BTM_BLE_SCAN_ENABLE_CALLED)
150eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    BTM_TRACE_ERROR("%s: state should be ENABLE_CALLED", __func__);
151f1dba910daa5f0ce9ca89f840bb7e6269f07af1dSatya Calloji
152eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  ble_batchscan_cb.cur_state = BTM_BLE_SCAN_ENABLED_STATE;
153eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski}
154911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
155eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowskivoid storage_config_cb(Callback<void(uint8_t /* status */)> cb, uint8_t* p,
156eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski                       uint16_t len) {
157eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  if (len < 2) {
158eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    BTM_TRACE_ERROR("%s: wrong length", __func__);
159eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    return;
160911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
161911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
162eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  uint8_t status, subcode;
163eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  STREAM_TO_UINT8(status, p);
164eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  STREAM_TO_UINT8(subcode, p);
165eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski
166eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  uint8_t expected_opcode = BTM_BLE_BATCH_SCAN_SET_STORAGE_PARAM;
167eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  if (subcode != expected_opcode) {
168eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    BTM_TRACE_ERROR("%s: bad subcode, expected: %d got: %d", __func__,
169eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski                    expected_opcode, subcode);
170eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    return;
171911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
172eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski
173eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  cb.Run(status);
174f1dba910daa5f0ce9ca89f840bb7e6269f07af1dSatya Calloji}
175f1dba910daa5f0ce9ca89f840bb7e6269f07af1dSatya Calloji
176eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowskivoid param_enable_cb(Callback<void(uint8_t /* status */)> cb, uint8_t* p,
177eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski                     uint16_t len) {
178eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  if (len < 2) {
179eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    BTM_TRACE_ERROR("%s: wrong length", __func__);
180eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    return;
181911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
182911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
183eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  uint8_t status, subcode;
184eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  STREAM_TO_UINT8(status, p);
185eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  STREAM_TO_UINT8(subcode, p);
186eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski
187eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  uint8_t expected_opcode = BTM_BLE_BATCH_SCAN_SET_PARAMS;
188eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  if (subcode != expected_opcode) {
189eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    BTM_TRACE_ERROR("%s: bad subcode: 0x%02x 0x%02x", __func__, expected_opcode,
190eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski                    subcode);
191911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
192911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
193f1dba910daa5f0ce9ca89f840bb7e6269f07af1dSatya Calloji
194eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  cb.Run(status);
195eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski}
196f1dba910daa5f0ce9ca89f840bb7e6269f07af1dSatya Calloji
197eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowskivoid disable_cb(base::Callback<void(uint8_t /* status */)> cb, uint8_t* p,
198eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski                uint16_t len) {
199eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  if (len < 2) {
200eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    BTM_TRACE_ERROR("%s: wrong length", __func__);
201eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    return;
202eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  }
203f1dba910daa5f0ce9ca89f840bb7e6269f07af1dSatya Calloji
204eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  uint8_t status, subcode;
205eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  STREAM_TO_UINT8(status, p);
206eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  STREAM_TO_UINT8(subcode, p);
207f1dba910daa5f0ce9ca89f840bb7e6269f07af1dSatya Calloji
208eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  uint8_t expected_opcode = BTM_BLE_BATCH_SCAN_SET_PARAMS;
209eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  if (subcode != expected_opcode) {
210eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    BTM_TRACE_ERROR("%s: bad subcode: 0x%02x 0x%02x", __func__, expected_opcode,
211eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski                    subcode);
212eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    return;
213eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  }
214f1dba910daa5f0ce9ca89f840bb7e6269f07af1dSatya Calloji
215eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  if (ble_batchscan_cb.cur_state != BTM_BLE_SCAN_DISABLE_CALLED) {
216eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    BTM_TRACE_ERROR("%s: state should be DISABLE_CALLED", __func__);
217eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  }
218eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski
219eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  if (BTM_SUCCESS == status) {
220eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    ble_batchscan_cb.cur_state = BTM_BLE_SCAN_DISABLED_STATE;
221eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  } else {
222eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    BTM_TRACE_ERROR("%s: Invalid state after disabled", __func__);
223eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    ble_batchscan_cb.cur_state = BTM_BLE_SCAN_INVALID_STATE;
224eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  }
225eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski
226eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  cb.Run(status);
227c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji}
228c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji
229eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski/**
230eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski * This function reads the reports from controller. |scan_mode| is the mode for
231eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski * which the reports are to be read
232eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski */
2333d5fbcaf9f191737b1c818523e1bf6831c50d586Jakub Pawlowskivoid btm_ble_read_batchscan_reports(tBTM_BLE_BATCH_SCAN_MODE scan_mode,
234eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski                                    hci_cmd_cb cb) {
235eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  uint8_t len = BTM_BLE_BATCH_SCAN_READ_RESULTS_LEN;
236eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  uint8_t param[len];
237eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  memset(param, 0, len);
238f1dba910daa5f0ce9ca89f840bb7e6269f07af1dSatya Calloji
239eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  uint8_t* pp = param;
240911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT8_TO_STREAM(pp, BTM_BLE_BATCH_SCAN_READ_RESULTS);
241911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT8_TO_STREAM(pp, scan_mode);
242f1dba910daa5f0ce9ca89f840bb7e6269f07af1dSatya Calloji
243eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  btu_hcif_send_cmd_with_cb(FROM_HERE, HCI_BLE_BATCH_SCAN_OCF, param, len, cb);
244f1dba910daa5f0ce9ca89f840bb7e6269f07af1dSatya Calloji}
245f1dba910daa5f0ce9ca89f840bb7e6269f07af1dSatya Calloji
246eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski/* read reports. data is accumulated in |data_all|, number of records is
247eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski * accumulated in |num_records_all| */
248eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowskivoid read_reports_cb(std::vector<uint8_t> data_all, uint8_t num_records_all,
249eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski                     tBTM_BLE_SCAN_REP_CBACK cb, uint8_t* p, uint16_t len) {
250911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (len < 2) {
251eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    BTM_TRACE_ERROR("%s: wrong length", __func__);
252911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
253911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
254c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji
255eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  uint8_t status, subcode;
256911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  STREAM_TO_UINT8(status, p);
257911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  STREAM_TO_UINT8(subcode, p);
258c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji
259eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  uint8_t expected_opcode = BTM_BLE_BATCH_SCAN_READ_RESULTS;
260eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  if (subcode != expected_opcode) {
261eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    BTM_TRACE_ERROR("%s: bad subcode, expected: %d got: %d", __func__,
262eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski                    expected_opcode, subcode);
263911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    return;
264911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
265911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
266eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  uint8_t report_format, num_records;
267eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  STREAM_TO_UINT8(report_format, p);
268eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  STREAM_TO_UINT8(num_records, p);
269c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji
270eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  BTM_TRACE_DEBUG("%s: status=%d,len=%d,rec=%d", __func__, status, len - 4,
271eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski                  num_records);
272c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji
273eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  if (num_records == 0) {
274eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    cb.Run(status, report_format, num_records_all, data_all);
275eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    return;
276eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  }
277c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji
278eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  if (len > 4) {
279eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    data_all.insert(data_all.end(), p, p + len - 4);
280eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    num_records_all += num_records;
281c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji
282eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    /* More records could be in the buffer and needs to be pulled out */
283eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    btm_ble_read_batchscan_reports(
284eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski        report_format, base::Bind(&read_reports_cb, std::move(data_all),
285eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski                                  num_records_all, std::move(cb)));
286911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
287c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji}
288c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji
289eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski/**
290eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski * This function writes the storage configuration in controller
291ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
2929ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * Parameters       batch_scan_full_max - Max storage space (in %) allocated to
2939ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *                                        full scanning
2949ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *                  batch_scan_trunc_max - Max storage space (in %) allocated to
2959ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *                                         truncated scanning
2969ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *                  batch_scan_notify_threshold - Set up notification level
2979ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *                                                based on total space
298ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
299eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski **/
300911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid btm_ble_set_storage_config(uint8_t batch_scan_full_max,
301911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                uint8_t batch_scan_trunc_max,
302eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski                                uint8_t batch_scan_notify_threshold,
303eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski                                hci_cmd_cb cb) {
304eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  uint8_t len = BTM_BLE_BATCH_SCAN_STORAGE_CFG_LEN;
305eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  uint8_t param[len];
306eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  memset(param, 0, len);
307911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
308eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  uint8_t* pp = param;
309911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT8_TO_STREAM(pp, BTM_BLE_BATCH_SCAN_SET_STORAGE_PARAM);
310911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT8_TO_STREAM(pp, batch_scan_full_max);
311911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT8_TO_STREAM(pp, batch_scan_trunc_max);
312911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  UINT8_TO_STREAM(pp, batch_scan_notify_threshold);
313911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
314eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  btu_hcif_send_cmd_with_cb(FROM_HERE, HCI_BLE_BATCH_SCAN_OCF, param, len, cb);
315c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji}
316c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji
317eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski/* This function writes the batch scan params in controller */
3183d5fbcaf9f191737b1c818523e1bf6831c50d586Jakub Pawlowskivoid btm_ble_set_batchscan_param(tBTM_BLE_BATCH_SCAN_MODE scan_mode,
319911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                 uint32_t scan_interval, uint32_t scan_window,
320911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                 tBLE_ADDR_TYPE addr_type,
321eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski                                 tBTM_BLE_DISCARD_RULE discard_rule,
322eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski                                 hci_cmd_cb cb) {
323911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  // Override param and decide addr_type based on own addr type
324911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  // TODO: Remove upper layer parameter?
325911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  addr_type = btm_cb.ble_ctr_cb.addr_mgnt_cb.own_addr_type;
326911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
327eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  uint8_t len = BTM_BLE_BATCH_SCAN_PARAM_CONFIG_LEN;
328eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  uint8_t param[len];
329eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  memset(param, 0, len);
330c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji
331eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  uint8_t* p = param;
332eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  UINT8_TO_STREAM(p, BTM_BLE_BATCH_SCAN_SET_PARAMS);
333eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  UINT8_TO_STREAM(p, scan_mode);
334eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  UINT32_TO_STREAM(p, scan_window);
335eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  UINT32_TO_STREAM(p, scan_interval);
336eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  UINT8_TO_STREAM(p, addr_type);
337eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  UINT8_TO_STREAM(p, discard_rule);
338c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji
339eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  btu_hcif_send_cmd_with_cb(FROM_HERE, HCI_BLE_BATCH_SCAN_OCF, param, len, cb);
340eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski}
341c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji
342eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski/* This function enables the customer specific feature in controller */
343eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowskivoid btm_ble_enable_batchscan(hci_cmd_cb cb) {
344eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  uint8_t len = BTM_BLE_BATCH_SCAN_ENB_DISB_LEN;
345eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  uint8_t param[len];
346eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  memset(param, 0, len);
347c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji
348eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  uint8_t* p = param;
349eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  UINT8_TO_STREAM(p, BTM_BLE_BATCH_SCAN_ENB_DISAB_CUST_FEATURE);
350eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  UINT8_TO_STREAM(p, 0x01 /* enable */);
351911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
352eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  btu_hcif_send_cmd_with_cb(FROM_HERE, HCI_BLE_BATCH_SCAN_OCF, param, len, cb);
353c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji}
354c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji
355eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski}  // namespace
356eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski
357c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji/*******************************************************************************
358ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
359ee96a3c60fca590d38025925c072d264e06493c4Myles Watson * Description      This function is called to write storage config params.
360ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
3619ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * Parameters:      batch_scan_full_max - Max storage space (in %) allocated to
3629ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *                                        full style
3639ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *                  batch_scan_trunc_max - Max storage space (in %) allocated to
3649ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *                                         trunc style
3659ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *                  batch_scan_notify_threshold - Setup notification level based
3669ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *                                                on total space
367eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski *                  cb - Setup callback pointer
368ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  p_thres_cback - Threshold callback pointer
369ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *                  ref_value - Reference value
370ee96a3c60fca590d38025925c072d264e06493c4Myles Watson *
371ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
372eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowskivoid BTM_BleSetStorageConfig(uint8_t batch_scan_full_max,
373eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski                             uint8_t batch_scan_trunc_max,
374eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski                             uint8_t batch_scan_notify_threshold,
375eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski                             Callback<void(uint8_t /* status */)> cb,
376eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski                             tBTM_BLE_SCAN_THRESHOLD_CBACK* p_thres_cback,
377eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski                             tBTM_BLE_REF_VALUE ref_value) {
378eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  if (!can_do_batch_scan()) {
379eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    cb.Run(BTM_ERR_PROCESSING);
380eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    return;
381eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  }
382911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
383eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  BTM_TRACE_EVENT("%s: %d, %d, %d, %d, %d", __func__,
384911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                  ble_batchscan_cb.cur_state, ref_value, batch_scan_full_max,
385911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                  batch_scan_trunc_max, batch_scan_notify_threshold);
386911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
387911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  ble_batchscan_cb.p_thres_cback = p_thres_cback;
388911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  ble_batchscan_cb.ref_value = ref_value;
389911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
390911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (batch_scan_full_max > BTM_BLE_ADV_SCAN_FULL_MAX ||
391911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      batch_scan_trunc_max > BTM_BLE_ADV_SCAN_TRUNC_MAX ||
392911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      batch_scan_notify_threshold > BTM_BLE_ADV_SCAN_THR_MAX) {
393911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BTM_TRACE_ERROR("Illegal set storage config params");
394eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    cb.Run(BTM_ILLEGAL_VALUE);
395eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    return;
396911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
397911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
398911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (BTM_BLE_SCAN_INVALID_STATE == ble_batchscan_cb.cur_state ||
399911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      BTM_BLE_SCAN_DISABLED_STATE == ble_batchscan_cb.cur_state ||
400911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      BTM_BLE_SCAN_DISABLE_CALLED == ble_batchscan_cb.cur_state) {
401eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    btm_ble_enable_batchscan(Bind(&feat_enable_cb));
402911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    ble_batchscan_cb.cur_state = BTM_BLE_SCAN_ENABLE_CALLED;
403911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
404911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
405911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  btm_ble_set_storage_config(batch_scan_full_max, batch_scan_trunc_max,
406eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski                             batch_scan_notify_threshold,
407eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski                             Bind(&storage_config_cb, cb));
408eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  return;
409c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji}
410c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji
411eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski/* This function is called to configure and enable batch scanning */
412eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowskivoid BTM_BleEnableBatchScan(tBTM_BLE_BATCH_SCAN_MODE scan_mode,
413eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski                            uint32_t scan_interval, uint32_t scan_window,
414eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski                            tBLE_ADDR_TYPE addr_type,
415eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski                            tBTM_BLE_DISCARD_RULE discard_rule,
416eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski                            Callback<void(uint8_t /* status */)> cb) {
417eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  BTM_TRACE_EVENT("%s: %d, %d, %d, %d, %d, %d", __func__, scan_mode,
418eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski                  scan_interval, scan_window, addr_type, discard_rule);
419eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski
420eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  if (!can_do_batch_scan()) {
421eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    cb.Run(BTM_ERR_PROCESSING);
422eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    return;
423911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
424911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
425eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  BTM_TRACE_DEBUG("%s: %d, %x, %x, %d, %d", __func__, scan_mode, scan_interval,
426eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski                  scan_window, discard_rule, ble_batchscan_cb.cur_state);
427911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
428911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Only 16 bits will be used for scan interval and scan window as per
429911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson   * agreement with Google */
430911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* So the standard LE range would suffice for scan interval and scan window */
431911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if ((BTM_BLE_ISVALID_PARAM(scan_interval, BTM_BLE_SCAN_INT_MIN,
432911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                             BTM_BLE_SCAN_INT_MAX) ||
433911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson       BTM_BLE_ISVALID_PARAM(scan_window, BTM_BLE_SCAN_WIN_MIN,
434911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                             BTM_BLE_SCAN_WIN_MAX)) &&
435911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      (BTM_BLE_BATCH_SCAN_MODE_PASS == scan_mode ||
436911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson       BTM_BLE_BATCH_SCAN_MODE_ACTI == scan_mode ||
437911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson       BTM_BLE_BATCH_SCAN_MODE_PASS_ACTI == scan_mode) &&
438911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      (BTM_BLE_DISCARD_OLD_ITEMS == discard_rule ||
439911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson       BTM_BLE_DISCARD_LOWER_RSSI_ITEMS == discard_rule)) {
440911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else {
441eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    BTM_TRACE_ERROR("%s: Illegal enable scan params", __func__);
442eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    cb.Run(BTM_ILLEGAL_VALUE);
443eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    return;
444911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
445c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji
446eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  if (BTM_BLE_SCAN_INVALID_STATE == ble_batchscan_cb.cur_state ||
447eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski      BTM_BLE_SCAN_DISABLED_STATE == ble_batchscan_cb.cur_state ||
448eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski      BTM_BLE_SCAN_DISABLE_CALLED == ble_batchscan_cb.cur_state) {
449eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    btm_ble_enable_batchscan(Bind(&feat_enable_cb));
450eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    ble_batchscan_cb.cur_state = BTM_BLE_SCAN_ENABLE_CALLED;
451eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  }
452c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji
453eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  ble_batchscan_cb.scan_mode = scan_mode;
454eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  ble_batchscan_cb.scan_interval = scan_interval;
455eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  ble_batchscan_cb.scan_window = scan_window;
456eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  ble_batchscan_cb.addr_type = addr_type;
457eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  ble_batchscan_cb.discard_rule = discard_rule;
458eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  /* This command starts batch scanning, if enabled */
459eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  btm_ble_set_batchscan_param(scan_mode, scan_interval, scan_window, addr_type,
460eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski                              discard_rule, Bind(&param_enable_cb, cb));
461eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski}
462c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji
463eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski/* This function is called to disable batch scanning */
464eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowskivoid BTM_BleDisableBatchScan(base::Callback<void(uint8_t /* status */)> cb) {
465eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  BTM_TRACE_EVENT(" BTM_BleDisableBatchScan");
466c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji
467eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  if (!can_do_batch_scan()) {
468eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    cb.Run(BTM_ERR_PROCESSING);
469eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    return;
470911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
471c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji
472eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  btm_ble_set_batchscan_param(
473eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski      BTM_BLE_BATCH_SCAN_MODE_DISABLE, ble_batchscan_cb.scan_interval,
474eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski      ble_batchscan_cb.scan_window, ble_batchscan_cb.addr_type,
475eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski      ble_batchscan_cb.discard_rule, Bind(&disable_cb, cb));
476eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  ble_batchscan_cb.cur_state = BTM_BLE_SCAN_DISABLE_CALLED;
477c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji}
478c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji
479eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski/* This function is called to start reading batch scan reports */
480eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowskivoid BTM_BleReadScanReports(tBTM_BLE_BATCH_SCAN_MODE scan_mode,
481eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski                            tBTM_BLE_SCAN_REP_CBACK cb) {
482911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t read_scan_mode = 0;
483911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
484eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  BTM_TRACE_EVENT("%s; %d", __func__, scan_mode);
485911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
486eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  if (!can_do_batch_scan()) {
487911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BTM_TRACE_ERROR("Controller does not support batch scan");
488eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    cb.Run(BTM_ERR_PROCESSING, 0, 0, {});
489eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    return;
490911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
491911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
492911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /*  Check if the requested scan mode has already been setup by the user */
493911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  read_scan_mode = ble_batchscan_cb.scan_mode & BTM_BLE_BATCH_SCAN_MODE_ACTI;
494911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (0 == read_scan_mode)
495911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    read_scan_mode = ble_batchscan_cb.scan_mode & BTM_BLE_BATCH_SCAN_MODE_PASS;
496911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
497911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /* Check only for modes, as scan reports can be called after disabling batch
498911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson   * scan */
499eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  if (read_scan_mode < 0 || (scan_mode != BTM_BLE_BATCH_SCAN_MODE_PASS &&
500eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski                             scan_mode != BTM_BLE_BATCH_SCAN_MODE_ACTI)) {
501911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    BTM_TRACE_ERROR("Illegal read scan params: %d, %d, %d", read_scan_mode,
502911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                    scan_mode, ble_batchscan_cb.cur_state);
503eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    cb.Run(BTM_ILLEGAL_VALUE, 0, 0, {});
504eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    return;
505911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
506eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski
507eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  btm_ble_read_batchscan_reports(
508eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski      scan_mode, base::Bind(&read_reports_cb, std::vector<uint8_t>(), 0, cb));
509eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  return;
510c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji}
511c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji
512eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski/* This function is called to setup the callback for tracking */
513eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowskivoid BTM_BleTrackAdvertiser(tBTM_BLE_TRACK_ADV_CBACK* p_track_cback,
514eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski                            tBTM_BLE_REF_VALUE ref_value) {
515eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  BTM_TRACE_EVENT("%s:", __func__);
516911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
517eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  if (!can_do_batch_scan()) {
518eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    BTM_TRACE_ERROR("Controller does not support batch scan");
519911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
520eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    tBTM_BLE_TRACK_ADV_DATA track_adv_data;
521eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    memset(&track_adv_data, 0, sizeof(tBTM_BLE_TRACK_ADV_DATA));
522eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    track_adv_data.advertiser_info_present =
523eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski        NO_ADV_INFO_PRESENT; /* Indicates failure */
524eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    track_adv_data.client_if = (uint8_t)ref_value;
525eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    p_track_cback(&track_adv_data);
526eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski    return;
527911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
528911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
529911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  ble_advtrack_cb.p_track_cback = p_track_cback;
530911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  ble_advtrack_cb.ref_value = ref_value;
531eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  return;
5321acb61ce065053f91a0f8d43e8328c9eeec4b5edSatya Calloji}
5331acb61ce065053f91a0f8d43e8328c9eeec4b5edSatya Calloji
534eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski/**
535eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski * This function initialize the batch scan control block.
536eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski **/
537911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid btm_ble_batchscan_init(void) {
538911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BTM_TRACE_EVENT(" btm_ble_batchscan_init");
539911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  memset(&ble_batchscan_cb, 0, sizeof(tBTM_BLE_BATCH_SCAN_CB));
540911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  memset(&ble_advtrack_cb, 0, sizeof(tBTM_BLE_ADV_TRACK_CB));
541911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BTM_RegisterForVSEvents(btm_ble_batchscan_filter_track_adv_vse_cback, true);
542c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji}
543c4e2596a112a0dd63ac681b1226548c0f95e828cSatya Calloji
544eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski/**
545eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski * This function cleans the batch scan control block.
546eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski **/
547911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonvoid btm_ble_batchscan_cleanup(void) {
548eab3651db4792695080d24b2a6e723a68cc62d22Jakub Pawlowski  BTM_TRACE_EVENT("%s", __func__);
549adb7bb50469db992969295792a7ba3b73f9e24b3Satya Calloji
550911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  memset(&ble_batchscan_cb, 0, sizeof(tBTM_BLE_BATCH_SCAN_CB));
551911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  memset(&ble_advtrack_cb, 0, sizeof(tBTM_BLE_ADV_TRACK_CB));
552adb7bb50469db992969295792a7ba3b73f9e24b3Satya Calloji}
553