developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 1 | From ad2f2f8a2c0b4d450a53c24d28769cd187071dee Mon Sep 17 00:00:00 2001 |
| 2 | From: Jaewan Kim <jaewan@google.com> |
| 3 | Date: Tue, 11 Oct 2022 14:34:05 +0900 |
| 4 | Subject: [PATCH 01/28] iw: info: print PMSR capabilities |
| 5 | |
| 6 | Print PMSR and FTM capabilities if any. |
| 7 | |
| 8 | Signed-off-by: Jaewan Kim <jaewan@google.com> |
| 9 | Link: https://lore.kernel.org/r/20221011053405.332375-1-jaewan@google.com |
| 10 | Signed-off-by: Johannes Berg <johannes.berg@intel.com> |
| 11 | --- |
| 12 | info.c | 121 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| 13 | 1 file changed, 121 insertions(+) |
| 14 | |
| 15 | diff --git a/info.c b/info.c |
| 16 | index 21ed07b..eb257f8 100644 |
| 17 | --- a/info.c |
| 18 | +++ b/info.c |
| 19 | @@ -169,6 +169,124 @@ static void ext_feat_print(enum nl80211_ext_feature_index idx) |
| 20 | } |
| 21 | } |
| 22 | |
| 23 | +static void __print_ftm_capability(struct nlattr *ftm_capa) |
| 24 | +{ |
| 25 | +#define PRINT_FTM_FLAG(T, NAME) \ |
| 26 | + do { \ |
| 27 | + if (T[NL80211_PMSR_FTM_CAPA_ATTR_##NAME]) \ |
| 28 | + printf("\t\t\t" #NAME "\n"); \ |
| 29 | + } while (0) |
| 30 | + |
| 31 | +#define PRINT_FTM_U8(T, NAME) \ |
| 32 | + do { \ |
| 33 | + if (T[NL80211_PMSR_FTM_CAPA_ATTR_##NAME]) \ |
| 34 | + printf("\t\t\t" #NAME ": %d\n", \ |
| 35 | + nla_get_u8(T[NL80211_PMSR_FTM_CAPA_ATTR_##NAME])); \ |
| 36 | + } while (0) |
| 37 | + |
| 38 | + struct nlattr *tb[NL80211_PMSR_FTM_CAPA_ATTR_MAX + 1]; |
| 39 | + int ret; |
| 40 | + |
| 41 | + printf("\t\tFTM (Fine time measurement or Flight time measurement)\n"); |
| 42 | + |
| 43 | + ret = nla_parse_nested(tb, NL80211_PMSR_FTM_CAPA_ATTR_MAX, ftm_capa, |
| 44 | + NULL); |
| 45 | + if (ret) |
| 46 | + return; |
| 47 | + |
| 48 | + if (tb[NL80211_PMSR_FTM_CAPA_ATTR_PREAMBLES]) { |
| 49 | +#define PRINT_PREAMBLE(P, V) \ |
| 50 | + do { \ |
| 51 | + if (P | NL80211_PREAMBLE_##V) \ |
| 52 | + printf(" " #V); \ |
| 53 | + } while (0) |
| 54 | + |
| 55 | + uint32_t preambles = |
| 56 | + nla_get_u32(tb[NL80211_PMSR_FTM_CAPA_ATTR_PREAMBLES]); |
| 57 | + printf("\t\t\tPreambles:"); |
| 58 | + |
| 59 | + PRINT_PREAMBLE(preambles, LEGACY); |
| 60 | + PRINT_PREAMBLE(preambles, HT); |
| 61 | + PRINT_PREAMBLE(preambles, VHT); |
| 62 | + PRINT_PREAMBLE(preambles, DMG); |
| 63 | + printf("\n"); |
| 64 | +#undef PRINT_PREAMBLE |
| 65 | + } |
| 66 | + if (tb[NL80211_PMSR_FTM_CAPA_ATTR_BANDWIDTHS]) { |
| 67 | +#define PRINT_BANDWIDTH(B, V) \ |
| 68 | + do { \ |
| 69 | + if (B | NL80211_CHAN_WIDTH_##V) \ |
| 70 | + printf(" " #V); \ |
| 71 | + } while (0) |
| 72 | + |
| 73 | + uint32_t bandwidth = |
| 74 | + nla_get_u32(tb[NL80211_PMSR_FTM_CAPA_ATTR_BANDWIDTHS]); |
| 75 | + printf("\t\t\tBandwidth:"); |
| 76 | + PRINT_BANDWIDTH(bandwidth, 20_NOHT); |
| 77 | + PRINT_BANDWIDTH(bandwidth, 20); |
| 78 | + PRINT_BANDWIDTH(bandwidth, 40); |
| 79 | + PRINT_BANDWIDTH(bandwidth, 80); |
| 80 | + PRINT_BANDWIDTH(bandwidth, 80P80); |
| 81 | + PRINT_BANDWIDTH(bandwidth, 160); |
| 82 | + PRINT_BANDWIDTH(bandwidth, 5); |
| 83 | + PRINT_BANDWIDTH(bandwidth, 10); |
| 84 | + PRINT_BANDWIDTH(bandwidth, 1); |
| 85 | + PRINT_BANDWIDTH(bandwidth, 2); |
| 86 | + PRINT_BANDWIDTH(bandwidth, 4); |
| 87 | + PRINT_BANDWIDTH(bandwidth, 8); |
| 88 | + PRINT_BANDWIDTH(bandwidth, 16); |
| 89 | + PRINT_BANDWIDTH(bandwidth, 320); |
| 90 | + printf("\n"); |
| 91 | +#undef PRINT_BANDWIDTH |
| 92 | + } |
| 93 | + PRINT_FTM_U8(tb, MAX_BURSTS_EXPONENT); |
| 94 | + PRINT_FTM_U8(tb, MAX_FTMS_PER_BURST); |
| 95 | + PRINT_FTM_FLAG(tb, ASAP); |
| 96 | + PRINT_FTM_FLAG(tb, NON_ASAP); |
| 97 | + PRINT_FTM_FLAG(tb, REQ_LCI); |
| 98 | + PRINT_FTM_FLAG(tb, REQ_CIVICLOC); |
| 99 | + PRINT_FTM_FLAG(tb, TRIGGER_BASED); |
| 100 | + PRINT_FTM_FLAG(tb, NON_TRIGGER_BASED); |
| 101 | + |
| 102 | +#undef PRINT_FTM_U8 |
| 103 | +#undef PRINT_FTM_FLAG |
| 104 | +} |
| 105 | + |
| 106 | +static void print_pmsr_capabilities(struct nlattr *pmsr_capa) |
| 107 | +{ |
| 108 | + struct nlattr *tb[NL80211_PMSR_ATTR_MAX + 1]; |
| 109 | + struct nlattr *nla; |
| 110 | + int size; |
| 111 | + int ret; |
| 112 | + |
| 113 | + printf("\tPeer measurement (PMSR)\n"); |
| 114 | + ret = nla_parse_nested(tb, NL80211_PMSR_ATTR_MAX, pmsr_capa, NULL); |
| 115 | + if (ret) { |
| 116 | + printf("\t\tMalformed PMSR\n"); |
| 117 | + return; |
| 118 | + } |
| 119 | + |
| 120 | + if (tb[NL80211_PMSR_ATTR_MAX_PEERS]) |
| 121 | + printf("\t\tMax peers: %d\n", |
| 122 | + nla_get_u32(tb[NL80211_PMSR_ATTR_MAX_PEERS])); |
| 123 | + if (tb[NL80211_PMSR_ATTR_REPORT_AP_TSF]) |
| 124 | + printf("\t\tREPORT_AP_TSF\n"); |
| 125 | + if (tb[NL80211_PMSR_ATTR_RANDOMIZE_MAC_ADDR]) |
| 126 | + printf("\t\tRANDOMIZE_MAC_ADDR\n"); |
| 127 | + |
| 128 | + if (tb[NL80211_PMSR_ATTR_TYPE_CAPA]) { |
| 129 | + nla_for_each_nested(nla, tb[NL80211_PMSR_ATTR_TYPE_CAPA], size) { |
| 130 | + switch (nla_type(nla)) { |
| 131 | + case NL80211_PMSR_TYPE_FTM: |
| 132 | + __print_ftm_capability(nla); |
| 133 | + break; |
| 134 | + } |
| 135 | + } |
| 136 | + } else { |
| 137 | + printf("\t\tPMSR type is missing\n"); |
| 138 | + } |
| 139 | +} |
| 140 | + |
| 141 | static int print_phy_handler(struct nl_msg *msg, void *arg) |
| 142 | { |
| 143 | struct nlattr *tb_msg[NL80211_ATTR_MAX + 1]; |
| 144 | @@ -741,6 +859,9 @@ broken_combination: |
| 145 | pat->max_pattern_len, pat->max_pkt_offset, rule->max_delay); |
| 146 | } |
| 147 | |
| 148 | + if (tb_msg[NL80211_ATTR_PEER_MEASUREMENTS]) |
| 149 | + print_pmsr_capabilities(tb_msg[NL80211_ATTR_PEER_MEASUREMENTS]); |
| 150 | + |
| 151 | if (tb_msg[NL80211_ATTR_MAX_AP_ASSOC_STA]) |
| 152 | printf("\tMaximum associated stations in AP mode: %u\n", |
| 153 | nla_get_u16(tb_msg[NL80211_ATTR_MAX_AP_ASSOC_STA])); |
| 154 | -- |
| 155 | 2.39.2 |
| 156 | |