diff --git a/wifi/1.0/default/wifi_legacy_hal.cpp b/wifi/1.0/default/wifi_legacy_hal.cpp index 7390b65db9..f902e6453e 100644 --- a/wifi/1.0/default/wifi_legacy_hal.cpp +++ b/wifi/1.0/default/wifi_legacy_hal.cpp @@ -59,6 +59,8 @@ void onAsyncStopComplete(wifi_handle handle) { const auto lock = hidl_sync_util::acquireGlobalLock(); if (on_stop_complete_internal_callback) { on_stop_complete_internal_callback(handle); + // Invalidate this callback since we don't want this firing again. + on_stop_complete_internal_callback = nullptr; } } @@ -1261,7 +1263,6 @@ WifiLegacyHal::getGscanCachedResults() { void WifiLegacyHal::invalidate() { global_handle_ = nullptr; wlan_interface_handle_ = nullptr; - on_stop_complete_internal_callback = nullptr; on_driver_memory_dump_internal_callback = nullptr; on_firmware_memory_dump_internal_callback = nullptr; on_gscan_event_internal_callback = nullptr; diff --git a/wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp index 3c2ba9a5fc..465ab64b79 100644 --- a/wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp +++ b/wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp @@ -20,21 +20,123 @@ #include +#include "wifi_hidl_call_util.h" #include "wifi_hidl_test_utils.h" -using ::android::hardware::wifi::V1_0::IWifiChip; using ::android::sp; +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::wifi::V1_0::IfaceType; +using ::android::hardware::wifi::V1_0::ChipId; +using ::android::hardware::wifi::V1_0::ChipModeId; +using ::android::hardware::wifi::V1_0::WifiDebugRingBufferStatus; +using ::android::hardware::wifi::V1_0::WifiDebugRingBufferVerboseLevel; +using ::android::hardware::wifi::V1_0::WifiDebugHostWakeReasonStats; +using ::android::hardware::wifi::V1_0::WifiStatus; +using ::android::hardware::wifi::V1_0::WifiStatusCode; +using ::android::hardware::wifi::V1_0::IWifiChip; +using ::android::hardware::wifi::V1_0::IWifiApIface; +using ::android::hardware::wifi::V1_0::IWifiIface; +using ::android::hardware::wifi::V1_0::IWifiNanIface; +using ::android::hardware::wifi::V1_0::IWifiP2pIface; +using ::android::hardware::wifi::V1_0::IWifiRttController; +using ::android::hardware::wifi::V1_0::IWifiStaIface; + +namespace { +constexpr WifiDebugRingBufferVerboseLevel kDebugRingBufferVerboseLvl = + WifiDebugRingBufferVerboseLevel::VERBOSE; +constexpr uint32_t kDebugRingBufferMaxInterval = 5; +constexpr uint32_t kDebugRingBufferMaxDataSize = 1024; + +/** + * Check if any of the ring buffer capabilities are set. + */ +bool hasAnyRingBufferCapabilities(uint32_t caps) { + return (caps & + (IWifiChip::ChipCapabilityMask::DEBUG_RING_BUFFER_CONNECT_EVENT | + IWifiChip::ChipCapabilityMask::DEBUG_RING_BUFFER_POWER_EVENT | + IWifiChip::ChipCapabilityMask::DEBUG_RING_BUFFER_WAKELOCK_EVENT | + IWifiChip::ChipCapabilityMask::DEBUG_RING_BUFFER_VENDOR_DATA)); +} +} // namespace /** * Fixture to use for all Wifi chip HIDL interface tests. */ class WifiChipHidlTest : public ::testing::VtsHalHidlTargetBaseTest { public: - virtual void SetUp() override {} + virtual void SetUp() override { + wifi_chip_ = getWifiChip(); + ASSERT_NE(nullptr, wifi_chip_.get()); + } virtual void TearDown() override { stopWifi(); } protected: + // Helper function to configure the Chip in one of the supported modes. + // Most of the non-mode-configuration-related methods require chip + // to be first configured. + ChipModeId configureChipForIfaceType(IfaceType type) { + ChipModeId mode_id; + EXPECT_TRUE( + configureChipToSupportIfaceType(wifi_chip_, type, &mode_id)); + return mode_id; + } + + uint32_t configureChipForStaIfaceAndGetCapabilities() { + configureChipForIfaceType(IfaceType::STA); + const auto& status_and_caps = HIDL_INVOKE(wifi_chip_, getCapabilities); + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_caps.first.code); + return status_and_caps.second; + } + + std::string getIfaceName(const sp& iface) { + const auto& status_and_name = HIDL_INVOKE(iface, getName); + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_name.first.code); + return status_and_name.second; + } + + WifiStatusCode createApIface(sp* ap_iface) { + const auto& status_and_iface = HIDL_INVOKE(wifi_chip_, createApIface); + *ap_iface = status_and_iface.second; + return status_and_iface.first.code; + } + + WifiStatusCode removeApIface(const std::string& name) { + return HIDL_INVOKE(wifi_chip_, removeApIface, name).code; + } + + WifiStatusCode createNanIface(sp* nan_iface) { + const auto& status_and_iface = HIDL_INVOKE(wifi_chip_, createNanIface); + *nan_iface = status_and_iface.second; + return status_and_iface.first.code; + } + + WifiStatusCode removeNanIface(const std::string& name) { + return HIDL_INVOKE(wifi_chip_, removeNanIface, name).code; + } + + WifiStatusCode createP2pIface(sp* p2p_iface) { + const auto& status_and_iface = HIDL_INVOKE(wifi_chip_, createP2pIface); + *p2p_iface = status_and_iface.second; + return status_and_iface.first.code; + } + + WifiStatusCode removeP2pIface(const std::string& name) { + return HIDL_INVOKE(wifi_chip_, removeP2pIface, name).code; + } + + WifiStatusCode createStaIface(sp* sta_iface) { + const auto& status_and_iface = HIDL_INVOKE(wifi_chip_, createStaIface); + *sta_iface = status_and_iface.second; + return status_and_iface.first.code; + } + + WifiStatusCode removeStaIface(const std::string& name) { + return HIDL_INVOKE(wifi_chip_, removeStaIface, name).code; + } + + sp wifi_chip_; }; /* @@ -46,3 +148,581 @@ TEST(WifiChipHidlTestNoFixture, Create) { EXPECT_NE(nullptr, getWifiChip().get()); stopWifi(); } + +/* + * GetId: + */ +TEST_F(WifiChipHidlTest, GetId) { + EXPECT_EQ(WifiStatusCode::SUCCESS, + HIDL_INVOKE(wifi_chip_, getId).first.code); +} + +/* + * GetAvailableMode: + */ +TEST_F(WifiChipHidlTest, GetAvailableModes) { + const auto& status_and_modes = HIDL_INVOKE(wifi_chip_, getAvailableModes); + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_modes.first.code); + EXPECT_LT(0u, status_and_modes.second.size()); +} + +/* + * ConfigureChip: + */ +TEST_F(WifiChipHidlTest, ConfigureChip) { + const auto& status_and_modes = HIDL_INVOKE(wifi_chip_, getAvailableModes); + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_modes.first.code); + EXPECT_LT(0u, status_and_modes.second.size()); + for (const auto& mode : status_and_modes.second) { + EXPECT_EQ(WifiStatusCode::SUCCESS, + HIDL_INVOKE(wifi_chip_, configureChip, mode.id).code); + } +} + +/* + * GetCapabilities: + */ +TEST_F(WifiChipHidlTest, GetCapabilities) { + configureChipForIfaceType(IfaceType::STA); + const auto& status_and_caps = HIDL_INVOKE(wifi_chip_, getCapabilities); + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_caps.first.code); + EXPECT_NE(0u, status_and_caps.second); +} + +/* + * GetMode: + */ +TEST_F(WifiChipHidlTest, GetMode) { + ChipModeId chip_mode_id = configureChipForIfaceType(IfaceType::STA); + const auto& status_and_mode = HIDL_INVOKE(wifi_chip_, getMode); + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_mode.first.code); + EXPECT_EQ(chip_mode_id, status_and_mode.second); +} + +/* + * RequestChipDebugInfo: + */ +TEST_F(WifiChipHidlTest, RequestChipDebugInfo) { + configureChipForIfaceType(IfaceType::STA); + const auto& status_and_chip_info = + HIDL_INVOKE(wifi_chip_, requestChipDebugInfo); + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_chip_info.first.code); + EXPECT_LT(0u, status_and_chip_info.second.driverDescription.size()); + EXPECT_LT(0u, status_and_chip_info.second.firmwareDescription.size()); +} + +/* + * RequestFirmwareDebugDump + */ +TEST_F(WifiChipHidlTest, RequestFirmwareDebugDump) { + uint32_t caps = configureChipForStaIfaceAndGetCapabilities(); + const auto& status_and_firmware_dump = + HIDL_INVOKE(wifi_chip_, requestFirmwareDebugDump); + if (caps & IWifiChip::ChipCapabilityMask::DEBUG_MEMORY_FIRMWARE_DUMP) { + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_firmware_dump.first.code); + } else { + EXPECT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, + status_and_firmware_dump.first.code); + } +} + +/* + * RequestDriverDebugDump + */ +TEST_F(WifiChipHidlTest, RequestDriverDebugDump) { + uint32_t caps = configureChipForStaIfaceAndGetCapabilities(); + const auto& status_and_driver_dump = + HIDL_INVOKE(wifi_chip_, requestDriverDebugDump); + if (caps & IWifiChip::ChipCapabilityMask::DEBUG_MEMORY_DRIVER_DUMP) { + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_driver_dump.first.code); + } else { + EXPECT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, + status_and_driver_dump.first.code); + } +} + +/* + * GetDebugRingBuffersStatus + */ +TEST_F(WifiChipHidlTest, GetDebugRingBuffersStatus) { + uint32_t caps = configureChipForStaIfaceAndGetCapabilities(); + const auto& status_and_ring_buffer_status = + HIDL_INVOKE(wifi_chip_, getDebugRingBuffersStatus); + if (hasAnyRingBufferCapabilities(caps)) { + EXPECT_EQ(WifiStatusCode::SUCCESS, + status_and_ring_buffer_status.first.code); + for (const auto& ring_buffer : status_and_ring_buffer_status.second) { + EXPECT_LT(0u, ring_buffer.ringName.size()); + } + } else { + EXPECT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, + status_and_ring_buffer_status.first.code); + } +} + +/* + * StartLoggingToDebugRingBuffer + */ +TEST_F(WifiChipHidlTest, StartLoggingToDebugRingBuffer) { + uint32_t caps = configureChipForStaIfaceAndGetCapabilities(); + std::string ring_name; + const auto& status_and_ring_buffer_status = + HIDL_INVOKE(wifi_chip_, getDebugRingBuffersStatus); + if (hasAnyRingBufferCapabilities(caps)) { + EXPECT_EQ(WifiStatusCode::SUCCESS, + status_and_ring_buffer_status.first.code); + ASSERT_LT(0u, status_and_ring_buffer_status.second.size()); + ring_name = status_and_ring_buffer_status.second[0].ringName.c_str(); + } else { + EXPECT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, + status_and_ring_buffer_status.first.code); + } + const auto& status = + HIDL_INVOKE(wifi_chip_, startLoggingToDebugRingBuffer, ring_name, + kDebugRingBufferVerboseLvl, kDebugRingBufferMaxInterval, + kDebugRingBufferMaxDataSize); + if (hasAnyRingBufferCapabilities(caps)) { + EXPECT_EQ(WifiStatusCode::SUCCESS, status.code); + } else { + EXPECT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, status.code); + } +} + +/* + * ForceDumpToDebugRingBuffer + */ +TEST_F(WifiChipHidlTest, ForceDumpToDebugRingBuffer) { + uint32_t caps = configureChipForStaIfaceAndGetCapabilities(); + std::string ring_name; + const auto& status_and_ring_buffer_status = + HIDL_INVOKE(wifi_chip_, getDebugRingBuffersStatus); + if (hasAnyRingBufferCapabilities(caps)) { + EXPECT_EQ(WifiStatusCode::SUCCESS, + status_and_ring_buffer_status.first.code); + ASSERT_LT(0u, status_and_ring_buffer_status.second.size()); + ring_name = status_and_ring_buffer_status.second[0].ringName.c_str(); + } else { + EXPECT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, + status_and_ring_buffer_status.first.code); + } + const auto& status = + HIDL_INVOKE(wifi_chip_, forceDumpToDebugRingBuffer, ring_name); + if (hasAnyRingBufferCapabilities(caps)) { + EXPECT_EQ(WifiStatusCode::SUCCESS, status.code); + } else { + EXPECT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, status.code); + } +} + +/* + * GetDebugHostWakeReasonStats + */ +TEST_F(WifiChipHidlTest, GetDebugHostWakeReasonStats) { + uint32_t caps = configureChipForStaIfaceAndGetCapabilities(); + const auto& status_and_debug_wake_reason = + HIDL_INVOKE(wifi_chip_, getDebugHostWakeReasonStats); + if (caps & IWifiChip::ChipCapabilityMask::DEBUG_HOST_WAKE_REASON_STATS) { + EXPECT_EQ(WifiStatusCode::SUCCESS, + status_and_debug_wake_reason.first.code); + } else { + EXPECT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, + status_and_debug_wake_reason.first.code); + } +} + +/* + * CreateApIface + * Configures the chip in AP mode and ensures that only 1 iface creation + * succeeds. The 2nd iface creation should be rejected. + */ +TEST_F(WifiChipHidlTest, CreateApIface) { + configureChipForIfaceType(IfaceType::AP); + + sp iface; + EXPECT_EQ(WifiStatusCode::SUCCESS, createApIface(&iface)); + EXPECT_NE(nullptr, iface.get()); + + EXPECT_EQ(WifiStatusCode::ERROR_NOT_AVAILABLE, createApIface(&iface)); +} + +/* + * GetApIfaceNames + * Configures the chip in AP mode and ensures that the iface list is empty + * before creating the iface. Then, create the iface and ensure that + * iface name is returned via the list. + */ +TEST_F(WifiChipHidlTest, GetApIfaceNames) { + configureChipForIfaceType(IfaceType::AP); + + const auto& status_and_iface_names1 = + HIDL_INVOKE(wifi_chip_, getApIfaceNames); + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_iface_names1.first.code); + EXPECT_EQ(0u, status_and_iface_names1.second.size()); + + sp iface; + EXPECT_EQ(WifiStatusCode::SUCCESS, createApIface(&iface)); + EXPECT_NE(nullptr, iface.get()); + + std::string iface_name = getIfaceName(iface); + const auto& status_and_iface_names2 = + HIDL_INVOKE(wifi_chip_, getApIfaceNames); + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_iface_names2.first.code); + EXPECT_EQ(1u, status_and_iface_names2.second.size()); + EXPECT_EQ(iface_name, status_and_iface_names2.second[0]); + + EXPECT_EQ(WifiStatusCode::SUCCESS, removeApIface(iface_name)); + const auto& status_and_iface_names3 = + HIDL_INVOKE(wifi_chip_, getApIfaceNames); + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_iface_names3.first.code); + EXPECT_EQ(0u, status_and_iface_names3.second.size()); +} + +/* + * GetApIface + * Configures the chip in AP mode and create an iface. Then, retrieve + * the iface object using the correct name and ensure any other name + * doesn't retrieve an iface object. + */ +TEST_F(WifiChipHidlTest, GetApIface) { + configureChipForIfaceType(IfaceType::AP); + + sp ap_iface; + EXPECT_EQ(WifiStatusCode::SUCCESS, createApIface(&ap_iface)); + EXPECT_NE(nullptr, ap_iface.get()); + + std::string iface_name = getIfaceName(ap_iface); + const auto& status_and_iface1 = + HIDL_INVOKE(wifi_chip_, getApIface, iface_name); + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_iface1.first.code); + EXPECT_NE(nullptr, status_and_iface1.second.get()); + + std::string invalid_name = iface_name + "0"; + const auto& status_and_iface2 = + HIDL_INVOKE(wifi_chip_, getApIface, invalid_name); + EXPECT_EQ(WifiStatusCode::ERROR_INVALID_ARGS, status_and_iface2.first.code); + EXPECT_EQ(nullptr, status_and_iface2.second.get()); +} + +/* + * RemoveApIface + * Configures the chip in AP mode and create an iface. Then, remove + * the iface object using the correct name and ensure any other name + * doesn't remove the iface. + */ +TEST_F(WifiChipHidlTest, RemoveApIface) { + configureChipForIfaceType(IfaceType::AP); + + sp ap_iface; + EXPECT_EQ(WifiStatusCode::SUCCESS, createApIface(&ap_iface)); + EXPECT_NE(nullptr, ap_iface.get()); + + std::string iface_name = getIfaceName(ap_iface); + std::string invalid_name = iface_name + "0"; + EXPECT_EQ(WifiStatusCode::ERROR_INVALID_ARGS, removeApIface(invalid_name)); + EXPECT_EQ(WifiStatusCode::SUCCESS, removeApIface(iface_name)); + + // No such iface exists now. So, this should return failure. + EXPECT_EQ(WifiStatusCode::ERROR_INVALID_ARGS, removeApIface(iface_name)); +} + +/* + * CreateNanIface + * Configures the chip in NAN mode and ensures that only 1 iface creation + * succeeds. The 2nd iface creation should be rejected. + */ +TEST_F(WifiChipHidlTest, CreateNanIface) { + configureChipForIfaceType(IfaceType::NAN); + + sp iface; + EXPECT_EQ(WifiStatusCode::SUCCESS, createNanIface(&iface)); + EXPECT_NE(nullptr, iface.get()); + + EXPECT_EQ(WifiStatusCode::ERROR_NOT_AVAILABLE, createNanIface(&iface)); +} + +/* + * GetNanIfaceNames + * Configures the chip in NAN mode and ensures that the iface list is empty + * before creating the iface. Then, create the iface and ensure that + * iface name is returned via the list. + */ +TEST_F(WifiChipHidlTest, GetNanIfaceNames) { + configureChipForIfaceType(IfaceType::NAN); + + const auto& status_and_iface_names1 = + HIDL_INVOKE(wifi_chip_, getNanIfaceNames); + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_iface_names1.first.code); + EXPECT_EQ(0u, status_and_iface_names1.second.size()); + + sp iface; + EXPECT_EQ(WifiStatusCode::SUCCESS, createNanIface(&iface)); + EXPECT_NE(nullptr, iface.get()); + + std::string iface_name = getIfaceName(iface); + const auto& status_and_iface_names2 = + HIDL_INVOKE(wifi_chip_, getNanIfaceNames); + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_iface_names2.first.code); + EXPECT_EQ(1u, status_and_iface_names2.second.size()); + EXPECT_EQ(iface_name, status_and_iface_names2.second[0]); + + EXPECT_EQ(WifiStatusCode::SUCCESS, removeNanIface(iface_name)); + const auto& status_and_iface_names3 = + HIDL_INVOKE(wifi_chip_, getNanIfaceNames); + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_iface_names3.first.code); + EXPECT_EQ(0u, status_and_iface_names3.second.size()); +} + +/* + * GetNanIface + * Configures the chip in NAN mode and create an iface. Then, retrieve + * the iface object using the correct name and ensure any other name + * doesn't retrieve an iface object. + */ +TEST_F(WifiChipHidlTest, GetNanIface) { + configureChipForIfaceType(IfaceType::NAN); + + sp nan_iface; + EXPECT_EQ(WifiStatusCode::SUCCESS, createNanIface(&nan_iface)); + EXPECT_NE(nullptr, nan_iface.get()); + + std::string iface_name = getIfaceName(nan_iface); + const auto& status_and_iface1 = + HIDL_INVOKE(wifi_chip_, getNanIface, iface_name); + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_iface1.first.code); + EXPECT_NE(nullptr, status_and_iface1.second.get()); + + std::string invalid_name = iface_name + "0"; + const auto& status_and_iface2 = + HIDL_INVOKE(wifi_chip_, getNanIface, invalid_name); + EXPECT_EQ(WifiStatusCode::ERROR_INVALID_ARGS, status_and_iface2.first.code); + EXPECT_EQ(nullptr, status_and_iface2.second.get()); +} + +/* + * RemoveNanIface + * Configures the chip in NAN mode and create an iface. Then, remove + * the iface object using the correct name and ensure any other name + * doesn't remove the iface. + */ +TEST_F(WifiChipHidlTest, RemoveNanIface) { + configureChipForIfaceType(IfaceType::NAN); + + sp nan_iface; + EXPECT_EQ(WifiStatusCode::SUCCESS, createNanIface(&nan_iface)); + EXPECT_NE(nullptr, nan_iface.get()); + + std::string iface_name = getIfaceName(nan_iface); + std::string invalid_name = iface_name + "0"; + EXPECT_EQ(WifiStatusCode::ERROR_INVALID_ARGS, removeNanIface(invalid_name)); + + EXPECT_EQ(WifiStatusCode::SUCCESS, removeNanIface(iface_name)); + + // No such iface exists now. So, this should return failure. + EXPECT_EQ(WifiStatusCode::ERROR_INVALID_ARGS, removeNanIface(iface_name)); +} + +/* + * CreateP2pIface + * Configures the chip in P2P mode and ensures that only 1 iface creation + * succeeds. The 2nd iface creation should be rejected. + */ +TEST_F(WifiChipHidlTest, CreateP2pIface) { + configureChipForIfaceType(IfaceType::P2P); + + sp iface; + EXPECT_EQ(WifiStatusCode::SUCCESS, createP2pIface(&iface)); + EXPECT_NE(nullptr, iface.get()); + + EXPECT_EQ(WifiStatusCode::ERROR_NOT_AVAILABLE, createP2pIface(&iface)); +} + +/* + * GetP2pIfaceNames + * Configures the chip in P2P mode and ensures that the iface list is empty + * before creating the iface. Then, create the iface and ensure that + * iface name is returned via the list. + */ +TEST_F(WifiChipHidlTest, GetP2pIfaceNames) { + configureChipForIfaceType(IfaceType::P2P); + + const auto& status_and_iface_names1 = + HIDL_INVOKE(wifi_chip_, getP2pIfaceNames); + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_iface_names1.first.code); + EXPECT_EQ(0u, status_and_iface_names1.second.size()); + + sp iface; + EXPECT_EQ(WifiStatusCode::SUCCESS, createP2pIface(&iface)); + EXPECT_NE(nullptr, iface.get()); + + std::string iface_name = getIfaceName(iface); + const auto& status_and_iface_names2 = + HIDL_INVOKE(wifi_chip_, getP2pIfaceNames); + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_iface_names2.first.code); + EXPECT_EQ(1u, status_and_iface_names2.second.size()); + EXPECT_EQ(iface_name, status_and_iface_names2.second[0]); + + EXPECT_EQ(WifiStatusCode::SUCCESS, removeP2pIface(iface_name)); + const auto& status_and_iface_names3 = + HIDL_INVOKE(wifi_chip_, getP2pIfaceNames); + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_iface_names3.first.code); + EXPECT_EQ(0u, status_and_iface_names3.second.size()); +} + +/* + * GetP2pIface + * Configures the chip in P2P mode and create an iface. Then, retrieve + * the iface object using the correct name and ensure any other name + * doesn't retrieve an iface object. + */ +TEST_F(WifiChipHidlTest, GetP2pIface) { + configureChipForIfaceType(IfaceType::P2P); + + sp p2p_iface; + EXPECT_EQ(WifiStatusCode::SUCCESS, createP2pIface(&p2p_iface)); + EXPECT_NE(nullptr, p2p_iface.get()); + + std::string iface_name = getIfaceName(p2p_iface); + const auto& status_and_iface1 = + HIDL_INVOKE(wifi_chip_, getP2pIface, iface_name); + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_iface1.first.code); + EXPECT_NE(nullptr, status_and_iface1.second.get()); + + std::string invalid_name = iface_name + "0"; + const auto& status_and_iface2 = + HIDL_INVOKE(wifi_chip_, getP2pIface, invalid_name); + EXPECT_EQ(WifiStatusCode::ERROR_INVALID_ARGS, status_and_iface2.first.code); + EXPECT_EQ(nullptr, status_and_iface2.second.get()); +} + +/* + * RemoveP2pIface + * Configures the chip in P2P mode and create an iface. Then, remove + * the iface object using the correct name and ensure any other name + * doesn't remove the iface. + */ +TEST_F(WifiChipHidlTest, RemoveP2pIface) { + configureChipForIfaceType(IfaceType::P2P); + + sp p2p_iface; + EXPECT_EQ(WifiStatusCode::SUCCESS, createP2pIface(&p2p_iface)); + EXPECT_NE(nullptr, p2p_iface.get()); + + std::string iface_name = getIfaceName(p2p_iface); + std::string invalid_name = iface_name + "0"; + EXPECT_EQ(WifiStatusCode::ERROR_INVALID_ARGS, removeP2pIface(invalid_name)); + EXPECT_EQ(WifiStatusCode::SUCCESS, removeP2pIface(iface_name)); + + // No such iface exists now. So, this should return failure. + EXPECT_EQ(WifiStatusCode::ERROR_INVALID_ARGS, removeP2pIface(iface_name)); +} + +/* + * CreateStaIface + * Configures the chip in STA mode and ensures that only 1 iface creation + * succeeds. The 2nd iface creation should be rejected. + */ +TEST_F(WifiChipHidlTest, CreateStaIface) { + configureChipForIfaceType(IfaceType::STA); + + sp iface; + EXPECT_EQ(WifiStatusCode::SUCCESS, createStaIface(&iface)); + EXPECT_NE(nullptr, iface.get()); + + EXPECT_EQ(WifiStatusCode::ERROR_NOT_AVAILABLE, createStaIface(&iface)); +} + +/* + * GetStaIfaceNames + * Configures the chip in STA mode and ensures that the iface list is empty + * before creating the iface. Then, create the iface and ensure that + * iface name is returned via the list. + */ +TEST_F(WifiChipHidlTest, GetStaIfaceNames) { + configureChipForIfaceType(IfaceType::STA); + + const auto& status_and_iface_names1 = + HIDL_INVOKE(wifi_chip_, getStaIfaceNames); + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_iface_names1.first.code); + EXPECT_EQ(0u, status_and_iface_names1.second.size()); + + sp iface; + EXPECT_EQ(WifiStatusCode::SUCCESS, createStaIface(&iface)); + EXPECT_NE(nullptr, iface.get()); + + std::string iface_name = getIfaceName(iface); + const auto& status_and_iface_names2 = + HIDL_INVOKE(wifi_chip_, getStaIfaceNames); + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_iface_names2.first.code); + EXPECT_EQ(1u, status_and_iface_names2.second.size()); + EXPECT_EQ(iface_name, status_and_iface_names2.second[0]); + + EXPECT_EQ(WifiStatusCode::SUCCESS, removeStaIface(iface_name)); + const auto& status_and_iface_names3 = + HIDL_INVOKE(wifi_chip_, getStaIfaceNames); + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_iface_names3.first.code); + EXPECT_EQ(0u, status_and_iface_names3.second.size()); +} + +/* + * GetStaIface + * Configures the chip in STA mode and create an iface. Then, retrieve + * the iface object using the correct name and ensure any other name + * doesn't retrieve an iface object. + */ +TEST_F(WifiChipHidlTest, GetStaIface) { + configureChipForIfaceType(IfaceType::STA); + + sp sta_iface; + EXPECT_EQ(WifiStatusCode::SUCCESS, createStaIface(&sta_iface)); + EXPECT_NE(nullptr, sta_iface.get()); + + std::string iface_name = getIfaceName(sta_iface); + const auto& status_and_iface1 = + HIDL_INVOKE(wifi_chip_, getStaIface, iface_name); + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_iface1.first.code); + EXPECT_NE(nullptr, status_and_iface1.second.get()); + + std::string invalid_name = iface_name + "0"; + const auto& status_and_iface2 = + HIDL_INVOKE(wifi_chip_, getStaIface, invalid_name); + EXPECT_EQ(WifiStatusCode::ERROR_INVALID_ARGS, status_and_iface2.first.code); + EXPECT_EQ(nullptr, status_and_iface2.second.get()); +} + +/* + * RemoveStaIface + * Configures the chip in STA mode and create an iface. Then, remove + * the iface object using the correct name and ensure any other name + * doesn't remove the iface. + */ +TEST_F(WifiChipHidlTest, RemoveStaIface) { + configureChipForIfaceType(IfaceType::STA); + + sp sta_iface; + EXPECT_EQ(WifiStatusCode::SUCCESS, createStaIface(&sta_iface)); + EXPECT_NE(nullptr, sta_iface.get()); + + std::string iface_name = getIfaceName(sta_iface); + std::string invalid_name = iface_name + "0"; + EXPECT_EQ(WifiStatusCode::ERROR_INVALID_ARGS, removeStaIface(invalid_name)); + EXPECT_EQ(WifiStatusCode::SUCCESS, removeStaIface(iface_name)); + + // No such iface exists now. So, this should return failure. + EXPECT_EQ(WifiStatusCode::ERROR_INVALID_ARGS, removeStaIface(iface_name)); +} + +/* + * CreateRttController + */ +TEST_F(WifiChipHidlTest, CreateRttController) { + configureChipForIfaceType(IfaceType::AP); + + sp iface; + EXPECT_EQ(WifiStatusCode::SUCCESS, createApIface(&iface)); + EXPECT_NE(nullptr, iface.get()); + + const auto& status_and_rtt_controller = + HIDL_INVOKE(wifi_chip_, createRttController, iface); + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_rtt_controller.first.code); + EXPECT_NE(nullptr, status_and_rtt_controller.second.get()); +} diff --git a/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp b/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp index e0c92fe104..0e10e42b65 100644 --- a/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp +++ b/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp @@ -35,6 +35,53 @@ using ::android::sp; using ::android::hardware::hidl_string; using ::android::hardware::hidl_vec; +namespace { +bool findAnyModeSupportingIfaceType( + IfaceType desired_type, const std::vector& modes, + ChipModeId* mode_id) { + for (const auto& mode : modes) { + for (const auto& combination : mode.availableCombinations) { + for (const auto& iface_limit : combination.limits) { + const auto& iface_types = iface_limit.types; + if (std::find(iface_types.begin(), iface_types.end(), + desired_type) != iface_types.end()) { + *mode_id = mode.id; + return true; + } + } + } + } + return false; +} + +bool configureChipToSupportIfaceTypeInternal(const sp& wifi_chip, + IfaceType type, + ChipModeId* configured_mode_id) { + if (!configured_mode_id) { + return false; + } + const auto& status_and_modes = HIDL_INVOKE(wifi_chip, getAvailableModes); + if (status_and_modes.first.code != WifiStatusCode::SUCCESS) { + return false; + } + if (!findAnyModeSupportingIfaceType(type, status_and_modes.second, + configured_mode_id)) { + return false; + } + if (HIDL_INVOKE(wifi_chip, configureChip, *configured_mode_id).code != + WifiStatusCode::SUCCESS) { + return false; + } + return true; +} + +bool configureChipToSupportIfaceTypeInternal(const sp& wifi_chip, + IfaceType type) { + ChipModeId mode_id; + return configureChipToSupportIfaceTypeInternal(wifi_chip, type, &mode_id); +} +} // namespace + void stopFramework() { ASSERT_EQ(std::system("stop"), 0); stopWifi(); @@ -53,79 +100,30 @@ sp getWifiChip() { if (!wifi.get()) { return nullptr; } - if (HIDL_INVOKE(wifi, start).code != WifiStatusCode::SUCCESS) { return nullptr; } - const auto& status_and_chip_ids = HIDL_INVOKE(wifi, getChipIds); const auto& chip_ids = status_and_chip_ids.second; if (status_and_chip_ids.first.code != WifiStatusCode::SUCCESS || chip_ids.size() != 1) { return nullptr; } - const auto& status_and_chip = HIDL_INVOKE(wifi, getChip, chip_ids[0]); if (status_and_chip.first.code != WifiStatusCode::SUCCESS) { return nullptr; } - return status_and_chip.second; } -// Since we currently only support one iface of each type. Just iterate thru the -// modes of operation and find the mode ID to use for that iface type. -bool findModeToSupportIfaceType(IfaceType type, - const std::vector& modes, - ChipModeId* mode_id) { - for (const auto& mode : modes) { - std::vector combinations = - mode.availableCombinations; - for (const auto& combination : combinations) { - std::vector iface_limits = - combination.limits; - for (const auto& iface_limit : iface_limits) { - std::vector iface_types = iface_limit.types; - for (const auto& iface_type : iface_types) { - if (iface_type == type) { - *mode_id = mode.id; - return true; - } - } - } - } - } - return false; -} - -bool configureChipToSupportIfaceType(const sp& wifi_chip, - IfaceType type) { - const auto& status_and_modes = HIDL_INVOKE(wifi_chip, getAvailableModes); - if (status_and_modes.first.code != WifiStatusCode::SUCCESS) { - return false; - } - - ChipModeId mode_id; - if (!findModeToSupportIfaceType(type, status_and_modes.second, &mode_id)) { - return false; - } - - if (HIDL_INVOKE(wifi_chip, configureChip, mode_id).code != - WifiStatusCode::SUCCESS) { - return false; - } - return true; -} - sp getWifiApIface() { sp wifi_chip = getWifiChip(); if (!wifi_chip.get()) { return nullptr; } - if (!configureChipToSupportIfaceType(wifi_chip, IfaceType::AP)) { + if (!configureChipToSupportIfaceTypeInternal(wifi_chip, IfaceType::AP)) { return nullptr; } - const auto& status_and_iface = HIDL_INVOKE(wifi_chip, createApIface); if (status_and_iface.first.code != WifiStatusCode::SUCCESS) { return nullptr; @@ -138,10 +136,9 @@ sp getWifiNanIface() { if (!wifi_chip.get()) { return nullptr; } - if (!configureChipToSupportIfaceType(wifi_chip, IfaceType::NAN)) { + if (!configureChipToSupportIfaceTypeInternal(wifi_chip, IfaceType::NAN)) { return nullptr; } - const auto& status_and_iface = HIDL_INVOKE(wifi_chip, createNanIface); if (status_and_iface.first.code != WifiStatusCode::SUCCESS) { return nullptr; @@ -154,10 +151,9 @@ sp getWifiP2pIface() { if (!wifi_chip.get()) { return nullptr; } - if (!configureChipToSupportIfaceType(wifi_chip, IfaceType::P2P)) { + if (!configureChipToSupportIfaceTypeInternal(wifi_chip, IfaceType::P2P)) { return nullptr; } - const auto& status_and_iface = HIDL_INVOKE(wifi_chip, createP2pIface); if (status_and_iface.first.code != WifiStatusCode::SUCCESS) { return nullptr; @@ -170,10 +166,9 @@ sp getWifiStaIface() { if (!wifi_chip.get()) { return nullptr; } - if (!configureChipToSupportIfaceType(wifi_chip, IfaceType::STA)) { + if (!configureChipToSupportIfaceTypeInternal(wifi_chip, IfaceType::STA)) { return nullptr; } - const auto& status_and_iface = HIDL_INVOKE(wifi_chip, createStaIface); if (status_and_iface.first.code != WifiStatusCode::SUCCESS) { return nullptr; @@ -190,7 +185,6 @@ sp getWifiRttController() { if (!wifi_sta_iface.get()) { return nullptr; } - const auto& status_and_controller = HIDL_INVOKE(wifi_chip, createRttController, wifi_sta_iface); if (status_and_controller.first.code != WifiStatusCode::SUCCESS) { @@ -199,6 +193,13 @@ sp getWifiRttController() { return status_and_controller.second; } +bool configureChipToSupportIfaceType(const sp& wifi_chip, + IfaceType type, + ChipModeId* configured_mode_id) { + return configureChipToSupportIfaceTypeInternal(wifi_chip, type, + configured_mode_id); +} + void stopWifi() { sp wifi = getWifi(); ASSERT_NE(wifi, nullptr); diff --git a/wifi/1.0/vts/functional/wifi_hidl_test_utils.h b/wifi/1.0/vts/functional/wifi_hidl_test_utils.h index 08933d902e..a723b2aa20 100644 --- a/wifi/1.0/vts/functional/wifi_hidl_test_utils.h +++ b/wifi/1.0/vts/functional/wifi_hidl_test_utils.h @@ -41,5 +41,11 @@ android::sp getWifiP2pIface(); android::sp getWifiStaIface(); android::sp getWifiRttController(); +// Configure the chip in a mode to support the creation of the provided +// iface type. +bool configureChipToSupportIfaceType( + const android::sp& wifi_chip, + android::hardware::wifi::V1_0::IfaceType type, + android::hardware::wifi::V1_0::ChipModeId* configured_mode_id); // Used to trigger IWifi.stop() at the end of every test. void stopWifi(); diff --git a/wifi/1.0/vts/functional/wifi_sta_iface_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_sta_iface_hidl_test.cpp index 44574876eb..0984241299 100644 --- a/wifi/1.0/vts/functional/wifi_sta_iface_hidl_test.cpp +++ b/wifi/1.0/vts/functional/wifi_sta_iface_hidl_test.cpp @@ -20,21 +20,28 @@ #include +#include "wifi_hidl_call_util.h" #include "wifi_hidl_test_utils.h" -using ::android::hardware::wifi::V1_0::IWifiStaIface; using ::android::sp; +using ::android::hardware::wifi::V1_0::IWifiStaIface; +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::VtsHalHidlTargetBaseTest { public: - virtual void SetUp() override {} + virtual void SetUp() override { + wifi_sta_iface_ = getWifiStaIface(); + ASSERT_NE(nullptr, wifi_sta_iface_.get()); + } virtual void TearDown() override { stopWifi(); } protected: + sp wifi_sta_iface_; }; /* @@ -46,3 +53,12 @@ TEST(WifiStaIfaceHidlTestNoFixture, Create) { EXPECT_NE(nullptr, getWifiStaIface().get()); stopWifi(); } + +/* + * GetCapabilities: + */ +TEST_F(WifiStaIfaceHidlTest, GetCapabilities) { + const auto& status_and_caps = HIDL_INVOKE(wifi_sta_iface_, getCapabilities); + EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_caps.first.code); + EXPECT_NE(0u, status_and_caps.second); +}