]> code.octet-stream.net Git - m17rt/blob - m17app/src/tnc.rs
Modem support for parsing packet frames
[m17rt] / m17app / src / tnc.rs
1 use std::io::{Read, Write};
2
3 /// A TNC that supports reading and writing M17 KISS messages.
4 ///
5 /// TNCs must be cloneable to support reading and writing from different threads,
6 /// via a working implementation of try_clone(). We do not require `Clone` directly
7 /// as this could not be fulfilled by `TcpStream`.
8 pub trait Tnc: Read + Write + Sized + Send + 'static {
9 /// Return a copy of this TNC.
10 ///
11 /// `M17App` will use this to create a second instance of the supplied TNC then use
12 /// one of them for reading and one of them for writing, concurrently across two threads.
13 ///
14 /// Implementations do not need to worry about trying to make two simultaneous reads or
15 /// two simultaneous writes do something sensible. `M17App` will not do this and it would
16 /// probably produce garbled KISS messages anyway.
17 fn try_clone(&mut self) -> Result<Self, TncError>;
18
19 /// Start I/O.
20 fn start(&mut self) -> Result<(), TncError>;
21
22 /// Shut down I/O - it is assumed we cannot restart.
23 fn close(&mut self) -> Result<(), TncError>;
24 }
25
26 #[derive(Debug, PartialEq, Eq, Clone)]
27 pub enum TncError {
28 // TODO: Good error cases
29 Unknown,
30 }
31
32 impl Tnc for std::net::TcpStream {
33 fn try_clone(&mut self) -> Result<Self, TncError> {
34 std::net::TcpStream::try_clone(self).map_err(|_| TncError::Unknown)
35 }
36
37 fn start(&mut self) -> Result<(), TncError> {
38 // already started, hopefully we get onto reading the socket quickly
39 Ok(())
40 }
41
42 fn close(&mut self) -> Result<(), TncError> {
43 self.shutdown(std::net::Shutdown::Both)
44 .map_err(|_| TncError::Unknown)
45 }
46 }