]> git.ipfire.org Git - thirdparty/iw.git/blobdiff - wowlan.c
iw: add missing station statistics
[thirdparty/iw.git] / wowlan.c
index fb7d956aa4b69c2fe024f20caee9b9694e66c471..e0cf316b165e5f89f69be44eaa6aed82fe4dcbb2 100644 (file)
--- a/wowlan.c
+++ b/wowlan.c
@@ -1,4 +1,3 @@
-#include <net/if.h>
 #include <errno.h>
 #include <string.h>
 #include <stdio.h>
@@ -160,8 +159,12 @@ static int wowlan_parse_tcp_file(struct nl_msg *msg, const char *fn)
                        tok->offset = atoi(offs);
                        memcpy(tok->token_stream, stream, stream_len);
 
-                       NLA_PUT(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN,
-                               sizeof(*tok) + stream_len, tok);
+                       if (nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN,
+                               sizeof(*tok) + stream_len, tok) < 0) {
+                               free(stream);
+                               free(tok);
+                               goto nla_put_failure;
+                       }
                        free(stream);
                        free(tok);
                } else {
@@ -177,168 +180,28 @@ static int wowlan_parse_tcp_file(struct nl_msg *msg, const char *fn)
        err = -ENOBUFS;
  close:
        fclose(f);
-       nla_nest_end(msg, tcp);
+       if (tcp)
+               nla_nest_end(msg, tcp);
        return err;
 }
 
 static int wowlan_parse_net_detect(struct nl_msg *msg, int *argc, char ***argv)
 {
-       struct nl_msg *matchset = NULL, *freqs = NULL;
-       struct nlattr *nd, *match = NULL;
-       enum {
-               ND_TOPLEVEL,
-               ND_MATCH,
-               ND_FREQS,
-       } parse_state = ND_TOPLEVEL;
-       int c  = *argc;
-       char *end, **v = *argv;
-       int err = 0, i = 0;
-       unsigned int freq, interval = 0;
-       bool have_matchset = false, have_freqs = false;
+       struct nlattr *nd;
+       int err = 0;
 
        nd = nla_nest_start(msg, NL80211_WOWLAN_TRIG_NET_DETECT);
-       if (!nd) {
-               err = -ENOBUFS;
-               goto out;
-       }
-
-       matchset = nlmsg_alloc();
-       if (!matchset) {
-               err = -ENOBUFS;
-               goto out;
-       }
-
-       freqs = nlmsg_alloc();
-       if (!freqs) {
-               err = -ENOBUFS;
-               goto out;
-       }
-
-       while (c) {
-               switch (parse_state) {
-               case ND_TOPLEVEL:
-                       if (!strcmp(v[0], "interval")) {
-                               c--; v++;
-                               if (c == 0) {
-                                       err = -EINVAL;
-                                       goto nla_put_failure;
-                               }
-
-                               if (interval) {
-                                       err = -EINVAL;
-                                       goto nla_put_failure;
-                               }
-                               interval = strtoul(v[0], &end, 10);
-                               if (*end || !interval) {
-                                       err = -EINVAL;
-                                       goto nla_put_failure;
-                               }
-                               NLA_PUT_U32(msg,
-                                           NL80211_ATTR_SCHED_SCAN_INTERVAL,
-                                           interval);
-                       } else if (!strcmp(v[0], "matches")) {
-                               parse_state = ND_MATCH;
-                               if (have_matchset) {
-                                       err = -EINVAL;
-                                       goto nla_put_failure;
-                               }
-
-                               i = 0;
-                       } else if (!strcmp(v[0], "freqs")) {
-                               parse_state = ND_FREQS;
-                               if (have_freqs) {
-                                       err = -EINVAL;
-                                       goto nla_put_failure;
-                               }
-
-                               have_freqs = true;
-                               i = 0;
-                       } else {
-                               /* this element is not for us, so
-                                * return to continue parsing.
-                                */
-                               goto nla_put_failure;
-                       }
-                       c--; v++;
-
-                       break;
-               case ND_MATCH:
-                       if (!strcmp(v[0], "ssid")) {
-                               c--; v++;
-                               if (c == 0) {
-                                       err = -EINVAL;
-                                       goto nla_put_failure;
-                               }
-
-                               /* TODO: for now we can only have an
-                                * SSID in the match, so we can start
-                                * the match nest here.
-                                */
-                               match = nla_nest_start(matchset, i);
-                               if (!match) {
-                                       err = -ENOBUFS;
-                                       goto nla_put_failure;
-                               }
-
-                               NLA_PUT(matchset,
-                                       NL80211_SCHED_SCAN_MATCH_ATTR_SSID,
-                                       strlen(v[0]), v[0]);
-                               nla_nest_end(matchset, match);
-                               match = NULL;
-
-                               have_matchset = true;
-                               i++;
-                               c--; v++;
-                       } else {
-                               /* other element that cannot be part
-                                * of a match indicates the end of the
-                                * match. */
-                               /* need at least one match in the matchset */
-                               if (i == 0) {
-                                       err = -EINVAL;
-                                       goto nla_put_failure;
-                               }
-
-                               parse_state = ND_TOPLEVEL;
-                       }
-
-                       break;
-               case ND_FREQS:
-                       freq = strtoul(v[0], &end, 10);
-                       if (*end) {
-                               if (i == 0) {
-                                       err = -EINVAL;
-                                       goto nla_put_failure;
-                               }
-
-                               parse_state = ND_TOPLEVEL;
-                       } else {
-                               NLA_PUT_U32(freqs, i, freq);
-                               i++;
-                               c--; v++;
-                       }
-                       break;
-               }
-       }
+       if (!nd)
+               return -ENOBUFS;
 
-       if (have_freqs)
-               nla_put_nested(msg, NL80211_ATTR_SCAN_FREQUENCIES, freqs);
-       if (have_matchset)
-               nla_put_nested(msg, NL80211_ATTR_SCHED_SCAN_MATCH, matchset);
+       err = parse_sched_scan(msg, argc, argv);
 
-nla_put_failure:
-       if (match)
-               nla_nest_end(msg, match);
-       nlmsg_free(freqs);
-       nlmsg_free(matchset);
        nla_nest_end(msg, nd);
-out:
-       *argc = c;
-       *argv = v;
+
        return err;
 }
 
