mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 11:36:00 +00:00
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
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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_;
|
||||
|
||||
@@ -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()};
|
||||
|
||||
Reference in New Issue
Block a user