Skip to content

Commit

Permalink
refactor: code refactor and more defmt trait implementations
Browse files Browse the repository at this point in the history
  • Loading branch information
tact1m4n3 committed May 18, 2024
1 parent aee8e21 commit 27e7d37
Show file tree
Hide file tree
Showing 8 changed files with 393 additions and 386 deletions.
374 changes: 25 additions & 349 deletions src/lib.rs

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src/address.rs → src/packet/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use num_enum::TryFromPrimitive;
/// Represents all CRSF packet addresses
#[non_exhaustive]
#[derive(Clone, Copy, Debug, PartialEq, Eq, TryFromPrimitive)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[repr(u8)]
pub enum PacketAddress {
Broadcast = 0x00,
Expand Down
43 changes: 29 additions & 14 deletions src/raw_packet.rs → src/packet/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,22 @@
use crate::{
address::PacketAddress, CrsfError, LinkStatistics, Packet, PacketType, Payload,
RcChannelsPacked, CRSF_MAX_LEN,
};
use crate::{Error, CRSF_MAX_LEN};

mod address;
pub use address::*;

mod typ;
pub use typ::*;

mod payload;
pub use payload::*;

/// Represents a packet
#[non_exhaustive]
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Packet {
LinkStatistics(LinkStatistics),
RcChannelsPacked(RcChannelsPacked),
}

/// Represents a raw packet (not parsed)
#[derive(Clone, Copy, Debug)]
Expand All @@ -20,7 +35,7 @@ impl RawPacket {

/// Create a new RawPacket from the given slice. The slice must be
/// at most `CRSF_MAX_LEN`bytes long.
pub fn new(slice: &[u8]) -> Result<RawPacket, CrsfError> {
pub fn new(slice: &[u8]) -> Result<RawPacket, Error> {
let mut packet = RawPacket {
buf: [0u8; CRSF_MAX_LEN],
len: slice.len(),
Expand All @@ -29,7 +44,7 @@ impl RawPacket {
packet
.buf
.get_mut(..slice.len())
.ok_or(CrsfError::BufferError)?
.ok_or(Error::BufferError)?
.copy_from_slice(slice);

Ok(packet)
Expand All @@ -41,13 +56,13 @@ impl RawPacket {
}

/// Get the payload section of the raw packet
pub fn payload(&self) -> Result<&[u8], CrsfError> {
pub fn payload(&self) -> Result<&[u8], Error> {
match (self.is_extended(), self.as_slice()) {
// Skip the [sync], [len], [type], [src], [dst] and [crc] bytes
(true, [_, _, _, _, _, payload @ .., _]) => Ok(payload),
// Skip the [sync], [len], [type] and [crc] bytes
(false, [_, _, _, payload @ .., _]) => Ok(payload),
_ => Err(CrsfError::BufferError),
_ => Err(Error::BufferError),
}
}

Expand All @@ -64,24 +79,24 @@ impl RawPacket {
/// Get the source and destination addresses of the packet.
/// This is only valid for extended packets, and will
/// return an error otherwise
pub fn dst_src(&self) -> Result<(PacketAddress, PacketAddress), CrsfError> {
pub fn dst_src(&self) -> Result<(PacketAddress, PacketAddress), Error> {
if self.is_extended() {
if let [_, _, _, dst, src, ..] = self.as_slice() {
match (PacketAddress::try_from(*dst), PacketAddress::try_from(*src)) {
(Ok(dst), Ok(src)) => Ok((dst, src)),
_ => Err(CrsfError::InvalidPayload),
_ => Err(Error::InvalidPayload),
}
} else {
Err(CrsfError::BufferError)
Err(Error::BufferError)
}
} else {
// NOTE Not sure what the error here should be
Err(CrsfError::UnknownType { typ: 0 })
Err(Error::UnknownType { typ: 0 })
}
}

/// Convert the raw packet into a parsed packet
pub fn into_packet(&self) -> Result<Packet, CrsfError> {
pub fn to_packet(&self) -> Result<Packet, Error> {
let payload = self.payload()?;
match PacketType::try_from(self.buf[2]) {
Ok(PacketType::RcChannelsPacked) => {
Expand All @@ -90,7 +105,7 @@ impl RawPacket {
Ok(PacketType::LinkStatistics) => {
LinkStatistics::decode(payload).map(Packet::LinkStatistics)
}
_ => Err(CrsfError::UnknownType { typ: self.buf[2] }),
_ => Err(Error::UnknownType { typ: self.buf[2] }),
}
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
//! LinkStatistics packet and related functions/implementations
use super::Payload;
use crate::to_array::{mut_array_start, ref_array_start};
use crate::{CrsfError, PacketType};
use crate::{
to_array::{mut_array_start, ref_array_start},
Error, PacketType, Payload,
};

/// Represents a LinkStatistics packet
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[allow(missing_docs)]
pub struct LinkStatistics {
pub uplink_rssi_1: u8,
Expand Down Expand Up @@ -59,14 +61,14 @@ impl Payload for LinkStatistics {
PacketType::LinkStatistics
}

fn decode(buf: &[u8]) -> Result<Self, crate::CrsfError> {
let data: &[u8; LEN] = ref_array_start(buf).ok_or(CrsfError::BufferError)?;
fn decode(buf: &[u8]) -> Result<Self, Error> {
let data: &[u8; LEN] = ref_array_start(buf).ok_or(Error::BufferError)?;

Ok(raw_decode(data))
}

fn encode<'a>(&self, buf: &'a mut [u8]) -> Result<&'a [u8], crate::CrsfError> {
let data: &mut [u8; LEN] = mut_array_start(buf).ok_or(CrsfError::BufferError)?;
fn encode<'a>(&self, buf: &'a mut [u8]) -> Result<&'a [u8], Error> {
let data: &mut [u8; LEN] = mut_array_start(buf).ok_or(Error::BufferError)?;

raw_encode(self, data);

Expand Down
18 changes: 9 additions & 9 deletions src/packets/mod.rs → src/packet/payload/mod.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
//! This module contains defines the behavior of a Payload, and provides implementations for
//! various payloads used in the CRSF protocol.
use crate::{crc8::Crc8, CrsfError, PacketType, RawPacket, CRSF_MAX_LEN, CRSF_SYNC_BYTE};
use crate::{crc8::Crc8, Error, PacketType, RawPacket, CRSF_MAX_LEN, CRSF_SYNC_BYTE};

pub mod rc_channels_packed;
pub use rc_channels_packed::RcChannelsPacked;

pub mod link_statistics;
mod link_statistics;
pub use link_statistics::LinkStatistics;

mod rc_channels_packed;
pub use rc_channels_packed::RcChannelsPacked;

/// A trait encapsulationg a CRSF payload. This trait is used to encode and decode payloads
/// to and from byte slices, as well as convert into a [`RawPacket`]s for transmitting elsewhere.
#[allow(clippy::len_without_is_empty)]
Expand All @@ -28,22 +28,22 @@ where
fn packet_type(&self) -> PacketType;

/// Decode a payload from a slice. This must not include the `sync`, `len`, `type`, or `crc` bytes.
fn decode(buf: &[u8]) -> Result<Self, CrsfError>;
fn decode(buf: &[u8]) -> Result<Self, Error>;

/// Encode a payload into a mutable slice. This does not include the `sync`, `len`, `type`, or `crc` bytes.
fn encode<'a>(&self, buf: &'a mut [u8]) -> Result<&'a [u8], CrsfError>;
fn encode<'a>(&self, buf: &'a mut [u8]) -> Result<&'a [u8], Error>;

/// Construct a new `RawPacket` from a `Packet`. This adds the `sync`, `len`, `type` bytes,
/// and calculates and adds the `crc` byte. This constructor assumes the given packet is valid.
fn to_raw_packet(&self) -> Result<RawPacket, CrsfError> {
fn to_raw_packet(&self) -> Result<RawPacket, Error> {
self.to_raw_packet_with_sync(CRSF_SYNC_BYTE)
}

/// Construct a new `RawPacket` from a `Packet`. This adds the given `sync` byte, `len`, `type` bytes,
/// and calculates and adds the `crc` byte. This constructor assumes the given packet is valid.
/// Note that changing the sync byte is not officially supported by the CRSF protocol, but is used
/// in some implementations as an "address" byte.
fn to_raw_packet_with_sync(&self, sync_byte: u8) -> Result<RawPacket, CrsfError> {
fn to_raw_packet_with_sync(&self, sync_byte: u8) -> Result<RawPacket, Error> {
let mut raw = RawPacket {
buf: [0u8; CRSF_MAX_LEN],
len: 4 + Self::LEN,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
//! RcChannelsPacked packet and related functions/implementations
use super::Payload;
use crate::to_array::{mut_array_start, ref_array_start};
use crate::{CrsfError, PacketType};
use crate::{
to_array::{mut_array_start, ref_array_start},
Error, PacketType, Payload,
};

/// Represents a RcChannelsPacked packet
#[derive(Debug, PartialEq, Clone, Copy)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct RcChannelsPacked(pub [u16; 16]);

const LEN: usize = RcChannelsPacked::LEN;
Expand Down Expand Up @@ -73,14 +75,14 @@ impl Payload for RcChannelsPacked {
PacketType::RcChannelsPacked
}

fn decode(buf: &[u8]) -> Result<Self, CrsfError> {
let data = ref_array_start(buf).ok_or(CrsfError::BufferError)?;
fn decode(buf: &[u8]) -> Result<Self, Error> {
let data = ref_array_start(buf).ok_or(Error::BufferError)?;

Ok(raw_decode(data))
}

fn encode<'a>(&self, buf: &'a mut [u8]) -> Result<&'a [u8], CrsfError> {
let data = mut_array_start(buf).ok_or(CrsfError::BufferError)?;
fn encode<'a>(&self, buf: &'a mut [u8]) -> Result<&'a [u8], Error> {
let data = mut_array_start(buf).ok_or(Error::BufferError)?;

raw_encode(self, data);

Expand Down
41 changes: 41 additions & 0 deletions src/packet/typ.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
use num_enum::TryFromPrimitive;

/// Represents all CRSF packet types
#[non_exhaustive]
#[derive(Clone, Copy, Debug, PartialEq, Eq, TryFromPrimitive)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[repr(u8)]
pub enum PacketType {
Gps = 0x02,
Vario = 0x07,
BatterySensor = 0x08,
BaroAltitude = 0x09,
Heartbeat = 0x0B,
LinkStatistics = 0x14,
RcChannelsPacked = 0x16,
SubsetRcChannelsPacked = 0x17,
LinkRxId = 0x1C,
LinkTxId = 0x1D,
Attitude = 0x1E,
FlightMode = 0x21,
DevicePing = 0x28,
DeviceInfo = 0x29,
ParameterSettingsEntry = 0x2B,
ParameterRead = 0x2C,
ParameterWrite = 0x2D,
ElrsStatus = 0x2E,
Command = 0x32,
RadioId = 0x3A,
KissRequest = 0x78,
KissResponse = 0x79,
MspRequest = 0x7A,
MspResponse = 0x7B,
MspWrite = 0x7C,
ArdupilotResponse = 0x80,
}

impl PacketType {
pub fn is_extended(self) -> bool {
self as u8 >= 0x28
}
}
Loading

0 comments on commit 27e7d37

Please sign in to comment.