mavlink_core/connection/
file.rs

1//! File MAVLINK connection
2
3use crate::connectable::FileConnectable;
4use crate::connection::MavConnection;
5use crate::error::{MessageReadError, MessageWriteError};
6use crate::peek_reader::PeekReader;
7use crate::{MavHeader, MavlinkVersion, Message};
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    })
29}
30
31pub struct FileConnection {
32    file: Mutex<PeekReader<File>>,
33    protocol_version: MavlinkVersion,
34    #[cfg(feature = "signing")]
35    signing_data: Option<SigningData>,
36}
37
38impl<M: Message> MavConnection<M> for FileConnection {
39    fn recv(&self) -> Result<(MavHeader, M), crate::error::MessageReadError> {
40        // TODO: fix that unwrap
41        // not simple b/c PoisonError is not simple
42        let mut file = self.file.lock().unwrap();
43
44        loop {
45            #[cfg(not(feature = "signing"))]
46            let result = read_versioned_msg(file.deref_mut(), self.protocol_version);
47            #[cfg(feature = "signing")]
48            let result = read_versioned_msg_signed(
49                file.deref_mut(),
50                self.protocol_version,
51                self.signing_data.as_ref(),
52            );
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    #[cfg(feature = "signing")]
80    fn setup_signing(&mut self, signing_data: Option<SigningConfig>) {
81        self.signing_data = signing_data.map(SigningData::from_config)
82    }
83}
84
85impl Connectable for FileConnectable {
86    fn connect<M: Message>(&self) -> io::Result<Box<dyn MavConnection<M> + Sync + Send>> {
87        Ok(Box::new(open(&self.address)?))
88    }
89}