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