diff --git a/package/iwinfo/Makefile b/package/iwinfo/Makefile index 5fd04d3d15..aa85298c2c 100644 --- a/package/iwinfo/Makefile +++ b/package/iwinfo/Makefile @@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=libiwinfo -PKG_RELEASE:=33 +PKG_RELEASE:=34 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) PKG_CONFIG_DEPENDS := \ diff --git a/package/iwinfo/src/iwinfo_nl80211.c b/package/iwinfo/src/iwinfo_nl80211.c index 4205336f6a..7595ea838c 100644 --- a/package/iwinfo/src/iwinfo_nl80211.c +++ b/package/iwinfo/src/iwinfo_nl80211.c @@ -351,6 +351,17 @@ static int nl80211_freq2channel(int freq) return (freq / 5) - 1000; } +static int nl80211_channel2freq(int channel) +{ + if (channel == 14) + return 2484; + + if (channel < 14) + return (channel * 5) + 2407; + + return (1000 + channel) * 5; +} + static char * nl80211_getval(const char *ifname, const char *buf, const char *key) { int i, len; @@ -751,32 +762,68 @@ int nl80211_get_bssid(const char *ifname, char *buf) return -1; } + +static int nl80211_get_channel_cb(struct nl_msg *msg, void *arg) +{ + int *channel = arg; + struct nlattr **attr = nl80211_parse(msg); + struct nlattr *binfo[NL80211_BSS_MAX + 1]; + + static struct nla_policy bss_policy[NL80211_BSS_MAX + 1] = { + [NL80211_BSS_FREQUENCY] = { .type = NLA_U32 }, + }; + + if (attr[NL80211_ATTR_BSS] && + !nla_parse_nested(binfo, NL80211_BSS_MAX, + attr[NL80211_ATTR_BSS], bss_policy)) + { + if (binfo[NL80211_BSS_FREQUENCY]) + *channel = + nl80211_freq2channel(nla_get_u32(binfo[NL80211_BSS_FREQUENCY])); + } + + return NL_SKIP; +} + int nl80211_get_channel(const char *ifname, int *buf) { - char *first; + char *res; + struct nl80211_msg_conveyor *req; - if (!wext_get_channel(ifname, buf)) - return 0; + *buf = 0; - else if ((first = nl80211_phy2ifname(nl80211_ifname2phy(ifname))) != NULL) - return wext_get_channel(first, buf); + if ((res = nl80211_hostapd_info(ifname)) && + (res = nl80211_getval(NULL, res, "channel"))) + { + *buf = atoi(res); + } + else + { + res = nl80211_phy2ifname(ifname); + req = nl80211_msg(res ? res : ifname, NL80211_CMD_GET_SCAN, NLM_F_DUMP); - return -1; + if (req) + { + nl80211_send(req, nl80211_get_channel_cb, buf); + nl80211_free(req); + } + } + + return (*buf == 0) ? -1 : 0; } int nl80211_get_frequency(const char *ifname, int *buf) { - char *first; - - if (!wext_get_frequency(ifname, buf)) + if (!nl80211_get_channel(ifname, buf)) + { + *buf = nl80211_channel2freq(*buf); return 0; - - else if ((first = nl80211_phy2ifname(nl80211_ifname2phy(ifname))) != NULL) - return wext_get_frequency(first, buf); + } return -1; } + int nl80211_get_txpower(const char *ifname, int *buf) { return wext_get_txpower(ifname, buf);