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