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/gap/peer_cache.h"
16
17 #include <gmock/gmock.h>
18 #include <gtest/gtest.h>
19 #include <pw_async/fake_dispatcher_fixture.h>
20
21 #include <vector>
22
23 #include "pw_bluetooth_sapphire/internal/host/common/device_class.h"
24 #include "pw_bluetooth_sapphire/internal/host/common/random.h"
25 #include "pw_bluetooth_sapphire/internal/host/common/uint128.h"
26 #include "pw_bluetooth_sapphire/internal/host/common/uuid.h"
27 #include "pw_bluetooth_sapphire/internal/host/gap/peer.h"
28 #include "pw_bluetooth_sapphire/internal/host/hci-spec/link_key.h"
29 #include "pw_bluetooth_sapphire/internal/host/hci/low_energy_scanner.h"
30 #include "pw_bluetooth_sapphire/internal/host/sm/smp.h"
31 #include "pw_bluetooth_sapphire/internal/host/sm/types.h"
32 #include "pw_bluetooth_sapphire/internal/host/sm/util.h"
33 #include "pw_bluetooth_sapphire/internal/host/testing/inspect.h"
34 #include "pw_bluetooth_sapphire/internal/host/testing/test_helpers.h"
35
36 namespace bt::gap {
37 namespace {
38
39 using namespace inspect::testing;
40
41 // All fields are initialized to zero as they are unused in these tests.
42 const hci_spec::LEConnectionParameters kTestParams;
43
44 // Arbitrary ID value used by the bonding tests below. The actual value of this
45 // constant does not effect the test logic.
46 constexpr PeerId kId(100);
47 constexpr int8_t kTestRSSI = 10;
48
49 const DeviceAddress kAddrBrEdr(DeviceAddress::Type::kBREDR,
50 {0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA});
51 const DeviceAddress kAddrLePublic(DeviceAddress::Type::kLEPublic,
52 {6, 5, 4, 3, 2, 1});
53 // LE Public Device Address that has the same value as a BR/EDR BD_ADDR, e.g. on
54 // a dual-mode device.
55 const DeviceAddress kAddrLeAlias(DeviceAddress::Type::kLEPublic,
56 {0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA});
57
58 // TODO(armansito): Make these adhere to privacy specification.
59 const DeviceAddress kAddrLeRandom(DeviceAddress::Type::kLERandom,
60 {1, 2, 3, 4, 5, 6});
61 const DeviceAddress kAddrLeRandom2(DeviceAddress::Type::kLERandom,
62 {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF});
63 const DeviceAddress kAddrLeAnon(DeviceAddress::Type::kLEAnonymous,
64 {1, 2, 3, 4, 5, 6});
65
66 // Arbitrary name value used by the bonding tests below. The actual value of
67 // this constant does not effect the test logic.
68 const std::string kName = "TestName";
69
70 const StaticByteBuffer kAdvData(0x05, // Length
71 0x09, // AD type: Complete Local Name
72 'T',
73 'e',
74 's',
75 't');
76 const auto kEirData = kAdvData;
77
78 const bt::sm::LTK kLTK;
79 const bt::sm::Key kKey{};
80
81 const bt::sm::LTK kBrEdrKey;
82 const bt::sm::LTK kInsecureBrEdrKey(
83 sm::SecurityProperties(/*encrypted=*/true,
84 /*authenticated=*/false,
85 /*secure_connections=*/false,
86 sm::kMaxEncryptionKeySize),
87 hci_spec::LinkKey(UInt128{1}, 2, 3));
88 const bt::sm::LTK kSecureBrEdrKey(
89 sm::SecurityProperties(/*encrypted=*/true,
90 /*authenticated=*/true,
91 /*secure_connections=*/true,
92 sm::kMaxEncryptionKeySize),
93 hci_spec::LinkKey(UInt128{4}, 5, 6));
94
95 const std::vector<bt::UUID> kBrEdrServices = {UUID(uint16_t{0x110a}),
96 UUID(uint16_t{0x110b})};
97
98 // Phone (Networking)
99 const DeviceClass kTestDeviceClass({0x06, 0x02, 0x02});
100
101 class PeerCacheTest : public pw::async::test::FakeDispatcherFixture {
102 public:
SetUp()103 void SetUp() override { cache_ = std::make_unique<PeerCache>(dispatcher()); }
104
TearDown()105 void TearDown() override {
106 RunUntilIdle();
107 cache_.reset();
108 }
109
110 protected:
111 // Creates a new Peer, and caches a pointer to that peer.
NewPeer(const DeviceAddress & addr,bool connectable)112 [[nodiscard]] bool NewPeer(const DeviceAddress& addr, bool connectable) {
113 auto* peer = cache()->NewPeer(addr, connectable);
114 if (!peer) {
115 return false;
116 }
117 peer_ = peer;
118 return true;
119 }
120
cache()121 PeerCache* cache() { return cache_.get(); }
122 // Returns the cached pointer to the peer created in the most recent call to
123 // NewPeer(). The caller must ensure that the peer has not expired out of
124 // the cache. (Tests of cache expiration should generally subclass the
125 // PeerCacheExpirationTest fixture.)
peer()126 Peer* peer() { return peer_; }
127
128 private:
129 std::unique_ptr<PeerCache> cache_;
130 Peer* peer_;
131 };
132
133 #ifndef NINSPECT
TEST_F(PeerCacheTest,InspectHierarchyContainsMetrics)134 TEST_F(PeerCacheTest, InspectHierarchyContainsMetrics) {
135 inspect::Inspector inspector;
136 cache()->AttachInspect(inspector.GetRoot());
137
138 auto le_matcher = AllOf(NodeMatches(AllOf(
139 NameMatches("le"),
140 PropertyList(UnorderedElementsAre(UintIs("bond_success_events", 0),
141 UintIs("bond_failure_events", 0),
142 UintIs("connection_events", 0),
143 UintIs("disconnection_events", 0))))));
144 auto bredr_matcher = AllOf(NodeMatches(AllOf(
145 NameMatches("bredr"),
146 PropertyList(UnorderedElementsAre(UintIs("bond_success_events", 0),
147 UintIs("bond_failure_events", 0),
148 UintIs("connection_events", 0),
149 UintIs("disconnection_events", 0))))));
150
151 auto metrics_node_matcher =
152 AllOf(NodeMatches(NameMatches(PeerMetrics::kInspectNodeName)),
153 ChildrenMatch(UnorderedElementsAre(bredr_matcher, le_matcher)));
154
155 auto peer_cache_matcher =
156 AllOf(NodeMatches(AllOf(PropertyList(testing::IsEmpty()))),
157 ChildrenMatch(UnorderedElementsAre(metrics_node_matcher)));
158
159 auto hierarchy = inspect::ReadFromVmo(inspector.DuplicateVmo()).take_value();
160 EXPECT_THAT(hierarchy,
161 AllOf(ChildrenMatch(UnorderedElementsAre(peer_cache_matcher))));
162 }
163 #endif // NINSPECT
164
165 #ifndef NINSPECT
TEST_F(PeerCacheTest,InspectHierarchyContainsAddedPeersAndDoesNotContainRemovedPeers)166 TEST_F(PeerCacheTest,
167 InspectHierarchyContainsAddedPeersAndDoesNotContainRemovedPeers) {
168 inspect::Inspector inspector;
169 cache()->AttachInspect(inspector.GetRoot());
170
171 Peer* peer0 = cache()->NewPeer(kAddrLePublic, /*connectable=*/true);
172 auto peer0_matcher = AllOf(NodeMatches(AllOf(NameMatches("peer_0x0"))));
173
174 cache()->NewPeer(kAddrBrEdr, /*connectable=*/true);
175 auto peer1_matcher = AllOf(NodeMatches(AllOf(NameMatches("peer_0x1"))));
176
177 auto metrics_matcher =
178 AllOf(NodeMatches(AllOf(NameMatches(PeerMetrics::kInspectNodeName))));
179
180 // Hierarchy should contain peer0 and peer1.
181 auto hierarchy = inspect::ReadFromVmo(inspector.DuplicateVmo()).take_value();
182 auto peer_cache_matcher0 =
183 AllOf(NodeMatches(AllOf(PropertyList(testing::IsEmpty()))),
184 ChildrenMatch(UnorderedElementsAre(
185 peer0_matcher, peer1_matcher, metrics_matcher)));
186 EXPECT_THAT(hierarchy,
187 AllOf(ChildrenMatch(UnorderedElementsAre(peer_cache_matcher0))));
188
189 // peer0 should be removed from hierarchy after it is removed from the cache
190 // because its Node is destroyed along with the Peer object.
191 EXPECT_TRUE(cache()->RemoveDisconnectedPeer(peer0->identifier()));
192 hierarchy = inspect::ReadFromVmo(inspector.DuplicateVmo()).take_value();
193 auto peer_cache_matcher1 = AllOf(
194 NodeMatches(AllOf(PropertyList(testing::IsEmpty()))),
195 ChildrenMatch(UnorderedElementsAre(peer1_matcher, metrics_matcher)));
196 EXPECT_THAT(hierarchy,
197 AllOf(ChildrenMatch(UnorderedElementsAre(peer_cache_matcher1))));
198 }
199 #endif // NINSPECT
200
TEST_F(PeerCacheTest,LookUp)201 TEST_F(PeerCacheTest, LookUp) {
202 StaticByteBuffer kAdvData0(0x05, 0x09, 'T', 'e', 's', 't');
203 StaticByteBuffer kAdvData1(
204 0x0C, 0x09, 'T', 'e', 's', 't', ' ', 'D', 'e', 'v', 'i', 'c', 'e');
205
206 // These should return false regardless of the input while the cache is empty.
207 EXPECT_FALSE(cache()->FindByAddress(kAddrLePublic));
208 EXPECT_FALSE(cache()->FindById(kId));
209
210 auto peer = cache()->NewPeer(kAddrLePublic, /*connectable=*/true);
211 ASSERT_TRUE(peer);
212 ASSERT_TRUE(peer->le());
213 EXPECT_EQ(TechnologyType::kLowEnergy, peer->technology());
214 EXPECT_TRUE(peer->connectable());
215 EXPECT_TRUE(peer->temporary());
216 EXPECT_EQ(kAddrLePublic, peer->address());
217 EXPECT_FALSE(peer->le()->parsed_advertising_data().has_value());
218 EXPECT_EQ(hci_spec::kRSSIInvalid, peer->rssi());
219
220 // A look up should return the same instance.
221 EXPECT_EQ(peer, cache()->FindById(peer->identifier()));
222 EXPECT_EQ(peer, cache()->FindByAddress(peer->address()));
223
224 // Adding a peer with the same address should return nullptr.
225 EXPECT_FALSE(cache()->NewPeer(kAddrLePublic, true));
226
227 peer->MutLe().SetAdvertisingData(
228 kTestRSSI, kAdvData1, pw::chrono::SystemClock::time_point());
229 EXPECT_TRUE(peer->le()->parsed_advertising_data().has_value());
230 EXPECT_EQ(kTestRSSI, peer->rssi());
231 ASSERT_TRUE(peer->name().has_value());
232 EXPECT_EQ(peer->name().value(), "Test Device");
233
234 peer->MutLe().SetAdvertisingData(
235 kTestRSSI, kAdvData0, pw::chrono::SystemClock::time_point());
236 EXPECT_TRUE(peer->le()->parsed_advertising_data().has_value());
237 EXPECT_EQ(kTestRSSI, peer->rssi());
238 ASSERT_TRUE(peer->name().has_value());
239 EXPECT_EQ(peer->name().value(), "Test");
240 }
241
TEST_F(PeerCacheTest,LookUpBrEdrPeerByLePublicAlias)242 TEST_F(PeerCacheTest, LookUpBrEdrPeerByLePublicAlias) {
243 ASSERT_FALSE(cache()->FindByAddress(kAddrLeAlias));
244 ASSERT_TRUE(NewPeer(kAddrBrEdr, true));
245 auto* p = cache()->FindByAddress(kAddrBrEdr);
246 ASSERT_TRUE(p);
247 EXPECT_EQ(peer(), p);
248
249 p = cache()->FindByAddress(kAddrLeAlias);
250 ASSERT_TRUE(p);
251 EXPECT_EQ(peer(), p);
252 EXPECT_EQ(DeviceAddress::Type::kBREDR, p->address().type());
253 }
254
TEST_F(PeerCacheTest,LookUpLePeerByBrEdrAlias)255 TEST_F(PeerCacheTest, LookUpLePeerByBrEdrAlias) {
256 EXPECT_FALSE(cache()->FindByAddress(kAddrBrEdr));
257 ASSERT_TRUE(NewPeer(kAddrLeAlias, true));
258 auto* p = cache()->FindByAddress(kAddrLeAlias);
259 ASSERT_TRUE(p);
260 EXPECT_EQ(peer(), p);
261
262 p = cache()->FindByAddress(kAddrBrEdr);
263 ASSERT_TRUE(p);
264 EXPECT_EQ(peer(), p);
265 EXPECT_EQ(DeviceAddress::Type::kLEPublic, p->address().type());
266 }
267
TEST_F(PeerCacheTest,NewPeerDoesNotCrashWhenNoCallbackIsRegistered)268 TEST_F(PeerCacheTest, NewPeerDoesNotCrashWhenNoCallbackIsRegistered) {
269 cache()->NewPeer(kAddrLePublic, /*connectable=*/true);
270 }
271
TEST_F(PeerCacheTest,ForEachEmpty)272 TEST_F(PeerCacheTest, ForEachEmpty) {
273 bool found = false;
274 cache()->ForEach([&](const auto&) { found = true; });
275 EXPECT_FALSE(found);
276 }
277
TEST_F(PeerCacheTest,ForEach)278 TEST_F(PeerCacheTest, ForEach) {
279 int count = 0;
280 ASSERT_TRUE(NewPeer(kAddrLePublic, true));
281 cache()->ForEach([&](const auto& p) {
282 count++;
283 EXPECT_EQ(peer()->identifier(), p.identifier());
284 EXPECT_EQ(peer()->address(), p.address());
285 });
286 EXPECT_EQ(1, count);
287 }
288
TEST_F(PeerCacheTest,NewPeerInvokesCallbackWhenPeerIsFirstRegistered)289 TEST_F(PeerCacheTest, NewPeerInvokesCallbackWhenPeerIsFirstRegistered) {
290 bool was_called = false;
291 cache()->add_peer_updated_callback(
292 [&was_called](const auto&) { was_called = true; });
293 cache()->NewPeer(kAddrLePublic, /*connectable=*/true);
294 EXPECT_TRUE(was_called);
295 }
296
TEST_F(PeerCacheTest,MultiplePeerUpdatedCallbacks)297 TEST_F(PeerCacheTest, MultiplePeerUpdatedCallbacks) {
298 size_t updated_count_0 = 0, updated_count_1 = 0;
299 PeerCache::CallbackId id_0 = cache()->add_peer_updated_callback(
300 [&](const auto&) { updated_count_0++; });
301 PeerCache::CallbackId id_1 = cache()->add_peer_updated_callback(
302 [&](const auto&) { updated_count_1++; });
303
304 cache()->NewPeer(kAddrLePublic, /*connectable=*/true);
305 EXPECT_EQ(updated_count_0, 1u);
306 EXPECT_EQ(updated_count_1, 1u);
307
308 cache()->NewPeer(kAddrLeRandom, /*connectable=*/true);
309 EXPECT_EQ(updated_count_0, 2u);
310 EXPECT_EQ(updated_count_1, 2u);
311
312 EXPECT_TRUE(cache()->remove_peer_updated_callback(id_0));
313 EXPECT_FALSE(cache()->remove_peer_updated_callback(id_0));
314 cache()->NewPeer(kAddrLeRandom2, /*connectable=*/true);
315 EXPECT_EQ(updated_count_0, 2u);
316 EXPECT_EQ(updated_count_1, 3u);
317
318 EXPECT_TRUE(cache()->remove_peer_updated_callback(id_1));
319 EXPECT_FALSE(cache()->remove_peer_updated_callback(id_1));
320 cache()->NewPeer(kAddrBrEdr, /*connectable=*/true);
321 EXPECT_EQ(updated_count_0, 2u);
322 EXPECT_EQ(updated_count_1, 3u);
323 }
324
TEST_F(PeerCacheTest,NewPeerDoesNotInvokeCallbackWhenPeerIsReRegistered)325 TEST_F(PeerCacheTest, NewPeerDoesNotInvokeCallbackWhenPeerIsReRegistered) {
326 int call_count = 0;
327 cache()->add_peer_updated_callback(
328 [&call_count](const auto&) { ++call_count; });
329 cache()->NewPeer(kAddrLePublic, /*connectable=*/true);
330 cache()->NewPeer(kAddrLePublic, /*connectable=*/true);
331 EXPECT_EQ(1, call_count);
332 }
333
TEST_F(PeerCacheTest,NewPeerIdentityKnown)334 TEST_F(PeerCacheTest, NewPeerIdentityKnown) {
335 EXPECT_TRUE(cache()->NewPeer(kAddrBrEdr, true)->identity_known());
336 EXPECT_TRUE(cache()->NewPeer(kAddrLePublic, true)->identity_known());
337 EXPECT_FALSE(cache()->NewPeer(kAddrLeRandom, true)->identity_known());
338 EXPECT_FALSE(cache()->NewPeer(kAddrLeAnon, false)->identity_known());
339 }
340
TEST_F(PeerCacheTest,NewPeerInitialTechnologyIsClassic)341 TEST_F(PeerCacheTest, NewPeerInitialTechnologyIsClassic) {
342 ASSERT_TRUE(NewPeer(kAddrBrEdr, true));
343
344 // A peer initialized with a BR/EDR address should start out as a
345 // classic-only.
346 ASSERT_TRUE(peer());
347 EXPECT_TRUE(peer()->bredr());
348 EXPECT_FALSE(peer()->le());
349 EXPECT_TRUE(peer()->identity_known());
350 EXPECT_EQ(TechnologyType::kClassic, peer()->technology());
351 }
352
TEST_F(PeerCacheTest,NewPeerInitialTechnologyLowEnergy)353 TEST_F(PeerCacheTest, NewPeerInitialTechnologyLowEnergy) {
354 // LE address types should initialize the peer as LE-only.
355 auto* le_publ_peer = cache()->NewPeer(kAddrLePublic, /*connectable=*/true);
356 auto* le_rand_peer = cache()->NewPeer(kAddrLeRandom, /*connectable=*/true);
357 auto* le_anon_peer = cache()->NewPeer(kAddrLeAnon, /*connectable=*/false);
358 ASSERT_TRUE(le_publ_peer);
359 ASSERT_TRUE(le_rand_peer);
360 ASSERT_TRUE(le_anon_peer);
361 EXPECT_TRUE(le_publ_peer->le());
362 EXPECT_TRUE(le_rand_peer->le());
363 EXPECT_TRUE(le_anon_peer->le());
364 EXPECT_FALSE(le_publ_peer->bredr());
365 EXPECT_FALSE(le_rand_peer->bredr());
366 EXPECT_FALSE(le_anon_peer->bredr());
367 EXPECT_EQ(TechnologyType::kLowEnergy, le_publ_peer->technology());
368 EXPECT_EQ(TechnologyType::kLowEnergy, le_rand_peer->technology());
369 EXPECT_EQ(TechnologyType::kLowEnergy, le_anon_peer->technology());
370 EXPECT_TRUE(le_publ_peer->identity_known());
371 EXPECT_FALSE(le_rand_peer->identity_known());
372 EXPECT_FALSE(le_anon_peer->identity_known());
373 }
374
TEST_F(PeerCacheTest,DisallowNewLowEnergyPeerIfBrEdrPeerExists)375 TEST_F(PeerCacheTest, DisallowNewLowEnergyPeerIfBrEdrPeerExists) {
376 ASSERT_TRUE(NewPeer(kAddrBrEdr, true));
377
378 // Try to add new LE peer with a public identity address containing the same
379 // value as the existing BR/EDR peer's BD_ADDR.
380 auto* le_alias_peer = cache()->NewPeer(kAddrLeAlias, /*connectable=*/true);
381 EXPECT_FALSE(le_alias_peer);
382 }
383
TEST_F(PeerCacheTest,DisallowNewBrEdrPeerIfLowEnergyPeerExists)384 TEST_F(PeerCacheTest, DisallowNewBrEdrPeerIfLowEnergyPeerExists) {
385 ASSERT_TRUE(NewPeer(kAddrLeAlias, true));
386
387 // Try to add new BR/EDR peer with BD_ADDR containing the same value as the
388 // existing LE peer's public identity address.
389 auto* bredr_alias_peer = cache()->NewPeer(kAddrBrEdr, /*connectable=*/true);
390 ASSERT_FALSE(bredr_alias_peer);
391 }
392
TEST_F(PeerCacheTest,BrEdrPeerBecomesDualModeWithAdvertisingData)393 TEST_F(PeerCacheTest, BrEdrPeerBecomesDualModeWithAdvertisingData) {
394 ASSERT_TRUE(NewPeer(kAddrBrEdr, true));
395 ASSERT_TRUE(peer()->bredr());
396 ASSERT_FALSE(peer()->le());
397
398 peer()->MutLe().SetAdvertisingData(
399 kTestRSSI, kAdvData, pw::chrono::SystemClock::time_point());
400 EXPECT_TRUE(peer()->le());
401 EXPECT_EQ(TechnologyType::kDualMode, peer()->technology());
402
403 // Searching by LE address should turn up this peer, which should retain its
404 // original address type.
405 auto* const le_peer = cache()->FindByAddress(kAddrLeAlias);
406 ASSERT_EQ(peer(), le_peer);
407 EXPECT_EQ(DeviceAddress::Type::kBREDR, peer()->address().type());
408 }
409
TEST_F(PeerCacheTest,BrEdrPeerBecomesDualModeWhenConnectedOverLowEnergy)410 TEST_F(PeerCacheTest, BrEdrPeerBecomesDualModeWhenConnectedOverLowEnergy) {
411 ASSERT_TRUE(NewPeer(kAddrBrEdr, true));
412 ASSERT_TRUE(peer()->bredr());
413 ASSERT_FALSE(peer()->le());
414
415 Peer::ConnectionToken conn_token = peer()->MutLe().RegisterConnection();
416 EXPECT_TRUE(peer()->le());
417 EXPECT_EQ(TechnologyType::kDualMode, peer()->technology());
418
419 auto* const le_peer = cache()->FindByAddress(kAddrLeAlias);
420 ASSERT_EQ(peer(), le_peer);
421 EXPECT_EQ(DeviceAddress::Type::kBREDR, peer()->address().type());
422 }
423
TEST_F(PeerCacheTest,BrEdrPeerBecomesDualModeWithLowEnergyConnParams)424 TEST_F(PeerCacheTest, BrEdrPeerBecomesDualModeWithLowEnergyConnParams) {
425 ASSERT_TRUE(NewPeer(kAddrBrEdr, true));
426 ASSERT_TRUE(peer()->bredr());
427 ASSERT_FALSE(peer()->le());
428
429 peer()->MutLe().SetConnectionParameters({});
430 EXPECT_TRUE(peer()->le());
431 EXPECT_EQ(TechnologyType::kDualMode, peer()->technology());
432
433 auto* const le_peer = cache()->FindByAddress(kAddrLeAlias);
434 ASSERT_EQ(peer(), le_peer);
435 EXPECT_EQ(DeviceAddress::Type::kBREDR, peer()->address().type());
436 }
437
TEST_F(PeerCacheTest,BrEdrPeerBecomesDualModeWithLowEnergyPreferredConnParams)438 TEST_F(PeerCacheTest,
439 BrEdrPeerBecomesDualModeWithLowEnergyPreferredConnParams) {
440 ASSERT_TRUE(NewPeer(kAddrBrEdr, true));
441 ASSERT_TRUE(peer()->bredr());
442 ASSERT_FALSE(peer()->le());
443
444 peer()->MutLe().SetPreferredConnectionParameters({});
445 EXPECT_TRUE(peer()->le());
446 EXPECT_EQ(TechnologyType::kDualMode, peer()->technology());
447
448 auto* const le_peer = cache()->FindByAddress(kAddrLeAlias);
449 ASSERT_EQ(peer(), le_peer);
450 EXPECT_EQ(DeviceAddress::Type::kBREDR, peer()->address().type());
451 }
452
TEST_F(PeerCacheTest,LowEnergyPeerBecomesDualModeWithInquiryData)453 TEST_F(PeerCacheTest, LowEnergyPeerBecomesDualModeWithInquiryData) {
454 ASSERT_TRUE(NewPeer(kAddrLeAlias, true));
455 ASSERT_TRUE(peer()->le());
456 ASSERT_FALSE(peer()->bredr());
457
458 StaticPacket<pw::bluetooth::emboss::InquiryResultWriter> ir;
459 ir.view().bd_addr().CopyFrom(kAddrLeAlias.value().view());
460 peer()->MutBrEdr().SetInquiryData(ir.view());
461 EXPECT_TRUE(peer()->bredr());
462 EXPECT_EQ(TechnologyType::kDualMode, peer()->technology());
463
464 // Searching by only BR/EDR technology should turn up this peer, which
465 // should still retain its original address type.
466 auto* const bredr_peer = cache()->FindByAddress(kAddrBrEdr);
467 ASSERT_EQ(peer(), bredr_peer);
468 EXPECT_EQ(DeviceAddress::Type::kLEPublic, peer()->address().type());
469 EXPECT_EQ(kAddrBrEdr, peer()->bredr()->address());
470 }
471
TEST_F(PeerCacheTest,LowEnergyPeerBecomesDualModeWhenConnectedOverClassic)472 TEST_F(PeerCacheTest, LowEnergyPeerBecomesDualModeWhenConnectedOverClassic) {
473 ASSERT_TRUE(NewPeer(kAddrLeAlias, true));
474 ASSERT_TRUE(peer()->le());
475 ASSERT_FALSE(peer()->bredr());
476
477 Peer::ConnectionToken token = peer()->MutBrEdr().RegisterConnection();
478 EXPECT_TRUE(peer()->bredr());
479 EXPECT_EQ(TechnologyType::kDualMode, peer()->technology());
480
481 auto* const bredr_peer = cache()->FindByAddress(kAddrBrEdr);
482 ASSERT_EQ(peer(), bredr_peer);
483 EXPECT_EQ(DeviceAddress::Type::kLEPublic, peer()->address().type());
484 EXPECT_EQ(kAddrBrEdr, peer()->bredr()->address());
485 }
486
TEST_F(PeerCacheTest,InitialAutoConnectBehavior)487 TEST_F(PeerCacheTest, InitialAutoConnectBehavior) {
488 ASSERT_TRUE(NewPeer(kAddrLeAlias, true));
489
490 // Peers are not autoconnected before they are bonded.
491 EXPECT_FALSE(peer()->le()->should_auto_connect());
492
493 sm::PairingData data;
494 data.peer_ltk = sm::LTK();
495 data.local_ltk = sm::LTK();
496 EXPECT_TRUE(cache()->StoreLowEnergyBond(peer()->identifier(), data));
497
498 // Bonded peers should autoconnect
499 EXPECT_TRUE(peer()->le()->should_auto_connect());
500
501 // Connecting peer leaves `should_auto_connect` unaffected.
502 Peer::ConnectionToken conn_token = peer()->MutLe().RegisterConnection();
503
504 EXPECT_TRUE(peer()->le()->should_auto_connect());
505 }
506
TEST_F(PeerCacheTest,AutoConnectDisabledAfterIntentionalDisconnect)507 TEST_F(PeerCacheTest, AutoConnectDisabledAfterIntentionalDisconnect) {
508 ASSERT_TRUE(NewPeer(kAddrLeAlias, true));
509 cache()->SetAutoConnectBehaviorForIntentionalDisconnect(peer()->identifier());
510 EXPECT_FALSE(peer()->le()->should_auto_connect());
511 }
512
TEST_F(PeerCacheTest,AutoConnectReenabledAfterSuccessfulConnect)513 TEST_F(PeerCacheTest, AutoConnectReenabledAfterSuccessfulConnect) {
514 ASSERT_TRUE(NewPeer(kAddrLeAlias, true));
515
516 // Only bonded peers are eligible for autoconnect.
517 sm::PairingData data;
518 data.peer_ltk = sm::LTK();
519 data.local_ltk = sm::LTK();
520 EXPECT_TRUE(cache()->StoreLowEnergyBond(peer()->identifier(), data));
521
522 cache()->SetAutoConnectBehaviorForIntentionalDisconnect(peer()->identifier());
523 EXPECT_FALSE(peer()->le()->should_auto_connect());
524
525 cache()->SetAutoConnectBehaviorForSuccessfulConnection(peer()->identifier());
526 EXPECT_TRUE(peer()->le()->should_auto_connect());
527 }
528
529 class PeerCacheTestBondingTest : public PeerCacheTest {
530 public:
SetUp()531 void SetUp() override {
532 PeerCacheTest::SetUp();
533 ASSERT_TRUE(NewPeer(kAddrLePublic, true));
534 bonded_callback_count_ = 0;
535 cache()->set_peer_bonded_callback(
536 [this](const auto&) { bonded_callback_count_++; });
537 updated_callback_count_ = 0;
538 updated_callback_id_ = cache()->add_peer_updated_callback(
539 [this](auto&) { updated_callback_count_++; });
540 removed_callback_count_ = 0;
541 cache()->set_peer_removed_callback(
542 [this](PeerId) { removed_callback_count_++; });
543 }
544
TearDown()545 void TearDown() override {
546 cache()->set_peer_removed_callback(nullptr);
547 removed_callback_count_ = 0;
548 EXPECT_TRUE(cache()->remove_peer_updated_callback(updated_callback_id_));
549 updated_callback_count_ = 0;
550 cache()->set_peer_bonded_callback(nullptr);
551 bonded_callback_count_ = 0;
552 PeerCacheTest::TearDown();
553 }
554
555 protected:
bonded_callback_called() const556 bool bonded_callback_called() const { return bonded_callback_count_ != 0; }
557
558 // Returns 0 at the beginning of each test case.
bonded_callback_count() const559 int bonded_callback_count() const { return bonded_callback_count_; }
560
updated_callback_count() const561 int updated_callback_count() const { return updated_callback_count_; }
562
removed_callback_count() const563 int removed_callback_count() const { return removed_callback_count_; }
564
565 private:
566 int bonded_callback_count_;
567 int updated_callback_count_;
568 int removed_callback_count_;
569 PeerCache::CallbackId updated_callback_id_ = 0;
570 };
571
TEST_F(PeerCacheTestBondingTest,AddBondedPeerFailsWithExistingId)572 TEST_F(PeerCacheTestBondingTest, AddBondedPeerFailsWithExistingId) {
573 sm::PairingData data;
574 data.peer_ltk = kLTK;
575 data.local_ltk = kLTK;
576 EXPECT_FALSE(
577 cache()->AddBondedPeer(BondingData{.identifier = peer()->identifier(),
578 .address = kAddrLeRandom,
579 .name = {},
580 .le_pairing_data = data,
581 .bredr_link_key = {},
582 .bredr_services = {}}));
583 EXPECT_FALSE(bonded_callback_called());
584 }
585
TEST_F(PeerCacheTestBondingTest,AddBondedPeerFailsWithExistingAddress)586 TEST_F(PeerCacheTestBondingTest, AddBondedPeerFailsWithExistingAddress) {
587 sm::PairingData data;
588 data.peer_ltk = kLTK;
589 data.local_ltk = kLTK;
590 EXPECT_FALSE(cache()->AddBondedPeer(BondingData{.identifier = kId,
591 .address = peer()->address(),
592 .name = {},
593 .le_pairing_data = data,
594 .bredr_link_key = {},
595 .bredr_services = {}}));
596 EXPECT_FALSE(bonded_callback_called());
597 }
598
TEST_F(PeerCacheTestBondingTest,AddBondedLowEnergyPeerFailsWithExistingBrEdrAliasAddress)599 TEST_F(PeerCacheTestBondingTest,
600 AddBondedLowEnergyPeerFailsWithExistingBrEdrAliasAddress) {
601 EXPECT_TRUE(NewPeer(kAddrBrEdr, true));
602 sm::PairingData data;
603 data.peer_ltk = kLTK;
604 data.local_ltk = kLTK;
605 EXPECT_FALSE(cache()->AddBondedPeer(BondingData{.identifier = kId,
606 .address = kAddrLeAlias,
607 .name = {},
608 .le_pairing_data = data,
609 .bredr_link_key = {},
610 .bredr_services = {}}));
611 EXPECT_FALSE(bonded_callback_called());
612 }
613
TEST_F(PeerCacheTestBondingTest,AddBondedBrEdrPeerFailsWithExistingLowEnergyAliasAddress)614 TEST_F(PeerCacheTestBondingTest,
615 AddBondedBrEdrPeerFailsWithExistingLowEnergyAliasAddress) {
616 EXPECT_TRUE(NewPeer(kAddrLeAlias, true));
617 EXPECT_FALSE(cache()->AddBondedPeer(BondingData{.identifier = kId,
618 .address = kAddrBrEdr,
619 .name = {},
620 .le_pairing_data = {},
621 .bredr_link_key = kBrEdrKey,
622 .bredr_services = {}}));
623 EXPECT_FALSE(bonded_callback_called());
624 }
625
TEST_F(PeerCacheTestBondingTest,AddBondedPeerFailsWithoutMandatoryKeys)626 TEST_F(PeerCacheTestBondingTest, AddBondedPeerFailsWithoutMandatoryKeys) {
627 sm::PairingData data;
628 EXPECT_FALSE(cache()->AddBondedPeer(BondingData{.identifier = kId,
629 .address = kAddrLeAlias,
630 .name = {},
631 .le_pairing_data = data,
632 .bredr_link_key = kBrEdrKey,
633 .bredr_services = {}}));
634 data.peer_ltk = kLTK;
635 data.local_ltk = kLTK;
636 EXPECT_FALSE(cache()->AddBondedPeer(BondingData{.identifier = kId,
637 .address = kAddrBrEdr,
638 .name = {},
639 .le_pairing_data = data,
640 .bredr_link_key = {},
641 .bredr_services = {}}));
642 EXPECT_FALSE(bonded_callback_called());
643 }
644
TEST_F(PeerCacheTestBondingTest,AddLowEnergyBondedPeerSuccess)645 TEST_F(PeerCacheTestBondingTest, AddLowEnergyBondedPeerSuccess) {
646 sm::PairingData data;
647 data.peer_ltk = kLTK;
648 data.local_ltk = kLTK;
649
650 EXPECT_TRUE(cache()->AddBondedPeer(BondingData{.identifier = kId,
651 .address = kAddrLeRandom,
652 .name = kName,
653 .le_pairing_data = data,
654 .bredr_link_key = {},
655 .bredr_services = {}}));
656 auto* peer = cache()->FindById(kId);
657 ASSERT_TRUE(peer);
658 EXPECT_EQ(peer, cache()->FindByAddress(kAddrLeRandom));
659 EXPECT_EQ(kId, peer->identifier());
660 EXPECT_EQ(kAddrLeRandom, peer->address());
661 EXPECT_EQ(kName, peer->name());
662 EXPECT_EQ(Peer::NameSource::kUnknown, peer->name_source());
663 EXPECT_TRUE(peer->identity_known());
664 ASSERT_TRUE(peer->le());
665 EXPECT_TRUE(peer->le()->bonded());
666 ASSERT_TRUE(peer->le()->bond_data());
667 EXPECT_EQ(data, *peer->le()->bond_data());
668 EXPECT_FALSE(peer->bredr());
669 EXPECT_EQ(TechnologyType::kLowEnergy, peer->technology());
670
671 // The "new bond" callback should not be called when restoring a previously
672 // bonded peer.
673 EXPECT_FALSE(bonded_callback_called());
674 }
675
TEST_F(PeerCacheTestBondingTest,AddBrEdrBondedPeerSuccess)676 TEST_F(PeerCacheTestBondingTest, AddBrEdrBondedPeerSuccess) {
677 sm::PairingData data;
678
679 EXPECT_TRUE(
680 cache()->AddBondedPeer(BondingData{.identifier = kId,
681 .address = kAddrBrEdr,
682 .name = {},
683 .le_pairing_data = data,
684 .bredr_link_key = kBrEdrKey,
685 .bredr_services = kBrEdrServices}));
686 auto* peer = cache()->FindById(kId);
687 ASSERT_TRUE(peer);
688 EXPECT_EQ(peer, cache()->FindByAddress(kAddrBrEdr));
689 EXPECT_EQ(kId, peer->identifier());
690 EXPECT_EQ(kAddrBrEdr, peer->address());
691 ASSERT_FALSE(peer->name());
692 EXPECT_TRUE(peer->identity_known());
693 ASSERT_TRUE(peer->bredr());
694 EXPECT_TRUE(peer->bredr()->bonded());
695 ASSERT_TRUE(peer->bredr()->link_key());
696 EXPECT_EQ(kBrEdrKey, *peer->bredr()->link_key());
697 EXPECT_THAT(peer->bredr()->services(),
698 testing::UnorderedElementsAreArray(kBrEdrServices));
699 EXPECT_FALSE(peer->le());
700 EXPECT_EQ(TechnologyType::kClassic, peer->technology());
701
702 // The "new bond" callback should not be called when restoring a previously
703 // bonded peer.
704 EXPECT_FALSE(bonded_callback_called());
705 }
706
TEST_F(PeerCacheTest,AddBondedPeerWithIrkIsAddedToResolvingList)707 TEST_F(PeerCacheTest, AddBondedPeerWithIrkIsAddedToResolvingList) {
708 sm::PairingData data;
709 data.peer_ltk = kLTK;
710 data.local_ltk = kLTK;
711 data.irk = sm::Key(sm::SecurityProperties(), Random<UInt128>());
712 data.identity_address = kAddrLeRandom;
713
714 EXPECT_TRUE(cache()->AddBondedPeer(BondingData{.identifier = kId,
715 .address = kAddrLeRandom,
716 .name = {},
717 .le_pairing_data = data,
718 .bredr_link_key = {},
719 .bredr_services = {}}));
720 auto* peer = cache()->FindByAddress(kAddrLeRandom);
721 ASSERT_TRUE(peer);
722 EXPECT_EQ(kAddrLeRandom, peer->address());
723
724 // Looking up the peer by RPA generated using the IRK should return the same
725 // peer.
726 DeviceAddress rpa = sm::util::GenerateRpa(data.irk->value());
727 EXPECT_EQ(peer, cache()->FindByAddress(rpa));
728 }
729
TEST_F(PeerCacheTest,AddBondedPeerWithIrkButWithoutIdentityAddressPanics)730 TEST_F(PeerCacheTest, AddBondedPeerWithIrkButWithoutIdentityAddressPanics) {
731 sm::PairingData data;
732 data.peer_ltk = kLTK;
733 data.local_ltk = kLTK;
734 data.irk = sm::Key(sm::SecurityProperties(), Random<UInt128>());
735
736 EXPECT_DEATH_IF_SUPPORTED(
737 cache()->AddBondedPeer(BondingData{.identifier = kId,
738 .address = kAddrLeRandom,
739 .name = {},
740 .le_pairing_data = data,
741 .bredr_link_key = {},
742 .bredr_services = {}}),
743 ".*identity_address.*");
744 }
745
TEST_F(PeerCacheTest,StoreLowEnergyBondWithIrkButWithoutIdentityAddressPanics)746 TEST_F(PeerCacheTest,
747 StoreLowEnergyBondWithIrkButWithoutIdentityAddressPanics) {
748 sm::PairingData data;
749 data.peer_ltk = kLTK;
750 data.local_ltk = kLTK;
751 data.irk = sm::Key(sm::SecurityProperties(), Random<UInt128>());
752
753 EXPECT_DEATH_IF_SUPPORTED(cache()->StoreLowEnergyBond(kId, data),
754 ".*identity_address.*");
755 }
756
TEST_F(PeerCacheTestBondingTest,StoreLowEnergyBondFailsWithNoKeys)757 TEST_F(PeerCacheTestBondingTest, StoreLowEnergyBondFailsWithNoKeys) {
758 sm::PairingData data;
759 EXPECT_FALSE(cache()->StoreLowEnergyBond(peer()->identifier(), data));
760 }
761
TEST_F(PeerCacheTestBondingTest,StoreLowEnergyBondPeerUnknown)762 TEST_F(PeerCacheTestBondingTest, StoreLowEnergyBondPeerUnknown) {
763 sm::PairingData data;
764 data.peer_ltk = kLTK;
765 data.local_ltk = kLTK;
766 EXPECT_FALSE(cache()->StoreLowEnergyBond(kId, data));
767 }
768
TEST_F(PeerCacheTestBondingTest,StoreLowEnergyBondWithLtk)769 TEST_F(PeerCacheTestBondingTest, StoreLowEnergyBondWithLtk) {
770 ASSERT_TRUE(peer()->temporary());
771 ASSERT_TRUE(peer()->le());
772 ASSERT_FALSE(peer()->le()->bonded());
773
774 sm::PairingData data;
775 data.peer_ltk = kLTK;
776 data.local_ltk = kLTK;
777 EXPECT_TRUE(cache()->StoreLowEnergyBond(peer()->identifier(), data));
778
779 EXPECT_TRUE(bonded_callback_called());
780 EXPECT_FALSE(peer()->temporary());
781 EXPECT_TRUE(peer()->le()->bonded());
782 EXPECT_TRUE(peer()->le()->bond_data());
783 EXPECT_EQ(data, *peer()->le()->bond_data());
784 }
785
TEST_F(PeerCacheTestBondingTest,StoreLowEnergyBondWithCsrk)786 TEST_F(PeerCacheTestBondingTest, StoreLowEnergyBondWithCsrk) {
787 ASSERT_TRUE(peer()->temporary());
788 ASSERT_TRUE(peer()->le());
789 ASSERT_FALSE(peer()->le()->bonded());
790
791 sm::PairingData data;
792 data.csrk = kKey;
793 EXPECT_TRUE(cache()->StoreLowEnergyBond(peer()->identifier(), data));
794
795 EXPECT_TRUE(bonded_callback_called());
796 EXPECT_FALSE(peer()->temporary());
797 EXPECT_TRUE(peer()->le()->bonded());
798 EXPECT_TRUE(peer()->le()->bond_data());
799 EXPECT_EQ(data, *peer()->le()->bond_data());
800 }
801
802 // StoreLowEnergyBond fails if it contains the address of a different,
803 // previously known peer.
TEST_F(PeerCacheTestBondingTest,StoreLowEnergyBondWithExistingDifferentIdentity)804 TEST_F(PeerCacheTestBondingTest,
805 StoreLowEnergyBondWithExistingDifferentIdentity) {
806 auto* p = cache()->NewPeer(kAddrLeRandom, /*connectable=*/true);
807
808 // Assign the other peer's address as identity.
809 sm::PairingData data;
810 data.peer_ltk = kLTK;
811 data.local_ltk = kLTK;
812 data.irk = sm::Key(sm::SecurityProperties(), Random<UInt128>());
813 data.identity_address = peer()->address();
814 EXPECT_FALSE(cache()->StoreLowEnergyBond(p->identifier(), data));
815 EXPECT_FALSE(p->le()->bonded());
816 EXPECT_TRUE(p->temporary());
817 }
818
819 // StoreLowEnergyBond fails if the new identity is the address of a "different"
820 // (another peer record with a distinct ID) BR/EDR peer.
TEST_F(PeerCacheTestBondingTest,StoreLowEnergyBondWithNewIdentityMatchingExistingBrEdrPeer)821 TEST_F(PeerCacheTestBondingTest,
822 StoreLowEnergyBondWithNewIdentityMatchingExistingBrEdrPeer) {
823 ASSERT_TRUE(NewPeer(kAddrBrEdr, true));
824 ASSERT_TRUE(NewPeer(kAddrLeRandom, true));
825 ASSERT_FALSE(peer()->identity_known());
826
827 sm::PairingData data;
828 data.peer_ltk = kLTK;
829 data.local_ltk = kLTK;
830 data.irk = sm::Key(sm::SecurityProperties(), Random<UInt128>());
831 // new identity address is same as another peer's BR/EDR identity
832 data.identity_address = kAddrLeAlias;
833 const auto old_address = peer()->address();
834 ASSERT_EQ(peer(), cache()->FindByAddress(old_address));
835 ASSERT_NE(peer(), cache()->FindByAddress(*data.identity_address));
836 EXPECT_FALSE(cache()->StoreLowEnergyBond(peer()->identifier(), data));
837 EXPECT_FALSE(peer()->identity_known());
838 }
839
840 // StoreLowEnergyBond succeeds if it contains an identity address that already
841 // matches the target peer.
TEST_F(PeerCacheTestBondingTest,StoreLowEnergyBondWithExistingMatchingIdentity)842 TEST_F(PeerCacheTestBondingTest,
843 StoreLowEnergyBondWithExistingMatchingIdentity) {
844 sm::PairingData data;
845 data.peer_ltk = kLTK;
846 data.local_ltk = kLTK;
847 data.irk = sm::Key(sm::SecurityProperties(), Random<UInt128>());
848 data.identity_address = peer()->address();
849 EXPECT_TRUE(cache()->StoreLowEnergyBond(peer()->identifier(), data));
850 EXPECT_TRUE(peer()->le()->bonded());
851 EXPECT_EQ(peer(), cache()->FindByAddress(*data.identity_address));
852 }
853
TEST_F(PeerCacheTestBondingTest,StoreLowEnergyBondWithNewIdentity)854 TEST_F(PeerCacheTestBondingTest, StoreLowEnergyBondWithNewIdentity) {
855 ASSERT_TRUE(NewPeer(kAddrLeRandom, true));
856 ASSERT_FALSE(peer()->identity_known());
857
858 sm::PairingData data;
859 data.peer_ltk = kLTK;
860 data.local_ltk = kLTK;
861 data.irk = sm::Key(sm::SecurityProperties(), Random<UInt128>());
862 data.identity_address = kAddrLeRandom2; // assign a new identity address
863 const auto old_address = peer()->address();
864 ASSERT_EQ(peer(), cache()->FindByAddress(old_address));
865 ASSERT_EQ(nullptr, cache()->FindByAddress(*data.identity_address));
866
867 EXPECT_TRUE(cache()->StoreLowEnergyBond(peer()->identifier(), data));
868 EXPECT_TRUE(peer()->le()->bonded());
869
870 // Address should have been updated.
871 ASSERT_NE(*data.identity_address, old_address);
872 EXPECT_EQ(*data.identity_address, peer()->address());
873 EXPECT_TRUE(peer()->identity_known());
874 EXPECT_EQ(peer(), cache()->FindByAddress(*data.identity_address));
875
876 // The old address should still map to |peer|.
877 ASSERT_EQ(peer(), cache()->FindByAddress(old_address));
878 }
879
TEST_F(PeerCacheTestBondingTest,StoreLowEnergyBondWithIrkIsAddedToResolvingList)880 TEST_F(PeerCacheTestBondingTest,
881 StoreLowEnergyBondWithIrkIsAddedToResolvingList) {
882 ASSERT_TRUE(NewPeer(kAddrLeRandom, true));
883 ASSERT_FALSE(peer()->identity_known());
884
885 sm::PairingData data;
886 data.peer_ltk = kLTK;
887 data.local_ltk = kLTK;
888 data.identity_address = kAddrLeRandom;
889 data.irk = sm::Key(sm::SecurityProperties(), Random<UInt128>());
890
891 EXPECT_TRUE(cache()->StoreLowEnergyBond(peer()->identifier(), data));
892 ASSERT_TRUE(peer()->le()->bonded());
893 ASSERT_TRUE(peer()->identity_known());
894
895 // Looking up the peer by RPA generated using the IRK should return the same
896 // peer.
897 DeviceAddress rpa = sm::util::GenerateRpa(data.irk->value());
898 EXPECT_EQ(peer(), cache()->FindByAddress(rpa));
899 }
900
TEST_F(PeerCacheTestBondingTest,RemovingPeerRemovesIrkFromResolvingList)901 TEST_F(PeerCacheTestBondingTest, RemovingPeerRemovesIrkFromResolvingList) {
902 sm::PairingData data;
903 data.peer_ltk = kLTK;
904 data.local_ltk = kLTK;
905 data.identity_address = kAddrLePublic;
906 data.irk = sm::Key(sm::SecurityProperties(), Random<UInt128>());
907
908 EXPECT_TRUE(cache()->StoreLowEnergyBond(peer()->identifier(), data));
909
910 // Removing peer should remove IRK from resolving list, allowing a new peer to
911 // be created with an RPA corresponding to the removed IRK. Because the
912 // resolving list is empty, FindByAddress should look up the peer by the RPA
913 // address, not the resolved address, and return the new peer.
914 EXPECT_TRUE(cache()->RemoveDisconnectedPeer(peer()->identifier()));
915 DeviceAddress rpa = sm::util::GenerateRpa(data.irk->value());
916 EXPECT_EQ(nullptr, cache()->FindByAddress(rpa));
917 ASSERT_TRUE(NewPeer(rpa, true));
918 EXPECT_EQ(peer(), cache()->FindByAddress(rpa));
919 // Subsequent calls to create a peer with the same RPA should fail.
920 EXPECT_FALSE(NewPeer(rpa, true));
921 }
922
TEST_F(PeerCacheTestBondingTest,StoreLowEnergyBondWithXTransportKeyNoBrEdr)923 TEST_F(PeerCacheTestBondingTest, StoreLowEnergyBondWithXTransportKeyNoBrEdr) {
924 // There's no preexisting BR/EDR data, the LE peer already exists.
925 sm::PairingData data;
926 data.peer_ltk = kLTK;
927 data.local_ltk = kLTK;
928 data.cross_transport_key = kSecureBrEdrKey;
929
930 EXPECT_TRUE(cache()->StoreLowEnergyBond(peer()->identifier(), data));
931 EXPECT_TRUE(peer()->le()->bonded());
932 // Storing an LE bond with a cross-transport BR/EDR key should mark the peer
933 // as dual-mode.
934 EXPECT_TRUE(peer()->bredr().has_value());
935 EXPECT_TRUE(peer()->bredr()->bonded());
936 EXPECT_EQ(kSecureBrEdrKey, peer()->bredr()->link_key().value());
937 EXPECT_EQ(bonded_callback_count(), 1);
938 }
939
TEST_F(PeerCacheTestBondingTest,StoreLowEnergyBondWithInsecureXTransportKeyExistingBrEdr)940 TEST_F(PeerCacheTestBondingTest,
941 StoreLowEnergyBondWithInsecureXTransportKeyExistingBrEdr) {
942 // The peer is already dual-mode with a secure BR/EDR key.
943 EXPECT_TRUE(peer()->MutBrEdr().SetBondData(kSecureBrEdrKey));
944 EXPECT_TRUE(peer()->bredr()->bonded());
945
946 sm::PairingData data;
947 data.peer_ltk = kLTK;
948 data.local_ltk = kLTK;
949 data.cross_transport_key = kInsecureBrEdrKey;
950 EXPECT_TRUE(cache()->StoreLowEnergyBond(peer()->identifier(), data));
951
952 // Verify that the existing BR/EDR key is not overwritten by a key of lesser
953 // security
954 sm::LTK current_bredr_key = peer()->bredr()->link_key().value();
955 EXPECT_NE(kInsecureBrEdrKey, current_bredr_key);
956 EXPECT_EQ(kSecureBrEdrKey, current_bredr_key);
957 }
958
TEST_F(PeerCacheTestBondingTest,StoreLowEnergyBondWithSameOrMoreSecureXTransportKeyExistingBrEdr)959 TEST_F(PeerCacheTestBondingTest,
960 StoreLowEnergyBondWithSameOrMoreSecureXTransportKeyExistingBrEdr) {
961 // The peer is already dual-mode with an insecure BR/EDR key.
962 EXPECT_TRUE(peer()->MutBrEdr().SetBondData(kInsecureBrEdrKey));
963 EXPECT_TRUE(peer()->bredr()->bonded());
964
965 sm::LTK kDifferentInsecureBrEdrKey(kInsecureBrEdrKey.security(),
966 hci_spec::LinkKey(UInt128{8}, 9, 10));
967 sm::PairingData data;
968 data.peer_ltk = kLTK;
969 data.local_ltk = kLTK;
970 data.cross_transport_key = kDifferentInsecureBrEdrKey;
971 EXPECT_TRUE(cache()->StoreLowEnergyBond(peer()->identifier(), data));
972
973 // Verify that the existing BR/EDR key is overwritten by a key of the same
974 // security ("if the key
975 // [...] already exists, then the devices shall not overwrite that existing
976 // key with a key that is weaker" v5.2 Vol. 3 Part C 14.1).
977 sm::LTK current_bredr_key = peer()->bredr()->link_key().value();
978 EXPECT_NE(kInsecureBrEdrKey, current_bredr_key);
979 EXPECT_EQ(kDifferentInsecureBrEdrKey, current_bredr_key);
980
981 // Verify that the existing BR/EDR key is also overwritten by a key of greater
982 // security.
983 data.cross_transport_key = kSecureBrEdrKey;
984 EXPECT_TRUE(cache()->StoreLowEnergyBond(peer()->identifier(), data));
985
986 current_bredr_key = peer()->bredr()->link_key().value();
987 EXPECT_NE(kDifferentInsecureBrEdrKey, current_bredr_key);
988 EXPECT_EQ(kSecureBrEdrKey, current_bredr_key);
989 }
990
TEST_F(PeerCacheTestBondingTest,StoreBrEdrBondWithUnknownAddress)991 TEST_F(PeerCacheTestBondingTest, StoreBrEdrBondWithUnknownAddress) {
992 ASSERT_EQ(nullptr, cache()->FindByAddress(kAddrBrEdr));
993 EXPECT_FALSE(cache()->StoreBrEdrBond(kAddrBrEdr, kBrEdrKey));
994 }
995
TEST_F(PeerCacheTestBondingTest,StoreBrEdrBond)996 TEST_F(PeerCacheTestBondingTest, StoreBrEdrBond) {
997 ASSERT_TRUE(NewPeer(kAddrBrEdr, true));
998 ASSERT_EQ(peer(), cache()->FindByAddress(kAddrBrEdr));
999 ASSERT_TRUE(peer()->temporary());
1000 ASSERT_FALSE(peer()->bonded());
1001 ASSERT_TRUE(peer()->bredr());
1002 ASSERT_FALSE(peer()->bredr()->bonded());
1003
1004 EXPECT_TRUE(cache()->StoreBrEdrBond(kAddrBrEdr, kBrEdrKey));
1005
1006 EXPECT_FALSE(peer()->temporary());
1007 EXPECT_TRUE(peer()->bonded());
1008 EXPECT_TRUE(peer()->bredr()->bonded());
1009 EXPECT_TRUE(peer()->bredr()->link_key());
1010 EXPECT_EQ(kBrEdrKey, *peer()->bredr()->link_key());
1011 }
1012
TEST_F(PeerCacheTestBondingTest,StoreBondsForBothTech)1013 TEST_F(PeerCacheTestBondingTest, StoreBondsForBothTech) {
1014 ASSERT_TRUE(NewPeer(kAddrBrEdr, true));
1015 ASSERT_EQ(peer(), cache()->FindByAddress(kAddrBrEdr));
1016 ASSERT_TRUE(peer()->temporary());
1017 ASSERT_FALSE(peer()->bonded());
1018
1019 peer()->MutLe().SetAdvertisingData(
1020 kTestRSSI, kAdvData, pw::chrono::SystemClock::time_point());
1021 ASSERT_EQ(TechnologyType::kDualMode, peer()->technology());
1022
1023 // Without Secure Connections cross-transport key generation, bonding on one
1024 // technology does not bond on the other.
1025 ASSERT_FALSE(kBrEdrKey.security().secure_connections());
1026 EXPECT_TRUE(cache()->StoreBrEdrBond(kAddrBrEdr, kBrEdrKey));
1027 EXPECT_TRUE(peer()->bonded());
1028 EXPECT_FALSE(peer()->le()->bonded());
1029
1030 sm::PairingData data;
1031 data.peer_ltk = kLTK;
1032 data.local_ltk = kLTK;
1033 EXPECT_TRUE(cache()->StoreLowEnergyBond(peer()->identifier(), data));
1034
1035 EXPECT_FALSE(peer()->temporary());
1036 EXPECT_TRUE(peer()->bonded());
1037 EXPECT_TRUE(peer()->bredr()->bonded());
1038 EXPECT_TRUE(peer()->le()->bonded());
1039 }
1040
TEST_F(PeerCacheTestBondingTest,BondsUpdatedWhenNewServicesAdded)1041 TEST_F(PeerCacheTestBondingTest, BondsUpdatedWhenNewServicesAdded) {
1042 ASSERT_TRUE(NewPeer(kAddrBrEdr, true));
1043 ASSERT_EQ(peer(), cache()->FindByAddress(kAddrBrEdr));
1044 ASSERT_FALSE(peer()->bonded());
1045
1046 ASSERT_FALSE(kBrEdrKey.security().secure_connections());
1047 EXPECT_TRUE(cache()->StoreBrEdrBond(kAddrBrEdr, kBrEdrKey));
1048 EXPECT_TRUE(peer()->bredr()->bonded());
1049 EXPECT_EQ(1, bonded_callback_count());
1050
1051 peer()->MutBrEdr().AddService(UUID());
1052 EXPECT_EQ(2, bonded_callback_count());
1053 }
1054
TEST_F(PeerCacheTestBondingTest,RemoveDisconnectedPeerOnUnknownPeer)1055 TEST_F(PeerCacheTestBondingTest, RemoveDisconnectedPeerOnUnknownPeer) {
1056 const PeerId id(0x9999);
1057 ASSERT_FALSE(cache()->FindById(id));
1058 EXPECT_TRUE(cache()->RemoveDisconnectedPeer(id));
1059 EXPECT_EQ(0, updated_callback_count());
1060 }
1061
TEST_F(PeerCacheTestBondingTest,RemoveDisconnectedPeerOnUnconnectedPeer)1062 TEST_F(PeerCacheTestBondingTest, RemoveDisconnectedPeerOnUnconnectedPeer) {
1063 ASSERT_FALSE(peer()->connected());
1064 const PeerId id = peer()->identifier();
1065 EXPECT_TRUE(cache()->RemoveDisconnectedPeer(id));
1066 EXPECT_EQ(1, removed_callback_count());
1067 EXPECT_FALSE(cache()->FindById(id));
1068 }
1069
TEST_F(PeerCacheTestBondingTest,RemoveDisconnectedPeerOnConnectedPeer)1070 TEST_F(PeerCacheTestBondingTest, RemoveDisconnectedPeerOnConnectedPeer) {
1071 Peer::ConnectionToken conn_token = peer()->MutLe().RegisterConnection();
1072 ASSERT_TRUE(peer()->connected());
1073 const PeerId id = peer()->identifier();
1074 EXPECT_FALSE(cache()->RemoveDisconnectedPeer(id));
1075 EXPECT_EQ(0, removed_callback_count());
1076 EXPECT_TRUE(cache()->FindById(id));
1077 }
1078
1079 // Fixture parameterized by peer address
1080 class DualModeBondingTest
1081 : public PeerCacheTestBondingTest,
1082 public ::testing::WithParamInterface<DeviceAddress> {};
1083
TEST_P(DualModeBondingTest,AddBondedPeerSuccess)1084 TEST_P(DualModeBondingTest, AddBondedPeerSuccess) {
1085 sm::PairingData data;
1086 data.peer_ltk = kLTK;
1087 data.local_ltk = kLTK;
1088
1089 const DeviceAddress& address = GetParam();
1090 EXPECT_TRUE(
1091 cache()->AddBondedPeer(BondingData{.identifier = kId,
1092 .address = address,
1093 .name = kName,
1094 .le_pairing_data = data,
1095 .bredr_link_key = kBrEdrKey,
1096 .bredr_services = kBrEdrServices}));
1097 auto* peer = cache()->FindById(kId);
1098 ASSERT_TRUE(peer);
1099 EXPECT_EQ(peer, cache()->FindByAddress(kAddrLeAlias));
1100 EXPECT_EQ(peer, cache()->FindByAddress(kAddrBrEdr));
1101 EXPECT_EQ(kId, peer->identifier());
1102 EXPECT_EQ(address, peer->address());
1103 EXPECT_EQ(kName, peer->name());
1104 EXPECT_EQ(Peer::NameSource::kUnknown, peer->name_source());
1105 EXPECT_TRUE(peer->identity_known());
1106 EXPECT_TRUE(peer->bonded());
1107 ASSERT_TRUE(peer->le());
1108 EXPECT_TRUE(peer->le()->bonded());
1109 ASSERT_TRUE(peer->le()->bond_data());
1110 EXPECT_EQ(data, *peer->le()->bond_data());
1111 ASSERT_TRUE(peer->bredr());
1112 EXPECT_TRUE(peer->bredr()->bonded());
1113 ASSERT_TRUE(peer->bredr()->link_key());
1114 EXPECT_EQ(kBrEdrKey, *peer->bredr()->link_key());
1115 EXPECT_THAT(peer->bredr()->services(),
1116 testing::UnorderedElementsAreArray(kBrEdrServices));
1117 EXPECT_EQ(TechnologyType::kDualMode, peer->technology());
1118
1119 // The "new bond" callback should not be called when restoring a previously
1120 // bonded peer.
1121 EXPECT_FALSE(bonded_callback_called());
1122 }
1123
1124 // Test dual-mode character of peer using the same address of both types.
1125 INSTANTIATE_TEST_SUITE_P(PeerCacheTest,
1126 DualModeBondingTest,
1127 ::testing::Values(kAddrBrEdr, kAddrLeAlias));
1128
1129 template <const DeviceAddress* DevAddr>
1130 class PeerCacheTest_UpdateCallbackTest : public PeerCacheTest {
1131 public:
SetUp()1132 void SetUp() override {
1133 PeerCacheTest::SetUp();
1134
1135 was_called_ = false;
1136 ASSERT_TRUE(NewPeer(*DevAddr, true));
1137 cache()->add_peer_updated_callback(
1138 [this](const auto&) { was_called_ = true; });
1139 ir_.view().bd_addr().CopyFrom(peer()->address().value().view());
1140 irr_.view().bd_addr().CopyFrom(peer()->address().value().view());
1141 extended_inquiry_result_event_.view().bd_addr().CopyFrom(
1142 peer()->address().value().view());
1143 eir_data().SetToZeros();
1144 EXPECT_FALSE(was_called_);
1145 }
1146
TearDown()1147 void TearDown() override { PeerCacheTest::TearDown(); }
1148
1149 protected:
ir()1150 pw::bluetooth::emboss::InquiryResultWriter ir() { return ir_.view(); }
irr()1151 pw::bluetooth::emboss::InquiryResultWithRssiWriter irr() {
1152 return irr_.view();
1153 }
1154 pw::bluetooth::emboss::ExtendedInquiryResultEventWriter
extended_inquiry_result_event()1155 extended_inquiry_result_event() {
1156 return extended_inquiry_result_event_.view();
1157 }
1158
eir_data()1159 MutableBufferView eir_data() {
1160 return MutableBufferView(extended_inquiry_result_event_.view()
1161 .extended_inquiry_response()
1162 .BackingStorage()
1163 .data(),
1164 extended_inquiry_result_event_.view()
1165 .extended_inquiry_response()
1166 .SizeInBytes());
1167 }
was_called() const1168 bool was_called() const { return was_called_; }
ClearWasCalled()1169 void ClearWasCalled() { was_called_ = false; }
1170
1171 private:
1172 bool was_called_;
1173 StaticPacket<pw::bluetooth::emboss::InquiryResultWriter> ir_;
1174 StaticPacket<pw::bluetooth::emboss::InquiryResultWithRssiWriter> irr_;
1175 StaticPacket<pw::bluetooth::emboss::ExtendedInquiryResultEventWriter>
1176 extended_inquiry_result_event_;
1177 };
1178
1179 using PeerCacheBrEdrUpdateCallbackTest =
1180 PeerCacheTest_UpdateCallbackTest<&kAddrBrEdr>;
1181 using PeerCacheLowEnergyUpdateCallbackTest =
1182 PeerCacheTest_UpdateCallbackTest<&kAddrLeAlias>;
1183
TEST_F(PeerCacheLowEnergyUpdateCallbackTest,ChangingLEConnectionStateTriggersUpdateCallback)1184 TEST_F(PeerCacheLowEnergyUpdateCallbackTest,
1185 ChangingLEConnectionStateTriggersUpdateCallback) {
1186 Peer::ConnectionToken conn_token = peer()->MutLe().RegisterConnection();
1187 EXPECT_TRUE(was_called());
1188 }
1189
TEST_F(PeerCacheLowEnergyUpdateCallbackTest,SetAdvertisingDataTriggersUpdateCallbackOnNameSet)1190 TEST_F(PeerCacheLowEnergyUpdateCallbackTest,
1191 SetAdvertisingDataTriggersUpdateCallbackOnNameSet) {
1192 peer()->MutLe().SetAdvertisingData(
1193 kTestRSSI, kAdvData, pw::chrono::SystemClock::time_point());
1194 EXPECT_TRUE(was_called());
1195 ASSERT_TRUE(peer()->name());
1196 EXPECT_EQ("Test", *peer()->name());
1197 EXPECT_EQ(Peer::NameSource::kAdvertisingDataComplete, *peer()->name_source());
1198 }
1199
TEST_F(PeerCacheLowEnergyUpdateCallbackTest,SetLowEnergyAdvertisingDataUpdateCallbackProvidesUpdatedPeer)1200 TEST_F(PeerCacheLowEnergyUpdateCallbackTest,
1201 SetLowEnergyAdvertisingDataUpdateCallbackProvidesUpdatedPeer) {
1202 ASSERT_NE(peer()->rssi(), kTestRSSI);
1203 cache()->add_peer_updated_callback([&](const auto& updated_peer) {
1204 ASSERT_TRUE(updated_peer.le());
1205 ASSERT_TRUE(updated_peer.name().has_value());
1206 EXPECT_EQ(updated_peer.name().value(), "Test");
1207 EXPECT_EQ(updated_peer.rssi(), kTestRSSI);
1208 });
1209 peer()->MutLe().SetAdvertisingData(
1210 kTestRSSI, kAdvData, pw::chrono::SystemClock::time_point());
1211 }
1212
TEST_F(PeerCacheLowEnergyUpdateCallbackTest,SetAdvertisingDataTriggersUpdateCallbackOnSameNameAndRssi)1213 TEST_F(PeerCacheLowEnergyUpdateCallbackTest,
1214 SetAdvertisingDataTriggersUpdateCallbackOnSameNameAndRssi) {
1215 peer()->MutLe().SetAdvertisingData(
1216 kTestRSSI, kAdvData, pw::chrono::SystemClock::time_point());
1217 ASSERT_TRUE(was_called());
1218
1219 ClearWasCalled();
1220 peer()->MutLe().SetAdvertisingData(
1221 kTestRSSI, kAdvData, pw::chrono::SystemClock::time_point());
1222 EXPECT_TRUE(was_called());
1223 }
1224
TEST_F(PeerCacheLowEnergyUpdateCallbackTest,SetLowEnergyConnectionParamsDoesNotTriggerUpdateCallback)1225 TEST_F(PeerCacheLowEnergyUpdateCallbackTest,
1226 SetLowEnergyConnectionParamsDoesNotTriggerUpdateCallback) {
1227 peer()->MutLe().SetConnectionParameters({});
1228 EXPECT_FALSE(was_called());
1229 }
1230
TEST_F(PeerCacheLowEnergyUpdateCallbackTest,SetLowEnergyPreferredConnectionParamsDoesNotTriggerUpdateCallback)1231 TEST_F(PeerCacheLowEnergyUpdateCallbackTest,
1232 SetLowEnergyPreferredConnectionParamsDoesNotTriggerUpdateCallback) {
1233 peer()->MutLe().SetPreferredConnectionParameters({});
1234 EXPECT_FALSE(was_called());
1235 }
1236
TEST_F(PeerCacheLowEnergyUpdateCallbackTest,BecomingDualModeTriggersUpdateCallBack)1237 TEST_F(PeerCacheLowEnergyUpdateCallbackTest,
1238 BecomingDualModeTriggersUpdateCallBack) {
1239 EXPECT_EQ(TechnologyType::kLowEnergy, peer()->technology());
1240
1241 size_t call_count = 0;
1242 cache()->add_peer_updated_callback([&](const auto&) { ++call_count; });
1243 peer()->MutBrEdr();
1244 EXPECT_EQ(TechnologyType::kDualMode, peer()->technology());
1245 EXPECT_EQ(call_count, 1U);
1246
1247 // Calling MutBrEdr again on doesn't trigger additional callbacks.
1248 peer()->MutBrEdr();
1249 EXPECT_EQ(call_count, 1U);
1250 peer()->MutBrEdr().SetInquiryData(extended_inquiry_result_event());
1251 EXPECT_EQ(call_count, 2U);
1252 }
1253
TEST_F(PeerCacheBrEdrUpdateCallbackTest,ChangingBrEdrConnectionStateTriggersUpdateCallback)1254 TEST_F(PeerCacheBrEdrUpdateCallbackTest,
1255 ChangingBrEdrConnectionStateTriggersUpdateCallback) {
1256 Peer::ConnectionToken token = peer()->MutBrEdr().RegisterConnection();
1257 EXPECT_TRUE(was_called());
1258 }
1259
TEST_F(PeerCacheBrEdrUpdateCallbackTest,SetBrEdrInquiryDataFromInquiryResultTriggersUpdateCallbackOnPeerClassSet)1260 TEST_F(
1261 PeerCacheBrEdrUpdateCallbackTest,
1262 SetBrEdrInquiryDataFromInquiryResultTriggersUpdateCallbackOnPeerClassSet) {
1263 ir().class_of_device().BackingStorage().WriteUInt(kTestDeviceClass.to_int());
1264 peer()->MutBrEdr().SetInquiryData(ir());
1265 EXPECT_TRUE(was_called());
1266 }
1267
TEST_F(PeerCacheBrEdrUpdateCallbackTest,SetBrEdrInquiryDataFromInquiryResultUpdateCallbackProvidesUpdatedPeer)1268 TEST_F(PeerCacheBrEdrUpdateCallbackTest,
1269 SetBrEdrInquiryDataFromInquiryResultUpdateCallbackProvidesUpdatedPeer) {
1270 ir().class_of_device().BackingStorage().WriteUInt(kTestDeviceClass.to_int());
1271 cache()->add_peer_updated_callback([](const auto& updated_peer) {
1272 ASSERT_TRUE(updated_peer.bredr());
1273 ASSERT_TRUE(updated_peer.bredr()->device_class());
1274 EXPECT_EQ(DeviceClass::MajorClass(0x02),
1275 updated_peer.bredr()->device_class()->major_class());
1276 });
1277 peer()->MutBrEdr().SetInquiryData(ir());
1278 }
1279
TEST_F(PeerCacheBrEdrUpdateCallbackTest,SetBrEdrInquiryDataFromInquiryResultDoesNotTriggerUpdateCallbackOnSameDeviceClass)1280 TEST_F(
1281 PeerCacheBrEdrUpdateCallbackTest,
1282 SetBrEdrInquiryDataFromInquiryResultDoesNotTriggerUpdateCallbackOnSameDeviceClass) {
1283 ir().class_of_device().BackingStorage().WriteUInt(kTestDeviceClass.to_int());
1284 peer()->MutBrEdr().SetInquiryData(ir());
1285 ASSERT_TRUE(was_called());
1286
1287 ClearWasCalled();
1288 peer()->MutBrEdr().SetInquiryData(ir());
1289 EXPECT_FALSE(was_called());
1290 }
1291
TEST_F(PeerCacheBrEdrUpdateCallbackTest,SetBrEdrInquiryDataFromInquiryResultRSSITriggersUpdateCallbackOnDeviceClassSet)1292 TEST_F(
1293 PeerCacheBrEdrUpdateCallbackTest,
1294 SetBrEdrInquiryDataFromInquiryResultRSSITriggersUpdateCallbackOnDeviceClassSet) {
1295 irr().class_of_device().major_device_class().Write(
1296 pw::bluetooth::emboss::MajorDeviceClass::PHONE);
1297 peer()->MutBrEdr().SetInquiryData(irr());
1298 EXPECT_TRUE(was_called());
1299 }
1300
TEST_F(PeerCacheBrEdrUpdateCallbackTest,SetBrEdrInquiryDataFromInquiryResultRSSIUpdateCallbackProvidesUpdatedPeer)1301 TEST_F(
1302 PeerCacheBrEdrUpdateCallbackTest,
1303 SetBrEdrInquiryDataFromInquiryResultRSSIUpdateCallbackProvidesUpdatedPeer) {
1304 irr().class_of_device().major_device_class().Write(
1305 pw::bluetooth::emboss::MajorDeviceClass::PHONE);
1306 cache()->add_peer_updated_callback([](const auto& updated_peer) {
1307 ASSERT_TRUE(updated_peer.bredr()->device_class());
1308 EXPECT_EQ(DeviceClass::MajorClass::kPhone,
1309 updated_peer.bredr()->device_class()->major_class());
1310 });
1311 peer()->MutBrEdr().SetInquiryData(irr());
1312 }
1313
TEST_F(PeerCacheBrEdrUpdateCallbackTest,SetBrEdrInquiryDataFromInquiryResultRSSIDoesNotTriggerUpdateCallbackOnSameDeviceClass)1314 TEST_F(
1315 PeerCacheBrEdrUpdateCallbackTest,
1316 SetBrEdrInquiryDataFromInquiryResultRSSIDoesNotTriggerUpdateCallbackOnSameDeviceClass) {
1317 irr().class_of_device().major_device_class().Write(
1318 pw::bluetooth::emboss::MajorDeviceClass::PHONE);
1319 peer()->MutBrEdr().SetInquiryData(irr());
1320 ASSERT_TRUE(was_called());
1321
1322 ClearWasCalled();
1323 peer()->MutBrEdr().SetInquiryData(irr());
1324 EXPECT_FALSE(was_called());
1325 }
1326
TEST_F(PeerCacheBrEdrUpdateCallbackTest,SetBrEdrInquiryDataFromInquiryResultRSSIDoesNotTriggerUpdateCallbackOnRSSI)1327 TEST_F(
1328 PeerCacheBrEdrUpdateCallbackTest,
1329 SetBrEdrInquiryDataFromInquiryResultRSSIDoesNotTriggerUpdateCallbackOnRSSI) {
1330 irr().rssi().Write(1);
1331 peer()->MutBrEdr().SetInquiryData(irr());
1332 ASSERT_TRUE(was_called()); // Callback due to |class_of_device|.
1333
1334 ClearWasCalled();
1335 irr().rssi().Write(20);
1336 peer()->MutBrEdr().SetInquiryData(irr());
1337 EXPECT_FALSE(was_called());
1338 }
1339
TEST_F(PeerCacheBrEdrUpdateCallbackTest,SetBrEdrInquiryDataFromExtendedInquiryResultEventParamsTriggersUpdateCallbackOnDeviceClassSet)1340 TEST_F(
1341 PeerCacheBrEdrUpdateCallbackTest,
1342 SetBrEdrInquiryDataFromExtendedInquiryResultEventParamsTriggersUpdateCallbackOnDeviceClassSet) {
1343 extended_inquiry_result_event().class_of_device().major_device_class().Write(
1344 pw::bluetooth::emboss::MajorDeviceClass::PHONE);
1345 peer()->MutBrEdr().SetInquiryData(extended_inquiry_result_event());
1346 EXPECT_TRUE(was_called());
1347 }
1348
TEST_F(PeerCacheBrEdrUpdateCallbackTest,SetBrEdrInquiryDataFromExtendedInquiryResultEventParamsTriggersUpdateCallbackOnNameSet)1349 TEST_F(
1350 PeerCacheBrEdrUpdateCallbackTest,
1351 SetBrEdrInquiryDataFromExtendedInquiryResultEventParamsTriggersUpdateCallbackOnNameSet) {
1352 peer()->MutBrEdr().SetInquiryData(extended_inquiry_result_event());
1353 ASSERT_TRUE(was_called()); // Callback due to |class_of_device|.
1354
1355 ClearWasCalled();
1356 eir_data().Write(kEirData);
1357 peer()->MutBrEdr().SetInquiryData(extended_inquiry_result_event());
1358 EXPECT_TRUE(was_called());
1359 }
1360
TEST_F(PeerCacheBrEdrUpdateCallbackTest,SetBrEdrInquiryDataFromExtendedInquiryResultEventParamsUpdateCallbackProvidesUpdatedPeer)1361 TEST_F(
1362 PeerCacheBrEdrUpdateCallbackTest,
1363 SetBrEdrInquiryDataFromExtendedInquiryResultEventParamsUpdateCallbackProvidesUpdatedPeer) {
1364 extended_inquiry_result_event().clock_offset().valid().Write(true);
1365 extended_inquiry_result_event().clock_offset().clock_offset().Write(1);
1366 extended_inquiry_result_event().page_scan_repetition_mode().Write(
1367 pw::bluetooth::emboss::PageScanRepetitionMode::R1_);
1368 extended_inquiry_result_event().rssi().Write(kTestRSSI);
1369 extended_inquiry_result_event().class_of_device().major_device_class().Write(
1370 pw::bluetooth::emboss::MajorDeviceClass::PHONE);
1371 eir_data().Write(kEirData);
1372 ASSERT_FALSE(peer()->name().has_value());
1373 ASSERT_EQ(peer()->rssi(), hci_spec::kRSSIInvalid);
1374 cache()->add_peer_updated_callback([](const auto& updated_peer) {
1375 const auto& data = updated_peer.bredr();
1376 ASSERT_TRUE(data);
1377 ASSERT_TRUE(data->clock_offset().has_value());
1378 ASSERT_TRUE(data->page_scan_repetition_mode().has_value());
1379 ASSERT_TRUE(data->device_class().has_value());
1380 ASSERT_TRUE(updated_peer.name().has_value());
1381
1382 EXPECT_EQ(*data->clock_offset(), 0x01);
1383 EXPECT_EQ(*data->page_scan_repetition_mode(),
1384 pw::bluetooth::emboss::PageScanRepetitionMode::R1_);
1385 EXPECT_EQ(DeviceClass::MajorClass(0x02),
1386 updated_peer.bredr()->device_class()->major_class());
1387 EXPECT_EQ(updated_peer.rssi(), kTestRSSI);
1388 EXPECT_EQ(*updated_peer.name(), "Test");
1389 EXPECT_EQ(*updated_peer.name_source(),
1390 Peer::NameSource::kInquiryResultComplete);
1391 });
1392 peer()->MutBrEdr().SetInquiryData(extended_inquiry_result_event());
1393 }
1394
TEST_F(PeerCacheBrEdrUpdateCallbackTest,SetBrEdrInquiryDataFromExtendedInquiryResultEventParamsGeneratesExactlyOneUpdateCallbackRegardlessOfNumberOfFieldsChanged)1395 TEST_F(
1396 PeerCacheBrEdrUpdateCallbackTest,
1397 SetBrEdrInquiryDataFromExtendedInquiryResultEventParamsGeneratesExactlyOneUpdateCallbackRegardlessOfNumberOfFieldsChanged) {
1398 extended_inquiry_result_event().clock_offset().valid().Write(true);
1399 extended_inquiry_result_event().clock_offset().clock_offset().Write(1);
1400 extended_inquiry_result_event().page_scan_repetition_mode().Write(
1401 pw::bluetooth::emboss::PageScanRepetitionMode::R1_);
1402 extended_inquiry_result_event().rssi().Write(kTestRSSI);
1403 extended_inquiry_result_event().class_of_device().major_device_class().Write(
1404 pw::bluetooth::emboss::MajorDeviceClass::PHONE);
1405
1406 size_t call_count = 0;
1407 cache()->add_peer_updated_callback([&](const auto&) { ++call_count; });
1408 peer()->MutBrEdr().SetInquiryData(extended_inquiry_result_event());
1409 EXPECT_EQ(call_count, 1U);
1410 }
1411
TEST_F(PeerCacheBrEdrUpdateCallbackTest,SetBrEdrInquiryDataFromExtendedInquiryResultEventParamsDoesNotTriggerUpdateCallbackOnSamePeerClass)1412 TEST_F(
1413 PeerCacheBrEdrUpdateCallbackTest,
1414 SetBrEdrInquiryDataFromExtendedInquiryResultEventParamsDoesNotTriggerUpdateCallbackOnSamePeerClass) {
1415 extended_inquiry_result_event().class_of_device().major_device_class().Write(
1416 pw::bluetooth::emboss::MajorDeviceClass::PHONE);
1417 peer()->MutBrEdr().SetInquiryData(extended_inquiry_result_event());
1418 ASSERT_TRUE(was_called());
1419
1420 ClearWasCalled();
1421 peer()->MutBrEdr().SetInquiryData(extended_inquiry_result_event());
1422 EXPECT_FALSE(was_called());
1423 }
1424
TEST_F(PeerCacheBrEdrUpdateCallbackTest,SetBrEdrInquiryDataFromExtendedInquiryResultEventParamsDoesNotTriggerUpdateCallbackOnSameName)1425 TEST_F(
1426 PeerCacheBrEdrUpdateCallbackTest,
1427 SetBrEdrInquiryDataFromExtendedInquiryResultEventParamsDoesNotTriggerUpdateCallbackOnSameName) {
1428 eir_data().Write(kEirData);
1429 peer()->MutBrEdr().SetInquiryData(extended_inquiry_result_event());
1430 ASSERT_TRUE(was_called());
1431
1432 ClearWasCalled();
1433 peer()->MutBrEdr().SetInquiryData(extended_inquiry_result_event());
1434 EXPECT_FALSE(was_called());
1435 }
1436
TEST_F(PeerCacheBrEdrUpdateCallbackTest,SetBrEdrInquiryDataFromExtendedInquiryResultEventParamsDoesNotTriggerUpdateCallbackOnRSSI)1437 TEST_F(
1438 PeerCacheBrEdrUpdateCallbackTest,
1439 SetBrEdrInquiryDataFromExtendedInquiryResultEventParamsDoesNotTriggerUpdateCallbackOnRSSI) {
1440 extended_inquiry_result_event().rssi().Write(1);
1441 peer()->MutBrEdr().SetInquiryData(extended_inquiry_result_event());
1442 ASSERT_TRUE(was_called()); // Callback due to |class_of_device|.
1443
1444 ClearWasCalled();
1445 extended_inquiry_result_event().rssi().Write(20);
1446 peer()->MutBrEdr().SetInquiryData(extended_inquiry_result_event());
1447 EXPECT_FALSE(was_called());
1448 }
1449
TEST_F(PeerCacheBrEdrUpdateCallbackTest,RegisterNameTriggersUpdateCallback)1450 TEST_F(PeerCacheBrEdrUpdateCallbackTest, RegisterNameTriggersUpdateCallback) {
1451 peer()->RegisterName("nombre");
1452 EXPECT_TRUE(was_called());
1453 }
1454
TEST_F(PeerCacheBrEdrUpdateCallbackTest,RegisterNameDoesNotTriggerUpdateCallbackOnSameName)1455 TEST_F(PeerCacheBrEdrUpdateCallbackTest,
1456 RegisterNameDoesNotTriggerUpdateCallbackOnSameName) {
1457 peer()->RegisterName("nombre");
1458 ASSERT_TRUE(was_called());
1459
1460 bool was_called_again = false;
1461 cache()->add_peer_updated_callback(
1462 [&](const auto&) { was_called_again = true; });
1463 peer()->RegisterName("nombre");
1464 EXPECT_FALSE(was_called_again);
1465 }
1466
TEST_F(PeerCacheBrEdrUpdateCallbackTest,BecomingDualModeTriggersUpdateCallBack)1467 TEST_F(PeerCacheBrEdrUpdateCallbackTest,
1468 BecomingDualModeTriggersUpdateCallBack) {
1469 EXPECT_EQ(TechnologyType::kClassic, peer()->technology());
1470
1471 size_t call_count = 0;
1472 cache()->add_peer_updated_callback([&](const auto&) { ++call_count; });
1473 peer()->MutLe();
1474 EXPECT_EQ(TechnologyType::kDualMode, peer()->technology());
1475 EXPECT_EQ(call_count, 1U);
1476
1477 // Calling MutLe again doesn't trigger additional callbacks.
1478 peer()->MutLe();
1479 EXPECT_EQ(call_count, 1U);
1480 peer()->MutLe().SetAdvertisingData(
1481 kTestRSSI, kAdvData, pw::chrono::SystemClock::time_point());
1482 EXPECT_EQ(call_count, 2U);
1483 }
1484
1485 class PeerCacheExpirationTest : public pw::async::test::FakeDispatcherFixture {
1486 public:
1487 PeerCacheExpirationTest() = default;
SetUp()1488 void SetUp() override {
1489 cache_.set_peer_removed_callback([this](PeerId) { peers_removed_++; });
1490 auto* peer = cache_.NewPeer(kAddrLeAlias, /*connectable=*/true);
1491 ASSERT_TRUE(peer);
1492 ASSERT_TRUE(peer->temporary());
1493 peer_addr_ = peer->address();
1494 peer_addr_alias_ = kAddrBrEdr;
1495 peer_id_ = peer->identifier();
1496 peers_removed_ = 0;
1497 }
1498
TearDown()1499 void TearDown() override {
1500 cache_.set_peer_removed_callback(nullptr);
1501 RunUntilIdle();
1502 }
1503
GetDefaultPeer()1504 Peer* GetDefaultPeer() { return cache_.FindById(peer_id_); }
GetPeerById(PeerId id)1505 Peer* GetPeerById(PeerId id) { return cache_.FindById(id); }
IsDefaultPeerAddressInCache() const1506 bool IsDefaultPeerAddressInCache() const {
1507 return cache_.FindByAddress(peer_addr_);
1508 }
IsOtherTransportAddressInCache() const1509 bool IsOtherTransportAddressInCache() const {
1510 return cache_.FindByAddress(peer_addr_alias_);
1511 }
IsDefaultPeerPresent()1512 bool IsDefaultPeerPresent() { return GetDefaultPeer(); }
NewPeer(const DeviceAddress & address,bool connectable)1513 Peer* NewPeer(const DeviceAddress& address, bool connectable) {
1514 return cache_.NewPeer(address, connectable);
1515 }
peers_removed() const1516 int peers_removed() const { return peers_removed_; }
1517
1518 private:
1519 PeerCache cache_{dispatcher()};
1520 DeviceAddress peer_addr_;
1521 DeviceAddress peer_addr_alias_;
1522 PeerId peer_id_;
1523 int peers_removed_;
1524 };
1525
TEST_F(PeerCacheExpirationTest,TemporaryDiesSixtySecondsAfterBirth)1526 TEST_F(PeerCacheExpirationTest, TemporaryDiesSixtySecondsAfterBirth) {
1527 RunFor(kCacheTimeout);
1528 EXPECT_FALSE(IsDefaultPeerPresent());
1529 EXPECT_EQ(1, peers_removed());
1530 }
1531
TEST_F(PeerCacheExpirationTest,TemporaryLivesForSixtySecondsAfterBirth)1532 TEST_F(PeerCacheExpirationTest, TemporaryLivesForSixtySecondsAfterBirth) {
1533 RunFor(kCacheTimeout - std::chrono::milliseconds(1));
1534 EXPECT_TRUE(IsDefaultPeerPresent());
1535 EXPECT_EQ(0, peers_removed());
1536 }
1537
TEST_F(PeerCacheExpirationTest,TemporaryLivesForSixtySecondsSinceLastSeen)1538 TEST_F(PeerCacheExpirationTest, TemporaryLivesForSixtySecondsSinceLastSeen) {
1539 RunFor(kCacheTimeout - std::chrono::milliseconds(1));
1540 ASSERT_TRUE(IsDefaultPeerPresent());
1541
1542 // Tickle peer, and verify it sticks around for another cache timeout.
1543 GetDefaultPeer()->RegisterName("nombre");
1544 RunFor(kCacheTimeout - std::chrono::milliseconds(1));
1545 EXPECT_TRUE(IsDefaultPeerPresent());
1546 }
1547
TEST_F(PeerCacheExpirationTest,TemporaryDiesSixtySecondsAfterLastSeen)1548 TEST_F(PeerCacheExpirationTest, TemporaryDiesSixtySecondsAfterLastSeen) {
1549 RunFor(kCacheTimeout - std::chrono::milliseconds(1));
1550 ASSERT_TRUE(IsDefaultPeerPresent());
1551
1552 // Tickle peer, and verify it expires after cache timeout.
1553 GetDefaultPeer()->RegisterName("nombre");
1554 RunFor(kCacheTimeout);
1555 EXPECT_FALSE(IsDefaultPeerPresent());
1556 }
1557
TEST_F(PeerCacheExpirationTest,CanMakeNonTemporaryJustBeforeSixtySeconds)1558 TEST_F(PeerCacheExpirationTest, CanMakeNonTemporaryJustBeforeSixtySeconds) {
1559 // At last possible moment, make peer non-temporary,
1560 RunFor(kCacheTimeout - std::chrono::milliseconds(1));
1561 ASSERT_TRUE(IsDefaultPeerPresent());
1562 Peer::ConnectionToken conn_token =
1563 GetDefaultPeer()->MutLe().RegisterConnection();
1564 ASSERT_FALSE(GetDefaultPeer()->temporary());
1565
1566 // Verify that the peer survives.
1567 RunFor(kCacheTimeout * 10);
1568 EXPECT_TRUE(IsDefaultPeerPresent());
1569 }
1570
TEST_F(PeerCacheExpirationTest,LEConnectedPeerLivesMuchMoreThanSixtySeconds)1571 TEST_F(PeerCacheExpirationTest, LEConnectedPeerLivesMuchMoreThanSixtySeconds) {
1572 ASSERT_TRUE(IsDefaultPeerPresent());
1573 Peer::ConnectionToken conn_token =
1574 GetDefaultPeer()->MutLe().RegisterConnection();
1575 RunFor(kCacheTimeout * 10);
1576 ASSERT_TRUE(IsDefaultPeerPresent());
1577 EXPECT_FALSE(GetDefaultPeer()->temporary());
1578 }
1579
TEST_F(PeerCacheExpirationTest,BREDRConnectedPeerLivesMuchMoreThanSixtySeconds)1580 TEST_F(PeerCacheExpirationTest,
1581 BREDRConnectedPeerLivesMuchMoreThanSixtySeconds) {
1582 ASSERT_TRUE(IsDefaultPeerPresent());
1583 Peer::ConnectionToken token =
1584 GetDefaultPeer()->MutBrEdr().RegisterConnection();
1585 RunFor(kCacheTimeout * 10);
1586 ASSERT_TRUE(IsDefaultPeerPresent());
1587 EXPECT_FALSE(GetDefaultPeer()->temporary());
1588 }
1589
TEST_F(PeerCacheExpirationTest,LePeerBecomesNonTemporaryWhenConnecting)1590 TEST_F(PeerCacheExpirationTest, LePeerBecomesNonTemporaryWhenConnecting) {
1591 ASSERT_TRUE(IsDefaultPeerPresent());
1592 ASSERT_EQ(kAddrLeAlias, GetDefaultPeer()->address());
1593 ASSERT_TRUE(GetDefaultPeer()->temporary());
1594
1595 Peer::InitializingConnectionToken init_token =
1596 GetDefaultPeer()->MutLe().RegisterInitializingConnection();
1597 EXPECT_FALSE(GetDefaultPeer()->temporary());
1598
1599 RunFor(kCacheTimeout);
1600 ASSERT_TRUE(IsDefaultPeerPresent());
1601 }
1602
TEST_F(PeerCacheExpirationTest,LEPublicPeerRemainsNonTemporaryOnDisconnect)1603 TEST_F(PeerCacheExpirationTest, LEPublicPeerRemainsNonTemporaryOnDisconnect) {
1604 ASSERT_TRUE(IsDefaultPeerPresent());
1605 ASSERT_EQ(kAddrLeAlias, GetDefaultPeer()->address());
1606 {
1607 Peer::ConnectionToken conn_token =
1608 GetDefaultPeer()->MutLe().RegisterConnection();
1609 ASSERT_FALSE(GetDefaultPeer()->temporary());
1610
1611 RunFor(kCacheTimeout + std::chrono::seconds(1));
1612 ASSERT_TRUE(IsDefaultPeerPresent());
1613 ASSERT_TRUE(GetDefaultPeer()->identity_known());
1614 // Destroy conn_token at end of scope
1615 }
1616 EXPECT_FALSE(GetDefaultPeer()->temporary());
1617
1618 RunFor(kCacheTimeout);
1619 EXPECT_TRUE(IsDefaultPeerPresent());
1620 }
1621
TEST_F(PeerCacheExpirationTest,LERandomPeerBecomesTemporaryOnDisconnect)1622 TEST_F(PeerCacheExpirationTest, LERandomPeerBecomesTemporaryOnDisconnect) {
1623 // Create our Peer, and get it into the kConnected state.
1624 PeerId custom_peer_id;
1625 std::optional<Peer::ConnectionToken> conn_token;
1626 {
1627 auto* custom_peer = NewPeer(kAddrLeRandom, /*connectable=*/true);
1628 ASSERT_TRUE(custom_peer);
1629 ASSERT_TRUE(custom_peer->temporary());
1630 ASSERT_FALSE(custom_peer->identity_known());
1631 custom_peer_id = custom_peer->identifier();
1632
1633 conn_token = custom_peer->MutLe().RegisterConnection();
1634 ASSERT_FALSE(custom_peer->temporary());
1635 ASSERT_FALSE(custom_peer->identity_known());
1636 }
1637
1638 // Verify that the connected peer does not expire out of the cache.
1639 // Then disconnect the peer, in preparation for the next stage of our test.
1640 {
1641 EXPECT_EQ(0, peers_removed());
1642 RunFor(std::chrono::seconds(61));
1643 EXPECT_EQ(1, peers_removed()); // Default peer timed out.
1644 auto* custom_peer = GetPeerById(custom_peer_id);
1645 ASSERT_TRUE(custom_peer);
1646 ASSERT_FALSE(custom_peer->identity_known());
1647
1648 conn_token.reset();
1649 EXPECT_TRUE(custom_peer->temporary());
1650 EXPECT_FALSE(custom_peer->identity_known());
1651 }
1652
1653 // Verify that the disconnected peer expires out of the cache.
1654 RunFor(std::chrono::seconds(61));
1655 EXPECT_FALSE(GetPeerById(custom_peer_id));
1656 EXPECT_EQ(2, peers_removed());
1657 }
1658
TEST_F(PeerCacheExpirationTest,BrEdrPeerRemainsNonTemporaryOnDisconnect)1659 TEST_F(PeerCacheExpirationTest, BrEdrPeerRemainsNonTemporaryOnDisconnect) {
1660 // Create our Peer, and get it into the kConnected state.
1661 PeerId custom_peer_id;
1662 std::optional<Peer::ConnectionToken> conn_token;
1663 {
1664 auto* custom_peer = NewPeer(kAddrLePublic, /*connectable=*/true);
1665 ASSERT_TRUE(custom_peer);
1666 conn_token = custom_peer->MutLe().RegisterConnection();
1667 custom_peer_id = custom_peer->identifier();
1668 }
1669
1670 // Verify that the connected peer does not expire out of the cache.
1671 // Then disconnect the peer, in preparation for the next stage of our test.
1672 {
1673 EXPECT_EQ(0, peers_removed());
1674 RunFor(kCacheTimeout * 10);
1675 EXPECT_EQ(1, peers_removed()); // Default peer timed out.
1676 auto* custom_peer = GetPeerById(custom_peer_id);
1677 ASSERT_TRUE(custom_peer);
1678 ASSERT_TRUE(custom_peer->identity_known());
1679 EXPECT_FALSE(custom_peer->temporary());
1680
1681 conn_token.reset();
1682 ASSERT_TRUE(GetPeerById(custom_peer_id));
1683 EXPECT_FALSE(custom_peer->temporary());
1684 }
1685
1686 // Verify that the disconnected peer does _not_ expire out of the cache.
1687 // We expect the peer to remain, because BrEdr peers are non-temporary
1688 // even when disconnected.
1689 RunFor(kCacheTimeout);
1690 EXPECT_TRUE(GetPeerById(custom_peer_id));
1691 EXPECT_EQ(1, peers_removed());
1692 }
1693
TEST_F(PeerCacheExpirationTest,ExpirationUpdatesAddressMap)1694 TEST_F(PeerCacheExpirationTest, ExpirationUpdatesAddressMap) {
1695 ASSERT_TRUE(IsDefaultPeerAddressInCache());
1696 ASSERT_TRUE(IsOtherTransportAddressInCache());
1697 RunFor(kCacheTimeout);
1698 EXPECT_FALSE(IsDefaultPeerAddressInCache());
1699 EXPECT_FALSE(IsOtherTransportAddressInCache());
1700 }
1701
TEST_F(PeerCacheExpirationTest,SetAdvertisingDataUpdatesExpiration)1702 TEST_F(PeerCacheExpirationTest, SetAdvertisingDataUpdatesExpiration) {
1703 RunFor(kCacheTimeout - std::chrono::milliseconds(1));
1704 ASSERT_TRUE(IsDefaultPeerPresent());
1705 GetDefaultPeer()->MutLe().SetAdvertisingData(
1706 kTestRSSI, StaticByteBuffer<1>{}, pw::chrono::SystemClock::time_point());
1707 RunFor(kCacheTimeout - std::chrono::milliseconds(1));
1708 EXPECT_TRUE(IsDefaultPeerPresent());
1709 // Setting advertising data with the same rssi & name should also update the
1710 // expiry.
1711 GetDefaultPeer()->MutLe().SetAdvertisingData(
1712 kTestRSSI, StaticByteBuffer<1>{}, pw::chrono::SystemClock::time_point());
1713 RunFor(std::chrono::milliseconds(1));
1714 EXPECT_TRUE(IsDefaultPeerPresent());
1715 }
1716
TEST_F(PeerCacheExpirationTest,SetBrEdrInquiryDataFromInquiryResultUpdatesExpiration)1717 TEST_F(PeerCacheExpirationTest,
1718 SetBrEdrInquiryDataFromInquiryResultUpdatesExpiration) {
1719 StaticPacket<pw::bluetooth::emboss::InquiryResultWriter> ir;
1720 ASSERT_TRUE(IsDefaultPeerPresent());
1721 ir.view().bd_addr().CopyFrom(GetDefaultPeer()->address().value().view());
1722
1723 RunFor(kCacheTimeout - std::chrono::milliseconds(1));
1724 ASSERT_TRUE(IsDefaultPeerPresent());
1725 GetDefaultPeer()->MutBrEdr().SetInquiryData(ir.view());
1726
1727 RunFor(std::chrono::milliseconds(1));
1728 EXPECT_TRUE(IsDefaultPeerPresent());
1729 }
1730
TEST_F(PeerCacheExpirationTest,SetBrEdrInquiryDataFromInquiryResultRSSIUpdatesExpiration)1731 TEST_F(PeerCacheExpirationTest,
1732 SetBrEdrInquiryDataFromInquiryResultRSSIUpdatesExpiration) {
1733 StaticPacket<pw::bluetooth::emboss::InquiryResultWithRssiWriter> irr;
1734 ASSERT_TRUE(IsDefaultPeerPresent());
1735 irr.view().bd_addr().CopyFrom(GetDefaultPeer()->address().value().view());
1736
1737 RunFor(kCacheTimeout - std::chrono::milliseconds(1));
1738 ASSERT_TRUE(IsDefaultPeerPresent());
1739 GetDefaultPeer()->MutBrEdr().SetInquiryData(irr.view());
1740
1741 RunFor(std::chrono::milliseconds(1));
1742 EXPECT_TRUE(IsDefaultPeerPresent());
1743 }
1744
TEST_F(PeerCacheExpirationTest,SetBrEdrInquiryDataFromExtendedInquiryResultEventParamsUpdatesExpiration)1745 TEST_F(
1746 PeerCacheExpirationTest,
1747 SetBrEdrInquiryDataFromExtendedInquiryResultEventParamsUpdatesExpiration) {
1748 StaticPacket<pw::bluetooth::emboss::ExtendedInquiryResultEventWriter> event;
1749 ASSERT_TRUE(IsDefaultPeerPresent());
1750 event.view().bd_addr().CopyFrom(GetDefaultPeer()->address().value().view());
1751
1752 RunFor(kCacheTimeout - std::chrono::milliseconds(1));
1753 ASSERT_TRUE(IsDefaultPeerPresent());
1754 GetDefaultPeer()->MutBrEdr().SetInquiryData(event.view());
1755
1756 RunFor(std::chrono::milliseconds(1));
1757 EXPECT_TRUE(IsDefaultPeerPresent());
1758 }
1759
TEST_F(PeerCacheExpirationTest,RegisterNameUpdatesExpiration)1760 TEST_F(PeerCacheExpirationTest, RegisterNameUpdatesExpiration) {
1761 RunFor(kCacheTimeout - std::chrono::milliseconds(1));
1762 ASSERT_TRUE(IsDefaultPeerPresent());
1763 GetDefaultPeer()->RegisterName({});
1764 RunFor(std::chrono::milliseconds(1));
1765 EXPECT_TRUE(IsDefaultPeerPresent());
1766 }
1767
1768 } // namespace
1769 } // namespace bt::gap
1770