Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 907cd721 authored by Abhishek Pandit-Subedi's avatar Abhishek Pandit-Subedi
Browse files

floss: Add BleScanner topshim

Add topshim implementation for the GATT BLE scanner. This topshim
implementation uses cxx to shim the BleScannerInterface which uses lots
of C++ functionality.

Bug: 189497489
Tag: #floss
Test: emerge-zork floss
BYPASS_LONG_LINES_REASON: Bluetooth likes 120 lines

Change-Id: I4775379a34e117aaf09366947c331c7b79111420
parent e6de0926
Loading
Loading
Loading
Loading
+245 −6
Original line number Diff line number Diff line
@@ -16,13 +16,20 @@

#include "gd/rust/topshim/gatt/gatt_ble_scanner_shim.h"

#include <base/bind.h>
#include <base/callback.h>

#include <algorithm>
#include <iterator>
#include <memory>
#include <vector>

#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 {
@@ -31,12 +38,65 @@ namespace rust {

namespace rusty = ::bluetooth::topshim::rust;

void BleScannerIntf::RegisterCallbacks() {
  // Register self as a callback handler. We will dispatch to Rust callbacks.
  scanner_intf_->RegisterCallbacks(this);
namespace internal {
ApcfCommand ConvertApcfFromRust(const RustApcfCommand& command) {
  RawAddress address = rusty::CopyFromRustAddress(command.address);

  // Copy vectors + arrays
  std::vector<uint8_t> name, data, data_mask;
  std::array<uint8_t, 16> 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;
}

// ScanningCallbacks overrides
std::vector<ApcfCommand> ConvertApcfVec(const ::rust::Vec<RustApcfCommand>& rustvec) {
  std::vector<ApcfCommand> 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<const signed char*>(&app_uuid), scannerId, status);
}
@@ -89,8 +149,8 @@ void BleScannerIntf::OnTrackAdvFoundLost(AdvertisingTrackInfo ati) {
      // .scan_response is copied below
  };

  std::copy(ati.adv_packet.begin(), ati.adv_packet.end(), std::back_inserter(rust_info.adv_packet));
  std::copy(ati.scan_response.begin(), ati.scan_response.end(), std::back_inserter(rust_info.scan_response));
  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);
}
@@ -104,6 +164,185 @@ 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<RustApcfCommand> 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,
      base::Bind(&BleScannerIntf::OnStartSyncCb, base::Unretained(this)),
      base::Bind(&BleScannerIntf::OnSyncReportCb, base::Unretained(this)),
      base::Bind(&BleScannerIntf::OnSyncLostCb, base::Unretained(this)));
}

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, base::Bind(&BleScannerIntf::OnSyncTransferCb, base::Unretained(this)));
}

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, base::Bind(&BleScannerIntf::OnSyncTransferCb, base::Unretained(this)));
}

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, base::Bind(&BleScannerIntf::OnStartSyncCb, base::Unretained(this)));
}

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::OnStartSyncCb(
    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::OnSyncReportCb(
    uint16_t sync_handle, int8_t tx_power, int8_t rssi, uint8_t status, std::vector<uint8_t> data) {
  rusty::gdscan_sync_report_callback(sync_handle, tx_power, rssi, status, data.data(), data.size());
}

void BleScannerIntf::OnSyncLostCb(uint16_t sync_handle) {
  rusty::gdscan_sync_lost_callback(sync_handle);
}

void BleScannerIntf::OnSyncTransferCb(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<BleScannerIntf> GetBleScannerIntf(const unsigned char* gatt_intf) {
  return std::make_unique<BleScannerIntf>(reinterpret_cast<const btgatt_interface_t*>(gatt_intf)->scanner);
}
+104 −2
Original line number Diff line number Diff line
@@ -26,13 +26,16 @@ namespace bluetooth {
namespace topshim {
namespace rust {

struct RustApcfCommand;
struct RustGattFilterParam;
struct RustRawAddress;
struct RustUuid;

class BleScannerIntf : public ScanningCallbacks {
 public:
  BleScannerIntf(BleScannerInterface* scanner_intf) : scanner_intf_(scanner_intf){};
  ~BleScannerIntf() = default;

  void RegisterCallbacks();

  // ScanningCallbacks overrides
  void OnScannerRegistered(const bluetooth::Uuid app_uuid, uint8_t scannerId, uint8_t status) override;

@@ -57,7 +60,106 @@ class BleScannerIntf : public ScanningCallbacks {

  void OnBatchScanThresholdCrossed(int client_if) override;

  // Implementations of BleScannerInterface. These don't inherit from
  // BleScannerInterface because the Rust FFI boundary requires some clever
  // modifications.

  // Register a scanner for a Uuid. Response comes back via
  // |OnRegisterCallback|.
  void RegisterScanner(RustUuid uuid);

  // Unregister a scanner with a |scanner_id|.
  void Unregister(uint8_t scanner_id);

  // Start/Stop LE scanning.
  void Scan(bool start);

  // Setup scan filter parameters. Get responses via
  // |OnFilterParamSetupCallback|.
  void ScanFilterParamSetup(uint8_t scanner_id, uint8_t action, uint8_t filter_index, RustGattFilterParam filter_param);

  // Adds filters to given filter index. Gets responses via
  // |OnFilterConfigCallback|.
  void ScanFilterAdd(uint8_t filter_index, ::rust::Vec<RustApcfCommand> filters);

  // Clear scan filter conditions for a specific index.
  void ScanFilterClear(uint8_t filter_index);

  // Enable/disable scan filter. Gets responses via |OnEnableCallback|.
  void ScanFilterEnable(bool enable);

  // Sets the LE scan interval and window in units of N * 0.625 msec. The result
  // of this action is returned via |OnStatusCallback|.
  void SetScanParameters(uint8_t scanner_id, uint16_t scan_interval, uint16_t scan_window);

  // Configure the batchscan storage and get a response via |OnStatusCallback|.
  void BatchscanConfigStorage(
      uint8_t scanner_id,
      int32_t batch_scan_full_max,
      int32_t batch_scan_trunc_max,
      int32_t batch_scan_notify_threshold);

  // Enable batchscan. Gets responses via |OnStatusCallback| with scanner id
  // = 0 (since multiple scanners can be registered).
  void BatchscanEnable(
      int32_t scan_mode, uint16_t scan_interval, uint16_t scan_window, int32_t addr_type, int32_t discard_rule);

  // Disable batchscan. Gets responses via |OnStatusCallback| with a scanner id
  // = 0 (since multiple scanners can be registered).
  void BatchscanDisable();

  // Read out batchscan report for a specific scanner. Gets responses via
  // |ScanningCallbacks::OnBatchScanReports|.
  void BatchscanReadReports(uint8_t scanner_id, int32_t scan_mode);

  // Start periodic sync. Gets responses via |OnStartSyncCb|. Periodic reports
  // come via |OnSyncReportCb| and |OnSyncLostCb|.
  void StartSync(uint8_t sid, RustRawAddress address, uint16_t skip, uint16_t timeout);

  // Stop periodic sync.
  void StopSync(uint16_t handle);

  // Cancel creating a periodic sync.
  void CancelCreateSync(uint8_t sid, RustRawAddress address);

  // Transfer sync data to target address. Gets responses via
  // |OnSyncTransferCb|.
  void TransferSync(RustRawAddress address, uint16_t service_data, uint16_t sync_handle);

  // Transfer set info to target address. Gets responses via |OnSyncTransferCb|.
  void TransferSetInfo(RustRawAddress address, uint16_t service_data, uint8_t adv_handle);

  // Sync tx parameters to target address. Gets responses via |OnStartSyncCb|.
  void SyncTxParameters(RustRawAddress address, uint8_t mode, uint16_t skip, uint16_t timeout);

  // Register scanning callbacks to be dispatched to the Rust layer via static
  // methods.
  void RegisterCallbacks();

 private:
  // The callback functions below will get base::Bind to the apis that need it
  // and will call the same Rust function with all the parameters. Some of these
  // callbacks don't have all the parameters coming back in the original
  // callback and will need the values to be base::Bind at the callsite.

  void OnRegisterCallback(RustUuid uuid, uint8_t scanner_id, uint8_t btm_status);
  void OnStatusCallback(uint8_t scanner_id, uint8_t btm_status);
  void OnEnableCallback(uint8_t action, uint8_t btm_status);
  void OnFilterParamSetupCallback(uint8_t scanner_id, uint8_t avbl_space, uint8_t action_type, uint8_t btm_status);
  void OnFilterConfigCallback(
      uint8_t filt_index, uint8_t filt_type, uint8_t avbl_space, uint8_t action, uint8_t btm_status);
  void OnStartSyncCb(
      uint8_t status,
      uint16_t sync_handle,
      uint8_t advertising_sid,
      uint8_t address_type,
      RawAddress address,
      uint8_t phy,
      uint16_t interval);
  void OnSyncReportCb(uint16_t sync_handle, int8_t tx_power, int8_t rssi, uint8_t status, std::vector<uint8_t> data);
  void OnSyncLostCb(uint16_t sync_handle);
  void OnSyncTransferCb(uint8_t status, RawAddress address);

  BleScannerInterface* scanner_intf_;
};

+342 −3

File changed.

Preview size limit exceeded, changes collapsed.