Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Signing #253

Merged
merged 11 commits into from
Aug 26, 2024
10 changes: 7 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,19 @@ jobs:
components: clippy
- uses: actions-rs-plus/clippy-check@v2
with:
args: --all --all-targets --features format-generated-code
args: --all --all-targets --features format-generated-code --features signing --features tokio-1

internal-tests:
runs-on: ubuntu-latest
strategy:
matrix:
dialect: ["ardupilotmega", "asluav", "matrixpilot", "minimal", "paparazzi", "python_array_test", "slugs", "standard", "test", "ualberta", "uavionix", "icarous", "common"]
signing: ["", "--features signing"]
steps:
- uses: actions/checkout@master
- uses: dtolnay/rust-toolchain@stable
- name: Run internal tests
run: cargo test --verbose --features ${{ matrix.dialect }} -- --nocapture
run: cargo test --verbose --features ${{ matrix.dialect }} ${{ matrix.signing }} -- --nocapture

mavlink-dump:
runs-on: ubuntu-latest
Expand All @@ -46,6 +47,9 @@ jobs:

msrv:
runs-on: ubuntu-latest
strategy:
matrix:
signing: ["", "--features signing"]
steps:
- uses: actions/checkout@master
- uses: dtolnay/rust-toolchain@master
Expand All @@ -59,7 +63,7 @@ jobs:
with:
use-cross: true
command: check
args: --all --all-targets
args: --all --all-targets ${{ matrix.signing }}

build:
needs: [formatting, linting, internal-tests, mavlink-dump, msrv]
Expand Down
2 changes: 2 additions & 0 deletions mavlink-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ serde = { version = "1.0.115", optional = true, features = ["derive"] }
serde_arrays = { version = "0.1.0", optional = true }
serial = { version = "0.4", optional = true }
tokio = { version = "1.0", default-features = false, features = ["io-util"], optional = true }
sha2 = { version = "0.10", optional = true }

