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

Commit 8be50ab4 authored by Ted Wang's avatar Ted Wang
Browse files

L2CAP: Update remote tx_window during channel configuration

* Update tx_window as transmit window in configuration request from
  remote.
* Fix logic of checking valid f bit, f bit should be valid only if:
  1. tx_state is in XMIT and f not set
  2. tx_state is in WAIT_F and f set to POLL_RESPONSE

* Add follwoing test cases in simple_l2cap_cert:
  test_resume_transmitting_when_received_rr
  test_resume_transmitting_when_acknowledge_previously_sent
  test_respond_to_rej
  test_handle_duplicate_srej
  test_handle_Receipt_rej_and_rr_with_f_set
  test_handle_rej_and_i_frame_with_f_set

* Add following test case in pts_l2cap_test:
  test_L2CAP_ERM_BV_05_C
  test_L2CAP_ERM_BV_06_C
  test_L2CAP_ERM_BV_13_C
  test_L2CAP_ERM_BI_03_C
  test_L2CAP_ERM_BI_04_C
  test_L2CAP_ERM_BI_05_C

Bug: 149182548
Test: run_cert.sh
Change-Id: I0828e570017b954980f23912937e36524814a0f6
parent 4d47be04
Loading
Loading
Loading
Loading
+20 −4
Original line number Diff line number Diff line
@@ -139,8 +139,16 @@ class L2capClassicModuleCertService : public L2capClassicModuleCert::Service {
    if (request->retransmission_config().mode() == ChannelRetransmissionFlowControlMode::ERTM) {
      auto option = std::make_unique<RetransmissionAndFlowControlConfigurationOption>();
      option->mode_ = RetransmissionAndFlowControlModeOption::ENHANCED_RETRANSMISSION;
      if (request->retransmission_config().tx_window()) {
        option->tx_window_size_ = request->retransmission_config().tx_window();
      } else {
        option->tx_window_size_ = 10;
      }
      if (request->retransmission_config().max_transmit()) {
        option->max_transmit_ = request->retransmission_config().max_transmit();
      } else {
        option->max_transmit_ = 20;
      }
      option->retransmission_time_out_ = 2000;
      option->monitor_time_out_ = 12000;
      option->maximum_pdu_size_ = 1010;
@@ -166,8 +174,16 @@ class L2capClassicModuleCertService : public L2capClassicModuleCert::Service {
    if (request->retransmission_config().mode() == ChannelRetransmissionFlowControlMode::ERTM) {
      auto option = std::make_unique<RetransmissionAndFlowControlConfigurationOption>();
      option->mode_ = RetransmissionAndFlowControlModeOption::ENHANCED_RETRANSMISSION;
      if (request->retransmission_config().tx_window()) {
        option->tx_window_size_ = request->retransmission_config().tx_window();
      } else {
        option->tx_window_size_ = 5;
      }
      if (request->retransmission_config().max_transmit()) {
        option->max_transmit_ = request->retransmission_config().max_transmit();
      } else {
        option->max_transmit_ = 1;
      }
      option->retransmission_time_out_ = 1000;
      option->monitor_time_out_ = 2000;
      option->maximum_pdu_size_ = 1010;
+146 −0
Original line number Diff line number Diff line
@@ -342,3 +342,149 @@ class PTSL2capTest(PTSBaseTestClass):
                    RetransmissionFlowControlMode.ERTM))
            self._assert_connection_complete(due_connection_asserts)
            self._pending_connection_close(timeout=60)

    def test_L2CAP_ERM_BV_05_C(self):
        """
        L2CAP/ERM/BV-05-C [Resume Transmitting I-Frames when an S-Frame [RR] is Received]
        Verify the IUT will cease transmission of I-frames when the negotiated TxWindow is full. Verify the
        IUT will resume transmission of I-frames when an S-frame [RR] is received that acknowledges
        previously sent I-frames.
        """
        with self._dut_connection_stream() as dut_connection_stream, \
            self._dut_connection_close_stream() as dut_connection_close_stream:
            due_connection_asserts = EventAsserts(dut_connection_stream)
            due_connection_close_asserts = EventAsserts(
                dut_connection_close_stream)
            psm = 1

            self.device_under_test.l2cap.SetDynamicChannel(
                l2cap_facade_pb2.SetEnableDynamicChannelRequest(
                    psm=psm,
                    retransmission_mode=l2cap_facade_pb2.
                    RetransmissionFlowControlMode.ERTM))
            self._assert_connection_complete(due_connection_asserts)
            self.device_under_test.l2cap.SendDynamicChannelPacket(
                l2cap_facade_pb2.DynamicChannelPacket(psm=psm, payload=b'abc'))
            self.device_under_test.l2cap.SendDynamicChannelPacket(
                l2cap_facade_pb2.DynamicChannelPacket(psm=psm, payload=b'abc'))
            self._assert_connection_close(due_connection_close_asserts)

    def test_L2CAP_ERM_BV_06_C(self):
        """
        L2CAP/ERM/BV-06-C [Resume Transmitting I-Frames when an I-Frame is Received]
        Verify the IUT will cease transmission of I-frames when the negotiated TxWindow is full. Verify the
        IUT will resume transmission of I-frames when an I-frame is received that acknowledges previously
        sent I-frames.
        """
        with self._dut_connection_stream() as dut_connection_stream, \
            self._dut_connection_close_stream() as dut_connection_close_stream:
            due_connection_asserts = EventAsserts(dut_connection_stream)
            due_connection_close_asserts = EventAsserts(
                dut_connection_close_stream)
            psm = 1

            self.device_under_test.l2cap.SetDynamicChannel(
                l2cap_facade_pb2.SetEnableDynamicChannelRequest(
                    psm=psm,
                    retransmission_mode=l2cap_facade_pb2.
                    RetransmissionFlowControlMode.ERTM))
            self._assert_connection_complete(due_connection_asserts)
            self.device_under_test.l2cap.SendDynamicChannelPacket(
                l2cap_facade_pb2.DynamicChannelPacket(psm=psm, payload=b'abc'))
            self.device_under_test.l2cap.SendDynamicChannelPacket(
                l2cap_facade_pb2.DynamicChannelPacket(psm=psm, payload=b'abc'))
            self._assert_connection_close(due_connection_close_asserts)

    def test_L2CAP_ERM_BV_13_C(self):
        """
        L2CAP/ERM/BV-13-C [Respond to S-Frame [REJ]]
        """
        with self._dut_connection_stream() as dut_connection_stream, \
            self._dut_connection_close_stream() as dut_connection_close_stream:
            due_connection_asserts = EventAsserts(dut_connection_stream)
            due_connection_close_asserts = EventAsserts(
                dut_connection_close_stream)
            psm = 1

            self.device_under_test.l2cap.SetDynamicChannel(
                l2cap_facade_pb2.SetEnableDynamicChannelRequest(
                    psm=psm,
                    retransmission_mode=l2cap_facade_pb2.
                    RetransmissionFlowControlMode.ERTM))
            self._assert_connection_complete(due_connection_asserts)
            self.device_under_test.l2cap.SendDynamicChannelPacket(
                l2cap_facade_pb2.DynamicChannelPacket(psm=psm, payload=b'abc'))
            self.device_under_test.l2cap.SendDynamicChannelPacket(
                l2cap_facade_pb2.DynamicChannelPacket(psm=psm, payload=b'abc'))
            self._assert_connection_close(due_connection_close_asserts)

    def test_L2CAP_ERM_BI_03_C(self):
        """
        L2CAP/ERM/BI-03-C [Handle Duplicate S-Frame [SREJ]]
        """
        with self._dut_connection_stream() as dut_connection_stream, \
            self._dut_connection_close_stream() as dut_connection_close_stream:
            due_connection_asserts = EventAsserts(dut_connection_stream)
            due_connection_close_asserts = EventAsserts(
                dut_connection_close_stream)
            psm = 1

            self.device_under_test.l2cap.SetDynamicChannel(
                l2cap_facade_pb2.SetEnableDynamicChannelRequest(
                    psm=psm,
                    retransmission_mode=l2cap_facade_pb2.
                    RetransmissionFlowControlMode.ERTM))
            self._assert_connection_complete(due_connection_asserts)
            self.device_under_test.l2cap.SendDynamicChannelPacket(
                l2cap_facade_pb2.DynamicChannelPacket(psm=psm, payload=b'abc'))
            self.device_under_test.l2cap.SendDynamicChannelPacket(
                l2cap_facade_pb2.DynamicChannelPacket(psm=psm, payload=b'abc'))
            self._assert_connection_close(due_connection_close_asserts)

    def test_L2CAP_ERM_BI_04_C(self):
        """
        L2CAP/ERM/BI-04-C [Handle Receipt of S-Frame [REJ] and S-Frame [RR, F=1]
        that Both Require Retransmission of the Same I-Frames]
        """
        with self._dut_connection_stream() as dut_connection_stream, \
            self._dut_connection_close_stream() as dut_connection_close_stream:
            due_connection_asserts = EventAsserts(dut_connection_stream)
            due_connection_close_asserts = EventAsserts(
                dut_connection_close_stream)
            psm = 1

            self.device_under_test.l2cap.SetDynamicChannel(
                l2cap_facade_pb2.SetEnableDynamicChannelRequest(
                    psm=psm,
                    retransmission_mode=l2cap_facade_pb2.
                    RetransmissionFlowControlMode.ERTM))
            self._assert_connection_complete(due_connection_asserts)
            self.device_under_test.l2cap.SendDynamicChannelPacket(
                l2cap_facade_pb2.DynamicChannelPacket(psm=psm, payload=b'abc'))
            self.device_under_test.l2cap.SendDynamicChannelPacket(
                l2cap_facade_pb2.DynamicChannelPacket(psm=psm, payload=b'abc'))
            self._assert_connection_close(due_connection_close_asserts)

    def test_L2CAP_ERM_BI_05_C(self):
        """
        L2CAP/ERM/BI-05-C [Handle receipt of S-Frame [REJ] and I-Frame [F=1] that
        Both Require Retransmission of the Same I-Frames]
        """
        with self._dut_connection_stream() as dut_connection_stream, \
            self._dut_connection_close_stream() as dut_connection_close_stream:
            due_connection_asserts = EventAsserts(dut_connection_stream)
            due_connection_close_asserts = EventAsserts(
                dut_connection_close_stream)
            psm = 1

            self.device_under_test.l2cap.SetDynamicChannel(
                l2cap_facade_pb2.SetEnableDynamicChannelRequest(
                    psm=psm,
                    retransmission_mode=l2cap_facade_pb2.
                    RetransmissionFlowControlMode.ERTM))
            self._assert_connection_complete(due_connection_asserts)
            self.device_under_test.l2cap.SendDynamicChannelPacket(
                l2cap_facade_pb2.DynamicChannelPacket(psm=psm, payload=b'abc'))
            self.device_under_test.l2cap.SendDynamicChannelPacket(
                l2cap_facade_pb2.DynamicChannelPacket(psm=psm, payload=b'abc'))
            self._assert_connection_close(due_connection_close_asserts)
+376 −12

File changed.

Preview size limit exceeded, changes collapsed.

+2 −2
Original line number Diff line number Diff line
@@ -499,7 +499,7 @@ struct ErtmController::impl {
  }

  bool with_valid_f_bit(Final f) {
    return f == Final::NOT_SET || tx_state_ == TxState::WAIT_F;
    return f == Final::NOT_SET ^ tx_state_ == TxState::WAIT_F;
  }

  bool with_unexpected_tx_seq(uint8_t tx_seq) {
@@ -1011,7 +1011,7 @@ void ErtmController::send_pdu(std::unique_ptr<packet::BasePacketBuilder> pdu) {

void ErtmController::SetRetransmissionAndFlowControlOptions(
    const RetransmissionAndFlowControlConfigurationOption& option) {
  local_tx_window_ = option.tx_window_size_;
  remote_tx_window_ = option.tx_window_size_;
  local_max_transmit_ = option.max_transmit_;
  local_retransmit_timeout_ms_ = option.retransmission_time_out_;
  local_monitor_timeout_ms_ = option.monitor_time_out_;
+3 −1
Original line number Diff line number Diff line
@@ -101,7 +101,9 @@ void Sender::UpdateClassicConfiguration(classic::internal::ChannelConfigurationS
  if (mode == RetransmissionAndFlowControlModeOption::ENHANCED_RETRANSMISSION) {
    data_controller_ =
        std::make_unique<ErtmController>(link_, channel_id_, remote_channel_id_, queue_end_, handler_, scheduler_);
    data_controller_->SetRetransmissionAndFlowControlOptions(config.local_retransmission_and_flow_control_);
    RetransmissionAndFlowControlConfigurationOption option = config.local_retransmission_and_flow_control_;
    option.tx_window_size_ = config.remote_retransmission_and_flow_control_.tx_window_size_;
    data_controller_->SetRetransmissionAndFlowControlOptions(option);
    data_controller_->EnableFcs(config.fcs_type_ == FcsType::DEFAULT);
    return;
  }