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

Commit 0bd447c2 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "RootCanal: Add multiple advertisers"

parents f7d9e63d 509f3f52
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@ cc_library_static {
        "model/controller/acl_connection.cc",
        "model/controller/acl_connection_handler.cc",
        "model/controller/dual_mode_controller.cc",
        "model/controller/le_advertiser.cc",
        "model/controller/link_layer_controller.cc",
        "model/controller/security_manager.cc",
        "model/devices/beacon.cc",
+96 −17
Original line number Diff line number Diff line
@@ -35,6 +35,9 @@ namespace test_vendor_lib {
constexpr char DualModeController::kControllerPropertiesFile[];
constexpr uint16_t DualModeController::kSecurityManagerNumKeys;
constexpr uint16_t kNumCommandPackets = 0x01;
constexpr uint16_t kLeMaximumAdvertisingDataLength = 256;
constexpr uint16_t kLeMaximumDataLength = 64;
constexpr uint16_t kLeMaximumDataTime = 0x148;

// Device methods.
void DualModeController::Initialize(const std::vector<std::string>& args) {
@@ -217,6 +220,12 @@ DualModeController::DualModeController(const std::string& properties_filename, u
              LeSetExtendedAdvertisingScanResponse);
  SET_HANDLER(OpCode::LE_SET_EXTENDED_ADVERTISING_ENABLE,
              LeSetExtendedAdvertisingEnable);
  SET_HANDLER(OpCode::LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH,
              LeReadMaximumAdvertisingDataLength);
  SET_HANDLER(OpCode::LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS,
              LeReadNumberOfSupportedAdvertisingSets);
  SET_HANDLER(OpCode::LE_REMOVE_ADVERTISING_SET, LeRemoveAdvertisingSet);
  SET_HANDLER(OpCode::LE_CLEAR_ADVERTISING_SETS, LeClearAdvertisingSets);
  SET_HANDLER(OpCode::LE_READ_REMOTE_FEATURES, LeReadRemoteFeatures);
  SET_HANDLER(OpCode::READ_REMOTE_VERSION_INFORMATION,
              ReadRemoteVersionInformation);
@@ -228,6 +237,7 @@ DualModeController::DualModeController(const std::string& properties_filename, u
              LeRemoveDeviceFromResolvingList);
  SET_HANDLER(OpCode::LE_CLEAR_RESOLVING_LIST, LeClearResolvingList);
  SET_HANDLER(OpCode::LE_READ_RESOLVING_LIST_SIZE, LeReadResolvingListSize);
  SET_HANDLER(OpCode::LE_READ_MAXIMUM_DATA_LENGTH, LeReadMaximumDataLength);
  SET_HANDLER(OpCode::LE_SET_EXTENDED_SCAN_PARAMETERS,
              LeSetExtendedScanParameters);
  SET_HANDLER(OpCode::LE_SET_EXTENDED_SCAN_ENABLE, LeSetExtendedScanEnable);
@@ -1427,12 +1437,18 @@ void DualModeController::LeSetAdvertisingParameters(CommandPacketView command) {
  auto command_view = gd_hci::LeSetAdvertisingParametersView::Create(
      gd_hci::LeAdvertisingCommandView::Create(command));
  ASSERT(command_view.IsValid());
  auto peer_address = command_view.GetPeerAddress();
  auto type = command_view.GetType();
  if (type != bluetooth::hci::AdvertisingType::ADV_DIRECT_IND &&
      type != bluetooth::hci::AdvertisingType::ADV_DIRECT_IND_LOW) {
    peer_address = Address::kEmpty;
  }
  properties_.SetLeAdvertisingParameters(
      command_view.GetIntervalMin(), command_view.GetIntervalMax(),
      static_cast<uint8_t>(command_view.GetType()),
      static_cast<uint8_t>(type),
      static_cast<uint8_t>(command_view.GetOwnAddressType()),
      static_cast<uint8_t>(command_view.GetPeerAddressType()),
      command_view.GetPeerAddress(), command_view.GetChannelMap(),
      static_cast<uint8_t>(command_view.GetPeerAddressType()), peer_address,
      command_view.GetChannelMap(),
      static_cast<uint8_t>(command_view.GetFilterPolicy()));

  auto packet =
@@ -1475,9 +1491,8 @@ void DualModeController::LeSetAdvertisingEnable(CommandPacketView command) {
  ASSERT(command_view.IsValid());
  auto status = link_layer_controller_.SetLeAdvertisingEnable(
      command_view.GetAdvertisingEnable() == gd_hci::Enable::ENABLED);
  auto packet = bluetooth::hci::LeSetAdvertisingEnableCompleteBuilder::Create(
      kNumCommandPackets, status);
  send_event_(std::move(packet));
  send_event_(bluetooth::hci::LeSetAdvertisingEnableCompleteBuilder::Create(
      kNumCommandPackets, status));
}

void DualModeController::LeSetScanParameters(CommandPacketView command) {
@@ -1690,6 +1705,19 @@ void DualModeController::LeReadResolvingListSize(CommandPacketView command) {
  send_event_(std::move(packet));
}

void DualModeController::LeReadMaximumDataLength(CommandPacketView command) {
  auto command_view = gd_hci::LeReadMaximumDataLengthView::Create(
      gd_hci::LeSecurityCommandView::Create(command));
  ASSERT(command_view.IsValid());
  bluetooth::hci::LeMaximumDataLength data_length;
  data_length.supported_max_rx_octets_ = kLeMaximumDataLength;
  data_length.supported_max_rx_time_ = kLeMaximumDataTime;
  data_length.supported_max_tx_octets_ = kLeMaximumDataLength + 10;
  data_length.supported_max_tx_time_ = kLeMaximumDataTime + 10;
  send_event_(bluetooth::hci::LeReadMaximumDataLengthCompleteBuilder::Create(
      kNumCommandPackets, ErrorCode::SUCCESS, data_length));
}

void DualModeController::LeAddDeviceToResolvingList(CommandPacketView command) {
  auto command_view = gd_hci::LeAddDeviceToResolvingListView::Create(
      gd_hci::LeSecurityCommandView::Create(command));
@@ -1921,7 +1949,9 @@ void DualModeController::LeSetExtendedAdvertisingRandomAddress(
  auto command_view = gd_hci::LeSetExtendedAdvertisingRandomAddressView::Create(
      gd_hci::LeAdvertisingCommandView::Create(command));
  ASSERT(command_view.IsValid());
  properties_.SetLeAddress(command_view.GetAdvertisingRandomAddress());
  link_layer_controller_.SetLeExtendedAddress(
      command_view.GetAdvertisingHandle(),
      command_view.GetAdvertisingRandomAddress());
  send_event_(
      bluetooth::hci::LeSetExtendedAdvertisingRandomAddressCompleteBuilder::
          Create(kNumCommandPackets, ErrorCode::SUCCESS));
@@ -1934,15 +1964,13 @@ void DualModeController::LeSetExtendedAdvertisingParameters(
          gd_hci::LeAdvertisingCommandView::Create(command));
  // TODO: Support non-legacy parameters
  ASSERT(command_view.IsValid());
  properties_.SetLeAdvertisingParameters(
  link_layer_controller_.SetLeExtendedAdvertisingParameters(
      command_view.GetAdvertisingHandle(),
      command_view.GetPrimaryAdvertisingIntervalMin(),
      command_view.GetPrimaryAdvertisingIntervalMax(),
      static_cast<uint8_t>(bluetooth::hci::AdvertisingType::ADV_IND),
      static_cast<uint8_t>(command_view.GetOwnAddressType()),
      static_cast<uint8_t>(command_view.GetPeerAddressType()),
      command_view.GetPeerAddress(),
      command_view.GetPrimaryAdvertisingChannelMap(),
      static_cast<uint8_t>(command_view.GetAdvertisingFilterPolicy()));
      command_view.GetAdvertisingEventLegacyProperties(),
      command_view.GetOwnAddressType(), command_view.GetPeerAddressType(),
      command_view.GetPeerAddress(), command_view.GetAdvertisingFilterPolicy());

  send_event_(
      bluetooth::hci::LeSetExtendedAdvertisingParametersCompleteBuilder::Create(
@@ -1957,7 +1985,9 @@ void DualModeController::LeSetExtendedAdvertisingData(
  auto raw_command_view = gd_hci::LeSetExtendedAdvertisingDataRawView::Create(
      gd_hci::LeAdvertisingCommandView::Create(command));
  ASSERT(raw_command_view.IsValid());
  properties_.SetLeAdvertisement(raw_command_view.GetAdvertisingData());
  link_layer_controller_.SetLeExtendedAdvertisingData(
      command_view.GetAdvertisingHandle(),
      raw_command_view.GetAdvertisingData());
  auto packet =
      bluetooth::hci::LeSetExtendedAdvertisingDataCompleteBuilder::Create(
          kNumCommandPackets, ErrorCode::SUCCESS);
@@ -1981,13 +2011,62 @@ void DualModeController::LeSetExtendedAdvertisingEnable(
  auto command_view = gd_hci::LeSetExtendedAdvertisingEnableView::Create(
      gd_hci::LeAdvertisingCommandView::Create(command));
  ASSERT(command_view.IsValid());
  auto status = link_layer_controller_.SetLeAdvertisingEnable(
      command_view.GetEnable() == gd_hci::Enable::ENABLED);
  auto enabled_sets = command_view.GetEnabledSets();
  ErrorCode status = ErrorCode::SUCCESS;
  if (enabled_sets.size() == 0) {
    link_layer_controller_.LeDisableAdvertisingSets();
  } else {
    status = link_layer_controller_.SetLeExtendedAdvertisingEnable(
        command_view.GetEnable(), command_view.GetEnabledSets());
  }
  send_event_(
      bluetooth::hci::LeSetExtendedAdvertisingEnableCompleteBuilder::Create(
          kNumCommandPackets, status));
}

void DualModeController::LeReadMaximumAdvertisingDataLength(
    CommandPacketView command) {
  auto command_view = gd_hci::LeReadMaximumAdvertisingDataLengthView::Create(
      gd_hci::LeAdvertisingCommandView::Create(command));
  ASSERT(command_view.IsValid());
  send_event_(
      bluetooth::hci::LeReadMaximumAdvertisingDataLengthCompleteBuilder::Create(
          kNumCommandPackets, ErrorCode::SUCCESS,
          kLeMaximumAdvertisingDataLength));
}

void DualModeController::LeReadNumberOfSupportedAdvertisingSets(
    CommandPacketView command) {
  auto command_view =
      gd_hci::LeReadNumberOfSupportedAdvertisingSetsView::Create(
          gd_hci::LeAdvertisingCommandView::Create(command));
  ASSERT(command_view.IsValid());
  send_event_(
      bluetooth::hci::LeReadNumberOfSupportedAdvertisingSetsCompleteBuilder::
          Create(
              kNumCommandPackets, ErrorCode::SUCCESS,
              link_layer_controller_.LeReadNumberOfSupportedAdvertisingSets()));
}

void DualModeController::LeRemoveAdvertisingSet(CommandPacketView command) {
  auto command_view = gd_hci::LeRemoveAdvertisingSetView::Create(
      gd_hci::LeAdvertisingCommandView::Create(command));
  ASSERT(command_view.IsValid());
  auto status = link_layer_controller_.LeRemoveAdvertisingSet(
      command_view.GetAdvertisingHandle());
  send_event_(bluetooth::hci::LeRemoveAdvertisingSetCompleteBuilder::Create(
      kNumCommandPackets, status));
}

void DualModeController::LeClearAdvertisingSets(CommandPacketView command) {
  auto command_view = gd_hci::LeClearAdvertisingSetsView::Create(
      gd_hci::LeAdvertisingCommandView::Create(command));
  ASSERT(command_view.IsValid());
  auto status = link_layer_controller_.LeClearAdvertisingSets();
  send_event_(bluetooth::hci::LeClearAdvertisingSetsCompleteBuilder::Create(
      kNumCommandPackets, status));
}

void DualModeController::LeExtendedScanParams(CommandPacketView command) {
  auto command_view = gd_hci::LeExtendedScanParamsView::Create(
      gd_hci::LeScanningCommandView::Create(command));
+15 −0
Original line number Diff line number Diff line
@@ -442,6 +442,9 @@ class DualModeController : public Device {
  // 7.8.41
  void LeReadResolvingListSize(CommandPacketView args);

  // 7.8.46
  void LeReadMaximumDataLength(CommandPacketView args);

  // 7.8.52
  void LeSetExtendedAdvertisingRandomAddress(CommandPacketView args);

@@ -457,6 +460,18 @@ class DualModeController : public Device {
  // 7.8.56
  void LeSetExtendedAdvertisingEnable(CommandPacketView args);

  // 7.8.57
  void LeReadMaximumAdvertisingDataLength(CommandPacketView args);

  // 7.8.58
  void LeReadNumberOfSupportedAdvertisingSets(CommandPacketView args);

  // 7.8.59
  void LeRemoveAdvertisingSet(CommandPacketView args);

  // 7.8.60
  void LeClearAdvertisingSets(CommandPacketView args);

  // 7.8.64
  void LeSetExtendedScanParameters(CommandPacketView args);

+147 −0
Original line number Diff line number Diff line
/*
 * Copyright 2020 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.
 */

#include "le_advertiser.h"

using namespace bluetooth::hci;

namespace test_vendor_lib {
void LeAdvertiser::Initialize(AddressWithType address,
                              AddressWithType peer_address,
                              LeScanningFilterPolicy filter_policy,
                              model::packets::AdvertisementType type,
                              const std::vector<uint8_t>& advertisement,
                              const std::vector<uint8_t>& scan_response,
                              std::chrono::steady_clock::duration interval) {
  address_ = address;
  peer_address_ = peer_address;
  filter_policy_ = filter_policy;
  type_ = type;
  advertisement_ = advertisement;
  scan_response_ = scan_response;
  interval_ = interval;
}

void LeAdvertiser::InitializeExtended(
    AddressType address_type, AddressWithType peer_address,
    LeScanningFilterPolicy filter_policy,
    model::packets::AdvertisementType type,
    std::chrono::steady_clock::duration interval) {
  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()));
}

void LeAdvertiser::Clear() {
  address_ = AddressWithType{};
  peer_address_ = AddressWithType{};
  filter_policy_ = LeScanningFilterPolicy::ACCEPT_ALL;
  type_ = model::packets::AdvertisementType::ADV_IND;
  advertisement_.clear();
  scan_response_.clear();
  interval_ = std::chrono::milliseconds(0);
  enabled_ = false;
}

void LeAdvertiser::SetAddress(Address address) {
  LOG_INFO("set address %s", address_.ToString().c_str());
  address_ = AddressWithType(address, address_.GetAddressType());
}

AddressWithType LeAdvertiser::GetAddress() const { return address_; }

void LeAdvertiser::SetData(const std::vector<uint8_t>& data) {
  advertisement_ = data;
}

void LeAdvertiser::Enable() {
  enabled_ = true;
  last_le_advertisement_ = std::chrono::steady_clock::now() - interval_;
  LOG_INFO("%s -> %s type = %hhx ad length %zu, scan length %zu",
           address_.ToString().c_str(), peer_address_.ToString().c_str(), type_,
           advertisement_.size(), scan_response_.size());
}

void LeAdvertiser::EnableExtended(
    std::chrono::steady_clock::duration duration) {
  last_le_advertisement_ = std::chrono::steady_clock::now();
  if (duration != std::chrono::milliseconds(0)) {
    ending_time_ = std::chrono::steady_clock::now() + duration;
  }
  enabled_ = true;
  LOG_INFO("%s -> %s type = %hhx ad length %zu, scan length %zu",
           address_.ToString().c_str(), peer_address_.ToString().c_str(), type_,
           advertisement_.size(), scan_response_.size());
}

void LeAdvertiser::Disable() { enabled_ = false; }

bool LeAdvertiser::IsEnabled() const { return enabled_; }

std::unique_ptr<model::packets::LeAdvertisementBuilder>
LeAdvertiser::GetAdvertisement(std::chrono::steady_clock::time_point now) {
  if (!enabled_) {
    return nullptr;
  }

  if (now - last_le_advertisement_ < interval_) {
    return nullptr;
  }

  if (last_le_advertisement_ < ending_time_ && ending_time_ < now) {
    enabled_ = false;
    return nullptr;
  }

  last_le_advertisement_ = now;
  return model::packets::LeAdvertisementBuilder::Create(
      address_.GetAddress(), peer_address_.GetAddress(),
      static_cast<model::packets::AddressType>(address_.GetAddressType()),
      type_, advertisement_);
}

std::unique_ptr<model::packets::LeScanResponseBuilder>
LeAdvertiser::GetScanResponse(bluetooth::hci::Address scanned,
                              bluetooth::hci::Address scanner) {
  if (scanned != address_.GetAddress() || !enabled_ || scan_response_.empty()) {
    return nullptr;
  }
  switch (filter_policy_) {
    case bluetooth::hci::LeScanningFilterPolicy::
        WHITE_LIST_AND_INITIATORS_IDENTITY:
    case bluetooth::hci::LeScanningFilterPolicy::WHITE_LIST_ONLY:
      LOG_WARN("ScanResponses don't handle white list filters");
      return nullptr;
    case bluetooth::hci::LeScanningFilterPolicy::CHECK_INITIATORS_IDENTITY:
      if (scanner != peer_address_.GetAddress()) {
        return nullptr;
      }
      break;
    case bluetooth::hci::LeScanningFilterPolicy::ACCEPT_ALL:
      break;
  }
  return model::packets::LeScanResponseBuilder::Create(
      address_.GetAddress(), peer_address_.GetAddress(),
      static_cast<model::packets::AddressType>(address_.GetAddressType()),
      model::packets::AdvertisementType::SCAN_RESPONSE, scan_response_);
}

}  // namespace test_vendor_lib
+86 −0
Original line number Diff line number Diff line
/*
 * Copyright 2020 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 <chrono>
#include <cstdint>
#include <memory>

#include "hci/address_with_type.h"
#include "hci/hci_packets.h"
#include "packets/link_layer_packets.h"

namespace test_vendor_lib {

// Track a single advertising instance
class LeAdvertiser {
 public:
  LeAdvertiser() = default;
  virtual ~LeAdvertiser() = default;

  void Initialize(bluetooth::hci::AddressWithType address,
                  bluetooth::hci::AddressWithType peer_address,
                  bluetooth::hci::LeScanningFilterPolicy filter_policy,
                  model::packets::AdvertisementType type,
                  const std::vector<uint8_t>& advertisement,
                  const std::vector<uint8_t>& scan_response,
                  std::chrono::steady_clock::duration interval);

  void InitializeExtended(bluetooth::hci::AddressType address_type,
                          bluetooth::hci::AddressWithType peer_address,
                          bluetooth::hci::LeScanningFilterPolicy filter_policy,
                          model::packets::AdvertisementType type,
                          std::chrono::steady_clock::duration interval);

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

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

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

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

  void Clear();

  void Disable();

  void Enable();

  void EnableExtended(std::chrono::steady_clock::duration duration);

  bool IsEnabled() const;

  bluetooth::hci::AddressWithType GetAddress() const;

 private:
  bluetooth::hci::AddressWithType address_{};
  bluetooth::hci::AddressWithType
      peer_address_{};  // For directed advertisements
  bluetooth::hci::LeScanningFilterPolicy filter_policy_{};
  model::packets::AdvertisementType type_{};
  std::vector<uint8_t> advertisement_;
  std::vector<uint8_t> scan_response_;
  std::chrono::steady_clock::duration interval_{};
  std::chrono::steady_clock::time_point ending_time_{};
  bool enabled_{false};
  std::chrono::steady_clock::time_point last_le_advertisement_;
};

}  // namespace test_vendor_lib
Loading