Merge changes from topic "Wi-Fi7: MLO Stats"
* changes:
wifi: Add Support for Multi-Link Layer stats in shim layer
wifi: Add multi link layer stats support to AIDL
wifi: Update vts test for GetLinkLayerStats()
wifi: Add unit test for multi link stats conversion
wifi: Fix unit test for LegacyLinkLayerStats
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerIfaceStats.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerIfaceStats.aidl
index cf68fc6..a419207 100644
--- a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerIfaceStats.aidl
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerIfaceStats.aidl
@@ -34,16 +34,5 @@
package android.hardware.wifi;
@VintfStability
parcelable StaLinkLayerIfaceStats {
- int beaconRx;
- int avgRssiMgmt;
- android.hardware.wifi.StaLinkLayerIfacePacketStats wmeBePktStats;
- android.hardware.wifi.StaLinkLayerIfacePacketStats wmeBkPktStats;
- android.hardware.wifi.StaLinkLayerIfacePacketStats wmeViPktStats;
- android.hardware.wifi.StaLinkLayerIfacePacketStats wmeVoPktStats;
- byte timeSliceDutyCycleInPercent;
- android.hardware.wifi.StaLinkLayerIfaceContentionTimeStats wmeBeContentionTimeStats;
- android.hardware.wifi.StaLinkLayerIfaceContentionTimeStats wmeBkContentionTimeStats;
- android.hardware.wifi.StaLinkLayerIfaceContentionTimeStats wmeViContentionTimeStats;
- android.hardware.wifi.StaLinkLayerIfaceContentionTimeStats wmeVoContentionTimeStats;
- android.hardware.wifi.StaPeerInfo[] peers;
+ android.hardware.wifi.StaLinkLayerLinkStats[] links;
}
diff --git a/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerLinkStats.aidl b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerLinkStats.aidl
new file mode 100644
index 0000000..714bba8
--- /dev/null
+++ b/wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerLinkStats.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.wifi;
+@VintfStability
+parcelable StaLinkLayerLinkStats {
+ int linkId;
+ int beaconRx;
+ int avgRssiMgmt;
+ android.hardware.wifi.StaLinkLayerIfacePacketStats wmeBePktStats;
+ android.hardware.wifi.StaLinkLayerIfacePacketStats wmeBkPktStats;
+ android.hardware.wifi.StaLinkLayerIfacePacketStats wmeViPktStats;
+ android.hardware.wifi.StaLinkLayerIfacePacketStats wmeVoPktStats;
+ byte timeSliceDutyCycleInPercent;
+ android.hardware.wifi.StaLinkLayerIfaceContentionTimeStats wmeBeContentionTimeStats;
+ android.hardware.wifi.StaLinkLayerIfaceContentionTimeStats wmeBkContentionTimeStats;
+ android.hardware.wifi.StaLinkLayerIfaceContentionTimeStats wmeViContentionTimeStats;
+ android.hardware.wifi.StaLinkLayerIfaceContentionTimeStats wmeVoContentionTimeStats;
+ android.hardware.wifi.StaPeerInfo[] peers;
+}
diff --git a/wifi/aidl/android/hardware/wifi/StaLinkLayerIfaceStats.aidl b/wifi/aidl/android/hardware/wifi/StaLinkLayerIfaceStats.aidl
index 78f8caa..3f8718f 100644
--- a/wifi/aidl/android/hardware/wifi/StaLinkLayerIfaceStats.aidl
+++ b/wifi/aidl/android/hardware/wifi/StaLinkLayerIfaceStats.aidl
@@ -16,64 +16,13 @@
package android.hardware.wifi;
-import android.hardware.wifi.StaLinkLayerIfaceContentionTimeStats;
-import android.hardware.wifi.StaLinkLayerIfacePacketStats;
-import android.hardware.wifi.StaPeerInfo;
+import android.hardware.wifi.StaLinkLayerLinkStats;
/**
- * Iface statistics for the current connection.
+ * Iface statistics for the current connection. Current connection may have
+ * single or multiple links.
*/
@VintfStability
parcelable StaLinkLayerIfaceStats {
- /**
- * Number beacons received from the connected AP.
- */
- int beaconRx;
- /**
- * Access Point Beacon and Management frames RSSI (averaged).
- */
- int avgRssiMgmt;
- /**
- * WME Best Effort Access Category packet counters.
- */
- StaLinkLayerIfacePacketStats wmeBePktStats;
- /**
- * WME Background Access Category packet counters.
- */
- StaLinkLayerIfacePacketStats wmeBkPktStats;
- /**
- * WME Video Access Category packet counters.
- */
- StaLinkLayerIfacePacketStats wmeViPktStats;
- /**
- * WME Voice Access Category packet counters.
- */
- StaLinkLayerIfacePacketStats wmeVoPktStats;
- /**
- * 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.
- */
- byte timeSliceDutyCycleInPercent;
- /**
- * WME Best Effort (BE) Access Category (AC) contention time statistics.
- */
- StaLinkLayerIfaceContentionTimeStats wmeBeContentionTimeStats;
- /**
- * WME Background (BK) Access Category (AC) contention time statistics.
- */
- StaLinkLayerIfaceContentionTimeStats wmeBkContentionTimeStats;
- /**
- * WME Video (VI) Access Category (AC) contention time statistics.
- */
- StaLinkLayerIfaceContentionTimeStats wmeViContentionTimeStats;
- /**
- * WME Voice (VO) Access Category (AC) contention time statistics.
- */
- StaLinkLayerIfaceContentionTimeStats wmeVoContentionTimeStats;
- /**
- * Per peer statistics.
- */
- StaPeerInfo[] peers;
+ StaLinkLayerLinkStats[] links;
}
diff --git a/wifi/aidl/android/hardware/wifi/StaLinkLayerLinkStats.aidl b/wifi/aidl/android/hardware/wifi/StaLinkLayerLinkStats.aidl
new file mode 100644
index 0000000..cf1a867
--- /dev/null
+++ b/wifi/aidl/android/hardware/wifi/StaLinkLayerLinkStats.aidl
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2022 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;
+
+import android.hardware.wifi.StaLinkLayerIfaceContentionTimeStats;
+import android.hardware.wifi.StaLinkLayerIfacePacketStats;
+import android.hardware.wifi.StaPeerInfo;
+
+/**
+ * Per Link statistics for the current connection. For MLO, this is
+ * the statistics for one link in the connection.
+ */
+@VintfStability
+parcelable StaLinkLayerLinkStats {
+ /**
+ * Identifier for the link within MLO. For single link operation this field
+ * is not relevant and can be set to 0.
+ */
+ int linkId;
+ /**
+ * Number of beacons received from the connected AP on the link.
+ */
+ int beaconRx;
+ /**
+ * Access Point Beacon and Management frames RSSI (averaged) on the link.
+ */
+ int avgRssiMgmt;
+ /**
+ * WME Best Effort Access Category packet counters on the link.
+ */
+ StaLinkLayerIfacePacketStats wmeBePktStats;
+ /**
+ * WME Background Access Category packet counters on the link.
+ */
+ StaLinkLayerIfacePacketStats wmeBkPktStats;
+ /**
+ * WME Video Access Category packet counters on the link.
+ */
+ StaLinkLayerIfacePacketStats wmeViPktStats;
+ /**
+ * WME Voice Access Category packet counters on the link.
+ */
+ StaLinkLayerIfacePacketStats wmeVoPktStats;
+ /**
+ * Duty cycle for the link.
+ * If this link is being served using time slicing on a radio with one or
+ * more links then the duty cycle assigned to this link in %. If not using
+ * time slicing, set to 100.
+ */
+ byte timeSliceDutyCycleInPercent;
+ /**
+ * WME Best Effort (BE) Access Category (AC) contention time statistics on
+ * the link.
+ */
+ StaLinkLayerIfaceContentionTimeStats wmeBeContentionTimeStats;
+ /**
+ * WME Background (BK) Access Category (AC) contention time statistics on
+ * the link.
+ */
+ StaLinkLayerIfaceContentionTimeStats wmeBkContentionTimeStats;
+ /**
+ * WME Video (VI) Access Category (AC) contention time statistics on the
+ * link.
+ */
+ StaLinkLayerIfaceContentionTimeStats wmeViContentionTimeStats;
+ /**
+ * WME Voice (VO) Access Category (AC) contention time statistics on the
+ * link.
+ */
+ StaLinkLayerIfaceContentionTimeStats wmeVoContentionTimeStats;
+ /**
+ * Per peer statistics for the link.
+ */
+ StaPeerInfo[] peers;
+}
diff --git a/wifi/aidl/default/aidl_struct_util.cpp b/wifi/aidl/default/aidl_struct_util.cpp
index ec8b396..fe7579b 100644
--- a/wifi/aidl/default/aidl_struct_util.cpp
+++ b/wifi/aidl/default/aidl_struct_util.cpp
@@ -940,69 +940,158 @@
return true;
}
+bool convertLegacyLinkLayerMlStatsToAidl(const legacy_hal::LinkLayerMlStats& legacy_ml_stats,
+ StaLinkLayerStats* aidl_stats) {
+ if (!aidl_stats) {
+ return false;
+ }
+ *aidl_stats = {};
+ std::vector<StaLinkLayerLinkStats> links;
+ // Iterate over each links
+ for (const auto& link : legacy_ml_stats.links) {
+ StaLinkLayerLinkStats linkStats = {};
+ linkStats.linkId = link.stat.link_id;
+ linkStats.beaconRx = link.stat.beacon_rx;
+ linkStats.avgRssiMgmt = link.stat.rssi_mgmt;
+ linkStats.wmeBePktStats.rxMpdu = link.stat.ac[legacy_hal::WIFI_AC_BE].rx_mpdu;
+ linkStats.wmeBePktStats.txMpdu = link.stat.ac[legacy_hal::WIFI_AC_BE].tx_mpdu;
+ linkStats.wmeBePktStats.lostMpdu = link.stat.ac[legacy_hal::WIFI_AC_BE].mpdu_lost;
+ linkStats.wmeBePktStats.retries = link.stat.ac[legacy_hal::WIFI_AC_BE].retries;
+ linkStats.wmeBeContentionTimeStats.contentionTimeMinInUsec =
+ link.stat.ac[legacy_hal::WIFI_AC_BE].contention_time_min;
+ linkStats.wmeBeContentionTimeStats.contentionTimeMaxInUsec =
+ link.stat.ac[legacy_hal::WIFI_AC_BE].contention_time_max;
+ linkStats.wmeBeContentionTimeStats.contentionTimeAvgInUsec =
+ link.stat.ac[legacy_hal::WIFI_AC_BE].contention_time_avg;
+ linkStats.wmeBeContentionTimeStats.contentionNumSamples =
+ link.stat.ac[legacy_hal::WIFI_AC_BE].contention_num_samples;
+ linkStats.wmeBkPktStats.rxMpdu = link.stat.ac[legacy_hal::WIFI_AC_BK].rx_mpdu;
+ linkStats.wmeBkPktStats.txMpdu = link.stat.ac[legacy_hal::WIFI_AC_BK].tx_mpdu;
+ linkStats.wmeBkPktStats.lostMpdu = link.stat.ac[legacy_hal::WIFI_AC_BK].mpdu_lost;
+ linkStats.wmeBkPktStats.retries = link.stat.ac[legacy_hal::WIFI_AC_BK].retries;
+ linkStats.wmeBkContentionTimeStats.contentionTimeMinInUsec =
+ link.stat.ac[legacy_hal::WIFI_AC_BK].contention_time_min;
+ linkStats.wmeBkContentionTimeStats.contentionTimeMaxInUsec =
+ link.stat.ac[legacy_hal::WIFI_AC_BK].contention_time_max;
+ linkStats.wmeBkContentionTimeStats.contentionTimeAvgInUsec =
+ link.stat.ac[legacy_hal::WIFI_AC_BK].contention_time_avg;
+ linkStats.wmeBkContentionTimeStats.contentionNumSamples =
+ link.stat.ac[legacy_hal::WIFI_AC_BK].contention_num_samples;
+ linkStats.wmeViPktStats.rxMpdu = link.stat.ac[legacy_hal::WIFI_AC_VI].rx_mpdu;
+ linkStats.wmeViPktStats.txMpdu = link.stat.ac[legacy_hal::WIFI_AC_VI].tx_mpdu;
+ linkStats.wmeViPktStats.lostMpdu = link.stat.ac[legacy_hal::WIFI_AC_VI].mpdu_lost;
+ linkStats.wmeViPktStats.retries = link.stat.ac[legacy_hal::WIFI_AC_VI].retries;
+ linkStats.wmeViContentionTimeStats.contentionTimeMinInUsec =
+ link.stat.ac[legacy_hal::WIFI_AC_VI].contention_time_min;
+ linkStats.wmeViContentionTimeStats.contentionTimeMaxInUsec =
+ link.stat.ac[legacy_hal::WIFI_AC_VI].contention_time_max;
+ linkStats.wmeViContentionTimeStats.contentionTimeAvgInUsec =
+ link.stat.ac[legacy_hal::WIFI_AC_VI].contention_time_avg;
+ linkStats.wmeViContentionTimeStats.contentionNumSamples =
+ link.stat.ac[legacy_hal::WIFI_AC_VI].contention_num_samples;
+ linkStats.wmeVoPktStats.rxMpdu = link.stat.ac[legacy_hal::WIFI_AC_VO].rx_mpdu;
+ linkStats.wmeVoPktStats.txMpdu = link.stat.ac[legacy_hal::WIFI_AC_VO].tx_mpdu;
+ linkStats.wmeVoPktStats.lostMpdu = link.stat.ac[legacy_hal::WIFI_AC_VO].mpdu_lost;
+ linkStats.wmeVoPktStats.retries = link.stat.ac[legacy_hal::WIFI_AC_VO].retries;
+ linkStats.wmeVoContentionTimeStats.contentionTimeMinInUsec =
+ link.stat.ac[legacy_hal::WIFI_AC_VO].contention_time_min;
+ linkStats.wmeVoContentionTimeStats.contentionTimeMaxInUsec =
+ link.stat.ac[legacy_hal::WIFI_AC_VO].contention_time_max;
+ linkStats.wmeVoContentionTimeStats.contentionTimeAvgInUsec =
+ link.stat.ac[legacy_hal::WIFI_AC_VO].contention_time_avg;
+ linkStats.wmeVoContentionTimeStats.contentionNumSamples =
+ link.stat.ac[legacy_hal::WIFI_AC_VO].contention_num_samples;
+ linkStats.timeSliceDutyCycleInPercent = link.stat.time_slicing_duty_cycle_percent;
+ // peer info legacy_stats conversion.
+ std::vector<StaPeerInfo> aidl_peers_info_stats;
+ for (const auto& legacy_peer_info_stats : link.peers) {
+ StaPeerInfo aidl_peer_info_stats;
+ if (!convertLegacyPeerInfoStatsToAidl(legacy_peer_info_stats, &aidl_peer_info_stats)) {
+ return false;
+ }
+ aidl_peers_info_stats.push_back(aidl_peer_info_stats);
+ }
+ linkStats.peers = aidl_peers_info_stats;
+ // Push link stats to aidl stats.
+ links.push_back(linkStats);
+ }
+ aidl_stats->iface.links = links;
+ // radio legacy_stats conversion.
+ std::vector<StaLinkLayerRadioStats> aidl_radios_stats;
+ for (const auto& legacy_radio_stats : legacy_ml_stats.radios) {
+ StaLinkLayerRadioStats aidl_radio_stats;
+ if (!convertLegacyLinkLayerRadioStatsToAidl(legacy_radio_stats, &aidl_radio_stats)) {
+ return false;
+ }
+ aidl_radios_stats.push_back(aidl_radio_stats);
+ }
+ aidl_stats->radios = aidl_radios_stats;
+ aidl_stats->timeStampInMs = ::android::uptimeMillis();
+
+ return true;
+}
+
bool convertLegacyLinkLayerStatsToAidl(const legacy_hal::LinkLayerStats& legacy_stats,
StaLinkLayerStats* aidl_stats) {
if (!aidl_stats) {
return false;
}
*aidl_stats = {};
+ std::vector<StaLinkLayerLinkStats> links;
+ StaLinkLayerLinkStats linkStats = {};
// iface legacy_stats conversion.
- aidl_stats->iface.beaconRx = legacy_stats.iface.beacon_rx;
- aidl_stats->iface.avgRssiMgmt = legacy_stats.iface.rssi_mgmt;
- aidl_stats->iface.wmeBePktStats.rxMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].rx_mpdu;
- aidl_stats->iface.wmeBePktStats.txMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].tx_mpdu;
- aidl_stats->iface.wmeBePktStats.lostMpdu =
- legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].mpdu_lost;
- aidl_stats->iface.wmeBePktStats.retries = legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].retries;
- aidl_stats->iface.wmeBeContentionTimeStats.contentionTimeMinInUsec =
+ linkStats.linkId = 0;
+ linkStats.beaconRx = legacy_stats.iface.beacon_rx;
+ linkStats.avgRssiMgmt = legacy_stats.iface.rssi_mgmt;
+ linkStats.wmeBePktStats.rxMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].rx_mpdu;
+ linkStats.wmeBePktStats.txMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].tx_mpdu;
+ linkStats.wmeBePktStats.lostMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].mpdu_lost;
+ linkStats.wmeBePktStats.retries = legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].retries;
+ linkStats.wmeBeContentionTimeStats.contentionTimeMinInUsec =
legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_min;
- aidl_stats->iface.wmeBeContentionTimeStats.contentionTimeMaxInUsec =
+ linkStats.wmeBeContentionTimeStats.contentionTimeMaxInUsec =
legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_max;
- aidl_stats->iface.wmeBeContentionTimeStats.contentionTimeAvgInUsec =
+ linkStats.wmeBeContentionTimeStats.contentionTimeAvgInUsec =
legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_avg;
- aidl_stats->iface.wmeBeContentionTimeStats.contentionNumSamples =
+ linkStats.wmeBeContentionTimeStats.contentionNumSamples =
legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_num_samples;
- aidl_stats->iface.wmeBkPktStats.rxMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].rx_mpdu;
- aidl_stats->iface.wmeBkPktStats.txMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].tx_mpdu;
- aidl_stats->iface.wmeBkPktStats.lostMpdu =
- legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].mpdu_lost;
- aidl_stats->iface.wmeBkPktStats.retries = legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].retries;
- aidl_stats->iface.wmeBkContentionTimeStats.contentionTimeMinInUsec =
+ linkStats.wmeBkPktStats.rxMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].rx_mpdu;
+ linkStats.wmeBkPktStats.txMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].tx_mpdu;
+ linkStats.wmeBkPktStats.lostMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].mpdu_lost;
+ linkStats.wmeBkPktStats.retries = legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].retries;
+ linkStats.wmeBkContentionTimeStats.contentionTimeMinInUsec =
legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_min;
- aidl_stats->iface.wmeBkContentionTimeStats.contentionTimeMaxInUsec =
+ linkStats.wmeBkContentionTimeStats.contentionTimeMaxInUsec =
legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_max;
- aidl_stats->iface.wmeBkContentionTimeStats.contentionTimeAvgInUsec =
+ linkStats.wmeBkContentionTimeStats.contentionTimeAvgInUsec =
legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_avg;
- aidl_stats->iface.wmeBkContentionTimeStats.contentionNumSamples =
+ linkStats.wmeBkContentionTimeStats.contentionNumSamples =
legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_num_samples;
- aidl_stats->iface.wmeViPktStats.rxMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].rx_mpdu;
- aidl_stats->iface.wmeViPktStats.txMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].tx_mpdu;
- aidl_stats->iface.wmeViPktStats.lostMpdu =
- legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].mpdu_lost;
- aidl_stats->iface.wmeViPktStats.retries = legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].retries;
- aidl_stats->iface.wmeViContentionTimeStats.contentionTimeMinInUsec =
+ linkStats.wmeViPktStats.rxMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].rx_mpdu;
+ linkStats.wmeViPktStats.txMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].tx_mpdu;
+ linkStats.wmeViPktStats.lostMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].mpdu_lost;
+ linkStats.wmeViPktStats.retries = legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].retries;
+ linkStats.wmeViContentionTimeStats.contentionTimeMinInUsec =
legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_min;
- aidl_stats->iface.wmeViContentionTimeStats.contentionTimeMaxInUsec =
+ linkStats.wmeViContentionTimeStats.contentionTimeMaxInUsec =
legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_max;
- aidl_stats->iface.wmeViContentionTimeStats.contentionTimeAvgInUsec =
+ linkStats.wmeViContentionTimeStats.contentionTimeAvgInUsec =
legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_avg;
- aidl_stats->iface.wmeViContentionTimeStats.contentionNumSamples =
+ linkStats.wmeViContentionTimeStats.contentionNumSamples =
legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_num_samples;
- aidl_stats->iface.wmeVoPktStats.rxMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].rx_mpdu;
- aidl_stats->iface.wmeVoPktStats.txMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].tx_mpdu;
- aidl_stats->iface.wmeVoPktStats.lostMpdu =
- legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].mpdu_lost;
- aidl_stats->iface.wmeVoPktStats.retries = legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].retries;
- aidl_stats->iface.wmeVoContentionTimeStats.contentionTimeMinInUsec =
+ linkStats.wmeVoPktStats.rxMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].rx_mpdu;
+ linkStats.wmeVoPktStats.txMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].tx_mpdu;
+ linkStats.wmeVoPktStats.lostMpdu = legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].mpdu_lost;
+ linkStats.wmeVoPktStats.retries = legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].retries;
+ linkStats.wmeVoContentionTimeStats.contentionTimeMinInUsec =
legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_min;
- aidl_stats->iface.wmeVoContentionTimeStats.contentionTimeMaxInUsec =
+ linkStats.wmeVoContentionTimeStats.contentionTimeMaxInUsec =
legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_max;
- aidl_stats->iface.wmeVoContentionTimeStats.contentionTimeAvgInUsec =
+ linkStats.wmeVoContentionTimeStats.contentionTimeAvgInUsec =
legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_avg;
- aidl_stats->iface.wmeVoContentionTimeStats.contentionNumSamples =
+ linkStats.wmeVoContentionTimeStats.contentionNumSamples =
legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_num_samples;
- aidl_stats->iface.timeSliceDutyCycleInPercent =
- legacy_stats.iface.info.time_slicing_duty_cycle_percent;
+ linkStats.timeSliceDutyCycleInPercent = legacy_stats.iface.info.time_slicing_duty_cycle_percent;
// peer info legacy_stats conversion.
std::vector<StaPeerInfo> aidl_peers_info_stats;
for (const auto& legacy_peer_info_stats : legacy_stats.peers) {
@@ -1012,7 +1101,9 @@
}
aidl_peers_info_stats.push_back(aidl_peer_info_stats);
}
- aidl_stats->iface.peers = aidl_peers_info_stats;
+ linkStats.peers = aidl_peers_info_stats;
+ links.push_back(linkStats);
+ aidl_stats->iface.links = links;
// radio legacy_stats conversion.
std::vector<StaLinkLayerRadioStats> aidl_radios_stats;
for (const auto& legacy_radio_stats : legacy_stats.radios) {
diff --git a/wifi/aidl/default/aidl_struct_util.h b/wifi/aidl/default/aidl_struct_util.h
index d8e1fd4..ac86755 100644
--- a/wifi/aidl/default/aidl_struct_util.h
+++ b/wifi/aidl/default/aidl_struct_util.h
@@ -89,6 +89,8 @@
bool convertLegacyVectorOfCachedGscanResultsToAidl(
const std::vector<legacy_hal::wifi_cached_scan_results>& legacy_cached_scan_results,
std::vector<StaScanData>* aidl_scan_datas);
+bool convertLegacyLinkLayerMlStatsToAidl(const legacy_hal::LinkLayerMlStats& legacy_ml_stats,
+ StaLinkLayerStats* aidl_stats);
bool convertLegacyLinkLayerStatsToAidl(const legacy_hal::LinkLayerStats& legacy_stats,
StaLinkLayerStats* aidl_stats);
bool convertLegacyRoamingCapabilitiesToAidl(
diff --git a/wifi/aidl/default/tests/aidl_struct_util_unit_tests.cpp b/wifi/aidl/default/tests/aidl_struct_util_unit_tests.cpp
index 4a69c24..c2de012 100644
--- a/wifi/aidl/default/tests/aidl_struct_util_unit_tests.cpp
+++ b/wifi/aidl/default/tests/aidl_struct_util_unit_tests.cpp
@@ -112,6 +112,285 @@
EXPECT_EQ(static_cast<int32_t>(legacy_iface_info2.channel), aidl_iface_info2.channel);
}
+TEST_F(AidlStructUtilTest, canConvertLegacyLinkLayerMlStatsToAidl) {
+ legacy_hal::LinkLayerMlStats legacy_ml_stats{};
+ // Add two radio stats
+ legacy_ml_stats.radios.push_back(legacy_hal::LinkLayerRadioStats{});
+ legacy_ml_stats.radios.push_back(legacy_hal::LinkLayerRadioStats{});
+ // Add two links.
+ legacy_ml_stats.links.push_back(legacy_hal::LinkStats{});
+ legacy_ml_stats.links.push_back(legacy_hal::LinkStats{});
+ // Set stats for each link.
+ for (legacy_hal::LinkStats& link : legacy_ml_stats.links) {
+ link.peers.push_back(legacy_hal::WifiPeerInfo{});
+ link.peers.push_back(legacy_hal::WifiPeerInfo{});
+ link.stat.beacon_rx = rand();
+ link.stat.rssi_mgmt = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_BE].rx_mpdu = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_BE].tx_mpdu = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_BE].mpdu_lost = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_BE].retries = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_BE].contention_time_min = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_BE].contention_time_max = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_BE].contention_time_avg = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_BE].contention_num_samples = rand();
+
+ link.stat.ac[legacy_hal::WIFI_AC_BK].rx_mpdu = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_BK].tx_mpdu = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_BK].mpdu_lost = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_BK].retries = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_BK].contention_time_min = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_BK].contention_time_max = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_BK].contention_time_avg = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_BK].contention_num_samples = rand();
+
+ link.stat.ac[legacy_hal::WIFI_AC_VI].rx_mpdu = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_VI].tx_mpdu = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_VI].mpdu_lost = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_VI].retries = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_VI].contention_time_min = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_VI].contention_time_max = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_VI].contention_time_avg = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_VI].contention_num_samples = rand();
+
+ link.stat.ac[legacy_hal::WIFI_AC_VO].rx_mpdu = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_VO].tx_mpdu = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_VO].mpdu_lost = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_VO].retries = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_VO].contention_time_min = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_VO].contention_time_max = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_VO].contention_time_avg = rand();
+ link.stat.ac[legacy_hal::WIFI_AC_VO].contention_num_samples = rand();
+
+ link.stat.time_slicing_duty_cycle_percent = rand();
+ link.stat.num_peers = 2;
+
+ // Set peer stats for each of the peers.
+ for (auto& peer : link.peers) {
+ peer.peer_info.bssload.sta_count = rand();
+ peer.peer_info.bssload.chan_util = rand();
+ wifi_rate_stat rate_stat1 = {
+ .rate = {3, 1, 2, 5, 0, 0},
+ .tx_mpdu = 0,
+ .rx_mpdu = 1,
+ .mpdu_lost = 2,
+ .retries = 3,
+ .retries_short = 4,
+ .retries_long = 5,
+ };
+ wifi_rate_stat rate_stat2 = {
+ .rate = {2, 2, 1, 6, 0, 1},
+ .tx_mpdu = 6,
+ .rx_mpdu = 7,
+ .mpdu_lost = 8,
+ .retries = 9,
+ .retries_short = 10,
+ .retries_long = 11,
+ };
+ peer.rate_stats.push_back(rate_stat1);
+ peer.rate_stats.push_back(rate_stat2);
+ }
+ }
+ // Set radio stats
+ for (auto& radio : legacy_ml_stats.radios) {
+ radio.stats.radio = rand();
+ 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());
+ }
+
+ legacy_hal::wifi_channel_stat channel_stat1 = {
+ .channel = {legacy_hal::WIFI_CHAN_WIDTH_20, 2437, 2437, 0},
+ .on_time = 0x1111,
+ .cca_busy_time = 0x55,
+ };
+ legacy_hal::wifi_channel_stat channel_stat2 = {
+ .channel = {legacy_hal::WIFI_CHAN_WIDTH_20, 5180, 5180, 0},
+ .on_time = 0x2222,
+ .cca_busy_time = 0x66,
+ };
+ radio.channel_stats.push_back(channel_stat1);
+ radio.channel_stats.push_back(channel_stat2);
+ }
+ // Convert to AIDL
+ StaLinkLayerStats converted{};
+ aidl_struct_util::convertLegacyLinkLayerMlStatsToAidl(legacy_ml_stats, &converted);
+ // Validate
+ int l = 0;
+ for (legacy_hal::LinkStats& link : legacy_ml_stats.links) {
+ EXPECT_EQ(link.stat.link_id, (uint8_t)converted.iface.links[l].linkId);
+ EXPECT_EQ(link.stat.beacon_rx, (uint32_t)converted.iface.links[l].beaconRx);
+ EXPECT_EQ(link.stat.rssi_mgmt, converted.iface.links[l].avgRssiMgmt);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BE].rx_mpdu,
+ converted.iface.links[l].wmeBePktStats.rxMpdu);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BE].tx_mpdu,
+ converted.iface.links[l].wmeBePktStats.txMpdu);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BE].mpdu_lost,
+ converted.iface.links[l].wmeBePktStats.lostMpdu);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BE].retries,
+ converted.iface.links[l].wmeBePktStats.retries);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BE].contention_time_min,
+ (uint32_t)converted.iface.links[l]
+ .wmeBeContentionTimeStats.contentionTimeMinInUsec);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BE].contention_time_max,
+ (uint32_t)converted.iface.links[l]
+ .wmeBeContentionTimeStats.contentionTimeMaxInUsec);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BE].contention_time_avg,
+ (uint32_t)converted.iface.links[l]
+ .wmeBeContentionTimeStats.contentionTimeAvgInUsec);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BE].contention_num_samples,
+ (uint32_t)converted.iface.links[l].wmeBeContentionTimeStats.contentionNumSamples);
+
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BK].rx_mpdu,
+ converted.iface.links[l].wmeBkPktStats.rxMpdu);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BK].tx_mpdu,
+ converted.iface.links[l].wmeBkPktStats.txMpdu);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BK].mpdu_lost,
+ converted.iface.links[l].wmeBkPktStats.lostMpdu);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BK].retries,
+ converted.iface.links[l].wmeBkPktStats.retries);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BK].contention_time_min,
+ (uint32_t)converted.iface.links[l]
+ .wmeBkContentionTimeStats.contentionTimeMinInUsec);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BK].contention_time_max,
+ (uint32_t)converted.iface.links[l]
+ .wmeBkContentionTimeStats.contentionTimeMaxInUsec);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BK].contention_time_avg,
+ (uint32_t)converted.iface.links[l]
+ .wmeBkContentionTimeStats.contentionTimeAvgInUsec);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_BK].contention_num_samples,
+ (uint32_t)converted.iface.links[l].wmeBkContentionTimeStats.contentionNumSamples);
+
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VI].rx_mpdu,
+ converted.iface.links[l].wmeViPktStats.rxMpdu);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VI].tx_mpdu,
+ converted.iface.links[l].wmeViPktStats.txMpdu);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VI].mpdu_lost,
+ converted.iface.links[l].wmeViPktStats.lostMpdu);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VI].retries,
+ converted.iface.links[l].wmeViPktStats.retries);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VI].contention_time_min,
+ (uint32_t)converted.iface.links[l]
+ .wmeViContentionTimeStats.contentionTimeMinInUsec);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VI].contention_time_max,
+ (uint32_t)converted.iface.links[l]
+ .wmeViContentionTimeStats.contentionTimeMaxInUsec);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VI].contention_time_avg,
+ (uint32_t)converted.iface.links[l]
+ .wmeViContentionTimeStats.contentionTimeAvgInUsec);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VI].contention_num_samples,
+ (uint32_t)converted.iface.links[l].wmeViContentionTimeStats.contentionNumSamples);
+
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VO].rx_mpdu,
+ converted.iface.links[l].wmeVoPktStats.rxMpdu);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VO].tx_mpdu,
+ converted.iface.links[l].wmeVoPktStats.txMpdu);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VO].mpdu_lost,
+ converted.iface.links[l].wmeVoPktStats.lostMpdu);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VO].retries,
+ converted.iface.links[l].wmeVoPktStats.retries);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VO].contention_time_min,
+ (uint32_t)converted.iface.links[l]
+ .wmeVoContentionTimeStats.contentionTimeMinInUsec);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VO].contention_time_max,
+ (uint32_t)converted.iface.links[l]
+ .wmeVoContentionTimeStats.contentionTimeMaxInUsec);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VO].contention_time_avg,
+ (uint32_t)converted.iface.links[l]
+ .wmeVoContentionTimeStats.contentionTimeAvgInUsec);
+ EXPECT_EQ(link.stat.ac[legacy_hal::WIFI_AC_VO].contention_num_samples,
+ (uint32_t)converted.iface.links[l].wmeVoContentionTimeStats.contentionNumSamples);
+
+ EXPECT_EQ(link.stat.time_slicing_duty_cycle_percent,
+ converted.iface.links[l].timeSliceDutyCycleInPercent);
+
+ EXPECT_EQ(link.peers.size(), converted.iface.links[l].peers.size());
+ for (size_t i = 0; i < link.peers.size(); i++) {
+ EXPECT_EQ(link.peers[i].peer_info.bssload.sta_count,
+ converted.iface.links[l].peers[i].staCount);
+ EXPECT_EQ(link.peers[i].peer_info.bssload.chan_util,
+ converted.iface.links[l].peers[i].chanUtil);
+ for (size_t j = 0; j < link.peers[i].rate_stats.size(); j++) {
+ EXPECT_EQ(
+ link.peers[i].rate_stats[j].rate.preamble,
+ (uint32_t)converted.iface.links[l].peers[i].rateStats[j].rateInfo.preamble);
+ EXPECT_EQ(link.peers[i].rate_stats[j].rate.nss,
+ (uint32_t)converted.iface.links[l].peers[i].rateStats[j].rateInfo.nss);
+ EXPECT_EQ(link.peers[i].rate_stats[j].rate.bw,
+ (uint32_t)converted.iface.links[l].peers[i].rateStats[j].rateInfo.bw);
+ EXPECT_EQ(link.peers[i].rate_stats[j].rate.rateMcsIdx,
+ (uint32_t)converted.iface.links[l]
+ .peers[i]
+ .rateStats[j]
+ .rateInfo.rateMcsIdx);
+ EXPECT_EQ(link.peers[i].rate_stats[j].tx_mpdu,
+ (uint32_t)converted.iface.links[l].peers[i].rateStats[j].txMpdu);
+ EXPECT_EQ(link.peers[i].rate_stats[j].rx_mpdu,
+ (uint32_t)converted.iface.links[l].peers[i].rateStats[j].rxMpdu);
+ EXPECT_EQ(link.peers[i].rate_stats[j].mpdu_lost,
+ (uint32_t)converted.iface.links[l].peers[i].rateStats[j].mpduLost);
+ EXPECT_EQ(link.peers[i].rate_stats[j].retries,
+ (uint32_t)converted.iface.links[l].peers[i].rateStats[j].retries);
+ }
+ }
+ ++l;
+ } // loop over links
+
+ EXPECT_EQ(legacy_ml_stats.radios.size(), converted.radios.size());
+ for (size_t i = 0; i < legacy_ml_stats.radios.size(); i++) {
+ EXPECT_EQ(legacy_ml_stats.radios[i].stats.radio, converted.radios[i].radioId);
+ EXPECT_EQ(legacy_ml_stats.radios[i].stats.on_time,
+ (uint32_t)converted.radios[i].onTimeInMs);
+ EXPECT_EQ(legacy_ml_stats.radios[i].stats.tx_time,
+ (uint32_t)converted.radios[i].txTimeInMs);
+ EXPECT_EQ(legacy_ml_stats.radios[i].stats.rx_time,
+ (uint32_t)converted.radios[i].rxTimeInMs);
+ EXPECT_EQ(legacy_ml_stats.radios[i].stats.on_time_scan,
+ (uint32_t)converted.radios[i].onTimeInMsForScan);
+ EXPECT_EQ(legacy_ml_stats.radios[i].tx_time_per_levels.size(),
+ converted.radios[i].txTimeInMsPerLevel.size());
+ for (size_t j = 0; j < legacy_ml_stats.radios[i].tx_time_per_levels.size(); j++) {
+ EXPECT_EQ(legacy_ml_stats.radios[i].tx_time_per_levels[j],
+ (uint32_t)converted.radios[i].txTimeInMsPerLevel[j]);
+ }
+ EXPECT_EQ(legacy_ml_stats.radios[i].stats.on_time_nbd,
+ (uint32_t)converted.radios[i].onTimeInMsForNanScan);
+ EXPECT_EQ(legacy_ml_stats.radios[i].stats.on_time_gscan,
+ (uint32_t)converted.radios[i].onTimeInMsForBgScan);
+ EXPECT_EQ(legacy_ml_stats.radios[i].stats.on_time_roam_scan,
+ (uint32_t)converted.radios[i].onTimeInMsForRoamScan);
+ EXPECT_EQ(legacy_ml_stats.radios[i].stats.on_time_pno_scan,
+ (uint32_t)converted.radios[i].onTimeInMsForPnoScan);
+ EXPECT_EQ(legacy_ml_stats.radios[i].stats.on_time_hs20,
+ (uint32_t)converted.radios[i].onTimeInMsForHs20Scan);
+ EXPECT_EQ(legacy_ml_stats.radios[i].channel_stats.size(),
+ converted.radios[i].channelStats.size());
+ for (size_t k = 0; k < legacy_ml_stats.radios[i].channel_stats.size(); k++) {
+ auto& legacy_channel_st = legacy_ml_stats.radios[i].channel_stats[k];
+ EXPECT_EQ(WifiChannelWidthInMhz::WIDTH_20,
+ converted.radios[i].channelStats[k].channel.width);
+ EXPECT_EQ(legacy_channel_st.channel.center_freq,
+ converted.radios[i].channelStats[k].channel.centerFreq);
+ EXPECT_EQ(legacy_channel_st.channel.center_freq0,
+ converted.radios[i].channelStats[k].channel.centerFreq0);
+ EXPECT_EQ(legacy_channel_st.channel.center_freq1,
+ converted.radios[i].channelStats[k].channel.centerFreq1);
+ EXPECT_EQ(legacy_channel_st.cca_busy_time,
+ (uint32_t)converted.radios[i].channelStats[k].ccaBusyTimeInMs);
+ EXPECT_EQ(legacy_channel_st.on_time,
+ (uint32_t)converted.radios[i].channelStats[k].onTimeInMs);
+ }
+ }
+}
+
TEST_F(AidlStructUtilTest, canConvertLegacyLinkLayerStatsToAidl) {
legacy_hal::LinkLayerStats legacy_stats{};
legacy_stats.radios.push_back(legacy_hal::LinkLayerRadioStats{});
@@ -215,78 +494,79 @@
StaLinkLayerStats converted{};
aidl_struct_util::convertLegacyLinkLayerStatsToAidl(legacy_stats, &converted);
- EXPECT_EQ(legacy_stats.iface.beacon_rx, (uint32_t)converted.iface.beaconRx);
- EXPECT_EQ(legacy_stats.iface.rssi_mgmt, converted.iface.avgRssiMgmt);
+ EXPECT_EQ(0, converted.iface.links[0].linkId);
+ EXPECT_EQ(legacy_stats.iface.beacon_rx, (uint32_t)converted.iface.links[0].beaconRx);
+ EXPECT_EQ(legacy_stats.iface.rssi_mgmt, converted.iface.links[0].avgRssiMgmt);
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].rx_mpdu,
- converted.iface.wmeBePktStats.rxMpdu);
+ converted.iface.links[0].wmeBePktStats.rxMpdu);
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].tx_mpdu,
- converted.iface.wmeBePktStats.txMpdu);
+ converted.iface.links[0].wmeBePktStats.txMpdu);
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].mpdu_lost,
- converted.iface.wmeBePktStats.lostMpdu);
+ converted.iface.links[0].wmeBePktStats.lostMpdu);
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].retries,
- converted.iface.wmeBePktStats.retries);
+ converted.iface.links[0].wmeBePktStats.retries);
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_min,
- (uint32_t)converted.iface.wmeBeContentionTimeStats.contentionTimeMinInUsec);
+ (uint32_t)converted.iface.links[0].wmeBeContentionTimeStats.contentionTimeMinInUsec);
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_max,
- (uint32_t)converted.iface.wmeBeContentionTimeStats.contentionTimeMaxInUsec);
+ (uint32_t)converted.iface.links[0].wmeBeContentionTimeStats.contentionTimeMaxInUsec);
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_time_avg,
- (uint32_t)converted.iface.wmeBeContentionTimeStats.contentionTimeAvgInUsec);
+ (uint32_t)converted.iface.links[0].wmeBeContentionTimeStats.contentionTimeAvgInUsec);
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].contention_num_samples,
- (uint32_t)converted.iface.wmeBeContentionTimeStats.contentionNumSamples);
+ (uint32_t)converted.iface.links[0].wmeBeContentionTimeStats.contentionNumSamples);
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].rx_mpdu,
- converted.iface.wmeBkPktStats.rxMpdu);
+ converted.iface.links[0].wmeBkPktStats.rxMpdu);
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].tx_mpdu,
- converted.iface.wmeBkPktStats.txMpdu);
+ converted.iface.links[0].wmeBkPktStats.txMpdu);
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].mpdu_lost,
- converted.iface.wmeBkPktStats.lostMpdu);
+ converted.iface.links[0].wmeBkPktStats.lostMpdu);
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].retries,
- converted.iface.wmeBkPktStats.retries);
+ converted.iface.links[0].wmeBkPktStats.retries);
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_min,
- (uint32_t)converted.iface.wmeBkContentionTimeStats.contentionTimeMinInUsec);
+ (uint32_t)converted.iface.links[0].wmeBkContentionTimeStats.contentionTimeMinInUsec);
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_max,
- (uint32_t)converted.iface.wmeBkContentionTimeStats.contentionTimeMaxInUsec);
+ (uint32_t)converted.iface.links[0].wmeBkContentionTimeStats.contentionTimeMaxInUsec);
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_time_avg,
- (uint32_t)converted.iface.wmeBkContentionTimeStats.contentionTimeAvgInUsec);
+ (uint32_t)converted.iface.links[0].wmeBkContentionTimeStats.contentionTimeAvgInUsec);
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_BK].contention_num_samples,
- (uint32_t)converted.iface.wmeBkContentionTimeStats.contentionNumSamples);
+ (uint32_t)converted.iface.links[0].wmeBkContentionTimeStats.contentionNumSamples);
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].rx_mpdu,
- converted.iface.wmeViPktStats.rxMpdu);
+ converted.iface.links[0].wmeViPktStats.rxMpdu);
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].tx_mpdu,
- converted.iface.wmeViPktStats.txMpdu);
+ converted.iface.links[0].wmeViPktStats.txMpdu);
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].mpdu_lost,
- converted.iface.wmeViPktStats.lostMpdu);
+ converted.iface.links[0].wmeViPktStats.lostMpdu);
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].retries,
- converted.iface.wmeViPktStats.retries);
+ converted.iface.links[0].wmeViPktStats.retries);
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_min,
- (uint32_t)converted.iface.wmeViContentionTimeStats.contentionTimeMinInUsec);
+ (uint32_t)converted.iface.links[0].wmeViContentionTimeStats.contentionTimeMinInUsec);
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_max,
- (uint32_t)converted.iface.wmeViContentionTimeStats.contentionTimeMaxInUsec);
+ (uint32_t)converted.iface.links[0].wmeViContentionTimeStats.contentionTimeMaxInUsec);
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_time_avg,
- (uint32_t)converted.iface.wmeViContentionTimeStats.contentionTimeAvgInUsec);
+ (uint32_t)converted.iface.links[0].wmeViContentionTimeStats.contentionTimeAvgInUsec);
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VI].contention_num_samples,
- (uint32_t)converted.iface.wmeViContentionTimeStats.contentionNumSamples);
+ (uint32_t)converted.iface.links[0].wmeViContentionTimeStats.contentionNumSamples);
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].rx_mpdu,
- converted.iface.wmeVoPktStats.rxMpdu);
+ converted.iface.links[0].wmeVoPktStats.rxMpdu);
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].tx_mpdu,
- converted.iface.wmeVoPktStats.txMpdu);
+ converted.iface.links[0].wmeVoPktStats.txMpdu);
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].mpdu_lost,
- converted.iface.wmeVoPktStats.lostMpdu);
+ converted.iface.links[0].wmeVoPktStats.lostMpdu);
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].retries,
- converted.iface.wmeVoPktStats.retries);
+ converted.iface.links[0].wmeVoPktStats.retries);
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_min,
- (uint32_t)converted.iface.wmeVoContentionTimeStats.contentionTimeMinInUsec);
+ (uint32_t)converted.iface.links[0].wmeVoContentionTimeStats.contentionTimeMinInUsec);
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_max,
- (uint32_t)converted.iface.wmeVoContentionTimeStats.contentionTimeMaxInUsec);
+ (uint32_t)converted.iface.links[0].wmeVoContentionTimeStats.contentionTimeMaxInUsec);
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_time_avg,
- (uint32_t)converted.iface.wmeVoContentionTimeStats.contentionTimeAvgInUsec);
+ (uint32_t)converted.iface.links[0].wmeVoContentionTimeStats.contentionTimeAvgInUsec);
EXPECT_EQ(legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_num_samples,
- (uint32_t)converted.iface.wmeVoContentionTimeStats.contentionNumSamples);
+ (uint32_t)converted.iface.links[0].wmeVoContentionTimeStats.contentionNumSamples);
EXPECT_EQ(legacy_stats.iface.info.time_slicing_duty_cycle_percent,
- converted.iface.timeSliceDutyCycleInPercent);
+ converted.iface.links[0].timeSliceDutyCycleInPercent);
EXPECT_EQ(legacy_stats.radios.size(), converted.radios.size());
for (size_t i = 0; i < legacy_stats.radios.size(); i++) {
@@ -331,29 +611,29 @@
}
}
- EXPECT_EQ(legacy_stats.peers.size(), converted.iface.peers.size());
+ EXPECT_EQ(legacy_stats.peers.size(), converted.iface.links[0].peers.size());
for (size_t i = 0; i < legacy_stats.peers.size(); i++) {
EXPECT_EQ(legacy_stats.peers[i].peer_info.bssload.sta_count,
- converted.iface.peers[i].staCount);
+ converted.iface.links[0].peers[i].staCount);
EXPECT_EQ(legacy_stats.peers[i].peer_info.bssload.chan_util,
- converted.iface.peers[i].chanUtil);
+ converted.iface.links[0].peers[i].chanUtil);
for (size_t j = 0; j < legacy_stats.peers[i].rate_stats.size(); j++) {
EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].rate.preamble,
- (uint32_t)converted.iface.peers[i].rateStats[j].rateInfo.preamble);
+ (uint32_t)converted.iface.links[0].peers[i].rateStats[j].rateInfo.preamble);
EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].rate.nss,
- (uint32_t)converted.iface.peers[i].rateStats[j].rateInfo.nss);
+ (uint32_t)converted.iface.links[0].peers[i].rateStats[j].rateInfo.nss);
EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].rate.bw,
- (uint32_t)converted.iface.peers[i].rateStats[j].rateInfo.bw);
+ (uint32_t)converted.iface.links[0].peers[i].rateStats[j].rateInfo.bw);
EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].rate.rateMcsIdx,
- (uint32_t)converted.iface.peers[i].rateStats[j].rateInfo.rateMcsIdx);
+ (uint32_t)converted.iface.links[0].peers[i].rateStats[j].rateInfo.rateMcsIdx);
EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].tx_mpdu,
- (uint32_t)converted.iface.peers[i].rateStats[j].txMpdu);
+ (uint32_t)converted.iface.links[0].peers[i].rateStats[j].txMpdu);
EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].rx_mpdu,
- (uint32_t)converted.iface.peers[i].rateStats[j].rxMpdu);
+ (uint32_t)converted.iface.links[0].peers[i].rateStats[j].rxMpdu);
EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].mpdu_lost,
- (uint32_t)converted.iface.peers[i].rateStats[j].mpduLost);
+ (uint32_t)converted.iface.links[0].peers[i].rateStats[j].mpduLost);
EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].retries,
- (uint32_t)converted.iface.peers[i].rateStats[j].retries);
+ (uint32_t)converted.iface.links[0].peers[i].rateStats[j].retries);
}
}
}
diff --git a/wifi/aidl/default/wifi_legacy_hal.cpp b/wifi/aidl/default/wifi_legacy_hal.cpp
index e4883d1..83f368e 100644
--- a/wifi/aidl/default/wifi_legacy_hal.cpp
+++ b/wifi/aidl/default/wifi_legacy_hal.cpp
@@ -119,6 +119,16 @@
}
}
+// Callback to be invoked for Multi link layer stats results.
+std::function<void((wifi_request_id, wifi_iface_ml_stat*, int, wifi_radio_stat*))>
+ on_link_layer_ml_stats_result_internal_callback;
+void onSyncLinkLayerMlStatsResult(wifi_request_id id, wifi_iface_ml_stat* iface_ml_stat,
+ int num_radios, wifi_radio_stat* radio_stat) {
+ if (on_link_layer_ml_stats_result_internal_callback) {
+ on_link_layer_ml_stats_result_internal_callback(id, iface_ml_stat, num_radios, radio_stat);
+ }
+}
+
// Callback to be invoked for rssi threshold breach.
std::function<void((wifi_request_id, uint8_t*, int8_t))>
on_rssi_threshold_breached_internal_callback;
@@ -682,10 +692,44 @@
&clear_mask_rsp, 1, &stop_rsp);
}
-std::pair<wifi_error, LinkLayerStats> WifiLegacyHal::getLinkLayerStats(
- const std::string& iface_name) {
- LinkLayerStats link_stats{};
+// Copies wifi_peer_info* to vector<WifiPeerInfo> and returns poiner to next element.
+wifi_peer_info* WifiLegacyHal::copyPeerInfo(wifi_peer_info* peer_ptr,
+ std::vector<WifiPeerInfo> peers) {
+ WifiPeerInfo peer;
+ peer.peer_info = *peer_ptr;
+ if (peer_ptr->num_rate > 0) {
+ // Copy the rate stats.
+ peer.rate_stats.assign(peer_ptr->rate_stats, peer_ptr->rate_stats + peer_ptr->num_rate);
+ }
+ peer.peer_info.num_rate = 0;
+ // Push peer info.
+ peers.push_back(peer);
+ // Return the address of next peer info.
+ return (wifi_peer_info*)((u8*)peer_ptr + sizeof(wifi_peer_info) +
+ (sizeof(wifi_rate_stat) * peer_ptr->num_rate));
+}
+// Copies wifi_link_stat* to vector<LinkStats> and returns poiner to next element.
+wifi_link_stat* WifiLegacyHal::copyLinkStat(wifi_link_stat* stat_ptr,
+ std::vector<LinkStats> stats) {
+ LinkStats linkStat;
+ linkStat.stat = *stat_ptr;
+ wifi_peer_info* l_peer_info_stats_ptr = stat_ptr->peer_info;
+ for (uint32_t i = 0; i < linkStat.stat.num_peers; i++) {
+ l_peer_info_stats_ptr = copyPeerInfo(l_peer_info_stats_ptr, linkStat.peers);
+ }
+ // Copied all peers to linkStat.peers.
+ linkStat.stat.num_peers = 0;
+ // Push link stat.
+ stats.push_back(linkStat);
+ // Read all peers, return the address of next wifi_link_stat.
+ return (wifi_link_stat*)l_peer_info_stats_ptr;
+}
+
+wifi_error WifiLegacyHal::getLinkLayerStats(const std::string& iface_name,
+ LinkLayerStats& link_stats,
+ LinkLayerMlStats& link_ml_stats) {
LinkLayerStats* link_stats_ptr = &link_stats;
+ link_stats_ptr->valid = false;
on_link_layer_stats_result_internal_callback = [&link_stats_ptr](
wifi_request_id /* id */,
@@ -694,6 +738,7 @@
wifi_radio_stat* radio_stats_ptr) {
wifi_radio_stat* l_radio_stats_ptr;
wifi_peer_info* l_peer_info_stats_ptr;
+ link_stats_ptr->valid = true;
if (iface_stats_ptr != nullptr) {
link_stats_ptr->iface = *iface_stats_ptr;
@@ -751,10 +796,69 @@
}
};
- wifi_error status = global_func_table_.wifi_get_link_stats(0, getIfaceHandle(iface_name),
- {onSyncLinkLayerStatsResult});
+ LinkLayerMlStats* link_ml_stats_ptr = &link_ml_stats;
+ link_ml_stats_ptr->valid = false;
+
+ on_link_layer_ml_stats_result_internal_callback =
+ [this, &link_ml_stats_ptr](wifi_request_id /* id */,
+ wifi_iface_ml_stat* iface_ml_stats_ptr, int num_radios,
+ wifi_radio_stat* radio_stats_ptr) {
+ wifi_radio_stat* l_radio_stats_ptr;
+ wifi_link_stat* l_link_stat_ptr;
+ link_ml_stats_ptr->valid = true;
+
+ if (iface_ml_stats_ptr != nullptr && iface_ml_stats_ptr->num_links > 0) {
+ // Copy stats from wifi_iface_ml_stat to LinkLayerMlStats,
+ // - num_links * links[] to vector of links.
+ // - num_peers * peer_info[] to vector of links[i].peers.
+ link_ml_stats_ptr->iface = *iface_ml_stats_ptr;
+ l_link_stat_ptr = iface_ml_stats_ptr->links;
+ for (int l = 0; l < iface_ml_stats_ptr->num_links; ++l) {
+ l_link_stat_ptr = copyLinkStat(l_link_stat_ptr, link_ml_stats_ptr->links);
+ }
+ } else {
+ LOG(ERROR) << "Invalid iface stats in link layer stats";
+ }
+ if (num_radios <= 0 || radio_stats_ptr == nullptr) {
+ LOG(ERROR) << "Invalid radio stats in link layer stats";
+ return;
+ }
+ l_radio_stats_ptr = radio_stats_ptr;
+ for (int i = 0; i < num_radios; i++) {
+ LinkLayerRadioStats radio;
+
+ radio.stats = *l_radio_stats_ptr;
+ // Copy over the tx level array to the separate vector.
+ if (l_radio_stats_ptr->num_tx_levels > 0 &&
+ l_radio_stats_ptr->tx_time_per_levels != nullptr) {
+ radio.tx_time_per_levels.assign(l_radio_stats_ptr->tx_time_per_levels,
+ l_radio_stats_ptr->tx_time_per_levels +
+ l_radio_stats_ptr->num_tx_levels);
+ }
+ radio.stats.num_tx_levels = 0;
+ radio.stats.tx_time_per_levels = nullptr;
+ /* Copy over the channel stat to separate vector */
+ if (l_radio_stats_ptr->num_channels > 0) {
+ /* Copy the channel stats */
+ radio.channel_stats.assign(
+ l_radio_stats_ptr->channels,
+ l_radio_stats_ptr->channels + l_radio_stats_ptr->num_channels);
+ }
+ link_ml_stats_ptr->radios.push_back(radio);
+ l_radio_stats_ptr =
+ (wifi_radio_stat*)((u8*)l_radio_stats_ptr + sizeof(wifi_radio_stat) +
+ (sizeof(wifi_channel_stat) *
+ l_radio_stats_ptr->num_channels));
+ }
+ };
+
+ wifi_error status = global_func_table_.wifi_get_link_stats(
+ 0, getIfaceHandle(iface_name),
+ {onSyncLinkLayerStatsResult, onSyncLinkLayerMlStatsResult});
on_link_layer_stats_result_internal_callback = nullptr;
- return {status, link_stats};
+ on_link_layer_ml_stats_result_internal_callback = nullptr;
+
+ return status;
}
wifi_error WifiLegacyHal::startRssiMonitoring(
@@ -1624,6 +1728,7 @@
on_gscan_event_internal_callback = nullptr;
on_gscan_full_result_internal_callback = nullptr;
on_link_layer_stats_result_internal_callback = nullptr;
+ on_link_layer_ml_stats_result_internal_callback = nullptr;
on_rssi_threshold_breached_internal_callback = nullptr;
on_ring_buffer_data_internal_callback = nullptr;
on_error_alert_internal_callback = nullptr;
diff --git a/wifi/aidl/default/wifi_legacy_hal.h b/wifi/aidl/default/wifi_legacy_hal.h
index 33ed359..c40118e 100644
--- a/wifi/aidl/default/wifi_legacy_hal.h
+++ b/wifi/aidl/default/wifi_legacy_hal.h
@@ -363,7 +363,21 @@
wifi_iface_stat iface;
std::vector<LinkLayerRadioStats> radios;
std::vector<WifiPeerInfo> peers;
+ bool valid;
};
+
+struct LinkStats {
+ wifi_link_stat stat;
+ std::vector<WifiPeerInfo> peers;
+};
+
+struct LinkLayerMlStats {
+ wifi_iface_ml_stat iface;
+ std::vector<LinkStats> links;
+ std::vector<LinkLayerRadioStats> radios;
+ bool valid;
+};
+
#pragma GCC diagnostic pop
// The |WLAN_DRIVER_WAKE_REASON_CNT.cmd_event_wake_cnt| and
@@ -537,7 +551,9 @@
// Link layer stats functions.
wifi_error enableLinkLayerStats(const std::string& iface_name, bool debug);
wifi_error disableLinkLayerStats(const std::string& iface_name);
- std::pair<wifi_error, LinkLayerStats> getLinkLayerStats(const std::string& iface_name);
+ wifi_error getLinkLayerStats(const std::string& iface_name,
+ legacy_hal::LinkLayerStats& legacy_stats,
+ legacy_hal::LinkLayerMlStats& legacy_ml_stats);
// RSSI monitor functions.
wifi_error startRssiMonitoring(
const std::string& iface_name, wifi_request_id id, int8_t max_rssi, int8_t min_rssi,
@@ -710,6 +726,8 @@
// Handles wifi (error) status of Virtual interface create/delete
wifi_error handleVirtualInterfaceCreateOrDeleteStatus(const std::string& ifname,
wifi_error status);
+ wifi_link_stat* copyLinkStat(wifi_link_stat* stat_ptr, std::vector<LinkStats> stats);
+ wifi_peer_info* copyPeerInfo(wifi_peer_info* peer_ptr, std::vector<WifiPeerInfo> peers);
// Global function table of legacy HAL.
wifi_hal_fn global_func_table_;
diff --git a/wifi/aidl/default/wifi_sta_iface.cpp b/wifi/aidl/default/wifi_sta_iface.cpp
index 57384bf..08ed9d2 100644
--- a/wifi/aidl/default/wifi_sta_iface.cpp
+++ b/wifi/aidl/default/wifi_sta_iface.cpp
@@ -404,13 +404,22 @@
std::pair<StaLinkLayerStats, ndk::ScopedAStatus> WifiStaIface::getLinkLayerStatsInternal() {
legacy_hal::wifi_error legacy_status;
- legacy_hal::LinkLayerStats legacy_stats;
- std::tie(legacy_status, legacy_stats) = legacy_hal_.lock()->getLinkLayerStats(ifname_);
+ legacy_hal::LinkLayerStats legacy_stats{};
+ legacy_hal::LinkLayerMlStats legacy_ml_stats{};
+ legacy_status = legacy_hal_.lock()->getLinkLayerStats(ifname_, legacy_stats, legacy_ml_stats);
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
return {StaLinkLayerStats{}, createWifiStatusFromLegacyError(legacy_status)};
}
StaLinkLayerStats aidl_stats;
- if (!aidl_struct_util::convertLegacyLinkLayerStatsToAidl(legacy_stats, &aidl_stats)) {
+ if (legacy_stats.valid) {
+ if (!aidl_struct_util::convertLegacyLinkLayerStatsToAidl(legacy_stats, &aidl_stats)) {
+ return {StaLinkLayerStats{}, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
+ }
+ } else if (legacy_ml_stats.valid) {
+ if (!aidl_struct_util::convertLegacyLinkLayerMlStatsToAidl(legacy_ml_stats, &aidl_stats)) {
+ return {StaLinkLayerStats{}, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
+ }
+ } else {
return {StaLinkLayerStats{}, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
}
return {aidl_stats, ndk::ScopedAStatus::ok()};
diff --git a/wifi/aidl/vts/functional/wifi_sta_iface_aidl_test.cpp b/wifi/aidl/vts/functional/wifi_sta_iface_aidl_test.cpp
index ef7e274..5e55315 100644
--- a/wifi/aidl/vts/functional/wifi_sta_iface_aidl_test.cpp
+++ b/wifi/aidl/vts/functional/wifi_sta_iface_aidl_test.cpp
@@ -145,7 +145,7 @@
std::shared_ptr<IWifiStaIface> iface;
auto status = createStaIface(&iface);
if (status.isOk()) {
- EXPECT_GT(link_layer_stats.iface.timeSliceDutyCycleInPercent, 0);
+ EXPECT_GT(link_layer_stats.iface.links[0].timeSliceDutyCycleInPercent, 0);
}
// Disable link layer stats collection.