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/identity_resolving_list.h"
16
17 #include "pw_bluetooth_sapphire/internal/host/common/random.h"
18 #include "pw_bluetooth_sapphire/internal/host/sm/util.h"
19 #include "pw_unit_test/framework.h"
20
21 namespace bt::gap {
22 namespace {
23
24 const DeviceAddress kAddress1(DeviceAddress::Type::kLERandom,
25 {6, 5, 4, 3, 2, 1});
26 const DeviceAddress kAddress2(DeviceAddress::Type::kLERandom,
27 {0x66, 0x55, 0x44, 0x33, 0x22, 0x11});
28
TEST(IdentityResolvingListTest,ResolveEmpty)29 TEST(IdentityResolvingListTest, ResolveEmpty) {
30 IdentityResolvingList rl;
31 EXPECT_EQ(std::nullopt, rl.Resolve(kAddress1));
32 }
33
TEST(IdentityResolvingListTest,Resolve)34 TEST(IdentityResolvingListTest, Resolve) {
35 IdentityResolvingList rl;
36
37 // Populate the list with two resolvable identities.
38 UInt128 irk1 = Random<UInt128>();
39 UInt128 irk2 = Random<UInt128>();
40 rl.Add(kAddress1, irk1);
41 rl.Add(kAddress2, irk2);
42
43 // Generate RPAs from the IRKs. The list should be able to resolve them.
44 DeviceAddress rpa1 = sm::util::GenerateRpa(irk1);
45 DeviceAddress rpa2 = sm::util::GenerateRpa(irk2);
46
47 auto identity1 = rl.Resolve(rpa1);
48 ASSERT_TRUE(identity1);
49 EXPECT_EQ(kAddress1, *identity1);
50
51 auto identity2 = rl.Resolve(rpa2);
52 ASSERT_TRUE(identity2);
53 EXPECT_EQ(kAddress2, *identity2);
54
55 // A resolvable address that can't be resolved by the list should report
56 // failure.
57 UInt128 unknown_irk = Random<UInt128>();
58 DeviceAddress unknown_rpa = sm::util::GenerateRpa(unknown_irk);
59 auto result = rl.Resolve(unknown_rpa);
60 EXPECT_FALSE(result);
61
62 // Removed identities should no longer resolve.
63 rl.Remove(kAddress2);
64 EXPECT_FALSE(rl.Resolve(rpa2));
65 EXPECT_EQ(kAddress1, *rl.Resolve(rpa1));
66
67 // Removing unknown devices should not crash.
68 rl.Remove(unknown_rpa);
69 rl.Remove(kAddress2);
70 }
71
72 // Tests that an identity address can be assigned a new IRK.
TEST(IdentityResolvingListTest,OverwriteIrk)73 TEST(IdentityResolvingListTest, OverwriteIrk) {
74 IdentityResolvingList rl;
75 UInt128 irk1 = Random<UInt128>();
76 UInt128 irk2 = Random<UInt128>();
77 DeviceAddress rpa1 = sm::util::GenerateRpa(irk1);
78 DeviceAddress rpa2 = sm::util::GenerateRpa(irk2);
79
80 rl.Add(kAddress1, irk1);
81 EXPECT_TRUE(rl.Resolve(rpa1));
82 EXPECT_FALSE(rl.Resolve(rpa2));
83
84 rl.Add(kAddress1, irk2);
85 EXPECT_FALSE(rl.Resolve(rpa1));
86 EXPECT_TRUE(rl.Resolve(rpa2));
87 }
88
89 } // namespace
90 } // namespace bt::gap
91