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

Commit 5a294e79 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge changes I759cbde6,I5db4372e

* changes:
  RootCanal: Rewrite LE connection logic
  RootCanal: Implement HCI parameter validation for LE connection commands
parents 4064ec51 0b51f53c
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -129,6 +129,9 @@ cc_test_host {
        "test/controller/le/le_remove_device_from_filter_accept_list_test.cc",
        "test/controller/le/le_add_device_to_resolving_list_test.cc",
        "test/controller/le/le_clear_resolving_list_test.cc",
        "test/controller/le/le_create_connection_test.cc",
        "test/controller/le/le_create_connection_cancel_test.cc",
        "test/controller/le/le_extended_create_connection_test.cc",
        "test/controller/le/le_remove_device_from_resolving_list_test.cc",
        "test/controller/le/le_set_address_resolution_enable_test.cc",
        "test/controller/le/le_set_advertising_parameters_test.cc",
+28 −75
Original line number Diff line number Diff line
@@ -229,7 +229,7 @@ DualModeController::DualModeController(const std::string& properties_filename,
  SET_SUPPORTED(CREATE_CONNECTION, CreateConnection);
  SET_SUPPORTED(CREATE_CONNECTION_CANCEL, CreateConnectionCancel);
  SET_SUPPORTED(DISCONNECT, Disconnect);
  SET_SUPPORTED(LE_CREATE_CONNECTION_CANCEL, LeConnectionCancel);
  SET_SUPPORTED(LE_CREATE_CONNECTION_CANCEL, LeCreateConnectionCancel);
  SET_SUPPORTED(LE_READ_FILTER_ACCEPT_LIST_SIZE, LeReadFilterAcceptListSize);
  SET_SUPPORTED(LE_CLEAR_FILTER_ACCEPT_LIST, LeClearFilterAcceptList);
  SET_SUPPORTED(LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST,
@@ -2195,38 +2195,31 @@ void DualModeController::LeCreateConnection(CommandView command) {
      gd_hci::LeConnectionManagementCommandView::Create(
          gd_hci::AclCommandView::Create(command)));
  ASSERT(command_view.IsValid());
  auto initiator_filter_policy = command_view.GetInitiatorFilterPolicy();

  link_layer_controller_.SetLeScanInterval(command_view.GetLeScanInterval());
  link_layer_controller_.SetLeScanWindow(command_view.GetLeScanWindow());
  link_layer_controller_.SetLeInitiatorFilterPolicy(initiator_filter_policy);

  if (initiator_filter_policy ==
      bluetooth::hci::InitiatorFilterPolicy::USE_PEER_ADDRESS) {
    // Connect list not used
    link_layer_controller_.SetLePeerAddress(AddressWithType{
        command_view.GetPeerAddress(), command_view.GetPeerAddressType()});
  }
  link_layer_controller_.SetLeConnectionOwnAddressType(
      command_view.GetOwnAddressType());
  link_layer_controller_.SetLeConnectionIntervalMin(
      command_view.GetConnIntervalMin());
  link_layer_controller_.SetLeConnectionIntervalMax(
      command_view.GetConnIntervalMax());
  link_layer_controller_.SetLeConnectionLatency(command_view.GetConnLatency());
  link_layer_controller_.SetLeSupervisionTimeout(
      command_view.GetSupervisionTimeout());
  link_layer_controller_.SetLeMinimumCeLength(
      command_view.GetMinimumCeLength());
  link_layer_controller_.SetLeMaximumCeLength(
  ErrorCode status = link_layer_controller_.LeCreateConnection(
      command_view.GetLeScanInterval(), command_view.GetLeScanWindow(),
      command_view.GetInitiatorFilterPolicy(),
      AddressWithType{
          command_view.GetPeerAddress(),
          command_view.GetPeerAddressType(),
      },
      command_view.GetOwnAddressType(), command_view.GetConnIntervalMin(),
      command_view.GetConnIntervalMax(), command_view.GetConnLatency(),
      command_view.GetSupervisionTimeout(), command_view.GetMinimumCeLength(),
      command_view.GetMaximumCeLength());

  auto status = link_layer_controller_.SetLeConnect(true, false);

  send_event_(bluetooth::hci::LeCreateConnectionStatusBuilder::Create(
      status, kNumCommandPackets));
}

void DualModeController::LeCreateConnectionCancel(CommandView command) {
  auto command_view = gd_hci::LeCreateConnectionCancelView::Create(
      gd_hci::LeConnectionManagementCommandView::Create(
          gd_hci::AclCommandView::Create(command)));
  ASSERT(command_view.IsValid());
  ErrorCode status = link_layer_controller_.LeCreateConnectionCancel();
  send_event_(bluetooth::hci::LeCreateConnectionCancelCompleteBuilder::Create(
      kNumCommandPackets, status));
}

void DualModeController::LeConnectionUpdate(CommandView command) {
  auto command_view = gd_hci::LeConnectionUpdateView::Create(
      gd_hci::LeConnectionManagementCommandView::Create(
@@ -2294,24 +2287,6 @@ void DualModeController::Disconnect(CommandView command) {
      status, kNumCommandPackets));
}

void DualModeController::LeConnectionCancel(CommandView command) {
  auto command_view = gd_hci::LeCreateConnectionCancelView::Create(
      gd_hci::LeConnectionManagementCommandView::Create(
          gd_hci::AclCommandView::Create(command)));
  ASSERT(command_view.IsValid());
  ErrorCode status = link_layer_controller_.SetLeConnect(false, false);
  send_event_(bluetooth::hci::LeCreateConnectionCancelCompleteBuilder::Create(
      kNumCommandPackets, status));

  send_event_(bluetooth::hci::LeConnectionCompleteBuilder::Create(
      ErrorCode::UNKNOWN_CONNECTION, kReservedHandle,
      bluetooth::hci::Role::CENTRAL,
      bluetooth::hci::AddressType::PUBLIC_DEVICE_ADDRESS,
      bluetooth::hci::Address(), 1 /* connection_interval */,
      2 /* connection_latency */, 3 /* supervision_timeout*/,
      static_cast<bluetooth::hci::ClockAccuracy>(0x00)));
}

void DualModeController::LeReadFilterAcceptListSize(CommandView command) {
  auto command_view = gd_hci::LeReadFilterAcceptListSizeView::Create(
      gd_hci::LeConnectionManagementCommandView::Create(
@@ -2474,35 +2449,13 @@ void DualModeController::LeExtendedCreateConnection(CommandView command) {
      gd_hci::LeConnectionManagementCommandView::Create(
          gd_hci::AclCommandView::Create(command)));
  ASSERT(command_view.IsValid());
  ASSERT_LOG(command_view.GetInitiatingPhys() == 1, "Only LE_1M is supported");
  auto params = command_view.GetPhyScanParameters();
  auto initiator_filter_policy = command_view.GetInitiatorFilterPolicy();

  link_layer_controller_.SetLeScanInterval(params[0].scan_interval_);
  link_layer_controller_.SetLeScanWindow(params[0].scan_window_);
  link_layer_controller_.SetLeInitiatorFilterPolicy(initiator_filter_policy);

  if (initiator_filter_policy ==
      gd_hci::InitiatorFilterPolicy::USE_PEER_ADDRESS) {
    link_layer_controller_.SetLePeerAddress(AddressWithType{
  ErrorCode status = link_layer_controller_.LeExtendedCreateConnection(
      command_view.GetInitiatorFilterPolicy(), command_view.GetOwnAddressType(),
      AddressWithType{
          command_view.GetPeerAddress(),
          command_view.GetPeerAddressType(),
    });
  }
  link_layer_controller_.SetLeConnectionOwnAddressType(
      command_view.GetOwnAddressType());
  link_layer_controller_.SetLeConnectionIntervalMin(
      params[0].conn_interval_min_);
  link_layer_controller_.SetLeConnectionIntervalMax(
      params[0].conn_interval_max_);
  link_layer_controller_.SetLeConnectionLatency(params[0].conn_latency_);
  link_layer_controller_.SetLeSupervisionTimeout(
      params[0].supervision_timeout_);
  link_layer_controller_.SetLeMinimumCeLength(params[0].min_ce_length_);
  link_layer_controller_.SetLeMaximumCeLength(params[0].max_ce_length_);

  auto status = link_layer_controller_.SetLeConnect(true, true);

      },
      command_view.GetInitiatingPhys(), command_view.GetPhyScanParameters());
  send_event_(bluetooth::hci::LeExtendedCreateConnectionStatusBuilder::Create(
      status, kNumCommandPackets));
}
+4 −4
Original line number Diff line number Diff line
@@ -469,11 +469,8 @@ class DualModeController : public Device {
  // 7.8.12
  void LeCreateConnection(CommandView args);

  // 7.8.18
  void LeConnectionUpdate(CommandView args);

  // 7.8.13
  void LeConnectionCancel(CommandView args);
  void LeCreateConnectionCancel(CommandView args);

  // 7.8.14
  void LeReadFilterAcceptListSize(CommandView args);
@@ -487,6 +484,9 @@ class DualModeController : public Device {
  // 7.8.17
  void LeRemoveDeviceFromFilterAcceptList(CommandView args);

  // 7.8.18
  void LeConnectionUpdate(CommandView args);

  // 7.8.21
  void LeReadRemoteFeatures(CommandView args);

+734 −221

File changed.

Preview size limit exceeded, changes collapsed.

+60 −66
Original line number Diff line number Diff line
@@ -295,52 +295,6 @@ class LinkLayerController {

  uint8_t LeReadNumberOfSupportedAdvertisingSets();

  void SetLeConnectionOwnAddressType(
      bluetooth::hci::OwnAddressType own_address_type) {
    le_connection_own_address_type_ = own_address_type;
  }
  ErrorCode SetLeConnect(bool le_connect, bool extended) {
    if (le_connect_ == le_connect) {
      return ErrorCode::COMMAND_DISALLOWED;
    }
    le_connect_ = le_connect;
    le_extended_connect_ = extended;
    le_pending_connect_ = false;
    return ErrorCode::SUCCESS;
  }
  void SetLeConnectionIntervalMin(uint16_t min) {
    le_connection_interval_min_ = min;
  }
  void SetLeConnectionIntervalMax(uint16_t max) {
    le_connection_interval_max_ = max;
  }
  void SetLeConnectionLatency(uint16_t latency) {
    le_connection_latency_ = latency;
  }
  void SetLeSupervisionTimeout(uint16_t timeout) {
    le_connection_supervision_timeout_ = timeout;
  }
  void SetLeMinimumCeLength(uint16_t min) {
    le_connection_minimum_ce_length_ = min;
  }
  void SetLeMaximumCeLength(uint16_t max) {
    le_connection_maximum_ce_length_ = max;
  }
  void SetLeInitiatorFilterPolicy(
      bluetooth::hci::InitiatorFilterPolicy le_initiator_filter_policy) {
    le_initiator_filter_policy_ = le_initiator_filter_policy;
  }
  void SetLePeerAddress(const AddressWithType& peer_address) {
    le_peer_address_ = peer_address;
  }

  void SetLeScanInterval(uint16_t le_scan_interval) {
    le_scan_interval_ = le_scan_interval;
  }
  void SetLeScanWindow(uint16_t le_scan_window) {
    le_scan_window_ = le_scan_window;
  }

  // Classic
  void StartInquiry(std::chrono::milliseconds timeout);
  void InquiryCancel();
@@ -538,6 +492,31 @@ class LinkLayerController {
      bool enable, bluetooth::hci::FilterDuplicates filter_duplicates,
      uint16_t duration, uint16_t period);

  // Legacy Connection

  // HCI LE Create Connection command (Vol 4, Part E § 7.8.12).
  ErrorCode LeCreateConnection(
      uint16_t scan_interval, uint16_t scan_window,
      bluetooth::hci::InitiatorFilterPolicy initiator_filter_policy,
      AddressWithType peer_address,
      bluetooth::hci::OwnAddressType own_address_type,
      uint16_t connection_interval_min, uint16_t connection_interval_max,
      uint16_t max_latency, uint16_t supervision_timeout,
      uint16_t min_ce_length, uint16_t max_ce_length);

  // HCI LE Create Connection Cancel command (Vol 4, Part E § 7.8.12).
  ErrorCode LeCreateConnectionCancel();

  // Extended Connection

  // HCI LE Extended Create Connection command (Vol 4, Part E § 7.8.66).
  ErrorCode LeExtendedCreateConnection(
      bluetooth::hci::InitiatorFilterPolicy initiator_filter_policy,
      bluetooth::hci::OwnAddressType own_address_type,
      AddressWithType peer_address, uint8_t initiating_phys,
      std::vector<bluetooth::hci::LeCreateConnPhyScanParameters>
          initiating_phy_parameters);

 protected:
  void SendLeLinkLayerPacketWithRssi(
      Address source, Address dest, uint8_t rssi,
@@ -847,9 +826,6 @@ class LinkLayerController {

  std::vector<uint8_t> extended_inquiry_data_;

  // The value is implementation defined.
  int8_t le_advertising_tx_power_{-10};

  AclConnectionHandler connections_;

  // Callbacks to schedule tasks.
@@ -946,23 +922,41 @@ class LinkLayerController {
  // Only one type of advertising may be used during a controller session.
  Scanner scanner_{};

  Address le_connecting_rpa_;
  uint16_t le_scan_interval_{};
  uint16_t le_scan_window_{};

  bool le_connect_{false};
  bool le_extended_connect_{false};
  bool le_pending_connect_{false};
  uint16_t le_connection_interval_min_{};
  uint16_t le_connection_interval_max_{};
  uint16_t le_connection_latency_{};
  uint16_t le_connection_supervision_timeout_{};
  uint16_t le_connection_minimum_ce_length_{};
  uint16_t le_connection_maximum_ce_length_{};
  bluetooth::hci::OwnAddressType le_connection_own_address_type_{};
  bluetooth::hci::InitiatorFilterPolicy le_initiator_filter_policy_{};

  AddressWithType le_peer_address_{};
  struct Initiator {
    bool connect_enable;
    bluetooth::hci::InitiatorFilterPolicy initiator_filter_policy;
    bluetooth::hci::AddressWithType peer_address{};
    bluetooth::hci::OwnAddressType own_address_type;

    struct PhyParameters {
      bool enabled;
      uint16_t scan_interval;
      uint16_t scan_window;
      uint16_t connection_interval_min;
      uint16_t connection_interval_max;
      uint16_t max_latency;
      uint16_t supervision_timeout;
      uint16_t min_ce_length;
      uint16_t max_ce_length;
    };

    PhyParameters le_1m_phy;
    PhyParameters le_2m_phy;
    PhyParameters le_coded_phy;

    // Save information about the ongoing connection.
    Address initiating_address{};  // TODO: AddressWithType
    std::optional<AddressWithType> pending_connect_request{};

    bool IsEnabled() const { return connect_enable; }
    void Disable() { connect_enable = false; }
  };

  // Legacy and extended initiating properties.
  // Legacy and extended initiating are disambiguated by the use
  // of legacy_advertising_in_use_ and extended_advertising_in_use_ flags.
  // Only one type of advertising may be used during a controller session.
  Initiator initiator_{};

  // Classic state
#ifdef ROOTCANAL_LMP
Loading