From ba4d7fe33762cd773d8da2820df0a5fc463d406b Mon Sep 17 00:00:00 2001 From: Mahesh KKV Date: Thu, 3 Nov 2022 09:56:07 -0700 Subject: [PATCH 1/5] wifi: Fix unit test for LegacyLinkLayerStats Due to the introduction of multi links, StaLinkLayerStats carries stats for multiple links as a vector. For LegacyLinkLayerStats, only single link will be available. So convertLegacyLinkLayerStatsToAidl() push the stats for single link as the first element of the link vector.Fix the unit test to index the first link. Bug: 246988155 Test: hardware/interfaces/wifi/aidl/default/tests/runtests.sh Change-Id: I8c9a8beca6bda6cf894edb616cdfe54f09d029f7 --- .../tests/aidl_struct_util_unit_tests.cpp | 93 ++++++++++--------- 1 file changed, 47 insertions(+), 46 deletions(-) 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 4a69c2426b..21b8d2d555 100644 --- a/wifi/aidl/default/tests/aidl_struct_util_unit_tests.cpp +++ b/wifi/aidl/default/tests/aidl_struct_util_unit_tests.cpp @@ -215,78 +215,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 +332,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); } } } From 43c7805bde450b10abe71aedb161ad24d423e71a Mon Sep 17 00:00:00 2001 From: Mahesh KKV Date: Thu, 3 Nov 2022 13:05:23 -0700 Subject: [PATCH 2/5] wifi: Add unit test for multi link stats conversion Bug: 246988155 Test: hardware/interfaces/wifi/aidl/default/tests/runtests.sh Change-Id: Ia38601dfb7bb5e43ee3b3aeb2a4ea93c7bbcba75 --- .../tests/aidl_struct_util_unit_tests.cpp | 279 ++++++++++++++++++ 1 file changed, 279 insertions(+) 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 21b8d2d555..c2de0122d7 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 @@ TEST_F(AidlStructUtilTest, CanConvertLegacyWifiMacInfosToAidlWithTwoMac) { EXPECT_EQ(static_cast(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{}); From 5fe40535ffbfdc3d0b36c36fef549e5c11f42322 Mon Sep 17 00:00:00 2001 From: Mahesh KKV Date: Thu, 3 Nov 2022 13:15:10 -0700 Subject: [PATCH 3/5] wifi: Update vts test for GetLinkLayerStats() Bug: 246988155 Test: atest VtsHalWifiStaIfaceTargetTest Change-Id: I0f3f211f5ff5374834da60214d45bba1b8a47b7a --- wifi/aidl/vts/functional/wifi_sta_iface_aidl_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 ef7e2747c9..5e55315781 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 @@ TEST_P(WifiStaIfaceAidlTest, GetLinkLayerStats) { std::shared_ptr 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. From 131f47c22130025d6dd0c552b38a5e4069ac4f23 Mon Sep 17 00:00:00 2001 From: Mahesh KKV Date: Sat, 22 Oct 2022 14:07:21 -0700 Subject: [PATCH 4/5] wifi: Add multi link layer stats support to AIDL Bug: 246988155 Test: mm -j Change-Id: I9b31988215d3953da6dde80aa68ead9236659d50 --- .../hardware/wifi/StaLinkLayerIfaceStats.aidl | 13 +-- .../hardware/wifi/StaLinkLayerLinkStats.aidl | 50 +++++++++++ .../hardware/wifi/StaLinkLayerIfaceStats.aidl | 59 +----------- .../hardware/wifi/StaLinkLayerLinkStats.aidl | 89 +++++++++++++++++++ 4 files changed, 144 insertions(+), 67 deletions(-) create mode 100644 wifi/aidl/aidl_api/android.hardware.wifi/current/android/hardware/wifi/StaLinkLayerLinkStats.aidl create mode 100644 wifi/aidl/android/hardware/wifi/StaLinkLayerLinkStats.aidl 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 cf68fc6bf4..a4192076d2 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 0000000000..714bba8e98 --- /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 -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 78f8caa6a7..3f8718fe74 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 0000000000..cf1a867839 --- /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; +} From 5f30d333d2c4bd021de7d0c1b4eddb061cf1d314 Mon Sep 17 00:00:00 2001 From: Mahesh KKV Date: Wed, 26 Oct 2022 14:07:44 -0700 Subject: [PATCH 5/5] wifi: Add Support for Multi-Link Layer stats in shim layer With MLO, WiFi 7 supports establishing multiple links between the Station and Access Point. Each of the link has its own stats. To maintain backward compatibility, if multi link stats is not supported by vendor, always fallback to single link layer stats. Bug: 246988155 Test: hardware/interfaces/wifi/aidl/default/tests/runtests.sh Change-Id: Iede8ce771f0e58975222808b1870e5e2e179384c --- wifi/aidl/default/aidl_struct_util.cpp | 173 +++++++++++++++++++------ wifi/aidl/default/aidl_struct_util.h | 2 + wifi/aidl/default/wifi_legacy_hal.cpp | 117 ++++++++++++++++- wifi/aidl/default/wifi_legacy_hal.h | 20 ++- wifi/aidl/default/wifi_sta_iface.cpp | 15 ++- 5 files changed, 276 insertions(+), 51 deletions(-) diff --git a/wifi/aidl/default/aidl_struct_util.cpp b/wifi/aidl/default/aidl_struct_util.cpp index ec8b3968f2..fe7579b234 100644 --- a/wifi/aidl/default/aidl_struct_util.cpp +++ b/wifi/aidl/default/aidl_struct_util.cpp @@ -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 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 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 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 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 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 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 d8e1fd48aa..ac86755382 100644 --- a/wifi/aidl/default/aidl_struct_util.h +++ b/wifi/aidl/default/aidl_struct_util.h @@ -89,6 +89,8 @@ bool convertLegacyGscanResultToAidl(const legacy_hal::wifi_scan_result& legacy_s bool convertLegacyVectorOfCachedGscanResultsToAidl( const std::vector& legacy_cached_scan_results, std::vector* 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/wifi_legacy_hal.cpp b/wifi/aidl/default/wifi_legacy_hal.cpp index e4883d19f3..83f368e0bf 100644 --- a/wifi/aidl/default/wifi_legacy_hal.cpp +++ b/wifi/aidl/default/wifi_legacy_hal.cpp @@ -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 + 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 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 WifiLegacyHal::getLinkLayerStats( - const std::string& iface_name) { - LinkLayerStats link_stats{}; +// Copies wifi_peer_info* to vector and returns poiner to next element. +wifi_peer_info* WifiLegacyHal::copyPeerInfo(wifi_peer_info* peer_ptr, + std::vector 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 and returns poiner to next element. +wifi_link_stat* WifiLegacyHal::copyLinkStat(wifi_link_stat* stat_ptr, + std::vector 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 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 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; diff --git a/wifi/aidl/default/wifi_legacy_hal.h b/wifi/aidl/default/wifi_legacy_hal.h index 33ed359baa..c40118e233 100644 --- a/wifi/aidl/default/wifi_legacy_hal.h +++ b/wifi/aidl/default/wifi_legacy_hal.h @@ -363,7 +363,21 @@ struct LinkLayerStats { wifi_iface_stat iface; std::vector radios; std::vector peers; + bool valid; }; + +struct LinkStats { + wifi_link_stat stat; + std::vector peers; +}; + +struct LinkLayerMlStats { + wifi_iface_ml_stat iface; + std::vector links; + std::vector 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 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 stats); + wifi_peer_info* copyPeerInfo(wifi_peer_info* peer_ptr, std::vector 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 57384bf4dd..08ed9d2b5c 100644 --- a/wifi/aidl/default/wifi_sta_iface.cpp +++ b/wifi/aidl/default/wifi_sta_iface.cpp @@ -404,13 +404,22 @@ ndk::ScopedAStatus WifiStaIface::disableLinkLayerStatsCollectionInternal() { std::pair 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()};