forked from external/yambar
module/network: Add link stats
Exports two new tags from network module, `ul-speed` and `dl-speed`. Because these work through polling, poll-interval must be set. Otherwise, these two tags always will be 0.
This commit is contained in:
parent
eb5cb9869c
commit
03e1c7dc13
4 changed files with 81 additions and 4 deletions
|
@ -22,6 +22,8 @@
|
||||||
* river: support for the new “mode” event present in version 3 of the
|
* river: support for the new “mode” event present in version 3 of the
|
||||||
river status manager protocol, in the form of a new tag, _”mode”_,
|
river status manager protocol, in the form of a new tag, _”mode”_,
|
||||||
in the `title` particle.
|
in the `title` particle.
|
||||||
|
* network: request link stats and expose under tags `dl-speed` and
|
||||||
|
`ul-speed` when `poll-interval` is set.
|
||||||
|
|
||||||
|
|
||||||
[153]: https://codeberg.org/dnkl/yambar/issues/153
|
[153]: https://codeberg.org/dnkl/yambar/issues/153
|
||||||
|
|
|
@ -51,6 +51,12 @@ address.
|
||||||
| tx-bitrate
|
| tx-bitrate
|
||||||
: int
|
: int
|
||||||
: TX bitrate in bits/s
|
: TX bitrate in bits/s
|
||||||
|
| dl-speed
|
||||||
|
: int
|
||||||
|
: Download speed in bits/s
|
||||||
|
| ul-speed
|
||||||
|
: int
|
||||||
|
: Upload speed in bits/s
|
||||||
|
|
||||||
|
|
||||||
# CONFIGURATION
|
# CONFIGURATION
|
||||||
|
@ -66,7 +72,8 @@ address.
|
||||||
| poll-interval
|
| poll-interval
|
||||||
: int
|
: int
|
||||||
: no
|
: no
|
||||||
: Periodically (in seconds) update the signal and rx+tx bitrate tags.
|
: Periodically (in seconds) update the signal, rx+tx bitrate, and
|
||||||
|
ul+dl speed tags.
|
||||||
|
|
||||||
|
|
||||||
# EXAMPLES
|
# EXAMPLES
|
||||||
|
|
|
@ -185,6 +185,7 @@ bar:
|
||||||
ipv4 == "": {string: {text: , font: *awesome, foreground: ffffff66}}
|
ipv4 == "": {string: {text: , font: *awesome, foreground: ffffff66}}
|
||||||
- network:
|
- network:
|
||||||
name: wlp2s0
|
name: wlp2s0
|
||||||
|
poll-interval: 1
|
||||||
content:
|
content:
|
||||||
map:
|
map:
|
||||||
default: {string: {text: , font: *awesome, foreground: ffffff66}}
|
default: {string: {text: , font: *awesome, foreground: ffffff66}}
|
||||||
|
@ -194,11 +195,12 @@ bar:
|
||||||
map:
|
map:
|
||||||
default:
|
default:
|
||||||
- string: {text: , font: *awesome}
|
- string: {text: , font: *awesome}
|
||||||
- string: {text: "{ssid}"}
|
- string: {text: "{ssid} {dl-speed:mb}/{ul-speed:mb} Mb/s"}
|
||||||
|
|
||||||
conditions:
|
conditions:
|
||||||
ipv4 == "":
|
ipv4 == "":
|
||||||
- string: {text: , font: *awesome, foreground: ffffff66}
|
- string: {text: , font: *awesome, foreground: ffffff66}
|
||||||
- string: {text: "{ssid}", foreground: ffffff66}
|
- string: {text: "{ssid} {dl-speed:mb}/{ul-speed:mb} Mb/s", foreground: ffffff66}
|
||||||
- alsa:
|
- alsa:
|
||||||
card: hw:PCH
|
card: hw:PCH
|
||||||
mixer: Master
|
mixer: Master
|
||||||
|
|
|
@ -31,6 +31,11 @@
|
||||||
|
|
||||||
#define UNUSED __attribute__((unused))
|
#define UNUSED __attribute__((unused))
|
||||||
|
|
||||||
|
struct rt_stats_msg {
|
||||||
|
struct rtmsg rth;
|
||||||
|
struct rtnl_link_stats64 stats;
|
||||||
|
};
|
||||||
|
|
||||||
struct af_addr {
|
struct af_addr {
|
||||||
int family;
|
int family;
|
||||||
union {
|
union {
|
||||||
|
@ -68,6 +73,12 @@ struct private {
|
||||||
int signal_strength_dbm;
|
int signal_strength_dbm;
|
||||||
uint32_t rx_bitrate;
|
uint32_t rx_bitrate;
|
||||||
uint32_t tx_bitrate;
|
uint32_t tx_bitrate;
|
||||||
|
|
||||||
|
uint64_t ul_speed;
|
||||||
|
uint64_t ul_bits;
|
||||||
|
|
||||||
|
uint64_t dl_speed;
|
||||||
|
uint64_t dl_bits;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -145,8 +156,10 @@ content(struct module *mod)
|
||||||
tag_new_int(mod, "signal", m->signal_strength_dbm),
|
tag_new_int(mod, "signal", m->signal_strength_dbm),
|
||||||
tag_new_int(mod, "rx-bitrate", m->rx_bitrate),
|
tag_new_int(mod, "rx-bitrate", m->rx_bitrate),
|
||||||
tag_new_int(mod, "tx-bitrate", m->tx_bitrate),
|
tag_new_int(mod, "tx-bitrate", m->tx_bitrate),
|
||||||
|
tag_new_float(mod, "dl-speed", m->dl_speed),
|
||||||
|
tag_new_float(mod, "ul-speed", m->ul_speed),
|
||||||
},
|
},
|
||||||
.count = 11,
|
.count = 13,
|
||||||
};
|
};
|
||||||
|
|
||||||
mtx_unlock(&mod->lock);
|
mtx_unlock(&mod->lock);
|
||||||
|
@ -252,6 +265,36 @@ send_rt_request(struct private *m, int request)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
send_rt_getstats_request(struct private *m)
|
||||||
|
{
|
||||||
|
struct {
|
||||||
|
struct nlmsghdr hdr;
|
||||||
|
struct if_stats_msg rt;
|
||||||
|
} req = {
|
||||||
|
.hdr = {
|
||||||
|
.nlmsg_len = NLMSG_LENGTH(sizeof(req.rt)),
|
||||||
|
.nlmsg_type = RTM_GETSTATS,
|
||||||
|
.nlmsg_flags = NLM_F_REQUEST,
|
||||||
|
.nlmsg_seq = 1,
|
||||||
|
.nlmsg_pid = nl_pid_value(),
|
||||||
|
},
|
||||||
|
|
||||||
|
.rt = {
|
||||||
|
.ifindex = m->ifindex,
|
||||||
|
.filter_mask = IFLA_STATS_LINK_64,
|
||||||
|
.family = AF_UNSPEC,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!send_nlmsg(m->rt_sock, &req, req.hdr.nlmsg_len)) {
|
||||||
|
LOG_ERRNO("%s: failed to send netlink RT getstats request (%d)",
|
||||||
|
m->iface, RTM_GETSTATS);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
send_ctrl_get_family_request(struct private *m)
|
send_ctrl_get_family_request(struct private *m)
|
||||||
{
|
{
|
||||||
|
@ -929,6 +972,23 @@ netlink_receive_messages(int sock, void **reply, size_t *len)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_stats(struct module *mod, struct rt_stats_msg *msg)
|
||||||
|
{
|
||||||
|
struct private *m = mod->private;
|
||||||
|
uint64_t ul_bits = msg->stats.tx_bytes*8;
|
||||||
|
uint64_t dl_bits = msg->stats.rx_bytes*8;
|
||||||
|
|
||||||
|
if (m->ul_bits != 0) {
|
||||||
|
m->ul_speed = (ul_bits - m->ul_bits) / m->poll_interval;
|
||||||
|
}
|
||||||
|
if (m->dl_bits != 0) {
|
||||||
|
m->dl_speed = (dl_bits - m->dl_bits) / m->poll_interval;
|
||||||
|
}
|
||||||
|
m->ul_bits = ul_bits;
|
||||||
|
m->dl_bits = dl_bits;
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
parse_rt_reply(struct module *mod, const struct nlmsghdr *hdr, size_t len)
|
parse_rt_reply(struct module *mod, const struct nlmsghdr *hdr, size_t len)
|
||||||
{
|
{
|
||||||
|
@ -967,6 +1027,11 @@ parse_rt_reply(struct module *mod, const struct nlmsghdr *hdr, size_t len)
|
||||||
handle_address(mod, hdr->nlmsg_type, msg, msg_len);
|
handle_address(mod, hdr->nlmsg_type, msg, msg_len);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case RTM_NEWSTATS: {
|
||||||
|
struct rt_stats_msg *msg = NLMSG_DATA(hdr);
|
||||||
|
handle_stats(mod, msg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case NLMSG_ERROR:{
|
case NLMSG_ERROR:{
|
||||||
const struct nlmsgerr *err = NLMSG_DATA(hdr);
|
const struct nlmsgerr *err = NLMSG_DATA(hdr);
|
||||||
|
@ -1200,6 +1265,7 @@ run(struct module *mod)
|
||||||
}
|
}
|
||||||
|
|
||||||
send_nl80211_get_station(m);
|
send_nl80211_get_station(m);
|
||||||
|
send_rt_getstats_request(m);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue