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 <VtsHalHidlTargetTestBase.h>
18 #include <android-base/logging.h>
19 #include <cutils/properties.h>
20 
21 #include <android/hidl/manager/1.0/IServiceManager.h>
22 #include <android/hidl/manager/1.0/IServiceNotification.h>
23 #include <hidl/HidlTransportSupport.h>
24 
25 #include <wifi_system/interface_tool.h>
26 #include <wifi_system/supplicant_manager.h>
27 
28 #include "supplicant_hidl_test_utils.h"
29 #include "wifi_hidl_test_utils.h"
30 
31 using ::android::sp;
32 using ::android::hardware::configureRpcThreadpool;
33 using ::android::hardware::joinRpcThreadpool;
34 using ::android::hardware::hidl_string;
35 using ::android::hardware::hidl_vec;
36 using ::android::hardware::Return;
37 using ::android::hardware::Void;
38 using ::android::hardware::wifi::V1_0::ChipModeId;
39 using ::android::hardware::wifi::V1_0::IWifiChip;
40 using ::android::hardware::wifi::supplicant::V1_0::ISupplicant;
41 using ::android::hardware::wifi::supplicant::V1_0::ISupplicantIface;
42 using ::android::hardware::wifi::supplicant::V1_0::ISupplicantNetwork;
43 using ::android::hardware::wifi::supplicant::V1_0::ISupplicantStaIface;
44 using ::android::hardware::wifi::supplicant::V1_0::ISupplicantStaNetwork;
45 using ::android::hardware::wifi::supplicant::V1_0::ISupplicantP2pIface;
46 using ::android::hardware::wifi::supplicant::V1_0::IfaceType;
47 using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatus;
48 using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode;
49 using ::android::hidl::manager::V1_0::IServiceNotification;
50 using ::android::wifi_system::InterfaceTool;
51 using ::android::wifi_system::SupplicantManager;
52 
53 extern WifiSupplicantHidlEnvironment* gEnv;
54 
55 namespace {
56 
57 // Helper function to initialize the driver and firmware to STA mode
58 // using the vendor HAL HIDL interface.
initilializeDriverAndFirmware(const std::string & wifi_instance_name)59 void initilializeDriverAndFirmware(const std::string& wifi_instance_name) {
60     sp<IWifiChip> wifi_chip = getWifiChip(wifi_instance_name);
61     ChipModeId mode_id;
62     EXPECT_TRUE(configureChipToSupportIfaceType(
63         wifi_chip, ::android::hardware::wifi::V1_0::IfaceType::STA, &mode_id));
64 }
65 
66 // Helper function to deinitialize the driver and firmware
67 // using the vendor HAL HIDL interface.
deInitilializeDriverAndFirmware(const std::string & wifi_instance_name)68 void deInitilializeDriverAndFirmware(const std::string& wifi_instance_name) {
69     stopWifi(wifi_instance_name);
70 }
71 
72 // Helper function to find any iface of the desired type exposed.
findIfaceOfType(sp<ISupplicant> supplicant,IfaceType desired_type,ISupplicant::IfaceInfo * out_info)73 bool findIfaceOfType(sp<ISupplicant> supplicant, IfaceType desired_type,
74                      ISupplicant::IfaceInfo* out_info) {
75     bool operation_failed = false;
76     std::vector<ISupplicant::IfaceInfo> iface_infos;
77     supplicant->listInterfaces([&](const SupplicantStatus& status,
78                                    hidl_vec<ISupplicant::IfaceInfo> infos) {
79         if (status.code != SupplicantStatusCode::SUCCESS) {
80             operation_failed = true;
81             return;
82         }
83         iface_infos = infos;
84     });
85     if (operation_failed) {
86         return false;
87     }
88     for (const auto& info : iface_infos) {
89         if (info.type == desired_type) {
90             *out_info = info;
91             return true;
92         }
93     }
94     return false;
95 }
96 
getStaIfaceName()97 std::string getStaIfaceName() {
98     std::array<char, PROPERTY_VALUE_MAX> buffer;
99     property_get("wifi.interface", buffer.data(), "wlan0");
100     return buffer.data();
101 }
102 
getP2pIfaceName()103 std::string getP2pIfaceName() {
104     std::array<char, PROPERTY_VALUE_MAX> buffer;
105     property_get("wifi.direct.interface", buffer.data(), "p2p0");
106     return buffer.data();
107 }
108 }  // namespace
109 
110 // Utility class to wait for wpa_supplicant's HIDL service registration.
111 class ServiceNotificationListener : public IServiceNotification {
112    public:
onRegistration(const hidl_string & fully_qualified_name,const hidl_string & instance_name,bool pre_existing)113     Return<void> onRegistration(const hidl_string& fully_qualified_name,
114                                 const hidl_string& instance_name,
115                                 bool pre_existing) override {
116         if (pre_existing) {
117             return Void();
118         }
119         std::unique_lock<std::mutex> lock(mutex_);
120         registered_.push_back(std::string(fully_qualified_name.c_str()) + "/" +
121                               instance_name.c_str());
122         lock.unlock();
123         condition_.notify_one();
124         return Void();
125     }
126 
registerForHidlServiceNotifications(const std::string & instance_name)127     bool registerForHidlServiceNotifications(const std::string& instance_name) {
128         if (!ISupplicant::registerForNotifications(instance_name, this)) {
129             return false;
130         }
131         configureRpcThreadpool(2, false);
132         return true;
133     }
134 
waitForHidlService(uint32_t timeout_in_millis,const std::string & instance_name)135     bool waitForHidlService(uint32_t timeout_in_millis,
136                             const std::string& instance_name) {
137         std::unique_lock<std::mutex> lock(mutex_);
138         condition_.wait_for(lock, std::chrono::milliseconds(timeout_in_millis),
139                             [&]() { return registered_.size() >= 1; });
140         if (registered_.size() != 1) {
141             return false;
142         }
143         std::string exptected_registered =
144             std::string(ISupplicant::descriptor) + "/" + instance_name;
145         if (registered_[0] != exptected_registered) {
146             LOG(ERROR) << "Expected: " << exptected_registered
147                        << ", Got: " << registered_[0];
148             return false;
149         }
150         return true;
151     }
152 
153    private:
154     std::vector<std::string> registered_{};
155     std::mutex mutex_;
156     std::condition_variable condition_;
157 };
158 
stopSupplicant()159 void stopSupplicant() { stopSupplicant(""); }
160 
stopSupplicant(const std::string & wifi_instance_name)161 void stopSupplicant(const std::string& wifi_instance_name) {
162     SupplicantManager supplicant_manager;
163 
164     ASSERT_TRUE(supplicant_manager.StopSupplicant());
165     deInitilializeDriverAndFirmware(wifi_instance_name);
166     ASSERT_FALSE(supplicant_manager.IsSupplicantRunning());
167 }
168 
169 // TODO(b/143892896): Remove old APIs after all supplicant tests are updated.
startSupplicantAndWaitForHidlService()170 void startSupplicantAndWaitForHidlService() {
171     startSupplicantAndWaitForHidlService("",
172                                          gEnv->getServiceName<ISupplicant>());
173 }
174 
startSupplicantAndWaitForHidlService(const std::string & wifi_instance_name,const std::string & supplicant_instance_name)175 void startSupplicantAndWaitForHidlService(
176     const std::string& wifi_instance_name,
177     const std::string& supplicant_instance_name) {
178     initilializeDriverAndFirmware(wifi_instance_name);
179 
180     android::sp<ServiceNotificationListener> notification_listener =
181         new ServiceNotificationListener();
182     ASSERT_TRUE(notification_listener->registerForHidlServiceNotifications(
183         supplicant_instance_name));
184 
185     SupplicantManager supplicant_manager;
186     ASSERT_TRUE(supplicant_manager.StartSupplicant());
187     ASSERT_TRUE(supplicant_manager.IsSupplicantRunning());
188 
189     ASSERT_TRUE(notification_listener->waitForHidlService(
190         500, 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 
233 // TODO(b/143892896): Remove old APIs after all supplicant tests are updated.
getSupplicant()234 sp<ISupplicant> getSupplicant() {
235     sp<ISupplicant> supplicant =
236         ::testing::VtsHalHidlTargetTestBase::getService<ISupplicant>(
237             gEnv->getServiceName<ISupplicant>());
238     // For 1.1 supplicant, we need to add interfaces at initialization.
239     if (is_1_1(supplicant)) {
240         addSupplicantStaIface_1_1(supplicant);
241         if (gEnv->isP2pOn) {
242             addSupplicantP2pIface_1_1(supplicant);
243         }
244     }
245     return supplicant;
246 }
247 
getSupplicant(const std::string & supplicant_instance_name,bool isP2pOn)248 sp<ISupplicant> getSupplicant(const std::string& supplicant_instance_name,
249                               bool isP2pOn) {
250     sp<ISupplicant> supplicant =
251         ISupplicant::getService(supplicant_instance_name);
252     // For 1.1 supplicant, we need to add interfaces at initialization.
253     if (is_1_1(supplicant)) {
254         addSupplicantStaIface_1_1(supplicant);
255         if (isP2pOn) {
256             addSupplicantP2pIface_1_1(supplicant);
257         }
258     }
259     return supplicant;
260 }
261 
262 // TODO(b/143892896): Remove old APIs after all supplicant tests are updated.
getSupplicantStaIface()263 sp<ISupplicantStaIface> getSupplicantStaIface() {
264     sp<ISupplicant> supplicant = getSupplicant();
265     return getSupplicantStaIface(supplicant);
266 }
267 
getSupplicantStaIface(const sp<ISupplicant> & supplicant)268 sp<ISupplicantStaIface> getSupplicantStaIface(
269     const sp<ISupplicant>& supplicant) {
270     if (!supplicant.get()) {
271         return nullptr;
272     }
273     ISupplicant::IfaceInfo info;
274     if (!findIfaceOfType(supplicant, IfaceType::STA, &info)) {
275         return nullptr;
276     }
277     bool operation_failed = false;
278     sp<ISupplicantStaIface> sta_iface;
279     supplicant->getInterface(info, [&](const SupplicantStatus& status,
280                                        const sp<ISupplicantIface>& iface) {
281         if (status.code != SupplicantStatusCode::SUCCESS) {
282             operation_failed = true;
283             return;
284         }
285         sta_iface = ISupplicantStaIface::castFrom(iface);
286     });
287     if (operation_failed) {
288         return nullptr;
289     }
290     return sta_iface;
291 }
292 
293 // TODO(b/143892896): Remove old APIs after all supplicant tests are updated.
createSupplicantStaNetwork()294 sp<ISupplicantStaNetwork> createSupplicantStaNetwork() {
295     return createSupplicantStaNetwork(getSupplicant());
296 }
297 
createSupplicantStaNetwork(const sp<ISupplicant> & supplicant)298 sp<ISupplicantStaNetwork> createSupplicantStaNetwork(
299     const sp<ISupplicant>& supplicant) {
300     sp<ISupplicantStaIface> sta_iface = getSupplicantStaIface(supplicant);
301     if (!sta_iface.get()) {
302         return nullptr;
303     }
304     bool operation_failed = false;
305     sp<ISupplicantStaNetwork> sta_network;
306     sta_iface->addNetwork([&](const SupplicantStatus& status,
307                               const sp<ISupplicantNetwork>& network) {
308         if (status.code != SupplicantStatusCode::SUCCESS) {
309             operation_failed = true;
310             return;
311         }
312         sta_network = ISupplicantStaNetwork::castFrom(network);
313     });
314     if (operation_failed) {
315         return nullptr;
316     }
317     return sta_network;
318 }
319 
320 // TODO(b/143892896): Remove old APIs after all supplicant tests are updated.
getSupplicantP2pIface()321 sp<ISupplicantP2pIface> getSupplicantP2pIface() {
322     return getSupplicantP2pIface(getSupplicant());
323 }
324 
getSupplicantP2pIface(const sp<ISupplicant> & supplicant)325 sp<ISupplicantP2pIface> getSupplicantP2pIface(
326     const sp<ISupplicant>& supplicant) {
327     if (!supplicant.get()) {
328         return nullptr;
329     }
330     ISupplicant::IfaceInfo info;
331     if (!findIfaceOfType(supplicant, IfaceType::P2P, &info)) {
332         return nullptr;
333     }
334     bool operation_failed = false;
335     sp<ISupplicantP2pIface> p2p_iface;
336     supplicant->getInterface(info, [&](const SupplicantStatus& status,
337                                        const sp<ISupplicantIface>& iface) {
338         if (status.code != SupplicantStatusCode::SUCCESS) {
339             operation_failed = true;
340             return;
341         }
342         p2p_iface = ISupplicantP2pIface::castFrom(iface);
343     });
344     if (operation_failed) {
345         return nullptr;
346     }
347     return p2p_iface;
348 }
349 
350 // TODO(b/143892896): Remove old APIs after all supplicant tests are updated.
turnOnExcessiveLogging()351 bool turnOnExcessiveLogging() {
352     return turnOnExcessiveLogging(getSupplicant());
353 }
354 
turnOnExcessiveLogging(const sp<ISupplicant> & supplicant)355 bool turnOnExcessiveLogging(const sp<ISupplicant>& supplicant) {
356     if (!supplicant.get()) {
357         return false;
358     }
359     bool operation_failed = false;
360     supplicant->setDebugParams(
361         ISupplicant::DebugLevel::EXCESSIVE,
362         true,  // show timestamps
363         true,  // show keys
364         [&](const SupplicantStatus& status) {
365             if (status.code != SupplicantStatusCode::SUCCESS) {
366                 operation_failed = true;
367             }
368         });
369     return !operation_failed;
370 }
371