summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2017-08-01 19:36:38 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2017-08-01 19:36:38 +0000
commit69099d84949a8044fdfc74e9d7ff6b9e57fc0bcd (patch)
tree9c97923869ff4f56717d7e0ac97c8588f816c798 /src
parent22a1dc61ef8e4e1c98e3a088db1dbc84d424c7a7 (diff)
downloadbcnm-69099d84949a8044fdfc74e9d7ff6b9e57fc0bcd.tar.xz
Flesh out libwpactrl
Diffstat (limited to 'src')
-rw-r--r--src/include/bcnm/wpactrl.h101
-rw-r--r--src/libwpactrl/deps-lib/wpactrl12
-rw-r--r--src/libwpactrl/wpactrl-internal.h3
-rw-r--r--src/libwpactrl/wpactrl_ackmsg.c (renamed from src/libwpactrl/wpactrl_nextmsg.c)2
-rw-r--r--src/libwpactrl/wpactrl_command.c52
-rw-r--r--src/libwpactrl/wpactrl_end.c5
-rw-r--r--src/libwpactrl/wpactrl_env_parse.c11
-rw-r--r--src/libwpactrl/wpactrl_filter_add.c3
-rw-r--r--src/libwpactrl/wpactrl_filter_match.c18
-rw-r--r--src/libwpactrl/wpactrl_query.c8
-rw-r--r--src/libwpactrl/wpactrl_querysa.c4
-rw-r--r--src/libwpactrl/wpactrl_scan_parse.c51
-rw-r--r--src/libwpactrl/wpactrl_start.c15
-rw-r--r--src/libwpactrl/wpactrl_update.c14
-rw-r--r--src/libwpactrl/wpactrl_xchg_computedeadline.c9
-rw-r--r--src/libwpactrl/wpactrl_xchg_event.c42
-rw-r--r--src/libwpactrl/wpactrl_xchg_free.c10
-rw-r--r--src/libwpactrl/wpactrl_xchg_init.c17
-rw-r--r--src/libwpactrl/wpactrl_xchg_start.c14
-rw-r--r--src/libwpactrl/wpactrl_xchg_timeout.c15
-rw-r--r--src/libwpactrl/wpactrl_xchg_zero.c5
21 files changed, 320 insertions, 91 deletions
diff --git a/src/include/bcnm/wpactrl.h b/src/include/bcnm/wpactrl.h
index df5f2c1..1c5610c 100644
--- a/src/include/bcnm/wpactrl.h
+++ b/src/include/bcnm/wpactrl.h
@@ -5,6 +5,7 @@
#include <sys/types.h>
#include <stdint.h>
+#include <errno.h>
#include <skalibs/gccattributes.h>
#include <skalibs/tai.h>
#include <skalibs/stralloc.h>
@@ -13,23 +14,23 @@
typedef enum wparesponse_e wparesponse_t, *wparesponse_t_ref ;
enum wparesponse_e
{
- WPA_ERROR = -1,
WPA_OK = 0,
- WPA_PONG,
- WPA_UNKNOWNCOMMAND,
- WPA_FAIL,
- WPA_FAILBUSY,
- WPA_FAILCHECKSUM,
- WPA_FAILINVALIDPIN,
- WPA_FAILCHANNELUNAVAILABLE,
- WPA_FAILCHANNELUNSUPPORTED,
- WPA_FAILINVALIDRANGE,
- WPA_FAILTOOLONGRESPONSE,
- WPA_FAILPBCOVERLAP,
- WPA_FAILUNKNOWNUUID,
- WPA_FAILNOAPSETTINGS,
- WPA_FAILNOIFNAMEATTACH,
- WPA_UNKNOWNRESPONSE
+ WPA_PONG = 1,
+ WPA_ERROR = -1,
+ WPA_UNKNOWNCOMMAND = -2,
+ WPA_FAIL = -3,
+ WPA_FAILBUSY = -4,
+ WPA_FAILCHECKSUM = -5,
+ WPA_FAILINVALIDPIN = -6,
+ WPA_FAILCHANNELUNAVAILABLE = -7,
+ WPA_FAILCHANNELUNSUPPORTED = -8,
+ WPA_FAILINVALIDRANGE = -9,
+ WPA_FAILTOOLONGRESPONSE = -10,
+ WPA_FAILPBCOVERLAP = -11,
+ WPA_FAILUNKNOWNUUID = -12,
+ WPA_FAILNOAPSETTINGS = -13,
+ WPA_FAILNOIFNAMEMATCH = -14,
+ WPA_UNKNOWNRESPONSE = -999
} ;
typedef struct wpactrl_s wpactrl_t, *wpactrl_t_ref ;
@@ -38,29 +39,31 @@ struct wpactrl_s
int fds ;
int fda ;
uint32_t options ;
+ tain_t tto ;
size_t datahead ;
stralloc data ;
stralloc filters ;
} ;
-#define WPACTRL_ZERO { .fds = -1, .fda = -1, .options = 0, .datahead = 0, .data = STRALLOC_ZERO, .filters = STRALLOC_ZERO }
+#define WPACTRL_ZERO { .fds = -1, .fda = -1, .options = 0, .tto = TAIN_ZERO, .datahead = 0, .data = STRALLOC_ZERO, .filters = STRALLOC_ZERO }
#define WPACTRL_OPTION_NOFILTER 0x0001U
extern wpactrl_t const wpactrl_zero ;
-extern int wpactrl_start (wpactrl_t *, char const *, tain_t const *, tain_t *) ;
-#define wpactrl_start_g(a, path, deadline) wpactrl_start(a, path, (deadline), &STAMP)
+extern int wpactrl_start (wpactrl_t *, char const *, unsigned int, tain_t *) ;
+#define wpactrl_start_g(a, path, timeout) wpactrl_start(a, path, (timeout), &STAMP)
extern void wpactrl_end (wpactrl_t *) ;
-extern wparesponse_t wpactrl_command (wpactrl_t *, char const *, size_t, tain_t const *, tain_t *) ;
-#define wpactrl_command_g(a, q, qlen, deadline) wpactrl_command(a, q, qlen, (deadline), &STAMP)
-extern ssize_t wpactrl_query (wpactrl_t *, char const *, size_t, char *, size_t, tain_t const *, tain_t *) ;
-#define wpactrl_query_g(a, q, qlen, ans, ansmax, deadline) wpactrl_query(a, q, qlen, ans, ansmax, (deadline), &STAMP)
-extern int wpactrl_querysa (wpactrl_t *, char const *, size_t, stralloc *, tain_t const *, tain_t *) ;
-#define wpactrl_querysa_g(a, q, qlen, sa, deadline) wpactrl_querysa(a, q, qlen, sa, (deadline), &STAMP)
+extern wparesponse_t wpactrl_command (wpactrl_t *, char const *, size_t, tain_t *) ;
+#define wpactrl_command_g(a, q, qlen) wpactrl_command(a, q, (qlen), &STAMP)
+extern ssize_t wpactrl_query (wpactrl_t *, char const *, size_t, char *, size_t, tain_t *) ;
+#define wpactrl_query_g(a, q, qlen, ans, ansmax) wpactrl_query(a, q, qlen, ans, (ansmax), &STAMP)
+extern int wpactrl_querysa (wpactrl_t *, char const *, size_t, stralloc *, tain_t *) ;
+#define wpactrl_querysa_g(a, q, qlen, sa) wpactrl_querysa(a, q, qlen, (sa), &STAMP)
extern int wpactrl_filter_add (wpactrl_t *, char const *) ;
extern void wpactrl_filter_remove (wpactrl_t *, char const *) ;
+extern int wpactrl_filter_match (wpactrl_t const *, char const *, size_t) ;
#define wpactrl_filter_activate(a) ((a)->options &= ~(uint32_t)WPACTRL_OPTION_NOFILTER)
#define wpactrl_filter_deactivate(a) ((a)->options |= WPACTRL_OPTION_NOFILTER)
@@ -70,7 +73,7 @@ extern char *wpactrl_msg (wpactrl_t *) gccattr_pure ;
extern void wpactrl_ackmsg (wpactrl_t *) ;
- /* High-level functions */
+ /* Helper functions for parsing answers from wpa_supplicant */
typedef struct wpactrl_scanres_s wpactrl_scanres_t, *wpactrl_scanres_t_ref ;
struct wpactrl_scanres_s
@@ -78,13 +81,53 @@ struct wpactrl_scanres_s
char bssid[6] ;
uint16_t frequency ;
uint16_t signal_level ;
- uint32_t flags ;
- size_t ssid ;
+ size_t flags_start ;
+ size_t flags_len ;
+ size_t ssid_start ;
+ size_t ssid_len ;
} ;
-#define WPACTRL_SCANRES_ZERO { .bssid = "\0\0\0\0\0", .frequency = 0, .signal_level = 0, .flags = 0, .ssid = 0 }
+#define WPACTRL_SCANRES_ZERO { .bssid = "\0\0\0\0\0", .frequency = 0, .signal_level = 0, .flags_start = 0, .flags_len = 0, .ssid_start = 0, .ssid_len = 0 }
extern int wpactrl_scan_parse (char const *, size_t, genalloc * /* wpactrl_scanres_t */, stralloc *) ;
+extern unsigned int wpactrl_env_parse (char *, size_t) ;
+
+
+ /* Higher-level functions for easy iopause */
+
+typedef int wpactrl_xchg_func_t (wpactrl_t *, char const *, size_t, void *, tain_t *) ;
+typedef wpactrl_xchg_func_t *wpactrl_xchg_func_t_ref ;
+
+typedef struct wpactrl_xchgitem_s wpactrl_xchgitem_t, *wpactrl_xchgitem_t_ref ;
+struct wpactrl_xchgitem_s
+{
+ char const *filter ;
+ wpactrl_xchg_func_t_ref f ;
+} ;
+
+typedef struct wpactrl_xchg_s wpactrl_xchg_t, *wpactrl_xchg_t_ref ;
+struct wpactrl_xchg_s
+{
+ stralloc sa ;
+ wpactrl_xchgitem_t const *tab ;
+ unsigned int n ;
+ unsigned int i ;
+ tain_t deadline ;
+ int status ;
+ void *aux ;
+} ;
+#define WPACTRL_XCHG_ZERO { .sa = STRALLOC_ZERO, .tab = 0, .n = 0, .i = 0, .deadline = TAIN_ZERO, .status = ECONNABORTED, .aux = 0 }
+#define WPACTRL_XCHG_INIT(array, size, limit, extra) { .sa = STRALLOC_ZERO, .tab = array, .n = size, .i = 0, .deadline = limit, .status = ECONNABORTED, .aux = extra }
+
+extern wpactrl_xchg_t const wpactrl_xchg_zero ;
+extern void wpactrl_xchg_free (wpactrl_xchg_t *) ;
+extern int wpactrl_xchg_init (wpactrl_xchg_t *, wpactrl_xchgitem_t const *, unsigned int, tain_t const *, void *) ;
+extern int wpactrl_xchg_start (wpactrl_t *, wpactrl_xchg_t *) ;
+extern void wpactrl_xchg_computedeadline (wpactrl_xchg_t const *, tain_t *) ;
+extern int wpactrl_xchg_timeout (wpactrl_xchg_t *, tain_t const *) ;
+#define wpactrl_xchg_timeout_g(dt) wpactrl_xchg_timeout((dt), &STAMP)
+extern int wpactrl_xchg_event (wpactrl_t *, wpactrl_xchg_t *, tain_t *) ;
+#define wpactrl_xchg_event_g(a, dt) wpactrl_xchg_event(a, (dt), &STAMP)
/*
diff --git a/src/libwpactrl/deps-lib/wpactrl b/src/libwpactrl/deps-lib/wpactrl
index 98cd9e6..1943682 100644
--- a/src/libwpactrl/deps-lib/wpactrl
+++ b/src/libwpactrl/deps-lib/wpactrl
@@ -1,12 +1,24 @@
+wpactrl_ackmsg.o
wpactrl_command.o
wpactrl_end.o
+wpactrl_env_parse.o
wpactrl_fd_recv.o
wpactrl_fd_timed_recv.o
wpactrl_filter_add.o
wpactrl_filter_exact_search.o
+wpactrl_filter_match.o
wpactrl_filter_remove.o
+wpactrl_msg.o
wpactrl_query.o
wpactrl_querysa.o
+wpactrl_scan_parse.o
wpactrl_start.o
wpactrl_update.o
+wpactrl_xchg_computedeadline.o
+wpactrl_xchg_event.o
+wpactrl_xchg_free.o
+wpactrl_xchg_init.o
+wpactrl_xchg_start.o
+wpactrl_xchg_timeout.o
+wpactrl_xchg_zero.o
wpactrl_zero.o
diff --git a/src/libwpactrl/wpactrl-internal.h b/src/libwpactrl/wpactrl-internal.h
index ddd2597..50f2fbd 100644
--- a/src/libwpactrl/wpactrl-internal.h
+++ b/src/libwpactrl/wpactrl-internal.h
@@ -4,6 +4,7 @@
#define BCNM_WPACTRL_INTERNAL_H
#include <sys/types.h>
+#include <stdint.h>
#include <skalibs/gccattributes.h>
#include <skalibs/tai.h>
#include <bcnm/wpactrl.h>
@@ -15,4 +16,6 @@ extern ssize_t wpactrl_fd_recv (int, char *, size_t) ;
extern ssize_t wpactrl_fd_timed_recv (int, char *, size_t, tain_t const *, tain_t *) ;
extern size_t wpactrl_filter_exact_search (wpactrl_t const *, char const *) gccattr_pure ;
+extern size_t wpactrl_xchgset_find (wpactrl_t const *, uint32_t) ;
+
#endif
diff --git a/src/libwpactrl/wpactrl_nextmsg.c b/src/libwpactrl/wpactrl_ackmsg.c
index 4954db9..6d0d3b6 100644
--- a/src/libwpactrl/wpactrl_nextmsg.c
+++ b/src/libwpactrl/wpactrl_ackmsg.c
@@ -3,7 +3,7 @@
#include <string.h>
#include <bcnm/wpactrl.h>
-void wpactrl_nextmsg (wpactrl_t *a)
+void wpactrl_ackmsg (wpactrl_t *a)
{
if (a->datahead < a->data.len) a->datahead += strlen(a->data.s + a->datahead) + 1 ;
if (a->datahead >= a->data.len)
diff --git a/src/libwpactrl/wpactrl_command.c b/src/libwpactrl/wpactrl_command.c
index c29a58a..34e31c2 100644
--- a/src/libwpactrl/wpactrl_command.c
+++ b/src/libwpactrl/wpactrl_command.c
@@ -6,36 +6,42 @@
#define WPARESPONSE_MAXLEN 28
-wparesponse_t wpactrl_command (wpactrl_t *a, char const *s, size_t len, tain_t const *deadline, tain_t *stamp)
+struct wparesponse_map_s
{
- static char const *wparesponses[] =
+ char const *s ;
+ wparesponse_t r ;
+} ;
+
+wparesponse_t wpactrl_command (wpactrl_t *a, char const *s, size_t len, tain_t *stamp)
+{
+ static struct wparesponse_map_s const wparesponses[] =
{
- "OK\n",
- "PONG\n",
- "UNKNOWN COMMAND\n",
- "FAIL\n",
- "FAIL-BUSY\n",
- "FAIL-CHECKSUM\n",
- "FAIL-INVALID-PIN\n",
- "FAIL-CHANNEL-UNAVAILABLE\n",
- "FAIL-CHANNEL-UNSUPPORTED\n",
- "FAIL-Invalid range\n",
- "FAIL-Too long response\n",
- "FAIL-PBC-OVERLAP\n",
- "FAIL-UNKNOWN-UUID\n",
- "FAIL-NO-AP-SETTINGS\n",
- "FAIL-NO-IFNAME-MATCH\n",
- 0
+ { "OK\n", WPA_OK },
+ { "PONG\n", WPA_PONG },
+ { "UNKNOWN COMMAND\n", WPA_UNKNOWNCOMMAND },
+ { "FAIL\n", WPA_FAIL },
+ { "FAIL-BUSY\n", WPA_FAILBUSY },
+ { "FAIL-CHECKSUM\n", WPA_FAILCHECKSUM },
+ { "FAIL-INVALID-PIN\n", WPA_FAILINVALIDPIN },
+ { "FAIL-CHANNEL-UNAVAILABLE\n", WPA_FAILCHANNELUNAVAILABLE },
+ { "FAIL-CHANNEL-UNSUPPORTED\n", WPA_FAILCHANNELUNSUPPORTED },
+ { "FAIL-Invalid range\n", WPA_FAILINVALIDRANGE },
+ { "FAIL-Too long response\n", WPA_FAILTOOLONGRESPONSE },
+ { "FAIL-PBC-OVERLAP\n", WPA_FAILPBCOVERLAP },
+ { "FAIL-UNKNOWN-UUID\n", WPA_FAILUNKNOWNUUID },
+ { "FAIL-NO-AP-SETTINGS\n", WPA_FAILNOAPSETTINGS },
+ { "FAIL-NO-IFNAME-MATCH\n", WPA_FAILNOIFNAMEMATCH },
+ { 0, WPA_UNKNOWNRESPONSE }
} ;
char buf[WPARESPONSE_MAXLEN] ;
- ssize_t r = wpactrl_query(a, s, len, buf, WPARESPONSE_MAXLEN, deadline, stamp) ;
+ ssize_t r = wpactrl_query(a, s, len, buf, WPARESPONSE_MAXLEN, stamp) ;
if (r < 0) return WPA_ERROR ;
if (!r) return (errno = EPIPE, WPA_ERROR) ;
{
- wparesponse_t i = 0 ;
- for (; wparesponses[i] ; i++)
- if (!strncmp(buf, wparesponses[i], r))
+ unsigned int i = 0 ;
+ for (; wparesponses[i].s ; i++)
+ if (!strncmp(buf, wparesponses[i].s, r))
break ;
- return i ;
+ return wparesponses[i].r ;
}
}
diff --git a/src/libwpactrl/wpactrl_end.c b/src/libwpactrl/wpactrl_end.c
index 40fdb4a..a14b6c8 100644
--- a/src/libwpactrl/wpactrl_end.c
+++ b/src/libwpactrl/wpactrl_end.c
@@ -1,11 +1,14 @@
/* ISC license. */
+#include <skalibs/stralloc.h>
#include <skalibs/djbunix.h>
#include <bcnm/wpactrl.h>
-void wpactrl_free (wpactrl_t *a)
+void wpactrl_end (wpactrl_t *a)
{
fd_close(a->fda) ;
fd_close(a->fds) ;
+ stralloc_free(&a->filters) ;
+ stralloc_free(&a->data) ;
*a = wpactrl_zero ;
}
diff --git a/src/libwpactrl/wpactrl_env_parse.c b/src/libwpactrl/wpactrl_env_parse.c
new file mode 100644
index 0000000..c722fd5
--- /dev/null
+++ b/src/libwpactrl/wpactrl_env_parse.c
@@ -0,0 +1,11 @@
+/* ISC license. */
+
+#include <bcnm/wpactrl.h>
+
+unsigned int wpactrl_env_parse (char *s, size_t len)
+{
+ size_t i = 0 ;
+ unsigned int n = 0 ;
+ for (; i < len ; i++) if (s[i] == '\n') (s[i] = 0, n++) ;
+ return n ;
+}
diff --git a/src/libwpactrl/wpactrl_filter_add.c b/src/libwpactrl/wpactrl_filter_add.c
index 8896e23..52e5b3a 100644
--- a/src/libwpactrl/wpactrl_filter_add.c
+++ b/src/libwpactrl/wpactrl_filter_add.c
@@ -1,12 +1,13 @@
/* ISC license. */
#include <string.h>
+#include <errno.h>
#include <skalibs/stralloc.h>
#include <bcnm/wpactrl.h>
#include "wpactrl-internal.h"
int wpactrl_filter_add (wpactrl_t *a, char const *s)
{
- if (wpactrl_filter_exact_search(a, s) < a->filters.len) return 1 ;
+ if (wpactrl_filter_exact_search(a, s) < a->filters.len) return (errno = EBUSY, 0) ;
return stralloc_catb(&a->filters, s, strlen(s)) ;
}
diff --git a/src/libwpactrl/wpactrl_filter_match.c b/src/libwpactrl/wpactrl_filter_match.c
new file mode 100644
index 0000000..30ed0ff
--- /dev/null
+++ b/src/libwpactrl/wpactrl_filter_match.c
@@ -0,0 +1,18 @@
+/* ISC license. */
+
+#include <string.h>
+#include <bcnm/wpactrl.h>
+
+int wpactrl_filter_match (wpactrl_t const *a, char const *s, size_t len)
+{
+ size_t filterlen = a->filters.len ;
+ char const *filters = a->filters.s ;
+ while (filterlen)
+ {
+ size_t flen = strlen(filters) ;
+ if (len >= flen && !strncmp(filters, s, flen)) return 1 ;
+ filters += flen+1 ;
+ filterlen -= flen+1 ;
+ }
+ return 0 ;
+}
diff --git a/src/libwpactrl/wpactrl_query.c b/src/libwpactrl/wpactrl_query.c
index 951c536..b03899f 100644
--- a/src/libwpactrl/wpactrl_query.c
+++ b/src/libwpactrl/wpactrl_query.c
@@ -4,8 +4,10 @@
#include <bcnm/wpactrl.h>
#include "wpactrl-internal.h"
-ssize_t wpactrl_query (wpactrl_t *a, char const *q, size_t qlen, char *ans, size_t ansmax, tain_t const *deadline, tain_t *stamp)
+ssize_t wpactrl_query (wpactrl_t *a, char const *q, size_t qlen, char *ans, size_t ansmax, tain_t *stamp)
{
- if (!ipc_timed_send(a->fds, q, qlen, deadline, stamp)) return WPA_ERROR ;
- return wpactrl_fd_timed_recv(a->fds, ans, ansmax, deadline, stamp) ;
+ tain_t deadline ;
+ tain_add(&deadline, stamp, &a->tto) ;
+ if (!ipc_timed_send(a->fds, q, qlen, &deadline, stamp)) return WPA_ERROR ;
+ return wpactrl_fd_timed_recv(a->fds, ans, ansmax, &deadline, stamp) ;
}
diff --git a/src/libwpactrl/wpactrl_querysa.c b/src/libwpactrl/wpactrl_querysa.c
index fe06202..887941f 100644
--- a/src/libwpactrl/wpactrl_querysa.c
+++ b/src/libwpactrl/wpactrl_querysa.c
@@ -5,10 +5,10 @@
#include <bcnm/wpactrl.h>
#include "wpactrl-internal.h"
-int wpactrl_querysa (wpactrl_t *a, char const *s, size_t len, stralloc *sa, tain_t const *deadline, tain_t *stamp)
+int wpactrl_querysa (wpactrl_t *a, char const *s, size_t len, stralloc *sa, tain_t *stamp)
{
char buf[WPACTRL_PACKET_MAX] ;
- ssize_t r = wpactrl_query(a, s, len, buf, WPACTRL_PACKET_MAX, deadline, stamp) ;
+ ssize_t r = wpactrl_query(a, s, len, buf, WPACTRL_PACKET_MAX, stamp) ;
if (r < 0) return 0 ;
if (!r) return (errno = EPIPE, 0) ;
return stralloc_catb(sa, buf, r) ;
diff --git a/src/libwpactrl/wpactrl_scan_parse.c b/src/libwpactrl/wpactrl_scan_parse.c
index 24f83c8..ab4a9fe 100644
--- a/src/libwpactrl/wpactrl_scan_parse.c
+++ b/src/libwpactrl/wpactrl_scan_parse.c
@@ -17,35 +17,60 @@ static size_t bssid_scan (char const *s, char *bssid)
char sep[6] = ":::::\t" ;
for (; i < 6 ; i++)
{
- if (!ucharn_scan(s, bssid + i, 1)) return 0 ;
- if (s[2] != sep[i]) return 0 ;
+ if (!ucharn_scan(s, bssid + i, 1)) goto eproto ;
+ if (s[2] != sep[i]) goto eproto ;
s += 3 ;
}
return 18 ;
+
+ eproto:
+ return (errno = EPROTO, 0) ;
}
-static size_t flags_scan (char const *s, uint32_t *flags)
+static int flags_scan (char const *s, size_t len, stralloc *sa)
{
- return 0 ;
+ while (len)
+ {
+ size_t pos ;
+ if (*s++ != '[') goto eproto ;
+ len-- ;
+ pos = byte_chr(s, len, ']') ;
+ if (pos >= len || !pos) goto eproto ;
+ if (!stralloc_catb(sa, s, pos) || !stralloc_0(sa)) return 0 ;
+ s += pos + 1 ; len -= pos + 1 ;
+ }
+ return 1 ;
+
+ eproto:
+ return (errno = EPROTO, 0) ;
}
static int wpactrl_scan_parse_one (char const *s, size_t len, wpactrl_scanres_t *thing, stralloc *sa)
{
+ wpactrl_scanres_t sr ;
size_t pos = byte_chr(s, len, '\t') ;
- if (pos >= len) return 0 ;
- if (pos != 18) return 0 ;
- if (bssid_scan(s, thing->bssid) != pos) return 0 ;
+ if (pos >= len) goto eproto ;
+ if (pos != 18) goto eproto ;
+ if (bssid_scan(s, sr.bssid) != pos) goto eproto ;
s += pos + 1 ; len -= pos + 1 ;
pos = byte_chr(s, len, '\t') ;
- if (pos >= len) return 0 ;
- if (uint16_scan(s, &thing->frequency) != pos) return 0 ;
+ if (pos >= len) goto eproto ;
+ if (uint16_scan(s, &sr.frequency) != pos) goto eproto ;
s += pos + 1 ; len -= pos + 1 ;
pos = byte_chr(s, len, '\t') ;
- if (pos >= len) return 0 ;
- if (flags_scan(s, &thing->flags) != pos) return 0 ;
+ if (pos >= len) goto eproto ;
+ sr.flags_start = sa->len ;
+ if (!flags_scan(s, pos, sa)) goto eproto ;
s += pos + 1 ; len -= pos + 1 ;
- thing->ssid = sa->len ;
- return stralloc_catb(sa, s, len - 1) && stralloc_0(sa) ;
+ sr.flags_len = sa->len - sr.flags_start ;
+ sr.ssid_start = sa->len ;
+ sr.ssid_len = len - 1 ;
+ if (!stralloc_catb(sa, s, len - 1) || !stralloc_0(sa)) return 0 ;
+ *thing = sr ;
+ return 1 ;
+
+ eproto:
+ return (errno = EPROTO, 0) ;
}
int wpactrl_scan_parse (char const *s, size_t len, genalloc *ga, stralloc *sa)
diff --git a/src/libwpactrl/wpactrl_start.c b/src/libwpactrl/wpactrl_start.c
index 86a266b..80018d5 100644
--- a/src/libwpactrl/wpactrl_start.c
+++ b/src/libwpactrl/wpactrl_start.c
@@ -8,24 +8,29 @@
#include <bcnm/wpactrl.h>
#include "wpactrl-internal.h"
-int wpactrl_start (wpactrl_t *a, char const *path, tain_t const *deadline, tain_t *stamp)
+int wpactrl_start (wpactrl_t *a, char const *path, unsigned int timeout, tain_t *stamp)
{
+ tain_t tto, deadline ;
int fda, fds ;
+ if (timeout) tain_from_millisecs(&tto, timeout) ;
+ else tto = tain_infinite_relative ;
fds = ipc_datagram_nbcoe() ;
if (fds < 0) goto err ;
- if (!ipc_timed_connect(fds, path, deadline, stamp)) goto errs ;
+ tain_add(&deadline, &tto, stamp) ;
+ if (!ipc_timed_connect(fds, path, &deadline, stamp)) goto errs ;
fda = ipc_datagram_nbcoe() ;
if (fda < 0) goto errs ;
- if (!ipc_timed_connect(fda, path, deadline, stamp)) goto erra ;
- if (!ipc_timed_send(fda, "ATTACH", 6, deadline, stamp)) goto erra ;
+ if (!ipc_timed_connect(fda, path, &deadline, stamp)) goto erra ;
+ if (!ipc_timed_send(fda, "ATTACH", 6, &deadline, stamp)) goto erra ;
{
ssize_t r ;
char answer[3] ;
- r = wpactrl_fd_timed_recv(fda, answer, 3, deadline, stamp) ;
+ r = wpactrl_fd_timed_recv(fda, answer, 3, &deadline, stamp) ;
if (r != 3 || memcmp(answer, "OK\n", 3)) goto erra ;
}
a->fds = fds ;
a->fda = fda ;
+ a->tto = tto ;
return 1 ;
erra:
diff --git a/src/libwpactrl/wpactrl_update.c b/src/libwpactrl/wpactrl_update.c
index 0462cbe..e5d8db1 100644
--- a/src/libwpactrl/wpactrl_update.c
+++ b/src/libwpactrl/wpactrl_update.c
@@ -8,18 +8,6 @@
#include <bcnm/wpactrl.h>
#include "wpactrl-internal.h"
-static inline int filter_search (char const *s, size_t len, char const *filters, size_t filterlen)
-{
- while (filterlen)
- {
- size_t flen = strlen(filters) ;
- if (len >= flen && !strncmp(filters, s, flen)) return 1 ;
- filters += flen+1 ;
- filterlen -= flen+1 ;
- }
- return 0 ;
-}
-
static inline int validate (char const *s, size_t len)
{
if (len < 4) return 0 ;
@@ -41,7 +29,7 @@ int wpactrl_update (wpactrl_t *a)
if (r < 0) return -1 ;
if (!r) break ;
if (a->options & WPACTRL_OPTION_NOFILTER
- || (validate(buf, r) && filter_search(buf, r, a->filters.s, a->filters.len)))
+ || (validate(buf, r) && wpactrl_filter_match(a, buf, r)))
{
buf[r] = 0 ;
if (!stralloc_catb(&a->data, buf, r+1)) return -1 ;
diff --git a/src/libwpactrl/wpactrl_xchg_computedeadline.c b/src/libwpactrl/wpactrl_xchg_computedeadline.c
new file mode 100644
index 0000000..baaac77
--- /dev/null
+++ b/src/libwpactrl/wpactrl_xchg_computedeadline.c
@@ -0,0 +1,9 @@
+/* ISC license. */
+
+#include <skalibs/tai.h>
+#include <bcnm/wpactrl.h>
+
+void wpactrl_xchg_computedeadline (wpactrl_xchg_t const *dt, tain_t *deadline)
+{
+ if (tain_less(&dt->deadline, deadline)) *deadline = dt->deadline ;
+}
diff --git a/src/libwpactrl/wpactrl_xchg_event.c b/src/libwpactrl/wpactrl_xchg_event.c
new file mode 100644
index 0000000..6d25295
--- /dev/null
+++ b/src/libwpactrl/wpactrl_xchg_event.c
@@ -0,0 +1,42 @@
+/* ISC license. */
+
+#include <string.h>
+#include <skalibs/stralloc.h>
+#include <bcnm/wpactrl.h>
+
+static inline size_t wpactrl_findmsg (wpactrl_t *a, char const *filter)
+{
+ size_t filterlen = strlen(filter) ;
+ size_t i = 0 ;
+ while (i < a->data.len)
+ {
+ if (!strncmp(a->data.s + i, filter, filterlen)) break ;
+ i += strlen(a->data.s + i) + 1 ;
+ }
+ return i ;
+}
+
+int wpactrl_xchg_event (wpactrl_t *a, wpactrl_xchg_t *dt, tain_t *stamp)
+{
+ size_t pos, len ;
+ if (dt->i >= dt->n) return 2 ;
+ pos = wpactrl_findmsg(a, dt->tab[dt->i].filter) ;
+ if (pos >= a->data.len) return 0 ;
+ dt->sa.len = 0 ;
+ len = strlen(a->data.s + pos) + 1 ;
+ if (dt->i == dt->n - 1)
+ {
+ if (!stralloc_catb(&dt->sa, a->data.s + pos, len)) return -1 ;
+ memmove(a->data.s + pos, a->data.s + pos + len, a->data.len - len) ;
+ a->data.len -= len ;
+ dt->status = 0 ;
+ wpactrl_filter_remove(a, dt->tab[dt->i].filter) ;
+ return 1 ;
+ }
+ if (!(*dt->tab[dt->i].f)(a, a->data.s + pos, len - 1, dt->aux, stamp)) return -1 ;
+ memmove(a->data.s + pos, a->data.s + pos + len, a->data.len - len) ;
+ a->data.len -= len ;
+ wpactrl_filter_remove(a, dt->tab[dt->i].filter) ;
+ if (!wpactrl_filter_add(a, dt->tab[++dt->i].filter)) return -1 ;
+ return 0 ;
+}
diff --git a/src/libwpactrl/wpactrl_xchg_free.c b/src/libwpactrl/wpactrl_xchg_free.c
new file mode 100644
index 0000000..e244a52
--- /dev/null
+++ b/src/libwpactrl/wpactrl_xchg_free.c
@@ -0,0 +1,10 @@
+/* ISC license. */
+
+#include <skalibs/stralloc.h>
+#include <bcnm/wpactrl.h>
+
+void wpactrl_xchg_free (wpactrl_xchg_t *dt)
+{
+ stralloc_free(&dt->sa) ;
+ *dt = wpactrl_xchg_zero ;
+}
diff --git a/src/libwpactrl/wpactrl_xchg_init.c b/src/libwpactrl/wpactrl_xchg_init.c
new file mode 100644
index 0000000..37006dd
--- /dev/null
+++ b/src/libwpactrl/wpactrl_xchg_init.c
@@ -0,0 +1,17 @@
+/* ISC license. */
+
+#include <errno.h>
+#include <skalibs/stralloc.h>
+#include <bcnm/wpactrl.h>
+
+int wpactrl_xchg_init (wpactrl_xchg_t *dt, wpactrl_xchgitem_t const *tab, unsigned int n, tain_t const *limit, void *aux)
+{
+ dt->sa.len = 0 ;
+ dt->tab = tab ;
+ dt->n = n ;
+ dt->i = 0 ;
+ dt->deadline = *limit ;
+ dt->status = ECONNABORTED ;
+ dt->aux = aux ;
+ return 1 ;
+}
diff --git a/src/libwpactrl/wpactrl_xchg_start.c b/src/libwpactrl/wpactrl_xchg_start.c
new file mode 100644
index 0000000..3b45f3e
--- /dev/null
+++ b/src/libwpactrl/wpactrl_xchg_start.c
@@ -0,0 +1,14 @@
+/* ISC license. */
+
+#include <errno.h>
+#include <skalibs/tai.h>
+#include <bcnm/wpactrl.h>
+
+int wpactrl_xchg_start (wpactrl_t *a, wpactrl_xchg_t *dt)
+{
+ if (!dt->n) return (errno = EINVAL, 0) ;
+ if (!wpactrl_filter_add(a, dt->tab[0].filter)) return 0 ;
+ dt->i = 0 ;
+ dt->status = EAGAIN ;
+ return 1 ;
+}
diff --git a/src/libwpactrl/wpactrl_xchg_timeout.c b/src/libwpactrl/wpactrl_xchg_timeout.c
new file mode 100644
index 0000000..01907ea
--- /dev/null
+++ b/src/libwpactrl/wpactrl_xchg_timeout.c
@@ -0,0 +1,15 @@
+/* ISC license. */
+
+#include <errno.h>
+#include <skalibs/tai.h>
+#include <bcnm/wpactrl.h>
+
+int wpactrl_xchg_timeout (wpactrl_xchg_t *dt, tain_t const *stamp)
+{
+ if (!tain_less(stamp, &dt->deadline))
+ {
+ dt->status = ETIMEDOUT ;
+ return 1 ;
+ }
+ else return 0 ;
+}
diff --git a/src/libwpactrl/wpactrl_xchg_zero.c b/src/libwpactrl/wpactrl_xchg_zero.c
new file mode 100644
index 0000000..28e51eb
--- /dev/null
+++ b/src/libwpactrl/wpactrl_xchg_zero.c
@@ -0,0 +1,5 @@
+/* ISC license. */
+
+#include <bcnm/wpactrl.h>
+
+wpactrl_xchg_t const wpactrl_xchg_zero = WPACTRL_XCHG_ZERO ;