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 <android/hidl/manager/1.0/IServiceNotification.h>
22 #include <hidl/HidlTransportSupport.h>
23 
24 #include <wifi_system/interface_tool.h>
25 #include <wifi_system/supplicant_manager.h>
26 
27 #include "supplicant_hidl_test_utils.h"
28 #include "wifi_hidl_test_utils.h"
29 
30 using ::android::sp;
31 using ::android::hardware::configureRpcThreadpool;
32 using ::android::hardware::joinRpcThreadpool;
33 using ::android::hardware::hidl_string;
34 using ::android::hardware::hidl_vec;
35 using ::android::hardware::Return;
36 using ::android::hardware::Void;
37 using ::android::hardware::wifi::V1_0::ChipModeId;
38 using ::android::hardware::wifi::V1_0::IWifiChip;
39 using ::android::hardware::wifi::supplicant::V1_0::ISupplicant;
40 using ::android::hardware::wifi::supplicant::V1_0::ISupplicantIface;
41 using ::android::hardware::wifi::supplicant::V1_0::ISupplicantNetwork;
42 using ::android::hardware::wifi::supplicant::V1_0::ISupplicantStaIface;
43 using ::android::hardware::wifi::supplicant::V1_0::ISupplicantStaNetwork;
44 using ::android::hardware::wifi::supplicant::V1_0::ISupplicantP2pIface;
45 using ::android::hardware::wifi::supplicant::V1_0::IfaceType;
46 using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatus;
47 using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode;
48 using ::android::hidl::manager::V1_0::IServiceNotification;
49 using ::android::wifi_system::InterfaceTool;
50 using ::android::wifi_system::SupplicantManager;
51 
52 namespace {
53 
54 // Helper function to initialize the driver and firmware to STA mode
55 // using the vendor HAL HIDL interface.
initilializeDriverAndFirmware(const std::string & wifi_instance_name)56 void initilializeDriverAndFirmware(const std::string& wifi_instance_name) {
57     // Skip if wifi instance is not set.
58     if (wifi_instance_name == "") {
59         return;
60     }
61 
62     sp<IWifiChip> wifi_chip = getWifiChip(wifi_instance_name);
63     ChipModeId mode_id;
64     EXPECT_TRUE(configureChipToSupportIfaceType(
65         wifi_chip, ::android::hardware::wifi::V1_0::IfaceType::STA, &mode_id));
66 }
67 
68 // Helper function to deinitialize the driver and firmware
69 // using the vendor HAL HIDL interface.
deInitilializeDriverAndFirmware(const std::string & wifi_instance_name)70 void deInitilializeDriverAndFirmware(const std::string& wifi_instance_name) {
71     // Skip if wifi instance is not set.
72     if (wifi_instance_name == "") {
73         return;
74     }
75 
76     stopWifi(wifi_instance_name);
77 }
78 
79 // Helper function to find any iface of the desired type exposed.
findIfaceOfType(sp<ISupplicant> supplicant,IfaceType desired_type,ISupplicant::IfaceInfo * out_info)80 bool findIfaceOfType(sp<ISupplicant> supplicant, IfaceType desired_type,
81                      ISupplicant::IfaceInfo* out_info) {
82     bool operation_failed = false;
83     std::vector<ISupplicant::IfaceInfo> iface_infos;
84     supplicant->listInterfaces([&](const SupplicantStatus& status,
85                                    hidl_vec<ISupplicant::IfaceInfo> infos) {
86         if (status.code != SupplicantStatusCode::SUCCESS) {
87             operation_failed = true;
88             return;
89         }
90         iface_infos = infos;
91     });
92     if (operation_failed) {
93         return false;
94     }
95     for (const auto& info : iface_infos) {
96         if (info.type == desired_type) {
97             *out_info = info;
98             return true;
99         }
100     }
101     return false;
102 }
103 
getStaIfaceName()104 std::string getStaIfaceName() {
105     std::array<char, PROPERTY_VALUE_MAX> buffer;
106     property_get("wifi.interface", buffer.data(), "wlan0");
107     return buffer.data();
108 }
109 
getP2pIfaceName()110 std::string getP2pIfaceName() {
111     std::array<char, PROPERTY_VALUE_MAX> buffer;
112     property_get("wifi.direct.interface", buffer.data(), "p2p0");
113     return buffer.data();
114 }
115 }  // namespace
116 
117 // Utility class to wait for wpa_supplicant's HIDL service registration.
118 class ServiceNotificationListener : public IServiceNotification {
119    public:
onRegistration(const hidl_string & fully_qualified_name,const hidl_string & instance_name,bool pre_existing)120     Return<void> onRegistration(const hidl_string& fully_qualified_name,
121                                 const hidl_string& instance_name,
122                                 bool pre_existing) override {
123         if (pre_existing) {
124             return Void();
125         }
126         std::unique_lock<std::mutex> lock(mutex_);
127         registered_.push_back(std::string(fully_qualified_name.c_str()) + "/" +
128                               instance_name.c_str());
129         lock.unlock();
130         condition_.notify_one();
131         return Void();
132     }
133 
registerForHidlServiceNotifications(const std::string & instance_name)134     bool registerForHidlServiceNotifications(const std::string& instance_name) {
135         if (!ISupplicant::registerForNotifications(instance_name, this)) {
136             return false;
137         }
138         configureRpcThreadpool(2, false);
139         return true;
140     }
141 
waitForHidlService(uint32_t timeout_in_millis,const std::string & instance_name)142     bool waitForHidlService(uint32_t timeout_in_millis,
143                             const std::string& instance_name) {
144         std::unique_lock<std::mutex> lock(mutex_);
145         condition_.wait_for(lock, std::chrono::milliseconds(timeout_in_millis),
146                             [&]() { return registered_.size() >= 1; });
147         if (registered_.size() != 1) {
148             return false;
149         }
150         std::string exptected_registered =
151             std::string(ISupplicant::descriptor) + "/" + instance_name;
152         if (registered_[0] != exptected_registered) {
153             LOG(ERROR) << "Expected: " << exptected_registered
154                        << ", Got: " << registered_[0];
155             return false;
156         }
157         return true;
158     }
159 
160    private:
161     std::vector<std::string> registered_{};
162     std::mutex mutex_;
163     std::condition_variable condition_;
164 };
165 
stopSupplicant()166 void stopSupplicant() { stopSupplicant(""); }
167 
stopSupplicant(const std::string & wifi_instance_name)168 void stopSupplicant(const std::string& wifi_instance_name) {
169     SupplicantManager supplicant_manager;
170 
171     ASSERT_TRUE(supplicant_manager.StopSupplicant());
172     deInitilializeDriverAndFirmware(wifi_instance_name);
173     ASSERT_FALSE(supplicant_manager.IsSupplicantRunning());
174 }
175 
startSupplicantAndWaitForHidlService(const std::string & wifi_instance_name,const std::string & supplicant_instance_name)176 void startSupplicantAndWaitForHidlService(
177     const std::string& wifi_instance_name,
178     const std::string& supplicant_instance_name) {
179     initilializeDriverAndFirmware(wifi_instance_name);
180 
181     android::sp<ServiceNotificationListener> notification_listener =
182         new ServiceNotificationListener();
183     ASSERT_TRUE(notification_listener->registerForHidlServiceNotifications(
184         supplicant_instance_name));
185 
186     SupplicantManager supplicant_manager;
187     ASSERT_TRUE(supplicant_manager.StartSupplicant());
188     ASSERT_TRUE(supplicant_manager.IsSupplicantRunning());
189 
190     ASSERT_TRUE(notification_listener->waitForHidlService(
191         500, supplicant_instance_name));
192 }
193 
is_1_1(const sp<ISupplicant> & supplicant)194 bool is_1_1(const sp<ISupplicant>& supplicant) {
195     sp<::android::hardware::wifi::supplicant::V1_1::ISupplicant>
196         supplicant_1_1 =
197             ::android::hardware::wifi::supplicant::V1_1::ISupplicant::castFrom(
198                 supplicant);
199     return supplicant_1_1.get() != nullptr;
200 }
201 
addSupplicantStaIface_1_1(const sp<ISupplicant> & supplicant)202 void addSupplicantStaIface_1_1(const sp<ISupplicant>& supplicant) {
203     sp<::android::hardware::wifi::supplicant::V1_1::ISupplicant>
204         supplicant_1_1 =
205             ::android::hardware::wifi::supplicant::V1_1::ISupplicant::castFrom(
206                 supplicant);
207     ASSERT_TRUE(supplicant_1_1.get());
208     ISupplicant::IfaceInfo info = {IfaceType::STA, getStaIfaceName()};
209     supplicant_1_1->addInterface(
210         info, [&](const SupplicantStatus& status,
211                   const sp<ISupplicantIface>& /* iface */) {
212             ASSERT_TRUE(
213                 (SupplicantStatusCode::SUCCESS == status.code) ||
214                 (SupplicantStatusCode::FAILURE_IFACE_EXISTS == status.code));
215         });
216 }
217 
addSupplicantP2pIface_1_1(const sp<ISupplicant> & supplicant)218 void addSupplicantP2pIface_1_1(const sp<ISupplicant>& supplicant) {
219     sp<::android::hardware::wifi::supplicant::V1_1::ISupplicant>
220         supplicant_1_1 =
221             ::android::hardware::wifi::supplicant::V1_1::ISupplicant::castFrom(
222                 supplicant);
223     ASSERT_TRUE(supplicant_1_1.get());
224     ISupplicant::IfaceInfo info = {IfaceType::P2P, getP2pIfaceName()};
225     supplicant_1_1->addInterface(
226         info, [&](const SupplicantStatus& status,
227                   const sp<ISupplicantIface>& /* iface */) {
228             ASSERT_TRUE(
229                 (SupplicantStatusCode::SUCCESS == status.code) ||
230                 (SupplicantStatusCode::FAILURE_IFACE_EXISTS == status.code));
231         });
232 }
233 
getSupplicant(const std::string & supplicant_instance_name,bool isP2pOn)234 sp<ISupplicant> getSupplicant(const std::string& supplicant_instance_name,
235                               bool isP2pOn) {
236     sp<ISupplicant> supplicant =
237         ISupplicant::getService(supplicant_instance_name);
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 (isP2pOn) {
242             addSupplicantP2pIface_1_1(supplicant);
243         }
244     }
245     return supplicant;
246 }
247 
getSupplicantStaIface(const sp<ISupplicant> & supplicant)248 sp<ISupplicantStaIface> getSupplicantStaIface(
249     const sp<ISupplicant>& supplicant) {
250     if (!supplicant.get()) {
251         return nullptr;
252     }
253     ISupplicant::IfaceInfo info;
254     if (!findIfaceOfType(supplicant, IfaceType::STA, &info)) {
255         return nullptr;
256     }
257     bool operation_failed = false;
258     sp<ISupplicantStaIface> sta_iface;
259     supplicant->getInterface(info, [&](const SupplicantStatus& status,
260                                        const sp<ISupplicantIface>& iface) {
261         if (status.code != SupplicantStatusCode::SUCCESS) {
262             operation_failed = true;
263             return;
264         }
265         sta_iface = ISupplicantStaIface::castFrom(iface);
266     });
267     if (operation_failed) {
268         return nullptr;
269     }
270     return sta_iface;
271 }
272 
createSupplicantStaNetwork(const sp<ISupplicant> & supplicant)273 sp<ISupplicantStaNetwork> createSupplicantStaNetwork(
274     const sp<ISupplicant>& supplicant) {
275     sp<ISupplicantStaIface> sta_iface = getSupplicantStaIface(supplicant);
276     if (!sta_iface.get()) {
277         return nullptr;
278     }
279     bool operation_failed = false;
280     sp<ISupplicantStaNetwork> sta_network;
281     sta_iface->addNetwork([&](const SupplicantStatus& status,
282                               const sp<ISupplicantNetwork>& network) {
283         if (status.code != SupplicantStatusCode::SUCCESS) {
284             operation_failed = true;
285             return;
286         }
287         sta_network = ISupplicantStaNetwork::castFrom(network);
288     });
289     if (operation_failed) {
290         return nullptr;
291     }
292     return sta_network;
293 }
294 
getSupplicantP2pIface(const sp<ISupplicant> & supplicant)295 sp<ISupplicantP2pIface> getSupplicantP2pIface(
296     const sp<ISupplicant>& supplicant) {
297     if (!supplicant.get()) {
298         return nullptr;
299     }
300     ISupplicant::IfaceInfo info;
301     if (!findIfaceOfType(supplicant, IfaceType::P2P, &info)) {
302         return nullptr;
303     }
304     bool operation_failed = false;
305     sp<ISupplicantP2pIface> p2p_iface;
306     supplicant->getInterface(info, [&](const SupplicantStatus& status,
307                                        const sp<ISupplicantIface>& iface) {
308         if (status.code != SupplicantStatusCode::SUCCESS) {
309             operation_failed = true;
310             return;
311         }
312         p2p_iface = ISupplicantP2pIface::castFrom(iface);
313     });
314     if (operation_failed) {
315         return nullptr;
316     }
317     return p2p_iface;
318 }
319 
turnOnExcessiveLogging(const sp<ISupplicant> & supplicant)320 bool turnOnExcessiveLogging(const sp<ISupplicant>& supplicant) {
321     if (!supplicant.get()) {
322         return false;
323     }
324     bool operation_failed = false;
325     supplicant->setDebugParams(
326         ISupplicant::DebugLevel::EXCESSIVE,
327         true,  // show timestamps
328         true,  // show keys
329         [&](const SupplicantStatus& status) {
330             if (status.code != SupplicantStatusCode::SUCCESS) {
331                 operation_failed = true;
332             }
333         });
334     return !operation_failed;
335 }
336