From e9873256d908d013e902400dc1dfd9537a33fc36 Mon Sep 17 00:00:00 2001 From: xshu Date: Tue, 7 Aug 2018 11:04:34 -0700 Subject: [PATCH] Add StaLinkLayerStats V1_3 Gets additional scan related information from legacy_hal up to framework. Bug: 77603419 Test: compile, unit tests Change-Id: I9c948166b640af192c8e6f85ed6c76719e0937a4 --- wifi/1.3/Android.bp | 6 + wifi/1.3/IWifiStaIface.hal | 44 +++++++ wifi/1.3/default/hidl_struct_util.cpp | 26 ++-- wifi/1.3/default/hidl_struct_util.h | 3 +- .../tests/hidl_struct_util_unit_tests.cpp | 112 ++++++++++++++++++ wifi/1.3/default/wifi_sta_iface.cpp | 16 ++- wifi/1.3/default/wifi_sta_iface.h | 10 +- wifi/1.3/types.hal | 68 +++++++++++ 8 files changed, 271 insertions(+), 14 deletions(-) create mode 100644 wifi/1.3/IWifiStaIface.hal create mode 100644 wifi/1.3/types.hal diff --git a/wifi/1.3/Android.bp b/wifi/1.3/Android.bp index 95fbf8346d..5e87c1c760 100644 --- a/wifi/1.3/Android.bp +++ b/wifi/1.3/Android.bp @@ -7,7 +7,9 @@ hidl_interface { enabled: true, }, srcs: [ + "types.hal", "IWifi.hal", + "IWifiStaIface.hal", ], interfaces: [ "android.hardware.wifi@1.0", @@ -15,6 +17,10 @@ hidl_interface { "android.hardware.wifi@1.2", "android.hidl.base@1.0", ], + types: [ + "StaLinkLayerRadioStats", + "StaLinkLayerStats", + ], gen_java: true, } diff --git a/wifi/1.3/IWifiStaIface.hal b/wifi/1.3/IWifiStaIface.hal new file mode 100644 index 0000000000..0dc6128564 --- /dev/null +++ b/wifi/1.3/IWifiStaIface.hal @@ -0,0 +1,44 @@ +/* + * Copyright 2018 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.3; + +import @1.0::WifiStatus; +import @1.2::IWifiStaIface; + +/** + * Interface used to represent a single STA iface. + * + * IWifiChip.createStaIface() may return a @1.3::IWifiStaIface when supported. + */ +interface IWifiStaIface extends @1.2::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_3() generates (WifiStatus status, StaLinkLayerStats stats); +}; diff --git a/wifi/1.3/default/hidl_struct_util.cpp b/wifi/1.3/default/hidl_struct_util.cpp index e793236f5e..c88ddaaae5 100644 --- a/wifi/1.3/default/hidl_struct_util.cpp +++ b/wifi/1.3/default/hidl_struct_util.cpp @@ -785,7 +785,7 @@ bool convertLegacyVectorOfDebugRxPacketFateToHidl( bool convertLegacyLinkLayerStatsToHidl( const legacy_hal::LinkLayerStats& legacy_stats, - StaLinkLayerStats* hidl_stats) { + V1_3::StaLinkLayerStats* hidl_stats) { if (!hidl_stats) { return false; } @@ -826,16 +826,26 @@ bool convertLegacyLinkLayerStatsToHidl( hidl_stats->iface.wmeVoPktStats.retries = legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].retries; // radio legacy_stats conversion. - std::vector hidl_radios_stats; + std::vector hidl_radios_stats; for (const auto& legacy_radio_stats : legacy_stats.radios) { - StaLinkLayerRadioStats hidl_radio_stats; - hidl_radio_stats.onTimeInMs = legacy_radio_stats.stats.on_time; - hidl_radio_stats.txTimeInMs = legacy_radio_stats.stats.tx_time; - hidl_radio_stats.rxTimeInMs = legacy_radio_stats.stats.rx_time; - hidl_radio_stats.onTimeInMsForScan = + V1_3::StaLinkLayerRadioStats hidl_radio_stats; + hidl_radio_stats.V1_0.onTimeInMs = legacy_radio_stats.stats.on_time; + hidl_radio_stats.V1_0.txTimeInMs = legacy_radio_stats.stats.tx_time; + hidl_radio_stats.V1_0.rxTimeInMs = legacy_radio_stats.stats.rx_time; + hidl_radio_stats.V1_0.onTimeInMsForScan = legacy_radio_stats.stats.on_time_scan; - hidl_radio_stats.txTimeInMsPerLevel = + hidl_radio_stats.V1_0.txTimeInMsPerLevel = legacy_radio_stats.tx_time_per_levels; + hidl_radio_stats.onTimeInMsForNanScan = + legacy_radio_stats.stats.on_time_nbd; + hidl_radio_stats.onTimeInMsForBgScan = + legacy_radio_stats.stats.on_time_gscan; + hidl_radio_stats.onTimeInMsForRoamScan = + legacy_radio_stats.stats.on_time_roam_scan; + hidl_radio_stats.onTimeInMsForPnoScan = + legacy_radio_stats.stats.on_time_pno_scan; + hidl_radio_stats.onTimeInMsForHs20Scan = + legacy_radio_stats.stats.on_time_hs20; hidl_radios_stats.push_back(hidl_radio_stats); } hidl_stats->radios = hidl_radios_stats; diff --git a/wifi/1.3/default/hidl_struct_util.h b/wifi/1.3/default/hidl_struct_util.h index e2ba00c1e8..8df484d063 100644 --- a/wifi/1.3/default/hidl_struct_util.h +++ b/wifi/1.3/default/hidl_struct_util.h @@ -24,6 +24,7 @@ #include #include #include +#include #include "wifi_legacy_hal.h" @@ -89,7 +90,7 @@ bool convertLegacyVectorOfCachedGscanResultsToHidl( std::vector* hidl_scan_datas); bool convertLegacyLinkLayerStatsToHidl( const legacy_hal::LinkLayerStats& legacy_stats, - StaLinkLayerStats* hidl_stats); + V1_3::StaLinkLayerStats* hidl_stats); bool convertLegacyRoamingCapabilitiesToHidl( const legacy_hal::wifi_roaming_capabilities& legacy_caps, StaRoamingCapabilities* hidl_caps); diff --git a/wifi/1.3/default/tests/hidl_struct_util_unit_tests.cpp b/wifi/1.3/default/tests/hidl_struct_util_unit_tests.cpp index 4cd3719293..d600a2be4d 100644 --- a/wifi/1.3/default/tests/hidl_struct_util_unit_tests.cpp +++ b/wifi/1.3/default/tests/hidl_struct_util_unit_tests.cpp @@ -126,6 +126,118 @@ TEST_F(HidlStructUtilTest, CanConvertLegacyWifiMacInfosToHidlWithTwoMac) { EXPECT_EQ(static_cast(legacy_iface_info2.channel), hidl_iface_info2.channel); } + +TEST_F(HidlStructUtilTest, canConvertLegacyLinkLayerStatsToHidl) { + legacy_hal::LinkLayerStats legacy_stats{}; + legacy_stats.radios.push_back(legacy_hal::LinkLayerRadioStats{}); + legacy_stats.radios.push_back(legacy_hal::LinkLayerRadioStats{}); + legacy_stats.iface.beacon_rx = rand(); + legacy_stats.iface.rssi_mgmt = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].rx_mpdu = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].tx_mpdu = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].mpdu_lost = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].retries = rand(); + + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].rx_mpdu = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].tx_mpdu = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].mpdu_lost = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].retries = rand(); + + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].rx_mpdu = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].tx_mpdu = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].mpdu_lost = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].retries = rand(); + + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].rx_mpdu = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].tx_mpdu = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].mpdu_lost = rand(); + legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].retries = rand(); + + for (auto& radio : legacy_stats.radios) { + radio.stats.on_time = rand(); + radio.stats.tx_time = rand(); + radio.stats.rx_time = rand(); + radio.stats.on_time_scan = rand(); + radio.stats.on_time_nbd = rand(); + radio.stats.on_time_gscan = rand(); + radio.stats.on_time_roam_scan = rand(); + radio.stats.on_time_pno_scan = rand(); + radio.stats.on_time_hs20 = rand(); + for (int i = 0; i < 4; i++) { + radio.tx_time_per_levels.push_back(rand()); + } + } + + V1_3::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.ac[legacy_hal::WIFI_AC_BE].rx_mpdu, + converted.iface.wmeBePktStats.rxMpdu); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].tx_mpdu, + converted.iface.wmeBePktStats.txMpdu); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].mpdu_lost, + converted.iface.wmeBePktStats.lostMpdu); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].retries, + converted.iface.wmeBePktStats.retries); + + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].rx_mpdu, + converted.iface.wmeBkPktStats.rxMpdu); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].tx_mpdu, + converted.iface.wmeBkPktStats.txMpdu); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].mpdu_lost, + converted.iface.wmeBkPktStats.lostMpdu); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].retries, + converted.iface.wmeBkPktStats.retries); + + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].rx_mpdu, + converted.iface.wmeViPktStats.rxMpdu); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].tx_mpdu, + converted.iface.wmeViPktStats.txMpdu); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].mpdu_lost, + converted.iface.wmeViPktStats.lostMpdu); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].retries, + converted.iface.wmeViPktStats.retries); + + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].rx_mpdu, + converted.iface.wmeVoPktStats.rxMpdu); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].tx_mpdu, + converted.iface.wmeVoPktStats.txMpdu); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].mpdu_lost, + converted.iface.wmeVoPktStats.lostMpdu); + EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].retries, + converted.iface.wmeVoPktStats.retries); + + EXPECT_EQ(legacy_stats.radios.size(), converted.radios.size()); + for (int i = 0; i < legacy_stats.radios.size(); i++) { + EXPECT_EQ(legacy_stats.radios[i].stats.on_time, + converted.radios[i].V1_0.onTimeInMs); + EXPECT_EQ(legacy_stats.radios[i].stats.tx_time, + converted.radios[i].V1_0.txTimeInMs); + EXPECT_EQ(legacy_stats.radios[i].stats.rx_time, + converted.radios[i].V1_0.rxTimeInMs); + EXPECT_EQ(legacy_stats.radios[i].stats.on_time_scan, + converted.radios[i].V1_0.onTimeInMsForScan); + EXPECT_EQ(legacy_stats.radios[i].tx_time_per_levels.size(), + converted.radios[i].V1_0.txTimeInMsPerLevel.size()); + for (int j = 0; j < legacy_stats.radios[i].tx_time_per_levels.size(); + j++) { + EXPECT_EQ(legacy_stats.radios[i].tx_time_per_levels[j], + converted.radios[i].V1_0.txTimeInMsPerLevel[j]); + } + EXPECT_EQ(legacy_stats.radios[i].stats.on_time_nbd, + converted.radios[i].onTimeInMsForNanScan); + EXPECT_EQ(legacy_stats.radios[i].stats.on_time_gscan, + converted.radios[i].onTimeInMsForBgScan); + EXPECT_EQ(legacy_stats.radios[i].stats.on_time_roam_scan, + converted.radios[i].onTimeInMsForRoamScan); + EXPECT_EQ(legacy_stats.radios[i].stats.on_time_pno_scan, + converted.radios[i].onTimeInMsForPnoScan); + EXPECT_EQ(legacy_stats.radios[i].stats.on_time_hs20, + converted.radios[i].onTimeInMsForHs20Scan); + } +} } // namespace implementation } // namespace V1_3 } // namespace wifi diff --git a/wifi/1.3/default/wifi_sta_iface.cpp b/wifi/1.3/default/wifi_sta_iface.cpp index 63341dfb4a..b0fa1aef6b 100644 --- a/wifi/1.3/default/wifi_sta_iface.cpp +++ b/wifi/1.3/default/wifi_sta_iface.cpp @@ -152,6 +152,13 @@ Return WifiStaIface::getLinkLayerStats( hidl_status_cb); } +Return WifiStaIface::getLinkLayerStats_1_3( + getLinkLayerStats_1_3_cb hidl_status_cb) { + return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID, + &WifiStaIface::getLinkLayerStatsInternal_1_3, + hidl_status_cb); +} + Return WifiStaIface::startRssiMonitoring( uint32_t cmd_id, int32_t max_rssi, int32_t min_rssi, startRssiMonitoring_cb hidl_status_cb) { @@ -445,8 +452,13 @@ WifiStatus WifiStaIface::disableLinkLayerStatsCollectionInternal() { return createWifiStatusFromLegacyError(legacy_status); } -std::pair +std::pair WifiStaIface::getLinkLayerStatsInternal() { + return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}}; +} + +std::pair +WifiStaIface::getLinkLayerStatsInternal_1_3() { legacy_hal::wifi_error legacy_status; legacy_hal::LinkLayerStats legacy_stats; std::tie(legacy_status, legacy_stats) = @@ -454,7 +466,7 @@ WifiStaIface::getLinkLayerStatsInternal() { if (legacy_status != legacy_hal::WIFI_SUCCESS) { return {createWifiStatusFromLegacyError(legacy_status), {}}; } - StaLinkLayerStats hidl_stats; + V1_3::StaLinkLayerStats hidl_stats; if (!hidl_struct_util::convertLegacyLinkLayerStatsToHidl(legacy_stats, &hidl_stats)) { return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}}; diff --git a/wifi/1.3/default/wifi_sta_iface.h b/wifi/1.3/default/wifi_sta_iface.h index 0fc61e2857..bc3090f241 100644 --- a/wifi/1.3/default/wifi_sta_iface.h +++ b/wifi/1.3/default/wifi_sta_iface.h @@ -19,7 +19,7 @@ #include #include -#include +#include #include @@ -36,7 +36,7 @@ using namespace android::hardware::wifi::V1_0; /** * HIDL interface object used to control a STA Iface instance. */ -class WifiStaIface : public V1_2::IWifiStaIface { +class WifiStaIface : public V1_3::IWifiStaIface { public: WifiStaIface(const std::string& ifname, const std::weak_ptr legacy_hal); @@ -75,6 +75,8 @@ class WifiStaIface : public V1_2::IWifiStaIface { disableLinkLayerStatsCollection_cb hidl_status_cb) override; Return getLinkLayerStats( getLinkLayerStats_cb hidl_status_cb) override; + Return getLinkLayerStats_1_3( + getLinkLayerStats_1_3_cb hidl_status_cb) override; Return startRssiMonitoring( uint32_t cmd_id, int32_t max_rssi, int32_t min_rssi, startRssiMonitoring_cb hidl_status_cb) override; @@ -130,7 +132,9 @@ class WifiStaIface : public V1_2::IWifiStaIface { WifiStatus stopBackgroundScanInternal(uint32_t cmd_id); WifiStatus enableLinkLayerStatsCollectionInternal(bool debug); WifiStatus disableLinkLayerStatsCollectionInternal(); - std::pair getLinkLayerStatsInternal(); + std::pair getLinkLayerStatsInternal(); + std::pair + getLinkLayerStatsInternal_1_3(); WifiStatus startRssiMonitoringInternal(uint32_t cmd_id, int32_t max_rssi, int32_t min_rssi); WifiStatus stopRssiMonitoringInternal(uint32_t cmd_id); diff --git a/wifi/1.3/types.hal b/wifi/1.3/types.hal new file mode 100644 index 0000000000..4585ff31b6 --- /dev/null +++ b/wifi/1.3/types.hal @@ -0,0 +1,68 @@ +/* + * Copyright 2018 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.3; + +import @1.0::StaLinkLayerRadioStats; +import @1.0::StaLinkLayerIfaceStats; +import @1.0::TimeStampInMs; + +struct StaLinkLayerRadioStats { + /** + * Baseline information as defined in HAL 1.0. + */ + @1.0::StaLinkLayerRadioStats V1_0; + + /** + * Total time for which the radio is awake due to NAN scan since boot or crash. + */ + uint32_t onTimeInMsForNanScan; + + /** + * Total time for which the radio is awake due to background scan since boot or crash. + */ + uint32_t onTimeInMsForBgScan; + + /** + * Total time for which the radio is awake due to roam scan since boot or crash. + */ + uint32_t onTimeInMsForRoamScan; + + /** + * Total time for which the radio is awake due to PNO scan since boot or crash. + */ + uint32_t onTimeInMsForPnoScan; + + /** + * Total time for which the radio is awake due to Hotspot 2.0 scans and GAS exchange since boot + * or crash. + */ + uint32_t onTimeInMsForHs20Scan; +}; + +/** + * Link layer stats retrieved via |getLinkLayerStats|. + */ +struct StaLinkLayerStats { + StaLinkLayerIfaceStats iface; + vec radios; + /** + * TimeStamp for each stats sample. + * This is the absolute milliseconds from boot when these stats were + * sampled. + */ + TimeStampInMs timeStampInMs; +}; \ No newline at end of file