mavlink_core/connection/direct_serial/
sync.rs1use super::config::SerialConfig;
4
5use crate::Dialect;
6use crate::MavlinkReader;
7use crate::connection::sync::{Connectable, DialectConnection, SyncTransport, Transport};
8use serialport::{DataBits, FlowControl, Parity, StopBits};
9use std::io;
10use std::sync::Mutex;
11use std::time::Duration;
12
13#[cfg(windows)]
14use serialport::COMPort as NativePort;
15#[cfg(unix)]
16use serialport::TTYPort as NativePort;
17
18pub struct SerialConnection {
19 read_port: Mutex<MavlinkReader<NativePort>>,
22 write_port: Mutex<NativePort>,
23}
24
25impl SyncTransport for SerialConnection {
26 type Reader = NativePort;
27 type Writer = NativePort;
28
29 fn reader(&self) -> std::sync::MutexGuard<'_, MavlinkReader<Self::Reader>> {
30 self.read_port.lock().unwrap()
31 }
32
33 fn lock_writer(&self) -> Option<std::sync::MutexGuard<'_, Self::Writer>> {
34 Some(self.write_port.lock().unwrap())
35 }
36
37 fn retry_receive(&self, error: &crate::error::MessageReadError) -> bool {
38 !matches!(error, crate::error::MessageReadError::Io(error) if error.kind() == io::ErrorKind::UnexpectedEof)
39 }
40}
41
42impl SerialConfig {
43 pub(crate) fn open(&self) -> io::Result<SerialConnection> {
44 let read_port = serialport::new(&self.port_name, self.baud_rate)
45 .data_bits(DataBits::Eight)
46 .parity(Parity::None)
47 .stop_bits(StopBits::One)
48 .flow_control(FlowControl::None)
49 .timeout(self.timeout.unwrap_or(Duration::from_millis(1)))
50 .open_native()?;
51 let write_port = read_port.try_clone_native()?;
52 Ok(SerialConnection {
53 read_port: Mutex::new(MavlinkReader::with_capacity(
54 self.buffer_capacity(),
55 read_port,
56 )),
57 write_port: Mutex::new(write_port),
58 })
59 }
60}
61
62impl Connectable for SerialConfig {
63 fn connect_with_dialect<D: Dialect + Send + Sync>(
64 &self,
65 dialect: D,
66 ) -> io::Result<DialectConnection<D>> {
67 Ok(DialectConnection::new(
68 Transport::Serial(self.open()?),
69 dialect,
70 ))
71 }
72}