Search Linux Wireless

[PATCH] iw: info: print PMSR capabilities

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Print PMSR and FTM capabilities if any.

Signed-off-by: Jaewan Kim <jaewan@xxxxxxxxxx>
---
 info.c |   3 ++
 iw.h   |   1 +
 util.c | 118 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 122 insertions(+)

diff --git a/info.c b/info.c
index 21ed07b..d13fc16 100644
--- a/info.c
+++ b/info.c
@@ -741,6 +741,9 @@ broken_combination:
 			pat->max_pattern_len, pat->max_pkt_offset, rule->max_delay);
 	}
 
+	if (tb_msg[NL80211_ATTR_PEER_MEASUREMENTS])
+		print_pmsr_capabilities(tb_msg[NL80211_ATTR_PEER_MEASUREMENTS]);
+
 	if (tb_msg[NL80211_ATTR_MAX_AP_ASSOC_STA])
 		printf("\tMaximum associated stations in AP mode: %u\n",
 		       nla_get_u16(tb_msg[NL80211_ATTR_MAX_AP_ASSOC_STA]));
diff --git a/iw.h b/iw.h
index e712c59..0707cb4 100644
--- a/iw.h
+++ b/iw.h
@@ -221,6 +221,7 @@ void print_vht_info(__u32 capa, const __u8 *mcs);
 void print_he_capability(const uint8_t *ie, int len);
 void print_he_info(struct nlattr *nl_iftype);
 void print_eht_info(struct nlattr *nl_iftype, int band);
+void print_pmsr_capabilities(const struct nlattr *pmsr_capa);
 
 char *channel_width_name(enum nl80211_chan_width width);
 const char *iftype_name(enum nl80211_iftype iftype);
diff --git a/util.c b/util.c
index 8a2ba10..18f6e71 100644
--- a/util.c
+++ b/util.c
@@ -1673,6 +1673,124 @@ void print_he_capability(const uint8_t *ie, int len)
 	__print_he_capa(mac_cap, phy_cap - 1, mcs_set, mcs_len, NULL, 0, false);
 }
 
