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