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