use core::fmt; use log::{info, warn}; use libboard_zynq::smoltcp; use libasync::task; use libasync::smoltcp::TcpStream; use num_derive::{FromPrimitive, ToPrimitive}; use num_traits::{FromPrimitive, ToPrimitive}; use crate::proto::*; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Error { NetworkError(smoltcp::Error), UnexpectedPattern, UnrecognizedPacket, } pub type Result = core::result::Result; impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { &Error::NetworkError(error) => write!(f, "network error: {}", error), &Error::UnexpectedPattern => write!(f, "unexpected pattern"), &Error::UnrecognizedPacket => write!(f, "unrecognized packet"), } } } impl From for Error { fn from(error: smoltcp::Error) -> Self { Error::NetworkError(error) } } #[derive(Debug, FromPrimitive, ToPrimitive)] enum HostMessage { MonitorProbe = 0, MonitorInjection = 3, Inject = 1, GetInjectionStatus = 2 } #[derive(Debug, FromPrimitive, ToPrimitive)] enum DeviceMessage { MonitorStatus = 0, InjectionStatus = 1 } async fn handle_connection(stream: &TcpStream) -> Result<()> { if !expect(&stream, b"ARTIQ moninj\n").await? { return Err(Error::UnexpectedPattern); } loop { let message: HostMessage = FromPrimitive::from_i8(read_i8(&stream).await?) .ok_or(Error::UnrecognizedPacket)?; info!("{:?}", message); } } pub fn start() { task::spawn(async move { loop { let stream = TcpStream::accept(1383, 2048, 2048).await.unwrap(); task::spawn(async { let _ = handle_connection(&stream) .await .map_err(|e| warn!("connection terminated: {}", e)); let _ = stream.flush().await; let _ = stream.abort().await; }); } }); }