• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/signaling_channel.h"
16 
17 #include <pw_assert/check.h>
18 #include <pw_async/dispatcher.h>
19 
20 #include <chrono>
21 
22 #include "pw_bluetooth_sapphire/internal/host/l2cap/fake_channel_test.h"
23 #include "pw_bluetooth_sapphire/internal/host/testing/test_helpers.h"
24 
25 namespace bt::l2cap::internal {
26 namespace {
27 
28 using Status = SignalingChannelInterface::Status;
29 
30 constexpr CommandCode kUnknownCommandCode = 0x00;
31 constexpr CommandCode kCommandCode = 0xFF;
32 constexpr hci_spec::ConnectionHandle kTestHandle = 0x0001;
33 constexpr uint16_t kTestMTU = 100;
34 constexpr CommandId kMaxCommandId = std::numeric_limits<CommandId>::max();
35 
__anonbeb7fcf60202(Status, const ByteBuffer&) 36 const auto kTestResponseHandler = [](Status, const ByteBuffer&) {
37   return SignalingChannel::ResponseHandlerAction::kCompleteOutboundTransaction;
38 };
39 
40 class TestSignalingChannel : public SignalingChannel {
41  public:
TestSignalingChannel(Channel::WeakPtr chan,pw::async::Dispatcher & dispatcher)42   explicit TestSignalingChannel(Channel::WeakPtr chan,
43                                 pw::async::Dispatcher& dispatcher)
44       : SignalingChannel(std::move(chan),
45                          pw::bluetooth::emboss::ConnectionRole::CENTRAL,
46                          dispatcher) {
47     set_mtu(kTestMTU);
48   }
49   ~TestSignalingChannel() override = default;
50 
51   using PacketCallback = fit::function<void(const SignalingPacket& packet)>;
set_packet_callback(PacketCallback cb)52   void set_packet_callback(PacketCallback cb) { packet_cb_ = std::move(cb); }
53 
54   // Expose GetNextCommandId() as public so it can be called by tests below.
55   using SignalingChannel::GetNextCommandId;
56 
57   // Expose ResponderImpl as public so it can be directly tested (rather than
58   // passed to RequestDelegate).
59   using SignalingChannel::ResponderImpl;
60 
61  private:
62   // SignalingChannel overrides
DecodeRxUnit(ByteBufferPtr sdu,const SignalingPacketHandler & cb)63   void DecodeRxUnit(ByteBufferPtr sdu,
64                     const SignalingPacketHandler& cb) override {
65     PW_CHECK(sdu);
66     if (sdu->size()) {
67       cb(SignalingPacket(sdu.get(), sdu->size() - sizeof(CommandHeader)));
68     } else {
69       // Silently drop the packet. See documentation in signaling_channel.h.
70     }
71   }
72 
IsSupportedResponse(CommandCode code) const73   bool IsSupportedResponse(CommandCode code) const override {
74     switch (code) {
75       case kCommandRejectCode:
76       case kEchoResponse:
77         return true;
78     }
79 
80     return false;
81   }
82 
HandlePacket(const SignalingPacket & packet)83   bool HandlePacket(const SignalingPacket& packet) override {
84     if (packet_cb_)
85       packet_cb_(packet);
86 
87     return SignalingChannel::HandlePacket(packet);
88   }
89 
90   PacketCallback packet_cb_;
91 
92   BT_DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(TestSignalingChannel);
93 };
94 
95 class SignalingChannelTest : public testing::FakeChannelTest {
96  public:
97   SignalingChannelTest() = default;
98   ~SignalingChannelTest() override = default;
99 
100  protected:
SetUp()101   void SetUp() override {
102     ChannelOptions options(kLESignalingChannelId);
103     options.conn_handle = kTestHandle;
104 
105     fake_channel_inst_ = CreateFakeChannel(options);
106     sig_ = std::make_unique<TestSignalingChannel>(
107         fake_channel_inst_->GetWeakPtr(), dispatcher());
108   }
109 
TearDown()110   void TearDown() override {
111     // Unless a test called DestroySig(), the signaling channel will outlive the
112     // underlying channel.
113     fake_channel_inst_ = nullptr;
114     DestroySig();
115   }
116 
sig() const117   TestSignalingChannel* sig() const { return sig_.get(); }
118 
DestroySig()119   void DestroySig() { sig_ = nullptr; }
120 
121  private:
122   std::unique_ptr<TestSignalingChannel> sig_;
123 
124   // Own the fake channel so that its lifetime can span beyond that of |sig_|.
125   std::unique_ptr<Channel> fake_channel_inst_;
126 
127   BT_DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(SignalingChannelTest);
128 };
129 
TEST_F(SignalingChannelTest,IgnoreEmptyFrame)130 TEST_F(SignalingChannelTest, IgnoreEmptyFrame) {
131   bool send_cb_called = false;
132   auto send_cb = [&send_cb_called](auto) { send_cb_called = true; };
133 
134   fake_chan()->SetSendCallback(std::move(send_cb), dispatcher());
135   fake_chan()->Receive(BufferView());
136 
137   RunUntilIdle();
138   EXPECT_FALSE(send_cb_called);
139 }
140 
TEST_F(SignalingChannelTest,Reject)141 TEST_F(SignalingChannelTest, Reject) {
142   constexpr uint8_t kTestId = 14;
143 
144   // Command Reject packet.
145   StaticByteBuffer expected(
146       // Command header
147       0x01,
148       kTestId,
149       0x02,
150       0x00,
151 
152       // Reason (Command not understood)
153       0x00,
154       0x00);
155 
156   // A command that TestSignalingChannel does not support.
157   StaticByteBuffer cmd(
158       // header
159       kUnknownCommandCode,
160       kTestId,
161       0x04,
162       0x00,
163 
164       // data
165       'L',
166       'O',
167       'L',
168       'Z');
169 
170   EXPECT_TRUE(ReceiveAndExpect(cmd, expected));
171 }
172 
TEST_F(SignalingChannelTest,RejectCommandCodeZero)173 TEST_F(SignalingChannelTest, RejectCommandCodeZero) {
174   constexpr uint8_t kTestId = 14;
175 
176   // Command Reject packet.
177   StaticByteBuffer expected(
178       // Command header
179       0x01,
180       kTestId,
181       0x02,
182       0x00,
183 
184       // Reason (Command not understood)
185       0x00,
186       0x00);
187 
188   // A command that TestSignalingChannel does not support.
189   StaticByteBuffer cmd(
190       // header
191       0x00,
192       kTestId,
193       0x04,
194       0x00,
195 
196       // data
197       'L',
198       'O',
199       'L',
200       'Z');
201 
202   EXPECT_TRUE(ReceiveAndExpect(cmd, expected));
203 }
204 
TEST_F(SignalingChannelTest,RejectNotUnderstoodWithResponder)205 TEST_F(SignalingChannelTest, RejectNotUnderstoodWithResponder) {
206   constexpr uint8_t kTestId = 14;
207 
208   StaticByteBuffer expected(
209       // Command header (Command Reject, ID, length)
210       0x01,
211       kTestId,
212       0x02,
213       0x00,
214 
215       // Reason (Command not understood)
216       0x00,
217       0x00);
218 
219   bool cb_called = false;
220   auto send_cb = [&expected, &cb_called](auto packet) {
221     cb_called = true;
222     EXPECT_TRUE(ContainersEqual(expected, *packet));
223   };
224   fake_chan()->SetSendCallback(std::move(send_cb), dispatcher());
225 
226   TestSignalingChannel::ResponderImpl responder(sig(), kCommandCode, kTestId);
227   responder.RejectNotUnderstood();
228 
229   RunUntilIdle();
230   EXPECT_TRUE(cb_called);
231 }
232 
TEST_F(SignalingChannelTest,RejectInvalidCIdWithResponder)233 TEST_F(SignalingChannelTest, RejectInvalidCIdWithResponder) {
234   constexpr uint8_t kTestId = 14;
235   constexpr uint16_t kLocalCId = 0xf00d;
236   constexpr uint16_t kRemoteCId = 0xcafe;
237 
238   StaticByteBuffer expected(
239       // Command header (Command Reject, ID, length)
240       0x01,
241       kTestId,
242       0x06,
243       0x00,
244 
245       // Reason (Invalid channel ID)
246       0x02,
247       0x00,
248 
249       // Data (Channel IDs),
250       LowerBits(kLocalCId),
251       UpperBits(kLocalCId),
252       LowerBits(kRemoteCId),
253       UpperBits(kRemoteCId));
254 
255   bool cb_called = false;
256   auto send_cb = [&expected, &cb_called](auto packet) {
257     cb_called = true;
258     EXPECT_TRUE(ContainersEqual(expected, *packet));
259   };
260   fake_chan()->SetSendCallback(std::move(send_cb), dispatcher());
261 
262   TestSignalingChannel::ResponderImpl responder(sig(), kCommandCode, kTestId);
263   responder.RejectInvalidChannelId(kLocalCId, kRemoteCId);
264 
265   RunUntilIdle();
266   EXPECT_TRUE(cb_called);
267 }
268 
TEST_F(SignalingChannelTest,InvalidMTU)269 TEST_F(SignalingChannelTest, InvalidMTU) {
270   constexpr uint8_t kTestId = 14;
271   constexpr uint16_t kTooSmallMTU = 7;
272 
273   // Command Reject packet.
274   StaticByteBuffer expected(
275       // Command header
276       0x01,
277       kTestId,
278       0x04,
279       0x00,
280 
281       // Reason (Signaling MTU exceeded)
282       0x01,
283       0x00,
284 
285       // The supported MTU
286       static_cast<uint8_t>(kTooSmallMTU),
287       0x00);
288 
289   // A command that is one octet larger than the MTU.
290   StaticByteBuffer cmd(
291       // header
292       kCommandCode,
293       kTestId,
294       0x04,
295       0x00,
296 
297       // data
298       'L',
299       'O',
300       'L',
301       'Z');
302 
303   sig()->set_mtu(kTooSmallMTU);
304   EXPECT_TRUE(ReceiveAndExpect(cmd, expected));
305 }
306 
TEST_F(SignalingChannelTest,HandlePacket)307 TEST_F(SignalingChannelTest, HandlePacket) {
308   constexpr uint8_t kTestId = 14;
309 
310   // A command that TestSignalingChannel supports.
311   StaticByteBuffer cmd(
312       // header
313       kCommandCode,
314       kTestId,
315       0x04,
316       0x00,
317 
318       // data
319       'L',
320       'O',
321       'L',
322       'Z');
323 
324   bool called = false;
325   sig()->set_packet_callback([&cmd, &called](auto packet) {
326     EXPECT_TRUE(ContainersEqual(cmd, packet.data()));
327     called = true;
328   });
329 
330   fake_chan()->Receive(cmd);
331 
332   RunUntilIdle();
333   EXPECT_TRUE(called);
334 }
335 
TEST_F(SignalingChannelTest,UseChannelAfterSignalFree)336 TEST_F(SignalingChannelTest, UseChannelAfterSignalFree) {
337   // Destroy the underlying channel's user (SignalingChannel).
338   DestroySig();
339 
340   // Ensure that the underlying channel is still alive.
341   ASSERT_TRUE(fake_chan().is_alive());
342 
343   // SignalingChannel is expected to deactivate the channel if it doesn't own
344   // it. Either way, the channel isn't in a state that can receive test data.
345   EXPECT_FALSE(fake_chan()->activated());
346 
347   // Ensure that closing the channel (possibly firing callback) is OK.
348   fake_chan()->Close();
349 
350   RunUntilIdle();
351 }
352 
TEST_F(SignalingChannelTest,ValidRequestCommandIds)353 TEST_F(SignalingChannelTest, ValidRequestCommandIds) {
354   EXPECT_EQ(0x01, sig()->GetNextCommandId());
355   for (int i = 0; i < kMaxCommandId + 1; i++) {
356     EXPECT_NE(0x00, sig()->GetNextCommandId());
357   }
358 }
359 
TEST_F(SignalingChannelTest,DoNotRejectUnsolicitedResponse)360 TEST_F(SignalingChannelTest, DoNotRejectUnsolicitedResponse) {
361   constexpr CommandId kTestCmdId = 97;
362   StaticByteBuffer cmd(
363       // Command header (Echo Response, length 1)
364       0x09,
365       kTestCmdId,
366       0x01,
367       0x00,
368 
369       // Payload
370       0x23);
371 
372   size_t send_count = 0;
373   auto send_cb = [&](auto) { send_count++; };
374   fake_chan()->SetSendCallback(std::move(send_cb), dispatcher());
375 
376   fake_chan()->Receive(cmd);
377   RunUntilIdle();
378   EXPECT_EQ(0u, send_count);
379 }
380 
TEST_F(SignalingChannelTest,RejectRemoteResponseWithWrongType)381 TEST_F(SignalingChannelTest, RejectRemoteResponseWithWrongType) {
382   constexpr CommandId kReqId = 1;
383 
384   // Remote's response with the correct ID but wrong type of response.
385   const StaticByteBuffer rsp_invalid_id(
386       // Disconnection Response with plausible 4-byte payload.
387       0x07,
388       kReqId,
389       0x04,
390       0x00,
391 
392       // Payload
393       0x0A,
394       0x00,
395       0x08,
396       0x00);
397   const StaticByteBuffer req_data('P', 'W', 'N');
398 
399   bool tx_success = false;
400   fake_chan()->SetSendCallback([&tx_success](auto) { tx_success = true; },
401                                dispatcher());
402 
403   bool echo_cb_called = false;
404   EXPECT_TRUE(sig()->SendRequest(
405       kEchoRequest, req_data, [&echo_cb_called](auto, auto&) {
406         echo_cb_called = true;
407         return SignalingChannel::ResponseHandlerAction::
408             kCompleteOutboundTransaction;
409       }));
410 
411   RunUntilIdle();
412   EXPECT_TRUE(tx_success);
413 
414   const StaticByteBuffer reject_rsp(
415       // Command header (Command Rejected)
416       0x01,
417       kReqId,
418       0x02,
419       0x00,
420 
421       // Reason (Command not understood)
422       0x00,
423       0x00);
424   bool reject_sent = false;
425   fake_chan()->SetSendCallback(
426       [&reject_rsp, &reject_sent](auto cb_packet) {
427         reject_sent = ContainersEqual(reject_rsp, *cb_packet);
428       },
429       dispatcher());
430 
431   fake_chan()->Receive(rsp_invalid_id);
432 
433   RunUntilIdle();
434   EXPECT_FALSE(echo_cb_called);
435   EXPECT_TRUE(reject_sent);
436 }
437 
438 // Ensure that the signaling channel can reuse outgoing command IDs. In the case
439 // that it's expecting a response on every single valid command ID, requests
440 // should fail.
TEST_F(SignalingChannelTest,ReuseCommandIdsUntilExhausted)441 TEST_F(SignalingChannelTest, ReuseCommandIdsUntilExhausted) {
442   int req_count = 0;
443   constexpr CommandId kRspId = 0x0c;
444 
445   auto check_header_id = [&req_count, kRspId](auto cb_packet) {
446     req_count++;
447     SignalingPacket sent_sig_pkt(cb_packet.get());
448     if (req_count == kMaxCommandId + 1) {
449       EXPECT_EQ(kRspId, sent_sig_pkt.header().id);
450     } else {
451       EXPECT_EQ(req_count, sent_sig_pkt.header().id);
452     }
453   };
454   fake_chan()->SetSendCallback(std::move(check_header_id), dispatcher());
455 
456   const StaticByteBuffer req_data('y', 'o', 'o', 'o', 'o', '\0');
457 
458   for (int i = 0; i < kMaxCommandId; i++) {
459     EXPECT_TRUE(
460         sig()->SendRequest(kEchoRequest, req_data, kTestResponseHandler));
461   }
462 
463   // All command IDs should be exhausted at this point, so no commands of this
464   // type should be allowed to be sent.
465   EXPECT_FALSE(
466       sig()->SendRequest(kEchoRequest, req_data, kTestResponseHandler));
467 
468   RunUntilIdle();
469   EXPECT_EQ(kMaxCommandId, req_count);
470 
471   // Remote finally responds to a request, but not in order requests were sent.
472   // This will free a command ID.
473   const StaticByteBuffer echo_rsp(
474       // Echo response with no payload.
475       0x09,
476       kRspId,
477       0x00,
478       0x00);
479   fake_chan()->Receive(echo_rsp);
480 
481   RunUntilIdle();
482 
483   // Request should use freed command ID.
484   EXPECT_TRUE(sig()->SendRequest(kEchoRequest, req_data, kTestResponseHandler));
485 
486   RunUntilIdle();
487   EXPECT_EQ(kMaxCommandId + 1, req_count);
488 }
489 
490 // Ensure that a response handler may destroy the signaling channel.
TEST_F(SignalingChannelTest,ResponseHandlerThatDestroysSigDoesNotCrash)491 TEST_F(SignalingChannelTest, ResponseHandlerThatDestroysSigDoesNotCrash) {
492   fake_chan()->SetSendCallback([](auto) {}, dispatcher());
493 
494   const StaticByteBuffer req_data('h', 'e', 'l', 'l', 'o');
495   bool rx_success = false;
496   EXPECT_TRUE(sig()->SendRequest(
497       kEchoRequest, req_data, [this, &rx_success](Status, const ByteBuffer&) {
498         rx_success = true;
499         DestroySig();
500         return SignalingChannel::ResponseHandlerAction::
501             kCompleteOutboundTransaction;
502       }));
503 
504   constexpr CommandId kReqId = 1;
505   const StaticByteBuffer echo_rsp(
506       // Command header (Echo Response, length 1)
507       kEchoResponse,
508       kReqId,
509       0x01,
510       0x00,
511 
512       // Payload
513       0x23);
514   fake_chan()->Receive(echo_rsp);
515 
516   RunUntilIdle();
517   EXPECT_FALSE(sig());
518   EXPECT_TRUE(rx_success);
519 }
520 
521 // Ensure that the signaling channel plumbs a rejection command from remote to
522 // the appropriate response handler.
TEST_F(SignalingChannelTest,RemoteRejectionPassedToHandler)523 TEST_F(SignalingChannelTest, RemoteRejectionPassedToHandler) {
524   const StaticByteBuffer reject_rsp(
525       // Command header (Command Rejected)
526       0x01,
527       0x01,
528       0x02,
529       0x00,
530 
531       // Reason (Command not understood)
532       0x00,
533       0x00);
534 
535   bool tx_success = false;
536   fake_chan()->SetSendCallback([&tx_success](auto) { tx_success = true; },
537                                dispatcher());
538 
539   const StaticByteBuffer req_data('h', 'e', 'l', 'l', 'o');
540   bool rx_success = false;
541   EXPECT_TRUE(sig()->SendRequest(
542       kEchoRequest,
543       req_data,
544       [&rx_success, &reject_rsp](Status status, const ByteBuffer& rsp_payload) {
545         rx_success = true;
546         EXPECT_EQ(Status::kReject, status);
547         EXPECT_TRUE(ContainersEqual(reject_rsp.view(sizeof(CommandHeader)),
548                                     rsp_payload));
549         return SignalingChannel::ResponseHandlerAction::
550             kCompleteOutboundTransaction;
551       }));
552 
553   RunUntilIdle();
554   EXPECT_TRUE(tx_success);
555 
556   // Remote sends back a rejection.
557   fake_chan()->Receive(reject_rsp);
558 
559   RunUntilIdle();
560   EXPECT_TRUE(rx_success);
561 }
562 
TEST_F(SignalingChannelTest,HandlerCompletedByResponseNotCalledAgainAfterRtxTimeout)563 TEST_F(SignalingChannelTest,
564        HandlerCompletedByResponseNotCalledAgainAfterRtxTimeout) {
565   bool tx_success = false;
566   fake_chan()->SetSendCallback([&tx_success](auto) { tx_success = true; },
567                                dispatcher());
568 
569   const StaticByteBuffer req_data('h', 'e', 'l', 'l', 'o');
570   int rx_cb_count = 0;
571   EXPECT_TRUE(sig()->SendRequest(
572       kEchoRequest, req_data, [&rx_cb_count](Status status, const ByteBuffer&) {
573         rx_cb_count++;
574         EXPECT_EQ(Status::kSuccess, status);
575         return SignalingChannel::ResponseHandlerAction::
576             kCompleteOutboundTransaction;
577       }));
578 
579   const StaticByteBuffer echo_rsp(
580       // Echo response with no payload.
581       0x09,
582       0x01,
583       0x00,
584       0x00);
585   fake_chan()->Receive(echo_rsp);
586 
587   RunUntilIdle();
588   EXPECT_TRUE(tx_success);
589   EXPECT_EQ(1, rx_cb_count);
590 
591   RunFor(kSignalingChannelResponseTimeout);
592   EXPECT_EQ(1, rx_cb_count);
593 }
594 
595 // Ensure that the signaling channel calls ResponseHandler with Status::kTimeOut
596 // after a request times out waiting for a peer response.
TEST_F(SignalingChannelTest,CallHandlerCalledAfterMaxNumberOfRtxTimeoutRetransmissions)597 TEST_F(SignalingChannelTest,
598        CallHandlerCalledAfterMaxNumberOfRtxTimeoutRetransmissions) {
599   size_t send_cb_count = 0;
600   auto send_cb = [&](auto cb_packet) {
601     SignalingPacket pkt(cb_packet.get());
602     EXPECT_EQ(pkt.header().id, 1u);
603     send_cb_count++;
604   };
605   fake_chan()->SetSendCallback(std::move(send_cb), dispatcher());
606 
607   const StaticByteBuffer req_data('h', 'e', 'l', 'l', 'o');
608   bool rx_cb_called = false;
609   EXPECT_TRUE(
610       sig()->SendRequest(kEchoRequest,
611                          req_data,
612                          [&rx_cb_called](Status status, const ByteBuffer&) {
613                            rx_cb_called = true;
614                            EXPECT_EQ(Status::kTimeOut, status);
615                            return SignalingChannel::ResponseHandlerAction::
616                                kCompleteOutboundTransaction;
617                          }));
618 
619   RunUntilIdle();
620   EXPECT_EQ(send_cb_count, 1u);
621   EXPECT_FALSE(rx_cb_called);
622 
623   auto timeout = kSignalingChannelResponseTimeout;
624   for (size_t i = 1; i < kMaxSignalingChannelTransmissions; i++) {
625     // Ensure retransmission doesn't happen before timeout.
626     RunFor(timeout - std::chrono::milliseconds(100));
627     EXPECT_EQ(send_cb_count, i);
628 
629     RunFor(std::chrono::milliseconds(100));
630     EXPECT_EQ(send_cb_count, 1 + i);
631     EXPECT_FALSE(rx_cb_called);
632 
633     timeout *= 2;
634   }
635 
636   send_cb_count = 0;
637   RunFor(timeout);
638   EXPECT_EQ(send_cb_count, 0u);
639   EXPECT_TRUE(rx_cb_called);
640 }
641 
TEST_F(SignalingChannelTest,TwoResponsesToARetransmittedOutboundRequest)642 TEST_F(SignalingChannelTest, TwoResponsesToARetransmittedOutboundRequest) {
643   size_t send_cb_count = 0;
644   auto send_cb = [&](auto cb_packet) {
645     SignalingPacket pkt(cb_packet.get());
646     EXPECT_EQ(pkt.header().id, 1u);
647     send_cb_count++;
648   };
649   fake_chan()->SetSendCallback(std::move(send_cb), dispatcher());
650 
651   const StaticByteBuffer req_data('h', 'e', 'l', 'l', 'o');
652   size_t rx_cb_count = 0;
653   EXPECT_TRUE(sig()->SendRequest(
654       kEchoRequest, req_data, [&rx_cb_count](Status status, const ByteBuffer&) {
655         rx_cb_count++;
656         EXPECT_EQ(Status::kSuccess, status);
657         return SignalingChannel::ResponseHandlerAction::
658             kCompleteOutboundTransaction;
659       }));
660 
661   RunUntilIdle();
662   EXPECT_EQ(1u, send_cb_count);
663   EXPECT_EQ(0u, rx_cb_count);
664 
665   RunFor(kSignalingChannelResponseTimeout);
666   EXPECT_EQ(2u, send_cb_count);
667   EXPECT_EQ(0u, rx_cb_count);
668 
669   const StaticByteBuffer echo_rsp(kEchoResponse, 0x01, 0x00, 0x00);
670   fake_chan()->Receive(echo_rsp);
671   EXPECT_EQ(2u, send_cb_count);
672   EXPECT_EQ(1u, rx_cb_count);
673 
674   // Second response should be ignored as it is unexpected.
675   fake_chan()->Receive(echo_rsp);
676   EXPECT_EQ(2u, send_cb_count);
677   EXPECT_EQ(1u, rx_cb_count);
678 }
679 
680 // When the response handler expects more responses, use the longer ERTX timeout
681 // for the following response.
TEST_F(SignalingChannelTest,ExpectAdditionalResponseExtendsRtxTimeoutToErtxTimeout)682 TEST_F(SignalingChannelTest,
683        ExpectAdditionalResponseExtendsRtxTimeoutToErtxTimeout) {
684   bool tx_success = false;
685   fake_chan()->SetSendCallback([&tx_success](auto) { tx_success = true; },
686                                dispatcher());
687 
688   const StaticByteBuffer req_data{'h', 'e', 'l', 'l', 'o'};
689   int rx_cb_calls = 0;
690   EXPECT_TRUE(sig()->SendRequest(
691       kEchoRequest, req_data, [&rx_cb_calls](Status status, const ByteBuffer&) {
692         rx_cb_calls++;
693         if (rx_cb_calls <= 2) {
694           EXPECT_EQ(Status::kSuccess, status);
695         } else {
696           EXPECT_EQ(Status::kTimeOut, status);
697         }
698         return SignalingChannel::ResponseHandlerAction::
699             kExpectAdditionalResponse;
700       }));
701 
702   RunUntilIdle();
703   EXPECT_TRUE(tx_success);
704   EXPECT_EQ(0, rx_cb_calls);
705 
706   const StaticByteBuffer echo_rsp(
707       // Echo response with no payload.
708       0x09,
709       0x01,
710       0x00,
711       0x00);
712   fake_chan()->Receive(echo_rsp);
713   EXPECT_EQ(1, rx_cb_calls);
714 
715   // The handler expects more responses so the RTX timer shouldn't have expired.
716   RunFor(kSignalingChannelResponseTimeout);
717 
718   fake_chan()->Receive(echo_rsp);
719   EXPECT_EQ(2, rx_cb_calls);
720 
721   // The second response should have reset the ERTX timer, so it shouldn't fire
722   // yet.
723   RunFor(kSignalingChannelExtendedResponseTimeout -
724          std::chrono::milliseconds(100));
725 
726   // If the renewed ERTX timer expires without a third response, receive a
727   // kTimeOut "response."
728   RunFor(std::chrono::seconds(1));
729   EXPECT_EQ(3, rx_cb_calls);
730 }
731 
TEST_F(SignalingChannelTest,RegisterRequestResponder)732 TEST_F(SignalingChannelTest, RegisterRequestResponder) {
733   const StaticByteBuffer remote_req(
734       // Disconnection Request.
735       0x06,
736       0x01,
737       0x04,
738       0x00,
739 
740       // Payload
741       0x0A,
742       0x00,
743       0x08,
744       0x00);
745   const BufferView& expected_payload = remote_req.view(sizeof(CommandHeader));
746 
747   auto expected_rej = StaticByteBuffer(
748       // Command header (Command rejected, length 2)
749       0x01,
750       0x01,
751       0x02,
752       0x00,
753 
754       // Reason (Command not understood)
755       0x00,
756       0x00);
757 
758   // Receive remote's request before a handler is assigned, expecting an
759   // outbound rejection.
760   ReceiveAndExpect(remote_req, expected_rej);
761 
762   // Register the handler.
763   bool cb_called = false;
764   sig()->ServeRequest(
765       kDisconnectionRequest,
766       [&cb_called, &expected_payload](const ByteBuffer& req_payload,
767                                       SignalingChannel::Responder* responder) {
768         cb_called = true;
769         EXPECT_TRUE(ContainersEqual(expected_payload, req_payload));
770         responder->Send(req_payload);
771       });
772 
773   const ByteBuffer& local_rsp = StaticByteBuffer(
774       // Disconnection Response.
775       0x07,
776       0x01,
777       0x04,
778       0x00,
779 
780       // Payload
781       0x0A,
782       0x00,
783       0x08,
784       0x00);
785 
786   // Receive the same command again.
787   ReceiveAndExpect(remote_req, local_rsp);
788   EXPECT_TRUE(cb_called);
789 }
790 
TEST_F(SignalingChannelTest,DoNotRejectRemoteResponseInvalidId)791 TEST_F(SignalingChannelTest, DoNotRejectRemoteResponseInvalidId) {
792   // Request will use ID = 1.
793   constexpr CommandId kIncorrectId = 2;
794   // Remote's echo response that has a different ID to what will be in the
795   // request header.
796   const StaticByteBuffer rsp_invalid_id(
797       // Echo response with 4-byte payload.
798       0x09,
799       kIncorrectId,
800       0x04,
801       0x00,
802 
803       // Payload
804       'L',
805       '3',
806       '3',
807       'T');
808   const BufferView req_data = rsp_invalid_id.view(sizeof(CommandHeader));
809 
810   bool tx_success = false;
811   fake_chan()->SetSendCallback([&tx_success](auto) { tx_success = true; },
812                                dispatcher());
813 
814   bool echo_cb_called = false;
815   EXPECT_TRUE(sig()->SendRequest(
816       kEchoRequest, req_data, [&echo_cb_called](auto, auto&) {
817         echo_cb_called = true;
818         return SignalingChannel::ResponseHandlerAction::
819             kCompleteOutboundTransaction;
820       }));
821 
822   RunUntilIdle();
823   EXPECT_TRUE(tx_success);
824 
825   bool reject_sent = false;
826   fake_chan()->SetSendCallback([&reject_sent](auto) { reject_sent = true; },
827                                dispatcher());
828 
829   fake_chan()->Receive(rsp_invalid_id);
830 
831   RunUntilIdle();
832   EXPECT_FALSE(echo_cb_called);
833   EXPECT_FALSE(reject_sent);
834 }
835 
836 }  // namespace
837 }  // namespace bt::l2cap::internal
838