[OpenWrt-Devel] [PATCH] Allow scan of single channel
Dmitry Ivanov
dmitrijs.ivanovs at ubnt.com
Thu Dec 17 05:47:29 EST 2015
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 <dima at ubnt.com>
---
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
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel
More information about the openwrt-devel
mailing list