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/hci/advertising_handle_map.h"
16
17 #include "pw_bluetooth_sapphire/internal/host/hci-spec/constants.h"
18 #include "pw_bluetooth_sapphire/internal/host/hci-spec/protocol.h"
19 #include "pw_unit_test/framework.h"
20
21 namespace bt::hci {
22 namespace {
23
TEST(AdvertisingHandleMapTest,LegacyAndExtended)24 TEST(AdvertisingHandleMapTest, LegacyAndExtended) {
25 AdvertisingHandleMap handle_map;
26 DeviceAddress address = DeviceAddress(DeviceAddress::Type::kLEPublic, {0});
27
28 std::optional<hci_spec::AdvertisingHandle> legacy_handle =
29 handle_map.MapHandle(address, /*extended_pdu=*/false);
30 std::optional<hci_spec::AdvertisingHandle> extended_handle =
31 handle_map.MapHandle(address, /*extended_pdu=*/true);
32
33 EXPECT_TRUE(legacy_handle);
34 EXPECT_TRUE(extended_handle);
35 EXPECT_NE(legacy_handle, extended_handle);
36 }
37
38 class AdvertisingHandleMapTest : public testing::TestWithParam<bool> {};
39 INSTANTIATE_TEST_SUITE_P(AdvertisingHandleMapTest,
40 AdvertisingHandleMapTest,
41 ::testing::Bool());
42
TEST_P(AdvertisingHandleMapTest,Bidirectional)43 TEST_P(AdvertisingHandleMapTest, Bidirectional) {
44 AdvertisingHandleMap handle_map;
45
46 DeviceAddress address_a = DeviceAddress(DeviceAddress::Type::kLEPublic, {0});
47 std::optional<hci_spec::AdvertisingHandle> handle_a =
48 handle_map.MapHandle(address_a, GetParam());
49 EXPECT_LE(handle_a.value(), hci_spec::kMaxAdvertisingHandle);
50 EXPECT_TRUE(handle_a);
51
52 DeviceAddress address_b = DeviceAddress(DeviceAddress::Type::kLEPublic, {1});
53 std::optional<hci_spec::AdvertisingHandle> handle_b =
54 handle_map.MapHandle(address_b, GetParam());
55 EXPECT_TRUE(handle_b);
56 EXPECT_LE(handle_b.value(), hci_spec::kMaxAdvertisingHandle);
57
58 EXPECT_EQ(address_a, handle_map.GetAddress(handle_a.value()));
59 EXPECT_EQ(address_b, handle_map.GetAddress(handle_b.value()));
60 }
61
TEST_P(AdvertisingHandleMapTest,GetHandleDoesntCreateMapping)62 TEST_P(AdvertisingHandleMapTest, GetHandleDoesntCreateMapping) {
63 AdvertisingHandleMap handle_map;
64 EXPECT_EQ(0u, handle_map.Size());
65 EXPECT_TRUE(handle_map.Empty());
66
67 DeviceAddress address = DeviceAddress(DeviceAddress::Type::kLEPublic, {0});
68 std::optional<hci_spec::AdvertisingHandle> handle =
69 handle_map.GetHandle(address, GetParam());
70 EXPECT_EQ(0u, handle_map.Size());
71 EXPECT_TRUE(handle_map.Empty());
72 EXPECT_FALSE(handle);
73
74 handle = handle_map.MapHandle(address, GetParam());
75 EXPECT_EQ(1u, handle_map.Size());
76 EXPECT_FALSE(handle_map.Empty());
77 EXPECT_TRUE(handle);
78 EXPECT_EQ(0u, handle.value());
79
80 handle = handle_map.GetHandle(address, GetParam());
81 EXPECT_EQ(1u, handle_map.Size());
82 EXPECT_FALSE(handle_map.Empty());
83 EXPECT_TRUE(handle);
84 }
85
TEST_P(AdvertisingHandleMapTest,MapHandleAlreadyExists)86 TEST_P(AdvertisingHandleMapTest, MapHandleAlreadyExists) {
87 AdvertisingHandleMap handle_map;
88
89 DeviceAddress address = DeviceAddress(DeviceAddress::Type::kLEPublic, {0});
90 std::optional<hci_spec::AdvertisingHandle> expected =
91 handle_map.MapHandle(address, GetParam());
92 EXPECT_LE(expected.value(), hci_spec::kMaxAdvertisingHandle);
93 ASSERT_TRUE(expected);
94
95 std::optional<hci_spec::AdvertisingHandle> actual =
96 handle_map.MapHandle(address, GetParam());
97 EXPECT_LE(actual.value(), hci_spec::kMaxAdvertisingHandle);
98 ASSERT_TRUE(actual);
99 EXPECT_EQ(expected, actual);
100 }
101
TEST_P(AdvertisingHandleMapTest,MapHandleMoreThanSupported)102 TEST_P(AdvertisingHandleMapTest, MapHandleMoreThanSupported) {
103 AdvertisingHandleMap handle_map;
104
105 for (uint8_t i = 0; i < handle_map.capacity(); i++) {
106 DeviceAddress address = DeviceAddress(DeviceAddress::Type::kLEPublic, {i});
107 std::optional<hci_spec::AdvertisingHandle> handle =
108 handle_map.MapHandle(address, GetParam());
109 EXPECT_LE(handle.value(), hci_spec::kMaxAdvertisingHandle);
110 EXPECT_TRUE(handle) << "Couldn't add device address " << i;
111 EXPECT_EQ(i + 1u, handle_map.Size());
112 }
113
114 DeviceAddress address =
115 DeviceAddress(DeviceAddress::Type::kLEPublic, {handle_map.capacity()});
116
117 std::optional<hci_spec::AdvertisingHandle> handle =
118 handle_map.MapHandle(address, GetParam());
119 EXPECT_FALSE(handle);
120 EXPECT_EQ(handle_map.capacity(), handle_map.Size());
121 }
122
TEST_P(AdvertisingHandleMapTest,MapHandleSupportHandleReallocation)123 TEST_P(AdvertisingHandleMapTest, MapHandleSupportHandleReallocation) {
124 AdvertisingHandleMap handle_map;
125
126 for (uint8_t i = 0; i < handle_map.capacity(); i++) {
127 DeviceAddress address = DeviceAddress(DeviceAddress::Type::kLEPublic, {i});
128 std::optional<hci_spec::AdvertisingHandle> handle =
129 handle_map.MapHandle(address, GetParam());
130 EXPECT_LE(handle.value(), hci_spec::kMaxAdvertisingHandle);
131 EXPECT_TRUE(handle) << "Couldn't add device address " << i;
132 EXPECT_EQ(i + 1u, handle_map.Size());
133 }
134
135 hci_spec::AdvertisingHandle old_handle = 0;
136 std::optional<DeviceAddress> old_address = handle_map.GetAddress(old_handle);
137 ASSERT_TRUE(old_address);
138
139 handle_map.RemoveHandle(old_handle);
140
141 DeviceAddress address =
142 DeviceAddress(DeviceAddress::Type::kLEPublic, {handle_map.capacity()});
143 std::optional<hci_spec::AdvertisingHandle> new_handle =
144 handle_map.MapHandle(address, GetParam());
145 EXPECT_LE(new_handle.value(), hci_spec::kMaxAdvertisingHandle);
146
147 ASSERT_TRUE(new_handle);
148 ASSERT_EQ(old_handle, new_handle.value());
149
150 std::optional<DeviceAddress> new_address =
151 handle_map.GetAddress(new_handle.value());
152 ASSERT_TRUE(new_address);
153 ASSERT_NE(old_address, new_address);
154 }
155
TEST_P(AdvertisingHandleMapTest,GetAddressNonExistent)156 TEST_P(AdvertisingHandleMapTest, GetAddressNonExistent) {
157 AdvertisingHandleMap handle_map;
158 std::optional<DeviceAddress> address = handle_map.GetAddress(0);
159 EXPECT_FALSE(address);
160 }
161
TEST_P(AdvertisingHandleMapTest,RemoveHandle)162 TEST_P(AdvertisingHandleMapTest, RemoveHandle) {
163 AdvertisingHandleMap handle_map;
164 EXPECT_TRUE(handle_map.Empty());
165
166 DeviceAddress address = DeviceAddress(DeviceAddress::Type::kLEPublic, {0});
167 std::optional<hci_spec::AdvertisingHandle> handle =
168 handle_map.MapHandle(address, GetParam());
169 ASSERT_TRUE(handle);
170 EXPECT_LE(handle.value(), hci_spec::kMaxAdvertisingHandle);
171 EXPECT_EQ(1u, handle_map.Size());
172 EXPECT_FALSE(handle_map.Empty());
173
174 handle_map.RemoveHandle(handle.value());
175 EXPECT_EQ(0u, handle_map.Size());
176 EXPECT_TRUE(handle_map.Empty());
177 }
178
TEST_P(AdvertisingHandleMapTest,RemoveAddress)179 TEST_P(AdvertisingHandleMapTest, RemoveAddress) {
180 AdvertisingHandleMap handle_map;
181 EXPECT_TRUE(handle_map.Empty());
182
183 DeviceAddress address = DeviceAddress(DeviceAddress::Type::kLEPublic, {0});
184 handle_map.MapHandle(address, GetParam());
185 EXPECT_EQ(1u, handle_map.Size());
186 EXPECT_FALSE(handle_map.Empty());
187
188 handle_map.RemoveAddress(address, GetParam());
189 EXPECT_EQ(0u, handle_map.Size());
190 EXPECT_TRUE(handle_map.Empty());
191 }
192
TEST_P(AdvertisingHandleMapTest,RemoveHandleNonExistent)193 TEST_P(AdvertisingHandleMapTest, RemoveHandleNonExistent) {
194 AdvertisingHandleMap handle_map;
195 DeviceAddress address = DeviceAddress(DeviceAddress::Type::kLEPublic, {0});
196 std::optional<hci_spec::AdvertisingHandle> handle =
197 handle_map.MapHandle(address, GetParam());
198 ASSERT_TRUE(handle);
199
200 size_t size = handle_map.Size();
201
202 handle_map.RemoveHandle(handle.value() + 1);
203
204 EXPECT_EQ(size, handle_map.Size());
205 handle = handle_map.MapHandle(address, GetParam());
206 EXPECT_TRUE(handle);
207 }
208
TEST_P(AdvertisingHandleMapTest,RemoveAddressNonExistent)209 TEST_P(AdvertisingHandleMapTest, RemoveAddressNonExistent) {
210 AdvertisingHandleMap handle_map;
211 DeviceAddress address = DeviceAddress(DeviceAddress::Type::kLEPublic, {0});
212 std::optional<hci_spec::AdvertisingHandle> handle =
213 handle_map.MapHandle(address, GetParam());
214 ASSERT_TRUE(handle);
215
216 size_t size = handle_map.Size();
217
218 DeviceAddress nonexistent_address =
219 DeviceAddress(DeviceAddress::Type::kLEPublic, {1});
220 handle_map.RemoveAddress(nonexistent_address, GetParam());
221
222 EXPECT_EQ(size, handle_map.Size());
223 handle = handle_map.MapHandle(address, GetParam());
224 EXPECT_TRUE(handle);
225 }
226
TEST_P(AdvertisingHandleMapTest,Clear)227 TEST_P(AdvertisingHandleMapTest, Clear) {
228 AdvertisingHandleMap handle_map;
229 std::optional<hci_spec::AdvertisingHandle> handle =
230 handle_map.MapHandle(DeviceAddress(DeviceAddress::Type::kLEPublic, {0}),
231 /*extended_pdu=*/false);
232 ASSERT_TRUE(handle);
233
234 EXPECT_LE(handle.value(), hci_spec::kMaxAdvertisingHandle);
235 EXPECT_EQ(1u, handle_map.Size());
236
237 handle_map.Clear();
238 EXPECT_EQ(0u, handle_map.Size());
239
240 std::optional<DeviceAddress> address = handle_map.GetAddress(handle.value());
241 EXPECT_FALSE(address);
242 }
243
244 } // namespace
245 } // namespace bt::hci
246