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

Commit 025bdbf6 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge changes I8e04ea0c,Ia710365d

* changes:
  gd: Handle data status for extended advertising report
  gd: Handle scan response
parents 0f6d792c 93f242ce
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -26,7 +26,6 @@
#include "hci/facade/le_scanning_manager_facade.grpc.pb.h"
#include "hci/facade/le_scanning_manager_facade.h"
#include "hci/facade/le_scanning_manager_facade.pb.h"
#include "hci/le_report.h"
#include "os/log.h"
#include "packet/raw_builder.h"

@@ -72,7 +71,7 @@ class LeScanningManagerFacadeService : public LeScanningManagerFacade::Service,
      int8_t tx_power,
      int8_t rssi,
      uint16_t periodic_advertising_interval,
      std::vector<GapData> advertising_data) {
      std::vector<uint8_t> advertising_data) {
    LeReportMsg le_report_msg;
    std::vector<LeExtendedAdvertisingReport> advertisements;
    LeExtendedAdvertisingReport le_extended_advertising_report;
+1 −1
Original line number Diff line number Diff line
@@ -4629,7 +4629,7 @@ struct LeExtendedAdvertisingReport {
  direct_address_type : DirectAdvertisingAddressType,
  direct_address : Address,
  _size_(advertising_data) : 8,
  advertising_data : GapData[],
  advertising_data : 8[],
}

packet LeExtendedAdvertisingReport : LeMetaEvent (subevent_code = EXTENDED_ADVERTISING_REPORT) {

system/gd/hci/le_report.h

deleted100644 → 0
+0 −105
Original line number Diff line number Diff line
/*
 * Copyright 2019 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.
 */
#pragma once

#include <memory>

#include "hci/hci_packets.h"

namespace bluetooth::hci {

class LeReport {
 public:
  explicit LeReport(const LeAdvertisingReport& advertisement)
      : report_type_(ReportType::ADVERTISING_EVENT),
        advertising_event_type_(advertisement.event_type_),
        address_(advertisement.address_),
        address_type_(static_cast<DirectAdvertisingAddressType>(advertisement.address_type_)),
        rssi_(advertisement.rssi_),
        gap_data_(advertisement.advertising_data_) {}
  explicit LeReport(const LeDirectedAdvertisingReport& advertisement)
      : report_type_(ReportType::DIRECTED_ADVERTISING_EVENT),
        address_(advertisement.address_),
        address_type_(advertisement.address_type_),
        rssi_(advertisement.rssi_) {}
  explicit LeReport(const LeExtendedAdvertisingReport& advertisement)
      : report_type_(ReportType::EXTENDED_ADVERTISING_EVENT),
        address_(advertisement.address_),
        address_type_(advertisement.address_type_),
        rssi_(advertisement.rssi_),
        gap_data_(advertisement.advertising_data_) {}
  virtual ~LeReport() = default;

  enum class ReportType {
    ADVERTISING_EVENT = 1,
    DIRECTED_ADVERTISING_EVENT = 2,
    EXTENDED_ADVERTISING_EVENT = 3,
  };
  const ReportType report_type_;

  ReportType GetReportType() const {
    return report_type_;
  }

  // Advertising Event
  const AdvertisingEventType advertising_event_type_{};
  const Address address_{};
  const DirectAdvertisingAddressType address_type_{};
  const int8_t rssi_;
  const std::vector<GapData> gap_data_{};
};

class DirectedLeReport : public LeReport {
 public:
  explicit DirectedLeReport(const LeDirectedAdvertisingReport& advertisement)
      : LeReport(advertisement), direct_address_type_(advertisement.address_type_),
        direct_address_(advertisement.direct_address_) {}
  explicit DirectedLeReport(const LeExtendedAdvertisingReport& advertisement)
      : LeReport(advertisement), direct_address_type_(advertisement.address_type_),
        direct_address_(advertisement.direct_address_) {}

  const DirectAdvertisingAddressType direct_address_type_{};
  const Address direct_address_{};
};

class ExtendedLeReport : public DirectedLeReport {
 public:
  explicit ExtendedLeReport(const LeExtendedAdvertisingReport& advertisement)
      : DirectedLeReport(advertisement),
        connectable_(advertisement.connectable_),
        scannable_(advertisement.scannable_),
        directed_(advertisement.directed_),
        scan_response_(advertisement.scan_response_),
        legacy_(advertisement.legacy_),
        complete_(advertisement.data_status_ == DataStatus::COMPLETE),
        truncated_(advertisement.data_status_ == DataStatus::TRUNCATED),
        primary_phy_(static_cast<uint8_t>(advertisement.primary_phy_)),
        secondary_phy_(static_cast<uint8_t>(advertisement.secondary_phy_)),
        tx_power_(advertisement.tx_power_) {}

  // Extended
  bool connectable_;
  bool scannable_;
  bool directed_;
  bool scan_response_;
  bool legacy_;
  bool complete_;
  bool truncated_;
  uint8_t primary_phy_;
  uint8_t secondary_phy_;
  int8_t tx_power_;
};
}  // namespace bluetooth::hci
 No newline at end of file
+146 −8
Original line number Diff line number Diff line
@@ -33,6 +33,12 @@ namespace hci {
constexpr uint16_t kDefaultLeScanWindow = 4800;
constexpr uint16_t kDefaultLeScanInterval = 4800;

constexpr uint8_t kScannableBit = 1;
constexpr uint8_t kDirectedBit = 2;
constexpr uint8_t kScanResponseBit = 3;
constexpr uint8_t kLegacyBit = 4;
constexpr uint8_t kDataStatusBits = 5;

const ModuleFactory LeScanningManager::Factory = ModuleFactory([]() { return new LeScanningManager(); });

enum class ScanApiType {
@@ -46,6 +52,79 @@ struct Scanner {
  bool in_use;
};

class AdvertisingCache {
 public:
  const std::vector<uint8_t>& Set(const AddressWithType& address_with_type, std::vector<uint8_t> data) {
    auto it = Find(address_with_type);
    if (it != items.end()) {
      it->data = std::move(data);
    }

    if (items.size() > cache_max) {
      items.pop_back();
    }

    items.emplace_front(address_with_type, std::move(data));
    return items.front().data;
  }

  bool Exist(const AddressWithType& address_with_type) {
    auto it = Find(address_with_type);
    if (it == items.end()) {
      return false;
    }
    return true;
  }

  const std::vector<uint8_t>& Append(const AddressWithType& address_with_type, std::vector<uint8_t> data) {
    auto it = Find(address_with_type);
    if (it != items.end()) {
      it->data.insert(it->data.end(), data.begin(), data.end());
      return it->data;
    }

    if (items.size() > cache_max) {
      items.pop_back();
    }

    items.emplace_front(address_with_type, std::move(data));
    return items.front().data;
  }

  /* Clear data for device |addr_type, addr| */
  void Clear(AddressWithType address_with_type) {
    auto it = Find(address_with_type);
    if (it != items.end()) {
      items.erase(it);
    }
  }

  void ClearAll() {
    items.clear();
  }

  struct Item {
    AddressWithType address_with_type;
    std::vector<uint8_t> data;

    Item(const AddressWithType& address_with_type, std::vector<uint8_t> data)
        : address_with_type(address_with_type), data(data) {}
  };

  std::list<Item>::iterator Find(const AddressWithType& address_with_type) {
    for (auto it = items.begin(); it != items.end(); it++) {
      if (it->address_with_type == address_with_type) {
        return it;
      }
    }
    return items.end();
  }

  /* we keep maximum 7 devices in the cache */
  const size_t cache_max = 1000;
  std::list<Item> items;
};

struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback {
  impl(Module* module) : module_(module), le_scanning_interface_(nullptr) {}

@@ -132,7 +211,6 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback
      return;
    }

    // TODO: handle AdvertisingCache for scan response
    for (LeAdvertisingReport report : reports) {
      uint16_t extended_event_type = 0;
      switch (report.event_type_) {
@@ -159,8 +237,15 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback
          return;
      }

      scanning_callbacks_->OnScanResult(
          (uint16_t)report.event_type_,
      std::vector<uint8_t> advertising_data = {};
      for (auto gap_data : report.advertising_data_) {
        advertising_data.push_back((uint8_t)gap_data.size() - 1);
        advertising_data.push_back((uint8_t)gap_data.data_type_);
        advertising_data.insert(advertising_data.end(), gap_data.data_.begin(), gap_data.data_.end());
      }

      process_advertising_package_content(
          extended_event_type,
          (uint8_t)report.address_type_,
          report.address_,
          (uint8_t)PrimaryPhyType::LE_1M,
@@ -169,7 +254,7 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback
          kTxPowerInformationNotPresent,
          report.rssi_,
          kNotPeriodicAdvertisement,
          report.advertising_data_);
          advertising_data);
    }
  }

@@ -207,11 +292,11 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback
      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(
      uint16_t event_type = report.connectable_ | (report.scannable_ << kScannableBit) |
                            (report.directed_ << kDirectedBit) | (report.scan_response_ << kScanResponseBit) |
                            (report.legacy_ << kLegacyBit) | ((uint16_t)report.data_status_ << kDataStatusBits);
      process_advertising_package_content(
          event_type,
          (uint8_t)report.address_type_,
          report.address_,
@@ -225,6 +310,58 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback
    }
  }

  void process_advertising_package_content(
      uint16_t event_type,
      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_advertising_interval,
      std::vector<uint8_t> advertising_data) {
    bool is_scannable = event_type & (1 << kScannableBit);
    bool is_scan_response = event_type & (1 << kScanResponseBit);
    bool is_legacy = event_type & (1 << kLegacyBit);
    // TODO handle anonymous advertisement (0xFF)
    AddressWithType address_with_type(address, (AddressType)address_type);

    if (is_legacy && is_scan_response && !advertising_cache_.Exist(address_with_type)) {
      return;
    }

    bool is_start = is_legacy && is_scannable && !is_scan_response;

    std::vector<uint8_t> const& adv_data = is_start ? advertising_cache_.Set(address_with_type, advertising_data)
                                                    : advertising_cache_.Append(address_with_type, advertising_data);

    uint8_t data_status = event_type >> kDataStatusBits;
    if (data_status == (uint8_t)DataStatus::CONTINUING) {
      // Waiting for whole data
      return;
    }

    if (is_scannable && !is_scan_response) {
      // Waiting for scan response
      return;
    }

    scanning_callbacks_->OnScanResult(
        event_type,
        address_type,
        address,
        primary_phy,
        secondary_phy,
        advertising_sid,
        tx_power,
        rssi,
        periodic_advertising_interval,
        adv_data);

    advertising_cache_.Clear(address_with_type);
  }

  void configure_scan() {
    std::vector<PhyScanParameters> parameter_vector;
    PhyScanParameters phy_scan_parameters;
@@ -389,6 +526,7 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback
  bool is_scanning_ = false;
  bool scan_on_resume_ = false;
  bool paused_ = false;
  AdvertisingCache advertising_cache_;

  uint32_t interval_ms_{1000};
  uint16_t window_ms_{1000};
+1 −2
Original line number Diff line number Diff line
@@ -19,7 +19,6 @@

#include "common/callback.h"
#include "hci/hci_packets.h"
#include "hci/le_report.h"
#include "hci/uuid.h"
#include "module.h"

@@ -49,7 +48,7 @@ class ScanningCallback {
      int8_t tx_power,
      int8_t rssi,
      uint16_t periodic_advertising_interval,
      std::vector<GapData> advertising_data) = 0;
      std::vector<uint8_t> 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;
Loading