From 2813fcb83452c7fd91d799a984613a616180a067 Mon Sep 17 00:00:00 2001 From: Thomas Karpiniec Date: Tue, 31 Dec 2024 13:42:27 +1100 Subject: [PATCH] Implement Tnc for TcpStream --- m17app/src/app.rs | 4 +-- m17app/src/lib.rs | 1 + m17app/src/soundmodem.rs | 47 +++++++++++++++++++++++++++++++++ m17app/src/tnc.rs | 56 +++++++++++----------------------------- m17core/src/tnc.rs | 2 +- 5 files changed, 66 insertions(+), 44 deletions(-) create mode 100644 m17app/src/soundmodem.rs diff --git a/m17app/src/app.rs b/m17app/src/app.rs index 6d056f9..aa040de 100644 --- a/m17app/src/app.rs +++ b/m17app/src/app.rs @@ -125,7 +125,7 @@ enum TncControlEvent { Close, } -fn spawn_reader(mut tnc: T, adapters: Arc>) { +fn spawn_reader(mut tnc: T, adapters: Arc>) { std::thread::spawn(move || { let mut kiss_buffer = KissBuffer::new(); let mut stream_running = false; @@ -241,7 +241,7 @@ fn spawn_reader(mut tnc: T, adapters: Arc(mut tnc: T, event_rx: mpsc::Receiver) { +fn spawn_writer(mut tnc: T, event_rx: mpsc::Receiver) { std::thread::spawn(move || { while let Ok(ev) = event_rx.recv() { match ev { diff --git a/m17app/src/lib.rs b/m17app/src/lib.rs index d135ca2..7530aa2 100755 --- a/m17app/src/lib.rs +++ b/m17app/src/lib.rs @@ -1,3 +1,4 @@ pub mod adapter; pub mod app; +pub mod soundmodem; pub mod tnc; diff --git a/m17app/src/soundmodem.rs b/m17app/src/soundmodem.rs new file mode 100644 index 0000000..83731da --- /dev/null +++ b/m17app/src/soundmodem.rs @@ -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 { + 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 { + 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 { + unimplemented!(); + } + + fn start(&mut self) -> Result<(), TncError> { + unimplemented!(); + } + + fn close(&mut self) -> Result<(), TncError> { + unimplemented!(); + } +} diff --git a/m17app/src/tnc.rs b/m17app/src/tnc.rs index 56cb661..99bacc7 100644 --- a/m17app/src/tnc.rs +++ b/m17app/src/tnc.rs @@ -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; fn start(&mut self) -> Result<(), TncError>; 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 { - 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 { - 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 { - unimplemented!(); + self.try_clone().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) } } diff --git a/m17core/src/tnc.rs b/m17core/src/tnc.rs index a6af088..79adaa4 100644 --- a/m17core/src/tnc.rs +++ b/m17core/src/tnc.rs @@ -12,7 +12,7 @@ impl SoftTnc { 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) {} -- 2.39.5