1 // Copyright 2021 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_hci/packet.h"
16
17 #include "pw_bytes/array.h"
18 #include "pw_bytes/byte_builder.h"
19 #include "pw_containers/algorithm.h"
20 #include "pw_status/status.h"
21 #include "pw_unit_test/framework.h"
22
23 namespace pw::bluetooth_hci {
24 namespace {
25
26 class PacketTest : public ::testing::Test {
27 protected:
28 constexpr static size_t kMaxHeaderSizeBytes = std::max({
29 CommandPacket::kHeaderSizeBytes,
30 AsyncDataPacket::kHeaderSizeBytes,
31 SyncDataPacket::kHeaderSizeBytes,
32 EventPacket::kHeaderSizeBytes,
33 });
34 // Arbitrarily add at most 2 bytes worth of payload (data or parameters).
35 constexpr static size_t kArbitraryMaxPayloadSizeBytes = 2;
36 constexpr static size_t kMaxPacketSizeBytes =
37 kMaxHeaderSizeBytes + kArbitraryMaxPayloadSizeBytes;
38 std::array<std::byte, kMaxPacketSizeBytes> packet_buffer_;
39 };
40
TEST_F(PacketTest,CommandPacketHeaderUndersizedEncode)41 TEST_F(PacketTest, CommandPacketHeaderUndersizedEncode) {
42 const CommandPacket packet(0u, ConstByteSpan());
43 EXPECT_EQ(0u, packet.parameters().size_bytes());
44 const Result<ConstByteSpan> encode_result = packet.Encode(
45 {packet_buffer_.data(), CommandPacket::kHeaderSizeBytes - 1});
46 EXPECT_EQ(Status::ResourceExhausted(), encode_result.status());
47 }
48
TEST_F(PacketTest,CommandPacketHeaderUndersizedDecode)49 TEST_F(PacketTest, CommandPacketHeaderUndersizedDecode) {
50 EXPECT_FALSE(CommandPacket::Decode(
51 {packet_buffer_.data(), CommandPacket::kHeaderSizeBytes - 1})
52 .has_value());
53 }
54
TEST_F(PacketTest,CommandPacketHeaderOnlyEncodeAndDecode)55 TEST_F(PacketTest, CommandPacketHeaderOnlyEncodeAndDecode) {
56 constexpr uint16_t kOpcodeCommandField = 0b00'0000'0000;
57 constexpr uint8_t kOpcodeGroupField = 0b11'1111;
58
59 constexpr uint16_t kOpcode = (kOpcodeGroupField << 10) | kOpcodeCommandField;
60
61 const CommandPacket packet(kOpcode, ConstByteSpan());
62 EXPECT_EQ(packet.type(), Packet::Type::kCommandPacket);
63 EXPECT_EQ(packet.size_bytes(), CommandPacket::kHeaderSizeBytes);
64 EXPECT_EQ(packet.opcode(), kOpcode);
65 EXPECT_EQ(packet.opcode_command_field(), kOpcodeCommandField);
66 EXPECT_EQ(packet.opcode_group_field(), kOpcodeGroupField);
67 EXPECT_EQ(packet.parameters().size_bytes(), 0u);
68
69 const Result<ConstByteSpan> encode_result = packet.Encode(packet_buffer_);
70 ASSERT_EQ(OkStatus(), encode_result.status());
71
72 constexpr std::array<const std::byte, CommandPacket::kHeaderSizeBytes>
73 kExpectedEncodedPacket = bytes::MakeArray<const std::byte>(
74 0b0000'0000, 0b1111'1100, 0b0000'0000);
75 const ConstByteSpan& encoded_packet = encode_result.value();
76 EXPECT_TRUE(pw::containers::Equal(kExpectedEncodedPacket, encoded_packet));
77
78 // First, decode it from a perfectly sized span which we just encoded.
79 std::optional<CommandPacket> possible_packet =
80 CommandPacket::Decode(encoded_packet);
81 ASSERT_TRUE(possible_packet.has_value());
82 CommandPacket& decoded_packet = possible_packet.value();
83 EXPECT_EQ(decoded_packet.type(), Packet::Type::kCommandPacket);
84 EXPECT_EQ(decoded_packet.size_bytes(), CommandPacket::kHeaderSizeBytes);
85 EXPECT_EQ(decoded_packet.opcode(), kOpcode);
86 EXPECT_EQ(decoded_packet.opcode_command_field(), kOpcodeCommandField);
87 EXPECT_EQ(decoded_packet.opcode_group_field(), kOpcodeGroupField);
88 EXPECT_EQ(decoded_packet.parameters().size_bytes(), 0u);
89
90 // Second, decode it from an oversized buffer.
91 possible_packet = CommandPacket::Decode({packet_buffer_});
92 ASSERT_TRUE(possible_packet.has_value());
93 decoded_packet = possible_packet.value();
94 EXPECT_EQ(decoded_packet.type(), Packet::Type::kCommandPacket);
95 EXPECT_EQ(decoded_packet.size_bytes(), CommandPacket::kHeaderSizeBytes);
96 EXPECT_EQ(decoded_packet.opcode(), kOpcode);
97 EXPECT_EQ(decoded_packet.opcode_command_field(), kOpcodeCommandField);
98 EXPECT_EQ(decoded_packet.opcode_group_field(), kOpcodeGroupField);
99 EXPECT_EQ(decoded_packet.parameters().size_bytes(), 0u);
100 }
101
TEST_F(PacketTest,CommandPacketWithParametersEncodeAndDecode)102 TEST_F(PacketTest, CommandPacketWithParametersEncodeAndDecode) {
103 constexpr uint16_t kOpcodeCommandField = 0b10'1010'1010;
104 constexpr uint8_t kOpcodeGroupField = 0b10'1010;
105
106 constexpr uint16_t kOpcode = (kOpcodeGroupField << 10) | kOpcodeCommandField;
107
108 constexpr std::array<const std::byte, kArbitraryMaxPayloadSizeBytes>
109 kParameters = bytes::MakeArray<const std::byte>(1, 2);
110 const CommandPacket packet(kOpcode, kParameters);
111 EXPECT_EQ(packet.type(), Packet::Type::kCommandPacket);
112 EXPECT_EQ(packet.size_bytes(),
113 CommandPacket::kHeaderSizeBytes + kArbitraryMaxPayloadSizeBytes);
114 EXPECT_EQ(packet.opcode(), kOpcode);
115 EXPECT_EQ(packet.opcode_command_field(), kOpcodeCommandField);
116 EXPECT_EQ(packet.opcode_group_field(), kOpcodeGroupField);
117 EXPECT_EQ(packet.parameters().size_bytes(), kArbitraryMaxPayloadSizeBytes);
118
119 const Result<ConstByteSpan> encode_result = packet.Encode(packet_buffer_);
120 ASSERT_EQ(OkStatus(), encode_result.status());
121
122 constexpr std::array<const std::byte,
123 CommandPacket::kHeaderSizeBytes +
124 kArbitraryMaxPayloadSizeBytes>
125 kExpectedEncodedPacket = bytes::MakeArray<const std::byte>(
126 0b1010'1010, 0b1010'1010, 0b0000'0010, 1, 2);
127 const ConstByteSpan& encoded_packet = encode_result.value();
128 EXPECT_TRUE(pw::containers::Equal(kExpectedEncodedPacket, encoded_packet));
129
130 // First, decode it from a perfectly sized span which we just encoded.
131 std::optional<CommandPacket> possible_packet =
132 CommandPacket::Decode(encoded_packet);
133 ASSERT_TRUE(possible_packet.has_value());
134 CommandPacket& decoded_packet = possible_packet.value();
135 EXPECT_EQ(decoded_packet.type(), Packet::Type::kCommandPacket);
136 EXPECT_EQ(decoded_packet.size_bytes(),
137 CommandPacket::kHeaderSizeBytes + kArbitraryMaxPayloadSizeBytes);
138 EXPECT_EQ(decoded_packet.opcode(), kOpcode);
139 EXPECT_EQ(decoded_packet.opcode_command_field(), kOpcodeCommandField);
140 EXPECT_EQ(decoded_packet.opcode_group_field(), kOpcodeGroupField);
141 EXPECT_EQ(decoded_packet.parameters().size_bytes(),
142 kArbitraryMaxPayloadSizeBytes);
143
144 // Second, decode it from an oversized buffer.
145 possible_packet = CommandPacket::Decode({packet_buffer_});
146 ASSERT_TRUE(possible_packet.has_value());
147 decoded_packet = possible_packet.value();
148 EXPECT_EQ(decoded_packet.type(), Packet::Type::kCommandPacket);
149 EXPECT_EQ(decoded_packet.size_bytes(),
150 CommandPacket::kHeaderSizeBytes + kArbitraryMaxPayloadSizeBytes);
151 EXPECT_EQ(decoded_packet.opcode(), kOpcode);
152 EXPECT_EQ(decoded_packet.opcode_command_field(), kOpcodeCommandField);
153 EXPECT_EQ(decoded_packet.opcode_group_field(), kOpcodeGroupField);
154 EXPECT_EQ(decoded_packet.parameters().size_bytes(),
155 kArbitraryMaxPayloadSizeBytes);
156 }
157
TEST_F(PacketTest,AsyncDataPacketHeaderUndersizedEncode)158 TEST_F(PacketTest, AsyncDataPacketHeaderUndersizedEncode) {
159 const AsyncDataPacket packet(0u, ConstByteSpan());
160 EXPECT_EQ(0u, packet.data().size_bytes());
161 const Result<ConstByteSpan> encode_result = packet.Encode(
162 {packet_buffer_.data(), AsyncDataPacket::kHeaderSizeBytes - 1});
163 EXPECT_EQ(Status::ResourceExhausted(), encode_result.status());
164 }
165
TEST_F(PacketTest,AsyncDataPacketHeaderUndersizedDecode)166 TEST_F(PacketTest, AsyncDataPacketHeaderUndersizedDecode) {
167 EXPECT_FALSE(AsyncDataPacket::Decode({packet_buffer_.data(),
168 AsyncDataPacket::kHeaderSizeBytes - 1})
169 .has_value());
170 }
171
TEST_F(PacketTest,AsyncDataPacketHeaderOnlyEncodeAndDecode)172 TEST_F(PacketTest, AsyncDataPacketHeaderOnlyEncodeAndDecode) {
173 constexpr uint16_t kHandle = 0b00'0000'0000;
174 constexpr uint8_t kPbFlag = 0b01;
175 constexpr uint8_t kBcFlag = 0b10;
176
177 constexpr uint16_t kHandleAndFragmentationBits =
178 kHandle | (kPbFlag << 12) | (kBcFlag << 14);
179
180 const AsyncDataPacket packet(kHandleAndFragmentationBits, ConstByteSpan());
181 EXPECT_EQ(packet.type(), Packet::Type::kAsyncDataPacket);
182 EXPECT_EQ(packet.size_bytes(), AsyncDataPacket::kHeaderSizeBytes);
183 EXPECT_EQ(packet.handle_and_fragmentation_bits(),
184 kHandleAndFragmentationBits);
185 EXPECT_EQ(packet.handle(), kHandle);
186 EXPECT_EQ(packet.pb_flag(), kPbFlag);
187 EXPECT_EQ(packet.bc_flag(), kBcFlag);
188 EXPECT_EQ(packet.data().size_bytes(), 0u);
189
190 const Result<ConstByteSpan> encode_result = packet.Encode(packet_buffer_);
191 ASSERT_EQ(OkStatus(), encode_result.status());
192
193 constexpr std::array<const std::byte, AsyncDataPacket::kHeaderSizeBytes>
194 kExpectedEncodedPacket = bytes::MakeArray<const std::byte>(
195 0b0000'0000, 0b1001'0000, 0b0000'0000, 0b0000'0000);
196 const ConstByteSpan& encoded_packet = encode_result.value();
197 EXPECT_TRUE(pw::containers::Equal(kExpectedEncodedPacket, encoded_packet));
198
199 // First, decode it from a perfectly sized span which we just encoded.
200 std::optional<AsyncDataPacket> possible_packet =
201 AsyncDataPacket::Decode(encoded_packet);
202 ASSERT_TRUE(possible_packet.has_value());
203 AsyncDataPacket& decoded_packet = possible_packet.value();
204 EXPECT_EQ(decoded_packet.type(), Packet::Type::kAsyncDataPacket);
205 EXPECT_EQ(decoded_packet.size_bytes(), AsyncDataPacket::kHeaderSizeBytes);
206 EXPECT_EQ(decoded_packet.handle_and_fragmentation_bits(),
207 kHandleAndFragmentationBits);
208 EXPECT_EQ(decoded_packet.handle(), kHandle);
209 EXPECT_EQ(decoded_packet.pb_flag(), kPbFlag);
210 EXPECT_EQ(decoded_packet.bc_flag(), kBcFlag);
211 EXPECT_EQ(decoded_packet.data().size_bytes(), 0u);
212
213 // Second, decode it from an oversized buffer.
214 possible_packet = AsyncDataPacket::Decode({packet_buffer_});
215 ASSERT_TRUE(possible_packet.has_value());
216 decoded_packet = possible_packet.value();
217 EXPECT_EQ(decoded_packet.type(), Packet::Type::kAsyncDataPacket);
218 EXPECT_EQ(decoded_packet.size_bytes(), AsyncDataPacket::kHeaderSizeBytes);
219 EXPECT_EQ(decoded_packet.handle_and_fragmentation_bits(),
220 kHandleAndFragmentationBits);
221 EXPECT_EQ(decoded_packet.handle(), kHandle);
222 EXPECT_EQ(decoded_packet.pb_flag(), kPbFlag);
223 EXPECT_EQ(decoded_packet.bc_flag(), kBcFlag);
224 EXPECT_EQ(decoded_packet.data().size_bytes(), 0u);
225 }
226
TEST_F(PacketTest,AsyncDataPacketWithDataEncodeAndDecode)227 TEST_F(PacketTest, AsyncDataPacketWithDataEncodeAndDecode) {
228 constexpr uint16_t kHandle = 0b00'0000'0000;
229 constexpr uint8_t kPbFlag = 0b01;
230 constexpr uint8_t kBcFlag = 0b10;
231
232 constexpr uint16_t kHandleAndFragmentationBits =
233 kHandle | (kPbFlag << 12) | (kBcFlag << 14);
234
235 constexpr std::array<const std::byte, kArbitraryMaxPayloadSizeBytes> kData =
236 bytes::MakeArray<const std::byte>(1, 2);
237 const AsyncDataPacket packet(kHandleAndFragmentationBits, kData);
238 EXPECT_EQ(packet.type(), Packet::Type::kAsyncDataPacket);
239 EXPECT_EQ(packet.size_bytes(),
240 AsyncDataPacket::kHeaderSizeBytes + kArbitraryMaxPayloadSizeBytes);
241 EXPECT_EQ(packet.handle_and_fragmentation_bits(),
242 kHandleAndFragmentationBits);
243 EXPECT_EQ(packet.handle(), kHandle);
244 EXPECT_EQ(packet.pb_flag(), kPbFlag);
245 EXPECT_EQ(packet.bc_flag(), kBcFlag);
246 EXPECT_EQ(packet.data().size_bytes(), kArbitraryMaxPayloadSizeBytes);
247
248 const Result<ConstByteSpan> encode_result = packet.Encode(packet_buffer_);
249 ASSERT_EQ(OkStatus(), encode_result.status());
250
251 constexpr std::array<const std::byte,
252 AsyncDataPacket::kHeaderSizeBytes +
253 kArbitraryMaxPayloadSizeBytes>
254 kExpectedEncodedPacket = bytes::MakeArray<const std::byte>(
255 0b0000'0000, 0b1001'0000, 0b0000'0010, 0b0000'0000, 1, 2);
256 const ConstByteSpan& encoded_packet = encode_result.value();
257 EXPECT_TRUE(pw::containers::Equal(kExpectedEncodedPacket, encoded_packet));
258
259 // First, decode it from a perfectly sized span which we just encoded.
260 std::optional<AsyncDataPacket> possible_packet =
261 AsyncDataPacket::Decode(encoded_packet);
262 ASSERT_TRUE(possible_packet.has_value());
263 AsyncDataPacket& decoded_packet = possible_packet.value();
264 EXPECT_EQ(decoded_packet.type(), Packet::Type::kAsyncDataPacket);
265 EXPECT_EQ(decoded_packet.size_bytes(),
266 AsyncDataPacket::kHeaderSizeBytes + kArbitraryMaxPayloadSizeBytes);
267 EXPECT_EQ(decoded_packet.handle_and_fragmentation_bits(),
268 kHandleAndFragmentationBits);
269 EXPECT_EQ(decoded_packet.handle(), kHandle);
270 EXPECT_EQ(decoded_packet.pb_flag(), kPbFlag);
271 EXPECT_EQ(decoded_packet.bc_flag(), kBcFlag);
272 EXPECT_EQ(decoded_packet.data().size_bytes(), kArbitraryMaxPayloadSizeBytes);
273
274 // Second, decode it from an oversized buffer.
275 possible_packet = AsyncDataPacket::Decode({packet_buffer_});
276 ASSERT_TRUE(possible_packet.has_value());
277 decoded_packet = possible_packet.value();
278 EXPECT_EQ(decoded_packet.type(), Packet::Type::kAsyncDataPacket);
279 EXPECT_EQ(decoded_packet.size_bytes(),
280 AsyncDataPacket::kHeaderSizeBytes + kArbitraryMaxPayloadSizeBytes);
281 EXPECT_EQ(decoded_packet.handle_and_fragmentation_bits(),
282 kHandleAndFragmentationBits);
283 EXPECT_EQ(decoded_packet.handle(), kHandle);
284 EXPECT_EQ(decoded_packet.pb_flag(), kPbFlag);
285 EXPECT_EQ(decoded_packet.bc_flag(), kBcFlag);
286 EXPECT_EQ(decoded_packet.data().size_bytes(), kArbitraryMaxPayloadSizeBytes);
287 }
288
TEST_F(PacketTest,SyncDataPacketHeaderUndersizedEncode)289 TEST_F(PacketTest, SyncDataPacketHeaderUndersizedEncode) {
290 const SyncDataPacket packet(0u, ConstByteSpan());
291 EXPECT_EQ(0u, packet.data().size_bytes());
292 const Result<ConstByteSpan> encode_result = packet.Encode(
293 {packet_buffer_.data(), SyncDataPacket::kHeaderSizeBytes - 1});
294 EXPECT_EQ(Status::ResourceExhausted(), encode_result.status());
295 }
296
TEST_F(PacketTest,SyncDataPacketHeaderUndersizedDecode)297 TEST_F(PacketTest, SyncDataPacketHeaderUndersizedDecode) {
298 EXPECT_FALSE(SyncDataPacket::Decode({packet_buffer_.data(),
299 SyncDataPacket::kHeaderSizeBytes - 1})
300 .has_value());
301 }
302
TEST_F(PacketTest,SyncDataPacketHeaderOnlyEncodeAndDecode)303 TEST_F(PacketTest, SyncDataPacketHeaderOnlyEncodeAndDecode) {
304 constexpr uint16_t kHandle = 0b00'0000'0000;
305 constexpr uint8_t kPacketStatusFlag = 0b11;
306 constexpr uint8_t kReservedBits = 0;
307
308 constexpr uint16_t kHandleAndStatusBits =
309 kHandle | (kPacketStatusFlag << 12) | (kReservedBits << 14);
310
311 const SyncDataPacket packet(kHandleAndStatusBits, ConstByteSpan());
312 EXPECT_EQ(packet.type(), Packet::Type::kSyncDataPacket);
313 EXPECT_EQ(packet.size_bytes(), SyncDataPacket::kHeaderSizeBytes);
314 EXPECT_EQ(packet.handle_and_status_bits(), kHandleAndStatusBits);
315 EXPECT_EQ(packet.handle(), kHandle);
316 EXPECT_EQ(packet.packet_status_flag(), kPacketStatusFlag);
317 EXPECT_EQ(packet.data().size_bytes(), 0u);
318
319 const Result<ConstByteSpan> encode_result = packet.Encode(packet_buffer_);
320 ASSERT_EQ(OkStatus(), encode_result.status());
321
322 constexpr std::array<const std::byte, SyncDataPacket::kHeaderSizeBytes>
323 kExpectedEncodedPacket = bytes::MakeArray<const std::byte>(
324 0b0000'0000, 0b0011'0000, 0b0000'0000);
325 const ConstByteSpan& encoded_packet = encode_result.value();
326 EXPECT_TRUE(pw::containers::Equal(kExpectedEncodedPacket, encoded_packet));
327
328 // First, decode it from a perfectly sized span which we just encoded.
329 std::optional<SyncDataPacket> possible_packet =
330 SyncDataPacket::Decode(encoded_packet);
331 ASSERT_TRUE(possible_packet.has_value());
332 SyncDataPacket& decoded_packet = possible_packet.value();
333 EXPECT_EQ(decoded_packet.type(), Packet::Type::kSyncDataPacket);
334 EXPECT_EQ(decoded_packet.size_bytes(), SyncDataPacket::kHeaderSizeBytes);
335 EXPECT_EQ(packet.handle_and_status_bits(), kHandleAndStatusBits);
336 EXPECT_EQ(decoded_packet.packet_status_flag(), kPacketStatusFlag);
337 EXPECT_EQ(decoded_packet.handle(), kHandle);
338 EXPECT_EQ(decoded_packet.data().size_bytes(), 0u);
339
340 // Second, decode it from an oversized buffer.
341 possible_packet = SyncDataPacket::Decode({packet_buffer_});
342 ASSERT_TRUE(possible_packet.has_value());
343 decoded_packet = possible_packet.value();
344 EXPECT_EQ(decoded_packet.type(), Packet::Type::kSyncDataPacket);
345 EXPECT_EQ(decoded_packet.size_bytes(), SyncDataPacket::kHeaderSizeBytes);
346 EXPECT_EQ(packet.handle_and_status_bits(), kHandleAndStatusBits);
347 EXPECT_EQ(decoded_packet.handle(), kHandle);
348 EXPECT_EQ(decoded_packet.packet_status_flag(), kPacketStatusFlag);
349 EXPECT_EQ(decoded_packet.data().size_bytes(), 0u);
350 }
351
TEST_F(PacketTest,SyncDataPacketWithDataEncodeAndDecode)352 TEST_F(PacketTest, SyncDataPacketWithDataEncodeAndDecode) {
353 constexpr uint16_t kHandle = 0b00'0000'0000;
354 constexpr uint8_t kPacketStatusFlag = 0b11;
355 constexpr uint8_t kReservedBits = 0;
356
357 constexpr uint16_t kHandleAndStatusBits =
358 kHandle | (kPacketStatusFlag << 12) | (kReservedBits << 14);
359
360 constexpr std::array<const std::byte, kArbitraryMaxPayloadSizeBytes> kData =
361 bytes::MakeArray<const std::byte>(1, 2);
362 const SyncDataPacket packet(kHandleAndStatusBits, kData);
363 EXPECT_EQ(packet.type(), Packet::Type::kSyncDataPacket);
364 EXPECT_EQ(packet.size_bytes(),
365 SyncDataPacket::kHeaderSizeBytes + kArbitraryMaxPayloadSizeBytes);
366 EXPECT_EQ(packet.handle_and_status_bits(), kHandleAndStatusBits);
367 EXPECT_EQ(packet.handle(), kHandle);
368 EXPECT_EQ(packet.packet_status_flag(), kPacketStatusFlag);
369 EXPECT_EQ(packet.data().size_bytes(), kArbitraryMaxPayloadSizeBytes);
370
371 const Result<ConstByteSpan> encode_result = packet.Encode(packet_buffer_);
372 ASSERT_EQ(OkStatus(), encode_result.status());
373
374 constexpr std::array<const std::byte,
375 SyncDataPacket::kHeaderSizeBytes +
376 kArbitraryMaxPayloadSizeBytes>
377 kExpectedEncodedPacket = bytes::MakeArray<const std::byte>(
378 0b0000'0000, 0b0011'0000, 0b0000'0010, 1, 2);
379 const ConstByteSpan& encoded_packet = encode_result.value();
380 EXPECT_TRUE(pw::containers::Equal(kExpectedEncodedPacket, encoded_packet));
381
382 // First, decode it from a perfectly sized span which we just encoded.
383 std::optional<SyncDataPacket> possible_packet =
384 SyncDataPacket::Decode(encoded_packet);
385 ASSERT_TRUE(possible_packet.has_value());
386 SyncDataPacket& decoded_packet = possible_packet.value();
387 EXPECT_EQ(decoded_packet.type(), Packet::Type::kSyncDataPacket);
388 EXPECT_EQ(decoded_packet.size_bytes(),
389 SyncDataPacket::kHeaderSizeBytes + kArbitraryMaxPayloadSizeBytes);
390 EXPECT_EQ(packet.handle_and_status_bits(), kHandleAndStatusBits);
391 EXPECT_EQ(packet.handle(), kHandle);
392 EXPECT_EQ(packet.packet_status_flag(), kPacketStatusFlag);
393 EXPECT_EQ(decoded_packet.data().size_bytes(), kArbitraryMaxPayloadSizeBytes);
394
395 // Second, decode it from an oversized buffer.
396 possible_packet = SyncDataPacket::Decode({packet_buffer_});
397 ASSERT_TRUE(possible_packet.has_value());
398 decoded_packet = possible_packet.value();
399 EXPECT_EQ(decoded_packet.type(), Packet::Type::kSyncDataPacket);
400 EXPECT_EQ(decoded_packet.size_bytes(),
401 SyncDataPacket::kHeaderSizeBytes + kArbitraryMaxPayloadSizeBytes);
402 EXPECT_EQ(packet.handle_and_status_bits(), kHandleAndStatusBits);
403 EXPECT_EQ(packet.handle(), kHandle);
404 EXPECT_EQ(packet.packet_status_flag(), kPacketStatusFlag);
405 EXPECT_EQ(decoded_packet.data().size_bytes(), kArbitraryMaxPayloadSizeBytes);
406 }
407
TEST_F(PacketTest,EventPacketHeaderUndersizedEncode)408 TEST_F(PacketTest, EventPacketHeaderUndersizedEncode) {
409 const EventPacket packet(0u, ConstByteSpan());
410 EXPECT_EQ(0u, packet.parameters().size_bytes());
411 const Result<ConstByteSpan> encode_result =
412 packet.Encode({packet_buffer_.data(), EventPacket::kHeaderSizeBytes - 1});
413 EXPECT_EQ(Status::ResourceExhausted(), encode_result.status());
414 }
415
TEST_F(PacketTest,EventPacketHeaderUndersizedDecode)416 TEST_F(PacketTest, EventPacketHeaderUndersizedDecode) {
417 EXPECT_FALSE(EventPacket::Decode(
418 {packet_buffer_.data(), EventPacket::kHeaderSizeBytes - 1})
419 .has_value());
420 }
421
TEST_F(PacketTest,EventPacketHeaderOnlyEncodeAndDecode)422 TEST_F(PacketTest, EventPacketHeaderOnlyEncodeAndDecode) {
423 constexpr uint8_t kEventCode = 0b1111'1111;
424
425 const EventPacket packet(kEventCode, ConstByteSpan());
426 EXPECT_EQ(packet.type(), Packet::Type::kEventPacket);
427 EXPECT_EQ(packet.size_bytes(), EventPacket::kHeaderSizeBytes);
428 EXPECT_EQ(packet.event_code(), kEventCode);
429 EXPECT_EQ(packet.parameters().size_bytes(), 0u);
430
431 const Result<ConstByteSpan> encode_result = packet.Encode(packet_buffer_);
432 ASSERT_EQ(OkStatus(), encode_result.status());
433
434 constexpr std::array<const std::byte, EventPacket::kHeaderSizeBytes>
435 kExpectedEncodedPacket =
436 bytes::MakeArray<const std::byte>(0b1111'11111, 0b0000'0000);
437 const ConstByteSpan& encoded_packet = encode_result.value();
438 EXPECT_TRUE(pw::containers::Equal(kExpectedEncodedPacket, encoded_packet));
439
440 // First, decode it from a perfectly sized span which we just encoded.
441 std::optional<EventPacket> possible_packet =
442 EventPacket::Decode(encoded_packet);
443 ASSERT_TRUE(possible_packet.has_value());
444 EventPacket& decoded_packet = possible_packet.value();
445 EXPECT_EQ(decoded_packet.type(), Packet::Type::kEventPacket);
446 EXPECT_EQ(decoded_packet.size_bytes(), EventPacket::kHeaderSizeBytes);
447 EXPECT_EQ(decoded_packet.event_code(), kEventCode);
448 EXPECT_EQ(decoded_packet.parameters().size_bytes(), 0u);
449
450 // Second, decode it from an oversized buffer.
451 possible_packet = EventPacket::Decode({packet_buffer_});
452 ASSERT_TRUE(possible_packet.has_value());
453 decoded_packet = possible_packet.value();
454 EXPECT_EQ(decoded_packet.type(), Packet::Type::kEventPacket);
455 EXPECT_EQ(decoded_packet.size_bytes(), EventPacket::kHeaderSizeBytes);
456 EXPECT_EQ(decoded_packet.event_code(), kEventCode);
457 EXPECT_EQ(decoded_packet.parameters().size_bytes(), 0u);
458 }
459
TEST_F(PacketTest,EventPacketWithParametersEncodeAndDecode)460 TEST_F(PacketTest, EventPacketWithParametersEncodeAndDecode) {
461 constexpr uint8_t kEventCode = 0b1111'0000;
462
463 constexpr std::array<const std::byte, kArbitraryMaxPayloadSizeBytes>
464 kParameters = bytes::MakeArray<const std::byte>(1, 2);
465 const EventPacket packet(kEventCode, kParameters);
466 EXPECT_EQ(packet.type(), Packet::Type::kEventPacket);
467 EXPECT_EQ(packet.size_bytes(),
468 EventPacket::kHeaderSizeBytes + kArbitraryMaxPayloadSizeBytes);
469 EXPECT_EQ(packet.event_code(), kEventCode);
470 EXPECT_EQ(packet.parameters().size_bytes(), kArbitraryMaxPayloadSizeBytes);
471
472 const Result<ConstByteSpan> encode_result = packet.Encode(packet_buffer_);
473 ASSERT_EQ(OkStatus(), encode_result.status());
474
475 constexpr std::array<const std::byte,
476 EventPacket::kHeaderSizeBytes +
477 kArbitraryMaxPayloadSizeBytes>
478 kExpectedEncodedPacket =
479 bytes::MakeArray<const std::byte>(0b1111'0000, 0b0000'0010, 1, 2);
480 const ConstByteSpan& encoded_packet = encode_result.value();
481 EXPECT_TRUE(pw::containers::Equal(kExpectedEncodedPacket, encoded_packet));
482
483 // First, decode it from a perfectly sized span which we just encoded.
484 std::optional<EventPacket> possible_packet =
485 EventPacket::Decode(encoded_packet);
486 ASSERT_TRUE(possible_packet.has_value());
487 EventPacket& decoded_packet = possible_packet.value();
488 EXPECT_EQ(decoded_packet.type(), Packet::Type::kEventPacket);
489 EXPECT_EQ(decoded_packet.size_bytes(),
490 EventPacket::kHeaderSizeBytes + kArbitraryMaxPayloadSizeBytes);
491 EXPECT_EQ(decoded_packet.event_code(), kEventCode);
492 EXPECT_EQ(decoded_packet.parameters().size_bytes(),
493 kArbitraryMaxPayloadSizeBytes);
494
495 // Second, decode it from an oversized buffer.
496 possible_packet = EventPacket::Decode({packet_buffer_});
497 ASSERT_TRUE(possible_packet.has_value());
498 decoded_packet = possible_packet.value();
499 EXPECT_EQ(decoded_packet.type(), Packet::Type::kEventPacket);
500 EXPECT_EQ(decoded_packet.size_bytes(),
501 EventPacket::kHeaderSizeBytes + kArbitraryMaxPayloadSizeBytes);
502 EXPECT_EQ(decoded_packet.event_code(), kEventCode);
503 EXPECT_EQ(decoded_packet.parameters().size_bytes(),
504 kArbitraryMaxPayloadSizeBytes);
505 }
506
507 } // namespace
508 } // namespace pw::bluetooth_hci
509