| 1 | --- a/station.c |
| 2 | +++ b/station.c |
| 3 | @@ -29,13 +29,43 @@ enum plink_actions { |
| 4 | PLINK_ACTION_BLOCK, |
| 5 | }; |
| 6 | |
| 7 | +static void print_sta_bitrate(struct nlattr *nla, const char *name) |
| 8 | +{ |
| 9 | + struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1]; |
| 10 | + |
| 11 | + static struct nla_policy rate_policy[NL80211_RATE_INFO_MAX + 1] = { |
| 12 | + [NL80211_RATE_INFO_BITRATE] = { .type = NLA_U16 }, |
| 13 | + [NL80211_RATE_INFO_MCS] = { .type = NLA_U8 }, |
| 14 | + [NL80211_RATE_INFO_40_MHZ_WIDTH] = { .type = NLA_FLAG }, |
| 15 | + [NL80211_RATE_INFO_SHORT_GI] = { .type = NLA_FLAG }, |
| 16 | + }; |
| 17 | + |
| 18 | + if (!nla) |
| 19 | + return; |
| 20 | + |
| 21 | + if (nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, nla, rate_policy)) { |
| 22 | + fprintf(stderr, "failed to parse nested rate attributes!\n"); |
| 23 | + } else { |
| 24 | + printf("\n\t%s:\t", name); |
| 25 | + if (rinfo[NL80211_RATE_INFO_BITRATE]) { |
| 26 | + int rate = nla_get_u16(rinfo[NL80211_RATE_INFO_BITRATE]); |
| 27 | + printf("%d.%d MBit/s", rate / 10, rate % 10); |
| 28 | + } |
| 29 | + |
| 30 | + if (rinfo[NL80211_RATE_INFO_MCS]) |
| 31 | + printf(" MCS %d", nla_get_u8(rinfo[NL80211_RATE_INFO_MCS])); |
| 32 | + if (rinfo[NL80211_RATE_INFO_40_MHZ_WIDTH]) |
| 33 | + printf(" 40Mhz"); |
| 34 | + if (rinfo[NL80211_RATE_INFO_SHORT_GI]) |
| 35 | + printf(" short GI"); |
| 36 | + } |
| 37 | +} |
| 38 | |
| 39 | static int print_sta_handler(struct nl_msg *msg, void *arg) |
| 40 | { |
| 41 | struct nlattr *tb[NL80211_ATTR_MAX + 1]; |
| 42 | struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); |
| 43 | struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1]; |
| 44 | - struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1]; |
| 45 | char mac_addr[20], state_name[10], dev[20]; |
| 46 | struct nl80211_sta_flag_update *sta_flags; |
| 47 | static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = { |
| 48 | @@ -46,6 +76,7 @@ static int print_sta_handler(struct nl_m |
| 49 | [NL80211_STA_INFO_TX_PACKETS] = { .type = NLA_U32 }, |
| 50 | [NL80211_STA_INFO_SIGNAL] = { .type = NLA_U8 }, |
| 51 | [NL80211_STA_INFO_TX_BITRATE] = { .type = NLA_NESTED }, |
| 52 | + [NL80211_STA_INFO_RX_BITRATE] = { .type = NLA_NESTED }, |
| 53 | [NL80211_STA_INFO_LLID] = { .type = NLA_U16 }, |
| 54 | [NL80211_STA_INFO_PLID] = { .type = NLA_U16 }, |
| 55 | [NL80211_STA_INFO_PLINK_STATE] = { .type = NLA_U8 }, |
| 56 | @@ -55,13 +86,6 @@ static int print_sta_handler(struct nl_m |
| 57 | { .minlen = sizeof(struct nl80211_sta_flag_update) }, |
| 58 | }; |
| 59 | |
| 60 | - static struct nla_policy rate_policy[NL80211_RATE_INFO_MAX + 1] = { |
| 61 | - [NL80211_RATE_INFO_BITRATE] = { .type = NLA_U16 }, |
| 62 | - [NL80211_RATE_INFO_MCS] = { .type = NLA_U8 }, |
| 63 | - [NL80211_RATE_INFO_40_MHZ_WIDTH] = { .type = NLA_FLAG }, |
| 64 | - [NL80211_RATE_INFO_SHORT_GI] = { .type = NLA_FLAG }, |
| 65 | - }; |
| 66 | - |
| 67 | nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), |
| 68 | genlmsg_attrlen(gnlh, 0), NULL); |
| 69 | |
| 70 | @@ -114,25 +138,8 @@ static int print_sta_handler(struct nl_m |
| 71 | printf("\n\tsignal avg:\t%d dBm", |
| 72 | (int8_t)nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL_AVG])); |
| 73 | |
| 74 | - if (sinfo[NL80211_STA_INFO_TX_BITRATE]) { |
| 75 | - if (nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, |
| 76 | - sinfo[NL80211_STA_INFO_TX_BITRATE], rate_policy)) { |
| 77 | - fprintf(stderr, "failed to parse nested rate attributes!\n"); |
| 78 | - } else { |
| 79 | - printf("\n\ttx bitrate:\t"); |
| 80 | - if (rinfo[NL80211_RATE_INFO_BITRATE]) { |
| 81 | - int rate = nla_get_u16(rinfo[NL80211_RATE_INFO_BITRATE]); |
| 82 | - printf("%d.%d MBit/s", rate / 10, rate % 10); |
| 83 | - } |
| 84 | - |
| 85 | - if (rinfo[NL80211_RATE_INFO_MCS]) |
| 86 | - printf(" MCS %d", nla_get_u8(rinfo[NL80211_RATE_INFO_MCS])); |
| 87 | - if (rinfo[NL80211_RATE_INFO_40_MHZ_WIDTH]) |
| 88 | - printf(" 40Mhz"); |
| 89 | - if (rinfo[NL80211_RATE_INFO_SHORT_GI]) |
| 90 | - printf(" short GI"); |
| 91 | - } |
| 92 | - } |
| 93 | + print_sta_bitrate(sinfo[NL80211_STA_INFO_TX_BITRATE], "tx bitrate"); |
| 94 | + print_sta_bitrate(sinfo[NL80211_STA_INFO_RX_BITRATE], "rx bitrate"); |
| 95 | |
| 96 | if (sinfo[NL80211_STA_INFO_LLID]) |
| 97 | printf("\n\tmesh llid:\t%d", |
| 98 | |