blob: dad708567c9597a092b5354a981ed17192448460 [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 */
16#include <VtsCoreUtil.h>
Chris Yed13f7b52021-06-24 12:52:55 -070017#include <aidl/Gtest.h>
18#include <aidl/Vintf.h>
Gabriel Birenb3eb5042021-11-03 19:40:44 +000019#include <aidl/android/hardware/wifi/hostapd/BnHostapd.h>
20#include <aidl/android/hardware/wifi/hostapd/BnHostapdCallback.h>
21#include <android/binder_manager.h>
Chris Yed13f7b52021-06-24 12:52:55 -070022#include <binder/IServiceManager.h>
23#include <binder/ProcessState.h>
24
Gabriel Birenb3eb5042021-11-03 19:40:44 +000025using aidl::android::hardware::wifi::hostapd::BandMask;
26using aidl::android::hardware::wifi::hostapd::BnHostapdCallback;
27using aidl::android::hardware::wifi::hostapd::ChannelParams;
28using aidl::android::hardware::wifi::hostapd::DebugLevel;
29using aidl::android::hardware::wifi::hostapd::EncryptionType;
30using aidl::android::hardware::wifi::hostapd::FrequencyRange;
31using aidl::android::hardware::wifi::hostapd::Ieee80211ReasonCode;
32using aidl::android::hardware::wifi::hostapd::IfaceParams;
33using aidl::android::hardware::wifi::hostapd::IHostapd;
34using aidl::android::hardware::wifi::hostapd::NetworkParams;
Chris Yed13f7b52021-06-24 12:52:55 -070035using android::ProcessState;
Chris Yed13f7b52021-06-24 12:52:55 -070036
37namespace {
38const unsigned char kNwSsid[] = {'t', 'e', 's', 't', '1', '2', '3', '4', '5'};
Gabriel Birenb3eb5042021-11-03 19:40:44 +000039const std::string kIfaceName = "wlan0";
40const std::string kPassphrase = "test12345";
41const std::string kInvalidMinPassphrase = "test";
42const std::string kInvalidMaxPassphrase =
43 "0123456789012345678901234567890123456789012345678901234567890123456789";
Chris Yed13f7b52021-06-24 12:52:55 -070044const int kIfaceChannel = 6;
45const int kIfaceInvalidChannel = 567;
46const std::vector<uint8_t> kTestZeroMacAddr(6, 0x0);
47const Ieee80211ReasonCode kTestDisconnectReasonCode =
48 Ieee80211ReasonCode::WLAN_REASON_UNSPECIFIED;
49
50inline BandMask operator|(BandMask a, BandMask b) {
51 return static_cast<BandMask>(static_cast<int32_t>(a) |
52 static_cast<int32_t>(b));
53}
54} // namespace
55
56class HostapdAidl : public testing::TestWithParam<std::string> {
57 public:
58 virtual void SetUp() override {
Gabriel Birenb3eb5042021-11-03 19:40:44 +000059 hostapd = IHostapd::fromBinder(ndk::SpAIBinder(
60 AServiceManager_waitForService(GetParam().c_str())));
Chris Yed13f7b52021-06-24 12:52:55 -070061 ASSERT_NE(hostapd, nullptr);
62 EXPECT_TRUE(hostapd->setDebugParams(DebugLevel::EXCESSIVE).isOk());
63 isAcsSupport = testing::checkSubstringInCommandOutput(
64 "/system/bin/cmd wifi get-softap-supported-features",
65 "wifi_softap_acs_supported");
66 isWpa3SaeSupport = testing::checkSubstringInCommandOutput(
67 "/system/bin/cmd wifi get-softap-supported-features",
68 "wifi_softap_wpa3_sae_supported");
69 isBridgedSupport = testing::checkSubstringInCommandOutput(
70 "/system/bin/cmd wifi get-softap-supported-features",
71 "wifi_softap_bridged_ap_supported");
72 }
73
74 virtual void TearDown() override {
75 hostapd->terminate();
76 // Wait 3 seconds to allow terminate to complete
77 sleep(3);
78 }
79
Gabriel Birenb3eb5042021-11-03 19:40:44 +000080 std::shared_ptr<IHostapd> hostapd;
Chris Yed13f7b52021-06-24 12:52:55 -070081 bool isAcsSupport;
82 bool isWpa3SaeSupport;
83 bool isBridgedSupport;
84
Gabriel Birenb3eb5042021-11-03 19:40:44 +000085 IfaceParams getIfaceParamsWithoutAcs(std::string iface_name) {
Chris Yed13f7b52021-06-24 12:52:55 -070086 IfaceParams iface_params;
87 ChannelParams channelParams;
88 std::vector<ChannelParams> vec_channelParams;
89
90 iface_params.name = iface_name;
91 iface_params.hwModeParams.enable80211N = true;
92 iface_params.hwModeParams.enable80211AC = false;
93 iface_params.hwModeParams.enable80211AX = false;
94 iface_params.hwModeParams.enable6GhzBand = false;
95
96 channelParams.enableAcs = false;
97 channelParams.acsShouldExcludeDfs = false;
98 channelParams.channel = kIfaceChannel;
99 channelParams.bandMask = BandMask::BAND_2_GHZ;
100
101 vec_channelParams.push_back(channelParams);
102 iface_params.channelParams = vec_channelParams;
103 return iface_params;
104 }
105
Gabriel Birenb3eb5042021-11-03 19:40:44 +0000106 IfaceParams getIfaceParamsWithBridgedModeACS(std::string iface_name) {
Chris Yed13f7b52021-06-24 12:52:55 -0700107 IfaceParams iface_params = getIfaceParamsWithoutAcs(iface_name);
108 iface_params.channelParams[0].enableAcs = true;
109 iface_params.channelParams[0].acsShouldExcludeDfs = true;
110
111 std::vector<ChannelParams> vec_channelParams;
112 vec_channelParams.push_back(iface_params.channelParams[0]);
113
114 ChannelParams second_channelParams;
115 second_channelParams.channel = 0;
116 second_channelParams.enableAcs = true;
117 second_channelParams.bandMask = BandMask::BAND_5_GHZ;
118 vec_channelParams.push_back(second_channelParams);
119
120 iface_params.channelParams = vec_channelParams;
121 return iface_params;
122 }
123
Gabriel Birenb3eb5042021-11-03 19:40:44 +0000124 IfaceParams getIfaceParamsWithAcs(std::string iface_name) {
Chris Yed13f7b52021-06-24 12:52:55 -0700125 IfaceParams iface_params = getIfaceParamsWithoutAcs(iface_name);
126 iface_params.channelParams[0].enableAcs = true;
127 iface_params.channelParams[0].acsShouldExcludeDfs = true;
128 iface_params.channelParams[0].channel = 0;
129 iface_params.channelParams[0].bandMask =
130 iface_params.channelParams[0].bandMask | BandMask::BAND_5_GHZ;
131 return iface_params;
132 }
133
Gabriel Birenb3eb5042021-11-03 19:40:44 +0000134 IfaceParams getIfaceParamsWithAcsAndFreqRange(std::string iface_name) {
Chris Yed13f7b52021-06-24 12:52:55 -0700135 IfaceParams iface_params = getIfaceParamsWithAcs(iface_name);
136 FrequencyRange freqRange;
137 freqRange.startMhz = 2412;
138 freqRange.endMhz = 2462;
139 std::vector<FrequencyRange> vec_FrequencyRange;
140 vec_FrequencyRange.push_back(freqRange);
141 iface_params.channelParams[0].acsChannelFreqRangesMhz =
142 vec_FrequencyRange;
143 return iface_params;
144 }
145
Gabriel Birenb3eb5042021-11-03 19:40:44 +0000146 IfaceParams getIfaceParamsWithAcsAndInvalidFreqRange(
147 std::string iface_name) {
Chris Yed13f7b52021-06-24 12:52:55 -0700148 IfaceParams iface_params =
149 getIfaceParamsWithAcsAndFreqRange(iface_name);
150 iface_params.channelParams[0].acsChannelFreqRangesMhz[0].startMhz =
151 222;
152 iface_params.channelParams[0].acsChannelFreqRangesMhz[0].endMhz =
153 999;
154 return iface_params;
155 }
156
Gabriel Birenb3eb5042021-11-03 19:40:44 +0000157 IfaceParams getIfaceParamsWithInvalidChannel(std::string iface_name) {
Chris Yed13f7b52021-06-24 12:52:55 -0700158 IfaceParams iface_params = getIfaceParamsWithoutAcs(iface_name);
159 iface_params.channelParams[0].channel = kIfaceInvalidChannel;
160 return iface_params;
161 }
162
163 NetworkParams getOpenNwParams() {
164 NetworkParams nw_params;
165 nw_params.ssid =
166 std::vector<uint8_t>(kNwSsid, kNwSsid + sizeof(kNwSsid));
167 nw_params.isHidden = false;
168 nw_params.encryptionType = EncryptionType::NONE;
169 nw_params.isMetered = true;
170 return nw_params;
171 }
172
173 NetworkParams getPskNwParamsWithNonMetered() {
174 NetworkParams nw_params = getOpenNwParams();
175 nw_params.encryptionType = EncryptionType::WPA2;
176 nw_params.passphrase = kPassphrase;
177 nw_params.isMetered = false;
178 return nw_params;
179 }
180
181 NetworkParams getPskNwParams() {
182 NetworkParams nw_params = getOpenNwParams();
183 nw_params.encryptionType = EncryptionType::WPA2;
184 nw_params.passphrase = kPassphrase;
185 return nw_params;
186 }
187
188 NetworkParams getInvalidPskNwParams() {
189 NetworkParams nw_params = getOpenNwParams();
190 nw_params.encryptionType = EncryptionType::WPA2;
191 nw_params.passphrase = kInvalidMaxPassphrase;
192 return nw_params;
193 }
194
195 NetworkParams getSaeTransitionNwParams() {
196 NetworkParams nw_params = getOpenNwParams();
197 nw_params.encryptionType = EncryptionType::WPA3_SAE_TRANSITION;
198 nw_params.passphrase = kPassphrase;
199 return nw_params;
200 }
201
202 NetworkParams getInvalidSaeTransitionNwParams() {
203 NetworkParams nw_params = getOpenNwParams();
204 nw_params.encryptionType = EncryptionType::WPA2;
205 nw_params.passphrase = kInvalidMinPassphrase;
206 return nw_params;
207 }
208
209 NetworkParams getSaeNwParams() {
210 NetworkParams nw_params = getOpenNwParams();
211 nw_params.encryptionType = EncryptionType::WPA3_SAE;
212 nw_params.passphrase = kPassphrase;
213 return nw_params;
214 }
215
216 NetworkParams getInvalidSaeNwParams() {
217 NetworkParams nw_params = getOpenNwParams();
218 nw_params.encryptionType = EncryptionType::WPA3_SAE;
Gabriel Birenb3eb5042021-11-03 19:40:44 +0000219 nw_params.passphrase = "";
Chris Yed13f7b52021-06-24 12:52:55 -0700220 return nw_params;
221 }
222};
223
Gabriel Birenb3eb5042021-11-03 19:40:44 +0000224class HostapdCallback : public BnHostapdCallback {
225 public:
226 HostapdCallback() = default;
227 ::ndk::ScopedAStatus onApInstanceInfoChanged(
228 const ::aidl::android::hardware::wifi::hostapd::ApInfo &) override {
229 return ndk::ScopedAStatus::ok();
230 }
231 ::ndk::ScopedAStatus onConnectedClientsChanged(
232 const ::aidl::android::hardware::wifi::hostapd::ClientInfo &) override {
233 return ndk::ScopedAStatus::ok();
234 }
Les Lee6645e9e2021-10-29 16:04:23 +0800235 ::ndk::ScopedAStatus onFailure(const std::string&, const std::string&) override {
Gabriel Birenb3eb5042021-11-03 19:40:44 +0000236 return ndk::ScopedAStatus::ok();
237 }
238};
239
240/**
241 * Register callback
242 */
243TEST_P(HostapdAidl, RegisterCallback) {
244 std::shared_ptr<HostapdCallback> callback =
245 ndk::SharedRefBase::make<HostapdCallback>();
246 ASSERT_NE(callback, nullptr);
247 EXPECT_TRUE(hostapd->registerCallback(callback).isOk());
248}
249
Chris Yed13f7b52021-06-24 12:52:55 -0700250/**
251 * Adds an access point with PSK network config & ACS enabled.
252 * Access point creation should pass.
253 */
254TEST_P(HostapdAidl, AddPskAccessPointWithAcs) {
255 if (!isAcsSupport) GTEST_SKIP() << "Missing ACS support";
256 auto status = hostapd->addAccessPoint(getIfaceParamsWithAcs(kIfaceName),
257 getPskNwParams());
258 EXPECT_TRUE(status.isOk());
259}
260
261/**
262 * Adds an access point with PSK network config, ACS enabled & frequency Range.
263 * Access point creation should pass.
264 */
265TEST_P(HostapdAidl, AddPskAccessPointWithAcsAndFreqRange) {
266 if (!isAcsSupport) GTEST_SKIP() << "Missing ACS support";
267 auto status = hostapd->addAccessPoint(
268 getIfaceParamsWithAcsAndFreqRange(kIfaceName), getPskNwParams());
269 EXPECT_TRUE(status.isOk());
270}
271
272/**
273 * Adds an access point with invalid channel range.
274 * Access point creation should fail.
275 */
276TEST_P(HostapdAidl, AddPskAccessPointWithAcsAndInvalidFreqRange) {
277 if (!isAcsSupport) GTEST_SKIP() << "Missing ACS support";
278 auto status = hostapd->addAccessPoint(
279 getIfaceParamsWithAcsAndInvalidFreqRange(kIfaceName), getPskNwParams());
280 EXPECT_FALSE(status.isOk());
281}
282
283/**
284 * Adds an access point with Open network config & ACS enabled.
285 * Access point creation should pass.
286 */
287TEST_P(HostapdAidl, AddOpenAccessPointWithAcs) {
288 if (!isAcsSupport) GTEST_SKIP() << "Missing ACS support";
289 auto status = hostapd->addAccessPoint(getIfaceParamsWithAcs(kIfaceName),
290 getOpenNwParams());
291 EXPECT_TRUE(status.isOk());
292}
293
294/**
295 * Adds an access point with PSK network config & ACS disabled.
296 * Access point creation should pass.
297 */
298TEST_P(HostapdAidl, AddPskAccessPointWithoutAcs) {
299 auto status = hostapd->addAccessPoint(getIfaceParamsWithoutAcs(kIfaceName),
300 getPskNwParams());
301 EXPECT_TRUE(status.isOk());
302}
303
304/**
305 * Adds an access point with PSK network config, ACS disabled & Non metered.
306 * Access point creation should pass.
307 */
308TEST_P(HostapdAidl, AddPskAccessPointWithoutAcsAndNonMetered) {
309 auto status = hostapd->addAccessPoint(getIfaceParamsWithoutAcs(kIfaceName),
310 getPskNwParamsWithNonMetered());
311 EXPECT_TRUE(status.isOk());
312}
313
314/**
315 * Adds an access point with Open network config & ACS disabled.
316 * Access point creation should pass.
317 */
318TEST_P(HostapdAidl, AddOpenAccessPointWithoutAcs) {
319 auto status = hostapd->addAccessPoint(getIfaceParamsWithoutAcs(kIfaceName),
320 getOpenNwParams());
321 EXPECT_TRUE(status.isOk());
322}
323
324/**
325 * Adds an access point with SAE Transition network config & ACS disabled.
326 * Access point creation should pass.
327 */
328TEST_P(HostapdAidl, AddSaeTransitionAccessPointWithoutAcs) {
329 if (!isWpa3SaeSupport) GTEST_SKIP() << "Missing SAE support";
330 auto status = hostapd->addAccessPoint(getIfaceParamsWithoutAcs(kIfaceName),
331 getSaeTransitionNwParams());
332 EXPECT_TRUE(status.isOk());
333}
334
335/**
336 * Adds an access point with SAE network config & ACS disabled.
337 * Access point creation should pass.
338 */
339TEST_P(HostapdAidl, AddSAEAccessPointWithoutAcs) {
340 if (!isWpa3SaeSupport) GTEST_SKIP() << "Missing SAE support";
341 auto status = hostapd->addAccessPoint(getIfaceParamsWithoutAcs(kIfaceName),
342 getSaeNwParams());
343 EXPECT_TRUE(status.isOk());
344}
345
346/**
347 * Adds & then removes an access point with PSK network config & ACS enabled.
348 * Access point creation & removal should pass.
349 */
350TEST_P(HostapdAidl, RemoveAccessPointWithAcs) {
351 if (!isAcsSupport) GTEST_SKIP() << "Missing ACS support";
352 auto status = hostapd->addAccessPoint(getIfaceParamsWithAcs(kIfaceName),
353 getPskNwParams());
354 EXPECT_TRUE(status.isOk());
355 EXPECT_TRUE(hostapd->removeAccessPoint(kIfaceName).isOk());
356}
357
358/**
359 * Adds & then removes an access point with PSK network config & ACS disabled.
360 * Access point creation & removal should pass.
361 */
362TEST_P(HostapdAidl, RemoveAccessPointWithoutAcs) {
363 auto status = hostapd->addAccessPoint(getIfaceParamsWithoutAcs(kIfaceName),
364 getPskNwParams());
365 EXPECT_TRUE(status.isOk());
366 EXPECT_TRUE(hostapd->removeAccessPoint(kIfaceName).isOk());
367}
368
369/**
370 * Adds an access point with invalid channel.
371 * Access point creation should fail.
372 */
373TEST_P(HostapdAidl, AddPskAccessPointWithInvalidChannel) {
374 auto status = hostapd->addAccessPoint(
375 getIfaceParamsWithInvalidChannel(kIfaceName), getPskNwParams());
376 EXPECT_FALSE(status.isOk());
377}
378
379/**
380 * Adds an access point with invalid PSK network config.
381 * Access point creation should fail.
382 */
383TEST_P(HostapdAidl, AddInvalidPskAccessPointWithoutAcs) {
384 auto status = hostapd->addAccessPoint(getIfaceParamsWithoutAcs(kIfaceName),
385 getInvalidPskNwParams());
386 EXPECT_FALSE(status.isOk());
387}
388
389/**
390 * Adds an access point with invalid SAE transition network config.
391 * Access point creation should fail.
392 */
393TEST_P(HostapdAidl, AddInvalidSaeTransitionAccessPointWithoutAcs) {
394 if (!isWpa3SaeSupport) GTEST_SKIP() << "Missing SAE support";
395 auto status = hostapd->addAccessPoint(getIfaceParamsWithoutAcs(kIfaceName),
396 getInvalidSaeTransitionNwParams());
397 EXPECT_FALSE(status.isOk());
398}
399
400/**
401 * Adds an access point with invalid SAE network config.
402 * Access point creation should fail.
403 */
404TEST_P(HostapdAidl, AddInvalidSaeAccessPointWithoutAcs) {
405 if (!isWpa3SaeSupport) GTEST_SKIP() << "Missing SAE support";
406 auto status = hostapd->addAccessPoint(getIfaceParamsWithoutAcs(kIfaceName),
407 getInvalidSaeNwParams());
408 EXPECT_FALSE(status.isOk());
409}
410
411/**
412 * forceClientDisconnect should fail when hotspot interface available.
413 */
414TEST_P(HostapdAidl, DisconnectClientWhenIfacAvailable) {
415 auto status = hostapd->addAccessPoint(getIfaceParamsWithoutAcs(kIfaceName),
416 getOpenNwParams());
417 EXPECT_TRUE(status.isOk());
418
419 status = hostapd->forceClientDisconnect(kIfaceName, kTestZeroMacAddr,
420 kTestDisconnectReasonCode);
421 EXPECT_FALSE(status.isOk());
422}
423
424/**
425 * AddAccessPointWithDualBandConfig should pass
426 */
427TEST_P(HostapdAidl, AddAccessPointWithDualBandConfig) {
428 if (!isBridgedSupport) GTEST_SKIP() << "Missing Bridged AP support";
429 auto status = hostapd->addAccessPoint(
430 getIfaceParamsWithBridgedModeACS(kIfaceName), getOpenNwParams());
431 EXPECT_TRUE(status.isOk());
432}
433
434INSTANTIATE_TEST_SUITE_P(
435 Hostapd, HostapdAidl,
436 testing::ValuesIn(android::getAidlHalInstanceNames(IHostapd::descriptor)),
437 android::PrintInstanceNameToString);
438
439int main(int argc, char **argv) {
440 ::testing::InitGoogleTest(&argc, argv);
441 ProcessState::self()->setThreadPoolMaxThreadCount(1);
442 ProcessState::self()->startThreadPool();
443 return RUN_ALL_TESTS();
444}