Sometimes it is enough to scan single channel only. This is much faster than scanning all of them and ingnoring unnecessary data.
Signed-off-by: Dmitry Ivanov <[email protected]> --- include/iwinfo.h | 1 + iwinfo_cli.c | 65 ++++++++++++++++++++++++++++++++++++++++---------------- iwinfo_nl80211.c | 33 +++++++++++++++++++++------- 3 files changed, 73 insertions(+), 26 deletions(-) diff --git a/include/iwinfo.h b/include/iwinfo.h index f8cec73..e5ea48e 100644 --- a/include/iwinfo.h +++ b/include/iwinfo.h @@ -202,6 +202,7 @@ struct iwinfo_ops { int (*assoclist)(const char *, char *, int *); int (*txpwrlist)(const char *, char *, int *); int (*scanlist)(const char *, char *, int *); + int (*scanlist2)(const char *, char *, int *, unsigned int); int (*freqlist)(const char *, char *, int *); int (*countrylist)(const char *, char *, int *); int (*lookup_phy)(const char *, char *); diff --git a/iwinfo_cli.c b/iwinfo_cli.c index 7cb90c2..b0cc76d 100644 --- a/iwinfo_cli.c +++ b/iwinfo_cli.c @@ -562,18 +562,32 @@ static void print_info(const struct iwinfo_ops *iw, const char *ifname) } -static void print_scanlist(const struct iwinfo_ops *iw, const char *ifname) +static void print_scanlist(const struct iwinfo_ops *iw, const char *ifname, unsigned int freq) { int i, x, len; char buf[IWINFO_BUFSIZE]; struct iwinfo_scanlist_entry *e; - if (iw->scanlist(ifname, buf, &len)) + if (freq) + { + if (!iw->scanlist2) + { + printf("Scanning of specific frequency not implemented\n\n"); + return; + } + if (iw->scanlist2(ifname, buf, &len, freq)) + { + printf("Scanning of specific frequency not possible\n\n"); + return; + } + } + else if (iw->scanlist(ifname, buf, &len)) { printf("Scanning not possible\n\n"); return; } - else if (len <= 0) + + if (len <= 0) { printf("No scan results\n\n"); return; @@ -794,6 +808,7 @@ int main(int argc, char **argv) "Usage:\n" " iwinfo <device> info\n" " iwinfo <device> scan\n" + " iwinfo <device> scan <freq>\n" " iwinfo <device> txpowerlist\n" " iwinfo <device> freqlist\n" " iwinfo <device> assoclist\n" @@ -831,25 +846,37 @@ int main(int argc, char **argv) if (argc > 3) { - iw = iwinfo_backend_by_name(argv[1]); - - if (!iw) - { - fprintf(stderr, "No such wireless backend: %s\n", argv[1]); - rv = 1; - } - else + switch (argv[2][0]) { - switch (argv[2][0]) + case 'p': + iw = iwinfo_backend_by_name(argv[1]); + + if (!iw) { - case 'p': - lookup_phy(iw, argv[3]); - break; + fprintf(stderr, "No such wireless backend: %s\n", argv[1]); + rv = 1; + goto finish; + } + + lookup_phy(iw, argv[3]); + break; + + case 's': + iw = iwinfo_backend(argv[1]); - default: - fprintf(stderr, "Unknown command: %s\n", argv[2]); + if (!iw) + { + fprintf(stderr, "No such wireless device: %s\n", argv[1]); rv = 1; + goto finish; } + + print_scanlist(iw, argv[1], atoi(argv[3])); + break; + + default: + fprintf(stderr, "Unknown command: %s\n", argv[2]); + rv = 1; } } else @@ -872,7 +899,7 @@ int main(int argc, char **argv) break; case 's': - print_scanlist(iw, argv[1]); + print_scanlist(iw, argv[1], 0); break; case 't': @@ -903,6 +930,8 @@ int main(int argc, char **argv) } } +finish: + iwinfo_finish(); return rv; diff --git a/iwinfo_nl80211.c b/iwinfo_nl80211.c index a65ed1e..de4cdd1 100644 --- a/iwinfo_nl80211.c +++ b/iwinfo_nl80211.c @@ -2083,7 +2083,7 @@ static int nl80211_get_scanlist_cb(struct nl_msg *msg, void *arg) return NL_SKIP; } -static int nl80211_get_scanlist_nl(const char *ifname, char *buf, int *len) +static int nl80211_get_scanlist_nl(const char *ifname, char *buf, int *len, unsigned int freq) { struct nl80211_msg_conveyor *req; struct nl80211_scanlist sl = { .e = (struct iwinfo_scanlist_entry *)buf }; @@ -2091,6 +2091,17 @@ static int nl80211_get_scanlist_nl(const char *ifname, char *buf, int *len) req = nl80211_msg(ifname, NL80211_CMD_TRIGGER_SCAN, 0); if (req) { + if (freq) + { + struct nlattr *freqs; + freqs = nla_nest_start(req->msg, NL80211_ATTR_SCAN_FREQUENCIES); + if (!freqs) + return -1; + if (nla_put_u32(req->msg, 1, freq)) + return -1; + nla_nest_end(req->msg, freqs); + } + nl80211_send(req, NULL, NULL); nl80211_free(req); } @@ -2298,7 +2309,7 @@ static int nl80211_get_scanlist_wpactl(const char *ifname, char *buf, int *len) return (count >= 0) ? 0 : -1; } -static int nl80211_get_scanlist(const char *ifname, char *buf, int *len) +static int nl80211_get_scanlist2(const char *ifname, char *buf, int *len, unsigned int freq) { char *res; int rv, mode; @@ -2311,13 +2322,13 @@ static int nl80211_get_scanlist(const char *ifname, char *buf, int *len) /* Reuse existing interface */ if ((res = nl80211_phy2ifname(ifname)) != NULL) { - return nl80211_get_scanlist(res, buf, len); + return nl80211_get_scanlist2(res, buf, len, freq); } /* Need to spawn a temporary iface for scanning */ else if ((res = nl80211_ifadd(ifname)) != NULL) { - rv = nl80211_get_scanlist(res, buf, len); + rv = nl80211_get_scanlist2(res, buf, len, freq); nl80211_ifdel(res); return rv; } @@ -2337,7 +2348,7 @@ static int nl80211_get_scanlist(const char *ifname, char *buf, int *len) mode == IWINFO_OPMODE_MONITOR) && iwinfo_ifup(ifname)) { - return nl80211_get_scanlist_nl(ifname, buf, len); + return nl80211_get_scanlist_nl(ifname, buf, len, freq); } /* AP scan */ @@ -2349,7 +2360,7 @@ static int nl80211_get_scanlist(const char *ifname, char *buf, int *len) if (!iwinfo_ifup(ifname)) return -1; - rv = nl80211_get_scanlist_nl(ifname, buf, len); + rv = nl80211_get_scanlist_nl(ifname, buf, len, freq); iwinfo_ifdown(ifname); return rv; } @@ -2366,7 +2377,7 @@ static int nl80211_get_scanlist(const char *ifname, char *buf, int *len) * additional interface and there's no need to tear down the ap */ if (iwinfo_ifup(res)) { - rv = nl80211_get_scanlist_nl(res, buf, len); + rv = nl80211_get_scanlist_nl(res, buf, len, freq); iwinfo_ifdown(res); } @@ -2374,7 +2385,7 @@ static int nl80211_get_scanlist(const char *ifname, char *buf, int *len) * during scan */ else if (iwinfo_ifdown(ifname) && iwinfo_ifup(res)) { - rv = nl80211_get_scanlist_nl(res, buf, len); + rv = nl80211_get_scanlist_nl(res, buf, len, freq); iwinfo_ifdown(res); iwinfo_ifup(ifname); nl80211_hostapd_hup(ifname); @@ -2388,6 +2399,11 @@ static int nl80211_get_scanlist(const char *ifname, char *buf, int *len) return -1; } +static int nl80211_get_scanlist(const char *ifname, char *buf, int *len) +{ + return nl80211_get_scanlist2(ifname, buf, len, 0); +} + static int nl80211_get_freqlist_cb(struct nl_msg *msg, void *arg) { int bands_remain, freqs_remain; @@ -2814,6 +2830,7 @@ const struct iwinfo_ops nl80211_ops = { .assoclist = nl80211_get_assoclist, .txpwrlist = nl80211_get_txpwrlist, .scanlist = nl80211_get_scanlist, + .scanlist2 = nl80211_get_scanlist2, .freqlist = nl80211_get_freqlist, .countrylist = nl80211_get_countrylist, .lookup_phy = nl80211_lookup_phyname, -- 2.1.4 _______________________________________________ openwrt-devel mailing list [email protected] https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel
