about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2017-07-09 07:46:23 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2017-07-09 07:46:23 +0000
commit22a1dc61ef8e4e1c98e3a088db1dbc84d424c7a7 (patch)
treeefc5d779a40c004e708bd6a99b359c660931249b
parent0c9b6b3625dff03b6d590af597aa0f194790addb (diff)
downloadbcnm-22a1dc61ef8e4e1c98e3a088db1dbc84d424c7a7.tar.gz
bcnm-22a1dc61ef8e4e1c98e3a088db1dbc84d424c7a7.tar.xz
bcnm-22a1dc61ef8e4e1c98e3a088db1dbc84d424c7a7.zip
Separate messages via \0, read messages one by one. Add wpactrl_scan_parse() skel.
-rw-r--r--doc/libwpactrl/index.html24
-rw-r--r--package/deps.mak5
-rw-r--r--src/include/bcnm/wpactrl.h27
-rw-r--r--src/libwpactrl/wpactrl-internal.h2
-rw-r--r--src/libwpactrl/wpactrl_msg.c8
-rw-r--r--src/libwpactrl/wpactrl_nextmsg.c14
-rw-r--r--src/libwpactrl/wpactrl_scan_parse.c79
-rw-r--r--src/libwpactrl/wpactrl_update.c8
8 files changed, 144 insertions, 23 deletions
diff --git a/doc/libwpactrl/index.html b/doc/libwpactrl/index.html
index 0d2870e..1115787 100644
--- a/doc/libwpactrl/index.html
+++ b/doc/libwpactrl/index.html
@@ -175,24 +175,18 @@ a spamming wpa_supplicant from monopolizing your program.
 </p>
 
 <p>
-<code> char *wpactrl_data (wpactrl_t *a) </code> <br />
-Returns a pointer to the unsolicited messages from wpa_supplicant
-that have been read by <tt>wpactrl_update()</tt> but haven't been
-acknowledged yet.
+<code> char *wpactrl_msg (wpactrl_t *a) </code> <br />
+Returns a pointer to the first unsolicited message from
+wpa_supplicant that has been read by <tt>wpactrl_update()</tt> but
+has not been acknowledged yet. If there's no such message,
+returns NULL.
 </p>
 
 <p>
-<code> char *wpactrl_datalen (wpactrl_t *a) </code> <br />
-Returns the length of unsolicited messages from wpa_supplicant
-that have been read by <tt>wpactrl_update()</tt> but haven't been
-acknowledged yet.
-</p>
-
-<p>
-<code> void wpactrl_ackdata (wpactrl_t *a) </code>
-Acknowledges reading the latest batch of unsolicited messages
-from wpa_supplicant: allows the next invocation of
-<tt>wpactrl_update()</tt> to reuse the storage.
+<code> void wpactrl_nextmsg (wpactrl_t *a) </code> <br />
+Acknowledges reading of one unsolicited message from wpa_supplicant.
+The next invocation of <tt>wpactrl_msg()</tt> will point to the next
+one.
 </p>
 
 <p>
diff --git a/package/deps.mak b/package/deps.mak
index e391903..3cda060 100644
--- a/package/deps.mak
+++ b/package/deps.mak
@@ -8,10 +8,13 @@ src/libwpactrl/wpactrl_end.o src/libwpactrl/wpactrl_end.lo: src/libwpactrl/wpact
 src/libwpactrl/wpactrl_fd_recv.o src/libwpactrl/wpactrl_fd_recv.lo: src/libwpactrl/wpactrl_fd_recv.c src/include/bcnm/wpactrl.h src/libwpactrl/wpactrl-internal.h
 src/libwpactrl/wpactrl_fd_timed_recv.o src/libwpactrl/wpactrl_fd_timed_recv.lo: src/libwpactrl/wpactrl_fd_timed_recv.c src/libwpactrl/wpactrl-internal.h
 src/libwpactrl/wpactrl_filter_add.o src/libwpactrl/wpactrl_filter_add.lo: src/libwpactrl/wpactrl_filter_add.c src/include/bcnm/wpactrl.h src/libwpactrl/wpactrl-internal.h
