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. 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. 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: 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 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 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 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 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 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 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 176 sp<ISupplicant> getSupplicant() { 177 return ::testing::VtsHalHidlTargetTestBase::getService<ISupplicant>(); 178 } 179 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 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 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 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