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/hci/advertising_report_parser.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_bluetooth_sapphire/internal/host/transport/control_packets.h"
20 #include "pw_unit_test/framework.h"
21
22 namespace bt::hci::test {
23 namespace {
24
TEST(AdvertisingReportParserTest,EmptyReport)25 TEST(AdvertisingReportParserTest, EmptyReport) {
26 StaticByteBuffer bytes(0x3E, 0x02, 0x02, 0x00);
27
28 auto event = EventPacket::New(bytes.size() - sizeof(hci_spec::EventHeader));
29 event->mutable_view()->mutable_data().Write(bytes);
30 event->InitializeFromBuffer();
31
32 hci::AdvertisingReportParser parser(*event);
33 EXPECT_FALSE(parser.HasMoreReports());
34
35 const hci_spec::LEAdvertisingReportData* data;
36 int8_t rssi;
37 EXPECT_FALSE(parser.GetNextReport(&data, &rssi));
38 }
39
TEST(AdvertisingReportParserTest,SingleReportMalformed)40 TEST(AdvertisingReportParserTest, SingleReportMalformed) {
41 // clang-format off
42
43 StaticByteBuffer bytes(
44 0x3E, 0x0B, 0x02, 0x01, // HCI event header and LE Meta Event params
45 0x03, 0x02, // event_type, address_type
46 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // address
47 0x00 // |length_data|. RSSI is missing
48 );
49
50 // clang-format on
51
52 auto event = EventPacket::New(bytes.size() - sizeof(hci_spec::EventHeader));
53 event->mutable_view()->mutable_data().Write(bytes);
54 event->InitializeFromBuffer();
55
56 hci::AdvertisingReportParser parser(*event);
57 EXPECT_TRUE(parser.HasMoreReports());
58 EXPECT_FALSE(parser.encountered_error());
59
60 const hci_spec::LEAdvertisingReportData* data;
61 int8_t rssi;
62 EXPECT_FALSE(parser.GetNextReport(&data, &rssi));
63 EXPECT_TRUE(parser.encountered_error());
64 }
65
TEST(AdvertisingReportParserTest,SingleReportNoData)66 TEST(AdvertisingReportParserTest, SingleReportNoData) {
67 // clang-format off
68
69 StaticByteBuffer bytes(
70 0x3E, 0x0C, 0x02, 0x01, // HCI event header and LE Meta Event params
71 0x03, 0x02, // event_type, address_type
72 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // address
73 0x00, 0x7F // |length_data|, RSSI
74 );
75
76 // clang-format on
77
78 auto event = EventPacket::New(bytes.size() - sizeof(hci_spec::EventHeader));
79 event->mutable_view()->mutable_data().Write(bytes);
80 event->InitializeFromBuffer();
81
82 AdvertisingReportParser parser(*event);
83 EXPECT_TRUE(parser.HasMoreReports());
84
85 const hci_spec::LEAdvertisingReportData* data;
86 int8_t rssi;
87 EXPECT_TRUE(parser.GetNextReport(&data, &rssi));
88 EXPECT_EQ(hci_spec::LEAdvertisingEventType::kAdvNonConnInd, data->event_type);
89 EXPECT_EQ(hci_spec::LEAddressType::kPublicIdentity, data->address_type);
90 EXPECT_EQ("06:05:04:03:02:01", data->address.ToString());
91 EXPECT_EQ(0u, data->length_data);
92 EXPECT_EQ(hci_spec::kRSSIInvalid, rssi);
93
94 // No other reports
95 EXPECT_FALSE(parser.HasMoreReports());
96 EXPECT_FALSE(parser.GetNextReport(&data, &rssi));
97
98 EXPECT_FALSE(parser.encountered_error());
99 }
100
TEST(AdvertisingReportParserTest,ReportsValidInvalid)101 TEST(AdvertisingReportParserTest, ReportsValidInvalid) {
102 // clang-format off
103
104 StaticByteBuffer bytes(
105 0x3E, 0x16, 0x02, 0x02, // HCI event header and LE Meta Event params
106 0x03, 0x02, // event_type, address_type
107 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // address
108 0x00, 0x7F, // |length_data|, RSSI
109 0x03, 0x02, // event_type, address_type
110 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // address
111 0x0A, 0x7F // malformed |length_data|, RSSI
112 );
113
114 // clang-format on
115
116 auto event = EventPacket::New(bytes.size() - sizeof(hci_spec::EventHeader));
117 event->mutable_view()->mutable_data().Write(bytes);
118 event->InitializeFromBuffer();
119
120 AdvertisingReportParser parser(*event);
121 EXPECT_TRUE(parser.HasMoreReports());
122 EXPECT_FALSE(parser.encountered_error());
123
124 const hci_spec::LEAdvertisingReportData* data;
125 int8_t rssi;
126 EXPECT_TRUE(parser.GetNextReport(&data, &rssi));
127 EXPECT_EQ(hci_spec::LEAdvertisingEventType::kAdvNonConnInd, data->event_type);
128 EXPECT_EQ(hci_spec::LEAddressType::kPublicIdentity, data->address_type);
129 EXPECT_EQ("06:05:04:03:02:01", data->address.ToString());
130 EXPECT_EQ(0u, data->length_data);
131 EXPECT_EQ(hci_spec::kRSSIInvalid, rssi);
132
133 // There are more reports...
134 EXPECT_TRUE(parser.HasMoreReports());
135 EXPECT_FALSE(parser.encountered_error());
136
137 // ...but the report is malformed.
138 EXPECT_FALSE(parser.GetNextReport(&data, &rssi));
139 EXPECT_TRUE(parser.encountered_error());
140 }
141
TEST(AdvertisingReportParserTest,ReportsAllValid)142 TEST(AdvertisingReportParserTest, ReportsAllValid) {
143 // clang-format off
144
145 StaticByteBuffer bytes(
146 0x3E, 0x28, 0x02, 0x03, // HCI event header and LE Meta Event params
147 0x03, 0x02, // event_type, address_type
148 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // address
149 0x00, 0x7F, // |length_data|, RSSI
150
151 0x00, 0x01, // event_type, address_type
152 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, // address
153 0x03, 0x01, 0x02, 0x03, 0x0F, // |length_data|, data, RSSI
154
155 0x01, 0x00, // event_type, address_type
156 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, // address
157 0x05, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // |length_data|, data
158 0x01 // RSSI
159 );
160
161 // clang-format on
162
163 auto event = EventPacket::New(bytes.size() - sizeof(hci_spec::EventHeader));
164 event->mutable_view()->mutable_data().Write(bytes);
165 event->InitializeFromBuffer();
166
167 AdvertisingReportParser parser(*event);
168 EXPECT_TRUE(parser.HasMoreReports());
169
170 const hci_spec::LEAdvertisingReportData* data;
171 int8_t rssi;
172 EXPECT_TRUE(parser.GetNextReport(&data, &rssi));
173 EXPECT_EQ(hci_spec::LEAdvertisingEventType::kAdvNonConnInd, data->event_type);
174 EXPECT_EQ(hci_spec::LEAddressType::kPublicIdentity, data->address_type);
175 EXPECT_EQ("06:05:04:03:02:01", data->address.ToString());
176 EXPECT_EQ(0u, data->length_data);
177 EXPECT_EQ(hci_spec::kRSSIInvalid, rssi);
178
179 // There are more reports
180 EXPECT_TRUE(parser.HasMoreReports());
181 EXPECT_TRUE(parser.GetNextReport(&data, &rssi));
182 EXPECT_EQ(hci_spec::LEAdvertisingEventType::kAdvInd, data->event_type);
183 EXPECT_EQ(hci_spec::LEAddressType::kRandom, data->address_type);
184 EXPECT_EQ("0C:0B:0A:09:08:07", data->address.ToString());
185 EXPECT_EQ(3, data->length_data);
186 EXPECT_TRUE(ContainersEqual(std::array<uint8_t, 3>{{0x01, 0x02, 0x03}},
187 data->data,
188 data->length_data));
189 EXPECT_EQ(15, rssi);
190
191 // There are more reports
192 EXPECT_TRUE(parser.HasMoreReports());
193 EXPECT_TRUE(parser.GetNextReport(&data, &rssi));
194 EXPECT_EQ(hci_spec::LEAdvertisingEventType::kAdvDirectInd, data->event_type);
195 EXPECT_EQ(hci_spec::LEAddressType::kPublic, data->address_type);
196 EXPECT_EQ("12:11:10:0F:0E:0D", data->address.ToString());
197 EXPECT_EQ(5, data->length_data);
198 EXPECT_TRUE(
199 ContainersEqual(std::array<uint8_t, 5>{{0xFF, 0xFF, 0xFF, 0xFF, 0xFF}},
200 data->data,
201 data->length_data));
202 EXPECT_EQ(1, rssi);
203
204 // No more reports.
205 EXPECT_FALSE(parser.HasMoreReports());
206 EXPECT_FALSE(parser.GetNextReport(&data, &rssi));
207
208 EXPECT_FALSE(parser.encountered_error());
209 }
210
TEST(AdvertisingReportParserTest,ReportCountLessThanPayloadSize)211 TEST(AdvertisingReportParserTest, ReportCountLessThanPayloadSize) {
212 // clang-format off
213
214 StaticByteBuffer bytes(
215 0x3E, 0x28, 0x02, // HCI event header and LE Meta Event param
216 0x01, // Event count is 1, even though packet contains 3
217 0x03, 0x02, // event_type, address_type
218 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // address
219 0x00, 0x7F, // |length_data|, RSSI
220
221 0x00, 0x01, // event_type, address_type
222 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, // address
223 0x03, 0x01, 0x02, 0x03, 0x0F, // |length_data|, data, RSSI
224
225 0x01, 0x00, // event_type, address_type
226 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, // address
227 0x05, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // |length_data|, data
228 0x01 // RSSI
229 );
230
231 // clang-format on
232
233 auto event = EventPacket::New(bytes.size() - sizeof(hci_spec::EventHeader));
234 event->mutable_view()->mutable_data().Write(bytes);
235 event->InitializeFromBuffer();
236
237 AdvertisingReportParser parser(*event);
238 EXPECT_TRUE(parser.HasMoreReports());
239 EXPECT_FALSE(parser.encountered_error());
240
241 const hci_spec::LEAdvertisingReportData* data;
242 int8_t rssi;
243 EXPECT_TRUE(parser.GetNextReport(&data, &rssi));
244 EXPECT_EQ(hci_spec::LEAdvertisingEventType::kAdvNonConnInd, data->event_type);
245 EXPECT_EQ(hci_spec::LEAddressType::kPublicIdentity, data->address_type);
246 EXPECT_EQ("06:05:04:03:02:01", data->address.ToString());
247 EXPECT_EQ(0u, data->length_data);
248 EXPECT_EQ(hci_spec::kRSSIInvalid, rssi);
249
250 // Since the packet is malformed (the event payload contains 3 reports while
251 // the header states there is only 1) this should return false.
252 EXPECT_FALSE(parser.encountered_error());
253 EXPECT_FALSE(parser.HasMoreReports());
254 EXPECT_TRUE(parser.encountered_error());
255
256 EXPECT_FALSE(parser.GetNextReport(&data, &rssi));
257 EXPECT_TRUE(parser.encountered_error());
258 }
259
TEST(AdvertisingReportParserTest,ReportCountGreaterThanPayloadSize)260 TEST(AdvertisingReportParserTest, ReportCountGreaterThanPayloadSize) {
261 // clang-format off
262
263 StaticByteBuffer bytes(
264 0x3E, 0x0C, 0x02, // HCI event header and LE Meta Event param
265 0x02, // Event count is 2, even though packet contains 1
266 0x03, 0x02, // event_type, address_type
267 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // address
268 0x00, 0x7F // |length_data|, RSSI
269 );
270
271 // clang-format on
272
273 auto event = EventPacket::New(bytes.size() - sizeof(hci_spec::EventHeader));
274 event->mutable_view()->mutable_data().Write(bytes);
275 event->InitializeFromBuffer();
276
277 AdvertisingReportParser parser(*event);
278 EXPECT_TRUE(parser.HasMoreReports());
279
280 const hci_spec::LEAdvertisingReportData* data;
281 int8_t rssi;
282 EXPECT_TRUE(parser.GetNextReport(&data, &rssi));
283 EXPECT_EQ(hci_spec::LEAdvertisingEventType::kAdvNonConnInd, data->event_type);
284 EXPECT_EQ(hci_spec::LEAddressType::kPublicIdentity, data->address_type);
285 EXPECT_EQ("06:05:04:03:02:01", data->address.ToString());
286 EXPECT_EQ(0u, data->length_data);
287 EXPECT_EQ(hci_spec::kRSSIInvalid, rssi);
288
289 EXPECT_FALSE(parser.encountered_error());
290
291 // Since the packet is malformed (the event payload contains 1 report while
292 // the header states there are 2) this should return false.
293 EXPECT_FALSE(parser.HasMoreReports());
294 EXPECT_FALSE(parser.GetNextReport(&data, &rssi));
295
296 EXPECT_TRUE(parser.encountered_error());
297 }
298
299 } // namespace
300 } // namespace bt::hci::test
301