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