2022-09-23 02:21:43

by Jaewan Kim

[permalink] [raw]
Subject: [PATCH] iw: info: print PMSR capabilities

Print PMSR and FTM capabilities if any.

Signed-off-by: Jaewan Kim <[email protected]>
---
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


2022-10-05 09:50:39

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH] iw: info: print PMSR capabilities

On Fri, 2022-09-23 at 10:55 +0900, Jaewan Kim wrote:
>
> +#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])); \

This doesn't compile, and there are also a few compiler warnings.

That's all easy to fix, but it does make me wonder if you tested this at
all, or accidentally sent out an unfixed version from before testing, or
so?

johannes

2022-10-05 09:51:57

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH] iw: info: print PMSR capabilities

On Fri, 2022-09-23 at 10:55 +0900, Jaewan Kim wrote:
>
> +++ 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);

Also, FWIW, it would probably make sense to make this static and put it
into info.c at least while it's not used elsewhere?

johannes