[features]
"std" = ["byteorder/std"]
Expand All @@ -40,4 +41,5 @@ tokio = { version = "1.0", default-features = false, features = ["io-util"], opt
"embedded-hal-02" = ["dep:nb", "dep:embedded-hal-02"]
"serde" = ["dep:serde", "dep:serde_arrays"]
"tokio-1" = ["dep:tokio"]
"signing" = ["dep:sha2"]
default = ["std", "tcp", "udp", "direct-serial", "serde"]
38 changes: 35 additions & 3 deletions mavlink-core/src/connection/direct_serial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,19 @@

use crate::connection::MavConnection;
use crate::peek_reader::PeekReader;
use crate::{read_versioned_msg, write_versioned_msg, MavHeader, MavlinkVersion, Message};
use crate::{MavHeader, MavlinkVersion, Message};
use core::ops::DerefMut;
use std::io;
use std::sync::Mutex;

use crate::error::{MessageReadError, MessageWriteError};
use serial::{prelude::*, SystemPort};

#[cfg(not(feature = "signing"))]
use crate::{read_versioned_msg, write_versioned_msg};
#[cfg(feature = "signing")]
use crate::{read_versioned_msg_signed, write_versioned_msg_signed, SigningConfig, SigningData};

pub fn open(settings: &str) -> io::Result<SerialConnection> {
let settings_toks: Vec<&str> = settings.split(':').collect();
if settings_toks.len() < 2 {
Expand Down Expand Up @@ -45,20 +50,32 @@ pub fn open(settings: &str) -> io::Result<SerialConnection> {
port: Mutex::new(PeekReader::new(port)),
sequence: Mutex::new(0),
protocol_version: MavlinkVersion::V2,
#[cfg(feature = "signing")]
signing_data: None,
})
}

pub struct SerialConnection {
port: Mutex<PeekReader<SystemPort>>,
sequence: Mutex<u8>,
protocol_version: MavlinkVersion,
#[cfg(feature = "signing")]
signing_data: Option<SigningData>,
}

impl<M: Message> MavConnection<M> for SerialConnection {
fn recv(&self) -> Result<(MavHeader, M), MessageReadError> {
let mut port = self.port.lock().unwrap();
loop {
match read_versioned_msg(port.deref_mut(), self.protocol_version) {
#[cfg(not(feature = "signing"))]
let result = read_versioned_msg(port.deref_mut(), self.protocol_version);
#[cfg(feature = "signing")]
let result = read_versioned_msg_signed(
port.deref_mut(),
self.protocol_version,
self.signing_data.as_ref(),
);
match result {
ok @ Ok(..) => {
return ok;
}
Expand All @@ -84,7 +101,17 @@ impl<M: Message> MavConnection<M> for SerialConnection {

*sequence = sequence.wrapping_add(1);

write_versioned_msg(port.reader_mut(), self.protocol_version, header, data)
#[cfg(not(feature = "signing"))]
let result = write_versioned_msg(port.reader_mut(), self.protocol_version, header, data);
#[cfg(feature = "signing")]
let result = write_versioned_msg_signed(
port.reader_mut(),
self.protocol_version,
header,
data,
self.signing_data.as_ref(),
);
result
}

fn set_protocol_version(&mut self, version: MavlinkVersion) {
Expand All @@ -94,4 +121,9 @@ impl<M: Message> MavConnection<M> for SerialConnection {
fn protocol_version(&self) -> MavlinkVersion {
self.protocol_version
}

#[cfg(feature = "signing")]
fn setup_signing(&mut self, signing_data: Option<SigningConfig>) {
self.signing_data = signing_data.map(SigningData::from_config)
}
}
26 changes: 24 additions & 2 deletions mavlink-core/src/connection/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,33 @@
use crate::connection::MavConnection;
use crate::error::{MessageReadError, MessageWriteError};
use crate::peek_reader::PeekReader;
use crate::{read_versioned_msg, MavHeader, MavlinkVersion, Message};
use crate::{MavHeader, MavlinkVersion, Message};
use core::ops::DerefMut;
use std::fs::File;
use std::io;
use std::sync::Mutex;

#[cfg(not(feature = "signing"))]
use crate::read_versioned_msg;
#[cfg(feature = "signing")]
use crate::{read_versioned_msg_signed, SigningConfig, SigningData};

pub fn open(file_path: &str) -> io::Result<FileConnection> {
let file = File::open(file_path)?;

Ok(FileConnection {
file: Mutex::new(PeekReader::new(file)),
protocol_version: MavlinkVersion::V2,
#[cfg(feature = "signing")]
signing_data: None,
})
}

pub struct FileConnection {
file: Mutex<PeekReader<File>>,
protocol_version: MavlinkVersion,
#[cfg(feature = "signing")]
signing_data: Option<SigningData>,
}

impl<M: Message> MavConnection<M> for FileConnection {
Expand All @@ -30,7 +39,15 @@ impl<M: Message> MavConnection<M> for FileConnection {
let mut file = self.file.lock().unwrap();

loop {
match read_versioned_msg(file.deref_mut(), self.protocol_version) {
#[cfg(not(feature = "signing"))]
let result = read_versioned_msg(file.deref_mut(), self.protocol_version);
#[cfg(feature = "signing")]
let result = read_versioned_msg_signed(
file.deref_mut(),
self.protocol_version,
self.signing_data.as_ref(),
);
match result {
ok @ Ok(..) => {
return ok;
}
Expand All @@ -55,4 +72,9 @@ impl<M: Message> MavConnection<M> for FileConnection {
fn protocol_version(&self) -> MavlinkVersion {
self.protocol_version
}

#[cfg(feature = "signing")]
fn setup_signing(&mut self, signing_data: Option<SigningConfig>) {
self.signing_data = signing_data.map(SigningData::from_config)
}
}
7 changes: 7 additions & 0 deletions mavlink-core/src/connection/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ mod udp;
#[cfg(feature = "direct-serial")]
mod direct_serial;

#[cfg(feature = "signing")]
use crate::SigningConfig;

mod file;

/// A MAVLink connection
Expand Down Expand Up @@ -47,6 +50,10 @@ pub trait MavConnection<M: Message> {
let header = MavHeader::default();
self.send(&header, data)
}

/// Setup secret key used for message signing, or disable message signing
#[cfg(feature = "signing")]
fn setup_signing(&mut self, signing_data: Option<SigningConfig>);
}

/// Connect to a MAVLink node by address string.
Expand Down
41 changes: 38 additions & 3 deletions mavlink-core/src/connection/tcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use crate::connection::MavConnection;
use crate::peek_reader::PeekReader;
use crate::{read_versioned_msg, write_versioned_msg, MavHeader, MavlinkVersion, Message};
use crate::{MavHeader, MavlinkVersion, Message};
use core::ops::DerefMut;
use std::io;
use std::net::ToSocketAddrs;
Expand All @@ -12,6 +12,12 @@ use std::time::Duration;

use super::get_socket_addr;

#[cfg(not(feature = "signing"))]
use crate::{read_versioned_msg, write_versioned_msg};

#[cfg(feature = "signing")]
use crate::{read_versioned_msg_signed, write_versioned_msg_signed, SigningConfig, SigningData};

pub fn select_protocol<M: Message>(
address: &str,
) -> io::Result<Box<dyn MavConnection<M> + Sync + Send>> {
Expand Down Expand Up @@ -42,6 +48,8 @@ pub fn tcpout<T: ToSocketAddrs>(address: T) -> io::Result<TcpConnection> {
sequence: 0,
}),
protocol_version: MavlinkVersion::V2,
#[cfg(feature = "signing")]
signing_data: None,
})
}

Expand All @@ -60,6 +68,8 @@ pub fn tcpin<T: ToSocketAddrs>(address: T) -> io::Result<TcpConnection> {
sequence: 0,
}),
protocol_version: MavlinkVersion::V2,
#[cfg(feature = "signing")]
signing_data: None,
})
}
Err(e) => {
Expand All @@ -78,6 +88,8 @@ pub struct TcpConnection {
reader: Mutex<PeekReader<TcpStream>>,
writer: Mutex<TcpWrite>,
protocol_version: MavlinkVersion,
#[cfg(feature = "signing")]
signing_data: Option<SigningData>,
}

struct TcpWrite {
Expand All @@ -88,7 +100,15 @@ struct TcpWrite {
impl<M: Message> MavConnection<M> for TcpConnection {
fn recv(&self) -> Result<(MavHeader, M), crate::error::MessageReadError> {
let mut reader = self.reader.lock().unwrap();
read_versioned_msg(reader.deref_mut(), self.protocol_version)
#[cfg(not(feature = "signing"))]
let result = read_versioned_msg(reader.deref_mut(), self.protocol_version);
#[cfg(feature = "signing")]
let result = read_versioned_msg_signed(
reader.deref_mut(),
self.protocol_version,
self.signing_data.as_ref(),
);
result
}

fn send(&self, header: &MavHeader, data: &M) -> Result<usize, crate::error::MessageWriteError> {
Expand All @@ -101,7 +121,17 @@ impl<M: Message> MavConnection<M> for TcpConnection {
};

lock.sequence = lock.sequence.wrapping_add(1);
write_versioned_msg(&mut lock.socket, self.protocol_version, header, data)
#[cfg(not(feature = "signing"))]
let result = write_versioned_msg(&mut lock.socket, self.protocol_version, header, data);
#[cfg(feature = "signing")]
let result = write_versioned_msg_signed(
&mut lock.socket,
self.protocol_version,
header,
data,
self.signing_data.as_ref(),
);
result
}

fn set_protocol_version(&mut self, version: MavlinkVersion) {
Expand All @@ -111,4 +141,9 @@ impl<M: Message> MavConnection<M> for TcpConnection {
fn protocol_version(&self) -> MavlinkVersion {
self.protocol_version
}

#[cfg(feature = "signing")]
fn setup_signing(&mut self, signing_data: Option<SigningConfig>) {
self.signing_data = signing_data.map(SigningData::from_config)
}
}
Loading
Loading