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 <android-base/logging.h>
18 #include <cutils/properties.h>
19 
20 #include <gtest/gtest.h>
21 #include <hidl/GtestPrinter.h>
22 #include <hidl/ServiceManagement.h>
23 
24 #include <android/hardware/wifi/1.0/IWifi.h>
25 #include <android/hardware/wifi/hostapd/1.1/IHostapd.h>
26 #include <android/hardware/wifi/hostapd/1.3/IHostapd.h>
27 
28 #include "hostapd_hidl_call_util.h"
29 #include "hostapd_hidl_test_utils.h"
30 
31 using ::android::sp;
32 using ::android::hardware::hidl_string;
33 using ::android::hardware::Return;
34 using ::android::hardware::Void;
35 using ::android::hardware::wifi::hostapd::V1_0::HostapdStatus;
36 using ::android::hardware::wifi::hostapd::V1_0::HostapdStatusCode;
37 using ::android::hardware::wifi::hostapd::V1_1::IHostapd;
38 using ::android::hardware::wifi::hostapd::V1_1::IHostapdCallback;
39 using ::android::hardware::wifi::V1_0::IWifi;
40 
41 namespace {
42 constexpr unsigned char kNwSsid[] = {'t', 'e', 's', 't', '1',
43                                      '2', '3', '4', '5'};
44 constexpr char kNwPassphrase[] = "test12345";
45 constexpr int kIfaceChannel = 6;
46 constexpr int kIfaceInvalidChannel = 567;
47 
48 }  // namespace
49 
50 class HostapdHidlTest
51     : public ::testing::TestWithParam<std::tuple<std::string, std::string>> {
52    public:
SetUp()53     virtual void SetUp() override {
54         wifi_instance_name_ = std::get<0>(GetParam());
55         hostapd_instance_name_ = std::get<1>(GetParam());
56         stopSupplicantIfNeeded(wifi_instance_name_);
57         startHostapdAndWaitForHidlService(wifi_instance_name_,
58                                           hostapd_instance_name_);
59         hostapd_ = IHostapd::getService(hostapd_instance_name_);
60         ASSERT_NE(hostapd_.get(), nullptr);
61     }
62 
TearDown()63     virtual void TearDown() override {
64         HIDL_INVOKE_VOID_WITHOUT_ARGUMENTS(hostapd_, terminate);
65         stopHostapd(wifi_instance_name_);
66     }
67 
68    protected:
getPrimaryWlanIfaceName()69     std::string getPrimaryWlanIfaceName() {
70         std::array<char, PROPERTY_VALUE_MAX> buffer;
71         auto res = property_get("ro.vendor.wifi.sap.interface",
72                                 buffer.data(), nullptr);
73         if (res > 0) return buffer.data();
74         property_get("wifi.interface", buffer.data(), "wlan0");
75         return buffer.data();
76     }
77 
getIfaceParamsWithAcs()78     IHostapd::IfaceParams getIfaceParamsWithAcs() {
79         ::android::hardware::wifi::hostapd::V1_0::IHostapd::IfaceParams
80             iface_params;
81         IHostapd::IfaceParams iface_params_1_1;
82 
83         iface_params.ifaceName = getPrimaryWlanIfaceName();
84         iface_params.hwModeParams.enable80211N = true;
85         iface_params.hwModeParams.enable80211AC = false;
86         iface_params.channelParams.enableAcs = true;
87         iface_params.channelParams.acsShouldExcludeDfs = true;
88         iface_params.channelParams.channel = 0;
89         iface_params.channelParams.band = IHostapd::Band::BAND_ANY;
90         iface_params_1_1.V1_0 = iface_params;
91         return iface_params_1_1;
92     }
93 
getIfaceParamsWithAcsAndChannelRange()94     IHostapd::IfaceParams getIfaceParamsWithAcsAndChannelRange() {
95         IHostapd::IfaceParams iface_params_1_1 = getIfaceParamsWithAcs();
96         IHostapd::ChannelParams channelParams;
97         IHostapd::AcsChannelRange acsChannelRange;
98         acsChannelRange.start = 1;
99         acsChannelRange.end = 11;
100         std::vector<IHostapd::AcsChannelRange> vec_acsChannelRange;
101         vec_acsChannelRange.push_back(acsChannelRange);
102         channelParams.acsChannelRanges = vec_acsChannelRange;
103         iface_params_1_1.channelParams = channelParams;
104         return iface_params_1_1;
105     }
106 
getIfaceParamsWithAcsAndInvalidChannelRange()107     IHostapd::IfaceParams getIfaceParamsWithAcsAndInvalidChannelRange() {
108         IHostapd::IfaceParams iface_params_1_1 =
109             getIfaceParamsWithAcsAndChannelRange();
110         iface_params_1_1.channelParams.acsChannelRanges[0].start = 222;
111         iface_params_1_1.channelParams.acsChannelRanges[0].end = 999;
112         return iface_params_1_1;
113     }
114 
getIfaceParamsWithoutAcs()115     IHostapd::IfaceParams getIfaceParamsWithoutAcs() {
116         ::android::hardware::wifi::hostapd::V1_0::IHostapd::IfaceParams
117             iface_params;
118         IHostapd::IfaceParams iface_params_1_1;
119 
120         iface_params.ifaceName = getPrimaryWlanIfaceName();
121         iface_params.hwModeParams.enable80211N = true;
122         iface_params.hwModeParams.enable80211AC = false;
123         iface_params.channelParams.enableAcs = false;
124         iface_params.channelParams.acsShouldExcludeDfs = false;
125         iface_params.channelParams.channel = kIfaceChannel;
126         iface_params.channelParams.band = IHostapd::Band::BAND_2_4_GHZ;
127         iface_params_1_1.V1_0 = iface_params;
128         return iface_params_1_1;
129     }
130 
getIfaceParamsWithInvalidChannel()131     IHostapd::IfaceParams getIfaceParamsWithInvalidChannel() {
132         IHostapd::IfaceParams iface_params_1_1 = getIfaceParamsWithoutAcs();
133         iface_params_1_1.V1_0.channelParams.channel = kIfaceInvalidChannel;
134         return iface_params_1_1;
135     }
136 
getPskNwParams()137     IHostapd::NetworkParams getPskNwParams() {
138         IHostapd::NetworkParams nw_params;
139         nw_params.ssid =
140             std::vector<uint8_t>(kNwSsid, kNwSsid + sizeof(kNwSsid));
141         nw_params.isHidden = false;
142         nw_params.encryptionType = IHostapd::EncryptionType::WPA2;
143         nw_params.pskPassphrase = kNwPassphrase;
144         return nw_params;
145     }
146 
getInvalidPskNwParams()147     IHostapd::NetworkParams getInvalidPskNwParams() {
148         IHostapd::NetworkParams nw_params;
149         nw_params.ssid =
150             std::vector<uint8_t>(kNwSsid, kNwSsid + sizeof(kNwSsid));
151         nw_params.isHidden = false;
152         nw_params.encryptionType = IHostapd::EncryptionType::WPA2;
153         return nw_params;
154     }
155 
getOpenNwParams()156     IHostapd::NetworkParams getOpenNwParams() {
157         IHostapd::NetworkParams nw_params;
158         nw_params.ssid =
159             std::vector<uint8_t>(kNwSsid, kNwSsid + sizeof(kNwSsid));
160         nw_params.isHidden = false;
161         nw_params.encryptionType = IHostapd::EncryptionType::NONE;
162         return nw_params;
163     }
164 
165     // IHostapd object used for all tests in this fixture.
166     sp<IHostapd> hostapd_;
167     std::string wifi_instance_name_;
168     std::string hostapd_instance_name_;
169 };
170 
171 class IfaceCallback : public IHostapdCallback {
onFailure(const hidl_string &)172     Return<void> onFailure(
173         const hidl_string& /* Name of the interface */) override {
174         return Void();
175     }
176 };
177 
is_1_3(const sp<IHostapd> & hostapd)178 bool is_1_3(const sp<IHostapd>& hostapd) {
179     sp<::android::hardware::wifi::hostapd::V1_3::IHostapd> hostapd_1_3 =
180         ::android::hardware::wifi::hostapd::V1_3::IHostapd::castFrom(hostapd);
181     return hostapd_1_3.get() != nullptr;
182 }
183 
184 /*
185  * RegisterCallback
186  */
TEST_P(HostapdHidlTest,registerCallback)187 TEST_P(HostapdHidlTest, registerCallback) {
188     if (is_1_3(hostapd_)) GTEST_SKIP() << "Ignore since current HIDL over 1.3";
189     hostapd_->registerCallback(
190         new IfaceCallback(), [](const HostapdStatus& status) {
191             EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
192         });
193 }
194 
195 /**
196  * Adds an access point with PSK network config & ACS enabled.
197  * Access point creation should pass.
198  */
TEST_P(HostapdHidlTest,AddPskAccessPointWithAcs)199 TEST_P(HostapdHidlTest, AddPskAccessPointWithAcs) {
200     auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_1,
201                               getIfaceParamsWithAcs(), getPskNwParams());
202     // TODO: b/140172237, fix this in R.
203     // EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
204 }
205 
206 /**
207  * Adds an access point with PSK network config, ACS enabled & channel Range.
208  * Access point creation should pass.
209  */
TEST_P(HostapdHidlTest,AddPskAccessPointWithAcsAndChannelRange)210 TEST_P(HostapdHidlTest, AddPskAccessPointWithAcsAndChannelRange) {
211     auto status =
212         HIDL_INVOKE(hostapd_, addAccessPoint_1_1,
213                     getIfaceParamsWithAcsAndChannelRange(), getPskNwParams());
214     // TODO: b/140172237, fix this in R
215     // EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
216 }
217 
218 /**
219  * Adds an access point with invalid channel range.
220  * Access point creation should fail.
221  */
TEST_P(HostapdHidlTest,AddPskAccessPointWithAcsAndInvalidChannelRange)222 TEST_P(HostapdHidlTest, AddPskAccessPointWithAcsAndInvalidChannelRange) {
223     auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_1,
224                               getIfaceParamsWithAcsAndInvalidChannelRange(),
225                               getPskNwParams());
226     // TODO: b/140172237, fix this in R
227     // EXPECT_NE(HostapdStatusCode::SUCCESS, status.code);
228 }
229 
230 /**
231  * Adds an access point with Open network config & ACS enabled.
232  * Access point creation should pass.
233  */
TEST_P(HostapdHidlTest,AddOpenAccessPointWithAcs)234 TEST_P(HostapdHidlTest, AddOpenAccessPointWithAcs) {
235     auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_1,
236                               getIfaceParamsWithAcs(), getOpenNwParams());
237     // TODO: b/140172237, fix this in R
238     // EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
239 }
240 
241 /**
242  * Adds an access point with PSK network config & ACS disabled.
243  * Access point creation should pass.
244  */
TEST_P(HostapdHidlTest,AddPskAccessPointWithoutAcs)245 TEST_P(HostapdHidlTest, AddPskAccessPointWithoutAcs) {
246     auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_1,
247                               getIfaceParamsWithoutAcs(), getPskNwParams());
248     // FAILURE_UNKNOWN is used by higher versions to indicate this API is no
249     // longer supported (replaced by an upgraded API)
250     if (status.code != HostapdStatusCode::FAILURE_UNKNOWN) {
251         EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
252     }
253 }
254 
255 /**
256  * Adds an access point with Open network config & ACS disabled.
257  * Access point creation should pass.
258  */
TEST_P(HostapdHidlTest,AddOpenAccessPointWithoutAcs)259 TEST_P(HostapdHidlTest, AddOpenAccessPointWithoutAcs) {
260     auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_1,
261                               getIfaceParamsWithoutAcs(), getOpenNwParams());
262     // FAILURE_UNKNOWN is used by higher versions to indicate this API is no
263     // longer supported (replaced by an upgraded API)
264     if (status.code != HostapdStatusCode::FAILURE_UNKNOWN) {
265         EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
266     }
267 }
268 
269 /**
270  * Adds & then removes an access point with PSK network config & ACS enabled.
271  * Access point creation & removal should pass.
272  */
TEST_P(HostapdHidlTest,RemoveAccessPointWithAcs)273 TEST_P(HostapdHidlTest, RemoveAccessPointWithAcs) {
274     auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_1,
275                               getIfaceParamsWithAcs(), getPskNwParams());
276     // TODO: b/140172237, fix this in R
277     /*
278     EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
279     status =
280         HIDL_INVOKE(hostapd_, removeAccessPoint, getPrimaryWlanIfaceName());
281     EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
282     */
283 }
284 
285 /**
286  * Adds & then removes an access point with PSK network config & ACS disabled.
287  * Access point creation & removal should pass.
288  */
TEST_P(HostapdHidlTest,RemoveAccessPointWithoutAcs)289 TEST_P(HostapdHidlTest, RemoveAccessPointWithoutAcs) {
290     auto status = HIDL_INVOKE(hostapd_, addAccessPoint_1_1,
291                               getIfaceParamsWithoutAcs(), getPskNwParams());
292     // FAILURE_UNKNOWN is used by higher versions to indicate this API is no
293     // longer supported (replaced by an upgraded API)
294     if (status.code != HostapdStatusCode::FAILURE_UNKNOWN) {
295         EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
296         status =
297             HIDL_INVOKE(hostapd_, removeAccessPoint, getPrimaryWlanIfaceName());
298         EXPECT_EQ(HostapdStatusCode::SUCCESS, status.code);
299     }
300 }
301 
302 /**
303  * Adds an access point with invalid channel.
304  * Access point creation should fail.
305  */
TEST_P(HostapdHidlTest,AddPskAccessPointWithInvalidChannel)306 TEST_P(HostapdHidlTest, AddPskAccessPointWithInvalidChannel) {
307     auto status =
308         HIDL_INVOKE(hostapd_, addAccessPoint_1_1,
309                     getIfaceParamsWithInvalidChannel(), getPskNwParams());
310     EXPECT_NE(HostapdStatusCode::SUCCESS, status.code);
311 }
312 
313 /**
314  * Adds an access point with invalid PSK network config.
315  * Access point creation should fail.
316  */
TEST_P(HostapdHidlTest,AddInvalidPskAccessPointWithoutAcs)317 TEST_P(HostapdHidlTest, AddInvalidPskAccessPointWithoutAcs) {
318     auto status =
319         HIDL_INVOKE(hostapd_, addAccessPoint_1_1, getIfaceParamsWithoutAcs(),
320                     getInvalidPskNwParams());
321     EXPECT_NE(HostapdStatusCode::SUCCESS, status.code);
322 }
323 
324 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(HostapdHidlTest);
325 INSTANTIATE_TEST_CASE_P(
326     PerInstance, HostapdHidlTest,
327     testing::Combine(
328         testing::ValuesIn(
329             android::hardware::getAllHalInstanceNames(IWifi::descriptor)),
330         testing::ValuesIn(android::hardware::getAllHalInstanceNames(
331             android::hardware::wifi::hostapd::V1_1::IHostapd::descriptor))),
332     android::hardware::PrintInstanceTupleNameToString<>);
333