• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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