rfc2217_rs/
server.rs

1use crate::serialport_conversions::*;
2use crate::{
3    codes, negotiation, parser, subnegotiation, Command, Negotiation, Parser, Subnegotiation,
4};
5use serialport::{ClearBuffer, FlowControl, SerialPort};
6use std::io::{self, BufWriter, Read, Write};
7use std::net::{TcpListener, TcpStream, ToSocketAddrs};
8
9#[derive(Debug)]
10pub enum Error {
11    Parsing(parser::Error),
12    SerialInit(serialport::Error),
13    Serial(io::Error),
14    Tcp(io::Error),
15}
16
17pub struct Server {
18    port: Box<dyn SerialPort>,
19    port_writer: BufWriter<Box<dyn SerialPort>>,
20    tcp_conn: TcpStream,
21    tcp_writer: BufWriter<TcpStream>,
22    tcp_answer_buf: [u8; subnegotiation::MAX_SIZE],
23    parser: Parser,
24    signature: Vec<u8>,
25    suspended_flow_control: FlowControl,
26    break_state: bool,
27}
28
29impl Server {
30    pub fn new<A: ToSocketAddrs>(serial_port_name: &str, tcp_addr: A) -> Result<Self, Error> {
31        let port = serialport::new(serial_port_name, 9600)
32            .open()
33            .map_err(Error::SerialInit)?;
34        let port_clone = port.try_clone().map_err(Error::SerialInit)?;
35        let listener = TcpListener::bind(tcp_addr).map_err(Error::Tcp)?;
36        let (connection, _) = listener.accept().map_err(Error::Tcp)?;
37        connection.set_nonblocking(true).map_err(Error::Tcp)?;
38        let cloned_connection = connection.try_clone().map_err(Error::Tcp)?;
39
40        Ok(Server {
41            port: port,
42            parser: Parser::new(),
43            port_writer: BufWriter::new(port_clone),
44            tcp_conn: connection,
45            tcp_writer: BufWriter::new(cloned_connection),
46            tcp_answer_buf: [0; subnegotiation::MAX_SIZE],
47            signature: Vec::new(),
48            suspended_flow_control: FlowControl::None,
49            break_state: false,
50        })
51    }
52
53    pub fn run(&mut self) -> Result<(), Error> {
54        // Read and handle the data from the TCP connection
55        let mut tcp_data = [0; 256];
56        match self.tcp_conn.read(&mut tcp_data) {
57            Ok(bytes_read) => {
58                self.process_tcp_data(&tcp_data[..bytes_read])?;
59            }
60            Err(error) => match error.kind() {
61                io::ErrorKind::WouldBlock => {}
62                _ => return Err(Error::Tcp(error)),
63            },
64        }
65
66        // Read and handle the data from the serial port
67        let mut port_data = [0; 256];
68        match self.port.read(&mut port_data) {
69            Ok(bytes_read) => {
70                for &byte in &port_data[..bytes_read] {
71                    // Escape all IAC bytes
72                    self.tcp_writer.write_all(&[byte]).map_err(Error::Tcp)?;
73                    if byte == codes::IAC {
74                        self.tcp_writer.write_all(&[byte]).map_err(Error::Tcp)?;
75                    }
76                }
77            }
78            Err(error) => match error.kind() {
79                io::ErrorKind::TimedOut => {}
80                _ => return Err(Error::Serial(error)),
81            },
82        }
83
84        // Flush the buffered data to be sent
85        self.port_writer.flush().map_err(Error::Serial)?;
86        self.tcp_writer.flush().map_err(Error::Tcp)?;
87
88        Ok(())
89    }
90
91    fn process_tcp_data(&mut self, bytes: &[u8]) -> Result<(), Error> {
92        for &byte in bytes {
93            if let Some(event) = self.parser.process_byte(byte).map_err(Error::Parsing)? {
94                let answer_size = self.process_event(event).map_err(Error::Serial)?;
95                self.tcp_writer
96                    .write_all(&self.tcp_answer_buf[..answer_size])
97                    .map_err(Error::Tcp)?;
98            }
99        }
100        Ok(())
101    }
102
103    fn process_event(&mut self, event: parser::Event) -> Result<usize, io::Error> {
104        match event {
105            parser::Event::Data(byte) => {
106                self.port_writer.write_all(&[byte])?;
107                Ok(0)
108            }
109            parser::Event::Command(command) => self.process_command(command),
110            parser::Event::Negotiation(negotiation) => self.process_negotiation(negotiation),
111            parser::Event::Subnegotiation(subnegotiation) => {
112                self.process_subnegotiation(subnegotiation)
113            }
114        }
115    }
116
117    fn process_command(&mut self, command: Command) -> Result<usize, io::Error> {
118        match command {
119            _ => Ok(0),
120        }
121    }
122
123    fn process_negotiation(&mut self, negotiation: Negotiation) -> Result<usize, io::Error> {
124        match negotiation.get_answer() {
125            Some(answer) => {
126                answer.serialize(&mut self.tcp_answer_buf[..negotiation::SIZE]);
127                Ok(negotiation::SIZE)
128            }
129            None => Ok(0),
130        }
131    }
132
133    fn process_subnegotiation(
134        &mut self,
135        subnegotiation: Subnegotiation,
136    ) -> Result<usize, io::Error> {
137        let answer_opt = match subnegotiation {
138            Subnegotiation::SetSignature { data, size } => {
139                // An empty signature constitutes a signature query
140                if size == 0 {
141                    let mut data = [0; subnegotiation::MAX_DATA_SIZE];
142                    let size = self.signature.len() as u8;
143                    data.copy_from_slice(&self.signature);
144                    Some(Subnegotiation::SetSignature { data, size })
145                } else {
146                    self.signature.copy_from_slice(&data[..size as usize]);
147                    Some(subnegotiation)
148                }
149            }
150
151            Subnegotiation::SetBaudRate(val) => {
152                if val == 0 {
153                    Some(Subnegotiation::SetBaudRate(self.port.baud_rate()?))
154                } else {
155                    self.port.set_baud_rate(val)?;
156                    Some(subnegotiation)
157                }
158            }
159
160            Subnegotiation::SetDataSize(val) => match u8_to_data_bits(val) {
161                Some(data_bits) => {
162                    self.port.set_data_bits(data_bits)?;
163                    Some(subnegotiation)
164                }
165                None => Some(Subnegotiation::SetDataSize(data_bits_to_u8(
166                    self.port.data_bits()?,
167                ))),
168            },
169
170            Subnegotiation::SetParity(val) => match u8_to_parity(val) {
171                Some(parity) => {
172                    self.port.set_parity(parity)?;
173                    Some(subnegotiation)
174                }
175                None => Some(Subnegotiation::SetParity(parity_to_u8(self.port.parity()?))),
176            },
177
178            Subnegotiation::SetStopSize(val) => match u8_to_stop_bits(val) {
179                Some(stop_bits) => {
180                    self.port.set_stop_bits(stop_bits)?;
181                    Some(subnegotiation)
182                }
183                None => Some(Subnegotiation::SetStopSize(stop_bits_to_u8(
184                    self.port.stop_bits()?,
185                ))),
186            },
187
188            Subnegotiation::SetControl(val) => self.handle_set_control(val)?,
189
190            Subnegotiation::FlowControlSuspend => {
191                self.suspended_flow_control = self.port.flow_control()?;
192                self.port.set_flow_control(FlowControl::None)?;
193                Some(subnegotiation)
194            }
195
196            Subnegotiation::FlowControlResume => {
197                self.port.set_flow_control(self.suspended_flow_control)?;
198                Some(subnegotiation)
199            }
200
201            Subnegotiation::PurgeData(val) => self.handle_purge_data(val)?,
202
203            _ => None,
204        };
205
206        match answer_opt {
207            Some(answer) => Ok(answer.serialize_server(&mut self.tcp_answer_buf)),
208            None => Ok(0),
209        }
210    }
211
212    fn handle_set_control(&mut self, val: u8) -> Result<Option<Subnegotiation>, io::Error> {
213        match val {
214            0 => Ok(Some(Subnegotiation::SetControl(flow_control_to_u8(
215                self.port.flow_control()?,
216            )))),
217            1 | 2 | 3 => {
218                self.port
219                    .set_flow_control(u8_to_flow_control(val).unwrap())?;
220                Ok(Some(Subnegotiation::SetControl(val)))
221            }
222            4 => match self.break_state {
223                true => Ok(Some(Subnegotiation::SetControl(5))),
224                false => Ok(Some(Subnegotiation::SetControl(6))),
225            },
226            5 => {
227                self.port.set_break()?;
228                self.break_state = true;
229                Ok(Some(Subnegotiation::SetControl(val)))
230            }
231            6 => {
232                self.port.clear_break()?;
233                self.break_state = false;
234                Ok(Some(Subnegotiation::SetControl(val)))
235            }
236            7 => match self.port.read_data_set_ready()? {
237                true => Ok(Some(Subnegotiation::SetControl(8))),
238                false => Ok(Some(Subnegotiation::SetControl(9))),
239            },
240            8 => {
241                self.port.write_data_terminal_ready(true)?;
242                Ok(Some(Subnegotiation::SetControl(val)))
243            }
244            9 => {
245                self.port.write_data_terminal_ready(false)?;
246                Ok(Some(Subnegotiation::SetControl(val)))
247            }
248            10 => match self.port.read_clear_to_send()? {
249                true => Ok(Some(Subnegotiation::SetControl(11))),
250                false => Ok(Some(Subnegotiation::SetControl(12))),
251            },
252            11 => {
253                self.port.write_request_to_send(true)?;
254                Ok(Some(Subnegotiation::SetControl(val)))
255            }
256            12 => {
257                self.port.write_request_to_send(false)?;
258                Ok(Some(Subnegotiation::SetControl(val)))
259            }
260            _ => Ok(None),
261        }
262    }
263
264    fn handle_purge_data(&mut self, val: u8) -> Result<Option<Subnegotiation>, io::Error> {
265        match val {
266            1 => {
267                self.port.clear(ClearBuffer::Input)?;
268                Ok(Some(Subnegotiation::PurgeData(val)))
269            }
270            2 => {
271                self.port.clear(ClearBuffer::Output)?;
272                Ok(Some(Subnegotiation::PurgeData(val)))
273            }
274            3 => {
275                self.port.clear(ClearBuffer::Input)?;
276                self.port.clear(ClearBuffer::Output)?;
277                Ok(Some(Subnegotiation::PurgeData(val)))
278            }
279            _ => Ok(None),
280        }
281    }
282}
283
284impl Negotiation {
285    fn get_answer(&self) -> Option<Negotiation> {
286        match (self.intent, self.option) {
287            (
288                negotiation::Intent::Will,
289                negotiation::Option::Binary
290                | negotiation::Option::ComPort
291                | negotiation::Option::SuppressGoAhead,
292            ) => Some(Negotiation {
293                intent: negotiation::Intent::Do,
294                option: self.option,
295            }),
296            (
297                negotiation::Intent::Do,
298                negotiation::Option::Binary
299                | negotiation::Option::ComPort
300                | negotiation::Option::SuppressGoAhead,
301            ) => None,
302            (negotiation::Intent::Will, _) => Some(Negotiation {
303                intent: negotiation::Intent::Dont,
304                option: self.option,
305            }),
306            (negotiation::Intent::Do, _) => Some(Negotiation {
307                intent: negotiation::Intent::Wont,
308                option: self.option,
309            }),
310            _ => panic!(),
311        }
312    }
313}