mavlink_core/connection/
direct_serial.rs1use crate::connectable::SerialConnectable;
4use crate::connection::MavConnection;
5use crate::peek_reader::PeekReader;
6use crate::{MavHeader, MavlinkVersion, Message};
7use core::ops::DerefMut;
8use std::io;
9use std::sync::Mutex;
10
11use crate::error::{MessageReadError, MessageWriteError};
12use serial::{prelude::*, SystemPort};
13
14#[cfg(not(feature = "signing"))]
15use crate::{read_versioned_msg, write_versioned_msg};
16#[cfg(feature = "signing")]
17use crate::{read_versioned_msg_signed, write_versioned_msg_signed, SigningConfig, SigningData};
18
19use super::Connectable;
20
21pub struct SerialConnection {
22 port: Mutex<PeekReader<SystemPort>>,
23 sequence: Mutex<u8>,
24 protocol_version: MavlinkVersion,
25 #[cfg(feature = "signing")]
26 signing_data: Option<SigningData>,
27}
28
29impl<M: Message> MavConnection<M> for SerialConnection {
30 fn recv(&self) -> Result<(MavHeader, M), MessageReadError> {
31 let mut port = self.port.lock().unwrap();
32 loop {
33 #[cfg(not(feature = "signing"))]
34 let result = read_versioned_msg(port.deref_mut(), self.protocol_version);
35 #[cfg(feature = "signing")]
36 let result = read_versioned_msg_signed(
37 port.deref_mut(),
38 self.protocol_version,
39 self.signing_data.as_ref(),
40 );
41 match result {
42 ok @ Ok(..) => {
43 return ok;
44 }
45 Err(MessageReadError::Io(e)) => {
46 if e.kind() == io::ErrorKind::UnexpectedEof {
47 return Err(MessageReadError::Io(e));
48 }
49 }
50 _ => {}
51 }
52 }
53 }
54
55 fn send(&self, header: &MavHeader, data: &M) -> Result<usize, MessageWriteError> {
56 let mut port = self.port.lock().unwrap();
57 let mut sequence = self.sequence.lock().unwrap();
58
59 let header = MavHeader {
60 sequence: *sequence,
61 system_id: header.system_id,
62 component_id: header.component_id,
63 };
64
65 *sequence = sequence.wrapping_add(1);
66
67 #[cfg(not(feature = "signing"))]
68 let result = write_versioned_msg(port.reader_mut(), self.protocol_version, header, data);
69 #[cfg(feature = "signing")]
70 let result = write_versioned_msg_signed(
71 port.reader_mut(),
72 self.protocol_version,
73 header,
74 data,
75 self.signing_data.as_ref(),
76 );
77 result
78 }
79
80 fn set_protocol_version(&mut self, version: MavlinkVersion) {
81 self.protocol_version = version;
82 }
83
84 fn protocol_version(&self) -> MavlinkVersion {
85 self.protocol_version
86 }
87
88 #[cfg(feature = "signing")]
89 fn setup_signing(&mut self, signing_data: Option<SigningConfig>) {
90 self.signing_data = signing_data.map(SigningData::from_config)
91 }
92}
93
94impl Connectable for SerialConnectable {
95 fn connect<M: Message>(&self) -> io::Result<Box<dyn MavConnection<M> + Sync + Send>> {
96 let baud_rate = serial::core::BaudRate::from_speed(self.baud_rate);
97 let settings = serial::core::PortSettings {
98 baud_rate,
99 char_size: serial::Bits8,
100 parity: serial::ParityNone,
101 stop_bits: serial::Stop1,
102 flow_control: serial::FlowNone,
103 };
104
105 let mut port = serial::open(&self.port_name)?;
106 port.configure(&settings)?;
107
108 Ok(Box::new(SerialConnection {
109 port: Mutex::new(PeekReader::new(port)),
110 sequence: Mutex::new(0),
111 protocol_version: MavlinkVersion::V2,
112 #[cfg(feature = "signing")]
113 signing_data: None,
114 }))
115 }
116}