mavlink_core/connection/
file.rs1use crate::connection::MavConnection;
4use crate::error::{MessageReadError, MessageWriteError};
5use crate::peek_reader::PeekReader;
6use crate::{Connectable, MAVLinkMessageRaw};
7use crate::{MavHeader, MavlinkVersion, Message, ReadVersion};
8use core::ops::DerefMut;
9use std::fs::File;
10use std::io;
11use std::path::PathBuf;
12use std::sync::Mutex;
13
14#[cfg(not(feature = "signing"))]
15use crate::{read_raw_versioned_msg, read_versioned_msg};
16#[cfg(feature = "signing")]
17use crate::{read_raw_versioned_msg_signed, read_versioned_msg_signed, SigningConfig, SigningData};
18
19pub mod config;
20
21use config::FileConfig;
22
23pub fn open(file_path: &PathBuf) -> io::Result<FileConnection> {
24 let file = File::open(file_path)?;
25
26 Ok(FileConnection {
27 file: Mutex::new(PeekReader::new(file)),
28 protocol_version: MavlinkVersion::V2,
29 #[cfg(feature = "signing")]
30 signing_data: None,
31 recv_any_version: false,
32 })
33}
34
35pub struct FileConnection {
36 file: Mutex<PeekReader<File>>,
37 protocol_version: MavlinkVersion,
38 recv_any_version: bool,
39 #[cfg(feature = "signing")]
40 signing_data: Option<SigningData>,
41}
42
43impl<M: Message> MavConnection<M> for FileConnection {
44 fn recv(&self) -> Result<(MavHeader, M), crate::error::MessageReadError> {
45 let mut file = self.file.lock().unwrap();
46
47 loop {
48 let version = ReadVersion::from_conn_cfg::<_, M>(self);
49 #[cfg(not(feature = "signing"))]
50 let result = read_versioned_msg(file.deref_mut(), version);
51 #[cfg(feature = "signing")]
52 let result =
53 read_versioned_msg_signed(file.deref_mut(), version, self.signing_data.as_ref());
54 match result {
55 ok @ Ok(..) => {
56 return ok;
57 }
58 Err(MessageReadError::Io(e)) => {
59 if e.kind() == io::ErrorKind::UnexpectedEof {
60 return Err(MessageReadError::Io(e));
61 }
62 }
63 _ => {}
64 }
65 }
66 }
67
68 fn recv_raw(&self) -> Result<MAVLinkMessageRaw, crate::error::MessageReadError> {
69 let mut file = self.file.lock().unwrap();
70
71 loop {
72 let version = ReadVersion::from_conn_cfg::<_, M>(self);
73 #[cfg(not(feature = "signing"))]
74 let result = read_raw_versioned_msg::<M, _>(file.deref_mut(), version);
75 #[cfg(feature = "signing")]
76 let result = read_raw_versioned_msg_signed::<M, _>(
77 file.deref_mut(),
78 version,
79 self.signing_data.as_ref(),
80 );
81 match result {
82 ok @ Ok(..) => {
83 return ok;
84 }
85 Err(MessageReadError::Io(e)) => {
86 if e.kind() == io::ErrorKind::UnexpectedEof {
87 return Err(MessageReadError::Io(e));
88 }
89 }
90 _ => {}
91 }
92 }
93 }
94
95 fn try_recv(&self) -> Result<(MavHeader, M), crate::error::MessageReadError> {
96 let mut file = self.file.lock().unwrap();
97 let version = ReadVersion::from_conn_cfg::<_, M>(self);
98
99 #[cfg(not(feature = "signing"))]
100 let result = read_versioned_msg(file.deref_mut(), version);
101 #[cfg(feature = "signing")]
102 let result =
103 read_versioned_msg_signed(file.deref_mut(), version, self.signing_data.as_ref());
104
105 result
106 }
107
108 fn send(&self, _header: &MavHeader, _data: &M) -> Result<usize, MessageWriteError> {
109 Ok(0)
110 }
111
112 fn set_protocol_version(&mut self, version: MavlinkVersion) {
113 self.protocol_version = version;
114 }
115
116 fn protocol_version(&self) -> MavlinkVersion {
117 self.protocol_version
118 }
119
120 fn set_allow_recv_any_version(&mut self, allow: bool) {
121 self.recv_any_version = allow;
122 }
123
124 fn allow_recv_any_version(&self) -> bool {
125 self.recv_any_version
126 }
127
128 #[cfg(feature = "signing")]
129 fn setup_signing(&mut self, signing_data: Option<SigningConfig>) {
130 self.signing_data = signing_data.map(SigningData::from_config);
131 }
132}
133
134impl Connectable for FileConfig {
135 fn connect<M: Message>(&self) -> io::Result<Box<dyn MavConnection<M> + Sync + Send>> {
136 Ok(Box::new(open(&self.address)?))
137 }
138}