Struct satrs::hal::std::udp_server::UdpTcServer

source ·
pub struct UdpTcServer<TcSender: PacketSenderRaw<Error = SendError>, SendError> {
    pub id: ComponentId,
    pub socket: UdpSocket,
    pub tc_sender: TcSender,
    /* private fields */
}
Available on crate feature std only.
Expand description

This UDP server can be used to receive CCSDS space packet telecommands or any other telecommand format.

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 sender in form of a special trait object which implements PacketSenderRaw. For example, this can be used to send the telecommands to a centralized TC source component for further processing and routing.

§Examples

use std::net::{IpAddr, Ipv4Addr, SocketAddr, UdpSocket};
use std::sync::mpsc;
use spacepackets::ecss::WritablePusPacket;
use satrs::hal::std::udp_server::UdpTcServer;
use satrs::ComponentId;
use satrs::tmtc::PacketSenderRaw;
use spacepackets::SpHeader;
use spacepackets::ecss::tc::PusTcCreator;

const UDP_SERVER_ID: ComponentId = 0x05;

let (packet_sender, packet_receiver) = mpsc::channel();
let dest_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 7777);
let mut udp_tc_server = UdpTcServer::new(UDP_SERVER_ID, dest_addr, 2048, packet_sender)
      .expect("Creating UDP TMTC server failed");
let sph = SpHeader::new_from_apid(0x02);
let pus_tc = PusTcCreator::new_simple(sph, 17, 1, &[], true);
// Can not fail.
let ping_tc_raw = pus_tc.to_vec().unwrap();

// Now create a UDP client and send the ping telecommand to the server.
let client = UdpSocket::bind("127.0.0.1:0").expect("creating UDP client failed");
client
    .send_to(&ping_tc_raw, dest_addr)
    .expect("Error sending PUS TC via UDP");
let recv_result = udp_tc_server.try_recv_tc();
assert!(recv_result.is_ok());
// The packet is received by the UDP TC server and sent via the mpsc channel.
let sent_packet_with_sender = packet_receiver.try_recv().expect("expected telecommand");
assert_eq!(sent_packet_with_sender.packet, ping_tc_raw);
assert_eq!(sent_packet_with_sender.sender_id, UDP_SERVER_ID);
// No more packets received.
matches!(packet_receiver.try_recv(), Err(mpsc::TryRecvError::Empty));

The satrs-example crate server code also includes example code 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.

Fields§

§id: ComponentId§socket: UdpSocket§tc_sender: TcSender

Implementations§

source§

impl<TcSender: PacketSenderRaw<Error = SendError>, SendError: Debug + 'static> UdpTcServer<TcSender, SendError>

source

pub fn new<A: ToSocketAddrs>( id: ComponentId, addr: A, max_recv_size: usize, tc_sender: TcSender ) -> Result<Self, Error>

source

pub fn try_recv_tc( &mut self ) -> Result<(usize, SocketAddr), ReceiveResult<SendError>>

source

pub fn last_sender(&self) -> Option<SocketAddr>

Auto Trait Implementations§

§

impl<TcSender, SendError> Freeze for UdpTcServer<TcSender, SendError>
where TcSender: Freeze,

§

impl<TcSender, SendError> RefUnwindSafe for UdpTcServer<TcSender, SendError>
where TcSender: RefUnwindSafe,

§

impl<TcSender, SendError> Send for UdpTcServer<TcSender, SendError>

§

impl<TcSender, SendError> Sync for UdpTcServer<TcSender, SendError>
where TcSender: Sync,

§

impl<TcSender, SendError> Unpin for UdpTcServer<TcSender, SendError>
where TcSender: Unpin,

§

impl<TcSender, SendError> UnwindSafe for UdpTcServer<TcSender, SendError>
where TcSender: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> Downcast for T
where T: Any,

source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
source§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
source§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Sync + Send>

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.