From 8be372a590151b6d4f4dc7f37571e8acf5bf9944 Mon Sep 17 00:00:00 2001 From: Nils Schneider Date: Wed, 2 Sep 2015 16:22:12 +0200 Subject: [PATCH] gluon-status-page-api: rewrite stations in C --- package/gluon-status-page-api/Makefile | 1 + .../status-page/www/cgi-bin/dyn/stations | 52 ----------- package/gluon-status-page-api/src/Makefile | 7 +- package/gluon-status-page-api/src/stations.c | 88 +++++++++++++++++++ 4 files changed, 95 insertions(+), 53 deletions(-) delete mode 100755 package/gluon-status-page-api/files/lib/gluon/status-page/www/cgi-bin/dyn/stations create mode 100755 package/gluon-status-page-api/src/stations.c diff --git a/package/gluon-status-page-api/Makefile b/package/gluon-status-page-api/Makefile index 863bbc39..91a7095a 100644 --- a/package/gluon-status-page-api/Makefile +++ b/package/gluon-status-page-api/Makefile @@ -23,6 +23,7 @@ endef define Package/gluon-status-page-api/install $(INSTALL_DIR) $(1)/lib/gluon/status-page/www/cgi-bin/dyn $(INSTALL_BIN) $(PKG_BUILD_DIR)/neighbours-batadv $(1)/lib/gluon/status-page/www/cgi-bin/dyn/ + $(INSTALL_BIN) $(PKG_BUILD_DIR)/stations $(1)/lib/gluon/status-page/www/cgi-bin/dyn/ $(CP) ./files/* $(1)/ endef diff --git a/package/gluon-status-page-api/files/lib/gluon/status-page/www/cgi-bin/dyn/stations b/package/gluon-status-page-api/files/lib/gluon/status-page/www/cgi-bin/dyn/stations deleted file mode 100755 index 637de649..00000000 --- a/package/gluon-status-page-api/files/lib/gluon/status-page/www/cgi-bin/dyn/stations +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/lua - -util = require 'luci.util' -json = require 'luci.jsonc' -nixio = require 'nixio' -iwinfo = require 'iwinfo' - -function badrequest() - io.write("Status: 400 Bad Request\n\n") - os.exit(1) -end - -function get_stations(iw, ifname) - local stations = {} - - for k, v in pairs(iw.assoclist(ifname)) do - stations[k:lower()] = {signal = v.signal, noise = v.noise, inactive = v.inactive} - end - - return stations -end - -local ifname = os.getenv("QUERY_STRING") - -if ifname == nil then badrequest() end - -local list = util.exec('batctl if') -local found = false -for _, line in ipairs(util.split(list)) do - if ifname == line:match('^(.-):') then - found = true - break - end -end - -if found == false then badrequest() end - -local wifitype = iwinfo.type(ifname) - -if wifitype == nil then badrequest() end - -local iw = iwinfo[wifitype] - -io.write("Access-Control-Allow-Origin: *\n") -io.write("Content-type: text/event-stream\n\n") - -while true do - local stations = json.stringify(get_stations(iw, ifname)) - io.write("data: " .. stations .. "\n\n") - io.flush() - nixio.nanosleep(0, 150e6) -end diff --git a/package/gluon-status-page-api/src/Makefile b/package/gluon-status-page-api/src/Makefile index 499bb55b..f0bee975 100644 --- a/package/gluon-status-page-api/src/Makefile +++ b/package/gluon-status-page-api/src/Makefile @@ -1,7 +1,12 @@ +CFLAGS += -std=c99 -D_BSD_SOURCE + CFLAGS += $(shell pkg-config --cflags json-c) LDFLAGS += $(shell pkg-config --libs json-c) -all: neighbours-batadv +all: neighbours-batadv stations neighbours-batadv: neighbours-batadv.c $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -Wall -o $@ $^ $(LDLIBS) + +stations: stations.c + $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -Wall -o $@ $^ $(LDLIBS) -liwinfo diff --git a/package/gluon-status-page-api/src/stations.c b/package/gluon-status-page-api/src/stations.c new file mode 100755 index 00000000..9cae3680 --- /dev/null +++ b/package/gluon-status-page-api/src/stations.c @@ -0,0 +1,88 @@ +#include +#include +#include +#include +#include +#include +#include + +#define STR(x) #x +#define XSTR(x) STR(x) + +#define BATIF_PREFIX "/sys/class/net/bat0/lower_" + +static struct json_object *get_stations(const struct iwinfo_ops *iw, const char *ifname) { + int len; + char buf[IWINFO_BUFSIZE]; + struct json_object *stations = json_object_new_object(); + + if (iw->assoclist(ifname, buf, &len) == -1) + return stations; + + // This is just: for entry in assoclist(ifname) + for (struct iwinfo_assoclist_entry *entry = (struct iwinfo_assoclist_entry *)buf; + (char*)(entry+1) <= buf + len; entry++) { + struct json_object *station = json_object_new_object(); + + json_object_object_add(station, "signal", json_object_new_int(entry->signal)); + json_object_object_add(station, "noise", json_object_new_int(entry->noise)); + json_object_object_add(station, "inactive", json_object_new_int(entry->inactive)); + + char macstr[18]; + + snprintf(macstr, sizeof(macstr), "%02x:%02x:%02x:%02x:%02x:%02x", + entry->mac[0], entry->mac[1], entry->mac[2], + entry->mac[3], entry->mac[4], entry->mac[5]); + + json_object_object_add(stations, macstr, station); + } + + return stations; +} + +static void badrequest() { + printf("Status: 400 Bad Request\n\n"); + exit(1); +} + +bool interface_is_valid(const char *ifname) { + if (strlen(ifname) > IF_NAMESIZE) + return false; + + if (strchr(ifname, '/') != NULL) + return false; + + char *path = alloca(1 + strlen(BATIF_PREFIX) + strlen(ifname)); + sprintf(path, "%s%s", BATIF_PREFIX, ifname); + + return access(path, F_OK) == 0; +} + +int main(void) { + char *ifname = getenv("QUERY_STRING"); + + if (ifname == NULL) + badrequest(); + + if (!interface_is_valid(ifname)) + badrequest(); + + const struct iwinfo_ops *iw = iwinfo_backend(ifname); + + if (iw == NULL) + badrequest(); + + printf("Access-Control-Allow-Origin: *\n"); + printf("Content-type: text/event-stream\n\n"); + + while (true) { + struct json_object *obj; + obj = get_stations(iw, ifname); + printf("data: %s\n\n", json_object_to_json_string_ext(obj, JSON_C_TO_STRING_PLAIN)); + fflush(stdout); + json_object_put(obj); + usleep(150000); + } + + return 0; +}