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

Commit fdc21422 authored by Jakub Pawlowski's avatar Jakub Pawlowski
Browse files

AclManager::create_le_connection fixes

* modern controllers require "Enhanced" version of Create Connection
Command
* They also require "Set Random Address" to be used before attempting to
create connection
* Use same parameters for connection initiation as the old  stack is using

Test: Attempt to Bond with LE device
Change-Id: I58eb54b4e45f5884a69079421b7a2c6a67b7a2bd
parent 0bdc2d61
Loading
Loading
Loading
Loading
+44 −16
Original line number Diff line number Diff line
@@ -937,18 +937,45 @@ struct AclManager::impl {
  void create_le_connection(AddressWithType address_with_type) {
    // TODO: Add white list handling.
    // TODO: Configure default LE connection parameters?
    uint16_t le_scan_interval = 0x0020;
    uint16_t le_scan_window = 0x0010;
    uint16_t le_scan_interval = 0x0060;
    uint16_t le_scan_window = 0x0030;
    InitiatorFilterPolicy initiator_filter_policy = InitiatorFilterPolicy::USE_PEER_ADDRESS;
    OwnAddressType own_address_type = OwnAddressType::RANDOM_DEVICE_ADDRESS;
    uint16_t conn_interval_min = 0x0006;
    uint16_t conn_interval_max = 0x0C00;
    uint16_t conn_latency = 0x0C0;
    uint16_t supervision_timeout = 0x0C00;
    uint16_t conn_interval_min = 0x0018;
    uint16_t conn_interval_max = 0x0028;
    uint16_t conn_latency = 0x0000;
    uint16_t supervision_timeout = 0x001f4;
    ASSERT(le_client_callbacks_ != nullptr);

    connecting_le_.insert(address_with_type);

    // TODO: make features check nicer, like HCI_LE_EXTENDED_ADVERTISING_SUPPORTED
    if (controller_->GetControllerLeLocalSupportedFeatures() & 0x0010) {
      LeCreateConnPhyScanParameters tmp;
      tmp.scan_interval_ = le_scan_interval;
      tmp.scan_window_ = le_scan_window;
      tmp.conn_interval_min_ = conn_interval_min;
      tmp.conn_interval_max_ = conn_interval_max;
      tmp.conn_latency_ = conn_latency;
      tmp.supervision_timeout_ = supervision_timeout;
      tmp.min_ce_length_ = 0x00;
      tmp.max_ce_length_ = 0x00;

      // With real controllers, we must set random address before using it to establish connection
      // TODO: have separate state machine generate new address when needed, consider using auto-generation in
      // controller
      hci_layer_->EnqueueCommand(hci::LeSetRandomAddressBuilder::Create(Address{{0x00, 0x11, 0xFF, 0xFF, 0x33, 0x22}}),
                                 common::BindOnce([](CommandCompleteView status) {}), handler_);

      hci_layer_->EnqueueCommand(LeExtendedCreateConnectionBuilder::Create(
                                     initiator_filter_policy, own_address_type, address_with_type.GetAddressType(),
                                     address_with_type.GetAddress(), 0x01 /* 1M PHY ONLY */, {tmp}),
                                 common::BindOnce([](CommandStatusView status) {
                                   ASSERT(status.IsValid());
                                   ASSERT(status.GetCommandOpCode() == OpCode::LE_EXTENDED_CREATE_CONNECTION);
                                 }),
                                 handler_);
    } else {
      hci_layer_->EnqueueCommand(
          LeCreateConnectionBuilder::Create(le_scan_interval, le_scan_window, initiator_filter_policy,
                                            address_with_type.GetAddressType(), address_with_type.GetAddress(),
@@ -960,6 +987,7 @@ struct AclManager::impl {
          }),
          handler_);
    }
  }

  void cancel_connect(Address address) {
    auto connecting_addr = connecting_.find(address);
+7 −0
Original line number Diff line number Diff line
@@ -81,12 +81,17 @@ class TestController : public Controller {
    return total_acl_buffers_;
  }

  uint64_t GetControllerLeLocalSupportedFeatures() const override {
    return le_local_supported_features_;
  }

  void CompletePackets(uint16_t handle, uint16_t packets) {
    acl_cb_handler_->Post(common::BindOnce(acl_cb_, handle, packets));
  }

  uint16_t acl_buffer_length_ = 1024;
  uint16_t total_acl_buffers_ = 2;
  uint64_t le_local_supported_features_ = 0;
  common::Callback<void(uint16_t /* handle */, uint16_t /* packets */)> acl_cb_;
  os::Handler* acl_cb_handler_ = nullptr;

@@ -497,6 +502,8 @@ TEST_F(AclManagerTest, invoke_registered_callback_connection_complete_fail) {
  fake_registry_.SynchronizeModuleHandler(&HciLayer::Factory, std::chrono::milliseconds(20));
}

// TODO: implement version of this test where controller supports Extended Advertising Feature in
// GetControllerLeLocalSupportedFeatures, and LE Extended Create Connection is used
TEST_F(AclManagerTest, invoke_registered_callback_le_connection_complete_success) {
  AddressWithType remote_with_type(remote, AddressType::PUBLIC_DEVICE_ADDRESS);
  test_hci_layer_->SetCommandFuture();