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. 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. 68 void deInitilializeDriverAndFirmware() { stopWifi(); } 69 70 // Helper function to find any iface of the desired type exposed. 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 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 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: 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 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 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 157 void stopSupplicant() { 158 SupplicantManager supplicant_manager; 159 160 ASSERT_TRUE(supplicant_manager.StopSupplicant()); 161 deInitilializeDriverAndFirmware(); 162 ASSERT_FALSE(supplicant_manager.IsSupplicantRunning()); 163 } 164 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 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 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 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 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 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 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 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 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