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