-src/libwpactrl/wpactrl_filter_exact_search.o src/libwpactrl/wpactrl_filter_exact_search.lo: src/libwpactrl/wpactrl_filter_exact_search.c
+src/libwpactrl/wpactrl_filter_exact_search.o src/libwpactrl/wpactrl_filter_exact_search.lo: src/libwpactrl/wpactrl_filter_exact_search.c src/libwpactrl/wpactrl-internal.h
 src/libwpactrl/wpactrl_filter_remove.o src/libwpactrl/wpactrl_filter_remove.lo: src/libwpactrl/wpactrl_filter_remove.c src/include/bcnm/wpactrl.h src/libwpactrl/wpactrl-internal.h
+src/libwpactrl/wpactrl_msg.o src/libwpactrl/wpactrl_msg.lo: src/libwpactrl/wpactrl_msg.c src/include/bcnm/wpactrl.h
+src/libwpactrl/wpactrl_nextmsg.o src/libwpactrl/wpactrl_nextmsg.lo: src/libwpactrl/wpactrl_nextmsg.c src/include/bcnm/wpactrl.h
 src/libwpactrl/wpactrl_query.o src/libwpactrl/wpactrl_query.lo: src/libwpactrl/wpactrl_query.c src/include/bcnm/wpactrl.h src/libwpactrl/wpactrl-internal.h
 src/libwpactrl/wpactrl_querysa.o src/libwpactrl/wpactrl_querysa.lo: src/libwpactrl/wpactrl_querysa.c src/include/bcnm/wpactrl.h src/libwpactrl/wpactrl-internal.h
+src/libwpactrl/wpactrl_scan_parse.o src/libwpactrl/wpactrl_scan_parse.lo: src/libwpactrl/wpactrl_scan_parse.c src/include/bcnm/wpactrl.h
 src/libwpactrl/wpactrl_start.o src/libwpactrl/wpactrl_start.lo: src/libwpactrl/wpactrl_start.c src/include/bcnm/wpactrl.h src/libwpactrl/wpactrl-internal.h
 src/libwpactrl/wpactrl_update.o src/libwpactrl/wpactrl_update.lo: src/libwpactrl/wpactrl_update.c src/include/bcnm/wpactrl.h src/libwpactrl/wpactrl-internal.h
 src/libwpactrl/wpactrl_zero.o src/libwpactrl/wpactrl_zero.lo: src/libwpactrl/wpactrl_zero.c src/include/bcnm/wpactrl.h
diff --git a/src/include/bcnm/wpactrl.h b/src/include/bcnm/wpactrl.h
index af105c3..df5f2c1 100644
--- a/src/include/bcnm/wpactrl.h
+++ b/src/include/bcnm/wpactrl.h
@@ -5,8 +5,10 @@
 
 #include <sys/types.h>
 #include <stdint.h>
+#include <skalibs/gccattributes.h>
 #include <skalibs/tai.h>
 #include <skalibs/stralloc.h>
+#include <skalibs/genalloc.h>
 
 typedef enum wparesponse_e wparesponse_t, *wparesponse_t_ref ;
 enum wparesponse_e
@@ -36,10 +38,11 @@ struct wpactrl_s
   int fds ;
   int fda ;
   uint32_t options ;
+  size_t datahead ;
   stralloc data ;
   stralloc filters ;
 } ;
-#define WPACTRL_ZERO { .fds = -1, .fda = -1, .options = 0, .data = STRALLOC_ZERO, .filters = STRALLOC_ZERO }
+#define WPACTRL_ZERO { .fds = -1, .fda = -1, .options = 0, .datahead = 0, .data = STRALLOC_ZERO, .filters = STRALLOC_ZERO }
 
 #define WPACTRL_OPTION_NOFILTER 0x0001U
 
