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, 0x7,
44                     OwnAddressType::PUBLIC_DEVICE_ADDRESS,
45                     PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS, Address::kEmpty,
46                     AdvertisingFilterPolicy::ALL_DEVICES, 0x70, PrimaryPhyType::LE_1M, 0,
47                     SecondaryPhyType::LE_2M, 0x0, false),
48             ErrorCode::SUCCESS);
49 
50   std::vector<uint8_t> scan_response_data = {1, 2, 3};
51   ASSERT_EQ(controller_.LeSetExtendedScanResponseData(0, Operation::COMPLETE_ADVERTISEMENT,
52                                                       FragmentPreference::CONTROLLER_MAY_FRAGMENT,
53                                                       scan_response_data),
54             ErrorCode::SUCCESS);
55 }
56 
TEST_F(LeSetExtendedScanResponseDataTest,Discard)57 TEST_F(LeSetExtendedScanResponseDataTest, Discard) {
58   ASSERT_EQ(controller_.LeSetExtendedAdvertisingParameters(
59                     0, MakeAdvertisingEventProperties(CONNECTABLE), 0x0800, 0x0800, 0x7,
60                     OwnAddressType::PUBLIC_DEVICE_ADDRESS,
61                     PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS, Address::kEmpty,
62                     AdvertisingFilterPolicy::ALL_DEVICES, 0x70, PrimaryPhyType::LE_1M, 0,
63                     SecondaryPhyType::LE_2M, 0x0, false),
64             ErrorCode::SUCCESS);
65 
66   ASSERT_EQ(controller_.LeSetExtendedScanResponseData(0, Operation::COMPLETE_ADVERTISEMENT,
67                                                       FragmentPreference::CONTROLLER_MAY_FRAGMENT,
68                                                       {}),
69             ErrorCode::SUCCESS);
70 }
71 
TEST_F(LeSetExtendedScanResponseDataTest,Unchanged)72 TEST_F(LeSetExtendedScanResponseDataTest, Unchanged) {
73   ASSERT_EQ(controller_.LeSetExtendedAdvertisingParameters(
74                     0, MakeAdvertisingEventProperties(SCANNABLE), 0x0800, 0x0800, 0x7,
75                     OwnAddressType::PUBLIC_DEVICE_ADDRESS,
76                     PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS, Address::kEmpty,
77                     AdvertisingFilterPolicy::ALL_DEVICES, 0x70, PrimaryPhyType::LE_1M, 0,
78                     SecondaryPhyType::LE_2M, 0x0, false),
79             ErrorCode::SUCCESS);
80 
81   std::vector<uint8_t> scan_response_data = {1, 2, 3};
82   ASSERT_EQ(controller_.LeSetExtendedScanResponseData(0, Operation::COMPLETE_ADVERTISEMENT,
83                                                       FragmentPreference::CONTROLLER_MAY_FRAGMENT,
84                                                       scan_response_data),
85             ErrorCode::SUCCESS);
86 
87   ASSERT_EQ(controller_.LeSetExtendedAdvertisingEnable(true, {MakeEnabledSet(0, 0, 0)}),
88             ErrorCode::SUCCESS);
89 
90   ASSERT_EQ(controller_.LeSetExtendedScanResponseData(
91                     0, Operation::UNCHANGED_DATA, FragmentPreference::CONTROLLER_MAY_FRAGMENT, {}),
92             ErrorCode::INVALID_HCI_COMMAND_PARAMETERS);
93 }
94 
TEST_F(LeSetExtendedScanResponseDataTest,Fragmented)95 TEST_F(LeSetExtendedScanResponseDataTest, Fragmented) {
96   ASSERT_EQ(controller_.LeSetExtendedAdvertisingParameters(
97                     0, MakeAdvertisingEventProperties(SCANNABLE), 0x0800, 0x0800, 0x7,
98                     OwnAddressType::PUBLIC_DEVICE_ADDRESS,
99                     PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS, Address::kEmpty,
100                     AdvertisingFilterPolicy::ALL_DEVICES, 0x70, PrimaryPhyType::LE_1M, 0,
101                     SecondaryPhyType::LE_2M, 0x0, false),
102             ErrorCode::SUCCESS);
103 
104   std::vector<uint8_t> first_scan_response_data_fragment = {1, 2, 3};
105   std::vector<uint8_t> intermediate_scan_response_data_fragment = {4, 5, 6};
106   std::vector<uint8_t> last_scan_response_data_fragment = {7, 8, 9};
107 
108   ASSERT_EQ(controller_.LeSetExtendedScanResponseData(0, Operation::FIRST_FRAGMENT,
109                                                       FragmentPreference::CONTROLLER_MAY_FRAGMENT,
110                                                       first_scan_response_data_fragment),
111             ErrorCode::SUCCESS);
112 
113   ASSERT_EQ(controller_.LeSetExtendedScanResponseData(0, Operation::INTERMEDIATE_FRAGMENT,
114                                                       FragmentPreference::CONTROLLER_MAY_FRAGMENT,
115                                                       intermediate_scan_response_data_fragment),
116             ErrorCode::SUCCESS);
117 
118   ASSERT_EQ(controller_.LeSetExtendedScanResponseData(0, Operation::LAST_FRAGMENT,
119                                                       FragmentPreference::CONTROLLER_MAY_FRAGMENT,
120                                                       last_scan_response_data_fragment),
121             ErrorCode::SUCCESS);
122 }
123 
TEST_F(LeSetExtendedScanResponseDataTest,UnknownAdvertisingHandle)124 TEST_F(LeSetExtendedScanResponseDataTest, UnknownAdvertisingHandle) {
125   ASSERT_EQ(controller_.LeSetExtendedAdvertisingParameters(
126                     0, MakeAdvertisingEventProperties(SCANNABLE), 0x0800, 0x0800, 0x7,
127                     OwnAddressType::PUBLIC_DEVICE_ADDRESS,
128                     PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS, Address::kEmpty,
129                     AdvertisingFilterPolicy::ALL_DEVICES, 0x70, PrimaryPhyType::LE_1M, 0,
130                     SecondaryPhyType::LE_2M, 0x0, false),
131             ErrorCode::SUCCESS);
132 
133   std::vector<uint8_t> scan_response_data = {1, 2, 3};
134   ASSERT_EQ(controller_.LeSetExtendedScanResponseData(1, Operation::COMPLETE_ADVERTISEMENT,
135                                                       FragmentPreference::CONTROLLER_MAY_FRAGMENT,
136                                                       scan_response_data),
137             ErrorCode::UNKNOWN_ADVERTISING_IDENTIFIER);
138 }
139 
TEST_F(LeSetExtendedScanResponseDataTest,UnexpectedScanResponseData)140 TEST_F(LeSetExtendedScanResponseDataTest, UnexpectedScanResponseData) {
141   ASSERT_EQ(controller_.LeSetExtendedAdvertisingParameters(
142                     0, MakeAdvertisingEventProperties(CONNECTABLE), 0x0800, 0x0800, 0x7,
143                     OwnAddressType::PUBLIC_DEVICE_ADDRESS,
144                     PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS, Address::kEmpty,
145                     AdvertisingFilterPolicy::ALL_DEVICES, 0x70, PrimaryPhyType::LE_1M, 0,
146                     SecondaryPhyType::LE_2M, 0x0, false),
147             ErrorCode::SUCCESS);
148 
149   std::vector<uint8_t> scan_response_data = {1, 2, 3};
150   ASSERT_EQ(controller_.LeSetExtendedScanResponseData(0, Operation::COMPLETE_ADVERTISEMENT,
151                                                       FragmentPreference::CONTROLLER_MAY_FRAGMENT,
152                                                       scan_response_data),
153             ErrorCode::INVALID_HCI_COMMAND_PARAMETERS);
154 }
155 
TEST_F(LeSetExtendedScanResponseDataTest,IncompleteLegacyScanResponseData)156 TEST_F(LeSetExtendedScanResponseDataTest, IncompleteLegacyScanResponseData) {
157   ASSERT_EQ(controller_.LeSetExtendedAdvertisingParameters(
158                     0, MakeAdvertisingEventProperties(LEGACY | SCANNABLE), 0x0800, 0x0800, 0x7,
159                     OwnAddressType::PUBLIC_DEVICE_ADDRESS,
160                     PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS, Address::kEmpty,
161                     AdvertisingFilterPolicy::ALL_DEVICES, 0x70, PrimaryPhyType::LE_1M, 0,
162                     SecondaryPhyType::LE_2M, 0x0, false),
163             ErrorCode::SUCCESS);
164 
165   std::vector<uint8_t> first_scan_response_data_fragment = {1, 2, 3};
166   ASSERT_EQ(controller_.LeSetExtendedScanResponseData(0, Operation::FIRST_FRAGMENT,
167                                                       FragmentPreference::CONTROLLER_MAY_FRAGMENT,
168                                                       first_scan_response_data_fragment),
169             ErrorCode::INVALID_HCI_COMMAND_PARAMETERS);
170 }
171 
TEST_F(LeSetExtendedScanResponseDataTest,InvalidLegacyScanResponseData)172 TEST_F(LeSetExtendedScanResponseDataTest, InvalidLegacyScanResponseData) {
173   ASSERT_EQ(controller_.LeSetExtendedAdvertisingParameters(
174                     0, MakeAdvertisingEventProperties(LEGACY | SCANNABLE), 0x0800, 0x0800, 0x7,
175                     OwnAddressType::PUBLIC_DEVICE_ADDRESS,
176                     PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS, Address::kEmpty,
177                     AdvertisingFilterPolicy::ALL_DEVICES, 0x70, PrimaryPhyType::LE_1M, 0,
178                     SecondaryPhyType::LE_2M, 0x0, false),
179             ErrorCode::SUCCESS);
180 
181   std::vector<uint8_t> scan_response_data = {1, 2, 3};
182   scan_response_data.resize(32);
183   ASSERT_EQ(controller_.LeSetExtendedScanResponseData(0, Operation::COMPLETE_ADVERTISEMENT,
184                                                       FragmentPreference::CONTROLLER_MAY_FRAGMENT,
185                                                       scan_response_data),
186             ErrorCode::INVALID_HCI_COMMAND_PARAMETERS);
187 }
188 
TEST_F(LeSetExtendedScanResponseDataTest,EmptyScanResponseDataFragment)189 TEST_F(LeSetExtendedScanResponseDataTest, EmptyScanResponseDataFragment) {
190   ASSERT_EQ(controller_.LeSetExtendedAdvertisingParameters(
191                     0, MakeAdvertisingEventProperties(SCANNABLE), 0x0800, 0x0800, 0x7,
192                     OwnAddressType::PUBLIC_DEVICE_ADDRESS,
193                     PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS, Address::kEmpty,
194                     AdvertisingFilterPolicy::ALL_DEVICES, 0x70, PrimaryPhyType::LE_1M, 0,
195                     SecondaryPhyType::LE_2M, 0x0, false),
196             ErrorCode::SUCCESS);
197 
198   std::vector<uint8_t> first_scan_response_data_fragment = {1, 2, 3};
199   std::vector<uint8_t> intermediate_scan_response_data_fragment = {4, 5, 6};
200   std::vector<uint8_t> last_scan_response_data_fragment = {7, 8, 9};
201 
202   ASSERT_EQ(controller_.LeSetExtendedScanResponseData(
203                     0, Operation::FIRST_FRAGMENT, FragmentPreference::CONTROLLER_MAY_FRAGMENT, {}),
204             ErrorCode::INVALID_HCI_COMMAND_PARAMETERS);
205 
206   ASSERT_EQ(controller_.LeSetExtendedScanResponseData(0, Operation::FIRST_FRAGMENT,
207                                                       FragmentPreference::CONTROLLER_MAY_FRAGMENT,
208                                                       first_scan_response_data_fragment),
209             ErrorCode::SUCCESS);
210 
211   ASSERT_EQ(controller_.LeSetExtendedScanResponseData(0, Operation::INTERMEDIATE_FRAGMENT,
212                                                       FragmentPreference::CONTROLLER_MAY_FRAGMENT,
213                                                       {}),
214             ErrorCode::INVALID_HCI_COMMAND_PARAMETERS);
215 
216   ASSERT_EQ(controller_.LeSetExtendedScanResponseData(0, Operation::INTERMEDIATE_FRAGMENT,
217                                                       FragmentPreference::CONTROLLER_MAY_FRAGMENT,
218                                                       intermediate_scan_response_data_fragment),
219             ErrorCode::SUCCESS);
220 
221   ASSERT_EQ(controller_.LeSetExtendedScanResponseData(
222                     0, Operation::LAST_FRAGMENT, FragmentPreference::CONTROLLER_MAY_FRAGMENT, {}),
223             ErrorCode::INVALID_HCI_COMMAND_PARAMETERS);
224 
225   ASSERT_EQ(controller_.LeSetExtendedScanResponseData(0, Operation::LAST_FRAGMENT,
226                                                       FragmentPreference::CONTROLLER_MAY_FRAGMENT,
227                                                       last_scan_response_data_fragment),
228             ErrorCode::SUCCESS);
229 }
230 
TEST_F(LeSetExtendedScanResponseDataTest,AdvertisingEnabled)231 TEST_F(LeSetExtendedScanResponseDataTest, AdvertisingEnabled) {
232   ASSERT_EQ(controller_.LeSetExtendedAdvertisingParameters(
233                     0, MakeAdvertisingEventProperties(SCANNABLE), 0x0800, 0x0800, 0x7,
234                     OwnAddressType::PUBLIC_DEVICE_ADDRESS,
235                     PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS, Address::kEmpty,
236                     AdvertisingFilterPolicy::ALL_DEVICES, 0x70, PrimaryPhyType::LE_1M, 0,
237                     SecondaryPhyType::LE_2M, 0x0, false),
238             ErrorCode::SUCCESS);
239 
240   std::vector<uint8_t> scan_response_data = {1, 2, 3};
241   ASSERT_EQ(controller_.LeSetExtendedScanResponseData(0, Operation::COMPLETE_ADVERTISEMENT,
242                                                       FragmentPreference::CONTROLLER_MAY_FRAGMENT,
243                                                       scan_response_data),
244             ErrorCode::SUCCESS);
245 
246   ASSERT_EQ(controller_.LeSetExtendedAdvertisingEnable(true, {MakeEnabledSet(0, 0, 0)}),
247             ErrorCode::SUCCESS);
248 
249   ASSERT_EQ(controller_.LeSetExtendedScanResponseData(0, Operation::FIRST_FRAGMENT,
250                                                       FragmentPreference::CONTROLLER_MAY_FRAGMENT,
251                                                       scan_response_data),
252             ErrorCode::COMMAND_DISALLOWED);
253 }
254 
TEST_F(LeSetExtendedScanResponseDataTest,EmptyExtendedScanResponseData)255 TEST_F(LeSetExtendedScanResponseDataTest, EmptyExtendedScanResponseData) {
256   ASSERT_EQ(controller_.LeSetExtendedAdvertisingParameters(
257                     0, MakeAdvertisingEventProperties(SCANNABLE), 0x0800, 0x0800, 0x7,
258                     OwnAddressType::PUBLIC_DEVICE_ADDRESS,
259                     PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS, Address::kEmpty,
260                     AdvertisingFilterPolicy::ALL_DEVICES, 0x70, PrimaryPhyType::LE_1M, 0,
261                     SecondaryPhyType::LE_2M, 0x0, false),
262             ErrorCode::SUCCESS);
263 
264   std::vector<uint8_t> scan_response_data = {1, 2, 3};
265   ASSERT_EQ(controller_.LeSetExtendedScanResponseData(0, Operation::COMPLETE_ADVERTISEMENT,
266                                                       FragmentPreference::CONTROLLER_MAY_FRAGMENT,
267                                                       scan_response_data),
268             ErrorCode::SUCCESS);
269 
270   ASSERT_EQ(controller_.LeSetExtendedAdvertisingEnable(true, {MakeEnabledSet(0, 0, 0)}),
271             ErrorCode::SUCCESS);
272 
273   ASSERT_EQ(controller_.LeSetExtendedScanResponseData(0, Operation::COMPLETE_ADVERTISEMENT,
274                                                       FragmentPreference::CONTROLLER_MAY_FRAGMENT,
275                                                       {}),
276             ErrorCode::COMMAND_DISALLOWED);
277 }
278 
TEST_F(LeSetExtendedScanResponseDataTest,ScanResponseDataLargerThanMemoryCapacity)279 TEST_F(LeSetExtendedScanResponseDataTest, ScanResponseDataLargerThanMemoryCapacity) {
280   ASSERT_EQ(controller_.LeSetExtendedAdvertisingParameters(
281                     0, MakeAdvertisingEventProperties(SCANNABLE), 0x0800, 0x0800, 0x7,
282                     OwnAddressType::PUBLIC_DEVICE_ADDRESS,
283                     PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS, Address::kEmpty,
284                     AdvertisingFilterPolicy::ALL_DEVICES, 0x70, PrimaryPhyType::LE_1M, 0,
285                     SecondaryPhyType::LE_2M, 0x0, false),
286             ErrorCode::SUCCESS);
287 
288   std::vector<uint8_t> scan_response_data_fragment = {1, 2, 3};
289   scan_response_data_fragment.resize(properties_.le_max_advertising_data_length);
290 
291   ASSERT_EQ(controller_.LeSetExtendedScanResponseData(0, Operation::FIRST_FRAGMENT,
292                                                       FragmentPreference::CONTROLLER_MAY_FRAGMENT,
293                                                       scan_response_data_fragment),
294             ErrorCode::SUCCESS);
295   ASSERT_EQ(controller_.LeSetExtendedScanResponseData(0, Operation::LAST_FRAGMENT,
296                                                       FragmentPreference::CONTROLLER_MAY_FRAGMENT,
297                                                       scan_response_data_fragment),
298             ErrorCode::MEMORY_CAPACITY_EXCEEDED);
299 }
300 
TEST_F(LeSetExtendedScanResponseDataTest,ScanResponseDataLargerThanPduCapacity)301 TEST_F(LeSetExtendedScanResponseDataTest, ScanResponseDataLargerThanPduCapacity) {
302   // Overwrite le_max_advertising_data_length to make sure that the correct
303   // check is triggered.
304   properties_.le_max_advertising_data_length = 5000;
305 
306   ASSERT_EQ(controller_.LeSetExtendedAdvertisingParameters(
307                     0, MakeAdvertisingEventProperties(SCANNABLE), 0x0800, 0x0800, 0x7,
308                     OwnAddressType::PUBLIC_DEVICE_ADDRESS,
309                     PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS, Address::kEmpty,
310                     AdvertisingFilterPolicy::ALL_DEVICES, 0x70, PrimaryPhyType::LE_1M, 0,
311                     SecondaryPhyType::LE_2M, 0x0, false),
312             ErrorCode::SUCCESS);
313 
314   std::vector<uint8_t> scan_response_data = {1, 2, 3};
315   ASSERT_EQ(controller_.LeSetExtendedScanResponseData(0, Operation::COMPLETE_ADVERTISEMENT,
316                                                       FragmentPreference::CONTROLLER_MAY_FRAGMENT,
317                                                       scan_response_data),
318             ErrorCode::SUCCESS);
319 
320   ASSERT_EQ(controller_.LeSetExtendedAdvertisingEnable(true, {MakeEnabledSet(0, 0, 0)}),
321             ErrorCode::SUCCESS);
322 
323   // No AUX chain possible for connectable advertising PDUs,
324   // the advertising data is limited to one PDU's payload.
325   scan_response_data.resize(1651);
326 
327   ASSERT_EQ(controller_.LeSetExtendedScanResponseData(0, Operation::COMPLETE_ADVERTISEMENT,
328                                                       FragmentPreference::CONTROLLER_MAY_FRAGMENT,
329                                                       scan_response_data),
330             ErrorCode::PACKET_TOO_LONG);
331 }
332 
333 }  // namespace rootcanal
334