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/supplement_data.h"
16
17 #include "pw_bluetooth_sapphire/internal/host/common/byte_buffer.h"
18 #include "pw_bluetooth_sapphire/internal/host/testing/test_helpers.h"
19 #include "pw_unit_test/framework.h"
20
21 namespace bt {
22 namespace {
23
TEST(SupplementDataTest,ReaderEmptyData)24 TEST(SupplementDataTest, ReaderEmptyData) {
25 BufferView empty;
26 SupplementDataReader reader(empty);
27 EXPECT_FALSE(reader.is_valid());
28 EXPECT_FALSE(reader.HasMoreData());
29 }
30
TEST(SupplementDataTest,ReaderMalformedData)31 TEST(SupplementDataTest, ReaderMalformedData) {
32 // TLV length exceeds the size of the payload
33 StaticByteBuffer bytes0(0x01);
34 SupplementDataReader reader(bytes0);
35 EXPECT_FALSE(reader.is_valid());
36 EXPECT_FALSE(reader.HasMoreData());
37
38 StaticByteBuffer bytes(0x05, 0x00, 0x00, 0x00, 0x00);
39 reader = SupplementDataReader(bytes);
40 EXPECT_FALSE(reader.is_valid());
41 EXPECT_FALSE(reader.HasMoreData());
42
43 // TLV length is 0. This is not considered malformed. Data should be valid but
44 // should not return more data.
45 bytes = StaticByteBuffer(0x00, 0x00, 0x00, 0x00, 0x00);
46 reader = SupplementDataReader(bytes);
47 EXPECT_TRUE(reader.is_valid());
48 EXPECT_FALSE(reader.HasMoreData());
49
50 // First field is valid, second field is not.
51 DataType type;
52 BufferView data;
53 bytes = StaticByteBuffer(0x02, 0x00, 0x00, 0x02, 0x00);
54 reader = SupplementDataReader(bytes);
55 EXPECT_FALSE(reader.is_valid());
56 EXPECT_FALSE(reader.HasMoreData());
57 EXPECT_FALSE(reader.GetNextField(&type, &data));
58
59 // First field is valid, second field has length 0.
60 bytes = StaticByteBuffer(0x02, 0x00, 0x00, 0x00, 0x00);
61 reader = SupplementDataReader(bytes);
62 EXPECT_TRUE(reader.is_valid());
63 EXPECT_TRUE(reader.HasMoreData());
64 EXPECT_TRUE(reader.GetNextField(&type, &data));
65 EXPECT_FALSE(reader.HasMoreData());
66 EXPECT_FALSE(reader.GetNextField(&type, &data));
67 }
68
TEST(SupplementDataTest,ReaderParseFields)69 TEST(SupplementDataTest, ReaderParseFields) {
70 StaticByteBuffer bytes(0x02, 0x01, 0x00, 0x05, 0x09, 'T', 'e', 's', 't');
71 SupplementDataReader reader(bytes);
72 EXPECT_TRUE(reader.is_valid());
73 EXPECT_TRUE(reader.HasMoreData());
74
75 DataType type;
76 BufferView data;
77 EXPECT_TRUE(reader.GetNextField(&type, &data));
78 EXPECT_EQ(DataType::kFlags, type);
79 EXPECT_EQ(1u, data.size());
80 EXPECT_TRUE(ContainersEqual(StaticByteBuffer(0x00), data));
81
82 EXPECT_TRUE(reader.HasMoreData());
83 EXPECT_TRUE(reader.GetNextField(&type, &data));
84 EXPECT_EQ(DataType::kCompleteLocalName, type);
85 EXPECT_EQ(4u, data.size());
86 EXPECT_TRUE(ContainersEqual(std::string("Test"), data));
87
88 EXPECT_FALSE(reader.HasMoreData());
89 EXPECT_FALSE(reader.GetNextField(&type, &data));
90 }
91
92 // Helper for computing the size of a string literal at compile time. sizeof()
93 // would have worked too but that counts the null character.
94 template <std::size_t N>
StringSize(char const (&)[N])95 constexpr size_t StringSize(char const (&)[N]) {
96 return N - 1;
97 }
98
TEST(SupplementDataTest,WriteFieldAndVerifyContents)99 TEST(SupplementDataTest, WriteFieldAndVerifyContents) {
100 constexpr char kValue0[] = "value zero";
101 constexpr char kValue1[] = "value one";
102 constexpr char kValue2[] = "value two";
103 constexpr char kValue3[] = "value three";
104
105 // Have just enough space for the first three values (+ 6 for 2 extra octets
106 // for each TLV field).
107 constexpr char kBufferSize =
108 StringSize(kValue0) + StringSize(kValue1) + StringSize(kValue2) + 6;
109 StaticByteBuffer<kBufferSize> buffer;
110
111 SupplementDataWriter writer(&buffer);
112 EXPECT_EQ(0u, writer.bytes_written());
113
114 // We write malformed values here for testing purposes.
115 EXPECT_TRUE(writer.WriteField(DataType::kFlags, BufferView(kValue0)));
116 EXPECT_EQ(StringSize(kValue0) + 2, writer.bytes_written());
117
118 EXPECT_TRUE(
119 writer.WriteField(DataType::kShortenedLocalName, BufferView(kValue1)));
120 EXPECT_EQ(StringSize(kValue0) + 2 + StringSize(kValue1) + 2,
121 writer.bytes_written());
122
123 // Trying to write kValue3 should fail because there isn't enough room left in
124 // the buffer.
125 EXPECT_FALSE(
126 writer.WriteField(DataType::kCompleteLocalName, BufferView(kValue3)));
127
128 // Writing kValue2 should fill up the buffer.
129 EXPECT_TRUE(
130 writer.WriteField(DataType::kCompleteLocalName, BufferView(kValue2)));
131 EXPECT_FALSE(
132 writer.WriteField(DataType::kCompleteLocalName, BufferView(kValue3)));
133 EXPECT_EQ(buffer.size(), writer.bytes_written());
134
135 // Verify the contents.
136 DataType type;
137 BufferView value;
138 SupplementDataReader reader(buffer);
139 EXPECT_TRUE(reader.is_valid());
140
141 EXPECT_TRUE(reader.GetNextField(&type, &value));
142 EXPECT_EQ(DataType::kFlags, type);
143 EXPECT_EQ(kValue0, value.AsString());
144
145 EXPECT_TRUE(reader.GetNextField(&type, &value));
146 EXPECT_EQ(DataType::kShortenedLocalName, type);
147 EXPECT_EQ(kValue1, value.AsString());
148
149 EXPECT_TRUE(reader.GetNextField(&type, &value));
150 EXPECT_EQ(DataType::kCompleteLocalName, type);
151 EXPECT_EQ(kValue2, value.AsString());
152
153 EXPECT_FALSE(reader.GetNextField(&type, &value));
154 }
155
156 } // namespace
157 } // namespace bt
158