1 // Copyright 2023 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 
15 #include "pw_bluetooth_sapphire/internal/host/l2cap/enhanced_retransmission_mode_tx_engine.h"
16 
17 #include <pw_async/fake_dispatcher_fixture.h>
18 
19 #include "pw_bluetooth_sapphire/internal/host/common/byte_buffer.h"
20 #include "pw_bluetooth_sapphire/internal/host/l2cap/fake_tx_channel.h"
21 #include "pw_bluetooth_sapphire/internal/host/l2cap/frame_headers.h"
22 #include "pw_bluetooth_sapphire/internal/host/testing/test_helpers.h"
23 #include "pw_unit_test/framework.h"
24 
25 namespace bt::l2cap::internal {
26 namespace {
27 
28 constexpr ChannelId kTestChannelId = 0x0001;
29 
30 using TxEngine = EnhancedRetransmissionModeTxEngine;
31 
32 class EnhancedRetransmissionModeTxEngineTest
33     : public pw::async::test::FakeDispatcherFixture {
34  public:
EnhancedRetransmissionModeTxEngineTest()35   EnhancedRetransmissionModeTxEngineTest()
36       : kDefaultPayload('h', 'e', 'l', 'l', 'o') {}
37 
38  protected:
39   // The default values are provided for use by tests which don't depend on the
40   // specific value a given parameter. This should make the tests easier to
41   // read, because the reader can focus on only the non-defaulted parameter
42   // values.
43   static constexpr auto kDefaultMTU = bt::l2cap::kDefaultMTU;
44   static constexpr size_t kDefaultMaxTransmissions = 1;
45   static constexpr size_t kDefaultTxWindow = 63;
46 
47   const StaticByteBuffer<5> kDefaultPayload;
48 
VerifyIsReceiverReadyPollFrame(ByteBuffer * buf)49   void VerifyIsReceiverReadyPollFrame(ByteBuffer* buf) {
50     ASSERT_TRUE(buf);
51     ASSERT_EQ(sizeof(SimpleSupervisoryFrame), buf->size());
52 
53     const auto sframe = buf->To<SimpleSupervisoryFrame>();
54     EXPECT_EQ(SupervisoryFunction::ReceiverReady, sframe.function());
55     EXPECT_TRUE(sframe.is_poll_request());
56   }
57 
58   // Helper to queue an SDU to the channel and notify the engine.
QueueSdu(TxEngine & engine,ByteBufferPtr sdu)59   void QueueSdu(TxEngine& engine, ByteBufferPtr sdu) {
60     channel_.QueueSdu(std::move(sdu));
61     engine.NotifySduQueued();
62   }
63 
channel()64   FakeTxChannel& channel() { return channel_; }
65 
66  private:
67   FakeTxChannel channel_;
68 };
69 
NoOpFailureCallback()70 void NoOpFailureCallback() {}
71 
TEST_F(EnhancedRetransmissionModeTxEngineTest,QueueSduTransmitsMinimalSizedSdu)72 TEST_F(EnhancedRetransmissionModeTxEngineTest,
73        QueueSduTransmitsMinimalSizedSdu) {
74   ByteBufferPtr last_pdu;
75   size_t n_pdus = 0;
76   channel().HandleSendFrame([&](auto pdu) {
77     ++n_pdus;
78     last_pdu = std::move(pdu);
79   });
80 
81   constexpr size_t kMtu = 10;
82   const StaticByteBuffer payload(1);
83   TxEngine tx_engine(kTestChannelId,
84                      kMtu,
85                      kDefaultMaxTransmissions,
86                      kDefaultTxWindow,
87                      channel(),
88                      NoOpFailureCallback,
89                      dispatcher());
90   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(payload));
91   EXPECT_EQ(1u, n_pdus);
92   ASSERT_TRUE(last_pdu);
93 
94   // See Core Spec v5.0, Volume 3, Part A, Table 3.2.
95   const StaticByteBuffer expected_pdu(0,   // Final Bit, TxSeq, MustBeZeroBit
96                                       0,   // SAR bits, ReqSeq
97                                       1);  // Payload
98   EXPECT_TRUE(ContainersEqual(expected_pdu, *last_pdu));
99 }
100 
TEST_F(EnhancedRetransmissionModeTxEngineTest,QueueSduTransmitsMaximalSizedSdu)101 TEST_F(EnhancedRetransmissionModeTxEngineTest,
102        QueueSduTransmitsMaximalSizedSdu) {
103   ByteBufferPtr last_pdu;
104   size_t n_pdus = 0;
105   channel().HandleSendFrame([&](auto pdu) {
106     ++n_pdus;
107     last_pdu = std::move(pdu);
108   });
109 
110   constexpr size_t kMtu = 1;
111   const StaticByteBuffer payload(1);
112   TxEngine tx_engine(kTestChannelId,
113                      kMtu,
114                      kDefaultMaxTransmissions,
115                      kDefaultTxWindow,
116                      channel(),
117                      NoOpFailureCallback,
118                      dispatcher());
119   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(payload));
120   EXPECT_EQ(1u, n_pdus);
121   ASSERT_TRUE(last_pdu);
122 
123   // See Core Spec v5.0, Volume 3, Part A, Table 3.2.
124   const StaticByteBuffer expected_pdu(0,   // Final Bit, TxSeq, MustBeZeroBit
125                                       0,   // SAR bits, ReqSeq
126                                       1);  // Payload
127   EXPECT_TRUE(ContainersEqual(expected_pdu, *last_pdu));
128 }
129 
TEST_F(EnhancedRetransmissionModeTxEngineTest,QueueSduSurvivesOversizedSdu)130 TEST_F(EnhancedRetransmissionModeTxEngineTest, QueueSduSurvivesOversizedSdu) {
131   // TODO(fxbug.dev/42054330): Update this test when we add support for
132   // segmentation.
133   constexpr size_t kMtu = 1;
134   TxEngine tx_engine(kTestChannelId,
135                      kMtu,
136                      kDefaultMaxTransmissions,
137                      kDefaultTxWindow,
138                      channel(),
139                      NoOpFailureCallback,
140                      dispatcher());
141   QueueSdu(tx_engine,
142            std::make_unique<DynamicByteBuffer>(StaticByteBuffer(1, 2)));
143 }
144 
TEST_F(EnhancedRetransmissionModeTxEngineTest,QueueSduSurvivesZeroByteSdu)145 TEST_F(EnhancedRetransmissionModeTxEngineTest, QueueSduSurvivesZeroByteSdu) {
146   TxEngine tx_engine(kTestChannelId,
147                      kDefaultMTU,
148                      kDefaultMaxTransmissions,
149                      kDefaultTxWindow,
150                      channel(),
151                      NoOpFailureCallback,
152                      dispatcher());
153   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>());
154 }
155 
TEST_F(EnhancedRetransmissionModeTxEngineTest,QueueSduAdvancesSequenceNumber)156 TEST_F(EnhancedRetransmissionModeTxEngineTest, QueueSduAdvancesSequenceNumber) {
157   const StaticByteBuffer payload(1);
158   ByteBufferPtr last_pdu;
159   channel().HandleSendFrame([&](auto pdu) { last_pdu = std::move(pdu); });
160   TxEngine tx_engine(kTestChannelId,
161                      kDefaultMTU,
162                      kDefaultMaxTransmissions,
163                      kDefaultTxWindow,
164                      channel(),
165                      NoOpFailureCallback,
166                      dispatcher());
167 
168   {
169     // See Core Spec v5.0, Volume 3, Part A, Table 3.2.
170     const StaticByteBuffer expected_pdu(0,   // Final Bit, TxSeq, MustBeZeroBit
171                                         0,   // SAR bits, ReqSeq
172                                         1);  // Payload
173 
174     QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(payload));
175     ASSERT_TRUE(last_pdu);
176     EXPECT_TRUE(ContainersEqual(expected_pdu, *last_pdu));
177   }
178 
179   {
180     // See Core Spec v5.0, Volume 3, Part A, Table 3.2.
181     const StaticByteBuffer expected_pdu(
182         1 << 1,  // Final Bit, TxSeq=1, MustBeZeroBit
183         0,       // SAR bits, ReqSeq
184         1);      // Payload
185     QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(payload));
186     ASSERT_TRUE(last_pdu);
187     EXPECT_TRUE(ContainersEqual(expected_pdu, *last_pdu));
188   }
189 
190   {
191     // See Core Spec v5.0, Volume 3, Part A, Table 3.2.
192     const StaticByteBuffer expected_pdu(
193         2 << 1,  // Final Bit, TxSeq=2, MustBeZeroBit
194         0,       // SAR bits, ReqSeq
195         1);      // Payload
196     QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(payload));
197     ASSERT_TRUE(last_pdu);
198     EXPECT_TRUE(ContainersEqual(expected_pdu, *last_pdu));
199   }
200 }
201 
TEST_F(EnhancedRetransmissionModeTxEngineTest,QueueSduRollsOverSequenceNumber)202 TEST_F(EnhancedRetransmissionModeTxEngineTest,
203        QueueSduRollsOverSequenceNumber) {
204   constexpr size_t kTxWindow = 63;  // Max possible value
205   const StaticByteBuffer payload(1);
206   ByteBufferPtr last_pdu;
207   channel().HandleSendFrame([&](auto pdu) { last_pdu = std::move(pdu); });
208   TxEngine tx_engine(kTestChannelId,
209                      kDefaultMTU,
210                      kDefaultMaxTransmissions,
211                      kTxWindow,
212                      channel(),
213                      NoOpFailureCallback,
214                      dispatcher());
215 
216   constexpr size_t kMaxSeq = 64;
217   for (size_t i = 0; i < kMaxSeq; ++i) {
218     QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(payload));
219     tx_engine.UpdateAckSeq((i + 1) % kMaxSeq, /*is_poll_response=*/false);
220   }
221 
222   // See Core Spec v5.0, Volume 3, Part A, Table 3.2.
223   const StaticByteBuffer expected_pdu(
224       0,   // Final Bit, TxSeq (rolls over from 63 to 0), MustBeZeroBit
225       0,   // SAR bits, ReqSeq
226       1);  // Payload
227   last_pdu = nullptr;
228   // Free up space for more transmissions. We need room for the 64th frame from
229   // above (since the TxWindow is 63), and the new 0th frame. Hence we
230   // acknowledge original frames 0 and 1.
231   tx_engine.UpdateAckSeq(2, /*is_poll_response=*/false);
232   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(payload));
233   ASSERT_TRUE(last_pdu);
234   EXPECT_TRUE(ContainersEqual(expected_pdu, *last_pdu));
235 }
236 
TEST_F(EnhancedRetransmissionModeTxEngineTest,QueueSduDoesNotTransmitBeyondTxWindow)237 TEST_F(EnhancedRetransmissionModeTxEngineTest,
238        QueueSduDoesNotTransmitBeyondTxWindow) {
239   constexpr size_t kTxWindow = 1;
240   size_t n_pdus = 0;
241   channel().HandleSendFrame([&](auto) { ++n_pdus; });
242   TxEngine tx_engine(kTestChannelId,
243                      kDefaultMTU,
244                      kDefaultMaxTransmissions,
245                      kTxWindow,
246                      channel(),
247                      NoOpFailureCallback,
248                      dispatcher());
249 
250   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
251   ASSERT_EQ(1u, n_pdus);
252 
253   n_pdus = 0;
254   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
255   EXPECT_EQ(0u, n_pdus);
256 }
257 
TEST_F(EnhancedRetransmissionModeTxEngineTest,QueueSduDoesNotTransmitBeyondTxWindowEvenIfQueueWrapsSequenceNumbers)258 TEST_F(EnhancedRetransmissionModeTxEngineTest,
259        QueueSduDoesNotTransmitBeyondTxWindowEvenIfQueueWrapsSequenceNumbers) {
260   constexpr size_t kTxWindow = 1;
261   size_t n_pdus = 0;
262   channel().HandleSendFrame([&](auto) { ++n_pdus; });
263   TxEngine tx_engine(kTestChannelId,
264                      kDefaultMTU,
265                      kDefaultMaxTransmissions,
266                      kTxWindow,
267                      channel(),
268                      NoOpFailureCallback,
269                      dispatcher());
270 
271   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
272   ASSERT_EQ(1u, n_pdus);
273 
274   constexpr size_t kMaxSeq = 64;
275   n_pdus = 0;
276   for (size_t i = 0; i < kMaxSeq; ++i) {
277     QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
278     ASSERT_EQ(0u, n_pdus);
279   }
280 }
281 
TEST_F(EnhancedRetransmissionModeTxEngineTest,EngineTransmitsReceiverReadyPollAfterTimeout)282 TEST_F(EnhancedRetransmissionModeTxEngineTest,
283        EngineTransmitsReceiverReadyPollAfterTimeout) {
284   ByteBufferPtr last_pdu;
285   channel().HandleSendFrame([&](auto pdu) { last_pdu = std::move(pdu); });
286   TxEngine tx_engine(kTestChannelId,
287                      kDefaultMTU,
288                      kDefaultMaxTransmissions,
289                      kDefaultTxWindow,
290                      channel(),
291                      NoOpFailureCallback,
292                      dispatcher());
293 
294   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
295   RunUntilIdle();
296   ASSERT_TRUE(last_pdu);
297   last_pdu = nullptr;
298 
299   ASSERT_TRUE(RunFor(std::chrono::seconds(2)));
300   SCOPED_TRACE("");
301   VerifyIsReceiverReadyPollFrame(last_pdu.get());
302 }
303 
TEST_F(EnhancedRetransmissionModeTxEngineTest,EngineTransmitsReceiverReadyPollOnlyOnceAfterTimeout)304 TEST_F(EnhancedRetransmissionModeTxEngineTest,
305        EngineTransmitsReceiverReadyPollOnlyOnceAfterTimeout) {
306   ByteBufferPtr last_pdu;
307   channel().HandleSendFrame([&](auto pdu) { last_pdu = std::move(pdu); });
308   TxEngine tx_engine(kTestChannelId,
309                      kDefaultMTU,
310                      kDefaultMaxTransmissions,
311                      kDefaultTxWindow,
312                      channel(),
313                      NoOpFailureCallback,
314                      dispatcher());
315 
316   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
317   RunUntilIdle();
318   ASSERT_TRUE(last_pdu);
319   last_pdu = nullptr;
320 
321   ASSERT_TRUE(RunFor(std::chrono::seconds(2)));
322   SCOPED_TRACE("");
323   RETURN_IF_FATAL(VerifyIsReceiverReadyPollFrame(last_pdu.get()));
324   last_pdu = nullptr;
325 
326   // Note: This value is chosen to be at least as long as
327   // kReceiverReadyPollTimerDuration, but shorter than kMonitorTimerDuration.
328   EXPECT_FALSE(RunFor(std::chrono::seconds(2)));  // No tasks were run.
329   EXPECT_FALSE(last_pdu);
330 }
331 
TEST_F(EnhancedRetransmissionModeTxEngineTest,EngineAdvancesReceiverReadyPollTimeoutOnNewTransmission)332 TEST_F(EnhancedRetransmissionModeTxEngineTest,
333        EngineAdvancesReceiverReadyPollTimeoutOnNewTransmission) {
334   ByteBufferPtr last_pdu;
335   channel().HandleSendFrame([&](auto pdu) { last_pdu = std::move(pdu); });
336   TxEngine tx_engine(kTestChannelId,
337                      kDefaultMTU,
338                      kDefaultMaxTransmissions,
339                      kDefaultTxWindow,
340                      channel(),
341                      NoOpFailureCallback,
342                      dispatcher());
343 
344   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
345   RunUntilIdle();
346   ASSERT_TRUE(last_pdu);
347   last_pdu = nullptr;
348 
349   ASSERT_FALSE(RunFor(std::chrono::seconds(1)));  // No events should fire.
350   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
351   RunUntilIdle();
352   last_pdu = nullptr;
353 
354   ASSERT_FALSE(
355       RunFor(std::chrono::seconds(1)));  // Original timeout should not fire.
356   ASSERT_TRUE(RunFor(std::chrono::seconds(1)));  // New timeout should fire.
357   SCOPED_TRACE("");
358   VerifyIsReceiverReadyPollFrame(last_pdu.get());
359 }
360 
TEST_F(EnhancedRetransmissionModeTxEngineTest,ReceiverReadyPollIncludesRequestSequenceNumber)361 TEST_F(EnhancedRetransmissionModeTxEngineTest,
362        ReceiverReadyPollIncludesRequestSequenceNumber) {
363   ByteBufferPtr last_pdu;
364   channel().HandleSendFrame([&](auto pdu) { last_pdu = std::move(pdu); });
365   TxEngine tx_engine(kTestChannelId,
366                      kDefaultMTU,
367                      kDefaultMaxTransmissions,
368                      kDefaultTxWindow,
369                      channel(),
370                      NoOpFailureCallback,
371                      dispatcher());
372 
373   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
374   RunUntilIdle();
375   tx_engine.UpdateReqSeq(1);
376   RunUntilIdle();
377   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
378   last_pdu = nullptr;
379 
380   SCOPED_TRACE("");
381   EXPECT_TRUE(RunFor(std::chrono::seconds(2)));
382   ASSERT_NO_FATAL_FAILURE(VerifyIsReceiverReadyPollFrame(last_pdu.get()));
383   EXPECT_EQ(1u, last_pdu->To<SimpleSupervisoryFrame>().receive_seq_num());
384 }
385 
TEST_F(EnhancedRetransmissionModeTxEngineTest,AckOfOnlyOutstandingFrameCancelsReceiverReadyPollTimeout)386 TEST_F(EnhancedRetransmissionModeTxEngineTest,
387        AckOfOnlyOutstandingFrameCancelsReceiverReadyPollTimeout) {
388   ByteBufferPtr last_pdu;
389   channel().HandleSendFrame([&](auto pdu) { last_pdu = std::move(pdu); });
390   TxEngine tx_engine(kTestChannelId,
391                      kDefaultMTU,
392                      kDefaultMaxTransmissions,
393                      kDefaultTxWindow,
394                      channel(),
395                      NoOpFailureCallback,
396                      dispatcher());
397 
398   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
399   RunUntilIdle();
400   ASSERT_TRUE(last_pdu);
401   last_pdu = nullptr;
402 
403   tx_engine.UpdateAckSeq(1, /*is_poll_response=*/false);
404   RunUntilIdle();
405 
406   EXPECT_FALSE(RunFor(std::chrono::seconds(2)));  // No tasks were run.
407   EXPECT_FALSE(last_pdu);
408 }
409 
TEST_F(EnhancedRetransmissionModeTxEngineTest,AckOfAllOutstandingFramesCancelsReceiverReadyPollTimeout)410 TEST_F(EnhancedRetransmissionModeTxEngineTest,
411        AckOfAllOutstandingFramesCancelsReceiverReadyPollTimeout) {
412   ByteBufferPtr last_pdu;
413   channel().HandleSendFrame([&](auto pdu) { last_pdu = std::move(pdu); });
414   TxEngine tx_engine(kTestChannelId,
415                      kDefaultMTU,
416                      kDefaultMaxTransmissions,
417                      kDefaultTxWindow,
418                      channel(),
419                      NoOpFailureCallback,
420                      dispatcher());
421 
422   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
423   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
424   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
425   RunUntilIdle();
426   ASSERT_TRUE(last_pdu);
427   last_pdu = nullptr;
428 
429   tx_engine.UpdateAckSeq(3, /*is_poll_response=*/false);
430   RunUntilIdle();
431 
432   EXPECT_FALSE(RunFor(std::chrono::seconds(2)));  // No tasks were run.
433   EXPECT_FALSE(last_pdu);
434 }
435 
TEST_F(EnhancedRetransmissionModeTxEngineTest,PartialAckDoesNotCancelReceiverReadyPollTimeout)436 TEST_F(EnhancedRetransmissionModeTxEngineTest,
437        PartialAckDoesNotCancelReceiverReadyPollTimeout) {
438   ByteBufferPtr last_pdu;
439   channel().HandleSendFrame([&](auto pdu) { last_pdu = std::move(pdu); });
440   TxEngine tx_engine(kTestChannelId,
441                      kDefaultMTU,
442                      kDefaultMaxTransmissions,
443                      kDefaultTxWindow,
444                      channel(),
445                      NoOpFailureCallback,
446                      dispatcher());
447 
448   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
449   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
450   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
451   RunUntilIdle();
452   ASSERT_TRUE(last_pdu);
453   last_pdu = nullptr;
454 
455   tx_engine.UpdateAckSeq(1, /*is_poll_response=*/false);
456   RunUntilIdle();
457 
458   // See Core Spec v5.0, Volume 3, Part A, Sec 8.6.5.6, under heading
459   // Process-ReqSeq. We should only Stop-RetransTimer if UnackedFrames is 0.
460   SCOPED_TRACE("");
461   EXPECT_TRUE(RunFor(std::chrono::seconds(2)));
462   VerifyIsReceiverReadyPollFrame(last_pdu.get());
463 }
464 
TEST_F(EnhancedRetransmissionModeTxEngineTest,NewTransmissionAfterAckedFrameReArmsReceiverReadyPollTimeout)465 TEST_F(EnhancedRetransmissionModeTxEngineTest,
466        NewTransmissionAfterAckedFrameReArmsReceiverReadyPollTimeout) {
467   ByteBufferPtr last_pdu;
468   channel().HandleSendFrame([&](auto pdu) { last_pdu = std::move(pdu); });
469   TxEngine tx_engine(kTestChannelId,
470                      kDefaultMTU,
471                      kDefaultMaxTransmissions,
472                      kDefaultTxWindow,
473                      channel(),
474                      NoOpFailureCallback,
475                      dispatcher());
476 
477   // Send a frame, and get the ACK.
478   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
479   RunUntilIdle();
480   tx_engine.UpdateAckSeq(1, /*is_poll_response=*/false);
481   RunUntilIdle();
482 
483   // Send a new frame.
484   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
485   last_pdu = nullptr;
486 
487   // Having earlier received an ACK for the previous frame should not have left
488   // around any state that would prevent us from sending a receiver-ready poll
489   // for the second frame.
490   SCOPED_TRACE("");
491   EXPECT_TRUE(RunFor(std::chrono::seconds(2)));
492   VerifyIsReceiverReadyPollFrame(last_pdu.get());
493 }
494 
TEST_F(EnhancedRetransmissionModeTxEngineTest,EngineRetransmitsReceiverReadyPollAfterMonitorTimeout)495 TEST_F(EnhancedRetransmissionModeTxEngineTest,
496        EngineRetransmitsReceiverReadyPollAfterMonitorTimeout) {
497   constexpr size_t kMaxTransmissions = 2;  // Allow retransmission
498   ByteBufferPtr last_pdu;
499   channel().HandleSendFrame([&](auto pdu) { last_pdu = std::move(pdu); });
500   TxEngine tx_engine(kTestChannelId,
501                      kDefaultMTU,
502                      kMaxTransmissions,
503                      kDefaultTxWindow,
504                      channel(),
505                      NoOpFailureCallback,
506                      dispatcher());
507 
508   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
509   RunUntilIdle();
510 
511   // First the receiver_ready_poll_task_ fires.
512   ASSERT_TRUE(RunFor(std::chrono::seconds(2)));
513   ASSERT_TRUE(last_pdu);
514   last_pdu = nullptr;
515 
516   // Then the monitor_task_ fires.
517   EXPECT_TRUE(RunFor(std::chrono::seconds(12)));
518   VerifyIsReceiverReadyPollFrame(last_pdu.get());
519 }
520 
TEST_F(EnhancedRetransmissionModeTxEngineTest,EngineDoesNotRetransmitReceiverReadyPollAfterMonitorTimeoutWhenRetransmissionsAreDisabled)521 TEST_F(
522     EnhancedRetransmissionModeTxEngineTest,
523     EngineDoesNotRetransmitReceiverReadyPollAfterMonitorTimeoutWhenRetransmissionsAreDisabled) {
524   constexpr size_t kMaxTransmissions = 1;
525   ByteBufferPtr last_pdu;
526   channel().HandleSendFrame([&](auto pdu) { last_pdu = std::move(pdu); });
527   TxEngine tx_engine(kTestChannelId,
528                      kDefaultMTU,
529                      kMaxTransmissions,
530                      kDefaultTxWindow,
531                      channel(),
532                      NoOpFailureCallback,
533                      dispatcher());
534 
535   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
536   RunUntilIdle();
537 
538   // First the receiver_ready_poll_task_ fires.
539   ASSERT_TRUE(RunFor(std::chrono::seconds(2)));
540   ASSERT_TRUE(last_pdu);
541   last_pdu = nullptr;
542 
543   // Run the event loop long enough for the monitor task to fire again. Because
544   // kMaxTransmissions == 1, the ReceiverReadyPoll should not be retransmitted.
545   RunFor(std::chrono::seconds(13));
546   EXPECT_FALSE(last_pdu);
547 }
548 
549 // See Core Spec v5.0, Volume 3, Part A, Sec 5.4, Table 8.6.5.8, for the row
550 // with "Recv ReqSeqAndFbit" and "F = 1".
TEST_F(EnhancedRetransmissionModeTxEngineTest,EngineStopsPollingReceiverReadyFromMonitorTaskAfterReceivingFinalUpdateForAckSeq)551 TEST_F(
552     EnhancedRetransmissionModeTxEngineTest,
553     EngineStopsPollingReceiverReadyFromMonitorTaskAfterReceivingFinalUpdateForAckSeq) {
554   constexpr size_t kMaxTransmissions = 3;  // Allow multiple retransmissions
555   ByteBufferPtr last_pdu;
556   TxEngine tx_engine(kTestChannelId,
557                      kDefaultMTU,
558                      kMaxTransmissions,
559                      kDefaultTxWindow,
560                      channel(),
561                      NoOpFailureCallback,
562                      dispatcher());
563 
564   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
565   RunUntilIdle();
566 
567   ASSERT_TRUE(RunFor(std::chrono::seconds(2)));   // receiver_ready_poll_task_
568   ASSERT_TRUE(RunFor(std::chrono::seconds(12)));  // monitor_task_
569   tx_engine.UpdateAckSeq(1, /*is_poll_response=*/true);
570   EXPECT_FALSE(RunFor(std::chrono::seconds(13)));  // No other tasks.
571 }
572 
573 // See Core Spec v5.0, Volume 3, Part A, Sec 5.4, Table 8.6.5.8, for the row
574 // with "Recv ReqSeqAndFbit" and "F = 0".
TEST_F(EnhancedRetransmissionModeTxEngineTest,EngineContinuesPollingReceiverReadyFromMonitorTaskAfterReceivingNonFinalUpdateForAckSeq)575 TEST_F(
576     EnhancedRetransmissionModeTxEngineTest,
577     EngineContinuesPollingReceiverReadyFromMonitorTaskAfterReceivingNonFinalUpdateForAckSeq) {
578   constexpr size_t kMaxTransmissions = 2;  // Allow retransmissions
579   ByteBufferPtr last_pdu;
580   channel().HandleSendFrame([&](auto pdu) { last_pdu = std::move(pdu); });
581   TxEngine tx_engine(kTestChannelId,
582                      kDefaultMTU,
583                      kMaxTransmissions,
584                      kDefaultTxWindow,
585                      channel(),
586                      NoOpFailureCallback,
587                      dispatcher());
588 
589   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
590   RunUntilIdle();
591 
592   ASSERT_TRUE(RunFor(std::chrono::seconds(2)));   // receiver_ready_poll_task_
593   ASSERT_TRUE(RunFor(std::chrono::seconds(12)));  // monitor_task_
594   tx_engine.UpdateAckSeq(1, /*is_poll_response=*/false);
595   EXPECT_TRUE(RunFor(std::chrono::seconds(12)));  // monitor_task_
596   VerifyIsReceiverReadyPollFrame(last_pdu.get());
597 }
598 
TEST_F(EnhancedRetransmissionModeTxEngineTest,EngineRetransmitsReceiverReadyPollAfterMultipleMonitorTimeouts)599 TEST_F(EnhancedRetransmissionModeTxEngineTest,
600        EngineRetransmitsReceiverReadyPollAfterMultipleMonitorTimeouts) {
601   constexpr size_t kMaxTransmissions = 3;  // Allow multiple retransmissions
602   ByteBufferPtr last_pdu;
603   channel().HandleSendFrame([&](auto pdu) { last_pdu = std::move(pdu); });
604   TxEngine tx_engine(kTestChannelId,
605                      kDefaultMTU,
606                      kMaxTransmissions,
607                      kDefaultTxWindow,
608                      channel(),
609                      NoOpFailureCallback,
610                      dispatcher());
611 
612   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
613   RunUntilIdle();
614 
615   ASSERT_TRUE(RunFor(std::chrono::seconds(2)));   // receiver_ready_poll_task_
616   ASSERT_TRUE(RunFor(std::chrono::seconds(12)));  // monitor_task_
617   ASSERT_FALSE(
618       RunFor(std::chrono::seconds(2)));  // RR-poll task does _not_ fire
619   last_pdu = nullptr;
620 
621   EXPECT_TRUE(RunFor(std::chrono::seconds(10)));  // monitor_task_ again
622   VerifyIsReceiverReadyPollFrame(last_pdu.get());
623 }
624 
TEST_F(EnhancedRetransmissionModeTxEngineTest,EngineRetransmitsReceiverReadyPollIndefinitelyAfterMonitorTimeoutWhenMaxTransmitsIsZero)625 TEST_F(
626     EnhancedRetransmissionModeTxEngineTest,
627     EngineRetransmitsReceiverReadyPollIndefinitelyAfterMonitorTimeoutWhenMaxTransmitsIsZero) {
628   constexpr size_t kMaxTransmissions = 0;
629   ByteBufferPtr last_pdu;
630   channel().HandleSendFrame([&](auto pdu) { last_pdu = std::move(pdu); });
631   TxEngine tx_engine(kTestChannelId,
632                      kDefaultMTU,
633                      kMaxTransmissions,
634                      kDefaultTxWindow,
635                      channel(),
636                      NoOpFailureCallback,
637                      dispatcher());
638 
639   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
640   RunUntilIdle();
641 
642   // First the receiver_ready_poll_task_ fires.
643   ASSERT_TRUE(RunFor(std::chrono::seconds(2)));
644   EXPECT_TRUE(last_pdu);
645   last_pdu = nullptr;
646 
647   // Then the monitor_task_ fires.
648   EXPECT_TRUE(RunFor(std::chrono::seconds(12)));
649   EXPECT_TRUE(last_pdu);
650   last_pdu = nullptr;
651 
652   // And the monitor_task_ fires again.
653   EXPECT_TRUE(RunFor(std::chrono::seconds(12)));
654   EXPECT_TRUE(last_pdu);
655   last_pdu = nullptr;
656 
657   // And the monitor_task_ fires yet again.
658   EXPECT_TRUE(RunFor(std::chrono::seconds(12)));
659   EXPECT_TRUE(last_pdu);
660 }
661 
TEST_F(EnhancedRetransmissionModeTxEngineTest,EngineStopsTransmittingReceiverReadyPollAfterMaxTransmits)662 TEST_F(EnhancedRetransmissionModeTxEngineTest,
663        EngineStopsTransmittingReceiverReadyPollAfterMaxTransmits) {
664   constexpr size_t kMaxTransmissions = 2;
665   ByteBufferPtr last_pdu;
666   channel().HandleSendFrame([&](auto pdu) { last_pdu = std::move(pdu); });
667   TxEngine tx_engine(kTestChannelId,
668                      kDefaultMTU,
669                      kMaxTransmissions,
670                      kDefaultTxWindow,
671                      channel(),
672                      NoOpFailureCallback,
673                      dispatcher());
674 
675   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
676   RunUntilIdle();
677 
678   ASSERT_TRUE(RunFor(std::chrono::seconds(2)));   // receiver_ready_poll_task_
679   ASSERT_TRUE(RunFor(std::chrono::seconds(12)));  // monitor_task_
680   ASSERT_TRUE(RunFor(std::chrono::seconds(12)));  // monitor_task_
681   last_pdu = nullptr;
682 
683   EXPECT_FALSE(RunFor(std::chrono::seconds(13)));
684   EXPECT_FALSE(last_pdu);
685 }
686 
TEST_F(EnhancedRetransmissionModeTxEngineTest,EngineClosesChannelAfterMaxTransmitsOfReceiverReadyPoll)687 TEST_F(EnhancedRetransmissionModeTxEngineTest,
688        EngineClosesChannelAfterMaxTransmitsOfReceiverReadyPoll) {
689   constexpr size_t kMaxTransmissions = 2;
690   bool connection_failed = false;
691   TxEngine tx_engine(
692       kTestChannelId,
693       kDefaultMTU,
694       kMaxTransmissions,
695       kDefaultTxWindow,
696       channel(),
697       [&] { connection_failed = true; },
698       dispatcher());
699 
700   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
701   RunUntilIdle();
702 
703   ASSERT_TRUE(RunFor(std::chrono::seconds(2)));   // receiver_ready_poll_task_
704   ASSERT_TRUE(RunFor(std::chrono::seconds(12)));  // monitor_task_
705   ASSERT_TRUE(RunFor(std::chrono::seconds(12)));  // monitor_task_
706   EXPECT_TRUE(connection_failed);
707 }
708 
TEST_F(EnhancedRetransmissionModeTxEngineTest,EngineClosesChannelAfterMaxTransmitsOfReceiverReadyPollEvenIfRetransmissionsAreDisabled)709 TEST_F(
710     EnhancedRetransmissionModeTxEngineTest,
711     EngineClosesChannelAfterMaxTransmitsOfReceiverReadyPollEvenIfRetransmissionsAreDisabled) {
712   constexpr size_t kMaxTransmissions = 1;
713   bool connection_failed = false;
714   TxEngine tx_engine(
715       kTestChannelId,
716       kDefaultMTU,
717       kMaxTransmissions,
718       kDefaultTxWindow,
719       channel(),
720       [&] { connection_failed = true; },
721       dispatcher());
722 
723   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
724   RunUntilIdle();
725 
726   ASSERT_TRUE(RunFor(std::chrono::seconds(2)));   // receiver_ready_poll_task_
727   ASSERT_TRUE(RunFor(std::chrono::seconds(12)));  // monitor_task_
728   EXPECT_TRUE(connection_failed);
729 }
730 
TEST_F(EnhancedRetransmissionModeTxEngineTest,EngineClosesChannelAfterMaxTransmitsOfIFrame)731 TEST_F(EnhancedRetransmissionModeTxEngineTest,
732        EngineClosesChannelAfterMaxTransmitsOfIFrame) {
733   constexpr size_t kMaxTransmissions = 2;
734   size_t num_info_frames_sent = 0;
735   bool connection_failed = false;
736   channel().HandleSendFrame([&](ByteBufferPtr pdu) {
737     if (pdu->size() >= sizeof(EnhancedControlField) &&
738         pdu->To<EnhancedControlField>().designates_information_frame()) {
739       ++num_info_frames_sent;
740     }
741   });
742   TxEngine tx_engine(
743       kTestChannelId,
744       kDefaultMTU,
745       kMaxTransmissions,
746       kDefaultTxWindow,
747       channel(),
748       [&] { connection_failed = true; },
749       dispatcher());
750 
751   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
752   RunUntilIdle();
753   ASSERT_EQ(1u, num_info_frames_sent);
754 
755   // Not having received an acknowledgement after 2 seconds,
756   // receiver_ready_poll_task_ will fire, and cause us to send a
757   // ReceiverReadyPoll.
758   ASSERT_TRUE(RunFor(std::chrono::seconds(2)));
759 
760   // The peer indicates that it has not received any frames. This causes us to
761   // retransmit the frame.
762   tx_engine.UpdateAckSeq(0, /*is_poll_response=*/true);
763   EXPECT_EQ(2u, num_info_frames_sent);
764 
765   // Not having received an acknowledgement after 2 seconds,
766   // receiver_ready_poll_task_ will fire, and cause us to send another
767   // ReceiverReadyPoll.
768   ASSERT_TRUE(RunFor(std::chrono::seconds(2)));
769 
770   // The connection should remain open, to allow the peer time to respond to our
771   // poll, and acknowledge the outstanding frame.
772   EXPECT_FALSE(connection_failed);
773 
774   // The peer again indicates that it has not received any frames.
775   tx_engine.UpdateAckSeq(0, /*is_poll_response=*/true);
776 
777   // Because we've exhausted kMaxTransmissions, the connection will be closed.
778   EXPECT_TRUE(connection_failed);
779 }
780 
TEST_F(EnhancedRetransmissionModeTxEngineTest,EngineExhaustsAllRetransmissionsOfIFrameBeforeClosingChannel)781 TEST_F(EnhancedRetransmissionModeTxEngineTest,
782        EngineExhaustsAllRetransmissionsOfIFrameBeforeClosingChannel) {
783   constexpr size_t kMaxTransmissions = 255;
784   size_t num_info_frames_sent = 0;
785   bool connection_failed = false;
786   channel().HandleSendFrame([&](ByteBufferPtr pdu) {
787     if (pdu->size() >= sizeof(EnhancedControlField) &&
788         pdu->To<EnhancedControlField>().designates_information_frame()) {
789       ++num_info_frames_sent;
790     }
791   });
792   TxEngine tx_engine(
793       kTestChannelId,
794       kDefaultMTU,
795       kMaxTransmissions,
796       kDefaultTxWindow,
797       channel(),
798       [&] { connection_failed = true; },
799       dispatcher());
800 
801   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
802   RunUntilIdle();
803 
804   for (size_t i = 0; i < kMaxTransmissions; ++i) {
805     // Not having received an acknowledgement after 2 seconds,
806     // receiver_ready_poll_task_ will fire, and cause us to send a
807     // ReceiverReadyPoll.
808     ASSERT_TRUE(RunFor(std::chrono::seconds(2))) << "(i=" << i << ")";
809 
810     // The connection should remain open, to allow the peer time to respond to
811     // our poll, and acknowledge the outstanding frame.
812     EXPECT_FALSE(connection_failed);
813 
814     // The peer indicates that it has not received any frames.
815     tx_engine.UpdateAckSeq(0, /*is_poll_response=*/true);
816   }
817 
818   // The connection is closed, and we've exhausted kMaxTransmissions.
819   EXPECT_TRUE(connection_failed);
820   EXPECT_EQ(255u, num_info_frames_sent);
821 }
822 
TEST_F(EnhancedRetransmissionModeTxEngineTest,EngineRetransmitsIFrameIndefinitelyWhenMaxTransmitsIsZero)823 TEST_F(EnhancedRetransmissionModeTxEngineTest,
824        EngineRetransmitsIFrameIndefinitelyWhenMaxTransmitsIsZero) {
825   constexpr size_t kMaxTransmissions = 0;
826   constexpr size_t kTxWindow = 2;
827   size_t num_info_frames_sent = 0;
828   bool connection_failed = false;
829   ByteBufferPtr last_tx_frame = nullptr;
830   channel().HandleSendFrame([&](ByteBufferPtr pdu) {
831     if (pdu->size() >= sizeof(EnhancedControlField) &&
832         pdu->To<EnhancedControlField>().designates_information_frame()) {
833       ++num_info_frames_sent;
834       last_tx_frame = std::move(pdu);
835     }
836   });
837   TxEngine tx_engine(
838       kTestChannelId,
839       kDefaultMTU,
840       kMaxTransmissions,
841       kTxWindow,
842       channel(),
843       [&] { connection_failed = true; },
844       dispatcher());
845 
846   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
847   EXPECT_EQ(1u, num_info_frames_sent);
848 
849   // This test should trigger enough transmissions to overflow an 8-bit transmit
850   // counter.
851   const auto kNumTransmissions =
852       size_t{2} * std::numeric_limits<uint8_t>::max();
853 
854   // Retransmissions after the initial one triggered by QueueSdu
855   for (size_t i = 0; i < kNumTransmissions - 1; ++i) {
856     // Not having received an acknowledgement after 2 seconds,
857     // receiver_ready_poll_task_ will fire, and cause us to send a
858     // ReceiverReadyPoll.
859     ASSERT_TRUE(RunFor(std::chrono::seconds(2))) << "(i=" << i << ")";
860 
861     // The connection should remain open, to allow the peer time to respond to
862     // our poll, and acknowledge the outstanding frame.
863     EXPECT_FALSE(connection_failed);
864 
865     // The peer indicates that it has not received any frames.
866     tx_engine.UpdateAckSeq(0, /*is_poll_response=*/true);
867   }
868 
869   // The connection is still open and we have transmitted more times than the
870   // greatest possible finite MaxTransmit option (which is 8-bit).
871   EXPECT_FALSE(connection_failed);
872   EXPECT_EQ(kNumTransmissions, num_info_frames_sent);
873 
874   // Check that the outbound frame's transmit count hasn't overflowed to zero by
875   // transmitting a different payload.
876   ASSERT_TRUE(ContainersEqual(
877       kDefaultPayload, last_tx_frame->view(sizeof(EnhancedControlField))));
878   num_info_frames_sent = 0;
879 
880   // If the first frame's transmit count had overflowed to zero, it would get
881   // sent out together with this new SDU because it would be indistinguishable
882   // from "never transmitted."
883   QueueSdu(tx_engine,
884            std::make_unique<DynamicByteBuffer>(StaticByteBuffer('@')));
885   EXPECT_EQ(1u, num_info_frames_sent);
886   EXPECT_EQ('@', (*last_tx_frame)[sizeof(EnhancedControlField)]);
887 }
888 
TEST_F(EnhancedRetransmissionModeTxEngineTest,EngineClosesChannelAfterMaxTransmitsOfIFrameEvenIfRetransmissionsAreDisabled)889 TEST_F(
890     EnhancedRetransmissionModeTxEngineTest,
891     EngineClosesChannelAfterMaxTransmitsOfIFrameEvenIfRetransmissionsAreDisabled) {
892   constexpr size_t kMaxTransmissions = 1;
893   bool connection_failed = false;
894   TxEngine tx_engine(
895       kTestChannelId,
896       kDefaultMTU,
897       kMaxTransmissions,
898       kDefaultTxWindow,
899       channel(),
900       [&] { connection_failed = true; },
901       dispatcher());
902 
903   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
904   RunUntilIdle();
905 
906   // Not having received an acknowledgement after 2 seconds,
907   // receiver_ready_poll_task_ will fire, and cause us to send a
908   // ReceiverReadyPoll.
909   ASSERT_TRUE(RunFor(std::chrono::seconds(2)));
910 
911   // The connection should remain open, to allow the peer time to respond to our
912   // poll, and acknowledge the outstanding frame.
913   EXPECT_FALSE(connection_failed);
914 
915   // The peer indicates that it has not received any frames.
916   tx_engine.UpdateAckSeq(0, /*is_poll_response=*/true);
917   EXPECT_TRUE(connection_failed);
918 }
919 
TEST_F(EnhancedRetransmissionModeTxEngineTest,EngineRetransmitsMissingFrameOnPollResponse)920 TEST_F(EnhancedRetransmissionModeTxEngineTest,
921        EngineRetransmitsMissingFrameOnPollResponse) {
922   constexpr size_t kMaxTransmissions = 2;
923   ByteBufferPtr last_pdu;
924   channel().HandleSendFrame([&](auto pdu) { last_pdu = std::move(pdu); });
925   TxEngine tx_engine(kTestChannelId,
926                      kDefaultMTU,
927                      kMaxTransmissions,
928                      kDefaultTxWindow,
929                      channel(),
930                      NoOpFailureCallback,
931                      dispatcher());
932 
933   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
934   RunUntilIdle();
935   last_pdu = nullptr;
936 
937   ASSERT_TRUE(RunFor(std::chrono::seconds(2)));  // receiver_ready_poll_task_
938   last_pdu = nullptr;
939 
940   tx_engine.UpdateAckSeq(0, /*is_poll_response=*/true);
941   ASSERT_TRUE(last_pdu);
942   ASSERT_GE(last_pdu->size(), sizeof(SimpleInformationFrameHeader));
943   ASSERT_TRUE(
944       last_pdu->To<EnhancedControlField>().designates_information_frame());
945   EXPECT_EQ(0u, last_pdu->To<SimpleInformationFrameHeader>().tx_seq());
946 }
947 
TEST_F(EnhancedRetransmissionModeTxEngineTest,EngineRetransmitsAllMissingFramesOnPollResponse)948 TEST_F(EnhancedRetransmissionModeTxEngineTest,
949        EngineRetransmitsAllMissingFramesOnPollResponse) {
950   constexpr size_t kMaxTransmissions = 2;
951   constexpr size_t kTxWindow = 63;
952   size_t n_pdus = 0;
953   ByteBufferPtr last_pdu;
954   channel().HandleSendFrame([&](auto pdu) {
955     ++n_pdus;
956     last_pdu = std::move(pdu);
957   });
958   TxEngine tx_engine(kTestChannelId,
959                      kDefaultMTU,
960                      kMaxTransmissions,
961                      kTxWindow,
962                      channel(),
963                      NoOpFailureCallback,
964                      dispatcher());
965 
966   // Send a TxWindow's worth of frames.
967   for (size_t i = 0; i < kTxWindow; ++i) {
968     QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
969   }
970   RunUntilIdle();
971 
972   // Let receiver_ready_poll_task_ fire, and clear out accumulated callback
973   // state.
974   ASSERT_TRUE(RunFor(std::chrono::seconds(2)));
975   n_pdus = 0;
976   last_pdu = nullptr;
977 
978   tx_engine.UpdateAckSeq(0, /*is_poll_response=*/true);
979   EXPECT_EQ(kTxWindow, n_pdus);
980   ASSERT_TRUE(last_pdu);
981   ASSERT_GE(last_pdu->size(), sizeof(SimpleInformationFrameHeader));
982   ASSERT_TRUE(
983       last_pdu->To<EnhancedControlField>().designates_information_frame());
984   EXPECT_EQ(kTxWindow - 1,
985             last_pdu->To<SimpleInformationFrameHeader>().tx_seq());
986 }
987 
TEST_F(EnhancedRetransmissionModeTxEngineTest,EngineRetransmitsAllMissingFramesOnPollResponseWithWrappedSequenceNumber)988 TEST_F(
989     EnhancedRetransmissionModeTxEngineTest,
990     EngineRetransmitsAllMissingFramesOnPollResponseWithWrappedSequenceNumber) {
991   constexpr size_t kMaxTransmissions = 2;
992   constexpr size_t kTxWindow = 63;
993   size_t n_pdus = 0;
994   ByteBufferPtr last_pdu;
995   channel().HandleSendFrame([&](auto pdu) {
996     ++n_pdus;
997     last_pdu = std::move(pdu);
998   });
999   TxEngine tx_engine(kTestChannelId,
1000                      kDefaultMTU,
1001                      kMaxTransmissions,
1002                      kTxWindow,
1003                      channel(),
1004                      NoOpFailureCallback,
1005                      dispatcher());
1006 
1007   // Send a TxWindow's worth of frames.
1008   for (size_t i = 0; i < kTxWindow; ++i) {
1009     QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1010   }
1011 
1012   // Acknowledge the first 32 of these frames (with sequence numbers 0...31).
1013   tx_engine.UpdateAckSeq(32, /*is_poll_response=*/false);
1014 
1015   // Queue 32 new frames (with sequence numbers 63, 0 ... 30).
1016   for (size_t i = 0; i < 32; ++i) {
1017     QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1018   }
1019   RunUntilIdle();
1020 
1021   // Let receiver_ready_poll_task_ fire, and then clear out accumulated callback
1022   // state.
1023   ASSERT_TRUE(RunFor(std::chrono::seconds(2)));
1024   n_pdus = 0;
1025   last_pdu = nullptr;
1026 
1027   // Repeat the earlier acknowledgement. This indicates that the peer has
1028   // not received frame 32.
1029   tx_engine.UpdateAckSeq(32, /*is_poll_response=*/true);
1030 
1031   // We expect to retransmit frames 32...63, and then 0...30. That's 63 frames
1032   // in total.
1033   EXPECT_EQ(63u, n_pdus);
1034   ASSERT_TRUE(last_pdu);
1035   ASSERT_GE(last_pdu->size(), sizeof(SimpleInformationFrameHeader));
1036   ASSERT_TRUE(
1037       last_pdu->To<EnhancedControlField>().designates_information_frame());
1038   EXPECT_EQ(30u, last_pdu->To<SimpleInformationFrameHeader>().tx_seq());
1039 }
1040 
TEST_F(EnhancedRetransmissionModeTxEngineTest,EngineProperlyHandlesPartialAckWithWrappedSequenceNumber)1041 TEST_F(EnhancedRetransmissionModeTxEngineTest,
1042        EngineProperlyHandlesPartialAckWithWrappedSequenceNumber) {
1043   constexpr size_t kMaxTransmissions = 2;
1044   constexpr size_t kTxWindow = 63;
1045   size_t n_pdus = 0;
1046   ByteBufferPtr last_pdu;
1047   channel().HandleSendFrame([&](auto pdu) {
1048     ++n_pdus;
1049     last_pdu = std::move(pdu);
1050   });
1051   TxEngine tx_engine(kTestChannelId,
1052                      kDefaultMTU,
1053                      kMaxTransmissions,
1054                      kTxWindow,
1055                      channel(),
1056                      NoOpFailureCallback,
1057                      dispatcher());
1058 
1059   // Send a TxWindow's worth of frames.
1060   for (size_t i = 0; i < kTxWindow; ++i) {
1061     QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1062   }
1063 
1064   // Acknowledge the first 62 of these frames (with sequence numbers 0...61).
1065   tx_engine.UpdateAckSeq(62, /*is_poll_response=*/false);
1066 
1067   // Queue 62 new frames. These frames have sequence numebrs 63, 0...60.
1068   // (Sequence number 62 was used when we queued the first batch of frames
1069   // above.)
1070   for (size_t i = 0; i < 62; ++i) {
1071     QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1072   }
1073   RunUntilIdle();
1074 
1075   // Let receiver_ready_poll_task_ fire, and then clear out accumulated callback
1076   // state.
1077   ASSERT_TRUE(RunFor(std::chrono::seconds(2)));
1078   n_pdus = 0;
1079   last_pdu = nullptr;
1080 
1081   // Acknowledge an additional 5 frames (with sequence numbers 62, 63, 0, 1, 2).
1082   tx_engine.UpdateAckSeq(3, /*is_poll_response=*/true);
1083 
1084   // Verify that all unacknowledged frames are retransmitted.
1085   EXPECT_EQ(58u, n_pdus);
1086   ASSERT_TRUE(last_pdu);
1087   ASSERT_GE(last_pdu->size(), sizeof(SimpleInformationFrameHeader));
1088   ASSERT_TRUE(
1089       last_pdu->To<EnhancedControlField>().designates_information_frame());
1090   EXPECT_EQ(60u, last_pdu->To<SimpleInformationFrameHeader>().tx_seq());
1091 }
1092 
TEST_F(EnhancedRetransmissionModeTxEngineTest,EngineDoesNotRetransmitFramesBeyondTxWindow)1093 TEST_F(EnhancedRetransmissionModeTxEngineTest,
1094        EngineDoesNotRetransmitFramesBeyondTxWindow) {
1095   constexpr size_t kMaxTransmissions = 2;
1096   constexpr size_t kTxWindow = 32;
1097   size_t n_pdus = 0;
1098   ByteBufferPtr last_pdu;
1099   channel().HandleSendFrame([&](auto pdu) {
1100     ++n_pdus;
1101     last_pdu = std::move(pdu);
1102   });
1103   TxEngine tx_engine(kTestChannelId,
1104                      kDefaultMTU,
1105                      kMaxTransmissions,
1106                      kTxWindow,
1107                      channel(),
1108                      NoOpFailureCallback,
1109                      dispatcher());
1110 
1111   // Queue two TxWindow's worth of frames. These have sequence numbers 0...63.
1112   for (size_t i = 0; i < 2 * kTxWindow; ++i) {
1113     QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1114   }
1115   RunUntilIdle();
1116 
1117   // Let receiver_ready_poll_task_ fire, and clear out accumulated callback
1118   // state.
1119   ASSERT_TRUE(RunFor(std::chrono::seconds(2)));
1120   n_pdus = 0;
1121   last_pdu = nullptr;
1122 
1123   tx_engine.UpdateAckSeq(0, /*is_poll_response=*/true);
1124   EXPECT_EQ(kTxWindow, n_pdus);
1125   ASSERT_TRUE(last_pdu);
1126   ASSERT_GE(last_pdu->size(), sizeof(SimpleInformationFrameHeader));
1127   EXPECT_EQ(kTxWindow - 1,
1128             last_pdu->To<SimpleInformationFrameHeader>().tx_seq());
1129 }
1130 
TEST_F(EnhancedRetransmissionModeTxEngineTest,EngineDoesNotRetransmitFramesBeyondTxWindowWhenWindowWraps)1131 TEST_F(EnhancedRetransmissionModeTxEngineTest,
1132        EngineDoesNotRetransmitFramesBeyondTxWindowWhenWindowWraps) {
1133   constexpr size_t kMaxTransmissions = 2;
1134   constexpr size_t kTxWindow = 48;
1135   size_t n_pdus = 0;
1136   ByteBufferPtr last_pdu;
1137   channel().HandleSendFrame([&](auto pdu) {
1138     ++n_pdus;
1139     last_pdu = std::move(pdu);
1140   });
1141   TxEngine tx_engine(kTestChannelId,
1142                      kDefaultMTU,
1143                      kMaxTransmissions,
1144                      kTxWindow,
1145                      channel(),
1146                      NoOpFailureCallback,
1147                      dispatcher());
1148 
1149   // Queue one TxWindow's worth of frames. This advances the sequence numbers,
1150   // so that further transmissions can wrap.
1151   for (size_t i = 0; i < 48; ++i) {
1152     QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1153   }
1154   tx_engine.UpdateAckSeq(48, /*is_poll_response=*/false);
1155   RunUntilIdle();
1156 
1157   // Queue another TxWindow's worth of frames. These have sequence
1158   // numbers 48..63, and 0..31. These _should_ be retransmitted at the next
1159   // UpdateAckSeq() call.
1160   for (size_t i = 0; i < 48; ++i) {
1161     QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1162   }
1163   RunUntilIdle();
1164 
1165   // Queue a few more frames, with sequence numbers 32..39. These should _not_
1166   // be retransmitted at the next UpdateAckSeq() call.
1167   for (size_t i = 0; i < 8; ++i) {
1168     QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1169   }
1170   RunUntilIdle();
1171 
1172   // Let receiver_ready_poll_task_ fire, and clear out accumulated callback
1173   // state.
1174   ASSERT_TRUE(RunFor(std::chrono::seconds(2)));
1175   n_pdus = 0;
1176   last_pdu = nullptr;
1177 
1178   // Report that the peer has not received frame 48. This should trigger
1179   // retranmissions of unacknowledged frames within the TxWindow.
1180   tx_engine.UpdateAckSeq(48, /*is_poll_response=*/true);
1181 
1182   // We expect to retransmit frames 48..63 and 0..31. The other frames are
1183   // beyond the transmit window.
1184   EXPECT_EQ(48u, n_pdus);
1185   ASSERT_TRUE(last_pdu);
1186   ASSERT_GE(last_pdu->size(), sizeof(SimpleInformationFrameHeader));
1187   ASSERT_TRUE(
1188       last_pdu->To<EnhancedControlField>().designates_information_frame());
1189   EXPECT_EQ(31u, last_pdu->To<SimpleInformationFrameHeader>().tx_seq());
1190 }
1191 
TEST_F(EnhancedRetransmissionModeTxEngineTest,EngineDoesNotRetransmitPreviouslyAckedFramesOnPollResponse)1192 TEST_F(EnhancedRetransmissionModeTxEngineTest,
1193        EngineDoesNotRetransmitPreviouslyAckedFramesOnPollResponse) {
1194   constexpr size_t kMaxTransmissions = 2;
1195   constexpr size_t kTxWindow = 2;
1196   size_t n_pdus = 0;
1197   ByteBufferPtr last_pdu;
1198   channel().HandleSendFrame([&](auto pdu) {
1199     ++n_pdus;
1200     last_pdu = std::move(pdu);
1201   });
1202   TxEngine tx_engine(kTestChannelId,
1203                      kDefaultMTU,
1204                      kMaxTransmissions,
1205                      kTxWindow,
1206                      channel(),
1207                      NoOpFailureCallback,
1208                      dispatcher());
1209 
1210   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1211   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1212   RunUntilIdle();
1213 
1214   // Let receiver_ready_poll_task_ fire, and clear out accumulated callback
1215   // state.
1216   ASSERT_TRUE(RunFor(std::chrono::seconds(2)));
1217   n_pdus = 0;
1218   last_pdu = nullptr;
1219 
1220   constexpr size_t kPollResponseReqSeq = 1;
1221   tx_engine.UpdateAckSeq(kPollResponseReqSeq, /*is_poll_response=*/true);
1222   EXPECT_EQ(kTxWindow - kPollResponseReqSeq, n_pdus);
1223   ASSERT_TRUE(last_pdu);
1224   ASSERT_GE(last_pdu->size(), sizeof(SimpleInformationFrameHeader));
1225   ASSERT_TRUE(
1226       last_pdu->To<EnhancedControlField>().designates_information_frame());
1227   EXPECT_EQ(1, last_pdu->To<SimpleInformationFrameHeader>().tx_seq());
1228 }
1229 
TEST_F(EnhancedRetransmissionModeTxEngineTest,AckOfFrameWithNoneOutstandingClosesChannel)1230 TEST_F(EnhancedRetransmissionModeTxEngineTest,
1231        AckOfFrameWithNoneOutstandingClosesChannel) {
1232   bool connection_failed = false;
1233   TxEngine tx_engine(
1234       kTestChannelId,
1235       kDefaultMTU,
1236       kDefaultMaxTransmissions,
1237       kDefaultTxWindow,
1238       channel(),
1239       [&] { connection_failed = true; },
1240       dispatcher());
1241 
1242   tx_engine.UpdateAckSeq(1, /*is_poll_response=*/false);
1243   EXPECT_TRUE(connection_failed);
1244 }
1245 
TEST_F(EnhancedRetransmissionModeTxEngineTest,AckOfMoreFramesThanAreOutstandingClosesChannel)1246 TEST_F(EnhancedRetransmissionModeTxEngineTest,
1247        AckOfMoreFramesThanAreOutstandingClosesChannel) {
1248   bool connection_failed = false;
1249   TxEngine tx_engine(
1250       kTestChannelId,
1251       kDefaultMTU,
1252       kDefaultMaxTransmissions,
1253       kDefaultTxWindow,
1254       channel(),
1255       [&] { connection_failed = true; },
1256       dispatcher());
1257 
1258   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1259   tx_engine.UpdateAckSeq(2, /*is_poll_response=*/true);
1260   EXPECT_TRUE(connection_failed);
1261 }
1262 
TEST_F(EnhancedRetransmissionModeTxEngineTest,EngineDoesNotCrashOnSpuriousAckAfterValidAck)1263 TEST_F(EnhancedRetransmissionModeTxEngineTest,
1264        EngineDoesNotCrashOnSpuriousAckAfterValidAck) {
1265   TxEngine tx_engine(kTestChannelId,
1266                      kDefaultMTU,
1267                      kDefaultMaxTransmissions,
1268                      kDefaultTxWindow,
1269                      channel(),
1270                      NoOpFailureCallback,
1271                      dispatcher());
1272   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1273   RunUntilIdle();
1274   tx_engine.UpdateAckSeq(1, /*is_poll_response=*/true);
1275   tx_engine.UpdateAckSeq(2, /*is_poll_response=*/true);
1276 }
1277 
TEST_F(EnhancedRetransmissionModeTxEngineTest,EngineDoesNotCrashOnSpuriousAckBeforeAnyDataHasBeenSent)1278 TEST_F(EnhancedRetransmissionModeTxEngineTest,
1279        EngineDoesNotCrashOnSpuriousAckBeforeAnyDataHasBeenSent) {
1280   TxEngine tx_engine(kTestChannelId,
1281                      kDefaultMTU,
1282                      kDefaultMaxTransmissions,
1283                      kDefaultTxWindow,
1284                      channel(),
1285                      NoOpFailureCallback,
1286                      dispatcher());
1287   for (uint8_t i = 0; i <= EnhancedControlField::kMaxSeqNum; ++i) {
1288     tx_engine.UpdateAckSeq(i, /*is_poll_response=*/true);
1289   }
1290 }
1291 
TEST_F(EnhancedRetransmissionModeTxEngineTest,QueueSduDoesNotTransmitFramesWhenRemoteIsBusy)1292 TEST_F(EnhancedRetransmissionModeTxEngineTest,
1293        QueueSduDoesNotTransmitFramesWhenRemoteIsBusy) {
1294   size_t n_pdus = 0;
1295   channel().HandleSendFrame([&](auto) { ++n_pdus; });
1296   TxEngine tx_engine(kTestChannelId,
1297                      kDefaultMTU,
1298                      kDefaultMaxTransmissions,
1299                      kDefaultTxWindow,
1300                      channel(),
1301                      NoOpFailureCallback,
1302                      dispatcher());
1303 
1304   tx_engine.SetRemoteBusy();
1305   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1306   RunUntilIdle();
1307   EXPECT_EQ(0u, n_pdus);
1308 }
1309 
TEST_F(EnhancedRetransmissionModeTxEngineTest,UpdateAckSeqTransmitsQueuedDataWhenPossible)1310 TEST_F(EnhancedRetransmissionModeTxEngineTest,
1311        UpdateAckSeqTransmitsQueuedDataWhenPossible) {
1312   constexpr size_t kTxWindow = 1;
1313   size_t n_pdus = 0;
1314   channel().HandleSendFrame([&](auto) { ++n_pdus; });
1315   TxEngine tx_engine(kTestChannelId,
1316                      kDefaultMTU,
1317                      kDefaultMaxTransmissions,
1318                      kTxWindow,
1319                      channel(),
1320                      NoOpFailureCallback,
1321                      dispatcher());
1322 
1323   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1324   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1325   RunUntilIdle();
1326   ASSERT_EQ(1u, n_pdus);
1327 
1328   n_pdus = 0;
1329   tx_engine.UpdateAckSeq(1, /*is_poll_response=*/false);
1330   RunUntilIdle();
1331   EXPECT_EQ(1u, n_pdus);
1332 }
1333 
TEST_F(EnhancedRetransmissionModeTxEngineTest,UpdateAckSeqTransmissionOfQueuedDataRespectsTxWindow)1334 TEST_F(EnhancedRetransmissionModeTxEngineTest,
1335        UpdateAckSeqTransmissionOfQueuedDataRespectsTxWindow) {
1336   constexpr size_t kTxWindow = 1;
1337   size_t n_pdus = 0;
1338   channel().HandleSendFrame([&](auto) { ++n_pdus; });
1339   TxEngine tx_engine(kTestChannelId,
1340                      kDefaultMTU,
1341                      kDefaultMaxTransmissions,
1342                      kTxWindow,
1343                      channel(),
1344                      NoOpFailureCallback,
1345                      dispatcher());
1346 
1347   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1348   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1349   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1350   RunUntilIdle();
1351   ASSERT_EQ(1u, n_pdus);
1352 
1353   n_pdus = 0;
1354   tx_engine.UpdateAckSeq(1, /*is_poll_response=*/false);
1355   RunUntilIdle();
1356   EXPECT_EQ(1u, n_pdus);
1357 }
1358 
TEST_F(EnhancedRetransmissionModeTxEngineTest,NonFinalUpdateAckSeqDoesNotTransmitQueuedFramesWhenRemoteIsBusy)1359 TEST_F(EnhancedRetransmissionModeTxEngineTest,
1360        NonFinalUpdateAckSeqDoesNotTransmitQueuedFramesWhenRemoteIsBusy) {
1361   constexpr size_t kTxWindow = 1;
1362   size_t n_pdus = 0;
1363   channel().HandleSendFrame([&](auto) { ++n_pdus; });
1364   TxEngine tx_engine(kTestChannelId,
1365                      kDefaultMTU,
1366                      kDefaultMaxTransmissions,
1367                      kTxWindow,
1368                      channel(),
1369                      NoOpFailureCallback,
1370                      dispatcher());
1371 
1372   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1373   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1374   RunUntilIdle();
1375   ASSERT_EQ(1u, n_pdus);
1376 
1377   n_pdus = 0;
1378   tx_engine.SetRemoteBusy();
1379   tx_engine.UpdateAckSeq(1, /*is_poll_response=*/false);
1380   RunUntilIdle();
1381   EXPECT_EQ(0u, n_pdus);
1382 }
1383 
TEST_F(EnhancedRetransmissionModeTxEngineTest,FinalUpdateAckSeqDoesNotTransmitQueuedFramesWhenRemoteIsBusy)1384 TEST_F(EnhancedRetransmissionModeTxEngineTest,
1385        FinalUpdateAckSeqDoesNotTransmitQueuedFramesWhenRemoteIsBusy) {
1386   constexpr size_t kTxWindow = 1;
1387   size_t n_pdus = 0;
1388   channel().HandleSendFrame([&](auto) { ++n_pdus; });
1389   TxEngine tx_engine(kTestChannelId,
1390                      kDefaultMTU,
1391                      kDefaultMaxTransmissions,
1392                      kTxWindow,
1393                      channel(),
1394                      NoOpFailureCallback,
1395                      dispatcher());
1396 
1397   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1398   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1399   RunUntilIdle();
1400   ASSERT_EQ(1u, n_pdus);
1401 
1402   n_pdus = 0;
1403   tx_engine.SetRemoteBusy();
1404   tx_engine.UpdateAckSeq(1, /*is_poll_response=*/true);
1405   RunUntilIdle();
1406   EXPECT_EQ(0u, n_pdus);
1407 }
1408 
TEST_F(EnhancedRetransmissionModeTxEngineTest,MaybeSendQueuedDataTransmitsAllQueuedFramesWithinTxWindow)1409 TEST_F(EnhancedRetransmissionModeTxEngineTest,
1410        MaybeSendQueuedDataTransmitsAllQueuedFramesWithinTxWindow) {
1411   constexpr size_t kTxWindow = 63;
1412   size_t n_pdus = 0;
1413   channel().HandleSendFrame([&](auto) { ++n_pdus; });
1414   TxEngine tx_engine(kTestChannelId,
1415                      kDefaultMTU,
1416                      kDefaultMaxTransmissions,
1417                      kTxWindow,
1418                      channel(),
1419                      NoOpFailureCallback,
1420                      dispatcher());
1421 
1422   tx_engine.SetRemoteBusy();
1423   for (size_t i = 0; i < kTxWindow; ++i) {
1424     QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1425   }
1426   RunUntilIdle();
1427   ASSERT_EQ(0u, n_pdus);
1428 
1429   tx_engine.ClearRemoteBusy();
1430   tx_engine.MaybeSendQueuedData();
1431   RunUntilIdle();
1432   EXPECT_EQ(kTxWindow, n_pdus);
1433 }
1434 
TEST_F(EnhancedRetransmissionModeTxEngineTest,MaybeSendQueuedDataDoesNotTransmitBeyondTxWindow)1435 TEST_F(EnhancedRetransmissionModeTxEngineTest,
1436        MaybeSendQueuedDataDoesNotTransmitBeyondTxWindow) {
1437   constexpr size_t kTxWindow = 32;
1438   size_t n_pdus = 0;
1439   channel().HandleSendFrame([&](auto) { ++n_pdus; });
1440   TxEngine tx_engine(kTestChannelId,
1441                      kDefaultMTU,
1442                      kDefaultMaxTransmissions,
1443                      kTxWindow,
1444                      channel(),
1445                      NoOpFailureCallback,
1446                      dispatcher());
1447 
1448   tx_engine.SetRemoteBusy();
1449   for (size_t i = 0; i < kTxWindow + 1; ++i) {
1450     QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1451   }
1452   RunUntilIdle();
1453   ASSERT_EQ(0u, n_pdus);
1454 
1455   tx_engine.ClearRemoteBusy();
1456   tx_engine.MaybeSendQueuedData();
1457   RunUntilIdle();
1458   EXPECT_EQ(kTxWindow, n_pdus);
1459 }
1460 
TEST_F(EnhancedRetransmissionModeTxEngineTest,MaybeSendQueuedDataRespectsRemoteBusy)1461 TEST_F(EnhancedRetransmissionModeTxEngineTest,
1462        MaybeSendQueuedDataRespectsRemoteBusy) {
1463   size_t n_pdus = 0;
1464   channel().HandleSendFrame([&](auto) { ++n_pdus; });
1465   TxEngine tx_engine(kTestChannelId,
1466                      kDefaultMTU,
1467                      kDefaultMaxTransmissions,
1468                      kDefaultTxWindow,
1469                      channel(),
1470                      NoOpFailureCallback,
1471                      dispatcher());
1472 
1473   tx_engine.SetRemoteBusy();
1474   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1475   RunUntilIdle();
1476   ASSERT_EQ(0u, n_pdus);
1477 
1478   tx_engine.MaybeSendQueuedData();
1479   RunUntilIdle();
1480   EXPECT_EQ(0u, n_pdus);
1481 }
1482 
TEST_F(EnhancedRetransmissionModeTxEngineTest,MaybeSendQueuedDataDoesNotCrashWhenCalledWithoutPendingPdus)1483 TEST_F(EnhancedRetransmissionModeTxEngineTest,
1484        MaybeSendQueuedDataDoesNotCrashWhenCalledWithoutPendingPdus) {
1485   TxEngine tx_engine(kTestChannelId,
1486                      kDefaultMTU,
1487                      kDefaultMaxTransmissions,
1488                      kDefaultTxWindow,
1489                      channel(),
1490                      NoOpFailureCallback,
1491                      dispatcher());
1492   tx_engine.MaybeSendQueuedData();
1493   RunUntilIdle();
1494 }
1495 
TEST_F(EnhancedRetransmissionModeTxEngineTest,QueueSduCanSendMoreFramesAfterClearingRemoteBusy)1496 TEST_F(EnhancedRetransmissionModeTxEngineTest,
1497        QueueSduCanSendMoreFramesAfterClearingRemoteBusy) {
1498   size_t n_pdus = 0;
1499   channel().HandleSendFrame([&](auto) { ++n_pdus; });
1500   TxEngine tx_engine(kTestChannelId,
1501                      kDefaultMTU,
1502                      kDefaultMaxTransmissions,
1503                      kDefaultTxWindow,
1504                      channel(),
1505                      NoOpFailureCallback,
1506                      dispatcher());
1507 
1508   tx_engine.SetRemoteBusy();
1509   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1510   RunUntilIdle();
1511   ASSERT_EQ(0u, n_pdus);
1512 
1513   tx_engine.ClearRemoteBusy();
1514   tx_engine.MaybeSendQueuedData();
1515   RunUntilIdle();
1516   ASSERT_EQ(1u, n_pdus);
1517   n_pdus = 0;
1518 
1519   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1520   RunUntilIdle();
1521   EXPECT_EQ(1u, n_pdus);
1522 }
1523 
TEST_F(EnhancedRetransmissionModeTxEngineTest,QueueSduMaintainsSduOrderingAfterClearRemoteBusy)1524 TEST_F(EnhancedRetransmissionModeTxEngineTest,
1525        QueueSduMaintainsSduOrderingAfterClearRemoteBusy) {
1526   std::vector<uint8_t> pdu_seq_numbers;
1527   channel().HandleSendFrame([&](ByteBufferPtr pdu) {
1528     if (pdu && pdu->size() >= sizeof(EnhancedControlField) &&
1529         pdu->To<EnhancedControlField>().designates_information_frame() &&
1530         pdu->size() >= sizeof(SimpleInformationFrameHeader)) {
1531       pdu_seq_numbers.push_back(
1532           pdu->To<SimpleInformationFrameHeader>().tx_seq());
1533     }
1534   });
1535   TxEngine tx_engine(kTestChannelId,
1536                      kDefaultMTU,
1537                      kDefaultMaxTransmissions,
1538                      kDefaultTxWindow,
1539                      channel(),
1540                      NoOpFailureCallback,
1541                      dispatcher());
1542 
1543   tx_engine.SetRemoteBusy();
1544   QueueSdu(tx_engine,
1545            std::make_unique<DynamicByteBuffer>(kDefaultPayload));  // seq=0
1546   RunUntilIdle();
1547   ASSERT_TRUE(pdu_seq_numbers.empty());
1548 
1549   tx_engine.ClearRemoteBusy();
1550   QueueSdu(tx_engine,
1551            std::make_unique<DynamicByteBuffer>(kDefaultPayload));  // seq=1
1552   RunUntilIdle();
1553 
1554   // This requirement isn't in the specification directly. But it seems
1555   // necessary given that we can sometimes exit the remote-busy condition
1556   // without transmitting the queued data. See Core Spec v5.0, Volume 3, Part A,
1557   // Table 8.7, row for "Recv RR (P=1)" for an example of such an operation.
1558   EXPECT_EQ((std::vector<uint8_t>{0, 1}), pdu_seq_numbers);
1559 }
1560 
TEST_F(EnhancedRetransmissionModeTxEngineTest,UpdateAckSeqRetransmitsUnackedFramesBeforeTransmittingQueuedFrames)1561 TEST_F(EnhancedRetransmissionModeTxEngineTest,
1562        UpdateAckSeqRetransmitsUnackedFramesBeforeTransmittingQueuedFrames) {
1563   constexpr size_t kMaxTransmissions = 2;
1564   constexpr size_t kTxWindow = 63;
1565   std::vector<uint8_t> pdu_seq_numbers;
1566   channel().HandleSendFrame([&](ByteBufferPtr pdu) {
1567     if (pdu && pdu->size() >= sizeof(EnhancedControlField) &&
1568         pdu->To<EnhancedControlField>().designates_information_frame() &&
1569         pdu->size() >= sizeof(SimpleInformationFrameHeader)) {
1570       pdu_seq_numbers.push_back(
1571           pdu->To<SimpleInformationFrameHeader>().tx_seq());
1572     }
1573   });
1574   TxEngine tx_engine(kTestChannelId,
1575                      kDefaultMTU,
1576                      kMaxTransmissions,
1577                      kTxWindow,
1578                      channel(),
1579                      NoOpFailureCallback,
1580                      dispatcher());
1581 
1582   // Send out two frames.
1583   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1584   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1585   RunUntilIdle();
1586   ASSERT_EQ(2u, pdu_seq_numbers.size());
1587   pdu_seq_numbers.clear();
1588 
1589   // Indicate the remote is busy, and queue a third frame.
1590   tx_engine.SetRemoteBusy();
1591   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1592   RunUntilIdle();
1593   ASSERT_TRUE(pdu_seq_numbers.empty());
1594 
1595   // Clear the busy condition, and then report the new ack sequence number.
1596   // Because the ack only acknowledges the first frame, the second frame should
1597   // be retransmitted. And that retransmission should come before the (initial)
1598   // transmission of the third frame.
1599   tx_engine.ClearRemoteBusy();
1600   tx_engine.UpdateAckSeq(1, /*is_poll_response=*/true);
1601   RunUntilIdle();
1602   EXPECT_EQ((std::vector{uint8_t{1}, uint8_t{2}}), pdu_seq_numbers);
1603 }
1604 
TEST_F(EnhancedRetransmissionModeTxEngineTest,QueueSduDoesNotTransmitNewFrameWhenEngineIsAwaitingPollResponse)1605 TEST_F(EnhancedRetransmissionModeTxEngineTest,
1606        QueueSduDoesNotTransmitNewFrameWhenEngineIsAwaitingPollResponse) {
1607   constexpr size_t kMaxTransmissions = 2;
1608   constexpr size_t kTxWindow = 3;
1609   std::vector<uint8_t> pdu_seq_numbers;
1610   channel().HandleSendFrame([&](ByteBufferPtr pdu) {
1611     if (pdu && pdu->size() >= sizeof(EnhancedControlField) &&
1612         pdu->To<EnhancedControlField>().designates_information_frame() &&
1613         pdu->size() >= sizeof(SimpleInformationFrameHeader)) {
1614       pdu_seq_numbers.push_back(
1615           pdu->To<SimpleInformationFrameHeader>().tx_seq());
1616     }
1617   });
1618   TxEngine tx_engine(kTestChannelId,
1619                      kDefaultMTU,
1620                      kMaxTransmissions,
1621                      kTxWindow,
1622                      channel(),
1623                      NoOpFailureCallback,
1624                      dispatcher());
1625 
1626   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1627   RunUntilIdle();
1628 
1629   // Let receiver_ready_poll_task_ fire. This moves the engine into the 'WAIT_F'
1630   // state.
1631   ASSERT_TRUE(RunFor(std::chrono::seconds(2)));
1632 
1633   // Queue a new frame.
1634   pdu_seq_numbers.clear();
1635   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1636   RunUntilIdle();
1637   EXPECT_EQ(std::vector<uint8_t>(), pdu_seq_numbers);
1638 }
1639 
TEST_F(EnhancedRetransmissionModeTxEngineTest,NonFinalUpdateAckSeqDoesNotTransmitNewFrameWhenEngineIsAwaitingPollResponse)1640 TEST_F(
1641     EnhancedRetransmissionModeTxEngineTest,
1642     NonFinalUpdateAckSeqDoesNotTransmitNewFrameWhenEngineIsAwaitingPollResponse) {
1643   constexpr size_t kMaxTransmissions = 2;
1644   constexpr size_t kTxWindow = 1;
1645   std::vector<uint8_t> pdu_seq_numbers;
1646   channel().HandleSendFrame([&](ByteBufferPtr pdu) {
1647     if (pdu && pdu->size() >= sizeof(EnhancedControlField) &&
1648         pdu->To<EnhancedControlField>().designates_information_frame() &&
1649         pdu->size() >= sizeof(SimpleInformationFrameHeader)) {
1650       pdu_seq_numbers.push_back(
1651           pdu->To<SimpleInformationFrameHeader>().tx_seq());
1652     }
1653   });
1654   TxEngine tx_engine(kTestChannelId,
1655                      kDefaultMTU,
1656                      kMaxTransmissions,
1657                      kTxWindow,
1658                      channel(),
1659                      NoOpFailureCallback,
1660                      dispatcher());
1661 
1662   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1663   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1664   RunUntilIdle();
1665 
1666   // Let receiver_ready_poll_task_ fire. This moves the engine into the 'WAIT_F'
1667   // state.
1668   ASSERT_TRUE(RunFor(std::chrono::seconds(2)));
1669 
1670   // Acknowledge the first frame, making room for the transmission of the second
1671   // frame.
1672   pdu_seq_numbers.clear();
1673   tx_engine.UpdateAckSeq(1, /*is_poll_response=*/false);
1674   RunUntilIdle();
1675 
1676   // Because we're still in the WAIT_F state, the second frame should _not_ be
1677   // transmitted.
1678   EXPECT_EQ(pdu_seq_numbers.end(),
1679             std::find(pdu_seq_numbers.begin(), pdu_seq_numbers.end(), 1));
1680 }
1681 
1682 // Note: to make the most of this test, the unit tests should be built with
1683 // ASAN.
TEST_F(EnhancedRetransmissionModeTxEngineTest,EngineDoesNotCrashIfExhaustionOfMaxTransmitForIFrameCausesEngineDestruction)1684 TEST_F(
1685     EnhancedRetransmissionModeTxEngineTest,
1686     EngineDoesNotCrashIfExhaustionOfMaxTransmitForIFrameCausesEngineDestruction) {
1687   constexpr size_t kMaxTransmissions = 1;
1688   constexpr size_t kTxWindow = 2;
1689   bool connection_failed = false;
1690   std::unique_ptr<TxEngine> tx_engine = std::make_unique<TxEngine>(
1691       kTestChannelId,
1692       kDefaultMTU,
1693       kMaxTransmissions,
1694       kTxWindow,
1695       channel(),
1696       [&] {
1697         connection_failed = true;
1698         tx_engine.reset();
1699       },
1700       dispatcher());
1701 
1702   // Queue three SDUs, of which two should be transmitted immediately.
1703   QueueSdu(*tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1704   QueueSdu(*tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1705   QueueSdu(*tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1706   RunUntilIdle();
1707 
1708   // Let receiver_ready_poll_task_ fire. This moves the engine into the 'WAIT_F'
1709   // state.
1710   ASSERT_TRUE(RunFor(std::chrono::seconds(2)));
1711 
1712   // Acknowledge the first frame, making room for the transmission of the third
1713   // frame. If the code is buggy, we may encounter use-after-free errors here.
1714   tx_engine->UpdateAckSeq(1, /*is_poll_response=*/true);
1715   RunUntilIdle();
1716 
1717   // Because we only allow one transmission, the connection should have failed.
1718   EXPECT_TRUE(connection_failed);
1719 }
1720 
TEST_F(EnhancedRetransmissionModeTxEngineTest,EngineDoesNotCrashIfExhaustionOfMaxTransmitForReceiverReadyPollCausesEngineDestruction)1721 TEST_F(
1722     EnhancedRetransmissionModeTxEngineTest,
1723     EngineDoesNotCrashIfExhaustionOfMaxTransmitForReceiverReadyPollCausesEngineDestruction) {
1724   constexpr size_t kMaxTransmissions = 1;
1725   bool connection_failed = false;
1726   std::unique_ptr<TxEngine> tx_engine = std::make_unique<TxEngine>(
1727       kTestChannelId,
1728       kDefaultMTU,
1729       kMaxTransmissions,
1730       kDefaultTxWindow,
1731       channel(),
1732       [&] {
1733         connection_failed = true;
1734         tx_engine.reset();
1735       },
1736       dispatcher());
1737 
1738   QueueSdu(*tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1739   RunUntilIdle();
1740 
1741   // Let receiver_ready_poll_task_ fire, to transmit the poll.
1742   ASSERT_TRUE(RunFor(std::chrono::seconds(2)));
1743 
1744   // Let monitor_task_ fire, to attempt retransmission of the poll. The
1745   // retransmission should fail, because we have exhausted kMaxTransmissions. If
1746   // the code is buggy, we may encounter use-after-free errors here.
1747   ASSERT_TRUE(RunFor(std::chrono::seconds(12)));
1748 
1749   EXPECT_TRUE(connection_failed);
1750 }
1751 
TEST_F(EnhancedRetransmissionModeTxEngineTest,TransmissionOfPduIncludesRequestSeqNum)1752 TEST_F(EnhancedRetransmissionModeTxEngineTest,
1753        TransmissionOfPduIncludesRequestSeqNum) {
1754   uint8_t outbound_req_seq = 0;
1755   channel().HandleSendFrame([&](ByteBufferPtr pdu) {
1756     if (pdu && pdu->size() >= sizeof(EnhancedControlField) &&
1757         pdu->To<EnhancedControlField>().designates_information_frame() &&
1758         pdu->size() >= sizeof(SimpleInformationFrameHeader)) {
1759       outbound_req_seq =
1760           pdu->To<SimpleInformationFrameHeader>().receive_seq_num();
1761     }
1762   });
1763   TxEngine tx_engine(kTestChannelId,
1764                      kDefaultMTU,
1765                      kDefaultMaxTransmissions,
1766                      kDefaultTxWindow,
1767                      channel(),
1768                      NoOpFailureCallback,
1769                      dispatcher());
1770 
1771   tx_engine.UpdateReqSeq(5);
1772   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1773   RunUntilIdle();
1774 
1775   EXPECT_EQ(5u, outbound_req_seq);
1776 }
1777 
TEST_F(EnhancedRetransmissionModeTxEngineTest,DeferredTransmissionOfPduIncludesCurrentRequestSeqNum)1778 TEST_F(EnhancedRetransmissionModeTxEngineTest,
1779        DeferredTransmissionOfPduIncludesCurrentRequestSeqNum) {
1780   constexpr size_t kTxWindow = 1;
1781   uint8_t outbound_req_seq = 0;
1782   channel().HandleSendFrame([&](ByteBufferPtr pdu) {
1783     if (pdu && pdu->size() >= sizeof(EnhancedControlField) &&
1784         pdu->To<EnhancedControlField>().designates_information_frame() &&
1785         pdu->size() >= sizeof(SimpleInformationFrameHeader)) {
1786       outbound_req_seq =
1787           pdu->To<SimpleInformationFrameHeader>().receive_seq_num();
1788     }
1789   });
1790   TxEngine tx_engine(kTestChannelId,
1791                      kDefaultMTU,
1792                      kDefaultMaxTransmissions,
1793                      kTxWindow,
1794                      channel(),
1795                      NoOpFailureCallback,
1796                      dispatcher());
1797 
1798   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1799   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1800   RunUntilIdle();
1801 
1802   tx_engine.UpdateReqSeq(5);
1803   tx_engine.UpdateAckSeq(1, /*is_poll_response=*/true);  // Peer acks first PDU.
1804   RunUntilIdle();
1805 
1806   // The second PDU should have been transmitted with ReqSeq = 5.
1807   EXPECT_EQ(5u, outbound_req_seq);
1808 }
1809 
TEST_F(EnhancedRetransmissionModeTxEngineTest,RetransmissionOfPduIncludesCurrentSeqNum)1810 TEST_F(EnhancedRetransmissionModeTxEngineTest,
1811        RetransmissionOfPduIncludesCurrentSeqNum) {
1812   constexpr size_t kMaxTransmissions = 2;
1813   uint8_t outbound_req_seq = 0;
1814   size_t n_info_frames = 0;
1815   channel().HandleSendFrame([&](ByteBufferPtr pdu) {
1816     if (pdu && pdu->size() >= sizeof(EnhancedControlField) &&
1817         pdu->To<EnhancedControlField>().designates_information_frame() &&
1818         pdu->size() >= sizeof(SimpleInformationFrameHeader)) {
1819       ++n_info_frames;
1820       outbound_req_seq =
1821           pdu->To<SimpleInformationFrameHeader>().receive_seq_num();
1822     }
1823   });
1824   TxEngine tx_engine(kTestChannelId,
1825                      kDefaultMTU,
1826                      kMaxTransmissions,
1827                      kDefaultTxWindow,
1828                      channel(),
1829                      NoOpFailureCallback,
1830                      dispatcher());
1831 
1832   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1833   RunUntilIdle();
1834   EXPECT_EQ(0u, outbound_req_seq);
1835 
1836   // The receive engine reports that it has received new data from our peer.
1837   tx_engine.UpdateReqSeq(10);
1838 
1839   // Let receiver_ready_poll_task_ fire. This triggers us to query if our peer
1840   // has received our data.
1841   ASSERT_TRUE(RunFor(std::chrono::seconds(2)));
1842 
1843   // Our peer indicates that it has not received our data.
1844   tx_engine.UpdateAckSeq(0, /*is_poll_response=*/true);
1845   RunUntilIdle();
1846 
1847   // Our retransmission should include our current request sequence number.
1848   EXPECT_EQ(2u, n_info_frames);
1849   EXPECT_EQ(10u, outbound_req_seq);
1850 }
1851 
TEST_F(EnhancedRetransmissionModeTxEngineTest,PollTaskLoopsEvenWhenRemoteIsBusy)1852 TEST_F(EnhancedRetransmissionModeTxEngineTest,
1853        PollTaskLoopsEvenWhenRemoteIsBusy) {
1854   size_t n_pdus = 0;
1855   channel().HandleSendFrame([&](auto) { ++n_pdus; });
1856   bool failure = false;
1857   auto connection_failure_callback = [&] { failure = true; };
1858   TxEngine tx_engine(
1859       /*channel_id=*/kTestChannelId,
1860       /*max_tx_sdu_size=*/kDefaultMTU,
1861       /*max_transmissions=*/2,
1862       /*n_frames_in_tx_window=*/kDefaultTxWindow,
1863       /*channel=*/channel(),
1864       /*connection_failure_callback=*/connection_failure_callback,
1865       dispatcher());
1866 
1867   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1868   ASSERT_EQ(1u, n_pdus);
1869 
1870   // Let receiver_ready_poll_task_ fire, to transmit the poll.
1871   ASSERT_TRUE(RunFor(std::chrono::seconds(2)));
1872   ASSERT_EQ(2u, n_pdus);
1873 
1874   // Receive a "set RemoteBusy" in the poll response (RNR with F=1).
1875   n_pdus = 0;
1876   tx_engine.SetRemoteBusy();
1877   tx_engine.UpdateAckSeq(0u, /*is_poll_response=*/true);
1878   ASSERT_EQ(0u, n_pdus);
1879 
1880   // No polls should have been sent out and the monitor task should not have
1881   // fired.
1882   RunFor(std::chrono::seconds(12));
1883   EXPECT_EQ(0u, n_pdus);
1884   EXPECT_FALSE(failure);
1885 }
1886 
TEST_F(EnhancedRetransmissionModeTxEngineTest,SetRangeRetransmitCausesUpdateAckSeqToRetransmit)1887 TEST_F(EnhancedRetransmissionModeTxEngineTest,
1888        SetRangeRetransmitCausesUpdateAckSeqToRetransmit) {
1889   size_t n_info_frames = 0;
1890   std::optional<uint8_t> tx_seq;
1891   channel().HandleSendFrame([&](ByteBufferPtr pdu) {
1892     if (pdu && pdu->size() >= sizeof(EnhancedControlField) &&
1893         pdu->To<EnhancedControlField>().designates_information_frame() &&
1894         pdu->size() >= sizeof(SimpleInformationFrameHeader)) {
1895       ++n_info_frames;
1896       tx_seq = pdu->To<SimpleInformationFrameHeader>().tx_seq();
1897     }
1898   });
1899   TxEngine tx_engine(/*channel_id=*/kTestChannelId,
1900                      /*max_tx_sdu_size=*/kDefaultMTU,
1901                      /*max_transmissions=*/4,
1902                      /*n_frames_in_tx_window=*/kDefaultTxWindow,
1903                      /*channel=*/channel(),
1904                      /*connection_failure_callback=*/NoOpFailureCallback,
1905                      dispatcher());
1906 
1907   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1908   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1909   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1910   ASSERT_EQ(3u, n_info_frames);
1911 
1912   // Request a retransmission of unacked data starting with TxSeq=1 (so the
1913   // second and third frames).
1914   n_info_frames = 0;
1915   tx_seq.reset();
1916   tx_engine.SetRangeRetransmit(/*is_poll_request=*/false);
1917   tx_engine.UpdateAckSeq(1u, /*is_poll_response=*/false);
1918   EXPECT_EQ(2u, n_info_frames);
1919   EXPECT_EQ(2u, tx_seq.value_or(0));
1920 
1921   // Subsequent UpdateAckSeqs do not perform retransmission.
1922   n_info_frames = 0;
1923   tx_engine.UpdateAckSeq(1u, /*is_poll_response=*/false);
1924   EXPECT_EQ(0u, n_info_frames);
1925 }
1926 
TEST_F(EnhancedRetransmissionModeTxEngineTest,SetRangeRetransmitWithPollRequestTriggersPollResponseOnFirstIFrame)1927 TEST_F(EnhancedRetransmissionModeTxEngineTest,
1928        SetRangeRetransmitWithPollRequestTriggersPollResponseOnFirstIFrame) {
1929   size_t n_info_frames = 0;
1930   channel().HandleSendFrame([&](ByteBufferPtr pdu) {
1931     if (pdu && pdu->size() >= sizeof(EnhancedControlField) &&
1932         pdu->To<EnhancedControlField>().designates_information_frame() &&
1933         pdu->size() >= sizeof(SimpleInformationFrameHeader)) {
1934       // We send two I-Frames to start, then retransmit both but the third frame
1935       // is in response to a poll request so its and only its poll response bit
1936       // should be set.
1937       SCOPED_TRACE(n_info_frames);
1938       EXPECT_EQ(n_info_frames == 2,
1939                 pdu->To<EnhancedControlField>().is_poll_response());
1940       ++n_info_frames;
1941     }
1942   });
1943   TxEngine tx_engine(/*channel_id=*/kTestChannelId,
1944                      /*max_tx_sdu_size=*/kDefaultMTU,
1945                      /*max_transmissions=*/3,
1946                      /*n_frames_in_tx_window=*/kDefaultTxWindow,
1947                      /*channel=*/channel(),
1948                      /*connection_failure_callback=*/NoOpFailureCallback,
1949                      dispatcher());
1950 
1951   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1952   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1953   ASSERT_EQ(2u, n_info_frames);
1954 
1955   // Request a retransmission of unacked data starting with TxSeq=0 (all
1956   // frames).
1957   tx_engine.SetRangeRetransmit(/*is_poll_request=*/true);
1958   tx_engine.UpdateAckSeq(0u, /*is_poll_response=*/false);
1959   EXPECT_EQ(4u, n_info_frames);
1960 }
1961 
TEST_F(EnhancedRetransmissionModeTxEngineTest,SetRangeRetransmitAfterPollTaskSuppressesSubsequentRetransmitByPollResponse)1962 TEST_F(
1963     EnhancedRetransmissionModeTxEngineTest,
1964     SetRangeRetransmitAfterPollTaskSuppressesSubsequentRetransmitByPollResponse) {
1965   size_t n_info_frames = 0;
1966   channel().HandleSendFrame([&](ByteBufferPtr pdu) {
1967     if (pdu && pdu->size() >= sizeof(EnhancedControlField) &&
1968         pdu->To<EnhancedControlField>().designates_information_frame() &&
1969         pdu->size() >= sizeof(SimpleInformationFrameHeader)) {
1970       ++n_info_frames;
1971     }
1972   });
1973   TxEngine tx_engine(/*channel_id=*/kTestChannelId,
1974                      /*max_tx_sdu_size=*/kDefaultMTU,
1975                      /*max_transmissions=*/4,
1976                      /*n_frames_in_tx_window=*/kDefaultTxWindow,
1977                      /*channel=*/channel(),
1978                      /*connection_failure_callback=*/NoOpFailureCallback,
1979                      dispatcher());
1980 
1981   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
1982   ASSERT_EQ(1u, n_info_frames);
1983 
1984   // Let receiver_ready_poll_task_ fire, to transmit the poll.
1985   ASSERT_TRUE(RunFor(std::chrono::seconds(2)));
1986 
1987   // Request a retransmission of unacked data starting with TxSeq=0.
1988   tx_engine.SetRangeRetransmit(/*is_poll_request=*/false);
1989   tx_engine.UpdateAckSeq(0u, /*is_poll_response=*/false);
1990   ASSERT_EQ(2u, n_info_frames);
1991 
1992   // Don't acknowledge data at TxSeq=0 again in the poll response, which _would_
1993   // retransmit them if they hadn't already been retransmitted.
1994   n_info_frames = 0;
1995   tx_engine.UpdateAckSeq(0u, /*is_poll_response=*/true);
1996   EXPECT_EQ(0u, n_info_frames);
1997 
1998   // And further non-acknowledgments that don't call for retransmission
1999   // shouldn't cause retransmission.
2000   tx_engine.UpdateAckSeq(0u, /*is_poll_response=*/false);
2001   EXPECT_EQ(0u, n_info_frames);
2002 
2003   // Or further acknowledgments, for that matter.
2004   tx_engine.UpdateAckSeq(1u, /*is_poll_response=*/false);
2005   EXPECT_EQ(0u, n_info_frames);
2006 }
2007 
TEST_F(EnhancedRetransmissionModeTxEngineTest,SetRangeRetransmitWithPollResponseSetDoesNotSuppressSubsequentRetransmissions)2008 TEST_F(
2009     EnhancedRetransmissionModeTxEngineTest,
2010     SetRangeRetransmitWithPollResponseSetDoesNotSuppressSubsequentRetransmissions) {
2011   size_t n_info_frames = 0;
2012   channel().HandleSendFrame([&](ByteBufferPtr pdu) {
2013     if (pdu && pdu->size() >= sizeof(EnhancedControlField) &&
2014         pdu->To<EnhancedControlField>().designates_information_frame() &&
2015         pdu->size() >= sizeof(SimpleInformationFrameHeader)) {
2016       ++n_info_frames;
2017     }
2018   });
2019   TxEngine tx_engine(/*channel_id=*/kTestChannelId,
2020                      /*max_tx_sdu_size=*/kDefaultMTU,
2021                      /*max_transmissions=*/4,
2022                      /*n_frames_in_tx_window=*/kDefaultTxWindow,
2023                      /*channel=*/channel(),
2024                      /*connection_failure_callback=*/NoOpFailureCallback,
2025                      dispatcher());
2026 
2027   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
2028   ASSERT_EQ(1u, n_info_frames);
2029 
2030   // Let receiver_ready_poll_task_ fire, to transmit the poll.
2031   ASSERT_TRUE(RunFor(std::chrono::seconds(2)));
2032 
2033   // Request a retransmission of unacked data starting with TxSeq=0 that also
2034   // acknowledges the poll.
2035   tx_engine.SetRangeRetransmit(/*is_poll_request=*/false);
2036   tx_engine.UpdateAckSeq(0u, /*is_poll_response=*/true);
2037   ASSERT_EQ(2u, n_info_frames);
2038 
2039   // Let receiver_ready_poll_task_ fire, to transmit the poll.
2040   ASSERT_TRUE(RunFor(std::chrono::seconds(2)));
2041 
2042   // Don't acknowledge data at TxSeq=0 again in the next poll response, which
2043   // causes another retransmission.
2044   tx_engine.UpdateAckSeq(0u, /*is_poll_response=*/true);
2045   EXPECT_EQ(3u, n_info_frames);
2046 }
2047 
TEST_F(EnhancedRetransmissionModeTxEngineTest,SetRangeRetransmitSuppressesRetransmissionsByRetransmitRangeWithPollResponse)2048 TEST_F(
2049     EnhancedRetransmissionModeTxEngineTest,
2050     SetRangeRetransmitSuppressesRetransmissionsByRetransmitRangeWithPollResponse) {
2051   size_t n_info_frames = 0;
2052   channel().HandleSendFrame([&](ByteBufferPtr pdu) {
2053     if (pdu && pdu->size() >= sizeof(EnhancedControlField) &&
2054         pdu->To<EnhancedControlField>().designates_information_frame() &&
2055         pdu->size() >= sizeof(SimpleInformationFrameHeader)) {
2056       ++n_info_frames;
2057     }
2058   });
2059   TxEngine tx_engine(/*channel_id=*/kTestChannelId,
2060                      /*max_tx_sdu_size=*/kDefaultMTU,
2061                      /*max_transmissions=*/4,
2062                      /*n_frames_in_tx_window=*/kDefaultTxWindow,
2063                      /*channel=*/channel(),
2064                      /*connection_failure_callback=*/NoOpFailureCallback,
2065                      dispatcher());
2066 
2067   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
2068   ASSERT_EQ(1u, n_info_frames);
2069 
2070   // Let receiver_ready_poll_task_ fire, to transmit the poll.
2071   ASSERT_TRUE(RunFor(std::chrono::seconds(2)));
2072 
2073   // Request a retransmission of unacked data starting with TxSeq=0.
2074   tx_engine.SetRangeRetransmit(/*is_poll_request=*/false);
2075   tx_engine.UpdateAckSeq(0u, /*is_poll_response=*/false);
2076   ASSERT_EQ(2u, n_info_frames);
2077 
2078   // Request retransmission _and_ don't acknowledge data at TxSeq=0, which
2079   // _would_ retransmit them if they hadn't already been retransmitted.
2080   n_info_frames = 0;
2081   tx_engine.SetRangeRetransmit(/*is_poll_request=*/false);
2082   tx_engine.UpdateAckSeq(0u, /*is_poll_response=*/true);
2083   EXPECT_EQ(0u, n_info_frames);
2084 
2085   // And further non-acknowledgments that don't call for retransmission
2086   // shouldn't cause retransmission.
2087   tx_engine.UpdateAckSeq(0u, /*is_poll_response=*/false);
2088   EXPECT_EQ(0u, n_info_frames);
2089 
2090   // Or further acknowledgments, for that matter.
2091   tx_engine.UpdateAckSeq(1u, /*is_poll_response=*/false);
2092   EXPECT_EQ(0u, n_info_frames);
2093 }
2094 
TEST_F(EnhancedRetransmissionModeTxEngineTest,SetSingleRetransmitCausesUpdateAckSeqToRetransmit)2095 TEST_F(EnhancedRetransmissionModeTxEngineTest,
2096        SetSingleRetransmitCausesUpdateAckSeqToRetransmit) {
2097   size_t n_info_frames = 0;
2098   std::optional<uint8_t> tx_seq;
2099   channel().HandleSendFrame([&](ByteBufferPtr pdu) {
2100     if (pdu && pdu->size() >= sizeof(EnhancedControlField) &&
2101         pdu->To<EnhancedControlField>().designates_information_frame() &&
2102         pdu->size() >= sizeof(SimpleInformationFrameHeader)) {
2103       ++n_info_frames;
2104       tx_seq = pdu->To<SimpleInformationFrameHeader>().tx_seq();
2105     }
2106   });
2107   TxEngine tx_engine(/*channel_id=*/kTestChannelId,
2108                      /*max_tx_sdu_size=*/kDefaultMTU,
2109                      /*max_transmissions=*/4,
2110                      /*n_frames_in_tx_window=*/kDefaultTxWindow,
2111                      /*channel=*/channel(),
2112                      /*connection_failure_callback=*/NoOpFailureCallback,
2113                      dispatcher());
2114 
2115   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
2116   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
2117   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
2118   ASSERT_EQ(3u, n_info_frames);
2119 
2120   // Request a retransmission of unacked data with TxSeq=1 (so only the second
2121   // frame).
2122   n_info_frames = 0;
2123   tx_seq.reset();
2124   tx_engine.SetSingleRetransmit(/*is_poll_request=*/false);
2125   tx_engine.UpdateAckSeq(1u, /*is_poll_response=*/false);
2126   EXPECT_EQ(1u, n_info_frames);
2127   EXPECT_EQ(1u, tx_seq.value_or(0));
2128 
2129   // Subsequent UpdateAckSeqs do not perform retransmission.
2130   n_info_frames = 0;
2131   tx_engine.UpdateAckSeq(1u, /*is_poll_response=*/false);
2132   EXPECT_EQ(0u, n_info_frames);
2133 }
2134 
TEST_F(EnhancedRetransmissionModeTxEngineTest,SetSingleRetransmitWithPollRequestTriggersPollResponseOnIFrame)2135 TEST_F(EnhancedRetransmissionModeTxEngineTest,
2136        SetSingleRetransmitWithPollRequestTriggersPollResponseOnIFrame) {
2137   size_t n_info_frames = 0;
2138   channel().HandleSendFrame([&](ByteBufferPtr pdu) {
2139     if (pdu && pdu->size() >= sizeof(EnhancedControlField) &&
2140         pdu->To<EnhancedControlField>().designates_information_frame() &&
2141         pdu->size() >= sizeof(SimpleInformationFrameHeader)) {
2142       // We send two I-Frames to start, then retransmit both but the third frame
2143       // is in response to a poll request so its and only its poll response bit
2144       // should be set.
2145       SCOPED_TRACE(n_info_frames);
2146       EXPECT_EQ(n_info_frames == 2,
2147                 pdu->To<EnhancedControlField>().is_poll_response());
2148       ++n_info_frames;
2149     }
2150   });
2151   TxEngine tx_engine(/*channel_id=*/kTestChannelId,
2152                      /*max_tx_sdu_size=*/kDefaultMTU,
2153                      /*max_transmissions=*/3,
2154                      /*n_frames_in_tx_window=*/kDefaultTxWindow,
2155                      /*channel=*/channel(),
2156                      /*connection_failure_callback=*/NoOpFailureCallback,
2157                      dispatcher());
2158 
2159   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
2160   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
2161   ASSERT_EQ(2u, n_info_frames);
2162 
2163   // Request a retransmission of unacked data with TxSeq=0 (first frame).
2164   tx_engine.SetSingleRetransmit(/*is_poll_request=*/true);
2165   tx_engine.UpdateAckSeq(0u, /*is_poll_response=*/false);
2166   EXPECT_EQ(3u, n_info_frames);
2167 
2168   // Request a retransmission of unacked data with TxSeq=1 (second frame).
2169   tx_engine.SetSingleRetransmit(/*is_poll_request=*/false);
2170   tx_engine.UpdateAckSeq(0u, /*is_poll_response=*/false);
2171   EXPECT_EQ(4u, n_info_frames);
2172 }
2173 
TEST_F(EnhancedRetransmissionModeTxEngineTest,SetSingleRetransmitOnlyAcksIFramesIfPollRequestIsSet)2174 TEST_F(EnhancedRetransmissionModeTxEngineTest,
2175        SetSingleRetransmitOnlyAcksIFramesIfPollRequestIsSet) {
2176   size_t n_info_frames = 0;
2177   std::optional<uint8_t> tx_seq;
2178   channel().HandleSendFrame([&](ByteBufferPtr pdu) {
2179     if (pdu && pdu->size() >= sizeof(EnhancedControlField) &&
2180         pdu->To<EnhancedControlField>().designates_information_frame() &&
2181         pdu->size() >= sizeof(SimpleInformationFrameHeader)) {
2182       ++n_info_frames;
2183       tx_seq = pdu->To<SimpleInformationFrameHeader>().tx_seq();
2184     }
2185   });
2186   TxEngine tx_engine(/*channel_id=*/kTestChannelId,
2187                      /*max_tx_sdu_size=*/kDefaultMTU,
2188                      /*max_transmissions=*/4,
2189                      /*n_frames_in_tx_window=*/2,
2190                      /*channel=*/channel(),
2191                      /*connection_failure_callback=*/NoOpFailureCallback,
2192                      dispatcher());
2193 
2194   // TxWindow prevents third I-Frame from going out.
2195   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
2196   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
2197   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
2198   ASSERT_EQ(2u, n_info_frames);
2199 
2200   // Request a retransmission of unacked data with TxSeq=1, not a poll request.
2201   n_info_frames = 0;
2202   tx_seq.reset();
2203   tx_engine.SetSingleRetransmit(/*is_poll_request=*/false);
2204   tx_engine.UpdateAckSeq(1u, /*is_poll_response=*/false);
2205 
2206   // Only the second I-Frame is retransmitted.
2207   EXPECT_EQ(1u, n_info_frames);
2208   EXPECT_EQ(1u, tx_seq.value_or(0));
2209 
2210   // Request a retransmission of unacked data with TxSeq=1, this time a poll
2211   // request.
2212   n_info_frames = 0;
2213   tx_seq.reset();
2214   tx_engine.SetSingleRetransmit(/*is_poll_request=*/true);
2215   tx_engine.UpdateAckSeq(1u, /*is_poll_response=*/false);
2216 
2217   // The first frame is acked, the second I-Frame is retransmitted, and the
2218   // third frame (which was pending because of TxWindow) is transmitted for the
2219   // first time.
2220   EXPECT_EQ(2u, n_info_frames);
2221   EXPECT_EQ(2u, tx_seq.value_or(0));
2222 }
2223 
TEST_F(EnhancedRetransmissionModeTxEngineTest,SetSingleRetransmitDuringPollRequestThenAgainWithPollResponseAndDifferentAckSeqBothCauseRetransmit)2224 TEST_F(
2225     EnhancedRetransmissionModeTxEngineTest,
2226     SetSingleRetransmitDuringPollRequestThenAgainWithPollResponseAndDifferentAckSeqBothCauseRetransmit) {
2227   size_t n_info_frames = 0;
2228   size_t n_supervisory_frames = 0;
2229   std::optional<uint8_t> tx_seq;
2230   channel().HandleSendFrame([&](ByteBufferPtr pdu) {
2231     if (pdu && pdu->size() >= sizeof(EnhancedControlField)) {
2232       if (pdu->To<EnhancedControlField>().designates_information_frame()) {
2233         ++n_info_frames;
2234         tx_seq = pdu->To<SimpleInformationFrameHeader>().tx_seq();
2235       } else if (pdu->To<EnhancedControlField>()
2236                      .designates_supervisory_frame()) {
2237         ++n_supervisory_frames;
2238       }
2239     }
2240   });
2241   TxEngine tx_engine(/*channel_id=*/kTestChannelId,
2242                      /*max_tx_sdu_size=*/kDefaultMTU,
2243                      /*max_transmissions=*/4,
2244                      /*n_frames_in_tx_window=*/kDefaultTxWindow,
2245                      /*channel=*/channel(),
2246                      /*connection_failure_callback=*/NoOpFailureCallback,
2247                      dispatcher());
2248 
2249   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
2250   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
2251   ASSERT_EQ(2u, n_info_frames);
2252 
2253   // Let receiver_ready_poll_task_ fire, to transmit the poll.
2254   ASSERT_TRUE(RunFor(std::chrono::seconds(2)));
2255   ASSERT_EQ(1U, n_supervisory_frames);
2256 
2257   // Request a retransmission of unacked data with TxSeq=1, not a poll response.
2258   n_info_frames = 0;
2259   tx_seq.reset();
2260   tx_engine.SetSingleRetransmit(/*is_poll_request=*/false);
2261   tx_engine.UpdateAckSeq(1u, /*is_poll_response=*/false);
2262 
2263   // The second I-Frame is retransmitted.
2264   EXPECT_EQ(1u, n_info_frames);
2265   EXPECT_EQ(1u, tx_seq.value_or(0));
2266 
2267   // Request a retransmission of unacked data with TxSeq=0, this time a poll
2268   // response.
2269   n_info_frames = 0;
2270   tx_seq.reset();
2271   tx_engine.SetSingleRetransmit(/*is_poll_request=*/false);
2272   tx_engine.UpdateAckSeq(0u, /*is_poll_response=*/true);
2273 
2274   // The first I-Frame is retransmitted.
2275   EXPECT_EQ(1u, n_info_frames);
2276   EXPECT_EQ(0u, tx_seq.value_or(1));
2277 
2278   // Test that the second poll request stopped the MonitorTimer by checking that
2279   // the ReceiverReady poll was sent.
2280   ASSERT_TRUE(RunFor(std::chrono::seconds(2)));
2281   EXPECT_EQ(2U, n_supervisory_frames);
2282 }
2283 
TEST_F(EnhancedRetransmissionModeTxEngineTest,SetSingleRetransmitDuringPollRequestSuppressesSingleRetransmitPollResponseWithSameAckSeq)2284 TEST_F(
2285     EnhancedRetransmissionModeTxEngineTest,
2286     SetSingleRetransmitDuringPollRequestSuppressesSingleRetransmitPollResponseWithSameAckSeq) {
2287   size_t n_info_frames = 0;
2288   size_t n_supervisory_frames = 0;
2289   std::optional<uint8_t> tx_seq;
2290   channel().HandleSendFrame([&](ByteBufferPtr pdu) {
2291     if (pdu && pdu->size() >= sizeof(EnhancedControlField)) {
2292       if (pdu->To<EnhancedControlField>().designates_information_frame()) {
2293         ++n_info_frames;
2294         tx_seq = pdu->To<SimpleInformationFrameHeader>().tx_seq();
2295       } else if (pdu->To<EnhancedControlField>()
2296                      .designates_supervisory_frame()) {
2297         ++n_supervisory_frames;
2298       }
2299     }
2300   });
2301   TxEngine tx_engine(/*channel_id=*/kTestChannelId,
2302                      /*max_tx_sdu_size=*/kDefaultMTU,
2303                      /*max_transmissions=*/4,
2304                      /*n_frames_in_tx_window=*/kDefaultTxWindow,
2305                      /*channel=*/channel(),
2306                      /*connection_failure_callback=*/NoOpFailureCallback,
2307                      dispatcher());
2308 
2309   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
2310   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
2311   ASSERT_EQ(2u, n_info_frames);
2312 
2313   // Let receiver_ready_poll_task_ fire, to transmit the poll.
2314   ASSERT_TRUE(RunFor(std::chrono::seconds(2)));
2315   ASSERT_EQ(1U, n_supervisory_frames);
2316 
2317   // Request a retransmission of unacked data with TxSeq=1, not a poll response.
2318   n_info_frames = 0;
2319   tx_seq.reset();
2320   tx_engine.SetSingleRetransmit(/*is_poll_request=*/false);
2321   tx_engine.UpdateAckSeq(1u, /*is_poll_response=*/false);
2322 
2323   // The second I-Frame is retransmitted.
2324   EXPECT_EQ(1u, n_info_frames);
2325   EXPECT_EQ(1u, tx_seq.value_or(0));
2326 
2327   // Request a retransmission of unacked data with TxSeq=1, this time a poll
2328   // response.
2329   n_info_frames = 0;
2330   tx_engine.SetSingleRetransmit(/*is_poll_request=*/false);
2331   tx_engine.UpdateAckSeq(1u, /*is_poll_response=*/true);
2332   EXPECT_EQ(0u, n_info_frames);  // No duplicate retransmission occurs.
2333 
2334   // Test that the second poll request stopped the MonitorTimer by checking that
2335   // the ReceiverReady poll was sent.
2336   ASSERT_TRUE(RunFor(std::chrono::seconds(2)));
2337   EXPECT_EQ(2U, n_supervisory_frames);
2338 }
2339 
2340 // This is a possible bug introduced by implementing SrejActioned to the letter
2341 // per Core Spec v5.{0–2} Vol 3, Part A, Sec 8.6.5.9–11.
TEST_F(EnhancedRetransmissionModeTxEngineTest,SetSingleRetransmitDuringPollRequestSuppressesRetransmissionErroneously)2342 TEST_F(
2343     EnhancedRetransmissionModeTxEngineTest,
2344     SetSingleRetransmitDuringPollRequestSuppressesRetransmissionErroneously) {
2345   size_t n_info_frames = 0;
2346   size_t n_supervisory_frames = 0;
2347   std::optional<uint8_t> tx_seq;
2348   channel().HandleSendFrame([&](ByteBufferPtr pdu) {
2349     if (pdu && pdu->size() >= sizeof(EnhancedControlField)) {
2350       if (pdu->To<EnhancedControlField>().designates_information_frame()) {
2351         ++n_info_frames;
2352         tx_seq = pdu->To<SimpleInformationFrameHeader>().tx_seq();
2353       } else if (pdu->To<EnhancedControlField>()
2354                      .designates_supervisory_frame()) {
2355         ++n_supervisory_frames;
2356       }
2357     }
2358   });
2359   TxEngine tx_engine(/*channel_id=*/kTestChannelId,
2360                      /*max_tx_sdu_size=*/kDefaultMTU,
2361                      /*max_transmissions=*/4,
2362                      /*n_frames_in_tx_window=*/kDefaultTxWindow,
2363                      /*channel=*/channel(),
2364                      /*connection_failure_callback=*/NoOpFailureCallback,
2365                      dispatcher());
2366 
2367   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
2368   QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
2369   ASSERT_EQ(2u, n_info_frames);
2370 
2371   // Let receiver_ready_poll_task_ fire, to transmit the poll.
2372   ASSERT_TRUE(RunFor(std::chrono::seconds(2)));
2373   ASSERT_EQ(1U, n_supervisory_frames);
2374 
2375   // Request a retransmission of unacked data with TxSeq=1, not a poll response.
2376   n_info_frames = 0;
2377   tx_engine.SetSingleRetransmit(/*is_poll_request=*/false);
2378   tx_engine.UpdateAckSeq(1u, /*is_poll_response=*/false);
2379   ASSERT_EQ(1u, n_info_frames);
2380 
2381   // Ack the first frame and complete the poll.
2382   n_info_frames = 0;
2383   tx_engine.UpdateAckSeq(1u, /*is_poll_response=*/true);
2384   ASSERT_EQ(1u, n_info_frames);  // Retransmission is not suppressed.
2385 
2386   // Send and acknowledge enough frames to roll over AckSeq.
2387   n_info_frames = 0;
2388   for (uint8_t i = 0; i < EnhancedControlField::kMaxSeqNum + 1; i++) {
2389     const uint8_t ack_seq =
2390         (tx_seq.value() + 1) %
2391         (static_cast<uint8_t>(EnhancedControlField::kMaxSeqNum) + 1);
2392     tx_engine.UpdateAckSeq(ack_seq, /*is_poll_response=*/false);
2393     QueueSdu(tx_engine, std::make_unique<DynamicByteBuffer>(kDefaultPayload));
2394   }
2395 
2396   // Now there's a new frame with TxSeq=1.
2397   ASSERT_EQ(uintmax_t{EnhancedControlField::kMaxSeqNum} + 1, n_info_frames);
2398   ASSERT_EQ(1u, tx_seq.value());
2399 
2400   // Let receiver_ready_poll_task_ fire, to transmit the poll.
2401   ASSERT_TRUE(RunFor(std::chrono::seconds(2)));
2402 
2403   n_info_frames = 0;
2404   tx_engine.SetSingleRetransmit(/*is_poll_request=*/false);
2405   tx_engine.UpdateAckSeq(1u, /*is_poll_response=*/true);
2406 
2407   // Even though this is a different frame than the first retransmission in this
2408   // test, the latter's SrejActioned state suppresses this retransmission.
2409   EXPECT_EQ(0u, n_info_frames);
2410 }
2411 
2412 }  // namespace
2413 }  // namespace bt::l2cap::internal
2414