@@ -63,9 +66,25 @@ extern void wpactrl_filter_remove (wpactrl_t *, char const *) ;
 #define wpactrl_filter_deactivate(a) ((a)->options |= WPACTRL_OPTION_NOFILTER)
 
 extern int wpactrl_update (wpactrl_t *) ;
-#define wpactrl_data(a) ((a)->data.s)
-#define wpactrl_datalen(a) ((a)->data.len))
-#define wpactrl_ackdata(a) ((a)->data.len = 0)
+extern char *wpactrl_msg (wpactrl_t *) gccattr_pure ;
+extern void wpactrl_ackmsg (wpactrl_t *) ;
+
+
+ /* High-level functions */
+
+typedef struct wpactrl_scanres_s wpactrl_scanres_t, *wpactrl_scanres_t_ref ;
+struct wpactrl_scanres_s
+{
+  char bssid[6] ;
+  uint16_t frequency ;
+  uint16_t signal_level ;
+  uint32_t flags ;
+  size_t ssid ;
+} ;
+#define WPACTRL_SCANRES_ZERO { .bssid = "\0\0\0\0\0", .frequency = 0, .signal_level = 0, .flags = 0, .ssid = 0 }
+
+extern int wpactrl_scan_parse (char const *, size_t, genalloc * /* wpactrl_scanres_t */, stralloc *) ;
+
 
 
  /*
diff --git a/src/libwpactrl/wpactrl-internal.h b/src/libwpactrl/wpactrl-internal.h
index b271eae..ddd2597 100644
--- a/src/libwpactrl/wpactrl-internal.h
+++ b/src/libwpactrl/wpactrl-internal.h
@@ -8,7 +8,7 @@
 #include <skalibs/tai.h>
 #include <bcnm/wpactrl.h>
 
-#define WPACTRL_PACKET_MAX 8192
+#define WPACTRL_PACKET_MAX 8191
 #define WPACTRL_RECV_MAX 32
 
 extern ssize_t wpactrl_fd_recv (int, char *, size_t) ;
diff --git a/src/libwpactrl/wpactrl_msg.c b/src/libwpactrl/wpactrl_msg.c
new file mode 100644
index 0000000..b452c4b
--- /dev/null
+++ b/src/libwpactrl/wpactrl_msg.c
@@ -0,0 +1,8 @@
+/* ISC license. */
+
+#include <bcnm/wpactrl.h>
+
+char *wpactrl_msg (wpactrl_t *a)
+{
+  return a->datahead < a->data.len ? a->data.s + a->datahead : 0 ;
+}
diff --git a/src/libwpactrl/wpactrl_nextmsg.c b/src/libwpactrl/wpactrl_nextmsg.c
new file mode 100644
index 0000000..4954db9
--- /dev/null
+++ b/src/libwpactrl/wpactrl_nextmsg.c
@@ -0,0 +1,14 @@
+/* ISC license. */
+
+#include <string.h>
+#include <bcnm/wpactrl.h>
+
+void wpactrl_nextmsg (wpactrl_t *a)
+{
+  if (a->datahead < a->data.len) a->datahead += strlen(a->data.s + a->datahead) + 1 ;
+  if (a->datahead >= a->data.len)
+  {
+    a->data.len = 0 ;
+    a->datahead = 0 ;
+  }
+}
diff --git a/src/libwpactrl/wpactrl_scan_parse.c b/src/libwpactrl/wpactrl_scan_parse.c
new file mode 100644
index 0000000..24f83c8
--- /dev/null
+++ b/src/libwpactrl/wpactrl_scan_parse.c
@@ -0,0 +1,79 @@
+/* ISC license. */
+
+#include <string.h>
+#include <stdint.h>
+#include <errno.h>
+#include <skalibs/uint16.h>
+#include <skalibs/bytestr.h>
+#include <skalibs/error.h>
+#include <skalibs/fmtscan.h>
+#include <skalibs/stralloc.h>
+#include <skalibs/genalloc.h>
+#include <bcnm/wpactrl.h>
+
+static size_t bssid_scan (char const *s, char *bssid)
+{
+  unsigned int i = 0 ;
+  char sep[6] = ":::::\t" ;
+  for (; i < 6 ; i++)
+  {
+    if (!ucharn_scan(s, bssid + i, 1)) return 0 ;
+    if (s[2] != sep[i]) return 0 ;
+    s += 3 ;
+  }
+  return 18 ;
+}
+
+static size_t flags_scan (char const *s, uint32_t *flags)
+{
+  return 0 ;
+}
+
+static int wpactrl_scan_parse_one (char const *s, size_t len, wpactrl_scanres_t *thing, stralloc *sa)
+{
+  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 ;
+  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 ;
+  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 ;
+  s += pos + 1 ; len -= pos + 1 ;
+  thing->ssid = sa->len ;
+  return stralloc_catb(sa, s, len - 1) && stralloc_0(sa) ;
+}
+
+int wpactrl_scan_parse (char const *s, size_t len, genalloc *ga, stralloc *sa)
+{
+  int sawasnull = !sa->s ;
+  int gawasnull = !genalloc_s(wpactrl_scanres_t, ga) ;
+  size_t sabase = sa->len ;
+  size_t gabase = genalloc_len(wpactrl_scanres_t, ga) ;
+  size_t start = byte_chr(s, len, '\n') ;
+  if (start++ >= len) return (errno = EPROTO, 0) ;
+  while (start < len)
+  {
+    size_t pos = byte_chr(s + start, len - start, '\n') ;
+    wpactrl_scanres_t thing ;
+    if (!wpactrl_scan_parse_one(s + start, pos, &thing, sa)) goto err ;
+    if (!genalloc_append(wpactrl_scanres_t, ga, &thing)) goto err ;
+    start += pos + 1 ;
+  }
+  return 1 ;
+
+ err:
+  {
+    int e = errno ;
+    if (gawasnull) genalloc_free(wpactrl_scanres_t, ga) ;
+    else genalloc_setlen(wpactrl_scanres_t, ga, gabase) ;
+    if (sawasnull) stralloc_free(sa) ;
+    else sa->len = sabase ;
+    errno = e ;
+  }
+  return 0 ;
+}
diff --git a/src/libwpactrl/wpactrl_update.c b/src/libwpactrl/wpactrl_update.c
index edbdc6f..0462cbe 100644
--- a/src/libwpactrl/wpactrl_update.c
+++ b/src/libwpactrl/wpactrl_update.c
@@ -1,6 +1,8 @@
 /* ISC license. */
 
 #include <string.h>
