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

Reply via email to