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
This commit is contained in:
Sunil Ravi
2022-12-16 17:31:21 +00:00
committed by Android (Google) Code Review
11 changed files with 747 additions and 165 deletions

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -940,69 +940,158 @@ bool convertLegacyLinkLayerRadioStatsToAidl(
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 @@ bool convertLegacyLinkLayerStatsToAidl(const legacy_hal::LinkLayerStats& legacy_
}
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) {

View File

@@ -89,6 +89,8 @@ bool convertLegacyGscanResultToAidl(const legacy_hal::wifi_scan_result& legacy_s
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(

View File

@@ -112,6 +112,285 @@ TEST_F(AidlStructUtilTest, CanConvertLegacyWifiMacInfosToAidlWithTwoMac) {
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 @@ TEST_F(AidlStructUtilTest, canConvertLegacyLinkLayerStatsToAidl) {
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 @@ TEST_F(AidlStructUtilTest, canConvertLegacyLinkLayerStatsToAidl) {
}
}
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);
}
}
}

View File

@@ -119,6 +119,16 @@ void onSyncLinkLayerStatsResult(wifi_request_id id, wifi_iface_stat* iface_stat,
}
}
// 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 @@ wifi_error WifiLegacyHal::disableLinkLayerStats(const std::string& iface_name) {
&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 @@ std::pair<wifi_error, LinkLayerStats> WifiLegacyHal::getLinkLayerStats(
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 @@ std::pair<wifi_error, LinkLayerStats> WifiLegacyHal::getLinkLayerStats(
}
};
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 @@ void WifiLegacyHal::invalidate() {
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;

View File

@@ -363,7 +363,21 @@ struct LinkLayerStats {
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 @@ class WifiLegacyHal {
// 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 @@ class WifiLegacyHal {
// 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_;

View File

@@ -404,13 +404,22 @@ ndk::ScopedAStatus WifiStaIface::disableLinkLayerStatsCollectionInternal() {
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()};

View File

@@ -145,7 +145,7 @@ TEST_P(WifiStaIfaceAidlTest, GetLinkLayerStats) {
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.