X-Git-Url: https://code.octet-stream.net/m17rt/blobdiff_plain/e67ea96c8a3d7c23ba29c6ed91ddb451927176a1..07aeda96f40483f81ae5184e576102e155371b38:/m17app/src/tnc.rs?ds=inline diff --git a/m17app/src/tnc.rs b/m17app/src/tnc.rs index 56cb661..ef30e38 100644 --- a/m17app/src/tnc.rs +++ b/m17app/src/tnc.rs @@ -1,60 +1,44 @@ -use std::io::{self, ErrorKind, Read, Write}; - -use m17core::tnc::SoftTnc; +use std::io::{Read, Write}; +/// A TNC that supports reading and writing M17 KISS messages. /// -pub trait Tnc: Read + Write + Sized { +/// TNCs must be cloneable to support reading and writing from different threads, +/// via a working implementation of try_clone(). We do not require `Clone` directly +/// as this could not be fulfilled by `TcpStream`. +pub trait Tnc: Read + Write + Sized + Send + 'static { + /// Return a copy of this TNC. + /// + /// `M17App` will use this to create a second instance of the supplied TNC then use + /// one of them for reading and one of them for writing, concurrently across two threads. + /// + /// Implementations do not need to worry about trying to make two simultaneous reads or + /// two simultaneous writes do something sensible. `M17App` will not do this and it would + /// probably produce garbled KISS messages anyway. fn try_clone(&mut self) -> Result; - fn start(&mut self) -> Result<(), TncError>; - fn close(&mut self) -> Result<(), TncError>; -} - -#[derive(Debug)] -pub enum TncError { - General(String), -} - -// TODO: move the following to its own module - -pub struct Soundmodem { - tnc: SoftTnc, - config: SoundmodemConfig, -} -pub struct SoundmodemConfig { - // sound cards, PTT, etc. -} + /// Start I/O. + fn start(&mut self); -impl Read for Soundmodem { - fn read(&mut self, buf: &mut [u8]) -> io::Result { - self.tnc - .read_kiss(buf) - .map_err(|s| io::Error::new(ErrorKind::Other, format!("{:?}", s))) - } + /// Shut down I/O - it is assumed we cannot restart. + fn close(&mut self); } -impl Write for Soundmodem { - fn write(&mut self, buf: &[u8]) -> std::io::Result { - self.tnc - .write_kiss(buf) - .map_err(|s| io::Error::new(ErrorKind::Other, format!("{:?}", s))) - } - - fn flush(&mut self) -> std::io::Result<()> { - Ok(()) - } +#[derive(Debug, PartialEq, Eq, Clone)] +pub enum TncError { + // TODO: Good error cases + Unknown, } -impl Tnc for Soundmodem { +impl Tnc for std::net::TcpStream { fn try_clone(&mut self) -> Result { - unimplemented!(); + std::net::TcpStream::try_clone(self).map_err(|_| TncError::Unknown) } - fn start(&mut self) -> Result<(), TncError> { - unimplemented!(); + fn start(&mut self) { + // already started, hopefully we get onto reading the socket quickly } - fn close(&mut self) -> Result<(), TncError> { - unimplemented!(); + fn close(&mut self) { + let _ = self.shutdown(std::net::Shutdown::Both); } }