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