/* * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "gd/rust/topshim/gatt/gatt_ble_scanner_shim.h" #include #include #include #include #include #include #include "bind_helpers.h" #include "gd/rust/topshim/common/utils.h" #include "include/hardware/bt_common_types.h" #include "rust/cxx.h" #include "src/profiles/gatt.rs.h" #include "types/bluetooth/uuid.h" #include "types/raw_address.h" namespace bluetooth { namespace topshim { namespace rust { namespace rusty = ::bluetooth::topshim::rust; namespace internal { ApcfCommand ConvertApcfFromRust(const RustApcfCommand& command) { RawAddress address = rusty::CopyFromRustAddress(command.address); // Copy vectors + arrays std::vector name, data, data_mask; std::array irk; std::copy(command.name.begin(), command.name.end(), std::back_inserter(name)); std::copy(command.data.begin(), command.data.end(), std::back_inserter(data)); std::copy(command.data_mask.begin(), command.data_mask.end(), std::back_inserter(data_mask)); std::copy(command.irk.begin(), command.irk.end(), std::begin(irk)); ApcfCommand converted = { .type = command.type_, .address = address, .addr_type = command.addr_type, .uuid = bluetooth::Uuid::From128BitBE(command.uuid.uu), .uuid_mask = bluetooth::Uuid::From128BitBE(command.uuid_mask.uu), .name = name, .company = command.company, .company_mask = command.company_mask, .data = data, .data_mask = data_mask, .irk = irk, }; return converted; } std::vector ConvertApcfVec(const ::rust::Vec& rustvec) { std::vector converted; for (const RustApcfCommand& command : rustvec) { converted.push_back(ConvertApcfFromRust(command)); } return converted; } ::btgatt_filt_param_setup_t ConvertRustFilterParam(const RustGattFilterParam& param) { ::btgatt_filt_param_setup_t converted = { .feat_seln = param.feat_seln, .list_logic_type = param.list_logic_type, .filt_logic_type = param.filt_logic_type, .rssi_high_thres = param.rssi_high_thres, .rssi_low_thres = param.rssi_low_thres, .dely_mode = param.delay_mode, .found_timeout = param.found_timeout, .lost_timeout = param.lost_timeout, .found_timeout_cnt = param.found_timeout_count, .num_of_tracking_entries = param.num_of_tracking_entries, }; return converted; } } // namespace internal // ScanningCallbacks implementations void BleScannerIntf::OnScannerRegistered(const bluetooth::Uuid app_uuid, uint8_t scannerId, uint8_t status) { rusty::gdscan_on_scanner_registered(reinterpret_cast(&app_uuid), scannerId, status); } void BleScannerIntf::OnSetScannerParameterComplete(uint8_t scannerId, uint8_t status) { rusty::gdscan_on_set_scanner_parameter_complete(scannerId, status); } void BleScannerIntf::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 adv_data) { RustRawAddress raw_address = rusty::CopyToRustAddress(bda); rusty::gdscan_on_scan_result( event_type, addr_type, reinterpret_cast(&raw_address), primary_phy, secondary_phy, advertising_sid, tx_power, rssi, periodic_adv_int, adv_data.data(), adv_data.size()); } void BleScannerIntf::OnTrackAdvFoundLost(AdvertisingTrackInfo ati) { rusty::RustRawAddress addr = rusty::CopyToRustAddress(ati.advertiser_address); rusty::RustAdvertisingTrackInfo rust_info = { .scanner_id = ati.scanner_id, .filter_index = ati.filter_index, .advertiser_state = ati.advertiser_state, .advertiser_info_present = ati.advertiser_info_present, .advertiser_address = addr, .advertiser_address_type = ati.advertiser_address_type, .tx_power = ati.tx_power, .rssi = ati.rssi, .timestamp = ati.time_stamp, .adv_packet_len = ati.adv_packet_len, // .adv_packet is copied below .scan_response_len = ati.scan_response_len, // .scan_response is copied below }; std::copy(rust_info.adv_packet.begin(), rust_info.adv_packet.end(), std::back_inserter(ati.adv_packet)); std::copy(rust_info.scan_response.begin(), rust_info.scan_response.end(), std::back_inserter(ati.scan_response)); rusty::gdscan_on_track_adv_found_lost(rust_info); } void BleScannerIntf::OnBatchScanReports( int client_if, int status, int report_format, int num_records, std::vector data) { rusty::gdscan_on_batch_scan_reports(client_if, status, report_format, num_records, data.data(), data.size()); } void BleScannerIntf::OnBatchScanThresholdCrossed(int client_if) { rusty::gdscan_on_batch_scan_threshold_crossed(client_if); } // BleScannerInterface implementations void BleScannerIntf::RegisterScanner(RustUuid uuid) { bluetooth::Uuid converted = bluetooth::Uuid::From128BitBE(uuid.uu); scanner_intf_->RegisterScanner( converted, base::Bind(&BleScannerIntf::OnRegisterCallback, base::Unretained(this), uuid)); } void BleScannerIntf::Unregister(uint8_t scanner_id) { scanner_intf_->Unregister(scanner_id); } void BleScannerIntf::Scan(bool start) { scanner_intf_->Scan(start); } void BleScannerIntf::ScanFilterParamSetup( uint8_t scanner_id, uint8_t action, uint8_t filter_index, RustGattFilterParam filter_param) { std::unique_ptr<::btgatt_filt_param_setup_t> converted = std::make_unique<::btgatt_filt_param_setup_t>(std::move(internal::ConvertRustFilterParam(filter_param))); scanner_intf_->ScanFilterParamSetup( scanner_id, action, filter_index, std::move(converted), base::Bind(&BleScannerIntf::OnFilterParamSetupCallback, base::Unretained(this), scanner_id)); } void BleScannerIntf::ScanFilterAdd(uint8_t filter_index, ::rust::Vec filters) { auto converted = internal::ConvertApcfVec(filters); scanner_intf_->ScanFilterAdd( filter_index, converted, base::Bind(&BleScannerIntf::OnFilterConfigCallback, base::Unretained(this), filter_index)); } void BleScannerIntf::ScanFilterClear(uint8_t filter_index) { scanner_intf_->ScanFilterClear( filter_index, base::Bind(&BleScannerIntf::OnFilterConfigCallback, base::Unretained(this), filter_index)); } void BleScannerIntf::ScanFilterEnable(bool enable) { scanner_intf_->ScanFilterEnable(enable, base::Bind(&BleScannerIntf::OnEnableCallback, base::Unretained(this))); } void BleScannerIntf::SetScanParameters(uint8_t scanner_id, uint16_t scan_interval, uint16_t scan_window) { scanner_intf_->SetScanParameters( scanner_id, scan_interval, scan_window, base::Bind(&BleScannerIntf::OnStatusCallback, base::Unretained(this), scanner_id)); } void BleScannerIntf::BatchscanConfigStorage( uint8_t scanner_id, int32_t batch_scan_full_max, int32_t batch_scan_trunc_max, int32_t batch_scan_notify_threshold) { scanner_intf_->BatchscanConfigStorage( scanner_id, batch_scan_full_max, batch_scan_trunc_max, batch_scan_notify_threshold, base::Bind(&BleScannerIntf::OnStatusCallback, base::Unretained(this), scanner_id)); } void BleScannerIntf::BatchscanEnable( int32_t scan_mode, uint16_t scan_interval, uint16_t scan_window, int32_t addr_type, int32_t discard_rule) { scanner_intf_->BatchscanEnable( scan_mode, scan_interval, scan_window, addr_type, discard_rule, base::Bind(&BleScannerIntf::OnStatusCallback, base::Unretained(this), 0)); } void BleScannerIntf::BatchscanDisable() { scanner_intf_->BatchscanDisable(base::Bind(&BleScannerIntf::OnStatusCallback, base::Unretained(this), 0)); } void BleScannerIntf::BatchscanReadReports(uint8_t scanner_id, int32_t scan_mode) { scanner_intf_->BatchscanReadReports(scanner_id, scan_mode); } void BleScannerIntf::StartSync(uint8_t sid, RustRawAddress address, uint16_t skip, uint16_t timeout) { RawAddress converted = rusty::CopyFromRustAddress(address); scanner_intf_->StartSync(sid, converted, skip, timeout, 0 /* place holder */); } void BleScannerIntf::StopSync(uint16_t handle) { scanner_intf_->StopSync(handle); } void BleScannerIntf::CancelCreateSync(uint8_t sid, RustRawAddress address) { RawAddress converted = rusty::CopyFromRustAddress(address); scanner_intf_->CancelCreateSync(sid, converted); } void BleScannerIntf::TransferSync(RustRawAddress address, uint16_t service_data, uint16_t sync_handle) { RawAddress converted = rusty::CopyFromRustAddress(address); scanner_intf_->TransferSync(converted, service_data, sync_handle, 0 /* place holder */); } void BleScannerIntf::TransferSetInfo(RustRawAddress address, uint16_t service_data, uint8_t adv_handle) { RawAddress converted = rusty::CopyFromRustAddress(address); scanner_intf_->TransferSetInfo(converted, service_data, adv_handle, 0 /* place holder */); } void BleScannerIntf::SyncTxParameters(RustRawAddress address, uint8_t mode, uint16_t skip, uint16_t timeout) { RawAddress converted = rusty::CopyFromRustAddress(address); scanner_intf_->SyncTxParameters(converted, mode, skip, timeout, 0 /* place holder */); } void BleScannerIntf::OnRegisterCallback(RustUuid uuid, uint8_t scanner_id, uint8_t btm_status) { rusty::gdscan_register_callback(uuid, scanner_id, btm_status); } void BleScannerIntf::OnStatusCallback(uint8_t scanner_id, uint8_t btm_status) { rusty::gdscan_status_callback(scanner_id, btm_status); } void BleScannerIntf::OnEnableCallback(uint8_t action, uint8_t btm_status) { rusty::gdscan_enable_callback(action, btm_status); } void BleScannerIntf::OnFilterParamSetupCallback( uint8_t scanner_id, uint8_t avbl_space, uint8_t action_type, uint8_t btm_status) { rusty::gdscan_filter_param_setup_callback(scanner_id, avbl_space, action_type, btm_status); } void BleScannerIntf::OnFilterConfigCallback( uint8_t filter_index, uint8_t filt_type, uint8_t avbl_space, uint8_t action, uint8_t btm_status) { rusty::gdscan_filter_config_callback(filter_index, filt_type, avbl_space, action, btm_status); } void BleScannerIntf::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) { RustRawAddress converted = rusty::CopyToRustAddress(address); rusty::gdscan_start_sync_callback(status, sync_handle, advertising_sid, address_type, &converted, phy, interval); } void BleScannerIntf::OnPeriodicSyncReport( uint16_t sync_handle, int8_t tx_power, int8_t rssi, uint8_t status, std::vector data) { rusty::gdscan_sync_report_callback(sync_handle, tx_power, rssi, status, data.data(), data.size()); } void BleScannerIntf::OnPeriodicSyncLost(uint16_t sync_handle) { rusty::gdscan_sync_lost_callback(sync_handle); } void BleScannerIntf::OnPeriodicSyncTransferred(int, uint8_t status, RawAddress address) { RustRawAddress converted = rusty::CopyToRustAddress(address); rusty::gdscan_sync_transfer_callback(status, &converted); } void BleScannerIntf::RegisterCallbacks() { // Register self as a callback handler. We will dispatch to Rust callbacks. scanner_intf_->RegisterCallbacks(this); } // ScanningCallbacks overrides std::unique_ptr GetBleScannerIntf(const unsigned char* gatt_intf) { return std::make_unique(reinterpret_cast(gatt_intf)->scanner); } } // namespace rust } // namespace topshim } // namespace bluetooth