From: Daniel Danzberger Date: Thu, 19 Dec 2019 14:41:24 +0000 (+0100) Subject: nl80211: add htmode to iwinfo_ops X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=bf2c1069a7f1;p=oweals%2Fiwinfo.git nl80211: add htmode to iwinfo_ops This callback shows the currently active HTMODE of the device. Signed-off-by: Daniel Danzberger --- diff --git a/include/iwinfo.h b/include/iwinfo.h index d035c9c..5e64294 100644 --- a/include/iwinfo.h +++ b/include/iwinfo.h @@ -88,8 +88,9 @@ enum iwinfo_htmode { IWINFO_HTMODE_VHT80 = (1 << 4), IWINFO_HTMODE_VHT80_80 = (1 << 5), IWINFO_HTMODE_VHT160 = (1 << 6), + IWINFO_HTMODE_NOHT = (1 << 7), - IWINFO_HTMODE_COUNT = 7 + IWINFO_HTMODE_COUNT = 8 }; extern const char *IWINFO_HTMODE_NAMES[IWINFO_HTMODE_COUNT]; @@ -231,6 +232,7 @@ struct iwinfo_ops { int (*mbssid_support)(const char *, int *); int (*hwmodelist)(const char *, int *); int (*htmodelist)(const char *, int *); + int (*htmode)(const char *, int *); int (*ssid)(const char *, char *); int (*bssid)(const char *, char *); int (*country)(const char *, char *); diff --git a/iwinfo_nl80211.c b/iwinfo_nl80211.c index 5990c78..2b2a043 100644 --- a/iwinfo_nl80211.c +++ b/iwinfo_nl80211.c @@ -2958,6 +2958,75 @@ out: return -1; } +struct chan_info { + int width; + int mode; +}; + +static int nl80211_get_htmode_cb(struct nl_msg *msg, void *arg) +{ + struct nlattr **tb = nl80211_parse(msg); + struct nlattr *cur; + struct chan_info *chn = arg; + + if ((cur = tb[NL80211_ATTR_CHANNEL_WIDTH])) + chn->width = nla_get_u32(cur); + + if ((cur = tb[NL80211_ATTR_BSS_HT_OPMODE])) + chn->mode = nla_get_u32(cur); + + return NL_SKIP; +} + +static int nl80211_get_htmode(const char *ifname, int *buf) +{ + struct chan_info chn = { .width = 0, .mode = 0 }; + char *res; + int err; + + res = nl80211_phy2ifname(ifname); + *buf = 0; + + err = nl80211_request(res ? res : ifname, + NL80211_CMD_GET_INTERFACE, 0, + nl80211_get_htmode_cb, &chn); + if (err) + return -1; + + switch (chn.width) { + case NL80211_CHAN_WIDTH_20: + if (chn.mode == -1) + *buf = IWINFO_HTMODE_VHT20; + else + *buf = IWINFO_HTMODE_HT20; + break; + case NL80211_CHAN_WIDTH_40: + if (chn.mode == -1) + *buf = IWINFO_HTMODE_VHT40; + else + *buf = IWINFO_HTMODE_HT40; + break; + case NL80211_CHAN_WIDTH_80: + *buf = IWINFO_HTMODE_VHT80; + break; + case NL80211_CHAN_WIDTH_80P80: + *buf = IWINFO_HTMODE_VHT80_80; + break; + case NL80211_CHAN_WIDTH_160: + *buf = IWINFO_HTMODE_VHT160; + break; + case NL80211_CHAN_WIDTH_5: + case NL80211_CHAN_WIDTH_10: + case NL80211_CHAN_WIDTH_20_NOHT: + *buf = IWINFO_HTMODE_NOHT; + break; + default: + return -1; + } + + return 0; +} + static int nl80211_get_htmodelist(const char *ifname, int *buf) { struct nl80211_modes m = { 0 }; @@ -3147,6 +3216,7 @@ const struct iwinfo_ops nl80211_ops = { .mbssid_support = nl80211_get_mbssid_support, .hwmodelist = nl80211_get_hwmodelist, .htmodelist = nl80211_get_htmodelist, + .htmode = nl80211_get_htmode, .mode = nl80211_get_mode, .ssid = nl80211_get_ssid, .bssid = nl80211_get_bssid,