orin-status: publish net_wifi_ssid from iw while WiFi is up, re-read every 10 s
/ crosscheck (push) Successful in 1s
/ crosscheck (push) Successful in 1s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DDwfd6Ki8UfG4hK6W5YpJz
This commit is contained in:
+25
-2
@@ -1,6 +1,7 @@
|
||||
//! Network links: WiFi, LTE and the USB link to the tablet. Up/down and rates
|
||||
//! from sysfs counters; WiFi signal from /proc/net/wireless; the modem's own view
|
||||
//! from ModemManager, polled on a thread because `mmcli` can take seconds.
|
||||
//! from sysfs counters; WiFi signal from /proc/net/wireless, its SSID from `iw`;
|
||||
//! the modem's own view from ModemManager, polled on a thread because `mmcli` can
|
||||
//! take seconds.
|
||||
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
@@ -52,6 +53,18 @@ fn wifi_dbm(iface: &str) -> Option<f64> {
|
||||
line.split_whitespace().nth(3)?.trim_end_matches('.').parse().ok()
|
||||
}
|
||||
|
||||
/// SSID of the associated network, from `iw dev <iface> link` ("\tSSID: name"); None when
|
||||
/// not associated. iw prints non-printable bytes as \xNN escapes, which are kept as they are.
|
||||
fn wifi_ssid(iface: &str) -> Option<String> {
|
||||
let out = Command::new("iw").args(["dev", iface, "link"]).output().ok()?;
|
||||
let text = String::from_utf8_lossy(&out.stdout);
|
||||
let ssid = text.lines().find_map(|l| l.trim_start().strip_prefix("SSID: "))?;
|
||||
Some(ssid.to_string())
|
||||
}
|
||||
|
||||
/// How often the SSID is re-read while WiFi stays up; a change of network without a drop is rare.
|
||||
const SSID_EVERY: Duration = Duration::from_secs(10);
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
struct Modem {
|
||||
state: String,
|
||||
@@ -80,6 +93,7 @@ fn poll_modem() -> Modem {
|
||||
pub struct Net {
|
||||
wifi: Option<String>,
|
||||
wifi_rate: Rate,
|
||||
ssid: Option<(Instant, Option<String>)>,
|
||||
lte_rate: Rate,
|
||||
tablet_rate: Rate,
|
||||
modem: Arc<Mutex<Option<Modem>>>,
|
||||
@@ -97,6 +111,7 @@ impl Net {
|
||||
Net {
|
||||
wifi: wifi_iface(),
|
||||
wifi_rate: Rate { prev: None },
|
||||
ssid: None,
|
||||
lte_rate: Rate { prev: None },
|
||||
tablet_rate: Rate { prev: None },
|
||||
modem,
|
||||
@@ -110,6 +125,14 @@ impl Net {
|
||||
if let Some(w) = self.wifi.clone() {
|
||||
let up = attr(&w, "operstate").as_deref() == Some("up");
|
||||
out.push(("net_wifi_up", json!(up)));
|
||||
if !up {
|
||||
self.ssid = None;
|
||||
} else if self.ssid.as_ref().is_none_or(|(at, _)| at.elapsed() >= SSID_EVERY) {
|
||||
self.ssid = Some((Instant::now(), wifi_ssid(&w)));
|
||||
}
|
||||
if let Some((_, Some(ssid))) = &self.ssid {
|
||||
out.push(("net_wifi_ssid", json!(ssid)));
|
||||
}
|
||||
if let Some(dbm) = wifi_dbm(&w).filter(|_| up) {
|
||||
out.push(("net_wifi_signal_dbm", json!(dbm)));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user