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