blob: c1f2bb72800c7688b7449b8784aa0ebc9254c501 [file] [log] [blame]
Chris Yed13f7b52021-06-24 12:52:55 -07001/*
2 * Copyright (C) 2021 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 */
Chris Ye02c7bb32022-01-13 12:13:48 -080016#include <android/hardware/wifi/1.0/IWifi.h>
17#include <android/hardware/wifi/hostapd/1.3/IHostapd.h>
18
Chris Yed13f7b52021-06-24 12:52:55 -070019#include <VtsCoreUtil.h>
Chris Yed13f7b52021-06-24 12:52:55 -070020#include <aidl/Gtest.h>
21#include <aidl/Vintf.h>
Gabriel Birenb3eb5042021-11-03 19:40:44 +000022#include <aidl/android/hardware/wifi/hostapd/BnHostapd.h>
23#include <aidl/android/hardware/wifi/hostapd/BnHostapdCallback.h>
24#include <android/binder_manager.h>
Chris Yed13f7b52021-06-24 12:52:55 -070025#include <binder/IServiceManager.h>
26#include <binder/ProcessState.h>
Chris Ye02c7bb32022-01-13 12:13:48 -080027#include <hidl/ServiceManagement.h>
28#include <hostapd_hidl_call_util.h>
29#include <hostapd_hidl_test_utils.h>
30#include <wifi_hidl_test_utils.h>
31#include <wifi_hidl_test_utils_1_5.h>
Chris Yed13f7b52021-06-24 12:52:55 -070032
Gabriel Birenb3eb5042021-11-03 19:40:44 +000033using aidl::android::hardware::wifi::hostapd::BandMask;
34using aidl::android::hardware::wifi::hostapd::BnHostapdCallback;
35using aidl::android::hardware::wifi::hostapd::ChannelParams;
36using aidl::android::hardware::wifi::hostapd::DebugLevel;
37using aidl::android::hardware::wifi::hostapd::EncryptionType;
38using aidl::android::hardware::wifi::hostapd::FrequencyRange;
39using aidl::android::hardware::wifi::hostapd::Ieee80211ReasonCode;
40using aidl::android::hardware::wifi::hostapd::IfaceParams;
41using aidl::android::hardware::wifi::hostapd::IHostapd;
42using aidl::android::hardware::wifi::hostapd::NetworkParams;
Chris Yed13f7b52021-06-24 12:52:55 -070043using android::ProcessState;
Chris Yed13f7b52021-06-24 12:52:55 -070044
45namespace {
46const unsigned char kNwSsid[] = {'t', 'e', 's', 't', '1', '2', '3', '4', '5'};
Gabriel Birenb3eb5042021-11-03 19:40:44 +000047const std::string kIfaceName = "wlan0";
48const std::string kPassphrase = "test12345";
49const std::string kInvalidMinPassphrase = "test";
50const std::string kInvalidMaxPassphrase =
51 "0123456789012345678901234567890123456789012345678901234567890123456789";
Chris Yed13f7b52021-06-24 12:52:55 -070052const int kIfaceChannel = 6;
53const int kIfaceInvalidChannel = 567;
54const std::vector<uint8_t> kTestZeroMacAddr(6, 0x0);
55const Ieee80211ReasonCode kTestDisconnectReasonCode =
56 Ieee80211ReasonCode::WLAN_REASON_UNSPECIFIED;
57
58inline BandMask operator|(BandMask a, BandMask b) {
59 return static_cast<BandMask>(static_cast<int32_t>(a) |
60 static_cast<int32_t>(b));
61}
62} // namespace
63
64class HostapdAidl : public testing::TestWithParam<std::string> {
65 public:
66 virtual void SetUp() override {
Gabriel Birenb3eb5042021-11-03 19:40:44 +000067 hostapd = IHostapd::fromBinder(ndk::SpAIBinder(
68 AServiceManager_waitForService(GetParam().c_str())));
Chris Yed13f7b52021-06-24 12:52:55 -070069 ASSERT_NE(hostapd, nullptr);
70 EXPECT_TRUE(hostapd->setDebugParams(DebugLevel::EXCESSIVE).isOk());
71 isAcsSupport = testing::checkSubstringInCommandOutput(
72 "/system/bin/cmd wifi get-softap-supported-features",
73 "wifi_softap_acs_supported");
74 isWpa3SaeSupport = testing::checkSubstringInCommandOutput(
75 "/system/bin/cmd wifi get-softap-supported-features",
76 "wifi_softap_wpa3_sae_supported");
77 isBridgedSupport = testing::checkSubstringInCommandOutput(
78 "/system/bin/cmd wifi get-softap-supported-features",
79 "wifi_softap_bridged_ap_supported");
Chris Ye02c7bb32022-01-13 12:13:48 -080080 const std::vector<std::string> instances = android::hardware::getAllHalInstanceNames(
81 ::android::hardware::wifi::V1_0::IWifi::descriptor);
82 EXPECT_NE(0, instances.size());
83 wifiInstanceName = instances[0];
Chris Yed13f7b52021-06-24 12:52:55 -070084 }
85
86 virtual void TearDown() override {
Chris Ye02c7bb32022-01-13 12:13:48 -080087 if (getWifi(wifiInstanceName) != nullptr) {
88 stopWifi(wifiInstanceName);
89 }
Chris Yed13f7b52021-06-24 12:52:55 -070090 hostapd->terminate();
91 // Wait 3 seconds to allow terminate to complete
92 sleep(3);
93 }
94
Gabriel Birenb3eb5042021-11-03 19:40:44 +000095 std::shared_ptr<IHostapd> hostapd;
Chris Ye02c7bb32022-01-13 12:13:48 -080096 std::string wifiInstanceName;
Chris Yed13f7b52021-06-24 12:52:55 -070097 bool isAcsSupport;
98 bool isWpa3SaeSupport;
99 bool isBridgedSupport;
100
Chris Ye02c7bb32022-01-13 12:13:48 -0800101 std::string setupApIfaceAndGetName(bool isBridged) {
102 android::sp<::android::hardware::wifi::V1_0::IWifiApIface> wifi_ap_iface;
103 if (isBridged) {
104 wifi_ap_iface = getBridgedWifiApIface_1_5(wifiInstanceName);
105 } else {
106 wifi_ap_iface = getWifiApIface_1_5(wifiInstanceName);
107 }
108 EXPECT_NE(nullptr, wifi_ap_iface.get());
109
110 const auto& status_and_name = HIDL_INVOKE(wifi_ap_iface, getName);
111 EXPECT_EQ(android::hardware::wifi::V1_0::WifiStatusCode::SUCCESS,
112 status_and_name.first.code);
113 return status_and_name.second;
114 }
115
Gabriel Birenb3eb5042021-11-03 19:40:44 +0000116 IfaceParams getIfaceParamsWithoutAcs(std::string iface_name) {
Chris Yed13f7b52021-06-24 12:52:55 -0700117 IfaceParams iface_params;
118 ChannelParams channelParams;
119 std::vector<ChannelParams> vec_channelParams;
120
121 iface_params.name = iface_name;
122 iface_params.hwModeParams.enable80211N = true;
123 iface_params.hwModeParams.enable80211AC = false;
124 iface_params.hwModeParams.enable80211AX = false;
125 iface_params.hwModeParams.enable6GhzBand = false;
126
127 channelParams.enableAcs = false;
128 channelParams.acsShouldExcludeDfs = false;
129 channelParams.channel = kIfaceChannel;
130 channelParams.bandMask = BandMask::BAND_2_GHZ;
131
132 vec_channelParams.push_back(channelParams);
133 iface_params.channelParams = vec_channelParams;
134 return iface_params;
135 }
136
Gabriel Birenb3eb5042021-11-03 19:40:44 +0000137 IfaceParams getIfaceParamsWithBridgedModeACS(std::string iface_name) {
Chris Yed13f7b52021-06-24 12:52:55 -0700138 IfaceParams iface_params = getIfaceParamsWithoutAcs(iface_name);
139 iface_params.channelParams[0].enableAcs = true;
140 iface_params.channelParams[0].acsShouldExcludeDfs = true;
141
142 std::vector<ChannelParams> vec_channelParams;
143 vec_channelParams.push_back(iface_params.channelParams[0]);
144
145 ChannelParams second_channelParams;
146 second_channelParams.channel = 0;
147 second_channelParams.enableAcs = true;
148 second_channelParams.bandMask = BandMask::BAND_5_GHZ;
149 vec_channelParams.push_back(second_channelParams);
150
151 iface_params.channelParams = vec_channelParams;
152 return iface_params;
153 }
154
Gabriel Birenb3eb5042021-11-03 19:40:44 +0000155 IfaceParams getIfaceParamsWithAcs(std::string iface_name) {
Chris Yed13f7b52021-06-24 12:52:55 -0700156 IfaceParams iface_params = getIfaceParamsWithoutAcs(iface_name);
157 iface_params.channelParams[0].enableAcs = true;
158 iface_params.channelParams[0].acsShouldExcludeDfs = true;
159 iface_params.channelParams[0].channel = 0;
160 iface_params.channelParams[0].bandMask =
161 iface_params.channelParams[0].bandMask | BandMask::BAND_5_GHZ;
162 return iface_params;
163 }
164
Gabriel Birenb3eb5042021-11-03 19:40:44 +0000165 IfaceParams getIfaceParamsWithAcsAndFreqRange(std::string iface_name) {
Chris Yed13f7b52021-06-24 12:52:55 -0700166 IfaceParams iface_params = getIfaceParamsWithAcs(iface_name);
167 FrequencyRange freqRange;
168 freqRange.startMhz = 2412;
169 freqRange.endMhz = 2462;
170 std::vector<FrequencyRange> vec_FrequencyRange;
171 vec_FrequencyRange.push_back(freqRange);
172 iface_params.channelParams[0].acsChannelFreqRangesMhz =
173 vec_FrequencyRange;
174 return iface_params;
175 }
176
Gabriel Birenb3eb5042021-11-03 19:40:44 +0000177 IfaceParams getIfaceParamsWithAcsAndInvalidFreqRange(
178 std::string iface_name) {
Chris Yed13f7b52021-06-24 12:52:55 -0700179 IfaceParams iface_params =
180 getIfaceParamsWithAcsAndFreqRange(iface_name);
181 iface_params.channelParams[0].acsChannelFreqRangesMhz[0].startMhz =
182 222;
183 iface_params.channelParams[0].acsChannelFreqRangesMhz[0].endMhz =
184 999;
185 return iface_params;
186 }
187
Gabriel Birenb3eb5042021-11-03 19:40:44 +0000188 IfaceParams getIfaceParamsWithInvalidChannel(std::string iface_name) {
Chris Yed13f7b52021-06-24 12:52:55 -0700189 IfaceParams iface_params = getIfaceParamsWithoutAcs(iface_name);
190 iface_params.channelParams[0].channel = kIfaceInvalidChannel;
191 return iface_params;
192 }
193
194 NetworkParams getOpenNwParams() {
195 NetworkParams nw_params;
196 nw_params.ssid =
197 std::vector<uint8_t>(kNwSsid, kNwSsid + sizeof(kNwSsid));
198 nw_params.isHidden = false;
199 nw_params.encryptionType = EncryptionType::NONE;
200 nw_params.isMetered = true;
201 return nw_params;
202 }
203
204 NetworkParams getPskNwParamsWithNonMetered() {
205 NetworkParams nw_params = getOpenNwParams();
206 nw_params.encryptionType = EncryptionType::WPA2;
207 nw_params.passphrase = kPassphrase;
208 nw_params.isMetered = false;
209 return nw_params;
210 }
211
212 NetworkParams getPskNwParams() {
213 NetworkParams nw_params = getOpenNwParams();
214 nw_params.encryptionType = EncryptionType::WPA2;
215 nw_params.passphrase = kPassphrase;
216 return nw_params;
217 }
218
219 NetworkParams getInvalidPskNwParams() {
220 NetworkParams nw_params = getOpenNwParams();
221 nw_params.encryptionType = EncryptionType::WPA2;
222 nw_params.passphrase = kInvalidMaxPassphrase;
223 return nw_params;
224 }
225
226 NetworkParams getSaeTransitionNwParams() {
227 NetworkParams nw_params = getOpenNwParams();
228 nw_params.encryptionType = EncryptionType::WPA3_SAE_TRANSITION;
229 nw_params.passphrase = kPassphrase;
230 return nw_params;
231 }
232
233 NetworkParams getInvalidSaeTransitionNwParams() {
234 NetworkParams nw_params = getOpenNwParams();
235 nw_params.encryptionType = EncryptionType::WPA2;
236 nw_params.passphrase = kInvalidMinPassphrase;
237 return nw_params;
238 }
239
240 NetworkParams getSaeNwParams() {
241 NetworkParams nw_params = getOpenNwParams();
242 nw_params.encryptionType = EncryptionType::WPA3_SAE;
243 nw_params.passphrase = kPassphrase;
244 return nw_params;
245 }
246
247 NetworkParams getInvalidSaeNwParams() {
248 NetworkParams nw_params = getOpenNwParams();
249 nw_params.encryptionType = EncryptionType::WPA3_SAE;
Gabriel Birenb3eb5042021-11-03 19:40:44 +0000250 nw_params.passphrase = "";
Chris Yed13f7b52021-06-24 12:52:55 -0700251 return nw_params;
252 }
253};
254
Gabriel Birenb3eb5042021-11-03 19:40:44 +0000255class HostapdCallback : public BnHostapdCallback {
256 public:
257 HostapdCallback() = default;
258 ::ndk::ScopedAStatus onApInstanceInfoChanged(
259 const ::aidl::android::hardware::wifi::hostapd::ApInfo &) override {
260 return ndk::ScopedAStatus::ok();
261 }
262 ::ndk::ScopedAStatus onConnectedClientsChanged(
263 const ::aidl::android::hardware::wifi::hostapd::ClientInfo &) override {
264 return ndk::ScopedAStatus::ok();
265 }
Les Lee6645e9e2021-10-29 16:04:23 +0800266 ::ndk::ScopedAStatus onFailure(const std::string&, const std::string&) override {
Gabriel Birenb3eb5042021-11-03 19:40:44 +0000267 return ndk::ScopedAStatus::ok();
268 }
269};
270
271/**
272 * Register callback
273 */
274TEST_P(HostapdAidl, RegisterCallback) {
275 std::shared_ptr<HostapdCallback> callback =
276 ndk::SharedRefBase::make<HostapdCallback>();
277 ASSERT_NE(callback, nullptr);
278 EXPECT_TRUE(hostapd->registerCallback(callback).isOk());
279}
280
Chris Yed13f7b52021-06-24 12:52:55 -0700281/**
282 * Adds an access point with PSK network config & ACS enabled.
283 * Access point creation should pass.
284 */
285TEST_P(HostapdAidl, AddPskAccessPointWithAcs) {
286 if (!isAcsSupport) GTEST_SKIP() << "Missing ACS support";
287 auto status = hostapd->addAccessPoint(getIfaceParamsWithAcs(kIfaceName),
288 getPskNwParams());
289 EXPECT_TRUE(status.isOk());
290}
291
292/**
293 * Adds an access point with PSK network config, ACS enabled & frequency Range.
294 * Access point creation should pass.
295 */
296TEST_P(HostapdAidl, AddPskAccessPointWithAcsAndFreqRange) {
297 if (!isAcsSupport) GTEST_SKIP() << "Missing ACS support";
298 auto status = hostapd->addAccessPoint(
299 getIfaceParamsWithAcsAndFreqRange(kIfaceName), getPskNwParams());
300 EXPECT_TRUE(status.isOk());
301}
302
303/**
304 * Adds an access point with invalid channel range.
305 * Access point creation should fail.
306 */
307TEST_P(HostapdAidl, AddPskAccessPointWithAcsAndInvalidFreqRange) {
308 if (!isAcsSupport) GTEST_SKIP() << "Missing ACS support";
309 auto status = hostapd->addAccessPoint(
310 getIfaceParamsWithAcsAndInvalidFreqRange(kIfaceName), getPskNwParams());
311 EXPECT_FALSE(status.isOk());
312}
313
314/**
315 * Adds an access point with Open network config & ACS enabled.
316 * Access point creation should pass.
317 */
318TEST_P(HostapdAidl, AddOpenAccessPointWithAcs) {
319 if (!isAcsSupport) GTEST_SKIP() << "Missing ACS support";
320 auto status = hostapd->addAccessPoint(getIfaceParamsWithAcs(kIfaceName),
321 getOpenNwParams());
322 EXPECT_TRUE(status.isOk());
323}
324
325/**
326 * Adds an access point with PSK network config & ACS disabled.
327 * Access point creation should pass.
328 */
329TEST_P(HostapdAidl, AddPskAccessPointWithoutAcs) {
330 auto status = hostapd->addAccessPoint(getIfaceParamsWithoutAcs(kIfaceName),
331 getPskNwParams());
332 EXPECT_TRUE(status.isOk());
333}
334
335/**
336 * Adds an access point with PSK network config, ACS disabled & Non metered.
337 * Access point creation should pass.
338 */
339TEST_P(HostapdAidl, AddPskAccessPointWithoutAcsAndNonMetered) {
340 auto status = hostapd->addAccessPoint(getIfaceParamsWithoutAcs(kIfaceName),
341 getPskNwParamsWithNonMetered());
342 EXPECT_TRUE(status.isOk());
343}
344
345/**
346 * Adds an access point with Open network config & ACS disabled.
347 * Access point creation should pass.
348 */
349TEST_P(HostapdAidl, AddOpenAccessPointWithoutAcs) {
350 auto status = hostapd->addAccessPoint(getIfaceParamsWithoutAcs(kIfaceName),
351 getOpenNwParams());
352 EXPECT_TRUE(status.isOk());
353}
354
355/**
356 * Adds an access point with SAE Transition network config & ACS disabled.
357 * Access point creation should pass.
358 */
359TEST_P(HostapdAidl, AddSaeTransitionAccessPointWithoutAcs) {
360 if (!isWpa3SaeSupport) GTEST_SKIP() << "Missing SAE support";
361 auto status = hostapd->addAccessPoint(getIfaceParamsWithoutAcs(kIfaceName),
362 getSaeTransitionNwParams());
363 EXPECT_TRUE(status.isOk());
364}
365
366/**
367 * Adds an access point with SAE network config & ACS disabled.
368 * Access point creation should pass.
369 */
370TEST_P(HostapdAidl, AddSAEAccessPointWithoutAcs) {
371 if (!isWpa3SaeSupport) GTEST_SKIP() << "Missing SAE support";
372 auto status = hostapd->addAccessPoint(getIfaceParamsWithoutAcs(kIfaceName),
373 getSaeNwParams());
374 EXPECT_TRUE(status.isOk());
375}
376
377/**
378 * Adds & then removes an access point with PSK network config & ACS enabled.
379 * Access point creation & removal should pass.
380 */
381TEST_P(HostapdAidl, RemoveAccessPointWithAcs) {
382 if (!isAcsSupport) GTEST_SKIP() << "Missing ACS support";
383 auto status = hostapd->addAccessPoint(getIfaceParamsWithAcs(kIfaceName),
384 getPskNwParams());
385 EXPECT_TRUE(status.isOk());
386 EXPECT_TRUE(hostapd->removeAccessPoint(kIfaceName).isOk());
387}
388
389/**
390 * Adds & then removes an access point with PSK network config & ACS disabled.
391 * Access point creation & removal should pass.
392 */
393TEST_P(HostapdAidl, RemoveAccessPointWithoutAcs) {
394 auto status = hostapd->addAccessPoint(getIfaceParamsWithoutAcs(kIfaceName),
395 getPskNwParams());
396 EXPECT_TRUE(status.isOk());
397 EXPECT_TRUE(hostapd->removeAccessPoint(kIfaceName).isOk());
398}
399
400/**
401 * Adds an access point with invalid channel.
402 * Access point creation should fail.
403 */
404TEST_P(HostapdAidl, AddPskAccessPointWithInvalidChannel) {
405 auto status = hostapd->addAccessPoint(
406 getIfaceParamsWithInvalidChannel(kIfaceName), getPskNwParams());
407 EXPECT_FALSE(status.isOk());
408}
409
410/**
411 * Adds an access point with invalid PSK network config.
412 * Access point creation should fail.
413 */
414TEST_P(HostapdAidl, AddInvalidPskAccessPointWithoutAcs) {
415 auto status = hostapd->addAccessPoint(getIfaceParamsWithoutAcs(kIfaceName),
416 getInvalidPskNwParams());
417 EXPECT_FALSE(status.isOk());
418}
419
420/**
421 * Adds an access point with invalid SAE transition network config.
422 * Access point creation should fail.
423 */
424TEST_P(HostapdAidl, AddInvalidSaeTransitionAccessPointWithoutAcs) {
425 if (!isWpa3SaeSupport) GTEST_SKIP() << "Missing SAE support";
426 auto status = hostapd->addAccessPoint(getIfaceParamsWithoutAcs(kIfaceName),
427 getInvalidSaeTransitionNwParams());
428 EXPECT_FALSE(status.isOk());
429}
430
431/**
432 * Adds an access point with invalid SAE network config.
433 * Access point creation should fail.
434 */
435TEST_P(HostapdAidl, AddInvalidSaeAccessPointWithoutAcs) {
436 if (!isWpa3SaeSupport) GTEST_SKIP() << "Missing SAE support";
437 auto status = hostapd->addAccessPoint(getIfaceParamsWithoutAcs(kIfaceName),
438 getInvalidSaeNwParams());
439 EXPECT_FALSE(status.isOk());
440}
441
442/**
443 * forceClientDisconnect should fail when hotspot interface available.
444 */
445TEST_P(HostapdAidl, DisconnectClientWhenIfacAvailable) {
446 auto status = hostapd->addAccessPoint(getIfaceParamsWithoutAcs(kIfaceName),
447 getOpenNwParams());
448 EXPECT_TRUE(status.isOk());
449
450 status = hostapd->forceClientDisconnect(kIfaceName, kTestZeroMacAddr,
451 kTestDisconnectReasonCode);
452 EXPECT_FALSE(status.isOk());
453}
454
455/**
456 * AddAccessPointWithDualBandConfig should pass
457 */
458TEST_P(HostapdAidl, AddAccessPointWithDualBandConfig) {
459 if (!isBridgedSupport) GTEST_SKIP() << "Missing Bridged AP support";
Chris Ye02c7bb32022-01-13 12:13:48 -0800460 std::string ifname = setupApIfaceAndGetName(true);
461 auto status =
462 hostapd->addAccessPoint(getIfaceParamsWithBridgedModeACS(ifname), getOpenNwParams());
Chris Yed13f7b52021-06-24 12:52:55 -0700463 EXPECT_TRUE(status.isOk());
464}
465
Gabriel Biren962d5df2022-01-12 23:15:17 +0000466GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(HostapdAidl);
Chris Yed13f7b52021-06-24 12:52:55 -0700467INSTANTIATE_TEST_SUITE_P(
468 Hostapd, HostapdAidl,
469 testing::ValuesIn(android::getAidlHalInstanceNames(IHostapd::descriptor)),
470 android::PrintInstanceNameToString);
471
472int main(int argc, char **argv) {
473 ::testing::InitGoogleTest(&argc, argv);
474 ProcessState::self()->setThreadPoolMaxThreadCount(1);
475 ProcessState::self()->startThreadPool();
476 return RUN_ALL_TESTS();
477}