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