Skip to main content

mavlink_core/connection/file/
sync.rs

1//! File MAVLINK connection
2
3use crate::connection::{Connection, MavConnection};
4use crate::connection_shared::{ConnectionState, read_message, read_raw_message};
5use crate::error::{MessageReadError, MessageWriteError};
6use crate::peek_reader::PeekReader;
7use crate::{Connectable, MAVLinkMessageRaw};
8use crate::{MavHeader, MavlinkVersion, Message};
9use core::ops::DerefMut;
10use std::fs::File;
11use std::io;
12use std::path::PathBuf;
13use std::sync::Mutex;
14
15#[cfg(feature = "mav2-message-signing")]
16use crate::SigningConfig;
17
18use super::config::FileConfig;
19
20pub fn open(file_path: &PathBuf) -> io::Result<FileConnection> {
21    let file = File::open(file_path)?;
22
23    Ok(FileConnection {
24        file: Mutex::new(PeekReader::new(file)),
25        state: ConnectionState::new(),
26    })
27}
28
29pub struct FileConnection {
30    file: Mutex<PeekReader<File>>,
31    state: ConnectionState,
32}
33
34impl<M: Message> MavConnection<M> for FileConnection {
35    fn recv(&self) -> Result<(MavHeader, M), crate::error::MessageReadError> {
36        let mut file = self.file.lock().unwrap();
37
38        loop {
39            let result = read_message::<M, _>(file.deref_mut(), &self.state);
40            match result {
41                ok @ Ok(..) => {
42                    return ok;
43                }
44                Err(MessageReadError::Io(e)) if e.kind() == io::ErrorKind::UnexpectedEof => {
45                    return Err(MessageReadError::Io(e));
46                }
47                _ => {}
48            }
49        }
50    }
51
52    fn recv_raw(&self) -> Result<MAVLinkMessageRaw, crate::error::MessageReadError> {
53        let mut file = self.file.lock().unwrap();
54
55        loop {
56            let result = read_raw_message::<M, _>(file.deref_mut(), &self.state);
57            match result {
58                ok @ Ok(..) => {
59                    return ok;
60                }
61                Err(MessageReadError::Io(e)) if e.kind() == io::ErrorKind::UnexpectedEof => {
62                    return Err(MessageReadError::Io(e));
63                }
64                _ => {}
65            }
66        }
67    }
68
69    fn try_recv(&self) -> Result<(MavHeader, M), crate::error::MessageReadError> {
70        let mut file = self.file.lock().unwrap();
71        read_message::<M, _>(file.deref_mut(), &self.state)
72    }
73
74    fn send(&self, _header: &MavHeader, _data: &M) -> Result<usize, MessageWriteError> {
75        Ok(0)
76    }
77
78    fn set_protocol_version(&mut self, version: MavlinkVersion) {
79        self.state.set_protocol_version(version);
80    }
81
82    fn protocol_version(&self) -> MavlinkVersion {
83        self.state.protocol_version()
84    }
85
86    fn set_allow_recv_any_version(&mut self, allow: bool) {
87        self.state.set_allow_recv_any_version(allow);
88    }
89
90    fn allow_recv_any_version(&self) -> bool {
91        self.state.allow_recv_any_version()
92    }
93
94    #[cfg(feature = "mav2-message-signing")]
95    fn setup_signing(&mut self, signing_data: Option<SigningConfig>) {
96        self.state.setup_signing(signing_data);
97    }
98}
99
100impl Connectable for FileConfig {
101    fn connect<M: Message>(&self) -> io::Result<Connection<M>> {
102        Ok(open(&self.address)?.into())
103    }
104}