commit 8943c1d65247d74a8b5ddc11a887a6811ead4237
parent 7ae4284dc093f01aefa07816dad84ea36b8f72f2
Author: Daniel Barlow <dan@telent.net>
Date: Sun, 3 Apr 2022 12:41:15 +0100
add wlan quality and ssid
Diffstat:
2 files changed, 62 insertions(+), 14 deletions(-)
diff --git a/blinkenlicht/default.nix b/blinkenlicht/default.nix
@@ -20,11 +20,14 @@ let
hash = "sha256:1nha32yilzagfwrs44hc763jgwxd700kaik1is7x7lsjjvkgapw7";
};
+ netlink = lua53Packages.callPackage ./netlink.nix {};
+
lua = lua5_3.withPackages (ps: with ps; [
lgi
luafilesystem
luaposix
readline
+ netlink
]);
in stdenv.mkDerivation {
diff --git a/blinkenlicht/nl.fnl b/blinkenlicht/nl.fnl
@@ -4,19 +4,61 @@
(table.concat (nl.groups) ", ")))
(local nls (nl.socket))
-;; when we have a default route, we get the ifname
-
;; $ grep DEVTYPE /sys/class/net/*/uevent
;; /sys/class/net/docker0/uevent:DEVTYPE=bridge
;; /sys/class/net/wlp4s0/uevent:DEVTYPE=wlan
;; /sys/class/net/wwp0s20f0u2i12/uevent:DEVTYPE=wwan
;; (ethernet and loopback devices don't have DEVTYPE)
+(fn devtype [ifname]
+ (with-open [f (io.open (.. "/sys/class/net/" ifname "/uevent") :r)]
+ (accumulate [dtype nil
+ line #(f:read "*l")
+ :until dtype]
+ (let [(name value) (line:match "([^=]+)=(.+)")]
+ (if (= name "DEVTYPE") value dtype)))))
+
;; if the type is wlan, we can get a signal strength indicator
;; from the "quality - link" column of /proc/net/wireless
-;; for wwan, need to determine how to get strength and carrier name
+(fn wlan-link-quality [ifname]
+ (with-open [f (io.open "/proc/net/wireless" :r)]
+ (accumulate [strength nil
+ line #(f:read "*l")
+ :until strength]
+ ;; "%6s: %04x %3d%c %3d%c %3d%c %6d %6d %6d "
+ ;; "%6d %6d %6d\n",
+ ;; https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/net/wireless/wext-proc.c#n49
+
+ (let [(name status link level)
+ (line:match "(.-): +(%x+) +(%S-)[ .] +(%S-)[ .]")]
+ (if (= name ifname)
+ (tonumber level)
+ strength)))))
+
+(fn wlan-link-ssid [ifname]
+ ;; could do this directly using an ioctl
+ ;; http://papermint-designs.com/dmo-blog/2016-08-how-to-get-the-essid-of-the-wifi-network-you-are-connected-to-#
+ (with-open [f (io.popen (.. "iwgetid " ifname " --raw") :r)]
+ (f:read "*l")))
+
+(fn get-network-info [event]
+ ;; augments a newlink event with relevant information, if it's
+ ;; sufficiently well-configured to have any
+ ;; "up" => administratively up
+ ;; "running" => can actually exchange packets
+ (when (= event.running "yes")
+ (let [dtype (devtype event.name)]
+ (tset event :devtype dtype)
+ (when (= dtype "wlan")
+ (if (not event.ssid)
+ (tset event :ssid (wlan-link-ssid event.name)))
+ (tset event :quality (wlan-link-quality event.name)))
+ (when (= dtype "wwan")
+ ;; for wwan, need to determine how to get strength and carrier name
+ )))
+ event)
(fn netlunk []
@@ -25,15 +67,13 @@
(fn handle-event [event]
(match event
{:event :newlink}
- (match event.up
- "yes" (tset links event.index event)
- "no" (tset links event.index nil))
+ (tset links event.index
+ (match event.up
+ "yes" (get-network-info event)
+ "no" event))
{:event :newroute}
- (tset routes (or event.dst "default")
- (if (. links event.index)
- event
- nil))
+ (tset routes (or event.dst "default") event)
{} (print :unhandled event.event)
))
@@ -44,7 +84,12 @@
:refresh #(each [_ event (ipairs (nls:event))]
(handle-event event))
:fd (nls:fd)
- :uplink (fn [self] routes.default)
+ :uplink (fn [self]
+ (let [defaultroute routes.default
+ interface (and defaultroute
+ (. links defaultroute.index))]
+ (and interface (= interface.running "yes")
+ (get-network-info interface))))
:wait #(nls:poll 1000)
:interface (fn [self ifnum] (. links ifnum))
}
@@ -54,9 +99,9 @@
(while (or (nl:wait) true)
(nl:refresh)
(match (nl:uplink)
- {:index ifnum}
- (print "default route through " (. (nl:interface ifnum) :name))
- {}
+ interface
+ (print "default route through " (view interface))
+ nil
(print "no default route")
)))