Message ID | 20191127172952.2143-3-daniel@dd-wrt.com |
---|---|
State | Superseded |
Headers | show |
Series | iwinfo/rpcd: add current hw and ht mode to info call | expand |
On 11/27/19 6:29 PM, Daniel Danzberger wrote: > This callback shows the currently active HTMODE of the device. > > Signed-off-by: Daniel Danzberger <daniel@dd-wrt.com> > --- > include/iwinfo.h | 4 ++- > iwinfo_nl80211.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 73 insertions(+), 1 deletion(-) > > 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 4b6ef91..36f1da2 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_NOHT: > + *buf = IWINFO_HTMODE_NOHT; > + break; > + 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: Should this also return IWINFO_HTMODE_NOHT ? > + default: > + break; Why not return an error if nothing matches? > + } > + > + 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, >
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 4b6ef91..36f1da2 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_NOHT: + *buf = IWINFO_HTMODE_NOHT; + break; + 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: + default: + break; + } + + 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,
This callback shows the currently active HTMODE of the device. Signed-off-by: Daniel Danzberger <daniel@dd-wrt.com> --- include/iwinfo.h | 4 ++- iwinfo_nl80211.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 1 deletion(-)