1 /*
2  * Copyright (C) 2016 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 <android-base/logging.h>
18 #include <cutils/properties.h>
19 
20 #include <android/hardware/wifi/1.0/IWifi.h>
21 #include <android/hardware/wifi/hostapd/1.0/IHostapd.h>
22 
23 #include <gtest/gtest.h>
24 #include <hidl/GtestPrinter.h>
25 #include <hidl/ServiceManagement.h>
26 
27 #include "hostapd_hidl_call_util.h"
28 #include "hostapd_hidl_test_utils.h"
29 
30 using ::android::sp;
31 using ::android::hardware::hidl_vec;
32 using ::android::hardware::wifi::hostapd::V1_0::HostapdStatus;
33 using ::android::hardware::wifi::hostapd::V1_0::HostapdStatusCode;
34 using ::android::hardware::wifi::hostapd::V1_0::IHostapd;
35 using ::android::hardware::wifi::V1_0::IWifi;
36 
37 namespace {
38 constexpr unsigned char kNwSsid[] = {'t', 'e', 's', 't', '1',
39                                      '2', '3', '4', '5'};
40 constexpr char kNwPassphrase[] = "test12345";
41 constexpr int kIfaceChannel = 6;
42 constexpr int kIfaceInvalidChannel = 567;
43 }  // namespace
44 
45 class HostapdHidlTest
46     : public ::testing::TestWithParam<std::tuple<std::string, std::string>> {
47    public:
SetUp()48     virtual void SetUp() override {
49         wifi_instance_name_ = std::get<0>(GetParam());
50         hostapd_instance_name_ = std::get<1>(GetParam());
51 
52         // Disable Wi-Fi framework to avoid interference
53         isWifiEnabled_ = isWifiFrameworkEnabled();
54         isScanAlwaysEnabled_ = isWifiScanAlwaysAvailable();
55         toggleWifiFramework(false);
56         toggleWifiScanAlwaysAvailable(false);
57 
58         stopSupplicantIfNeeded(wifi_instance_name_);
59         startHostapdAndWaitForHidlService(wifi_instance_name_,
60                                           hostapd_instance_name_);
61         hostapd_ = IHostapd::getService(hostapd_instance_name_);
62         ASSERT_NE(hostapd_.get(), nullptr);
63     }
64 
TearDown()65     virtual void TearDown() override {
66         HIDL_INVOKE_VOID_WITHOUT_ARGUMENTS(hostapd_, terminate);
67         stopHostapd(wifi_instance_name_);
68 
69         // Restore Wi-Fi framework state
70         toggleWifiFramework(isWifiEnabled_);
71         toggleWifiScanAlwaysAvailable(isScanAlwaysEnabled_);
72     }
73 
74    protected:
75      bool isWifiEnabled_ = false;
76      bool isScanAlwaysEnabled_ = false;
77 
getPrimaryWlanIfaceName()78      std::string getPrimaryWlanIfaceName() {
79         std::array<char, PROPERTY_VALUE_MAX> buffer;
80         property_get("wifi.interface", buffer.data(), "wlan0");
81         return buffer.data();
82      }
83 
getIfaceParamsWithAcs()84     IHostapd::IfaceParams getIfaceParamsWithAcs() {
85         IHostapd::IfaceParams iface_params;
86         iface_params.ifaceName = getPrimaryWlanIfaceName();
87         iface_params.hwModeParams.enable80211N = true;
88         iface_params.hwModeParams.enable80211AC = false;
89         iface_params.channelParams.enableAcs = true;
90         iface_params.channelParams.acsShouldExcludeDfs = true;
91         iface_params.channelParams.channel = 0;
92         iface_params.channelParams.band = IHostapd::Band::BAND_ANY;
93         return iface_params;
94     }
95 
getIfaceParamsWithoutAcs()96     IHostapd::IfaceParams getIfaceParamsWithoutAcs() {
97         IHostapd::IfaceParams iface_params;
98         iface_params.ifaceName = getPrimaryWlanIfaceName();
99         iface_params.hwModeParams.enable80211N = true;
100         iface_params.hwModeParams.enable80211AC = false;
101         iface_params.channelParams.enableAcs = false;
102         iface_params.channelParams.acsShouldExcludeDfs = false;
103         iface_params.channelParams.channel = kIfaceChannel;
104         iface_params.channelParams.band = IHostapd::Band::BAND_2_4_GHZ;
105         return iface_params;
106     }
107 
getIfaceParamsWithInvalidChannel()108     IHostapd::IfaceParams getIfaceParamsWithInvalidChannel() {
109         IHostapd::IfaceParams iface_params;
110         iface_params.ifaceName = getPrimaryWlanIfaceName();
111         iface_params.hwModeParams.enable80211N = true;
112         iface_params.hwModeParams.enable80211AC = false;
113         iface_params.channelParams.enableAcs = false;
114         iface_params.channelParams.acsShouldExcludeDfs = false;
115         iface_params.channelParams.channel = kIfaceInvalidChannel;
116         iface_params.channelParams.band = IHostapd::Band::BAND_2_4_GHZ;
117         return iface_params;
118     }
119 
getPskNwParams()120     IHostapd::NetworkParams getPskNwParams() {
121         IHostapd::NetworkParams nw_params;
122         nw_params.ssid =
123             std::vector<uint8_t>(kNwSsid, kNwSsid + sizeof(kNwSsid));
124         nw_params.isHidden = false;
125         nw_params.encryptionType = IHostapd::EncryptionType::WPA2;
126         nw_params.pskPassphrase = kNwPassphrase;
127         return nw_params;
128     }
129 
getInvalidPskNwParams()130     IHostapd::NetworkParams getInvalidPskNwParams() {
131         IHostapd::NetworkParams nw_params;
132         nw_params.ssid =
133             std::vector<uint8_t>(kNwSsid, kNwSsid + sizeof(kNwSsid));
134         nw_params.isHidden = false;
135         nw_params.encryptionType = IHostapd::EncryptionType::WPA2;
136         return nw_params;
137     }
138 
getOpenNwParams()139     IHostapd::NetworkParams getOpenNwParams() {
140         IHostapd::NetworkParams nw_params;
141         nw_params.ssid =
142             std::vector<uint8_t>(kNwSsid, kNwSsid + sizeof(kNwSsid));
143         nw_params.isHidden = false;
144         nw_params.encryptionType = IHostapd::EncryptionType::NONE;
145         return nw_params;
146     }
147     // IHostapd object used for all tests in this fixture.
148     sp<IHostapd> hostapd_;
149     std::string wifi_instance_name_;
150     std::string hostapd_instance_name_;
151 };
152 
153 /*
154  * Create:
155  * Ensures that an instance of the IHostapd proxy object is
156  * successfully created.
157  */
TEST_P(HostapdHidlTest,Create)158 TEST_P(HostapdHidlTest, Create) {
159     stopHostapd(wifi_instance_name_);
160     startHostapdAndWaitForHidlService(wifi_instance_name_,
161                                       hostapd_instance_name_);
162     hostapd_ = IHostapd::getService(hostapd_instance_name_);
163     EXPECT_NE(nullptr, hostapd_.get());
164 }
165 
166 /**
167  * Adds an access point with PSK network config & ACS enabled.
168  * Access point creation should pass.
169  */
TEST_P(HostapdHidlTest,AddPskAccessPointWithAcs)170 TEST_P(HostapdHidlTest, AddPskAccessPointWithAcs) {
171     if (!is_1_1(hostapd_)) {
172         auto status = HIDL_INVOKE(hostapd_, addAccessPoint,
173                                   getIfaceParamsWithAcs(), getPskNwParams());
174         // TODO: b/140172237, fix this in R
175         // EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
176     }
177 }
178 
179 /**
180  * Adds an access point with Open network config & ACS enabled.
181  * Access point creation should pass.
182  */
TEST_P(HostapdHidlTest,AddOpenAccessPointWithAcs)183 TEST_P(HostapdHidlTest, AddOpenAccessPointWithAcs) {
184     if (!is_1_1(hostapd_)) {
185         auto status = HIDL_INVOKE(hostapd_, addAccessPoint,
186                                   getIfaceParamsWithAcs(), getOpenNwParams());
187         // TODO: b/140172237, fix this in R
188         // EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
189     }
190 }
191 
192 /**
193  * Adds an access point with PSK network config & ACS disabled.
194  * Access point creation should pass.
195  */
TEST_P(HostapdHidlTest,AddPskAccessPointWithoutAcs)196 TEST_P(HostapdHidlTest, AddPskAccessPointWithoutAcs) {
197     if (!is_1_1(hostapd_)) {
198         auto status = HIDL_INVOKE(hostapd_, addAccessPoint,
199                                   getIfaceParamsWithoutAcs(), getPskNwParams());
200         EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
201     }
202 }
203 
204 /**
205  * Adds an access point with Open network config & ACS disabled.
206  * Access point creation should pass.
207  */
TEST_P(HostapdHidlTest,AddOpenAccessPointWithoutAcs)208 TEST_P(HostapdHidlTest, AddOpenAccessPointWithoutAcs) {
209     if (!is_1_1(hostapd_)) {
210         auto status =
211             HIDL_INVOKE(hostapd_, addAccessPoint, getIfaceParamsWithoutAcs(),
212                         getOpenNwParams());
213         EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
214     }
215 }
216 
217 /**
218  * Adds & then removes an access point with PSK network config & ACS enabled.
219  * Access point creation & removal should pass.
220  */
TEST_P(HostapdHidlTest,RemoveAccessPointWithAcs)221 TEST_P(HostapdHidlTest, RemoveAccessPointWithAcs) {
222     if (!is_1_1(hostapd_)) {
223         auto status = HIDL_INVOKE(hostapd_, addAccessPoint,
224                                   getIfaceParamsWithAcs(), getPskNwParams());
225         // TODO: b/140172237, fix this in R
226         /*
227         EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
228         status =
229             HIDL_INVOKE(hostapd_, removeAccessPoint, getPrimaryWlanIfaceName());
230         EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
231         */
232     }
233 }
234 
235 /**
236  * Adds & then removes an access point with PSK network config & ACS disabled.
237  * Access point creation & removal should pass.
238  */
TEST_P(HostapdHidlTest,RemoveAccessPointWithoutAcs)239 TEST_P(HostapdHidlTest, RemoveAccessPointWithoutAcs) {
240     if (!is_1_1(hostapd_)) {
241         auto status = HIDL_INVOKE(hostapd_, addAccessPoint,
242                                   getIfaceParamsWithoutAcs(), getPskNwParams());
243         EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
244         status =
245             HIDL_INVOKE(hostapd_, removeAccessPoint, getPrimaryWlanIfaceName());
246         EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
247     }
248 }
249 
250 /**
251  * Adds an access point with invalid channel.
252  * Access point creation should fail.
253  */
TEST_P(HostapdHidlTest,AddPskAccessPointWithInvalidChannel)254 TEST_P(HostapdHidlTest, AddPskAccessPointWithInvalidChannel) {
255     if (!is_1_1(hostapd_)) {
256         auto status =
257             HIDL_INVOKE(hostapd_, addAccessPoint,
258                         getIfaceParamsWithInvalidChannel(), getPskNwParams());
259         EXPECT_NE(HostapdStatusCode::SUCCESS, status.code);
260     }
261 }
262 
263 /**
264  * Adds an access point with invalid PSK network config.
265  * Access point creation should fail.
266  */
TEST_P(HostapdHidlTest,AddInvalidPskAccessPointWithoutAcs)267 TEST_P(HostapdHidlTest, AddInvalidPskAccessPointWithoutAcs) {
268     if (!is_1_1(hostapd_)) {
269         auto status =
270             HIDL_INVOKE(hostapd_, addAccessPoint, getIfaceParamsWithoutAcs(),
271                         getInvalidPskNwParams());
272         EXPECT_NE(HostapdStatusCode::SUCCESS, status.code);
273     }
274 }
275 
276 /*
277  * Terminate
278  * This terminates the service.
279  */
TEST_P(HostapdHidlTest,Terminate)280 TEST_P(HostapdHidlTest, Terminate) { hostapd_->terminate(); }
281 
282 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(HostapdHidlTest);
283 INSTANTIATE_TEST_SUITE_P(
284     PerInstance, HostapdHidlTest,
285     testing::Combine(
286         testing::ValuesIn(
287             android::hardware::getAllHalInstanceNames(IWifi::descriptor)),
288         testing::ValuesIn(
289             android::hardware::getAllHalInstanceNames(IHostapd::descriptor))),
290     android::hardware::PrintInstanceTupleNameToString<>);
291