added more tests for ccsds sp header impl

This commit is contained in:
Robin Müller 2022-06-14 17:26:29 +02:00
parent dcc29e1c5e
commit 645b265742
No known key found for this signature in database
GPG Key ID: 11D4952C8CCEF814
3 changed files with 263 additions and 197 deletions

80
Cargo.lock generated
View File

@ -95,15 +95,6 @@ version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
name = "ccsds_spacepacket"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "82251e34d2bbc33273c38d7720b65373e55e311fa0c4134b60b03601dbc92cf2"
dependencies = [
"deku 0.12.6",
]
[[package]] [[package]]
name = "cfg-if" name = "cfg-if"
version = "0.1.10" version = "0.1.10"
@ -170,38 +161,14 @@ dependencies = [
"lazy_static", "lazy_static",
] ]
[[package]]
name = "darling"
version = "0.13.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c"
dependencies = [
"darling_core 0.13.4",
"darling_macro 0.13.4",
]
[[package]] [[package]]
name = "darling" name = "darling"
version = "0.14.1" version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4529658bdda7fd6769b8614be250cdcfc3aeb0ee72fe66f9e41e5e5eb73eac02" checksum = "4529658bdda7fd6769b8614be250cdcfc3aeb0ee72fe66f9e41e5e5eb73eac02"
dependencies = [ dependencies = [
"darling_core 0.14.1", "darling_core",
"darling_macro 0.14.1", "darling_macro",
]
[[package]]
name = "darling_core"
version = "0.13.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610"
dependencies = [
"fnv",
"ident_case",
"proc-macro2",
"quote",
"strsim",
"syn",
] ]
[[package]] [[package]]
@ -218,38 +185,17 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "darling_macro"
version = "0.13.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835"
dependencies = [
"darling_core 0.13.4",
"quote",
"syn",
]
[[package]] [[package]]
name = "darling_macro" name = "darling_macro"
version = "0.14.1" version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddfc69c5bfcbd2fc09a0f38451d2daf0e372e367986a83906d1b0dbc88134fb5" checksum = "ddfc69c5bfcbd2fc09a0f38451d2daf0e372e367986a83906d1b0dbc88134fb5"
dependencies = [ dependencies = [
"darling_core 0.14.1", "darling_core",
"quote", "quote",
"syn", "syn",
] ]
[[package]]
name = "deku"
version = "0.12.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe18ce09f5d512cad19bbac22e395aa36cfa12cf699a3bcb3787af62dde4b13a"
dependencies = [
"bitvec",
"deku_derive 0.12.6",
]
[[package]] [[package]]
name = "deku" name = "deku"
version = "0.13.1" version = "0.13.1"
@ -257,20 +203,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "868ccf23869582b2d79279e402db457fe341da24a0c5a8927c6154a5b4733dc3" checksum = "868ccf23869582b2d79279e402db457fe341da24a0c5a8927c6154a5b4733dc3"
dependencies = [ dependencies = [
"bitvec", "bitvec",
"deku_derive 0.13.1", "deku_derive",
]
[[package]]
name = "deku_derive"
version = "0.12.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "691ea0b164aad4a4517f5b47130e15868af1f02fed614c45a1967cbfe2c318d7"
dependencies = [
"darling 0.13.4",
"proc-macro-crate",
"proc-macro2",
"quote",
"syn",
] ]
[[package]] [[package]]
@ -279,7 +212,7 @@ version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4dfb4274ccd1c87a598e98b398b4b630aecb2e8a32fd7c88ffa190fb73870f72" checksum = "4dfb4274ccd1c87a598e98b398b4b630aecb2e8a32fd7c88ffa190fb73870f72"
dependencies = [ dependencies = [
"darling 0.14.1", "darling",
"proc-macro-crate", "proc-macro-crate",
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -351,8 +284,7 @@ name = "launchpad"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"bus", "bus",
"ccsds_spacepacket", "deku",
"deku 0.13.1",
"heapless", "heapless",
"num", "num",
"postcard", "postcard",

View File

@ -13,5 +13,5 @@ heapless = "0.7.13"
postcard = { version = "0.7.3", features = ["use-std"] } postcard = { version = "0.7.3", features = ["use-std"] }
serde = "1.0.137" serde = "1.0.137"
deku = "0.13" deku = "0.13"
ccsds_spacepacket = "0.2.0" # ccsds_spacepacket = "0.2.0"
zerocopy = "0.6.1" zerocopy = "0.6.1"

378
src/sp.rs
View File

@ -1,5 +1,4 @@
//! # Space related components including CCSDS and ECSS packet standards //! # Space related components including CCSDS and ECSS packet standards
pub use ccsds_spacepacket::PrimaryHeader as DekuSpHeader;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug, PartialEq, Copy, Clone)] #[derive(Serialize, Deserialize, Debug, PartialEq, Copy, Clone)]
@ -20,6 +19,10 @@ impl TryFrom<u8> for PacketType {
} }
} }
pub fn type_from_packet_id(packet_id: u16) -> PacketType {
PacketType::try_from((packet_id >> 12) as u8 & 0b1).unwrap()
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Copy, Clone)] #[derive(Serialize, Deserialize, Debug, PartialEq, Copy, Clone)]
pub enum SequenceFlags { pub enum SequenceFlags {
ContinuationSegment = 0b00, ContinuationSegment = 0b00,
@ -44,25 +47,92 @@ impl TryFrom<u8> for SequenceFlags {
} }
} }
#[derive(Serialize, Deserialize, Debug, PartialEq, Copy, Clone)]
pub struct PacketId {
pub ptype: PacketType,
pub sec_header_flag: bool,
pub apid: u16
}
impl PacketId {
pub fn raw(&self) -> u16 {
((self.ptype as u16) << 12) | ((self.sec_header_flag as u16) << 11) | self.apid
}
}
impl From<u16> for PacketId {
fn from(raw_id: u16) -> Self {
PacketId {
ptype: PacketType::try_from(((raw_id >> 12) & 0b1) as u8).unwrap(),
sec_header_flag: ((raw_id >> 11) & 0b1) != 0,
apid: raw_id & 0x7FFF
}
}
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Copy, Clone)]
pub struct PacketSequenceCtrl {
pub seq_flags: SequenceFlags,
pub ssc: u16
}
impl PacketSequenceCtrl {
pub fn raw(&self) -> u16 {
((self.seq_flags as u16) << 14) | self.ssc
}
}
impl From<u16> for PacketSequenceCtrl {
fn from(raw_id: u16) -> Self {
PacketSequenceCtrl {
seq_flags: SequenceFlags::try_from(((raw_id >> 14) & 0b11) as u8).unwrap(),
ssc: raw_id & 0x3FFF
}
}
}
macro_rules! sph_from_other {
($Self: path, $other: path) => {
impl From<$other> for $Self {
fn from(other: $other) -> Self {
Self::from_composite_fields(other.packet_id(), other.psc(), other.data_len(), Some(other.version()))
}
}
}
}
/// Generic trait to access fields of a CCSDS space packet header according to CCSDS 133.0-B-2 /// Generic trait to access fields of a CCSDS space packet header according to CCSDS 133.0-B-2
pub trait CcsdsPrimaryHeader { pub trait CcsdsPrimaryHeader {
const SEQ_FLAG_MASK: u16 = 0xC000; const SEQ_FLAG_MASK: u16 = 0xC000;
fn from_composite_fields(packet_id: PacketId, psc: PacketSequenceCtrl, data_len: u16, version: Option<u8>) -> Self;
fn version(&self) -> u8; fn version(&self) -> u8;
/// Retrieve 13 bit Packet Identification field. Can usually be retrieved with a bitwise AND fn packet_id(&self) -> PacketId;
/// of the first 2 bytes with 0x1FFF fn psc(&self) -> PacketSequenceCtrl;
fn packet_id(&self) -> u16;
/// Retrieve Packet Sequence Count
fn psc(&self) -> u16;
/// Retrieve data length field /// Retrieve data length field
fn data_len(&self) -> u16; fn data_len(&self) -> u16;
/// Retrieve 13 bit Packet Identification field. Can usually be retrieved with a bitwise AND
/// of the first 2 bytes with 0x1FFF
#[inline]
fn packet_id_raw(&self) -> u16 {
self.packet_id().raw()
}
/// Retrieve Packet Sequence Count
#[inline]
fn psc_raw(&self) -> u16 {
self.psc().raw()
}
#[inline] #[inline]
/// Retrieve Packet Type (TM: 0, TC: 1) /// Retrieve Packet Type (TM: 0, TC: 1)
fn ptype(&self) -> PacketType { fn ptype(&self) -> PacketType {
// This call should never fail because only 0 and 1 can be passed to the try_from call // This call should never fail because only 0 and 1 can be passed to the try_from call
PacketType::try_from((self.packet_id() >> 12) as u8 & 0b1).unwrap() self.packet_id().ptype
} }
#[inline] #[inline]
fn is_tm(&self) -> bool { fn is_tm(&self) -> bool {
self.ptype() == PacketType::Tm self.ptype() == PacketType::Tm
@ -77,52 +147,45 @@ pub trait CcsdsPrimaryHeader {
/// and false if it is not /// and false if it is not
#[inline] #[inline]
fn sec_header_flag(&self) -> bool { fn sec_header_flag(&self) -> bool {
(self.packet_id() >> 11) & 0x01 != 0 self.packet_id().sec_header_flag
} }
/// Retrieve Application Process ID /// Retrieve Application Process ID
#[inline] #[inline]
fn apid(&self) -> u16 { fn apid(&self) -> u16 {
self.packet_id() & 0x7FF self.packet_id().apid
} }
#[inline] #[inline]
fn ssc(&self) -> u16 { fn ssc(&self) -> u16 {
self.psc() & (!Self::SEQ_FLAG_MASK) self.psc().ssc
} }
#[inline] #[inline]
fn sequence_flags(&self) -> SequenceFlags { fn sequence_flags(&self) -> SequenceFlags {
// This call should never fail because the mask ensures that only valid values are passed // This call should never fail because the mask ensures that only valid values are passed
// into the try_from function // into the try_from function
SequenceFlags::try_from(((self.psc() & Self::SEQ_FLAG_MASK) >> 14) as u8).unwrap() self.psc().seq_flags
} }
} }
pub mod srd { pub mod srd {
use crate::sp::SequenceFlags; use crate::sp::{self, SequenceFlags, CcsdsPrimaryHeader, PacketType, PacketId, PacketSequenceCtrl};
use crate::sp::{CcsdsPrimaryHeader, PacketType};
/// Space Packet Primary Header according to CCSDS 133.0-B-2 /// Space Packet Primary Header according to CCSDS 133.0-B-2
#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq)] #[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq)]
pub struct SpHeader { pub struct SpHeader {
pub version: u8, pub version: u8,
pub ptype: PacketType, pub packet_id: PacketId,
pub apid: u16, pub psc: PacketSequenceCtrl,
pub sec_header_flag: bool,
pub seq_flags: SequenceFlags,
pub ssc: u16,
pub data_len: u16, pub data_len: u16,
} }
impl Default for SpHeader { impl Default for SpHeader {
fn default() -> Self { fn default() -> Self {
SpHeader { SpHeader {
version: 0, version: 0,
ptype: PacketType::Tm, packet_id: PacketId{ ptype: PacketType::Tm, apid: 0, sec_header_flag: true},
apid: 0, psc: PacketSequenceCtrl { seq_flags: SequenceFlags::Unsegmented, ssc: 0},
sec_header_flag: true,
seq_flags: SequenceFlags::Unsegmented,
ssc: 0,
data_len: 0, data_len: 0,
} }
} }
@ -132,12 +195,11 @@ pub mod srd {
if ssc > num::pow(2, 14) || apid > num::pow(2, 11) { if ssc > num::pow(2, 14) || apid > num::pow(2, 11) {
return None; return None;
} }
Some(SpHeader { let mut header = SpHeader::default();
ptype, header.packet_id.apid = apid;
apid, header.packet_id.ptype = ptype;
ssc, header.psc.ssc = ssc;
..Default::default() Some(header)
})
} }
pub fn tm(apid: u16, ssc: u16) -> Option<Self> { pub fn tm(apid: u16, ssc: u16) -> Option<Self> {
@ -150,21 +212,32 @@ pub mod srd {
} }
impl CcsdsPrimaryHeader for SpHeader { impl CcsdsPrimaryHeader for SpHeader {
fn from_composite_fields(packet_id: PacketId, psc: PacketSequenceCtrl, data_len: u16, version: Option<u8>) -> Self {
let mut version_to_set = 0b000;
if let Some(version) = version {
version_to_set = version;
}
SpHeader {
version: version_to_set,
packet_id,
psc,
data_len
}
}
#[inline] #[inline]
fn version(&self) -> u8 { fn version(&self) -> u8 {
self.version self.version
} }
/// Retrieve Packet Identification composite field
#[inline] #[inline]
fn packet_id(&self) -> u16 { fn packet_id(&self) -> PacketId {
((self.ptype as u16) << 13) | ((self.sec_header_flag as u16) << 12) | self.apid self.packet_id
} }
/// Function to retrieve the packet sequence control field
#[inline] #[inline]
fn psc(&self) -> u16 { fn psc(&self) -> PacketSequenceCtrl {
((self.seq_flags as u16) << 14) | self.sec_header_flag as u16 self.psc
} }
#[inline] #[inline]
@ -172,35 +245,54 @@ pub mod srd {
self.data_len self.data_len
} }
} }
sph_from_other!(SpHeader, sp::zc::SpHeader);
// sph_from_other!(SpHeader, sp::deku::SpHeader);
} }
pub mod zc { pub mod zc {
use crate::sp::CcsdsPrimaryHeader; use crate::sp::{self, CcsdsPrimaryHeader, PacketId, PacketSequenceCtrl};
use zerocopy::byteorder::NetworkEndian; use zerocopy::byteorder::NetworkEndian;
use zerocopy::{AsBytes, FromBytes, Unaligned, U16}; use zerocopy::{AsBytes, FromBytes, Unaligned, U16};
#[derive(FromBytes, AsBytes, Unaligned)] #[derive(FromBytes, AsBytes, Unaligned)]
#[repr(C)] #[repr(C)]
struct SpHeader { pub struct SpHeader {
version_packet_id: U16<NetworkEndian>, version_packet_id: U16<NetworkEndian>,
psc: U16<NetworkEndian>, psc: U16<NetworkEndian>,
data_len: U16<NetworkEndian>, data_len: U16<NetworkEndian>,
} }
impl SpHeader {
pub fn new(packet_id: PacketId, psc: PacketSequenceCtrl, data_len: u16, version: Option<u8>) -> Self {
let mut version_packet_id = packet_id.raw();
if let Some(version) = version {
version_packet_id = ((version as u16) << 13) | packet_id.raw()
}
SpHeader {
version_packet_id: U16::from(version_packet_id),
psc: U16::from(psc.raw()),
data_len: U16::from(data_len)
}
}
}
impl CcsdsPrimaryHeader for SpHeader { impl CcsdsPrimaryHeader for SpHeader {
fn from_composite_fields(packet_id: PacketId, psc: PacketSequenceCtrl, data_len: u16, version: Option<u8>) -> Self {
SpHeader::new(packet_id, psc, data_len, version)
}
#[inline] #[inline]
fn version(&self) -> u8 { fn version(&self) -> u8 {
((self.version_packet_id.get() >> 13) as u8) & 0b111 ((self.version_packet_id.get() >> 13) as u8) & 0b111
} }
#[inline] fn packet_id(&self) -> PacketId {
fn packet_id(&self) -> u16 { PacketId::from(self.packet_id_raw())
self.version_packet_id.get() & 0x1FFF
} }
#[inline] fn psc(&self) -> PacketSequenceCtrl {
fn psc(&self) -> u16 { PacketSequenceCtrl::from(self.packet_id_raw())
self.psc.get()
} }
#[inline] #[inline]
@ -208,51 +300,68 @@ pub mod zc {
self.data_len.get() self.data_len.get()
} }
} }
sph_from_other!(SpHeader, sp::srd::SpHeader);
//sph_from_other!(SpHeader, sp::deku::SpHeader);
} }
/*
pub mod deku { pub mod deku {
use crate::sp::srd::SpHeader; pub use ccsds_spacepacket::PrimaryHeader as SpHeader;
use crate::sp::{CcsdsPrimaryHeader, DekuSpHeader, PacketType, SequenceFlags}; use crate::sp::{self, PacketId, PacketSequenceCtrl};
use ccsds_spacepacket::PrimaryHeader; use crate::sp::{CcsdsPrimaryHeader, PacketType, SequenceFlags};
/// The [DekuSpHeader] is very useful to deserialize a packed raw space packet header with 6 bytes. impl CcsdsPrimaryHeader for SpHeader {
/// This function allows converting it to the [SpHeader] which is compatible to the [serde] fn from_composite_fields(packet_id: PacketId, psc: PacketSequenceCtrl, data_len: u16, version: Option<u8>) -> Self {
/// framework let mut version_to_set = 0b000;
impl TryFrom<DekuSpHeader> for SpHeader { if let Some(version) = version {
type Error = (); version_to_set = version;
}
fn try_from(header: PrimaryHeader) -> Result<Self, Self::Error> { let packet_type = match packet_id.ptype {
let seq_num = SequenceFlags::try_from(header.sequence_flags as u8)?; PacketType::Tm => ccsds_spacepacket::types::PacketType::Data,
let packet_type = PacketType::try_from(header.packet_type as u8)?; PacketType::Tc => ccsds_spacepacket::types::PacketType::Command
let sec_header_flag = header.sec_header_flag as u8 != 0; };
Ok(SpHeader { let sec_header_flag = match packet_id.sec_header_flag {
version: header.version, true => ccsds_spacepacket::types::SecondaryHeaderFlag::Present,
seq_flags: seq_num, false => ccsds_spacepacket::types::SecondaryHeaderFlag::NotPresent
data_len: header.data_length, };
ssc: header.sequence_count, let sequence_flags = match psc.seq_flags {
ptype: packet_type, SequenceFlags::ContinuationSegment => ccsds_spacepacket::types::SeqFlag::Continuation,
apid: header.app_proc_id, SequenceFlags::FirstSegment => ccsds_spacepacket::types::SeqFlag::FirstSegment,
SequenceFlags::LastSegment => ccsds_spacepacket::types::SeqFlag::LastSegment,
SequenceFlags::Unsegmented => ccsds_spacepacket::types::SeqFlag::Unsegmented
};
SpHeader {
version: version_to_set,
packet_type,
sec_header_flag, sec_header_flag,
}) app_proc_id: packet_id.apid,
sequence_flags,
sequence_count: psc.ssc,
data_length: data_len
}
} }
}
impl CcsdsPrimaryHeader for DekuSpHeader {
#[inline] #[inline]
fn version(&self) -> u8 { fn version(&self) -> u8 {
self.version self.version
} }
#[inline] #[inline]
fn packet_id(&self) -> u16 { fn packet_id(&self) -> PacketId {
((self.packet_type as u16) << 12) PacketId {
| ((self.sec_header_flag as u16) << 11) ptype: PacketType::try_from(self.packet_type as u8).unwrap(),
| self.app_proc_id apid: self.app_proc_id,
sec_header_flag: self.sec_header_flag as u8 != 0
}
} }
#[inline] #[inline]
fn psc(&self) -> u16 { fn psc(&self) -> PacketSequenceCtrl {
((self.sequence_flags as u16) << 14) | self.sequence_count PacketSequenceCtrl {
seq_flags: SequenceFlags::try_from(self.sequence_flags as u8).unwrap(),
ssc: self.sequence_count
}
} }
#[inline] #[inline]
@ -260,79 +369,104 @@ pub mod deku {
self.data_length self.data_length
} }
} }
/// It is possible to convert the [serde] compatible [SpHeader] back into a [DekuSpHeader]
/// to allow for packed binary serialization
impl TryFrom<SpHeader> for DekuSpHeader {
type Error = ();
fn try_from(value: SpHeader) -> Result<Self, Self::Error> { sph_from_other!(SpHeader, sp::srd::SpHeader);
use ccsds_spacepacket::types::PacketType as DekuPacketType; sph_from_other!(SpHeader, sp::zc::SpHeader);
use ccsds_spacepacket::types::SecondaryHeaderFlag as DekuSecHeaderFlag;
use ccsds_spacepacket::types::SeqFlag as DekuSeqFlag;
let sequence_flags = match value.seq_flags as u8 {
x if x == SequenceFlags::Unsegmented as u8 => DekuSeqFlag::Unsegmented,
x if x == SequenceFlags::FirstSegment as u8 => DekuSeqFlag::FirstSegment,
x if x == SequenceFlags::LastSegment as u8 => DekuSeqFlag::LastSegment,
x if x == SequenceFlags::ContinuationSegment as u8 => DekuSeqFlag::Continuation,
_ => return Err(()),
};
let packet_type = match value.ptype as u8 {
x if x == PacketType::Tm as u8 => DekuPacketType::Data,
x if x == PacketType::Tc as u8 => DekuPacketType::Command,
_ => return Err(()),
};
let sec_header_flag = match value.sec_header_flag as bool {
true => DekuSecHeaderFlag::Present,
false => DekuSecHeaderFlag::NotPresent,
};
Ok(DekuSpHeader {
version: value.version,
packet_type,
sec_header_flag,
app_proc_id: value.apid,
sequence_flags,
data_length: value.data_len,
sequence_count: value.ssc,
})
}
}
} }
*/
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::sp::srd::SpHeader; use crate::sp::srd::SpHeader;
use crate::sp::{DekuSpHeader, PacketType, SequenceFlags}; use crate::sp::{CcsdsPrimaryHeader, PacketType, SequenceFlags};
use postcard::{from_bytes, to_stdvec}; use postcard::{from_bytes, to_stdvec};
use crate::sp;
#[test] #[test]
fn test_deser_internally() { fn test_deser_internally() {
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_eq!(sp_header.sec_header_flag, true); assert_eq!(sp_header.sec_header_flag(), true);
assert_eq!(sp_header.ptype, PacketType::Tc); assert_eq!(sp_header.ptype(), PacketType::Tc);
assert_eq!(sp_header.ssc, 12); assert_eq!(sp_header.ssc(), 12);
assert_eq!(sp_header.apid, 0x42); assert_eq!(sp_header.apid(), 0x42);
assert_eq!(sp_header.seq_flags, SequenceFlags::Unsegmented); assert_eq!(sp_header.sequence_flags(), SequenceFlags::Unsegmented);
assert_eq!(sp_header.data_len, 0); assert_eq!(sp_header.data_len(), 0);
let output = to_stdvec(&sp_header).unwrap(); let output = to_stdvec(&sp_header).unwrap();
println!("Output: {:?} with length {}", output, output.len());
let sp_header: SpHeader = from_bytes(&output).unwrap(); let sp_header: SpHeader = from_bytes(&output).unwrap();
assert_eq!(sp_header.version, 0b000); assert_eq!(sp_header.version, 0b000);
assert_eq!(sp_header.sec_header_flag, true); assert_eq!(sp_header.packet_id.sec_header_flag, true);
assert_eq!(sp_header.ptype, PacketType::Tc); assert_eq!(sp_header.ptype(), PacketType::Tc);
assert_eq!(sp_header.ssc, 12); assert_eq!(sp_header.ssc(), 12);
assert_eq!(sp_header.apid, 0x42); assert_eq!(sp_header.apid(), 0x42);
assert_eq!(sp_header.seq_flags, SequenceFlags::Unsegmented); assert_eq!(sp_header.sequence_flags(), SequenceFlags::Unsegmented);
assert_eq!(sp_header.packet_id_raw(), 0x1842);
assert_eq!(sp_header.psc_raw(), 0xC00C);
assert_eq!(sp_header.version(), 0b000);
assert_eq!(sp_header.data_len, 0); assert_eq!(sp_header.data_len, 0);
let mut sp_header = SpHeader::tm(0x7, 22).expect("Error creating SP header");
sp_header.data_len = 36;
assert_eq!(sp_header.version(), 0b000);
assert_eq!(sp_header.sec_header_flag(), true);
assert_eq!(sp_header.ptype(), PacketType::Tm);
assert_eq!(sp_header.ssc(), 22);
assert_eq!(sp_header.apid(), 0x07);
assert_eq!(sp_header.sequence_flags(), SequenceFlags::Unsegmented);
assert_eq!(sp_header.packet_id_raw(), 0x0807);
assert_eq!(sp_header.psc_raw(), 0xC016);
assert_eq!(sp_header.data_len(), 36);
assert_eq!(sp_header.version(), 0b000);
} }
/*
#[test] #[test]
fn test_deser_to_raw_packed_deku() { fn test_deser_to_raw_packed_deku() {
let sp_header = SpHeader::tc(0x42, 12).expect("Error creating SP header"); let sp_header = SpHeader::tc(0x42, 12).expect("Error creating SP header");
// TODO: Wait with these tests until KubOS merged // TODO: Wait with these tests until KubOS merged
// https://github.com/KubOS-Preservation-Group/ccsds-spacepacket/pull/14 // https://github.com/KubOS-Preservation-Group/ccsds-spacepacket/pull/14
let _deku_header = let _deku_header =
DekuSpHeader::try_from(sp_header).expect("Error creating Deku Sp Header"); deku::SpHeader::try_from(sp_header).expect("Error creating Deku Sp Header");
// deku_header.to_bytes().unwrap(); // deku_header.to_bytes().unwrap();
} }
*/
#[test]
fn test_deser_zerocopy() {
use zerocopy::{AsBytes};
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);
let sp_header_zc = sp::zc::SpHeader::from(sp_header);
let slice = sp_header_zc.as_bytes();
assert_eq!(slice.len(), 6);
assert_eq!(slice[0], 0x1F);
assert_eq!(slice[1], 0xFF);
assert_eq!(slice[2], 0xFF);
assert_eq!(slice[3], 0xFF);
assert_eq!(slice[4], 0x00);
assert_eq!(slice[5], 0x00);
let mut slice = [0; 6];
sp_header_zc.write_to(slice.as_mut_slice());
assert_eq!(slice.len(), 6);
assert_eq!(slice[0], 0x1F);
assert_eq!(slice[1], 0xFF);
assert_eq!(slice[2], 0xFF);
assert_eq!(slice[3], 0xFF);
assert_eq!(slice[4], 0x00);
assert_eq!(slice[5], 0x00);
let mut test_vec = vec![0 as u8; 6];
let slice = test_vec.as_mut_slice();
sp_header_zc.write_to(slice);
let slice = test_vec.as_slice();
assert_eq!(slice.len(), 6);
assert_eq!(slice[0], 0x1F);
assert_eq!(slice[1], 0xFF);
assert_eq!(slice[2], 0xFF);
assert_eq!(slice[3], 0xFF);
assert_eq!(slice[4], 0x00);
assert_eq!(slice[5], 0x00);
}
} }