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

Commit df4ce69b authored by Hansong Zhang's avatar Hansong Zhang Committed by android-build-merger
Browse files

Merge "L2CAP: Handle initial channel configuration"

am: e1fd6ed9

Change-Id: Iabaaa863fc8b3e17e6d800bbc81ed4b56a423a94
parents 570c6ef6 e1fd6ed9
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@ service L2capModuleCert {
  rpc FetchConnectionComplete(facade.EventStreamRequest) returns (stream ConnectionCompleteEvent) {}
  rpc DisconnectLink(DisconnectLinkRequest) returns (google.protobuf.Empty) {}
  rpc SendConnectionRequest(ConnectionRequest) returns (google.protobuf.Empty) {}
  rpc SendConfigurationRequest(ConfigurationRequest) returns (SendConfigurationRequestResult) {}
  rpc SendDisconnectionRequest(DisconnectionRequest) returns (google.protobuf.Empty) {}
}

@@ -34,6 +35,10 @@ message ConnectionRequest {
  uint32 scid = 3;
}

message ConfigurationRequest {}

message SendConfigurationRequestResult {}

message DisconnectionRequest {
  facade.BluetoothAddress remote = 1;
  uint32 dcid = 2;
+13 −0
Original line number Diff line number Diff line
@@ -101,6 +101,19 @@ class L2capModuleCertService : public L2capModuleCert::Service {
    return ::grpc::Status::OK;
  }

  ::grpc::Status SendConfigurationRequest(
      ::grpc::ServerContext* context, const ::bluetooth::l2cap::classic::cert::ConfigurationRequest* request,
      ::bluetooth::l2cap::classic::cert::SendConfigurationRequestResult* response) override {
    auto builder = ConfigurationRequestBuilder::Create(1, 0x40, Continuation::END, {});
    auto l2cap_builder = BasicFrameBuilder::Create(1, std::move(builder));
    outgoing_packet_queue_.push(std::move(l2cap_builder));
    if (outgoing_packet_queue_.size() == 1) {
      acl_connection_->GetAclQueueEnd()->RegisterEnqueue(
          handler_, common::Bind(&L2capModuleCertService::enqueue_packet_to_acl, common::Unretained(this)));
    }
    return ::grpc::Status::OK;
  }

  ::grpc::Status SendDisconnectionRequest(::grpc::ServerContext* context, const cert::DisconnectionRequest* request,
                                          ::google::protobuf::Empty* response) override {
    auto builder = DisconnectionRequestBuilder::Create(3, 0x40, 101);
+2 −0
Original line number Diff line number Diff line
@@ -89,6 +89,8 @@ class SimpleL2capTest(GdBaseTestClass):

        dut_packet_stream.subscribe()
        cert_packet_stream.subscribe()
        self.cert_device.l2cap.SendConfigurationRequest(l2cap_cert_pb2.ConfigurationRequest())

        self.cert_device.l2cap.SendL2capPacket(l2cap_facade_pb2.L2capPacket(channel=2, payload=b"abc"))
        dut_packet_stream.assert_event_occurs(
            lambda packet: b"abc" in packet.payload
+39 −11
Original line number Diff line number Diff line
@@ -63,29 +63,39 @@ void ClassicSignallingManager::OnCommandReject(CommandRejectView command_reject_
}

void ClassicSignallingManager::SendConnectionRequest(Psm psm, Cid local_cid) {
  PendingCommand pending_command = {next_signal_id_, CommandCode::CONNECTION_REQUEST, psm, local_cid, {}, {}};
  PendingCommand pending_command = {next_signal_id_, CommandCode::CONNECTION_REQUEST, psm, local_cid, {}, {}, {}};
  next_signal_id_++;
  pending_commands_.push(pending_command);
  pending_commands_.push(std::move(pending_command));
  if (pending_commands_.size() == 1) {
    handle_send_next_command();
  }
}

void ClassicSignallingManager::SendConfigurationRequest() {}
void ClassicSignallingManager::SendConfigurationRequest(Cid remote_cid,
                                                        std::vector<std::unique_ptr<ConfigurationOption>> config) {
  PendingCommand pending_command = {next_signal_id_,  CommandCode::CONFIGURATION_REQUEST, {}, {}, remote_cid, {},
                                    std::move(config)};
  next_signal_id_++;
  pending_commands_.push(std::move(pending_command));
  if (pending_commands_.size() == 1) {
    handle_send_next_command();
  }
}

void ClassicSignallingManager::SendDisconnectionRequest(Cid local_cid, Cid remote_cid) {
  PendingCommand pending_command = {next_signal_id_, CommandCode::DISCONNECTION_REQUEST, {}, local_cid, remote_cid, {}};
  PendingCommand pending_command = {
      next_signal_id_, CommandCode::DISCONNECTION_REQUEST, {}, local_cid, remote_cid, {}, {}};
  next_signal_id_++;
  pending_commands_.push(pending_command);
  pending_commands_.push(std::move(pending_command));
  if (pending_commands_.size() == 1) {
    handle_send_next_command();
  }
}

void ClassicSignallingManager::SendInformationRequest(InformationRequestInfoType type) {
  PendingCommand pending_command = {next_signal_id_, CommandCode::INFORMATION_REQUEST, {}, {}, {}, type};
  PendingCommand pending_command = {next_signal_id_, CommandCode::INFORMATION_REQUEST, {}, {}, {}, type, {}};
  next_signal_id_++;
  pending_commands_.push(pending_command);
  pending_commands_.push(std::move(pending_command));
  if (pending_commands_.size() == 1) {
    handle_send_next_command();
  }
@@ -131,6 +141,7 @@ void ClassicSignallingManager::OnConnectionRequest(SignalId signal_id, Psm psm,
  send_connection_response(signal_id, remote_cid, new_channel->GetCid(), ConnectionResponseResult::SUCCESS,
                           ConnectionResponseStatus::NO_FURTHER_INFORMATION_AVAILABLE);
  std::unique_ptr<DynamicChannel> channel = std::make_unique<DynamicChannel>(new_channel, handler_);
  SendConfigurationRequest(remote_cid, {});
  dynamic_service_manager_->GetService(psm)->NotifyChannelCreation(std::move(channel));
}

@@ -158,11 +169,21 @@ void ClassicSignallingManager::OnConnectionResponse(SignalId signal_id, Cid cid,
                           ConnectionResponseStatus::NO_FURTHER_INFORMATION_AVAILABLE);
  std::unique_ptr<DynamicChannel> channel = std::make_unique<DynamicChannel>(new_channel, handler_);
  dynamic_service_manager_->GetService(pending_psm)->NotifyChannelCreation(std::move(channel));
  SendConfigurationRequest(remote_cid, {});
  alarm_.Cancel();
}

void ClassicSignallingManager::OnConfigurationRequest(SignalId signal_id, Cid cid, Continuation is_continuation,
                                                      std::vector<std::unique_ptr<ConfigurationOption>> option) {}
                                                      std::vector<std::unique_ptr<ConfigurationOption>> option) {
  auto channel = channel_allocator_->FindChannelByCid(cid);
  if (channel == nullptr) {
    LOG_WARN("Configuration request for an unknown channel");
    return;
  }
  auto response = ConfigurationResponseBuilder::Create(signal_id.Value(), cid, is_continuation,
                                                       ConfigurationResponseResult::SUCCESS, {});
  enqueue_buffer_->Enqueue(std::move(response), handler_);
}

void ClassicSignallingManager::OnConfigurationResponse(SignalId signal_id, Cid cid, Continuation is_continuation,
                                                       ConfigurationResponseResult result,
@@ -365,14 +386,14 @@ void ClassicSignallingManager::send_connection_response(SignalId signal_id, Cid

void ClassicSignallingManager::on_command_timeout() {
  LOG_WARN("Response time out");
  // TODO: drop the link?
  link_->OnAclDisconnected(hci::ErrorCode::SUCCESS);
}

void ClassicSignallingManager::handle_send_next_command() {
  if (pending_commands_.empty()) {
    return;
  }
  pending_command_ = pending_commands_.front();
  pending_command_ = std::move(pending_commands_.front());
  pending_commands_.pop();

  auto signal_id = pending_command_.signal_id_;
@@ -380,6 +401,7 @@ void ClassicSignallingManager::handle_send_next_command() {
  auto source_cid = pending_command_.source_cid_;
  auto destination_cid = pending_command_.destination_cid_;
  auto info_type = pending_command_.info_type_;
  auto config = std::move(pending_command_.config_);
  switch (pending_command_.command_code_) {
    case CommandCode::CONNECTION_REQUEST: {
      auto builder = ConnectionRequestBuilder::Create(signal_id.Value(), psm, source_cid);
@@ -388,8 +410,14 @@ void ClassicSignallingManager::handle_send_next_command() {
                      kTimeout);
      break;
    }
    case CommandCode::CONFIGURATION_REQUEST:
    case CommandCode::CONFIGURATION_REQUEST: {
      auto builder =
          ConfigurationRequestBuilder::Create(signal_id.Value(), destination_cid, Continuation::END, std::move(config));
      enqueue_buffer_->Enqueue(std::move(builder), handler_);
      alarm_.Schedule(common::BindOnce(&ClassicSignallingManager::on_command_timeout, common::Unretained(this)),
                      kTimeout);
      break;
    }
    case CommandCode::DISCONNECTION_REQUEST: {
      auto builder = DisconnectionRequestBuilder::Create(signal_id.Value(), destination_cid, source_cid);
      enqueue_buffer_->Enqueue(std::move(builder), handler_);
+3 −1
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@

#include <cstdint>
#include <queue>
#include <vector>

#include "l2cap/cid.h"
#include "l2cap/classic/internal/dynamic_channel_allocator.h"
@@ -44,6 +45,7 @@ struct PendingCommand {
  Cid source_cid_;
  Cid destination_cid_;
  InformationRequestInfoType info_type_;
  std::vector<std::unique_ptr<ConfigurationOption>> config_;
};

class Link;
@@ -61,7 +63,7 @@ class ClassicSignallingManager {

  void SendConnectionRequest(Psm psm, Cid local_cid);

  void SendConfigurationRequest();
  void SendConfigurationRequest(Cid remote_cid, std::vector<std::unique_ptr<ConfigurationOption>> config);

  void SendDisconnectionRequest(Cid local_cid, Cid remote_cid);