mavlink_core/connection/
file.rs1use crate::connectable::FileConnectable;
4use crate::connection::MavConnection;
5use crate::error::{MessageReadError, MessageWriteError};
6use crate::peek_reader::PeekReader;
7use crate::{MavHeader, MavlinkVersion, Message, ReadVersion};
8use core::ops::DerefMut;
9use std::fs::File;
10use std::io;
11use std::sync::Mutex;
12
13#[cfg(not(feature = "signing"))]
14use crate::read_versioned_msg;
15#[cfg(feature = "signing")]
16use crate::{read_versioned_msg_signed, SigningConfig, SigningData};
17
18use super::Connectable;
19
20pub fn open(file_path: &str) -> io::Result<FileConnection> {
21 let file = File::open(file_path)?;
22
23 Ok(FileConnection {
24 file: Mutex::new(PeekReader::new(file)),
25 protocol_version: MavlinkVersion::V2,
26 #[cfg(feature = "signing")]
27 signing_data: None,
28 recv_any_version: false,
29 })
30}
31
32pub struct FileConnection {
33 file: Mutex<PeekReader<File>>,
34 protocol_version: MavlinkVersion,
35 recv_any_version: bool,
36 #[cfg(feature = "signing")]
37 signing_data: Option<SigningData>,
38}
39
40impl<M: Message> MavConnection<M> for FileConnection {
41 fn recv(&self) -> Result<(MavHeader, M), crate::error::MessageReadError> {
42 let mut file = self.file.lock().unwrap();
45
46 loop {
47 let version = ReadVersion::from_conn_cfg::<_, M>(self);
48 #[cfg(not(feature = "signing"))]
49 let result = read_versioned_msg(file.deref_mut(), version);
50 #[cfg(feature = "signing")]
51 let result =
52 read_versioned_msg_signed(file.deref_mut(), version, self.signing_data.as_ref());
53 match result {
54 ok @ Ok(..) => {
55 return ok;
56 }
57 Err(MessageReadError::Io(e)) => {
58 if e.kind() == io::ErrorKind::UnexpectedEof {
59 return Err(MessageReadError::Io(e));
60 }
61 }
62 _ => {}
63 }
64 }
65 }
66
67 fn send(&self, _header: &MavHeader, _data: &M) -> Result<usize, MessageWriteError> {
68 Ok(0)
69 }
70
71 fn set_protocol_version(&mut self, version: MavlinkVersion) {
72 self.protocol_version = version;
73 }
74
75 fn protocol_version(&self) -> MavlinkVersion {
76 self.protocol_version
77 }
78
79 fn set_allow_recv_any_version(&mut self, allow: bool) {
80 self.recv_any_version = allow
81 }
82
83 fn allow_recv_any_version(&self) -> bool {
84 self.recv_any_version
85 }
86
87 #[cfg(feature = "signing")]
88 fn setup_signing(&mut self, signing_data: Option<SigningConfig>) {
89 self.signing_data = signing_data.map(SigningData::from_config)
90 }
91}
92
93impl Connectable for FileConnectable {
94 fn connect<M: Message>(&self) -> io::Result<Box<dyn MavConnection<M> + Sync + Send>> {
95 Ok(Box::new(open(&self.address)?))
96 }
97}