1 /*
2 * Copyright (C) 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "rust/topshim/gatt/gatt_ble_scanner_shim.h"
18
19 #include <base/functional/bind.h>
20 #include <base/functional/callback.h>
21
22 #include <algorithm>
23 #include <iterator>
24 #include <memory>
25 #include <utility>
26 #include <vector>
27
28 #include "include/hardware/bt_common_types.h"
29 #include "rust/cxx.h"
30 #include "src/profiles/gatt.rs.h"
31 #include "types/bluetooth/uuid.h"
32 #include "types/raw_address.h"
33
34 namespace bluetooth {
35 namespace topshim {
36 namespace rust {
37
38 namespace rusty = ::bluetooth::topshim::rust;
39
40 namespace internal {
ConvertApcfFromRust(const RustApcfCommand & command)41 ApcfCommand ConvertApcfFromRust(const RustApcfCommand& command) {
42 // Copy vectors + arrays
43 std::vector<uint8_t> name, data, data_mask, meta_data;
44 std::array<uint8_t, 16> irk;
45 std::copy(command.name.begin(), command.name.end(), std::back_inserter(name));
46 std::copy(command.data.begin(), command.data.end(), std::back_inserter(data));
47 std::copy(command.data_mask.begin(), command.data_mask.end(), std::back_inserter(data_mask));
48 std::copy(command.irk.begin(), command.irk.end(), std::begin(irk));
49 std::copy(command.meta_data.begin(), command.meta_data.end(), std::back_inserter(meta_data));
50
51 ApcfCommand converted = {
52 .type = command.type_,
53 .address = command.address,
54 .addr_type = command.addr_type,
55 .uuid = command.uuid,
56 .uuid_mask = command.uuid_mask,
57 .name = name,
58 .company = command.company,
59 .company_mask = command.company_mask,
60 .org_id = command.org_id,
61 .tds_flags = command.tds_flags,
62 .tds_flags_mask = command.tds_flags_mask,
63 .meta_data_type = command.meta_data_type,
64 .meta_data = meta_data,
65 .ad_type = command.ad_type,
66 .data = data,
67 .data_mask = data_mask,
68 .irk = irk,
69 };
70
71 return converted;
72 }
73
ConvertApcfVec(const::rust::Vec<RustApcfCommand> & rustvec)74 std::vector<ApcfCommand> ConvertApcfVec(const ::rust::Vec<RustApcfCommand>& rustvec) {
75 std::vector<ApcfCommand> converted;
76
77 for (const RustApcfCommand& command : rustvec) {
78 converted.push_back(ConvertApcfFromRust(command));
79 }
80
81 return converted;
82 }
83
ConvertRustByteArray(const::rust::Vec<uint8_t> & bytes)84 std::vector<uint8_t> ConvertRustByteArray(const ::rust::Vec<uint8_t>& bytes) {
85 std::vector<uint8_t> converted;
86
87 std::copy(bytes.begin(), bytes.end(), std::back_inserter(converted));
88
89 return converted;
90 }
91
ConvertAdvMonitorPattern(const RustMsftAdvMonitorPattern & pattern)92 MsftAdvMonitorPattern ConvertAdvMonitorPattern(const RustMsftAdvMonitorPattern& pattern) {
93 MsftAdvMonitorPattern converted = {
94 .ad_type = pattern.ad_type,
95 .start_byte = pattern.start_byte,
96 .pattern = ConvertRustByteArray(pattern.pattern),
97 };
98
99 return converted;
100 }
101
ConvertAdvMonitorPatterns(const::rust::Vec<RustMsftAdvMonitorPattern> & patterns)102 std::vector<MsftAdvMonitorPattern> ConvertAdvMonitorPatterns(
103 const ::rust::Vec<RustMsftAdvMonitorPattern>& patterns) {
104 std::vector<MsftAdvMonitorPattern> converted;
105
106 for (const auto& pattern : patterns) {
107 converted.push_back(ConvertAdvMonitorPattern(pattern));
108 }
109
110 return converted;
111 }
112
ConvertAdvMonitorAddress(RustMsftAdvMonitorAddress rust_addr_info)113 MsftAdvMonitorAddress ConvertAdvMonitorAddress(RustMsftAdvMonitorAddress rust_addr_info) {
114 MsftAdvMonitorAddress addr_info;
115 addr_info.addr_type = rust_addr_info.addr_type;
116 addr_info.bd_addr = rust_addr_info.bd_addr;
117 return addr_info;
118 }
119
ConvertAdvMonitor(const RustMsftAdvMonitor & monitor)120 MsftAdvMonitor ConvertAdvMonitor(const RustMsftAdvMonitor& monitor) {
121 MsftAdvMonitor converted = {
122 .rssi_threshold_high = monitor.rssi_high_threshold,
123 .rssi_threshold_low = monitor.rssi_low_threshold,
124 .rssi_threshold_low_time_interval = monitor.rssi_low_timeout,
125 .rssi_sampling_period = monitor.rssi_sampling_period,
126 .condition_type = monitor.condition_type,
127 .patterns = ConvertAdvMonitorPatterns(monitor.patterns),
128 .addr_info = ConvertAdvMonitorAddress(monitor.addr_info),
129 };
130 return converted;
131 }
132 } // namespace internal
133
134 // ScanningCallbacks implementations
135
OnScannerRegistered(const bluetooth::Uuid app_uuid,uint8_t scannerId,uint8_t status)136 void BleScannerIntf::OnScannerRegistered(const bluetooth::Uuid app_uuid, uint8_t scannerId,
137 uint8_t status) {
138 rusty::gdscan_on_scanner_registered(reinterpret_cast<const signed char*>(&app_uuid), scannerId,
139 status);
140 }
141
OnSetScannerParameterComplete(uint8_t scannerId,uint8_t status)142 void BleScannerIntf::OnSetScannerParameterComplete(uint8_t scannerId, uint8_t status) {
143 rusty::gdscan_on_set_scanner_parameter_complete(scannerId, status);
144 }
145
OnScanResult(uint16_t event_type,uint8_t addr_type,RawAddress addr,uint8_t primary_phy,uint8_t secondary_phy,uint8_t advertising_sid,int8_t tx_power,int8_t rssi,uint16_t periodic_adv_int,std::vector<uint8_t> adv_data)146 void BleScannerIntf::OnScanResult(uint16_t event_type, uint8_t addr_type, RawAddress addr,
147 uint8_t primary_phy, uint8_t secondary_phy,
148 uint8_t advertising_sid, int8_t tx_power, int8_t rssi,
149 uint16_t periodic_adv_int, std::vector<uint8_t> adv_data) {
150 rusty::gdscan_on_scan_result(event_type, addr_type, &addr, primary_phy, secondary_phy,
151 advertising_sid, tx_power, rssi, periodic_adv_int, adv_data.data(),
152 adv_data.size());
153 }
154
OnTrackAdvFoundLost(AdvertisingTrackInfo ati)155 void BleScannerIntf::OnTrackAdvFoundLost(AdvertisingTrackInfo ati) {
156 rusty::RustAdvertisingTrackInfo rust_info = {
157 .monitor_handle = ati.monitor_handle,
158 .scanner_id = ati.scanner_id,
159 .filter_index = ati.filter_index,
160 .advertiser_state = ati.advertiser_state,
161 .advertiser_info_present = ati.advertiser_info_present,
162 .advertiser_address = ati.advertiser_address,
163 .advertiser_address_type = ati.advertiser_address_type,
164 .tx_power = ati.tx_power,
165 .rssi = ati.rssi,
166 .timestamp = ati.time_stamp,
167 .adv_packet_len = ati.adv_packet_len,
168 // .adv_packet is copied below
169 .scan_response_len = ati.scan_response_len,
170 // .scan_response is copied below
171 };
172
173 std::copy(rust_info.adv_packet.begin(), rust_info.adv_packet.end(),
174 std::back_inserter(ati.adv_packet));
175 std::copy(rust_info.scan_response.begin(), rust_info.scan_response.end(),
176 std::back_inserter(ati.scan_response));
177
178 rusty::gdscan_on_track_adv_found_lost(rust_info);
179 }
180
OnBatchScanReports(int client_if,int status,int report_format,int num_records,std::vector<uint8_t> data)181 void BleScannerIntf::OnBatchScanReports(int client_if, int status, int report_format,
182 int num_records, std::vector<uint8_t> data) {
183 rusty::gdscan_on_batch_scan_reports(client_if, status, report_format, num_records, data.data(),
184 data.size());
185 }
186
OnBatchScanThresholdCrossed(int client_if)187 void BleScannerIntf::OnBatchScanThresholdCrossed(int client_if) {
188 rusty::gdscan_on_batch_scan_threshold_crossed(client_if);
189 }
190
191 // BleScannerInterface implementations
192
RegisterScanner(Uuid uuid)193 void BleScannerIntf::RegisterScanner(Uuid uuid) {
194 scanner_intf_->RegisterScanner(
195 uuid, base::Bind(&BleScannerIntf::OnRegisterCallback, base::Unretained(this), uuid));
196 }
197
Unregister(uint8_t scanner_id)198 void BleScannerIntf::Unregister(uint8_t scanner_id) { scanner_intf_->Unregister(scanner_id); }
199
Scan(bool start)200 void BleScannerIntf::Scan(bool start) { scanner_intf_->Scan(start); }
201
ScanFilterParamSetup(uint8_t scanner_id,uint8_t action,uint8_t filter_index,btgatt_filt_param_setup_t filter_param)202 void BleScannerIntf::ScanFilterParamSetup(uint8_t scanner_id, uint8_t action, uint8_t filter_index,
203 btgatt_filt_param_setup_t filter_param) {
204 auto converted = std::make_unique<::btgatt_filt_param_setup_t>(std::move(filter_param));
205
206 scanner_intf_->ScanFilterParamSetup(scanner_id, action, filter_index, std::move(converted),
207 base::Bind(&BleScannerIntf::OnFilterParamSetupCallback,
208 base::Unretained(this), scanner_id));
209 }
210
ScanFilterAdd(uint8_t filter_index,::rust::Vec<RustApcfCommand> filters)211 void BleScannerIntf::ScanFilterAdd(uint8_t filter_index, ::rust::Vec<RustApcfCommand> filters) {
212 auto converted = internal::ConvertApcfVec(filters);
213 scanner_intf_->ScanFilterAdd(filter_index, converted,
214 base::Bind(&BleScannerIntf::OnFilterConfigCallback,
215 base::Unretained(this), filter_index));
216 }
217
ScanFilterClear(uint8_t filter_index)218 void BleScannerIntf::ScanFilterClear(uint8_t filter_index) {
219 scanner_intf_->ScanFilterClear(filter_index, base::Bind(&BleScannerIntf::OnFilterConfigCallback,
220 base::Unretained(this), filter_index));
221 }
222
ScanFilterEnable(bool enable)223 void BleScannerIntf::ScanFilterEnable(bool enable) {
224 scanner_intf_->ScanFilterEnable(
225 enable, base::Bind(&BleScannerIntf::OnEnableCallback, base::Unretained(this)));
226 }
227
IsMsftSupported()228 bool BleScannerIntf::IsMsftSupported() { return scanner_intf_->IsMsftSupported(); }
229
MsftAdvMonitorAdd(const RustMsftAdvMonitor & monitor)230 void BleScannerIntf::MsftAdvMonitorAdd(const RustMsftAdvMonitor& monitor) {
231 scanner_intf_->MsftAdvMonitorAdd(
232 internal::ConvertAdvMonitor(monitor),
233 base::Bind(&BleScannerIntf::OnMsftAdvMonitorAddCallback, base::Unretained(this)));
234 }
235
MsftAdvMonitorRemove(uint8_t monitor_handle)236 void BleScannerIntf::MsftAdvMonitorRemove(uint8_t monitor_handle) {
237 scanner_intf_->MsftAdvMonitorRemove(
238 monitor_handle,
239 base::Bind(&BleScannerIntf::OnMsftAdvMonitorRemoveCallback, base::Unretained(this)));
240 }
241
MsftAdvMonitorEnable(bool enable)242 void BleScannerIntf::MsftAdvMonitorEnable(bool enable) {
243 scanner_intf_->MsftAdvMonitorEnable(
244 enable,
245 base::Bind(&BleScannerIntf::OnMsftAdvMonitorEnableCallback, base::Unretained(this)));
246 }
247
SetScanParameters(uint8_t scanner_id,uint8_t scan_type,uint16_t scan_interval,uint16_t scan_window,uint8_t scan_phy)248 void BleScannerIntf::SetScanParameters(uint8_t scanner_id, uint8_t scan_type,
249 uint16_t scan_interval, uint16_t scan_window,
250 uint8_t scan_phy) {
251 scanner_intf_->SetScanParameters(
252 scanner_id, scan_type, scan_interval, scan_window, scan_phy,
253 base::Bind(&BleScannerIntf::OnStatusCallback, base::Unretained(this), scanner_id));
254 }
255
BatchscanConfigStorage(uint8_t scanner_id,int32_t batch_scan_full_max,int32_t batch_scan_trunc_max,int32_t batch_scan_notify_threshold)256 void BleScannerIntf::BatchscanConfigStorage(uint8_t scanner_id, int32_t batch_scan_full_max,
257 int32_t batch_scan_trunc_max,
258 int32_t batch_scan_notify_threshold) {
259 scanner_intf_->BatchscanConfigStorage(
260 scanner_id, batch_scan_full_max, batch_scan_trunc_max, batch_scan_notify_threshold,
261 base::Bind(&BleScannerIntf::OnStatusCallback, base::Unretained(this), scanner_id));
262 }
263
BatchscanEnable(int32_t scan_mode,uint16_t scan_interval,uint16_t scan_window,int32_t addr_type,int32_t discard_rule)264 void BleScannerIntf::BatchscanEnable(int32_t scan_mode, uint16_t scan_interval,
265 uint16_t scan_window, int32_t addr_type,
266 int32_t discard_rule) {
267 scanner_intf_->BatchscanEnable(
268 scan_mode, scan_interval, scan_window, addr_type, discard_rule,
269 base::Bind(&BleScannerIntf::OnStatusCallback, base::Unretained(this), 0));
270 }
271
BatchscanDisable()272 void BleScannerIntf::BatchscanDisable() {
273 scanner_intf_->BatchscanDisable(
274 base::Bind(&BleScannerIntf::OnStatusCallback, base::Unretained(this), 0));
275 }
276
BatchscanReadReports(uint8_t scanner_id,int32_t scan_mode)277 void BleScannerIntf::BatchscanReadReports(uint8_t scanner_id, int32_t scan_mode) {
278 scanner_intf_->BatchscanReadReports(scanner_id, scan_mode);
279 }
280
StartSync(uint8_t sid,RawAddress addr,uint16_t skip,uint16_t timeout)281 void BleScannerIntf::StartSync(uint8_t sid, RawAddress addr, uint16_t skip, uint16_t timeout) {
282 scanner_intf_->StartSync(sid, addr, skip, timeout, 0 /* place holder */);
283 }
284
StopSync(uint16_t handle)285 void BleScannerIntf::StopSync(uint16_t handle) { scanner_intf_->StopSync(handle); }
286
CancelCreateSync(uint8_t sid,RawAddress addr)287 void BleScannerIntf::CancelCreateSync(uint8_t sid, RawAddress addr) {
288 scanner_intf_->CancelCreateSync(sid, addr);
289 }
290
TransferSync(RawAddress addr,uint16_t service_data,uint16_t sync_handle)291 void BleScannerIntf::TransferSync(RawAddress addr, uint16_t service_data, uint16_t sync_handle) {
292 scanner_intf_->TransferSync(addr, service_data, sync_handle, 0 /* place holder */);
293 }
294
TransferSetInfo(RawAddress addr,uint16_t service_data,uint8_t adv_handle)295 void BleScannerIntf::TransferSetInfo(RawAddress addr, uint16_t service_data, uint8_t adv_handle) {
296 scanner_intf_->TransferSetInfo(addr, service_data, adv_handle, 0 /* place holder */);
297 }
298
SyncTxParameters(RawAddress addr,uint8_t mode,uint16_t skip,uint16_t timeout)299 void BleScannerIntf::SyncTxParameters(RawAddress addr, uint8_t mode, uint16_t skip,
300 uint16_t timeout) {
301 scanner_intf_->SyncTxParameters(addr, mode, skip, timeout, 0 /* place holder */);
302 }
303
OnRegisterCallback(Uuid uuid,uint8_t scanner_id,uint8_t btm_status)304 void BleScannerIntf::OnRegisterCallback(Uuid uuid, uint8_t scanner_id, uint8_t btm_status) {
305 rusty::gdscan_register_callback(uuid, scanner_id, btm_status);
306 }
307
OnStatusCallback(uint8_t scanner_id,uint8_t btm_status)308 void BleScannerIntf::OnStatusCallback(uint8_t scanner_id, uint8_t btm_status) {
309 rusty::gdscan_status_callback(scanner_id, btm_status);
310 }
311
OnEnableCallback(uint8_t action,uint8_t btm_status)312 void BleScannerIntf::OnEnableCallback(uint8_t action, uint8_t btm_status) {
313 rusty::gdscan_enable_callback(action, btm_status);
314 }
315
OnFilterParamSetupCallback(uint8_t scanner_id,uint8_t avbl_space,uint8_t action_type,uint8_t btm_status)316 void BleScannerIntf::OnFilterParamSetupCallback(uint8_t scanner_id, uint8_t avbl_space,
317 uint8_t action_type, uint8_t btm_status) {
318 rusty::gdscan_filter_param_setup_callback(scanner_id, avbl_space, action_type, btm_status);
319 }
320
OnFilterConfigCallback(uint8_t filter_index,uint8_t filt_type,uint8_t avbl_space,uint8_t action,uint8_t btm_status)321 void BleScannerIntf::OnFilterConfigCallback(uint8_t filter_index, uint8_t filt_type,
322 uint8_t avbl_space, uint8_t action,
323 uint8_t btm_status) {
324 rusty::gdscan_filter_config_callback(filter_index, filt_type, avbl_space, action, btm_status);
325 }
326
OnMsftAdvMonitorAddCallback(uint8_t monitor_handle,uint8_t status)327 void BleScannerIntf::OnMsftAdvMonitorAddCallback(uint8_t monitor_handle, uint8_t status) {
328 rusty::gdscan_msft_adv_monitor_add_callback(monitor_handle, status);
329 }
330
OnMsftAdvMonitorRemoveCallback(uint8_t status)331 void BleScannerIntf::OnMsftAdvMonitorRemoveCallback(uint8_t status) {
332 rusty::gdscan_msft_adv_monitor_remove_callback(status);
333 }
334
OnMsftAdvMonitorEnableCallback(uint8_t status)335 void BleScannerIntf::OnMsftAdvMonitorEnableCallback(uint8_t status) {
336 rusty::gdscan_msft_adv_monitor_enable_callback(status);
337 }
338
OnPeriodicSyncStarted(int,uint8_t status,uint16_t sync_handle,uint8_t advertising_sid,uint8_t address_type,RawAddress addr,uint8_t phy,uint16_t interval)339 void BleScannerIntf::OnPeriodicSyncStarted(int, uint8_t status, uint16_t sync_handle,
340 uint8_t advertising_sid, uint8_t address_type,
341 RawAddress addr, uint8_t phy, uint16_t interval) {
342 rusty::gdscan_start_sync_callback(status, sync_handle, advertising_sid, address_type, &addr, phy,
343 interval);
344 }
345
OnPeriodicSyncReport(uint16_t sync_handle,int8_t tx_power,int8_t rssi,uint8_t status,std::vector<uint8_t> data)346 void BleScannerIntf::OnPeriodicSyncReport(uint16_t sync_handle, int8_t tx_power, int8_t rssi,
347 uint8_t status, std::vector<uint8_t> data) {
348 rusty::gdscan_sync_report_callback(sync_handle, tx_power, rssi, status, data.data(), data.size());
349 }
350
OnPeriodicSyncLost(uint16_t sync_handle)351 void BleScannerIntf::OnPeriodicSyncLost(uint16_t sync_handle) {
352 rusty::gdscan_sync_lost_callback(sync_handle);
353 }
354
OnPeriodicSyncTransferred(int,uint8_t status,RawAddress addr)355 void BleScannerIntf::OnPeriodicSyncTransferred(int, uint8_t status, RawAddress addr) {
356 rusty::gdscan_sync_transfer_callback(status, &addr);
357 }
358
OnBigInfoReport(uint16_t sync_handle,bool encrypted)359 void BleScannerIntf::OnBigInfoReport(uint16_t sync_handle, bool encrypted) {
360 rusty::gdscan_biginfo_report_callback(sync_handle, encrypted);
361 }
362
RegisterCallbacks()363 void BleScannerIntf::RegisterCallbacks() {
364 // Register self as a callback handler. We will dispatch to Rust callbacks.
365 scanner_intf_->RegisterCallbacks(this);
366 }
367
368 // ScanningCallbacks overrides
GetBleScannerIntf(const unsigned char * gatt_intf)369 std::unique_ptr<BleScannerIntf> GetBleScannerIntf(const unsigned char* gatt_intf) {
370 return std::make_unique<BleScannerIntf>(
371 reinterpret_cast<const btgatt_interface_t*>(gatt_intf)->scanner);
372 }
373
374 } // namespace rust
375 } // namespace topshim
376 } // namespace bluetooth
377