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 <vector>
26
27 #include "include/hardware/bt_common_types.h"
28 #include "rust/cxx.h"
29 #include "src/profiles/gatt.rs.h"
30 #include "types/bluetooth/uuid.h"
31 #include "types/raw_address.h"
32
33 namespace bluetooth {
34 namespace topshim {
35 namespace rust {
36
37 namespace rusty = ::bluetooth::topshim::rust;
38
39 namespace internal {
ConvertApcfFromRust(const RustApcfCommand & command)40 ApcfCommand ConvertApcfFromRust(const RustApcfCommand& command) {
41 // Copy vectors + arrays
42 std::vector<uint8_t> name, data, data_mask, meta_data;
43 std::array<uint8_t, 16> irk;
44 std::copy(command.name.begin(), command.name.end(), std::back_inserter(name));
45 std::copy(command.data.begin(), command.data.end(), std::back_inserter(data));
46 std::copy(command.data_mask.begin(), command.data_mask.end(), std::back_inserter(data_mask));
47 std::copy(command.irk.begin(), command.irk.end(), std::begin(irk));
48 std::copy(command.meta_data.begin(), command.meta_data.end(), std::back_inserter(meta_data));
49
50 ApcfCommand converted = {
51 .type = command.type_,
52 .address = command.address,
53 .addr_type = command.addr_type,
54 .uuid = command.uuid,
55 .uuid_mask = command.uuid_mask,
56 .name = name,
57 .company = command.company,
58 .company_mask = command.company_mask,
59 .org_id = command.org_id,
60 .tds_flags = command.tds_flags,
61 .tds_flags_mask = command.tds_flags_mask,
62 .meta_data_type = command.meta_data_type,
63 .meta_data = meta_data,
64 .ad_type = command.ad_type,
65 .data = data,
66 .data_mask = data_mask,
67 .irk = irk,
68 };
69
70 return converted;
71 }
72
ConvertApcfVec(const::rust::Vec<RustApcfCommand> & rustvec)73 std::vector<ApcfCommand> ConvertApcfVec(const ::rust::Vec<RustApcfCommand>& rustvec) {
74 std::vector<ApcfCommand> converted;
75
76 for (const RustApcfCommand& command : rustvec) {
77 converted.push_back(ConvertApcfFromRust(command));
78 }
79
80 return converted;
81 }
82
ConvertRustByteArray(const::rust::Vec<uint8_t> & bytes)83 std::vector<uint8_t> ConvertRustByteArray(const ::rust::Vec<uint8_t>& bytes) {
84 std::vector<uint8_t> converted;
85
86 std::copy(bytes.begin(), bytes.end(), std::back_inserter(converted));
87
88 return converted;
89 }
90
ConvertAdvMonitorPattern(const RustMsftAdvMonitorPattern & pattern)91 MsftAdvMonitorPattern ConvertAdvMonitorPattern(const RustMsftAdvMonitorPattern& pattern) {
92 MsftAdvMonitorPattern converted = {
93 .ad_type = pattern.ad_type,
94 .start_byte = pattern.start_byte,
95 .pattern = ConvertRustByteArray(pattern.pattern),
96 };
97
98 return converted;
99 }
100
ConvertAdvMonitorPatterns(const::rust::Vec<RustMsftAdvMonitorPattern> & patterns)101 std::vector<MsftAdvMonitorPattern> ConvertAdvMonitorPatterns(const ::rust::Vec<RustMsftAdvMonitorPattern>& patterns) {
102 std::vector<MsftAdvMonitorPattern> converted;
103
104 for (const auto& pattern : patterns) {
105 converted.push_back(ConvertAdvMonitorPattern(pattern));
106 }
107
108 return converted;
109 }
110
ConvertAdvMonitorAddress(RustMsftAdvMonitorAddress rust_addr_info)111 MsftAdvMonitorAddress ConvertAdvMonitorAddress(RustMsftAdvMonitorAddress rust_addr_info) {
112 MsftAdvMonitorAddress addr_info;
113 addr_info.addr_type = rust_addr_info.addr_type;
114 addr_info.bd_addr = rust_addr_info.bd_addr;
115 return addr_info;
116 }
117
ConvertAdvMonitor(const RustMsftAdvMonitor & monitor)118 MsftAdvMonitor ConvertAdvMonitor(const RustMsftAdvMonitor& monitor) {
119 MsftAdvMonitor converted = {
120 .rssi_threshold_high = monitor.rssi_high_threshold,
121 .rssi_threshold_low = monitor.rssi_low_threshold,
122 .rssi_threshold_low_time_interval = monitor.rssi_low_timeout,
123 .rssi_sampling_period = monitor.rssi_sampling_period,
124 .condition_type = monitor.condition_type,
125 .patterns = ConvertAdvMonitorPatterns(monitor.patterns),
126 .addr_info = ConvertAdvMonitorAddress(monitor.addr_info),
127 };
128 return converted;
129 }
130 } // namespace internal
131
132 // ScanningCallbacks implementations
133
OnScannerRegistered(const bluetooth::Uuid app_uuid,uint8_t scannerId,uint8_t status)134 void BleScannerIntf::OnScannerRegistered(const bluetooth::Uuid app_uuid, uint8_t scannerId, uint8_t status) {
135 rusty::gdscan_on_scanner_registered(reinterpret_cast<const signed char*>(&app_uuid), scannerId, status);
136 }
137
OnSetScannerParameterComplete(uint8_t scannerId,uint8_t status)138 void BleScannerIntf::OnSetScannerParameterComplete(uint8_t scannerId, uint8_t status) {
139 rusty::gdscan_on_set_scanner_parameter_complete(scannerId, status);
140 }
141
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)142 void BleScannerIntf::OnScanResult(
143 uint16_t event_type,
144 uint8_t addr_type,
145 RawAddress addr,
146 uint8_t primary_phy,
147 uint8_t secondary_phy,
148 uint8_t advertising_sid,
149 int8_t tx_power,
150 int8_t rssi,
151 uint16_t periodic_adv_int,
152 std::vector<uint8_t> adv_data) {
153 rusty::gdscan_on_scan_result(
154 event_type,
155 addr_type,
156 &addr,
157 primary_phy,
158 secondary_phy,
159 advertising_sid,
160 tx_power,
161 rssi,
162 periodic_adv_int,
163 adv_data.data(),
164 adv_data.size());
165 }
166
OnTrackAdvFoundLost(AdvertisingTrackInfo ati)167 void BleScannerIntf::OnTrackAdvFoundLost(AdvertisingTrackInfo ati) {
168 rusty::RustAdvertisingTrackInfo rust_info = {
169 .monitor_handle = ati.monitor_handle,
170 .scanner_id = ati.scanner_id,
171 .filter_index = ati.filter_index,
172 .advertiser_state = ati.advertiser_state,
173 .advertiser_info_present = ati.advertiser_info_present,
174 .advertiser_address = ati.advertiser_address,
175 .advertiser_address_type = ati.advertiser_address_type,
176 .tx_power = ati.tx_power,
177 .rssi = ati.rssi,
178 .timestamp = ati.time_stamp,
179 .adv_packet_len = ati.adv_packet_len,
180 // .adv_packet is copied below
181 .scan_response_len = ati.scan_response_len,
182 // .scan_response is copied below
183 };
184
185 std::copy(rust_info.adv_packet.begin(), rust_info.adv_packet.end(), std::back_inserter(ati.adv_packet));
186 std::copy(rust_info.scan_response.begin(), rust_info.scan_response.end(), std::back_inserter(ati.scan_response));
187
188 rusty::gdscan_on_track_adv_found_lost(rust_info);
189 }
190
OnBatchScanReports(int client_if,int status,int report_format,int num_records,std::vector<uint8_t> data)191 void BleScannerIntf::OnBatchScanReports(
192 int client_if, int status, int report_format, int num_records, std::vector<uint8_t> data) {
193 rusty::gdscan_on_batch_scan_reports(client_if, status, report_format, num_records, data.data(), data.size());
194 }
195
OnBatchScanThresholdCrossed(int client_if)196 void BleScannerIntf::OnBatchScanThresholdCrossed(int client_if) {
197 rusty::gdscan_on_batch_scan_threshold_crossed(client_if);
198 }
199
200 // BleScannerInterface implementations
201
RegisterScanner(Uuid uuid)202 void BleScannerIntf::RegisterScanner(Uuid uuid) {
203 scanner_intf_->RegisterScanner(
204 uuid, base::Bind(&BleScannerIntf::OnRegisterCallback, base::Unretained(this), uuid));
205 }
206
Unregister(uint8_t scanner_id)207 void BleScannerIntf::Unregister(uint8_t scanner_id) {
208 scanner_intf_->Unregister(scanner_id);
209 }
210
Scan(bool start)211 void BleScannerIntf::Scan(bool start) {
212 scanner_intf_->Scan(start);
213 }
214
ScanFilterParamSetup(uint8_t scanner_id,uint8_t action,uint8_t filter_index,btgatt_filt_param_setup_t filter_param)215 void BleScannerIntf::ScanFilterParamSetup(
216 uint8_t scanner_id,
217 uint8_t action,
218 uint8_t filter_index,
219 btgatt_filt_param_setup_t filter_param) {
220 auto converted = std::make_unique<::btgatt_filt_param_setup_t>(std::move(filter_param));
221
222 scanner_intf_->ScanFilterParamSetup(
223 scanner_id,
224 action,
225 filter_index,
226 std::move(converted),
227 base::Bind(&BleScannerIntf::OnFilterParamSetupCallback, base::Unretained(this), scanner_id));
228 }
229
ScanFilterAdd(uint8_t filter_index,::rust::Vec<RustApcfCommand> filters)230 void BleScannerIntf::ScanFilterAdd(uint8_t filter_index, ::rust::Vec<RustApcfCommand> filters) {
231 auto converted = internal::ConvertApcfVec(filters);
232 scanner_intf_->ScanFilterAdd(
233 filter_index,
234 converted,
235 base::Bind(&BleScannerIntf::OnFilterConfigCallback, base::Unretained(this), filter_index));
236 }
237
ScanFilterClear(uint8_t filter_index)238 void BleScannerIntf::ScanFilterClear(uint8_t filter_index) {
239 scanner_intf_->ScanFilterClear(
240 filter_index, base::Bind(&BleScannerIntf::OnFilterConfigCallback, base::Unretained(this), filter_index));
241 }
242
ScanFilterEnable(bool enable)243 void BleScannerIntf::ScanFilterEnable(bool enable) {
244 scanner_intf_->ScanFilterEnable(enable, base::Bind(&BleScannerIntf::OnEnableCallback, base::Unretained(this)));
245 }
246
247 #if TARGET_FLOSS
248
IsMsftSupported()249 bool BleScannerIntf::IsMsftSupported() {
250 return scanner_intf_->IsMsftSupported();
251 }
252
MsftAdvMonitorAdd(uint32_t call_id,const RustMsftAdvMonitor & monitor)253 void BleScannerIntf::MsftAdvMonitorAdd(uint32_t call_id, const RustMsftAdvMonitor& monitor) {
254 scanner_intf_->MsftAdvMonitorAdd(
255 internal::ConvertAdvMonitor(monitor),
256 base::Bind(&BleScannerIntf::OnMsftAdvMonitorAddCallback, base::Unretained(this), call_id));
257 }
258
MsftAdvMonitorRemove(uint32_t call_id,uint8_t monitor_handle)259 void BleScannerIntf::MsftAdvMonitorRemove(uint32_t call_id, uint8_t monitor_handle) {
260 scanner_intf_->MsftAdvMonitorRemove(
261 monitor_handle, base::Bind(&BleScannerIntf::OnMsftAdvMonitorRemoveCallback, base::Unretained(this), call_id));
262 }
263
MsftAdvMonitorEnable(uint32_t call_id,bool enable)264 void BleScannerIntf::MsftAdvMonitorEnable(uint32_t call_id, bool enable) {
265 scanner_intf_->MsftAdvMonitorEnable(
266 enable, base::Bind(&BleScannerIntf::OnMsftAdvMonitorEnableCallback, base::Unretained(this), call_id));
267 }
268
269 #else
270
IsMsftSupported()271 bool BleScannerIntf::IsMsftSupported() {
272 return false;
273 }
MsftAdvMonitorAdd(uint32_t,const RustMsftAdvMonitor &)274 void BleScannerIntf::MsftAdvMonitorAdd(uint32_t, const RustMsftAdvMonitor&) {}
MsftAdvMonitorRemove(uint32_t,uint8_t)275 void BleScannerIntf::MsftAdvMonitorRemove(uint32_t, uint8_t) {}
MsftAdvMonitorEnable(uint32_t,bool)276 void BleScannerIntf::MsftAdvMonitorEnable(uint32_t, bool) {}
277
278 #endif
279
SetScanParameters(uint8_t scanner_id,uint8_t scan_type,uint16_t scan_interval,uint16_t scan_window,uint8_t scan_phy)280 void BleScannerIntf::SetScanParameters(
281 uint8_t scanner_id,
282 uint8_t scan_type,
283 uint16_t scan_interval,
284 uint16_t scan_window,
285 uint8_t scan_phy) {
286 scanner_intf_->SetScanParameters(
287 scanner_id,
288 scan_type,
289 scan_interval,
290 scan_window,
291 scan_phy,
292 base::Bind(&BleScannerIntf::OnStatusCallback, base::Unretained(this), scanner_id));
293 }
294
BatchscanConfigStorage(uint8_t scanner_id,int32_t batch_scan_full_max,int32_t batch_scan_trunc_max,int32_t batch_scan_notify_threshold)295 void BleScannerIntf::BatchscanConfigStorage(
296 uint8_t scanner_id,
297 int32_t batch_scan_full_max,
298 int32_t batch_scan_trunc_max,
299 int32_t batch_scan_notify_threshold) {
300 scanner_intf_->BatchscanConfigStorage(
301 scanner_id,
302 batch_scan_full_max,
303 batch_scan_trunc_max,
304 batch_scan_notify_threshold,
305 base::Bind(&BleScannerIntf::OnStatusCallback, base::Unretained(this), scanner_id));
306 }
307
BatchscanEnable(int32_t scan_mode,uint16_t scan_interval,uint16_t scan_window,int32_t addr_type,int32_t discard_rule)308 void BleScannerIntf::BatchscanEnable(
309 int32_t scan_mode, uint16_t scan_interval, uint16_t scan_window, int32_t addr_type, int32_t discard_rule) {
310 scanner_intf_->BatchscanEnable(
311 scan_mode,
312 scan_interval,
313 scan_window,
314 addr_type,
315 discard_rule,
316 base::Bind(&BleScannerIntf::OnStatusCallback, base::Unretained(this), 0));
317 }
318
BatchscanDisable()319 void BleScannerIntf::BatchscanDisable() {
320 scanner_intf_->BatchscanDisable(base::Bind(&BleScannerIntf::OnStatusCallback, base::Unretained(this), 0));
321 }
322
BatchscanReadReports(uint8_t scanner_id,int32_t scan_mode)323 void BleScannerIntf::BatchscanReadReports(uint8_t scanner_id, int32_t scan_mode) {
324 scanner_intf_->BatchscanReadReports(scanner_id, scan_mode);
325 }
326
StartSync(uint8_t sid,RawAddress addr,uint16_t skip,uint16_t timeout)327 void BleScannerIntf::StartSync(uint8_t sid, RawAddress addr, uint16_t skip, uint16_t timeout) {
328 scanner_intf_->StartSync(sid, addr, skip, timeout, 0 /* place holder */);
329 }
330
StopSync(uint16_t handle)331 void BleScannerIntf::StopSync(uint16_t handle) {
332 scanner_intf_->StopSync(handle);
333 }
334
CancelCreateSync(uint8_t sid,RawAddress addr)335 void BleScannerIntf::CancelCreateSync(uint8_t sid, RawAddress addr) {
336 scanner_intf_->CancelCreateSync(sid, addr);
337 }
338
TransferSync(RawAddress addr,uint16_t service_data,uint16_t sync_handle)339 void BleScannerIntf::TransferSync(RawAddress addr, uint16_t service_data, uint16_t sync_handle) {
340 scanner_intf_->TransferSync(addr, service_data, sync_handle, 0 /* place holder */);
341 }
342
TransferSetInfo(RawAddress addr,uint16_t service_data,uint8_t adv_handle)343 void BleScannerIntf::TransferSetInfo(RawAddress addr, uint16_t service_data, uint8_t adv_handle) {
344 scanner_intf_->TransferSetInfo(addr, service_data, adv_handle, 0 /* place holder */);
345 }
346
SyncTxParameters(RawAddress addr,uint8_t mode,uint16_t skip,uint16_t timeout)347 void BleScannerIntf::SyncTxParameters(RawAddress addr, uint8_t mode, uint16_t skip, uint16_t timeout) {
348 scanner_intf_->SyncTxParameters(addr, mode, skip, timeout, 0 /* place holder */);
349 }
350
OnRegisterCallback(Uuid uuid,uint8_t scanner_id,uint8_t btm_status)351 void BleScannerIntf::OnRegisterCallback(Uuid uuid, uint8_t scanner_id, uint8_t btm_status) {
352 rusty::gdscan_register_callback(uuid, scanner_id, btm_status);
353 }
354
OnStatusCallback(uint8_t scanner_id,uint8_t btm_status)355 void BleScannerIntf::OnStatusCallback(uint8_t scanner_id, uint8_t btm_status) {
356 rusty::gdscan_status_callback(scanner_id, btm_status);
357 }
358
OnEnableCallback(uint8_t action,uint8_t btm_status)359 void BleScannerIntf::OnEnableCallback(uint8_t action, uint8_t btm_status) {
360 rusty::gdscan_enable_callback(action, btm_status);
361 }
362
OnFilterParamSetupCallback(uint8_t scanner_id,uint8_t avbl_space,uint8_t action_type,uint8_t btm_status)363 void BleScannerIntf::OnFilterParamSetupCallback(
364 uint8_t scanner_id, uint8_t avbl_space, uint8_t action_type, uint8_t btm_status) {
365 rusty::gdscan_filter_param_setup_callback(scanner_id, avbl_space, action_type, btm_status);
366 }
367
OnFilterConfigCallback(uint8_t filter_index,uint8_t filt_type,uint8_t avbl_space,uint8_t action,uint8_t btm_status)368 void BleScannerIntf::OnFilterConfigCallback(
369 uint8_t filter_index, uint8_t filt_type, uint8_t avbl_space, uint8_t action, uint8_t btm_status) {
370 rusty::gdscan_filter_config_callback(filter_index, filt_type, avbl_space, action, btm_status);
371 }
372
373 #if TARGET_FLOSS
OnMsftAdvMonitorAddCallback(uint32_t call_id,uint8_t monitor_handle,uint8_t status)374 void BleScannerIntf::OnMsftAdvMonitorAddCallback(uint32_t call_id, uint8_t monitor_handle, uint8_t status) {
375 rusty::gdscan_msft_adv_monitor_add_callback(call_id, monitor_handle, status);
376 }
377
OnMsftAdvMonitorRemoveCallback(uint32_t call_id,uint8_t status)378 void BleScannerIntf::OnMsftAdvMonitorRemoveCallback(uint32_t call_id, uint8_t status) {
379 rusty::gdscan_msft_adv_monitor_remove_callback(call_id, status);
380 }
381
OnMsftAdvMonitorEnableCallback(uint32_t call_id,uint8_t status)382 void BleScannerIntf::OnMsftAdvMonitorEnableCallback(uint32_t call_id, uint8_t status) {
383 rusty::gdscan_msft_adv_monitor_enable_callback(call_id, status);
384 }
385 #endif
386
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)387 void BleScannerIntf::OnPeriodicSyncStarted(
388 int,
389 uint8_t status,
390 uint16_t sync_handle,
391 uint8_t advertising_sid,
392 uint8_t address_type,
393 RawAddress addr,
394 uint8_t phy,
395 uint16_t interval) {
396 rusty::gdscan_start_sync_callback(status, sync_handle, advertising_sid, address_type, &addr, phy, interval);
397 }
398
OnPeriodicSyncReport(uint16_t sync_handle,int8_t tx_power,int8_t rssi,uint8_t status,std::vector<uint8_t> data)399 void BleScannerIntf::OnPeriodicSyncReport(
400 uint16_t sync_handle, int8_t tx_power, int8_t rssi, uint8_t status, std::vector<uint8_t> data) {
401 rusty::gdscan_sync_report_callback(sync_handle, tx_power, rssi, status, data.data(), data.size());
402 }
403
OnPeriodicSyncLost(uint16_t sync_handle)404 void BleScannerIntf::OnPeriodicSyncLost(uint16_t sync_handle) {
405 rusty::gdscan_sync_lost_callback(sync_handle);
406 }
407
OnPeriodicSyncTransferred(int,uint8_t status,RawAddress addr)408 void BleScannerIntf::OnPeriodicSyncTransferred(int, uint8_t status, RawAddress addr) {
409 rusty::gdscan_sync_transfer_callback(status, &addr);
410 }
411
OnBigInfoReport(uint16_t sync_handle,bool encrypted)412 void BleScannerIntf::OnBigInfoReport(uint16_t sync_handle, bool encrypted) {
413 rusty::gdscan_biginfo_report_callback(sync_handle, encrypted);
414 }
415
RegisterCallbacks()416 void BleScannerIntf::RegisterCallbacks() {
417 // Register self as a callback handler. We will dispatch to Rust callbacks.
418 scanner_intf_->RegisterCallbacks(this);
419 }
420
421 // ScanningCallbacks overrides
GetBleScannerIntf(const unsigned char * gatt_intf)422 std::unique_ptr<BleScannerIntf> GetBleScannerIntf(const unsigned char* gatt_intf) {
423 return std::make_unique<BleScannerIntf>(reinterpret_cast<const btgatt_interface_t*>(gatt_intf)->scanner);
424 }
425
426 } // namespace rust
427 } // namespace topshim
428 } // namespace bluetooth
429