/* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Staache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include #include #include "wifi_hidl_call_util.h" #include "wifi_hidl_test_utils.h" using ::android::sp; using ::android::hardware::wifi::V1_0::Bssid; using ::android::hardware::wifi::V1_0::CommandId; using ::android::hardware::wifi::V1_0::IfaceType; using ::android::hardware::wifi::V1_0::IWifi; using ::android::hardware::wifi::V1_0::IWifiStaIface; using ::android::hardware::wifi::V1_0::Rssi; using ::android::hardware::wifi::V1_0::Ssid; using ::android::hardware::wifi::V1_0::StaApfPacketFilterCapabilities; using ::android::hardware::wifi::V1_0::StaRoamingConfig; using ::android::hardware::wifi::V1_0::StaRoamingState; using ::android::hardware::wifi::V1_0::WifiBand; using ::android::hardware::wifi::V1_0::WifiStatus; using ::android::hardware::wifi::V1_0::WifiStatusCode; /** * Fixture to use for all STA Iface HIDL interface tests. */ class WifiStaIfaceHidlTest : public ::testing::TestWithParam { public: virtual void SetUp() override { // Make sure test starts with a clean state stopWifi(GetInstanceName()); wifi_sta_iface_ = getWifiStaIface(GetInstanceName()); ASSERT_NE(nullptr, wifi_sta_iface_.get()); } virtual void TearDown() override { stopWifi(GetInstanceName()); } protected: bool isCapabilitySupported(IWifiStaIface::StaIfaceCapabilityMask cap_mask) { const auto& status_and_caps = HIDL_INVOKE(wifi_sta_iface_, getCapabilities); EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_caps.first.code); return (status_and_caps.second & cap_mask) != 0; } sp wifi_sta_iface_; std::string GetInstanceName() { return GetParam(); } }; /* * Create: * Ensures that an instance of the IWifiStaIface proxy object is * successfully created. */ TEST_P(WifiStaIfaceHidlTest, Create) { // The creation of a proxy object is tested as part of SetUp method. } /* * GetCapabilities: */ TEST_P(WifiStaIfaceHidlTest, GetCapabilities) { const auto& status_and_caps = HIDL_INVOKE(wifi_sta_iface_, getCapabilities); EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_caps.first.code); EXPECT_GT(status_and_caps.second, 0u); } /* * GetType: * Ensures that the correct interface type is returned for station interface. */ TEST_P(WifiStaIfaceHidlTest, GetType) { const auto& status_and_type = HIDL_INVOKE(wifi_sta_iface_, getType); EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_type.first.code); EXPECT_EQ(IfaceType::STA, status_and_type.second); } /* * GetApfPacketFilterCapabilities: * Ensures that we can retrieve APF packet filter capabilites. */ TEST_P(WifiStaIfaceHidlTest, GetApfPacketFilterCapabilities) { if (!isCapabilitySupported(IWifiStaIface::StaIfaceCapabilityMask::APF)) { // No-op if APF packet filer is not supported. return; } const auto& status_and_caps = HIDL_INVOKE(wifi_sta_iface_, getApfPacketFilterCapabilities); EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_caps.first.code); } /* * GetBackgroundScanCapabilities: * Ensures that we can retrieve background scan capabilities. */ TEST_P(WifiStaIfaceHidlTest, GetBackgroundScanCapabilities) { if (!isCapabilitySupported( IWifiStaIface::StaIfaceCapabilityMask::BACKGROUND_SCAN)) { // No-op if background scan is not supported. return; } const auto& status_and_caps = HIDL_INVOKE(wifi_sta_iface_, getBackgroundScanCapabilities); EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_caps.first.code); } /* * GetValidFrequenciesForBand: * Ensures that we can retrieve valid frequencies for 2.4 GHz band. */ TEST_P(WifiStaIfaceHidlTest, GetValidFrequenciesForBand) { const auto& status_and_freqs = HIDL_INVOKE( wifi_sta_iface_, getValidFrequenciesForBand, WifiBand::BAND_24GHZ); EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_freqs.first.code); EXPECT_GT(status_and_freqs.second.size(), 0u); } /* * LinkLayerStatsCollection: * Ensures that calls to enable, disable, and retrieve link layer stats * will return a success status code. */ TEST_P(WifiStaIfaceHidlTest, LinkLayerStatsCollection) { if (!isCapabilitySupported( IWifiStaIface::StaIfaceCapabilityMask::LINK_LAYER_STATS)) { // No-op if link layer stats is not supported. return; } sp<::android::hardware::wifi::V1_3::IWifiStaIface> iface_converted = ::android::hardware::wifi::V1_3::IWifiStaIface::castFrom( wifi_sta_iface_); if (iface_converted != nullptr) { // Skip this test since this API is deprecated in this newer HAL version return; } // Enable link layer stats collection. EXPECT_EQ(WifiStatusCode::SUCCESS, HIDL_INVOKE(wifi_sta_iface_, enableLinkLayerStatsCollection, true) .code); // Retrieve link layer stats. EXPECT_EQ(WifiStatusCode::SUCCESS, HIDL_INVOKE(wifi_sta_iface_, getLinkLayerStats).first.code); // Disable link layer stats collection. EXPECT_EQ( WifiStatusCode::SUCCESS, HIDL_INVOKE(wifi_sta_iface_, disableLinkLayerStatsCollection).code); } /* * RSSIMonitoring: * Ensures that calls to enable RSSI monitoring will return an error status * code if device is not connected to an AP. * Ensures that calls to disable RSSI monitoring will return an error status * code if RSSI monitoring is not enabled. */ TEST_P(WifiStaIfaceHidlTest, RSSIMonitoring) { if (!isCapabilitySupported( IWifiStaIface::StaIfaceCapabilityMask::RSSI_MONITOR)) { // No-op if RSSI monitor is not supported. return; } const CommandId kCmd = 1; const Rssi kMaxRssi = -50; const Rssi kMinRssi = -90; // This is going to fail because device is not connected to an AP. EXPECT_NE(WifiStatusCode::SUCCESS, HIDL_INVOKE(wifi_sta_iface_, startRssiMonitoring, kCmd, kMaxRssi, kMinRssi) .code); // This is going to fail because RSSI monitoring is not enabled. EXPECT_NE(WifiStatusCode::SUCCESS, HIDL_INVOKE(wifi_sta_iface_, stopRssiMonitoring, kCmd).code); } /* * RoamingControl: * Ensures that calls to configure and enable roaming will return a success * status code. */ TEST_P(WifiStaIfaceHidlTest, RoamingControl) { if (!isCapabilitySupported( IWifiStaIface::StaIfaceCapabilityMask::CONTROL_ROAMING)) { // No-op if roaming control is not supported. return; } // Retrieve roaming capabilities. const auto& status_and_cap = HIDL_INVOKE(wifi_sta_iface_, getRoamingCapabilities); EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_cap.first.code); // Setup roaming configuration based on roaming capabilities. const auto& cap = status_and_cap.second; StaRoamingConfig roaming_config; if (cap.maxBlacklistSize > 0) { Bssid black_list_bssid{ std::array{{0x11, 0x22, 0x33, 0x44, 0x55, 0x66}}}; roaming_config.bssidBlacklist = android::hardware::hidl_vec{black_list_bssid}; } if (cap.maxWhitelistSize > 0) { Ssid white_list_ssid{ std::array{{0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC}}}; roaming_config.ssidWhitelist = android::hardware::hidl_vec{white_list_ssid}; } // Configure roaming. EXPECT_EQ( WifiStatusCode::SUCCESS, HIDL_INVOKE(wifi_sta_iface_, configureRoaming, roaming_config).code); // Enable roaming. EXPECT_EQ( WifiStatusCode::SUCCESS, HIDL_INVOKE(wifi_sta_iface_, setRoamingState, StaRoamingState::ENABLED) .code); } /* * EnableNDOffload: * Ensures that calls to enable neighbor discovery offload will return a success * status code. */ TEST_P(WifiStaIfaceHidlTest, EnableNDOffload) { if (!isCapabilitySupported( IWifiStaIface::StaIfaceCapabilityMask::ND_OFFLOAD)) { // No-op if nd offload is not supported. return; } EXPECT_EQ(WifiStatusCode::SUCCESS, HIDL_INVOKE(wifi_sta_iface_, enableNdOffload, true).code); } /* * SetScanningMacOui: * Ensures that calls to set scanning MAC OUI will return a NOT_SUPPORTED * code since it is now deprecated. */ TEST_P(WifiStaIfaceHidlTest, SetScanningMacOui) { if (!isCapabilitySupported( IWifiStaIface::StaIfaceCapabilityMask::SCAN_RAND)) { // No-op if SetScanningMacOui is not supported. return; } const android::hardware::hidl_array kOui{ std::array{{0x10, 0x22, 0x33}}}; EXPECT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, HIDL_INVOKE(wifi_sta_iface_, setScanningMacOui, kOui).code); } /* * PacketFateMonitoring: * Ensures that calls to start packet fate monitoring and retrieve TX/RX * packets will return a success status code. */ TEST_P(WifiStaIfaceHidlTest, PacketFateMonitoring) { if (!isCapabilitySupported( IWifiStaIface::StaIfaceCapabilityMask::DEBUG_PACKET_FATE)) { // No-op if packet fate monitor is not supported. return; } // Start packet fate monitoring. EXPECT_EQ( WifiStatusCode::SUCCESS, HIDL_INVOKE(wifi_sta_iface_, startDebugPacketFateMonitoring).code); // Retrieve packets. EXPECT_EQ(WifiStatusCode::SUCCESS, HIDL_INVOKE(wifi_sta_iface_, getDebugTxPacketFates).first.code); EXPECT_EQ(WifiStatusCode::SUCCESS, HIDL_INVOKE(wifi_sta_iface_, getDebugRxPacketFates).first.code); } GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiStaIfaceHidlTest); INSTANTIATE_TEST_SUITE_P( PerInstance, WifiStaIfaceHidlTest, testing::ValuesIn( android::hardware::getAllHalInstanceNames(IWifi::descriptor)), android::hardware::PrintInstanceNameToString);