summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/bcnm/wpactrl.h26
-rw-r--r--src/libwpactrl/deps-lib/wpactrl4
-rw-r--r--src/libwpactrl/wpactrl_filter_match.c2
-rw-r--r--src/libwpactrl/wpactrl_startscan.c30
-rw-r--r--src/libwpactrl/wpactrl_xchg_cbres_free.c11
-rw-r--r--src/libwpactrl/wpactrl_xchg_cbres_zero.c5
-rw-r--r--src/libwpactrl/wpactrl_xchg_event.c22
-rw-r--r--src/libwpactrl/wpactrl_xchg_free.c10
-rw-r--r--src/libwpactrl/wpactrl_xchg_init.c2
-rw-r--r--src/libwpactrl/wpactrl_xchg_timeout.c3
10 files changed, 82 insertions, 33 deletions
diff --git a/src/include/bcnm/wpactrl.h b/src/include/bcnm/wpactrl.h
index 874a14f..7c31b22 100644
--- a/src/include/bcnm/wpactrl.h
+++ b/src/include/bcnm/wpactrl.h
@@ -68,6 +68,7 @@ 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)
+#define wpactrl_fd(a) ((a)->fda)
extern int wpactrl_update (wpactrl_t *) ;
extern char *wpactrl_msg (wpactrl_t *) gccattr_pure ;
extern void wpactrl_ackmsg (wpactrl_t *) ;
@@ -118,13 +119,12 @@ 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 ;
+ wpactrl_xchg_func_t_ref cb ;
} ;
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 ;
@@ -132,20 +132,30 @@ struct wpactrl_xchg_s
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 }
+#define WPACTRL_XCHG_ZERO { .tab = 0, .n = 0, .i = 0, .deadline = TAIN_ZERO, .status = ECONNABORTED, .aux = 0 }
+#define WPACTRL_XCHG_INIT(array, size, limit, extra) { .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 void 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_timeout (wpactrl_t *, wpactrl_xchg_t *, tain_t const *) ;
+#define wpactrl_xchg_timeout_g(a, dt) wpactrl_xchg_timeout(a, (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)
+typedef struct wpactrl_xchg_cbres_s wpactrl_xchg_cbres_t, *wpactrl_xchg_cbres_t_ref ;
+struct wpactrl_xchg_cbres_s
+{
+ genalloc parsed ;
+ stralloc storage ;
+} ;
+#define WPACTRL_XCHG_CBRES_ZERO { .parsed = GENALLOC_ZERO, .storage = STRALLOC_ZERO }
+
+extern wpactrl_xchg_cbres_t const wpactrl_xchg_cbres_zero ;
+extern void wpactrl_xchg_cbres_free (wpactrl_xchg_cbres_t *) ;
+
/* High-level functions for common calls to wpa_supplicant */
@@ -167,5 +177,7 @@ extern wparesponse_t wpactrl_selectnetwork (wpactrl_t *, uint32_t, tain_t *) ;
extern int wpactrl_associate (wpactrl_t *, char const *, char const *, tain_t *) ;
#define wpactrl_associate_g(a, ssid, psk) wpactrl_associate(a, ssid, (psk), &STAMP)
+extern int wpactrl_startscan (wpactrl_t *, wpactrl_xchg_t *, wpactrl_xchg_cbres_t *, tain_t const *, tain_t *) ;
+#define wpactrl_startscan_g(a, xchg, res, limit) wpactrl_startscan(a, xchg, res, (limit), &STAMP)
#endif
diff --git a/src/libwpactrl/deps-lib/wpactrl b/src/libwpactrl/deps-lib/wpactrl
index 74d579a..d1e7a2b 100644
--- a/src/libwpactrl/deps-lib/wpactrl
+++ b/src/libwpactrl/deps-lib/wpactrl
@@ -22,10 +22,12 @@ wpactrl_scan_parse.o
wpactrl_selectnetwork.o
wpactrl_setnetworkoption.o
wpactrl_start.o
+wpactrl_startscan.o
wpactrl_update.o
+wpactrl_xchg_cbres_free.o
+wpactrl_xchg_cbres_zero.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
diff --git a/src/libwpactrl/wpactrl_filter_match.c b/src/libwpactrl/wpactrl_filter_match.c
index 30ed0ff..09b6eab 100644
--- a/src/libwpactrl/wpactrl_filter_match.c
+++ b/src/libwpactrl/wpactrl_filter_match.c
@@ -7,6 +7,8 @@ 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 ;
+ if (len < 4) return 0 ;
+ s += 3 ; len -= 3 ;
while (filterlen)
{
size_t flen = strlen(filters) ;
diff --git a/src/libwpactrl/wpactrl_startscan.c b/src/libwpactrl/wpactrl_startscan.c
new file mode 100644
index 0000000..7ce5f52
--- /dev/null
+++ b/src/libwpactrl/wpactrl_startscan.c
@@ -0,0 +1,30 @@
+/* ISC license. */
+
+#include <errno.h>
+#include <bcnm/wpactrl.h>
+#include "wpactrl-internal.h"
+
+static int wpactrl_scan_cb (wpactrl_t *a, char const *s, size_t len, void *aux, tain_t *stamp)
+{
+ wpactrl_xchg_cbres_t *res = aux ;
+ char buf[WPACTRL_PACKET_MAX] ;
+ ssize_t r = wpactrl_query(a, "SCAN_RESULTS", buf, WPACTRL_PACKET_MAX, stamp) ;
+ if (r <= 0) return 0 ;
+ (void)s ;
+ (void)len ;
+ return wpactrl_scan_parse(buf, r, &res->parsed, &res->storage) ;
+}
+
+static wpactrl_xchgitem_t wpactrl_xchgitem_scan =
+{
+ .filter = "CTRL-EVENT-SCAN-RESULTS",
+ .cb = &wpactrl_scan_cb
+} ;
+
+int wpactrl_startscan (wpactrl_t *a, wpactrl_xchg_t *xchg, wpactrl_xchg_cbres_t *res, tain_t const *deadline, tain_t *stamp)
+{
+ wparesponse_t r = wpactrl_command(a, "SCAN", stamp) ;
+ if (r != WPA_OK && r != WPA_FAILBUSY) return (errno = EIO, 0) ;
+ wpactrl_xchg_init(xchg, &wpactrl_xchgitem_scan, 1, deadline, res) ;
+ return wpactrl_xchg_start(a, xchg) ;
+}
diff --git a/src/libwpactrl/wpactrl_xchg_cbres_free.c b/src/libwpactrl/wpactrl_xchg_cbres_free.c
new file mode 100644
index 0000000..b12a3fc
--- /dev/null
+++ b/src/libwpactrl/wpactrl_xchg_cbres_free.c
@@ -0,0 +1,11 @@
+/* ISC license. */
+
+#include <skalibs/stralloc.h>
+#include <skalibs/genalloc.h>
+#include <bcnm/wpactrl.h>
+
+void wpactrl_xchg_cbres_free (wpactrl_xchg_cbres_t *cr)
+{
+ genalloc_free(int, &cr->parsed) ; /* relies on genericity of genalloc_free */
+ stralloc_free(&cr->storage) ;
+}
diff --git a/src/libwpactrl/wpactrl_xchg_cbres_zero.c b/src/libwpactrl/wpactrl_xchg_cbres_zero.c
new file mode 100644
index 0000000..c38dc33
--- /dev/null
+++ b/src/libwpactrl/wpactrl_xchg_cbres_zero.c
@@ -0,0 +1,5 @@
+/* ISC license. */
+
+#include <bcnm/wpactrl.h>
+
+wpactrl_xchg_cbres_t const wpactrl_xchg_cbres_zero = WPACTRL_XCHG_CBRES_ZERO ;
diff --git a/src/libwpactrl/wpactrl_xchg_event.c b/src/libwpactrl/wpactrl_xchg_event.c
index 6d25295..e9d2f06 100644
--- a/src/libwpactrl/wpactrl_xchg_event.c
+++ b/src/libwpactrl/wpactrl_xchg_event.c
@@ -1,6 +1,8 @@
/* ISC license. */
#include <string.h>
+#include <errno.h>
+#include <skalibs/error.h>
#include <skalibs/stralloc.h>
#include <bcnm/wpactrl.h>
@@ -10,7 +12,7 @@ static inline size_t wpactrl_findmsg (wpactrl_t *a, char const *filter)
size_t i = 0 ;
while (i < a->data.len)
{
- if (!strncmp(a->data.s + i, filter, filterlen)) break ;
+ if (!strncmp(a->data.s + i + 3, filter, filterlen)) break ;
i += strlen(a->data.s + i) + 1 ;
}
return i ;
@@ -20,23 +22,19 @@ 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 ;
+ if (!error_isagain(dt->status)) return (errno = EINVAL, -1) ;
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 (!(*dt->tab[dt->i].cb)(a, a->data.s + pos, len - 1, dt->aux, stamp)) return -2 ;
+ 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 (++dt->i == dt->n)
{
- 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 ;
+ 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
deleted file mode 100644
index e244a52..0000000
--- a/src/libwpactrl/wpactrl_xchg_free.c
+++ /dev/null
@@ -1,10 +0,0 @@
-/* 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
index 2e2f391..b9d35f0 100644
--- a/src/libwpactrl/wpactrl_xchg_init.c
+++ b/src/libwpactrl/wpactrl_xchg_init.c
@@ -1,12 +1,10 @@
/* ISC license. */
#include <errno.h>
-#include <skalibs/stralloc.h>
#include <bcnm/wpactrl.h>
void 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 ;
diff --git a/src/libwpactrl/wpactrl_xchg_timeout.c b/src/libwpactrl/wpactrl_xchg_timeout.c
index 01907ea..fd99390 100644
--- a/src/libwpactrl/wpactrl_xchg_timeout.c
+++ b/src/libwpactrl/wpactrl_xchg_timeout.c
@@ -4,11 +4,12 @@
#include <skalibs/tai.h>
#include <bcnm/wpactrl.h>
-int wpactrl_xchg_timeout (wpactrl_xchg_t *dt, tain_t const *stamp)
+int wpactrl_xchg_timeout (wpactrl_t *a, wpactrl_xchg_t *dt, tain_t const *stamp)
{
if (!tain_less(stamp, &dt->deadline))
{
dt->status = ETIMEDOUT ;
+ wpactrl_filter_remove(a, dt->tab[dt->i].filter) ;
return 1 ;
}
else return 0 ;