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