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