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()59 void initilializeDriverAndFirmware() {
60 sp<IWifiChip> wifi_chip = getWifiChip();
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()68 void deInitilializeDriverAndFirmware() { stopWifi(); }
69
70 // Helper function to find any iface of the desired type exposed.
findIfaceOfType(sp<ISupplicant> supplicant,IfaceType desired_type,ISupplicant::IfaceInfo * out_info)71 bool findIfaceOfType(sp<ISupplicant> supplicant, IfaceType desired_type,
72 ISupplicant::IfaceInfo* out_info) {
73 bool operation_failed = false;
74 std::vector<ISupplicant::IfaceInfo> iface_infos;
75 supplicant->listInterfaces([&](const SupplicantStatus& status,
76 hidl_vec<ISupplicant::IfaceInfo> infos) {
77 if (status.code != SupplicantStatusCode::SUCCESS) {
78 operation_failed = true;
79 return;
80 }
81 iface_infos = infos;
82 });
83 if (operation_failed) {
84 return false;
85 }
86 for (const auto& info : iface_infos) {
87 if (info.type == desired_type) {
88 *out_info = info;
89 return true;
90 }
91 }
92 return false;
93 }
94
getStaIfaceName()95 std::string getStaIfaceName() {
96 std::array<char, PROPERTY_VALUE_MAX> buffer;
97 property_get("wifi.interface", buffer.data(), "wlan0");
98 return buffer.data();
99 }
100
getP2pIfaceName()101 std::string getP2pIfaceName() {
102 std::array<char, PROPERTY_VALUE_MAX> buffer;
103 property_get("wifi.direct.interface", buffer.data(), "p2p0");
104 return buffer.data();
105 }
106 } // namespace
107
108 // Utility class to wait for wpa_supplicant's HIDL service registration.
109 class ServiceNotificationListener : public IServiceNotification {
110 public:
onRegistration(const hidl_string & fully_qualified_name,const hidl_string & instance_name,bool pre_existing)111 Return<void> onRegistration(const hidl_string& fully_qualified_name,
112 const hidl_string& instance_name,
113 bool pre_existing) override {
114 if (pre_existing) {
115 return Void();
116 }
117 std::unique_lock<std::mutex> lock(mutex_);
118 registered_.push_back(std::string(fully_qualified_name.c_str()) + "/" +
119 instance_name.c_str());
120 lock.unlock();
121 condition_.notify_one();
122 return Void();
123 }
124
registerForHidlServiceNotifications(const std::string & instance_name)125 bool registerForHidlServiceNotifications(const std::string& instance_name) {
126 if (!ISupplicant::registerForNotifications(instance_name, this)) {
127 return false;
128 }
129 configureRpcThreadpool(2, false);
130 return true;
131 }
132
waitForHidlService(uint32_t timeout_in_millis,const std::string & instance_name)133 bool waitForHidlService(uint32_t timeout_in_millis,
134 const std::string& instance_name) {
135 std::unique_lock<std::mutex> lock(mutex_);
136 condition_.wait_for(lock, std::chrono::milliseconds(timeout_in_millis),
137 [&]() { return registered_.size() >= 1; });
138 if (registered_.size() != 1) {
139 return false;
140 }
141 std::string exptected_registered =
142 std::string(ISupplicant::descriptor) + "/" + instance_name;
143 if (registered_[0] != exptected_registered) {
144 LOG(ERROR) << "Expected: " << exptected_registered
145 << ", Got: " << registered_[0];
146 return false;
147 }
148 return true;
149 }
150
151 private:
152 std::vector<std::string> registered_{};
153 std::mutex mutex_;
154 std::condition_variable condition_;
155 };
156
stopSupplicant()157 void stopSupplicant() {
158 SupplicantManager supplicant_manager;
159
160 ASSERT_TRUE(supplicant_manager.StopSupplicant());
161 deInitilializeDriverAndFirmware();
162 ASSERT_FALSE(supplicant_manager.IsSupplicantRunning());
163 }
164
startSupplicantAndWaitForHidlService()165 void startSupplicantAndWaitForHidlService() {
166 initilializeDriverAndFirmware();
167
168 android::sp<ServiceNotificationListener> notification_listener =
169 new ServiceNotificationListener();
170 string service_name = gEnv->getServiceName<ISupplicant>();
171 ASSERT_TRUE(notification_listener->registerForHidlServiceNotifications(
172 service_name));
173
174 SupplicantManager supplicant_manager;
175 ASSERT_TRUE(supplicant_manager.StartSupplicant());
176 ASSERT_TRUE(supplicant_manager.IsSupplicantRunning());
177
178 ASSERT_TRUE(notification_listener->waitForHidlService(200, service_name));
179 }
180
is_1_1(const sp<ISupplicant> & supplicant)181 bool is_1_1(const sp<ISupplicant>& supplicant) {
182 sp<::android::hardware::wifi::supplicant::V1_1::ISupplicant>
183 supplicant_1_1 =
184 ::android::hardware::wifi::supplicant::V1_1::ISupplicant::castFrom(
185 supplicant);
186 return supplicant_1_1.get() != nullptr;
187 }
188
addSupplicantStaIface_1_1(const sp<ISupplicant> & supplicant)189 void addSupplicantStaIface_1_1(const sp<ISupplicant>& supplicant) {
190 sp<::android::hardware::wifi::supplicant::V1_1::ISupplicant>
191 supplicant_1_1 =
192 ::android::hardware::wifi::supplicant::V1_1::ISupplicant::castFrom(
193 supplicant);
194 ASSERT_TRUE(supplicant_1_1.get());
195 ISupplicant::IfaceInfo info = {IfaceType::STA, getStaIfaceName()};
196 supplicant_1_1->addInterface(
197 info, [&](const SupplicantStatus& status,
198 const sp<ISupplicantIface>& /* iface */) {
199 ASSERT_TRUE(
200 (SupplicantStatusCode::SUCCESS == status.code) ||
201 (SupplicantStatusCode::FAILURE_IFACE_EXISTS == status.code));
202 });
203 }
204
addSupplicantP2pIface_1_1(const sp<ISupplicant> & supplicant)205 void addSupplicantP2pIface_1_1(const sp<ISupplicant>& supplicant) {
206 sp<::android::hardware::wifi::supplicant::V1_1::ISupplicant>
207 supplicant_1_1 =
208 ::android::hardware::wifi::supplicant::V1_1::ISupplicant::castFrom(
209 supplicant);
210 ASSERT_TRUE(supplicant_1_1.get());
211 ISupplicant::IfaceInfo info = {IfaceType::P2P, getP2pIfaceName()};
212 supplicant_1_1->addInterface(
213 info, [&](const SupplicantStatus& status,
214 const sp<ISupplicantIface>& /* iface */) {
215 ASSERT_TRUE(
216 (SupplicantStatusCode::SUCCESS == status.code) ||
217 (SupplicantStatusCode::FAILURE_IFACE_EXISTS == status.code));
218 });
219 }
220
getSupplicant()221 sp<ISupplicant> getSupplicant() {
222 sp<ISupplicant> supplicant =
223 ::testing::VtsHalHidlTargetTestBase::getService<ISupplicant>(
224 gEnv->getServiceName<ISupplicant>());
225 // For 1.1 supplicant, we need to add interfaces at initialization.
226 if (is_1_1(supplicant)) {
227 addSupplicantStaIface_1_1(supplicant);
228 addSupplicantP2pIface_1_1(supplicant);
229 }
230 return supplicant;
231 }
232
getSupplicantStaIface()233 sp<ISupplicantStaIface> getSupplicantStaIface() {
234 sp<ISupplicant> supplicant = getSupplicant();
235 if (!supplicant.get()) {
236 return nullptr;
237 }
238 ISupplicant::IfaceInfo info;
239 if (!findIfaceOfType(supplicant, IfaceType::STA, &info)) {
240 return nullptr;
241 }
242 bool operation_failed = false;
243 sp<ISupplicantStaIface> sta_iface;
244 supplicant->getInterface(info, [&](const SupplicantStatus& status,
245 const sp<ISupplicantIface>& iface) {
246 if (status.code != SupplicantStatusCode::SUCCESS) {
247 operation_failed = true;
248 return;
249 }
250 sta_iface = ISupplicantStaIface::castFrom(iface);
251 });
252 if (operation_failed) {
253 return nullptr;
254 }
255 return sta_iface;
256 }
257
createSupplicantStaNetwork()258 sp<ISupplicantStaNetwork> createSupplicantStaNetwork() {
259 sp<ISupplicantStaIface> sta_iface = getSupplicantStaIface();
260 if (!sta_iface.get()) {
261 return nullptr;
262 }
263 bool operation_failed = false;
264 sp<ISupplicantStaNetwork> sta_network;
265 sta_iface->addNetwork([&](const SupplicantStatus& status,
266 const sp<ISupplicantNetwork>& network) {
267 if (status.code != SupplicantStatusCode::SUCCESS) {
268 operation_failed = true;
269 return;
270 }
271 sta_network = ISupplicantStaNetwork::castFrom(network);
272 });
273 if (operation_failed) {
274 return nullptr;
275 }
276 return sta_network;
277 }
278
getSupplicantP2pIface()279 sp<ISupplicantP2pIface> getSupplicantP2pIface() {
280 sp<ISupplicant> supplicant = getSupplicant();
281 if (!supplicant.get()) {
282 return nullptr;
283 }
284 ISupplicant::IfaceInfo info;
285 if (!findIfaceOfType(supplicant, IfaceType::P2P, &info)) {
286 return nullptr;
287 }
288 bool operation_failed = false;
289 sp<ISupplicantP2pIface> p2p_iface;
290 supplicant->getInterface(info, [&](const SupplicantStatus& status,
291 const sp<ISupplicantIface>& iface) {
292 if (status.code != SupplicantStatusCode::SUCCESS) {
293 operation_failed = true;
294 return;
295 }
296 p2p_iface = ISupplicantP2pIface::castFrom(iface);
297 });
298 if (operation_failed) {
299 return nullptr;
300 }
301 return p2p_iface;
302 }
303
turnOnExcessiveLogging()304 bool turnOnExcessiveLogging() {
305 sp<ISupplicant> supplicant = getSupplicant();
306 if (!supplicant.get()) {
307 return false;
308 }
309 bool operation_failed = false;
310 supplicant->setDebugParams(
311 ISupplicant::DebugLevel::EXCESSIVE,
312 true, // show timestamps
313 true, // show keys
314 [&](const SupplicantStatus& status) {
315 if (status.code != SupplicantStatusCode::SUCCESS) {
316 operation_failed = true;
317 }
318 });
319 return !operation_failed;
320 }
321