]> code.octet-stream.net Git - m17rt/blobdiff - m17app/src/tnc.rs
Support for baseband output to a soundcard
[m17rt] / m17app / src / tnc.rs
index 56cb6613e5be8f2b5f1834a87f13d21bc732763d..e7799b4843cb713fd819e1390110dc8a9030b81c 100644 (file)
@@ -1,60 +1,46 @@
-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<Self, TncError>;
+
+    /// Start I/O.
     fn start(&mut self) -> Result<(), TncError>;
+
+    /// Shut down I/O - it is assumed we cannot restart.
     fn close(&mut self) -> Result<(), TncError>;
 }
 
-#[derive(Debug)]
+#[derive(Debug, PartialEq, Eq, Clone)]
 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.
-}
-
-impl Read for Soundmodem {
-    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
-        self.tnc
-            .read_kiss(buf)
-            .map_err(|s| io::Error::new(ErrorKind::Other, format!("{:?}", s)))
-    }
+    // TODO: Good error cases
+    Unknown,
 }
 
-impl Write for Soundmodem {
-    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
-        self.tnc
-            .write_kiss(buf)
-            .map_err(|s| io::Error::new(ErrorKind::Other, format!("{:?}", s)))
-    }
-
-    fn flush(&mut self) -> std::io::Result<()> {
-        Ok(())
-    }
-}
-
-impl Tnc for Soundmodem {
+impl Tnc for std::net::TcpStream {
     fn try_clone(&mut self) -> Result<Self, TncError> {
-        unimplemented!();
+        std::net::TcpStream::try_clone(self).map_err(|_| TncError::Unknown)
     }
 
     fn start(&mut self) -> Result<(), TncError> {
-        unimplemented!();
+        // already started, hopefully we get onto reading the socket quickly
+        Ok(())
     }
 
     fn close(&mut self) -> Result<(), TncError> {
-        unimplemented!();
+        self.shutdown(std::net::Shutdown::Both)
+            .map_err(|_| TncError::Unknown)
     }
 }