From e42ace24045ec47bf1396a0ecefb729f02825a21 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Mon, 13 Mar 2017 10:44:20 -0700 Subject: [PATCH] wifi: Add support for multiple radio stats Previously, we've always assumed that we have only one instance of radio stats fetched in link layer stats. This is no longer true for the newer devices which support multiple radios. Also, Changed the timestamp member from uint32_t to uint64_t. Bug: 36148086 Test: The error logs no longer seen on newer devices. Change-Id: I048a1db7cc0bfb0dc0dacafff2156f42a8ae1e63 --- wifi/1.0/default/hidl_struct_util.cpp | 16 +++++--- wifi/1.0/default/wifi_legacy_hal.cpp | 58 ++++++++++++++------------- wifi/1.0/default/wifi_legacy_hal.h | 8 +++- wifi/1.0/types.hal | 4 +- 4 files changed, 50 insertions(+), 36 deletions(-) diff --git a/wifi/1.0/default/hidl_struct_util.cpp b/wifi/1.0/default/hidl_struct_util.cpp index a89f8c0492..fb93c5ad9c 100644 --- a/wifi/1.0/default/hidl_struct_util.cpp +++ b/wifi/1.0/default/hidl_struct_util.cpp @@ -706,11 +706,17 @@ bool convertLegacyLinkLayerStatsToHidl( hidl_stats->iface.wmeVoPktStats.retries = legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].retries; // radio legacy_stats conversion. - hidl_stats->radio.onTimeInMs = legacy_stats.radio.on_time; - hidl_stats->radio.txTimeInMs = legacy_stats.radio.tx_time; - hidl_stats->radio.rxTimeInMs = legacy_stats.radio.rx_time; - hidl_stats->radio.onTimeInMsForScan = legacy_stats.radio.on_time_scan; - hidl_stats->radio.txTimeInMsPerLevel = legacy_stats.radio_tx_time_per_levels; + std::vector hidl_radios_stats; + for (const auto& legacy_radio_stats : legacy_stats.radios) { + StaLinkLayerRadioStats hidl_radio_stats; + hidl_radio_stats.onTimeInMs = legacy_radio_stats.stats.on_time; + hidl_radio_stats.txTimeInMs = legacy_radio_stats.stats.tx_time; + hidl_radio_stats.rxTimeInMs = legacy_radio_stats.stats.rx_time; + hidl_radio_stats.onTimeInMsForScan = legacy_radio_stats.stats.on_time_scan; + hidl_radio_stats.txTimeInMsPerLevel = legacy_radio_stats.tx_time_per_levels; + hidl_radios_stats.push_back(hidl_radio_stats); + } + hidl_stats->radios = hidl_radios_stats; // Timestamp in the HAL wrapper here since it's not provided in the legacy // HAL API. hidl_stats->timeStampInMs = uptimeMillis(); diff --git a/wifi/1.0/default/wifi_legacy_hal.cpp b/wifi/1.0/default/wifi_legacy_hal.cpp index f902e6453e..5fc022849c 100644 --- a/wifi/1.0/default/wifi_legacy_hal.cpp +++ b/wifi/1.0/default/wifi_legacy_hal.cpp @@ -601,33 +601,37 @@ std::pair WifiLegacyHal::getLinkLayerStats() { LinkLayerStats link_stats{}; LinkLayerStats* link_stats_ptr = &link_stats; - on_link_layer_stats_result_internal_callback = [&link_stats_ptr]( - wifi_request_id /* id */, - wifi_iface_stat* iface_stats_ptr, - int num_radios, - wifi_radio_stat* radio_stats_ptr) { - if (iface_stats_ptr != nullptr) { - link_stats_ptr->iface = *iface_stats_ptr; - link_stats_ptr->iface.num_peers = 0; - } else { - LOG(ERROR) << "Invalid iface stats in link layer stats"; - } - if (num_radios == 1 && radio_stats_ptr != nullptr) { - link_stats_ptr->radio = *radio_stats_ptr; - // Copy over the tx level array to the separate vector. - if (radio_stats_ptr->num_tx_levels > 0 && - radio_stats_ptr->tx_time_per_levels != nullptr) { - link_stats_ptr->radio_tx_time_per_levels.assign( - radio_stats_ptr->tx_time_per_levels, - radio_stats_ptr->tx_time_per_levels + - radio_stats_ptr->num_tx_levels); - } - link_stats_ptr->radio.num_tx_levels = 0; - link_stats_ptr->radio.tx_time_per_levels = nullptr; - } else { - LOG(ERROR) << "Invalid radio stats in link layer stats"; - } - }; + on_link_layer_stats_result_internal_callback = + [&link_stats_ptr](wifi_request_id /* id */, + wifi_iface_stat* iface_stats_ptr, + int num_radios, + wifi_radio_stat* radio_stats_ptr) { + if (iface_stats_ptr != nullptr) { + link_stats_ptr->iface = *iface_stats_ptr; + link_stats_ptr->iface.num_peers = 0; + } 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; + } + for (int i = 0; i < num_radios; i++) { + LinkLayerRadioStats radio; + radio.stats = radio_stats_ptr[i]; + // Copy over the tx level array to the separate vector. + if (radio_stats_ptr[i].num_tx_levels > 0 && + radio_stats_ptr[i].tx_time_per_levels != nullptr) { + radio.tx_time_per_levels.assign( + radio_stats_ptr[i].tx_time_per_levels, + radio_stats_ptr[i].tx_time_per_levels + + radio_stats_ptr[i].num_tx_levels); + } + radio.stats.num_tx_levels = 0; + radio.stats.tx_time_per_levels = nullptr; + link_stats_ptr->radios.push_back(radio); + } + }; wifi_error status = global_func_table_.wifi_get_link_stats( 0, wlan_interface_handle_, {onSyncLinkLayerStatsResult}); diff --git a/wifi/1.0/default/wifi_legacy_hal.h b/wifi/1.0/default/wifi_legacy_hal.h index c8fd5bdf58..f79e62a962 100644 --- a/wifi/1.0/default/wifi_legacy_hal.h +++ b/wifi/1.0/default/wifi_legacy_hal.h @@ -49,10 +49,14 @@ struct PacketFilterCapabilities { // The |wifi_radio_stat.tx_time_per_levels| stats is provided as a pointer in // |wifi_radio_stat| structure in the legacy HAL API. Separate that out // into a separate return element to avoid passing pointers around. +struct LinkLayerRadioStats { + wifi_radio_stat stats; + std::vector tx_time_per_levels; +}; + struct LinkLayerStats { wifi_iface_stat iface; - wifi_radio_stat radio; - std::vector radio_tx_time_per_levels; + std::vector radios; }; #pragma GCC diagnostic pop diff --git a/wifi/1.0/types.hal b/wifi/1.0/types.hal index d90d5be742..d3845c9b49 100644 --- a/wifi/1.0/types.hal +++ b/wifi/1.0/types.hal @@ -143,7 +143,7 @@ typedef MacAddress Bssid; /** * TimeStamp in milliseconds (ms). */ -typedef uint32_t TimeStampInMs; +typedef uint64_t TimeStampInMs; /** * TimeStamp in microseconds (us). @@ -478,7 +478,7 @@ struct StaLinkLayerRadioStats { */ struct StaLinkLayerStats { StaLinkLayerIfaceStats iface; - StaLinkLayerRadioStats radio; + vec radios; /** * TimeStamp for each stats sample. * This is the absolute milliseconds from boot when these stats were