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

Commit 6f187827 authored by Hansong Zhang's avatar Hansong Zhang
Browse files

L2cap LE: Send channel open callback after remote version

Make sure remote version info is known when channel is open.  SMP needs
it immediately.

Tag: #gd-refactor
Bug: 141555841
Test: cert/run
Change-Id: I35fa5153adda3e6eda48607cf391804a06d24192
parent d4d9f061
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -47,6 +47,8 @@ SecurityPolicy SecurityLevelToPolicy(SecurityLevel level) {
  }
}

static constexpr auto kChannelOpenTimeout = std::chrono::seconds(4);

class L2capLeModuleFacadeService : public L2capLeModuleFacade::Service {
 public:
  L2capLeModuleFacadeService(L2capLeModule* l2cap_layer, os::Handler* facade_handler)
@@ -152,7 +154,7 @@ class L2capLeModuleFacadeService : public L2capLeModuleFacade::Service {
          address, {}, psm_, common::Bind(&L2capDynamicChannelHelper::on_connection_open, common::Unretained(this)),
          common::Bind(&L2capDynamicChannelHelper::on_connect_fail, common::Unretained(this)), handler_);
      std::unique_lock<std::mutex> lock(channel_open_cv_mutex_);
      if (!channel_open_cv_.wait_for(lock, std::chrono::seconds(2), [this] { return channel_ != nullptr; })) {
      if (!channel_open_cv_.wait_for(lock, kChannelOpenTimeout, [this] { return channel_ != nullptr; })) {
        LOG_WARN("Channel is not open for psm %d", psm_);
      }
    }
@@ -209,7 +211,7 @@ class L2capLeModuleFacadeService : public L2capLeModuleFacade::Service {
    bool SendPacket(std::vector<uint8_t> packet) {
      if (channel_ == nullptr) {
        std::unique_lock<std::mutex> lock(channel_open_cv_mutex_);
        if (!channel_open_cv_.wait_for(lock, std::chrono::seconds(2), [this] { return channel_ != nullptr; })) {
        if (!channel_open_cv_.wait_for(lock, kChannelOpenTimeout, [this] { return channel_ != nullptr; })) {
          LOG_WARN("Channel is not open for psm %d", psm_);
          return false;
        }
@@ -302,7 +304,7 @@ class L2capLeModuleFacadeService : public L2capLeModuleFacade::Service {
      fixed_channel_manager_->ConnectServices(
          address, common::BindOnce(&L2capFixedChannelHelper::on_connect_fail, common::Unretained(this)), handler_);
      std::unique_lock<std::mutex> lock(channel_open_cv_mutex_);
      if (!channel_open_cv_.wait_for(lock, std::chrono::seconds(2), [this] { return channel_ != nullptr; })) {
      if (!channel_open_cv_.wait_for(lock, kChannelOpenTimeout, [this] { return channel_ != nullptr; })) {
        LOG_WARN("Channel is not open for cid %d", cid_);
      }
    }
@@ -359,7 +361,7 @@ class L2capLeModuleFacadeService : public L2capLeModuleFacade::Service {
    bool SendPacket(std::vector<uint8_t> packet) {
      if (channel_ == nullptr) {
        std::unique_lock<std::mutex> lock(channel_open_cv_mutex_);
        if (!channel_open_cv_.wait_for(lock, std::chrono::seconds(2), [this] { return channel_ != nullptr; })) {
        if (!channel_open_cv_.wait_for(lock, kChannelOpenTimeout, [this] { return channel_ != nullptr; })) {
          LOG_WARN("Channel is not open for cid %d", cid_);
          return false;
        }
+16 −15
Original line number Diff line number Diff line
@@ -121,21 +121,6 @@ void LinkManager::OnLeConnectSuccess(hci::AddressWithType connecting_address_wit
        link->GetRole());
  }

  // Allocate and distribute channels for all registered fixed channel services
  auto fixed_channel_services = fixed_channel_service_manager_->GetRegisteredServices();
  for (auto& fixed_channel_service : fixed_channel_services) {
    auto fixed_channel_impl = link->AllocateFixedChannel(fixed_channel_service.first,
                                                         SecurityPolicy::NO_SECURITY_WHATSOEVER_PLAINTEXT_TRANSPORT_OK);
    fixed_channel_service.second->NotifyChannelCreation(
        std::make_unique<FixedChannel>(fixed_channel_impl, l2cap_handler_));
  }
  if (pending_dynamic_channels_.find(connected_address_with_type) != pending_dynamic_channels_.end()) {
    for (auto& psm_callback : pending_dynamic_channels_[connected_address_with_type]) {
      link->SendConnectionRequest(psm_callback.first, std::move(psm_callback.second));
    }
    pending_dynamic_channels_.erase(connected_address_with_type);
  }

  // Remove device from pending links list, if any
  pending_links_.erase(connecting_address_with_type);

@@ -188,6 +173,22 @@ void LinkManager::OnReadRemoteVersionInformationComplete(
        manufacturer_name,
        sub_version);
  }

  auto* link = GetLink(address_with_type);
  // Allocate and distribute channels for all registered fixed channel services
  auto fixed_channel_services = fixed_channel_service_manager_->GetRegisteredServices();
  for (auto& fixed_channel_service : fixed_channel_services) {
    auto fixed_channel_impl = link->AllocateFixedChannel(
        fixed_channel_service.first, SecurityPolicy::NO_SECURITY_WHATSOEVER_PLAINTEXT_TRANSPORT_OK);
    fixed_channel_service.second->NotifyChannelCreation(
        std::make_unique<FixedChannel>(fixed_channel_impl, l2cap_handler_));
  }
  if (pending_dynamic_channels_.find(address_with_type) != pending_dynamic_channels_.end()) {
    for (auto& psm_callback : pending_dynamic_channels_[address_with_type]) {
      link->SendConnectionRequest(psm_callback.first, std::move(psm_callback.second));
    }
    pending_dynamic_channels_.erase(address_with_type);
  }
}

}  // namespace internal
+24 −0
Original line number Diff line number Diff line
@@ -147,6 +147,12 @@ TEST_F(L2capLeLinkManagerTest, connect_fixed_channel_service_without_acl) {
                                              common::Unretained(hci_le_connection_callbacks), address_with_type,
                                              std::move(acl_connection)));
  SyncHandler(hci_callback_handler);
  connection_management_handler->Post(common::BindOnce(
      &hci::acl_manager::LeConnectionManagementCallbacks::OnReadRemoteVersionInformationComplete,
      common::Unretained(connection_management_callbacks),
      0,
      0,
      0));
  auto future_1_status = future_1.wait_for(kTestIdleDisconnectTimeoutShort);
  EXPECT_EQ(future_1_status, std::future_status::ready);
  auto future_2_status = future_2.wait_for(kTestIdleDisconnectTimeoutShort);
@@ -336,6 +342,12 @@ TEST_F(L2capLeLinkManagerTest, not_acquiring_channels_should_disconnect_acl_afte
                                              common::Unretained(hci_le_connection_callbacks), address_with_type,
                                              std::move(acl_connection)));
  SyncHandler(hci_callback_handler);
  connection_management_handler->Post(common::BindOnce(
      &hci::acl_manager::LeConnectionManagementCallbacks::OnReadRemoteVersionInformationComplete,
      common::Unretained(connection_management_callbacks),
      0,
      0,
      0));
  auto future_1_status = future_1.wait_for(kTestIdleDisconnectTimeoutShort);
  EXPECT_EQ(future_1_status, std::future_status::ready);
  EXPECT_NE(channel_1, nullptr);
@@ -425,6 +437,12 @@ TEST_F(L2capLeLinkManagerTest, acquiring_channels_should_not_disconnect_acl_afte
                                              common::Unretained(hci_le_connection_callbacks), address_with_type,
                                              std::move(acl_connection)));
  SyncHandler(hci_callback_handler);
  connection_management_handler->Post(common::BindOnce(
      &hci::acl_manager::LeConnectionManagementCallbacks::OnReadRemoteVersionInformationComplete,
      common::Unretained(connection_management_callbacks),
      0,
      0,
      0));
  auto future_1_status = future_1.wait_for(kTestIdleDisconnectTimeoutShort);
  EXPECT_EQ(future_1_status, std::future_status::ready);
  EXPECT_NE(channel_1, nullptr);
@@ -516,6 +534,12 @@ TEST_F(L2capLeLinkManagerTest, acquiring_and_releasing_channels_should_eventuall
                                              common::Unretained(hci_le_connection_callbacks), address_with_type,
                                              std::move(acl_connection)));
  SyncHandler(hci_callback_handler);
  connection_management_handler->Post(common::BindOnce(
      &hci::acl_manager::LeConnectionManagementCallbacks::OnReadRemoteVersionInformationComplete,
      common::Unretained(connection_management_callbacks),
      0,
      0,
      0));
  auto future_1_status = future_1.wait_for(kTestIdleDisconnectTimeoutShort);
  EXPECT_EQ(future_1_status, std::future_status::ready);
  EXPECT_NE(channel_1, nullptr);
+3 −2
Original line number Diff line number Diff line
@@ -483,9 +483,10 @@ void LinkLayerController::IncomingReadRemoteExtendedFeaturesResponse(
void LinkLayerController::IncomingReadRemoteVersion(
    model::packets::LinkLayerPacketView packet) {
  SendLinkLayerPacket(
      model::packets::ReadRemoteSupportedFeaturesResponseBuilder::Create(
      model::packets::ReadRemoteVersionInformationResponseBuilder::Create(
          packet.GetDestinationAddress(), packet.GetSourceAddress(),
          properties_.GetSupportedFeatures()));
          properties_.GetLmpPalVersion(), properties_.GetLmpPalSubversion(),
          properties_.GetManufacturerName()));
}

void LinkLayerController::IncomingReadRemoteVersionResponse(