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_rx_engine.h"
16
17 #include "pw_bluetooth_sapphire/internal/host/l2cap/fragmenter.h"
18 #include "pw_bluetooth_sapphire/internal/host/testing/test_helpers.h"
19 #include "pw_unit_test/framework.h"
20
21 namespace bt::l2cap::internal {
22 namespace {
23
24 constexpr hci_spec::ConnectionHandle kTestHandle = 0x0001;
25 constexpr ChannelId kTestChannelId = 0x0001;
26 constexpr uint8_t kExtendedControlPBitMask = 0b0001'0000;
27 constexpr uint8_t kExtendedControlFBitMask = 0b1000'0000;
28 constexpr uint8_t kExtendedControlReceiverReadyBits = 0b0000'0000;
29 constexpr uint8_t kExtendedControlReceiverNotReadyBits = 0b0000'1000;
30 constexpr uint8_t kExtendedControlRejectBits = 0b0000'0100;
31 constexpr uint8_t kExtendedControlSelectiveRejectBits = 0b0000'1100;
32
33 using Engine = EnhancedRetransmissionModeRxEngine;
34
NoOpTxCallback(ByteBufferPtr)35 void NoOpTxCallback(ByteBufferPtr) {}
NoOpFailureCallback()36 void NoOpFailureCallback() {}
37
TEST(EnhancedRetransmissionModeRxEngineTest,ProcessPduImmediatelyReturnsDataForUnsegmentedSdu)38 TEST(EnhancedRetransmissionModeRxEngineTest,
39 ProcessPduImmediatelyReturnsDataForUnsegmentedSdu) {
40 // See Core Spec, v5, Vol 3, Part A, Table 3.2 for the first two bytes.
41 const StaticByteBuffer payload(0, 0, 'h', 'e', 'l', 'l', 'o');
42 const ByteBufferPtr sdu =
43 Engine(NoOpTxCallback, NoOpFailureCallback)
44 .ProcessPdu(Fragmenter(kTestHandle)
45 .BuildFrame(kTestChannelId,
46 payload,
47 FrameCheckSequenceOption::kIncludeFcs));
48 ASSERT_TRUE(sdu);
49 EXPECT_TRUE(ContainersEqual(StaticByteBuffer('h', 'e', 'l', 'l', 'o'), *sdu));
50 }
51
TEST(EnhancedRetransmissionModeRxEngineTest,ProcessPduCanHandleZeroBytePayload)52 TEST(EnhancedRetransmissionModeRxEngineTest,
53 ProcessPduCanHandleZeroBytePayload) {
54 // See Core Spec, v5, Vol 3, Part A, Table 3.2 for the first two bytes.
55 const StaticByteBuffer payload(0, 0);
56 const ByteBufferPtr sdu =
57 Engine(NoOpTxCallback, NoOpFailureCallback)
58 .ProcessPdu(Fragmenter(kTestHandle)
59 .BuildFrame(kTestChannelId,
60 payload,
61 FrameCheckSequenceOption::kIncludeFcs));
62 ASSERT_TRUE(sdu);
63 EXPECT_EQ(0u, sdu->size());
64 }
65
TEST(EnhancedRetransmissionModeRxEngineTest,ProcessPduCanHandleZeroBytePdu)66 TEST(EnhancedRetransmissionModeRxEngineTest, ProcessPduCanHandleZeroBytePdu) {
67 // See Core Spec, v5, Vol 3, Part A, Table 3.2 for the first two bytes.
68 const StaticByteBuffer payload{0, 0};
69
70 // FCS footer is entirely omitted.
71 const ByteBufferPtr sdu =
72 Engine(NoOpTxCallback, NoOpFailureCallback)
73 .ProcessPdu(Fragmenter(kTestHandle)
74 .BuildFrame(kTestChannelId,
75 payload,
76 FrameCheckSequenceOption::kNoFcs));
77 EXPECT_FALSE(sdu);
78 }
79
TEST(EnhancedRetransmissionModeRxEngineTest,ProcessPduCanHandleIncompleteFcsFooter)80 TEST(EnhancedRetransmissionModeRxEngineTest,
81 ProcessPduCanHandleIncompleteFcsFooter) {
82 // See Core Spec, v5, Vol 3, Part A, Table 3.2 for the first two bytes.
83 // No payload is present and only one byte of the FCS footer is present.
84 const StaticByteBuffer payload{0, 0, 0};
85 const ByteBufferPtr sdu =
86 Engine(NoOpTxCallback, NoOpFailureCallback)
87 .ProcessPdu(Fragmenter(kTestHandle)
88 .BuildFrame(kTestChannelId,
89 payload,
90 FrameCheckSequenceOption::kNoFcs));
91 EXPECT_FALSE(sdu);
92 }
93
TEST(EnhancedRetransmissionModeRxEngineTest,ProcessPduDoesNotGenerateSduForOutOfSequencePdu)94 TEST(EnhancedRetransmissionModeRxEngineTest,
95 ProcessPduDoesNotGenerateSduForOutOfSequencePdu) {
96 // See Core Spec, v5, Vol 3, Part A, Table 3.2 for the first two bytes.
97 const StaticByteBuffer payload( //
98 1 << 1, // TxSeq = 1, R=0
99 0, // SAR and ReqSeq
100 'h',
101 'e',
102 'l',
103 'l',
104 'o');
105 EXPECT_FALSE(
106 Engine(NoOpTxCallback, NoOpFailureCallback)
107 .ProcessPdu(Fragmenter(kTestHandle)
108 .BuildFrame(kTestChannelId,
109 payload,
110 FrameCheckSequenceOption::kIncludeFcs)));
111 }
112
TEST(EnhancedRetransmissionModeRxEngineTest,ProcessPduAdvancesSequenceNumberOnInSequenceFrame)113 TEST(EnhancedRetransmissionModeRxEngineTest,
114 ProcessPduAdvancesSequenceNumberOnInSequenceFrame) {
115 Engine rx_engine(NoOpTxCallback, NoOpFailureCallback);
116
117 // Send with sequence 0.
118 {
119 const StaticByteBuffer payload( //
120 0 << 1, // TxSeq=0, R=0
121 0, // SAR and ReqSeq
122 'h',
123 'e',
124 'l',
125 'l',
126 'o');
127 ASSERT_TRUE(rx_engine.ProcessPdu(
128 Fragmenter(kTestHandle)
129 .BuildFrame(kTestChannelId,
130 payload,
131 FrameCheckSequenceOption::kIncludeFcs)));
132 }
133
134 // Send with sequence 1.
135 {
136 const StaticByteBuffer payload( //
137 1 << 1, // TxSeq=1, R=0
138 0, // SAR and ReqSeq
139 'h',
140 'e',
141 'l',
142 'l',
143 'o');
144 ASSERT_TRUE(rx_engine.ProcessPdu(
145 Fragmenter(kTestHandle)
146 .BuildFrame(kTestChannelId,
147 payload,
148 FrameCheckSequenceOption::kIncludeFcs)));
149 }
150
151 // Send with sequence 2.
152 {
153 const StaticByteBuffer payload( //
154 2 << 1, // TxSeq=2, R=0
155 0, // SAR and ReqSeq
156 'h',
157 'e',
158 'l',
159 'l',
160 'o');
161 EXPECT_TRUE(rx_engine.ProcessPdu(
162 Fragmenter(kTestHandle)
163 .BuildFrame(kTestChannelId,
164 payload,
165 FrameCheckSequenceOption::kIncludeFcs)));
166 }
167 }
168
TEST(EnhancedRetransmissionModeRxEngineTest,ProcessPduRollsOverSequenceNumber)169 TEST(EnhancedRetransmissionModeRxEngineTest,
170 ProcessPduRollsOverSequenceNumber) {
171 Engine rx_engine(NoOpTxCallback, NoOpFailureCallback);
172 StaticByteBuffer payload( //
173 0 << 1, // TxSeq=0, R=0
174 0, // SAR and ReqSeq
175 'h',
176 'e',
177 'l',
178 'l',
179 'o');
180 for (size_t i = 0; i < 64; ++i) {
181 payload[0] = static_cast<uint8_t>(i << 1); // Set TxSeq
182 ASSERT_TRUE(rx_engine.ProcessPdu(
183 Fragmenter(kTestHandle)
184 .BuildFrame(kTestChannelId,
185 payload,
186 FrameCheckSequenceOption::kIncludeFcs)))
187 << " (i=" << i << ")";
188 }
189
190 // Per Core Spec v5, Vol 3, Part A, Sec 8.3, the sequence number should now
191 // roll over to 0.
192 payload[0] = 0 << 1;
193 EXPECT_TRUE(rx_engine.ProcessPdu(
194 Fragmenter(kTestHandle)
195 .BuildFrame(
196 kTestChannelId, payload, FrameCheckSequenceOption::kIncludeFcs)));
197 }
198
TEST(EnhancedRetransmissionModeRxEngineTest,ProcessPduDoesNotAdvanceSequenceNumberForOutOfSequencePdu)199 TEST(EnhancedRetransmissionModeRxEngineTest,
200 ProcessPduDoesNotAdvanceSequenceNumberForOutOfSequencePdu) {
201 Engine rx_engine(NoOpTxCallback, NoOpFailureCallback);
202 const StaticByteBuffer out_of_seq( //
203 1 << 1, // TxSeq=1, R=0
204 0, // SAR and ReqSeq
205 'h',
206 'e',
207 'l',
208 'l',
209 'o');
210 ASSERT_FALSE(rx_engine.ProcessPdu(
211 Fragmenter(kTestHandle)
212 .BuildFrame(kTestChannelId,
213 out_of_seq,
214 FrameCheckSequenceOption::kIncludeFcs)));
215
216 const StaticByteBuffer in_seq( //
217 0 << 1, // TxSeq=0, R=0
218 0, // SAR and ReqSeq
219 'h',
220 'e',
221 'l',
222 'l',
223 'o');
224 EXPECT_TRUE(rx_engine.ProcessPdu(
225 Fragmenter(kTestHandle)
226 .BuildFrame(
227 kTestChannelId, in_seq, FrameCheckSequenceOption::kIncludeFcs)));
228 }
229
TEST(EnhancedRetransmissionModeRxEngineTest,ProcessPduImmediatelyAcksUnsegmentedSdu)230 TEST(EnhancedRetransmissionModeRxEngineTest,
231 ProcessPduImmediatelyAcksUnsegmentedSdu) {
232 size_t n_acks = 0;
233 ByteBufferPtr outbound_ack;
234 auto tx_callback = [&](auto pdu) {
235 outbound_ack = std::move(pdu);
236 ++n_acks;
237 };
238
239 // See Core Spec, v5, Vol 3, Part A, Table 3.2 for the first two bytes.
240 const StaticByteBuffer payload(0, 0, 'h', 'e', 'l', 'l', 'o');
241 ASSERT_TRUE(
242 Engine(tx_callback, NoOpFailureCallback)
243 .ProcessPdu(Fragmenter(kTestHandle)
244 .BuildFrame(kTestChannelId,
245 payload,
246 FrameCheckSequenceOption::kIncludeFcs)));
247 EXPECT_EQ(1u, n_acks);
248 ASSERT_TRUE(outbound_ack);
249 ASSERT_EQ(sizeof(SimpleReceiverReadyFrame), outbound_ack->size());
250
251 auto ack_frame =
252 *reinterpret_cast<const SimpleReceiverReadyFrame*>(outbound_ack->data());
253 EXPECT_EQ(SupervisoryFunction::ReceiverReady, ack_frame.function());
254 EXPECT_EQ(1u, ack_frame.receive_seq_num());
255 }
256
TEST(EnhancedRetransmissionModeRxEngineTest,ProcessPduSendsCorrectReqSeqOnRollover)257 TEST(EnhancedRetransmissionModeRxEngineTest,
258 ProcessPduSendsCorrectReqSeqOnRollover) {
259 size_t n_acks = 0;
260 ByteBufferPtr last_ack;
261 auto tx_callback = [&](auto pdu) {
262 last_ack = std::move(pdu);
263 ++n_acks;
264 };
265
266 Engine rx_engine(tx_callback, NoOpFailureCallback);
267 // See Core Spec, v5, Vol 3, Part A, Table 3.2 for the first two bytes.
268 for (size_t i = 0; i < 64; ++i) {
269 const StaticByteBuffer payload(i << 1, 0, 'h', 'e', 'l', 'l', 'o');
270 ASSERT_TRUE(rx_engine.ProcessPdu(
271 Fragmenter(kTestHandle)
272 .BuildFrame(kTestChannelId,
273 payload,
274 FrameCheckSequenceOption::kIncludeFcs)))
275 << " (i=" << i << ")";
276 }
277 EXPECT_EQ(64u, n_acks);
278 ASSERT_TRUE(last_ack);
279 ASSERT_EQ(sizeof(SimpleReceiverReadyFrame), last_ack->size());
280
281 auto ack_frame =
282 *reinterpret_cast<const SimpleReceiverReadyFrame*>(last_ack->data());
283 EXPECT_EQ(SupervisoryFunction::ReceiverReady, ack_frame.function());
284 EXPECT_EQ(0u, ack_frame.receive_seq_num());
285 }
286
TEST(EnhancedRetransmissionModeRxEngineTest,ProcessPduDoesNotAckOutOfSequenceFrame)287 TEST(EnhancedRetransmissionModeRxEngineTest,
288 ProcessPduDoesNotAckOutOfSequenceFrame) {
289 size_t n_acks = 0;
290 ByteBufferPtr outbound_ack;
291 auto tx_callback = [&](auto pdu) {
292 outbound_ack = std::move(pdu);
293 ++n_acks;
294 };
295
296 // See Core Spec, v5, Vol 3, Part A, Table 3.2 for the first two bytes.
297 const StaticByteBuffer payload(1, 0, 'h', 'e', 'l', 'l', 'o');
298
299 // Per Core Spec, v5, Vol 3, Part A, Sec 8.4.7.1, receipt of an
300 // out-of-sequence frame should cause us to transmit a Reject frame. We assume
301 // that we should _not_ also transmit a ReceiverReady frame.
302 //
303 // TODO(fxbug.dev/42055218): Revise this test when we start sending Reject
304 // frames.
305 ASSERT_FALSE(
306 Engine(tx_callback, NoOpFailureCallback)
307 .ProcessPdu(Fragmenter(kTestHandle)
308 .BuildFrame(kTestChannelId,
309 payload,
310 FrameCheckSequenceOption::kIncludeFcs)));
311 EXPECT_EQ(0u, n_acks);
312 }
313
TEST(EnhancedRetransmissionModeRxEngineTest,ProcessPduRespondsToReceiverReadyPollRequest)314 TEST(EnhancedRetransmissionModeRxEngineTest,
315 ProcessPduRespondsToReceiverReadyPollRequest) {
316 size_t n_outbound_frames = 0;
317 ByteBufferPtr last_outbound_frame;
318 auto tx_callback = [&](auto pdu) {
319 last_outbound_frame = std::move(pdu);
320 ++n_outbound_frames;
321 };
322
323 Engine rx_engine(tx_callback, NoOpFailureCallback);
324 // Send an I-frame to advance the receiver's sequence number.
325 // See Core Spec, v5, Vol 3, Part A, Table 3.2 for the first two bytes.
326 const StaticByteBuffer info_frame(0, 0, 'h', 'e', 'l', 'l', 'o');
327 rx_engine.ProcessPdu(Fragmenter(kTestHandle)
328 .BuildFrame(kTestChannelId,
329 info_frame,
330 FrameCheckSequenceOption::kIncludeFcs));
331 ASSERT_EQ(1u, n_outbound_frames);
332
333 // Now send a ReceiverReady poll request. See Core Spec, v5, Vol 3, Part A,
334 // Table 3.2 and Table 3.5 for frame format.
335 const StaticByteBuffer receiver_ready_poll_request(
336 0b1 | kExtendedControlPBitMask, 0);
337 auto local_sdu = rx_engine.ProcessPdu(
338 Fragmenter(kTestHandle)
339 .BuildFrame(kTestChannelId,
340 receiver_ready_poll_request,
341 FrameCheckSequenceOption::kIncludeFcs));
342 EXPECT_FALSE(local_sdu); // No payload in a ReceiverReady frame.
343 EXPECT_EQ(2u, n_outbound_frames);
344 ASSERT_TRUE(last_outbound_frame);
345 ASSERT_EQ(sizeof(SimpleSupervisoryFrame), last_outbound_frame->size());
346
347 auto sframe = *reinterpret_cast<const SimpleSupervisoryFrame*>(
348 last_outbound_frame->data());
349 EXPECT_EQ(SupervisoryFunction::ReceiverReady, sframe.function());
350 EXPECT_EQ(1u, sframe.receive_seq_num());
351 EXPECT_TRUE(sframe.is_poll_response());
352 EXPECT_FALSE(sframe.is_poll_request());
353 }
354
TEST(EnhancedRetransmissionModeRxEngineTest,ProcessPduCallsReceiveSeqNumCallback)355 TEST(EnhancedRetransmissionModeRxEngineTest,
356 ProcessPduCallsReceiveSeqNumCallback) {
357 Engine rx_engine(NoOpTxCallback, NoOpFailureCallback);
358
359 std::optional<uint8_t> receive_seq_num;
360 std::optional<bool> receive_is_poll_response;
361 auto receive_seq_num_callback = [&receive_seq_num, &receive_is_poll_response](
362 uint8_t seq_num, bool is_poll_response) {
363 receive_seq_num = seq_num;
364 receive_is_poll_response = is_poll_response;
365 };
366 rx_engine.set_receive_seq_num_callback(receive_seq_num_callback);
367
368 // Send an I-frame containing an acknowledgment up to the 3rd frame that we
369 // transmitted. See Core Spec, v5, Vol 3, Part A, Section 3.3.2, Table 3.2 for
370 // the first two bytes.
371 StaticByteBuffer info_frame(0, 3, 'h', 'e', 'l', 'l', 'o');
372 rx_engine.ProcessPdu(Fragmenter(kTestHandle)
373 .BuildFrame(kTestChannelId,
374 info_frame,
375 FrameCheckSequenceOption::kIncludeFcs));
376 ASSERT_TRUE(receive_seq_num.has_value());
377 EXPECT_EQ(3, receive_seq_num.value());
378 ASSERT_TRUE(receive_is_poll_response.has_value());
379 EXPECT_FALSE(receive_is_poll_response.value());
380
381 receive_is_poll_response.reset();
382
383 // Same as above but the 'F' bit is set.
384 info_frame[0] |= kExtendedControlFBitMask;
385 rx_engine.ProcessPdu(Fragmenter(kTestHandle)
386 .BuildFrame(kTestChannelId,
387 info_frame,
388 FrameCheckSequenceOption::kIncludeFcs));
389 ASSERT_TRUE(receive_is_poll_response.has_value());
390 EXPECT_TRUE(receive_is_poll_response.value());
391
392 receive_seq_num.reset();
393 receive_is_poll_response.reset();
394
395 // Send an S-frame containing an acknowledgment up to the 4th frame that we
396 // transmitted. F is set. See Core Spec, v5, Vol 3, Part A, Section 3.3.2,
397 // Table 3.2 for the frame format.
398 StaticByteBuffer receiver_ready(0b1 | kExtendedControlFBitMask, 4);
399 auto local_sdu = rx_engine.ProcessPdu(
400 Fragmenter(kTestHandle)
401 .BuildFrame(kTestChannelId,
402 receiver_ready,
403 FrameCheckSequenceOption::kIncludeFcs));
404 ASSERT_TRUE(receive_seq_num.has_value());
405 EXPECT_EQ(4, receive_seq_num.value());
406 ASSERT_TRUE(receive_is_poll_response.has_value());
407 EXPECT_TRUE(receive_is_poll_response.value());
408
409 receive_is_poll_response.reset();
410
411 // Same as above but the 'F' bit is clear.
412 receiver_ready[0] &= ~kExtendedControlFBitMask;
413 rx_engine.ProcessPdu(Fragmenter(kTestHandle)
414 .BuildFrame(kTestChannelId,
415 receiver_ready,
416 FrameCheckSequenceOption::kIncludeFcs));
417 ASSERT_TRUE(receive_is_poll_response.has_value());
418 EXPECT_FALSE(receive_is_poll_response.value());
419 }
420
TEST(EnhancedRetransmissionModeRxEngineTest,ProcessPduCallsAckSeqNumCallback)421 TEST(EnhancedRetransmissionModeRxEngineTest, ProcessPduCallsAckSeqNumCallback) {
422 Engine rx_engine(NoOpTxCallback, NoOpFailureCallback);
423
424 std::optional<uint8_t> ack_seq_num;
425 auto ack_seq_num_callback = [&ack_seq_num](uint8_t seq_num) {
426 ack_seq_num = seq_num;
427 };
428 rx_engine.set_ack_seq_num_callback(ack_seq_num_callback);
429
430 // Send an I-frame containing a sequence number for the first frame the
431 // receiver has sent. See Core Spec, v5, Vol 3, Part A, Section 3.3.2,
432 // Table 3.2 for the first two bytes.
433 StaticByteBuffer info_frame(0, 0, 'h', 'e', 'l', 'l', 'o');
434 rx_engine.ProcessPdu(Fragmenter(kTestHandle)
435 .BuildFrame(kTestChannelId,
436 info_frame,
437 FrameCheckSequenceOption::kIncludeFcs));
438 ASSERT_TRUE(ack_seq_num.has_value());
439
440 // We should now expect the next (second) frame to have a sequence number
441 // of 1.
442 EXPECT_EQ(1, ack_seq_num.value());
443 }
444
TEST(EnhancedRetransmissionModeRxEngineTest,ProcessPduCallsRemoteBusySetCallbackOnReceiverNotReady)445 TEST(EnhancedRetransmissionModeRxEngineTest,
446 ProcessPduCallsRemoteBusySetCallbackOnReceiverNotReady) {
447 Engine rx_engine(NoOpTxCallback, NoOpFailureCallback);
448
449 bool receive_seq_num_called = false;
450 rx_engine.set_receive_seq_num_callback(
451 [&](uint8_t, bool) { receive_seq_num_called = true; });
452
453 bool remote_busy_set_called = false;
454 auto remote_busy_set_callback = [&receive_seq_num_called,
455 &remote_busy_set_called] {
456 // RemoteBusy state should be updated before ReceiveSeqNum to immediately
457 // suppress retransmissions.
458 EXPECT_FALSE(receive_seq_num_called);
459 remote_busy_set_called = true;
460 };
461 rx_engine.set_remote_busy_set_callback(remote_busy_set_callback);
462
463 const StaticByteBuffer receiver_not_ready(
464 0b1 | kExtendedControlReceiverNotReadyBits, 0);
465 auto local_sdu = rx_engine.ProcessPdu(
466 Fragmenter(kTestHandle)
467 .BuildFrame(kTestChannelId,
468 receiver_not_ready,
469 FrameCheckSequenceOption::kIncludeFcs));
470 EXPECT_FALSE(local_sdu); // No payload in a ReceiverNotReady frame.
471 EXPECT_TRUE(remote_busy_set_called);
472 EXPECT_TRUE(receive_seq_num_called);
473
474 remote_busy_set_called = false;
475 local_sdu = rx_engine.ProcessPdu(
476 Fragmenter(kTestHandle)
477 .BuildFrame(kTestChannelId,
478 receiver_not_ready,
479 FrameCheckSequenceOption::kIncludeFcs));
480 EXPECT_FALSE(local_sdu); // No payload in a ReceiverNotReady frame.
481
482 // Second RNR should not invoke the callback.
483 EXPECT_FALSE(remote_busy_set_called);
484 }
485
TEST(EnhancedRetransmissionModeRxEngineTest,ProcessPduCallsRemoteBusySetCallbackOnReceiverNotReadyAfterReceiverReadyClearedBusy)486 TEST(
487 EnhancedRetransmissionModeRxEngineTest,
488 ProcessPduCallsRemoteBusySetCallbackOnReceiverNotReadyAfterReceiverReadyClearedBusy) {
489 Engine rx_engine(NoOpTxCallback, NoOpFailureCallback);
490
491 const StaticByteBuffer receiver_not_ready(
492 0b1 | kExtendedControlReceiverNotReadyBits, 0);
493 auto local_sdu = rx_engine.ProcessPdu(
494 Fragmenter(kTestHandle)
495 .BuildFrame(kTestChannelId,
496 receiver_not_ready,
497 FrameCheckSequenceOption::kIncludeFcs));
498 EXPECT_FALSE(local_sdu); // No payload in a ReceiverNotReady frame.
499
500 // This RR should clear RemoteBusy.
501 const StaticByteBuffer receiver_ready(0b1, 0);
502 local_sdu = rx_engine.ProcessPdu(
503 Fragmenter(kTestHandle)
504 .BuildFrame(kTestChannelId,
505 receiver_ready,
506 FrameCheckSequenceOption::kIncludeFcs));
507 EXPECT_FALSE(local_sdu); // No payload in a ReceiverReady frame.
508
509 bool remote_busy_set_called = false;
510 auto remote_busy_set_callback = [&remote_busy_set_called] {
511 remote_busy_set_called = true;
512 };
513 rx_engine.set_remote_busy_set_callback(remote_busy_set_callback);
514
515 // Receive a second RNR.
516 local_sdu = rx_engine.ProcessPdu(
517 Fragmenter(kTestHandle)
518 .BuildFrame(kTestChannelId,
519 receiver_not_ready,
520 FrameCheckSequenceOption::kIncludeFcs));
521 EXPECT_FALSE(local_sdu); // No payload in a ReceiverNotReady frame.
522
523 // Second RNR should invoke the callback because it's setting RemoteBusy once
524 // again.
525 EXPECT_TRUE(remote_busy_set_called);
526 }
527
528 // Test parameter is a bitmask to the Extended Control Field.
529 class ExtendedControlFieldBitsTest : public testing::TestWithParam<uint16_t> {};
530
TEST_P(ExtendedControlFieldBitsTest,ProcessPduCallsRemoteBusyClearedCallbackOnNonRnrSFrameAfterReceiverNotReady)531 TEST_P(
532 ExtendedControlFieldBitsTest,
533 ProcessPduCallsRemoteBusyClearedCallbackOnNonRnrSFrameAfterReceiverNotReady) {
534 Engine rx_engine(NoOpTxCallback, NoOpFailureCallback);
535
536 bool receive_seq_num_called = false;
537 int remote_busy_set_calls = 0;
538 rx_engine.set_remote_busy_set_callback([&] { remote_busy_set_calls++; });
539
540 int remote_busy_cleared_calls = 0;
541 auto remote_busy_cleared_callback = [&receive_seq_num_called,
542 &remote_busy_cleared_calls] {
543 // RemoteBusy state should be updated before ReceiveSeqNum to immediately
544 // resume retransmissions.
545 EXPECT_FALSE(receive_seq_num_called);
546 remote_busy_cleared_calls++;
547 };
548 rx_engine.set_remote_busy_cleared_callback(remote_busy_cleared_callback);
549
550 const StaticByteBuffer receiver_not_ready(
551 0b1 | kExtendedControlReceiverNotReadyBits, 0);
552 auto local_sdu = rx_engine.ProcessPdu(
553 Fragmenter(kTestHandle)
554 .BuildFrame(kTestChannelId,
555 receiver_not_ready,
556 FrameCheckSequenceOption::kIncludeFcs));
557 EXPECT_FALSE(local_sdu); // No payload in a ReceiverNotReady frame.
558
559 EXPECT_EQ(1, remote_busy_set_calls);
560 EXPECT_EQ(0, remote_busy_cleared_calls);
561
562 // The RNR invokes this callback but we only care about the callback ordering
563 // of the next frame.
564 rx_engine.set_receive_seq_num_callback(
565 [&](uint8_t, bool) { receive_seq_num_called = true; });
566
567 // This non-RNR S-Frame should clear RemoteBusy.
568 const uint16_t control_bits_to_set = GetParam();
569 const StaticByteBuffer non_rnr_s_frame(0b1 | LowerBits(control_bits_to_set),
570 0);
571 local_sdu = rx_engine.ProcessPdu(
572 Fragmenter(kTestHandle)
573 .BuildFrame(kTestChannelId,
574 non_rnr_s_frame,
575 FrameCheckSequenceOption::kIncludeFcs));
576 EXPECT_FALSE(local_sdu); // No payload in an S-Frame.
577
578 EXPECT_EQ(1, remote_busy_set_calls);
579 EXPECT_EQ(1, remote_busy_cleared_calls);
580 EXPECT_TRUE(receive_seq_num_called);
581
582 // Receive a second non-RNR.
583 local_sdu = rx_engine.ProcessPdu(
584 Fragmenter(kTestHandle)
585 .BuildFrame(kTestChannelId,
586 non_rnr_s_frame,
587 FrameCheckSequenceOption::kIncludeFcs));
588 EXPECT_FALSE(local_sdu); // No payload in an S-Frame.
589
590 EXPECT_EQ(1, remote_busy_set_calls);
591 EXPECT_EQ(1, remote_busy_cleared_calls);
592
593 // Second S-Frame shouldn't invoke either callback because RemoteBusy remains
594 // cleared.
595 }
596
597 INSTANTIATE_TEST_SUITE_P(EnhancedRetransmissionModeRxEngineTestNonRnrSFrames,
598 ExtendedControlFieldBitsTest,
599 testing::Values(kExtendedControlReceiverReadyBits,
600 kExtendedControlRejectBits,
601 kExtendedControlSelectiveRejectBits));
602
TEST(EnhancedRetransmissionModeRxEngineTest,ProcessPduCallsRangeRetransmitSetCallbackThenReceiveSeqNumCallbackOnReject)603 TEST(
604 EnhancedRetransmissionModeRxEngineTest,
605 ProcessPduCallsRangeRetransmitSetCallbackThenReceiveSeqNumCallbackOnReject) {
606 Engine rx_engine(NoOpTxCallback, NoOpFailureCallback);
607
608 std::optional<bool> receive_is_poll_request;
609 rx_engine.set_range_retransmit_set_callback(
610 [&](bool is_poll_request) { receive_is_poll_request = is_poll_request; });
611
612 std::optional<uint8_t> receive_seq_num;
613 std::optional<bool> receive_is_poll_response;
614 auto receive_seq_num_callback = [&](uint8_t seq_num, bool is_poll_response) {
615 // RangeRetransmitCallback should be called before ReceiveSeqNumCallback.
616 EXPECT_TRUE(receive_is_poll_request.has_value());
617 receive_seq_num = seq_num;
618 receive_is_poll_response = is_poll_response;
619 };
620 rx_engine.set_receive_seq_num_callback(receive_seq_num_callback);
621
622 // Send a REJ S-frame containing acknowledgment up to the 3rd frame that we
623 // transmitted. See Core Spec, v5, Vol 3, Part A, Section 3.3.2, Table 3.2 for
624 // the first two bytes.
625 auto rej_frame = StaticByteBuffer(0b1 | kExtendedControlRejectBits, 3);
626 rx_engine.ProcessPdu(Fragmenter(kTestHandle)
627 .BuildFrame(kTestChannelId,
628 rej_frame,
629 FrameCheckSequenceOption::kIncludeFcs));
630 EXPECT_TRUE(receive_seq_num.has_value());
631 EXPECT_TRUE(receive_is_poll_response.has_value());
632 }
633
TEST(EnhancedRetransmissionModeRxEngineTest,ProcessPduCallsSingleRetransmitSetCallbackThenReceiveSeqNumCallbackOnSelectiveReject)634 TEST(
635 EnhancedRetransmissionModeRxEngineTest,
636 ProcessPduCallsSingleRetransmitSetCallbackThenReceiveSeqNumCallbackOnSelectiveReject) {
637 Engine rx_engine(NoOpTxCallback, NoOpFailureCallback);
638
639 std::optional<bool> receive_is_poll_request;
640 rx_engine.set_single_retransmit_set_callback(
641 [&](bool is_poll_request) { receive_is_poll_request = is_poll_request; });
642
643 std::optional<uint8_t> receive_seq_num;
644 std::optional<bool> receive_is_poll_response;
645 auto receive_seq_num_callback = [&](uint8_t seq_num, bool is_poll_response) {
646 // SingleRetransmitCallback should be called before ReceiveSeqNumCallback.
647 EXPECT_TRUE(receive_is_poll_request.has_value());
648 receive_seq_num = seq_num;
649 receive_is_poll_response = is_poll_response;
650 };
651 rx_engine.set_receive_seq_num_callback(receive_seq_num_callback);
652
653 // Send an SREJ S-frame containing acknowledgment up to the 3rd frame that we
654 // transmitted. See Core Spec, v5, Vol 3, Part A, Section 3.3.2, Table 3.2 for
655 // the first two bytes.
656 auto srej_frame =
657 StaticByteBuffer(0b1 | kExtendedControlSelectiveRejectBits, 3);
658 rx_engine.ProcessPdu(Fragmenter(kTestHandle)
659 .BuildFrame(kTestChannelId,
660 srej_frame,
661 FrameCheckSequenceOption::kIncludeFcs));
662 EXPECT_TRUE(receive_seq_num.has_value());
663 EXPECT_TRUE(receive_is_poll_response.has_value());
664 }
665
TEST(EnhancedRetransmissionModeRxEngineTest,ProcessPduWithPollResponseAndPollRequestClosesChannel)666 TEST(EnhancedRetransmissionModeRxEngineTest,
667 ProcessPduWithPollResponseAndPollRequestClosesChannel) {
668 bool connection_failed = false;
669 Engine rx_engine(NoOpTxCallback, [&] { connection_failed = true; });
670
671 // Send an RR S-frame with both poll request and response bits set.
672 // See Core Spec, v5, Vol 3, Part A, Section 3.3.2, Table 3.2 for field
673 // definitions.
674 auto rr_frame = StaticByteBuffer(
675 0b1 | kExtendedControlFBitMask | kExtendedControlPBitMask, 0);
676 rx_engine.ProcessPdu(Fragmenter(kTestHandle)
677 .BuildFrame(kTestChannelId,
678 rr_frame,
679 FrameCheckSequenceOption::kIncludeFcs));
680 EXPECT_TRUE(connection_failed);
681 }
682
683 } // namespace
684 } // namespace bt::l2cap::internal
685