start with mio tcp client
This commit is contained in:
@ -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;
|
||||
|
83
src/interface/tcp_spp_client.rs
Normal file
83
src/interface/tcp_spp_client.rs
Normal 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(())
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user