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