1 /*
2 * Copyright 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <gtest/gtest.h>
18
19 #include <chrono>
20 #include <cstdint>
21 #include <memory>
22 #include <thread>
23 #include <vector>
24
25 #include "hci/address.h"
26 #include "hci/hci_packets.h"
27 #include "model/controller/link_layer_controller.h"
28 #include "packet/bit_inserter.h"
29 #include "packet/packet_view.h"
30 #include "packets/link_layer_packets.h"
31
32 namespace rootcanal {
33
34 using namespace bluetooth::hci;
35
36 class LeScanningFilterDuplicates : public ::testing::Test {
37 public:
LeScanningFilterDuplicates()38 LeScanningFilterDuplicates() {}
39
40 ~LeScanningFilterDuplicates() override = default;
41
SetUp()42 void SetUp() override {
43 event_listener_called_ = 0;
44 controller_.RegisterEventChannel(event_listener_);
45 controller_.RegisterRemoteChannel(remote_listener_);
46
47 auto to_mask = [](auto event) -> uint64_t {
48 return UINT64_C(1) << (static_cast<uint8_t>(event) - 1);
49 };
50
51 // Set event mask to receive (extended) Advertising Reports
52 controller_.SetEventMask(to_mask(EventCode::LE_META_EVENT));
53
54 controller_.SetLeEventMask(
55 to_mask(SubeventCode::ADVERTISING_REPORT) |
56 to_mask(SubeventCode::EXTENDED_ADVERTISING_REPORT) |
57 to_mask(SubeventCode::DIRECTED_ADVERTISING_REPORT));
58 }
59
StartScan(FilterDuplicates filter_duplicates)60 void StartScan(FilterDuplicates filter_duplicates) {
61 ASSERT_EQ(ErrorCode::SUCCESS, controller_.LeSetScanParameters(
62 LeScanType::ACTIVE, 0x4, 0x4,
63 OwnAddressType::PUBLIC_DEVICE_ADDRESS,
64 LeScanningFilterPolicy::ACCEPT_ALL));
65 ASSERT_EQ(ErrorCode::SUCCESS,
66 controller_.LeSetScanEnable(
67 true, filter_duplicates == FilterDuplicates::ENABLED));
68 }
69
StopScan(void)70 void StopScan(void) {
71 ASSERT_EQ(ErrorCode::SUCCESS, controller_.LeSetScanEnable(false, false));
72 }
73
StartExtendedScan(FilterDuplicates filter_duplicates,uint16_t duration=0,uint16_t period=0)74 void StartExtendedScan(FilterDuplicates filter_duplicates,
75 uint16_t duration = 0, uint16_t period = 0) {
76 bluetooth::hci::PhyScanParameters param;
77 param.le_scan_type_ = LeScanType::ACTIVE;
78 param.le_scan_interval_ = 0x4;
79 param.le_scan_window_ = 0x4;
80
81 ASSERT_EQ(ErrorCode::SUCCESS,
82 controller_.LeSetExtendedScanParameters(
83 OwnAddressType::PUBLIC_DEVICE_ADDRESS,
84 LeScanningFilterPolicy::ACCEPT_ALL, 0x1, {param}));
85 ASSERT_EQ(ErrorCode::SUCCESS,
86 controller_.LeSetExtendedScanEnable(true, filter_duplicates,
87 duration, period));
88 }
89
StopExtendedScan(void)90 void StopExtendedScan(void) {
91 ASSERT_EQ(ErrorCode::SUCCESS, controller_.LeSetExtendedScanEnable(
92 false, FilterDuplicates::DISABLED, 0, 0));
93 }
94
95 /// Helper for building ScanResponse packets
LeScanResponse(std::vector<uint8_t> const data={})96 static model::packets::LinkLayerPacketView LeScanResponse(
97 std::vector<uint8_t> const data = {}) {
98 return FromBuilder(*model::packets::LeScanResponseBuilder::Create(
99 Address::kEmpty, Address::kEmpty, model::packets::AddressType::PUBLIC,
100 data));
101 }
102
103 /// Helper for building LeLegacyAdvertisingPdu packets
LeLegacyAdvertisingPdu(std::vector<uint8_t> const data={})104 static model::packets::LinkLayerPacketView LeLegacyAdvertisingPdu(
105 std::vector<uint8_t> const data = {}) {
106 return FromBuilder(*model::packets::LeLegacyAdvertisingPduBuilder::Create(
107 Address::kEmpty, Address::kEmpty, model::packets::AddressType::PUBLIC,
108 model::packets::AddressType::PUBLIC,
109 model::packets::LegacyAdvertisingType::ADV_IND, data));
110 }
111
112 /// Helper for building LeExtendedAdvertisingPdu packets
LeExtendedAdvertisingPdu(std::vector<uint8_t> const data={})113 static model::packets::LinkLayerPacketView LeExtendedAdvertisingPdu(
114 std::vector<uint8_t> const data = {}) {
115 return FromBuilder(*model::packets::LeExtendedAdvertisingPduBuilder::Create(
116 Address::kEmpty, Address::kEmpty, model::packets::AddressType::PUBLIC,
117 model::packets::AddressType::PUBLIC, 0, 1, 0, 0, 0,
118 model::packets::PrimaryPhyType::LE_1M,
119 model::packets::SecondaryPhyType::LE_1M, 0, data));
120 }
121
122 enum Filtered {
123 kFiltered,
124 kReported,
125 };
126
SendPacket(model::packets::LinkLayerPacketView packet)127 void SendPacket(model::packets::LinkLayerPacketView packet) {
128 controller_.IncomingPacket(packet, -90);
129 }
130
131 /// Helper for sending the provided packet to the controller then checking if
132 /// it was reported or filtered
SendPacketAndCheck(model::packets::LinkLayerPacketView packet)133 enum Filtered SendPacketAndCheck(model::packets::LinkLayerPacketView packet) {
134 unsigned const before = event_listener_called_;
135 SendPacket(packet);
136
137 if (before == event_listener_called_) {
138 return kFiltered;
139 }
140 return kReported;
141 }
142
143 protected:
144 Address address_{};
145 ControllerProperties properties_{};
146 LinkLayerController controller_{address_, properties_};
147 static unsigned event_listener_called_;
148
149 private:
event_listener_(std::shared_ptr<EventBuilder>)150 static void event_listener_(std::shared_ptr<EventBuilder> /* event */) {
151 event_listener_called_++;
152 }
153
remote_listener_(std::shared_ptr<model::packets::LinkLayerPacketBuilder>,Phy::Type,int8_t)154 static void remote_listener_(
155 std::shared_ptr<model::packets::LinkLayerPacketBuilder> /* packet */,
156 Phy::Type /* phy */, int8_t /* tx_power */) {}
157
158 /// Helper for building packet view from packet builder
FromBuilder(model::packets::LinkLayerPacketBuilder & builder)159 static model::packets::LinkLayerPacketView FromBuilder(
160 model::packets::LinkLayerPacketBuilder& builder) {
161 std::shared_ptr<std::vector<uint8_t>> buffer(new std::vector<uint8_t>);
162 auto bit_inserter = bluetooth::packet::BitInserter(*buffer);
163
164 builder.Serialize(bit_inserter);
165
166 return model::packets::LinkLayerPacketView::Create(
167 PacketView<kLittleEndian>(buffer));
168 }
169 };
170
171 unsigned LeScanningFilterDuplicates::event_listener_called_ = 0;
172
TEST_F(LeScanningFilterDuplicates,LegacyAdvertisingPduDuringLegacyScan)173 TEST_F(LeScanningFilterDuplicates, LegacyAdvertisingPduDuringLegacyScan) {
174 StopScan();
175 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeLegacyAdvertisingPdu()));
176
177 StartScan(FilterDuplicates::DISABLED);
178 ASSERT_EQ(kReported, SendPacketAndCheck(LeLegacyAdvertisingPdu()));
179 ASSERT_EQ(kReported, SendPacketAndCheck(LeLegacyAdvertisingPdu()));
180
181 StopScan();
182 StartScan(FilterDuplicates::ENABLED);
183 ASSERT_EQ(kReported, SendPacketAndCheck(LeLegacyAdvertisingPdu()));
184 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeLegacyAdvertisingPdu()));
185 ASSERT_EQ(kReported, SendPacketAndCheck(LeLegacyAdvertisingPdu({0})));
186 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeLegacyAdvertisingPdu({0})));
187 ASSERT_EQ(kReported, SendPacketAndCheck(LeLegacyAdvertisingPdu({0, 1})));
188 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeLegacyAdvertisingPdu({0, 1})));
189 }
190
TEST_F(LeScanningFilterDuplicates,LegacyAdvertisingPduDuringExtendedScan)191 TEST_F(LeScanningFilterDuplicates, LegacyAdvertisingPduDuringExtendedScan) {
192 StopExtendedScan();
193 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeLegacyAdvertisingPdu()));
194
195 StartExtendedScan(FilterDuplicates::DISABLED);
196 ASSERT_EQ(kReported, SendPacketAndCheck(LeLegacyAdvertisingPdu()));
197 ASSERT_EQ(kReported, SendPacketAndCheck(LeLegacyAdvertisingPdu()));
198
199 StopExtendedScan();
200 StartExtendedScan(FilterDuplicates::ENABLED);
201 ASSERT_EQ(kReported, SendPacketAndCheck(LeLegacyAdvertisingPdu()));
202 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeLegacyAdvertisingPdu()));
203 ASSERT_EQ(kReported, SendPacketAndCheck(LeLegacyAdvertisingPdu({0})));
204 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeLegacyAdvertisingPdu({0})));
205 ASSERT_EQ(kReported, SendPacketAndCheck(LeLegacyAdvertisingPdu({0, 1})));
206 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeLegacyAdvertisingPdu({0, 1})));
207 }
208
TEST_F(LeScanningFilterDuplicates,ExtendedAdvertisingPduDuringLegacyScan)209 TEST_F(LeScanningFilterDuplicates, ExtendedAdvertisingPduDuringLegacyScan) {
210 StopScan();
211 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeExtendedAdvertisingPdu()));
212
213 StartScan(FilterDuplicates::DISABLED);
214 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeExtendedAdvertisingPdu()));
215 }
216
TEST_F(LeScanningFilterDuplicates,ExtendedAdvertisingPduDuringExtendedScan)217 TEST_F(LeScanningFilterDuplicates, ExtendedAdvertisingPduDuringExtendedScan) {
218 StopExtendedScan();
219 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeExtendedAdvertisingPdu()));
220
221 StartExtendedScan(FilterDuplicates::DISABLED);
222 ASSERT_EQ(kReported, SendPacketAndCheck(LeExtendedAdvertisingPdu()));
223 ASSERT_EQ(kReported, SendPacketAndCheck(LeExtendedAdvertisingPdu()));
224
225 StopExtendedScan();
226 StartExtendedScan(FilterDuplicates::ENABLED);
227 ASSERT_EQ(kReported, SendPacketAndCheck(LeExtendedAdvertisingPdu()));
228 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeExtendedAdvertisingPdu()));
229 ASSERT_EQ(kReported, SendPacketAndCheck(LeExtendedAdvertisingPdu({0})));
230 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeExtendedAdvertisingPdu({0})));
231 ASSERT_EQ(kReported, SendPacketAndCheck(LeExtendedAdvertisingPdu({0, 1})));
232 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeExtendedAdvertisingPdu({0, 1})));
233 }
234
TEST_F(LeScanningFilterDuplicates,LeScanResponseToLegacyAdvertisingDuringLegacyScan)235 TEST_F(LeScanningFilterDuplicates,
236 LeScanResponseToLegacyAdvertisingDuringLegacyScan) {
237 StopScan();
238 SendPacket(LeLegacyAdvertisingPdu());
239 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeScanResponse()));
240
241 StartScan(FilterDuplicates::DISABLED);
242 SendPacket(LeLegacyAdvertisingPdu());
243 ASSERT_EQ(kReported, SendPacketAndCheck(LeScanResponse()));
244 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeScanResponse()));
245 SendPacket(LeLegacyAdvertisingPdu());
246 ASSERT_EQ(kReported, SendPacketAndCheck(LeScanResponse()));
247 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeScanResponse()));
248
249 StopScan();
250 StartScan(FilterDuplicates::ENABLED);
251 SendPacket(LeLegacyAdvertisingPdu());
252 ASSERT_EQ(kReported, SendPacketAndCheck(LeScanResponse()));
253 SendPacket(LeLegacyAdvertisingPdu()); // Duplicate
254 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeScanResponse()));
255 SendPacket(LeLegacyAdvertisingPdu({0}));
256 ASSERT_EQ(kReported, SendPacketAndCheck(LeScanResponse({0})));
257 SendPacket(LeLegacyAdvertisingPdu({0})); // Duplicate
258 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeScanResponse({0})));
259 SendPacket(LeLegacyAdvertisingPdu({0, 1}));
260 ASSERT_EQ(kReported, SendPacketAndCheck(LeScanResponse({0, 1})));
261 SendPacket(LeLegacyAdvertisingPdu({0, 1})); // Duplicate
262 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeScanResponse({0, 1})));
263 }
264
TEST_F(LeScanningFilterDuplicates,LeScanResponseToLegacyAdvertisingDuringExtendedScan)265 TEST_F(LeScanningFilterDuplicates,
266 LeScanResponseToLegacyAdvertisingDuringExtendedScan) {
267 StopExtendedScan();
268 SendPacket(LeLegacyAdvertisingPdu());
269 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeScanResponse()));
270
271 StartExtendedScan(FilterDuplicates::DISABLED);
272 SendPacket(LeLegacyAdvertisingPdu());
273 ASSERT_EQ(kReported, SendPacketAndCheck(LeScanResponse()));
274 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeScanResponse()));
275 SendPacket(LeLegacyAdvertisingPdu());
276 ASSERT_EQ(kReported, SendPacketAndCheck(LeScanResponse()));
277 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeScanResponse()));
278
279 StopExtendedScan();
280 StartExtendedScan(FilterDuplicates::ENABLED);
281 SendPacket(LeLegacyAdvertisingPdu());
282 ASSERT_EQ(kReported, SendPacketAndCheck(LeScanResponse()));
283 SendPacket(LeLegacyAdvertisingPdu()); // Duplicate
284 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeScanResponse()));
285 SendPacket(LeLegacyAdvertisingPdu({0}));
286 ASSERT_EQ(kReported, SendPacketAndCheck(LeScanResponse({0})));
287 SendPacket(LeLegacyAdvertisingPdu({0})); // Duplicate
288 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeScanResponse({0})));
289 SendPacket(LeLegacyAdvertisingPdu({0, 1}));
290 ASSERT_EQ(kReported, SendPacketAndCheck(LeScanResponse({0, 1})));
291 SendPacket(LeLegacyAdvertisingPdu({0, 1})); // Duplicate
292 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeScanResponse({0, 1})));
293 }
294
TEST_F(LeScanningFilterDuplicates,LeScanResponseToExtendedAdvertisingDuringLegacyScan)295 TEST_F(LeScanningFilterDuplicates,
296 LeScanResponseToExtendedAdvertisingDuringLegacyScan) {
297 StopScan();
298 SendPacket(LeExtendedAdvertisingPdu());
299 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeScanResponse()));
300
301 StartScan(FilterDuplicates::DISABLED);
302 SendPacket(LeExtendedAdvertisingPdu());
303 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeScanResponse()));
304 SendPacket(LeExtendedAdvertisingPdu());
305 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeScanResponse()));
306 }
307
TEST_F(LeScanningFilterDuplicates,LeScanResponseToExtendedAdvertisingDuringExtendedScan)308 TEST_F(LeScanningFilterDuplicates,
309 LeScanResponseToExtendedAdvertisingDuringExtendedScan) {
310 StopExtendedScan();
311 SendPacket(LeExtendedAdvertisingPdu());
312 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeScanResponse()));
313
314 StartExtendedScan(FilterDuplicates::DISABLED);
315 SendPacket(LeExtendedAdvertisingPdu());
316 ASSERT_EQ(kReported, SendPacketAndCheck(LeScanResponse()));
317 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeScanResponse()));
318 SendPacket(LeExtendedAdvertisingPdu());
319 ASSERT_EQ(kReported, SendPacketAndCheck(LeScanResponse()));
320 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeScanResponse()));
321
322 StopExtendedScan();
323 StartExtendedScan(FilterDuplicates::ENABLED);
324 SendPacket(LeExtendedAdvertisingPdu());
325 ASSERT_EQ(kReported, SendPacketAndCheck(LeScanResponse()));
326 SendPacket(LeExtendedAdvertisingPdu()); // Duplicate
327 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeScanResponse()));
328 SendPacket(LeExtendedAdvertisingPdu({0}));
329 ASSERT_EQ(kReported, SendPacketAndCheck(LeScanResponse({0})));
330 SendPacket(LeExtendedAdvertisingPdu({0})); // Duplicate
331 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeScanResponse({0})));
332 SendPacket(LeExtendedAdvertisingPdu({0, 1}));
333 ASSERT_EQ(kReported, SendPacketAndCheck(LeScanResponse({0, 1})));
334 SendPacket(LeExtendedAdvertisingPdu({0, 1})); // Duplicate
335 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeScanResponse({0, 1})));
336 }
337
TEST_F(LeScanningFilterDuplicates,HistoryClearedBetweenLegacyScans)338 TEST_F(LeScanningFilterDuplicates, HistoryClearedBetweenLegacyScans) {
339 StopScan();
340 StartScan(FilterDuplicates::ENABLED);
341 ASSERT_EQ(kReported, SendPacketAndCheck(LeLegacyAdvertisingPdu()));
342 ASSERT_EQ(kReported, SendPacketAndCheck(LeScanResponse()));
343 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeLegacyAdvertisingPdu()));
344 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeScanResponse()));
345
346 StopScan();
347 StartScan(FilterDuplicates::ENABLED);
348 ASSERT_EQ(kReported, SendPacketAndCheck(LeLegacyAdvertisingPdu()));
349 ASSERT_EQ(kReported, SendPacketAndCheck(LeScanResponse()));
350 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeLegacyAdvertisingPdu()));
351 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeScanResponse()));
352 }
353
TEST_F(LeScanningFilterDuplicates,HistoryClearedBetweenExtendedScans)354 TEST_F(LeScanningFilterDuplicates, HistoryClearedBetweenExtendedScans) {
355 StopExtendedScan();
356 StartExtendedScan(FilterDuplicates::ENABLED);
357 ASSERT_EQ(kReported, SendPacketAndCheck(LeLegacyAdvertisingPdu()));
358 ASSERT_EQ(kReported, SendPacketAndCheck(LeScanResponse()));
359 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeLegacyAdvertisingPdu()));
360 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeScanResponse()));
361 ASSERT_EQ(kReported, SendPacketAndCheck(LeExtendedAdvertisingPdu()));
362 ASSERT_EQ(kReported, SendPacketAndCheck(LeScanResponse({0})));
363 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeExtendedAdvertisingPdu()));
364 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeScanResponse({0})));
365
366 StopExtendedScan();
367 StartExtendedScan(FilterDuplicates::ENABLED);
368 ASSERT_EQ(kReported, SendPacketAndCheck(LeLegacyAdvertisingPdu()));
369 ASSERT_EQ(kReported, SendPacketAndCheck(LeScanResponse()));
370 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeLegacyAdvertisingPdu()));
371 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeScanResponse()));
372 ASSERT_EQ(kReported, SendPacketAndCheck(LeExtendedAdvertisingPdu()));
373 ASSERT_EQ(kReported, SendPacketAndCheck(LeScanResponse({0})));
374 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeExtendedAdvertisingPdu()));
375 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeScanResponse({0})));
376 }
377
TEST_F(LeScanningFilterDuplicates,ResetHistoryAfterEachPeriod)378 TEST_F(LeScanningFilterDuplicates, ResetHistoryAfterEachPeriod) {
379 StopExtendedScan();
380 // Minimal period is 1.28 seconds
381 StartExtendedScan(FilterDuplicates::RESET_EACH_PERIOD, 100, 1);
382 ASSERT_EQ(kReported, SendPacketAndCheck(LeExtendedAdvertisingPdu()));
383 ASSERT_EQ(kReported, SendPacketAndCheck(LeScanResponse({0})));
384 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeExtendedAdvertisingPdu()));
385 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeScanResponse({0})));
386
387 std::this_thread::sleep_for(std::chrono::milliseconds(1300));
388 controller_.Tick();
389
390 ASSERT_EQ(kReported, SendPacketAndCheck(LeExtendedAdvertisingPdu()));
391 ASSERT_EQ(kReported, SendPacketAndCheck(LeScanResponse({0})));
392 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeExtendedAdvertisingPdu()));
393 ASSERT_EQ(kFiltered, SendPacketAndCheck(LeScanResponse({0})));
394 }
395 } // namespace rootcanal
396