utils: add simple ubus query support
Some wireless runtime parameters are not available via nl80211, e.g. the effective Mesh ID so we need to fetch those from ubus state info. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
This commit is contained in:
parent
44956b780d
commit
d991fe5481
3 changed files with 98 additions and 1 deletions
2
Makefile
2
Makefile
|
@ -1,6 +1,6 @@
|
||||||
IWINFO_BACKENDS = $(BACKENDS)
|
IWINFO_BACKENDS = $(BACKENDS)
|
||||||
IWINFO_CFLAGS = $(CFLAGS) -std=gnu99 -fstrict-aliasing -Iinclude
|
IWINFO_CFLAGS = $(CFLAGS) -std=gnu99 -fstrict-aliasing -Iinclude
|
||||||
IWINFO_LDFLAGS = -luci -lubox
|
IWINFO_LDFLAGS = -luci -lubox -lubus
|
||||||
|
|
||||||
IWINFO_LIB = libiwinfo.so
|
IWINFO_LIB = libiwinfo.so
|
||||||
IWINFO_LIB_LDFLAGS = $(LDFLAGS) -shared
|
IWINFO_LIB_LDFLAGS = $(LDFLAGS) -shared
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <uci.h>
|
#include <uci.h>
|
||||||
|
#include <libubus.h>
|
||||||
|
|
||||||
#include "iwinfo.h"
|
#include "iwinfo.h"
|
||||||
|
|
||||||
|
@ -58,4 +59,7 @@ void iwinfo_parse_rsn(struct iwinfo_crypto_entry *c, uint8_t *data, uint8_t len,
|
||||||
struct uci_section *iwinfo_uci_get_radio(const char *name, const char *type);
|
struct uci_section *iwinfo_uci_get_radio(const char *name, const char *type);
|
||||||
void iwinfo_uci_free(void);
|
void iwinfo_uci_free(void);
|
||||||
|
|
||||||
|
int iwinfo_ubus_query(const char *ifname, const char *field,
|
||||||
|
char *buf, size_t len);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -404,3 +404,96 @@ void iwinfo_uci_free(void)
|
||||||
uci_free_context(uci_ctx);
|
uci_free_context(uci_ctx);
|
||||||
uci_ctx = NULL;
|
uci_ctx = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct iwinfo_ubus_query_state {
|
||||||
|
const char *ifname;
|
||||||
|
const char *field;
|
||||||
|
size_t len;
|
||||||
|
char *buf;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void iwinfo_ubus_query_cb(struct ubus_request *req, int type,
|
||||||
|
struct blob_attr *msg)
|
||||||
|
{
|
||||||
|
struct iwinfo_ubus_query_state *st = req->priv;
|
||||||
|
|
||||||
|
struct blobmsg_policy pol1[2] = {
|
||||||
|
{ "ifname", BLOBMSG_TYPE_STRING },
|
||||||
|
{ "config", BLOBMSG_TYPE_TABLE }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct blobmsg_policy pol2 = { st->field, BLOBMSG_TYPE_STRING };
|
||||||
|
struct blob_attr *cur, *cur2, *cur3, *cfg[2], *res;
|
||||||
|
int rem, rem2, rem3;
|
||||||
|
|
||||||
|
blobmsg_for_each_attr(cur, msg, rem) {
|
||||||
|
if (blobmsg_type(cur) != BLOBMSG_TYPE_TABLE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
blobmsg_for_each_attr(cur2, cur, rem2) {
|
||||||
|
if (blobmsg_type(cur2) != BLOBMSG_TYPE_ARRAY)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (strcmp(blobmsg_name(cur2), "interfaces"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
blobmsg_for_each_attr(cur3, cur2, rem3) {
|
||||||
|
blobmsg_parse(pol1, sizeof(pol1) / sizeof(pol1[0]), cfg,
|
||||||
|
blobmsg_data(cur3), blobmsg_len(cur3));
|
||||||
|
|
||||||
|
if (!cfg[0] || !cfg[1] ||
|
||||||
|
strcmp(blobmsg_get_string(cfg[0]), st->ifname))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
blobmsg_parse(&pol2, 1, &res,
|
||||||
|
blobmsg_data(cfg[1]), blobmsg_len(cfg[1]));
|
||||||
|
|
||||||
|
if (!res)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
strncpy(st->buf, blobmsg_get_string(res), st->len);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int iwinfo_ubus_query(const char *ifname, const char *field,
|
||||||
|
char *buf, size_t len)
|
||||||
|
{
|
||||||
|
struct iwinfo_ubus_query_state st = {
|
||||||
|
.ifname = ifname,
|
||||||
|
.field = field,
|
||||||
|
.buf = buf,
|
||||||
|
.len = len
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ubus_context *ctx = NULL;
|
||||||
|
struct blob_buf b = { };
|
||||||
|
int rv = -1;
|
||||||
|
uint32_t id;
|
||||||
|
|
||||||
|
blob_buf_init(&b, 0);
|
||||||
|
|
||||||
|
ctx = ubus_connect(NULL);
|
||||||
|
|
||||||
|
if (!ctx)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (ubus_lookup_id(ctx, "network.wireless", &id))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (ubus_invoke(ctx, id, "status", b.head, iwinfo_ubus_query_cb, &st, 250))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
rv = 0;
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (ctx)
|
||||||
|
ubus_free(ctx);
|
||||||
|
|
||||||
|
blob_buf_free(&b);
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue