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

Commit 6ef6544a authored by Myles Watson's avatar Myles Watson
Browse files

RootCanal: Add an Rssi wrapper packet

External simulators could wrap packets to change
their RSSI.  For now, the packets that support this are
LeAdvertisement LeScanResponse and Inquiry.

Bug: 217583108
Test: cert/run
Tag: #feature
Change-Id: I443d80d9f79b2b29a788d2d523cc9c78f0563c26
parent 773ebd5d
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -2416,7 +2416,8 @@ void DualModeController::LeSetExtendedAdvertisingParameters(
      command_view.GetPrimaryAdvertisingIntervalMax(),
      command_view.GetAdvertisingEventLegacyProperties(),
      command_view.GetOwnAddressType(), command_view.GetPeerAddressType(),
      command_view.GetPeerAddress(), command_view.GetAdvertisingFilterPolicy());
      command_view.GetPeerAddress(), command_view.GetAdvertisingFilterPolicy(),
      command_view.GetAdvertisingTxPower());

  send_event_(
      bluetooth::hci::LeSetExtendedAdvertisingParametersCompleteBuilder::Create(
+36 −14
Original line number Diff line number Diff line
@@ -33,21 +33,23 @@ void LeAdvertiser::Initialize(AddressWithType address,
  advertisement_ = advertisement;
  scan_response_ = scan_response;
  interval_ = interval;
  tx_power_ = kTxPowerUnavailable;
}

void LeAdvertiser::InitializeExtended(
    AddressType address_type, AddressWithType peer_address,
    LeScanningFilterPolicy filter_policy,
    model::packets::AdvertisementType type,
    std::chrono::steady_clock::duration interval) {
    std::chrono::steady_clock::duration interval, uint8_t tx_power) {
  address_ = AddressWithType(address_.GetAddress(), address_type);
  peer_address_ = peer_address;
  filter_policy_ = filter_policy;
  type_ = type;
  interval_ = interval;
  LOG_INFO("%s -> %s type = %hhx interval = %d ms", address_.ToString().c_str(),
           peer_address.ToString().c_str(), type_,
           static_cast<int>(interval_.count()));
  tx_power_ = tx_power;
  LOG_INFO("%s -> %s type = %hhx interval = %d ms tx_power = 0x%hhx",
           address_.ToString().c_str(), peer_address.ToString().c_str(), type_,
           static_cast<int>(interval_.count()), tx_power);
}

void LeAdvertiser::Clear() {
@@ -110,7 +112,7 @@ bool LeAdvertiser::IsConnectable() const {

uint8_t LeAdvertiser::GetNumAdvertisingEvents() const { return num_events_; }

std::unique_ptr<model::packets::LeAdvertisementBuilder>
std::unique_ptr<model::packets::LinkLayerPacketBuilder>
LeAdvertiser::GetAdvertisement(std::chrono::steady_clock::time_point now) {
  if (!enabled_) {
    return nullptr;
@@ -127,13 +129,23 @@ LeAdvertiser::GetAdvertisement(std::chrono::steady_clock::time_point now) {

  last_le_advertisement_ = now;
  num_events_ += (num_events_ < 255 ? 1 : 0);
  if (tx_power_ == kTxPowerUnavailable) {
    return model::packets::LeAdvertisementBuilder::Create(
        address_.GetAddress(), peer_address_.GetAddress(),
        static_cast<model::packets::AddressType>(address_.GetAddressType()),
        type_, advertisement_);
  } else {
    uint8_t tx_power_jittered = 2 + tx_power_ - (num_events_ & 0x03);
    return model::packets::RssiWrapperBuilder::Create(
        address_.GetAddress(), peer_address_.GetAddress(), tx_power_jittered,
        model::packets::LeAdvertisementBuilder::Create(
            address_.GetAddress(), peer_address_.GetAddress(),
            static_cast<model::packets::AddressType>(address_.GetAddressType()),
            type_, advertisement_));
  }
}

std::unique_ptr<model::packets::LeScanResponseBuilder>
std::unique_ptr<model::packets::LinkLayerPacketBuilder>
LeAdvertiser::GetScanResponse(bluetooth::hci::Address scanned,
                              bluetooth::hci::Address scanner) {
  if (scanned != address_.GetAddress() || !enabled_) {
@@ -153,10 +165,20 @@ LeAdvertiser::GetScanResponse(bluetooth::hci::Address scanned,
    case bluetooth::hci::LeScanningFilterPolicy::ACCEPT_ALL:
      break;
  }
  if (tx_power_ == kTxPowerUnavailable) {
    return model::packets::LeScanResponseBuilder::Create(
        address_.GetAddress(), peer_address_.GetAddress(),
        static_cast<model::packets::AddressType>(address_.GetAddressType()),
      model::packets::AdvertisementType::SCAN_RESPONSE, scan_response_);
        type_, advertisement_);
  } else {
    uint8_t tx_power_jittered = 2 + tx_power_ - (num_events_ & 0x03);
    return model::packets::RssiWrapperBuilder::Create(
        address_.GetAddress(), peer_address_.GetAddress(), tx_power_jittered,
        model::packets::LeScanResponseBuilder::Create(
            address_.GetAddress(), peer_address_.GetAddress(),
            static_cast<model::packets::AddressType>(address_.GetAddressType()),
            type_, advertisement_));
  }
}

}  // namespace test_vendor_lib
+6 −3
Original line number Diff line number Diff line
@@ -44,7 +44,8 @@ class LeAdvertiser {
                          bluetooth::hci::AddressWithType peer_address,
                          bluetooth::hci::LeScanningFilterPolicy filter_policy,
                          model::packets::AdvertisementType type,
                          std::chrono::steady_clock::duration interval);
                          std::chrono::steady_clock::duration interval,
                          uint8_t tx_power);

  void SetAddress(bluetooth::hci::Address address);

@@ -52,10 +53,10 @@ class LeAdvertiser {

  void SetScanResponse(const std::vector<uint8_t>& data);

  std::unique_ptr<model::packets::LeAdvertisementBuilder> GetAdvertisement(
  std::unique_ptr<model::packets::LinkLayerPacketBuilder> GetAdvertisement(
      std::chrono::steady_clock::time_point);

  std::unique_ptr<model::packets::LeScanResponseBuilder> GetScanResponse(
  std::unique_ptr<model::packets::LinkLayerPacketBuilder> GetScanResponse(
      bluetooth::hci::Address scanned_address,
      bluetooth::hci::Address scanner_address);

@@ -87,6 +88,8 @@ class LeAdvertiser {
  std::vector<uint8_t> scan_response_;
  std::chrono::steady_clock::duration interval_{};
  std::chrono::steady_clock::time_point ending_time_{};
  static constexpr uint8_t kTxPowerUnavailable = 0x7f;
  uint8_t tx_power_{kTxPowerUnavailable};
  uint8_t num_events_{0};
  bool extended_{false};
  bool enabled_{false};
+44 −16
Original line number Diff line number Diff line
@@ -51,6 +51,17 @@ static uint8_t GetRssi() {
  return -(rssi);
}

void LinkLayerController::SendLeLinkLayerPacketWithRssi(
    Address source, Address dest, uint8_t rssi,
    std::unique_ptr<model::packets::LinkLayerPacketBuilder> packet) {
  std::shared_ptr<model::packets::RssiWrapperBuilder> shared_packet =
      model::packets::RssiWrapperBuilder::Create(source, dest, rssi,
                                                 std::move(packet));
  ScheduleTask(kNoDelayMs, [this, shared_packet]() {
    send_to_remote_(shared_packet, Phy::Type::LOW_ENERGY);
  });
}

void LinkLayerController::SendLeLinkLayerPacket(
    std::unique_ptr<model::packets::LinkLayerPacketBuilder> packet) {
  std::shared_ptr<model::packets::LinkLayerPacketBuilder> shared_packet =
@@ -218,6 +229,20 @@ ErrorCode LinkLayerController::SendScoToRemote(
void LinkLayerController::IncomingPacket(
    model::packets::LinkLayerPacketView incoming) {
  ASSERT(incoming.IsValid());
  if (incoming.GetType() == PacketType::RSSI_WRAPPER) {
    auto rssi_wrapper = model::packets::RssiWrapperView::Create(incoming);
    ASSERT(rssi_wrapper.IsValid());
    auto wrapped =
        model::packets::LinkLayerPacketView::Create(rssi_wrapper.GetPayload());
    IncomingPacketWithRssi(wrapped, rssi_wrapper.GetRssi());
  } else {
    IncomingPacketWithRssi(incoming, GetRssi());
  }
}

void LinkLayerController::IncomingPacketWithRssi(
    model::packets::LinkLayerPacketView incoming, uint8_t rssi) {
  ASSERT(incoming.IsValid());
  auto destination_address = incoming.GetDestinationAddress();

  // Match broadcasts
@@ -278,7 +303,7 @@ void LinkLayerController::IncomingPacket(
      break;
    case model::packets::PacketType::INQUIRY:
      if (inquiry_scans_enabled_) {
        IncomingInquiryPacket(incoming);
        IncomingInquiryPacket(incoming, rssi);
      }
      break;
    case model::packets::PacketType::INQUIRY_RESPONSE:
@@ -307,7 +332,7 @@ void LinkLayerController::IncomingPacket(
      break;
    case model::packets::PacketType::LE_ADVERTISEMENT:
      if (le_scan_enable_ != bluetooth::hci::OpCode::NONE || le_connect_) {
        IncomingLeAdvertisementPacket(incoming);
        IncomingLeAdvertisementPacket(incoming, rssi);
      }
      break;
    case model::packets::PacketType::LE_CONNECT:
@@ -341,7 +366,7 @@ void LinkLayerController::IncomingPacket(
    case model::packets::PacketType::LE_SCAN_RESPONSE:
      if (le_scan_enable_ != bluetooth::hci::OpCode::NONE &&
          le_scan_type_ == 1) {
        IncomingLeScanResponsePacket(incoming);
        IncomingLeScanResponsePacket(incoming, rssi);
      }
      break;
    case model::packets::PacketType::PAGE:
@@ -403,6 +428,9 @@ void LinkLayerController::IncomingPacket(
    case (model::packets::PacketType::READ_CLOCK_OFFSET_RESPONSE):
      IncomingReadClockOffsetResponse(incoming);
      break;
    case (model::packets::PacketType::RSSI_WRAPPER):
      LOG_ERROR("Dropping double-wrapped RSSI packet");
      break;
    case model::packets::PacketType::SCO_CONNECTION_REQUEST:
      IncomingScoConnectionRequest(incoming);
      break;
@@ -722,7 +750,7 @@ void LinkLayerController::IncomingEncryptConnectionResponse(
}

void LinkLayerController::IncomingInquiryPacket(
    model::packets::LinkLayerPacketView incoming) {
    model::packets::LinkLayerPacketView incoming, uint8_t rssi) {
  auto inquiry = model::packets::InquiryView::Create(incoming);
  ASSERT(inquiry.IsValid());

@@ -741,7 +769,7 @@ void LinkLayerController::IncomingInquiryPacket(
              properties_.GetAddress(), peer,
              properties_.GetPageScanRepetitionMode(),
              properties_.GetClassOfDevice(), properties_.GetClockOffset(),
              GetRssi()));
              rssi));
    } break;
    case (model::packets::InquiryType::EXTENDED): {
      SendLinkLayerPacket(
@@ -749,7 +777,7 @@ void LinkLayerController::IncomingInquiryPacket(
              properties_.GetAddress(), peer,
              properties_.GetPageScanRepetitionMode(),
              properties_.GetClassOfDevice(), properties_.GetClockOffset(),
              GetRssi(), properties_.GetExtendedInquiryData()));
              rssi, properties_.GetExtendedInquiryData()));

    } break;
    default:
@@ -1251,7 +1279,7 @@ static Address generate_rpa(
}

void LinkLayerController::IncomingLeAdvertisementPacket(
    model::packets::LinkLayerPacketView incoming) {
    model::packets::LinkLayerPacketView incoming, uint8_t rssi) {
  // TODO: Handle multiple advertisements per packet.

  Address address = incoming.GetSourceAddress();
@@ -1273,7 +1301,7 @@ void LinkLayerController::IncomingLeAdvertisementPacket(
    raw_builder_ptr->AddAddress(address);
    raw_builder_ptr->AddOctets1(ad.size());
    raw_builder_ptr->AddOctets(ad);
    raw_builder_ptr->AddOctets1(GetRssi());
    raw_builder_ptr->AddOctets1(rssi);
    if (properties_.IsUnmasked(EventCode::LE_META_EVENT)) {
      send_event_(bluetooth::hci::EventBuilder::Create(
          bluetooth::hci::EventCode::LE_META_EVENT,
@@ -1313,7 +1341,7 @@ void LinkLayerController::IncomingLeAdvertisementPacket(
    raw_builder_ptr->AddOctets1(0);     // Secondary_PHY
    raw_builder_ptr->AddOctets1(0xFF);  // Advertising_SID - not provided
    raw_builder_ptr->AddOctets1(0x7F);  // Tx_Power - Not available
    raw_builder_ptr->AddOctets1(GetRssi());
    raw_builder_ptr->AddOctets1(rssi);
    raw_builder_ptr->AddOctets2(0);  // Periodic_Advertising_Interval - None
    raw_builder_ptr->AddOctets1(0);  // Direct_Address_Type - PUBLIC
    raw_builder_ptr->AddAddress(Address::kEmpty);  // Direct_Address
@@ -1801,7 +1829,7 @@ void LinkLayerController::IncomingLeScanPacket(
}

void LinkLayerController::IncomingLeScanResponsePacket(
    model::packets::LinkLayerPacketView incoming) {
    model::packets::LinkLayerPacketView incoming, uint8_t rssi) {
  auto scan_response = model::packets::LeScanResponseView::Create(incoming);
  ASSERT(scan_response.IsValid());
  vector<uint8_t> ad = scan_response.GetData();
@@ -1818,7 +1846,7 @@ void LinkLayerController::IncomingLeScanResponsePacket(
    report.address_type_ =
        static_cast<bluetooth::hci::AddressType>(address_type);
    report.advertising_data_ = scan_response.GetData();
    report.rssi_ = GetRssi();
    report.rssi_ = rssi;

    if (properties_.IsUnmasked(EventCode::LE_META_EVENT) &&
        properties_.GetLeEventSupported(
@@ -1844,7 +1872,7 @@ void LinkLayerController::IncomingLeScanResponsePacket(
    report.advertising_sid_ = 0xFF;
    report.tx_power_ = 0x7F;
    report.advertising_data_ = ad;
    report.rssi_ = GetRssi();
    report.rssi_ = rssi;
    send_event_(
        bluetooth::hci::LeExtendedAdvertisingReportBuilder::Create({report}));
  }
@@ -2979,7 +3007,7 @@ ErrorCode LinkLayerController::SetLeExtendedAdvertisingParameters(
    bluetooth::hci::LegacyAdvertisingProperties type,
    bluetooth::hci::OwnAddressType own_address_type,
    bluetooth::hci::PeerAddressType peer_address_type, Address peer,
    bluetooth::hci::AdvertisingFilterPolicy filter_policy) {
    bluetooth::hci::AdvertisingFilterPolicy filter_policy, uint8_t tx_power) {
  model::packets::AdvertisementType ad_type;
  switch (type) {
    case bluetooth::hci::LegacyAdvertisingProperties::ADV_IND:
@@ -3054,9 +3082,9 @@ ErrorCode LinkLayerController::SetLeExtendedAdvertisingParameters(
      break;
  }

  advertisers_[set].InitializeExtended(own_address_address_type, peer_address,
                                       scanning_filter_policy, ad_type,
                                       std::chrono::milliseconds(interval_ms));
  advertisers_[set].InitializeExtended(
      own_address_address_type, peer_address, scanning_filter_policy, ad_type,
      std::chrono::milliseconds(interval_ms), tx_power);

  return ErrorCode::SUCCESS;
}
+13 −5
Original line number Diff line number Diff line
@@ -97,6 +97,9 @@ class LinkLayerController {
 private:
  void SendDisconnectionCompleteEvent(uint16_t handle, uint8_t reason);

  void IncomingPacketWithRssi(model::packets::LinkLayerPacketView incoming,
                              uint8_t rssi);

 public:
  void IncomingPacket(model::packets::LinkLayerPacketView incoming);

@@ -156,7 +159,7 @@ class LinkLayerController {
      bluetooth::hci::LegacyAdvertisingProperties type,
      bluetooth::hci::OwnAddressType own_address_type,
      bluetooth::hci::PeerAddressType peer_address_type, Address peer,
      bluetooth::hci::AdvertisingFilterPolicy filter_policy);
      bluetooth::hci::AdvertisingFilterPolicy filter_policy, uint8_t tx_power);
  ErrorCode LeRemoveAdvertisingSet(uint8_t set);
  ErrorCode LeClearAdvertisingSets();
  void LeConnectionUpdateComplete(uint16_t handle, uint16_t interval_min,
@@ -376,6 +379,9 @@ class LinkLayerController {
  void HandleIso(bluetooth::hci::IsoView iso);

 protected:
  void SendLeLinkLayerPacketWithRssi(
      Address source, Address dest, uint8_t rssi,
      std::unique_ptr<model::packets::LinkLayerPacketBuilder> packet);
  void SendLeLinkLayerPacket(
      std::unique_ptr<model::packets::LinkLayerPacketBuilder> packet);
  void SendLinkLayerPacket(
@@ -386,7 +392,8 @@ class LinkLayerController {
  void IncomingEncryptConnection(model::packets::LinkLayerPacketView packet);
  void IncomingEncryptConnectionResponse(
      model::packets::LinkLayerPacketView packet);
  void IncomingInquiryPacket(model::packets::LinkLayerPacketView packet);
  void IncomingInquiryPacket(model::packets::LinkLayerPacketView packet,
                             uint8_t rssi);
  void IncomingInquiryResponsePacket(
      model::packets::LinkLayerPacketView packet);
  void IncomingIoCapabilityRequestPacket(
@@ -402,8 +409,8 @@ class LinkLayerController {
      model::packets::LinkLayerPacketView packet);
  void IncomingKeypressNotificationPacket(
      model::packets::LinkLayerPacketView packet);
  void IncomingLeAdvertisementPacket(
      model::packets::LinkLayerPacketView packet);
  void IncomingLeAdvertisementPacket(model::packets::LinkLayerPacketView packet,
                                     uint8_t rssi);
  void IncomingLeConnectPacket(model::packets::LinkLayerPacketView packet);
  void IncomingLeConnectCompletePacket(
      model::packets::LinkLayerPacketView packet);
@@ -418,7 +425,8 @@ class LinkLayerController {
  void IncomingLeReadRemoteFeaturesResponse(
      model::packets::LinkLayerPacketView packet);
  void IncomingLeScanPacket(model::packets::LinkLayerPacketView packet);
  void IncomingLeScanResponsePacket(model::packets::LinkLayerPacketView packet);
  void IncomingLeScanResponsePacket(model::packets::LinkLayerPacketView packet,
                                    uint8_t rssi);
  void IncomingPagePacket(model::packets::LinkLayerPacketView packet);
  void IncomingPageRejectPacket(model::packets::LinkLayerPacketView packet);
  void IncomingPageResponsePacket(model::packets::LinkLayerPacketView packet);
Loading