• 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/fake_local_address_delegate.h"
16 #include "pw_bluetooth_sapphire/internal/host/hci/legacy_low_energy_scanner.h"
17 #include "pw_bluetooth_sapphire/internal/host/testing/controller_test.h"
18 #include "pw_bluetooth_sapphire/internal/host/testing/fake_controller.h"
19 #include "pw_bluetooth_sapphire/internal/host/testing/fake_peer.h"
20 
21 // LowEnergyScanner has many potential subclasses (e.g. LegacyLowEnergyScanner,
22 // ExtendedLowEnergyScanner, etc). The unique features of these subclasses are
23 // tested individually in their own unittest files. However, there are some
24 // common features that all LowEnergyScanners should follow. This test file
25 // implements a type parameterized test to exercise those common features.
26 //
27 // If you add a new subclass of LowEnergyScanner in the future, make sure to add
28 // its type to the list of types below (in the TYPED_TEST_SUITE) so that its
29 // common features are exercised as well.
30 
31 namespace bt::hci {
32 
33 using bt::testing::FakeController;
34 using bt::testing::FakePeer;
35 using TestingBase = bt::testing::FakeDispatcherControllerTest<FakeController>;
36 
37 constexpr pw::chrono::SystemClock::duration kScanPeriod =
38     std::chrono::seconds(10);
39 constexpr pw::chrono::SystemClock::duration kPwScanPeriod =
40     std::chrono::seconds(10);
41 constexpr pw::chrono::SystemClock::duration kScanResponseTimeout =
42     std::chrono::seconds(2);
43 constexpr pw::chrono::SystemClock::duration kPwScanResponseTimeout =
44     std::chrono::seconds(2);
45 
46 // The unit tests below assume that the scan period is longer than the scan
47 // response timeout when exercising timeout expiration.
48 static_assert(kScanResponseTimeout < kScanPeriod,
49               "expected a smaller scan response timeout for testing");
50 
51 const StaticByteBuffer kPlainAdvDataBytes('T', 'e', 's', 't');
52 const StaticByteBuffer kPlainScanRspBytes('D', 'a', 't', 'a');
53 
54 constexpr char kPlainAdvData[] = "Test";
55 constexpr char kPlainScanRsp[] = "Data";
56 constexpr char kAdvDataAndScanRsp[] = "TestData";
57 
58 const DeviceAddress kPublicAddress1(DeviceAddress::Type::kLEPublic, {1});
59 const DeviceAddress kPublicAddress2(DeviceAddress::Type::kLEPublic, {2});
60 
61 const DeviceAddress kRandomAddress1(DeviceAddress::Type::kLERandom, {3});
62 const DeviceAddress kRandomAddress2(DeviceAddress::Type::kLERandom, {4});
63 const DeviceAddress kRandomAddress3(DeviceAddress::Type::kLERandom, {5});
64 const DeviceAddress kRandomAddress4(DeviceAddress::Type::kLERandom, {6});
65 
66 template <typename T>
67 class LowEnergyScannerTest : public TestingBase,
68                              public LowEnergyScanner::Delegate {
69  public:
70   LowEnergyScannerTest() = default;
71   ~LowEnergyScannerTest() override = default;
72 
73  protected:
SetUp()74   void SetUp() override {
75     TestingBase::SetUp();
76 
77     FakeController::Settings settings;
78     settings.ApplyLegacyLEConfig();
79     this->test_device()->set_settings(settings);
80 
81     scanner_ = std::unique_ptr<T>(CreateScannerInternal());
82     scanner_->set_delegate(this);
83   }
84 
TearDown()85   void TearDown() override {
86     scanner_ = nullptr;
87     this->test_device()->Stop();
88     TestingBase::TearDown();
89   }
90 
91   template <bool same = std::is_same_v<T, LegacyLowEnergyScanner>>
CreateScannerInternal()92   std::enable_if_t<same, LegacyLowEnergyScanner>* CreateScannerInternal() {
93     return new LegacyLowEnergyScanner(
94         fake_address_delegate(), transport()->GetWeakPtr(), dispatcher());
95   }
96 
97   using PeerFoundCallback =
98       fit::function<void(const LowEnergyScanResult&, const ByteBuffer&)>;
set_peer_found_callback(PeerFoundCallback cb)99   void set_peer_found_callback(PeerFoundCallback cb) {
100     peer_found_cb_ = std::move(cb);
101   }
102 
103   using DirectedAdvCallback = fit::function<void(const LowEnergyScanResult&)>;
set_directed_adv_callback(DirectedAdvCallback cb)104   void set_directed_adv_callback(DirectedAdvCallback cb) {
105     directed_adv_cb_ = std::move(cb);
106   }
107 
StartScan(bool active,pw::chrono::SystemClock::duration period=LowEnergyScanner::kPeriodInfinite)108   bool StartScan(bool active,
109                  pw::chrono::SystemClock::duration period =
110                      LowEnergyScanner::kPeriodInfinite) {
111     LowEnergyScanner::ScanOptions options{
112         .active = active,
113         .filter_duplicates = true,
114         .period = period,
115         .scan_response_timeout = kPwScanResponseTimeout};
116     return scanner()->StartScan(
117         options, [this](auto status) { last_scan_status_ = status; });
118   }
119 
120   // LowEnergyScanner::Observer override:
OnPeerFound(const LowEnergyScanResult & result,const ByteBuffer & data)121   void OnPeerFound(const LowEnergyScanResult& result,
122                    const ByteBuffer& data) override {
123     if (peer_found_cb_) {
124       peer_found_cb_(result, data);
125     }
126   }
127 
128   // LowEnergyScanner::Observer override:
OnDirectedAdvertisement(const LowEnergyScanResult & result)129   void OnDirectedAdvertisement(const LowEnergyScanResult& result) override {
130     if (directed_adv_cb_) {
131       directed_adv_cb_(result);
132     }
133   }
134 
135   // Adds 6 fake peers using kAddress[0-5] above.
AddFakePeers()136   void AddFakePeers() {
137     // Generates ADV_IND, scan response is reported in a single HCI event.
138     auto fake_peer =
139         std::make_unique<FakePeer>(kPublicAddress1, dispatcher(), true, true);
140     fake_peer->set_advertising_data(kPlainAdvDataBytes);
141     fake_peer->set_scan_response(/*should_batch_reports=*/true,
142                                  kPlainScanRspBytes);
143     test_device()->AddPeer(std::move(fake_peer));
144 
145     // Generates ADV_SCAN_IND, scan response is reported over multiple HCI
146     // events.
147     fake_peer =
148         std::make_unique<FakePeer>(kRandomAddress1, dispatcher(), false, true);
149     fake_peer->set_advertising_data(kPlainAdvDataBytes);
150     fake_peer->set_scan_response(/*should_batch_reports=*/false,
151                                  kPlainScanRspBytes);
152     test_device()->AddPeer(std::move(fake_peer));
153 
154     // Generates ADV_IND, empty scan response is reported over multiple HCI
155     // events.
156     fake_peer =
157         std::make_unique<FakePeer>(kPublicAddress2, dispatcher(), true, true);
158     fake_peer->set_advertising_data(kPlainAdvDataBytes);
159     fake_peer->set_scan_response(/*should_batch_reports=*/false,
160                                  DynamicByteBuffer());
161     test_device()->AddPeer(std::move(fake_peer));
162 
163     // Generates ADV_IND, empty adv data and non-empty scan response is reported
164     // over multiple HCI events.
165     fake_peer =
166         std::make_unique<FakePeer>(kRandomAddress2, dispatcher(), true, true);
167     fake_peer->set_scan_response(/*should_batch_reports=*/false,
168                                  kPlainScanRspBytes);
169     test_device()->AddPeer(std::move(fake_peer));
170 
171     // Generates ADV_IND, a scan response is never sent even though ADV_IND is
172     // scannable.
173     fake_peer =
174         std::make_unique<FakePeer>(kRandomAddress3, dispatcher(), true, false);
175     fake_peer->set_advertising_data(kPlainAdvDataBytes);
176     test_device()->AddPeer(std::move(fake_peer));
177 
178     // Generates ADV_NONCONN_IND
179     fake_peer =
180         std::make_unique<FakePeer>(kRandomAddress4, dispatcher(), false, false);
181     fake_peer->set_advertising_data(kPlainAdvDataBytes);
182     test_device()->AddPeer(std::move(fake_peer));
183   }
184 
scanner() const185   LowEnergyScanner* scanner() const { return scanner_.get(); }
fake_address_delegate()186   FakeLocalAddressDelegate* fake_address_delegate() {
187     return &fake_address_delegate_;
188   }
189 
last_scan_status() const190   LowEnergyScanner::ScanStatus last_scan_status() const {
191     return last_scan_status_;
192   }
193 
194  private:
195   PeerFoundCallback peer_found_cb_;
196   DirectedAdvCallback directed_adv_cb_;
197   FakeLocalAddressDelegate fake_address_delegate_{dispatcher()};
198   std::unique_ptr<LowEnergyScanner> scanner_;
199 
200   LowEnergyScanner::ScanStatus last_scan_status_;
201 
202   BT_DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(LowEnergyScannerTest);
203 };
204 
205 using Implementations = ::testing::Types<LegacyLowEnergyScanner>;
206 TYPED_TEST_SUITE(LowEnergyScannerTest, Implementations);
207 
TYPED_TEST(LowEnergyScannerTest,StartScanHCIErrors)208 TYPED_TEST(LowEnergyScannerTest, StartScanHCIErrors) {
209   EXPECT_TRUE(this->scanner()->IsIdle());
210   EXPECT_FALSE(this->scanner()->IsScanning());
211   EXPECT_FALSE(this->test_device()->le_scan_state().enabled);
212 
213   // Set Scan Parameters will fail.
214   this->test_device()->SetDefaultResponseStatus(
215       hci_spec::kLESetScanParameters,
216       pw::bluetooth::emboss::StatusCode::HARDWARE_FAILURE);
217   EXPECT_EQ(0, this->test_device()->le_scan_state().scan_interval);
218 
219   EXPECT_TRUE(this->StartScan(false));
220   EXPECT_EQ(LowEnergyScanner::State::kInitiating, this->scanner()->state());
221 
222   // Calling StartScan() should fail as the state is not kIdle.
223   EXPECT_FALSE(this->StartScan(false));
224   this->RunUntilIdle();
225 
226   // Status should be failure and the scan parameters shouldn't have applied.
227   EXPECT_EQ(LowEnergyScanner::ScanStatus::kFailed, this->last_scan_status());
228   EXPECT_EQ(0, this->test_device()->le_scan_state().scan_interval);
229   EXPECT_FALSE(this->test_device()->le_scan_state().enabled);
230   EXPECT_TRUE(this->scanner()->IsIdle());
231   EXPECT_FALSE(this->scanner()->IsScanning());
232 
233   // Set Scan Parameters will succeed but Set Scan Enable will fail.
234   this->test_device()->ClearDefaultResponseStatus(
235       hci_spec::kLESetScanParameters);
236   this->test_device()->SetDefaultResponseStatus(
237       hci_spec::kLESetScanEnable,
238       pw::bluetooth::emboss::StatusCode::HARDWARE_FAILURE);
239 
240   EXPECT_TRUE(this->StartScan(false));
241   EXPECT_EQ(LowEnergyScanner::State::kInitiating, this->scanner()->state());
242   this->RunUntilIdle();
243 
244   // Status should be failure but the scan parameters should have applied.
245   EXPECT_EQ(LowEnergyScanner::ScanStatus::kFailed, this->last_scan_status());
246   EXPECT_EQ(hci_spec::defaults::kLEScanInterval,
247             this->test_device()->le_scan_state().scan_interval);
248   EXPECT_EQ(hci_spec::defaults::kLEScanWindow,
249             this->test_device()->le_scan_state().scan_window);
250   EXPECT_EQ(pw::bluetooth::emboss::LEScanFilterPolicy::BASIC_UNFILTERED,
251             this->test_device()->le_scan_state().filter_policy);
252   EXPECT_FALSE(this->test_device()->le_scan_state().enabled);
253   EXPECT_TRUE(this->scanner()->IsIdle());
254   EXPECT_FALSE(this->scanner()->IsScanning());
255 }
256 
TYPED_TEST(LowEnergyScannerTest,StartScan)257 TYPED_TEST(LowEnergyScannerTest, StartScan) {
258   EXPECT_TRUE(this->scanner()->IsIdle());
259   EXPECT_FALSE(this->scanner()->IsScanning());
260   EXPECT_FALSE(this->test_device()->le_scan_state().enabled);
261 
262   EXPECT_TRUE(this->StartScan(true, kPwScanPeriod));
263   EXPECT_EQ(LowEnergyScanner::State::kInitiating, this->scanner()->state());
264   this->RunUntilIdle();
265 
266   // Scan should have started.
267   EXPECT_EQ(LowEnergyScanner::ScanStatus::kActive, this->last_scan_status());
268   EXPECT_EQ(hci_spec::defaults::kLEScanInterval,
269             this->test_device()->le_scan_state().scan_interval);
270   EXPECT_EQ(hci_spec::defaults::kLEScanWindow,
271             this->test_device()->le_scan_state().scan_window);
272   EXPECT_EQ(pw::bluetooth::emboss::LEScanFilterPolicy::BASIC_UNFILTERED,
273             this->test_device()->le_scan_state().filter_policy);
274   EXPECT_EQ(pw::bluetooth::emboss::LEScanType::ACTIVE,
275             this->test_device()->le_scan_state().scan_type);
276   EXPECT_TRUE(this->test_device()->le_scan_state().filter_duplicates);
277   EXPECT_TRUE(this->test_device()->le_scan_state().enabled);
278   EXPECT_EQ(LowEnergyScanner::State::kActiveScanning, this->scanner()->state());
279   EXPECT_TRUE(this->scanner()->IsScanning());
280 
281   // Calling StartScan should fail as a scan is already in progress.
282   EXPECT_FALSE(this->StartScan(true));
283 
284   // After 10 s (kScanPeriod) the scan should stop by itself.
285   this->RunFor(kScanPeriod);
286 
287   EXPECT_EQ(LowEnergyScanner::ScanStatus::kComplete, this->last_scan_status());
288   EXPECT_FALSE(this->test_device()->le_scan_state().enabled);
289   EXPECT_TRUE(this->scanner()->IsIdle());
290   EXPECT_FALSE(this->scanner()->IsScanning());
291 }
292 
TYPED_TEST(LowEnergyScannerTest,StopScan)293 TYPED_TEST(LowEnergyScannerTest, StopScan) {
294   EXPECT_TRUE(this->scanner()->IsIdle());
295   EXPECT_FALSE(this->scanner()->IsScanning());
296   EXPECT_FALSE(this->test_device()->le_scan_state().enabled);
297 
298   // Calling StopScan should fail while a scan is not in progress.
299   EXPECT_FALSE(this->scanner()->StopScan());
300 
301   // Pass a long scan period value. This should not matter as we will terminate
302   // the scan directly.
303   EXPECT_TRUE(this->StartScan(true, kPwScanPeriod * 10u));
304   EXPECT_EQ(LowEnergyScanner::State::kInitiating, this->scanner()->state());
305   this->RunUntilIdle();
306 
307   // Scan should have started.
308   EXPECT_EQ(LowEnergyScanner::ScanStatus::kActive, this->last_scan_status());
309   EXPECT_TRUE(this->test_device()->le_scan_state().enabled);
310   EXPECT_EQ(LowEnergyScanner::State::kActiveScanning, this->scanner()->state());
311   EXPECT_TRUE(this->scanner()->IsScanning());
312 
313   // StopScan() should terminate the scan session and the status should be
314   // kStopped.
315   EXPECT_TRUE(this->scanner()->StopScan());
316   this->RunUntilIdle();
317 
318   EXPECT_EQ(LowEnergyScanner::ScanStatus::kStopped, this->last_scan_status());
319   EXPECT_FALSE(this->test_device()->le_scan_state().enabled);
320   EXPECT_TRUE(this->scanner()->IsIdle());
321   EXPECT_FALSE(this->scanner()->IsScanning());
322 }
323 
TYPED_TEST(LowEnergyScannerTest,StopScanWhileInitiating)324 TYPED_TEST(LowEnergyScannerTest, StopScanWhileInitiating) {
325   EXPECT_TRUE(this->scanner()->IsIdle());
326   EXPECT_FALSE(this->scanner()->IsScanning());
327   EXPECT_FALSE(this->test_device()->le_scan_state().enabled);
328 
329   EXPECT_TRUE(this->StartScan(true));
330   EXPECT_EQ(LowEnergyScanner::State::kInitiating, this->scanner()->state());
331 
332   // Call StopScan(). This should cancel the HCI command sequence set up by
333   // StartScan() so that the it never completes. The HCI_LE_Set_Scan_Parameters
334   // command *may* get sent but the scan should never get enabled.
335   EXPECT_TRUE(this->scanner()->StopScan());
336   this->RunUntilIdle();
337 
338   EXPECT_EQ(LowEnergyScanner::ScanStatus::kStopped, this->last_scan_status());
339   EXPECT_FALSE(this->test_device()->le_scan_state().enabled);
340   EXPECT_TRUE(this->scanner()->IsIdle());
341   EXPECT_FALSE(this->scanner()->IsScanning());
342 }
343 
TYPED_TEST(LowEnergyScannerTest,ScanResponseTimeout)344 TYPED_TEST(LowEnergyScannerTest, ScanResponseTimeout) {
345   constexpr pw::chrono::SystemClock::duration kHalfTimeout =
346       kScanResponseTimeout / 2;
347 
348   std::unordered_set<DeviceAddress> results;
349   this->set_peer_found_callback([&](const auto& result, const auto& data) {
350     results.insert(result.address);
351   });
352 
353   // Add a peer that sends a scan response and one that doesn't.
354   auto fake_peer = std::make_unique<FakePeer>(
355       kRandomAddress1, this->dispatcher(), false, true);
356   fake_peer->set_advertising_data(kPlainAdvDataBytes);
357   fake_peer->set_scan_response(/*should_batch_reports=*/false,
358                                kPlainScanRspBytes);
359   this->test_device()->AddPeer(std::move(fake_peer));
360 
361   fake_peer = std::make_unique<FakePeer>(
362       kRandomAddress2, this->dispatcher(), true, false);
363   fake_peer->set_advertising_data(kPlainAdvDataBytes);
364   this->test_device()->AddPeer(std::move(fake_peer));
365 
366   EXPECT_TRUE(this->StartScan(true));
367   this->RunUntilIdle();
368   ASSERT_EQ(1u, results.size());
369   EXPECT_EQ(1u, results.count(kRandomAddress1));
370 
371   // Advance the time but do not expire the timeout.
372   this->RunFor(kHalfTimeout);
373   ASSERT_EQ(1u, results.size());
374 
375   // Add another peer that doesn't send a scan response after the kHalfTimeout
376   // delay. This is to test that a separate timeout is kept for every peer.
377   fake_peer = std::make_unique<FakePeer>(
378       kRandomAddress3, this->dispatcher(), true, false);
379   fake_peer->set_advertising_data(kPlainAdvDataBytes);
380   this->test_device()->AddPeer(std::move(fake_peer));
381 
382   // Expire the first timeout.
383   this->RunFor(kHalfTimeout);
384   ASSERT_EQ(2u, results.size());
385   EXPECT_EQ(1u, results.count(kRandomAddress1));
386   EXPECT_EQ(1u, results.count(kRandomAddress2));
387 
388   // Expire the second timeout.
389   this->RunFor(kHalfTimeout);
390   ASSERT_EQ(3u, results.size());
391   EXPECT_EQ(1u, results.count(kRandomAddress1));
392   EXPECT_EQ(1u, results.count(kRandomAddress2));
393   EXPECT_EQ(1u, results.count(kRandomAddress3));
394 }
395 
TYPED_TEST(LowEnergyScannerTest,ActiveScanResults)396 TYPED_TEST(LowEnergyScannerTest, ActiveScanResults) {
397   // One of the 6 fake peers is scannable but never sends scan response
398   // packets. That peer doesn't get reported until the end of the scan period.
399   constexpr size_t kExpectedResultCount = 5u;
400 
401   this->AddFakePeers();
402 
403   std::map<DeviceAddress, std::pair<LowEnergyScanResult, std::string>> results;
404   this->set_peer_found_callback([&](const auto& result, const auto& data) {
405     results[result.address] = std::make_pair(result, data.ToString());
406   });
407 
408   // Perform an active scan.
409   EXPECT_TRUE(this->StartScan(true, kPwScanPeriod));
410   EXPECT_EQ(LowEnergyScanner::State::kInitiating, this->scanner()->state());
411 
412   this->RunUntilIdle();
413 
414   ASSERT_EQ(kExpectedResultCount, results.size());
415 
416   // Ending the scan period should notify Fake Peer #4.
417   this->RunFor(kScanPeriod);
418   EXPECT_EQ(LowEnergyScanner::ScanStatus::kComplete, this->last_scan_status());
419   ASSERT_EQ(kExpectedResultCount + 1, results.size());
420 
421   // Verify the 6 results against the fake peers that were set up by
422   // this->AddFakePeers(). Since the scan period ended naturally,
423   // LowEnergyScanner should generate a peer found event for all pending reports
424   // even if a scan response was not received for a scannable peer (see Fake
425   // Peer 4, i.e. kRandomAddress3).
426 
427   // Result 0 (ADV_IND)
428   {
429     const auto& iter = results.find(kPublicAddress1);
430     ASSERT_NE(iter, results.end());
431 
432     const auto& result_pair = iter->second;
433     EXPECT_EQ(kAdvDataAndScanRsp, result_pair.second);
434     EXPECT_EQ(kPublicAddress1, result_pair.first.address);
435     EXPECT_TRUE(result_pair.first.connectable);
436     results.erase(iter);
437   }
438 
439   // Result 1 (ADV_SCAN_IND)
440   {
441     const auto& iter = results.find(kRandomAddress1);
442     ASSERT_NE(iter, results.end());
443 
444     const auto& result_pair = iter->second;
445     EXPECT_EQ(kAdvDataAndScanRsp, result_pair.second);
446     EXPECT_EQ(kRandomAddress1, result_pair.first.address);
447     EXPECT_FALSE(result_pair.first.connectable);
448     results.erase(iter);
449   }
450 
451   // Result 2 (ADV_IND), empty scan response
452   {
453     const auto& iter = results.find(kPublicAddress2);
454     ASSERT_NE(iter, results.end());
455 
456     const auto& result_pair = iter->second;
457     EXPECT_EQ(kPlainAdvData, result_pair.second);
458     EXPECT_EQ(kPublicAddress2, result_pair.first.address);
459     EXPECT_TRUE(result_pair.first.connectable);
460     results.erase(iter);
461   }
462 
463   // Result 3 (ADV_IND), empty advertising data w/ scan response
464   {
465     const auto& iter = results.find(kRandomAddress2);
466     ASSERT_NE(iter, results.end());
467 
468     const auto& result_pair = iter->second;
469     EXPECT_EQ(kPlainScanRsp, result_pair.second);
470     EXPECT_EQ(kRandomAddress2, result_pair.first.address);
471     EXPECT_TRUE(result_pair.first.connectable);
472     results.erase(iter);
473   }
474 
475   // Result 4 (ADV_IND), no scan response
476   {
477     const auto& iter = results.find(kRandomAddress3);
478     ASSERT_NE(iter, results.end());
479 
480     const auto& result_pair = iter->second;
481     EXPECT_EQ(kPlainAdvData, result_pair.second);
482     EXPECT_EQ(kRandomAddress3, result_pair.first.address);
483     EXPECT_TRUE(result_pair.first.connectable);
484     results.erase(iter);
485   }
486 
487   // Result 5 (ADV_NONCONN_IND)
488   {
489     const auto& iter = results.find(kRandomAddress4);
490     ASSERT_NE(iter, results.end());
491 
492     const auto& result_pair = iter->second;
493     EXPECT_EQ(kPlainAdvData, result_pair.second);
494     EXPECT_EQ(kRandomAddress4, result_pair.first.address);
495     EXPECT_FALSE(result_pair.first.connectable);
496     results.erase(iter);
497   }
498 
499   // No other reports are expected
500   EXPECT_TRUE(results.empty());
501 }
502 
TYPED_TEST(LowEnergyScannerTest,StopDuringActiveScan)503 TYPED_TEST(LowEnergyScannerTest, StopDuringActiveScan) {
504   this->AddFakePeers();
505 
506   std::map<DeviceAddress, std::pair<LowEnergyScanResult, std::string>> results;
507   this->set_peer_found_callback(
508       [&results](const auto& result, const auto& data) {
509         results[result.address] = std::make_pair(result, data.ToString());
510       });
511 
512   // Perform an active scan indefinitely. This means that the scan period will
513   // never complete by itself.
514   EXPECT_TRUE(this->StartScan(true));
515   EXPECT_EQ(LowEnergyScanner::State::kInitiating, this->scanner()->state());
516   this->RunUntilIdle();
517   EXPECT_EQ(LowEnergyScanner::State::kActiveScanning, this->scanner()->state());
518 
519   // Run the loop until we've seen an event for the last peer that we
520   // added. Fake Peer kRandomAddress3 is scannable but it never sends a scan
521   // response so we expect that to remain in the scanner's pending reports list.
522   this->RunUntilIdle();
523   EXPECT_EQ(5u, results.size());
524   EXPECT_EQ(results.find(kRandomAddress3), results.end());
525 
526   // Stop the scan. Since we are terminating the scan period early,
527   // LowEnergyScanner should not send a report for the pending peer.
528   EXPECT_TRUE(this->scanner()->StopScan());
529   this->RunUntilIdle();
530   EXPECT_TRUE(this->scanner()->IsIdle());
531 
532   EXPECT_EQ(5u, results.size());
533   EXPECT_EQ(results.find(kRandomAddress3), results.end());
534 }
535 
TYPED_TEST(LowEnergyScannerTest,PassiveScanResults)536 TYPED_TEST(LowEnergyScannerTest, PassiveScanResults) {
537   constexpr size_t kExpectedResultCount = 6u;
538   this->AddFakePeers();
539 
540   std::map<DeviceAddress, std::pair<LowEnergyScanResult, std::string>> results;
541   this->set_peer_found_callback([&](const auto& result, const auto& data) {
542     results[result.address] = std::make_pair(result, data.ToString());
543   });
544 
545   // Perform a passive scan.
546   EXPECT_TRUE(this->StartScan(false));
547 
548   EXPECT_EQ(LowEnergyScanner::State::kInitiating, this->scanner()->state());
549 
550   this->RunUntilIdle();
551   EXPECT_EQ(LowEnergyScanner::State::kPassiveScanning,
552             this->scanner()->state());
553   EXPECT_EQ(LowEnergyScanner::ScanStatus::kPassive, this->last_scan_status());
554   ASSERT_EQ(kExpectedResultCount, results.size());
555 
556   // Verify the 6 results against the fake peers that were set up by
557   // this->AddFakePeers(). All Scan Response PDUs should have been ignored.
558 
559   // Result 0
560   {
561     const auto& iter = results.find(kPublicAddress1);
562     ASSERT_NE(iter, results.end());
563 
564     const auto& result_pair = iter->second;
565     EXPECT_EQ(kPlainAdvData, result_pair.second);
566     EXPECT_EQ(kPublicAddress1, result_pair.first.address);
567     EXPECT_TRUE(result_pair.first.connectable);
568     results.erase(iter);
569   }
570 
571   // Result 1
572   {
573     const auto& iter = results.find(kRandomAddress1);
574     ASSERT_NE(iter, results.end());
575 
576     const auto& result_pair = iter->second;
577     EXPECT_EQ(kPlainAdvData, result_pair.second);
578     EXPECT_EQ(kRandomAddress1, result_pair.first.address);
579     EXPECT_FALSE(result_pair.first.connectable);
580     results.erase(iter);
581   }
582 
583   // Result 2
584   {
585     const auto& iter = results.find(kPublicAddress2);
586     ASSERT_NE(iter, results.end());
587 
588     const auto& result_pair = iter->second;
589     EXPECT_EQ(kPlainAdvData, result_pair.second);
590     EXPECT_EQ(kPublicAddress2, result_pair.first.address);
591     EXPECT_TRUE(result_pair.first.connectable);
592     results.erase(iter);
593   }
594 
595   // Result 3
596   {
597     const auto& iter = results.find(kRandomAddress2);
598     ASSERT_NE(iter, results.end());
599 
600     const auto& result_pair = iter->second;
601     EXPECT_EQ("", result_pair.second);
602     EXPECT_EQ(kRandomAddress2, result_pair.first.address);
603     EXPECT_TRUE(result_pair.first.connectable);
604     results.erase(iter);
605   }
606 
607   // Result 4
608   {
609     const auto& iter = results.find(kRandomAddress3);
610     ASSERT_NE(iter, results.end());
611 
612     const auto& result_pair = iter->second;
613     EXPECT_EQ(kPlainAdvData, result_pair.second);
614     EXPECT_EQ(kRandomAddress3, result_pair.first.address);
615     EXPECT_TRUE(result_pair.first.connectable);
616     results.erase(iter);
617   }
618 
619   // Result 5
620   {
621     const auto& iter = results.find(kRandomAddress4);
622     ASSERT_NE(iter, results.end());
623 
624     const auto& result_pair = iter->second;
625     EXPECT_EQ(kPlainAdvData, result_pair.second);
626     EXPECT_EQ(kRandomAddress4, result_pair.first.address);
627     EXPECT_FALSE(result_pair.first.connectable);
628     results.erase(iter);
629   }
630 
631   EXPECT_TRUE(results.empty());
632 }
633 
TYPED_TEST(LowEnergyScannerTest,DirectedReport)634 TYPED_TEST(LowEnergyScannerTest, DirectedReport) {
635   const auto& kPublicUnresolved = kPublicAddress1;
636   const auto& kPublicResolved = kPublicAddress2;
637   const auto& kRandomUnresolved = kRandomAddress1;
638   const auto& kRandomResolved = kRandomAddress2;
639   constexpr size_t kExpectedResultCount = 4u;
640 
641   // Unresolved public.
642   auto fake_peer = std::make_unique<FakePeer>(
643       kPublicUnresolved, this->dispatcher(), true, false);
644   fake_peer->set_directed_advertising_enabled(true);
645   this->test_device()->AddPeer(std::move(fake_peer));
646 
647   // Unresolved random.
648   fake_peer = std::make_unique<FakePeer>(
649       kRandomUnresolved, this->dispatcher(), true, false);
650   fake_peer->set_directed_advertising_enabled(true);
651   this->test_device()->AddPeer(std::move(fake_peer));
652 
653   // Resolved public.
654   fake_peer = std::make_unique<FakePeer>(
655       kPublicResolved, this->dispatcher(), true, false);
656   fake_peer->set_address_resolved(true);
657   fake_peer->set_directed_advertising_enabled(true);
658   this->test_device()->AddPeer(std::move(fake_peer));
659 
660   // Resolved random.
661   fake_peer = std::make_unique<FakePeer>(
662       kRandomResolved, this->dispatcher(), true, false);
663   fake_peer->set_address_resolved(true);
664   fake_peer->set_directed_advertising_enabled(true);
665   this->test_device()->AddPeer(std::move(fake_peer));
666 
667   std::unordered_map<DeviceAddress, LowEnergyScanResult> results;
668   this->set_directed_adv_callback(
669       [&](const auto& result) { results[result.address] = result; });
670 
671   EXPECT_TRUE(this->StartScan(true));
672   EXPECT_EQ(LowEnergyScanner::State::kInitiating, this->scanner()->state());
673 
674   this->RunUntilIdle();
675 
676   ASSERT_EQ(LowEnergyScanner::ScanStatus::kActive, this->last_scan_status());
677   ASSERT_EQ(kExpectedResultCount, results.size());
678 
679   ASSERT_TRUE(results.count(kPublicUnresolved));
680   EXPECT_FALSE(results[kPublicUnresolved].resolved);
681 
682   ASSERT_TRUE(results.count(kRandomUnresolved));
683   EXPECT_FALSE(results[kRandomUnresolved].resolved);
684 
685   ASSERT_TRUE(results.count(kPublicResolved));
686   EXPECT_TRUE(results[kPublicResolved].resolved);
687 
688   ASSERT_TRUE(results.count(kRandomResolved));
689   EXPECT_TRUE(results[kRandomResolved].resolved);
690 }
691 
TYPED_TEST(LowEnergyScannerTest,AllowsRandomAddressChange)692 TYPED_TEST(LowEnergyScannerTest, AllowsRandomAddressChange) {
693   EXPECT_TRUE(this->scanner()->AllowsRandomAddressChange());
694   EXPECT_TRUE(this->StartScan(false));
695 
696   // Address change should not be allowed while the procedure is pending.
697   EXPECT_TRUE(this->scanner()->IsInitiating());
698   EXPECT_FALSE(this->scanner()->AllowsRandomAddressChange());
699 
700   this->RunUntilIdle();
701   EXPECT_TRUE(this->scanner()->IsPassiveScanning());
702   EXPECT_FALSE(this->scanner()->AllowsRandomAddressChange());
703 }
704 
TYPED_TEST(LowEnergyScannerTest,AllowsRandomAddressChangeWhileRequestingLocalAddress)705 TYPED_TEST(LowEnergyScannerTest,
706            AllowsRandomAddressChangeWhileRequestingLocalAddress) {
707   // Make the local address delegate report its result asynchronously.
708   this->fake_address_delegate()->set_async(true);
709   EXPECT_TRUE(this->StartScan(false));
710 
711   // The scanner should be in the initiating state without initiating controller
712   // procedures that would prevent a local address change.
713   EXPECT_TRUE(this->scanner()->IsInitiating());
714   EXPECT_TRUE(this->scanner()->AllowsRandomAddressChange());
715 
716   this->RunUntilIdle();
717   EXPECT_TRUE(this->scanner()->IsPassiveScanning());
718   EXPECT_FALSE(this->scanner()->AllowsRandomAddressChange());
719 }
720 
TYPED_TEST(LowEnergyScannerTest,ScanUsingPublicAddress)721 TYPED_TEST(LowEnergyScannerTest, ScanUsingPublicAddress) {
722   this->fake_address_delegate()->set_local_address(kPublicAddress1);
723   EXPECT_TRUE(this->StartScan(false));
724   this->RunUntilIdle();
725   EXPECT_TRUE(this->scanner()->IsPassiveScanning());
726   EXPECT_EQ(pw::bluetooth::emboss::LEOwnAddressType::PUBLIC,
727             this->test_device()->le_scan_state().own_address_type);
728 }
729 
TYPED_TEST(LowEnergyScannerTest,ScanUsingRandomAddress)730 TYPED_TEST(LowEnergyScannerTest, ScanUsingRandomAddress) {
731   this->fake_address_delegate()->set_local_address(kRandomAddress1);
732   EXPECT_TRUE(this->StartScan(false));
733   this->RunUntilIdle();
734   EXPECT_TRUE(this->scanner()->IsPassiveScanning());
735   EXPECT_EQ(pw::bluetooth::emboss::LEOwnAddressType::RANDOM,
736             this->test_device()->le_scan_state().own_address_type);
737 }
738 
TYPED_TEST(LowEnergyScannerTest,StopScanWhileWaitingForLocalAddress)739 TYPED_TEST(LowEnergyScannerTest, StopScanWhileWaitingForLocalAddress) {
740   this->fake_address_delegate()->set_async(true);
741   EXPECT_TRUE(this->StartScan(false));
742 
743   // Should be waiting for the random address.
744   EXPECT_TRUE(this->scanner()->IsInitiating());
745   EXPECT_TRUE(this->scanner()->AllowsRandomAddressChange());
746 
747   EXPECT_TRUE(this->scanner()->StopScan());
748   this->RunUntilIdle();
749 
750   // Should end up not scanning.
751   EXPECT_TRUE(this->scanner()->IsIdle());
752   EXPECT_FALSE(this->test_device()->le_scan_state().enabled);
753 }
754 
755 }  // namespace bt::hci
756