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 <VtsHalHidlTargetTestBase.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_hal/driver_tool.h>
25 #include <wifi_system/interface_tool.h>
26 #include <wifi_system/supplicant_manager.h>
27 
28 #include "supplicant_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::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::ISupplicantStaIface;
41 using ::android::hardware::wifi::supplicant::V1_0::ISupplicantStaNetwork;
42 using ::android::hardware::wifi::supplicant::V1_0::ISupplicantP2pIface;
43 using ::android::hardware::wifi::supplicant::V1_0::IfaceType;
44 using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatus;
45 using ::android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode;
46 using ::android::hidl::manager::V1_0::IServiceNotification;
47 using ::android::wifi_hal::DriverTool;
48 using ::android::wifi_system::InterfaceTool;
49 using ::android::wifi_system::SupplicantManager;
50 
51 namespace {
52 const char kSupplicantServiceName[] = "default";
53 
54 // Helper function to initialize the driver and firmware to STA mode.
initilializeDriverAndFirmware()55 void initilializeDriverAndFirmware() {
56     DriverTool driver_tool;
57     InterfaceTool iface_tool;
58     EXPECT_TRUE(driver_tool.LoadDriver());
59     EXPECT_TRUE(driver_tool.ChangeFirmwareMode(DriverTool::kFirmwareModeSta));
60     EXPECT_TRUE(iface_tool.SetWifiUpState(true));
61 }
62 
63 // Helper function to find any iface of the desired type exposed.
findIfaceOfType(sp<ISupplicant> supplicant,IfaceType desired_type,ISupplicant::IfaceInfo * out_info)64 bool findIfaceOfType(sp<ISupplicant> supplicant, IfaceType desired_type,
65                      ISupplicant::IfaceInfo* out_info) {
66     bool operation_failed = false;
67     std::vector<ISupplicant::IfaceInfo> iface_infos;
68     supplicant->listInterfaces([&](const SupplicantStatus& status,
69                                    hidl_vec<ISupplicant::IfaceInfo> infos) {
70         if (status.code != SupplicantStatusCode::SUCCESS) {
71             operation_failed = true;
72             return;
73         }
74         iface_infos = infos;
75     });
76     if (operation_failed) {
77         return false;
78     }
79     for (const auto& info : iface_infos) {
80         if (info.type == desired_type) {
81             *out_info = info;
82             return true;
83         }
84     }
85     return false;
86 }
87 }  // namespace
88 
89 // Utility class to wait for wpa_supplicant's HIDL service registration.
90 class ServiceNotificationListener : public IServiceNotification {
91    public:
onRegistration(const hidl_string & fully_qualified_name,const hidl_string & instance_name,bool pre_existing)92     Return<void> onRegistration(const hidl_string& fully_qualified_name,
93                                 const hidl_string& instance_name,
94                                 bool pre_existing) override {
95         if (pre_existing) {
96             return Void();
97         }
98         std::unique_lock<std::mutex> lock(mutex_);
99         registered_.push_back(std::string(fully_qualified_name.c_str()) + "/" +
100                               instance_name.c_str());
101         lock.unlock();
102         condition_.notify_one();
103         return Void();
104     }
105 
registerForHidlServiceNotifications(const std::string & instance_name)106     bool registerForHidlServiceNotifications(const std::string& instance_name) {
107         if (!ISupplicant::registerForNotifications(instance_name, this)) {
108             return false;
109         }
110         configureRpcThreadpool(2, false);
111         return true;
112     }
113 
waitForHidlService(uint32_t timeout_in_millis,const std::string & instance_name)114     bool waitForHidlService(uint32_t timeout_in_millis,
115                             const std::string& instance_name) {
116         std::unique_lock<std::mutex> lock(mutex_);
117         condition_.wait_for(lock, std::chrono::milliseconds(timeout_in_millis),
118                             [&]() { return registered_.size() >= 1; });
119         if (registered_.size() != 1) {
120             return false;
121         }
122         std::string exptected_registered =
123             std::string(ISupplicant::descriptor) + "/" + instance_name;
124         if (registered_[0] != exptected_registered) {
125             LOG(ERROR) << "Expected: " << exptected_registered
126                        << ", Got: " << registered_[0];
127             return false;
128         }
129         return true;
130     }
131 
132    private:
133     std::vector<std::string> registered_{};
134     std::mutex mutex_;
135     std::condition_variable condition_;
136 };
137 
stopWifiFramework()138 void stopWifiFramework() {
139     ASSERT_EQ(std::system("stop"), 0);
140     // TODO: Use some other mechanism to wait for the framework to
141     // finish disabling.
142     sleep(5);
143 }
144 
startWifiFramework()145 void startWifiFramework() {
146     ASSERT_EQ(std::system("start"), 0);
147     // These tests don't care whether the framework
148     // finished enabling or not.
149 }
150 
stopSupplicant()151 void stopSupplicant() {
152     DriverTool driver_tool;
153     SupplicantManager supplicant_manager;
154 
155     ASSERT_TRUE(supplicant_manager.StopSupplicant());
156     ASSERT_TRUE(driver_tool.UnloadDriver());
157     ASSERT_FALSE(supplicant_manager.IsSupplicantRunning());
158 }
159 
startSupplicantAndWaitForHidlService()160 void startSupplicantAndWaitForHidlService() {
161     initilializeDriverAndFirmware();
162 
163     android::sp<ServiceNotificationListener> notification_listener =
164         new ServiceNotificationListener();
165     ASSERT_TRUE(notification_listener->registerForHidlServiceNotifications(
166         kSupplicantServiceName));
167 
168     SupplicantManager supplicant_manager;
169     ASSERT_TRUE(supplicant_manager.StartSupplicant());
170     ASSERT_TRUE(supplicant_manager.IsSupplicantRunning());
171 
172     ASSERT_TRUE(
173         notification_listener->waitForHidlService(200, kSupplicantServiceName));
174 }
175 
getSupplicant()176 sp<ISupplicant> getSupplicant() {
177     return ::testing::VtsHalHidlTargetTestBase::getService<ISupplicant>();
178 }
179 
getSupplicantStaIface()180 sp<ISupplicantStaIface> getSupplicantStaIface() {
181     sp<ISupplicant> supplicant = getSupplicant();
182     if (!supplicant.get()) {
183         return nullptr;
184     }
185     ISupplicant::IfaceInfo info;
186     if (!findIfaceOfType(supplicant, IfaceType::STA, &info)) {
187         return nullptr;
188     }
189     bool operation_failed = false;
190     sp<ISupplicantStaIface> sta_iface;
191     supplicant->getInterface(info, [&](const SupplicantStatus& status,
192                                        const sp<ISupplicantIface>& iface) {
193         if (status.code != SupplicantStatusCode::SUCCESS) {
194             operation_failed = true;
195             return;
196         }
197         sta_iface = ISupplicantStaIface::castFrom(iface);
198     });
199     if (operation_failed) {
200         return nullptr;
201     }
202     return sta_iface;
203 }
204 
createSupplicantStaNetwork()205 sp<ISupplicantStaNetwork> createSupplicantStaNetwork() {
206     sp<ISupplicantStaIface> sta_iface = getSupplicantStaIface();
207     if (!sta_iface.get()) {
208         return nullptr;
209     }
210     bool operation_failed = false;
211     sp<ISupplicantStaNetwork> sta_network;
212     sta_iface->addNetwork([&](const SupplicantStatus& status,
213                               const sp<ISupplicantNetwork>& network) {
214         if (status.code != SupplicantStatusCode::SUCCESS) {
215             operation_failed = true;
216             return;
217         }
218         sta_network = ISupplicantStaNetwork::castFrom(network);
219     });
220     if (operation_failed) {
221         return nullptr;
222     }
223     return sta_network;
224 }
225 
getSupplicantP2pIface()226 sp<ISupplicantP2pIface> getSupplicantP2pIface() {
227     sp<ISupplicant> supplicant = getSupplicant();
228     if (!supplicant.get()) {
229         return nullptr;
230     }
231     ISupplicant::IfaceInfo info;
232     if (!findIfaceOfType(supplicant, IfaceType::P2P, &info)) {
233         return nullptr;
234     }
235     bool operation_failed = false;
236     sp<ISupplicantP2pIface> p2p_iface;
237     supplicant->getInterface(info, [&](const SupplicantStatus& status,
238                                        const sp<ISupplicantIface>& iface) {
239         if (status.code != SupplicantStatusCode::SUCCESS) {
240             operation_failed = true;
241             return;
242         }
243         p2p_iface = ISupplicantP2pIface::castFrom(iface);
244     });
245     if (operation_failed) {
246         return nullptr;
247     }
248     return p2p_iface;
249 }
250 
turnOnExcessiveLogging()251 bool turnOnExcessiveLogging() {
252     sp<ISupplicant> supplicant = getSupplicant();
253     if (!supplicant.get()) {
254         return false;
255     }
256     bool operation_failed = false;
257     supplicant->setDebugParams(
258         ISupplicant::DebugLevel::EXCESSIVE,
259         true,  // show timestamps
260         true,  // show keys
261         [&](const SupplicantStatus& status) {
262             if (status.code != SupplicantStatusCode::SUCCESS) {
263                 operation_failed = true;
264             }
265         });
266     return !operation_failed;
267 }
268