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()};