mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 11:36:00 +00:00
wifi: Add STA + STA HIDL API's
Add the HIDL API's + shim + VTS tests. Bug: 170305665 Test: atest VtsHalWifiV1_3TargetTest VtsHalWifiV1_5TargetTest Change-Id: I26ada11aebfe8082bfda251cf7e6990e0aa08a06
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
|
||||
#include <android/hardware/wifi/1.3/IWifi.h>
|
||||
#include <android/hardware/wifi/1.3/IWifiStaIface.h>
|
||||
#include <android/hardware/wifi/1.5/IWifiStaIface.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <hidl/GtestPrinter.h>
|
||||
#include <hidl/ServiceManagement.h>
|
||||
@@ -88,7 +89,6 @@ TEST_P(WifiStaIfaceHidlTest, GetLinkLayerStats_1_3) {
|
||||
// No-op if link layer stats is not supported.
|
||||
return;
|
||||
}
|
||||
|
||||
// Enable link layer stats collection.
|
||||
EXPECT_EQ(WifiStatusCode::SUCCESS,
|
||||
HIDL_INVOKE(wifi_sta_iface_, enableLinkLayerStatsCollection, true)
|
||||
@@ -96,8 +96,17 @@ TEST_P(WifiStaIfaceHidlTest, GetLinkLayerStats_1_3) {
|
||||
// Retrieve link layer stats.
|
||||
const auto& status_and_stats =
|
||||
HIDL_INVOKE(wifi_sta_iface_, getLinkLayerStats_1_3);
|
||||
EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_stats.first.code);
|
||||
EXPECT_GT(status_and_stats.second.timeStampInMs, 0u);
|
||||
sp<android::hardware::wifi::V1_5::IWifiStaIface> staIface1_5 =
|
||||
android::hardware::wifi::V1_5::IWifiStaIface::castFrom(wifi_sta_iface_);
|
||||
if (staIface1_5.get() == nullptr) {
|
||||
EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_stats.first.code);
|
||||
EXPECT_GT(status_and_stats.second.timeStampInMs, 0u);
|
||||
} else {
|
||||
// not supported on 1.5 HAL.
|
||||
EXPECT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED,
|
||||
status_and_stats.first.code);
|
||||
}
|
||||
|
||||
// Disable link layer stats collection.
|
||||
EXPECT_EQ(
|
||||
WifiStatusCode::SUCCESS,
|
||||
|
||||
@@ -9,6 +9,7 @@ hidl_interface {
|
||||
"IWifiChip.hal",
|
||||
"IWifiNanIface.hal",
|
||||
"IWifiNanIfaceEventCallback.hal",
|
||||
"IWifiStaIface.hal",
|
||||
],
|
||||
interfaces: [
|
||||
"android.hardware.wifi@1.0",
|
||||
|
||||
@@ -35,6 +35,53 @@ interface IWifiChip extends @1.4::IWifiChip {
|
||||
WIGIG = 1 << 14,
|
||||
};
|
||||
|
||||
/**
|
||||
* When there are 2 or more simultaneous STA connections, this use case hint indicates what
|
||||
* use-case is being enabled by the framework. This use case hint can be used by the firmware
|
||||
* to modify various firmware configurations like:
|
||||
* - Allowed BSSIDs the firmware can choose for the initial connection/roaming attempts.
|
||||
* - Duty cycle to choose for the 2 STA connections if the radio is in MCC mode.
|
||||
* - Whether roaming, APF and other offloads needs to be enabled or not.
|
||||
* Note:
|
||||
* - This will be invoked before an active wifi connection is established on the second
|
||||
* interface.
|
||||
* - This use-case hint is implicitly void when the second STA interface is brought down.
|
||||
*/
|
||||
enum MultiStaUseCase : uint8_t {
|
||||
/**
|
||||
* Usage:
|
||||
* - This will be sent down for make before break use-case.
|
||||
* - Platform is trying to speculatively connect to a second network and evaluate it without
|
||||
* disrupting the primary connection.
|
||||
* Requirements for Firmware:
|
||||
* - Do not reduce the number of tx/rx chains of primary connection.
|
||||
* - If using MCC, should set the MCC duty cycle of the primary connection to be higher than
|
||||
* the secondary connection (maybe 70/30 split).
|
||||
* - Should pick the best BSSID for the secondary STA (disregard the chip mode) independent
|
||||
* of the primary STA:
|
||||
* - Don’t optimize for DBS vs MCC/SCC
|
||||
* - Should not impact the primary connection’s bssid selection:
|
||||
* - Don’t downgrade chains of the existing primary connection.
|
||||
* - Don’t optimize for DBS vs MCC/SCC.
|
||||
*/
|
||||
DUAL_STA_TRANSIENT_PREFER_PRIMARY = 0,
|
||||
/**
|
||||
* Usage:
|
||||
* - This will be sent down for any app requested peer to peer connections.
|
||||
* - In this case, both the connections needs to be allocated equal resources.
|
||||
* - For the peer to peer use case, BSSID for the secondary connection will be chosen by the
|
||||
* framework.
|
||||
*
|
||||
* Requirements for Firmware:
|
||||
* - Can choose MCC or DBS mode depending on the MCC efficiency and HW capability.
|
||||
* - If using MCC, set the MCC duty cycle of the primary connection to be equal to the
|
||||
* secondary connection.
|
||||
* - Prefer BSSID candidates which will help provide the best "overall" performance for both
|
||||
* the connections.
|
||||
*/
|
||||
DUAL_STA_NON_TRANSIENT_UNBIASED = 1,
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the capabilities supported by this chip.
|
||||
*
|
||||
@@ -48,4 +95,36 @@ interface IWifiChip extends @1.4::IWifiChip {
|
||||
*/
|
||||
getCapabilities_1_5()
|
||||
generates (WifiStatus status, bitfield<ChipCapabilityMask> capabilities);
|
||||
|
||||
/**
|
||||
* Invoked to indicate that the provided iface is the primary STA iface when there are more
|
||||
* than 1 STA iface concurrently active.
|
||||
* Note: If the wifi firmware/chip cannot support multiple instances of any offload
|
||||
* (like roaming, APF, rssi threshold, etc), the firmware should ensure that these
|
||||
* offloads are at least enabled for the primary interface. If the new primary interface is
|
||||
* already connected to a network, the firmware must switch all the offloads on
|
||||
* this new interface without disconnecting.
|
||||
*
|
||||
* @param ifname Name of the STA iface.
|
||||
* @return status WifiStatus of the operation.
|
||||
* Possible status codes:
|
||||
* |WifiStatusCode.SUCCESS|,
|
||||
* |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
|
||||
* |WifiStatusCode.ERROR_INVALID_ARGS|
|
||||
*/
|
||||
setMultiStaPrimaryConnection(string ifName) generates (WifiStatus status);
|
||||
|
||||
/**
|
||||
* Invoked to indicate the STA + STA use-case that is active.
|
||||
*
|
||||
* Refer to documentation of |MultiStaUseCase| for details.
|
||||
*
|
||||
* @param useCase Use case that is active.
|
||||
* @return status WifiStatus of the operation.
|
||||
* Possible status codes:
|
||||
* |WifiStatusCode.SUCCESS|,
|
||||
* |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
|
||||
* |WifiStatusCode.ERROR_INVALID_ARGS|
|
||||
*/
|
||||
setMultiStaUseCase(MultiStaUseCase useCase) generates (WifiStatus status);
|
||||
};
|
||||
|
||||
@@ -92,13 +92,12 @@ interface IWifiNanIface extends @1.4::IWifiNanIface {
|
||||
* |WifiStatusCode.SUCCESS|,
|
||||
* |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|
|
||||
*/
|
||||
registerEventCallback_1_5(IWifiNanIfaceEventCallback callback)
|
||||
generates (WifiStatus status);
|
||||
registerEventCallback_1_5(IWifiNanIfaceEventCallback callback) generates (WifiStatus status);
|
||||
|
||||
/**
|
||||
* Get NAN capabilities. Asynchronous response is with
|
||||
* |IWifiNanIfaceEventCallback.notifyCapabilitiesResponse|.
|
||||
|
||||
*
|
||||
* Note: supersedes the @1.0::IWifiNanIface.getCapabilitiesRequest() method which is deprecated
|
||||
* as of HAL version 1.5.
|
||||
*
|
||||
@@ -109,5 +108,5 @@ interface IWifiNanIface extends @1.4::IWifiNanIface {
|
||||
* |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
|
||||
* |WifiStatusCode.ERROR_UNKNOWN|
|
||||
*/
|
||||
getCapabilitiesRequest_1_5(CommandIdShort cmdId) generates (WifiStatus status);
|
||||
};
|
||||
getCapabilitiesRequest_1_5(CommandIdShort cmdId) generates (WifiStatus status);
|
||||
};
|
||||
|
||||
@@ -40,5 +40,5 @@ interface IWifiNanIfaceEventCallback extends @1.2::IWifiNanIfaceEventCallback {
|
||||
* @param capabilities Capability data.
|
||||
*/
|
||||
oneway notifyCapabilitiesResponse_1_5(CommandIdShort id, WifiNanStatus status,
|
||||
NanCapabilities capabilities);
|
||||
};
|
||||
NanCapabilities capabilities);
|
||||
};
|
||||
|
||||
44
wifi/1.5/IWifiStaIface.hal
Normal file
44
wifi/1.5/IWifiStaIface.hal
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache 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.
|
||||
*/
|
||||
|
||||
package android.hardware.wifi@1.5;
|
||||
|
||||
import @1.0::WifiStatus;
|
||||
import @1.3::IWifiStaIface;
|
||||
|
||||
/**
|
||||
* Interface used to represent a single STA iface.
|
||||
*
|
||||
* IWifiChip.createStaIface() must return a @1.5::IWifiStaIface when supported.
|
||||
*/
|
||||
interface IWifiStaIface extends @1.3::IWifiStaIface {
|
||||
/**
|
||||
* Retrieve the latest link layer stats.
|
||||
* Must fail if |StaIfaceCapabilityMask.LINK_LAYER_STATS| is not set or if
|
||||
* link layer stats collection hasn't been explicitly enabled.
|
||||
*
|
||||
* @return status WifiStatus of the operation.
|
||||
* Possible status codes:
|
||||
* |WifiStatusCode.SUCCESS|,
|
||||
* |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
|
||||
* |WifiStatusCode.ERROR_NOT_SUPPORTED|,
|
||||
* |WifiStatusCode.ERROR_NOT_STARTED|,
|
||||
* |WifiStatusCode.ERROR_NOT_AVAILABLE|,
|
||||
* |WifiStatusCode.ERROR_UNKNOWN|
|
||||
* @return stats Instance of |LinkLayerStats|.
|
||||
*/
|
||||
getLinkLayerStats_1_5() generates (WifiStatus status, StaLinkLayerStats stats);
|
||||
};
|
||||
@@ -866,46 +866,48 @@ bool convertLegacyLinkLayerRadioStatsToHidl(
|
||||
|
||||
bool convertLegacyLinkLayerStatsToHidl(
|
||||
const legacy_hal::LinkLayerStats& legacy_stats,
|
||||
V1_3::StaLinkLayerStats* hidl_stats) {
|
||||
StaLinkLayerStats* hidl_stats) {
|
||||
if (!hidl_stats) {
|
||||
return false;
|
||||
}
|
||||
*hidl_stats = {};
|
||||
// iface legacy_stats conversion.
|
||||
hidl_stats->iface.beaconRx = legacy_stats.iface.beacon_rx;
|
||||
hidl_stats->iface.avgRssiMgmt = legacy_stats.iface.rssi_mgmt;
|
||||
hidl_stats->iface.wmeBePktStats.rxMpdu =
|
||||
hidl_stats->iface.V1_0.beaconRx = legacy_stats.iface.beacon_rx;
|
||||
hidl_stats->iface.V1_0.avgRssiMgmt = legacy_stats.iface.rssi_mgmt;
|
||||
hidl_stats->iface.V1_0.wmeBePktStats.rxMpdu =
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].rx_mpdu;
|
||||
hidl_stats->iface.wmeBePktStats.txMpdu =
|
||||
hidl_stats->iface.V1_0.wmeBePktStats.txMpdu =
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].tx_mpdu;
|
||||
hidl_stats->iface.wmeBePktStats.lostMpdu =
|
||||
hidl_stats->iface.V1_0.wmeBePktStats.lostMpdu =
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].mpdu_lost;
|
||||
hidl_stats->iface.wmeBePktStats.retries =
|
||||
hidl_stats->iface.V1_0.wmeBePktStats.retries =
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].retries;
|
||||
hidl_stats->iface.wmeBkPktStats.rxMpdu =
|
||||
hidl_stats->iface.V1_0.wmeBkPktStats.rxMpdu =
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].rx_mpdu;
|
||||
hidl_stats->iface.wmeBkPktStats.txMpdu =
|
||||
hidl_stats->iface.V1_0.wmeBkPktStats.txMpdu =
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].tx_mpdu;
|
||||
hidl_stats->iface.wmeBkPktStats.lostMpdu =
|
||||
hidl_stats->iface.V1_0.wmeBkPktStats.lostMpdu =
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].mpdu_lost;
|
||||
hidl_stats->iface.wmeBkPktStats.retries =
|
||||
hidl_stats->iface.V1_0.wmeBkPktStats.retries =
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].retries;
|
||||
hidl_stats->iface.wmeViPktStats.rxMpdu =
|
||||
hidl_stats->iface.V1_0.wmeViPktStats.rxMpdu =
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].rx_mpdu;
|
||||
hidl_stats->iface.wmeViPktStats.txMpdu =
|
||||
hidl_stats->iface.V1_0.wmeViPktStats.txMpdu =
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].tx_mpdu;
|
||||
hidl_stats->iface.wmeViPktStats.lostMpdu =
|
||||
hidl_stats->iface.V1_0.wmeViPktStats.lostMpdu =
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].mpdu_lost;
|
||||
hidl_stats->iface.wmeViPktStats.retries =
|
||||
hidl_stats->iface.V1_0.wmeViPktStats.retries =
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].retries;
|
||||
hidl_stats->iface.wmeVoPktStats.rxMpdu =
|
||||
hidl_stats->iface.V1_0.wmeVoPktStats.rxMpdu =
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].rx_mpdu;
|
||||
hidl_stats->iface.wmeVoPktStats.txMpdu =
|
||||
hidl_stats->iface.V1_0.wmeVoPktStats.txMpdu =
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].tx_mpdu;
|
||||
hidl_stats->iface.wmeVoPktStats.lostMpdu =
|
||||
hidl_stats->iface.V1_0.wmeVoPktStats.lostMpdu =
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].mpdu_lost;
|
||||
hidl_stats->iface.wmeVoPktStats.retries =
|
||||
hidl_stats->iface.V1_0.wmeVoPktStats.retries =
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].retries;
|
||||
hidl_stats->iface.timeSliceDutyCycleInPercent =
|
||||
legacy_stats.iface.info.time_slicing_duty_cycle_percent;
|
||||
// radio legacy_stats conversion.
|
||||
std::vector<V1_3::StaLinkLayerRadioStats> hidl_radios_stats;
|
||||
for (const auto& legacy_radio_stats : legacy_stats.radios) {
|
||||
@@ -2787,6 +2789,17 @@ legacy_hal::wifi_interface_type convertHidlIfaceTypeToLegacy(
|
||||
}
|
||||
CHECK(false);
|
||||
}
|
||||
|
||||
legacy_hal::wifi_multi_sta_use_case convertHidlMultiStaUseCaseToLegacy(
|
||||
IWifiChip::MultiStaUseCase use_case) {
|
||||
switch (use_case) {
|
||||
case IWifiChip::MultiStaUseCase::DUAL_STA_TRANSIENT_PREFER_PRIMARY:
|
||||
return legacy_hal::WIFI_DUAL_STA_TRANSIENT_PREFER_PRIMARY;
|
||||
case IWifiChip::MultiStaUseCase::DUAL_STA_NON_TRANSIENT_UNBIASED:
|
||||
return legacy_hal::WIFI_DUAL_STA_NON_TRANSIENT_UNBIASED;
|
||||
}
|
||||
CHECK(false);
|
||||
}
|
||||
} // namespace hidl_struct_util
|
||||
} // namespace implementation
|
||||
} // namespace V1_5
|
||||
|
||||
@@ -69,6 +69,8 @@ bool convertLegacyWifiMacInfosToHidl(
|
||||
hidl_radio_mode_infos);
|
||||
legacy_hal::wifi_interface_type convertHidlIfaceTypeToLegacy(
|
||||
IfaceType hidl_interface_type);
|
||||
legacy_hal::wifi_multi_sta_use_case convertHidlMultiStaUseCaseToLegacy(
|
||||
IWifiChip::MultiStaUseCase use_case);
|
||||
|
||||
// STA iface conversion methods.
|
||||
bool convertLegacyFeaturesToHidlStaCapabilities(
|
||||
@@ -96,7 +98,7 @@ bool convertLegacyVectorOfCachedGscanResultsToHidl(
|
||||
std::vector<StaScanData>* hidl_scan_datas);
|
||||
bool convertLegacyLinkLayerStatsToHidl(
|
||||
const legacy_hal::LinkLayerStats& legacy_stats,
|
||||
V1_3::StaLinkLayerStats* hidl_stats);
|
||||
StaLinkLayerStats* hidl_stats);
|
||||
bool convertLegacyRoamingCapabilitiesToHidl(
|
||||
const legacy_hal::wifi_roaming_capabilities& legacy_caps,
|
||||
StaRoamingCapabilities* hidl_caps);
|
||||
|
||||
@@ -154,6 +154,8 @@ TEST_F(HidlStructUtilTest, canConvertLegacyLinkLayerStatsToHidl) {
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].mpdu_lost = rand();
|
||||
legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].retries = rand();
|
||||
|
||||
legacy_stats.iface.info.time_slicing_duty_cycle_percent = rand();
|
||||
|
||||
for (auto& radio : legacy_stats.radios) {
|
||||
radio.stats.on_time = rand();
|
||||
radio.stats.tx_time = rand();
|
||||
@@ -182,46 +184,49 @@ TEST_F(HidlStructUtilTest, canConvertLegacyLinkLayerStatsToHidl) {
|
||||
radio.channel_stats.push_back(channel_stat2);
|
||||
}
|
||||
|
||||
V1_3::StaLinkLayerStats converted{};
|
||||
V1_5::StaLinkLayerStats converted{};
|
||||
hidl_struct_util::convertLegacyLinkLayerStatsToHidl(legacy_stats,
|
||||
&converted);
|
||||
EXPECT_EQ(legacy_stats.iface.beacon_rx, converted.iface.beaconRx);
|
||||
EXPECT_EQ(legacy_stats.iface.rssi_mgmt, converted.iface.avgRssiMgmt);
|
||||
EXPECT_EQ(legacy_stats.iface.beacon_rx, converted.iface.V1_0.beaconRx);
|
||||
EXPECT_EQ(legacy_stats.iface.rssi_mgmt, converted.iface.V1_0.avgRssiMgmt);
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].rx_mpdu,
|
||||
converted.iface.wmeBePktStats.rxMpdu);
|
||||
converted.iface.V1_0.wmeBePktStats.rxMpdu);
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].tx_mpdu,
|
||||
converted.iface.wmeBePktStats.txMpdu);
|
||||
converted.iface.V1_0.wmeBePktStats.txMpdu);
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].mpdu_lost,
|
||||
converted.iface.wmeBePktStats.lostMpdu);
|
||||
converted.iface.V1_0.wmeBePktStats.lostMpdu);
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].retries,
|
||||
converted.iface.wmeBePktStats.retries);
|
||||
converted.iface.V1_0.wmeBePktStats.retries);
|
||||
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].rx_mpdu,
|
||||
converted.iface.wmeBkPktStats.rxMpdu);
|
||||
converted.iface.V1_0.wmeBkPktStats.rxMpdu);
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].tx_mpdu,
|
||||
converted.iface.wmeBkPktStats.txMpdu);
|
||||
converted.iface.V1_0.wmeBkPktStats.txMpdu);
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].mpdu_lost,
|
||||
converted.iface.wmeBkPktStats.lostMpdu);
|
||||
converted.iface.V1_0.wmeBkPktStats.lostMpdu);
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].retries,
|
||||
converted.iface.wmeBkPktStats.retries);
|
||||
converted.iface.V1_0.wmeBkPktStats.retries);
|
||||
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].rx_mpdu,
|
||||
converted.iface.wmeViPktStats.rxMpdu);
|
||||
converted.iface.V1_0.wmeViPktStats.rxMpdu);
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].tx_mpdu,
|
||||
converted.iface.wmeViPktStats.txMpdu);
|
||||
converted.iface.V1_0.wmeViPktStats.txMpdu);
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].mpdu_lost,
|
||||
converted.iface.wmeViPktStats.lostMpdu);
|
||||
converted.iface.V1_0.wmeViPktStats.lostMpdu);
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].retries,
|
||||
converted.iface.wmeViPktStats.retries);
|
||||
converted.iface.V1_0.wmeViPktStats.retries);
|
||||
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].rx_mpdu,
|
||||
converted.iface.wmeVoPktStats.rxMpdu);
|
||||
converted.iface.V1_0.wmeVoPktStats.rxMpdu);
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].tx_mpdu,
|
||||
converted.iface.wmeVoPktStats.txMpdu);
|
||||
converted.iface.V1_0.wmeVoPktStats.txMpdu);
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].mpdu_lost,
|
||||
converted.iface.wmeVoPktStats.lostMpdu);
|
||||
converted.iface.V1_0.wmeVoPktStats.lostMpdu);
|
||||
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].retries,
|
||||
converted.iface.wmeVoPktStats.retries);
|
||||
converted.iface.V1_0.wmeVoPktStats.retries);
|
||||
|
||||
EXPECT_EQ(legacy_stats.iface.info.time_slicing_duty_cycle_percent,
|
||||
converted.iface.timeSliceDutyCycleInPercent);
|
||||
|
||||
EXPECT_EQ(legacy_stats.radios.size(), converted.radios.size());
|
||||
for (size_t i = 0; i < legacy_stats.radios.size(); i++) {
|
||||
|
||||
@@ -678,6 +678,20 @@ Return<void> WifiChip::registerEventCallback_1_4(
|
||||
hidl_status_cb, event_callback);
|
||||
}
|
||||
|
||||
Return<void> WifiChip::setMultiStaPrimaryConnection(
|
||||
const hidl_string& ifname, setMultiStaPrimaryConnection_cb hidl_status_cb) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
|
||||
&WifiChip::setMultiStaPrimaryConnectionInternal,
|
||||
hidl_status_cb, ifname);
|
||||
}
|
||||
|
||||
Return<void> WifiChip::setMultiStaUseCase(
|
||||
MultiStaUseCase use_case, setMultiStaUseCase_cb hidl_status_cb) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
|
||||
&WifiChip::setMultiStaUseCaseInternal,
|
||||
hidl_status_cb, use_case);
|
||||
}
|
||||
|
||||
void WifiChip::invalidateAndRemoveAllIfaces() {
|
||||
invalidateAndClearAll(ap_ifaces_);
|
||||
invalidateAndClearAll(nan_ifaces_);
|
||||
@@ -1016,7 +1030,7 @@ WifiStatus WifiChip::removeP2pIfaceInternal(const std::string& ifname) {
|
||||
return createWifiStatus(WifiStatusCode::SUCCESS);
|
||||
}
|
||||
|
||||
std::pair<WifiStatus, sp<V1_3::IWifiStaIface>>
|
||||
std::pair<WifiStatus, sp<V1_5::IWifiStaIface>>
|
||||
WifiChip::createStaIfaceInternal() {
|
||||
if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::STA)) {
|
||||
return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
|
||||
@@ -1050,7 +1064,7 @@ WifiChip::getStaIfaceNamesInternal() {
|
||||
return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(sta_ifaces_)};
|
||||
}
|
||||
|
||||
std::pair<WifiStatus, sp<V1_3::IWifiStaIface>> WifiChip::getStaIfaceInternal(
|
||||
std::pair<WifiStatus, sp<V1_5::IWifiStaIface>> WifiChip::getStaIfaceInternal(
|
||||
const std::string& ifname) {
|
||||
const auto iface = findUsingName(sta_ifaces_, ifname);
|
||||
if (!iface.get()) {
|
||||
@@ -1295,6 +1309,19 @@ WifiStatus WifiChip::registerEventCallbackInternal_1_4(
|
||||
return createWifiStatus(WifiStatusCode::SUCCESS);
|
||||
}
|
||||
|
||||
WifiStatus WifiChip::setMultiStaPrimaryConnectionInternal(
|
||||
const std::string& ifname) {
|
||||
auto legacy_status =
|
||||
legacy_hal_.lock()->multiStaSetPrimaryConnection(ifname);
|
||||
return createWifiStatusFromLegacyError(legacy_status);
|
||||
}
|
||||
|
||||
WifiStatus WifiChip::setMultiStaUseCaseInternal(MultiStaUseCase use_case) {
|
||||
auto legacy_status = legacy_hal_.lock()->multiStaSetUseCase(
|
||||
hidl_struct_util::convertHidlMultiStaUseCaseToLegacy(use_case));
|
||||
return createWifiStatusFromLegacyError(legacy_status);
|
||||
}
|
||||
|
||||
WifiStatus WifiChip::handleChipConfiguration(
|
||||
/* NONNULL */ std::unique_lock<std::recursive_mutex>* lock,
|
||||
ChipModeId mode_id) {
|
||||
|
||||
@@ -163,6 +163,12 @@ class WifiChip : public V1_5::IWifiChip {
|
||||
Return<void> registerEventCallback_1_4(
|
||||
const sp<V1_4::IWifiChipEventCallback>& event_callback,
|
||||
registerEventCallback_1_4_cb hidl_status_cb) override;
|
||||
Return<void> setMultiStaPrimaryConnection(
|
||||
const hidl_string& ifname,
|
||||
setMultiStaPrimaryConnection_cb hidl_status_cb) override;
|
||||
Return<void> setMultiStaUseCase(
|
||||
MultiStaUseCase use_case,
|
||||
setMultiStaUseCase_cb hidl_status_cb) override;
|
||||
|
||||
private:
|
||||
void invalidateAndRemoveAllIfaces();
|
||||
@@ -201,9 +207,9 @@ class WifiChip : public V1_5::IWifiChip {
|
||||
std::pair<WifiStatus, sp<IWifiP2pIface>> getP2pIfaceInternal(
|
||||
const std::string& ifname);
|
||||
WifiStatus removeP2pIfaceInternal(const std::string& ifname);
|
||||
std::pair<WifiStatus, sp<V1_3::IWifiStaIface>> createStaIfaceInternal();
|
||||
std::pair<WifiStatus, sp<V1_5::IWifiStaIface>> createStaIfaceInternal();
|
||||
std::pair<WifiStatus, std::vector<hidl_string>> getStaIfaceNamesInternal();
|
||||
std::pair<WifiStatus, sp<V1_3::IWifiStaIface>> getStaIfaceInternal(
|
||||
std::pair<WifiStatus, sp<V1_5::IWifiStaIface>> getStaIfaceInternal(
|
||||
const std::string& ifname);
|
||||
WifiStatus removeStaIfaceInternal(const std::string& ifname);
|
||||
std::pair<WifiStatus, sp<V1_0::IWifiRttController>>
|
||||
@@ -233,6 +239,8 @@ class WifiChip : public V1_5::IWifiChip {
|
||||
createRttControllerInternal_1_4(const sp<IWifiIface>& bound_iface);
|
||||
WifiStatus registerEventCallbackInternal_1_4(
|
||||
const sp<V1_4::IWifiChipEventCallback>& event_callback);
|
||||
WifiStatus setMultiStaPrimaryConnectionInternal(const std::string& ifname);
|
||||
WifiStatus setMultiStaUseCaseInternal(MultiStaUseCase use_case);
|
||||
|
||||
WifiStatus handleChipConfiguration(
|
||||
std::unique_lock<std::recursive_mutex>* lock, ChipModeId mode_id);
|
||||
|
||||
@@ -1510,6 +1510,17 @@ wifi_error WifiLegacyHal::getSupportedIfaceName(uint32_t iface_type,
|
||||
return res;
|
||||
}
|
||||
|
||||
wifi_error WifiLegacyHal::multiStaSetPrimaryConnection(
|
||||
const std::string& ifname) {
|
||||
return global_func_table_.wifi_multi_sta_set_primary_connection(
|
||||
global_handle_, getIfaceHandle(ifname));
|
||||
}
|
||||
|
||||
wifi_error WifiLegacyHal::multiStaSetUseCase(wifi_multi_sta_use_case use_case) {
|
||||
return global_func_table_.wifi_multi_sta_set_use_case(global_handle_,
|
||||
use_case);
|
||||
}
|
||||
|
||||
void WifiLegacyHal::invalidate() {
|
||||
global_handle_ = nullptr;
|
||||
iface_name_to_handle_.clear();
|
||||
|
||||
@@ -382,6 +382,10 @@ class WifiLegacyHal {
|
||||
virtual wifi_error deleteVirtualInterface(const std::string& ifname);
|
||||
wifi_error getSupportedIfaceName(uint32_t iface_type, std::string& ifname);
|
||||
|
||||
// STA + STA functions
|
||||
virtual wifi_error multiStaSetPrimaryConnection(const std::string& ifname);
|
||||
virtual wifi_error multiStaSetUseCase(wifi_multi_sta_use_case use_case);
|
||||
|
||||
private:
|
||||
// Retrieve interface handles for all the available interfaces.
|
||||
wifi_error retrieveIfaceHandles();
|
||||
|
||||
@@ -147,6 +147,8 @@ bool initHalFuncTableWithStubs(wifi_hal_fn* hal_fn) {
|
||||
populateStubFor(&hal_fn->wifi_get_supported_iface_name);
|
||||
populateStubFor(&hal_fn->wifi_early_initialize);
|
||||
populateStubFor(&hal_fn->wifi_get_chip_feature_set);
|
||||
populateStubFor(&hal_fn->wifi_multi_sta_set_primary_connection);
|
||||
populateStubFor(&hal_fn->wifi_multi_sta_set_use_case);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -163,6 +163,13 @@ Return<void> WifiStaIface::getLinkLayerStats_1_3(
|
||||
hidl_status_cb);
|
||||
}
|
||||
|
||||
Return<void> WifiStaIface::getLinkLayerStats_1_5(
|
||||
getLinkLayerStats_1_5_cb hidl_status_cb) {
|
||||
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
|
||||
&WifiStaIface::getLinkLayerStatsInternal_1_5,
|
||||
hidl_status_cb);
|
||||
}
|
||||
|
||||
Return<void> WifiStaIface::startRssiMonitoring(
|
||||
uint32_t cmd_id, int32_t max_rssi, int32_t min_rssi,
|
||||
startRssiMonitoring_cb hidl_status_cb) {
|
||||
@@ -470,6 +477,11 @@ WifiStaIface::getLinkLayerStatsInternal() {
|
||||
|
||||
std::pair<WifiStatus, V1_3::StaLinkLayerStats>
|
||||
WifiStaIface::getLinkLayerStatsInternal_1_3() {
|
||||
return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}};
|
||||
}
|
||||
|
||||
std::pair<WifiStatus, V1_5::StaLinkLayerStats>
|
||||
WifiStaIface::getLinkLayerStatsInternal_1_5() {
|
||||
legacy_hal::wifi_error legacy_status;
|
||||
legacy_hal::LinkLayerStats legacy_stats;
|
||||
std::tie(legacy_status, legacy_stats) =
|
||||
@@ -477,7 +489,7 @@ WifiStaIface::getLinkLayerStatsInternal_1_3() {
|
||||
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
|
||||
return {createWifiStatusFromLegacyError(legacy_status), {}};
|
||||
}
|
||||
V1_3::StaLinkLayerStats hidl_stats;
|
||||
V1_5::StaLinkLayerStats hidl_stats;
|
||||
if (!hidl_struct_util::convertLegacyLinkLayerStatsToHidl(legacy_stats,
|
||||
&hidl_stats)) {
|
||||
return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
#include <android-base/macros.h>
|
||||
#include <android/hardware/wifi/1.0/IWifiStaIfaceEventCallback.h>
|
||||
#include <android/hardware/wifi/1.3/IWifiStaIface.h>
|
||||
#include <android/hardware/wifi/1.5/IWifiStaIface.h>
|
||||
|
||||
#include "hidl_callback_util.h"
|
||||
#include "wifi_iface_util.h"
|
||||
@@ -35,7 +35,7 @@ using namespace android::hardware::wifi::V1_0;
|
||||
/**
|
||||
* HIDL interface object used to control a STA Iface instance.
|
||||
*/
|
||||
class WifiStaIface : public V1_3::IWifiStaIface {
|
||||
class WifiStaIface : public V1_5::IWifiStaIface {
|
||||
public:
|
||||
WifiStaIface(const std::string& ifname,
|
||||
const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
|
||||
@@ -78,6 +78,8 @@ class WifiStaIface : public V1_3::IWifiStaIface {
|
||||
getLinkLayerStats_cb hidl_status_cb) override;
|
||||
Return<void> getLinkLayerStats_1_3(
|
||||
getLinkLayerStats_1_3_cb hidl_status_cb) override;
|
||||
Return<void> getLinkLayerStats_1_5(
|
||||
getLinkLayerStats_1_5_cb hidl_status_cb) override;
|
||||
Return<void> startRssiMonitoring(
|
||||
uint32_t cmd_id, int32_t max_rssi, int32_t min_rssi,
|
||||
startRssiMonitoring_cb hidl_status_cb) override;
|
||||
@@ -138,6 +140,8 @@ class WifiStaIface : public V1_3::IWifiStaIface {
|
||||
std::pair<WifiStatus, V1_0::StaLinkLayerStats> getLinkLayerStatsInternal();
|
||||
std::pair<WifiStatus, V1_3::StaLinkLayerStats>
|
||||
getLinkLayerStatsInternal_1_3();
|
||||
std::pair<WifiStatus, V1_5::StaLinkLayerStats>
|
||||
getLinkLayerStatsInternal_1_5();
|
||||
WifiStatus startRssiMonitoringInternal(uint32_t cmd_id, int32_t max_rssi,
|
||||
int32_t min_rssi);
|
||||
WifiStatus stopRssiMonitoringInternal(uint32_t cmd_id);
|
||||
|
||||
@@ -16,10 +16,14 @@
|
||||
|
||||
package android.hardware.wifi@1.5;
|
||||
|
||||
import @1.0::StaLinkLayerIfaceStats;
|
||||
import @1.0::StaLinkLayerIfacePacketStats;
|
||||
import @1.0::TimeStampInMs;
|
||||
import @1.0::WifiBand;
|
||||
import @1.0::NanCipherSuiteType;
|
||||
import @1.0::NanCapabilities;
|
||||
import @1.2::NanConfigRequestSupplemental;
|
||||
import @1.3::StaLinkLayerRadioStats;
|
||||
|
||||
/**
|
||||
* Wifi bands defined in 80211 spec.
|
||||
@@ -48,6 +52,7 @@ struct NanConfigRequestSupplemental {
|
||||
* Baseline information as defined in HAL 1.2.
|
||||
*/
|
||||
@1.2::NanConfigRequestSupplemental V1_2;
|
||||
|
||||
/**
|
||||
* Controls whether NAN instant communication mode is enabled.
|
||||
*/
|
||||
@@ -62,8 +67,43 @@ struct NanCapabilities {
|
||||
* Baseline information as defined in HAL 1.0.
|
||||
*/
|
||||
@1.0::NanCapabilities V1_0;
|
||||
|
||||
/**
|
||||
* Flag to indicate id instant communication mode is supported.
|
||||
*/
|
||||
bool instantCommunicationModeSupportFlag;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Iface statistics for the current connection.
|
||||
*/
|
||||
struct StaLinkLayerIfaceStats {
|
||||
/**
|
||||
* Baseline information as defined in HAL 1.0.
|
||||
*/
|
||||
@1.0::StaLinkLayerIfaceStats V1_0;
|
||||
|
||||
/**
|
||||
* Duty cycle for the iface.
|
||||
* if this iface is being served using time slicing on a radio with one or more ifaces
|
||||
* (i.e MCC), then the duty cycle assigned to this iface in %.
|
||||
* If not using time slicing (i.e SCC or DBS), set to 100.
|
||||
*/
|
||||
uint8_t timeSliceDutyCycleInPercent;
|
||||
};
|
||||
|
||||
/**
|
||||
* Link layer stats retrieved via |getLinkLayerStats|.
|
||||
*/
|
||||
struct StaLinkLayerStats {
|
||||
StaLinkLayerIfaceStats iface;
|
||||
|
||||
vec<StaLinkLayerRadioStats> radios;
|
||||
|
||||
/**
|
||||
* TimeStamp for each stats sample.
|
||||
* This is the absolute milliseconds from boot when these stats were
|
||||
* sampled.
|
||||
*/
|
||||
TimeStampInMs timeStampInMs;
|
||||
};
|
||||
|
||||
@@ -14,6 +14,29 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
cc_test {
|
||||
name: "VtsHalWifiV1_5TargetTest",
|
||||
defaults: ["VtsHalTargetTestDefaults"],
|
||||
srcs: [
|
||||
"wifi_chip_hidl_test.cpp",
|
||||
"wifi_sta_iface_hidl_test.cpp",
|
||||
],
|
||||
static_libs: [
|
||||
"VtsHalWifiV1_0TargetTestUtil",
|
||||
"android.hardware.wifi@1.0",
|
||||
"android.hardware.wifi@1.1",
|
||||
"android.hardware.wifi@1.2",
|
||||
"android.hardware.wifi@1.3",
|
||||
"android.hardware.wifi@1.4",
|
||||
"android.hardware.wifi@1.5",
|
||||
"libwifi-system-iface",
|
||||
],
|
||||
test_suites: [
|
||||
"general-tests",
|
||||
"vts",
|
||||
],
|
||||
}
|
||||
|
||||
// These tests are split out so that they can be conditioned on presence of the
|
||||
// "android.hardware.wifi.aware" feature.
|
||||
cc_test {
|
||||
|
||||
149
wifi/1.5/vts/functional/wifi_chip_hidl_test.cpp
Normal file
149
wifi/1.5/vts/functional/wifi_chip_hidl_test.cpp
Normal file
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache 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 <VtsHalHidlTargetCallbackBase.h>
|
||||
#include <android-base/logging.h>
|
||||
|
||||
#undef NAN // NAN is defined in bionic/libc/include/math.h:38
|
||||
|
||||
#include <android/hardware/wifi/1.4/IWifiChipEventCallback.h>
|
||||
#include <android/hardware/wifi/1.5/IWifi.h>
|
||||
#include <android/hardware/wifi/1.5/IWifiChip.h>
|
||||
#include <android/hardware/wifi/1.5/IWifiStaIface.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <hidl/GtestPrinter.h>
|
||||
#include <hidl/ServiceManagement.h>
|
||||
|
||||
#include "wifi_hidl_call_util.h"
|
||||
#include "wifi_hidl_test_utils.h"
|
||||
|
||||
using ::android::sp;
|
||||
using ::android::hardware::hidl_string;
|
||||
using ::android::hardware::hidl_vec;
|
||||
using ::android::hardware::Return;
|
||||
using ::android::hardware::Void;
|
||||
using ::android::hardware::wifi::V1_0::ChipModeId;
|
||||
using ::android::hardware::wifi::V1_0::IfaceType;
|
||||
using ::android::hardware::wifi::V1_0::IWifiIface;
|
||||
using ::android::hardware::wifi::V1_0::IWifiStaIface;
|
||||
using ::android::hardware::wifi::V1_0::WifiDebugRingBufferStatus;
|
||||
using ::android::hardware::wifi::V1_0::WifiStatus;
|
||||
using ::android::hardware::wifi::V1_0::WifiStatusCode;
|
||||
using ::android::hardware::wifi::V1_4::IWifiChipEventCallback;
|
||||
using ::android::hardware::wifi::V1_5::IWifiChip;
|
||||
|
||||
/**
|
||||
* Fixture to use for all Wifi chip HIDL interface tests.
|
||||
*/
|
||||
class WifiChipHidlTest : public ::testing::TestWithParam<std::string> {
|
||||
public:
|
||||
virtual void SetUp() override {
|
||||
// Make sure to start with a clean state
|
||||
stopWifi(GetInstanceName());
|
||||
|
||||
wifi_chip_ = IWifiChip::castFrom(getWifiChip(GetInstanceName()));
|
||||
ASSERT_NE(nullptr, wifi_chip_.get());
|
||||
}
|
||||
|
||||
virtual void TearDown() override { stopWifi(GetInstanceName()); }
|
||||
|
||||
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, bool expectSuccess) {
|
||||
ChipModeId mode_id;
|
||||
EXPECT_EQ(expectSuccess,
|
||||
configureChipToSupportIfaceType(wifi_chip_, type, &mode_id));
|
||||
return mode_id;
|
||||
}
|
||||
|
||||
WifiStatusCode createStaIface(sp<IWifiStaIface>* sta_iface) {
|
||||
const auto& status_and_iface = HIDL_INVOKE(wifi_chip_, createStaIface);
|
||||
*sta_iface = status_and_iface.second;
|
||||
return status_and_iface.first.code;
|
||||
}
|
||||
|
||||
std::string getIfaceName(const sp<IWifiIface>& iface) {
|
||||
const auto& status_and_name = HIDL_INVOKE(iface, getName);
|
||||
EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_name.first.code);
|
||||
return status_and_name.second;
|
||||
}
|
||||
|
||||
std::vector<sp<IWifiStaIface>> create2StaIfacesIfPossible() {
|
||||
configureChipForIfaceType(IfaceType::STA, true);
|
||||
sp<IWifiStaIface> iface1, iface2;
|
||||
EXPECT_EQ(WifiStatusCode::SUCCESS, createStaIface(&iface1));
|
||||
EXPECT_NE(nullptr, iface1.get());
|
||||
|
||||
// Try to create 2nd iface
|
||||
auto status = createStaIface(&iface2);
|
||||
if (status != WifiStatusCode::SUCCESS) {
|
||||
return {iface1};
|
||||
}
|
||||
EXPECT_NE(nullptr, iface2.get());
|
||||
return {iface1, iface2};
|
||||
}
|
||||
|
||||
sp<IWifiChip> wifi_chip_;
|
||||
|
||||
private:
|
||||
std::string GetInstanceName() { return GetParam(); }
|
||||
};
|
||||
|
||||
/*
|
||||
* setMultiStaPrimaryConnection
|
||||
*
|
||||
* Only run if device supports 2 STA ifaces.
|
||||
*/
|
||||
TEST_P(WifiChipHidlTest, setMultiStaPrimaryConnection) {
|
||||
auto ifaces = create2StaIfacesIfPossible();
|
||||
if (ifaces.size() < 2) {
|
||||
GTEST_SKIP() << "Device does not support more than 1 STA concurrently";
|
||||
}
|
||||
|
||||
const auto& status = HIDL_INVOKE(wifi_chip_, setMultiStaPrimaryConnection,
|
||||
getIfaceName(ifaces.front()));
|
||||
if (status.code != WifiStatusCode::SUCCESS) {
|
||||
EXPECT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, status.code);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* setMultiStaUseCase
|
||||
*
|
||||
* Only run if device supports 2 STA ifaces.
|
||||
*/
|
||||
TEST_P(WifiChipHidlTest, setMultiStaUseCase) {
|
||||
auto ifaces = create2StaIfacesIfPossible();
|
||||
if (ifaces.size() < 2) {
|
||||
GTEST_SKIP() << "Device does not support more than 1 STA concurrently";
|
||||
}
|
||||
|
||||
const auto& status = HIDL_INVOKE(
|
||||
wifi_chip_, setMultiStaUseCase,
|
||||
IWifiChip::MultiStaUseCase::DUAL_STA_TRANSIENT_PREFER_PRIMARY);
|
||||
if (status.code != WifiStatusCode::SUCCESS) {
|
||||
EXPECT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED, status.code);
|
||||
}
|
||||
}
|
||||
|
||||
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiChipHidlTest);
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
PerInstance, WifiChipHidlTest,
|
||||
testing::ValuesIn(android::hardware::getAllHalInstanceNames(
|
||||
::android::hardware::wifi::V1_5::IWifi::descriptor)),
|
||||
android::hardware::PrintInstanceNameToString);
|
||||
117
wifi/1.5/vts/functional/wifi_sta_iface_hidl_test.cpp
Normal file
117
wifi/1.5/vts/functional/wifi_sta_iface_hidl_test.cpp
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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 <numeric>
|
||||
#include <vector>
|
||||
|
||||
#include <android-base/logging.h>
|
||||
|
||||
#include <android/hardware/wifi/1.5/IWifi.h>
|
||||
#include <android/hardware/wifi/1.5/IWifiChip.h>
|
||||
#include <android/hardware/wifi/1.5/IWifiStaIface.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <hidl/GtestPrinter.h>
|
||||
#include <hidl/ServiceManagement.h>
|
||||
|
||||
#include "wifi_hidl_call_util.h"
|
||||
#include "wifi_hidl_test_utils.h"
|
||||
|
||||
using ::android::sp;
|
||||
using ::android::hardware::hidl_array;
|
||||
using ::android::hardware::wifi::V1_0::WifiStatus;
|
||||
using ::android::hardware::wifi::V1_0::WifiStatusCode;
|
||||
using ::android::hardware::wifi::V1_5::IWifiChip;
|
||||
using ::android::hardware::wifi::V1_5::IWifiStaIface;
|
||||
|
||||
/**
|
||||
* Fixture to use for all STA Iface HIDL interface tests.
|
||||
*/
|
||||
class WifiStaIfaceHidlTest : public ::testing::TestWithParam<std::string> {
|
||||
public:
|
||||
virtual void SetUp() override {
|
||||
// Make sure to start with a clean state
|
||||
stopWifi(GetInstanceName());
|
||||
|
||||
wifi_sta_iface_ =
|
||||
IWifiStaIface::castFrom(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;
|
||||
}
|
||||
|
||||
WifiStatusCode createStaIface(sp<IWifiStaIface>* sta_iface) {
|
||||
sp<IWifiChip> wifi_chip =
|
||||
IWifiChip::castFrom(getWifiChip(GetInstanceName()));
|
||||
EXPECT_NE(nullptr, wifi_chip.get());
|
||||
const auto& status_and_iface = HIDL_INVOKE(wifi_chip, createStaIface);
|
||||
*sta_iface = IWifiStaIface::castFrom(status_and_iface.second);
|
||||
return status_and_iface.first.code;
|
||||
}
|
||||
|
||||
sp<IWifiStaIface> wifi_sta_iface_;
|
||||
|
||||
private:
|
||||
std::string GetInstanceName() { return GetParam(); }
|
||||
};
|
||||
|
||||
/*
|
||||
* GetLinkLayerStats_1_5
|
||||
* Ensures that calls to get link layer stats V1_5 will retrieve a non-empty
|
||||
* StaLinkLayerStats after link layer stats collection is enabled.
|
||||
*/
|
||||
TEST_P(WifiStaIfaceHidlTest, GetLinkLayerStats_1_5) {
|
||||
if (!isCapabilitySupported(
|
||||
IWifiStaIface::StaIfaceCapabilityMask::LINK_LAYER_STATS)) {
|
||||
// No-op if link layer stats is not supported.
|
||||
return;
|
||||
}
|
||||
|
||||
// Enable link layer stats collection.
|
||||
EXPECT_EQ(WifiStatusCode::SUCCESS,
|
||||
HIDL_INVOKE(wifi_sta_iface_, enableLinkLayerStatsCollection, true)
|
||||
.code);
|
||||
// Retrieve link layer stats.
|
||||
const auto& status_and_stats =
|
||||
HIDL_INVOKE(wifi_sta_iface_, getLinkLayerStats_1_5);
|
||||
EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_stats.first.code);
|
||||
EXPECT_GT(status_and_stats.second.timeStampInMs, 0u);
|
||||
// Try to create 2nd iface. If yes, it should fill in the duty cycle field.
|
||||
sp<IWifiStaIface> iface;
|
||||
auto status = createStaIface(&iface);
|
||||
if (status == WifiStatusCode::SUCCESS) {
|
||||
EXPECT_GT(status_and_stats.second.iface.timeSliceDutyCycleInPercent,
|
||||
0u);
|
||||
}
|
||||
// Disable link layer stats collection.
|
||||
EXPECT_EQ(
|
||||
WifiStatusCode::SUCCESS,
|
||||
HIDL_INVOKE(wifi_sta_iface_, disableLinkLayerStatsCollection).code);
|
||||
}
|
||||
|
||||
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiStaIfaceHidlTest);
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
PerInstance, WifiStaIfaceHidlTest,
|
||||
testing::ValuesIn(android::hardware::getAllHalInstanceNames(
|
||||
::android::hardware::wifi::V1_5::IWifi::descriptor)),
|
||||
android::hardware::PrintInstanceNameToString);
|
||||
Reference in New Issue
Block a user