X-Git-Url: http://git.archive.openwrt.org/?a=blobdiff_plain;f=iwinfo_nl80211.c;h=256249234386f6bdf1f51643c5f0a977214ddaa9;hb=9842d2507fa19cdf7d0bfd76df73609d14473b49;hp=66ace26101c8c6a969a7fb9f62f563abb01c92c8;hpb=fe7133f7e5a4faca63b6d939c6d55d09d8c240fb;p=project%2Fiwinfo.git diff --git a/iwinfo_nl80211.c b/iwinfo_nl80211.c index 66ace26..2562492 100644 --- a/iwinfo_nl80211.c +++ b/iwinfo_nl80211.c @@ -24,6 +24,7 @@ #include #include +#include #include "iwinfo_nl80211.h" #define min(x, y) ((x) < (y)) ? (x) : (y) @@ -125,6 +126,27 @@ static int nl80211_readint(const char *path) return rv; } +static int nl80211_readstr(const char *path, char *buffer, int length) +{ + int fd; + int rv = -1; + + if ((fd = open(path, O_RDONLY)) > -1) + { + if ((rv = read(fd, buffer, length - 1)) > 0) + { + if (buffer[rv - 1] == '\n') + rv--; + + buffer[rv] = 0; + } + + close(fd); + } + + return rv; +} + static int nl80211_msg_error(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg) @@ -210,45 +232,92 @@ static struct nl80211_msg_conveyor * nl80211_ctl(int cmd, int flags) return nl80211_new(nls->nlctrl, cmd, flags); } -static int nl80211_phy_idx_from_uci(const char *name) +static int nl80211_phy_idx_from_uci_path(struct uci_section *s) { - struct uci_section *s; const char *opt; char buf[128]; - glob_t gl; - FILE *f = NULL; int idx = -1; - int err; - - s = iwinfo_uci_get_radio(name, "mac80211"); - if (!s) - goto free; + glob_t gl; opt = uci_lookup_option_string(uci_ctx, s, "path"); if (!opt) - goto free; + return -1; - snprintf(buf, sizeof(buf), "/sys/devices/%s/ieee80211/*/index", opt); - err = glob(buf, 0, NULL, &gl); - if (err) - goto free; + snprintf(buf, sizeof(buf), "/sys/devices/%s/ieee80211/*/index", opt); /**/ + if (glob(buf, 0, NULL, &gl)) + return -1; - if (gl.gl_pathc) - f = fopen(gl.gl_pathv[0], "r"); + if (gl.gl_pathc > 0) + idx = nl80211_readint(gl.gl_pathv[0]); globfree(&gl); - if (!f) - goto free; + return idx; +} - err = fread(buf, 1, sizeof(buf) - 1, f); - fclose(f); +static int nl80211_phy_idx_from_uci_macaddr(struct uci_section *s) +{ + const char *opt; + char buf[128]; + int i, idx = -1; + glob_t gl; + + opt = uci_lookup_option_string(uci_ctx, s, "macaddr"); + if (!opt) + return -1; + + snprintf(buf, sizeof(buf), "/sys/class/ieee80211/*", opt); /**/ + if (glob(buf, 0, NULL, &gl)) + return -1; - if (err <= 0) + for (i = 0; i < gl.gl_pathc; i++) + { + snprintf(buf, sizeof(buf), "%s/macaddress", gl.gl_pathv[i]); + if (nl80211_readstr(buf, buf, sizeof(buf)) <= 0) + continue; + + if (fnmatch(opt, buf, FNM_CASEFOLD)) + continue; + + snprintf(buf, sizeof(buf), "%s/index", gl.gl_pathv[i]); + if ((idx = nl80211_readint(buf)) > -1) + break; + } + + globfree(&gl); + + return idx; +} + +static int nl80211_phy_idx_from_uci_phy(struct uci_section *s) +{ + const char *opt; + char buf[128]; + + opt = uci_lookup_option_string(uci_ctx, s, "phy"); + if (!opt) + return -1; + + snprintf(buf, sizeof(buf), "/sys/class/ieee80211/%s/index", opt); + return nl80211_readint(buf); +} + +static int nl80211_phy_idx_from_uci(const char *name) +{ + struct uci_section *s; + int idx = -1; + + s = iwinfo_uci_get_radio(name, "mac80211"); + if (!s) goto free; - buf[err] = 0; - idx = atoi(buf); + idx = nl80211_phy_idx_from_uci_path(s); + + if (idx < 0) + idx = nl80211_phy_idx_from_uci_macaddr(s); + + if (idx < 0) + idx = nl80211_phy_idx_from_uci_phy(s); free: iwinfo_uci_free(); @@ -2205,9 +2274,8 @@ static int nl80211_get_freqlist_cb(struct nl_msg *msg, void *arg) e->channel = nl80211_freq2channel(e->mhz); e->restricted = ( - freqs[NL80211_FREQUENCY_ATTR_PASSIVE_SCAN] || - freqs[NL80211_FREQUENCY_ATTR_NO_IBSS] || - freqs[NL80211_FREQUENCY_ATTR_RADAR] + freqs[NL80211_FREQUENCY_ATTR_NO_IR] && + !freqs[NL80211_FREQUENCY_ATTR_RADAR] ) ? 1 : 0; e++; @@ -2314,13 +2382,6 @@ static int nl80211_get_hwmodelist_cb(struct nl_msg *msg, void *arg) if (caps > 0) *modes |= IWINFO_80211_N; - if (bands[NL80211_BAND_ATTR_VHT_CAPA]) - vht_caps = nla_get_u32(bands[NL80211_BAND_ATTR_VHT_CAPA]); - - /* Treat any nonzero capability as 11ac */ - if (vht_caps > 0) - *modes |= IWINFO_80211_AC; - nla_for_each_nested(freq, bands[NL80211_BAND_ATTR_FREQS], freqs_remain) { @@ -2335,6 +2396,14 @@ static int nl80211_get_hwmodelist_cb(struct nl_msg *msg, void *arg) *modes |= IWINFO_80211_B; *modes |= IWINFO_80211_G; } + else if (bands[NL80211_BAND_ATTR_VHT_CAPA]) + { + vht_caps = nla_get_u32(bands[NL80211_BAND_ATTR_VHT_CAPA]); + + /* Treat any nonzero capability as 11ac */ + if (vht_caps > 0) + *modes |= IWINFO_80211_AC; + } else if (!(*modes & IWINFO_80211_AC)) { *modes |= IWINFO_80211_A; @@ -2377,15 +2446,15 @@ static int nl80211_get_ifcomb_cb(struct nl_msg *msg, void *arg) [NL80211_IFACE_COMB_LIMITS] = { .type = NLA_NESTED }, [NL80211_IFACE_COMB_MAXNUM] = { .type = NLA_U32 }, }; - struct nlattr *tb_comb[NUM_NL80211_IFACE_COMB]; + struct nlattr *tb_comb[NUM_NL80211_IFACE_COMB+1]; static struct nla_policy iface_limit_policy[NUM_NL80211_IFACE_LIMIT] = { [NL80211_IFACE_LIMIT_TYPES] = { .type = NLA_NESTED }, [NL80211_IFACE_LIMIT_MAX] = { .type = NLA_U32 }, }; - struct nlattr *tb_limit[NUM_NL80211_IFACE_LIMIT]; + struct nlattr *tb_limit[NUM_NL80211_IFACE_LIMIT+1]; struct nlattr *limit; - nla_parse_nested(tb_comb, NL80211_BAND_ATTR_MAX, comb, iface_combination_policy); + nla_parse_nested(tb_comb, NUM_NL80211_IFACE_COMB, comb, iface_combination_policy); if (!tb_comb[NL80211_IFACE_COMB_LIMITS]) continue; @@ -2506,6 +2575,17 @@ static int nl80211_get_frequency_offset(const char *ifname, int *buf) return 0; } +static int nl80211_lookup_phyname(const char *section, char *buf) +{ + int idx; + + if ((idx = nl80211_phy_idx_from_uci(section)) < 0) + return -1; + + sprintf(buf, "phy%d", idx); + return 0; +} + const struct iwinfo_ops nl80211_ops = { .name = "nl80211", .probe = nl80211_probe, @@ -2534,5 +2614,6 @@ const struct iwinfo_ops nl80211_ops = { .scanlist = nl80211_get_scanlist, .freqlist = nl80211_get_freqlist, .countrylist = nl80211_get_countrylist, + .lookup_phy = nl80211_lookup_phyname, .close = nl80211_close };