-static int handle_wowlan_enable(struct nl80211_state *state, struct nl_cb *cb,
+static int handle_wowlan_enable(struct nl80211_state *state,
                                struct nl_msg *msg, int argc, char **argv,
                                enum id_input id)
 {
@@ -454,7 +317,7 @@ static int handle_wowlan_enable(struct nl80211_state *state, struct nl_cb *cb,
        return err;
 }
 COMMAND(wowlan, enable, "[any] [disconnect] [magic-packet] [gtk-rekey-failure] [eap-identity-request]"
-       " [4way-handshake] [rfkill-release] [net-detect interval <in_msecs> [freqs <freq>+] [matches [ssid <ssid>]+]]"
+       " [4way-handshake] [rfkill-release] [net-detect " SCHED_SCAN_OPTIONS "]"
        " [tcp <config-file>] [patterns [offset1+]<pattern1> ...]",
        NL80211_CMD_SET_WOWLAN, 0, CIB_PHY, handle_wowlan_enable,
        "Enable WoWLAN with the given triggers.\n"
@@ -472,10 +335,10 @@ COMMAND(wowlan, enable, "[any] [disconnect] [magic-packet] [gtk-rekey-failure] [
        "  [data.seq=len,offset[,start]]\n"
        "  [data.tok=len,offset,<token stream>]\n\n"
        "Net-detect configuration example:\n"
-       " iw phy0 wowlan enable net-detect interval 5000 freqs 2412 2422 matches ssid foo ssid bar");
+       " iw phy0 wowlan enable net-detect interval 5000 delay 30 freqs 2412 2422 matches ssid foo ssid bar");
 
 
-static int handle_wowlan_disable(struct nl80211_state *state, struct nl_cb *cb,
+static int handle_wowlan_disable(struct nl80211_state *state,
                                 struct nl_msg *msg, int argc, char **argv,
                                 enum id_input id)
 {
@@ -534,9 +397,13 @@ static int print_wowlan_handler(struct nl_msg *msg, void *arg)
                          nla_len(trig[NL80211_WOWLAN_TRIG_NET_DETECT]), NULL);
 
                if (nd[NL80211_ATTR_SCHED_SCAN_INTERVAL])
-                       printf("\tscan interval: %d msecs\n",
+                       printf("\tscan interval: %u msecs\n",
                               nla_get_u32(nd[NL80211_ATTR_SCHED_SCAN_INTERVAL]));
 
+               if (nd[NL80211_ATTR_SCHED_SCAN_DELAY])
+                       printf("\tinitial scan delay: %u secs\n",
+                              nla_get_u32(nd[NL80211_ATTR_SCHED_SCAN_DELAY]));
+
                if (nd[NL80211_ATTR_SCHED_SCAN_MATCH]) {
                        printf("\tmatches:\n");
                        nla_for_each_nested(match,
@@ -607,12 +474,11 @@ static int print_wowlan_handler(struct nl_msg *msg, void *arg)
        return NL_SKIP;
 }
 
-static int handle_wowlan_show(struct nl80211_state *state, struct nl_cb *cb,
+static int handle_wowlan_show(struct nl80211_state *state,
                              struct nl_msg *msg, int argc, char **argv,
                              enum id_input id)
 {
-       nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM,
-                 print_wowlan_handler, NULL);
+       register_handler(print_wowlan_handler, NULL);
 
        return 0;
 }