]> code.octet-stream.net Git - m17rt/commitdiff
Implement Tnc for TcpStream
authorThomas Karpiniec <tom.karpiniec@outlook.com>
Tue, 31 Dec 2024 02:42:27 +0000 (13:42 +1100)
committerThomas Karpiniec <tom.karpiniec@outlook.com>
Tue, 31 Dec 2024 02:42:27 +0000 (13:42 +1100)
m17app/src/app.rs
m17app/src/lib.rs
m17app/src/soundmodem.rs [new file with mode: 0644]
m17app/src/tnc.rs
m17core/src/tnc.rs

index 6d056f9b3a55627abe8597925b8259affa76c0b9..aa040de51948e9632a15adb77da5fe01ef132a4c 100644 (file)
@@ -125,7 +125,7 @@ enum TncControlEvent {
     Close,
 }
 
     Close,
 }
 
-fn spawn_reader<T: Tnc + Send + 'static>(mut tnc: T, adapters: Arc<RwLock<Adapters>>) {
+fn spawn_reader<T: Tnc>(mut tnc: T, adapters: Arc<RwLock<Adapters>>) {
     std::thread::spawn(move || {
         let mut kiss_buffer = KissBuffer::new();
         let mut stream_running = false;
     std::thread::spawn(move || {
         let mut kiss_buffer = KissBuffer::new();
         let mut stream_running = false;
@@ -241,7 +241,7 @@ fn spawn_reader<T: Tnc + Send + 'static>(mut tnc: T, adapters: Arc<RwLock<Adapte
     });
 }
 
     });
 }
 
-fn spawn_writer<T: Tnc + Send + 'static>(mut tnc: T, event_rx: mpsc::Receiver<TncControlEvent>) {
+fn spawn_writer<T: Tnc>(mut tnc: T, event_rx: mpsc::Receiver<TncControlEvent>) {
     std::thread::spawn(move || {
         while let Ok(ev) = event_rx.recv() {
             match ev {
     std::thread::spawn(move || {
         while let Ok(ev) = event_rx.recv() {
             match ev {
index d135ca2b63dd120e40053e9abe8fa40bbff676e8..7530aa26521ed6051b7760b7f290590d0ff5c174 100755 (executable)
@@ -1,3 +1,4 @@
 pub mod adapter;
 pub mod app;
 pub mod adapter;
 pub mod app;
+pub mod soundmodem;
 pub mod tnc;
 pub mod tnc;
diff --git a/m17app/src/soundmodem.rs b/m17app/src/soundmodem.rs
new file mode 100644 (file)
index 0000000..83731da
--- /dev/null
@@ -0,0 +1,47 @@
+use std::io::{self, ErrorKind, Read, Write};
+
+use crate::tnc::{Tnc, TncError};
+use m17core::tnc::SoftTnc;
+
+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)))
+    }
+}
+
+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 {
+    fn try_clone(&mut self) -> Result<Self, TncError> {
+        unimplemented!();
+    }
+
+    fn start(&mut self) -> Result<(), TncError> {
+        unimplemented!();
+    }
+
+    fn close(&mut self) -> Result<(), TncError> {
+        unimplemented!();
+    }
+}
index 56cb6613e5be8f2b5f1834a87f13d21bc732763d..99bacc721aa9a5e99dd96fa31989472f32c0b6c8 100644 (file)
@@ -1,60 +1,34 @@
-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 {
     fn try_clone(&mut self) -> Result<Self, TncError>;
     fn start(&mut self) -> Result<(), TncError>;
     fn close(&mut self) -> Result<(), TncError>;
 }
 
     fn try_clone(&mut self) -> Result<Self, TncError>;
     fn start(&mut self) -> Result<(), TncError>;
     fn close(&mut self) -> Result<(), TncError>;
 }
 
-#[derive(Debug)]
+#[derive(Debug, PartialEq, Eq, Clone)]
 pub enum TncError {
 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)))
-    }
-}
-
-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(())
-    }
+    // TODO: Good error cases
+    Unknown,
 }
 
 }
 
-impl Tnc for Soundmodem {
+impl Tnc for std::net::TcpStream {
     fn try_clone(&mut self) -> Result<Self, TncError> {
     fn try_clone(&mut self) -> Result<Self, TncError> {
-        unimplemented!();
+        self.try_clone().map_err(|_| TncError::Unknown)
     }
 
     fn start(&mut self) -> Result<(), TncError> {
     }
 
     fn start(&mut self) -> Result<(), TncError> {
-        unimplemented!();
+        // already started, hopefully we get onto reading the socket quickly
+        Ok(())
     }
 
     fn close(&mut self) -> Result<(), TncError> {
     }
 
     fn close(&mut self) -> Result<(), TncError> {
-        unimplemented!();
+        self.shutdown(std::net::Shutdown::Both)
+            .map_err(|_| TncError::Unknown)
     }
 }
     }
 }
index a6af088e2d29906b753a49e8c96a8a8612227d1f..79adaa491a1f0461cf96a8710524c2d27000f37d 100644 (file)
@@ -12,7 +12,7 @@ impl SoftTnc {
         Ok(())
     }
 
         Ok(())
     }
 
-    ///
+    /// Update the number of samples that have been received by the incoming stream, as a form of timekeeping
     pub fn advance_samples(&mut self, _samples: u64) {}
 
     pub fn set_data_carrier_detect(&mut self, _dcd: bool) {}
     pub fn advance_samples(&mut self, _samples: u64) {}
 
     pub fn set_data_carrier_detect(&mut self, _dcd: bool) {}