+static void __print_ftm_capability(struct nlattr *ftm_capa)
+{
+#define PRINT_FTM_FLAG(T, NAME) \
+	do { \
+		if (T[NL80211_PMSR_FTM_CAPA_ATTR_##NAME]) \
+			printf("\t\t\t" #NAME "\n"); \
+	} while (0)
+
+#define PRINT_FTM_U8(T, NAME) \
+	do { \
+		if (T[NL80211_PMSR_FTM_CAPA_ATTR_##NAME]) \
+			printf("\t\t\t" #NAME "=\n", \
+				nla_get_u8(T[NL80211_PMSR_FTM_CAPA_ATTR_##NAME])); \
+	} while (0)
+
+	struct nlattr *tb[NL80211_PMSR_FTM_CAPA_ATTR_MAX + 1];
+	int ret;
+
+	printf("\t\tFTM (Fine time measurement or Flight time measurement)\n");
+
+	ret = nla_parse_nested(tb, NL80211_PMSR_FTM_CAPA_ATTR_MAX, ftm_capa,
+			       NULL);
+	if (ret)
+		return;
+
+	if (tb[NL80211_PMSR_FTM_CAPA_ATTR_PREAMBLES]) {
+#define PRINT_PREAMBLE(P, V) \
+	do { \
+		if (P | NL80211_PREAMBLE_##V) \
+			printf(#V " "); \
+	} while (0)
+
+		uint32_t preambles =
+			nla_get_u32(tb[NL80211_PMSR_FTM_CAPA_ATTR_PREAMBLES]);
+		printf("\t\t\tPreambles=");
+
+		PRINT_PREAMBLE(preambles, LEGACY);
+		PRINT_PREAMBLE(preambles, HT);
+		PRINT_PREAMBLE(preambles, VHT);
+		PRINT_PREAMBLE(preambles, DMG);
+		printf("\n");
+#undef PRINT_PREAMBLE
+	}
+	if (tb[NL80211_PMSR_FTM_CAPA_ATTR_BANDWIDTHS]) {
+#define PRINT_BANDWIDTH(B, V) \
+	do { \
+		if (B | NL80211_CHAN_WIDTH_##V) \
+			printf(#V " "); \
+	} while (0)
+
+		uint32_t bandwidth =
+			nla_get_u32(tb[NL80211_PMSR_FTM_CAPA_ATTR_BANDWIDTHS]);
+		printf("\t\t\tBandwidth=");
+		PRINT_BANDWIDTH(bandwidth, 20_NOHT);
+		PRINT_BANDWIDTH(bandwidth, 20);
+		PRINT_BANDWIDTH(bandwidth, 40);
+		PRINT_BANDWIDTH(bandwidth, 80);
+		PRINT_BANDWIDTH(bandwidth, 80P80);
+		PRINT_BANDWIDTH(bandwidth, 160);
+		PRINT_BANDWIDTH(bandwidth, 5);
+		PRINT_BANDWIDTH(bandwidth, 10);
+		PRINT_BANDWIDTH(bandwidth, 1);
+		PRINT_BANDWIDTH(bandwidth, 2);
+		PRINT_BANDWIDTH(bandwidth, 4);
+		PRINT_BANDWIDTH(bandwidth, 8);
+		PRINT_BANDWIDTH(bandwidth, 16);
+		PRINT_BANDWIDTH(bandwidth, 320);
+		printf("\n");
+#undef PRINT_BANDWIDTH
+	}
+	PRINT_FTM_U8(tb, MAX_BURSTS_EXPONENT);
+	PRINT_FTM_U8(tb, MAX_FTMS_PER_BURST);
+	PRINT_FTM_FLAG(tb, ASAP);
+	PRINT_FTM_FLAG(tb, NON_ASAP);
+	PRINT_FTM_FLAG(tb, REQ_LCI);
+	PRINT_FTM_FLAG(tb, REQ_CIVICLOC);
+	PRINT_FTM_FLAG(tb, TRIGGER_BASED);
+	PRINT_FTM_FLAG(tb, NON_TRIGGER_BASED);
+
+#undef PRINT_FTM_U8
+#undef PRINT_FTM_FLAG
+}
+
+void print_pmsr_capabilities(struct nlattr *pmsr_capa)
+{
+	struct nlattr *tb[NL80211_PMSR_ATTR_MAX + 1];
+	struct nlattr *nla;
+	int size;
+	int ret;
+
+	printf("\tPeer measurement (PMSR)\n");
+	ret = nla_parse_nested(tb, NL80211_PMSR_ATTR_MAX, pmsr_capa, NULL);
+	if (ret) {
+		printf("\t\tMalformed PMSR\n");
+		return;
+	}
+
+	if (tb[NL80211_PMSR_ATTR_MAX_PEERS])
+		printf("\t\tMax peers=%d\n",
+		       nla_get_u32(tb[NL80211_PMSR_ATTR_MAX_PEERS]));
+	if (tb[NL80211_PMSR_ATTR_REPORT_AP_TSF])
+		printf("\t\tREPORT_AP_TSF\n");
+	if (tb[NL80211_PMSR_ATTR_RANDOMIZE_MAC_ADDR])
+		printf("\t\tRANDOMIZE_MAC_ADDR\n");
+
+	if (tb[NL80211_PMSR_ATTR_TYPE_CAPA]) {
+		nla_for_each_nested(nla, tb[NL80211_PMSR_ATTR_TYPE_CAPA], size) {
+			switch (nla_type(nla)) {
+			case NL80211_PMSR_TYPE_FTM:
+				__print_ftm_capability(nla);
+				break;
+			}
+		}
+	} else {
+		printf("\t\tPMSR type is missing\n");
+	}
+}
+
 void iw_hexdump(const char *prefix, const __u8 *buf, size_t size)
 {
 	size_t i;
-- 
2.37.3.998.g577e59143f-goog




[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux