]> git.ipfire.org Git - thirdparty/iw.git/commitdiff
iw: add scheduled scan plans configuration
authorAvraham Stern <avraham.stern@intel.com>
Sun, 8 Nov 2015 08:09:14 +0000 (10:09 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Thu, 14 Apr 2016 09:09:25 +0000 (11:09 +0200)
Scheduled scan now supports configuring multiple 'scan plans'.
Each scan plan specifies the interval between scans and the number
of iterations to scan. So add an option to configure scan plans
for scheduled scan
At least one scan plan must be configured. Note that all scan plans
but the last one must specify the scan interval and the number of
iterations. The last scan plan must specify only the interval and
will be run infinitely.
The option to set only an interval is kept for backwards
compatibility. However, the new scan plans option and the old interval
optoin are mutually exclusive.

Signed-off-by: Avraham Stern <avraham.stern@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
info.c
iw.h
scan.c

diff --git a/info.c b/info.c
index d724ca28e7a3bb580fd1b0acda68d9e244cb8acf..32de0af1bba18b932f34852fb8895bc4c15734f1 100644 (file)
--- a/info.c
+++ b/info.c
@@ -248,6 +248,15 @@ next:
        if (tb_msg[NL80211_ATTR_MAX_MATCH_SETS])
                printf("\tmax # match sets: %d\n",
                       nla_get_u8(tb_msg[NL80211_ATTR_MAX_MATCH_SETS]));
+       if (tb_msg[NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS])
+               printf("\tmax # scan plans: %d\n",
+                      nla_get_u32(tb_msg[NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS]));
+       if (tb_msg[NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL])
+               printf("\tmax scan plan interval: %d\n",
+                      nla_get_u32(tb_msg[NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL]));
+       if (tb_msg[NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS])
+               printf("\tmax scan plan iterations: %d\n",
+                      nla_get_u32(tb_msg[NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS]));
 
        if (tb_msg[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]) {
                unsigned int frag;
diff --git a/iw.h b/iw.h
index 3ab260637db8b5c0ddedf486e09360f5e9b87e2c..b58e8395bce60b809bf4524a17550e4e3cc21926 100644 (file)
--- a/iw.h
+++ b/iw.h
@@ -186,8 +186,9 @@ void iw_hexdump(const char *prefix, const __u8 *data, size_t len);
 
 int get_cf1(const struct chanmode *chanmode, unsigned long freq);
 
-#define SCHED_SCAN_OPTIONS "interval <in_msecs> [delay <in_secs>] " \
-       "[freqs <freq>+] [matches [ssid <ssid>]+]] [active [ssid <ssid>]+|passive] [randomise[=<addr>/<mask>]]"
+#define SCHED_SCAN_OPTIONS "[interval <in_msecs> | scan_plans [<interval_secs:iterations>*] <interval_secs>] " \
+       "[delay <in_secs>] [freqs <freq>+] [matches [ssid <ssid>]+]] [active [ssid <ssid>]+|passive] "  \
+       "[randomise[=<addr>/<mask>]]"
 int parse_sched_scan(struct nl_msg *msg, int *argc, char ***argv);
 
 DECLARE_SECTION(set);
diff --git a/scan.c b/scan.c
index bc1f936d9f0a6c5e48d03eb4e68b647a549cfc11..a942769dbc3e4f6a48d0e9e902298934a93332d8 100644 (file)
--- a/scan.c
+++ b/scan.c
@@ -101,19 +101,21 @@ static int parse_random_mac_addr(struct nl_msg *msg, char *arg)
 int parse_sched_scan(struct nl_msg *msg, int *argc, char ***argv)
 {
        struct nl_msg *matchset = NULL, *freqs = NULL, *ssids = NULL;
-       struct nlattr *match = NULL;
+       struct nl_msg *scan_plans = NULL;
+       struct nlattr *match = NULL, *plan = NULL;
        enum {
                ND_TOPLEVEL,
                ND_MATCH,
                ND_FREQS,
                ND_ACTIVE,
+               ND_PLANS,
        } parse_state = ND_TOPLEVEL;
        int c  = *argc;
        char *end, **v = *argv;
        int err = 0, i = 0;
-       unsigned int freq, interval = 0, delay = 0;
+       unsigned int freq, interval = 0, delay = 0, iterations = 0;
        bool have_matchset = false, have_freqs = false, have_ssids = false;
-       bool have_active = false, have_passive = false;
+       bool have_active = false, have_passive = false, have_plans = false;
        uint32_t flags = 0;
 
        matchset = nlmsg_alloc();
@@ -134,6 +136,12 @@ int parse_sched_scan(struct nl_msg *msg, int *argc, char ***argv)
                goto out;
        }
 
+       scan_plans = nlmsg_alloc();
+       if (!scan_plans) {
+               err = -ENOBUFS;
+               goto out;
+       }
+
        while (c) {
                switch (parse_state) {
                case ND_TOPLEVEL:
@@ -144,7 +152,7 @@ int parse_sched_scan(struct nl_msg *msg, int *argc, char ***argv)
                                        goto nla_put_failure;
                                }
 
-                               if (interval) {
+                               if (interval || have_plans) {
                                        err = -EINVAL;
                                        goto nla_put_failure;
                                }
@@ -156,6 +164,15 @@ int parse_sched_scan(struct nl_msg *msg, int *argc, char ***argv)
                                NLA_PUT_U32(msg,
                                            NL80211_ATTR_SCHED_SCAN_INTERVAL,
                                            interval);
+                       } else if (!strcmp(v[0], "scan_plans")) {
+                               parse_state = ND_PLANS;
+                               if (have_plans || interval) {
+                                       err = -EINVAL;
+                                       goto nla_put_failure;
+                               }
+
+                               have_plans = true;
+                               i = 0;
                        } else if (!strcmp(v[0], "delay")) {
                                c--; v++;
                                if (c == 0) {
@@ -309,6 +326,47 @@ int parse_sched_scan(struct nl_msg *msg, int *argc, char ***argv)
                                parse_state = ND_TOPLEVEL;
                        }
                        break;
+               case ND_PLANS:
+                       iterations = 0;
+                       interval = strtoul(v[0], &end, 10);
+                       if (*end) {
+                               char *iter;
+
+                               if (*end != ':') {
+                                       err = -EINVAL;
+                                       goto nla_put_failure;
+                               }
+
+                               iter = ++end;
+                               iterations = strtoul(iter, &end, 10);
+                               if (*end || !iterations) {
+                                       err = -EINVAL;
+                                       goto nla_put_failure;
+                               }
+                       }
+
+                       plan = nla_nest_start(scan_plans, i + 1);
+                       if (!plan) {
+                               err = -ENOBUFS;
+                               goto nla_put_failure;
+                       }
+
+                       NLA_PUT_U32(scan_plans,
+                                   NL80211_SCHED_SCAN_PLAN_INTERVAL,
+                                   interval);
+
+                       if (iterations)
+                               NLA_PUT_U32(scan_plans,
+                                           NL80211_SCHED_SCAN_PLAN_ITERATIONS,
+                                           iterations);
+                       else
+                               parse_state = ND_TOPLEVEL;
+
+                       nla_nest_end(scan_plans, plan);
+                       plan = NULL;
+                       i++;
+                       c--; v++;
+                       break;
                }
        }
 
@@ -320,6 +378,8 @@ int parse_sched_scan(struct nl_msg *msg, int *argc, char ***argv)
                nla_put_nested(msg, NL80211_ATTR_SCAN_FREQUENCIES, freqs);
        if (have_matchset)
                nla_put_nested(msg, NL80211_ATTR_SCHED_SCAN_MATCH, matchset);
+       if (have_plans)
+               nla_put_nested(msg, NL80211_ATTR_SCHED_SCAN_PLANS, scan_plans);
        if (flags)
                NLA_PUT_U32(msg, NL80211_ATTR_SCAN_FLAGS, flags);
 
@@ -328,6 +388,7 @@ nla_put_failure:
                nla_nest_end(msg, match);
        nlmsg_free(freqs);
        nlmsg_free(matchset);
+       nlmsg_free(scan_plans);
 
 out:
        *argc = c;