use delegate, some minor fixes

This commit is contained in:
Robin Müller 2022-06-18 14:47:24 +02:00
parent 786ed44fb4
commit 75319496b5
No known key found for this signature in database
GPG Key ID: 71B58F8A3CDFA9AC
4 changed files with 90 additions and 42 deletions

12
Cargo.lock generated
View File

@ -234,6 +234,17 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "delegate"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d70a2d4995466955a415223acf3c9c934b9ff2339631cdf4ffc893da4bacd717"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "embedded-hal" name = "embedded-hal"
version = "0.2.7" version = "0.2.7"
@ -629,6 +640,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"crc", "crc",
"deku", "deku",
"delegate",
"num", "num",
"postcard", "postcard",
"serde", "serde",

View File

@ -12,3 +12,4 @@ serde = "1.0.137"
deku = "0.13" deku = "0.13"
zerocopy = "0.6.1" zerocopy = "0.6.1"
crc = "3.0.0" crc = "3.0.0"
delegate = "0.7.0"

View File

@ -1,4 +1,6 @@
//! # Space related components including CCSDS and ECSS packet standards //! # Space related components including CCSDS and ECSS packet standards
extern crate core;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
pub mod ecss; pub mod ecss;
pub mod tc; pub mod tc;
@ -32,7 +34,7 @@ impl TryFrom<u8> for PacketType {
} }
} }
pub fn type_from_packet_id(packet_id: u16) -> PacketType { pub fn packet_type_in_raw_packet_id(packet_id: u16) -> PacketType {
PacketType::try_from((packet_id >> 12) as u8 & 0b1).unwrap() PacketType::try_from((packet_id >> 12) as u8 & 0b1).unwrap()
} }
@ -69,18 +71,16 @@ pub struct PacketId {
impl PacketId { impl PacketId {
pub fn new(ptype: PacketType, sec_header_flag: bool, apid: u16) -> Option<PacketId> { pub fn new(ptype: PacketType, sec_header_flag: bool, apid: u16) -> Option<PacketId> {
if apid > num::pow(2, 11) - 1 { let mut pid = PacketId {
return None;
}
Some(PacketId {
ptype, ptype,
sec_header_flag, sec_header_flag,
apid, apid: 0,
}) };
pid.set_apid(apid).then(|| pid)
} }
pub fn set_apid(&mut self, apid: u16) -> bool { pub fn set_apid(&mut self, apid: u16) -> bool {
if apid > num::pow(2, 11) { if apid > num::pow(2, 11) - 1 {
return false; return false;
} }
self.apid = apid; self.apid = apid;
@ -114,14 +114,13 @@ pub struct PacketSequenceCtrl {
impl PacketSequenceCtrl { impl PacketSequenceCtrl {
pub fn new(seq_flags: SequenceFlags, ssc: u16) -> Option<PacketSequenceCtrl> { pub fn new(seq_flags: SequenceFlags, ssc: u16) -> Option<PacketSequenceCtrl> {
if ssc > num::pow(2, 14) - 1 { let mut psc = PacketSequenceCtrl { seq_flags, ssc: 0 };
return None; psc.set_ssc(ssc).then(|| psc)
}
Some(PacketSequenceCtrl { seq_flags, ssc })
} }
pub fn raw(&self) -> u16 { pub fn raw(&self) -> u16 {
((self.seq_flags as u16) << 14) | self.ssc ((self.seq_flags as u16) << 14) | self.ssc
} }
pub fn set_ssc(&mut self, ssc: u16) -> bool { pub fn set_ssc(&mut self, ssc: u16) -> bool {
if ssc > num::pow(2, 14) - 1 { if ssc > num::pow(2, 14) - 1 {
return false; return false;
@ -267,7 +266,7 @@ pub mod srd {
} }
impl SpHeader { impl SpHeader {
pub fn new(apid: u16, ptype: PacketType, ssc: u16) -> Option<Self> { pub fn new(apid: u16, ptype: PacketType, ssc: u16) -> Option<Self> {
if ssc > num::pow(2, 14) || apid > num::pow(2, 11) { if ssc > num::pow(2, 14) - 1 || apid > num::pow(2, 11) - 1 {
return None; return None;
} }
let mut header = SpHeader::default(); let mut header = SpHeader::default();
@ -415,31 +414,54 @@ pub mod zc {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::srd::SpHeader; use crate::srd::SpHeader;
use crate::{zc, CcsdsPacket, PacketId, PacketSequenceCtrl, PacketType, SequenceFlags}; use crate::{
packet_type_in_raw_packet_id, zc, CcsdsPacket, CcsdsPrimaryHeader, PacketId,
PacketSequenceCtrl, PacketType, SequenceFlags,
};
use postcard::{from_bytes, to_stdvec}; use postcard::{from_bytes, to_stdvec};
#[test] #[test]
fn test_helpers() { fn test_helpers() {
let packet_id = PacketId { assert_eq!(
ptype: PacketType::Tm, SequenceFlags::try_from(0b00).expect("SEQ flag creation failed"),
sec_header_flag: false, SequenceFlags::ContinuationSegment
apid: 0x42, );
}; assert_eq!(
assert_eq!(packet_id.raw(), 0x42); SequenceFlags::try_from(0b01).expect("SEQ flag creation failed"),
SequenceFlags::FirstSegment
);
assert_eq!(
SequenceFlags::try_from(0b10).expect("SEQ flag creation failed"),
SequenceFlags::LastSegment
);
assert_eq!(
SequenceFlags::try_from(0b11).expect("SEQ flag creation failed"),
SequenceFlags::Unsegmented
);
assert!(SequenceFlags::try_from(0b100).is_err());
assert!(PacketType::try_from(0b10).is_err());
let packet_id =
PacketId::new(PacketType::Tm, false, 0x42).expect("Packet ID creation failed");
assert_eq!(packet_id.raw(), 0x0042);
let packet_id_from_raw = PacketId::from(packet_id.raw()); let packet_id_from_raw = PacketId::from(packet_id.raw());
assert_eq!(
packet_type_in_raw_packet_id(packet_id.raw()),
PacketType::Tm
);
assert_eq!(packet_id_from_raw, packet_id); assert_eq!(packet_id_from_raw, packet_id);
let packet_id_invalid = PacketId::new(PacketType::Tc, true, 0xFFFF); let packet_id_invalid = PacketId::new(PacketType::Tc, true, 0xFFFF);
assert!(packet_id_invalid.is_none()); assert!(packet_id_invalid.is_none());
let packet_id_from_new = PacketId::new(PacketType::Tm, false, 0x42).unwrap(); let packet_id_from_new = PacketId::new(PacketType::Tm, false, 0x42).unwrap();
assert_eq!(packet_id_from_new, packet_id); assert_eq!(packet_id_from_new, packet_id);
let psc = PacketSequenceCtrl { let mut psc = PacketSequenceCtrl::new(SequenceFlags::ContinuationSegment, 77)
seq_flags: SequenceFlags::ContinuationSegment, .expect("PSC creation failed");
ssc: 77,
};
assert_eq!(psc.raw(), 77); assert_eq!(psc.raw(), 77);
let psc_from_raw = PacketSequenceCtrl::from(psc.raw()); let psc_from_raw = PacketSequenceCtrl::from(psc.raw());
assert_eq!(psc_from_raw, psc); assert_eq!(psc_from_raw, psc);
// Fails because SSC is limited to 14 bits
assert!(!psc.set_ssc(num::pow(2, 15)));
assert_eq!(psc.raw(), 77);
let psc_invalid = PacketSequenceCtrl::new(SequenceFlags::FirstSegment, 0xFFFF); let psc_invalid = PacketSequenceCtrl::new(SequenceFlags::FirstSegment, 0xFFFF);
assert!(psc_invalid.is_none()); assert!(psc_invalid.is_none());
@ -448,7 +470,7 @@ mod tests {
} }
#[test] #[test]
fn test_deser_internally() { fn test_serde_sph() {
let sp_header = SpHeader::tc(0x42, 12).expect("Error creating SP header"); let sp_header = SpHeader::tc(0x42, 12).expect("Error creating SP header");
assert_eq!(sp_header.version(), 0b000); assert_eq!(sp_header.version(), 0b000);
assert!(sp_header.is_tc()); assert!(sp_header.is_tc());
@ -484,14 +506,33 @@ mod tests {
assert_eq!(sp_header.psc_raw(), 0xC016); assert_eq!(sp_header.psc_raw(), 0xC016);
assert_eq!(sp_header.data_len(), 36); assert_eq!(sp_header.data_len(), 36);
assert_eq!(sp_header.version(), 0b000); assert_eq!(sp_header.version(), 0b000);
let from_comp_fields = SpHeader::from_composite_fields(
PacketId::new(PacketType::Tc, true, 0x42).unwrap(),
PacketSequenceCtrl::new(SequenceFlags::Unsegmented, 0x7).unwrap(),
0,
None,
);
assert_eq!(from_comp_fields.ptype(), PacketType::Tc);
assert_eq!(from_comp_fields.apid(), 0x42);
assert_eq!(from_comp_fields.sec_header_flag(), true);
assert_eq!(
from_comp_fields.sequence_flags(),
SequenceFlags::Unsegmented
);
assert_eq!(from_comp_fields.ssc(), 0x7);
assert_eq!(from_comp_fields.data_len(), 0);
} }
#[test] #[test]
fn test_deser_zerocopy() { fn test_zc_sph() {
use zerocopy::AsBytes; use zerocopy::AsBytes;
let sp_header = SpHeader::tc(0x7FF, num::pow(2, 14) - 1).expect("Error creating SP header"); let sp_header = SpHeader::tc(0x7FF, num::pow(2, 14) - 1).expect("Error creating SP header");
assert_eq!(sp_header.packet_id.ptype, PacketType::Tc); assert_eq!(sp_header.ptype(), PacketType::Tc);
assert_eq!(sp_header.apid(), 0x7FF);
assert_eq!(sp_header.data_len(), 0);
assert_eq!(sp_header.version(), 0b000);
assert!(sp_header.is_tc()); assert!(sp_header.is_tc());
let sp_header_zc = zc::SpHeader::from(sp_header); let sp_header_zc = zc::SpHeader::from(sp_header);
let slice = sp_header_zc.as_bytes(); let slice = sp_header_zc.as_bytes();

View File

@ -46,6 +46,7 @@ pub mod srd {
use crate::ecss::{PusPacket, PusVersion, CRC_CCITT_FALSE}; use crate::ecss::{PusPacket, PusVersion, CRC_CCITT_FALSE};
use crate::srd::SpHeader; use crate::srd::SpHeader;
use crate::{CcsdsPacket, PacketError, PacketId, PacketSequenceCtrl, PacketType}; use crate::{CcsdsPacket, PacketError, PacketId, PacketSequenceCtrl, PacketType};
use delegate::delegate;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::mem::size_of; use std::mem::size_of;
use zerocopy::AsBytes; use zerocopy::AsBytes;
@ -194,22 +195,15 @@ pub mod srd {
Ok(appended_len) Ok(appended_len)
} }
} }
//noinspection RsTraitImplementation
impl CcsdsPacket for PusTc<'_> { impl CcsdsPacket for PusTc<'_> {
fn version(&self) -> u8 { delegate!(to self.sph {
self.sph.version fn version(&self) -> u8;
} fn packet_id(&self) -> PacketId;
fn psc(&self) -> PacketSequenceCtrl;
fn packet_id(&self) -> PacketId { fn data_len(&self) -> u16;
self.sph.packet_id });
}
fn psc(&self) -> PacketSequenceCtrl {
self.sph.psc
}
fn data_len(&self) -> u16 {
self.sph.data_len
}
} }
impl PusPacket for PusTc<'_> { impl PusPacket for PusTc<'_> {