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 PeerId kId(5);
678 sm::PairingData data;
679
680 EXPECT_TRUE(
681 cache()->AddBondedPeer(BondingData{.identifier = kId,
682 .address = kAddrBrEdr,
683 .name = {},
684 .le_pairing_data = data,
685 .bredr_link_key = kBrEdrKey,
686 .bredr_services = kBrEdrServices}));
687 auto* peer = cache()->FindById(kId);
688 ASSERT_TRUE(peer);
689 EXPECT_EQ(peer, cache()->FindByAddress(kAddrBrEdr));
690 EXPECT_EQ(kId, peer->identifier());
691 EXPECT_EQ(kAddrBrEdr, peer->address());
692 ASSERT_FALSE(peer->name());
693 EXPECT_TRUE(peer->identity_known());
694 ASSERT_TRUE(peer->bredr());
695 EXPECT_TRUE(peer->bredr()->bonded());
696 ASSERT_TRUE(peer->bredr()->link_key());
697 EXPECT_EQ(kBrEdrKey, *peer->bredr()->link_key());
698 EXPECT_THAT(peer->bredr()->services(),
699 testing::UnorderedElementsAreArray(kBrEdrServices));
700 EXPECT_FALSE(peer->le());
701 EXPECT_EQ(TechnologyType::kClassic, peer->technology());
702
703 // The "new bond" callback should not be called when restoring a previously
704 // bonded peer.
705 EXPECT_FALSE(bonded_callback_called());
706 }
707
TEST_F(PeerCacheTest,AddBondedPeerWithIrkIsAddedToResolvingList)708 TEST_F(PeerCacheTest, AddBondedPeerWithIrkIsAddedToResolvingList) {
709 sm::PairingData data;
710 data.peer_ltk = kLTK;
711 data.local_ltk = kLTK;
712 data.irk = sm::Key(sm::SecurityProperties(), Random<UInt128>());
713 data.identity_address = kAddrLeRandom;
714
715 EXPECT_TRUE(cache()->AddBondedPeer(BondingData{.identifier = kId,
716 .address = kAddrLeRandom,
717 .name = {},
718 .le_pairing_data = data,
719 .bredr_link_key = {},
720 .bredr_services = {}}));
721 auto* peer = cache()->FindByAddress(kAddrLeRandom);
722 ASSERT_TRUE(peer);
723 EXPECT_EQ(kAddrLeRandom, peer->address());
724
725 // Looking up the peer by RPA generated using the IRK should return the same
726 // peer.
727 DeviceAddress rpa = sm::util::GenerateRpa(data.irk->value());
728 EXPECT_EQ(peer, cache()->FindByAddress(rpa));
729 }
730
TEST_F(PeerCacheTest,AddBondedPeerWithIrkButWithoutIdentityAddressPanics)731 TEST_F(PeerCacheTest, AddBondedPeerWithIrkButWithoutIdentityAddressPanics) {
732 sm::PairingData data;
733 data.peer_ltk = kLTK;
734 data.local_ltk = kLTK;
735 data.irk = sm::Key(sm::SecurityProperties(), Random<UInt128>());
736
737 EXPECT_DEATH_IF_SUPPORTED(
738 cache()->AddBondedPeer(BondingData{.identifier = kId,
739 .address = kAddrLeRandom,
740 .name = {},
741 .le_pairing_data = data,
742 .bredr_link_key = {},
743 .bredr_services = {}}),
744 ".*identity_address.*");
745 }
746
TEST_F(PeerCacheTest,StoreLowEnergyBondWithIrkButWithoutIdentityAddressPanics)747 TEST_F(PeerCacheTest,
748 StoreLowEnergyBondWithIrkButWithoutIdentityAddressPanics) {
749 sm::PairingData data;
750 data.peer_ltk = kLTK;
751 data.local_ltk = kLTK;
752 data.irk = sm::Key(sm::SecurityProperties(), Random<UInt128>());
753
754 EXPECT_DEATH_IF_SUPPORTED(cache()->StoreLowEnergyBond(kId, data),
755 ".*identity_address.*");
756 }
757
TEST_F(PeerCacheTestBondingTest,StoreLowEnergyBondFailsWithNoKeys)758 TEST_F(PeerCacheTestBondingTest, StoreLowEnergyBondFailsWithNoKeys) {
759 sm::PairingData data;
760 EXPECT_FALSE(cache()->StoreLowEnergyBond(peer()->identifier(), data));
761 }
762
TEST_F(PeerCacheTestBondingTest,StoreLowEnergyBondPeerUnknown)763 TEST_F(PeerCacheTestBondingTest, StoreLowEnergyBondPeerUnknown) {
764 sm::PairingData data;
765 data.peer_ltk = kLTK;
766 data.local_ltk = kLTK;
767 EXPECT_FALSE(cache()->StoreLowEnergyBond(kId, data));
768 }
769
TEST_F(PeerCacheTestBondingTest,StoreLowEnergyBondWithLtk)770 TEST_F(PeerCacheTestBondingTest, StoreLowEnergyBondWithLtk) {
771 ASSERT_TRUE(peer()->temporary());
772 ASSERT_TRUE(peer()->le());
773 ASSERT_FALSE(peer()->le()->bonded());
774
775 sm::PairingData data;
776 data.peer_ltk = kLTK;
777 data.local_ltk = kLTK;
778 EXPECT_TRUE(cache()->StoreLowEnergyBond(peer()->identifier(), data));
779
780 EXPECT_TRUE(bonded_callback_called());
781 EXPECT_FALSE(peer()->temporary());
782 EXPECT_TRUE(peer()->le()->bonded());
783 EXPECT_TRUE(peer()->le()->bond_data());
784 EXPECT_EQ(data, *peer()->le()->bond_data());
785 }
786
TEST_F(PeerCacheTestBondingTest,StoreLowEnergyBondWithCsrk)787 TEST_F(PeerCacheTestBondingTest, StoreLowEnergyBondWithCsrk) {
788 ASSERT_TRUE(peer()->temporary());
789 ASSERT_TRUE(peer()->le());
790 ASSERT_FALSE(peer()->le()->bonded());
791
792 sm::PairingData data;
793 data.csrk = kKey;
794 EXPECT_TRUE(cache()->StoreLowEnergyBond(peer()->identifier(), data));
795
796 EXPECT_TRUE(bonded_callback_called());
797 EXPECT_FALSE(peer()->temporary());
798 EXPECT_TRUE(peer()->le()->bonded());
799 EXPECT_TRUE(peer()->le()->bond_data());
800 EXPECT_EQ(data, *peer()->le()->bond_data());
801 }
802
803 // StoreLowEnergyBond fails if it contains the address of a different,
804 // previously known peer.
TEST_F(PeerCacheTestBondingTest,StoreLowEnergyBondWithExistingDifferentIdentity)805 TEST_F(PeerCacheTestBondingTest,
806 StoreLowEnergyBondWithExistingDifferentIdentity) {
807 auto* p = cache()->NewPeer(kAddrLeRandom, /*connectable=*/true);
808
809 // Assign the other peer's address as identity.
810 sm::PairingData data;
811 data.peer_ltk = kLTK;
812 data.local_ltk = kLTK;
813 data.irk = sm::Key(sm::SecurityProperties(), Random<UInt128>());
814 data.identity_address = peer()->address();
815 EXPECT_FALSE(cache()->StoreLowEnergyBond(p->identifier(), data));
816 EXPECT_FALSE(p->le()->bonded());
817 EXPECT_TRUE(p->temporary());
818 }
819
820 // StoreLowEnergyBond fails if the new identity is the address of a "different"
821 // (another peer record with a distinct ID) BR/EDR peer.
TEST_F(PeerCacheTestBondingTest,StoreLowEnergyBondWithNewIdentityMatchingExistingBrEdrPeer)822 TEST_F(PeerCacheTestBondingTest,
823 StoreLowEnergyBondWithNewIdentityMatchingExistingBrEdrPeer) {
824 ASSERT_TRUE(NewPeer(kAddrBrEdr, true));
825 ASSERT_TRUE(NewPeer(kAddrLeRandom, true));
826 ASSERT_FALSE(peer()->identity_known());
827
828 sm::PairingData data;
829 data.peer_ltk = kLTK;
830 data.local_ltk = kLTK;
831 data.irk = sm::Key(sm::SecurityProperties(), Random<UInt128>());
832 // new identity address is same as another peer's BR/EDR identity
833 data.identity_address = kAddrLeAlias;
834 const auto old_address = peer()->address();
835 ASSERT_EQ(peer(), cache()->FindByAddress(old_address));
836 ASSERT_NE(peer(), cache()->FindByAddress(*data.identity_address));
837 EXPECT_FALSE(cache()->StoreLowEnergyBond(peer()->identifier(), data));
838 EXPECT_FALSE(peer()->identity_known());
839 }
840
841 // StoreLowEnergyBond succeeds if it contains an identity address that already
842 // matches the target peer.
TEST_F(PeerCacheTestBondingTest,StoreLowEnergyBondWithExistingMatchingIdentity)843 TEST_F(PeerCacheTestBondingTest,
844 StoreLowEnergyBondWithExistingMatchingIdentity) {
845 sm::PairingData data;
846 data.peer_ltk = kLTK;
847 data.local_ltk = kLTK;
848 data.irk = sm::Key(sm::SecurityProperties(), Random<UInt128>());
849 data.identity_address = peer()->address();
850 EXPECT_TRUE(cache()->StoreLowEnergyBond(peer()->identifier(), data));
851 EXPECT_TRUE(peer()->le()->bonded());
852 EXPECT_EQ(peer(), cache()->FindByAddress(*data.identity_address));
853 }
854
TEST_F(PeerCacheTestBondingTest,StoreLowEnergyBondWithNewIdentity)855 TEST_F(PeerCacheTestBondingTest, StoreLowEnergyBondWithNewIdentity) {
856 ASSERT_TRUE(NewPeer(kAddrLeRandom, true));
857 ASSERT_FALSE(peer()->identity_known());
858
859 sm::PairingData data;
860 data.peer_ltk = kLTK;
861 data.local_ltk = kLTK;
862 data.irk = sm::Key(sm::SecurityProperties(), Random<UInt128>());
863 data.identity_address = kAddrLeRandom2; // assign a new identity address
864 const auto old_address = peer()->address();
865 ASSERT_EQ(peer(), cache()->FindByAddress(old_address));
866 ASSERT_EQ(nullptr, cache()->FindByAddress(*data.identity_address));
867
868 EXPECT_TRUE(cache()->StoreLowEnergyBond(peer()->identifier(), data));
869 EXPECT_TRUE(peer()->le()->bonded());
870
871 // Address should have been updated.
872 ASSERT_NE(*data.identity_address, old_address);
873 EXPECT_EQ(*data.identity_address, peer()->address());
874 EXPECT_TRUE(peer()->identity_known());
875 EXPECT_EQ(peer(), cache()->FindByAddress(*data.identity_address));
876
877 // The old address should still map to |peer|.
878 ASSERT_EQ(peer(), cache()->FindByAddress(old_address));
879 }
880
TEST_F(PeerCacheTestBondingTest,StoreLowEnergyBondWithIrkIsAddedToResolvingList)881 TEST_F(PeerCacheTestBondingTest,
882 StoreLowEnergyBondWithIrkIsAddedToResolvingList) {
883 ASSERT_TRUE(NewPeer(kAddrLeRandom, true));
884 ASSERT_FALSE(peer()->identity_known());
885
886 sm::PairingData data;
887 data.peer_ltk = kLTK;
888 data.local_ltk = kLTK;
889 data.identity_address = kAddrLeRandom;
890 data.irk = sm::Key(sm::SecurityProperties(), Random<UInt128>());
891
892 EXPECT_TRUE(cache()->StoreLowEnergyBond(peer()->identifier(), data));
893 ASSERT_TRUE(peer()->le()->bonded());
894 ASSERT_TRUE(peer()->identity_known());
895
896 // Looking up the peer by RPA generated using the IRK should return the same
897 // peer.
898 DeviceAddress rpa = sm::util::GenerateRpa(data.irk->value());
899 EXPECT_EQ(peer(), cache()->FindByAddress(rpa));
900 }
901
TEST_F(PeerCacheTestBondingTest,RemovingPeerRemovesIrkFromResolvingList)902 TEST_F(PeerCacheTestBondingTest, RemovingPeerRemovesIrkFromResolvingList) {
903 sm::PairingData data;
904 data.peer_ltk = kLTK;
905 data.local_ltk = kLTK;
906 data.identity_address = kAddrLePublic;
907 data.irk = sm::Key(sm::SecurityProperties(), Random<UInt128>());
908
909 EXPECT_TRUE(cache()->StoreLowEnergyBond(peer()->identifier(), data));
910
911 // Removing peer should remove IRK from resolving list, allowing a new peer to
912 // be created with an RPA corresponding to the removed IRK. Because the
913 // resolving list is empty, FindByAddress should look up the peer by the RPA
914 // address, not the resolved address, and return the new peer.
915 EXPECT_TRUE(cache()->RemoveDisconnectedPeer(peer()->identifier()));
916 DeviceAddress rpa = sm::util::GenerateRpa(data.irk->value());
917 EXPECT_EQ(nullptr, cache()->FindByAddress(rpa));
918 ASSERT_TRUE(NewPeer(rpa, true));
919 EXPECT_EQ(peer(), cache()->FindByAddress(rpa));
920 // Subsequent calls to create a peer with the same RPA should fail.
921 EXPECT_FALSE(NewPeer(rpa, true));
922 }
923
TEST_F(PeerCacheTestBondingTest,StoreLowEnergyBondWithXTransportKeyNoBrEdr)924 TEST_F(PeerCacheTestBondingTest, StoreLowEnergyBondWithXTransportKeyNoBrEdr) {
925 // There's no preexisting BR/EDR data, the LE peer already exists.
926 sm::PairingData data;
927 data.peer_ltk = kLTK;
928 data.local_ltk = kLTK;
929 data.cross_transport_key = kSecureBrEdrKey;
930
931 EXPECT_TRUE(cache()->StoreLowEnergyBond(peer()->identifier(), data));
932 EXPECT_TRUE(peer()->le()->bonded());
933 // Storing an LE bond with a cross-transport BR/EDR key shouldn't
934 // automatically mark the peer as dual-mode.
935 EXPECT_FALSE(peer()->bredr().has_value());
936
937 // Make the peer dual-mode, and verify that the peer is already bonded over
938 // BR/EDR with the stored cross-transport key.
939 peer()->MutBrEdr();
940 EXPECT_TRUE(peer()->bredr()->bonded());
941 EXPECT_EQ(kSecureBrEdrKey, peer()->bredr()->link_key().value());
942 }
943
TEST_F(PeerCacheTestBondingTest,StoreLowEnergyBondWithInsecureXTransportKeyExistingBrEdr)944 TEST_F(PeerCacheTestBondingTest,
945 StoreLowEnergyBondWithInsecureXTransportKeyExistingBrEdr) {
946 // The peer is already dual-mode with a secure BR/EDR key.
947 peer()->MutBrEdr().SetBondData(kSecureBrEdrKey);
948 EXPECT_TRUE(peer()->bredr()->bonded());
949
950 sm::PairingData data;
951 data.peer_ltk = kLTK;
952 data.local_ltk = kLTK;
953 data.cross_transport_key = kInsecureBrEdrKey;
954 EXPECT_TRUE(cache()->StoreLowEnergyBond(peer()->identifier(), data));
955
956 // Verify that the existing BR/EDR key is not overwritten by a key of lesser
957 // security
958 sm::LTK current_bredr_key = peer()->bredr()->link_key().value();
959 EXPECT_NE(kInsecureBrEdrKey, current_bredr_key);
960 EXPECT_EQ(kSecureBrEdrKey, current_bredr_key);
961 }
962
TEST_F(PeerCacheTestBondingTest,StoreLowEnergyBondWithXTransportKeyExistingBrEdr)963 TEST_F(PeerCacheTestBondingTest,
964 StoreLowEnergyBondWithXTransportKeyExistingBrEdr) {
965 // The peer is already dual-mode with an insecure BR/EDR key.
966 peer()->MutBrEdr().SetBondData(kInsecureBrEdrKey);
967 EXPECT_TRUE(peer()->bredr()->bonded());
968
969 sm::LTK kDifferentInsecureBrEdrKey(kInsecureBrEdrKey.security(),
970 hci_spec::LinkKey(UInt128{8}, 9, 10));
971 sm::PairingData data;
972 data.peer_ltk = kLTK;
973 data.local_ltk = kLTK;
974 data.cross_transport_key = kDifferentInsecureBrEdrKey;
975 EXPECT_TRUE(cache()->StoreLowEnergyBond(peer()->identifier(), data));
976
977 // Verify that the existing BR/EDR key is overwritten by a key of the same
978 // security ("if the key
979 // [...] already exists, then the devices shall not overwrite that existing
980 // key with a key that is weaker" v5.2 Vol. 3 Part C 14.1).
981 sm::LTK current_bredr_key = peer()->bredr()->link_key().value();
982 EXPECT_NE(kInsecureBrEdrKey, current_bredr_key);
983 EXPECT_EQ(kDifferentInsecureBrEdrKey, current_bredr_key);
984
985 // Verify that the existing BR/EDR key is also overwritten by a key of greater
986 // security.
987 data.cross_transport_key = kSecureBrEdrKey;
988 EXPECT_TRUE(cache()->StoreLowEnergyBond(peer()->identifier(), data));
989
990 current_bredr_key = peer()->bredr()->link_key().value();
991 EXPECT_NE(kDifferentInsecureBrEdrKey, current_bredr_key);
992 EXPECT_EQ(kSecureBrEdrKey, current_bredr_key);
993 }
994
TEST_F(PeerCacheTestBondingTest,StoreBrEdrBondWithUnknownAddress)995 TEST_F(PeerCacheTestBondingTest, StoreBrEdrBondWithUnknownAddress) {
996 ASSERT_EQ(nullptr, cache()->FindByAddress(kAddrBrEdr));
997 EXPECT_FALSE(cache()->StoreBrEdrBond(kAddrBrEdr, kBrEdrKey));
998 }
999
TEST_F(PeerCacheTestBondingTest,StoreBrEdrBond)1000 TEST_F(PeerCacheTestBondingTest, StoreBrEdrBond) {
1001 ASSERT_TRUE(NewPeer(kAddrBrEdr, true));
1002 ASSERT_EQ(peer(), cache()->FindByAddress(kAddrBrEdr));
1003 ASSERT_TRUE(peer()->temporary());
1004 ASSERT_FALSE(peer()->bonded());
1005 ASSERT_TRUE(peer()->bredr());
1006 ASSERT_FALSE(peer()->bredr()->bonded());
1007
1008 EXPECT_TRUE(cache()->StoreBrEdrBond(kAddrBrEdr, kBrEdrKey));
1009
1010 EXPECT_FALSE(peer()->temporary());
1011 EXPECT_TRUE(peer()->bonded());
1012 EXPECT_TRUE(peer()->bredr()->bonded());
1013 EXPECT_TRUE(peer()->bredr()->link_key());
1014 EXPECT_EQ(kBrEdrKey, *peer()->bredr()->link_key());
1015 }
1016
TEST_F(PeerCacheTestBondingTest,StoreBondsForBothTech)1017 TEST_F(PeerCacheTestBondingTest, StoreBondsForBothTech) {
1018 ASSERT_TRUE(NewPeer(kAddrBrEdr, true));
1019 ASSERT_EQ(peer(), cache()->FindByAddress(kAddrBrEdr));
1020 ASSERT_TRUE(peer()->temporary());
1021 ASSERT_FALSE(peer()->bonded());
1022
1023 peer()->MutLe().SetAdvertisingData(
1024 kTestRSSI, kAdvData, pw::chrono::SystemClock::time_point());
1025 ASSERT_EQ(TechnologyType::kDualMode, peer()->technology());
1026
1027 // Without Secure Connections cross-transport key generation, bonding on one
1028 // technology does not bond on the other.
1029 ASSERT_FALSE(kBrEdrKey.security().secure_connections());
1030 EXPECT_TRUE(cache()->StoreBrEdrBond(kAddrBrEdr, kBrEdrKey));
1031 EXPECT_TRUE(peer()->bonded());
1032 EXPECT_FALSE(peer()->le()->bonded());
1033
1034 sm::PairingData data;
1035 data.peer_ltk = kLTK;
1036 data.local_ltk = kLTK;
1037 EXPECT_TRUE(cache()->StoreLowEnergyBond(peer()->identifier(), data));
1038
1039 EXPECT_FALSE(peer()->temporary());
1040 EXPECT_TRUE(peer()->bonded());
1041 EXPECT_TRUE(peer()->bredr()->bonded());
1042 EXPECT_TRUE(peer()->le()->bonded());
1043 }
1044
TEST_F(PeerCacheTestBondingTest,BondsUpdatedWhenNewServicesAdded)1045 TEST_F(PeerCacheTestBondingTest, BondsUpdatedWhenNewServicesAdded) {
1046 ASSERT_TRUE(NewPeer(kAddrBrEdr, true));
1047 ASSERT_EQ(peer(), cache()->FindByAddress(kAddrBrEdr));
1048 ASSERT_FALSE(peer()->bonded());
1049
1050 ASSERT_FALSE(kBrEdrKey.security().secure_connections());
1051 EXPECT_TRUE(cache()->StoreBrEdrBond(kAddrBrEdr, kBrEdrKey));
1052 EXPECT_TRUE(peer()->bredr()->bonded());
1053 EXPECT_EQ(1, bonded_callback_count());
1054
1055 peer()->MutBrEdr().AddService(UUID());
1056 EXPECT_EQ(2, bonded_callback_count());
1057 }
1058
TEST_F(PeerCacheTestBondingTest,RemoveDisconnectedPeerOnUnknownPeer)1059 TEST_F(PeerCacheTestBondingTest, RemoveDisconnectedPeerOnUnknownPeer) {
1060 const PeerId id(0x9999);
1061 ASSERT_FALSE(cache()->FindById(id));
1062 EXPECT_TRUE(cache()->RemoveDisconnectedPeer(id));
1063 EXPECT_EQ(0, updated_callback_count());
1064 }
1065
TEST_F(PeerCacheTestBondingTest,RemoveDisconnectedPeerOnUnconnectedPeer)1066 TEST_F(PeerCacheTestBondingTest, RemoveDisconnectedPeerOnUnconnectedPeer) {
1067 ASSERT_FALSE(peer()->connected());
1068 const PeerId id = peer()->identifier();
1069 EXPECT_TRUE(cache()->RemoveDisconnectedPeer(id));
1070 EXPECT_EQ(1, removed_callback_count());
1071 EXPECT_FALSE(cache()->FindById(id));
1072 }
1073
TEST_F(PeerCacheTestBondingTest,RemoveDisconnectedPeerOnConnectedPeer)1074 TEST_F(PeerCacheTestBondingTest, RemoveDisconnectedPeerOnConnectedPeer) {
1075 Peer::ConnectionToken conn_token = peer()->MutLe().RegisterConnection();
1076 ASSERT_TRUE(peer()->connected());
1077 const PeerId id = peer()->identifier();
1078 EXPECT_FALSE(cache()->RemoveDisconnectedPeer(id));
1079 EXPECT_EQ(0, removed_callback_count());
1080 EXPECT_TRUE(cache()->FindById(id));
1081 }
1082
1083 // Fixture parameterized by peer address
1084 class DualModeBondingTest
1085 : public PeerCacheTestBondingTest,
1086 public ::testing::WithParamInterface<DeviceAddress> {};
1087
TEST_P(DualModeBondingTest,AddBondedPeerSuccess)1088 TEST_P(DualModeBondingTest, AddBondedPeerSuccess) {
1089 PeerId kId(5);
1090 sm::PairingData data;
1091 data.peer_ltk = kLTK;
1092 data.local_ltk = kLTK;
1093
1094 const DeviceAddress& address = GetParam();
1095 EXPECT_TRUE(
1096 cache()->AddBondedPeer(BondingData{.identifier = kId,
1097 .address = address,
1098 .name = kName,
1099 .le_pairing_data = data,
1100 .bredr_link_key = kBrEdrKey,
1101 .bredr_services = kBrEdrServices}));
1102 auto* peer = cache()->FindById(kId);
1103 ASSERT_TRUE(peer);
1104 EXPECT_EQ(peer, cache()->FindByAddress(kAddrLeAlias));
1105 EXPECT_EQ(peer, cache()->FindByAddress(kAddrBrEdr));
1106 EXPECT_EQ(kId, peer->identifier());
1107 EXPECT_EQ(address, peer->address());
1108 EXPECT_EQ(kName, peer->name());
1109 EXPECT_EQ(Peer::NameSource::kUnknown, peer->name_source());
1110 EXPECT_TRUE(peer->identity_known());
1111 EXPECT_TRUE(peer->bonded());
1112 ASSERT_TRUE(peer->le());
1113 EXPECT_TRUE(peer->le()->bonded());
1114 ASSERT_TRUE(peer->le()->bond_data());
1115 EXPECT_EQ(data, *peer->le()->bond_data());
1116 ASSERT_TRUE(peer->bredr());
1117 EXPECT_TRUE(peer->bredr()->bonded());
1118 ASSERT_TRUE(peer->bredr()->link_key());
1119 EXPECT_EQ(kBrEdrKey, *peer->bredr()->link_key());
1120 EXPECT_THAT(peer->bredr()->services(),
1121 testing::UnorderedElementsAreArray(kBrEdrServices));
1122 EXPECT_EQ(TechnologyType::kDualMode, peer->technology());
1123
1124 // The "new bond" callback should not be called when restoring a previously
1125 // bonded peer.
1126 EXPECT_FALSE(bonded_callback_called());
1127 }
1128
1129 // Test dual-mode character of peer using the same address of both types.
1130 INSTANTIATE_TEST_SUITE_P(PeerCacheTest,
1131 DualModeBondingTest,
1132 ::testing::Values(kAddrBrEdr, kAddrLeAlias));
1133
1134 template <const DeviceAddress* DevAddr>
1135 class PeerCacheTest_UpdateCallbackTest : public PeerCacheTest {
1136 public:
SetUp()1137 void SetUp() override {
1138 PeerCacheTest::SetUp();
1139
1140 was_called_ = false;
1141 ASSERT_TRUE(NewPeer(*DevAddr, true));
1142 cache()->add_peer_updated_callback(
1143 [this](const auto&) { was_called_ = true; });
1144 ir_.view().bd_addr().CopyFrom(peer()->address().value().view());
1145 irr_.view().bd_addr().CopyFrom(peer()->address().value().view());
1146 extended_inquiry_result_event_.view().bd_addr().CopyFrom(
1147 peer()->address().value().view());
1148 eir_data().SetToZeros();
1149 EXPECT_FALSE(was_called_);
1150 }
1151
TearDown()1152 void TearDown() override { PeerCacheTest::TearDown(); }
1153
1154 protected:
ir()1155 pw::bluetooth::emboss::InquiryResultWriter ir() { return ir_.view(); }
irr()1156 pw::bluetooth::emboss::InquiryResultWithRssiWriter irr() {
1157 return irr_.view();
1158 }
1159 pw::bluetooth::emboss::ExtendedInquiryResultEventWriter
extended_inquiry_result_event()1160 extended_inquiry_result_event() {
1161 return extended_inquiry_result_event_.view();
1162 }
1163
eir_data()1164 MutableBufferView eir_data() {
1165 return MutableBufferView(extended_inquiry_result_event_.view()
1166 .extended_inquiry_response()
1167 .BackingStorage()
1168 .data(),
1169 extended_inquiry_result_event_.view()
1170 .extended_inquiry_response()
1171 .SizeInBytes());
1172 }
was_called() const1173 bool was_called() const { return was_called_; }
ClearWasCalled()1174 void ClearWasCalled() { was_called_ = false; }
1175
1176 private:
1177 bool was_called_;
1178 StaticPacket<pw::bluetooth::emboss::InquiryResultWriter> ir_;
1179 StaticPacket<pw::bluetooth::emboss::InquiryResultWithRssiWriter> irr_;
1180 StaticPacket<pw::bluetooth::emboss::ExtendedInquiryResultEventWriter>
1181 extended_inquiry_result_event_;
1182 };
1183
1184 using PeerCacheBrEdrUpdateCallbackTest =
1185 PeerCacheTest_UpdateCallbackTest<&kAddrBrEdr>;
1186 using PeerCacheLowEnergyUpdateCallbackTest =
1187 PeerCacheTest_UpdateCallbackTest<&kAddrLeAlias>;
1188
TEST_F(PeerCacheLowEnergyUpdateCallbackTest,ChangingLEConnectionStateTriggersUpdateCallback)1189 TEST_F(PeerCacheLowEnergyUpdateCallbackTest,
1190 ChangingLEConnectionStateTriggersUpdateCallback) {
1191 Peer::ConnectionToken conn_token = peer()->MutLe().RegisterConnection();
1192 EXPECT_TRUE(was_called());
1193 }
1194
TEST_F(PeerCacheLowEnergyUpdateCallbackTest,SetAdvertisingDataTriggersUpdateCallbackOnNameSet)1195 TEST_F(PeerCacheLowEnergyUpdateCallbackTest,
1196 SetAdvertisingDataTriggersUpdateCallbackOnNameSet) {
1197 peer()->MutLe().SetAdvertisingData(
1198 kTestRSSI, kAdvData, pw::chrono::SystemClock::time_point());
1199 EXPECT_TRUE(was_called());
1200 ASSERT_TRUE(peer()->name());
1201 EXPECT_EQ("Test", *peer()->name());
1202 EXPECT_EQ(Peer::NameSource::kAdvertisingDataComplete, *peer()->name_source());
1203 }
1204
TEST_F(PeerCacheLowEnergyUpdateCallbackTest,SetLowEnergyAdvertisingDataUpdateCallbackProvidesUpdatedPeer)1205 TEST_F(PeerCacheLowEnergyUpdateCallbackTest,
1206 SetLowEnergyAdvertisingDataUpdateCallbackProvidesUpdatedPeer) {
1207 ASSERT_NE(peer()->rssi(), kTestRSSI);
1208 cache()->add_peer_updated_callback([&](const auto& updated_peer) {
1209 ASSERT_TRUE(updated_peer.le());
1210 ASSERT_TRUE(updated_peer.name().has_value());
1211 EXPECT_EQ(updated_peer.name().value(), "Test");
1212 EXPECT_EQ(updated_peer.rssi(), kTestRSSI);
1213 });
1214 peer()->MutLe().SetAdvertisingData(
1215 kTestRSSI, kAdvData, pw::chrono::SystemClock::time_point());
1216 }
1217
TEST_F(PeerCacheLowEnergyUpdateCallbackTest,SetAdvertisingDataTriggersUpdateCallbackOnSameNameAndRssi)1218 TEST_F(PeerCacheLowEnergyUpdateCallbackTest,
1219 SetAdvertisingDataTriggersUpdateCallbackOnSameNameAndRssi) {
1220 peer()->MutLe().SetAdvertisingData(
1221 kTestRSSI, kAdvData, pw::chrono::SystemClock::time_point());
1222 ASSERT_TRUE(was_called());
1223
1224 ClearWasCalled();
1225 peer()->MutLe().SetAdvertisingData(
1226 kTestRSSI, kAdvData, pw::chrono::SystemClock::time_point());
1227 EXPECT_TRUE(was_called());
1228 }
1229
TEST_F(PeerCacheLowEnergyUpdateCallbackTest,SetLowEnergyConnectionParamsDoesNotTriggerUpdateCallback)1230 TEST_F(PeerCacheLowEnergyUpdateCallbackTest,
1231 SetLowEnergyConnectionParamsDoesNotTriggerUpdateCallback) {
1232 peer()->MutLe().SetConnectionParameters({});
1233 EXPECT_FALSE(was_called());
1234 }
1235
TEST_F(PeerCacheLowEnergyUpdateCallbackTest,SetLowEnergyPreferredConnectionParamsDoesNotTriggerUpdateCallback)1236 TEST_F(PeerCacheLowEnergyUpdateCallbackTest,
1237 SetLowEnergyPreferredConnectionParamsDoesNotTriggerUpdateCallback) {
1238 peer()->MutLe().SetPreferredConnectionParameters({});
1239 EXPECT_FALSE(was_called());
1240 }
1241
TEST_F(PeerCacheLowEnergyUpdateCallbackTest,BecomingDualModeTriggersUpdateCallBack)1242 TEST_F(PeerCacheLowEnergyUpdateCallbackTest,
1243 BecomingDualModeTriggersUpdateCallBack) {
1244 EXPECT_EQ(TechnologyType::kLowEnergy, peer()->technology());
1245
1246 size_t call_count = 0;
1247 cache()->add_peer_updated_callback([&](const auto&) { ++call_count; });
1248 peer()->MutBrEdr();
1249 EXPECT_EQ(TechnologyType::kDualMode, peer()->technology());
1250 EXPECT_EQ(call_count, 1U);
1251
1252 // Calling MutBrEdr again on doesn't trigger additional callbacks.
1253 peer()->MutBrEdr();
1254 EXPECT_EQ(call_count, 1U);
1255 peer()->MutBrEdr().SetInquiryData(extended_inquiry_result_event());
1256 EXPECT_EQ(call_count, 2U);
1257 }
1258
TEST_F(PeerCacheBrEdrUpdateCallbackTest,ChangingBrEdrConnectionStateTriggersUpdateCallback)1259 TEST_F(PeerCacheBrEdrUpdateCallbackTest,
1260 ChangingBrEdrConnectionStateTriggersUpdateCallback) {
1261 Peer::ConnectionToken token = peer()->MutBrEdr().RegisterConnection();
1262 EXPECT_TRUE(was_called());
1263 }
1264
TEST_F(PeerCacheBrEdrUpdateCallbackTest,SetBrEdrInquiryDataFromInquiryResultTriggersUpdateCallbackOnPeerClassSet)1265 TEST_F(
1266 PeerCacheBrEdrUpdateCallbackTest,
1267 SetBrEdrInquiryDataFromInquiryResultTriggersUpdateCallbackOnPeerClassSet) {
1268 ir().class_of_device().BackingStorage().WriteUInt(kTestDeviceClass.to_int());
1269 peer()->MutBrEdr().SetInquiryData(ir());
1270 EXPECT_TRUE(was_called());
1271 }
1272
TEST_F(PeerCacheBrEdrUpdateCallbackTest,SetBrEdrInquiryDataFromInquiryResultUpdateCallbackProvidesUpdatedPeer)1273 TEST_F(PeerCacheBrEdrUpdateCallbackTest,
1274 SetBrEdrInquiryDataFromInquiryResultUpdateCallbackProvidesUpdatedPeer) {
1275 ir().class_of_device().BackingStorage().WriteUInt(kTestDeviceClass.to_int());
1276 cache()->add_peer_updated_callback([](const auto& updated_peer) {
1277 ASSERT_TRUE(updated_peer.bredr());
1278 ASSERT_TRUE(updated_peer.bredr()->device_class());
1279 EXPECT_EQ(DeviceClass::MajorClass(0x02),
1280 updated_peer.bredr()->device_class()->major_class());
1281 });
1282 peer()->MutBrEdr().SetInquiryData(ir());
1283 }
1284
TEST_F(PeerCacheBrEdrUpdateCallbackTest,SetBrEdrInquiryDataFromInquiryResultDoesNotTriggerUpdateCallbackOnSameDeviceClass)1285 TEST_F(
1286 PeerCacheBrEdrUpdateCallbackTest,
1287 SetBrEdrInquiryDataFromInquiryResultDoesNotTriggerUpdateCallbackOnSameDeviceClass) {
1288 ir().class_of_device().BackingStorage().WriteUInt(kTestDeviceClass.to_int());
1289 peer()->MutBrEdr().SetInquiryData(ir());
1290 ASSERT_TRUE(was_called());
1291
1292 ClearWasCalled();
1293 peer()->MutBrEdr().SetInquiryData(ir());
1294 EXPECT_FALSE(was_called());
1295 }
1296
TEST_F(PeerCacheBrEdrUpdateCallbackTest,SetBrEdrInquiryDataFromInquiryResultRSSITriggersUpdateCallbackOnDeviceClassSet)1297 TEST_F(
1298 PeerCacheBrEdrUpdateCallbackTest,
1299 SetBrEdrInquiryDataFromInquiryResultRSSITriggersUpdateCallbackOnDeviceClassSet) {
1300 irr().class_of_device().major_device_class().Write(
1301 pw::bluetooth::emboss::MajorDeviceClass::PHONE);
1302 peer()->MutBrEdr().SetInquiryData(irr());
1303 EXPECT_TRUE(was_called());
1304 }
1305
TEST_F(PeerCacheBrEdrUpdateCallbackTest,SetBrEdrInquiryDataFromInquiryResultRSSIUpdateCallbackProvidesUpdatedPeer)1306 TEST_F(
1307 PeerCacheBrEdrUpdateCallbackTest,
1308 SetBrEdrInquiryDataFromInquiryResultRSSIUpdateCallbackProvidesUpdatedPeer) {
1309 irr().class_of_device().major_device_class().Write(
1310 pw::bluetooth::emboss::MajorDeviceClass::PHONE);
1311 cache()->add_peer_updated_callback([](const auto& updated_peer) {
1312 ASSERT_TRUE(updated_peer.bredr()->device_class());
1313 EXPECT_EQ(DeviceClass::MajorClass::kPhone,
1314 updated_peer.bredr()->device_class()->major_class());
1315 });
1316 peer()->MutBrEdr().SetInquiryData(irr());
1317 }
1318
TEST_F(PeerCacheBrEdrUpdateCallbackTest,SetBrEdrInquiryDataFromInquiryResultRSSIDoesNotTriggerUpdateCallbackOnSameDeviceClass)1319 TEST_F(
1320 PeerCacheBrEdrUpdateCallbackTest,
1321 SetBrEdrInquiryDataFromInquiryResultRSSIDoesNotTriggerUpdateCallbackOnSameDeviceClass) {
1322 irr().class_of_device().major_device_class().Write(
1323 pw::bluetooth::emboss::MajorDeviceClass::PHONE);
1324 peer()->MutBrEdr().SetInquiryData(irr());
1325 ASSERT_TRUE(was_called());
1326
1327 ClearWasCalled();
1328 peer()->MutBrEdr().SetInquiryData(irr());
1329 EXPECT_FALSE(was_called());
1330 }
1331
TEST_F(PeerCacheBrEdrUpdateCallbackTest,SetBrEdrInquiryDataFromInquiryResultRSSIDoesNotTriggerUpdateCallbackOnRSSI)1332 TEST_F(
1333 PeerCacheBrEdrUpdateCallbackTest,
1334 SetBrEdrInquiryDataFromInquiryResultRSSIDoesNotTriggerUpdateCallbackOnRSSI) {
1335 irr().rssi().Write(1);
1336 peer()->MutBrEdr().SetInquiryData(irr());
1337 ASSERT_TRUE(was_called()); // Callback due to |class_of_device|.
1338
1339 ClearWasCalled();
1340 irr().rssi().Write(20);
1341 peer()->MutBrEdr().SetInquiryData(irr());
1342 EXPECT_FALSE(was_called());
1343 }
1344
TEST_F(PeerCacheBrEdrUpdateCallbackTest,SetBrEdrInquiryDataFromExtendedInquiryResultEventParamsTriggersUpdateCallbackOnDeviceClassSet)1345 TEST_F(
1346 PeerCacheBrEdrUpdateCallbackTest,
1347 SetBrEdrInquiryDataFromExtendedInquiryResultEventParamsTriggersUpdateCallbackOnDeviceClassSet) {
1348 extended_inquiry_result_event().class_of_device().major_device_class().Write(
1349 pw::bluetooth::emboss::MajorDeviceClass::PHONE);
1350 peer()->MutBrEdr().SetInquiryData(extended_inquiry_result_event());
1351 EXPECT_TRUE(was_called());
1352 }
1353
TEST_F(PeerCacheBrEdrUpdateCallbackTest,SetBrEdrInquiryDataFromExtendedInquiryResultEventParamsTriggersUpdateCallbackOnNameSet)1354 TEST_F(
1355 PeerCacheBrEdrUpdateCallbackTest,
1356 SetBrEdrInquiryDataFromExtendedInquiryResultEventParamsTriggersUpdateCallbackOnNameSet) {
1357 peer()->MutBrEdr().SetInquiryData(extended_inquiry_result_event());
1358 ASSERT_TRUE(was_called()); // Callback due to |class_of_device|.
1359
1360 ClearWasCalled();
1361 eir_data().Write(kEirData);
1362 peer()->MutBrEdr().SetInquiryData(extended_inquiry_result_event());
1363 EXPECT_TRUE(was_called());
1364 }
1365
TEST_F(PeerCacheBrEdrUpdateCallbackTest,SetBrEdrInquiryDataFromExtendedInquiryResultEventParamsUpdateCallbackProvidesUpdatedPeer)1366 TEST_F(
1367 PeerCacheBrEdrUpdateCallbackTest,
1368 SetBrEdrInquiryDataFromExtendedInquiryResultEventParamsUpdateCallbackProvidesUpdatedPeer) {
1369 extended_inquiry_result_event().clock_offset().valid().Write(true);
1370 extended_inquiry_result_event().clock_offset().clock_offset().Write(1);
1371 extended_inquiry_result_event().page_scan_repetition_mode().Write(
1372 pw::bluetooth::emboss::PageScanRepetitionMode::R1_);
1373 extended_inquiry_result_event().rssi().Write(kTestRSSI);
1374 extended_inquiry_result_event().class_of_device().major_device_class().Write(
1375 pw::bluetooth::emboss::MajorDeviceClass::PHONE);
1376 eir_data().Write(kEirData);
1377 ASSERT_FALSE(peer()->name().has_value());
1378 ASSERT_EQ(peer()->rssi(), hci_spec::kRSSIInvalid);
1379 cache()->add_peer_updated_callback([](const auto& updated_peer) {
1380 const auto& data = updated_peer.bredr();
1381 ASSERT_TRUE(data);
1382 ASSERT_TRUE(data->clock_offset().has_value());
1383 ASSERT_TRUE(data->page_scan_repetition_mode().has_value());
1384 ASSERT_TRUE(data->device_class().has_value());
1385 ASSERT_TRUE(updated_peer.name().has_value());
1386
1387 EXPECT_EQ(*data->clock_offset(), 0x01);
1388 EXPECT_EQ(*data->page_scan_repetition_mode(),
1389 pw::bluetooth::emboss::PageScanRepetitionMode::R1_);
1390 EXPECT_EQ(DeviceClass::MajorClass(0x02),
1391 updated_peer.bredr()->device_class()->major_class());
1392 EXPECT_EQ(updated_peer.rssi(), kTestRSSI);
1393 EXPECT_EQ(*updated_peer.name(), "Test");
1394 EXPECT_EQ(*updated_peer.name_source(),
1395 Peer::NameSource::kInquiryResultComplete);
1396 });
1397 peer()->MutBrEdr().SetInquiryData(extended_inquiry_result_event());
1398 }
1399
TEST_F(PeerCacheBrEdrUpdateCallbackTest,SetBrEdrInquiryDataFromExtendedInquiryResultEventParamsGeneratesExactlyOneUpdateCallbackRegardlessOfNumberOfFieldsChanged)1400 TEST_F(
1401 PeerCacheBrEdrUpdateCallbackTest,
1402 SetBrEdrInquiryDataFromExtendedInquiryResultEventParamsGeneratesExactlyOneUpdateCallbackRegardlessOfNumberOfFieldsChanged) {
1403 extended_inquiry_result_event().clock_offset().valid().Write(true);
1404 extended_inquiry_result_event().clock_offset().clock_offset().Write(1);
1405 extended_inquiry_result_event().page_scan_repetition_mode().Write(
1406 pw::bluetooth::emboss::PageScanRepetitionMode::R1_);
1407 extended_inquiry_result_event().rssi().Write(kTestRSSI);
1408 extended_inquiry_result_event().class_of_device().major_device_class().Write(
1409 pw::bluetooth::emboss::MajorDeviceClass::PHONE);
1410
1411 size_t call_count = 0;
1412 cache()->add_peer_updated_callback([&](const auto&) { ++call_count; });
1413 peer()->MutBrEdr().SetInquiryData(extended_inquiry_result_event());
1414 EXPECT_EQ(call_count, 1U);
1415 }
1416
TEST_F(PeerCacheBrEdrUpdateCallbackTest,SetBrEdrInquiryDataFromExtendedInquiryResultEventParamsDoesNotTriggerUpdateCallbackOnSamePeerClass)1417 TEST_F(
1418 PeerCacheBrEdrUpdateCallbackTest,
1419 SetBrEdrInquiryDataFromExtendedInquiryResultEventParamsDoesNotTriggerUpdateCallbackOnSamePeerClass) {
1420 extended_inquiry_result_event().class_of_device().major_device_class().Write(
1421 pw::bluetooth::emboss::MajorDeviceClass::PHONE);
1422 peer()->MutBrEdr().SetInquiryData(extended_inquiry_result_event());
1423 ASSERT_TRUE(was_called());
1424
1425 ClearWasCalled();
1426 peer()->MutBrEdr().SetInquiryData(extended_inquiry_result_event());
1427 EXPECT_FALSE(was_called());
1428 }
1429
TEST_F(PeerCacheBrEdrUpdateCallbackTest,SetBrEdrInquiryDataFromExtendedInquiryResultEventParamsDoesNotTriggerUpdateCallbackOnSameName)1430 TEST_F(
1431 PeerCacheBrEdrUpdateCallbackTest,
1432 SetBrEdrInquiryDataFromExtendedInquiryResultEventParamsDoesNotTriggerUpdateCallbackOnSameName) {
1433 eir_data().Write(kEirData);
1434 peer()->MutBrEdr().SetInquiryData(extended_inquiry_result_event());
1435 ASSERT_TRUE(was_called());
1436
1437 ClearWasCalled();
1438 peer()->MutBrEdr().SetInquiryData(extended_inquiry_result_event());
1439 EXPECT_FALSE(was_called());
1440 }
1441
TEST_F(PeerCacheBrEdrUpdateCallbackTest,SetBrEdrInquiryDataFromExtendedInquiryResultEventParamsDoesNotTriggerUpdateCallbackOnRSSI)1442 TEST_F(
1443 PeerCacheBrEdrUpdateCallbackTest,
1444 SetBrEdrInquiryDataFromExtendedInquiryResultEventParamsDoesNotTriggerUpdateCallbackOnRSSI) {
1445 extended_inquiry_result_event().rssi().Write(1);
1446 peer()->MutBrEdr().SetInquiryData(extended_inquiry_result_event());
1447 ASSERT_TRUE(was_called()); // Callback due to |class_of_device|.
1448
1449 ClearWasCalled();
1450 extended_inquiry_result_event().rssi().Write(20);
1451 peer()->MutBrEdr().SetInquiryData(extended_inquiry_result_event());
1452 EXPECT_FALSE(was_called());
1453 }
1454
TEST_F(PeerCacheBrEdrUpdateCallbackTest,RegisterNameTriggersUpdateCallback)1455 TEST_F(PeerCacheBrEdrUpdateCallbackTest, RegisterNameTriggersUpdateCallback) {
1456 peer()->RegisterName("nombre");
1457 EXPECT_TRUE(was_called());
1458 }
1459
TEST_F(PeerCacheBrEdrUpdateCallbackTest,RegisterNameDoesNotTriggerUpdateCallbackOnSameName)1460 TEST_F(PeerCacheBrEdrUpdateCallbackTest,
1461 RegisterNameDoesNotTriggerUpdateCallbackOnSameName) {
1462 peer()->RegisterName("nombre");
1463 ASSERT_TRUE(was_called());
1464
1465 bool was_called_again = false;
1466 cache()->add_peer_updated_callback(
1467 [&](const auto&) { was_called_again = true; });
1468 peer()->RegisterName("nombre");
1469 EXPECT_FALSE(was_called_again);
1470 }
1471
TEST_F(PeerCacheBrEdrUpdateCallbackTest,BecomingDualModeTriggersUpdateCallBack)1472 TEST_F(PeerCacheBrEdrUpdateCallbackTest,
1473 BecomingDualModeTriggersUpdateCallBack) {
1474 EXPECT_EQ(TechnologyType::kClassic, peer()->technology());
1475
1476 size_t call_count = 0;
1477 cache()->add_peer_updated_callback([&](const auto&) { ++call_count; });
1478 peer()->MutLe();
1479 EXPECT_EQ(TechnologyType::kDualMode, peer()->technology());
1480 EXPECT_EQ(call_count, 1U);
1481
1482 // Calling MutLe again doesn't trigger additional callbacks.
1483 peer()->MutLe();
1484 EXPECT_EQ(call_count, 1U);
1485 peer()->MutLe().SetAdvertisingData(
1486 kTestRSSI, kAdvData, pw::chrono::SystemClock::time_point());
1487 EXPECT_EQ(call_count, 2U);
1488 }
1489
1490 class PeerCacheExpirationTest : public pw::async::test::FakeDispatcherFixture {
1491 public:
1492 PeerCacheExpirationTest() = default;
SetUp()1493 void SetUp() override {
1494 cache_.set_peer_removed_callback([this](PeerId) { peers_removed_++; });
1495 auto* peer = cache_.NewPeer(kAddrLeAlias, /*connectable=*/true);
1496 ASSERT_TRUE(peer);
1497 ASSERT_TRUE(peer->temporary());
1498 peer_addr_ = peer->address();
1499 peer_addr_alias_ = kAddrBrEdr;
1500 peer_id_ = peer->identifier();
1501 peers_removed_ = 0;
1502 }
1503
TearDown()1504 void TearDown() override {
1505 cache_.set_peer_removed_callback(nullptr);
1506 RunUntilIdle();
1507 }
1508
GetDefaultPeer()1509 Peer* GetDefaultPeer() { return cache_.FindById(peer_id_); }
GetPeerById(PeerId id)1510 Peer* GetPeerById(PeerId id) { return cache_.FindById(id); }
IsDefaultPeerAddressInCache() const1511 bool IsDefaultPeerAddressInCache() const {
1512 return cache_.FindByAddress(peer_addr_);
1513 }
IsOtherTransportAddressInCache() const1514 bool IsOtherTransportAddressInCache() const {
1515 return cache_.FindByAddress(peer_addr_alias_);
1516 }
IsDefaultPeerPresent()1517 bool IsDefaultPeerPresent() { return GetDefaultPeer(); }
NewPeer(const DeviceAddress & address,bool connectable)1518 Peer* NewPeer(const DeviceAddress& address, bool connectable) {
1519 return cache_.NewPeer(address, connectable);
1520 }
peers_removed() const1521 int peers_removed() const { return peers_removed_; }
1522
1523 private:
1524 PeerCache cache_{dispatcher()};
1525 DeviceAddress peer_addr_;
1526 DeviceAddress peer_addr_alias_;
1527 PeerId peer_id_;
1528 int peers_removed_;
1529 };
1530
TEST_F(PeerCacheExpirationTest,TemporaryDiesSixtySecondsAfterBirth)1531 TEST_F(PeerCacheExpirationTest, TemporaryDiesSixtySecondsAfterBirth) {
1532 RunFor(kCacheTimeout);
1533 EXPECT_FALSE(IsDefaultPeerPresent());
1534 EXPECT_EQ(1, peers_removed());
1535 }
1536
TEST_F(PeerCacheExpirationTest,TemporaryLivesForSixtySecondsAfterBirth)1537 TEST_F(PeerCacheExpirationTest, TemporaryLivesForSixtySecondsAfterBirth) {
1538 RunFor(kCacheTimeout - std::chrono::milliseconds(1));
1539 EXPECT_TRUE(IsDefaultPeerPresent());
1540 EXPECT_EQ(0, peers_removed());
1541 }
1542
TEST_F(PeerCacheExpirationTest,TemporaryLivesForSixtySecondsSinceLastSeen)1543 TEST_F(PeerCacheExpirationTest, TemporaryLivesForSixtySecondsSinceLastSeen) {
1544 RunFor(kCacheTimeout - std::chrono::milliseconds(1));
1545 ASSERT_TRUE(IsDefaultPeerPresent());
1546
1547 // Tickle peer, and verify it sticks around for another cache timeout.
1548 GetDefaultPeer()->RegisterName("nombre");
1549 RunFor(kCacheTimeout - std::chrono::milliseconds(1));
1550 EXPECT_TRUE(IsDefaultPeerPresent());
1551 }
1552
TEST_F(PeerCacheExpirationTest,TemporaryDiesSixtySecondsAfterLastSeen)1553 TEST_F(PeerCacheExpirationTest, TemporaryDiesSixtySecondsAfterLastSeen) {
1554 RunFor(kCacheTimeout - std::chrono::milliseconds(1));
1555 ASSERT_TRUE(IsDefaultPeerPresent());
1556
1557 // Tickle peer, and verify it expires after cache timeout.
1558 GetDefaultPeer()->RegisterName("nombre");
1559 RunFor(kCacheTimeout);
1560 EXPECT_FALSE(IsDefaultPeerPresent());
1561 }
1562
TEST_F(PeerCacheExpirationTest,CanMakeNonTemporaryJustBeforeSixtySeconds)1563 TEST_F(PeerCacheExpirationTest, CanMakeNonTemporaryJustBeforeSixtySeconds) {
1564 // At last possible moment, make peer non-temporary,
1565 RunFor(kCacheTimeout - std::chrono::milliseconds(1));
1566 ASSERT_TRUE(IsDefaultPeerPresent());
1567 Peer::ConnectionToken conn_token =
1568 GetDefaultPeer()->MutLe().RegisterConnection();
1569 ASSERT_FALSE(GetDefaultPeer()->temporary());
1570
1571 // Verify that the peer survives.
1572 RunFor(kCacheTimeout * 10);
1573 EXPECT_TRUE(IsDefaultPeerPresent());
1574 }
1575
TEST_F(PeerCacheExpirationTest,LEConnectedPeerLivesMuchMoreThanSixtySeconds)1576 TEST_F(PeerCacheExpirationTest, LEConnectedPeerLivesMuchMoreThanSixtySeconds) {
1577 ASSERT_TRUE(IsDefaultPeerPresent());
1578 Peer::ConnectionToken conn_token =
1579 GetDefaultPeer()->MutLe().RegisterConnection();
1580 RunFor(kCacheTimeout * 10);
1581 ASSERT_TRUE(IsDefaultPeerPresent());
1582 EXPECT_FALSE(GetDefaultPeer()->temporary());
1583 }
1584
TEST_F(PeerCacheExpirationTest,BREDRConnectedPeerLivesMuchMoreThanSixtySeconds)1585 TEST_F(PeerCacheExpirationTest,
1586 BREDRConnectedPeerLivesMuchMoreThanSixtySeconds) {
1587 ASSERT_TRUE(IsDefaultPeerPresent());
1588 Peer::ConnectionToken token =
1589 GetDefaultPeer()->MutBrEdr().RegisterConnection();
1590 RunFor(kCacheTimeout * 10);
1591 ASSERT_TRUE(IsDefaultPeerPresent());
1592 EXPECT_FALSE(GetDefaultPeer()->temporary());
1593 }
1594
TEST_F(PeerCacheExpirationTest,LePeerBecomesNonTemporaryWhenConnecting)1595 TEST_F(PeerCacheExpirationTest, LePeerBecomesNonTemporaryWhenConnecting) {
1596 ASSERT_TRUE(IsDefaultPeerPresent());
1597 ASSERT_EQ(kAddrLeAlias, GetDefaultPeer()->address());
1598 ASSERT_TRUE(GetDefaultPeer()->temporary());
1599
1600 Peer::InitializingConnectionToken init_token =
1601 GetDefaultPeer()->MutLe().RegisterInitializingConnection();
1602 EXPECT_FALSE(GetDefaultPeer()->temporary());
1603
1604 RunFor(kCacheTimeout);
1605 ASSERT_TRUE(IsDefaultPeerPresent());
1606 }
1607
TEST_F(PeerCacheExpirationTest,LEPublicPeerRemainsNonTemporaryOnDisconnect)1608 TEST_F(PeerCacheExpirationTest, LEPublicPeerRemainsNonTemporaryOnDisconnect) {
1609 ASSERT_TRUE(IsDefaultPeerPresent());
1610 ASSERT_EQ(kAddrLeAlias, GetDefaultPeer()->address());
1611 {
1612 Peer::ConnectionToken conn_token =
1613 GetDefaultPeer()->MutLe().RegisterConnection();
1614 ASSERT_FALSE(GetDefaultPeer()->temporary());
1615
1616 RunFor(kCacheTimeout + std::chrono::seconds(1));
1617 ASSERT_TRUE(IsDefaultPeerPresent());
1618 ASSERT_TRUE(GetDefaultPeer()->identity_known());
1619 // Destroy conn_token at end of scope
1620 }
1621 EXPECT_FALSE(GetDefaultPeer()->temporary());
1622
1623 RunFor(kCacheTimeout);
1624 EXPECT_TRUE(IsDefaultPeerPresent());
1625 }
1626
TEST_F(PeerCacheExpirationTest,LERandomPeerBecomesTemporaryOnDisconnect)1627 TEST_F(PeerCacheExpirationTest, LERandomPeerBecomesTemporaryOnDisconnect) {
1628 // Create our Peer, and get it into the kConnected state.
1629 PeerId custom_peer_id;
1630 std::optional<Peer::ConnectionToken> conn_token;
1631 {
1632 auto* custom_peer = NewPeer(kAddrLeRandom, /*connectable=*/true);
1633 ASSERT_TRUE(custom_peer);
1634 ASSERT_TRUE(custom_peer->temporary());
1635 ASSERT_FALSE(custom_peer->identity_known());
1636 custom_peer_id = custom_peer->identifier();
1637
1638 conn_token = custom_peer->MutLe().RegisterConnection();
1639 ASSERT_FALSE(custom_peer->temporary());
1640 ASSERT_FALSE(custom_peer->identity_known());
1641 }
1642
1643 // Verify that the connected peer does not expire out of the cache.
1644 // Then disconnect the peer, in preparation for the next stage of our test.
1645 {
1646 EXPECT_EQ(0, peers_removed());
1647 RunFor(std::chrono::seconds(61));
1648 EXPECT_EQ(1, peers_removed()); // Default peer timed out.
1649 auto* custom_peer = GetPeerById(custom_peer_id);
1650 ASSERT_TRUE(custom_peer);
1651 ASSERT_FALSE(custom_peer->identity_known());
1652
1653 conn_token.reset();
1654 EXPECT_TRUE(custom_peer->temporary());
1655 EXPECT_FALSE(custom_peer->identity_known());
1656 }
1657
1658 // Verify that the disconnected peer expires out of the cache.
1659 RunFor(std::chrono::seconds(61));
1660 EXPECT_FALSE(GetPeerById(custom_peer_id));
1661 EXPECT_EQ(2, peers_removed());
1662 }
1663
TEST_F(PeerCacheExpirationTest,BrEdrPeerRemainsNonTemporaryOnDisconnect)1664 TEST_F(PeerCacheExpirationTest, BrEdrPeerRemainsNonTemporaryOnDisconnect) {
1665 // Create our Peer, and get it into the kConnected state.
1666 PeerId custom_peer_id;
1667 std::optional<Peer::ConnectionToken> conn_token;
1668 {
1669 auto* custom_peer = NewPeer(kAddrLePublic, /*connectable=*/true);
1670 ASSERT_TRUE(custom_peer);
1671 conn_token = custom_peer->MutLe().RegisterConnection();
1672 custom_peer_id = custom_peer->identifier();
1673 }
1674
1675 // Verify that the connected peer does not expire out of the cache.
1676 // Then disconnect the peer, in preparation for the next stage of our test.
1677 {
1678 EXPECT_EQ(0, peers_removed());
1679 RunFor(kCacheTimeout * 10);
1680 EXPECT_EQ(1, peers_removed()); // Default peer timed out.
1681 auto* custom_peer = GetPeerById(custom_peer_id);
1682 ASSERT_TRUE(custom_peer);
1683 ASSERT_TRUE(custom_peer->identity_known());
1684 EXPECT_FALSE(custom_peer->temporary());
1685
1686 conn_token.reset();
1687 ASSERT_TRUE(GetPeerById(custom_peer_id));
1688 EXPECT_FALSE(custom_peer->temporary());
1689 }
1690
1691 // Verify that the disconnected peer does _not_ expire out of the cache.
1692 // We expect the peer to remain, because BrEdr peers are non-temporary
1693 // even when disconnected.
1694 RunFor(kCacheTimeout);
1695 EXPECT_TRUE(GetPeerById(custom_peer_id));
1696 EXPECT_EQ(1, peers_removed());
1697 }
1698
TEST_F(PeerCacheExpirationTest,ExpirationUpdatesAddressMap)1699 TEST_F(PeerCacheExpirationTest, ExpirationUpdatesAddressMap) {
1700 ASSERT_TRUE(IsDefaultPeerAddressInCache());
1701 ASSERT_TRUE(IsOtherTransportAddressInCache());
1702 RunFor(kCacheTimeout);
1703 EXPECT_FALSE(IsDefaultPeerAddressInCache());
1704 EXPECT_FALSE(IsOtherTransportAddressInCache());
1705 }
1706
TEST_F(PeerCacheExpirationTest,SetAdvertisingDataUpdatesExpiration)1707 TEST_F(PeerCacheExpirationTest, SetAdvertisingDataUpdatesExpiration) {
1708 RunFor(kCacheTimeout - std::chrono::milliseconds(1));
1709 ASSERT_TRUE(IsDefaultPeerPresent());
1710 GetDefaultPeer()->MutLe().SetAdvertisingData(
1711 kTestRSSI, StaticByteBuffer<1>{}, pw::chrono::SystemClock::time_point());
1712 RunFor(kCacheTimeout - std::chrono::milliseconds(1));
1713 EXPECT_TRUE(IsDefaultPeerPresent());
1714 // Setting advertising data with the same rssi & name should also update the
1715 // expiry.
1716 GetDefaultPeer()->MutLe().SetAdvertisingData(
1717 kTestRSSI, StaticByteBuffer<1>{}, pw::chrono::SystemClock::time_point());
1718 RunFor(std::chrono::milliseconds(1));
1719 EXPECT_TRUE(IsDefaultPeerPresent());
1720 }
1721
TEST_F(PeerCacheExpirationTest,SetBrEdrInquiryDataFromInquiryResultUpdatesExpiration)1722 TEST_F(PeerCacheExpirationTest,
1723 SetBrEdrInquiryDataFromInquiryResultUpdatesExpiration) {
1724 StaticPacket<pw::bluetooth::emboss::InquiryResultWriter> ir;
1725 ASSERT_TRUE(IsDefaultPeerPresent());
1726 ir.view().bd_addr().CopyFrom(GetDefaultPeer()->address().value().view());
1727
1728 RunFor(kCacheTimeout - std::chrono::milliseconds(1));
1729 ASSERT_TRUE(IsDefaultPeerPresent());
1730 GetDefaultPeer()->MutBrEdr().SetInquiryData(ir.view());
1731
1732 RunFor(std::chrono::milliseconds(1));
1733 EXPECT_TRUE(IsDefaultPeerPresent());
1734 }
1735
TEST_F(PeerCacheExpirationTest,SetBrEdrInquiryDataFromInquiryResultRSSIUpdatesExpiration)1736 TEST_F(PeerCacheExpirationTest,
1737 SetBrEdrInquiryDataFromInquiryResultRSSIUpdatesExpiration) {
1738 StaticPacket<pw::bluetooth::emboss::InquiryResultWithRssiWriter> irr;
1739 ASSERT_TRUE(IsDefaultPeerPresent());
1740 irr.view().bd_addr().CopyFrom(GetDefaultPeer()->address().value().view());
1741
1742 RunFor(kCacheTimeout - std::chrono::milliseconds(1));
1743 ASSERT_TRUE(IsDefaultPeerPresent());
1744 GetDefaultPeer()->MutBrEdr().SetInquiryData(irr.view());
1745
1746 RunFor(std::chrono::milliseconds(1));
1747 EXPECT_TRUE(IsDefaultPeerPresent());
1748 }
1749
TEST_F(PeerCacheExpirationTest,SetBrEdrInquiryDataFromExtendedInquiryResultEventParamsUpdatesExpiration)1750 TEST_F(
1751 PeerCacheExpirationTest,
1752 SetBrEdrInquiryDataFromExtendedInquiryResultEventParamsUpdatesExpiration) {
1753 StaticPacket<pw::bluetooth::emboss::ExtendedInquiryResultEventWriter> event;
1754 ASSERT_TRUE(IsDefaultPeerPresent());
1755 event.view().bd_addr().CopyFrom(GetDefaultPeer()->address().value().view());
1756
1757 RunFor(kCacheTimeout - std::chrono::milliseconds(1));
1758 ASSERT_TRUE(IsDefaultPeerPresent());
1759 GetDefaultPeer()->MutBrEdr().SetInquiryData(event.view());
1760
1761 RunFor(std::chrono::milliseconds(1));
1762 EXPECT_TRUE(IsDefaultPeerPresent());
1763 }
1764
TEST_F(PeerCacheExpirationTest,RegisterNameUpdatesExpiration)1765 TEST_F(PeerCacheExpirationTest, RegisterNameUpdatesExpiration) {
1766 RunFor(kCacheTimeout - std::chrono::milliseconds(1));
1767 ASSERT_TRUE(IsDefaultPeerPresent());
1768 GetDefaultPeer()->RegisterName({});
1769 RunFor(std::chrono::milliseconds(1));
1770 EXPECT_TRUE(IsDefaultPeerPresent());
1771 }
1772
1773 } // namespace
1774 } // namespace bt::gap
1775