use anyhow::Result;
use clap::Parser;
use libexail::{Message, NavigationBlock, parse_datagram};
use std::net::UdpSocket;
#[derive(Parser)]
#[command(about = "Listen for Exail datagrams on UDP")]
struct Args {
#[arg(default_value_t = 8080)]
port: u16,
#[arg(short, long)]
verbose: bool,
}
fn main() -> Result<()> {
let args = Args::parse();
let addr = format!("0.0.0.0:{}", args.port);
let socket = UdpSocket::bind(&addr)?;
eprintln!("Listening on {addr}...");
let mut buf = [0u8; 65536];
let mut count: usize = 0;
loop {
let (n, src) = socket.recv_from(&mut buf)?;
match parse_datagram(&buf[..n]) {
Ok(msg) => {
count += 1;
if args.verbose {
println!("#{count} [{src}] {msg:?}");
continue;
}
match &msg {
Message::NavigationData(frame) => {
print!("#{count} [{src}] NavigationData:");
for block in &frame.navigation {
match block {
NavigationBlock::Position(p) => {
print!(
" lat={:.6} lon={:.6} alt={:.2}m",
p.latitude, p.longitude, p.altitude,
);
}
NavigationBlock::AttitudeHeading(a) => {
print!(
" hdg={:.1} roll={:.1} pitch={:.1}",
a.heading, a.roll, a.pitch,
);
}
_ => {}
}
}
println!();
}
Message::InputData(_) => println!("#{count} [{src}] InputData"),
Message::Command(_) => println!("#{count} [{src}] Command"),
Message::Answer(_) => println!("#{count} [{src}] Answer"),
}
}
Err(e) => {
eprintln!("[{src}] Parse error: {e:?}");
}
}
}
}