Search Linux Wireless

[PATCH] iw: add packet offset information for wowlan pattern

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Amitkumar Karwar <akarwar@xxxxxxxxxxx>

Now user can provide packet offset along with the pattern in
"iw wowlan" command. Default offset will be 0 when it is not
provided.

A trailing ':' should be used for single byte pattern to
distinguish it from an offset.
Ex. "iw phy phy# wowlan patterns 18 43:" means wakeup on
offset 18 pattern 0x43.

Signed-off-by: Amitkumar Karwar <akarwar@xxxxxxxxxxx>
Signed-off-by: Bing Zhao <bzhao@xxxxxxxxxxx>
---
 util.c   |  2 ++
 wowlan.c | 30 +++++++++++++++++++++++-------
 2 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/util.c b/util.c
index c272c1d..6ef86cd 100644
--- a/util.c
+++ b/util.c
@@ -75,6 +75,8 @@ int parse_hex_mask(char *hexmask, unsigned char **result, size_t *result_len,
 		if (cp) {
 			*cp = 0;
 			cp++;
+		} else if (!strlen(hexmask)) {
+			break;
 		}
 
 		if (result_mask && (strcmp(hexmask, "-") == 0 ||
diff --git a/wowlan.c b/wowlan.c
index 6d324ef..a314c7d 100644
--- a/wowlan.c
+++ b/wowlan.c
@@ -26,7 +26,8 @@ static int handle_wowlan_enable(struct nl80211_state *state, struct nl_cb *cb,
 	int err = -ENOBUFS;
 	unsigned char *pat, *mask;
 	size_t patlen;
-	int patnum = 0;
+	int patnum = 0, pkt_offset;
+	char *eptr;
 
 	wowlan = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS);
 	if (!wowlan)
@@ -62,7 +63,16 @@ static int handle_wowlan_enable(struct nl80211_state *state, struct nl_cb *cb,
 			}
 			break;
 		case PS_PAT:
-			if (parse_hex_mask(argv[0], &pat, &patlen, &mask)) {
+			pkt_offset = strtoul(argv[0], &eptr, 10);
+			if (eptr != argv[0] + strlen(argv[0])) {
+				/* packet offset is not provided, set default value to 0 */
+				pkt_offset = 0;
+			} else {
+				argv++;
+				argc--;
+			}
+
+			if (!argc || parse_hex_mask(argv[0], &pat, &patlen, &mask)) {
 				err = 1;
 				goto nla_put_failure;
 			}
@@ -71,6 +81,7 @@ static int handle_wowlan_enable(struct nl80211_state *state, struct nl_cb *cb,
 				DIV_ROUND_UP(patlen, 8), mask);
 			NLA_PUT(patterns, NL80211_WOWLAN_PKTPAT_PATTERN,
 				patlen, pat);
+			NLA_PUT_U32(patterns, NL80211_WOWLAN_PKTPAT_OFFSET, pkt_offset);
 			nla_nest_end(patterns, pattern);
 			free(mask);
 			free(pat);
@@ -91,12 +102,14 @@ 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] [patterns <pattern>*]",
+	" [4way-handshake] [rfkill-release] [patterns [offset1] <pattern1> ...]",
 	NL80211_CMD_SET_WOWLAN, 0, CIB_PHY, handle_wowlan_enable,
 	"Enable WoWLAN with the given triggers.\n"
 	"Each pattern is given as a bytestring with '-' in places where any byte\n"
 	"may be present, e.g. 00:11:22:-:44 will match 00:11:22:33:44 and\n"
-	"00:11:22:33:ff:44 etc.");
+	"00:11:22:33:ff:44 etc.\n"
+	"Use ':' for single byte pattern as well, e.g. 18 43: will match '43' "
+	"after 18 bytes of offset in Rx packet.");
 
 
 static int handle_wowlan_disable(struct nl80211_state *state, struct nl_cb *cb,
@@ -152,23 +165,26 @@ static int print_wowlan_handler(struct nl_msg *msg, void *arg)
 				    trig[NL80211_WOWLAN_TRIG_PKT_PATTERN],
 				    rem_pattern) {
 			struct nlattr *patattr[NUM_NL80211_WOWLAN_PKTPAT];
-			int i, patlen, masklen;
+			int i, patlen, masklen, pkt_offset;
 			uint8_t *mask, *pat;
 			nla_parse(patattr, MAX_NL80211_WOWLAN_PKTPAT,
 				  nla_data(pattern), nla_len(pattern),
 				  NULL);
 			if (!patattr[NL80211_WOWLAN_PKTPAT_MASK] ||
-			    !patattr[NL80211_WOWLAN_PKTPAT_PATTERN]) {
+			    !patattr[NL80211_WOWLAN_PKTPAT_PATTERN] ||
+			    !patattr[NL80211_WOWLAN_PKTPAT_OFFSET]) {
 				printf(" * (invalid pattern specification)\n");
 				continue;
 			}
 			masklen = nla_len(patattr[NL80211_WOWLAN_PKTPAT_MASK]);
 			patlen = nla_len(patattr[NL80211_WOWLAN_PKTPAT_PATTERN]);
+			pkt_offset = nla_get_u32(patattr[NL80211_WOWLAN_PKTPAT_OFFSET]);
 			if (DIV_ROUND_UP(patlen, 8) != masklen) {
 				printf(" * (invalid pattern specification)\n");
 				continue;
 			}
-			printf(" * wake up on pattern: ");
+			printf(" * wake up on packet offset: %d", pkt_offset);
+			printf(" pattern: ");
 			pat = nla_data(patattr[NL80211_WOWLAN_PKTPAT_PATTERN]);
 			mask = nla_data(patattr[NL80211_WOWLAN_PKTPAT_MASK]);
 			for (i = 0; i < patlen; i++) {
-- 
1.8.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux