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/hidl/manager/1.0/IServiceManager.h>
21 #include <hidl/HidlTransportSupport.h>
22
23 #include <wifi_system/interface_tool.h>
24 #include <wifi_system/supplicant_manager.h>
25
26 #include "supplicant_hidl_test_utils.h"
27 #include "wifi_hidl_test_utils.h"
28
29 using ::android::sp;
30 using ::android::hardware::configureRpcThreadpool;
31 using ::android::hardware::hidl_string;
32 using ::android::hardware::hidl_vec;
33 using ::android::hardware::joinRpcThreadpool;
34 using ::android::hardware::Return;
35 using ::android::hardware::Void;
36 using ::android::hardware::wifi::supplicant::V1_0::IfaceType;
37 using ::android::hardware::wifi::supplicant::V1_0::ISupplicant;
38 using ::android::hardware::wifi::supplicant::V1_0::ISupplicantIface;
39 using ::android::hardware::wifi::supplicant::V1_0::ISupplicantNetwork;
40 using ::android::hardware::wifi::supplicant::V1_0::ISupplicantP2pIface;
41 using ::android::hardware::wifi::supplicant::V1_0::ISupplicantStaIface;
42 using ::android::hardware::wifi::supplicant::V1_0::ISupplicantStaNetwork;
43 using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatus;
44 using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode;
45 using ::android::hardware::wifi::V1_0::ChipModeId;
46 using ::android::hardware::wifi::V1_0::IWifi;
47 using ::android::hardware::wifi::V1_0::IWifiChip;
48 using ::android::wifi_system::InterfaceTool;
49 using ::android::wifi_system::SupplicantManager;
50
51 namespace {
52
waitForWifiHalStop(const std::string & wifi_instance_name)53 bool waitForWifiHalStop(const std::string& wifi_instance_name) {
54 sp<IWifi> wifi = getWifi(wifi_instance_name);
55 int count = 50; /* wait at most 5 seconds for completion */
56 while (count-- > 0) {
57 if (wifi != nullptr && !wifi->isStarted()) {
58 return true;
59 }
60 usleep(100000);
61 wifi = getWifi(wifi_instance_name);
62 }
63 LOG(ERROR) << "Wifi HAL was not stopped";
64 return false;
65 }
66
waitForSupplicantState(bool is_running)67 bool waitForSupplicantState(bool is_running) {
68 SupplicantManager supplicant_manager;
69 int count = 50; /* wait at most 5 seconds for completion */
70 while (count-- > 0) {
71 if (supplicant_manager.IsSupplicantRunning() == is_running) {
72 return true;
73 }
74 usleep(100000);
75 }
76 LOG(ERROR) << "Supplicant not " << is_running ? "running" : "stopped";
77 return false;
78 }
79
80 // Helper function to wait for supplicant to be started by framework on wifi
81 // enable.
waitForSupplicantStart()82 bool waitForSupplicantStart() { return waitForSupplicantState(true); }
83
84 // Helper function to wait for supplicant to be stopped by framework on wifi
85 // disable.
waitForSupplicantStop()86 bool waitForSupplicantStop() { return waitForSupplicantState(false); }
87
88 // Helper function to find any iface of the desired type exposed.
findIfaceOfType(sp<ISupplicant> supplicant,IfaceType desired_type,ISupplicant::IfaceInfo * out_info)89 bool findIfaceOfType(sp<ISupplicant> supplicant, IfaceType desired_type,
90 ISupplicant::IfaceInfo* out_info) {
91 bool operation_failed = false;
92 std::vector<ISupplicant::IfaceInfo> iface_infos;
93 supplicant->listInterfaces([&](const SupplicantStatus& status,
94 hidl_vec<ISupplicant::IfaceInfo> infos) {
95 if (status.code != SupplicantStatusCode::SUCCESS) {
96 operation_failed = true;
97 return;
98 }
99 iface_infos = infos;
100 });
101 if (operation_failed) {
102 return false;
103 }
104 for (const auto& info : iface_infos) {
105 if (info.type == desired_type) {
106 *out_info = info;
107 return true;
108 }
109 }
110 return false;
111 }
112
getStaIfaceName()113 std::string getStaIfaceName() {
114 std::array<char, PROPERTY_VALUE_MAX> buffer;
115 property_get("wifi.interface", buffer.data(), "wlan0");
116 return buffer.data();
117 }
118
getP2pIfaceName()119 std::string getP2pIfaceName() {
120 std::array<char, PROPERTY_VALUE_MAX> buffer;
121 property_get("wifi.direct.interface", buffer.data(), "p2p0");
122 return buffer.data();
123 }
124 } // namespace
125
startWifiFramework()126 bool startWifiFramework() {
127 std::system("svc wifi enable");
128 std::system("cmd wifi set-scan-always-available enabled");
129 return waitForSupplicantStart(); // wait for wifi to start.
130 }
131
stopWifiFramework(const std::string & wifi_instance_name)132 bool stopWifiFramework(const std::string& wifi_instance_name) {
133 std::system("svc wifi disable");
134 std::system("cmd wifi set-scan-always-available disabled");
135 return waitForSupplicantStop() && waitForWifiHalStop(wifi_instance_name);
136 }
137
stopSupplicant()138 void stopSupplicant() { stopSupplicant(""); }
139
stopSupplicant(const std::string & wifi_instance_name)140 void stopSupplicant(const std::string& wifi_instance_name) {
141 SupplicantManager supplicant_manager;
142
143 ASSERT_TRUE(supplicant_manager.StopSupplicant());
144 deInitializeDriverAndFirmware(wifi_instance_name);
145 ASSERT_FALSE(supplicant_manager.IsSupplicantRunning());
146 }
147
148 // Helper function to initialize the driver and firmware to STA mode
149 // using the vendor HAL HIDL interface.
initializeDriverAndFirmware(const std::string & wifi_instance_name)150 void initializeDriverAndFirmware(const std::string& wifi_instance_name) {
151 // Skip if wifi instance is not set.
152 if (wifi_instance_name == "") {
153 return;
154 }
155 if (getWifi(wifi_instance_name) != nullptr) {
156 sp<IWifiChip> wifi_chip = getWifiChip(wifi_instance_name);
157 ChipModeId mode_id;
158 EXPECT_TRUE(configureChipToSupportIfaceType(
159 wifi_chip, ::android::hardware::wifi::V1_0::IfaceType::STA,
160 &mode_id));
161 } else {
162 LOG(WARNING) << __func__ << ": Vendor HAL not supported";
163 }
164 }
165
166 // Helper function to deinitialize the driver and firmware
167 // using the vendor HAL HIDL interface.
deInitializeDriverAndFirmware(const std::string & wifi_instance_name)168 void deInitializeDriverAndFirmware(const std::string& wifi_instance_name) {
169 // Skip if wifi instance is not set.
170 if (wifi_instance_name == "") {
171 return;
172 }
173 if (getWifi(wifi_instance_name) != nullptr) {
174 stopWifi(wifi_instance_name);
175 } else {
176 LOG(WARNING) << __func__ << ": Vendor HAL not supported";
177 }
178 }
179
startSupplicantAndWaitForHidlService(const std::string & wifi_instance_name,const std::string & supplicant_instance_name)180 void startSupplicantAndWaitForHidlService(
181 const std::string& wifi_instance_name,
182 const std::string& supplicant_instance_name) {
183 initializeDriverAndFirmware(wifi_instance_name);
184
185 SupplicantManager supplicant_manager;
186 ASSERT_TRUE(supplicant_manager.StartSupplicant());
187 ASSERT_TRUE(supplicant_manager.IsSupplicantRunning());
188
189 // Wait for supplicant service to come up.
190 ISupplicant::getService(supplicant_instance_name);
191 }
192
is_1_1(const sp<ISupplicant> & supplicant)193 bool is_1_1(const sp<ISupplicant>& supplicant) {
194 sp<::android::hardware::wifi::supplicant::V1_1::ISupplicant>
195 supplicant_1_1 =
196 ::android::hardware::wifi::supplicant::V1_1::ISupplicant::castFrom(
197 supplicant);
198 return supplicant_1_1.get() != nullptr;
199 }
200
addSupplicantStaIface_1_1(const sp<ISupplicant> & supplicant)201 void addSupplicantStaIface_1_1(const sp<ISupplicant>& supplicant) {
202 sp<::android::hardware::wifi::supplicant::V1_1::ISupplicant>
203 supplicant_1_1 =
204 ::android::hardware::wifi::supplicant::V1_1::ISupplicant::castFrom(
205 supplicant);
206 ASSERT_TRUE(supplicant_1_1.get());
207 ISupplicant::IfaceInfo info = {IfaceType::STA, getStaIfaceName()};
208 supplicant_1_1->addInterface(
209 info, [&](const SupplicantStatus& status,
210 const sp<ISupplicantIface>& /* iface */) {
211 ASSERT_TRUE(
212 (SupplicantStatusCode::SUCCESS == status.code) ||
213 (SupplicantStatusCode::FAILURE_IFACE_EXISTS == status.code));
214 });
215 }
216
addSupplicantP2pIface_1_1(const sp<ISupplicant> & supplicant)217 void addSupplicantP2pIface_1_1(const sp<ISupplicant>& supplicant) {
218 sp<::android::hardware::wifi::supplicant::V1_1::ISupplicant>
219 supplicant_1_1 =
220 ::android::hardware::wifi::supplicant::V1_1::ISupplicant::castFrom(
221 supplicant);
222 ASSERT_TRUE(supplicant_1_1.get());
223 ISupplicant::IfaceInfo info = {IfaceType::P2P, getP2pIfaceName()};
224 supplicant_1_1->addInterface(
225 info, [&](const SupplicantStatus& status,
226 const sp<ISupplicantIface>& /* iface */) {
227 ASSERT_TRUE(
228 (SupplicantStatusCode::SUCCESS == status.code) ||
229 (SupplicantStatusCode::FAILURE_IFACE_EXISTS == status.code));
230 });
231 }
232
getSupplicant(const std::string & supplicant_instance_name,bool isP2pOn)233 sp<ISupplicant> getSupplicant(const std::string& supplicant_instance_name,
234 bool isP2pOn) {
235 sp<ISupplicant> supplicant =
236 ISupplicant::getService(supplicant_instance_name);
237 // For 1.1 supplicant, we need to add interfaces at initialization.
238 if (is_1_1(supplicant)) {
239 addSupplicantStaIface_1_1(supplicant);
240 if (isP2pOn) {
241 addSupplicantP2pIface_1_1(supplicant);
242 }
243 }
244 return supplicant;
245 }
246
getSupplicantStaIface(const sp<ISupplicant> & supplicant)247 sp<ISupplicantStaIface> getSupplicantStaIface(
248 const sp<ISupplicant>& supplicant) {
249 if (!supplicant.get()) {
250 return nullptr;
251 }
252 ISupplicant::IfaceInfo info;
253 if (!findIfaceOfType(supplicant, IfaceType::STA, &info)) {
254 return nullptr;
255 }
256 bool operation_failed = false;
257 sp<ISupplicantStaIface> sta_iface;
258 supplicant->getInterface(info, [&](const SupplicantStatus& status,
259 const sp<ISupplicantIface>& iface) {
260 if (status.code != SupplicantStatusCode::SUCCESS) {
261 operation_failed = true;
262 return;
263 }
264 sta_iface = ISupplicantStaIface::castFrom(iface);
265 });
266 if (operation_failed) {
267 return nullptr;
268 }
269 return sta_iface;
270 }
271
createSupplicantStaNetwork(const sp<ISupplicant> & supplicant)272 sp<ISupplicantStaNetwork> createSupplicantStaNetwork(
273 const sp<ISupplicant>& supplicant) {
274 sp<ISupplicantStaIface> sta_iface = getSupplicantStaIface(supplicant);
275 if (!sta_iface.get()) {
276 return nullptr;
277 }
278 bool operation_failed = false;
279 sp<ISupplicantStaNetwork> sta_network;
280 sta_iface->addNetwork([&](const SupplicantStatus& status,
281 const sp<ISupplicantNetwork>& network) {
282 if (status.code != SupplicantStatusCode::SUCCESS) {
283 operation_failed = true;
284 return;
285 }
286 sta_network = ISupplicantStaNetwork::castFrom(network);
287 });
288 if (operation_failed) {
289 return nullptr;
290 }
291 return sta_network;
292 }
293
getSupplicantP2pIface(const sp<ISupplicant> & supplicant)294 sp<ISupplicantP2pIface> getSupplicantP2pIface(
295 const sp<ISupplicant>& supplicant) {
296 if (!supplicant.get()) {
297 return nullptr;
298 }
299 ISupplicant::IfaceInfo info;
300 if (!findIfaceOfType(supplicant, IfaceType::P2P, &info)) {
301 return nullptr;
302 }
303 bool operation_failed = false;
304 sp<ISupplicantP2pIface> p2p_iface;
305 supplicant->getInterface(info, [&](const SupplicantStatus& status,
306 const sp<ISupplicantIface>& iface) {
307 if (status.code != SupplicantStatusCode::SUCCESS) {
308 operation_failed = true;
309 return;
310 }
311 p2p_iface = ISupplicantP2pIface::castFrom(iface);
312 });
313 if (operation_failed) {
314 return nullptr;
315 }
316 return p2p_iface;
317 }
318
turnOnExcessiveLogging(const sp<ISupplicant> & supplicant)319 bool turnOnExcessiveLogging(const sp<ISupplicant>& supplicant) {
320 if (!supplicant.get()) {
321 return false;
322 }
323 bool operation_failed = false;
324 supplicant->setDebugParams(
325 ISupplicant::DebugLevel::EXCESSIVE,
326 true, // show timestamps
327 true, // show keys
328 [&](const SupplicantStatus& status) {
329 if (status.code != SupplicantStatusCode::SUCCESS) {
330 operation_failed = true;
331 }
332 });
333 return !operation_failed;
334 }
335
waitForFrameworkReady()336 bool waitForFrameworkReady() {
337 int waitCount = 15;
338 do {
339 // Check whether package service is ready or not.
340 if (!testing::checkSubstringInCommandOutput(
341 "/system/bin/service check package", ": not found")) {
342 return true;
343 }
344 LOG(INFO) << "Framework is not ready";
345 sleep(1);
346 } while (waitCount-- > 0);
347 return false;
348 }
349