diff --git a/fsrc-core/src/hal/host/mod.rs b/fsrc-core/src/hal/host/mod.rs index d9e7799..8057db1 100644 --- a/fsrc-core/src/hal/host/mod.rs +++ b/fsrc-core/src/hal/host/mod.rs @@ -1 +1,2 @@ +//! Helper modules intended to be used on hosts with a full [std] runtime pub mod udp_server; diff --git a/fsrc-core/src/hal/host/udp_server.rs b/fsrc-core/src/hal/host/udp_server.rs index 1414901..e880b5f 100644 --- a/fsrc-core/src/hal/host/udp_server.rs +++ b/fsrc-core/src/hal/host/udp_server.rs @@ -1,10 +1,25 @@ +//! UDP server helper components use crate::tmtc::ReceivesTc; use std::boxed::Box; -use std::io::ErrorKind; +use std::io::{Error, ErrorKind}; use std::net::{SocketAddr, ToSocketAddrs, UdpSocket}; use std::vec; use std::vec::Vec; +/// This TC server helper can be used to receive raw PUS telecommands thorough a UDP interface. +/// +/// It caches all received telecomands into a vector. The maximum expected telecommand size should +/// be declared upfront. This avoids dynamic allocation during run-time. The user can specify a TC +/// receiver in form of a special trait object which implements [ReceivesTc]. Please note that the +/// receiver should copy out the received data if it the data is required past the +/// [ReceivesTc::pass_tc] call. +/// +/// # Examples +/// +/// The [fsrc-example crate](https://egit.irs.uni-stuttgart.de/rust/fsrc-launchpad/src/branch/obsw-client-example/fsrc-example) server code includes +/// [example code](https://egit.irs.uni-stuttgart.de/rust/fsrc-launchpad/src/branch/obsw-client-example/fsrc-example/src/bin/obsw/tmtc.rs) +/// on how to use this TC server. It uses the server to receive PUS telecommands on a specific port +/// and then forwards them to a generic CCSDS packet receiver. pub struct UdpTcServer { pub socket: UdpSocket, recv_buf: Vec, @@ -15,26 +30,29 @@ pub struct UdpTcServer { #[derive(Debug)] pub enum ReceiveResult { WouldBlock, - OtherIoError(std::io::Error), + IoError(Error), ReceiverError(E), } +impl From for ReceiveResult { + fn from(e: Error) -> Self { + ReceiveResult::IoError(e) + } +} + impl UdpTcServer { pub fn new( addr: A, max_recv_size: usize, tc_receiver: Box>, - ) -> Result { + ) -> Result { let server = Self { socket: UdpSocket::bind(addr)?, recv_buf: vec![0; max_recv_size], sender_addr: None, tc_receiver, }; - server - .socket - .set_nonblocking(true) - .expect("Setting server non blocking failed"); + server.socket.set_nonblocking(true)?; Ok(server) } @@ -42,10 +60,10 @@ impl UdpTcServer { let res = match self.socket.recv_from(&mut self.recv_buf) { Ok(res) => res, Err(e) => { - return if e.kind() == ErrorKind::WouldBlock { + return if e.kind() == ErrorKind::WouldBlock || e.kind() == ErrorKind::TimedOut { Err(ReceiveResult::WouldBlock) } else { - Err(ReceiveResult::OtherIoError(e)) + Err(e.into()) } } }; diff --git a/fsrc-example/src/bin/obsw/tmtc.rs b/fsrc-example/src/bin/obsw/tmtc.rs index 1c9ad9e..4ac7237 100644 --- a/fsrc-example/src/bin/obsw/tmtc.rs +++ b/fsrc-example/src/bin/obsw/tmtc.rs @@ -83,7 +83,7 @@ fn core_tc_handling(udp_tmtc_server: &mut UdpTmtcServer) -> bool { true } }, - ReceiveResult::OtherIoError(e) => { + ReceiveResult::IoError(e) => { println!("IO error {e}"); false }