diff mbox series

[OpenWrt-Devel] libiwinfo: nl80211: add mesh stats on assoclist.

Message ID 20181031084942.23695-1-daniel@dd-wrt.com
State Accepted
Delegated to: John Crispin
Headers show
Series [OpenWrt-Devel] libiwinfo: nl80211: add mesh stats on assoclist. | expand

Commit Message

Daniel Danzberger Oct. 31, 2018, 8:49 a.m. UTC
Signed-off-by: Daniel Danzberger <daniel@dd-wrt.com>
---
 include/iwinfo.h |  6 +++++
 iwinfo_nl80211.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 82 insertions(+)
diff mbox series

Patch

diff --git a/include/iwinfo.h b/include/iwinfo.h
index 49ee7f0..02ad623 100644
--- a/include/iwinfo.h
+++ b/include/iwinfo.h
@@ -126,6 +126,12 @@  struct iwinfo_assoclist_entry {
 	uint8_t is_mfp:1;
 	uint8_t is_tdls:1;
 	uint32_t thr;
+	uint16_t llid;
+	uint16_t plid;
+	char plink_state[16];
+	char local_ps[16];
+	char peer_ps[16];
+	char nonpeer_ps[16];
 };
 
 struct iwinfo_survey_entry {
diff --git a/iwinfo_nl80211.c b/iwinfo_nl80211.c
index ca78742..5154230 100644
--- a/iwinfo_nl80211.c
+++ b/iwinfo_nl80211.c
@@ -1756,6 +1756,57 @@  static int nl80211_get_survey_cb(struct nl_msg *msg, void *arg)
 	return NL_SKIP;
 }
 
+
+static void plink_state_to_str(char *dst, unsigned state)
+{
+	switch (state) {
+	case NL80211_PLINK_LISTEN:
+		strcpy(dst, "LISTEN");
+		break;
+	case NL80211_PLINK_OPN_SNT:
+		strcpy(dst, "OPN_SNT");
+		break;
+	case NL80211_PLINK_OPN_RCVD:
+		strcpy(dst, "OPN_RCVD");
+		break;
+	case NL80211_PLINK_CNF_RCVD:
+		strcpy(dst, "CNF_RCVD");
+		break;
+	case NL80211_PLINK_ESTAB:
+		strcpy(dst, "ESTAB");
+		break;
+	case NL80211_PLINK_HOLDING:
+		strcpy(dst, "HOLDING");
+		break;
+	case NL80211_PLINK_BLOCKED:
+		strcpy(dst, "BLOCKED");
+		break;
+	default:
+		strcpy(dst, "UNKNOWN");
+		break;
+	}
+}
+
+static void power_mode_to_str(char *dst, struct nlattr *a)
+{
+	enum nl80211_mesh_power_mode pm = nla_get_u32(a);
+
+	switch (pm) {
+	case NL80211_MESH_POWER_ACTIVE:
+		strcpy(dst, "ACTIVE");
+		break;
+	case NL80211_MESH_POWER_LIGHT_SLEEP:
+		strcpy(dst, "LIGHT SLEEP");
+		break;
+	case NL80211_MESH_POWER_DEEP_SLEEP:
+		strcpy(dst, "DEEP SLEEP");
+		break;
+	default:
+		strcpy(dst, "UNKNOWN");
+		break;
+	}
+}
+
 static int nl80211_get_assoclist_cb(struct nl_msg *msg, void *arg)
 {
 	struct nl80211_array_buf *arr = arg;
@@ -1783,6 +1834,13 @@  static int nl80211_get_assoclist_cb(struct nl_msg *msg, void *arg)
 		[NL80211_STA_INFO_STA_FLAGS] =
 			{ .minlen = sizeof(struct nl80211_sta_flag_update) },
 		[NL80211_STA_INFO_EXPECTED_THROUGHPUT]   = { .type = NLA_U32    },
+		/* mesh */
+		[NL80211_STA_INFO_LLID]          = { .type = NLA_U16	},
+		[NL80211_STA_INFO_PLID]          = { .type = NLA_U16	},
+		[NL80211_STA_INFO_PLINK_STATE]   = { .type = NLA_U8	},
+		[NL80211_STA_INFO_LOCAL_PM]      = { .type = NLA_U32	},
+		[NL80211_STA_INFO_PEER_PM]       = { .type = NLA_U32	},
+		[NL80211_STA_INFO_NONPEER_PM]    = { .type = NLA_U32	},
 	};
 
 	static struct nla_policy rate_policy[NL80211_RATE_INFO_MAX + 1] = {
@@ -1852,6 +1910,24 @@  static int nl80211_get_assoclist_cb(struct nl_msg *msg, void *arg)
 		if (sinfo[NL80211_STA_INFO_EXPECTED_THROUGHPUT])
 			e->thr = nla_get_u32(sinfo[NL80211_STA_INFO_EXPECTED_THROUGHPUT]);
 
+		/* mesh */
+		if (sinfo[NL80211_STA_INFO_LLID])
+			e->llid = nla_get_u16(sinfo[NL80211_STA_INFO_LLID]);
+
+		if (sinfo[NL80211_STA_INFO_PLID])
+			e->plid = nla_get_u16(sinfo[NL80211_STA_INFO_PLID]);
+
+		if (sinfo[NL80211_STA_INFO_PLINK_STATE])
+			plink_state_to_str(e->plink_state,
+				nla_get_u8(sinfo[NL80211_STA_INFO_PLINK_STATE]));
+
+		if (sinfo[NL80211_STA_INFO_LOCAL_PM])
+			power_mode_to_str(e->local_ps, sinfo[NL80211_STA_INFO_LOCAL_PM]);
+		if (sinfo[NL80211_STA_INFO_PEER_PM])
+			power_mode_to_str(e->peer_ps, sinfo[NL80211_STA_INFO_PEER_PM]);
+		if (sinfo[NL80211_STA_INFO_NONPEER_PM])
+			power_mode_to_str(e->nonpeer_ps, sinfo[NL80211_STA_INFO_NONPEER_PM]);
+
 		/* Station flags */
 		if (sinfo[NL80211_STA_INFO_STA_FLAGS])
 		{