• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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