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

Commit 1a688ea8 authored by Chienyuan's avatar Chienyuan
Browse files

gd: Implement basic scan function

Tag: #refactor
Bug: 169390539
Test: gd/cert/run --host
Change-Id: Ifb4ea21a4cdab2d3587a9d5d4cf1255be536b231
parent af3de085
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -4618,8 +4618,7 @@ struct LeExtendedAdvertisingReport {
  address : Address,
  primary_phy : PrimaryPhyType,
  secondary_phy : SecondaryPhyType,
  advertising_sid : 4, // SID subfield in the ADI field
  _reserved_ : 4,
  advertising_sid : 8, // SID subfield in the ADI field
  tx_power : 8,
  rssi : 8, // -127 to +20 (0x7F means not available)
  periodic_advertising_interval : 16, // 0x006 to 0xFFFF (7.5 ms to 82s)
+91 −6
Original line number Diff line number Diff line
@@ -91,6 +91,7 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback
      case hci::SubeventCode::EXTENDED_ADVERTISING_REPORT:
        handle_advertising_report<LeExtendedAdvertisingReportView, LeExtendedAdvertisingReport, ExtendedLeReport>(
            LeExtendedAdvertisingReportView::Create(event));
        handle_extended_advertising_report(LeExtendedAdvertisingReportView::Create(event));
        break;
      case hci::SubeventCode::SCAN_TIMEOUT:
        if (registered_callback_ != nullptr) {
@@ -104,6 +105,40 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback
    }
  }

  void handle_extended_advertising_report(LeExtendedAdvertisingReportView event_view) {
    if (scanning_callbacks_ == nullptr) {
      LOG_INFO("Dropping advertising event (no registered handler)");
      return;
    }
    if (!event_view.IsValid()) {
      LOG_INFO("Dropping invalid advertising event");
      return;
    }
    std::vector<LeExtendedAdvertisingReport> reports = event_view.GetAdvertisingReports();
    if (reports.empty()) {
      LOG_INFO("Zero results in advertising event");
      return;
    }

    // TODO: handle AdvertisingCache for scan response
    for (LeExtendedAdvertisingReport report : reports) {
      uint16_t event_type = report.connectable_ | (report.scannable_ << 1) | (report.directed_ << 2) |
                            (report.scan_response_ << 3) | (report.legacy_ << 4) | ((uint16_t)report.data_status_ << 5);

      scanning_callbacks_->OnScanResult(
          event_type,
          (uint8_t)report.address_type_,
          report.address_,
          (uint8_t)report.primary_phy_,
          (uint8_t)report.secondary_phy_,
          report.advertising_sid_,
          report.tx_power_,
          report.rssi_,
          report.periodic_advertising_interval_,
          report.advertising_data_);
    }
  }

  template <class EventType, class ReportStructType, class ReportType>
  void handle_advertising_report(EventType event_view) {
    if (registered_callback_ == nullptr) {
@@ -196,7 +231,52 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback
    }
  }

  void start_scan(LeScanningManagerCallbacks* le_scanning_manager_callbacks) {
  void scan(bool start) {
    if (start) {
      start_scan();
    } else {
      stop_scan();
    }
  }

  void start_scan() {
    switch (api_type_) {
      case ScanApiType::EXTENDED:
        le_scanning_interface_->EnqueueCommand(
            hci::LeSetExtendedScanEnableBuilder::Create(
                Enable::ENABLED, FilterDuplicates::DISABLED /* filter duplicates */, 0, 0),
            module_handler_->BindOnce(impl::check_status));
        break;
      case ScanApiType::ANDROID_HCI:
      case ScanApiType::LEGACY:
        le_scanning_interface_->EnqueueCommand(
            hci::LeSetScanEnableBuilder::Create(Enable::ENABLED, Enable::DISABLED /* filter duplicates */),
            module_handler_->BindOnce(impl::check_status));
        break;
    }
  }

  void stop_scan() {
    switch (api_type_) {
      case ScanApiType::EXTENDED:
        le_scanning_interface_->EnqueueCommand(
            hci::LeSetExtendedScanEnableBuilder::Create(
                Enable::DISABLED, FilterDuplicates::DISABLED /* filter duplicates */, 0, 0),
            module_handler_->BindOnce(impl::check_status));
        registered_callback_ = nullptr;
        break;
      case ScanApiType::ANDROID_HCI:
      case ScanApiType::LEGACY:
        le_scanning_interface_->EnqueueCommand(
            hci::LeSetScanEnableBuilder::Create(Enable::DISABLED, Enable::DISABLED /* filter duplicates */),
            module_handler_->BindOnce(impl::check_status));
        registered_callback_ = nullptr;
        break;
    }
  }

  // TODO remove
  void start_scan_old(LeScanningManagerCallbacks* le_scanning_manager_callbacks) {
    registered_callback_ = le_scanning_manager_callbacks;

    if (!address_manager_registered) {
@@ -226,7 +306,8 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback
    }
  }

  void stop_scan(common::Callback<void()> on_stopped, bool from_on_pause) {
  // TODO remove
  void stop_scan_old(common::Callback<void()> on_stopped, bool from_on_pause) {
    if (address_manager_registered && !from_on_pause) {
      cached_registered_callback_ = nullptr;
      le_address_manager_->Unregister(this);
@@ -260,7 +341,7 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback

  void OnPause() override {
    cached_registered_callback_ = registered_callback_;
    stop_scan(common::Bind(&impl::ack_pause, common::Unretained(this)), true);
    stop_scan_old(common::Bind(&impl::ack_pause, common::Unretained(this)), true);
  }

  void ack_pause() {
@@ -271,7 +352,7 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback
    if (cached_registered_callback_ != nullptr) {
      auto cached_registered_callback = cached_registered_callback_;
      cached_registered_callback_ = nullptr;
      start_scan(cached_registered_callback);
      start_scan_old(cached_registered_callback);
    }
    le_address_manager_->AckResume(this);
  }
@@ -359,12 +440,16 @@ void LeScanningManager::Unregister(ScannerId scanner_id) {
  CallOn(pimpl_.get(), &impl::unregister_scanner, scanner_id);
}

void LeScanningManager::Scan(bool start) {
  CallOn(pimpl_.get(), &impl::scan, start);
}

void LeScanningManager::StartScan(LeScanningManagerCallbacks* callbacks) {
  GetHandler()->Post(common::Bind(&impl::start_scan, common::Unretained(pimpl_.get()), callbacks));
  GetHandler()->Post(common::Bind(&impl::start_scan_old, common::Unretained(pimpl_.get()), callbacks));
}

void LeScanningManager::StopScan(common::Callback<void()> on_stopped) {
  GetHandler()->Post(common::Bind(&impl::stop_scan, common::Unretained(pimpl_.get()), on_stopped, false));
  GetHandler()->Post(common::Bind(&impl::stop_scan_old, common::Unretained(pimpl_.get()), on_stopped, false));
}

void LeScanningManager::RegisterScanningCallback(ScanningCallback* scanning_callback) {
+6 −4
Original line number Diff line number Diff line
@@ -49,15 +49,15 @@ class ScanningCallback {
      const bluetooth::hci::Uuid app_uuid, ScannerId scanner_id, ScanningStatus status) = 0;
  virtual void OnScanResult(
      uint16_t event_type,
      uint8_t addr_type,
      Address* bda,
      uint8_t address_type,
      Address address,
      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) = 0;
      uint16_t periodic_advertising_interval,
      std::vector<GapData> advertising_data) = 0;
  virtual void OnTrackAdvFoundLost() = 0;
  virtual void OnBatchScanReports(
      int client_if, int status, int report_format, int num_records, std::vector<uint8_t> data) = 0;
@@ -72,6 +72,8 @@ class LeScanningManager : public bluetooth::Module {

  void Unregister(ScannerId scanner_id);

  void Scan(bool start);

  void StartScan(LeScanningManagerCallbacks* callbacks);

  void StopScan(common::Callback<void()> on_stopped);
+31 −5
Original line number Diff line number Diff line
@@ -52,7 +52,10 @@ class BleScannerInterfaceImpl : public BleScannerInterface,
  }

  /** Start or stop LE device scanning */
  void Scan(bool start) { LOG(INFO) << __func__ << " in shim layer"; }
  void Scan(bool start) {
    LOG(INFO) << __func__ << " in shim layer";
    bluetooth::shim::GetScanning()->Scan(start);
  }

  /** Setup scan filter params */
  void ScanFilterParamSetup(
@@ -134,11 +137,34 @@ class BleScannerInterfaceImpl : public BleScannerInterface,
                                scanner_id, status));
  };

  void OnScanResult(uint16_t event_type, uint8_t addr_type,
                    bluetooth::hci::Address* bda, uint8_t primary_phy,
  void OnScanResult(uint16_t event_type, uint8_t address_type,
                    bluetooth::hci::Address address, 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){};
                    int8_t tx_power, int8_t rssi,
                    uint16_t periodic_advertising_interval,
                    std::vector<bluetooth::hci::GapData> advertising_data) {
    RawAddress raw_address;
    RawAddress::FromString(address.ToString(), raw_address);
    std::unique_ptr<RawAddress> raw_address_ptr(new RawAddress(raw_address));

    std::vector<uint8_t> adv_data = {};
    for (auto gap_data : advertising_data) {
      gap_data.size();
      adv_data.push_back((uint8_t)gap_data.size() - 1);
      adv_data.push_back((uint8_t)gap_data.data_type_);
      adv_data.insert(adv_data.end(), gap_data.data_.begin(),
                      gap_data.data_.end());
    }

    do_in_jni_thread(
        FROM_HERE,
        base::BindOnce(&ScanningCallbacks::OnScanResult,
                       base::Unretained(scanning_callbacks_), event_type,
                       address_type, raw_address_ptr.get(), primary_phy,
                       secondary_phy, advertising_sid, tx_power, rssi,
                       periodic_advertising_interval, adv_data));
  };

  void OnTrackAdvFoundLost(){};

  void OnBatchScanReports(int client_if, int status, int report_format,