added more tests for ccsds sp header impl
This commit is contained in:
parent
dcc29e1c5e
commit
645b265742
80
Cargo.lock
generated
80
Cargo.lock
generated
@ -95,15 +95,6 @@ version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.10"
|
||||
@ -170,38 +161,14 @@ dependencies = [
|
||||
"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]]
|
||||
name = "darling"
|
||||
version = "0.14.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4529658bdda7fd6769b8614be250cdcfc3aeb0ee72fe66f9e41e5e5eb73eac02"
|
||||
dependencies = [
|
||||
"darling_core 0.14.1",
|
||||
"darling_macro 0.14.1",
|
||||
]
|
||||
|
||||
[[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",
|
||||
"darling_core",
|
||||
"darling_macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -218,38 +185,17 @@ dependencies = [
|
||||
"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]]
|
||||
name = "darling_macro"
|
||||
version = "0.14.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ddfc69c5bfcbd2fc09a0f38451d2daf0e372e367986a83906d1b0dbc88134fb5"
|
||||
dependencies = [
|
||||
"darling_core 0.14.1",
|
||||
"darling_core",
|
||||
"quote",
|
||||
"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]]
|
||||
name = "deku"
|
||||
version = "0.13.1"
|
||||
@ -257,20 +203,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "868ccf23869582b2d79279e402db457fe341da24a0c5a8927c6154a5b4733dc3"
|
||||
dependencies = [
|
||||
"bitvec",
|
||||
"deku_derive 0.13.1",
|
||||
]
|
||||
|
||||
[[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",
|
||||
"deku_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -279,7 +212,7 @@ version = "0.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4dfb4274ccd1c87a598e98b398b4b630aecb2e8a32fd7c88ffa190fb73870f72"
|
||||
dependencies = [
|
||||
"darling 0.14.1",
|
||||
"darling",
|
||||
"proc-macro-crate",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -351,8 +284,7 @@ name = "launchpad"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bus",
|
||||
"ccsds_spacepacket",
|
||||
"deku 0.13.1",
|
||||
"deku",
|
||||
"heapless",
|
||||
"num",
|
||||
"postcard",
|
||||
|
@ -13,5 +13,5 @@ heapless = "0.7.13"
|
||||
postcard = { version = "0.7.3", features = ["use-std"] }
|
||||
serde = "1.0.137"
|
||||
deku = "0.13"
|
||||
ccsds_spacepacket = "0.2.0"
|
||||
# ccsds_spacepacket = "0.2.0"
|
||||
zerocopy = "0.6.1"
|
||||
|
378
src/sp.rs
378
src/sp.rs
@ -1,5 +1,4 @@
|
||||
//! # Space related components including CCSDS and ECSS packet standards
|
||||
pub use ccsds_spacepacket::PrimaryHeader as DekuSpHeader;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[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)]
|
||||
pub enum SequenceFlags {
|
||||
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
|
||||
pub trait CcsdsPrimaryHeader {
|
||||
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;
|
||||
/// Retrieve 13 bit Packet Identification field. Can usually be retrieved with a bitwise AND
|
||||
/// of the first 2 bytes with 0x1FFF
|
||||
fn packet_id(&self) -> u16;
|
||||
/// Retrieve Packet Sequence Count
|
||||
fn psc(&self) -> u16;
|
||||
fn packet_id(&self) -> PacketId;
|
||||
fn psc(&self) -> PacketSequenceCtrl;
|
||||
|
||||
/// Retrieve data length field
|
||||
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]
|
||||
/// Retrieve Packet Type (TM: 0, TC: 1)
|
||||
fn ptype(&self) -> PacketType {
|
||||
// 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]
|
||||
fn is_tm(&self) -> bool {
|
||||
self.ptype() == PacketType::Tm
|
||||
@ -77,52 +147,45 @@ pub trait CcsdsPrimaryHeader {
|
||||
/// and false if it is not
|
||||
#[inline]
|
||||
fn sec_header_flag(&self) -> bool {
|
||||
(self.packet_id() >> 11) & 0x01 != 0
|
||||
self.packet_id().sec_header_flag
|
||||
}
|
||||
|
||||
/// Retrieve Application Process ID
|
||||
#[inline]
|
||||
fn apid(&self) -> u16 {
|
||||
self.packet_id() & 0x7FF
|
||||
self.packet_id().apid
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn ssc(&self) -> u16 {
|
||||
self.psc() & (!Self::SEQ_FLAG_MASK)
|
||||
self.psc().ssc
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn sequence_flags(&self) -> SequenceFlags {
|
||||
// This call should never fail because the mask ensures that only valid values are passed
|
||||
// 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 {
|
||||
use crate::sp::SequenceFlags;
|
||||
use crate::sp::{CcsdsPrimaryHeader, PacketType};
|
||||
use crate::sp::{self, SequenceFlags, CcsdsPrimaryHeader, PacketType, PacketId, PacketSequenceCtrl};
|
||||
|
||||
/// Space Packet Primary Header according to CCSDS 133.0-B-2
|
||||
#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq)]
|
||||
pub struct SpHeader {
|
||||
pub version: u8,
|
||||
pub ptype: PacketType,
|
||||
pub apid: u16,
|
||||
pub sec_header_flag: bool,
|
||||
pub seq_flags: SequenceFlags,
|
||||
pub ssc: u16,
|
||||
pub packet_id: PacketId,
|
||||
pub psc: PacketSequenceCtrl,
|
||||
pub data_len: u16,
|
||||
}
|
||||
impl Default for SpHeader {
|
||||
fn default() -> Self {
|
||||
SpHeader {
|
||||
version: 0,
|
||||
ptype: PacketType::Tm,
|
||||
apid: 0,
|
||||
sec_header_flag: true,
|
||||
seq_flags: SequenceFlags::Unsegmented,
|
||||
ssc: 0,
|
||||
packet_id: PacketId{ ptype: PacketType::Tm, apid: 0, sec_header_flag: true},
|
||||
psc: PacketSequenceCtrl { seq_flags: SequenceFlags::Unsegmented, ssc: 0},
|
||||
data_len: 0,
|
||||
}
|
||||
}
|
||||
@ -132,12 +195,11 @@ pub mod srd {
|
||||
if ssc > num::pow(2, 14) || apid > num::pow(2, 11) {
|
||||
return None;
|
||||
}
|
||||
Some(SpHeader {
|
||||
ptype,
|
||||
apid,
|
||||
ssc,
|
||||
..Default::default()
|
||||
})
|
||||
let mut header = SpHeader::default();
|
||||
header.packet_id.apid = apid;
|
||||
header.packet_id.ptype = ptype;
|
||||
header.psc.ssc = ssc;
|
||||
Some(header)
|
||||
}
|
||||
|
||||
pub fn tm(apid: u16, ssc: u16) -> Option<Self> {
|
||||
@ -150,21 +212,32 @@ pub mod srd {
|
||||
}
|
||||
|
||||
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]
|
||||
fn version(&self) -> u8 {
|
||||
self.version
|
||||
}
|
||||
|
||||
/// Retrieve Packet Identification composite field
|
||||
#[inline]
|
||||
fn packet_id(&self) -> u16 {
|
||||
((self.ptype as u16) << 13) | ((self.sec_header_flag as u16) << 12) | self.apid
|
||||
fn packet_id(&self) -> PacketId {
|
||||
self.packet_id
|
||||
}
|
||||
|
||||
/// Function to retrieve the packet sequence control field
|
||||
#[inline]
|
||||
fn psc(&self) -> u16 {
|
||||
((self.seq_flags as u16) << 14) | self.sec_header_flag as u16
|
||||
fn psc(&self) -> PacketSequenceCtrl {
|
||||
self.psc
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -172,35 +245,54 @@ pub mod srd {
|
||||
self.data_len
|
||||
}
|
||||
}
|
||||
|
||||
sph_from_other!(SpHeader, sp::zc::SpHeader);
|
||||
// sph_from_other!(SpHeader, sp::deku::SpHeader);
|
||||
}
|
||||
|
||||
pub mod zc {
|
||||
use crate::sp::CcsdsPrimaryHeader;
|
||||
use crate::sp::{self, CcsdsPrimaryHeader, PacketId, PacketSequenceCtrl};
|
||||
use zerocopy::byteorder::NetworkEndian;
|
||||
use zerocopy::{AsBytes, FromBytes, Unaligned, U16};
|
||||
|
||||
#[derive(FromBytes, AsBytes, Unaligned)]
|
||||
#[repr(C)]
|
||||
struct SpHeader {
|
||||
pub struct SpHeader {
|
||||
version_packet_id: U16<NetworkEndian>,
|
||||
psc: 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 {
|
||||
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]
|
||||
fn version(&self) -> u8 {
|
||||
((self.version_packet_id.get() >> 13) as u8) & 0b111
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn packet_id(&self) -> u16 {
|
||||
self.version_packet_id.get() & 0x1FFF
|
||||
fn packet_id(&self) -> PacketId {
|
||||
PacketId::from(self.packet_id_raw())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn psc(&self) -> u16 {
|
||||
self.psc.get()
|
||||
fn psc(&self) -> PacketSequenceCtrl {
|
||||
PacketSequenceCtrl::from(self.packet_id_raw())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -208,51 +300,68 @@ pub mod zc {
|
||||
self.data_len.get()
|
||||
}
|
||||
}
|
||||
|
||||
sph_from_other!(SpHeader, sp::srd::SpHeader);
|
||||
//sph_from_other!(SpHeader, sp::deku::SpHeader);
|
||||
}
|
||||
|
||||
/*
|
||||
pub mod deku {
|
||||
use crate::sp::srd::SpHeader;
|
||||
use crate::sp::{CcsdsPrimaryHeader, DekuSpHeader, PacketType, SequenceFlags};
|
||||
use ccsds_spacepacket::PrimaryHeader;
|
||||
pub use ccsds_spacepacket::PrimaryHeader as SpHeader;
|
||||
use crate::sp::{self, PacketId, PacketSequenceCtrl};
|
||||
use crate::sp::{CcsdsPrimaryHeader, PacketType, SequenceFlags};
|
||||
|
||||
/// The [DekuSpHeader] is very useful to deserialize a packed raw space packet header with 6 bytes.
|
||||
/// This function allows converting it to the [SpHeader] which is compatible to the [serde]
|
||||
/// framework
|
||||
impl TryFrom<DekuSpHeader> for SpHeader {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(header: PrimaryHeader) -> Result<Self, Self::Error> {
|
||||
let seq_num = SequenceFlags::try_from(header.sequence_flags as u8)?;
|
||||
let packet_type = PacketType::try_from(header.packet_type as u8)?;
|
||||
let sec_header_flag = header.sec_header_flag as u8 != 0;
|
||||
Ok(SpHeader {
|
||||
version: header.version,
|
||||
seq_flags: seq_num,
|
||||
data_len: header.data_length,
|
||||
ssc: header.sequence_count,
|
||||
ptype: packet_type,
|
||||
apid: header.app_proc_id,
|
||||
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;
|
||||
}
|
||||
let packet_type = match packet_id.ptype {
|
||||
PacketType::Tm => ccsds_spacepacket::types::PacketType::Data,
|
||||
PacketType::Tc => ccsds_spacepacket::types::PacketType::Command
|
||||
};
|
||||
let sec_header_flag = match packet_id.sec_header_flag {
|
||||
true => ccsds_spacepacket::types::SecondaryHeaderFlag::Present,
|
||||
false => ccsds_spacepacket::types::SecondaryHeaderFlag::NotPresent
|
||||
};
|
||||
let sequence_flags = match psc.seq_flags {
|
||||
SequenceFlags::ContinuationSegment => ccsds_spacepacket::types::SeqFlag::Continuation,
|
||||
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,
|
||||
})
|
||||
app_proc_id: packet_id.apid,
|
||||
sequence_flags,
|
||||
sequence_count: psc.ssc,
|
||||
data_length: data_len
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CcsdsPrimaryHeader for DekuSpHeader {
|
||||
#[inline]
|
||||
fn version(&self) -> u8 {
|
||||
self.version
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn packet_id(&self) -> u16 {
|
||||
((self.packet_type as u16) << 12)
|
||||
| ((self.sec_header_flag as u16) << 11)
|
||||
| self.app_proc_id
|
||||
fn packet_id(&self) -> PacketId {
|
||||
PacketId {
|
||||
ptype: PacketType::try_from(self.packet_type as u8).unwrap(),
|
||||
apid: self.app_proc_id,
|
||||
sec_header_flag: self.sec_header_flag as u8 != 0
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn psc(&self) -> u16 {
|
||||
((self.sequence_flags as u16) << 14) | self.sequence_count
|
||||
fn psc(&self) -> PacketSequenceCtrl {
|
||||
PacketSequenceCtrl {
|
||||
seq_flags: SequenceFlags::try_from(self.sequence_flags as u8).unwrap(),
|
||||
ssc: self.sequence_count
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -260,79 +369,104 @@ pub mod deku {
|
||||
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> {
|
||||
use ccsds_spacepacket::types::PacketType as DekuPacketType;
|
||||
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,
|
||||
})
|
||||
}
|
||||
}
|
||||
sph_from_other!(SpHeader, sp::srd::SpHeader);
|
||||
sph_from_other!(SpHeader, sp::zc::SpHeader);
|
||||
}
|
||||
*/
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::sp::srd::SpHeader;
|
||||
use crate::sp::{DekuSpHeader, PacketType, SequenceFlags};
|
||||
use crate::sp::{CcsdsPrimaryHeader, PacketType, SequenceFlags};
|
||||
use postcard::{from_bytes, to_stdvec};
|
||||
use crate::sp;
|
||||
|
||||
#[test]
|
||||
fn test_deser_internally() {
|
||||
let sp_header = SpHeader::tc(0x42, 12).expect("Error creating SP header");
|
||||
assert_eq!(sp_header.version, 0b000);
|
||||
assert_eq!(sp_header.sec_header_flag, true);
|
||||
assert_eq!(sp_header.ptype, PacketType::Tc);
|
||||
assert_eq!(sp_header.ssc, 12);
|
||||
assert_eq!(sp_header.apid, 0x42);
|
||||
assert_eq!(sp_header.seq_flags, SequenceFlags::Unsegmented);
|
||||
assert_eq!(sp_header.data_len, 0);
|
||||
assert_eq!(sp_header.version(), 0b000);
|
||||
assert_eq!(sp_header.sec_header_flag(), true);
|
||||
assert_eq!(sp_header.ptype(), PacketType::Tc);
|
||||
assert_eq!(sp_header.ssc(), 12);
|
||||
assert_eq!(sp_header.apid(), 0x42);
|
||||
assert_eq!(sp_header.sequence_flags(), SequenceFlags::Unsegmented);
|
||||
assert_eq!(sp_header.data_len(), 0);
|
||||
let output = to_stdvec(&sp_header).unwrap();
|
||||
println!("Output: {:?} with length {}", output, output.len());
|
||||
let sp_header: SpHeader = from_bytes(&output).unwrap();
|
||||
assert_eq!(sp_header.version, 0b000);
|
||||
assert_eq!(sp_header.sec_header_flag, true);
|
||||
assert_eq!(sp_header.ptype, PacketType::Tc);
|
||||
assert_eq!(sp_header.ssc, 12);
|
||||
assert_eq!(sp_header.apid, 0x42);
|
||||
assert_eq!(sp_header.seq_flags, SequenceFlags::Unsegmented);
|
||||
assert_eq!(sp_header.packet_id.sec_header_flag, true);
|
||||
assert_eq!(sp_header.ptype(), PacketType::Tc);
|
||||
assert_eq!(sp_header.ssc(), 12);
|
||||
assert_eq!(sp_header.apid(), 0x42);
|
||||
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);
|
||||
|
||||
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]
|
||||
fn test_deser_to_raw_packed_deku() {
|
||||
let sp_header = SpHeader::tc(0x42, 12).expect("Error creating SP header");
|
||||
// TODO: Wait with these tests until KubOS merged
|
||||
// https://github.com/KubOS-Preservation-Group/ccsds-spacepacket/pull/14
|
||||
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();
|
||||
}
|
||||
*/
|
||||
|
||||
#[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);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user