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