xref: /aosp_15_r20/external/pigweed/pw_bluetooth_sapphire/host/gap/peer_test.cc (revision 61c4878ac05f98d0ceed94b57d316916de578985)
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.h"
16 
17 #include <gmock/gmock.h>
18 #include <gtest/gtest.h>
19 #include <pw_async/fake_dispatcher_fixture.h>
20 
21 #include "pw_bluetooth_sapphire/internal/host/common/advertising_data.h"
22 #include "pw_bluetooth_sapphire/internal/host/common/byte_buffer.h"
23 #include "pw_bluetooth_sapphire/internal/host/common/manufacturer_names.h"
24 #include "pw_bluetooth_sapphire/internal/host/hci-spec/util.h"
25 #include "pw_bluetooth_sapphire/internal/host/testing/inspect_util.h"
26 
27 namespace bt::gap {
28 namespace {
29 
30 #ifndef NINSPECT
31 using namespace inspect::testing;
32 using bt::testing::GetInspectValue;
33 using bt::testing::ReadInspect;
34 
35 constexpr uint16_t kManufacturer = 0x0001;
36 constexpr uint16_t kSubversion = 0x0002;
37 #endif  // NINSPECT
38 
39 const StaticByteBuffer kAdvData(0x05,  // Length
40                                 0x09,  // AD type: Complete Local Name
41                                 'T',
42                                 'e',
43                                 's',
44                                 't');
45 
46 const StaticByteBuffer kInvalidAdvData{
47     // 32 bit service UUIDs are supposed to be 4 bytes, but the value in this
48     // TLV field is only 3
49     // bytes long, hence the AdvertisingData is not valid.
50     0x04,
51     static_cast<uint8_t>(DataType::kComplete32BitServiceUuids),
52     0x01,
53     0x02,
54     0x03,
55 };
56 
57 const bt::sm::LTK kLTK;
58 
59 const DeviceAddress kAddrLePublic(DeviceAddress::Type::kLEPublic,
60                                   {1, 2, 3, 4, 5, 6});
61 const DeviceAddress kAddrLeRandom(DeviceAddress::Type::kLERandom,
62                                   {1, 2, 3, 4, 5, 6});
63 const DeviceAddress kAddrBrEdr(DeviceAddress::Type::kBREDR,
64                                {0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA});
65 // LE Public Device Address that has the same value as a BR/EDR BD_ADDR, e.g. on
66 // a dual-mode device.
67 const DeviceAddress kAddrLeAlias(DeviceAddress::Type::kLEPublic,
68                                  {0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA});
69 
70 const bt::sm::LTK kSecureBrEdrKey(
71     sm::SecurityProperties(/*encrypted=*/true,
72                            /*authenticated=*/true,
73                            /*secure_connections=*/true,
74                            sm::kMaxEncryptionKeySize),
75     hci_spec::LinkKey(UInt128{4}, 5, 6));
76 
77 class PeerTest : public pw::async::test::FakeDispatcherFixture {
78  public:
79   PeerTest() = default;
80 
SetUp()81   void SetUp() override {
82     // Set up a default peer.
83     SetUpPeer(/*address=*/kAddrLePublic, /*connectable=*/true);
84   }
85 
TearDown()86   void TearDown() override { peer_.reset(); }
87 
88  protected:
89   // Can be used to override or reset the default peer. Resets metrics to
90   // prevent interference between peers (e.g. by metrics updated in
91   // construction).
SetUpPeer(const DeviceAddress & address,bool connectable)92   void SetUpPeer(const DeviceAddress& address, bool connectable) {
93     address_ = address;
94     peer_ = std::make_unique<Peer>(
95         fit::bind_member<&PeerTest::NotifyListenersCallback>(this),
96         fit::bind_member<&PeerTest::UpdateExpiryCallback>(this),
97         fit::bind_member<&PeerTest::DualModeCallback>(this),
98         fit::bind_member<&PeerTest::StoreLowEnergyBondCallback>(this),
99         PeerId(1),
100         address_,
101         connectable,
102         &metrics_,
103         dispatcher());
104     peer_->AttachInspect(peer_inspector_.GetRoot());
105     // Reset metrics as they should only apply to the new peer under test.
106     metrics_.AttachInspect(metrics_inspector_.GetRoot());
107   }
peer()108   Peer& peer() { return *peer_; }
109 
110 #ifndef NINSPECT
ReadPeerInspect()111   inspect::Hierarchy ReadPeerInspect() { return ReadInspect(peer_inspector_); }
112 
InspectLowEnergyConnectionState()113   std::string InspectLowEnergyConnectionState() {
114     std::optional<std::string> val =
115         GetInspectValue<inspect::StringPropertyValue>(
116             peer_inspector_,
117             {"peer",
118              "le_data",
119              Peer::LowEnergyData::kInspectConnectionStateName});
120     PW_CHECK(val);
121     return *val;
122   }
123 
InspectAdvertisingDataParseFailureCount()124   int64_t InspectAdvertisingDataParseFailureCount() {
125     std::optional<int64_t> val = GetInspectValue<inspect::IntPropertyValue>(
126         peer_inspector_,
127         {"peer",
128          "le_data",
129          Peer::LowEnergyData::kInspectAdvertisingDataParseFailureCountName});
130     PW_CHECK(val);
131     return *val;
132   }
133 
InspectLastAdvertisingDataParseFailure()134   std::string InspectLastAdvertisingDataParseFailure() {
135     std::optional<std::string> val =
136         GetInspectValue<inspect::StringPropertyValue>(
137             peer_inspector_,
138             {"peer",
139              "le_data",
140              Peer::LowEnergyData::kInspectLastAdvertisingDataParseFailureName});
141     PW_CHECK(val);
142     return *val;
143   }
144 
MetricsLowEnergyConnections()145   uint64_t MetricsLowEnergyConnections() {
146     std::optional<uint64_t> val = GetInspectValue<inspect::UintPropertyValue>(
147         metrics_inspector_, {"metrics", "le", "connection_events"});
148     PW_CHECK(val);
149     return *val;
150   }
151 
MetricsLowEnergyDisconnections()152   uint64_t MetricsLowEnergyDisconnections() {
153     std::optional<uint64_t> val = GetInspectValue<inspect::UintPropertyValue>(
154         metrics_inspector_, {"metrics", "le", "disconnection_events"});
155     PW_CHECK(val);
156     return *val;
157   }
158 
InspectBrEdrConnectionState()159   std::string InspectBrEdrConnectionState() {
160     std::optional<std::string> val =
161         GetInspectValue<inspect::StringPropertyValue>(
162             peer_inspector_,
163             {"peer",
164              "bredr_data",
165              Peer::BrEdrData::kInspectConnectionStateName});
166     PW_CHECK(val);
167     return *val;
168   }
169 
MetricsBrEdrConnections()170   uint64_t MetricsBrEdrConnections() {
171     std::optional<uint64_t> val = GetInspectValue<inspect::UintPropertyValue>(
172         metrics_inspector_, {"metrics", "bredr", "connection_events"});
173     PW_CHECK(val);
174     return *val;
175   }
176 
MetricsBrEdrDisconnections()177   uint64_t MetricsBrEdrDisconnections() {
178     std::optional<uint64_t> val = GetInspectValue<inspect::UintPropertyValue>(
179         metrics_inspector_, {"metrics", "bredr", "disconnection_events"});
180     PW_CHECK(val);
181     return *val;
182   }
183 #endif  // NINSPECT
184 
set_notify_listeners_cb(Peer::NotifyListenersCallback cb)185   void set_notify_listeners_cb(Peer::NotifyListenersCallback cb) {
186     notify_listeners_cb_ = std::move(cb);
187   }
set_update_expiry_cb(Peer::PeerCallback cb)188   void set_update_expiry_cb(Peer::PeerCallback cb) {
189     update_expiry_cb_ = std::move(cb);
190   }
set_dual_mode_cb(Peer::PeerCallback cb)191   void set_dual_mode_cb(Peer::PeerCallback cb) {
192     dual_mode_cb_ = std::move(cb);
193   }
set_store_le_bond_cb(Peer::StoreLowEnergyBondCallback cb)194   void set_store_le_bond_cb(Peer::StoreLowEnergyBondCallback cb) {
195     store_le_bond_cb_ = std::move(cb);
196   }
197 
198  private:
NotifyListenersCallback(const Peer & peer,Peer::NotifyListenersChange change)199   void NotifyListenersCallback(const Peer& peer,
200                                Peer::NotifyListenersChange change) {
201     if (notify_listeners_cb_) {
202       notify_listeners_cb_(peer, change);
203     }
204   }
205 
UpdateExpiryCallback(const Peer & peer)206   void UpdateExpiryCallback(const Peer& peer) {
207     if (update_expiry_cb_) {
208       update_expiry_cb_(peer);
209     }
210   }
211 
DualModeCallback(const Peer & peer)212   void DualModeCallback(const Peer& peer) {
213     if (dual_mode_cb_) {
214       dual_mode_cb_(peer);
215     }
216   }
217 
StoreLowEnergyBondCallback(const sm::PairingData & data)218   bool StoreLowEnergyBondCallback(const sm::PairingData& data) {
219     if (store_le_bond_cb_) {
220       return store_le_bond_cb_(data);
221     }
222     return false;
223   }
224 
225   std::unique_ptr<Peer> peer_;
226   DeviceAddress address_;
227   Peer::NotifyListenersCallback notify_listeners_cb_;
228   Peer::PeerCallback update_expiry_cb_;
229   Peer::PeerCallback dual_mode_cb_;
230   Peer::StoreLowEnergyBondCallback store_le_bond_cb_;
231   inspect::Inspector metrics_inspector_;
232   PeerMetrics metrics_;
233   inspect::Inspector peer_inspector_;
234 };
235 
236 class PeerDeathTest : public PeerTest {};
237 
238 #ifndef NINSPECT
TEST_F(PeerTest,InspectHierarchy)239 TEST_F(PeerTest, InspectHierarchy) {
240   peer().set_version(pw::bluetooth::emboss::CoreSpecificationVersion::V5_0,
241                      kManufacturer,
242                      kSubversion);
243 
244   peer().RegisterName("Sapphire��", Peer::NameSource::kGenericAccessService);
245 
246   peer().MutLe();
247   ASSERT_TRUE(peer().le().has_value());
248 
249   peer().MutLe().SetFeatures(hci_spec::LESupportedFeatures{0x0000000000000001});
250 
251   peer().MutBrEdr().AddService(UUID(uint16_t{0x110b}));
252 
253   auto bredr_data_matcher = AllOf(NodeMatches(
254       AllOf(NameMatches(Peer::BrEdrData::kInspectNodeName),
255             PropertyList(UnorderedElementsAre(
256                 StringIs(Peer::BrEdrData::kInspectConnectionStateName,
257                          Peer::ConnectionStateToString(
258                              peer().bredr()->connection_state())),
259                 StringIs(Peer::BrEdrData::kInspectServicesName,
260                          "{ 0000110b-0000-1000-8000-00805f9b34fb }"))))));
261 
262   auto le_data_matcher = AllOf(NodeMatches(AllOf(
263       NameMatches(Peer::LowEnergyData::kInspectNodeName),
264       PropertyList(UnorderedElementsAre(
265           StringIs(
266               Peer::LowEnergyData::kInspectConnectionStateName,
267               Peer::ConnectionStateToString(peer().le()->connection_state())),
268           IntIs(
269               Peer::LowEnergyData::kInspectAdvertisingDataParseFailureCountName,
270               0),
271           StringIs(
272               Peer::LowEnergyData::kInspectLastAdvertisingDataParseFailureName,
273               ""),
274           BoolIs(Peer::LowEnergyData::kInspectBondDataName,
275                  peer().le()->bonded()),
276           StringIs(Peer::LowEnergyData::kInspectFeaturesName,
277                    "0x0000000000000001"))))));
278 
279   auto peer_matcher = AllOf(
280       NodeMatches(PropertyList(UnorderedElementsAre(
281           StringIs(Peer::kInspectPeerIdName, peer().identifier().ToString()),
282           StringIs(Peer::kInspectPeerNameName,
283                    peer().name().value() + " [source: " +
284                        Peer::NameSourceToString(
285                            Peer::NameSource::kGenericAccessService) +
286                        "]"),
287           StringIs(Peer::kInspectTechnologyName,
288                    TechnologyTypeToString(peer().technology())),
289           StringIs(Peer::kInspectAddressName, peer().address().ToString()),
290           BoolIs(Peer::kInspectConnectableName, peer().connectable()),
291           BoolIs(Peer::kInspectTemporaryName, peer().temporary()),
292           StringIs(Peer::kInspectFeaturesName, peer().features().ToString()),
293           StringIs(Peer::kInspectVersionName,
294                    hci_spec::HCIVersionToString(peer().version().value())),
295           StringIs(Peer::kInspectManufacturerName,
296                    GetManufacturerName(kManufacturer))))),
297       ChildrenMatch(UnorderedElementsAre(bredr_data_matcher, le_data_matcher)));
298   // clang-format on
299   inspect::Hierarchy hierarchy = ReadPeerInspect();
300   EXPECT_THAT(hierarchy,
301               AllOf(ChildrenMatch(UnorderedElementsAre(peer_matcher))));
302 }
303 #endif  // NINSPECT
304 
305 #ifndef NINSPECT
TEST_F(PeerTest,SetBrEdrBondDataUpdatesInspectProperties)306 TEST_F(PeerTest, SetBrEdrBondDataUpdatesInspectProperties) {
307   const char* const kInspectLevelPropertyName = "level";
308   const char* const kInspectEncryptedPropertyName = "encrypted";
309   const char* const kInspectSecureConnectionsPropertyName =
310       "secure_connections";
311   const char* const kInspectAuthenticatedPropertyName = "authenticated";
312   const char* const kInspectKeyTypePropertyName = "key_type";
313 
314   peer().set_version(pw::bluetooth::emboss::CoreSpecificationVersion::V5_0,
315                      kManufacturer,
316                      kSubversion);
317 
318   peer().RegisterName("Sapphire��", Peer::NameSource::kGenericAccessService);
319 
320   peer().MutLe();
321   ASSERT_TRUE(peer().le().has_value());
322 
323   peer().MutLe().SetFeatures(hci_spec::LESupportedFeatures{0x0000000000000001});
324 
325   peer().MutBrEdr().AddService(UUID(uint16_t{0x110b}));
326   peer().MutBrEdr().SetBondData(kLTK);
327 
328   // clang-format off
329   auto bredr_data_matcher = AllOf(
330     NodeMatches(AllOf(
331       NameMatches(Peer::BrEdrData::kInspectNodeName),
332       PropertyList(UnorderedElementsAre(
333         StringIs(Peer::BrEdrData::kInspectConnectionStateName,
334                  Peer::ConnectionStateToString(peer().bredr()->connection_state())),
335         StringIs(Peer::BrEdrData::kInspectServicesName, "{ 0000110b-0000-1000-8000-00805f9b34fb }")
336         )))));
337 
338   auto le_data_matcher = AllOf(
339     NodeMatches(AllOf(
340       NameMatches(Peer::LowEnergyData::kInspectNodeName),
341       PropertyList(UnorderedElementsAre(
342         StringIs(Peer::LowEnergyData::kInspectConnectionStateName,
343                  Peer::ConnectionStateToString(peer().le()->connection_state())),
344         IntIs(Peer::LowEnergyData::kInspectAdvertisingDataParseFailureCountName, 0),
345         StringIs(Peer::LowEnergyData::kInspectLastAdvertisingDataParseFailureName, ""),
346         BoolIs(Peer::LowEnergyData::kInspectBondDataName, peer().le()->bonded()),
347         StringIs(Peer::LowEnergyData::kInspectFeaturesName, "0x0000000000000001")
348         )))));
349 
350   auto peer_matcher = AllOf(
351     NodeMatches(
352       PropertyList(UnorderedElementsAre(
353         StringIs(Peer::kInspectPeerIdName, peer().identifier().ToString()),
354         StringIs(Peer::kInspectPeerNameName, peer().name().value() + " [source: " + Peer::NameSourceToString(Peer::NameSource::kGenericAccessService) + "]"),
355         StringIs(Peer::kInspectTechnologyName, TechnologyTypeToString(peer().technology())),
356         StringIs(Peer::kInspectAddressName, peer().address().ToString()),
357         BoolIs(Peer::kInspectConnectableName, peer().connectable()),
358         BoolIs(Peer::kInspectTemporaryName, peer().temporary()),
359         StringIs(Peer::kInspectFeaturesName, peer().features().ToString()),
360         StringIs(Peer::kInspectVersionName, hci_spec::HCIVersionToString(peer().version().value())),
361         StringIs(Peer::kInspectManufacturerName, GetManufacturerName(kManufacturer))
362         ))),
363     ChildrenMatch(UnorderedElementsAre(bredr_data_matcher, le_data_matcher)));
364   // clang-format on
365   inspect::Hierarchy hierarchy = ReadPeerInspect();
366   EXPECT_THAT(hierarchy,
367               AllOf(ChildrenMatch(UnorderedElementsAre(peer_matcher))));
368 
369   peer().MutBrEdr().SetBondData(kSecureBrEdrKey);
370 
371   const sm::SecurityProperties security_properties =
372       peer().bredr()->link_key().value().security();
373   auto link_key_matcher = AllOf(NodeMatches(
374       AllOf(NameMatches("link_key"),
375             PropertyList(UnorderedElementsAre(
376                 StringIs(kInspectLevelPropertyName,
377                          LevelToString(security_properties.level())),
378                 BoolIs(kInspectEncryptedPropertyName,
379                        security_properties.encrypted()),
380                 BoolIs(kInspectSecureConnectionsPropertyName,
381                        security_properties.secure_connections()),
382                 BoolIs(kInspectAuthenticatedPropertyName,
383                        security_properties.authenticated()),
384                 StringIs(kInspectKeyTypePropertyName,
385                          hci_spec::LinkKeyTypeToString(
386                              security_properties.GetLinkKeyType())))))));
387 
388   auto bredr_data_matcher2 =
389       AllOf(NodeMatches(AllOf(
390                 NameMatches(Peer::BrEdrData::kInspectNodeName),
391                 PropertyList(UnorderedElementsAre(
392                     StringIs(Peer::BrEdrData::kInspectConnectionStateName,
393                              Peer::ConnectionStateToString(
394                                  peer().bredr()->connection_state())),
395                     StringIs(Peer::BrEdrData::kInspectServicesName,
396                              "{ 0000110b-0000-1000-8000-00805f9b34fb }"))))),
397             ChildrenMatch(UnorderedElementsAre(link_key_matcher)));
398 
399   auto le_data_matcher2 = AllOf(NodeMatches(AllOf(
400       NameMatches(Peer::LowEnergyData::kInspectNodeName),
401       PropertyList(UnorderedElementsAre(
402           StringIs(
403               Peer::LowEnergyData::kInspectConnectionStateName,
404               Peer::ConnectionStateToString(peer().le()->connection_state())),
405           IntIs(
406               Peer::LowEnergyData::kInspectAdvertisingDataParseFailureCountName,
407               0),
408           StringIs(
409               Peer::LowEnergyData::kInspectLastAdvertisingDataParseFailureName,
410               ""),
411           BoolIs(Peer::LowEnergyData::kInspectBondDataName,
412                  peer().le()->bonded()),
413           StringIs(Peer::LowEnergyData::kInspectFeaturesName,
414                    "0x0000000000000001"))))));
415 
416   auto peer_matcher2 = AllOf(
417       NodeMatches(PropertyList(UnorderedElementsAre(
418           StringIs(Peer::kInspectPeerIdName, peer().identifier().ToString()),
419           StringIs(Peer::kInspectPeerNameName,
420                    peer().name().value() + " [source: " +
421                        Peer::NameSourceToString(
422                            Peer::NameSource::kGenericAccessService) +
423                        "]"),
424           StringIs(Peer::kInspectTechnologyName,
425                    TechnologyTypeToString(peer().technology())),
426           StringIs(Peer::kInspectAddressName, peer().address().ToString()),
427           BoolIs(Peer::kInspectConnectableName, peer().connectable()),
428           BoolIs(Peer::kInspectTemporaryName, peer().temporary()),
429           StringIs(Peer::kInspectFeaturesName, peer().features().ToString()),
430           StringIs(Peer::kInspectVersionName,
431                    hci_spec::HCIVersionToString(peer().version().value())),
432           StringIs(Peer::kInspectManufacturerName,
433                    GetManufacturerName(kManufacturer))))),
434       ChildrenMatch(
435           UnorderedElementsAre(bredr_data_matcher2, le_data_matcher2)));
436   // clang-format on
437   hierarchy = ReadPeerInspect();
438   EXPECT_THAT(hierarchy,
439               AllOf(ChildrenMatch(UnorderedElementsAre(peer_matcher2))));
440 }
441 #endif  // NINSPECT
442 
TEST_F(PeerTest,BrEdrDataAddServiceNotifiesListeners)443 TEST_F(PeerTest, BrEdrDataAddServiceNotifiesListeners) {
444   // Initialize BrEdrData.
445   peer().MutBrEdr();
446   ASSERT_TRUE(peer().bredr()->services().empty());
447 
448   bool listener_notified = false;
449   set_notify_listeners_cb([&](auto&, Peer::NotifyListenersChange change) {
450     listener_notified = true;
451     // Non-bonded peer should not update bond
452     EXPECT_EQ(Peer::NotifyListenersChange::kBondNotUpdated, change);
453   });
454 
455   constexpr UUID kServiceUuid;
456   peer().MutBrEdr().AddService(kServiceUuid);
457   EXPECT_TRUE(listener_notified);
458   EXPECT_EQ(1u, peer().bredr()->services().count(kServiceUuid));
459 
460   // De-duplicate subsequent additions of the same service.
461   listener_notified = false;
462   peer().MutBrEdr().AddService(kServiceUuid);
463   EXPECT_FALSE(listener_notified);
464 }
465 
TEST_F(PeerTest,BrEdrDataAddServiceOnBondedPeerNotifiesListenersToUpdateBond)466 TEST_F(PeerTest, BrEdrDataAddServiceOnBondedPeerNotifiesListenersToUpdateBond) {
467   // Initialize BrEdrData.
468   peer().MutBrEdr().SetBondData({});
469   ASSERT_TRUE(peer().bredr()->services().empty());
470 
471   bool listener_notified = false;
472   set_notify_listeners_cb([&](auto&, Peer::NotifyListenersChange change) {
473     listener_notified = true;
474     // Bonded peer should update bond
475     EXPECT_EQ(Peer::NotifyListenersChange::kBondUpdated, change);
476   });
477 
478   peer().MutBrEdr().AddService(UUID());
479   EXPECT_TRUE(listener_notified);
480 }
481 
TEST_F(PeerTest,LowEnergyDataSetAdvDataWithInvalidUtf8NameDoesNotUpdatePeerName)482 TEST_F(PeerTest,
483        LowEnergyDataSetAdvDataWithInvalidUtf8NameDoesNotUpdatePeerName) {
484   peer().MutLe();  // Initialize LowEnergyData.
485   ASSERT_FALSE(peer().name().has_value());
486 
487   bool listener_notified = false;
488   set_notify_listeners_cb(
489       [&](auto&, Peer::NotifyListenersChange) { listener_notified = true; });
490 
491   const StaticByteBuffer kBadAdvData(
492       0x05,  // Length
493       0x09,  // AD type: Complete Local Name
494       'T',
495       'e',
496       's',
497       0xFF  // 0xFF should not appear in a valid UTF-8 string
498   );
499 
500   peer().MutLe().SetAdvertisingData(
501       /*rssi=*/0, kBadAdvData, pw::chrono::SystemClock::time_point());
502   EXPECT_TRUE(listener_notified);  // Fresh AD still results in an update
503   EXPECT_FALSE(peer().name().has_value());
504 }
505 
TEST_F(PeerTest,BrEdrDataSetEirDataWithInvalidUtf8NameDoesNotUpdatePeerName)506 TEST_F(PeerTest, BrEdrDataSetEirDataWithInvalidUtf8NameDoesNotUpdatePeerName) {
507   peer().MutBrEdr();  // Initialize BrEdrData.
508   ASSERT_FALSE(peer().name().has_value());
509 
510   bool listener_notified = false;
511   set_notify_listeners_cb(
512       [&](auto&, Peer::NotifyListenersChange) { listener_notified = true; });
513 
514   const StaticByteBuffer kEirData(
515       0x05,  // Length
516       0x09,  // AD type: Complete Local Name
517       'T',
518       'e',
519       's',
520       0xFF  // 0xFF should not appear in a valid UTF-8 string
521   );
522 
523   StaticPacket<pw::bluetooth::emboss::ExtendedInquiryResultEventWriter> eirep;
524   eirep.view().num_responses().Write(1);
525   eirep.view().bd_addr().CopyFrom(peer().address().value().view());
526   eirep.view().extended_inquiry_response().BackingStorage().CopyFrom(
527       ::emboss::support::ReadOnlyContiguousBuffer(&kEirData), kEirData.size());
528 
529   peer().MutBrEdr().SetInquiryData(eirep.view());
530   EXPECT_TRUE(listener_notified);  // Fresh EIR data still results in an update
531   EXPECT_FALSE(peer().name().has_value());
532 }
533 
TEST_F(PeerTest,RegisterNameWithInvalidUtf8NameDoesNotUpdatePeerName)534 TEST_F(PeerTest, RegisterNameWithInvalidUtf8NameDoesNotUpdatePeerName) {
535   ASSERT_FALSE(peer().name().has_value());
536 
537   bool listener_notified = false;
538   set_notify_listeners_cb(
539       [&](auto&, Peer::NotifyListenersChange) { listener_notified = true; });
540 
541   const std::string kName =
542       "Tes\xFF\x01";  // 0xFF should not appear in a valid UTF-8 string
543   peer().RegisterName(kName);
544   EXPECT_FALSE(listener_notified);
545   EXPECT_FALSE(peer().name().has_value());
546 }
547 
TEST_F(PeerTest,LowEnergyAdvertisingDataTimestamp)548 TEST_F(PeerTest, LowEnergyAdvertisingDataTimestamp) {
549   EXPECT_FALSE(peer().MutLe().parsed_advertising_data_timestamp());
550   peer().MutLe().SetAdvertisingData(
551       /*rssi=*/0,
552       kAdvData,
553       pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(1)));
554   ASSERT_TRUE(peer().MutLe().parsed_advertising_data_timestamp());
555   EXPECT_EQ(peer().MutLe().parsed_advertising_data_timestamp().value(),
556             pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(1)));
557 
558   peer().MutLe().SetAdvertisingData(
559       /*rssi=*/0,
560       kAdvData,
561       pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(2)));
562   ASSERT_TRUE(peer().MutLe().parsed_advertising_data_timestamp());
563   EXPECT_EQ(peer().MutLe().parsed_advertising_data_timestamp().value(),
564             pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(2)));
565 
566   // SetAdvertisingData with data that fails to parse should not update the
567   // advertising data timestamp.
568   peer().MutLe().SetAdvertisingData(
569       /*rssi=*/0,
570       kInvalidAdvData,
571       pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(3)));
572   ASSERT_TRUE(peer().MutLe().parsed_advertising_data_timestamp());
573   EXPECT_EQ(peer().MutLe().parsed_advertising_data_timestamp().value(),
574             pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(2)));
575 }
576 
TEST_F(PeerTest,SettingLowEnergyAdvertisingDataUpdatesLastUpdated)577 TEST_F(PeerTest, SettingLowEnergyAdvertisingDataUpdatesLastUpdated) {
578   EXPECT_EQ(peer().last_updated(),
579             pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(0)));
580 
581   int notify_count = 0;
582   set_notify_listeners_cb([&](const Peer&, Peer::NotifyListenersChange) {
583     EXPECT_EQ(peer().last_updated(),
584               pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(2)));
585     notify_count++;
586   });
587 
588   RunFor(pw::chrono::SystemClock::duration(2));
589   peer().MutLe().SetAdvertisingData(
590       /*rssi=*/0,
591       kAdvData,
592       pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(1)));
593   EXPECT_EQ(peer().last_updated(),
594             pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(2)));
595   EXPECT_GE(notify_count, 1);
596 }
597 
TEST_F(PeerTest,RegisteringLowEnergyInitializingConnectionUpdatesLastUpdated)598 TEST_F(PeerTest, RegisteringLowEnergyInitializingConnectionUpdatesLastUpdated) {
599   EXPECT_EQ(peer().last_updated(),
600             pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(0)));
601 
602   int notify_count = 0;
603   set_notify_listeners_cb([&](const Peer&, Peer::NotifyListenersChange) {
604     EXPECT_EQ(peer().last_updated(),
605               pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(2)));
606     notify_count++;
607   });
608 
609   RunFor(pw::chrono::SystemClock::duration(2));
610   Peer::InitializingConnectionToken token =
611       peer().MutLe().RegisterInitializingConnection();
612   EXPECT_EQ(peer().last_updated(),
613             pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(2)));
614   EXPECT_GE(notify_count, 1);
615 }
616 
TEST_F(PeerTest,SettingLowEnergyBondDataUpdatesLastUpdated)617 TEST_F(PeerTest, SettingLowEnergyBondDataUpdatesLastUpdated) {
618   EXPECT_EQ(peer().last_updated(),
619             pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(0)));
620 
621   int notify_count = 0;
622   set_notify_listeners_cb([&](const Peer&, Peer::NotifyListenersChange) {
623     EXPECT_EQ(peer().last_updated(),
624               pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(2)));
625     notify_count++;
626   });
627 
628   RunFor(pw::chrono::SystemClock::duration(2));
629   sm::PairingData data;
630   data.peer_ltk = kLTK;
631   data.local_ltk = kLTK;
632   peer().MutLe().SetBondData(data);
633   EXPECT_EQ(peer().last_updated(),
634             pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(2)));
635   EXPECT_GE(notify_count, 1);
636 }
637 
TEST_F(PeerTest,RegisteringBrEdrInitializingConnectionUpdatesLastUpdated)638 TEST_F(PeerTest, RegisteringBrEdrInitializingConnectionUpdatesLastUpdated) {
639   EXPECT_EQ(peer().last_updated(),
640             pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(0)));
641 
642   int notify_count = 0;
643   set_notify_listeners_cb([&](const Peer&, Peer::NotifyListenersChange) {
644     EXPECT_EQ(peer().last_updated(),
645               pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(2)));
646     notify_count++;
647   });
648 
649   RunFor(pw::chrono::SystemClock::duration(2));
650   Peer::InitializingConnectionToken token =
651       peer().MutBrEdr().RegisterInitializingConnection();
652   EXPECT_EQ(peer().last_updated(),
653             pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(2)));
654   EXPECT_GE(notify_count, 1);
655 }
656 
TEST_F(PeerTest,SettingInquiryDataUpdatesLastUpdated)657 TEST_F(PeerTest, SettingInquiryDataUpdatesLastUpdated) {
658   SetUpPeer(/*address=*/kAddrLeAlias, /*connectable=*/true);
659   EXPECT_EQ(peer().last_updated(),
660             pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(0)));
661 
662   int notify_count = 0;
663   set_notify_listeners_cb([&](const Peer&, Peer::NotifyListenersChange) {
664     EXPECT_EQ(peer().last_updated(),
665               pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(2)));
666     notify_count++;
667   });
668 
669   RunFor(pw::chrono::SystemClock::duration(2));
670   StaticPacket<pw::bluetooth::emboss::InquiryResultWriter> ir;
671   ir.view().bd_addr().CopyFrom(kAddrLeAlias.value().view());
672   peer().MutBrEdr().SetInquiryData(ir.view());
673   EXPECT_EQ(peer().last_updated(),
674             pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(2)));
675   EXPECT_GE(notify_count, 1);
676 }
677 
TEST_F(PeerTest,SettingBrEdrBondDataUpdatesLastUpdated)678 TEST_F(PeerTest, SettingBrEdrBondDataUpdatesLastUpdated) {
679   EXPECT_EQ(peer().last_updated(),
680             pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(0)));
681 
682   int notify_count = 0;
683   set_notify_listeners_cb([&](const Peer&, Peer::NotifyListenersChange) {
684     EXPECT_EQ(peer().last_updated(),
685               pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(2)));
686     notify_count++;
687   });
688 
689   RunFor(pw::chrono::SystemClock::duration(2));
690   peer().MutBrEdr().SetBondData(kSecureBrEdrKey);
691   EXPECT_EQ(peer().last_updated(),
692             pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(2)));
693   EXPECT_GE(notify_count, 1);
694 }
695 
TEST_F(PeerTest,SettingAddingBrEdrServiceUpdatesLastUpdated)696 TEST_F(PeerTest, SettingAddingBrEdrServiceUpdatesLastUpdated) {
697   EXPECT_EQ(peer().last_updated(),
698             pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(0)));
699 
700   int notify_count = 0;
701   set_notify_listeners_cb([&](const Peer&, Peer::NotifyListenersChange) {
702     EXPECT_EQ(peer().last_updated(),
703               pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(2)));
704     notify_count++;
705   });
706 
707   RunFor(pw::chrono::SystemClock::duration(2));
708   peer().MutBrEdr().AddService(UUID(uint16_t{0x110b}));
709   EXPECT_EQ(peer().last_updated(),
710             pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(2)));
711   EXPECT_GE(notify_count, 1);
712 }
713 
TEST_F(PeerTest,RegisteringNameUpdatesLastUpdated)714 TEST_F(PeerTest, RegisteringNameUpdatesLastUpdated) {
715   EXPECT_EQ(peer().last_updated(),
716             pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(0)));
717 
718   int notify_count = 0;
719   set_notify_listeners_cb([&](const Peer&, Peer::NotifyListenersChange) {
720     EXPECT_EQ(peer().last_updated(),
721               pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(2)));
722     notify_count++;
723   });
724 
725   RunFor(pw::chrono::SystemClock::duration(2));
726   peer().RegisterName("name");
727   EXPECT_EQ(peer().last_updated(),
728             pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(2)));
729   EXPECT_GE(notify_count, 1);
730 }
731 
TEST_F(PeerTest,RegisterAndUnregisterTwoLowEnergyConnections)732 TEST_F(PeerTest, RegisterAndUnregisterTwoLowEnergyConnections) {
733   SetUpPeer(/*address=*/kAddrLeRandom, /*connectable=*/true);
734 
735   int update_expiry_count = 0;
736   set_update_expiry_cb([&](const Peer&) { update_expiry_count++; });
737   int notify_count = 0;
738   set_notify_listeners_cb(
739       [&](const Peer&, Peer::NotifyListenersChange) { notify_count++; });
740 
741   std::optional<Peer::ConnectionToken> token_0 =
742       peer().MutLe().RegisterConnection();
743   // A notification and expiry update are sent when the peer becomes
744   // non-temporary, and a second notification and update expiry are sent because
745   // the connection is registered.
746   EXPECT_EQ(update_expiry_count, 2);
747   EXPECT_EQ(notify_count, 2);
748   EXPECT_FALSE(peer().temporary());
749   EXPECT_EQ(peer().le()->connection_state(), Peer::ConnectionState::kConnected);
750 #ifndef NINSPECT
751   EXPECT_EQ(InspectLowEnergyConnectionState(),
752             Peer::ConnectionStateToString(Peer::ConnectionState::kConnected));
753   EXPECT_EQ(MetricsLowEnergyConnections(), 1u);
754 #endif  // NINSPECT
755 
756   std::optional<Peer::ConnectionToken> token_1 =
757       peer().MutLe().RegisterConnection();
758   // The second connection should not update expiry or notify.
759   EXPECT_EQ(update_expiry_count, 2);
760   EXPECT_EQ(notify_count, 2);
761   EXPECT_FALSE(peer().temporary());
762   EXPECT_EQ(peer().le()->connection_state(), Peer::ConnectionState::kConnected);
763 #ifndef NINSPECT
764   EXPECT_EQ(InspectLowEnergyConnectionState(),
765             Peer::ConnectionStateToString(Peer::ConnectionState::kConnected));
766   // Although the second connection does not change the high-level connection
767   // state, we track it in metrics to support multiple connections to the same
768   // peer.
769   EXPECT_EQ(MetricsLowEnergyConnections(), 2u);
770   EXPECT_EQ(MetricsLowEnergyDisconnections(), 0u);
771 #endif  // NINSPECT
772 
773   token_0.reset();
774   EXPECT_EQ(update_expiry_count, 2);
775   EXPECT_EQ(notify_count, 2);
776   EXPECT_FALSE(peer().temporary());
777   EXPECT_EQ(peer().le()->connection_state(), Peer::ConnectionState::kConnected);
778 #ifndef NINSPECT
779   EXPECT_EQ(InspectLowEnergyConnectionState(),
780             Peer::ConnectionStateToString(Peer::ConnectionState::kConnected));
781   EXPECT_EQ(MetricsLowEnergyDisconnections(), 1u);
782 #endif  // NINSPECT
783 
784   token_1.reset();
785   EXPECT_EQ(update_expiry_count, 3);
786   EXPECT_EQ(notify_count, 3);
787   EXPECT_TRUE(peer().temporary());
788   EXPECT_EQ(peer().le()->connection_state(),
789             Peer::ConnectionState::kNotConnected);
790 #ifndef NINSPECT
791   EXPECT_EQ(
792       InspectLowEnergyConnectionState(),
793       Peer::ConnectionStateToString(Peer::ConnectionState::kNotConnected));
794   EXPECT_EQ(MetricsLowEnergyDisconnections(), 2u);
795 #endif  // NINSPECT
796 }
797 
TEST_F(PeerTest,RegisterAndUnregisterLowEnergyConnectionsWhenIdentityKnown)798 TEST_F(PeerTest, RegisterAndUnregisterLowEnergyConnectionsWhenIdentityKnown) {
799   EXPECT_TRUE(peer().identity_known());
800   std::optional<Peer::ConnectionToken> token =
801       peer().MutLe().RegisterConnection();
802   EXPECT_FALSE(peer().temporary());
803   token.reset();
804   // The peer's identity is known, so it should stay non-temporary upon
805   // disconnection.
806   EXPECT_FALSE(peer().temporary());
807   EXPECT_EQ(peer().le()->connection_state(),
808             Peer::ConnectionState::kNotConnected);
809 #ifndef NINSPECT
810   EXPECT_EQ(
811       InspectLowEnergyConnectionState(),
812       Peer::ConnectionStateToString(Peer::ConnectionState::kNotConnected));
813 #endif  // NINSPECT
814 }
815 
TEST_F(PeerTest,RegisterAndUnregisterInitializingLowEnergyConnectionsWhenIdentityKnown)816 TEST_F(PeerTest,
817        RegisterAndUnregisterInitializingLowEnergyConnectionsWhenIdentityKnown) {
818   EXPECT_TRUE(peer().identity_known());
819   std::optional<Peer::InitializingConnectionToken> token =
820       peer().MutLe().RegisterInitializingConnection();
821   EXPECT_FALSE(peer().temporary());
822   token.reset();
823   // The peer's identity is known, so it should stay non-temporary upon
824   // disconnection.
825   EXPECT_FALSE(peer().temporary());
826   EXPECT_EQ(peer().le()->connection_state(),
827             Peer::ConnectionState::kNotConnected);
828 #ifndef NINSPECT
829   EXPECT_EQ(
830       InspectLowEnergyConnectionState(),
831       Peer::ConnectionStateToString(Peer::ConnectionState::kNotConnected));
832 #endif  // NINSPECT
833 }
834 
TEST_F(PeerTest,RegisterAndUnregisterLowEnergyConnectionDuringInitializingConnection)835 TEST_F(PeerTest,
836        RegisterAndUnregisterLowEnergyConnectionDuringInitializingConnection) {
837   SetUpPeer(/*address=*/kAddrLeRandom, /*connectable=*/true);
838 
839   int update_expiry_count = 0;
840   set_update_expiry_cb([&](const Peer&) { update_expiry_count++; });
841   int notify_count = 0;
842   set_notify_listeners_cb(
843       [&](const Peer&, Peer::NotifyListenersChange) { notify_count++; });
844 
845   std::optional<Peer::InitializingConnectionToken> init_token =
846       peer().MutLe().RegisterInitializingConnection();
847   // A notification and expiry update are sent when the peer becomes
848   // non-temporary, and a second notification and update expiry are sent because
849   // the initializing connection is registered.
850   EXPECT_EQ(update_expiry_count, 2);
851   EXPECT_EQ(notify_count, 2);
852   EXPECT_FALSE(peer().temporary());
853   EXPECT_EQ(peer().le()->connection_state(),
854             Peer::ConnectionState::kInitializing);
855 #ifndef NINSPECT
856   EXPECT_EQ(
857       InspectLowEnergyConnectionState(),
858       Peer::ConnectionStateToString(Peer::ConnectionState::kInitializing));
859 #endif  // NINSPECT
860 
861   std::optional<Peer::ConnectionToken> conn_token =
862       peer().MutLe().RegisterConnection();
863   EXPECT_EQ(update_expiry_count, 3);
864   EXPECT_EQ(notify_count, 3);
865   EXPECT_FALSE(peer().temporary());
866   EXPECT_EQ(peer().le()->connection_state(), Peer::ConnectionState::kConnected);
867 #ifndef NINSPECT
868   EXPECT_EQ(InspectLowEnergyConnectionState(),
869             Peer::ConnectionStateToString(Peer::ConnectionState::kConnected));
870 #endif  // NINSPECT
871 
872   conn_token.reset();
873   EXPECT_EQ(update_expiry_count, 4);
874   EXPECT_EQ(notify_count, 4);
875   EXPECT_FALSE(peer().temporary());
876   EXPECT_EQ(peer().le()->connection_state(),
877             Peer::ConnectionState::kInitializing);
878 #ifndef NINSPECT
879   EXPECT_EQ(
880       InspectLowEnergyConnectionState(),
881       Peer::ConnectionStateToString(Peer::ConnectionState::kInitializing));
882 #endif  // NINSPECT
883 
884   init_token.reset();
885   EXPECT_EQ(update_expiry_count, 5);
886   EXPECT_EQ(notify_count, 5);
887   EXPECT_TRUE(peer().temporary());
888   EXPECT_EQ(peer().le()->connection_state(),
889             Peer::ConnectionState::kNotConnected);
890 #ifndef NINSPECT
891   EXPECT_EQ(
892       InspectLowEnergyConnectionState(),
893       Peer::ConnectionStateToString(Peer::ConnectionState::kNotConnected));
894 #endif  // NINSPECT
895 }
896 
TEST_F(PeerTest,RegisterAndUnregisterInitializingLowEnergyConnectionDuringConnection)897 TEST_F(PeerTest,
898        RegisterAndUnregisterInitializingLowEnergyConnectionDuringConnection) {
899   SetUpPeer(/*address=*/kAddrLeRandom, /*connectable=*/true);
900 
901   int update_expiry_count = 0;
902   set_update_expiry_cb([&](const Peer&) { update_expiry_count++; });
903   int notify_count = 0;
904   set_notify_listeners_cb(
905       [&](const Peer&, Peer::NotifyListenersChange) { notify_count++; });
906 
907   std::optional<Peer::ConnectionToken> conn_token =
908       peer().MutLe().RegisterConnection();
909   // A notification and expiry update are sent when the peer becomes
910   // non-temporary, and a second notification and update expiry are sent because
911   // the initializing connection is registered.
912   EXPECT_EQ(update_expiry_count, 2);
913   EXPECT_EQ(notify_count, 2);
914   EXPECT_FALSE(peer().temporary());
915   EXPECT_EQ(peer().le()->connection_state(), Peer::ConnectionState::kConnected);
916 #ifndef NINSPECT
917   EXPECT_EQ(InspectLowEnergyConnectionState(),
918             Peer::ConnectionStateToString(Peer::ConnectionState::kConnected));
919 #endif  // NINSPECT
920 
921   std::optional<Peer::InitializingConnectionToken> init_token =
922       peer().MutLe().RegisterInitializingConnection();
923   // Initializing connections should not affect the expiry or notify listeners
924   // for peers that are already connected.
925   EXPECT_EQ(update_expiry_count, 2);
926   EXPECT_EQ(notify_count, 2);
927   EXPECT_FALSE(peer().temporary());
928   EXPECT_EQ(peer().le()->connection_state(), Peer::ConnectionState::kConnected);
929 #ifndef NINSPECT
930   EXPECT_EQ(InspectLowEnergyConnectionState(),
931             Peer::ConnectionStateToString(Peer::ConnectionState::kConnected));
932 #endif  // NINSPECT
933 
934   init_token.reset();
935   EXPECT_EQ(update_expiry_count, 2);
936   EXPECT_EQ(notify_count, 2);
937   EXPECT_FALSE(peer().temporary());
938   EXPECT_EQ(peer().le()->connection_state(), Peer::ConnectionState::kConnected);
939 #ifndef NINSPECT
940   EXPECT_EQ(InspectLowEnergyConnectionState(),
941             Peer::ConnectionStateToString(Peer::ConnectionState::kConnected));
942 #endif  // NINSPECT
943 
944   conn_token.reset();
945   EXPECT_EQ(update_expiry_count, 3);
946   EXPECT_EQ(notify_count, 3);
947   EXPECT_TRUE(peer().temporary());
948   EXPECT_EQ(peer().le()->connection_state(),
949             Peer::ConnectionState::kNotConnected);
950 #ifndef NINSPECT
951   EXPECT_EQ(
952       InspectLowEnergyConnectionState(),
953       Peer::ConnectionStateToString(Peer::ConnectionState::kNotConnected));
954 #endif  // NINSPECT
955 }
956 
TEST_F(PeerTest,RegisterAndUnregisterTwoLowEnergyInitializingConnections)957 TEST_F(PeerTest, RegisterAndUnregisterTwoLowEnergyInitializingConnections) {
958   SetUpPeer(/*address=*/kAddrLeRandom, /*connectable=*/true);
959 
960   int update_expiry_count = 0;
961   set_update_expiry_cb([&](const Peer&) { update_expiry_count++; });
962   int notify_count = 0;
963   set_notify_listeners_cb(
964       [&](const Peer&, Peer::NotifyListenersChange) { notify_count++; });
965 
966   std::optional<Peer::InitializingConnectionToken> token_0 =
967       peer().MutLe().RegisterInitializingConnection();
968   // A notification and expiry update are sent when the peer becomes
969   // non-temporary, and a second notification and update expiry are sent because
970   // the initializing connection is registered.
971   EXPECT_EQ(update_expiry_count, 2);
972   EXPECT_EQ(notify_count, 2);
973   EXPECT_FALSE(peer().temporary());
974   EXPECT_EQ(peer().le()->connection_state(),
975             Peer::ConnectionState::kInitializing);
976 #ifndef NINSPECT
977   EXPECT_EQ(
978       InspectLowEnergyConnectionState(),
979       Peer::ConnectionStateToString(Peer::ConnectionState::kInitializing));
980 #endif  // NINSPECT
981 
982   std::optional<Peer::InitializingConnectionToken> token_1 =
983       peer().MutLe().RegisterInitializingConnection();
984   // The second initializing connection should not update expiry or notify.
985   EXPECT_EQ(update_expiry_count, 2);
986   EXPECT_EQ(notify_count, 2);
987   EXPECT_FALSE(peer().temporary());
988   EXPECT_EQ(peer().le()->connection_state(),
989             Peer::ConnectionState::kInitializing);
990 #ifndef NINSPECT
991   EXPECT_EQ(
992       InspectLowEnergyConnectionState(),
993       Peer::ConnectionStateToString(Peer::ConnectionState::kInitializing));
994 #endif  // NINSPECT
995 
996   token_0.reset();
997   EXPECT_EQ(update_expiry_count, 2);
998   EXPECT_EQ(notify_count, 2);
999   EXPECT_FALSE(peer().temporary());
1000   EXPECT_EQ(peer().le()->connection_state(),
1001             Peer::ConnectionState::kInitializing);
1002 #ifndef NINSPECT
1003   EXPECT_EQ(
1004       InspectLowEnergyConnectionState(),
1005       Peer::ConnectionStateToString(Peer::ConnectionState::kInitializing));
1006 #endif  // NINSPECT
1007   token_1.reset();
1008   EXPECT_EQ(update_expiry_count, 3);
1009   EXPECT_EQ(notify_count, 3);
1010   // The peer's identity is not known, so it should become temporary upon
1011   // disconnection.
1012   EXPECT_TRUE(peer().temporary());
1013   EXPECT_EQ(peer().le()->connection_state(),
1014             Peer::ConnectionState::kNotConnected);
1015 #ifndef NINSPECT
1016   EXPECT_EQ(
1017       InspectLowEnergyConnectionState(),
1018       Peer::ConnectionStateToString(Peer::ConnectionState::kNotConnected));
1019 #endif  // NINSPECT
1020 }
1021 
TEST_F(PeerTest,MovingLowEnergyConnectionTokenWorksAsExpected)1022 TEST_F(PeerTest, MovingLowEnergyConnectionTokenWorksAsExpected) {
1023   std::optional<Peer::ConnectionToken> token_0 =
1024       peer().MutLe().RegisterConnection();
1025   EXPECT_EQ(peer().le()->connection_state(), Peer::ConnectionState::kConnected);
1026 
1027   std::optional<Peer::ConnectionToken> token_1 = std::move(token_0);
1028   EXPECT_EQ(peer().le()->connection_state(), Peer::ConnectionState::kConnected);
1029 
1030   token_0.reset();
1031   EXPECT_EQ(peer().le()->connection_state(), Peer::ConnectionState::kConnected);
1032 
1033   token_1.reset();
1034   EXPECT_EQ(peer().le()->connection_state(),
1035             Peer::ConnectionState::kNotConnected);
1036 }
1037 
TEST_F(PeerTest,RegisterNamesWithVariousSources)1038 TEST_F(PeerTest, RegisterNamesWithVariousSources) {
1039   ASSERT_FALSE(peer().name().has_value());
1040   ASSERT_TRUE(
1041       peer().RegisterName("test", Peer::NameSource::kAdvertisingDataComplete));
1042 
1043   // Test that name with lower source priority does not replace stored name with
1044   // higher priority.
1045   ASSERT_FALSE(peer().RegisterName("test", Peer::NameSource::kUnknown));
1046 
1047   // Test that name with higher source priority replaces stored name with lower
1048   // priority.
1049   ASSERT_TRUE(
1050       peer().RegisterName("test", Peer::NameSource::kGenericAccessService));
1051 
1052   // Test that stored name is not replaced with an identical name from an
1053   // identical source.
1054   ASSERT_FALSE(
1055       peer().RegisterName("test", Peer::NameSource::kGenericAccessService));
1056 
1057   // Test that stored name is replaced by a different name from the same source.
1058   ASSERT_TRUE(peer().RegisterName("different_name",
1059                                   Peer::NameSource::kGenericAccessService));
1060 }
1061 
TEST_F(PeerTest,SetValidAdvertisingData)1062 TEST_F(PeerTest, SetValidAdvertisingData) {
1063   constexpr const char* kLocalName = "Test";
1064   StaticByteBuffer raw_data{
1065       // Length - Type - Value formatted Local name
1066       0x05,
1067       static_cast<uint8_t>(DataType::kCompleteLocalName),
1068       kLocalName[0],
1069       kLocalName[1],
1070       kLocalName[2],
1071       kLocalName[3],
1072   };
1073   peer().MutLe().SetAdvertisingData(
1074       /*rssi=*/32, raw_data, pw::chrono::SystemClock::time_point());
1075   // Setting an AdvertisingData with a local name field should update the peer's
1076   // local name.
1077   ASSERT_TRUE(peer().name().has_value());
1078   EXPECT_EQ(kLocalName, peer().name().value());
1079   EXPECT_EQ(Peer::NameSource::kAdvertisingDataComplete, peer().name_source());
1080 #ifndef NINSPECT
1081   EXPECT_EQ(0, InspectAdvertisingDataParseFailureCount());
1082   EXPECT_EQ("", InspectLastAdvertisingDataParseFailure());
1083 #endif  // NINSPECT
1084 }
1085 
TEST_F(PeerTest,SetShortenedLocalName)1086 TEST_F(PeerTest, SetShortenedLocalName) {
1087   constexpr const char* kLocalName = "Test";
1088   StaticByteBuffer raw_data{
1089       // Length - Type - Value formatted Local name
1090       0x05,
1091       static_cast<uint8_t>(DataType::kShortenedLocalName),
1092       kLocalName[0],
1093       kLocalName[1],
1094       kLocalName[2],
1095       kLocalName[3],
1096   };
1097   peer().MutLe().SetAdvertisingData(
1098       /*rssi=*/32, raw_data, pw::chrono::SystemClock::time_point());
1099   ASSERT_TRUE(peer().name().has_value());
1100   EXPECT_EQ(kLocalName, peer().name().value());
1101   EXPECT_EQ(Peer::NameSource::kAdvertisingDataShortened, peer().name_source());
1102 }
1103 
TEST_F(PeerTest,SetInvalidAdvertisingData)1104 TEST_F(PeerTest, SetInvalidAdvertisingData) {
1105   peer().MutLe().SetAdvertisingData(
1106       /*rssi=*/32, kInvalidAdvData, pw::chrono::SystemClock::time_point());
1107 
1108 #ifndef NINSPECT
1109   EXPECT_EQ(1, InspectAdvertisingDataParseFailureCount());
1110   EXPECT_EQ(AdvertisingData::ParseErrorToString(
1111                 AdvertisingData::ParseError::kUuidsMalformed),
1112             InspectLastAdvertisingDataParseFailure());
1113 #endif  // NINSPECT
1114 }
1115 
TEST_F(PeerDeathTest,RegisterTwoBrEdrConnectionsAsserts)1116 TEST_F(PeerDeathTest, RegisterTwoBrEdrConnectionsAsserts) {
1117   SetUpPeer(/*address=*/kAddrBrEdr, /*connectable=*/true);
1118   std::optional<Peer::ConnectionToken> token_0 =
1119       peer().MutBrEdr().RegisterConnection();
1120   ASSERT_DEATH_IF_SUPPORTED(
1121       {
1122         std::optional<Peer::ConnectionToken> token_1 =
1123             peer().MutBrEdr().RegisterConnection();
1124       },
1125       ".*already registered.*");
1126 }
1127 
TEST_F(PeerTest,RegisterAndUnregisterInitializingBrEdrConnectionLeavesPeerTemporary)1128 TEST_F(PeerTest,
1129        RegisterAndUnregisterInitializingBrEdrConnectionLeavesPeerTemporary) {
1130   SetUpPeer(/*address=*/kAddrBrEdr, /*connectable=*/true);
1131   EXPECT_TRUE(peer().identity_known());
1132   std::optional<Peer::InitializingConnectionToken> token =
1133       peer().MutBrEdr().RegisterInitializingConnection();
1134   EXPECT_FALSE(peer().temporary());
1135   token.reset();
1136   EXPECT_TRUE(peer().temporary());
1137   EXPECT_EQ(peer().bredr()->connection_state(),
1138             Peer::ConnectionState::kNotConnected);
1139 #ifndef NINSPECT
1140   EXPECT_EQ(
1141       InspectBrEdrConnectionState(),
1142       Peer::ConnectionStateToString(Peer::ConnectionState::kNotConnected));
1143 #endif  // NINSPECT
1144 }
1145 
TEST_F(PeerTest,RegisterAndUnregisterBrEdrConnectionWithoutBonding)1146 TEST_F(PeerTest, RegisterAndUnregisterBrEdrConnectionWithoutBonding) {
1147   SetUpPeer(/*address=*/kAddrBrEdr, /*connectable=*/true);
1148 
1149   int update_expiry_count = 0;
1150   set_update_expiry_cb([&](const Peer&) { update_expiry_count++; });
1151   int notify_count = 0;
1152   set_notify_listeners_cb(
1153       [&](const Peer&, Peer::NotifyListenersChange) { notify_count++; });
1154 
1155   std::optional<Peer::ConnectionToken> conn_token =
1156       peer().MutBrEdr().RegisterConnection();
1157   // A notification and expiry update are sent when the peer becomes
1158   // non-temporary, and a second notification and update expiry are sent because
1159   // the initializing connection is registered.
1160   EXPECT_EQ(update_expiry_count, 2);
1161   EXPECT_EQ(notify_count, 2);
1162   EXPECT_FALSE(peer().temporary());
1163   EXPECT_EQ(peer().bredr()->connection_state(),
1164             Peer::ConnectionState::kConnected);
1165 #ifndef NINSPECT
1166   EXPECT_EQ(InspectBrEdrConnectionState(),
1167             Peer::ConnectionStateToString(Peer::ConnectionState::kConnected));
1168 #endif  // NINSPECT
1169 
1170   conn_token.reset();
1171   EXPECT_EQ(update_expiry_count, 3);
1172   EXPECT_EQ(notify_count, 3);
1173   // BR/EDR peers should become non-temporary after disconnecting if not bonded.
1174   EXPECT_TRUE(peer().temporary());
1175   EXPECT_EQ(peer().bredr()->connection_state(),
1176             Peer::ConnectionState::kNotConnected);
1177 #ifndef NINSPECT
1178   EXPECT_EQ(
1179       InspectBrEdrConnectionState(),
1180       Peer::ConnectionStateToString(Peer::ConnectionState::kNotConnected));
1181 #endif  // NINSPECT
1182 }
1183 
TEST_F(PeerTest,RegisterAndUnregisterBrEdrConnectionWithBonding)1184 TEST_F(PeerTest, RegisterAndUnregisterBrEdrConnectionWithBonding) {
1185   SetUpPeer(/*address=*/kAddrBrEdr, /*connectable=*/true);
1186 
1187   int update_expiry_count = 0;
1188   set_update_expiry_cb([&](const Peer&) { update_expiry_count++; });
1189   int notify_count = 0;
1190   set_notify_listeners_cb(
1191       [&](const Peer&, Peer::NotifyListenersChange) { notify_count++; });
1192 
1193   std::optional<Peer::ConnectionToken> conn_token =
1194       peer().MutBrEdr().RegisterConnection();
1195   // A notification and expiry update are sent when the peer becomes
1196   // non-temporary, and a second notification and update expiry are sent because
1197   // the initializing connection is registered.
1198   EXPECT_EQ(update_expiry_count, 2);
1199   EXPECT_EQ(notify_count, 2);
1200   EXPECT_FALSE(peer().temporary());
1201   EXPECT_EQ(peer().bredr()->connection_state(),
1202             Peer::ConnectionState::kConnected);
1203 #ifndef NINSPECT
1204   EXPECT_EQ(InspectBrEdrConnectionState(),
1205             Peer::ConnectionStateToString(Peer::ConnectionState::kConnected));
1206 #endif  // NINSPECT
1207 
1208   peer().MutBrEdr().SetBondData(kSecureBrEdrKey);
1209   EXPECT_EQ(update_expiry_count, 2);
1210   EXPECT_EQ(notify_count, 3);
1211 
1212   conn_token.reset();
1213   EXPECT_EQ(update_expiry_count, 3);
1214   EXPECT_EQ(notify_count, 4);
1215   // Bonded BR/EDR peers should remain non-temporary after disconnecting.
1216   EXPECT_FALSE(peer().temporary());
1217   EXPECT_EQ(peer().bredr()->connection_state(),
1218             Peer::ConnectionState::kNotConnected);
1219 #ifndef NINSPECT
1220   EXPECT_EQ(
1221       InspectBrEdrConnectionState(),
1222       Peer::ConnectionStateToString(Peer::ConnectionState::kNotConnected));
1223 #endif  // NINSPECT
1224 }
1225 
TEST_F(PeerTest,RegisterAndUnregisterBrEdrConnectionDuringInitializingConnection)1226 TEST_F(PeerTest,
1227        RegisterAndUnregisterBrEdrConnectionDuringInitializingConnection) {
1228   SetUpPeer(/*address=*/kAddrBrEdr, /*connectable=*/true);
1229 
1230   int update_expiry_count = 0;
1231   set_update_expiry_cb([&](const Peer&) { update_expiry_count++; });
1232   int notify_count = 0;
1233   set_notify_listeners_cb(
1234       [&](const Peer&, Peer::NotifyListenersChange) { notify_count++; });
1235 
1236   std::optional<Peer::InitializingConnectionToken> init_token =
1237       peer().MutBrEdr().RegisterInitializingConnection();
1238   // Expiry is updated for state change + becoming non-temporary.
1239   EXPECT_EQ(update_expiry_count, 2);
1240   // 1 notification for becoming non-temporary.
1241   EXPECT_EQ(notify_count, 1);
1242   EXPECT_FALSE(peer().temporary());
1243   EXPECT_EQ(peer().bredr()->connection_state(),
1244             Peer::ConnectionState::kInitializing);
1245 #ifndef NINSPECT
1246   EXPECT_EQ(
1247       InspectBrEdrConnectionState(),
1248       Peer::ConnectionStateToString(Peer::ConnectionState::kInitializing));
1249 #endif  // NINSPECT
1250 
1251   // The connection state should not change when registering a connection
1252   // because the peer is still initializing.
1253   std::optional<Peer::ConnectionToken> conn_token =
1254       peer().MutBrEdr().RegisterConnection();
1255   EXPECT_EQ(update_expiry_count, 2);
1256   EXPECT_EQ(notify_count, 1);
1257   EXPECT_FALSE(peer().temporary());
1258   EXPECT_EQ(peer().bredr()->connection_state(),
1259             Peer::ConnectionState::kInitializing);
1260 #ifndef NINSPECT
1261   EXPECT_EQ(
1262       InspectBrEdrConnectionState(),
1263       Peer::ConnectionStateToString(Peer::ConnectionState::kInitializing));
1264 #endif  // NINSPECT
1265 
1266   conn_token.reset();
1267   EXPECT_EQ(update_expiry_count, 2);
1268   EXPECT_EQ(notify_count, 1);
1269   EXPECT_FALSE(peer().temporary());
1270   EXPECT_EQ(peer().bredr()->connection_state(),
1271             Peer::ConnectionState::kInitializing);
1272 #ifndef NINSPECT
1273   EXPECT_EQ(
1274       InspectBrEdrConnectionState(),
1275       Peer::ConnectionStateToString(Peer::ConnectionState::kInitializing));
1276 #endif  // NINSPECT
1277 
1278   init_token.reset();
1279   EXPECT_EQ(update_expiry_count, 3);
1280   EXPECT_EQ(notify_count, 1);
1281   EXPECT_TRUE(peer().temporary());
1282   EXPECT_EQ(peer().bredr()->connection_state(),
1283             Peer::ConnectionState::kNotConnected);
1284 #ifndef NINSPECT
1285   EXPECT_EQ(
1286       InspectBrEdrConnectionState(),
1287       Peer::ConnectionStateToString(Peer::ConnectionState::kNotConnected));
1288 #endif  // NINSPECT
1289 }
1290 
TEST_F(PeerTest,RegisterBrEdrConnectionDuringInitializingConnectionAndThenCompleteInitialization)1291 TEST_F(
1292     PeerTest,
1293     RegisterBrEdrConnectionDuringInitializingConnectionAndThenCompleteInitialization) {
1294   SetUpPeer(/*address=*/kAddrBrEdr, /*connectable=*/true);
1295 
1296   int update_expiry_count = 0;
1297   set_update_expiry_cb([&](const Peer&) { update_expiry_count++; });
1298   int notify_count = 0;
1299   set_notify_listeners_cb(
1300       [&](const Peer&, Peer::NotifyListenersChange) { notify_count++; });
1301 
1302   std::optional<Peer::InitializingConnectionToken> init_token =
1303       peer().MutBrEdr().RegisterInitializingConnection();
1304   // Expiry is updated for state change + becoming non-temporary.
1305   EXPECT_EQ(update_expiry_count, 2);
1306   // 1 notification for becoming non-temporary.
1307   EXPECT_EQ(notify_count, 1);
1308   EXPECT_FALSE(peer().temporary());
1309   EXPECT_EQ(peer().bredr()->connection_state(),
1310             Peer::ConnectionState::kInitializing);
1311 #ifndef NINSPECT
1312   EXPECT_EQ(
1313       InspectBrEdrConnectionState(),
1314       Peer::ConnectionStateToString(Peer::ConnectionState::kInitializing));
1315 #endif  // NINSPECT
1316 
1317   // The connection state should not change when registering a connection
1318   // because the peer is still initializing.
1319   std::optional<Peer::ConnectionToken> conn_token =
1320       peer().MutBrEdr().RegisterConnection();
1321   EXPECT_EQ(update_expiry_count, 2);
1322   EXPECT_EQ(notify_count, 1);
1323   EXPECT_FALSE(peer().temporary());
1324   EXPECT_EQ(peer().bredr()->connection_state(),
1325             Peer::ConnectionState::kInitializing);
1326 #ifndef NINSPECT
1327   EXPECT_EQ(
1328       InspectBrEdrConnectionState(),
1329       Peer::ConnectionStateToString(Peer::ConnectionState::kInitializing));
1330 #endif  // NINSPECT
1331 
1332   // When initialization completes, the connection state should become
1333   // kConnected.
1334   init_token.reset();
1335   EXPECT_EQ(update_expiry_count, 3);
1336   EXPECT_EQ(notify_count, 2);
1337   EXPECT_FALSE(peer().temporary());
1338   EXPECT_EQ(peer().bredr()->connection_state(),
1339             Peer::ConnectionState::kConnected);
1340 #ifndef NINSPECT
1341   EXPECT_EQ(InspectBrEdrConnectionState(),
1342             Peer::ConnectionStateToString(Peer::ConnectionState::kConnected));
1343 #endif  // NINSPECT
1344 
1345   conn_token.reset();
1346   EXPECT_EQ(update_expiry_count, 4);
1347   EXPECT_EQ(notify_count, 3);
1348   EXPECT_TRUE(peer().temporary());
1349   EXPECT_EQ(peer().bredr()->connection_state(),
1350             Peer::ConnectionState::kNotConnected);
1351 #ifndef NINSPECT
1352   EXPECT_EQ(
1353       InspectBrEdrConnectionState(),
1354       Peer::ConnectionStateToString(Peer::ConnectionState::kNotConnected));
1355 #endif  // NINSPECT
1356 }
1357 
TEST_F(PeerDeathTest,RegisterInitializingBrEdrConnectionDuringConnectionAsserts)1358 TEST_F(PeerDeathTest,
1359        RegisterInitializingBrEdrConnectionDuringConnectionAsserts) {
1360   SetUpPeer(/*address=*/kAddrBrEdr, /*connectable=*/true);
1361 
1362   int update_expiry_count = 0;
1363   set_update_expiry_cb([&](const Peer&) { update_expiry_count++; });
1364   int notify_count = 0;
1365   set_notify_listeners_cb(
1366       [&](const Peer&, Peer::NotifyListenersChange) { notify_count++; });
1367 
1368   std::optional<Peer::ConnectionToken> conn_token =
1369       peer().MutBrEdr().RegisterConnection();
1370   // A notification and expiry update are sent when the peer becomes
1371   // non-temporary, and a second notification and update expiry are sent because
1372   // the initializing connection is registered.
1373   EXPECT_EQ(update_expiry_count, 2);
1374   EXPECT_EQ(notify_count, 2);
1375   EXPECT_FALSE(peer().temporary());
1376   EXPECT_EQ(peer().bredr()->connection_state(),
1377             Peer::ConnectionState::kConnected);
1378 #ifndef NINSPECT
1379   EXPECT_EQ(InspectBrEdrConnectionState(),
1380             Peer::ConnectionStateToString(Peer::ConnectionState::kConnected));
1381 #endif  // NINSPECT
1382 
1383   // Registering an initializing connection when the peer is already connected
1384   // should assert.
1385   ASSERT_DEATH_IF_SUPPORTED(
1386       {
1387         Peer::InitializingConnectionToken init_token =
1388             peer().MutBrEdr().RegisterInitializingConnection();
1389       },
1390       ".*connected.*");
1391 }
1392 
TEST_F(PeerTest,RegisterAndUnregisterTwoBrEdrInitializingConnections)1393 TEST_F(PeerTest, RegisterAndUnregisterTwoBrEdrInitializingConnections) {
1394   SetUpPeer(/*address=*/kAddrBrEdr, /*connectable=*/true);
1395 
1396   int update_expiry_count = 0;
1397   set_update_expiry_cb([&](const Peer&) { update_expiry_count++; });
1398   int notify_count = 0;
1399   set_notify_listeners_cb(
1400       [&](const Peer&, Peer::NotifyListenersChange) { notify_count++; });
1401 
1402   std::optional<Peer::InitializingConnectionToken> token_0 =
1403       peer().MutBrEdr().RegisterInitializingConnection();
1404   EXPECT_EQ(update_expiry_count, 2);
1405   EXPECT_EQ(notify_count, 1);
1406   EXPECT_FALSE(peer().temporary());
1407   EXPECT_EQ(peer().bredr()->connection_state(),
1408             Peer::ConnectionState::kInitializing);
1409 #ifndef NINSPECT
1410   std::optional<std::string> inspect_conn_state = InspectBrEdrConnectionState();
1411   ASSERT_TRUE(inspect_conn_state);
1412   EXPECT_EQ(
1413       inspect_conn_state.value(),
1414       Peer::ConnectionStateToString(Peer::ConnectionState::kInitializing));
1415 #endif  // NINSPECT
1416 
1417   std::optional<Peer::InitializingConnectionToken> token_1 =
1418       peer().MutBrEdr().RegisterInitializingConnection();
1419   // The second initializing connection should not update expiry or notify.
1420   EXPECT_EQ(update_expiry_count, 2);
1421   EXPECT_EQ(notify_count, 1);
1422   EXPECT_FALSE(peer().temporary());
1423   EXPECT_EQ(peer().bredr()->connection_state(),
1424             Peer::ConnectionState::kInitializing);
1425 #ifndef NINSPECT
1426   inspect_conn_state = InspectBrEdrConnectionState();
1427   ASSERT_TRUE(inspect_conn_state);
1428   EXPECT_EQ(
1429       inspect_conn_state.value(),
1430       Peer::ConnectionStateToString(Peer::ConnectionState::kInitializing));
1431 #endif  // NINSPECT
1432 
1433   token_0.reset();
1434   EXPECT_EQ(update_expiry_count, 2);
1435   EXPECT_EQ(notify_count, 1);
1436   EXPECT_FALSE(peer().temporary());
1437   EXPECT_EQ(peer().bredr()->connection_state(),
1438             Peer::ConnectionState::kInitializing);
1439 #ifndef NINSPECT
1440   inspect_conn_state = InspectBrEdrConnectionState();
1441   ASSERT_TRUE(inspect_conn_state);
1442   EXPECT_EQ(
1443       inspect_conn_state.value(),
1444       Peer::ConnectionStateToString(Peer::ConnectionState::kInitializing));
1445 #endif  // NINSPECT
1446 
1447   token_1.reset();
1448   EXPECT_EQ(update_expiry_count, 3);
1449   EXPECT_EQ(notify_count, 1);
1450   EXPECT_TRUE(peer().temporary());
1451   EXPECT_EQ(peer().bredr()->connection_state(),
1452             Peer::ConnectionState::kNotConnected);
1453 #ifndef NINSPECT
1454   inspect_conn_state = InspectBrEdrConnectionState();
1455   ASSERT_TRUE(inspect_conn_state);
1456   EXPECT_EQ(
1457       inspect_conn_state.value(),
1458       Peer::ConnectionStateToString(Peer::ConnectionState::kNotConnected));
1459 #endif  // NINSPECT
1460 }
1461 
TEST_F(PeerTest,SettingLeAdvertisingDataOfBondedPeerDoesNotUpdateName)1462 TEST_F(PeerTest, SettingLeAdvertisingDataOfBondedPeerDoesNotUpdateName) {
1463   peer().RegisterName("alice");
1464   sm::PairingData data;
1465   data.peer_ltk = kLTK;
1466   data.local_ltk = kLTK;
1467   peer().MutLe().SetBondData(data);
1468 
1469   const StaticByteBuffer kBondedAdvData(0x08,  // Length
1470                                         0x09,  // AD type: Complete Local Name
1471                                         'M',
1472                                         'a',
1473                                         'l',
1474                                         'l',
1475                                         'o',
1476                                         'r',
1477                                         'y');
1478   peer().MutLe().SetAdvertisingData(
1479       /*rssi=*/0,
1480       kBondedAdvData,
1481       pw::chrono::SystemClock::time_point(std::chrono::nanoseconds(0)));
1482 
1483   ASSERT_TRUE(peer().name().has_value());
1484   EXPECT_EQ(peer().name().value(), "alice");
1485 }
1486 
TEST_F(PeerTest,SettingInquiryDataOfBondedPeerDoesNotUpdateName)1487 TEST_F(PeerTest, SettingInquiryDataOfBondedPeerDoesNotUpdateName) {
1488   peer().RegisterName("alice");
1489   peer().MutBrEdr().SetBondData(kLTK);
1490 
1491   const StaticByteBuffer kEirData(0x08,  // Length
1492                                   0x09,  // AD type: Complete Local Name
1493                                   'M',
1494                                   'a',
1495                                   'l',
1496                                   'l',
1497                                   'o',
1498                                   'r',
1499                                   'y');
1500   StaticPacket<pw::bluetooth::emboss::ExtendedInquiryResultEventWriter> eirep;
1501   eirep.view().num_responses().Write(1);
1502   eirep.view().bd_addr().CopyFrom(peer().address().value().view());
1503   eirep.view().extended_inquiry_response().BackingStorage().CopyFrom(
1504       ::emboss::support::ReadOnlyContiguousBuffer(&kEirData), kEirData.size());
1505 
1506   peer().MutBrEdr().SetInquiryData(eirep.view());
1507 
1508   ASSERT_TRUE(peer().name().has_value());
1509   EXPECT_EQ(peer().name().value(), "alice");
1510 }
1511 
TEST_F(PeerTest,BrEdrDataSetEirDataDoesUpdatePeerName)1512 TEST_F(PeerTest, BrEdrDataSetEirDataDoesUpdatePeerName) {
1513   peer().MutBrEdr();  // Initialize BrEdrData.
1514   ASSERT_FALSE(peer().name().has_value());
1515 
1516   bool listener_notified = false;
1517   set_notify_listeners_cb(
1518       [&](auto&, Peer::NotifyListenersChange) { listener_notified = true; });
1519 
1520   const StaticByteBuffer kEirData(0x0D,  // Length (13)
1521                                   0x09,  // AD type: Complete Local Name
1522                                   'S',
1523                                   'a',
1524                                   'p',
1525                                   'p',
1526                                   'h',
1527                                   'i',
1528                                   'r',
1529                                   'e',
1530                                   0xf0,
1531                                   0x9f,
1532                                   0x92,
1533                                   0x96);
1534 
1535   StaticPacket<pw::bluetooth::emboss::ExtendedInquiryResultEventWriter> eirep;
1536   eirep.view().num_responses().Write(1);
1537   eirep.view().bd_addr().CopyFrom(peer().address().value().view());
1538   eirep.view().extended_inquiry_response().BackingStorage().CopyFrom(
1539       ::emboss::support::ReadOnlyContiguousBuffer(&kEirData), kEirData.size());
1540 
1541   peer().MutBrEdr().SetInquiryData(eirep.view());
1542 
1543   EXPECT_TRUE(listener_notified);  // Fresh EIR data results in an update
1544   ASSERT_TRUE(peer().name().has_value());
1545   EXPECT_EQ(peer().name().value(), "Sapphire��");
1546 }
1547 
TEST_F(PeerTest,SetEirDataUpdatesServiceUUIDs)1548 TEST_F(PeerTest, SetEirDataUpdatesServiceUUIDs) {
1549   peer().MutBrEdr();  // Initialize BrEdrData.
1550                       // clang-format off
1551   const StaticByteBuffer kEirJustServiceUuids{
1552       // One 16-bit UUID: AudioSink
1553       0x03, static_cast<uint8_t>(DataType::kIncomplete16BitServiceUuids), 0x0A, 0x11,
1554   };
1555 
1556   StaticPacket<pw::bluetooth::emboss::ExtendedInquiryResultEventWriter> eirep;
1557   eirep.view().num_responses().Write(1);
1558   eirep.view().bd_addr().CopyFrom(peer().address().value().view());
1559   eirep.view().extended_inquiry_response().BackingStorage().CopyFrom(
1560       ::emboss::support::ReadOnlyContiguousBuffer(&kEirJustServiceUuids),
1561       kEirJustServiceUuids.size());
1562   peer().MutBrEdr().SetInquiryData(eirep.view());
1563 
1564   EXPECT_EQ(peer().bredr()->services().size(), 1u);
1565   EXPECT_EQ(peer().bredr()->services().count(UUID((uint16_t)0x110A)), 1u);
1566 }
1567 
TEST_F(PeerTest,LowEnergyStoreBondCallsCallback)1568 TEST_F(PeerTest, LowEnergyStoreBondCallsCallback) {
1569   int cb_count = 0;
1570   set_store_le_bond_cb([&cb_count](const sm::PairingData&) {
1571     cb_count++;
1572     return true;
1573   });
1574 
1575   sm::PairingData data;
1576   data.peer_ltk = kLTK;
1577   data.local_ltk = kLTK;
1578   EXPECT_TRUE(peer().MutLe().StoreBond(data));
1579   EXPECT_EQ(cb_count, 1);
1580 }
1581 
1582 }  // namespace
1583 }  // namespace bt::gap
1584