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

Commit abcd2c15 authored by Kyunglyul Hyun's avatar Kyunglyul Hyun
Browse files

AckPause when disarmed

There are some cases where `le_impl` doest not
call `AckPause`, preventing it from entering the
PAUSED state and `le_address_manager` from
handling subsequent commands.

This change ensures that `le_impl` calls AckPause when
it's disarmed.

Bug: 348637133
Bug: 357024179
Test: atest LeImplTest

Change-Id: I945b97b1aedc1b32e17895b3a222a08cb8be0c67
parent aa17a7c0
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -325,6 +325,11 @@ public:
    log::debug("{} --> {}", connectability_state_machine_text(connectability_state_),
               connectability_state_machine_text(state));
    connectability_state_ = state;
    if (com::android::bluetooth::flags::le_impl_ack_pause_disarmed()) {
      if (state == ConnectabilityState::DISARMED && pause_connection) {
        le_address_manager_->AckPause(this);
      }
    }
  }

  // connection canceled by LeAddressManager.OnPause(), will auto reconnect by
@@ -333,8 +338,10 @@ public:
    log::assert_that(pause_connection, "Connection must be paused to ack the le address manager");
    arm_on_resume_ = true;
    set_connectability_state(ConnectabilityState::DISARMED);
    if (!com::android::bluetooth::flags::le_impl_ack_pause_disarmed()) {
      le_address_manager_->AckPause(this);
    }
  }

  void on_common_le_connection_complete(AddressWithType address_with_type) {
    auto connecting_addr_with_type = connecting_le_.find(address_with_type);
+53 −1
Original line number Diff line number Diff line
@@ -387,7 +387,6 @@ protected:

    CommandView cancel_connection = CommandView::Create(
            PacketView<packet::kLittleEndian>(std::make_shared<std::vector<uint8_t>>()));
    ;

    if (!com::android::bluetooth::flags::
                improve_create_connection_for_already_connecting_device()) {
@@ -1606,6 +1605,59 @@ TEST_F(LeImplTest, direct_connection_after_direct_connection_with_improvement) {
  test_direct_connect_after_direct_connect();
}

TEST_F(LeImplTest, direct_connection_cancel_but_connected) {
  com::android::bluetooth::flags::provider_->le_impl_ack_pause_disarmed(true);

  set_random_device_address_policy();
  controller_->AddSupported(OpCode::LE_EXTENDED_CREATE_CONNECTION);

  hci::AddressWithType address({0x21, 0x22, 0x23, 0x24, 0x25, 0x26},
                               AddressType::PUBLIC_DEVICE_ADDRESS);

  // Create first direct connection
  le_impl_->create_le_connection(address, true, /* is_direct */ true);
  hci_layer_->GetCommand(OpCode::LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST);
  hci_layer_->IncomingEvent(
          LeAddDeviceToFilterAcceptListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS));
  hci_layer_->GetCommand(OpCode::LE_EXTENDED_CREATE_CONNECTION);
  hci_layer_->IncomingEvent(
          LeExtendedCreateConnectionStatusBuilder::Create(ErrorCode::SUCCESS, 0x01));
  sync_handler();
  ASSERT_EQ(ConnectabilityState::ARMED, le_impl_->connectability_state_);

  // Cancel the connection
  le_impl_->cancel_connect(address);
  hci_layer_->GetCommand(OpCode::LE_CREATE_CONNECTION_CANCEL);
  hci_layer_->IncomingEvent(
          LeCreateConnectionCancelCompleteBuilder::Create(0x01, ErrorCode::SUCCESS));

  // According to the spec, UNKNOWN_CONNECTION should be reported but some controller could
  // report SUCCESS when there is a race between cancel and connect.
  hci_layer_->IncomingLeMetaEvent(LeEnhancedConnectionCompleteBuilder::Create(
          ErrorCode::SUCCESS, kHciHandle, Role::CENTRAL, AddressType::PUBLIC_DEVICE_ADDRESS,
          remote_address_, local_rpa_, remote_rpa_, 0x0024, 0x0000, 0x0011, ClockAccuracy::PPM_30));
  sync_handler();
  ASSERT_EQ(ConnectabilityState::DISARMED, le_impl_->connectability_state_);
  ASSERT_TRUE(le_impl_->accept_list.empty());

  // Disconnect and reconnect
  le_impl_->on_le_disconnect(kHciHandle, ErrorCode::REMOTE_USER_TERMINATED_CONNECTION);
  sync_handler();

  le_impl_->create_le_connection(address, true, /* is_direct */ true);
  ASSERT_TRUE(le_impl_->accept_list.contains(address));
  sync_handler();

  le_impl_->OnPause();
  hci_layer_->GetCommand(OpCode::LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST);
  hci_layer_->IncomingEvent(
          LeAddDeviceToFilterAcceptListCompleteBuilder::Create(0x01, ErrorCode::SUCCESS));
  hci_layer_->GetCommand(OpCode::LE_EXTENDED_CREATE_CONNECTION);
  hci_layer_->IncomingEvent(
          LeExtendedCreateConnectionStatusBuilder::Create(ErrorCode::SUCCESS, 0x01));
  sync_handler();
}

}  // namespace acl_manager
}  // namespace hci
}  // namespace bluetooth