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