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