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

Commit c0e70b78 authored by David Duarte's avatar David Duarte
Browse files

le_impl: Fix direct connection for device already in acceptlist

create_le_connection relies on a side effect of
add_device_to_connect_list to disarm and re-arm itself.

If a device was already in the acceptlist, add_device_to_connect_list
will do nothing and will not re-arm the connection.

This commit adds some logic to explicity handle this case, by
disarming the le_impl manually and marking a flag to re-arm
it afterwards.

Bug: 308032317
Test: atest --host LeImplTest#direct_connection_after_background_connection
Change-Id: I9c7121457bc49f1fbe4c64f588f4cce22ec4e510
parent 14a5736e
Loading
Loading
Loading
Loading
+21 −5
Original line number Diff line number Diff line
@@ -354,6 +354,11 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback {
        on_le_connection_canceled_on_pause();
        return;
      }
      if (status == ErrorCode::UNKNOWN_CONNECTION && arm_on_disarm_) {
        arm_on_disarm_ = false;
        arm_connectability();
        return;
      }
      on_common_le_connection_complete(remote_address);
      if (status == ErrorCode::UNKNOWN_CONNECTION) {
        if (remote_address.GetAddress() != Address::kEmpty) {
@@ -1021,9 +1026,13 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback {
      return;
    }

    bool already_in_connect_list = connect_list.find(address_with_type) != connect_list.end();
    // TODO: Configure default LE connection parameters?
    if (add_to_connect_list) {
      if (!already_in_connect_list) {
        add_device_to_connect_list(address_with_type);
      }

      if (is_direct) {
        direct_connections_.insert(address_with_type);
        if (create_connection_timeout_alarms_.find(address_with_type) == create_connection_timeout_alarms_.end()) {
@@ -1060,10 +1069,16 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback {
    switch (connectability_state_) {
      case ConnectabilityState::ARMED:
      case ConnectabilityState::ARMING:
        // Ignored, if we add new device to the filter accept list, create connection command will be sent by OnResume.
        if (already_in_connect_list) {
          arm_on_disarm_ = true;
          disarm_connectability();
        } else {
          // Ignored, if we add new device to the filter accept list, create connection command will
          // be sent by OnResume.
          LOG_DEBUG(
              "Deferred until filter accept list updated create connection state %s",
              connectability_state_machine_text(connectability_state_).c_str());
        }
        break;
      default:
        // If we added to filter accept list then the arming of the le state machine
@@ -1299,6 +1314,7 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback {
  LeAcceptlistCallbacks* le_acceptlist_callbacks_ = nullptr;
  std::unordered_set<AddressWithType> connecting_le_{};
  bool arm_on_resume_{};
  bool arm_on_disarm_{};
  std::unordered_set<AddressWithType> direct_connections_{};
  // Set of devices that will not be removed from connect list after direct connect timeout
  std::unordered_set<AddressWithType> background_connections_;
+0 −5
Original line number Diff line number Diff line
@@ -1861,10 +1861,6 @@ TEST_F(LeImplTest, direct_connection_after_background_connection) {
  auto raw_direct_create_connection = hci_layer_->GetCommandOptional(OpCode::LE_CREATE_CONNECTION);

  // assert
#if 1
  // TODO: Switch to the other branch, this should not fail
  ASSERT_FALSE(raw_direct_create_connection.has_value());
#else
  ASSERT_TRUE(raw_direct_create_connection.has_value());
  auto bg_create_connection = LeCreateConnectionView::Create(
      LeConnectionManagementCommandView::Create(AclCommandView::Create(raw_bg_create_connection)));
@@ -1875,7 +1871,6 @@ TEST_F(LeImplTest, direct_connection_after_background_connection) {
  EXPECT_TRUE(direct_create_connection.IsValid());
  LOG_INFO("Scan Interval %u", direct_create_connection.GetLeScanInterval());
  ASSERT_NE(direct_create_connection.GetLeScanInterval(), bg_create_connection.GetLeScanInterval());
#endif
}

}  // namespace acl_manager