src/connectivity/bluetooth/core/bt-host/l2cap/enhanced_retransmission_mode_engines_unittest.cc
// This tests the integration of receiving Selective Reject frames that are not poll requests,
// triggering retransmission only. This mirrors the L2CAP Test Specification v5.0.2
// L2CAP/ERM/BV-15-C.
This tests the integration of receiving Selective Reject frames that are not poll requests,
triggering retransmission only. This mirrors the L2CAP Test Specification v5.0.2
L2CAP/ERM/BV-15-C.
This tests the integration of receiving Selective Reject frames that are not poll requests triggering retransmission only . This mirrors the L2CAP Test Specification v5 . 0 . 2 L2CAP / ERM / BV - 15 - C .
TEST_F(L2CAP_EnhancedRetransmissionModeEnginesTest, RetransmitAfterReceivingSelectiveRejectSFrame) {
  int tx_count = 0;
  std::array<int, 4> iframe_tx_counts{};
  auto tx_callback = [&tx_count, &iframe_tx_counts](ByteBufferPtr pdu) {
    tx_count++;
    ASSERT_LE(sizeof(SimpleInformationFrameHeader), pdu->size());
    ASSERT_TRUE(pdu->As<EnhancedControlField>().designates_information_frame());
    const auto& header = pdu->As<SimpleInformationFrameHeader>();
    ASSERT_GT(iframe_tx_counts.size(), header.tx_seq());
    iframe_tx_counts[header.tx_seq()]++;
  };
  auto [rx_engine, tx_engine] = MakeLinkedEnhancedRetransmissionModeEngines(
      kTestChannelId, kDefaultMTU, kMaxTransmissions, 3, tx_callback,
      NoOpFailureCallback);
  ASSERT_TRUE(rx_engine);
  ASSERT_TRUE(tx_engine);
  for (int i = 0; i < 4; i++) {
    tx_engine->QueueSdu(std::make_unique<DynamicByteBuffer>(StaticByteBuffer('a' + i)));
  }
  EXPECT_EQ(3, tx_count);
  EXPECT_THAT(iframe_tx_counts, testing::ElementsAre(1, 1, 1, 0));
  auto selective_reject = StaticByteBuffer(0b1 | kExtendedControlSrejFunctionMask, 1);
  rx_engine->ProcessPdu(
      Fragmenter(kTestHandle)
          .BuildFrame(kTestChannelId, selective_reject, FrameCheckSequenceOption::kIncludeFcs));
  EXPECT_EQ(4, tx_count);
  EXPECT_THAT(iframe_tx_counts, testing::ElementsAre(1, 2, 1, 0));
  auto ack_3 = StaticByteBuffer(0b1, 3);
  rx_engine->ProcessPdu(
      Fragmenter(kTestHandle)
          .BuildFrame(kTestChannelId, ack_3, FrameCheckSequenceOption::kIncludeFcs));
  EXPECT_EQ(5, tx_count);
  EXPECT_THAT(iframe_tx_counts, testing::ElementsAre(1, 2, 1, 1));
  auto ack_4 = StaticByteBuffer(0b1, 4);
  rx_engine->ProcessPdu(
      Fragmenter(kTestHandle)
          .BuildFrame(kTestChannelId, ack_4, FrameCheckSequenceOption::kIncludeFcs));
  EXPECT_EQ(5, tx_count);
}
TEST_F ( L2CAP_EnhancedRetransmissionModeEnginesTest , RetransmitAfterReceivingSelectiveRejectSFrame ) { int tx_count = 0 ; std :: array < int , 4 > iframe_tx_counts { } ; auto tx_callback = [ & tx_count , & iframe_tx_counts ] ( ByteBufferPtr pdu ) { tx_count ++ ; ASSERT_LE ( sizeof ( SimpleInformationFrameHeader ) , pdu -> size ( ) ) ; ASSERT_TRUE ( pdu -> As < EnhancedControlField > ( ) . designates_information_frame ( ) ) ; const auto & header = pdu -> As < SimpleInformationFrameHeader > ( ) ; ASSERT_GT ( iframe_tx_counts . size ( ) , header . tx_seq ( ) ) ; iframe_tx_counts [ header . tx_seq ( ) ] ++ ; } ; auto [ rx_engine , tx_engine ] = MakeLinkedEnhancedRetransmissionModeEngines ( kTestChannelId , kDefaultMTU , kMaxTransmissions , 3 , tx_callback , NoOpFailureCallback ) ; ASSERT_TRUE ( rx_engine ) ; ASSERT_TRUE ( tx_engine ) ; for ( int i = 0 ; i < 4 ; i ++ ) { tx_engine -> QueueSdu ( std :: make_unique < DynamicByteBuffer > ( StaticByteBuffer ( ' ' + i ) ) ) ; } EXPECT_EQ ( 3 , tx_count ) ; EXPECT_THAT ( iframe_tx_counts , testing :: ElementsAre ( 1 , 1 , 1 , 0 ) ) ; auto selective_reject = StaticByteBuffer ( 0b1 | kExtendedControlSrejFunctionMask , 1 ) ; rx_engine -> ProcessPdu ( Fragmenter ( kTestHandle ) . BuildFrame ( kTestChannelId , selective_reject , FrameCheckSequenceOption :: kIncludeFcs ) ) ; EXPECT_EQ ( 4 , tx_count ) ; EXPECT_THAT ( iframe_tx_counts , testing :: ElementsAre ( 1 , 2 , 1 , 0 ) ) ; auto ack_3 = StaticByteBuffer ( 0b1 , 3 ) ; rx_engine -> ProcessPdu ( Fragmenter ( kTestHandle ) . BuildFrame ( kTestChannelId , ack_3 , FrameCheckSequenceOption :: kIncludeFcs ) ) ; EXPECT_EQ ( 5 , tx_count ) ; EXPECT_THAT ( iframe_tx_counts , testing :: ElementsAre ( 1 , 2 , 1 , 1 ) ) ; auto ack_4 = StaticByteBuffer ( 0b1 , 4 ) ; rx_engine -> ProcessPdu ( Fragmenter ( kTestHandle ) . BuildFrame ( kTestChannelId , ack_4 , FrameCheckSequenceOption :: kIncludeFcs ) ) ; EXPECT_EQ ( 5 , tx_count ) ; }
This tests the integration of receiving Selective Reject frames that are not poll requests,
triggering retransmission only.
This tests the integration of receiving Selective Reject frames that are not poll requests triggering retransmission only .
/*n_frames_in_tx_window=*/ // TxWindow caps transmissions. // Receive an S-frame containing a retransmission request for seq = 1. 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 I-Frame 1 only. // Receive an S-frame containing an acknowledgment up to seq = 3. // Initial transmission of I-Frame 3 after the acknowledgment freed up transmit window capacity. // Receive an S-frame containing an acknowledgment up to seq = 3.