1 /*
2 * Copyright (C) 2019 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 <VtsCoreUtil.h>
18
19 #include <android-base/logging.h>
20 #include <cutils/properties.h>
21
22 #include <gtest/gtest.h>
23 #include <hidl/GtestPrinter.h>
24 #include <hidl/ServiceManagement.h>
25
26 #include <android/hardware/wifi/1.0/IWifi.h>
27 #include <android/hardware/wifi/hostapd/1.2/IHostapd.h>
28
29 #include "hostapd_hidl_call_util.h"
30 #include "hostapd_hidl_test_utils.h"
31
32 using ::android::sp;
33 using ::android::hardware::hidl_string;
34 using ::android::hardware::Return;
35 using ::android::hardware::Void;
36 using ::android::hardware::wifi::hostapd::V1_2::DebugLevel;
37 using ::android::hardware::wifi::hostapd::V1_2::HostapdStatusCode;
38 using ::android::hardware::wifi::hostapd::V1_2::Ieee80211ReasonCode;
39 using ::android::hardware::wifi::hostapd::V1_2::IHostapd;
40 using ::android::hardware::wifi::V1_0::IWifi;
41
42 namespace {
43 constexpr unsigned char kNwSsid[] = {'t', 'e', 's', 't', '1',
44 '2', '3', '4', '5'};
45 constexpr char kNwPassphrase[] = "test12345";
46 constexpr char kInvalidMaxPskNwPassphrase[] =
47 "0123456789012345678901234567890123456789012345678901234567890123456789";
48 constexpr char kInvalidMinPskNwPassphrase[] = "test";
49 constexpr int kIfaceChannel = 6;
50 constexpr int kIfaceInvalidChannel = 567;
51 constexpr uint8_t kTestZeroMacAddr[] = {[0 ... 5] = 0x0};
52 constexpr Ieee80211ReasonCode kTestDisconnectReasonCode =
53 Ieee80211ReasonCode::WLAN_REASON_UNSPECIFIED;
54 } // namespace
55
56 class HostapdHidlTest
57 : public ::testing::TestWithParam<std::tuple<std::string, std::string>> {
58 public:
SetUp()59 virtual void SetUp() override {
60 wifi_instance_name_ = std::get<0>(GetParam());
61 hostapd_instance_name_ = std::get<1>(GetParam());
62 stopSupplicantIfNeeded(wifi_instance_name_);
63 startHostapdAndWaitForHidlService(wifi_instance_name_,
64 hostapd_instance_name_);
65 hostapd_ = IHostapd::getService(hostapd_instance_name_);
66 ASSERT_NE(hostapd_.get(), nullptr);
67 isAcsSupport_ = testing::checkSubstringInCommandOutput(
68 "/system/bin/cmd wifi get-softap-supported-features",
69 "wifi_softap_acs_supported");
70 isWpa3SaeSupport_ = testing::checkSubstringInCommandOutput(
71 "/system/bin/cmd wifi get-softap-supported-features",
72 "wifi_softap_wpa3_sae_supported");
73 }
74
TearDown()75 virtual void TearDown() override { stopHostapd(hostapd_instance_name_); }
76
77 protected:
78 bool isWpa3SaeSupport_ = false;
79 bool isAcsSupport_ = false;
getPrimaryWlanIfaceName()80 std::string getPrimaryWlanIfaceName() {
81 std::array<char, PROPERTY_VALUE_MAX> buffer;
82 auto res = property_get("ro.vendor.wifi.sap.interface", buffer.data(),
83 nullptr);
84 if (res > 0) return buffer.data();
85 property_get("wifi.interface", buffer.data(), "wlan0");
86 return buffer.data();
87 }
88
getIfaceParamsWithoutAcs()89 IHostapd::IfaceParams getIfaceParamsWithoutAcs() {
90 ::android::hardware::wifi::hostapd::V1_0::IHostapd::IfaceParams
91 iface_params;
92 ::android::hardware::wifi::hostapd::V1_1::IHostapd::IfaceParams
93 iface_params_1_1;
94 IHostapd::IfaceParams iface_params_1_2;
95
96 iface_params.ifaceName = getPrimaryWlanIfaceName();
97 iface_params.hwModeParams.enable80211N = true;
98 iface_params.hwModeParams.enable80211AC = false;
99 iface_params.channelParams.enableAcs = false;
100 iface_params.channelParams.acsShouldExcludeDfs = false;
101 iface_params.channelParams.channel = kIfaceChannel;
102 iface_params_1_1.V1_0 = iface_params;
103 iface_params_1_2.V1_1 = iface_params_1_1;
104 // Newly added attributes in V1_2
105 iface_params_1_2.hwModeParams.enable80211AX = false;
106 iface_params_1_2.hwModeParams.enable6GhzBand = false;
107 iface_params_1_2.channelParams.bandMask = 0;
108 iface_params_1_2.channelParams.bandMask |=
109 IHostapd::BandMask::BAND_2_GHZ;
110 return iface_params_1_2;
111 }
112
getIfaceParamsWithAcs()113 IHostapd::IfaceParams getIfaceParamsWithAcs() {
114 // First get the settings for WithoutAcs and then make changes
115 IHostapd::IfaceParams iface_params_1_2 = getIfaceParamsWithoutAcs();
116 iface_params_1_2.V1_1.V1_0.channelParams.enableAcs = true;
117 iface_params_1_2.V1_1.V1_0.channelParams.acsShouldExcludeDfs = true;
118 iface_params_1_2.V1_1.V1_0.channelParams.channel = 0;
119 iface_params_1_2.channelParams.bandMask |=
120 IHostapd::BandMask::BAND_5_GHZ;
121
122 return iface_params_1_2;
123 }
124
getIfaceParamsWithAcsAndFreqRange()125 IHostapd::IfaceParams getIfaceParamsWithAcsAndFreqRange() {
126 IHostapd::IfaceParams iface_params_1_2 = getIfaceParamsWithAcs();
127 ::android::hardware::wifi::hostapd::V1_2::IHostapd::AcsFrequencyRange
128 acsFrequencyRange;
129 acsFrequencyRange.start = 2412;
130 acsFrequencyRange.end = 2462;
131 std::vector<::android::hardware::wifi::hostapd::V1_2::IHostapd::
132 AcsFrequencyRange>
133 vec_acsFrequencyRange;
134 vec_acsFrequencyRange.push_back(acsFrequencyRange);
135 iface_params_1_2.channelParams.acsChannelFreqRangesMhz =
136 vec_acsFrequencyRange;
137 return iface_params_1_2;
138 }
139
getIfaceParamsWithAcsAndInvalidFreqRange()140 IHostapd::IfaceParams getIfaceParamsWithAcsAndInvalidFreqRange() {
141 IHostapd::IfaceParams iface_params_1_2 =
142 getIfaceParamsWithAcsAndFreqRange();
143 iface_params_1_2.channelParams.acsChannelFreqRangesMhz[0].start = 222;
144 iface_params_1_2.channelParams.acsChannelFreqRangesMhz[0].end = 999;
145 return iface_params_1_2;
146 }
147
getOpenNwParams()148 IHostapd::NetworkParams getOpenNwParams() {
149 IHostapd::NetworkParams nw_params_1_2;
150 ::android::hardware::wifi::hostapd::V1_0::IHostapd::NetworkParams
151 nw_params_1_0;
152 nw_params_1_0.ssid =
153 std::vector<uint8_t>(kNwSsid, kNwSsid + sizeof(kNwSsid));
154 nw_params_1_0.isHidden = false;
155 nw_params_1_2.V1_0 = nw_params_1_0;
156 nw_params_1_2.encryptionType = IHostapd::EncryptionType::NONE;
157 return nw_params_1_2;
158 }
159
getPskNwParams()160 IHostapd::NetworkParams getPskNwParams() {
161 IHostapd::NetworkParams nw_params_1_2 = getOpenNwParams();
162 nw_params_1_2.encryptionType = IHostapd::EncryptionType::WPA2;
163 nw_params_1_2.passphrase = kNwPassphrase;
164 return nw_params_1_2;
165 }
166
getInvalidPskNwParams()167 IHostapd::NetworkParams getInvalidPskNwParams() {
168 IHostapd::NetworkParams nw_params_1_2 = getOpenNwParams();
169 nw_params_1_2.encryptionType = IHostapd::EncryptionType::WPA2;
170 nw_params_1_2.passphrase = kInvalidMaxPskNwPassphrase;
171
172 return nw_params_1_2;
173 }
174
getSaeTransitionNwParams()175 IHostapd::NetworkParams getSaeTransitionNwParams() {
176 IHostapd::NetworkParams nw_params_1_2 = getOpenNwParams();
177 nw_params_1_2.encryptionType =
178 IHostapd::EncryptionType::WPA3_SAE_TRANSITION;
179 nw_params_1_2.passphrase = kNwPassphrase;
180 return nw_params_1_2;
181 }
182
getInvalidSaeTransitionNwParams()183 IHostapd::NetworkParams getInvalidSaeTransitionNwParams() {
184 IHostapd::NetworkParams nw_params_1_2 = getOpenNwParams();
185 nw_params_1_2.encryptionType = IHostapd::EncryptionType::WPA2;
186 nw_params_1_2.passphrase = kInvalidMinPskNwPassphrase;
187 return nw_params_1_2;
188 }
189
getSaeNwParams()190 IHostapd::NetworkParams getSaeNwParams() {
191 IHostapd::NetworkParams nw_params_1_2 = getOpenNwParams();
192 nw_params_1_2.encryptionType = IHostapd::EncryptionType::WPA3_SAE;
193 nw_params_1_2.passphrase = kNwPassphrase;
194 return nw_params_1_2;
195 }
196
getInvalidSaeNwParams()197 IHostapd::NetworkParams getInvalidSaeNwParams() {
198 IHostapd::NetworkParams nw_params_1_2 = getOpenNwParams();
199 nw_params_1_2.encryptionType = IHostapd::EncryptionType::WPA3_SAE;
200 nw_params_1_2.passphrase = "";
201 return nw_params_1_2;
202 }
203
getIfaceParamsWithInvalidChannel()204 IHostapd::IfaceParams getIfaceParamsWithInvalidChannel() {
205 IHostapd::IfaceParams iface_params_1_2 = getIfaceParamsWithoutAcs();
206 iface_params_1_2.V1_1.V1_0.channelParams.channel = kIfaceInvalidChannel;
207 return iface_params_1_2;
208 }
209
210 // IHostapd object used for all tests in this fixture.
211 sp<IHostapd> hostapd_;
212 std::string wifi_instance_name_;
213 std::string hostapd_instance_name_;
214 };
215
216 /**
217 * Adds an access point with PSK network config & ACS enabled.
218 * Access point creation should pass.
219 */
TEST_P(HostapdHidlTest,AddPskAccessPointWithAcs)220 TEST_P(HostapdHidlTest, AddPskAccessPointWithAcs) {
221 if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support";
222 auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
223 getIfaceParamsWithAcs(), getPskNwParams());
224 EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
225 }
226
227 /**
228 * Adds an access point with PSK network config, ACS enabled & frequency Range.
229 * Access point creation should pass.
230 */
TEST_P(HostapdHidlTest,AddPskAccessPointWithAcsAndFreqRange)231 TEST_P(HostapdHidlTest, AddPskAccessPointWithAcsAndFreqRange) {
232 if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support";
233 auto status =
234 HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
235 getIfaceParamsWithAcsAndFreqRange(), getPskNwParams());
236 EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
237 }
238
239 /**
240 * Adds an access point with invalid channel range.
241 * Access point creation should fail.
242 */
TEST_P(HostapdHidlTest,AddPskAccessPointWithAcsAndInvalidFreqRange)243 TEST_P(HostapdHidlTest, AddPskAccessPointWithAcsAndInvalidFreqRange) {
244 if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support";
245 auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
246 getIfaceParamsWithAcsAndInvalidFreqRange(),
247 getPskNwParams());
248 EXPECT_NE(HostapdStatusCode::SUCCESS, status.code);
249 }
250
251 /**
252 * Adds an access point with Open network config & ACS enabled.
253 * Access point creation should pass.
254 */
TEST_P(HostapdHidlTest,AddOpenAccessPointWithAcs)255 TEST_P(HostapdHidlTest, AddOpenAccessPointWithAcs) {
256 if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support";
257 auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
258 getIfaceParamsWithAcs(), getOpenNwParams());
259 EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
260 }
261
262 /**
263 * Adds an access point with PSK network config & ACS disabled.
264 * Access point creation should pass.
265 */
TEST_P(HostapdHidlTest,AddPskAccessPointWithoutAcs)266 TEST_P(HostapdHidlTest, AddPskAccessPointWithoutAcs) {
267 auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
268 getIfaceParamsWithoutAcs(), getPskNwParams());
269 EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
270 }
271
272 /**
273 * Adds an access point with Open network config & ACS disabled.
274 * Access point creation should pass.
275 */
TEST_P(HostapdHidlTest,AddOpenAccessPointWithoutAcs)276 TEST_P(HostapdHidlTest, AddOpenAccessPointWithoutAcs) {
277 auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
278 getIfaceParamsWithoutAcs(), getOpenNwParams());
279 EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
280 }
281
282 /**
283 * Adds an access point with SAE Transition network config & ACS disabled.
284 * Access point creation should pass.
285 */
TEST_P(HostapdHidlTest,AddSaeTransitionAccessPointWithoutAcs)286 TEST_P(HostapdHidlTest, AddSaeTransitionAccessPointWithoutAcs) {
287 if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support";
288 auto status =
289 HIDL_INVOKE(hostapd_, addAccessPoint_1_2, getIfaceParamsWithoutAcs(),
290 getSaeTransitionNwParams());
291 EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
292 }
293
294 /**
295 * Adds an access point with SAE network config & ACS disabled.
296 * Access point creation should pass.
297 */
TEST_P(HostapdHidlTest,AddSAEAccessPointWithoutAcs)298 TEST_P(HostapdHidlTest, AddSAEAccessPointWithoutAcs) {
299 if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support";
300 auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
301 getIfaceParamsWithoutAcs(), getSaeNwParams());
302 EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
303 }
304
305 /**
306 * Adds & then removes an access point with PSK network config & ACS enabled.
307 * Access point creation & removal should pass.
308 */
TEST_P(HostapdHidlTest,RemoveAccessPointWithAcs)309 TEST_P(HostapdHidlTest, RemoveAccessPointWithAcs) {
310 if (!isAcsSupport_) GTEST_SKIP() << "Missing ACS support";
311 auto status_1_2 = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
312 getIfaceParamsWithAcs(), getPskNwParams());
313 EXPECT_EQ(HostapdStatusCode::SUCCESS, status_1_2.code);
314 auto status =
315 HIDL_INVOKE(hostapd_, removeAccessPoint, getPrimaryWlanIfaceName());
316 EXPECT_EQ(
317 android::hardware::wifi::hostapd::V1_0::HostapdStatusCode::SUCCESS,
318 status.code);
319 }
320
321 /**
322 * Adds & then removes an access point with PSK network config & ACS disabled.
323 * Access point creation & removal should pass.
324 */
TEST_P(HostapdHidlTest,RemoveAccessPointWithoutAcs)325 TEST_P(HostapdHidlTest, RemoveAccessPointWithoutAcs) {
326 auto status_1_2 = HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
327 getIfaceParamsWithoutAcs(), getPskNwParams());
328 EXPECT_EQ(HostapdStatusCode::SUCCESS, status_1_2.code);
329 auto status =
330 HIDL_INVOKE(hostapd_, removeAccessPoint, getPrimaryWlanIfaceName());
331 EXPECT_EQ(
332 android::hardware::wifi::hostapd::V1_0::HostapdStatusCode::SUCCESS,
333 status.code);
334 }
335
336 /**
337 * Adds an access point with invalid channel.
338 * Access point creation should fail.
339 */
TEST_P(HostapdHidlTest,AddPskAccessPointWithInvalidChannel)340 TEST_P(HostapdHidlTest, AddPskAccessPointWithInvalidChannel) {
341 auto status =
342 HIDL_INVOKE(hostapd_, addAccessPoint_1_2,
343 getIfaceParamsWithInvalidChannel(), getPskNwParams());
344 EXPECT_NE(HostapdStatusCode::SUCCESS, status.code);
345 }
346
347 /**
348 * Adds an access point with invalid PSK network config.
349 * Access point creation should fail.
350 */
TEST_P(HostapdHidlTest,AddInvalidPskAccessPointWithoutAcs)351 TEST_P(HostapdHidlTest, AddInvalidPskAccessPointWithoutAcs) {
352 auto status =
353 HIDL_INVOKE(hostapd_, addAccessPoint_1_2, getIfaceParamsWithoutAcs(),
354 getInvalidPskNwParams());
355 EXPECT_NE(HostapdStatusCode::SUCCESS, status.code);
356 }
357
358 /**
359 * Adds an access point with invalid SAE transition network config.
360 * Access point creation should fail.
361 */
TEST_P(HostapdHidlTest,AddInvalidSaeTransitionAccessPointWithoutAcs)362 TEST_P(HostapdHidlTest, AddInvalidSaeTransitionAccessPointWithoutAcs) {
363 if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support";
364 auto status =
365 HIDL_INVOKE(hostapd_, addAccessPoint_1_2, getIfaceParamsWithoutAcs(),
366 getInvalidSaeTransitionNwParams());
367 EXPECT_NE(HostapdStatusCode::SUCCESS, status.code);
368 }
369
370 /**
371 * Adds an access point with invalid SAE network config.
372 * Access point creation should fail.
373 */
TEST_P(HostapdHidlTest,AddInvalidSaeAccessPointWithoutAcs)374 TEST_P(HostapdHidlTest, AddInvalidSaeAccessPointWithoutAcs) {
375 if (!isWpa3SaeSupport_) GTEST_SKIP() << "Missing SAE support";
376 auto status =
377 HIDL_INVOKE(hostapd_, addAccessPoint_1_2, getIfaceParamsWithoutAcs(),
378 getInvalidSaeNwParams());
379 EXPECT_NE(HostapdStatusCode::SUCCESS, status.code);
380 }
381
382 /**
383 * forceClientDisconnect should return FAILURE_IFACE_UNKNOWN
384 * when hotspot interface doesn't init..
385 */
TEST_P(HostapdHidlTest,DisconnectClientWhenIfaceNotAvailable)386 TEST_P(HostapdHidlTest, DisconnectClientWhenIfaceNotAvailable) {
387 auto status =
388 HIDL_INVOKE(hostapd_, forceClientDisconnect, getPrimaryWlanIfaceName(),
389 kTestZeroMacAddr, kTestDisconnectReasonCode);
390 EXPECT_EQ(HostapdStatusCode::FAILURE_IFACE_UNKNOWN, status.code);
391 }
392
393 /**
394 * forceClientDisconnect should return FAILURE_CLIENT_UNKNOWN
395 * when hotspot interface available.
396 */
TEST_P(HostapdHidlTest,DisconnectClientWhenIfacAvailable)397 TEST_P(HostapdHidlTest, DisconnectClientWhenIfacAvailable) {
398 auto status_1_2 =
399 HIDL_INVOKE(hostapd_, addAccessPoint_1_2, getIfaceParamsWithoutAcs(),
400 getOpenNwParams());
401 EXPECT_EQ(HostapdStatusCode::SUCCESS, status_1_2.code);
402
403 status_1_2 =
404 HIDL_INVOKE(hostapd_, forceClientDisconnect, getPrimaryWlanIfaceName(),
405 kTestZeroMacAddr, kTestDisconnectReasonCode);
406 EXPECT_EQ(HostapdStatusCode::FAILURE_CLIENT_UNKNOWN, status_1_2.code);
407 }
408
409 /*
410 * SetDebugParams
411 */
TEST_P(HostapdHidlTest,SetDebugParams)412 TEST_P(HostapdHidlTest, SetDebugParams) {
413 auto status = HIDL_INVOKE(hostapd_, setDebugParams, DebugLevel::EXCESSIVE);
414 EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
415 }
416
417 INSTANTIATE_TEST_CASE_P(
418 PerInstance, HostapdHidlTest,
419 testing::Combine(
420 testing::ValuesIn(
421 android::hardware::getAllHalInstanceNames(IWifi::descriptor)),
422 testing::ValuesIn(android::hardware::getAllHalInstanceNames(
423 android::hardware::wifi::hostapd::V1_2::IHostapd::descriptor))),
424 android::hardware::PrintInstanceTupleNameToString<>);
425