From dabb2e140749cc1f4583541abfe692fc232a2af3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Fri, 27 Aug 2021 15:56:31 +0200 Subject: [PATCH] module/network: add support for periodically polling Wi-Fi stats MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds a new ‘poll-interval’ option to the network module. When set to a non-zero value, the following Wi-Fi stats will be updated: * Signal strength * RX+TX bitrate --- doc/yambar-modules-network.5.scd | 5 ++++ modules/network.c | 50 ++++++++++++++++++++++++++++++-- 2 files changed, 52 insertions(+), 3 deletions(-) diff --git a/doc/yambar-modules-network.5.scd b/doc/yambar-modules-network.5.scd index 27ce739..8ac46a1 100644 --- a/doc/yambar-modules-network.5.scd +++ b/doc/yambar-modules-network.5.scd @@ -63,6 +63,11 @@ address. : string : yes : Name of network interface to monitor +| poll-interval +: int +: no +: Periodically (in seconds) update the signal and rx+tx bitrate tags. + # EXAMPLES diff --git a/modules/network.c b/modules/network.c index 30cd35d..bf32c57 100644 --- a/modules/network.c +++ b/modules/network.c @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -41,6 +42,7 @@ struct af_addr { struct private { char *iface; struct particle *label; + int poll_interval; int genl_sock; int rt_sock; @@ -1097,6 +1099,25 @@ run(struct module *mod) int ret = 1; struct private *m = mod->private; + int timer_fd = -1; + if (m->poll_interval > 0) { + timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC); + if (timer_fd < 0) { + LOG_ERRNO("%s: failed to create poll timer FD", m->iface); + goto out; + } + + struct itimerspec poll_time = { + .it_value = {.tv_sec = m->poll_interval}, + .it_interval = {.tv_sec = m->poll_interval}, + }; + + if (timerfd_settime(timer_fd, 0, &poll_time, NULL) < 0) { + LOG_ERRNO("%s: failed to arm poll timer", m->iface); + goto out; + } + } + m->rt_sock = netlink_connect_rt(); m->genl_sock = netlink_connect_genl(); @@ -1115,9 +1136,10 @@ run(struct module *mod) {.fd = mod->abort_fd, .events = POLLIN}, {.fd = m->rt_sock, .events = POLLIN}, {.fd = m->genl_sock, .events = POLLIN}, + {.fd = timer_fd, .events = POLLIN}, }; - poll(fds, 3, -1); + poll(fds, 3 + (timer_fd >= 0 ? 1 : 0), -1); if (fds[0].revents & (POLLIN | POLLHUP)) break; @@ -1129,6 +1151,11 @@ run(struct module *mod) break; } + if (fds[3].revents & POLLHUP) { + LOG_ERR("%s: disconnected from timer FD", m->iface); + break; + } + if (fds[1].revents & POLLIN) { /* Read one (or more) messages */ void *reply; @@ -1159,6 +1186,17 @@ run(struct module *mod) free(reply); } + + if (fds[3].revents & POLLIN) { + uint64_t count; + ssize_t amount = read(timer_fd, &count, sizeof(count)); + if (amount < 0) { + LOG_ERRNO("failed to read from timer FD"); + break; + } + + send_nl80211_get_station(m); + } } ret = 0; @@ -1168,16 +1206,19 @@ run(struct module *mod) close(m->rt_sock); if (m->genl_sock >= 0) close(m->genl_sock); + if (timer_fd >= 0) + close(timer_fd); m->rt_sock = m->genl_sock = -1; return ret; } static struct module * -network_new(const char *iface, struct particle *label) +network_new(const char *iface, struct particle *label, int poll_interval) { struct private *priv = calloc(1, sizeof(*priv)); priv->iface = strdup(iface); priv->label = label; + priv->poll_interval = poll_interval; priv->genl_sock = -1; priv->rt_sock = -1; @@ -1200,9 +1241,11 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited) { const struct yml_node *name = yml_get_value(node, "name"); const struct yml_node *content = yml_get_value(node, "content"); + const struct yml_node *poll = yml_get_value(node, "poll-interval"); return network_new( - yml_value_as_string(name), conf_to_particle(content, inherited)); + yml_value_as_string(name), conf_to_particle(content, inherited), + poll != NULL ? yml_value_as_int(poll) : 0); } static bool @@ -1210,6 +1253,7 @@ verify_conf(keychain_t *chain, const struct yml_node *node) { static const struct attr_info attrs[] = { {"name", true, &conf_verify_string}, + {"poll-interval", false, &conf_verify_int}, MODULE_COMMON_ATTRS, };