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

Commit 05896110 authored by Rahul Arya's avatar Rahul Arya Committed by Automerger Merge Worker
Browse files

Merge "Handle non-significant data in advertising reports" am: 02a05b5e

parents 0b6a2fa6 02a05b5e
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -124,15 +124,15 @@ class LeScanningManagerFacadeService : public LeScanningManagerFacade::Service,
      uint16_t periodic_advertising_interval,
      std::vector<uint8_t> advertising_data) {
    AdvertisingReportMsg advertising_report_msg;
    std::vector<LeExtendedAdvertisingResponse> advertisements;
    LeExtendedAdvertisingResponse le_extended_advertising_report;
    std::vector<LeExtendedAdvertisingResponseRaw> advertisements;
    LeExtendedAdvertisingResponseRaw le_extended_advertising_report;
    le_extended_advertising_report.address_type_ = (DirectAdvertisingAddressType)address_type;
    le_extended_advertising_report.address_ = address;
    le_extended_advertising_report.advertising_data_ = advertising_data;
    le_extended_advertising_report.rssi_ = rssi;
    advertisements.push_back(le_extended_advertising_report);

    auto builder = LeExtendedAdvertisingReportBuilder::Create(advertisements);
    auto builder = LeExtendedAdvertisingReportRawBuilder::Create(advertisements);
    std::vector<uint8_t> bytes;
    BitInserter bit_inserter(bytes);
    builder->Serialize(bit_inserter);
+34 −2
Original line number Diff line number Diff line
@@ -57,6 +57,11 @@ enum GapDataType : 8 {
  MANUFACTURER_SPECIFIC_DATA = 0xFF,
}

struct LengthAndData {
  _size_(data) : 8,
  data: 8[],
}

struct GapData {
  _size_(data) : 8, // Including one byte for data_type
  data_type : GapDataType,
@@ -5536,7 +5541,7 @@ struct LeAdvertisingResponse {
  address_type : AddressType,
  address : Address,
  _size_(advertising_data) : 8,
  advertising_data : GapData[],
  advertising_data : LengthAndData[],
  rssi : 8,
}

@@ -5672,6 +5677,28 @@ enum DataStatus : 2 {
}

struct LeExtendedAdvertisingResponse {
  connectable : 1,
  scannable : 1,
  directed : 1,
  scan_response : 1,
  legacy : 1,
  data_status : DataStatus,
  _reserved_ : 9,
  address_type : DirectAdvertisingAddressType,
  address : Address,
  primary_phy : PrimaryPhyType,
  secondary_phy : SecondaryPhyType,
  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)
  direct_address_type : DirectAdvertisingAddressType,
  direct_address : Address,
  _size_(advertising_data) : 8,
  advertising_data: LengthAndData[],
}

struct LeExtendedAdvertisingResponseRaw {
  connectable : 1,
  scannable : 1,
  directed : 1,
@@ -5693,6 +5720,11 @@ struct LeExtendedAdvertisingResponse {
  advertising_data: 8[],
}

packet LeExtendedAdvertisingReportRaw : LeMetaEvent (subevent_code = EXTENDED_ADVERTISING_REPORT) {
  _count_(responses) : 8,
  responses : LeExtendedAdvertisingResponseRaw[],
}

packet LeExtendedAdvertisingReport : LeMetaEvent (subevent_code = EXTENDED_ADVERTISING_REPORT) {
  _count_(responses) : 8,
  responses : LeExtendedAdvertisingResponse[],
+13 −12
Original line number Diff line number Diff line
@@ -381,13 +381,6 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback
          return;
      }

      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_,
@@ -398,7 +391,7 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback
          kTxPowerInformationNotPresent,
          report.rssi_,
          kNotPeriodicAdvertisement,
          advertising_data);
          report.advertising_data_);
    }
  }

@@ -456,11 +449,19 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback
      int8_t tx_power,
      int8_t rssi,
      uint16_t periodic_advertising_interval,
      std::vector<uint8_t> advertising_data) {
      std::vector<bluetooth::hci::LengthAndData> advertising_data) {
    bool is_scannable = event_type & (1 << kScannableBit);
    bool is_scan_response = event_type & (1 << kScanResponseBit);
    bool is_legacy = event_type & (1 << kLegacyBit);

    auto significant_data = std::vector<uint8_t>{};
    for (const auto& datum : advertising_data) {
      if (!datum.data_.empty()) {
        significant_data.push_back(static_cast<uint8_t>(datum.data_.size()));
        significant_data.insert(significant_data.end(), datum.data_.begin(), datum.data_.end());
      }
    }

    if (address_type == (uint8_t)DirectAdvertisingAddressType::NO_ADDRESS) {
      scanning_callbacks_->OnScanResult(
          event_type,
@@ -472,7 +473,7 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback
          tx_power,
          rssi,
          periodic_advertising_interval,
          advertising_data);
          significant_data);
      return;
    } else if (address == Address::kEmpty) {
      LOG_WARN("Receive non-anonymous advertising report with empty address, skip!");
@@ -487,8 +488,8 @@ struct LeScanningManager::impl : public bluetooth::hci::LeAddressManagerCallback

    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);
    std::vector<uint8_t> const& adv_data = is_start ? advertising_cache_.Set(address_with_type, significant_data)
                                                    : advertising_cache_.Append(address_with_type, significant_data);

    uint8_t data_status = event_type >> kDataStatusBits;
    if (data_status == (uint8_t)DataStatus::CONTINUING) {
+95 −34
Original line number Diff line number Diff line
@@ -31,6 +31,9 @@
#include "os/thread.h"
#include "packet/raw_builder.h"

using ::testing::_;
using ::testing::Eq;

namespace bluetooth {
namespace hci {
namespace {
@@ -412,15 +415,17 @@ TEST_F(LeScanningManagerTest, start_scan_test) {
  report.event_type_ = AdvertisingEventType::ADV_DIRECT_IND;
  report.address_type_ = AddressType::PUBLIC_DEVICE_ADDRESS;
  Address::FromString("12:34:56:78:9a:bc", report.address_);
  std::vector<GapData> gap_data{};
  GapData data_item{};
  data_item.data_type_ = GapDataType::FLAGS;
  data_item.data_ = {0x34};
  gap_data.push_back(data_item);
  data_item.data_type_ = GapDataType::COMPLETE_LOCAL_NAME;
  data_item.data_ = {'r', 'a', 'n', 'd', 'o', 'm', ' ', 'd', 'e', 'v', 'i', 'c', 'e'};
  gap_data.push_back(data_item);
  report.advertising_data_ = gap_data;
  std::vector<LengthAndData> adv_data{};
  LengthAndData data_item{};
  data_item.data_.push_back(static_cast<uint8_t>(GapDataType::FLAGS));
  data_item.data_.push_back(0x34);
  adv_data.push_back(data_item);
  data_item.data_.push_back(static_cast<uint8_t>(GapDataType::COMPLETE_LOCAL_NAME));
  for (auto octet : {'r', 'a', 'n', 'd', 'o', 'm', ' ', 'd', 'e', 'v', 'i', 'c', 'e'}) {
    data_item.data_.push_back(octet);
  }
  adv_data.push_back(data_item);
  report.advertising_data_ = adv_data;

  EXPECT_CALL(mock_callbacks_, OnScanResult);

@@ -442,15 +447,17 @@ TEST_F(LeAndroidHciScanningManagerTest, start_scan_test) {
  report.event_type_ = AdvertisingEventType::ADV_DIRECT_IND;
  report.address_type_ = AddressType::PUBLIC_DEVICE_ADDRESS;
  Address::FromString("12:34:56:78:9a:bc", report.address_);
  std::vector<GapData> gap_data{};
  GapData data_item{};
  data_item.data_type_ = GapDataType::FLAGS;
  data_item.data_ = {0x34};
  gap_data.push_back(data_item);
  data_item.data_type_ = GapDataType::COMPLETE_LOCAL_NAME;
  data_item.data_ = {'r', 'a', 'n', 'd', 'o', 'm', ' ', 'd', 'e', 'v', 'i', 'c', 'e'};
  gap_data.push_back(data_item);
  report.advertising_data_ = gap_data;
  std::vector<LengthAndData> adv_data{};
  LengthAndData data_item{};
  data_item.data_.push_back(static_cast<uint8_t>(GapDataType::FLAGS));
  data_item.data_.push_back(0x34);
  adv_data.push_back(data_item);
  data_item.data_.push_back(static_cast<uint8_t>(GapDataType::COMPLETE_LOCAL_NAME));
  for (auto octet : {'r', 'a', 'n', 'd', 'o', 'm', ' ', 'd', 'e', 'v', 'i', 'c', 'e'}) {
    data_item.data_.push_back(octet);
  }
  adv_data.push_back(data_item);
  report.advertising_data_ = adv_data;

  EXPECT_CALL(mock_callbacks_, OnScanResult);

@@ -667,28 +674,82 @@ TEST_F(LeExtendedScanningManagerTest, start_scan_test) {
  report.scannable_ = 0;
  report.address_type_ = DirectAdvertisingAddressType::PUBLIC_DEVICE_ADDRESS;
  Address::FromString("12:34:56:78:9a:bc", report.address_);
  std::vector<GapData> gap_data{};
  GapData data_item{};
  data_item.data_type_ = GapDataType::FLAGS;
  data_item.data_ = {0x34};
  gap_data.push_back(data_item);
  data_item.data_type_ = GapDataType::COMPLETE_LOCAL_NAME;
  data_item.data_ = {'r', 'a', 'n', 'd', 'o', 'm', ' ', 'd', 'e', 'v', 'i', 'c', 'e'};
  gap_data.push_back(data_item);
  std::vector<uint8_t> advertising_data = {};
  for (auto data : gap_data) {
    advertising_data.push_back((uint8_t)data.size() - 1);
    advertising_data.push_back((uint8_t)data.data_type_);
    advertising_data.insert(advertising_data.end(), data.data_.begin(), data.data_.end());
  }

  report.advertising_data_ = advertising_data;
  std::vector<LengthAndData> adv_data{};
  LengthAndData data_item{};
  data_item.data_.push_back(static_cast<uint8_t>(GapDataType::FLAGS));
  data_item.data_.push_back(0x34);
  adv_data.push_back(data_item);
  data_item.data_.push_back(static_cast<uint8_t>(GapDataType::COMPLETE_LOCAL_NAME));
  for (auto octet : {'r', 'a', 'n', 'd', 'o', 'm', ' ', 'd', 'e', 'v', 'i', 'c', 'e'}) {
    data_item.data_.push_back(octet);
  }
  adv_data.push_back(data_item);

  report.advertising_data_ = adv_data;

  EXPECT_CALL(mock_callbacks_, OnScanResult);

  test_hci_layer_->IncomingLeMetaEvent(LeExtendedAdvertisingReportBuilder::Create({report}));
}

TEST_F(LeExtendedScanningManagerTest, drop_insignificant_bytes_test) {
  // Enable scan
  test_hci_layer_->SetCommandFuture(2);
  le_scanning_manager->Scan(true);
  ASSERT_EQ(param_opcode_, test_hci_layer_->GetCommand().GetOpCode());
  test_hci_layer_->IncomingEvent(LeSetExtendedScanParametersCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS));
  ASSERT_EQ(enable_opcode_, test_hci_layer_->GetCommand().GetOpCode());
  test_hci_layer_->IncomingEvent(LeSetExtendedScanEnableCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS));

  // Prepare advertisement report
  LeExtendedAdvertisingResponse advertisement_report{};
  advertisement_report.connectable_ = 1;
  advertisement_report.scannable_ = 1;
  advertisement_report.address_type_ = DirectAdvertisingAddressType::PUBLIC_DEVICE_ADDRESS;
  Address::FromString("12:34:56:78:9a:bc", advertisement_report.address_);
  std::vector<LengthAndData> adv_data{};
  LengthAndData flags_data{};
  flags_data.data_.push_back(static_cast<uint8_t>(GapDataType::FLAGS));
  flags_data.data_.push_back(0x34);
  adv_data.push_back(flags_data);
  LengthAndData name_data{};
  name_data.data_.push_back(static_cast<uint8_t>(GapDataType::COMPLETE_LOCAL_NAME));
  for (auto octet : "random device") {
    name_data.data_.push_back(octet);
  }
  adv_data.push_back(name_data);
  for (int i = 0; i != 5; ++i) {
    adv_data.push_back({});  // pad with a few insigificant zeros
  }
  advertisement_report.advertising_data_ = adv_data;

  // Prepare scan response report
  auto scan_response_report = advertisement_report;
  scan_response_report.scan_response_ = true;
  LengthAndData extra_data{};
  extra_data.data_.push_back(static_cast<uint8_t>(GapDataType::MANUFACTURER_SPECIFIC_DATA));
  for (auto octet : "manufacturer specific") {
    extra_data.data_.push_back(octet);
  }
  adv_data = {extra_data};
  for (int i = 0; i != 5; ++i) {
    adv_data.push_back({});  // pad with a few insigificant zeros
  }
  scan_response_report.advertising_data_ = adv_data;

  // We expect the two reports to be concatenated, excluding the zero-padding
  auto result = std::vector<uint8_t>();
  packet::BitInserter it(result);
  flags_data.Serialize(it);
  name_data.Serialize(it);
  extra_data.Serialize(it);
  EXPECT_CALL(mock_callbacks_, OnScanResult(_, _, _, _, _, _, _, _, _, result));

  // Send both reports
  test_hci_layer_->IncomingLeMetaEvent(LeExtendedAdvertisingReportBuilder::Create({advertisement_report}));
  test_hci_layer_->IncomingLeMetaEvent(LeExtendedAdvertisingReportBuilder::Create({scan_response_report}));
}

}  // namespace
}  // namespace hci
}  // namespace bluetooth
+3 −3
Original line number Diff line number Diff line
@@ -2128,7 +2128,7 @@ void LinkLayerController::IncomingLeScanResponsePacket(

  if (le_scan_enable_ == bluetooth::hci::OpCode::LE_SET_EXTENDED_SCAN_ENABLE &&
      IsLeEventUnmasked(SubeventCode::EXTENDED_ADVERTISING_REPORT)) {
    bluetooth::hci::LeExtendedAdvertisingResponse report{};
    bluetooth::hci::LeExtendedAdvertisingResponseRaw report{};
    report.address_ = incoming.GetSourceAddress();
    report.address_type_ =
        static_cast<bluetooth::hci::DirectAdvertisingAddressType>(address_type);
@@ -2141,8 +2141,8 @@ void LinkLayerController::IncomingLeScanResponsePacket(
    report.tx_power_ = 0x7F;
    report.advertising_data_ = ad;
    report.rssi_ = rssi;
    send_event_(
        bluetooth::hci::LeExtendedAdvertisingReportBuilder::Create({report}));
    send_event_(bluetooth::hci::LeExtendedAdvertisingReportRawBuilder::Create(
        {report}));
  }
}