From 5aa8c5496cd86a1b092d192ffc2364c7a23df25f Mon Sep 17 00:00:00 2001 From: Daniel Danzberger Date: Wed, 31 Oct 2018 09:49:42 +0100 Subject: [PATCH] libiwinfo: nl80211: add mesh stats on assoclist. Signed-off-by: Daniel Danzberger --- include/iwinfo.h | 6 ++++ iwinfo_nl80211.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) 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]) {