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_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