src/connectivity/bluetooth/core/bt-host/l2cap/enhanced_retransmission_mode_engines_unittest.cc
// This tests that explicitly requested retransmission and receiving a poll response that doesn't
// acknowledge all I-Frames results in only a single set of retransmissions. This mirrors the L2CAP
// Test Specification v5.0.2 L2CAP/ERM/BI-04-C.
This tests that explicitly requested retransmission and receiving a poll response that doesn't
acknowledge all I-Frames results in only a single set of retransmissions. This mirrors the L2CAP
Test Specification v5.0.2 L2CAP/ERM/BI-04-C.
This tests that explicitly requested retransmission and receiving a poll response that doesn ' t acknowledge all I - Frames results in only a single set of retransmissions . This mirrors the L2CAP Test Specification v5 . 0 . 2 L2CAP / ERM / BI - 04 - C .
TEST_F(L2CAP_EnhancedRetransmissionModeEnginesTest,
       RetransmitAfterReceivingRejectSFrameAndReceiverReadyPollResponseNotAcknowledgingSentFrames) {
  int tx_count = 0;
  int iframe_0_tx_count = 0;
  int iframe_1_tx_count = 0;
  auto tx_callback = [&tx_count, &iframe_0_tx_count, &iframe_1_tx_count](ByteBufferPtr pdu) {
    tx_count++;
    if (tx_count == 3) {
      ASSERT_EQ(sizeof(SimpleSupervisoryFrame), pdu->size());
      ASSERT_TRUE(pdu->As<EnhancedControlField>().designates_supervisory_frame());
      ASSERT_TRUE(pdu->As<SimpleSupervisoryFrame>().is_poll_request());
      return;
    }
    ASSERT_LE(sizeof(SimpleInformationFrameHeader), pdu->size());
    ASSERT_TRUE(pdu->As<EnhancedControlField>().designates_information_frame());
    const auto& header = pdu->As<SimpleInformationFrameHeader>();
    if (header.tx_seq() == 0) {
      iframe_0_tx_count++;
    } else if (header.tx_seq() == 1) {
      iframe_1_tx_count++;
    }
  };
  auto [rx_engine, tx_engine] = MakeLinkedEnhancedRetransmissionModeEngines(
      kTestChannelId, kDefaultMTU, kMaxTransmissions, kTxWindow, tx_callback, NoOpFailureCallback);
  ASSERT_TRUE(rx_engine);
  ASSERT_TRUE(tx_engine);
  tx_engine->QueueSdu(std::make_unique<DynamicByteBuffer>(StaticByteBuffer('a')));
  tx_engine->QueueSdu(std::make_unique<DynamicByteBuffer>(StaticByteBuffer('b')));
  EXPECT_EQ(2, tx_count);
  EXPECT_EQ(1, iframe_0_tx_count);
  EXPECT_EQ(1, iframe_1_tx_count);
  ASSERT_TRUE(RunLoopFor(kErtmReceiverReadyPollTimerDuration));
  EXPECT_EQ(3, tx_count);
  auto reject = StaticByteBuffer(0b1 | kExtendedControlRejFunctionMask, 0);
  rx_engine->ProcessPdu(
      Fragmenter(kTestHandle)
          .BuildFrame(kTestChannelId, reject, FrameCheckSequenceOption::kIncludeFcs));
  auto receiver_ready_0 = StaticByteBuffer(0b1 | kExtendedControlFBitMask, 0);
  rx_engine->ProcessPdu(
      Fragmenter(kTestHandle)
          .BuildFrame(kTestChannelId, receiver_ready_0, FrameCheckSequenceOption::kIncludeFcs));
  EXPECT_EQ(5, tx_count);
  EXPECT_EQ(2, iframe_0_tx_count);
  EXPECT_EQ(2, iframe_1_tx_count);
  auto receiver_ready_2 = StaticByteBuffer(0b1, 2);
  rx_engine->ProcessPdu(
      Fragmenter(kTestHandle)
          .BuildFrame(kTestChannelId, receiver_ready_2, FrameCheckSequenceOption::kIncludeFcs));
  EXPECT_EQ(5, tx_count);
}
TEST_F ( L2CAP_EnhancedRetransmissionModeEnginesTest , RetransmitAfterReceivingRejectSFrameAndReceiverReadyPollResponseNotAcknowledgingSentFrames ) { int tx_count = 0 ; int iframe_0_tx_count = 0 ; int iframe_1_tx_count = 0 ; auto tx_callback = [ & tx_count , & iframe_0_tx_count , & iframe_1_tx_count ] ( ByteBufferPtr pdu ) { tx_count ++ ; if ( tx_count == 3 ) { ASSERT_EQ ( sizeof ( SimpleSupervisoryFrame ) , pdu -> size ( ) ) ; ASSERT_TRUE ( pdu -> As < EnhancedControlField > ( ) . designates_supervisory_frame ( ) ) ; ASSERT_TRUE ( pdu -> As < SimpleSupervisoryFrame > ( ) . is_poll_request ( ) ) ; return ; } ASSERT_LE ( sizeof ( SimpleInformationFrameHeader ) , pdu -> size ( ) ) ; ASSERT_TRUE ( pdu -> As < EnhancedControlField > ( ) . designates_information_frame ( ) ) ; const auto & header = pdu -> As < SimpleInformationFrameHeader > ( ) ; if ( header . tx_seq ( ) == 0 ) { iframe_0_tx_count ++ ; } else if ( header . tx_seq ( ) == 1 ) { iframe_1_tx_count ++ ; } } ; auto [ rx_engine , tx_engine ] = MakeLinkedEnhancedRetransmissionModeEngines ( kTestChannelId , kDefaultMTU , kMaxTransmissions , kTxWindow , tx_callback , NoOpFailureCallback ) ; ASSERT_TRUE ( rx_engine ) ; ASSERT_TRUE ( tx_engine ) ; tx_engine -> QueueSdu ( std :: make_unique < DynamicByteBuffer > ( StaticByteBuffer ( ' ' ) ) ) ; tx_engine -> QueueSdu ( std :: make_unique < DynamicByteBuffer > ( StaticByteBuffer ( ' ' ) ) ) ; EXPECT_EQ ( 2 , tx_count ) ; EXPECT_EQ ( 1 , iframe_0_tx_count ) ; EXPECT_EQ ( 1 , iframe_1_tx_count ) ; ASSERT_TRUE ( RunLoopFor ( kErtmReceiverReadyPollTimerDuration ) ) ; EXPECT_EQ ( 3 , tx_count ) ; auto reject = StaticByteBuffer ( 0b1 | kExtendedControlRejFunctionMask , 0 ) ; rx_engine -> ProcessPdu ( Fragmenter ( kTestHandle ) . BuildFrame ( kTestChannelId , reject , FrameCheckSequenceOption :: kIncludeFcs ) ) ; auto receiver_ready_0 = StaticByteBuffer ( 0b1 | kExtendedControlFBitMask , 0 ) ; rx_engine -> ProcessPdu ( Fragmenter ( kTestHandle ) . BuildFrame ( kTestChannelId , receiver_ready_0 , FrameCheckSequenceOption :: kIncludeFcs ) ) ; EXPECT_EQ ( 5 , tx_count ) ; EXPECT_EQ ( 2 , iframe_0_tx_count ) ; EXPECT_EQ ( 2 , iframe_1_tx_count ) ; auto receiver_ready_2 = StaticByteBuffer ( 0b1 , 2 ) ; rx_engine -> ProcessPdu ( Fragmenter ( kTestHandle ) . BuildFrame ( kTestChannelId , receiver_ready_2 , FrameCheckSequenceOption :: kIncludeFcs ) ) ; EXPECT_EQ ( 5 , tx_count ) ; }
This tests that explicitly requested retransmission and receiving a poll response that doesn't
acknowledge all I-Frames results in only a single set of retransmissions.
This tests that explicitly requested retransmission and receiving a poll response that doesn ' t acknowledge all I - Frames results in only a single set of retransmissions .
// After outbound I-Frames, expect an outbound poll request S-Frame. // Receive an S-frame containing a retransmission request starting at seq = 0. See Core Spec v5.0, // Vol 3, Part A, Section 3.3.2 S-Frame Enhanced Control Field. // Receive an S-frame containing an acknowledgment not including the frames that we transmitted. F // is set. See Core Spec v5.0, Vol 3, Part A, Section 3.3.2 S-Frame Enhanced Control Field. // Check that this caused a retransmission of the two I-Frames only once each. // Acknowledge all of the outbound I-Frames per the specification's sequence diagram.