serial_io/
unix.rs

1//! Unix impl of mio-enabled serial ports.
2
3use std::io::{self, Read, Write};
4use std::os::unix::prelude::*;
5use std::time::Duration;
6
7use mio::event::Source;
8use mio::unix::SourceFd;
9use mio::{Interest, Registry, Token};
10
11use serialport::{
12    ClearBuffer, DataBits, Error, ErrorKind, FlowControl, Parity, SerialPort, SerialPortBuilder,
13    StopBits, TTYPort,
14};
15
16use nix::sys::termios::{self, SetArg, SpecialCharacterIndices};
17use nix::{self, libc};
18
19#[cfg(feature = "tokio")]
20pub mod tokio;
21
22/// *nix serial port using termios
23#[derive(Debug)]
24pub struct Serial {
25    inner: TTYPort,
26}
27
28fn map_nix_error(e: nix::Error) -> Error {
29    Error {
30        kind: ErrorKind::Io(io::ErrorKind::Other),
31        description: e.to_string(),
32    }
33}
34
35impl Serial {
36    /// Open a non-blocking serial port from the provided builder.
37    ///
38    /// ## Example
39    ///
40    /// ```ignore
41    /// use serial_io::{build, Serial, TTYPort};
42    ///
43    /// let builder = build(tty_path, 9600);
44    /// let serial = Serial::from_builder(&builder).unwrap();
45    /// # fn main() {}
46    /// ```
47    pub fn from_builder(builder: &SerialPortBuilder) -> crate::Result<Self> {
48        let port = TTYPort::open(builder).unwrap();
49        Self::from_serial(port)
50    }
51
52    fn from_serial(port: TTYPort) -> crate::Result<Self> {
53        // Get the termios structure
54        let mut t = termios::tcgetattr(port.as_raw_fd()).map_err(map_nix_error)?;
55
56        // Set VMIN = 1 to block until at least one character is received.
57        t.control_chars[SpecialCharacterIndices::VMIN as usize] = 1;
58        termios::tcsetattr(port.as_raw_fd(), SetArg::TCSANOW, &t).map_err(map_nix_error)?;
59
60        // Set the O_NONBLOCK flag.
61        let flags = unsafe { libc::fcntl(port.as_raw_fd(), libc::F_GETFL) };
62        if flags < 0 {
63            return Err(io::Error::last_os_error().into());
64        }
65
66        match unsafe { libc::fcntl(port.as_raw_fd(), libc::F_SETFL, flags | libc::O_NONBLOCK) } {
67            0 => Ok(Serial { inner: port }),
68            _ => Err(io::Error::last_os_error().into()),
69        }
70    }
71
72    /// Create a pair of pseudo serial terminals
73    ///
74    /// ## Returns
75    /// Two connected `Serial` objects: `(master, slave)`
76    ///
77    /// ## Errors
78    /// Attempting any IO or parameter settings on the slave tty after the master
79    /// tty is closed will return errors.
80    ///
81    /// ## Examples
82    ///
83    /// ```
84    /// use serial_io::Serial;
85    ///
86    /// let (master, slave) = Serial::pair().unwrap();
87    /// ```
88    pub fn pair() -> crate::Result<(Self, Self)> {
89        let (master, slave) = TTYPort::pair()?;
90
91        let master = Self::from_serial(master)?;
92        let slave = Self::from_serial(slave)?;
93
94        Ok((master, slave))
95    }
96
97    /// Sets the exclusivity of the port
98    ///
99    /// If a port is exclusive, then trying to open the same device path again
100    /// will fail.
101    ///
102    /// See the man pages for the tiocexcl and tiocnxcl ioctl's for more details.
103    ///
104    /// ## Errors
105    ///
106    /// * `Io` for any error while setting exclusivity for the port.
107    pub fn set_exclusive(&mut self, exclusive: bool) -> crate::Result<()> {
108        self.inner.set_exclusive(exclusive).map_err(|e| e)
109    }
110
111    /// Returns the exclusivity of the port
112    ///
113    /// If a port is exclusive, then trying to open the same device path again
114    /// will fail.
115    pub fn exclusive(&self) -> bool {
116        self.inner.exclusive()
117    }
118}
119
120impl SerialPort for Serial {
121    /// Return the name associated with the serial port, if known.
122    fn name(&self) -> Option<String> {
123        self.inner.name()
124    }
125
126    /// Returns the current baud rate.
127    ///
128    /// This function returns `None` if the baud rate could not be determined. This may occur if
129    /// the hardware is in an uninitialized state. Setting a baud rate with `set_baud_rate()`
130    /// should initialize the baud rate to a supported value.
131    fn baud_rate(&self) -> crate::Result<u32> {
132        self.inner.baud_rate()
133    }
134
135    /// Returns the character size.
136    ///
137    /// This function returns `None` if the character size could not be determined. This may occur
138    /// if the hardware is in an uninitialized state or is using a non-standard character size.
139    /// Setting a baud rate with `set_char_size()` should initialize the character size to a
140    /// supported value.
141    fn data_bits(&self) -> crate::Result<DataBits> {
142        self.inner.data_bits()
143    }
144
145    /// Returns the flow control mode.
146    ///
147    /// This function returns `None` if the flow control mode could not be determined. This may
148    /// occur if the hardware is in an uninitialized state or is using an unsupported flow control
149    /// mode. Setting a flow control mode with `set_flow_control()` should initialize the flow
150    /// control mode to a supported value.
151    fn flow_control(&self) -> crate::Result<FlowControl> {
152        self.inner.flow_control()
153    }
154
155    /// Returns the parity-checking mode.
156    ///
157    /// This function returns `None` if the parity mode could not be determined. This may occur if
158    /// the hardware is in an uninitialized state or is using a non-standard parity mode. Setting
159    /// a parity mode with `set_parity()` should initialize the parity mode to a supported value.
160    fn parity(&self) -> crate::Result<Parity> {
161        self.inner.parity()
162    }
163
164    /// Returns the number of stop bits.
165    ///
166    /// This function returns `None` if the number of stop bits could not be determined. This may
167    /// occur if the hardware is in an uninitialized state or is using an unsupported stop bit
168    /// configuration. Setting the number of stop bits with `set_stop-bits()` should initialize the
169    /// stop bits to a supported value.
170    fn stop_bits(&self) -> crate::Result<StopBits> {
171        self.inner.stop_bits()
172    }
173
174    /// Returns the current timeout. This parameter is const and equal to zero and implemented due
175    /// to required for trait completeness.
176    fn timeout(&self) -> Duration {
177        Duration::from_secs(0)
178    }
179
180    /// Sets the baud rate.
181    ///
182    /// ## Errors
183    ///
184    /// If the implementation does not support the requested baud rate, this function may return an
185    /// `InvalidInput` error. Even if the baud rate is accepted by `set_baud_rate()`, it may not be
186    /// supported by the underlying hardware.
187    fn set_baud_rate(&mut self, baud_rate: u32) -> crate::Result<()> {
188        self.inner.set_baud_rate(baud_rate)
189    }
190
191    /// Sets the character size.
192    fn set_data_bits(&mut self, data_bits: DataBits) -> crate::Result<()> {
193        self.inner.set_data_bits(data_bits)
194    }
195
196    /// Sets the flow control mode.
197    fn set_flow_control(&mut self, flow_control: FlowControl) -> crate::Result<()> {
198        self.inner.set_flow_control(flow_control)
199    }
200
201    /// Sets the parity-checking mode.
202    fn set_parity(&mut self, parity: Parity) -> crate::Result<()> {
203        self.inner.set_parity(parity)
204    }
205
206    /// Sets the number of stop bits.
207    fn set_stop_bits(&mut self, stop_bits: StopBits) -> crate::Result<()> {
208        self.inner.set_stop_bits(stop_bits)
209    }
210
211    /// Sets the timeout for future I/O operations. This parameter is ignored but
212    /// required for trait completeness.
213    fn set_timeout(&mut self, _: Duration) -> crate::Result<()> {
214        Ok(())
215    }
216
217    // Functions for setting non-data control signal pins
218
219    /// Sets the state of the RTS (Request To Send) control signal.
220    ///
221    /// Setting a value of `true` asserts the RTS control signal. `false` clears the signal.
222    ///
223    /// ## Errors
224    ///
225    /// This function returns an error if the RTS control signal could not be set to the desired
226    /// state on the underlying hardware:
227    ///
228    /// * `NoDevice` if the device was disconnected.
229    /// * `Io` for any other type of I/O error.
230    fn write_request_to_send(&mut self, level: bool) -> crate::Result<()> {
231        self.inner.write_request_to_send(level)
232    }
233
234    /// Writes to the Data Terminal Ready pin
235    ///
236    /// Setting a value of `true` asserts the DTR control signal. `false` clears the signal.
237    ///
238    /// ## Errors
239    ///
240    /// This function returns an error if the DTR control signal could not be set to the desired
241    /// state on the underlying hardware:
242    ///
243    /// * `NoDevice` if the device was disconnected.
244    /// * `Io` for any other type of I/O error.
245    fn write_data_terminal_ready(&mut self, level: bool) -> crate::Result<()> {
246        self.inner.write_data_terminal_ready(level)
247    }
248
249    // Functions for reading additional pins
250
251    /// Reads the state of the CTS (Clear To Send) control signal.
252    ///
253    /// This function returns a boolean that indicates whether the CTS control signal is asserted.
254    ///
255    /// ## Errors
256    ///
257    /// This function returns an error if the state of the CTS control signal could not be read
258    /// from the underlying hardware:
259    ///
260    /// * `NoDevice` if the device was disconnected.
261    /// * `Io` for any other type of I/O error.
262    fn read_clear_to_send(&mut self) -> crate::Result<bool> {
263        self.inner.read_clear_to_send()
264    }
265
266    /// Reads the state of the Data Set Ready control signal.
267    ///
268    /// This function returns a boolean that indicates whether the DSR control signal is asserted.
269    ///
270    /// ## Errors
271    ///
272    /// This function returns an error if the state of the DSR control signal could not be read
273    /// from the underlying hardware:
274    ///
275    /// * `NoDevice` if the device was disconnected.
276    /// * `Io` for any other type of I/O error.
277    fn read_data_set_ready(&mut self) -> crate::Result<bool> {
278        self.inner.read_data_set_ready()
279    }
280
281    /// Reads the state of the Ring Indicator control signal.
282    ///
283    /// This function returns a boolean that indicates whether the RI control signal is asserted.
284    ///
285    /// ## Errors
286    ///
287    /// This function returns an error if the state of the RI control signal could not be read from
288    /// the underlying hardware:
289    ///
290    /// * `NoDevice` if the device was disconnected.
291    /// * `Io` for any other type of I/O error.
292    fn read_ring_indicator(&mut self) -> crate::Result<bool> {
293        self.inner.read_ring_indicator()
294    }
295
296    /// Reads the state of the Carrier Detect control signal.
297    ///
298    /// This function returns a boolean that indicates whether the CD control signal is asserted.
299    ///
300    /// ## Errors
301    ///
302    /// This function returns an error if the state of the CD control signal could not be read from
303    /// the underlying hardware:
304    ///
305    /// * `NoDevice` if the device was disconnected.
306    /// * `Io` for any other type of I/O error.
307    fn read_carrier_detect(&mut self) -> crate::Result<bool> {
308        self.inner.read_carrier_detect()
309    }
310
311    /// Gets the number of bytes available to be read from the input buffer.
312    ///
313    /// # Errors
314    ///
315    /// This function may return the following errors:
316    ///
317    /// * `NoDevice` if the device was disconnected.
318    /// * `Io` for any other type of I/O error.
319    fn bytes_to_read(&self) -> crate::Result<u32> {
320        self.inner.bytes_to_read()
321    }
322
323    /// Get the number of bytes written to the output buffer, awaiting transmission.
324    ///
325    /// # Errors
326    ///
327    /// This function may return the following errors:
328    ///
329    /// * `NoDevice` if the device was disconnected.
330    /// * `Io` for any other type of I/O error.
331    fn bytes_to_write(&self) -> crate::Result<u32> {
332        self.inner.bytes_to_write()
333    }
334
335    /// Discards all bytes from the serial driver's input buffer and/or output buffer.
336    ///
337    /// # Errors
338    ///
339    /// This function may return the following errors:
340    ///
341    /// * `NoDevice` if the device was disconnected.
342    /// * `Io` for any other type of I/O error.
343    fn clear(&self, buffer_to_clear: ClearBuffer) -> crate::Result<()> {
344        self.inner.clear(buffer_to_clear)
345    }
346
347    /// Attempts to clone the `SerialPort`. This allow you to write and read simultaneously from the
348    /// same serial connection. Please note that if you want a real asynchronous serial port you
349    /// should look at [mio-serial](https://crates.io/crates/mio-serial) or
350    /// [tokio-serial](https://crates.io/crates/tokio-serial).
351    ///
352    /// Also, you must be very carefull when changing the settings of a cloned `SerialPort` : since
353    /// the settings are cached on a per object basis, trying to modify them from two different
354    /// objects can cause some nasty behavior.
355    ///
356    /// # Errors
357    ///
358    /// This function returns an error if the serial port couldn't be cloned.
359    fn try_clone(&self) -> crate::Result<Box<dyn SerialPort>> {
360        self.inner.try_clone()
361    }
362
363    /// Start transmitting a break
364    fn set_break(&self) -> crate::Result<()> {
365        self.inner.set_break()
366    }
367
368    /// Stop transmitting a break
369    fn clear_break(&self) -> crate::Result<()> {
370        self.inner.clear_break()
371    }
372}
373
374macro_rules! uninterruptibly {
375    ($e:expr) => {{
376        loop {
377            match $e {
378                Err(ref error) if error.kind() == io::ErrorKind::Interrupted => {}
379                res => break res,
380            }
381        }
382    }};
383}
384
385impl Read for Serial {
386    fn read(&mut self, bytes: &mut [u8]) -> io::Result<usize> {
387        uninterruptibly!(match unsafe {
388            libc::read(
389                self.as_raw_fd(),
390                bytes.as_ptr() as *mut libc::c_void,
391                bytes.len() as libc::size_t,
392            )
393        } {
394            x if x >= 0 => Ok(x as usize),
395            _ => Err(io::Error::last_os_error()),
396        })
397    }
398}
399
400impl Write for Serial {
401    fn write(&mut self, bytes: &[u8]) -> io::Result<usize> {
402        uninterruptibly!(match unsafe {
403            libc::write(
404                self.as_raw_fd(),
405                bytes.as_ptr() as *const libc::c_void,
406                bytes.len() as libc::size_t,
407            )
408        } {
409            x if x >= 0 => Ok(x as usize),
410            _ => Err(io::Error::last_os_error()),
411        })
412    }
413
414    fn flush(&mut self) -> io::Result<()> {
415        uninterruptibly!(
416            termios::tcdrain(self.inner.as_raw_fd()).map_err(|error| match error {
417                nix::Error::Sys(errno) => io::Error::from(errno),
418                error => io::Error::new(io::ErrorKind::Other, error.to_string()),
419            })
420        )
421    }
422}
423
424impl<'a> Read for &'a Serial {
425    fn read(&mut self, bytes: &mut [u8]) -> io::Result<usize> {
426        uninterruptibly!(match unsafe {
427            libc::read(
428                self.as_raw_fd(),
429                bytes.as_ptr() as *mut libc::c_void,
430                bytes.len() as libc::size_t,
431            )
432        } {
433            x if x >= 0 => Ok(x as usize),
434            _ => Err(io::Error::last_os_error()),
435        })
436    }
437}
438
439impl<'a> Write for &'a Serial {
440    fn write(&mut self, bytes: &[u8]) -> io::Result<usize> {
441        uninterruptibly!(match unsafe {
442            libc::write(
443                self.as_raw_fd(),
444                bytes.as_ptr() as *const libc::c_void,
445                bytes.len() as libc::size_t,
446            )
447        } {
448            x if x >= 0 => Ok(x as usize),
449            _ => Err(io::Error::last_os_error()),
450        })
451    }
452
453    fn flush(&mut self) -> io::Result<()> {
454        uninterruptibly!(
455            termios::tcdrain(self.inner.as_raw_fd()).map_err(|error| match error {
456                nix::Error::Sys(errno) => io::Error::from(errno),
457                error => io::Error::new(io::ErrorKind::Other, error.to_string()),
458            })
459        )
460    }
461}
462
463impl AsRawFd for Serial {
464    fn as_raw_fd(&self) -> RawFd {
465        self.inner.as_raw_fd()
466    }
467}
468
469impl IntoRawFd for Serial {
470    fn into_raw_fd(self) -> RawFd {
471        self.inner.into_raw_fd()
472    }
473}
474
475impl FromRawFd for Serial {
476    unsafe fn from_raw_fd(fd: RawFd) -> Self {
477        let port = TTYPort::from_raw_fd(fd);
478        Serial { inner: port }
479    }
480}
481
482impl Source for Serial {
483    fn register(
484        &mut self,
485        registry: &Registry,
486        token: Token,
487        interests: Interest,
488    ) -> io::Result<()> {
489        SourceFd(&self.as_raw_fd()).register(registry, token, interests)
490    }
491
492    fn reregister(
493        &mut self,
494        registry: &Registry,
495        token: Token,
496        interests: Interest,
497    ) -> io::Result<()> {
498        SourceFd(&self.as_raw_fd()).reregister(registry, token, interests)
499    }
500
501    fn deregister(&mut self, registry: &Registry) -> io::Result<()> {
502        SourceFd(&self.as_raw_fd()).deregister(registry)
503    }
504}