OBSW-Client Example #11
@ -1 +1,2 @@
|
||||
//! Helper modules intended to be used on hosts with a full [std] runtime
|
||||
pub mod udp_server;
|
||||
|
@ -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<E> {
|
||||
pub socket: UdpSocket,
|
||||
recv_buf: Vec<u8>,
|
||||
@ -15,26 +30,29 @@ pub struct UdpTcServer<E> {
|
||||
#[derive(Debug)]
|
||||
pub enum ReceiveResult<E> {
|
||||
WouldBlock,
|
||||
OtherIoError(std::io::Error),
|
||||
IoError(Error),
|
||||
ReceiverError(E),
|
||||
}
|
||||
|
||||
impl<E> From<Error> for ReceiveResult<E> {
|
||||
fn from(e: Error) -> Self {
|
||||
ReceiveResult::IoError(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl<E> UdpTcServer<E> {
|
||||
pub fn new<A: ToSocketAddrs>(
|
||||
addr: A,
|
||||
max_recv_size: usize,
|
||||
tc_receiver: Box<dyn ReceivesTc<Error = E>>,
|
||||
) -> Result<Self, std::io::Error> {
|
||||
) -> Result<Self, Error> {
|
||||
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<E> UdpTcServer<E> {
|
||||
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())
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user