1 /*
2 * Copyright 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <gtest/gtest.h>
18
19 #include "model/controller/link_layer_controller.h"
20 #include "test_helpers.h"
21
22 namespace rootcanal {
23
24 using namespace bluetooth::hci;
25
26 class LeSetExtendedScanResponseDataTest : public ::testing::Test {
27 public:
LeSetExtendedScanResponseDataTest()28 LeSetExtendedScanResponseDataTest() {
29 // Reduce the number of advertising sets to simplify testing.
30 properties_.le_num_supported_advertising_sets = 2;
31 properties_.le_max_advertising_data_length = 300;
32 };
33 ~LeSetExtendedScanResponseDataTest() override = default;
34
35 protected:
36 Address address_{0};
37 ControllerProperties properties_{};
38 LinkLayerController controller_{address_, properties_};
39 };
40
TEST_F(LeSetExtendedScanResponseDataTest,Complete)41 TEST_F(LeSetExtendedScanResponseDataTest, Complete) {
42 ASSERT_EQ(controller_.LeSetExtendedAdvertisingParameters(
43 0, MakeAdvertisingEventProperties(SCANNABLE), 0x0800, 0x0800,
44 0x7, OwnAddressType::PUBLIC_DEVICE_ADDRESS,
45 PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS,
46 Address::kEmpty, AdvertisingFilterPolicy::ALL_DEVICES, 0x70,
47 PrimaryPhyType::LE_1M, 0, SecondaryPhyType::LE_2M, 0x0, false),
48 ErrorCode::SUCCESS);
49
50 std::vector<uint8_t> scan_response_data = {1, 2, 3};
51 ASSERT_EQ(
52 controller_.LeSetExtendedScanResponseData(
53 0, Operation::COMPLETE_ADVERTISEMENT,
54 FragmentPreference::CONTROLLER_MAY_FRAGMENT, scan_response_data),
55 ErrorCode::SUCCESS);
56 }
57
TEST_F(LeSetExtendedScanResponseDataTest,Discard)58 TEST_F(LeSetExtendedScanResponseDataTest, Discard) {
59 ASSERT_EQ(controller_.LeSetExtendedAdvertisingParameters(
60 0, MakeAdvertisingEventProperties(CONNECTABLE), 0x0800, 0x0800,
61 0x7, OwnAddressType::PUBLIC_DEVICE_ADDRESS,
62 PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS,
63 Address::kEmpty, AdvertisingFilterPolicy::ALL_DEVICES, 0x70,
64 PrimaryPhyType::LE_1M, 0, SecondaryPhyType::LE_2M, 0x0, false),
65 ErrorCode::SUCCESS);
66
67 ASSERT_EQ(controller_.LeSetExtendedScanResponseData(
68 0, Operation::COMPLETE_ADVERTISEMENT,
69 FragmentPreference::CONTROLLER_MAY_FRAGMENT, {}),
70 ErrorCode::SUCCESS);
71 }
72
TEST_F(LeSetExtendedScanResponseDataTest,Unchanged)73 TEST_F(LeSetExtendedScanResponseDataTest, Unchanged) {
74 ASSERT_EQ(controller_.LeSetExtendedAdvertisingParameters(
75 0, MakeAdvertisingEventProperties(SCANNABLE), 0x0800, 0x0800,
76 0x7, OwnAddressType::PUBLIC_DEVICE_ADDRESS,
77 PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS,
78 Address::kEmpty, AdvertisingFilterPolicy::ALL_DEVICES, 0x70,
79 PrimaryPhyType::LE_1M, 0, SecondaryPhyType::LE_2M, 0x0, false),
80 ErrorCode::SUCCESS);
81
82 std::vector<uint8_t> scan_response_data = {1, 2, 3};
83 ASSERT_EQ(
84 controller_.LeSetExtendedScanResponseData(
85 0, Operation::COMPLETE_ADVERTISEMENT,
86 FragmentPreference::CONTROLLER_MAY_FRAGMENT, scan_response_data),
87 ErrorCode::SUCCESS);
88
89 ASSERT_EQ(controller_.LeSetExtendedAdvertisingEnable(
90 true, {MakeEnabledSet(0, 0, 0)}),
91 ErrorCode::SUCCESS);
92
93 ASSERT_EQ(controller_.LeSetExtendedScanResponseData(
94 0, Operation::UNCHANGED_DATA,
95 FragmentPreference::CONTROLLER_MAY_FRAGMENT, {}),
96 ErrorCode::INVALID_HCI_COMMAND_PARAMETERS);
97 }
98
TEST_F(LeSetExtendedScanResponseDataTest,Fragmented)99 TEST_F(LeSetExtendedScanResponseDataTest, Fragmented) {
100 ASSERT_EQ(controller_.LeSetExtendedAdvertisingParameters(
101 0, MakeAdvertisingEventProperties(SCANNABLE), 0x0800, 0x0800,
102 0x7, OwnAddressType::PUBLIC_DEVICE_ADDRESS,
103 PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS,
104 Address::kEmpty, AdvertisingFilterPolicy::ALL_DEVICES, 0x70,
105 PrimaryPhyType::LE_1M, 0, SecondaryPhyType::LE_2M, 0x0, false),
106 ErrorCode::SUCCESS);
107
108 std::vector<uint8_t> first_scan_response_data_fragment = {1, 2, 3};
109 std::vector<uint8_t> intermediate_scan_response_data_fragment = {4, 5, 6};
110 std::vector<uint8_t> last_scan_response_data_fragment = {7, 8, 9};
111
112 ASSERT_EQ(controller_.LeSetExtendedScanResponseData(
113 0, Operation::FIRST_FRAGMENT,
114 FragmentPreference::CONTROLLER_MAY_FRAGMENT,
115 first_scan_response_data_fragment),
116 ErrorCode::SUCCESS);
117
118 ASSERT_EQ(controller_.LeSetExtendedScanResponseData(
119 0, Operation::INTERMEDIATE_FRAGMENT,
120 FragmentPreference::CONTROLLER_MAY_FRAGMENT,
121 intermediate_scan_response_data_fragment),
122 ErrorCode::SUCCESS);
123
124 ASSERT_EQ(controller_.LeSetExtendedScanResponseData(
125 0, Operation::LAST_FRAGMENT,
126 FragmentPreference::CONTROLLER_MAY_FRAGMENT,
127 last_scan_response_data_fragment),
128 ErrorCode::SUCCESS);
129 }
130
TEST_F(LeSetExtendedScanResponseDataTest,UnknownAdvertisingHandle)131 TEST_F(LeSetExtendedScanResponseDataTest, UnknownAdvertisingHandle) {
132 ASSERT_EQ(controller_.LeSetExtendedAdvertisingParameters(
133 0, MakeAdvertisingEventProperties(SCANNABLE), 0x0800, 0x0800,
134 0x7, OwnAddressType::PUBLIC_DEVICE_ADDRESS,
135 PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS,
136 Address::kEmpty, AdvertisingFilterPolicy::ALL_DEVICES, 0x70,
137 PrimaryPhyType::LE_1M, 0, SecondaryPhyType::LE_2M, 0x0, false),
138 ErrorCode::SUCCESS);
139
140 std::vector<uint8_t> scan_response_data = {1, 2, 3};
141 ASSERT_EQ(
142 controller_.LeSetExtendedScanResponseData(
143 1, Operation::COMPLETE_ADVERTISEMENT,
144 FragmentPreference::CONTROLLER_MAY_FRAGMENT, scan_response_data),
145 ErrorCode::UNKNOWN_ADVERTISING_IDENTIFIER);
146 }
147
TEST_F(LeSetExtendedScanResponseDataTest,UnexpectedScanResponseData)148 TEST_F(LeSetExtendedScanResponseDataTest, UnexpectedScanResponseData) {
149 ASSERT_EQ(controller_.LeSetExtendedAdvertisingParameters(
150 0, MakeAdvertisingEventProperties(CONNECTABLE), 0x0800, 0x0800,
151 0x7, OwnAddressType::PUBLIC_DEVICE_ADDRESS,
152 PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS,
153 Address::kEmpty, AdvertisingFilterPolicy::ALL_DEVICES, 0x70,
154 PrimaryPhyType::LE_1M, 0, SecondaryPhyType::LE_2M, 0x0, false),
155 ErrorCode::SUCCESS);
156
157 std::vector<uint8_t> scan_response_data = {1, 2, 3};
158 ASSERT_EQ(
159 controller_.LeSetExtendedScanResponseData(
160 0, Operation::COMPLETE_ADVERTISEMENT,
161 FragmentPreference::CONTROLLER_MAY_FRAGMENT, scan_response_data),
162 ErrorCode::INVALID_HCI_COMMAND_PARAMETERS);
163 }
164
TEST_F(LeSetExtendedScanResponseDataTest,IncompleteLegacyScanResponseData)165 TEST_F(LeSetExtendedScanResponseDataTest, IncompleteLegacyScanResponseData) {
166 ASSERT_EQ(controller_.LeSetExtendedAdvertisingParameters(
167 0, MakeAdvertisingEventProperties(LEGACY | SCANNABLE), 0x0800,
168 0x0800, 0x7, OwnAddressType::PUBLIC_DEVICE_ADDRESS,
169 PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS,
170 Address::kEmpty, AdvertisingFilterPolicy::ALL_DEVICES, 0x70,
171 PrimaryPhyType::LE_1M, 0, SecondaryPhyType::LE_2M, 0x0, false),
172 ErrorCode::SUCCESS);
173
174 std::vector<uint8_t> first_scan_response_data_fragment = {1, 2, 3};
175 ASSERT_EQ(controller_.LeSetExtendedScanResponseData(
176 0, Operation::FIRST_FRAGMENT,
177 FragmentPreference::CONTROLLER_MAY_FRAGMENT,
178 first_scan_response_data_fragment),
179 ErrorCode::INVALID_HCI_COMMAND_PARAMETERS);
180 }
181
TEST_F(LeSetExtendedScanResponseDataTest,InvalidLegacyScanResponseData)182 TEST_F(LeSetExtendedScanResponseDataTest, InvalidLegacyScanResponseData) {
183 ASSERT_EQ(controller_.LeSetExtendedAdvertisingParameters(
184 0, MakeAdvertisingEventProperties(LEGACY | SCANNABLE), 0x0800,
185 0x0800, 0x7, OwnAddressType::PUBLIC_DEVICE_ADDRESS,
186 PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS,
187 Address::kEmpty, AdvertisingFilterPolicy::ALL_DEVICES, 0x70,
188 PrimaryPhyType::LE_1M, 0, SecondaryPhyType::LE_2M, 0x0, false),
189 ErrorCode::SUCCESS);
190
191 std::vector<uint8_t> scan_response_data = {1, 2, 3};
192 scan_response_data.resize(32);
193 ASSERT_EQ(
194 controller_.LeSetExtendedScanResponseData(
195 0, Operation::COMPLETE_ADVERTISEMENT,
196 FragmentPreference::CONTROLLER_MAY_FRAGMENT, scan_response_data),
197 ErrorCode::INVALID_HCI_COMMAND_PARAMETERS);
198 }
199
TEST_F(LeSetExtendedScanResponseDataTest,EmptyScanResponseDataFragment)200 TEST_F(LeSetExtendedScanResponseDataTest, EmptyScanResponseDataFragment) {
201 ASSERT_EQ(controller_.LeSetExtendedAdvertisingParameters(
202 0, MakeAdvertisingEventProperties(SCANNABLE), 0x0800, 0x0800,
203 0x7, OwnAddressType::PUBLIC_DEVICE_ADDRESS,
204 PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS,
205 Address::kEmpty, AdvertisingFilterPolicy::ALL_DEVICES, 0x70,
206 PrimaryPhyType::LE_1M, 0, SecondaryPhyType::LE_2M, 0x0, false),
207 ErrorCode::SUCCESS);
208
209 std::vector<uint8_t> first_scan_response_data_fragment = {1, 2, 3};
210 std::vector<uint8_t> intermediate_scan_response_data_fragment = {4, 5, 6};
211 std::vector<uint8_t> last_scan_response_data_fragment = {7, 8, 9};
212
213 ASSERT_EQ(controller_.LeSetExtendedScanResponseData(
214 0, Operation::FIRST_FRAGMENT,
215 FragmentPreference::CONTROLLER_MAY_FRAGMENT, {}),
216 ErrorCode::INVALID_HCI_COMMAND_PARAMETERS);
217
218 ASSERT_EQ(controller_.LeSetExtendedScanResponseData(
219 0, Operation::FIRST_FRAGMENT,
220 FragmentPreference::CONTROLLER_MAY_FRAGMENT,
221 first_scan_response_data_fragment),
222 ErrorCode::SUCCESS);
223
224 ASSERT_EQ(controller_.LeSetExtendedScanResponseData(
225 0, Operation::INTERMEDIATE_FRAGMENT,
226 FragmentPreference::CONTROLLER_MAY_FRAGMENT, {}),
227 ErrorCode::INVALID_HCI_COMMAND_PARAMETERS);
228
229 ASSERT_EQ(controller_.LeSetExtendedScanResponseData(
230 0, Operation::INTERMEDIATE_FRAGMENT,
231 FragmentPreference::CONTROLLER_MAY_FRAGMENT,
232 intermediate_scan_response_data_fragment),
233 ErrorCode::SUCCESS);
234
235 ASSERT_EQ(controller_.LeSetExtendedScanResponseData(
236 0, Operation::LAST_FRAGMENT,
237 FragmentPreference::CONTROLLER_MAY_FRAGMENT, {}),
238 ErrorCode::INVALID_HCI_COMMAND_PARAMETERS);
239
240 ASSERT_EQ(controller_.LeSetExtendedScanResponseData(
241 0, Operation::LAST_FRAGMENT,
242 FragmentPreference::CONTROLLER_MAY_FRAGMENT,
243 last_scan_response_data_fragment),
244 ErrorCode::SUCCESS);
245 }
246
TEST_F(LeSetExtendedScanResponseDataTest,AdvertisingEnabled)247 TEST_F(LeSetExtendedScanResponseDataTest, AdvertisingEnabled) {
248 ASSERT_EQ(controller_.LeSetExtendedAdvertisingParameters(
249 0, MakeAdvertisingEventProperties(SCANNABLE), 0x0800, 0x0800,
250 0x7, OwnAddressType::PUBLIC_DEVICE_ADDRESS,
251 PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS,
252 Address::kEmpty, AdvertisingFilterPolicy::ALL_DEVICES, 0x70,
253 PrimaryPhyType::LE_1M, 0, SecondaryPhyType::LE_2M, 0x0, false),
254 ErrorCode::SUCCESS);
255
256 std::vector<uint8_t> scan_response_data = {1, 2, 3};
257 ASSERT_EQ(
258 controller_.LeSetExtendedScanResponseData(
259 0, Operation::COMPLETE_ADVERTISEMENT,
260 FragmentPreference::CONTROLLER_MAY_FRAGMENT, scan_response_data),
261 ErrorCode::SUCCESS);
262
263 ASSERT_EQ(controller_.LeSetExtendedAdvertisingEnable(
264 true, {MakeEnabledSet(0, 0, 0)}),
265 ErrorCode::SUCCESS);
266
267 ASSERT_EQ(
268 controller_.LeSetExtendedScanResponseData(
269 0, Operation::FIRST_FRAGMENT,
270 FragmentPreference::CONTROLLER_MAY_FRAGMENT, scan_response_data),
271 ErrorCode::COMMAND_DISALLOWED);
272 }
273
TEST_F(LeSetExtendedScanResponseDataTest,EmptyExtendedScanResponseData)274 TEST_F(LeSetExtendedScanResponseDataTest, EmptyExtendedScanResponseData) {
275 ASSERT_EQ(controller_.LeSetExtendedAdvertisingParameters(
276 0, MakeAdvertisingEventProperties(SCANNABLE), 0x0800, 0x0800,
277 0x7, OwnAddressType::PUBLIC_DEVICE_ADDRESS,
278 PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS,
279 Address::kEmpty, AdvertisingFilterPolicy::ALL_DEVICES, 0x70,
280 PrimaryPhyType::LE_1M, 0, SecondaryPhyType::LE_2M, 0x0, false),
281 ErrorCode::SUCCESS);
282
283 std::vector<uint8_t> scan_response_data = {1, 2, 3};
284 ASSERT_EQ(
285 controller_.LeSetExtendedScanResponseData(
286 0, Operation::COMPLETE_ADVERTISEMENT,
287 FragmentPreference::CONTROLLER_MAY_FRAGMENT, scan_response_data),
288 ErrorCode::SUCCESS);
289
290 ASSERT_EQ(controller_.LeSetExtendedAdvertisingEnable(
291 true, {MakeEnabledSet(0, 0, 0)}),
292 ErrorCode::SUCCESS);
293
294 ASSERT_EQ(controller_.LeSetExtendedScanResponseData(
295 0, Operation::COMPLETE_ADVERTISEMENT,
296 FragmentPreference::CONTROLLER_MAY_FRAGMENT, {}),
297 ErrorCode::COMMAND_DISALLOWED);
298 }
299
TEST_F(LeSetExtendedScanResponseDataTest,ScanResponseDataLargerThanMemoryCapacity)300 TEST_F(LeSetExtendedScanResponseDataTest,
301 ScanResponseDataLargerThanMemoryCapacity) {
302 ASSERT_EQ(controller_.LeSetExtendedAdvertisingParameters(
303 0, MakeAdvertisingEventProperties(SCANNABLE), 0x0800, 0x0800,
304 0x7, OwnAddressType::PUBLIC_DEVICE_ADDRESS,
305 PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS,
306 Address::kEmpty, AdvertisingFilterPolicy::ALL_DEVICES, 0x70,
307 PrimaryPhyType::LE_1M, 0, SecondaryPhyType::LE_2M, 0x0, false),
308 ErrorCode::SUCCESS);
309
310 std::vector<uint8_t> scan_response_data_fragment = {1, 2, 3};
311 scan_response_data_fragment.resize(
312 properties_.le_max_advertising_data_length);
313
314 ASSERT_EQ(controller_.LeSetExtendedScanResponseData(
315 0, Operation::FIRST_FRAGMENT,
316 FragmentPreference::CONTROLLER_MAY_FRAGMENT,
317 scan_response_data_fragment),
318 ErrorCode::SUCCESS);
319 ASSERT_EQ(controller_.LeSetExtendedScanResponseData(
320 0, Operation::LAST_FRAGMENT,
321 FragmentPreference::CONTROLLER_MAY_FRAGMENT,
322 scan_response_data_fragment),
323 ErrorCode::MEMORY_CAPACITY_EXCEEDED);
324 }
325
TEST_F(LeSetExtendedScanResponseDataTest,ScanResponseDataLargerThanPduCapacity)326 TEST_F(LeSetExtendedScanResponseDataTest,
327 ScanResponseDataLargerThanPduCapacity) {
328 // Overwrite le_max_advertising_data_length to make sure that the correct
329 // check is triggered.
330 properties_.le_max_advertising_data_length = 5000;
331
332 ASSERT_EQ(controller_.LeSetExtendedAdvertisingParameters(
333 0, MakeAdvertisingEventProperties(SCANNABLE), 0x0800, 0x0800,
334 0x7, OwnAddressType::PUBLIC_DEVICE_ADDRESS,
335 PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS,
336 Address::kEmpty, AdvertisingFilterPolicy::ALL_DEVICES, 0x70,
337 PrimaryPhyType::LE_1M, 0, SecondaryPhyType::LE_2M, 0x0, false),
338 ErrorCode::SUCCESS);
339
340 std::vector<uint8_t> scan_response_data = {1, 2, 3};
341 ASSERT_EQ(
342 controller_.LeSetExtendedScanResponseData(
343 0, Operation::COMPLETE_ADVERTISEMENT,
344 FragmentPreference::CONTROLLER_MAY_FRAGMENT, scan_response_data),
345 ErrorCode::SUCCESS);
346
347 ASSERT_EQ(controller_.LeSetExtendedAdvertisingEnable(
348 true, {MakeEnabledSet(0, 0, 0)}),
349 ErrorCode::SUCCESS);
350
351 // No AUX chain possible for connectable advertising PDUs,
352 // the advertising data is limited to one PDU's payload.
353 scan_response_data.resize(1651);
354
355 ASSERT_EQ(
356 controller_.LeSetExtendedScanResponseData(
357 0, Operation::COMPLETE_ADVERTISEMENT,
358 FragmentPreference::CONTROLLER_MAY_FRAGMENT, scan_response_data),
359 ErrorCode::PACKET_TOO_LONG);
360 }
361
362 } // namespace rootcanal
363