• 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/le_signaling_channel.h"
16 
17 #include "pw_bluetooth_sapphire/internal/host/l2cap/fake_channel_test.h"
18 #include "pw_bluetooth_sapphire/internal/host/testing/test_helpers.h"
19 
20 namespace bt::l2cap::internal {
21 namespace {
22 
23 constexpr hci_spec::ConnectionHandle kTestHandle = 0x0001;
24 constexpr uint8_t kTestCmdId = 1;
25 
26 template <pw::bluetooth::emboss::ConnectionRole Role =
27               pw::bluetooth::emboss::ConnectionRole::CENTRAL>
28 class LESignalingChannelTestBase : public testing::FakeChannelTest {
29  public:
30   LESignalingChannelTestBase() = default;
31   ~LESignalingChannelTestBase() override = default;
32 
33  protected:
SetUp()34   void SetUp() override {
35     ChannelOptions options(kLESignalingChannelId);
36     options.conn_handle = kTestHandle;
37 
38     fake_sig_chan_ = CreateFakeChannel(options);
39     sig_ = std::make_unique<LESignalingChannel>(
40         fake_sig_chan_->GetWeakPtr(), Role, dispatcher());
41   }
42 
TearDown()43   void TearDown() override { sig_ = nullptr; }
44 
sig() const45   LESignalingChannel* sig() const { return sig_.get(); }
46 
47  private:
48   std::unique_ptr<testing::FakeChannel> fake_sig_chan_;
49   std::unique_ptr<LESignalingChannel> sig_;
50 
51   BT_DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(LESignalingChannelTestBase);
52 };
53 
54 using LESignalingChannelTest = LESignalingChannelTestBase<>;
55 
56 using LESignalingChannelPeripheralTest = LESignalingChannelTestBase<
57     pw::bluetooth::emboss::ConnectionRole::PERIPHERAL>;
58 
TEST_F(LESignalingChannelTest,IgnoreEmptyFrame)59 TEST_F(LESignalingChannelTest, IgnoreEmptyFrame) {
60   bool send_cb_called = false;
61   auto send_cb = [&send_cb_called](auto) { send_cb_called = true; };
62 
63   fake_chan()->SetSendCallback(std::move(send_cb), dispatcher());
64   fake_chan()->Receive(BufferView());
65 
66   RunUntilIdle();
67   EXPECT_FALSE(send_cb_called);
68 }
69 
TEST_F(LESignalingChannelTest,RejectMalformedTooLarge)70 TEST_F(LESignalingChannelTest, RejectMalformedTooLarge) {
71   // Command Reject packet.
72   // clang-format off
73   StaticByteBuffer expected(
74       // Command header
75       0x01, kTestCmdId, 0x02, 0x00,
76 
77       // Reason (Command not understood)
78       0x00, 0x00);
79 
80   // Header-encoded length is less than the otherwise-valid Connection Parameter
81   // Update packet's payload size.
82   StaticByteBuffer cmd_with_oversize_payload(
83       0x12, kTestCmdId, 0x07, 0x00,
84 
85       // Valid connection parameters
86       0x06, 0x00,
87       0x80, 0x0C,
88       0xF3, 0x01,
89       0x80, 0x0C);
90   // clang-format on
91 
92   EXPECT_TRUE(ReceiveAndExpect(cmd_with_oversize_payload, expected));
93 }
94 
TEST_F(LESignalingChannelTest,RejectMalformedTooSmall)95 TEST_F(LESignalingChannelTest, RejectMalformedTooSmall) {
96   // Command Reject packet.
97   // clang-format off
98   StaticByteBuffer expected(
99       // Command header
100       0x01, kTestCmdId, 0x02, 0x00,
101 
102       // Reason (Command not understood)
103       0x00, 0x00);
104 
105   // Header-encoded length is more than the otherwise-valid Connection Parameter
106   // Update packet's payload size.
107   StaticByteBuffer cmd_with_undersize_payload(
108       0x12, kTestCmdId, 0x09, 0x00,
109 
110       // Valid connection parameters
111       0x06, 0x00,
112       0x80, 0x0C,
113       0xF3, 0x01,
114       0x80, 0x0C);
115   // clang-format on
116 
117   EXPECT_TRUE(ReceiveAndExpect(cmd_with_undersize_payload, expected));
118 }
119 
TEST_F(LESignalingChannelTest,DefaultMTU)120 TEST_F(LESignalingChannelTest, DefaultMTU) {
121   constexpr size_t kCommandSize = kMinLEMTU + 1;
122 
123   // The channel should start out with the minimum MTU as the default (23
124   // octets).
125   StaticByteBuffer<kCommandSize> cmd;
126 
127   // Make sure that the packet is well formed (the command code does not
128   // matter).
129   MutableSignalingPacket packet(&cmd, kCommandSize - sizeof(CommandHeader));
130   packet.mutable_header()->id = kTestCmdId;
131   packet.mutable_header()->length = htole16(packet.payload_size());
132 
133   // Command Reject packet.
134   // clang-format off
135   StaticByteBuffer expected(
136       // Command header
137       0x01, kTestCmdId, 0x04, 0x00,
138 
139       // Reason (Signaling MTU exceeded)
140       0x01, 0x00,
141 
142       // The supported MTU (23)
143       0x17, 0x00);
144   // clang-format on
145 
146   EXPECT_TRUE(ReceiveAndExpect(cmd, expected));
147 }
148 
149 }  // namespace
150 }  // namespace bt::l2cap::internal
151