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