Home | History | Annotate | Download | only in wifi_hal
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *     http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "sync.h"
     18 
     19 #define LOG_TAG  "WifiHAL"
     20 
     21 #include <utils/Log.h>
     22 
     23 #include "wifi_hal.h"
     24 #include "common.h"
     25 #include "cpp_bindings.h"
     26 #include "llstatscommand.h"
     27 #include "vendor_definitions.h"
     28 
     29 //Singleton Static Instance
     30 LLStatsCommand* LLStatsCommand::mLLStatsCommandInstance  = NULL;
     31 
     32 // This function implements creation of Vendor command
     33 // For LLStats just call base Vendor command create
     34 int LLStatsCommand::create() {
     35     int ifindex;
     36     int ret = mMsg.create(NL80211_CMD_VENDOR, 0, 0);
     37     if (ret < 0) {
     38         return ret;
     39     }
     40     // insert the oui in the msg
     41     ret = mMsg.put_u32(NL80211_ATTR_VENDOR_ID, mVendor_id);
     42     if (ret < 0)
     43         goto out;
     44 
     45     // insert the subcmd in the msg
     46     ret = mMsg.put_u32(NL80211_ATTR_VENDOR_SUBCMD, mSubcmd);
     47     if (ret < 0)
     48         goto out;
     49 
     50     ALOGI("mVendor_id = %d, Subcmd = %d in  %s:%d\n", mVendor_id, mSubcmd, __func__, __LINE__);
     51 out:
     52     return ret;
     53 }
     54 
     55 LLStatsCommand::LLStatsCommand(wifi_handle handle, int id, u32 vendor_id, u32 subcmd)
     56         : WifiVendorCommand(handle, id, vendor_id, subcmd)
     57 {
     58     ALOGV("LLStatsCommand %p constructed", this);
     59     memset(&mClearRspParams, 0,sizeof(LLStatsClearRspParams));
     60     memset(&mResultsParams, 0,sizeof(LLStatsResultsParams));
     61     memset(&mHandler, 0,sizeof(mHandler));
     62 }
     63 
     64 LLStatsCommand::~LLStatsCommand()
     65 {
     66     ALOGW("LLStatsCommand %p distructor", this);
     67     mLLStatsCommandInstance = NULL;
     68 }
     69 
     70 LLStatsCommand* LLStatsCommand::instance(wifi_handle handle)
     71 {
     72     if (handle == NULL) {
     73         ALOGE("Interface Handle is invalid");
     74         return NULL;
     75     }
     76     if (mLLStatsCommandInstance == NULL) {
     77         mLLStatsCommandInstance = new LLStatsCommand(handle, 0,
     78                 OUI_QCA,
     79                 QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET);
     80         ALOGV("LLStatsCommand %p created", mLLStatsCommandInstance);
     81         return mLLStatsCommandInstance;
     82     }
     83     else
     84     {
     85         if (handle != getWifiHandle(mLLStatsCommandInstance->mInfo))
     86         {
     87             /* upper layer must have cleaned up the handle and reinitialized,
     88                so we need to update the same */
     89             ALOGE("Handle different, update the handle");
     90             mLLStatsCommandInstance->mInfo = (hal_info *)handle;
     91         }
     92     }
     93     ALOGV("LLStatsCommand %p created already", mLLStatsCommandInstance);
     94     return mLLStatsCommandInstance;
     95 }
     96 
     97 void LLStatsCommand::initGetContext(u32 reqId)
     98 {
     99     mRequestId = reqId;
    100     memset(&mResultsParams, 0,sizeof(LLStatsResultsParams));
    101     memset(&mHandler, 0,sizeof(mHandler));
    102 }
    103 
    104 void LLStatsCommand::setSubCmd(u32 subcmd)
    105 {
    106     mSubcmd = subcmd;
    107 }
    108 
    109 void LLStatsCommand::setHandler(wifi_stats_result_handler handler)
    110 {
    111     mHandler = handler;
    112 }
    113 
    114 static wifi_error get_wifi_interface_info(wifi_interface_link_layer_info *stats,
    115                                           struct nlattr **tb_vendor)
    116 {
    117     u32 len = 0;
    118     u8 *data;
    119 
    120     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE])
    121     {
    122         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE not found", __func__);
    123         return WIFI_ERROR_INVALID_ARGS;
    124     }
    125     stats->mode = (wifi_interface_mode)nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE]);
    126 
    127 
    128     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR])
    129     {
    130         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR not found", __func__);
    131         return WIFI_ERROR_INVALID_ARGS;
    132     }
    133     len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR]);
    134     len = ((sizeof(stats->mac_addr) <= len) ? sizeof(stats->mac_addr) : len);
    135     memcpy(&stats->mac_addr[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR]), len);
    136 
    137     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE])
    138     {
    139         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE not found", __func__);
    140         return WIFI_ERROR_INVALID_ARGS;
    141     }
    142     stats->state = (wifi_connection_state)nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE]);
    143 
    144     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING])
    145     {
    146         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING not found", __func__);
    147         return WIFI_ERROR_INVALID_ARGS;
    148     }
    149     stats->roaming = (wifi_roam_state)nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING]);
    150 
    151     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES])
    152     {
    153         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES not found", __func__);
    154         return WIFI_ERROR_INVALID_ARGS;
    155     }
    156     stats->capabilities = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES]);
    157 
    158     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID])
    159     {
    160         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID not found", __func__);
    161         return WIFI_ERROR_INVALID_ARGS;
    162     }
    163     len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID]);
    164     len = ((sizeof(stats->ssid) <= len) ? sizeof(stats->ssid) : len);
    165     memcpy(&stats->ssid[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID]), len);
    166 
    167     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID])
    168     {
    169         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID not found", __func__);
    170         return WIFI_ERROR_INVALID_ARGS;
    171     }
    172     len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID]);
    173     len = ((sizeof(stats->bssid) <= len) ? sizeof(stats->bssid) : len);
    174     memcpy(&stats->bssid[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID]), len);
    175 
    176     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR])
    177     {
    178         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR not found", __func__);
    179         return WIFI_ERROR_INVALID_ARGS;
    180     }
    181     len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR]);
    182     len = ((sizeof(stats->ap_country_str) <= len) ? sizeof(stats->ap_country_str) : len);
    183     memcpy(&stats->ap_country_str[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR]),
    184            len);
    185 
    186     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR])
    187     {
    188         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR not found", __func__);
    189         return WIFI_ERROR_INVALID_ARGS;
    190     }
    191     len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR]);
    192     len = ((sizeof(stats->country_str) < len) ? sizeof(stats->country_str) : len);
    193     memcpy(&stats->country_str[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR]),
    194            len);
    195 
    196     ALOGI("STATS IFACE: Mode %d", stats->mode);
    197     ALOGI("STATS IFACE: MAC %pM", stats->mac_addr);
    198     ALOGI("STATS IFACE: State %d ", stats->state);
    199     ALOGI("STATS IFACE: Roaming %d ", stats->roaming);
    200     ALOGI("STATS IFACE: capabilities %0x ", stats->capabilities);
    201     ALOGI("STATS IFACE: SSID %s ", stats->ssid);
    202     ALOGI("STATS IFACE: BSSID %pM ", stats->bssid);
    203     ALOGI("STATS IFACE: AP country str %c%c%c ", stats->ap_country_str[0],
    204             stats->ap_country_str[1], stats->ap_country_str[2]);
    205     ALOGI("STATS IFACE:Country String for this Association %c%c%c", stats->country_str[0],
    206             stats->country_str[1], stats->country_str[2]);
    207     return WIFI_SUCCESS;
    208 }
    209 
    210 static wifi_error get_wifi_wmm_ac_stat(wifi_wmm_ac_stat *stats,
    211                                        struct nlattr **tb_vendor)
    212 {
    213 
    214     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC])
    215     {
    216         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC not found", __func__);
    217         return WIFI_ERROR_INVALID_ARGS;
    218     }
    219     stats->ac                     = (wifi_traffic_ac)nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC]);
    220 
    221     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU])
    222     {
    223         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU not found", __func__);
    224         return WIFI_ERROR_INVALID_ARGS;
    225     }
    226     stats->tx_mpdu                = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU]);
    227 
    228     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU])
    229     {
    230         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU not found", __func__);
    231         return WIFI_ERROR_INVALID_ARGS;
    232     }
    233     stats->rx_mpdu                = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU]);
    234 
    235     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST])
    236     {
    237         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST not found", __func__);
    238         return WIFI_ERROR_INVALID_ARGS;
    239     }
    240     stats->tx_mcast               = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST]);
    241 
    242     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST])
    243     {
    244         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST not found", __func__);
    245         return WIFI_ERROR_INVALID_ARGS;
    246     }
    247     stats->rx_mcast               = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST]);
    248 
    249     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU])
    250     {
    251         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU not found", __func__);
    252         return WIFI_ERROR_INVALID_ARGS;
    253     }
    254     stats->rx_ampdu               = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU]);
    255 
    256     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU])
    257     {
    258         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU not found", __func__);
    259         return WIFI_ERROR_INVALID_ARGS;
    260     }
    261     stats->tx_ampdu               = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU]);
    262 
    263     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST])
    264     {
    265         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST not found", __func__);
    266         return WIFI_ERROR_INVALID_ARGS;
    267     }
    268     stats->mpdu_lost              = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST]);
    269 
    270     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES])
    271     {
    272         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES not found", __func__);
    273         return WIFI_ERROR_INVALID_ARGS;
    274     }
    275     stats->retries                = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES]);
    276 
    277     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT])
    278     {
    279         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT not found", __func__);
    280         return WIFI_ERROR_INVALID_ARGS;
    281     }
    282     stats->retries_short          = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT]);
    283 
    284     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG])
    285     {
    286         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG not found", __func__);
    287         return WIFI_ERROR_INVALID_ARGS;
    288     }
    289     stats->retries_long           = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG]);
    290 
    291     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN])
    292     {
    293         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN not found", __func__);
    294         return WIFI_ERROR_INVALID_ARGS;
    295     }
    296     stats->contention_time_min    = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN]);
    297 
    298     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX])
    299     {
    300         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX not found", __func__);
    301         return WIFI_ERROR_INVALID_ARGS;
    302     }
    303     stats->contention_time_max    = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX]);
    304 
    305     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG])
    306     {
    307         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG not found", __func__);
    308         return WIFI_ERROR_INVALID_ARGS;
    309     }
    310     stats->contention_time_avg    = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG]);
    311 
    312     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES])
    313     {
    314         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES not found", __func__);
    315         return WIFI_ERROR_INVALID_ARGS;
    316     }
    317     stats->contention_num_samples = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES]);
    318 
    319     ALOGI("STATS IFACE: ac  %u ", stats->ac);
    320     ALOGI("STATS IFACE: txMpdu  %u ", stats->tx_mpdu) ;
    321     ALOGI("STATS IFACE: rxMpdu  %u ", stats->rx_mpdu);
    322     ALOGI("STATS IFACE: txMcast  %u ", stats->tx_mcast);
    323     ALOGI("STATS IFACE: rxMcast  %u ", stats->rx_mcast);
    324     ALOGI("STATS IFACE: rxAmpdu  %u ", stats->rx_ampdu);
    325     ALOGI("STATS IFACE: txAmpdu  %u ", stats->tx_ampdu);
    326     ALOGI("STATS IFACE: mpduLost  %u ", stats->mpdu_lost);
    327     ALOGI("STATS IFACE: retries %u  ", stats->retries);
    328     ALOGI("STATS IFACE: retriesShort  %u ",
    329             stats->retries_short);
    330     ALOGI("STATS IFACE: retriesLong  %u  ",
    331             stats->retries_long);
    332     ALOGI("STATS IFACE: contentionTimeMin  %u ",
    333             stats->contention_time_min);
    334     ALOGI("STATS IFACE: contentionTimeMax  %u ",
    335             stats->contention_time_max);
    336     ALOGI("STATS IFACE: contentionTimeAvg  %u ",
    337             stats->contention_time_avg);
    338     ALOGI("STATS IFACE: contentionNumSamples  %u ",
    339             stats->contention_num_samples);
    340     return WIFI_SUCCESS;
    341 }
    342 
    343 static wifi_error get_wifi_rate_stat(wifi_rate_stat *stats,
    344                                      struct nlattr **tb_vendor)
    345 {
    346 
    347     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE])
    348     {
    349         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE not found", __func__);
    350         return WIFI_ERROR_INVALID_ARGS;
    351     }
    352     stats->rate.preamble        = nla_get_u8(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE]);
    353 
    354     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS])
    355     {
    356         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS not found", __func__);
    357         return WIFI_ERROR_INVALID_ARGS;
    358     }
    359     stats->rate.nss             = nla_get_u8(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS]);
    360 
    361     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW])
    362     {
    363         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW not found", __func__);
    364         return WIFI_ERROR_INVALID_ARGS;
    365     }
    366     stats->rate.bw              = nla_get_u8(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW]);
    367 
    368     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX])
    369     {
    370         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX not found", __func__);
    371         return WIFI_ERROR_INVALID_ARGS;
    372     }
    373     stats->rate.rateMcsIdx      = nla_get_u8(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX]);
    374 
    375     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE])
    376     {
    377         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE not found", __func__);
    378         return WIFI_ERROR_INVALID_ARGS;
    379     }
    380     stats->rate.bitrate         = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE]);
    381 
    382     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU])
    383     {
    384         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU not found", __func__);
    385         return WIFI_ERROR_INVALID_ARGS;
    386     }
    387     stats->tx_mpdu              = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU]);
    388 
    389     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU])
    390     {
    391         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU not found", __func__);
    392         return WIFI_ERROR_INVALID_ARGS;
    393     }
    394     stats->rx_mpdu              = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU]);
    395 
    396     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST])
    397     {
    398         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST not found", __func__);
    399         return WIFI_ERROR_INVALID_ARGS;
    400     }
    401     stats->mpdu_lost            = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST]);
    402 
    403     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES])
    404     {
    405         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES not found", __func__);
    406         return WIFI_ERROR_INVALID_ARGS;
    407     }
    408     stats->retries              = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES]);
    409 
    410     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT])
    411     {
    412         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT not found", __func__);
    413         return WIFI_ERROR_INVALID_ARGS;
    414     }
    415     stats->retries_short        = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT]);
    416 
    417     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG])
    418     {
    419         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG not found", __func__);
    420         return WIFI_ERROR_INVALID_ARGS;
    421     }
    422     stats->retries_long         = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG]);
    423 
    424     ALOGI("STATS PEER_ALL : preamble  %u", stats->rate.preamble);
    425     ALOGI("STATS PEER_ALL : nss %u", stats->rate.nss);
    426     ALOGI("STATS PEER_ALL : bw %u", stats->rate.bw);
    427     ALOGI("STATS PEER_ALL : rateMcsIdx  %u", stats->rate.rateMcsIdx);
    428     ALOGI("STATS PEER_ALL : bitrate %u", stats->rate.bitrate);
    429 
    430     ALOGI("STATS PEER_ALL : txMpdu %u", stats->tx_mpdu);
    431     ALOGI("STATS PEER_ALL : rxMpdu %u", stats->rx_mpdu);
    432     ALOGI("STATS PEER_ALL : mpduLost %u", stats->mpdu_lost);
    433     ALOGI("STATS PEER_ALL : retries %u", stats->retries);
    434     ALOGI("STATS PEER_ALL : retriesShort %u", stats->retries_short);
    435     ALOGI("STATS PEER_ALL : retriesLong %u", stats->retries_long);
    436     return WIFI_SUCCESS;
    437 }
    438 
    439 static wifi_error get_wifi_peer_info(wifi_peer_info *stats,
    440                                      struct nlattr **tb_vendor)
    441 {
    442     u32 i = 0, len = 0;
    443     int rem;
    444     wifi_rate_stat * pRateStats;
    445     struct nlattr *rateInfo;
    446     wifi_error ret = WIFI_SUCCESS;
    447 
    448     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE])
    449     {
    450         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE not found", __func__);
    451         return WIFI_ERROR_INVALID_ARGS;
    452     }
    453     stats->type                   = (wifi_peer_type)nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE]);
    454 
    455     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS])
    456     {
    457         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS not found", __func__);
    458         return WIFI_ERROR_INVALID_ARGS;
    459     }
    460     len = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS]);
    461     len = ((sizeof(stats->peer_mac_address) <= len) ? sizeof(stats->peer_mac_address) : len);
    462     memcpy((void *)&stats->peer_mac_address[0], nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS]),
    463             len);
    464 
    465     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES])
    466     {
    467         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES not found", __func__);
    468         return WIFI_ERROR_INVALID_ARGS;
    469     }
    470     stats->capabilities           = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES]);
    471 
    472     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES])
    473     {
    474         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES not found", __func__);
    475         return WIFI_ERROR_INVALID_ARGS;
    476     }
    477     stats->num_rate               = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES]);
    478 
    479     ALOGI("STATS PEER_ALL : numPeers %u", stats->type);
    480     ALOGI("STATS PEER_ALL : peerMacAddress  %0x:%0x:%0x:%0x:%0x:%0x ",
    481             stats->peer_mac_address[0], stats->peer_mac_address[1],
    482             stats->peer_mac_address[2],stats->peer_mac_address[3],
    483             stats->peer_mac_address[4],stats->peer_mac_address[5]);
    484     ALOGI("STATS PEER_ALL : capabilities %0x", stats->capabilities);
    485     ALOGI("STATS PEER_ALL :  numRate %u", stats->num_rate);
    486 
    487 
    488     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO])
    489     {
    490         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO not found", __func__);
    491         return WIFI_ERROR_INVALID_ARGS;
    492     }
    493     for (rateInfo = (struct nlattr *) nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO]), rem = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO]);
    494             nla_ok(rateInfo, rem);
    495             rateInfo = nla_next(rateInfo, &(rem)))
    496     {
    497         struct nlattr *tb2[ QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX+ 1];
    498         pRateStats = (wifi_rate_stat *) ((u8 *)stats->rate_stats + (i++ * sizeof(wifi_rate_stat)));
    499 
    500         nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX, (struct nlattr *) nla_data(rateInfo), nla_len(rateInfo), NULL);
    501         ret = get_wifi_rate_stat(pRateStats, tb2);
    502         if(ret != WIFI_SUCCESS)
    503         {
    504             return ret;
    505         }
    506     }
    507     return WIFI_SUCCESS;
    508 }
    509 
    510 wifi_error LLStatsCommand::get_wifi_iface_stats(wifi_iface_stat *stats,
    511                                                 struct nlattr **tb_vendor)
    512 {
    513     struct nlattr *wmmInfo;
    514     wifi_wmm_ac_stat *pWmmStats;
    515     int i=0, rem;
    516     wifi_error ret = WIFI_SUCCESS;
    517 
    518     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX])
    519     {
    520         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX"
    521                 "not found", __func__);
    522         return WIFI_ERROR_INVALID_ARGS;
    523     }
    524     stats->beacon_rx = nla_get_u32(tb_vendor[
    525             QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX]);
    526 
    527     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET])
    528     {
    529         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET"
    530                 " not found", __func__);
    531         stats->average_tsf_offset = 0;
    532     } else {
    533         stats->average_tsf_offset = nla_get_u64(tb_vendor[
    534                 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET]);
    535     }
    536 
    537     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED])
    538     {
    539         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED"
    540                 " not found", __func__);
    541         stats->leaky_ap_detected = 0;
    542     } else {
    543         stats->leaky_ap_detected = nla_get_u32(tb_vendor[
    544                 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED]);
    545     }
    546 
    547     if (!tb_vendor[
    548         QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED])
    549     {
    550         ALOGE("%s: "
    551         "QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED"
    552                 " not found", __func__);
    553         stats->leaky_ap_avg_num_frames_leaked = 0;
    554     } else {
    555         stats->leaky_ap_avg_num_frames_leaked = nla_get_u32(tb_vendor[
    556            QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED]);
    557     }
    558 
    559     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME])
    560     {
    561         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME"
    562                 " not found", __func__);
    563         stats->leaky_ap_guard_time = 0;
    564     } else {
    565         stats->leaky_ap_guard_time = nla_get_u32(tb_vendor[
    566                 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME]);
    567     }
    568 
    569     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX])
    570     {
    571         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX"
    572                 " not found", __func__);
    573         return WIFI_ERROR_INVALID_ARGS;
    574     }
    575     stats->mgmt_rx         = nla_get_u32(tb_vendor[
    576             QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX]);
    577 
    578     if (!tb_vendor[
    579             QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX])
    580     {
    581         ALOGE("%s: "
    582                 "QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX"
    583                 " not found", __func__);
    584         return WIFI_ERROR_INVALID_ARGS;
    585     }
    586     stats->mgmt_action_rx  = nla_get_u32(tb_vendor[
    587             QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX]);
    588 
    589     if (!tb_vendor[
    590             QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX])
    591     {
    592         ALOGE("%s: "
    593                 "QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX"
    594                 " not found", __func__);
    595         return WIFI_ERROR_INVALID_ARGS;
    596     }
    597     stats->mgmt_action_tx  = nla_get_u32(tb_vendor[
    598             QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX]);
    599 
    600     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT])
    601     {
    602         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT"
    603                 " not found", __func__);
    604         return WIFI_ERROR_INVALID_ARGS;
    605     }
    606     stats->rssi_mgmt       = get_s32(tb_vendor[
    607             QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT]);
    608 
    609     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA])
    610     {
    611         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA"
    612                 " not found", __func__);
    613         return WIFI_ERROR_INVALID_ARGS;
    614     }
    615     stats->rssi_data       = get_s32(tb_vendor[
    616             QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA]);
    617 
    618     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK])
    619     {
    620         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK"
    621                 " not found", __func__);
    622         return WIFI_ERROR_INVALID_ARGS;
    623     }
    624     stats->rssi_ack        = get_s32(tb_vendor[
    625             QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK]);
    626 
    627     ALOGI("STATS IFACE: beaconRx : %u ", stats->beacon_rx);
    628     ALOGI("STATS IFACE: mgmtRx %u ", stats->mgmt_rx);
    629     ALOGI("STATS IFACE: mgmtActionRx  %u ", stats->mgmt_action_rx);
    630     ALOGI("STATS IFACE: mgmtActionTx %u ", stats->mgmt_action_tx);
    631     ALOGI("STATS IFACE: rssiMgmt %d ", stats->rssi_mgmt);
    632     ALOGI("STATS IFACE: rssiData %d ", stats->rssi_data);
    633     ALOGI("STATS IFACE: rssiAck  %d ", stats->rssi_ack);
    634 
    635     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO])
    636     {
    637         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO"
    638                 " not found", __func__);
    639         return WIFI_ERROR_INVALID_ARGS;
    640     }
    641 
    642     for (wmmInfo = (struct nlattr *) nla_data(tb_vendor[
    643                 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO]),
    644             rem = nla_len(tb_vendor[
    645                 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO]);
    646             nla_ok(wmmInfo, rem);
    647             wmmInfo = nla_next(wmmInfo, &(rem)))
    648     {
    649         struct nlattr *tb2[ QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX+ 1];
    650         pWmmStats = (wifi_wmm_ac_stat *) ((u8 *)stats->ac
    651                 + (i++ * sizeof(wifi_wmm_ac_stat)));
    652         nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX,
    653                 (struct nlattr *) nla_data(wmmInfo),
    654                 nla_len(wmmInfo), NULL);
    655         ret = get_wifi_wmm_ac_stat(pWmmStats, tb2);
    656         if(ret != WIFI_SUCCESS)
    657         {
    658             return ret;
    659         }
    660     }
    661 
    662     return WIFI_SUCCESS;
    663 }
    664 
    665 static wifi_error get_wifi_radio_stats(wifi_radio_stat *stats,
    666                                        struct nlattr **tb_vendor)
    667 {
    668     u32 i = 0;
    669     struct nlattr *chInfo;
    670     wifi_channel_stat *pChStats;
    671     int rem;
    672     wifi_error ret = WIFI_SUCCESS;
    673 
    674     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID])
    675     {
    676         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID not found", __func__);
    677         return WIFI_ERROR_INVALID_ARGS;
    678     }
    679     stats->radio             = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID]);
    680 
    681     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME])
    682     {
    683         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME not found", __func__);
    684         return WIFI_ERROR_INVALID_ARGS;
    685     }
    686     stats->on_time           = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME]);
    687 
    688     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME])
    689     {
    690         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME not found", __func__);
    691         return WIFI_ERROR_INVALID_ARGS;
    692     }
    693     stats->tx_time           = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME]);
    694 
    695     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME])
    696     {
    697         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME not found", __func__);
    698         return WIFI_ERROR_INVALID_ARGS;
    699     }
    700     stats->rx_time           = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME]);
    701 
    702     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN])
    703     {
    704         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN not found", __func__);
    705         return WIFI_ERROR_INVALID_ARGS;
    706     }
    707     stats->on_time_scan      = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN]);
    708 
    709     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD])
    710     {
    711         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD not found", __func__);
    712         return WIFI_ERROR_INVALID_ARGS;
    713     }
    714     stats->on_time_nbd       = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD]);
    715 
    716     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_GSCAN])
    717     {
    718         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_GSCAN not found", __func__);
    719         return WIFI_ERROR_INVALID_ARGS;
    720     }
    721     stats->on_time_gscan     = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_GSCAN]);
    722 
    723     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN])
    724     {
    725         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN not found", __func__);
    726         return WIFI_ERROR_INVALID_ARGS;
    727     }
    728     stats->on_time_roam_scan = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN]);
    729 
    730     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN])
    731     {
    732         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN not found", __func__);
    733         return WIFI_ERROR_INVALID_ARGS;
    734     }
    735     stats->on_time_pno_scan  = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN]);
    736 
    737     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20])
    738     {
    739         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20 not found", __func__);
    740         return WIFI_ERROR_INVALID_ARGS;
    741     }
    742     stats->on_time_hs20      = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20]);
    743 
    744 
    745     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS])
    746     {
    747         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS not found", __func__);
    748         return WIFI_ERROR_INVALID_ARGS;
    749     }
    750     stats->num_channels                           = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS]);
    751 
    752 
    753     if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO])
    754     {
    755         ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO not found", __func__);
    756         return WIFI_ERROR_INVALID_ARGS;
    757     }
    758     for (chInfo = (struct nlattr *) nla_data(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO]), rem = nla_len(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO]);
    759             nla_ok(chInfo, rem);
    760             chInfo = nla_next(chInfo, &(rem)))
    761     {
    762         struct nlattr *tb2[ QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX+ 1];
    763         pChStats = (wifi_channel_stat *) ((u8 *)stats->channels + (i++ * (sizeof(wifi_channel_stat))));
    764         nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX, (struct nlattr *) nla_data(chInfo), nla_len(chInfo), NULL);
    765 
    766         if (!tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH])
    767         {
    768             ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH not found", __func__);
    769             return WIFI_ERROR_INVALID_ARGS;
    770         }
    771         pChStats->channel.width                  = (wifi_channel_width)nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH]);
    772 
    773         if (!tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ])
    774         {
    775             ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ not found", __func__);
    776             return WIFI_ERROR_INVALID_ARGS;
    777         }
    778         pChStats->channel.center_freq            = (wifi_channel)nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ]);
    779 
    780         if (!tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0])
    781         {
    782             ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0 not found", __func__);
    783             return WIFI_ERROR_INVALID_ARGS;
    784         }
    785         pChStats->channel.center_freq0           = (wifi_channel)nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0]);
    786 
    787         if (!tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1])
    788         {
    789             ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1 not found", __func__);
    790             return WIFI_ERROR_INVALID_ARGS;
    791         }
    792         pChStats->channel.center_freq1           = (wifi_channel)nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1]);
    793 
    794         if (!tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME])
    795         {
    796             ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME not found", __func__);
    797             return WIFI_ERROR_INVALID_ARGS;
    798         }
    799         pChStats->on_time                = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME]);
    800 
    801         if (!tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME])
    802         {
    803             ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME not found", __func__);
    804             return WIFI_ERROR_INVALID_ARGS;
    805         }
    806         pChStats->cca_busy_time          = nla_get_u32(tb2[QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME]);
    807     }
    808     return WIFI_SUCCESS;
    809 }
    810 
    811 void LLStatsCommand::getClearRspParams(u32 *stats_clear_rsp_mask, u8 *stop_rsp)
    812 {
    813     *stats_clear_rsp_mask =  mClearRspParams.stats_clear_rsp_mask;
    814     *stop_rsp = mClearRspParams.stop_rsp;
    815 }
    816 
    817 int LLStatsCommand::requestResponse()
    818 {
    819     return WifiCommand::requestResponse(mMsg);
    820 }
    821 
    822 int LLStatsCommand::handleResponse(WifiEvent &reply)
    823 {
    824     ALOGI("Got a LLStats message from Driver");
    825     unsigned i=0;
    826     int status = WIFI_ERROR_NONE;
    827     WifiVendorCommand::handleResponse(reply);
    828 
    829     // Parse the vendordata and get the attribute
    830 
    831     switch(mSubcmd)
    832     {
    833         case QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET:
    834         {
    835             u32 resultsBufSize = 0;
    836             struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX + 1];
    837             int rem;
    838 
    839             nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX,
    840                     (struct nlattr *)mVendorData,
    841                     mDataLen, NULL);
    842 
    843             if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE])
    844             {
    845                 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE not found",
    846                         __func__);
    847                 status = WIFI_ERROR_INVALID_ARGS;
    848                 goto cleanup;
    849             }
    850 
    851             switch(nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE]))
    852             {
    853                 case QCA_NL80211_VENDOR_SUBCMD_LL_STATS_TYPE_RADIO:
    854                 {
    855                     ALOGI("QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS"
    856                           " Received");
    857                     if (!tb_vendor[
    858                         QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS
    859                         ])
    860                     {
    861                         ALOGE("%s:"
    862                             "QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS"
    863                             " not found", __func__);
    864                         status = WIFI_ERROR_INVALID_ARGS;
    865                         goto cleanup;
    866                     }
    867 
    868                     ALOGI(" NumChan is %d\n ",
    869                             nla_get_u32(tb_vendor[
    870                             QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS]));
    871 
    872                     resultsBufSize += (nla_get_u32(tb_vendor[
    873                             QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS])
    874                             * sizeof(wifi_channel_stat)
    875                             + sizeof(wifi_radio_stat));
    876                     mResultsParams.radio_stat =
    877                             (wifi_radio_stat *)malloc(resultsBufSize);
    878                     if (!mResultsParams.radio_stat)
    879                     {
    880                         ALOGE("%s: radio_stat: malloc Failed", __func__);
    881                         status = WIFI_ERROR_OUT_OF_MEMORY;
    882                         goto cleanup;
    883                     }
    884                     memset(mResultsParams.radio_stat, 0, resultsBufSize);
    885 
    886                     wifi_channel_stat *pWifiChannelStats;
    887                     status = get_wifi_radio_stats(mResultsParams.radio_stat,
    888                               tb_vendor);
    889                     if(status != WIFI_SUCCESS)
    890                     {
    891                         goto cleanup;
    892                     }
    893 
    894                     ALOGI(" radio is %u ", mResultsParams.radio_stat->radio);
    895                     ALOGI(" onTime is %u ", mResultsParams.radio_stat->on_time);
    896                     ALOGI(" txTime is %u ", mResultsParams.radio_stat->tx_time);
    897                     ALOGI(" rxTime is %u ", mResultsParams.radio_stat->rx_time);
    898                     ALOGI(" onTimeScan is %u ",
    899                         mResultsParams.radio_stat->on_time_scan);
    900                     ALOGI(" onTimeNbd is %u ",
    901                         mResultsParams.radio_stat->on_time_nbd);
    902                     ALOGI(" onTimeGscan is %u ",
    903                         mResultsParams.radio_stat->on_time_gscan);
    904                     ALOGI(" onTimeRoamScan is %u",
    905                         mResultsParams.radio_stat->on_time_roam_scan);
    906                     ALOGI(" onTimePnoScan is %u ",
    907                         mResultsParams.radio_stat->on_time_pno_scan);
    908                     ALOGI(" onTimeHs20 is %u ",
    909                         mResultsParams.radio_stat->on_time_hs20);
    910                     ALOGI(" numChannels is %u ",
    911                         mResultsParams.radio_stat->num_channels);
    912                     for ( i=0; i < mResultsParams.radio_stat->num_channels; i++)
    913                     {
    914                         pWifiChannelStats =
    915                             (wifi_channel_stat *) (
    916                                 (u8 *)mResultsParams.radio_stat->channels
    917                                 + (i * sizeof(wifi_channel_stat)));
    918 
    919                         ALOGI("  width is %u ",
    920                              pWifiChannelStats->channel.width);
    921                         ALOGI("  CenterFreq %u ",
    922                              pWifiChannelStats->channel.center_freq);
    923                         ALOGI("  CenterFreq0 %u ",
    924                              pWifiChannelStats->channel.center_freq0);
    925                         ALOGI("  CenterFreq1 %u ",
    926                              pWifiChannelStats->channel.center_freq1);
    927                         ALOGI("  onTime %u ",
    928                              pWifiChannelStats->on_time);
    929                         ALOGI("  ccaBusyTime %u ",
    930                              pWifiChannelStats->cca_busy_time);
    931                     }
    932                 }
    933                 break;
    934 
    935                 case QCA_NL80211_VENDOR_SUBCMD_LL_STATS_TYPE_IFACE:
    936                 {
    937                     ALOGI("QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS"
    938                             " Received");
    939                     resultsBufSize = sizeof(wifi_iface_stat);
    940                     mResultsParams.iface_stat =
    941                         (wifi_iface_stat *) malloc (resultsBufSize);
    942                     if (!mResultsParams.iface_stat)
    943                     {
    944                         ALOGE("%s: iface_stat: malloc Failed", __func__);
    945                         status = WIFI_ERROR_OUT_OF_MEMORY;
    946                         goto cleanup;
    947                     }
    948                     memset(mResultsParams.iface_stat, 0, resultsBufSize);
    949                     status = get_wifi_interface_info(
    950                             &mResultsParams.iface_stat->info, tb_vendor);
    951                     if(status != WIFI_SUCCESS)
    952                     {
    953                         goto cleanup;
    954                     }
    955                     status = get_wifi_iface_stats(mResultsParams.iface_stat,
    956                             tb_vendor);
    957                     if(status != WIFI_SUCCESS)
    958                     {
    959                         goto cleanup;
    960                     }
    961                     if (!tb_vendor[
    962                         QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS])
    963                     {
    964                         ALOGE("%s:QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS"
    965                                 " not found", __func__);
    966                         ALOGE("Expecting Peer stats event");
    967                     } else {
    968                         mResultsParams.iface_stat->num_peers =
    969                             nla_get_u32(tb_vendor[
    970                                 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS]);
    971                         ALOGI("%s: numPeers is %u\n", __func__,
    972                                 mResultsParams.iface_stat->num_peers);
    973                         if(mResultsParams.iface_stat->num_peers == 0)
    974                         {
    975                             ALOGE("Not Expecting Peer stats event");
    976                             // Number of Radios are 1 for now
    977                             mHandler.on_link_stats_results(mRequestId,
    978                                     mResultsParams.iface_stat,
    979                                     1,
    980                                     mResultsParams.radio_stat);
    981                             if(mResultsParams.radio_stat)
    982                             {
    983                                 free(mResultsParams.radio_stat);
    984                                 mResultsParams.radio_stat = NULL;
    985                             }
    986                             free(mResultsParams.iface_stat);
    987                             mResultsParams.iface_stat = NULL;
    988                         }
    989                     }
    990                 }
    991                 break;
    992 
    993                 case QCA_NL80211_VENDOR_SUBCMD_LL_STATS_TYPE_PEERS:
    994                 {
    995                     struct nlattr *peerInfo;
    996                     wifi_iface_stat *pIfaceStat;
    997                     u32 numPeers, num_rates = 0;
    998                     ALOGI("QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS"
    999                           " Received");
   1000                     if (!tb_vendor[
   1001                             QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS])
   1002                     {
   1003                         ALOGE("%s:QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS"
   1004                               " not found", __func__);
   1005                         status = WIFI_ERROR_INVALID_ARGS;
   1006                         goto cleanup;
   1007                     }
   1008                     ALOGI(" numPeers is %u in %s\n",
   1009                             nla_get_u32(tb_vendor[
   1010                             QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS]),
   1011                             __func__);
   1012 
   1013                     if((numPeers = nla_get_u32(tb_vendor[
   1014                         QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS])) > 0)
   1015                     {
   1016                         if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO])
   1017                         {
   1018                             ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO"
   1019                                     " not found", __func__);
   1020                             status = WIFI_ERROR_INVALID_ARGS;
   1021                             goto cleanup;
   1022                         }
   1023                         for (peerInfo = (struct nlattr *) nla_data(tb_vendor[
   1024                              QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO]),
   1025                              rem = nla_len(tb_vendor[
   1026                              QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO]);
   1027                                 nla_ok(peerInfo, rem);
   1028                                 peerInfo = nla_next(peerInfo, &(rem)))
   1029                         {
   1030                             struct nlattr *tb2[
   1031                                 QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX+ 1];
   1032 
   1033                             nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX,
   1034                                     (struct nlattr *) nla_data(peerInfo),
   1035                                     nla_len(peerInfo), NULL);
   1036 
   1037                             if (!tb2[
   1038                              QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES])
   1039                             {
   1040                                 ALOGE("%s:"
   1041                              "QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES"
   1042                              " not found", __func__);
   1043                                 status = WIFI_ERROR_INVALID_ARGS;
   1044                                 goto cleanup;
   1045                             }
   1046                             num_rates += nla_get_u32(tb2[
   1047                             QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES]);
   1048                         }
   1049                         resultsBufSize += (numPeers * sizeof(wifi_peer_info)
   1050                                 + num_rates * sizeof(wifi_rate_stat)
   1051                                 + sizeof (wifi_iface_stat));
   1052                         pIfaceStat = (wifi_iface_stat *) malloc (
   1053                                 resultsBufSize);
   1054                         if (!pIfaceStat)
   1055                         {
   1056                             ALOGE("%s: pIfaceStat: malloc Failed", __func__);
   1057                             status = WIFI_ERROR_OUT_OF_MEMORY;
   1058                             goto cleanup;
   1059                         }
   1060 
   1061                         memset(pIfaceStat, 0, resultsBufSize);
   1062                         if(mResultsParams.iface_stat)
   1063                             memcpy ( pIfaceStat, mResultsParams.iface_stat,
   1064                                 sizeof(wifi_iface_stat));
   1065                         wifi_peer_info *pPeerStats;
   1066                         pIfaceStat->num_peers = numPeers;
   1067 
   1068                         if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO])
   1069                         {
   1070                             ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO"
   1071                                   " not found", __func__);
   1072                             status = WIFI_ERROR_INVALID_ARGS;
   1073                             goto cleanup;
   1074                         }
   1075                         for (peerInfo = (struct nlattr *) nla_data(tb_vendor[
   1076                             QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO]),
   1077                             rem = nla_len(tb_vendor[
   1078                                 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO]);
   1079                                 nla_ok(peerInfo, rem);
   1080                                 peerInfo = nla_next(peerInfo, &(rem)))
   1081                         {
   1082                             struct nlattr *tb2[
   1083                                 QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX+ 1];
   1084                             pPeerStats = (wifi_peer_info *) (
   1085                                            (u8 *)pIfaceStat->peer_info
   1086                                            + (i++ * sizeof(wifi_peer_info)));
   1087                             nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX,
   1088                                 (struct nlattr *) nla_data(peerInfo),
   1089                                 nla_len(peerInfo), NULL);
   1090                             status = get_wifi_peer_info(pPeerStats, tb2);
   1091                             if(status != WIFI_SUCCESS)
   1092                             {
   1093                                 goto cleanup;
   1094                             }
   1095                         }
   1096                         if(mResultsParams.iface_stat)
   1097                             free (mResultsParams.iface_stat);
   1098                         mResultsParams.iface_stat = pIfaceStat;
   1099                     }
   1100 
   1101                     // Number of Radios are 1 for now
   1102                     mHandler.on_link_stats_results(mRequestId,
   1103                             mResultsParams.iface_stat, 1,
   1104                             mResultsParams.radio_stat);
   1105                     if(mResultsParams.radio_stat)
   1106                     {
   1107                         free(mResultsParams.radio_stat);
   1108                         mResultsParams.radio_stat = NULL;
   1109                     }
   1110                     if(mResultsParams.iface_stat)
   1111                     {
   1112                         free(mResultsParams.iface_stat);
   1113                         mResultsParams.iface_stat = NULL;
   1114                     }
   1115                 }
   1116                 break;
   1117 
   1118                 case QCA_NL80211_VENDOR_SUBCMD_LL_STATS_TYPE_INVALID:
   1119                 default:
   1120                     //error case should not happen print log
   1121                     ALOGE("%s: Wrong LLStats subcmd received %d", __func__,
   1122                            mSubcmd);
   1123             }
   1124         }
   1125         break;
   1126 
   1127         case QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR:
   1128         {
   1129             struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
   1130             nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
   1131                     (struct nlattr *)mVendorData,
   1132                     mDataLen, NULL);
   1133 
   1134             if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK])
   1135             {
   1136                 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK not found", __func__);
   1137                 return WIFI_ERROR_INVALID_ARGS;
   1138             }
   1139             ALOGI("Resp mask : %d\n", nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK]));
   1140 
   1141             if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP])
   1142             {
   1143                 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP not found", __func__);
   1144                 return WIFI_ERROR_INVALID_ARGS;
   1145             }
   1146             ALOGI("STOP resp : %d\n", nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP]));
   1147 
   1148             if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK])
   1149             {
   1150                 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK not found", __func__);
   1151                 return WIFI_ERROR_INVALID_ARGS;
   1152             }
   1153             mClearRspParams.stats_clear_rsp_mask = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK]);
   1154 
   1155             if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP])
   1156             {
   1157                 ALOGE("%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP not found", __func__);
   1158                 return WIFI_ERROR_INVALID_ARGS;
   1159             }
   1160             mClearRspParams.stop_rsp = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP]);
   1161             break;
   1162         }
   1163         default :
   1164             ALOGE("%s: Wrong LLStats subcmd received %d", __func__, mSubcmd);
   1165     }
   1166     return NL_SKIP;
   1167 
   1168 cleanup:
   1169     if(mResultsParams.radio_stat)
   1170     {
   1171         free(mResultsParams.radio_stat);
   1172         mResultsParams.radio_stat = NULL;
   1173     }
   1174 
   1175     if(mResultsParams.iface_stat)
   1176     {
   1177         free(mResultsParams.iface_stat);
   1178         mResultsParams.iface_stat = NULL;
   1179     }
   1180     return status;
   1181 }
   1182 
   1183 //Implementation of the functions exposed in linklayer.h
   1184 wifi_error wifi_set_link_stats(wifi_interface_handle iface,
   1185                                wifi_link_layer_params params)
   1186 {
   1187     int ret = 0;
   1188     LLStatsCommand *LLCommand;
   1189     struct nlattr *nl_data;
   1190     interface_info *iinfo = getIfaceInfo(iface);
   1191     wifi_handle handle = getWifiHandle(iface);
   1192 
   1193     LLCommand = LLStatsCommand::instance(handle);
   1194     if (LLCommand == NULL) {
   1195         ALOGE("%s: Error LLStatsCommand NULL", __func__);
   1196         return WIFI_ERROR_UNKNOWN;
   1197     }
   1198     LLCommand->setSubCmd(QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET);
   1199 
   1200     /* create the message */
   1201     ret = LLCommand->create();
   1202     if (ret < 0)
   1203         goto cleanup;
   1204 
   1205     ret = LLCommand->set_iface_id(iinfo->name);
   1206     if (ret < 0)
   1207         goto cleanup;
   1208 
   1209     /*add the attributes*/
   1210     nl_data = LLCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
   1211     if (!nl_data)
   1212         goto cleanup;
   1213     /**/
   1214     ret = LLCommand->put_u32(QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD,
   1215                                   params.mpdu_size_threshold);
   1216     if (ret < 0)
   1217         goto cleanup;
   1218     /**/
   1219     ret = LLCommand->put_u32(
   1220                 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING,
   1221                 params.aggressive_statistics_gathering);
   1222     if (ret < 0)
   1223         goto cleanup;
   1224     LLCommand->attr_end(nl_data);
   1225 
   1226     ret = LLCommand->requestResponse();
   1227     if (ret != 0) {
   1228         ALOGE("%s: requestResponse Error:%d",__func__, ret);
   1229     }
   1230 
   1231 cleanup:
   1232     return (wifi_error)ret;
   1233 }
   1234 
   1235 //Implementation of the functions exposed in LLStats.h
   1236 wifi_error wifi_get_link_stats(wifi_request_id id,
   1237                                wifi_interface_handle iface,
   1238                                wifi_stats_result_handler handler)
   1239 {
   1240     int ret = 0;
   1241     LLStatsCommand *LLCommand;
   1242     struct nlattr *nl_data;
   1243     interface_info *iinfo = getIfaceInfo(iface);
   1244     wifi_handle handle = getWifiHandle(iface);
   1245 
   1246     LLCommand = LLStatsCommand::instance(handle);
   1247     if (LLCommand == NULL) {
   1248         ALOGE("%s: Error LLStatsCommand NULL", __func__);
   1249         return WIFI_ERROR_UNKNOWN;
   1250     }
   1251     LLCommand->setSubCmd(QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET);
   1252 
   1253     LLCommand->initGetContext(id);
   1254 
   1255     LLCommand->setHandler(handler);
   1256 
   1257     /* create the message */
   1258     ret = LLCommand->create();
   1259     if (ret < 0)
   1260         goto cleanup;
   1261 
   1262     ret = LLCommand->set_iface_id(iinfo->name);
   1263     if (ret < 0)
   1264         goto cleanup;
   1265     /*add the attributes*/
   1266     nl_data = LLCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
   1267     if (!nl_data)
   1268         goto cleanup;
   1269     ret = LLCommand->put_u32(QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID,
   1270                                   id);
   1271     if (ret < 0)
   1272         goto cleanup;
   1273     ret = LLCommand->put_u32(QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK,
   1274                                   7);
   1275     if (ret < 0)
   1276         goto cleanup;
   1277 
   1278     /**/
   1279     LLCommand->attr_end(nl_data);
   1280 
   1281     ret = LLCommand->requestResponse();
   1282     if (ret != 0) {
   1283         ALOGE("%s: requestResponse Error:%d",__func__, ret);
   1284     }
   1285     if (ret < 0)
   1286         goto cleanup;
   1287 
   1288 cleanup:
   1289     return (wifi_error)ret;
   1290 }
   1291 
   1292 
   1293 //Implementation of the functions exposed in LLStats.h
   1294 wifi_error wifi_clear_link_stats(wifi_interface_handle iface,
   1295                                  u32 stats_clear_req_mask,
   1296                                  u32 *stats_clear_rsp_mask,
   1297                                  u8 stop_req, u8 *stop_rsp)
   1298 {
   1299     int ret = 0;
   1300     LLStatsCommand *LLCommand;
   1301     struct nlattr *nl_data;
   1302     interface_info *iinfo = getIfaceInfo(iface);
   1303     wifi_handle handle = getWifiHandle(iface);
   1304 
   1305     LLCommand = LLStatsCommand::instance(handle);
   1306     if (LLCommand == NULL) {
   1307         ALOGE("%s: Error LLStatsCommand NULL", __func__);
   1308         return WIFI_ERROR_UNKNOWN;
   1309     }
   1310     LLCommand->setSubCmd(QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR);
   1311 
   1312     /* create the message */
   1313     ret = LLCommand->create();
   1314     if (ret < 0)
   1315         goto cleanup;
   1316 
   1317     ret = LLCommand->set_iface_id(iinfo->name);
   1318     if (ret < 0)
   1319         goto cleanup;
   1320     /*add the attributes*/
   1321     nl_data = LLCommand->attr_start(NL80211_ATTR_VENDOR_DATA);
   1322     if (!nl_data)
   1323         goto cleanup;
   1324     /**/
   1325     ret = LLCommand->put_u32(QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK,
   1326                                   stats_clear_req_mask);
   1327     if (ret < 0)
   1328         goto cleanup;
   1329     /**/
   1330     ret = LLCommand->put_u8(QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ,
   1331                                    stop_req);
   1332     if (ret < 0)
   1333         goto cleanup;
   1334     LLCommand->attr_end(nl_data);
   1335 
   1336     ret = LLCommand->requestResponse();
   1337     if (ret != 0) {
   1338         ALOGE("%s: requestResponse Error:%d",__func__, ret);
   1339     }
   1340 
   1341     LLCommand->getClearRspParams(stats_clear_rsp_mask, stop_rsp);
   1342 
   1343 cleanup:
   1344     delete LLCommand;
   1345     return (wifi_error)ret;
   1346 }
   1347 
   1348