start with mio tcp client

This commit is contained in:
2024-04-13 15:16:53 +02:00
parent d9629dee38
commit 6dddfd5a70
14 changed files with 225 additions and 153 deletions

View File

@ -1,3 +1,4 @@
pub mod can;
pub mod tcp;
pub mod udp;
pub mod tcp_server;
pub mod tcp_spp_client;
pub mod udp_server;

View File

@ -0,0 +1,83 @@
use std::io::{self, Read};
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
use std::sync::mpsc;
use mio::net::TcpStream;
use mio::{Events, Interest, Poll, Token};
use ops_sat_rs::config::TCP_SPP_SERVER_PORT;
use satrs::spacepackets::ecss::CCSDS_HEADER_LEN;
use satrs::spacepackets::{CcsdsPacket, SpHeader};
pub struct TcpSppClient {
poll: Poll,
events: Events,
client: TcpStream,
read_buf: [u8; 4096],
tc_source_tx: mpsc::Sender<Vec<u8>>,
}
impl TcpSppClient {
pub fn new() -> io::Result<Self> {
let poll = Poll::new()?;
let events = Events::with_capacity(128);
let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 1, 1)), TCP_SPP_SERVER_PORT);
let mut client = TcpStream::connect(addr)?;
poll.registry().register(
&mut client,
Token(0),
Interest::READABLE | Interest::WRITABLE,
)?;
Ok(Self {
poll,
events,
client,
read_buf: [0; 4096],
})
}
pub fn periodic_operation(&mut self) -> io::Result<()> {
self.poll.poll(&mut self.events, None)?;
let events: Vec<mio::event::Event> = self.events.iter().cloned().collect();
for event in events {
if event.token() == Token(0) {
if event.is_readable() {
self.read_from_server()?;
}
if event.is_writable() {
// Read packets from a queue and send them here..
// self.client.write_all(b"hello")?;
}
}
}
Ok(())
}
pub fn read_from_server(&mut self) -> io::Result<()> {
match self.client.read(&mut self.read_buf) {
Ok(0) => return Err(io::Error::from(io::ErrorKind::BrokenPipe)),
Ok(n) => {
if n < CCSDS_HEADER_LEN + 1 {
log::warn!("received packet smaller than minimum expected packet size.");
log::debug!("{:?}", &self.read_buf[..n]);
return Ok(());
}
// We already checked that the received size has the minimum expected size.
let (sp_header, data) =
SpHeader::from_be_bytes(&self.read_buf[..n]).expect("parsing SP header failed");
let full_expected_packet_len = sp_header.total_len();
// We received an incomplete frame?
if n < full_expected_packet_len {
log::warn!(
"received incomplete SPP, with detected packet length {} but read buffer length {}",
full_expected_packet_len, n
);
return Ok(());
}
self.tc_source_tx
.send(self.read_buf[0..full_expected_packet_len].to_vec());
}
Err(e) => return Err(e),
}
Ok(())
}
}