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 "gd/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 "bind_helpers.h"
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 = bluetooth::Uuid::From128BitBE(command.uuid.uu),
56 .uuid_mask = bluetooth::Uuid::From128BitBE(command.uuid_mask.uu),
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(const ::rust::Vec<RustMsftAdvMonitorPattern>& patterns) {
103 std::vector<MsftAdvMonitorPattern> converted;
104
105 for (const auto& pattern : patterns) {
106 converted.push_back(ConvertAdvMonitorPattern(pattern));
107 }
108
109 return converted;
110 }
111
ConvertAdvMonitor(const RustMsftAdvMonitor & monitor)112 MsftAdvMonitor ConvertAdvMonitor(const RustMsftAdvMonitor& monitor) {
113 MsftAdvMonitor converted = {
114 .rssi_threshold_high = monitor.rssi_high_threshold,
115 .rssi_threshold_low = monitor.rssi_low_threshold,
116 .rssi_threshold_low_time_interval = monitor.rssi_low_timeout,
117 .rssi_sampling_period = monitor.rssi_sampling_period,
118 .patterns = ConvertAdvMonitorPatterns(monitor.patterns),
119 };
120 return converted;
121 }
122
ConvertRustFilterParam(const RustGattFilterParam & param)123 ::btgatt_filt_param_setup_t ConvertRustFilterParam(const RustGattFilterParam& param) {
124 ::btgatt_filt_param_setup_t converted = {
125 .feat_seln = param.feat_seln,
126 .list_logic_type = param.list_logic_type,
127 .filt_logic_type = param.filt_logic_type,
128 .rssi_high_thres = param.rssi_high_thres,
129 .rssi_low_thres = param.rssi_low_thres,
130 .dely_mode = param.delay_mode,
131 .found_timeout = param.found_timeout,
132 .lost_timeout = param.lost_timeout,
133 .found_timeout_cnt = param.found_timeout_count,
134 .num_of_tracking_entries = param.num_of_tracking_entries,
135 };
136
137 return converted;
138 }
139 } // namespace internal
140
141 // ScanningCallbacks implementations
142
OnScannerRegistered(const bluetooth::Uuid app_uuid,uint8_t scannerId,uint8_t status)143 void BleScannerIntf::OnScannerRegistered(const bluetooth::Uuid app_uuid, uint8_t scannerId, uint8_t status) {
144 rusty::gdscan_on_scanner_registered(reinterpret_cast<const signed char*>(&app_uuid), scannerId, status);
145 }
146
OnSetScannerParameterComplete(uint8_t scannerId,uint8_t status)147 void BleScannerIntf::OnSetScannerParameterComplete(uint8_t scannerId, uint8_t status) {
148 rusty::gdscan_on_set_scanner_parameter_complete(scannerId, status);
149 }
150
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)151 void BleScannerIntf::OnScanResult(
152 uint16_t event_type,
153 uint8_t addr_type,
154 RawAddress addr,
155 uint8_t primary_phy,
156 uint8_t secondary_phy,
157 uint8_t advertising_sid,
158 int8_t tx_power,
159 int8_t rssi,
160 uint16_t periodic_adv_int,
161 std::vector<uint8_t> adv_data) {
162 rusty::gdscan_on_scan_result(
163 event_type,
164 addr_type,
165 &addr,
166 primary_phy,
167 secondary_phy,
168 advertising_sid,
169 tx_power,
170 rssi,
171 periodic_adv_int,
172 adv_data.data(),
173 adv_data.size());
174 }
175
OnTrackAdvFoundLost(AdvertisingTrackInfo ati)176 void BleScannerIntf::OnTrackAdvFoundLost(AdvertisingTrackInfo ati) {
177 rusty::RustAdvertisingTrackInfo rust_info = {
178 .monitor_handle = ati.monitor_handle,
179 .scanner_id = ati.scanner_id,
180 .filter_index = ati.filter_index,
181 .advertiser_state = ati.advertiser_state,
182 .advertiser_info_present = ati.advertiser_info_present,
183 .advertiser_address = ati.advertiser_address,
184 .advertiser_address_type = ati.advertiser_address_type,
185 .tx_power = ati.tx_power,
186 .rssi = ati.rssi,
187 .timestamp = ati.time_stamp,
188 .adv_packet_len = ati.adv_packet_len,
189 // .adv_packet is copied below
190 .scan_response_len = ati.scan_response_len,
191 // .scan_response is copied below
192 };
193
194 std::copy(rust_info.adv_packet.begin(), rust_info.adv_packet.end(), std::back_inserter(ati.adv_packet));
195 std::copy(rust_info.scan_response.begin(), rust_info.scan_response.end(), std::back_inserter(ati.scan_response));
196
197 rusty::gdscan_on_track_adv_found_lost(rust_info);
198 }
199
OnBatchScanReports(int client_if,int status,int report_format,int num_records,std::vector<uint8_t> data)200 void BleScannerIntf::OnBatchScanReports(
201 int client_if, int status, int report_format, int num_records, std::vector<uint8_t> data) {
202 rusty::gdscan_on_batch_scan_reports(client_if, status, report_format, num_records, data.data(), data.size());
203 }
204
OnBatchScanThresholdCrossed(int client_if)205 void BleScannerIntf::OnBatchScanThresholdCrossed(int client_if) {
206 rusty::gdscan_on_batch_scan_threshold_crossed(client_if);
207 }
208
209 // BleScannerInterface implementations
210
RegisterScanner(RustUuid uuid)211 void BleScannerIntf::RegisterScanner(RustUuid uuid) {
212 bluetooth::Uuid converted = bluetooth::Uuid::From128BitBE(uuid.uu);
213 scanner_intf_->RegisterScanner(
214 converted, base::Bind(&BleScannerIntf::OnRegisterCallback, base::Unretained(this), uuid));
215 }
216
Unregister(uint8_t scanner_id)217 void BleScannerIntf::Unregister(uint8_t scanner_id) {
218 scanner_intf_->Unregister(scanner_id);
219 }
220
Scan(bool start)221 void BleScannerIntf::Scan(bool start) {
222 scanner_intf_->Scan(start);
223 }
224
ScanFilterParamSetup(uint8_t scanner_id,uint8_t action,uint8_t filter_index,RustGattFilterParam filter_param)225 void BleScannerIntf::ScanFilterParamSetup(
226 uint8_t scanner_id, uint8_t action, uint8_t filter_index, RustGattFilterParam filter_param) {
227 std::unique_ptr<::btgatt_filt_param_setup_t> converted =
228 std::make_unique<::btgatt_filt_param_setup_t>(std::move(internal::ConvertRustFilterParam(filter_param)));
229
230 scanner_intf_->ScanFilterParamSetup(
231 scanner_id,
232 action,
233 filter_index,
234 std::move(converted),
235 base::Bind(&BleScannerIntf::OnFilterParamSetupCallback, base::Unretained(this), scanner_id));
236 }
237
ScanFilterAdd(uint8_t filter_index,::rust::Vec<RustApcfCommand> filters)238 void BleScannerIntf::ScanFilterAdd(uint8_t filter_index, ::rust::Vec<RustApcfCommand> filters) {
239 auto converted = internal::ConvertApcfVec(filters);
240 scanner_intf_->ScanFilterAdd(
241 filter_index,
242 converted,
243 base::Bind(&BleScannerIntf::OnFilterConfigCallback, base::Unretained(this), filter_index));
244 }
245
ScanFilterClear(uint8_t filter_index)246 void BleScannerIntf::ScanFilterClear(uint8_t filter_index) {
247 scanner_intf_->ScanFilterClear(
248 filter_index, base::Bind(&BleScannerIntf::OnFilterConfigCallback, base::Unretained(this), filter_index));
249 }
250
ScanFilterEnable(bool enable)251 void BleScannerIntf::ScanFilterEnable(bool enable) {
252 scanner_intf_->ScanFilterEnable(enable, base::Bind(&BleScannerIntf::OnEnableCallback, base::Unretained(this)));
253 }
254
IsMsftSupported()255 bool BleScannerIntf::IsMsftSupported() {
256 return scanner_intf_->IsMsftSupported();
257 }
258
MsftAdvMonitorAdd(uint32_t call_id,const RustMsftAdvMonitor & monitor)259 void BleScannerIntf::MsftAdvMonitorAdd(uint32_t call_id, const RustMsftAdvMonitor& monitor) {
260 scanner_intf_->MsftAdvMonitorAdd(
261 internal::ConvertAdvMonitor(monitor),
262 base::Bind(&BleScannerIntf::OnMsftAdvMonitorAddCallback, base::Unretained(this), call_id));
263 }
264
MsftAdvMonitorRemove(uint32_t call_id,uint8_t monitor_handle)265 void BleScannerIntf::MsftAdvMonitorRemove(uint32_t call_id, uint8_t monitor_handle) {
266 scanner_intf_->MsftAdvMonitorRemove(
267 monitor_handle, base::Bind(&BleScannerIntf::OnMsftAdvMonitorRemoveCallback, base::Unretained(this), call_id));
268 }
269
MsftAdvMonitorEnable(uint32_t call_id,bool enable)270 void BleScannerIntf::MsftAdvMonitorEnable(uint32_t call_id, bool enable) {
271 scanner_intf_->MsftAdvMonitorEnable(
272 enable, base::Bind(&BleScannerIntf::OnMsftAdvMonitorEnableCallback, base::Unretained(this), call_id));
273 }
274
SetScanParameters(uint8_t scanner_id,uint16_t scan_interval,uint16_t scan_window)275 void BleScannerIntf::SetScanParameters(uint8_t scanner_id, uint16_t scan_interval, uint16_t scan_window) {
276 scanner_intf_->SetScanParameters(
277 scanner_id,
278 scan_interval,
279 scan_window,
280 base::Bind(&BleScannerIntf::OnStatusCallback, base::Unretained(this), scanner_id));
281 }
282
BatchscanConfigStorage(uint8_t scanner_id,int32_t batch_scan_full_max,int32_t batch_scan_trunc_max,int32_t batch_scan_notify_threshold)283 void BleScannerIntf::BatchscanConfigStorage(
284 uint8_t scanner_id,
285 int32_t batch_scan_full_max,
286 int32_t batch_scan_trunc_max,
287 int32_t batch_scan_notify_threshold) {
288 scanner_intf_->BatchscanConfigStorage(
289 scanner_id,
290 batch_scan_full_max,
291 batch_scan_trunc_max,
292 batch_scan_notify_threshold,
293 base::Bind(&BleScannerIntf::OnStatusCallback, base::Unretained(this), scanner_id));
294 }
295
BatchscanEnable(int32_t scan_mode,uint16_t scan_interval,uint16_t scan_window,int32_t addr_type,int32_t discard_rule)296 void BleScannerIntf::BatchscanEnable(
297 int32_t scan_mode, uint16_t scan_interval, uint16_t scan_window, int32_t addr_type, int32_t discard_rule) {
298 scanner_intf_->BatchscanEnable(
299 scan_mode,
300 scan_interval,
301 scan_window,
302 addr_type,
303 discard_rule,
304 base::Bind(&BleScannerIntf::OnStatusCallback, base::Unretained(this), 0));
305 }
306
BatchscanDisable()307 void BleScannerIntf::BatchscanDisable() {
308 scanner_intf_->BatchscanDisable(base::Bind(&BleScannerIntf::OnStatusCallback, base::Unretained(this), 0));
309 }
310
BatchscanReadReports(uint8_t scanner_id,int32_t scan_mode)311 void BleScannerIntf::BatchscanReadReports(uint8_t scanner_id, int32_t scan_mode) {
312 scanner_intf_->BatchscanReadReports(scanner_id, scan_mode);
313 }
314
StartSync(uint8_t sid,RawAddress addr,uint16_t skip,uint16_t timeout)315 void BleScannerIntf::StartSync(uint8_t sid, RawAddress addr, uint16_t skip, uint16_t timeout) {
316 scanner_intf_->StartSync(sid, addr, skip, timeout, 0 /* place holder */);
317 }
318
StopSync(uint16_t handle)319 void BleScannerIntf::StopSync(uint16_t handle) {
320 scanner_intf_->StopSync(handle);
321 }
322
CancelCreateSync(uint8_t sid,RawAddress addr)323 void BleScannerIntf::CancelCreateSync(uint8_t sid, RawAddress addr) {
324 scanner_intf_->CancelCreateSync(sid, addr);
325 }
326
TransferSync(RawAddress addr,uint16_t service_data,uint16_t sync_handle)327 void BleScannerIntf::TransferSync(RawAddress addr, uint16_t service_data, uint16_t sync_handle) {
328 scanner_intf_->TransferSync(addr, service_data, sync_handle, 0 /* place holder */);
329 }
330
TransferSetInfo(RawAddress addr,uint16_t service_data,uint8_t adv_handle)331 void BleScannerIntf::TransferSetInfo(RawAddress addr, uint16_t service_data, uint8_t adv_handle) {
332 scanner_intf_->TransferSetInfo(addr, service_data, adv_handle, 0 /* place holder */);
333 }
334
SyncTxParameters(RawAddress addr,uint8_t mode,uint16_t skip,uint16_t timeout)335 void BleScannerIntf::SyncTxParameters(RawAddress addr, uint8_t mode, uint16_t skip, uint16_t timeout) {
336 scanner_intf_->SyncTxParameters(addr, mode, skip, timeout, 0 /* place holder */);
337 }
338
OnRegisterCallback(RustUuid uuid,uint8_t scanner_id,uint8_t btm_status)339 void BleScannerIntf::OnRegisterCallback(RustUuid uuid, uint8_t scanner_id, uint8_t btm_status) {
340 rusty::gdscan_register_callback(uuid, scanner_id, btm_status);
341 }
342
OnStatusCallback(uint8_t scanner_id,uint8_t btm_status)343 void BleScannerIntf::OnStatusCallback(uint8_t scanner_id, uint8_t btm_status) {
344 rusty::gdscan_status_callback(scanner_id, btm_status);
345 }
346
OnEnableCallback(uint8_t action,uint8_t btm_status)347 void BleScannerIntf::OnEnableCallback(uint8_t action, uint8_t btm_status) {
348 rusty::gdscan_enable_callback(action, btm_status);
349 }
350
OnFilterParamSetupCallback(uint8_t scanner_id,uint8_t avbl_space,uint8_t action_type,uint8_t btm_status)351 void BleScannerIntf::OnFilterParamSetupCallback(
352 uint8_t scanner_id, uint8_t avbl_space, uint8_t action_type, uint8_t btm_status) {
353 rusty::gdscan_filter_param_setup_callback(scanner_id, avbl_space, action_type, btm_status);
354 }
355
OnFilterConfigCallback(uint8_t filter_index,uint8_t filt_type,uint8_t avbl_space,uint8_t action,uint8_t btm_status)356 void BleScannerIntf::OnFilterConfigCallback(
357 uint8_t filter_index, uint8_t filt_type, uint8_t avbl_space, uint8_t action, uint8_t btm_status) {
358 rusty::gdscan_filter_config_callback(filter_index, filt_type, avbl_space, action, btm_status);
359 }
360
OnMsftAdvMonitorAddCallback(uint32_t call_id,uint8_t monitor_handle,uint8_t status)361 void BleScannerIntf::OnMsftAdvMonitorAddCallback(uint32_t call_id, uint8_t monitor_handle, uint8_t status) {
362 rusty::gdscan_msft_adv_monitor_add_callback(call_id, monitor_handle, status);
363 }
364
OnMsftAdvMonitorRemoveCallback(uint32_t call_id,uint8_t status)365 void BleScannerIntf::OnMsftAdvMonitorRemoveCallback(uint32_t call_id, uint8_t status) {
366 rusty::gdscan_msft_adv_monitor_remove_callback(call_id, status);
367 }
368
OnMsftAdvMonitorEnableCallback(uint32_t call_id,uint8_t status)369 void BleScannerIntf::OnMsftAdvMonitorEnableCallback(uint32_t call_id, uint8_t status) {
370 rusty::gdscan_msft_adv_monitor_enable_callback(call_id, status);
371 }
372
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)373 void BleScannerIntf::OnPeriodicSyncStarted(
374 int,
375 uint8_t status,
376 uint16_t sync_handle,
377 uint8_t advertising_sid,
378 uint8_t address_type,
379 RawAddress addr,
380 uint8_t phy,
381 uint16_t interval) {
382 rusty::gdscan_start_sync_callback(status, sync_handle, advertising_sid, address_type, &addr, phy, interval);
383 }
384
OnPeriodicSyncReport(uint16_t sync_handle,int8_t tx_power,int8_t rssi,uint8_t status,std::vector<uint8_t> data)385 void BleScannerIntf::OnPeriodicSyncReport(
386 uint16_t sync_handle, int8_t tx_power, int8_t rssi, uint8_t status, std::vector<uint8_t> data) {
387 rusty::gdscan_sync_report_callback(sync_handle, tx_power, rssi, status, data.data(), data.size());
388 }
389
OnPeriodicSyncLost(uint16_t sync_handle)390 void BleScannerIntf::OnPeriodicSyncLost(uint16_t sync_handle) {
391 rusty::gdscan_sync_lost_callback(sync_handle);
392 }
393
OnPeriodicSyncTransferred(int,uint8_t status,RawAddress addr)394 void BleScannerIntf::OnPeriodicSyncTransferred(int, uint8_t status, RawAddress addr) {
395 rusty::gdscan_sync_transfer_callback(status, &addr);
396 }
397
OnBigInfoReport(uint16_t sync_handle,bool encrypted)398 void BleScannerIntf::OnBigInfoReport(uint16_t sync_handle, bool encrypted) {
399 rusty::gdscan_biginfo_report_callback(sync_handle, encrypted);
400 }
401
RegisterCallbacks()402 void BleScannerIntf::RegisterCallbacks() {
403 // Register self as a callback handler. We will dispatch to Rust callbacks.
404 scanner_intf_->RegisterCallbacks(this);
405 }
406
407 // ScanningCallbacks overrides
GetBleScannerIntf(const unsigned char * gatt_intf)408 std::unique_ptr<BleScannerIntf> GetBleScannerIntf(const unsigned char* gatt_intf) {
409 return std::make_unique<BleScannerIntf>(reinterpret_cast<const btgatt_interface_t*>(gatt_intf)->scanner);
410 }
411
412 } // namespace rust
413 } // namespace topshim
414 } // namespace bluetooth
415