Patchwork wpa_supplicant: Add PKTCNT_POLL command to get TX packet counters

login
register
mail settings
Submitter Yuhao Zheng
Date Aug. 30, 2012, 5:17 p.m.
Message ID <20120830172420.76BE137FD0@ushik.mtv.corp.google.com>
Download mbox | patch
Permalink /patch/180848/
State Accepted
Commit dc7785f845ed540e59fd7886fe61e8181495020a
Headers show

Comments

Yuhao Zheng - Aug. 30, 2012, 5:17 p.m.
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
---
 src/drivers/driver_nl80211.c |    4 ++++
 wpa_supplicant/ctrl_iface.c  |   21 +++++++++++++++++++++
 wpa_supplicant/driver_i.h    |    8 ++++++++
 wpa_supplicant/wpa_cli.c     |   10 ++++++++++
 4 files changed, 43 insertions(+), 0 deletions(-)
Jouni Malinen - Sept. 5, 2012, 2:09 p.m.
Thanks, applied. Though, please note that the read_sta_data() driver_op
used to be AP only operation and it would not have been available in a
wpa_supplicant build if AP support (e.g., for P2P) was not included in
the build. I changed that in a separate commit so that the function is
now available for all wpa_supplicant builds.

Patch

diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 069e026..180e2f9 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -7373,6 +7373,7 @@  static int get_sta_handler(struct nl_msg *msg, void *arg)
 		[NL80211_STA_INFO_TX_BYTES] = { .type = NLA_U32 },
 		[NL80211_STA_INFO_RX_PACKETS] = { .type = NLA_U32 },
 		[NL80211_STA_INFO_TX_PACKETS] = { .type = NLA_U32 },
+		[NL80211_STA_INFO_TX_FAILED] = { .type = NLA_U32 },
 	};
 
 	nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
@@ -7408,6 +7409,9 @@  static int get_sta_handler(struct nl_msg *msg, void *arg)
 	if (stats[NL80211_STA_INFO_TX_PACKETS])
 		data->tx_packets =
 			nla_get_u32(stats[NL80211_STA_INFO_TX_PACKETS]);
+	if (stats[NL80211_STA_INFO_TX_FAILED])
+		data->tx_retry_failed =
+			nla_get_u32(stats[NL80211_STA_INFO_TX_FAILED]);
 
 	return NL_SKIP;
 }
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index d7ce6fe..916daa4 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -4305,6 +4305,24 @@  static int wpa_supplicant_signal_poll(struct wpa_supplicant *wpa_s, char *buf,
 }
 
 
+static int wpa_supplicant_pktcnt_poll(struct wpa_supplicant *wpa_s, char *buf,
+				      size_t buflen)
+{
+	struct hostap_sta_driver_data sta;
+	int ret;
+
+	ret = wpa_drv_pktcnt_poll(wpa_s, &sta);
+	if (ret)
+		return -1;
+
+	ret = os_snprintf(buf, buflen, "TXGOOD=%lu\nTXBAD=%lu\nRXGOOD=%lu\n",
+			  sta.tx_packets, sta.tx_retry_failed, sta.rx_packets);
+	if (ret < 0 || (size_t)ret > buflen)
+		return -1;
+	return ret;
+}
+
+
 char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
 					 char *buf, size_t *resp_len)
 {
@@ -4806,6 +4824,9 @@  char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
 	} else if (os_strncmp(buf, "SIGNAL_POLL", 11) == 0) {
 		reply_len = wpa_supplicant_signal_poll(wpa_s, reply,
 						       reply_size);
+	} else if (os_strncmp(buf, "PKTCNT_POLL", 11) == 0) {
+		reply_len = wpa_supplicant_pktcnt_poll(wpa_s, reply,
+						       reply_size);
 #ifdef CONFIG_AUTOSCAN
 	} else if (os_strncmp(buf, "AUTOSCAN ", 9) == 0) {
 		if (wpa_supplicant_ctrl_iface_autoscan(wpa_s, buf + 9))
diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h
index ac0936a..e28fecb 100644
--- a/wpa_supplicant/driver_i.h
+++ b/wpa_supplicant/driver_i.h
@@ -463,6 +463,14 @@  static inline int wpa_drv_signal_poll(struct wpa_supplicant *wpa_s,
 	return -1;
 }
 
+static inline int wpa_drv_pktcnt_poll(struct wpa_supplicant *wpa_s,
+				      struct hostap_sta_driver_data *sta)
+{
+	if (wpa_s->driver->read_sta_data)
+		return wpa_s->driver->read_sta_data(wpa_s->drv_priv, sta, wpa_s->bssid);
+	return -1;
+}
+
 static inline int wpa_drv_set_ap_wps_ie(struct wpa_supplicant *wpa_s,
 					const struct wpabuf *beacon,
 					const struct wpabuf *proberesp,
diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c
index 2cb9513..e510b9b 100644
--- a/wpa_supplicant/wpa_cli.c
+++ b/wpa_supplicant/wpa_cli.c
@@ -2174,6 +2174,13 @@  static int wpa_cli_cmd_signal_poll(struct wpa_ctrl *ctrl, int argc,
 }
 
 
+static int wpa_cli_cmd_pktcnt_poll(struct wpa_ctrl *ctrl, int argc,
+				   char *argv[])
+{
+	return wpa_ctrl_command(ctrl, "PKTCNT_POLL");
+}
+
+
 static int wpa_cli_cmd_reauthenticate(struct wpa_ctrl *ctrl, int argc,
 				      char *argv[])
 {
@@ -2619,6 +2626,9 @@  static struct wpa_cli_cmd wpa_cli_commands[] = {
 	{ "signal_poll", wpa_cli_cmd_signal_poll, NULL,
 	  cli_cmd_flag_none,
 	  "= get signal parameters" },
+	{ "pktcnt_poll", wpa_cli_cmd_pktcnt_poll, NULL,
+	  cli_cmd_flag_none,
+	  "= get TX/RX packet counters" },
 	{ "reauthenticate", wpa_cli_cmd_reauthenticate, NULL,
 	  cli_cmd_flag_none,
 	  "= trigger IEEE 802.1X/EAPOL reauthentication" },