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/common/packet_view.h"
16
17 #include <string>
18
19 #include "pw_bluetooth_sapphire/internal/host/common/byte_buffer.h"
20 #include "pw_bluetooth_sapphire/internal/host/testing/test_helpers.h"
21 #include "pw_unit_test/framework.h"
22
23 #pragma clang diagnostic ignored "-Wzero-length-array"
24
25 namespace bt {
26 namespace {
27
28 struct TestHeader {
29 uint16_t field16;
30 uint8_t field8;
31 } __attribute__((packed));
32
33 struct TestPayload {
34 uint8_t arg0;
35 uint16_t arg1;
36 uint8_t arg2[2];
37 uint8_t arg3[0];
38 } __attribute__((packed));
39
TEST(PacketViewTest,EmptyPayload)40 TEST(PacketViewTest, EmptyPayload) {
41 constexpr size_t kBufferSize = sizeof(TestHeader);
42
43 StaticByteBuffer<kBufferSize> buffer;
44
45 // Assign some values to the header portion.
46 *reinterpret_cast<uint16_t*>(buffer.mutable_data()) = 512;
47 buffer[2] = 255;
48
49 PacketView<TestHeader> packet(&buffer);
50 EXPECT_EQ(kBufferSize, packet.size());
51 EXPECT_EQ(0u, packet.payload_size());
52 EXPECT_EQ(0u, packet.payload_data().size());
53
54 EXPECT_EQ(512, packet.header().field16);
55 EXPECT_EQ(255, packet.header().field8);
56
57 // Verify the buffer contents.
58 // TODO(armansito): This assumes that the packet is encoded in Bluetooth
59 // network byte-order which is little-endian. For now we rely on the fact that
60 // both ARM64 and x86-64 have little-endian encoding schemes to get away with
61 // not explicitly encoding the entries. This is obviously wrong on other
62 // architectures and will need to be addressed.
63 constexpr std::array<uint8_t, kBufferSize> kExpected{{0x00, 0x02, 0xFF}};
64 EXPECT_TRUE(ContainersEqual(kExpected, buffer));
65 }
66
TEST(PacketViewTest,NonEmptyPayload)67 TEST(PacketViewTest, NonEmptyPayload) {
68 constexpr size_t kPayloadPadding = 4;
69 constexpr size_t kPayloadSize = sizeof(TestPayload) + kPayloadPadding;
70 constexpr size_t kBufferSize = sizeof(TestHeader) + kPayloadSize;
71
72 StaticByteBuffer<kBufferSize> buffer;
73 buffer.SetToZeros();
74
75 MutablePacketView<TestHeader> packet(&buffer, kPayloadSize);
76 EXPECT_EQ(kBufferSize, packet.size());
77 EXPECT_EQ(kPayloadSize, packet.payload_size());
78 EXPECT_NE(nullptr, packet.payload_data().data());
79
80 auto payload = packet.mutable_payload<TestPayload>();
81 EXPECT_NE(nullptr, payload);
82
83 // Modify the payload.
84 payload->arg0 = 127;
85 payload->arg2[0] = 1;
86 payload->arg2[1] = 2;
87 memcpy(payload->arg3, "Test", 4);
88
89 constexpr std::array<uint8_t, kBufferSize> kExpected{{
90 0x00,
91 0x00,
92 0x00, // header
93 0x7F, // arg0
94 0x00,
95 0x00, // arg1
96 0x01,
97 0x02, // arg2
98 'T',
99 'e',
100 's',
101 't' // arg3
102 }};
103 EXPECT_TRUE(ContainersEqual(kExpected, buffer));
104 }
105
106 } // namespace
107 } // namespace bt
108