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