satrs_core/hal/std/
udp_server.rs1use crate::tmtc::{ReceivesTc, ReceivesTcCore};
3use std::boxed::Box;
4use std::io::{Error, ErrorKind};
5use std::net::{SocketAddr, ToSocketAddrs, UdpSocket};
6use std::vec;
7use std::vec::Vec;
8
9pub struct UdpTcServer<E> {
61 pub socket: UdpSocket,
62 recv_buf: Vec<u8>,
63 sender_addr: Option<SocketAddr>,
64 tc_receiver: Box<dyn ReceivesTc<Error = E>>,
65}
66
67#[derive(Debug)]
68pub enum ReceiveResult<E> {
69 NothingReceived,
70 IoError(Error),
71 ReceiverError(E),
72}
73
74impl<E> From<Error> for ReceiveResult<E> {
75 fn from(e: Error) -> Self {
76 ReceiveResult::IoError(e)
77 }
78}
79
80impl<E: PartialEq> PartialEq for ReceiveResult<E> {
81 fn eq(&self, other: &Self) -> bool {
82 use ReceiveResult::*;
83 match (self, other) {
84 (IoError(ref e), IoError(ref other_e)) => e.kind() == other_e.kind(),
85 (NothingReceived, NothingReceived) => true,
86 (ReceiverError(e), ReceiverError(other_e)) => e == other_e,
87 _ => false,
88 }
89 }
90}
91
92impl<E: Eq + PartialEq> Eq for ReceiveResult<E> {}
93
94impl<E: 'static> ReceivesTcCore for UdpTcServer<E> {
95 type Error = E;
96
97 fn pass_tc(&mut self, tc_raw: &[u8]) -> Result<(), Self::Error> {
98 self.tc_receiver.pass_tc(tc_raw)
99 }
100}
101
102impl<E: 'static> UdpTcServer<E> {
103 pub fn new<A: ToSocketAddrs>(
104 addr: A,
105 max_recv_size: usize,
106 tc_receiver: Box<dyn ReceivesTc<Error = E>>,
107 ) -> Result<Self, Error> {
108 let server = Self {
109 socket: UdpSocket::bind(addr)?,
110 recv_buf: vec![0; max_recv_size],
111 sender_addr: None,
112 tc_receiver,
113 };
114 server.socket.set_nonblocking(true)?;
115 Ok(server)
116 }
117
118 pub fn try_recv_tc(&mut self) -> Result<(usize, SocketAddr), ReceiveResult<E>> {
119 let res = match self.socket.recv_from(&mut self.recv_buf) {
120 Ok(res) => res,
121 Err(e) => {
122 return if e.kind() == ErrorKind::WouldBlock || e.kind() == ErrorKind::TimedOut {
123 Err(ReceiveResult::NothingReceived)
124 } else {
125 Err(e.into())
126 }
127 }
128 };
129 let (num_bytes, from) = res;
130 self.sender_addr = Some(from);
131 self.tc_receiver
132 .pass_tc(&self.recv_buf[0..num_bytes])
133 .map_err(|e| ReceiveResult::ReceiverError(e))?;
134 Ok(res)
135 }
136
137 pub fn last_sender(&self) -> Option<SocketAddr> {
138 self.sender_addr
139 }
140}
141
142#[cfg(test)]
143mod tests {
144 use crate::hal::std::udp_server::{ReceiveResult, UdpTcServer};
145 use crate::tmtc::ReceivesTcCore;
146 use spacepackets::ecss::tc::PusTcCreator;
147 use spacepackets::ecss::WritablePusPacket;
148 use spacepackets::SpHeader;
149 use std::boxed::Box;
150 use std::collections::VecDeque;
151 use std::net::{IpAddr, Ipv4Addr, SocketAddr, UdpSocket};
152 use std::vec::Vec;
153
154 fn is_send<T: Send>(_: &T) {}
155
156 #[derive(Default)]
157 struct PingReceiver {
158 pub sent_cmds: VecDeque<Vec<u8>>,
159 }
160
161 impl ReceivesTcCore for PingReceiver {
162 type Error = ();
163
164 fn pass_tc(&mut self, tc_raw: &[u8]) -> Result<(), Self::Error> {
165 let mut sent_data = Vec::new();
166 sent_data.extend_from_slice(tc_raw);
167 self.sent_cmds.push_back(sent_data);
168 Ok(())
169 }
170 }
171
172 #[test]
173 fn basic_test() {
174 let mut buf = [0; 32];
175 let dest_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 7777);
176 let ping_receiver = PingReceiver::default();
177 is_send(&ping_receiver);
178 let mut udp_tc_server = UdpTcServer::new(dest_addr, 2048, Box::new(ping_receiver))
179 .expect("Creating UDP TMTC server failed");
180 is_send(&udp_tc_server);
181 let mut sph = SpHeader::tc_unseg(0x02, 0, 0).unwrap();
182 let pus_tc = PusTcCreator::new_simple(&mut sph, 17, 1, None, true);
183 let len = pus_tc
184 .write_to_bytes(&mut buf)
185 .expect("Error writing PUS TC packet");
186 let client = UdpSocket::bind("127.0.0.1:7778").expect("Connecting to UDP server failed");
187 client
188 .send_to(&buf[0..len], dest_addr)
189 .expect("Error sending PUS TC via UDP");
190 let local_addr = client.local_addr().unwrap();
191 udp_tc_server
192 .try_recv_tc()
193 .expect("Error receiving sent telecommand");
194 assert_eq!(
195 udp_tc_server.last_sender().expect("No sender set"),
196 local_addr
197 );
198 let ping_receiver: &mut PingReceiver = udp_tc_server.tc_receiver.downcast_mut().unwrap();
199 assert_eq!(ping_receiver.sent_cmds.len(), 1);
200 let sent_cmd = ping_receiver.sent_cmds.pop_front().unwrap();
201 assert_eq!(sent_cmd, buf[0..len]);
202 }
203
204 #[test]
205 fn test_nothing_received() {
206 let dest_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 7779);
207 let ping_receiver = PingReceiver::default();
208 let mut udp_tc_server = UdpTcServer::new(dest_addr, 2048, Box::new(ping_receiver))
209 .expect("Creating UDP TMTC server failed");
210 let res = udp_tc_server.try_recv_tc();
211 assert!(res.is_err());
212 let err = res.unwrap_err();
213 assert_eq!(err, ReceiveResult::NothingReceived);
214 }
215}