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 LeSetExtendedAdvertisingEnableTest : public ::testing::Test {
27 public:
LeSetExtendedAdvertisingEnableTest()28   LeSetExtendedAdvertisingEnableTest() {
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 = 2000;
32   }
33   ~LeSetExtendedAdvertisingEnableTest() override = default;
34 
35 protected:
36   Address address_{0};
37   ControllerProperties properties_{};
38   LinkLayerController controller_{address_, properties_};
39 };
40 
TEST_F(LeSetExtendedAdvertisingEnableTest,DisableAll)41 TEST_F(LeSetExtendedAdvertisingEnableTest, DisableAll) {
42   ASSERT_EQ(controller_.LeSetExtendedAdvertisingEnable(false, {}), ErrorCode::SUCCESS);
43 }
44 
TEST_F(LeSetExtendedAdvertisingEnableTest,DisableSelected)45 TEST_F(LeSetExtendedAdvertisingEnableTest, DisableSelected) {
46   ASSERT_EQ(controller_.LeSetExtendedAdvertisingParameters(
47                     0, MakeAdvertisingEventProperties(CONNECTABLE), 0x0800, 0x0800, 0x7,
48                     OwnAddressType::PUBLIC_DEVICE_ADDRESS,
49                     PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS, Address::kEmpty,
50                     AdvertisingFilterPolicy::ALL_DEVICES, 0x70, PrimaryPhyType::LE_1M, 0,
51                     SecondaryPhyType::LE_2M, 0x0, false),
52             ErrorCode::SUCCESS);
53 
54   ASSERT_EQ(controller_.LeSetExtendedAdvertisingEnable(false, {MakeEnabledSet(0, 0, 0)}),
55             ErrorCode::SUCCESS);
56 }
57 
TEST_F(LeSetExtendedAdvertisingEnableTest,EnableUsingPublicAddress)58 TEST_F(LeSetExtendedAdvertisingEnableTest, EnableUsingPublicAddress) {
59   ASSERT_EQ(controller_.LeSetExtendedAdvertisingParameters(
60                     0, MakeAdvertisingEventProperties(LEGACY | CONNECTABLE | SCANNABLE), 0x0800,
61                     0x0800, 0x7, OwnAddressType::PUBLIC_DEVICE_ADDRESS,
62                     PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS, Address::kEmpty,
63                     AdvertisingFilterPolicy::ALL_DEVICES, 0x70, PrimaryPhyType::LE_1M, 0,
64                     SecondaryPhyType::LE_2M, 0x0, false),
65             ErrorCode::SUCCESS);
66 
67   ASSERT_EQ(controller_.LeSetExtendedAdvertisingEnable(true, {MakeEnabledSet(0, 0, 0)}),
68             ErrorCode::SUCCESS);
69 }
70 
TEST_F(LeSetExtendedAdvertisingEnableTest,EnableUsingTimeout)71 TEST_F(LeSetExtendedAdvertisingEnableTest, EnableUsingTimeout) {
72   ASSERT_EQ(controller_.LeSetExtendedAdvertisingParameters(
73                     0, MakeAdvertisingEventProperties(LEGACY | CONNECTABLE | SCANNABLE), 0x0800,
74                     0x0800, 0x7, OwnAddressType::PUBLIC_DEVICE_ADDRESS,
75                     PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS, Address::kEmpty,
76                     AdvertisingFilterPolicy::ALL_DEVICES, 0x70, PrimaryPhyType::LE_1M, 0,
77                     SecondaryPhyType::LE_2M, 0x0, false),
78             ErrorCode::SUCCESS);
79 
80   ASSERT_EQ(controller_.LeSetExtendedAdvertisingEnable(true, {MakeEnabledSet(0, 0x40, 0)}),
81             ErrorCode::SUCCESS);
82 }
83 
TEST_F(LeSetExtendedAdvertisingEnableTest,EnableUsingRandomAddress)84 TEST_F(LeSetExtendedAdvertisingEnableTest, EnableUsingRandomAddress) {
85   ASSERT_EQ(controller_.LeSetExtendedAdvertisingParameters(
86                     0, MakeAdvertisingEventProperties(LEGACY | CONNECTABLE | SCANNABLE), 0x0800,
87                     0x0800, 0x7, OwnAddressType::RANDOM_DEVICE_ADDRESS,
88                     PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS, Address::kEmpty,
89                     AdvertisingFilterPolicy::ALL_DEVICES, 0x70, PrimaryPhyType::LE_1M, 0,
90                     SecondaryPhyType::LE_2M, 0x0, false),
91             ErrorCode::SUCCESS);
92 
93   ASSERT_EQ(controller_.LeSetAdvertisingSetRandomAddress(0, Address{1}), ErrorCode::SUCCESS);
94 
95   ASSERT_EQ(controller_.LeSetExtendedAdvertisingEnable(true, {MakeEnabledSet(0, 0x40, 0)}),
96             ErrorCode::SUCCESS);
97 }
98 
TEST_F(LeSetExtendedAdvertisingEnableTest,EnableUsingResolvableAddress)99 TEST_F(LeSetExtendedAdvertisingEnableTest, EnableUsingResolvableAddress) {
100   ASSERT_EQ(controller_.LeSetExtendedAdvertisingParameters(
101                     0, MakeAdvertisingEventProperties(LEGACY | CONNECTABLE | SCANNABLE), 0x0800,
102                     0x0800, 0x7, OwnAddressType::RESOLVABLE_OR_RANDOM_ADDRESS,
103                     PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS, Address{1},
104                     AdvertisingFilterPolicy::ALL_DEVICES, 0x70, PrimaryPhyType::LE_1M, 0,
105                     SecondaryPhyType::LE_2M, 0x0, false),
106             ErrorCode::SUCCESS);
107   ASSERT_EQ(controller_.LeAddDeviceToResolvingList(
108                     PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS, Address{1},
109                     std::array<uint8_t, 16>{1}, std::array<uint8_t, 16>{1}),
110             ErrorCode::SUCCESS);
111   ASSERT_EQ(controller_.LeSetAddressResolutionEnable(true), ErrorCode::SUCCESS);
112   // Note: the command will fail if the peer address is not in the resolvable
113   // address list and the random address is not set.
114   // Success here signifies that the RPA was successfully generated.
115   ASSERT_EQ(controller_.LeSetExtendedAdvertisingEnable(true, {MakeEnabledSet(0, 0x40, 0)}),
116             ErrorCode::SUCCESS);
117 }
118 
TEST_F(LeSetExtendedAdvertisingEnableTest,DuplicateAdvertisingHandle)119 TEST_F(LeSetExtendedAdvertisingEnableTest, DuplicateAdvertisingHandle) {
120   ASSERT_EQ(controller_.LeSetExtendedAdvertisingParameters(
121                     0, MakeAdvertisingEventProperties(LEGACY | CONNECTABLE | SCANNABLE), 0x0800,
122                     0x0800, 0x7, OwnAddressType::PUBLIC_DEVICE_ADDRESS,
123                     PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS, Address::kEmpty,
124                     AdvertisingFilterPolicy::ALL_DEVICES, 0x70, PrimaryPhyType::LE_1M, 0,
125                     SecondaryPhyType::LE_2M, 0x0, false),
126             ErrorCode::SUCCESS);
127 
128   ASSERT_EQ(controller_.LeSetExtendedAdvertisingEnable(
129                     true, {MakeEnabledSet(0, 0, 0), MakeEnabledSet(0, 0, 0)}),
130             ErrorCode::INVALID_HCI_COMMAND_PARAMETERS);
131 }
132 
TEST_F(LeSetExtendedAdvertisingEnableTest,UnknownAdvertisingHandle)133 TEST_F(LeSetExtendedAdvertisingEnableTest, UnknownAdvertisingHandle) {
134   ASSERT_EQ(controller_.LeSetExtendedAdvertisingParameters(
135                     0, MakeAdvertisingEventProperties(LEGACY | CONNECTABLE | SCANNABLE), 0x0800,
136                     0x0800, 0x7, OwnAddressType::PUBLIC_DEVICE_ADDRESS,
137                     PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS, Address::kEmpty,
138                     AdvertisingFilterPolicy::ALL_DEVICES, 0x70, PrimaryPhyType::LE_1M, 0,
139                     SecondaryPhyType::LE_2M, 0x0, false),
140             ErrorCode::SUCCESS);
141 
142   ASSERT_EQ(controller_.LeSetExtendedAdvertisingEnable(
143                     true, {MakeEnabledSet(0, 0, 0), MakeEnabledSet(1, 0, 0)}),
144             ErrorCode::UNKNOWN_ADVERTISING_IDENTIFIER);
145 }
146 
TEST_F(LeSetExtendedAdvertisingEnableTest,MissingAdvertisingHandle)147 TEST_F(LeSetExtendedAdvertisingEnableTest, MissingAdvertisingHandle) {
148   ASSERT_EQ(controller_.LeSetExtendedAdvertisingEnable(true, {}),
149             ErrorCode::INVALID_HCI_COMMAND_PARAMETERS);
150 }
151 
TEST_F(LeSetExtendedAdvertisingEnableTest,InvalidDuration)152 TEST_F(LeSetExtendedAdvertisingEnableTest, InvalidDuration) {
153   ASSERT_EQ(
154           controller_.LeSetExtendedAdvertisingParameters(
155                   0,
156                   MakeAdvertisingEventProperties(LEGACY | DIRECTED | CONNECTABLE | HIGH_DUTY_CYCLE),
157                   0x0800, 0x0800, 0x7, OwnAddressType::PUBLIC_DEVICE_ADDRESS,
158                   PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS, Address::kEmpty,
159                   AdvertisingFilterPolicy::ALL_DEVICES, 0x70, PrimaryPhyType::LE_1M, 0,
160                   SecondaryPhyType::LE_2M, 0x0, false),
161           ErrorCode::SUCCESS);
162 
163   ASSERT_EQ(controller_.LeSetExtendedAdvertisingEnable(true, {MakeEnabledSet(0, 0, 0)}),
164             ErrorCode::INVALID_HCI_COMMAND_PARAMETERS);
165 
166   ASSERT_EQ(controller_.LeSetExtendedAdvertisingEnable(true, {MakeEnabledSet(0, 0x801, 0)}),
167             ErrorCode::INVALID_HCI_COMMAND_PARAMETERS);
168 }
169 
TEST_F(LeSetExtendedAdvertisingEnableTest,PartialAdvertisingData)170 TEST_F(LeSetExtendedAdvertisingEnableTest, PartialAdvertisingData) {
171   ASSERT_EQ(controller_.LeSetExtendedAdvertisingParameters(
172                     0, MakeAdvertisingEventProperties(CONNECTABLE), 0x0800, 0x0800, 0x7,
173                     OwnAddressType::PUBLIC_DEVICE_ADDRESS,
174                     PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS, Address::kEmpty,
175                     AdvertisingFilterPolicy::ALL_DEVICES, 0x70, PrimaryPhyType::LE_1M, 0,
176                     SecondaryPhyType::LE_2M, 0x0, false),
177             ErrorCode::SUCCESS);
178 
179   std::vector<uint8_t> first_advertising_data_fragment = {1, 2, 3};
180   ASSERT_EQ(controller_.LeSetExtendedAdvertisingData(0, Operation::FIRST_FRAGMENT,
181                                                      FragmentPreference::CONTROLLER_MAY_FRAGMENT,
182                                                      first_advertising_data_fragment),
183             ErrorCode::SUCCESS);
184 
185   ASSERT_EQ(controller_.LeSetExtendedAdvertisingEnable(true, {MakeEnabledSet(0, 0, 0)}),
186             ErrorCode::COMMAND_DISALLOWED);
187 }
188 
TEST_F(LeSetExtendedAdvertisingEnableTest,PartialScanResponseData)189 TEST_F(LeSetExtendedAdvertisingEnableTest, PartialScanResponseData) {
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   ASSERT_EQ(controller_.LeSetExtendedScanResponseData(0, Operation::FIRST_FRAGMENT,
200                                                       FragmentPreference::CONTROLLER_MAY_FRAGMENT,
201                                                       first_scan_response_data_fragment),
202             ErrorCode::SUCCESS);
203 
204   ASSERT_EQ(controller_.LeSetExtendedAdvertisingEnable(true, {MakeEnabledSet(0, 0, 0)}),
205             ErrorCode::COMMAND_DISALLOWED);
206 }
207 
TEST_F(LeSetExtendedAdvertisingEnableTest,EmptyScanResponseData)208 TEST_F(LeSetExtendedAdvertisingEnableTest, EmptyScanResponseData) {
209   ASSERT_EQ(controller_.LeSetExtendedAdvertisingParameters(
210                     0, MakeAdvertisingEventProperties(SCANNABLE), 0x0800, 0x0800, 0x7,
211                     OwnAddressType::PUBLIC_DEVICE_ADDRESS,
212                     PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS, Address::kEmpty,
213                     AdvertisingFilterPolicy::ALL_DEVICES, 0x70, PrimaryPhyType::LE_1M, 0,
214                     SecondaryPhyType::LE_2M, 0x0, false),
215             ErrorCode::SUCCESS);
216 
217   ASSERT_EQ(controller_.LeSetExtendedAdvertisingEnable(true, {MakeEnabledSet(0, 0, 0)}),
218             ErrorCode::COMMAND_DISALLOWED);
219 }
220 
TEST_F(LeSetExtendedAdvertisingEnableTest,AdvertisingDataLargerThanPduCapacity)221 TEST_F(LeSetExtendedAdvertisingEnableTest, AdvertisingDataLargerThanPduCapacity) {
222   ASSERT_EQ(controller_.LeSetExtendedAdvertisingParameters(
223                     0, MakeAdvertisingEventProperties(CONNECTABLE), 0x0800, 0x0800, 0x7,
224                     OwnAddressType::PUBLIC_DEVICE_ADDRESS,
225                     PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS, Address::kEmpty,
226                     AdvertisingFilterPolicy::ALL_DEVICES, 0x70, PrimaryPhyType::LE_1M, 0,
227                     SecondaryPhyType::LE_2M, 0x0, false),
228             ErrorCode::SUCCESS);
229 
230   std::vector<uint8_t> advertising_data = {1, 2, 3};
231   advertising_data.resize(254);
232   ASSERT_EQ(controller_.LeSetExtendedAdvertisingData(0, Operation::COMPLETE_ADVERTISEMENT,
233                                                      FragmentPreference::CONTROLLER_MAY_FRAGMENT,
234                                                      advertising_data),
235             ErrorCode::SUCCESS);
236 
237   ASSERT_EQ(controller_.LeSetExtendedAdvertisingEnable(true, {MakeEnabledSet(0, 0, 0)}),
238             ErrorCode::INVALID_HCI_COMMAND_PARAMETERS);
239 }
240 
TEST_F(LeSetExtendedAdvertisingEnableTest,AdvertisingDataLargerThanMaxPduCapacity)241 TEST_F(LeSetExtendedAdvertisingEnableTest, AdvertisingDataLargerThanMaxPduCapacity) {
242   ASSERT_EQ(controller_.LeSetExtendedAdvertisingParameters(
243                     0, MakeAdvertisingEventProperties(0), 0x0800, 0x0800, 0x7,
244                     OwnAddressType::PUBLIC_DEVICE_ADDRESS,
245                     PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS, Address::kEmpty,
246                     AdvertisingFilterPolicy::ALL_DEVICES, 0x70, PrimaryPhyType::LE_1M, 0,
247                     SecondaryPhyType::LE_2M, 0x0, false),
248             ErrorCode::SUCCESS);
249 
250   std::vector<uint8_t> advertising_data = {1, 2, 3};
251   advertising_data.resize(1651);
252   ASSERT_EQ(controller_.LeSetExtendedAdvertisingData(0, Operation::COMPLETE_ADVERTISEMENT,
253                                                      FragmentPreference::CONTROLLER_MAY_FRAGMENT,
254                                                      advertising_data),
255             ErrorCode::SUCCESS);
256 
257   ASSERT_EQ(controller_.LeSetExtendedAdvertisingEnable(true, {MakeEnabledSet(0, 0, 0)}),
258             ErrorCode::PACKET_TOO_LONG);
259 }
260 
TEST_F(LeSetExtendedAdvertisingEnableTest,NoRandomAddress)261 TEST_F(LeSetExtendedAdvertisingEnableTest, NoRandomAddress) {
262   ASSERT_EQ(controller_.LeSetExtendedAdvertisingParameters(
263                     0, MakeAdvertisingEventProperties(CONNECTABLE), 0x0800, 0x0800, 0x7,
264                     OwnAddressType::RANDOM_DEVICE_ADDRESS,
265                     PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS, Address::kEmpty,
266                     AdvertisingFilterPolicy::ALL_DEVICES, 0x70, PrimaryPhyType::LE_1M, 0,
267                     SecondaryPhyType::LE_2M, 0x0, false),
268             ErrorCode::SUCCESS);
269 
270   ASSERT_EQ(controller_.LeSetExtendedAdvertisingEnable(true, {MakeEnabledSet(0, 0, 0)}),
271             ErrorCode::INVALID_HCI_COMMAND_PARAMETERS);
272 }
273 
TEST_F(LeSetExtendedAdvertisingEnableTest,NoResolvableOrRandomAddress)274 TEST_F(LeSetExtendedAdvertisingEnableTest, NoResolvableOrRandomAddress) {
275   ASSERT_EQ(controller_.LeSetExtendedAdvertisingParameters(
276                     0, MakeAdvertisingEventProperties(CONNECTABLE), 0x0800, 0x0800, 0x7,
277                     OwnAddressType::RESOLVABLE_OR_RANDOM_ADDRESS,
278                     PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS, Address::kEmpty,
279                     AdvertisingFilterPolicy::ALL_DEVICES, 0x70, PrimaryPhyType::LE_1M, 0,
280                     SecondaryPhyType::LE_2M, 0x0, false),
281             ErrorCode::SUCCESS);
282 
283   ASSERT_EQ(controller_.LeSetExtendedAdvertisingEnable(true, {MakeEnabledSet(0, 0, 0)}),
284             ErrorCode::INVALID_HCI_COMMAND_PARAMETERS);
285 }
286 
287 }  // namespace rootcanal
288