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