summaryrefslogtreecommitdiff
path: root/qcwcn/wifi_hal/llstats.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'qcwcn/wifi_hal/llstats.cpp')
-rw-r--r--qcwcn/wifi_hal/llstats.cpp35
1 files changed, 30 insertions, 5 deletions
diff --git a/qcwcn/wifi_hal/llstats.cpp b/qcwcn/wifi_hal/llstats.cpp
index 407a6c3..8e827e2 100644
--- a/qcwcn/wifi_hal/llstats.cpp
+++ b/qcwcn/wifi_hal/llstats.cpp
@@ -54,6 +54,7 @@ LLStatsCommand::LLStatsCommand(wifi_handle handle, int id, u32 vendor_id, u32 su
memset(&mHandler, 0,sizeof(mHandler));
mRadioStatsSize = 0;
mNumRadios = 0;
+ mNumRadiosAllocated = 0;
}
LLStatsCommand::~LLStatsCommand()
@@ -863,6 +864,11 @@ wifi_error LLStatsCommand::notifyResponse()
/* Indicate stats to framework only if both radio and iface stats
* are present */
if (mResultsParams.radio_stat && mResultsParams.iface_stat) {
+ if (mNumRadios > mNumRadiosAllocated) {
+ ALOGE("%s: Force reset mNumRadios=%d to allocated=%d",
+ __FUNCTION__, mNumRadios, mNumRadiosAllocated);
+ mNumRadios = mNumRadiosAllocated;
+ }
mHandler.on_link_stats_results(mRequestId,
mResultsParams.iface_stat, mNumRadios,
mResultsParams.radio_stat);
@@ -881,6 +887,11 @@ void LLStatsCommand::clearStats()
if(mResultsParams.radio_stat)
{
wifi_radio_stat *radioStat = mResultsParams.radio_stat;
+ if (mNumRadios > mNumRadiosAllocated) {
+ ALOGE("%s: Force reset mNumRadios=%d to allocated=%d",
+ __FUNCTION__, mNumRadios, mNumRadiosAllocated);
+ mNumRadios = mNumRadiosAllocated;
+ }
for (u8 radio = 0; radio < mNumRadios; radio++) {
if (radioStat->tx_time_per_levels) {
free(radioStat->tx_time_per_levels);
@@ -894,6 +905,7 @@ void LLStatsCommand::clearStats()
mResultsParams.radio_stat = NULL;
mRadioStatsSize = 0;
mNumRadios = 0;
+ mNumRadiosAllocated = 0;
}
if(mResultsParams.iface_stat)
{
@@ -978,6 +990,7 @@ int LLStatsCommand::handleResponse(WifiEvent &reply)
+ mRadioStatsSize);
memset(radioStatsBuf, 0, resultsBufSize);
mRadioStatsSize += resultsBufSize;
+ mNumRadiosAllocated ++;
if (tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_TX_LEVELS])
radioStatsBuf->num_tx_levels = nla_get_u32(tb_vendor[
@@ -1151,10 +1164,19 @@ int LLStatsCommand::handleResponse(WifiEvent &reply)
memset(pIfaceStat, 0, resultsBufSize);
if(mResultsParams.iface_stat) {
- memcpy ( pIfaceStat, mResultsParams.iface_stat,
- sizeof(wifi_iface_stat));
- free (mResultsParams.iface_stat);
- mResultsParams.iface_stat = pIfaceStat;
+ if(resultsBufSize >= sizeof(wifi_iface_stat)) {
+ memcpy ( pIfaceStat, mResultsParams.iface_stat,
+ sizeof(wifi_iface_stat));
+ free (mResultsParams.iface_stat);
+ mResultsParams.iface_stat = pIfaceStat;
+ } else {
+ ALOGE("%s: numPeers = %u, num_rates= %u, "
+ "either numPeers or num_rates is invalid",
+ __FUNCTION__,numPeers,num_rates);
+ status = WIFI_ERROR_UNKNOWN;
+ free(pIfaceStat);
+ goto cleanup;
+ }
}
wifi_peer_info *pPeerStats;
pIfaceStat->num_peers = numPeers;
@@ -1166,6 +1188,7 @@ int LLStatsCommand::handleResponse(WifiEvent &reply)
status = WIFI_ERROR_INVALID_ARGS;
goto cleanup;
}
+ num_rates = 0;
for (peerInfo = (struct nlattr *) nla_data(tb_vendor[
QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO]),
rem = nla_len(tb_vendor[
@@ -1177,7 +1200,8 @@ int LLStatsCommand::handleResponse(WifiEvent &reply)
QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX+ 1];
pPeerStats = (wifi_peer_info *) (
(u8 *)pIfaceStat->peer_info
- + (i++ * sizeof(wifi_peer_info)));
+ + (i++ * sizeof(wifi_peer_info))
+ + (num_rates * sizeof(wifi_rate_stat)));
nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX,
(struct nlattr *) nla_data(peerInfo),
nla_len(peerInfo), NULL);
@@ -1186,6 +1210,7 @@ int LLStatsCommand::handleResponse(WifiEvent &reply)
{
goto cleanup;
}
+ num_rates += pPeerStats->num_rate;
}
}