mavlink_core/connection/
file.rs1use crate::connection::{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 = "mav2-message-signing"))]
15use crate::{read_versioned_msg, read_versioned_raw_message};
16#[cfg(feature = "mav2-message-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 = "mav2-message-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 = "mav2-message-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 let version = ReadVersion::from_conn_cfg::<_, M>(self);
49
50 loop {
51 #[cfg(not(feature = "mav2-message-signing"))]
52 let result = read_versioned_msg(file.deref_mut(), version);
53 #[cfg(feature = "mav2-message-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)) if e.kind() == io::ErrorKind::UnexpectedEof => {
61 return Err(MessageReadError::Io(e));
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 let version = ReadVersion::from_conn_cfg::<_, M>(self);
71
72 loop {
73 #[cfg(not(feature = "mav2-message-signing"))]
74 let result = read_versioned_raw_message::<M, _>(file.deref_mut(), version);
75 #[cfg(feature = "mav2-message-signing")]
76 let result = read_versioned_raw_message_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)) if e.kind() == io::ErrorKind::UnexpectedEof => {
86 return Err(MessageReadError::Io(e));
87 }
88 _ => {}
89 }
90 }
91 }
92
93 fn try_recv(&self) -> Result<(MavHeader, M), crate::error::MessageReadError> {
94 let mut file = self.file.lock().unwrap();
95 let version = ReadVersion::from_conn_cfg::<_, M>(self);
96
97 #[cfg(not(feature = "mav2-message-signing"))]
98 let result = read_versioned_msg(file.deref_mut(), version);
99 #[cfg(feature = "mav2-message-signing")]
100 let result =
101 read_versioned_msg_signed(file.deref_mut(), version, self.signing_data.as_ref());
102
103 result
104 }
105
106 fn send(&self, _header: &MavHeader, _data: &M) -> Result<usize, MessageWriteError> {
107 Ok(0)
108 }
109
110 fn set_protocol_version(&mut self, version: MavlinkVersion) {
111 self.protocol_version = version;
112 }
113
114 fn protocol_version(&self) -> MavlinkVersion {
115 self.protocol_version
116 }
117
118 fn set_allow_recv_any_version(&mut self, allow: bool) {
119 self.recv_any_version = allow;
120 }
121
122 fn allow_recv_any_version(&self) -> bool {
123 self.recv_any_version
124 }
125
126 #[cfg(feature = "mav2-message-signing")]
127 fn setup_signing(&mut self, signing_data: Option<SigningConfig>) {
128 self.signing_data = signing_data.map(SigningData::from_config);
129 }
130}
131
132impl Connectable for FileConfig {
133 fn connect<M: Message>(&self) -> io::Result<Connection<M>> {
134 Ok(open(&self.address)?.into())
135 }
136}