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/bind.h>
20 #include <base/callback.h>
21
22 #include <algorithm>
23 #include <iterator>
24 #include <memory>
25 #include <vector>
26
27 #include "bind_helpers.h"
28 #include "gd/rust/topshim/common/utils.h"
29 #include "include/hardware/bt_common_types.h"
30 #include "rust/cxx.h"
31 #include "src/profiles/gatt.rs.h"
32 #include "types/bluetooth/uuid.h"
33 #include "types/raw_address.h"
34
35 namespace bluetooth {
36 namespace topshim {
37 namespace rust {
38
39 namespace rusty = ::bluetooth::topshim::rust;
40
41 namespace internal {
ConvertApcfFromRust(const RustApcfCommand & command)42 ApcfCommand ConvertApcfFromRust(const RustApcfCommand& command) {
43 RawAddress address = rusty::CopyFromRustAddress(command.address);
44
45 // Copy vectors + arrays
46 std::vector<uint8_t> name, data, data_mask;
47 std::array<uint8_t, 16> irk;
48 std::copy(command.name.begin(), command.name.end(), std::back_inserter(name));
49 std::copy(command.data.begin(), command.data.end(), std::back_inserter(data));
50 std::copy(command.data_mask.begin(), command.data_mask.end(), std::back_inserter(data_mask));
51 std::copy(command.irk.begin(), command.irk.end(), std::begin(irk));
52
53 ApcfCommand converted = {
54 .type = command.type_,
55 .address = address,
56 .addr_type = command.addr_type,
57 .uuid = bluetooth::Uuid::From128BitBE(command.uuid.uu),
58 .uuid_mask = bluetooth::Uuid::From128BitBE(command.uuid_mask.uu),
59 .name = name,
60 .company = command.company,
61 .company_mask = command.company_mask,
62 .ad_type = command.ad_type,
63 .data = data,
64 .data_mask = data_mask,
65 .irk = irk,
66 };
67
68 return converted;
69 }
70
ConvertApcfVec(const::rust::Vec<RustApcfCommand> & rustvec)71 std::vector<ApcfCommand> ConvertApcfVec(const ::rust::Vec<RustApcfCommand>& rustvec) {
72 std::vector<ApcfCommand> converted;
73
74 for (const RustApcfCommand& command : rustvec) {
75 converted.push_back(ConvertApcfFromRust(command));
76 }
77
78 return converted;
79 }
80
ConvertRustFilterParam(const RustGattFilterParam & param)81 ::btgatt_filt_param_setup_t ConvertRustFilterParam(const RustGattFilterParam& param) {
82 ::btgatt_filt_param_setup_t converted = {
83 .feat_seln = param.feat_seln,
84 .list_logic_type = param.list_logic_type,
85 .filt_logic_type = param.filt_logic_type,
86 .rssi_high_thres = param.rssi_high_thres,
87 .rssi_low_thres = param.rssi_low_thres,
88 .dely_mode = param.delay_mode,
89 .found_timeout = param.found_timeout,
90 .lost_timeout = param.lost_timeout,
91 .found_timeout_cnt = param.found_timeout_count,
92 .num_of_tracking_entries = param.num_of_tracking_entries,
93 };
94
95 return converted;
96 }
97 } // namespace internal
98
99 // ScanningCallbacks implementations
100
OnScannerRegistered(const bluetooth::Uuid app_uuid,uint8_t scannerId,uint8_t status)101 void BleScannerIntf::OnScannerRegistered(const bluetooth::Uuid app_uuid, uint8_t scannerId, uint8_t status) {
102 rusty::gdscan_on_scanner_registered(reinterpret_cast<const signed char*>(&app_uuid), scannerId, status);
103 }
104
OnSetScannerParameterComplete(uint8_t scannerId,uint8_t status)105 void BleScannerIntf::OnSetScannerParameterComplete(uint8_t scannerId, uint8_t status) {
106 rusty::gdscan_on_set_scanner_parameter_complete(scannerId, status);
107 }
108
OnScanResult(uint16_t event_type,uint8_t addr_type,RawAddress bda,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)109 void BleScannerIntf::OnScanResult(
110 uint16_t event_type,
111 uint8_t addr_type,
112 RawAddress bda,
113 uint8_t primary_phy,
114 uint8_t secondary_phy,
115 uint8_t advertising_sid,
116 int8_t tx_power,
117 int8_t rssi,
118 uint16_t periodic_adv_int,
119 std::vector<uint8_t> adv_data) {
120 RustRawAddress raw_address = rusty::CopyToRustAddress(bda);
121 rusty::gdscan_on_scan_result(
122 event_type,
123 addr_type,
124 reinterpret_cast<const signed char*>(&raw_address),
125 primary_phy,
126 secondary_phy,
127 advertising_sid,
128 tx_power,
129 rssi,
130 periodic_adv_int,
131 adv_data.data(),
132 adv_data.size());
133 }
134
OnTrackAdvFoundLost(AdvertisingTrackInfo ati)135 void BleScannerIntf::OnTrackAdvFoundLost(AdvertisingTrackInfo ati) {
136 rusty::RustRawAddress addr = rusty::CopyToRustAddress(ati.advertiser_address);
137 rusty::RustAdvertisingTrackInfo rust_info = {
138 .scanner_id = ati.scanner_id,
139 .filter_index = ati.filter_index,
140 .advertiser_state = ati.advertiser_state,
141 .advertiser_info_present = ati.advertiser_info_present,
142 .advertiser_address = addr,
143 .advertiser_address_type = ati.advertiser_address_type,
144 .tx_power = ati.tx_power,
145 .rssi = ati.rssi,
146 .timestamp = ati.time_stamp,
147 .adv_packet_len = ati.adv_packet_len,
148 // .adv_packet is copied below
149 .scan_response_len = ati.scan_response_len,
150 // .scan_response is copied below
151 };
152
153 std::copy(rust_info.adv_packet.begin(), rust_info.adv_packet.end(), std::back_inserter(ati.adv_packet));
154 std::copy(rust_info.scan_response.begin(), rust_info.scan_response.end(), std::back_inserter(ati.scan_response));
155
156 rusty::gdscan_on_track_adv_found_lost(rust_info);
157 }
158
OnBatchScanReports(int client_if,int status,int report_format,int num_records,std::vector<uint8_t> data)159 void BleScannerIntf::OnBatchScanReports(
160 int client_if, int status, int report_format, int num_records, std::vector<uint8_t> data) {
161 rusty::gdscan_on_batch_scan_reports(client_if, status, report_format, num_records, data.data(), data.size());
162 }
163
OnBatchScanThresholdCrossed(int client_if)164 void BleScannerIntf::OnBatchScanThresholdCrossed(int client_if) {
165 rusty::gdscan_on_batch_scan_threshold_crossed(client_if);
166 }
167
168 // BleScannerInterface implementations
169
RegisterScanner(RustUuid uuid)170 void BleScannerIntf::RegisterScanner(RustUuid uuid) {
171 bluetooth::Uuid converted = bluetooth::Uuid::From128BitBE(uuid.uu);
172 scanner_intf_->RegisterScanner(
173 converted, base::Bind(&BleScannerIntf::OnRegisterCallback, base::Unretained(this), uuid));
174 }
175
Unregister(uint8_t scanner_id)176 void BleScannerIntf::Unregister(uint8_t scanner_id) {
177 scanner_intf_->Unregister(scanner_id);
178 }
179
Scan(bool start)180 void BleScannerIntf::Scan(bool start) {
181 scanner_intf_->Scan(start);
182 }
183
ScanFilterParamSetup(uint8_t scanner_id,uint8_t action,uint8_t filter_index,RustGattFilterParam filter_param)184 void BleScannerIntf::ScanFilterParamSetup(
185 uint8_t scanner_id, uint8_t action, uint8_t filter_index, RustGattFilterParam filter_param) {
186 std::unique_ptr<::btgatt_filt_param_setup_t> converted =
187 std::make_unique<::btgatt_filt_param_setup_t>(std::move(internal::ConvertRustFilterParam(filter_param)));
188
189 scanner_intf_->ScanFilterParamSetup(
190 scanner_id,
191 action,
192 filter_index,
193 std::move(converted),
194 base::Bind(&BleScannerIntf::OnFilterParamSetupCallback, base::Unretained(this), scanner_id));
195 }
196
ScanFilterAdd(uint8_t filter_index,::rust::Vec<RustApcfCommand> filters)197 void BleScannerIntf::ScanFilterAdd(uint8_t filter_index, ::rust::Vec<RustApcfCommand> filters) {
198 auto converted = internal::ConvertApcfVec(filters);
199 scanner_intf_->ScanFilterAdd(
200 filter_index,
201 converted,
202 base::Bind(&BleScannerIntf::OnFilterConfigCallback, base::Unretained(this), filter_index));
203 }
204
ScanFilterClear(uint8_t filter_index)205 void BleScannerIntf::ScanFilterClear(uint8_t filter_index) {
206 scanner_intf_->ScanFilterClear(
207 filter_index, base::Bind(&BleScannerIntf::OnFilterConfigCallback, base::Unretained(this), filter_index));
208 }
209
ScanFilterEnable(bool enable)210 void BleScannerIntf::ScanFilterEnable(bool enable) {
211 scanner_intf_->ScanFilterEnable(enable, base::Bind(&BleScannerIntf::OnEnableCallback, base::Unretained(this)));
212 }
213
SetScanParameters(uint8_t scanner_id,uint16_t scan_interval,uint16_t scan_window)214 void BleScannerIntf::SetScanParameters(uint8_t scanner_id, uint16_t scan_interval, uint16_t scan_window) {
215 scanner_intf_->SetScanParameters(
216 scanner_id,
217 scan_interval,
218 scan_window,
219 base::Bind(&BleScannerIntf::OnStatusCallback, base::Unretained(this), scanner_id));
220 }
221
BatchscanConfigStorage(uint8_t scanner_id,int32_t batch_scan_full_max,int32_t batch_scan_trunc_max,int32_t batch_scan_notify_threshold)222 void BleScannerIntf::BatchscanConfigStorage(
223 uint8_t scanner_id,
224 int32_t batch_scan_full_max,
225 int32_t batch_scan_trunc_max,
226 int32_t batch_scan_notify_threshold) {
227 scanner_intf_->BatchscanConfigStorage(
228 scanner_id,
229 batch_scan_full_max,
230 batch_scan_trunc_max,
231 batch_scan_notify_threshold,
232 base::Bind(&BleScannerIntf::OnStatusCallback, base::Unretained(this), scanner_id));
233 }
234
BatchscanEnable(int32_t scan_mode,uint16_t scan_interval,uint16_t scan_window,int32_t addr_type,int32_t discard_rule)235 void BleScannerIntf::BatchscanEnable(
236 int32_t scan_mode, uint16_t scan_interval, uint16_t scan_window, int32_t addr_type, int32_t discard_rule) {
237 scanner_intf_->BatchscanEnable(
238 scan_mode,
239 scan_interval,
240 scan_window,
241 addr_type,
242 discard_rule,
243 base::Bind(&BleScannerIntf::OnStatusCallback, base::Unretained(this), 0));
244 }
245
BatchscanDisable()246 void BleScannerIntf::BatchscanDisable() {
247 scanner_intf_->BatchscanDisable(base::Bind(&BleScannerIntf::OnStatusCallback, base::Unretained(this), 0));
248 }
249
BatchscanReadReports(uint8_t scanner_id,int32_t scan_mode)250 void BleScannerIntf::BatchscanReadReports(uint8_t scanner_id, int32_t scan_mode) {
251 scanner_intf_->BatchscanReadReports(scanner_id, scan_mode);
252 }
253
StartSync(uint8_t sid,RustRawAddress address,uint16_t skip,uint16_t timeout)254 void BleScannerIntf::StartSync(uint8_t sid, RustRawAddress address, uint16_t skip, uint16_t timeout) {
255 RawAddress converted = rusty::CopyFromRustAddress(address);
256 scanner_intf_->StartSync(sid, converted, skip, timeout, 0 /* place holder */);
257 }
258
StopSync(uint16_t handle)259 void BleScannerIntf::StopSync(uint16_t handle) {
260 scanner_intf_->StopSync(handle);
261 }
262
CancelCreateSync(uint8_t sid,RustRawAddress address)263 void BleScannerIntf::CancelCreateSync(uint8_t sid, RustRawAddress address) {
264 RawAddress converted = rusty::CopyFromRustAddress(address);
265 scanner_intf_->CancelCreateSync(sid, converted);
266 }
267
TransferSync(RustRawAddress address,uint16_t service_data,uint16_t sync_handle)268 void BleScannerIntf::TransferSync(RustRawAddress address, uint16_t service_data, uint16_t sync_handle) {
269 RawAddress converted = rusty::CopyFromRustAddress(address);
270 scanner_intf_->TransferSync(converted, service_data, sync_handle, 0 /* place holder */);
271 }
272
TransferSetInfo(RustRawAddress address,uint16_t service_data,uint8_t adv_handle)273 void BleScannerIntf::TransferSetInfo(RustRawAddress address, uint16_t service_data, uint8_t adv_handle) {
274 RawAddress converted = rusty::CopyFromRustAddress(address);
275 scanner_intf_->TransferSetInfo(converted, service_data, adv_handle, 0 /* place holder */);
276 }
277
SyncTxParameters(RustRawAddress address,uint8_t mode,uint16_t skip,uint16_t timeout)278 void BleScannerIntf::SyncTxParameters(RustRawAddress address, uint8_t mode, uint16_t skip, uint16_t timeout) {
279 RawAddress converted = rusty::CopyFromRustAddress(address);
280 scanner_intf_->SyncTxParameters(converted, mode, skip, timeout, 0 /* place holder */);
281 }
282
OnRegisterCallback(RustUuid uuid,uint8_t scanner_id,uint8_t btm_status)283 void BleScannerIntf::OnRegisterCallback(RustUuid uuid, uint8_t scanner_id, uint8_t btm_status) {
284 rusty::gdscan_register_callback(uuid, scanner_id, btm_status);
285 }
286
OnStatusCallback(uint8_t scanner_id,uint8_t btm_status)287 void BleScannerIntf::OnStatusCallback(uint8_t scanner_id, uint8_t btm_status) {
288 rusty::gdscan_status_callback(scanner_id, btm_status);
289 }
290
OnEnableCallback(uint8_t action,uint8_t btm_status)291 void BleScannerIntf::OnEnableCallback(uint8_t action, uint8_t btm_status) {
292 rusty::gdscan_enable_callback(action, btm_status);
293 }
294
OnFilterParamSetupCallback(uint8_t scanner_id,uint8_t avbl_space,uint8_t action_type,uint8_t btm_status)295 void BleScannerIntf::OnFilterParamSetupCallback(
296 uint8_t scanner_id, uint8_t avbl_space, uint8_t action_type, uint8_t btm_status) {
297 rusty::gdscan_filter_param_setup_callback(scanner_id, avbl_space, action_type, btm_status);
298 }
299
OnFilterConfigCallback(uint8_t filter_index,uint8_t filt_type,uint8_t avbl_space,uint8_t action,uint8_t btm_status)300 void BleScannerIntf::OnFilterConfigCallback(
301 uint8_t filter_index, uint8_t filt_type, uint8_t avbl_space, uint8_t action, uint8_t btm_status) {
302 rusty::gdscan_filter_config_callback(filter_index, filt_type, avbl_space, action, btm_status);
303 }
304
OnPeriodicSyncStarted(int,uint8_t status,uint16_t sync_handle,uint8_t advertising_sid,uint8_t address_type,RawAddress address,uint8_t phy,uint16_t interval)305 void BleScannerIntf::OnPeriodicSyncStarted(
306 int,
307 uint8_t status,
308 uint16_t sync_handle,
309 uint8_t advertising_sid,
310 uint8_t address_type,
311 RawAddress address,
312 uint8_t phy,
313 uint16_t interval) {
314 RustRawAddress converted = rusty::CopyToRustAddress(address);
315 rusty::gdscan_start_sync_callback(status, sync_handle, advertising_sid, address_type, &converted, phy, interval);
316 }
317
OnPeriodicSyncReport(uint16_t sync_handle,int8_t tx_power,int8_t rssi,uint8_t status,std::vector<uint8_t> data)318 void BleScannerIntf::OnPeriodicSyncReport(
319 uint16_t sync_handle, int8_t tx_power, int8_t rssi, uint8_t status, std::vector<uint8_t> data) {
320 rusty::gdscan_sync_report_callback(sync_handle, tx_power, rssi, status, data.data(), data.size());
321 }
322
OnPeriodicSyncLost(uint16_t sync_handle)323 void BleScannerIntf::OnPeriodicSyncLost(uint16_t sync_handle) {
324 rusty::gdscan_sync_lost_callback(sync_handle);
325 }
326
OnPeriodicSyncTransferred(int,uint8_t status,RawAddress address)327 void BleScannerIntf::OnPeriodicSyncTransferred(int, uint8_t status, RawAddress address) {
328 RustRawAddress converted = rusty::CopyToRustAddress(address);
329 rusty::gdscan_sync_transfer_callback(status, &converted);
330 }
331
RegisterCallbacks()332 void BleScannerIntf::RegisterCallbacks() {
333 // Register self as a callback handler. We will dispatch to Rust callbacks.
334 scanner_intf_->RegisterCallbacks(this);
335 }
336
337 // ScanningCallbacks overrides
GetBleScannerIntf(const unsigned char * gatt_intf)338 std::unique_ptr<BleScannerIntf> GetBleScannerIntf(const unsigned char* gatt_intf) {
339 return std::make_unique<BleScannerIntf>(reinterpret_cast<const btgatt_interface_t*>(gatt_intf)->scanner);
340 }
341
342 } // namespace rust
343 } // namespace topshim
344 } // namespace bluetooth
345