• 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/bredr_command_handler.h"
16 
17 #include <pw_async/fake_dispatcher_fixture.h>
18 
19 #include <memory>
20 #include <unordered_map>
21 #include <vector>
22 
23 #include "pw_bluetooth_sapphire/internal/host/l2cap/channel_configuration.h"
24 #include "pw_bluetooth_sapphire/internal/host/l2cap/fake_signaling_channel.h"
25 #include "pw_bluetooth_sapphire/internal/host/l2cap/l2cap_defs.h"
26 #include "pw_bluetooth_sapphire/internal/host/testing/test_helpers.h"
27 
28 namespace bt::l2cap::internal {
29 namespace {
30 
31 constexpr uint16_t kPsm = 0x0001;
32 constexpr ChannelId kLocalCId = 0x0040;
33 constexpr ChannelId kRemoteCId = 0x60a3;
34 
35 class BrEdrCommandHandlerTest : public pw::async::test::FakeDispatcherFixture {
36  public:
37   BrEdrCommandHandlerTest() = default;
38   ~BrEdrCommandHandlerTest() override = default;
39   BT_DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(BrEdrCommandHandlerTest);
40 
41  protected:
42   // TestLoopFixture overrides
SetUp()43   void SetUp() override {
44     signaling_channel_ =
45         std::make_unique<testing::FakeSignalingChannel>(dispatcher());
46     command_handler_ = std::make_unique<BrEdrCommandHandler>(
47         fake_sig(),
48         fit::bind_member<&BrEdrCommandHandlerTest::OnRequestFail>(this));
49     request_fail_callback_ = nullptr;
50     failed_requests_ = 0;
51   }
52 
TearDown()53   void TearDown() override {
54     request_fail_callback_ = nullptr;
55     signaling_channel_ = nullptr;
56     command_handler_ = nullptr;
57   }
58 
fake_sig() const59   testing::FakeSignalingChannel* fake_sig() const {
60     return signaling_channel_.get();
61   }
cmd_handler() const62   BrEdrCommandHandler* cmd_handler() const { return command_handler_.get(); }
failed_requests() const63   size_t failed_requests() const { return failed_requests_; }
64 
set_request_fail_callback(fit::closure request_fail_callback)65   void set_request_fail_callback(fit::closure request_fail_callback) {
66     BT_ASSERT(!request_fail_callback_);
67     request_fail_callback_ = std::move(request_fail_callback);
68   }
69 
70  private:
OnRequestFail()71   void OnRequestFail() {
72     failed_requests_++;
73     if (request_fail_callback_) {
74       request_fail_callback_();
75     }
76   }
77 
78   std::unique_ptr<testing::FakeSignalingChannel> signaling_channel_;
79   std::unique_ptr<BrEdrCommandHandler> command_handler_;
80   fit::closure request_fail_callback_;
81   size_t failed_requests_;
82 };
83 
TEST_F(BrEdrCommandHandlerTest,OutboundConnReqRej)84 TEST_F(BrEdrCommandHandlerTest, OutboundConnReqRej) {
85   constexpr ChannelId kBadLocalCId = 0x0005;  // Not a dynamic channel
86 
87   // Connection Request payload
88   StaticByteBuffer expected_conn_req(
89       // PSM
90       LowerBits(kPsm),
91       UpperBits(kPsm),
92 
93       // Source CID
94       LowerBits(kBadLocalCId),
95       UpperBits(kBadLocalCId));
96 
97   // Command Reject payload
98   StaticByteBuffer rej_rsp(
99       // Reject Reason (invalid channel ID)
100       LowerBits(static_cast<uint16_t>(RejectReason::kInvalidCID)),
101       UpperBits(static_cast<uint16_t>(RejectReason::kInvalidCID)),
102 
103       // Local (relative to rejecter) CID
104       LowerBits(kInvalidChannelId),
105       UpperBits(kInvalidChannelId),
106 
107       // Remote (relative to rejecter) CID
108       LowerBits(kBadLocalCId),
109       UpperBits(kBadLocalCId));
110   EXPECT_OUTBOUND_REQ(*fake_sig(),
111                       kConnectionRequest,
112                       expected_conn_req.view(),
113                       {SignalingChannel::Status::kReject, rej_rsp.view()});
114 
115   bool cb_called = false;
116   auto on_conn_rsp = [&cb_called, kBadLocalCId](
117                          const BrEdrCommandHandler::ConnectionResponse& rsp) {
118     cb_called = true;
119     EXPECT_EQ(BrEdrCommandHandler::Status::kReject, rsp.status());
120     EXPECT_EQ(kInvalidChannelId, rsp.remote_cid());
121     EXPECT_EQ(kBadLocalCId, rsp.local_cid());
122     return BrEdrCommandHandler::ResponseHandlerAction::
123         kCompleteOutboundTransaction;
124   };
125 
126   EXPECT_TRUE(cmd_handler()->SendConnectionRequest(
127       kPsm, kBadLocalCId, std::move(on_conn_rsp)));
128   RunUntilIdle();
129   EXPECT_TRUE(cb_called);
130 }
131 
TEST_F(BrEdrCommandHandlerTest,OutboundConnReqRejNotEnoughBytesInRejection)132 TEST_F(BrEdrCommandHandlerTest, OutboundConnReqRejNotEnoughBytesInRejection) {
133   constexpr ChannelId kBadLocalCId = 0x0005;  // Not a dynamic channel
134 
135   // Connection Request payload
136   StaticByteBuffer expected_conn_req(
137       // PSM
138       LowerBits(kPsm),
139       UpperBits(kPsm),
140 
141       // Source CID
142       LowerBits(kBadLocalCId),
143       UpperBits(kBadLocalCId));
144 
145   // Command Reject payload (the invalid channel IDs are missing)
146   StaticByteBuffer rej_rsp(
147       // Reject Reason (invalid channel ID)
148       LowerBits(static_cast<uint16_t>(RejectReason::kInvalidCID)),
149       UpperBits(static_cast<uint16_t>(RejectReason::kInvalidCID)));
150 
151   EXPECT_OUTBOUND_REQ(*fake_sig(),
152                       kConnectionRequest,
153                       expected_conn_req.view(),
154                       {SignalingChannel::Status::kReject, rej_rsp.view()});
155 
156   bool cb_called = false;
157   auto on_conn_rsp =
158       [&cb_called](const BrEdrCommandHandler::ConnectionResponse& rsp) {
159         cb_called = true;
160         return BrEdrCommandHandler::ResponseHandlerAction::
161             kCompleteOutboundTransaction;
162       };
163 
164   EXPECT_TRUE(cmd_handler()->SendConnectionRequest(
165       kPsm, kBadLocalCId, std::move(on_conn_rsp)));
166   RunUntilIdle();
167   EXPECT_FALSE(cb_called);
168 }
169 
TEST_F(BrEdrCommandHandlerTest,OutboundConnReqRspOk)170 TEST_F(BrEdrCommandHandlerTest, OutboundConnReqRspOk) {
171   // Connection Request payload
172   StaticByteBuffer expected_conn_req(
173       // PSM
174       LowerBits(kPsm),
175       UpperBits(kPsm),
176 
177       // Source CID
178       LowerBits(kLocalCId),
179       UpperBits(kLocalCId));
180 
181   // Connection Response payload
182   StaticByteBuffer ok_conn_rsp(
183       // Destination CID
184       LowerBits(kRemoteCId),
185       UpperBits(kRemoteCId),
186 
187       // Source CID
188       LowerBits(kLocalCId),
189       UpperBits(kLocalCId),
190 
191       // Result (Successful)
192       0x00,
193       0x00,
194 
195       // Status (No further information available)
196       0x00,
197       0x00);
198   EXPECT_OUTBOUND_REQ(*fake_sig(),
199                       kConnectionRequest,
200                       expected_conn_req.view(),
201                       {SignalingChannel::Status::kSuccess, ok_conn_rsp.view()});
202 
203   bool cb_called = false;
204   auto on_conn_rsp =
205       [&cb_called](const BrEdrCommandHandler::ConnectionResponse& rsp) {
206         cb_called = true;
207         EXPECT_EQ(BrEdrCommandHandler::Status::kSuccess, rsp.status());
208         EXPECT_EQ(kRemoteCId, rsp.remote_cid());
209         EXPECT_EQ(kLocalCId, rsp.local_cid());
210         EXPECT_EQ(ConnectionResult::kSuccess, rsp.result());
211         EXPECT_EQ(ConnectionStatus::kNoInfoAvailable, rsp.conn_status());
212         return SignalingChannel::ResponseHandlerAction::
213             kCompleteOutboundTransaction;
214       };
215 
216   EXPECT_TRUE(cmd_handler()->SendConnectionRequest(
217       kPsm, kLocalCId, std::move(on_conn_rsp)));
218   RunUntilIdle();
219   EXPECT_TRUE(cb_called);
220 }
221 
TEST_F(BrEdrCommandHandlerTest,OutboundConnReqRspPendingAuthThenOk)222 TEST_F(BrEdrCommandHandlerTest, OutboundConnReqRspPendingAuthThenOk) {
223   // Connection Request payload
224   StaticByteBuffer expected_conn_req(
225       // PSM
226       LowerBits(kPsm),
227       UpperBits(kPsm),
228 
229       // Source CID
230       LowerBits(kLocalCId),
231       UpperBits(kLocalCId));
232 
233   // Connection Response payload
234   StaticByteBuffer pend_conn_rsp(
235       // Destination CID
236       LowerBits(kRemoteCId),
237       UpperBits(kRemoteCId),
238 
239       // Source CID
240       LowerBits(kLocalCId),
241       UpperBits(kLocalCId),
242 
243       // Result (Pending)
244       0x01,
245       0x00,
246 
247       // Status (Authorization pending)
248       0x02,
249       0x00);
250 
251   StaticByteBuffer ok_conn_rsp(
252       // Destination CID
253       LowerBits(kRemoteCId),
254       UpperBits(kRemoteCId),
255 
256       // Source CID
257       LowerBits(kLocalCId),
258       UpperBits(kLocalCId),
259 
260       // Result (Successful)
261       0x00,
262       0x00,
263 
264       // Status (No further information available)
265       0x00,
266       0x00);
267   EXPECT_OUTBOUND_REQ(
268       *fake_sig(),
269       kConnectionRequest,
270       expected_conn_req.view(),
271       {SignalingChannel::Status::kSuccess, pend_conn_rsp.view()},
272       {SignalingChannel::Status::kSuccess, ok_conn_rsp.view()});
273 
274   int cb_count = 0;
275   auto on_conn_rsp = [&cb_count](
276                          const BrEdrCommandHandler::ConnectionResponse& rsp) {
277     cb_count++;
278     EXPECT_EQ(kRemoteCId, rsp.remote_cid());
279     EXPECT_EQ(kLocalCId, rsp.local_cid());
280     if (cb_count == 1) {
281       EXPECT_EQ(BrEdrCommandHandler::Status::kSuccess, rsp.status());
282       EXPECT_EQ(ConnectionResult::kPending, rsp.result());
283       EXPECT_EQ(ConnectionStatus::kAuthorizationPending, rsp.conn_status());
284       return SignalingChannel::ResponseHandlerAction::kExpectAdditionalResponse;
285     } else if (cb_count == 2) {
286       EXPECT_EQ(BrEdrCommandHandler::Status::kSuccess, rsp.status());
287       EXPECT_EQ(ConnectionResult::kSuccess, rsp.result());
288       EXPECT_EQ(ConnectionStatus::kNoInfoAvailable, rsp.conn_status());
289     }
290     return SignalingChannel::ResponseHandlerAction::
291         kCompleteOutboundTransaction;
292   };
293 
294   EXPECT_TRUE(cmd_handler()->SendConnectionRequest(
295       kPsm, kLocalCId, std::move(on_conn_rsp)));
296   RunUntilIdle();
297   EXPECT_EQ(2, cb_count);
298 }
299 
TEST_F(BrEdrCommandHandlerTest,OutboundConnReqRspTimeOut)300 TEST_F(BrEdrCommandHandlerTest, OutboundConnReqRspTimeOut) {
301   // Connection Request payload
302   StaticByteBuffer expected_conn_req(
303       // PSM
304       LowerBits(kPsm),
305       UpperBits(kPsm),
306 
307       // Source CID
308       LowerBits(kLocalCId),
309       UpperBits(kLocalCId));
310 
311   EXPECT_OUTBOUND_REQ(*fake_sig(),
312                       kConnectionRequest,
313                       expected_conn_req.view(),
314                       {SignalingChannel::Status::kTimeOut, {}});
315 
316   ASSERT_EQ(0u, failed_requests());
317 
318   auto on_conn_rsp = [](auto&) {
319     ADD_FAILURE();
320     return SignalingChannel::ResponseHandlerAction::
321         kCompleteOutboundTransaction;
322   };
323   EXPECT_TRUE(cmd_handler()->SendConnectionRequest(
324       kPsm, kLocalCId, std::move(on_conn_rsp)));
325   RETURN_IF_FATAL(RunUntilIdle());
326   EXPECT_EQ(1u, failed_requests());
327 }
328 
TEST_F(BrEdrCommandHandlerTest,InboundInfoReqRspNotSupported)329 TEST_F(BrEdrCommandHandlerTest, InboundInfoReqRspNotSupported) {
330   BrEdrCommandHandler::InformationRequestCallback cb = [](InformationType type,
331                                                           auto responder) {
332     EXPECT_EQ(InformationType::kConnectionlessMTU, type);
333     responder->SendNotSupported();
334   };
335   cmd_handler()->ServeInformationRequest(std::move(cb));
336 
337   // Information Request payload
338   StaticByteBuffer info_req(
339       // Type = Connectionless MTU
340       0x01,
341       0x00);
342 
343   // Information Response payload
344   StaticByteBuffer expected_rsp(
345       // Type = Connectionless MTU
346       0x01,
347       0x00,
348 
349       // Result = Not supported
350       0x01,
351       0x00);
352 
353   RETURN_IF_FATAL(
354       fake_sig()->ReceiveExpect(kInformationRequest, info_req, expected_rsp));
355 }
356 
TEST_F(BrEdrCommandHandlerTest,InboundInfoReqRspConnlessMtu)357 TEST_F(BrEdrCommandHandlerTest, InboundInfoReqRspConnlessMtu) {
358   BrEdrCommandHandler::InformationRequestCallback cb = [](InformationType type,
359                                                           auto responder) {
360     EXPECT_EQ(InformationType::kConnectionlessMTU, type);
361     responder->SendConnectionlessMtu(0x02dc);
362   };
363   cmd_handler()->ServeInformationRequest(std::move(cb));
364 
365   // Information Request payload
366   StaticByteBuffer info_req(
367       // Type = Connectionless MTU
368       0x01,
369       0x00);
370 
371   // Information Response payload
372   StaticByteBuffer expected_rsp(
373       // Type = Connectionless MTU
374       0x01,
375       0x00,
376 
377       // Result = Success
378       0x00,
379       0x00,
380 
381       // Data (MTU)
382       0xdc,
383       0x02);
384 
385   RETURN_IF_FATAL(
386       fake_sig()->ReceiveExpect(kInformationRequest, info_req, expected_rsp));
387 }
388 
TEST_F(BrEdrCommandHandlerTest,InboundInfoReqRspExtendedFeatures)389 TEST_F(BrEdrCommandHandlerTest, InboundInfoReqRspExtendedFeatures) {
390   BrEdrCommandHandler::InformationRequestCallback cb = [](InformationType type,
391                                                           auto responder) {
392     EXPECT_EQ(InformationType::kExtendedFeaturesSupported, type);
393     responder->SendExtendedFeaturesSupported(0xfaceb00c);
394   };
395   cmd_handler()->ServeInformationRequest(std::move(cb));
396 
397   // Information Request payload
398   StaticByteBuffer info_req(
399       // Type = Features Mask
400       0x02,
401       0x00);
402 
403   // Information Response payload
404   StaticByteBuffer expected_rsp(
405       // Type = Features Mask
406       0x02,
407       0x00,
408 
409       // Result = Success
410       0x00,
411       0x00,
412 
413       // Data (Mask)
414       0x0c,
415       0xb0,
416       0xce,
417       0xfa);
418 
419   RETURN_IF_FATAL(
420       fake_sig()->ReceiveExpect(kInformationRequest, info_req, expected_rsp));
421 }
422 
TEST_F(BrEdrCommandHandlerTest,InboundInfoReqRspFixedChannels)423 TEST_F(BrEdrCommandHandlerTest, InboundInfoReqRspFixedChannels) {
424   BrEdrCommandHandler::InformationRequestCallback cb = [](InformationType type,
425                                                           auto responder) {
426     EXPECT_EQ(InformationType::kFixedChannelsSupported, type);
427     responder->SendFixedChannelsSupported(0xcafef00d4badc0deUL);
428   };
429   cmd_handler()->ServeInformationRequest(std::move(cb));
430 
431   // Information Request payload
432   StaticByteBuffer info_req(
433       // Type = Fixed Channels
434       0x03,
435       0x00);
436 
437   // Configuration Response payload
438   StaticByteBuffer expected_rsp(
439       // Type = Fixed Channels
440       0x03,
441       0x00,
442 
443       // Result = Success
444       0x00,
445       0x00,
446 
447       // Data (Mask)
448       0xde,
449       0xc0,
450       0xad,
451       0x4b,
452       0x0d,
453       0xf0,
454       0xfe,
455       0xca);
456 
457   RETURN_IF_FATAL(
458       fake_sig()->ReceiveExpect(kInformationRequest, info_req, expected_rsp));
459 }
460 
TEST_F(BrEdrCommandHandlerTest,InboundConfigReqEmptyRspOkEmpty)461 TEST_F(BrEdrCommandHandlerTest, InboundConfigReqEmptyRspOkEmpty) {
462   BrEdrCommandHandler::ConfigurationRequestCallback cb =
463       [](ChannelId local_cid,
464          uint16_t flags,
465          ChannelConfiguration config,
466          auto responder) {
467         EXPECT_EQ(kLocalCId, local_cid);
468         EXPECT_EQ(0x6006, flags);
469         EXPECT_FALSE(config.mtu_option().has_value());
470         EXPECT_FALSE(config.retransmission_flow_control_option().has_value());
471         EXPECT_EQ(0u, config.unknown_options().size());
472 
473         responder->Send(kRemoteCId,
474                         0x0001,
475                         ConfigurationResult::kPending,
476                         ChannelConfiguration::ConfigurationOptions());
477       };
478   cmd_handler()->ServeConfigurationRequest(std::move(cb));
479 
480   // Configuration Request payload
481   StaticByteBuffer config_req(
482       // Destination Channel ID
483       LowerBits(kLocalCId),
484       UpperBits(kLocalCId),
485 
486       // Flags
487       0x06,
488       0x60);
489 
490   // Configuration Response payload
491   StaticByteBuffer expected_rsp(
492       // Destination Channel ID
493       LowerBits(kRemoteCId),
494       UpperBits(kRemoteCId),
495 
496       // Flags
497       0x01,
498       0x00,
499 
500       // Result = Pending
501       0x04,
502       0x00);
503 
504   RETURN_IF_FATAL(fake_sig()->ReceiveExpect(
505       kConfigurationRequest, config_req, expected_rsp));
506 }
507 
TEST_F(BrEdrCommandHandlerTest,OutboundConfigReqRspPendingEmpty)508 TEST_F(BrEdrCommandHandlerTest, OutboundConfigReqRspPendingEmpty) {
509   // Configuration Request payload
510   StaticByteBuffer expected_config_req(
511       // Destination CID
512       LowerBits(kRemoteCId),
513       UpperBits(kRemoteCId),
514 
515       // Flags (non-zero to test encoding)
516       0x01,
517       0x00,
518 
519       // Data (Config Options)
520       0x01,  // Type = MTU
521       0x02,  // Length = 2
522       0x30,
523       0x00  // MTU = 48
524   );
525 
526   // Configuration Response payload
527   StaticByteBuffer pending_config_req(
528       // Source CID
529       LowerBits(kLocalCId),
530       UpperBits(kLocalCId),
531 
532       // Flags (non-zero to test encoding)
533       0x04,
534       0x00,
535 
536       // Result = Pending
537       0x04,
538       0x00,
539 
540       // Data (Config Options)
541       0x01,  // Type = MTU
542       0x02,  // Length = 2
543       0x60,
544       0x00  // MTU = 96
545   );
546 
547   EXPECT_OUTBOUND_REQ(
548       *fake_sig(),
549       kConfigurationRequest,
550       expected_config_req.view(),
551       {SignalingChannel::Status::kSuccess, pending_config_req.view()});
552 
553   bool cb_called = false;
554   BrEdrCommandHandler::ConfigurationResponseCallback on_config_rsp =
555       [&cb_called](const BrEdrCommandHandler::ConfigurationResponse& rsp) {
556         cb_called = true;
557         EXPECT_EQ(SignalingChannel::Status::kSuccess, rsp.status());
558         EXPECT_EQ(kLocalCId, rsp.local_cid());
559         EXPECT_EQ(0x0004, rsp.flags());
560         EXPECT_EQ(ConfigurationResult::kPending, rsp.result());
561         EXPECT_TRUE(rsp.config().mtu_option().has_value());
562         EXPECT_EQ(96u, rsp.config().mtu_option()->mtu());
563         return SignalingChannel::ResponseHandlerAction::
564             kCompleteOutboundTransaction;
565       };
566 
567   ChannelConfiguration config;
568   config.set_mtu_option(ChannelConfiguration::MtuOption(48));
569 
570   EXPECT_TRUE(cmd_handler()->SendConfigurationRequest(
571       kRemoteCId, 0x0001, config.Options(), std::move(on_config_rsp)));
572   RunUntilIdle();
573   EXPECT_TRUE(cb_called);
574 }
575 
TEST_F(BrEdrCommandHandlerTest,OutboundConfigReqRspTimeOut)576 TEST_F(BrEdrCommandHandlerTest, OutboundConfigReqRspTimeOut) {
577   // Configuration Request payload
578   StaticByteBuffer expected_config_req(
579       // Destination CID
580       LowerBits(kRemoteCId),
581       UpperBits(kRemoteCId),
582 
583       // Flags (non-zero to test encoding)
584       0x01,
585       0xf0,
586 
587       // Data (Config Options)
588       0x01,  // Type = MTU
589       0x02,  // Length = 2
590       0x30,
591       0x00  // MTU = 48
592   );
593 
594   // Disconnect Request payload
595   StaticByteBuffer expected_discon_req(
596       // Destination CID
597       LowerBits(kRemoteCId),
598       UpperBits(kRemoteCId),
599 
600       // Source CID
601       LowerBits(kLocalCId),
602       UpperBits(kLocalCId));
603 
604   EXPECT_OUTBOUND_REQ(*fake_sig(),
605                       kConfigurationRequest,
606                       expected_config_req.view(),
607                       {SignalingChannel::Status::kTimeOut, {}});
608   EXPECT_OUTBOUND_REQ(
609       *fake_sig(), kDisconnectionRequest, expected_discon_req.view());
610 
611   set_request_fail_callback([this]() {
612     // Should still be allowed to send requests even after one failed
613     auto on_discon_rsp = [](auto&) {};
614     EXPECT_TRUE(cmd_handler()->SendDisconnectionRequest(
615         kRemoteCId, kLocalCId, std::move(on_discon_rsp)));
616   });
617 
618   ASSERT_EQ(0u, failed_requests());
619 
620   auto on_config_rsp = [](auto&) {
621     ADD_FAILURE();
622     return SignalingChannel::ResponseHandlerAction::
623         kCompleteOutboundTransaction;
624   };
625 
626   ChannelConfiguration config;
627   config.set_mtu_option(ChannelConfiguration::MtuOption(48));
628 
629   EXPECT_TRUE(cmd_handler()->SendConfigurationRequest(
630       kRemoteCId, 0xf001, config.Options(), std::move(on_config_rsp)));
631   RETURN_IF_FATAL(RunUntilIdle());
632   EXPECT_EQ(1u, failed_requests());
633 }
TEST_F(BrEdrCommandHandlerTest,OutboundInfoReqRspOk)634 TEST_F(BrEdrCommandHandlerTest, OutboundInfoReqRspOk) {
635   // Information Request payload
636   StaticByteBuffer expected_info_req(
637       // Information Type
638       LowerBits(
639           static_cast<uint16_t>(InformationType::kExtendedFeaturesSupported)),
640       UpperBits(
641           static_cast<uint16_t>(InformationType::kExtendedFeaturesSupported)));
642 
643   // Information Response payload
644   StaticByteBuffer ok_info_rsp(
645       // Information Type
646       LowerBits(
647           static_cast<uint16_t>(InformationType::kExtendedFeaturesSupported)),
648       UpperBits(
649           static_cast<uint16_t>(InformationType::kExtendedFeaturesSupported)),
650 
651       // Information Result
652       LowerBits(static_cast<uint16_t>(InformationResult::kSuccess)),
653       UpperBits(static_cast<uint16_t>(InformationResult::kSuccess)),
654 
655       // Data (extended features mask, 4 bytes)
656       LowerBits(kExtendedFeaturesBitFixedChannels),
657       0,
658       0,
659       0);
660 
661   EXPECT_OUTBOUND_REQ(*fake_sig(),
662                       kInformationRequest,
663                       expected_info_req.view(),
664                       {SignalingChannel::Status::kSuccess, ok_info_rsp.view()});
665 
666   bool cb_called = false;
667   BrEdrCommandHandler::InformationResponseCallback on_info_cb =
668       [&cb_called](const BrEdrCommandHandler::InformationResponse& rsp) {
669         cb_called = true;
670         EXPECT_EQ(SignalingChannel::Status::kSuccess, rsp.status());
671         EXPECT_EQ(InformationResult::kSuccess, rsp.result());
672         EXPECT_EQ(InformationType::kExtendedFeaturesSupported, rsp.type());
673         EXPECT_EQ(kExtendedFeaturesBitFixedChannels, rsp.extended_features());
674       };
675 
676   EXPECT_TRUE(cmd_handler()->SendInformationRequest(
677       InformationType::kExtendedFeaturesSupported, std::move(on_info_cb)));
678   RunUntilIdle();
679   EXPECT_TRUE(cb_called);
680 }
681 
TEST_F(BrEdrCommandHandlerTest,OutboundInfoReqRspNotSupported)682 TEST_F(BrEdrCommandHandlerTest, OutboundInfoReqRspNotSupported) {
683   // Information Request payload
684   StaticByteBuffer expected_info_req(
685       // Information Type
686       LowerBits(static_cast<uint16_t>(InformationType::kConnectionlessMTU)),
687       UpperBits(static_cast<uint16_t>(InformationType::kConnectionlessMTU)));
688 
689   // Information Response payload
690   StaticByteBuffer error_info_rsp(
691       // Information Type
692       LowerBits(static_cast<uint16_t>(InformationType::kConnectionlessMTU)),
693       UpperBits(static_cast<uint16_t>(InformationType::kConnectionlessMTU)),
694 
695       // Information Result
696       LowerBits(static_cast<uint16_t>(InformationResult::kNotSupported)),
697       UpperBits(static_cast<uint16_t>(InformationResult::kNotSupported)));
698 
699   EXPECT_OUTBOUND_REQ(
700       *fake_sig(),
701       kInformationRequest,
702       expected_info_req.view(),
703       {SignalingChannel::Status::kSuccess, error_info_rsp.view()});
704 
705   bool cb_called = false;
706   BrEdrCommandHandler::InformationResponseCallback on_info_cb =
707       [&cb_called](const BrEdrCommandHandler::InformationResponse& rsp) {
708         cb_called = true;
709         EXPECT_EQ(SignalingChannel::Status::kSuccess, rsp.status());
710         EXPECT_EQ(InformationResult::kNotSupported, rsp.result());
711         EXPECT_EQ(InformationType::kConnectionlessMTU, rsp.type());
712       };
713 
714   EXPECT_TRUE(cmd_handler()->SendInformationRequest(
715       InformationType::kConnectionlessMTU, std::move(on_info_cb)));
716   RunUntilIdle();
717   EXPECT_TRUE(cb_called);
718 }
719 
TEST_F(BrEdrCommandHandlerTest,OutboundInfoReqRspHeaderNotEnoughBytes)720 TEST_F(BrEdrCommandHandlerTest, OutboundInfoReqRspHeaderNotEnoughBytes) {
721   // Information Request payload
722   StaticByteBuffer expected_info_req(
723       // Information Type
724       LowerBits(
725           static_cast<uint16_t>(InformationType::kExtendedFeaturesSupported)),
726       UpperBits(
727           static_cast<uint16_t>(InformationType::kExtendedFeaturesSupported)));
728 
729   // Information Response payload
730   StaticByteBuffer malformed_info_rsp(
731       // 1 of 4 bytes expected of an Information Response just to be able to
732       // parse it.
733       LowerBits(
734           static_cast<uint16_t>(InformationType::kExtendedFeaturesSupported)));
735 
736   EXPECT_OUTBOUND_REQ(
737       *fake_sig(),
738       kInformationRequest,
739       expected_info_req.view(),
740       {SignalingChannel::Status::kSuccess, malformed_info_rsp.view()});
741 
742   bool cb_called = false;
743   BrEdrCommandHandler::InformationResponseCallback on_info_cb =
744       [&cb_called](const BrEdrCommandHandler::InformationResponse& rsp) {
745         cb_called = true;
746       };
747 
748   EXPECT_TRUE(cmd_handler()->SendInformationRequest(
749       InformationType::kExtendedFeaturesSupported, std::move(on_info_cb)));
750   RunUntilIdle();
751   EXPECT_FALSE(cb_called);
752 }
753 
TEST_F(BrEdrCommandHandlerTest,OutboundInfoReqRspPayloadNotEnoughBytes)754 TEST_F(BrEdrCommandHandlerTest, OutboundInfoReqRspPayloadNotEnoughBytes) {
755   // Information Request payload
756   StaticByteBuffer expected_info_req(
757       // Information Type
758       LowerBits(
759           static_cast<uint16_t>(InformationType::kExtendedFeaturesSupported)),
760       UpperBits(
761           static_cast<uint16_t>(InformationType::kExtendedFeaturesSupported)));
762 
763   // Information Response payload
764   StaticByteBuffer malformed_info_rsp(
765       // Information Type
766       LowerBits(
767           static_cast<uint16_t>(InformationType::kExtendedFeaturesSupported)),
768       UpperBits(
769           static_cast<uint16_t>(InformationType::kExtendedFeaturesSupported)),
770 
771       // Information Result
772       LowerBits(static_cast<uint16_t>(InformationResult::kSuccess)),
773       UpperBits(static_cast<uint16_t>(InformationResult::kSuccess)),
774 
775       // Data (2 of 4 bytes expected of an extended features mask)
776       0,
777       0);
778 
779   EXPECT_OUTBOUND_REQ(
780       *fake_sig(),
781       kInformationRequest,
782       expected_info_req.view(),
783       {SignalingChannel::Status::kSuccess, malformed_info_rsp.view()});
784 
785   bool cb_called = false;
786   BrEdrCommandHandler::InformationResponseCallback on_info_cb =
787       [&cb_called](const BrEdrCommandHandler::InformationResponse& rsp) {
788         cb_called = true;
789       };
790 
791   EXPECT_TRUE(cmd_handler()->SendInformationRequest(
792       InformationType::kExtendedFeaturesSupported, std::move(on_info_cb)));
793   RunUntilIdle();
794   EXPECT_FALSE(cb_called);
795 }
796 
797 // Accept and pass a valid Information Response even if it doesn't have the type
798 // requested.
TEST_F(BrEdrCommandHandlerTest,OutboundInfoReqRspWrongType)799 TEST_F(BrEdrCommandHandlerTest, OutboundInfoReqRspWrongType) {
800   // Information Request payload
801   StaticByteBuffer expected_info_req(
802       // Information Type
803       LowerBits(
804           static_cast<uint16_t>(InformationType::kExtendedFeaturesSupported)),
805       UpperBits(
806           static_cast<uint16_t>(InformationType::kExtendedFeaturesSupported)));
807 
808   // Information Response payload
809   StaticByteBuffer mismatch_info_rsp(
810       // Information Type
811       LowerBits(static_cast<uint16_t>(InformationType::kConnectionlessMTU)),
812       UpperBits(static_cast<uint16_t>(InformationType::kConnectionlessMTU)),
813 
814       // Information Result
815       LowerBits(static_cast<uint16_t>(InformationResult::kSuccess)),
816       UpperBits(static_cast<uint16_t>(InformationResult::kSuccess)),
817 
818       // Data (connectionless broadcast MTU, 2 bytes)
819       0x40,
820       0);
821 
822   EXPECT_OUTBOUND_REQ(
823       *fake_sig(),
824       kInformationRequest,
825       expected_info_req.view(),
826       {SignalingChannel::Status::kSuccess, mismatch_info_rsp.view()});
827 
828   bool cb_called = false;
829   BrEdrCommandHandler::InformationResponseCallback on_info_cb =
830       [&cb_called](const BrEdrCommandHandler::InformationResponse& rsp) {
831         cb_called = true;
832         EXPECT_EQ(SignalingChannel::Status::kSuccess, rsp.status());
833         EXPECT_EQ(InformationResult::kSuccess, rsp.result());
834         EXPECT_EQ(InformationType::kConnectionlessMTU, rsp.type());
835         EXPECT_EQ(0x40, rsp.connectionless_mtu());
836       };
837 
838   EXPECT_TRUE(cmd_handler()->SendInformationRequest(
839       InformationType::kExtendedFeaturesSupported, std::move(on_info_cb)));
840   RunUntilIdle();
841   EXPECT_TRUE(cb_called);
842 }
843 
844 // Allow types of information besides those known to BrEdrCommandHandler.
TEST_F(BrEdrCommandHandlerTest,OutboundInfoReqUnknownType)845 TEST_F(BrEdrCommandHandlerTest, OutboundInfoReqUnknownType) {
846   // Information Request payload
847   StaticByteBuffer expected_info_req(
848       // Information Type
849       0x04,
850       0);
851 
852   // Information Response payload
853   StaticByteBuffer ok_info_rsp(
854       // Information Type
855       0x04,
856       0,
857 
858       // Information Result
859       LowerBits(static_cast<uint16_t>(InformationResult::kSuccess)),
860       UpperBits(static_cast<uint16_t>(InformationResult::kSuccess)),
861 
862       // Data (some payload)
863       't',
864       'e',
865       's',
866       't');
867 
868   EXPECT_OUTBOUND_REQ(*fake_sig(),
869                       kInformationRequest,
870                       expected_info_req.view(),
871                       {SignalingChannel::Status::kSuccess, ok_info_rsp.view()});
872 
873   bool cb_called = false;
874   BrEdrCommandHandler::InformationResponseCallback on_info_cb =
875       [&cb_called](const BrEdrCommandHandler::InformationResponse& rsp) {
876         cb_called = true;
877         EXPECT_EQ(SignalingChannel::Status::kSuccess, rsp.status());
878         EXPECT_EQ(InformationResult::kSuccess, rsp.result());
879         EXPECT_EQ(static_cast<InformationType>(0x04), rsp.type());
880       };
881 
882   EXPECT_TRUE(cmd_handler()->SendInformationRequest(
883       static_cast<InformationType>(0x04), std::move(on_info_cb)));
884   RunUntilIdle();
885   EXPECT_TRUE(cb_called);
886 }
887 
TEST_F(BrEdrCommandHandlerTest,InboundConnReqRspPending)888 TEST_F(BrEdrCommandHandlerTest, InboundConnReqRspPending) {
889   BrEdrCommandHandler::ConnectionRequestCallback cb =
890       [](Psm psm, ChannelId remote_cid, auto responder) {
891         EXPECT_EQ(kPsm, psm);
892         EXPECT_EQ(kRemoteCId, remote_cid);
893         responder->Send(kLocalCId,
894                         ConnectionResult::kPending,
895                         ConnectionStatus::kAuthorizationPending);
896       };
897   cmd_handler()->ServeConnectionRequest(std::move(cb));
898 
899   // Connection Request payload
900   StaticByteBuffer conn_req(
901       // PSM
902       LowerBits(kPsm),
903       UpperBits(kPsm),
904 
905       // Source CID (relative to requester)
906       LowerBits(kRemoteCId),
907       UpperBits(kRemoteCId));
908 
909   // Connection Response payload
910   StaticByteBuffer conn_rsp(
911       // Destination CID (relative to requester)
912       LowerBits(kLocalCId),
913       UpperBits(kLocalCId),
914 
915       // Source CID (relative to requester)
916       LowerBits(kRemoteCId),
917       UpperBits(kRemoteCId),
918 
919       // Connection Result
920       LowerBits(static_cast<uint16_t>(ConnectionResult::kPending)),
921       UpperBits(static_cast<uint16_t>(ConnectionResult::kPending)),
922 
923       // Connection Status
924       LowerBits(static_cast<uint16_t>(ConnectionStatus::kAuthorizationPending)),
925       UpperBits(
926           static_cast<uint16_t>(ConnectionStatus::kAuthorizationPending)));
927 
928   RETURN_IF_FATAL(
929       fake_sig()->ReceiveExpect(kConnectionRequest, conn_req, conn_rsp));
930 }
931 
TEST_F(BrEdrCommandHandlerTest,InboundConnReqBadPsm)932 TEST_F(BrEdrCommandHandlerTest, InboundConnReqBadPsm) {
933   constexpr uint16_t kBadPsm = 0x0002;
934 
935   // Request callback shouldn't even be called for an invalid PSM.
936   bool req_cb_called = false;
937   BrEdrCommandHandler::ConnectionRequestCallback cb =
938       [&req_cb_called](Psm psm, ChannelId remote_cid, auto responder) {
939         req_cb_called = true;
940       };
941   cmd_handler()->ServeConnectionRequest(std::move(cb));
942 
943   // Connection Request payload
944   StaticByteBuffer conn_req(
945       // PSM
946       LowerBits(kBadPsm),
947       UpperBits(kBadPsm),
948 
949       // Source CID (relative to requester)
950       LowerBits(kRemoteCId),
951       UpperBits(kRemoteCId));
952 
953   // Connection Response payload
954   StaticByteBuffer conn_rsp(
955       // Destination CID (relative to requester)
956       LowerBits(kInvalidChannelId),
957       UpperBits(kInvalidChannelId),
958 
959       // Source CID (relative to requester)
960       LowerBits(kRemoteCId),
961       UpperBits(kRemoteCId),
962 
963       // Connection Result
964       LowerBits(static_cast<uint16_t>(ConnectionResult::kPsmNotSupported)),
965       UpperBits(static_cast<uint16_t>(ConnectionResult::kPsmNotSupported)),
966 
967       // Connection Status
968       LowerBits(static_cast<uint16_t>(ConnectionStatus::kNoInfoAvailable)),
969       UpperBits(static_cast<uint16_t>(ConnectionStatus::kNoInfoAvailable)));
970 
971   RETURN_IF_FATAL(
972       fake_sig()->ReceiveExpect(kConnectionRequest, conn_req, conn_rsp));
973   EXPECT_FALSE(req_cb_called);
974 }
975 
TEST_F(BrEdrCommandHandlerTest,InboundConnReqNonDynamicSrcCId)976 TEST_F(BrEdrCommandHandlerTest, InboundConnReqNonDynamicSrcCId) {
977   // Request callback shouldn't even be called for an invalid Source Channel ID.
978   bool req_cb_called = false;
979   BrEdrCommandHandler::ConnectionRequestCallback cb =
980       [&req_cb_called](Psm psm, ChannelId remote_cid, auto responder) {
981         req_cb_called = true;
982       };
983   cmd_handler()->ServeConnectionRequest(std::move(cb));
984 
985   // Connection Request payload
986   StaticByteBuffer conn_req(
987       // PSM
988       LowerBits(kPsm),
989       UpperBits(kPsm),
990 
991       // Source CID: fixed channel for Security Manager (relative to requester)
992       LowerBits(kSMPChannelId),
993       UpperBits(kSMPChannelId));
994 
995   // Connection Response payload
996   StaticByteBuffer conn_rsp(
997       // Destination CID (relative to requester)
998       LowerBits(kInvalidChannelId),
999       UpperBits(kInvalidChannelId),
1000 
1001       // Source CID (relative to requester)
1002       LowerBits(kSMPChannelId),
1003       UpperBits(kSMPChannelId),
1004 
1005       // Connection Result
1006       LowerBits(static_cast<uint16_t>(ConnectionResult::kInvalidSourceCID)),
1007       UpperBits(static_cast<uint16_t>(ConnectionResult::kInvalidSourceCID)),
1008 
1009       // Connection Status
1010       LowerBits(static_cast<uint16_t>(ConnectionStatus::kNoInfoAvailable)),
1011       UpperBits(static_cast<uint16_t>(ConnectionStatus::kNoInfoAvailable)));
1012 
1013   RETURN_IF_FATAL(
1014       fake_sig()->ReceiveExpect(kConnectionRequest, conn_req, conn_rsp));
1015   EXPECT_FALSE(req_cb_called);
1016 }
1017 
1018 }  // namespace
1019 }  // namespace bt::l2cap::internal
1020