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