use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, OnceLock};
use std::time::Duration;
use mx_remote::{BayUid, Config, DeviceUid, EventHandler, Remote};
static CLIENT: OnceLock<Arc<Remote>> = OnceLock::new();
struct Printer;
impl EventHandler for Printer {
fn on_device_update(&self, device: DeviceUid) {
let Some(remote) = CLIENT.get() else { return };
let Some(info) = remote.device(device) else {
return;
};
println!(
" {device} {:<16} {:<12} {:<16} protocol {:#04x}, {} bays{}",
info.model,
info.serial,
info.name,
info.supported_protocol,
info.bays.len(),
if info.online { "" } else { " (offline)" },
);
}
fn on_bay_update(&self, bay: BayUid) {
let Some(remote) = CLIENT.get() else { return };
let Some(info) = remote.bay(bay) else { return };
println!(
" bay {} {:<16} {}",
bay.port,
info.user_name,
match info.signal_detected {
Some(true) => "signal",
_ => "no signal",
},
);
}
}
fn main() -> std::io::Result<()> {
let mut config = Config::default();
config.name = Some("discover".to_owned());
if let Some(address) = std::env::args().nth(1) {
config.local_ip = Some(address.parse().map_err(|_| {
std::io::Error::new(std::io::ErrorKind::InvalidInput, "not an IPv4 address")
})?);
}
let remote = Arc::new(Remote::new(config, Arc::new(Printer))?);
let _ = CLIENT.set(Arc::clone(&remote));
remote.start()?;
if let Some(target) = remote.target() {
println!("listening, sending to {target}. Ctrl-C to stop.");
}
let running = Arc::new(AtomicBool::new(true));
let stop = Arc::clone(&running);
ctrl_c(move || stop.store(false, Ordering::Relaxed));
while running.load(Ordering::Relaxed) {
std::thread::sleep(Duration::from_millis(200));
}
let devices = remote.devices();
println!("\n{} device(s):", devices.len());
for device in devices {
Printer.on_device_update(device);
}
remote.close();
Ok(())
}
fn ctrl_c(f: impl FnOnce() + Send + 'static) {
static HANDLER: OnceLock<()> = OnceLock::new();
let _ = HANDLER.set(());
std::thread::spawn(move || {
let mut line = String::new();
let _ = std::io::stdin().read_line(&mut line);
f();
});
}