summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Danzberger <daniel@dd-wrt.com>2018-10-31 09:49:42 +0100
committerJohn Crispin <john@phrozen.org>2018-11-26 11:03:17 +0100
commit5aa8c5496cd86a1b092d192ffc2364c7a23df25f (patch)
treee6fd7347c2bb5bc60f6cc51446e8921db26de13c
parent77a9e98009d43200ab7140acf1fdfd7d3b055c51 (diff)
downloadiwinfo-5aa8c5496cd86a1b092d192ffc2364c7a23df25f.tar.gz
libiwinfo: nl80211: add mesh stats on assoclist.
Signed-off-by: Daniel Danzberger <daniel@dd-wrt.com>
-rw-r--r--include/iwinfo.h6
-rw-r--r--iwinfo_nl80211.c76
2 files changed, 82 insertions, 0 deletions
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])
{