Home | History | Annotate | Download | only in functional
      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