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