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

Commit d91d1b19 authored by Hansong Zhang's avatar Hansong Zhang
Browse files

L2CAP Classic: Unreserve channel on connection response fail

Free the reserved cid when dynamic channel isn't opened

Test: bluetooth_test_gd and run_cert.sh
Bug: 145626799
Change-Id: I64f5e59cc15a1188cec94c827f7c5ea147803e22
parent 8c16302d
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -79,6 +79,11 @@ void Link::SendConnectionRequest(Psm psm, Cid local_cid,
  signalling_manager_.SendConnectionRequest(psm, local_cid);
}

void Link::OnOutgoingConnectionRequestFail(Cid local_cid) {
  local_cid_to_pending_dynamic_channel_connection_map_.erase(local_cid);
  dynamic_channel_allocator_.FreeChannel(local_cid);
}

void Link::SendDisconnectionRequest(Cid local_cid, Cid remote_cid) {
  signalling_manager_.SendDisconnectionRequest(local_cid, remote_cid);
}
+3 −0
Original line number Diff line number Diff line
@@ -79,6 +79,9 @@ class Link : public l2cap::internal::ILink {
  virtual void SendConnectionRequest(Psm psm, Cid local_cid,
                                     PendingDynamicChannelConnection pending_dynamic_channel_connection);

  // Invoked by signalling manager to indicate an outgoing connection request failed and link shall free resources
  virtual void OnOutgoingConnectionRequestFail(Cid local_cid);

  virtual void SendInformationRequest(InformationRequestInfoType type);

  virtual void SendDisconnectionRequest(Cid local_cid, Cid remote_cid) override;
+6 −0
Original line number Diff line number Diff line
@@ -217,6 +217,7 @@ void ClassicSignallingManager::OnConnectionResponse(SignalId signal_id, Cid remo
  }
  alarm_.Cancel();
  if (result != ConnectionResponseResult::SUCCESS) {
    link_->OnOutgoingConnectionRequestFail(cid);
    handle_send_next_command();
    return;
  }
@@ -224,6 +225,7 @@ void ClassicSignallingManager::OnConnectionResponse(SignalId signal_id, Cid remo
  auto new_channel = link_->AllocateReservedDynamicChannel(cid, pending_psm, remote_cid, {});
  if (new_channel == nullptr) {
    LOG_WARN("Can't allocate dynamic channel");
    link_->OnOutgoingConnectionRequestFail(cid);
    handle_send_next_command();
    return;
  }
@@ -665,6 +667,10 @@ void ClassicSignallingManager::on_command_timeout() {
  auto last_sent_command = std::move(pending_commands_.front());
  pending_commands_.pop();
  switch (last_sent_command.command_code_) {
    case CommandCode::CONNECTION_REQUEST: {
      link_->OnOutgoingConnectionRequestFail(last_sent_command.source_cid_);
      break;
    }
    case CommandCode::CONFIGURATION_REQUEST: {
      SendDisconnectionRequest(last_sent_command.source_cid_, last_sent_command.destination_cid_);
      break;
+1 −1
Original line number Diff line number Diff line
@@ -87,6 +87,7 @@ Cid DynamicChannelAllocator::ReserveChannel() {
}

void DynamicChannelAllocator::FreeChannel(Cid cid) {
  used_cid_.erase(cid);
  auto channel = FindChannelByCid(cid);
  if (channel == nullptr) {
    LOG_INFO("Channel is not in use: psm %d, device %s", cid, link_->GetDevice().ToString().c_str());
@@ -94,7 +95,6 @@ void DynamicChannelAllocator::FreeChannel(Cid cid) {
  }
  used_remote_cid_.erase(channel->GetRemoteCid());
  channels_.erase(cid);
  used_cid_.erase(cid);
}

bool DynamicChannelAllocator::IsPsmUsed(Psm psm) const {
+5 −0
Original line number Diff line number Diff line
@@ -87,6 +87,11 @@ void Link::SendDisconnectionRequest(Cid local_cid, Cid remote_cid) {
  signalling_manager_.SendDisconnectRequest(local_cid, remote_cid);
}

void Link::OnOutgoingConnectionRequestFail(Cid local_cid) {
  local_cid_to_pending_dynamic_channel_connection_map_.erase(local_cid);
  dynamic_channel_allocator_.FreeChannel(local_cid);
}

std::shared_ptr<l2cap::internal::DynamicChannelImpl> Link::AllocateDynamicChannel(Psm psm, Cid remote_cid,
                                                                                  SecurityPolicy security_policy) {
  auto channel = dynamic_channel_allocator_.AllocateChannel(psm, remote_cid, security_policy);
Loading