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