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

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

L2CAP: Handle pending command response and fix response

Test: run_cert.sh
Bug: 141555841
Change-Id: Ibedf49573d3787c9b96afd416977da9ef998fdeb
parent 97d93634
Loading
Loading
Loading
Loading
+10 −6
Original line number Diff line number Diff line
@@ -517,13 +517,13 @@ class SimpleL2capTest(GdBaseTestClass):
                    channel=self.scid_dcid_map[scid], req_seq=3, s=0))

            l2cap_event_asserts.assert_event_occurs(
                lambda log: print(log) or log.HasField("data_packet") and log.data_packet.channel == scid and basic_frame_to_enhanced_information_frame(log.data_packet.payload) == b'abc'
                lambda log: log.HasField("data_packet") and log.data_packet.channel == scid and basic_frame_to_enhanced_information_frame(log.data_packet.payload) == b'abc'
            )
            l2cap_event_asserts.assert_event_occurs(
                lambda log: print(log) or log.HasField("data_packet") and log.data_packet.channel == scid and basic_frame_to_enhanced_information_frame(log.data_packet.payload) == b'abc'
                lambda log: log.HasField("data_packet") and log.data_packet.channel == scid and basic_frame_to_enhanced_information_frame(log.data_packet.payload) == b'abc'
            )
            l2cap_event_asserts.assert_event_occurs(
                lambda log: print(log) or log.HasField("data_packet") and log.data_packet.channel == scid and basic_frame_to_enhanced_information_frame(log.data_packet.payload) == b'abc'
                lambda log: log.HasField("data_packet") and log.data_packet.channel == scid and basic_frame_to_enhanced_information_frame(log.data_packet.payload) == b'abc'
            )
            l2cap_event_asserts_alt.assert_event_occurs_at_most(
                lambda log: log.HasField("data_packet"), 3)
@@ -636,15 +636,19 @@ class SimpleL2capTest(GdBaseTestClass):
                    channel=self.scid_dcid_map[scid],
                    req_seq=0,
                    tx_seq=0,
                    sar=0))
                    sar=0,
                    sdu_size=3,
                    information=b"abc"))
            self.cert_device.l2cap.SendIFrame(
                l2cap_cert_pb2.IFrame(
                    channel=self.scid_dcid_map[scid],
                    req_seq=0,
                    tx_seq=(self.tx_window - 1),
                    sar=0))
                    sar=0,
                    sdu_size=3,
                    information=b"def"))
            l2cap_event_asserts.assert_event_occurs(
                lambda log: print(log) or log.HasField("data_packet") and log.data_packet.channel == scid and log.data_packet.payload == b'\x05\x01'
                lambda log: log.HasField("data_packet") and log.data_packet.channel == scid and log.data_packet.payload == b'\x05\x01'
            )
            self.cert_device.l2cap.SendSFrame(
                l2cap_cert_pb2.SFrame(
+22 −6
Original line number Diff line number Diff line
@@ -92,7 +92,7 @@ void ClassicSignallingManager::SendDisconnectionRequest(Cid local_cid, Cid remot
      next_signal_id_, CommandCode::DISCONNECTION_REQUEST, {}, local_cid, remote_cid, {}, {}};
  next_signal_id_++;
  pending_commands_.push(std::move(pending_command));
  channel_configuration_[local_cid] = ChannelConfigurationState();
  channel_configuration_.erase(local_cid);
  if (command_just_sent_.signal_id_ == kInvalidSignalId) {
    handle_send_next_command();
  }
@@ -205,6 +205,12 @@ void ClassicSignallingManager::OnConnectionResponse(SignalId signal_id, Cid remo
    handle_send_next_command();
    return;
  }
  if (result == ConnectionResponseResult::PENDING) {
    alarm_.Schedule(common::BindOnce(&ClassicSignallingManager::on_command_timeout, common::Unretained(this)),
                    kTimeout);
    return;
  }

  command_just_sent_.signal_id_ = kInvalidSignalId;
  alarm_.Cancel();
  if (result != ConnectionResponseResult::SUCCESS) {
@@ -262,7 +268,7 @@ void ClassicSignallingManager::OnConnectionResponse(SignalId signal_id, Cid remo
    config.emplace_back(std::move(retransmission_flow_control_configuration));
    config.emplace_back(std::move(fcs_option));
  }
  SendConfigurationRequest(remote_cid, {});
  SendConfigurationRequest(remote_cid, std::move(config));
}

void ClassicSignallingManager::OnConfigurationRequest(SignalId signal_id, Cid cid, Continuation is_continuation,
@@ -288,7 +294,7 @@ void ClassicSignallingManager::OnConfigurationRequest(SignalId signal_id, Cid ci
        break;
      }
      case ConfigurationOptionType::RETRANSMISSION_AND_FLOW_CONTROL: {
        auto config = RetransmissionAndFlowControlConfigurationOption::Specialize(option.get());
        auto* config = RetransmissionAndFlowControlConfigurationOption::Specialize(option.get());
        if (config->retransmission_time_out_ == 0) {
          config->retransmission_time_out_ = 2000;
        }
@@ -296,7 +302,7 @@ void ClassicSignallingManager::OnConfigurationRequest(SignalId signal_id, Cid ci
          config->monitor_time_out_ = 12000;
        }
        configuration_state.remote_retransmission_and_flow_control_ = *config;
        rsp_options.emplace_back(std::make_unique<ConfigurationOption>(*config));
        rsp_options.emplace_back(std::make_unique<RetransmissionAndFlowControlConfigurationOption>(*config));
        break;
      }
      case ConfigurationOptionType::FRAME_CHECK_SEQUENCE: {
@@ -349,7 +355,17 @@ void ClassicSignallingManager::OnConfigurationResponse(SignalId signal_id, Cid c
    return;
  }

  // TODO: Handle status not SUCCESS
  if (result == ConfigurationResponseResult::PENDING) {
    alarm_.Schedule(common::BindOnce(&ClassicSignallingManager::on_command_timeout, common::Unretained(this)),
                    kTimeout);
    return;
  }

  if (result != ConfigurationResponseResult::SUCCESS) {
    LOG_WARN("Configuration response not SUCCESS");
    handle_send_next_command();
    return;
  }

  auto& configuration_state = channel_configuration_[channel->GetCid()];

@@ -404,7 +420,7 @@ void ClassicSignallingManager::OnDisconnectionRequest(SignalId signal_id, Cid ci
    LOG_WARN("Disconnect request for an unknown channel");
    return;
  }
  channel_configuration_[cid] = ChannelConfigurationState();
  channel_configuration_.erase(cid);
  auto builder = DisconnectionResponseBuilder::Create(signal_id.Value(), cid, remote_cid);
  enqueue_buffer_->Enqueue(std::move(builder), handler_);
  channel->OnClosed(hci::ErrorCode::SUCCESS);