+#include <errno.h>
+#include <skalibs/error.h>
 #include <skalibs/allreadwrite.h>
 #include <skalibs/stralloc.h>
 #include <bcnm/wpactrl.h>
@@ -24,6 +26,7 @@ static inline int validate (char const *s, size_t len)
   if (s[0] != '<') return 0 ;
   if (!memchr("123456789", s[1], 9)) return 0 ;
   if (s[2] != '>') return 0 ;
+  if (strnlen(s, len) < len) return 0 ;
   return s[len-1] == '\n' ;
 }
 
@@ -31,7 +34,7 @@ int wpactrl_update (wpactrl_t *a)
 {
   unsigned int n = WPACTRL_RECV_MAX ;
   unsigned int count = 0 ;
-  char buf[WPACTRL_PACKET_MAX] ;
+  char buf[WPACTRL_PACKET_MAX+1] ;
   while (n--)
   {
     ssize_t r = sanitize_read(wpactrl_fd_recv(a->fda, buf, WPACTRL_PACKET_MAX)) ;
@@ -40,7 +43,8 @@ int wpactrl_update (wpactrl_t *a)
     if (a->options & WPACTRL_OPTION_NOFILTER
      || (validate(buf, r) && filter_search(buf, r, a->filters.s, a->filters.len)))
     {
-      if (!stralloc_catb(&a->data, buf, r)) return -1 ;
+      buf[r] = 0 ;
+      if (!stralloc_catb(&a->data, buf, r+1)) return -1 ;
       count++ ;
     }
   }