added byte level check
This commit is contained in:
parent
70ec75ff87
commit
de660ad26c
@ -31,8 +31,6 @@ pub trait PusPacket: CcsdsPacket {
|
||||
|
||||
fn service(&self) -> u8;
|
||||
fn subservice(&self) -> u8;
|
||||
fn source_id(&self) -> u16;
|
||||
fn ack_flags(&self) -> u8;
|
||||
|
||||
fn user_data(&self) -> Option<&[u8]>;
|
||||
fn crc16(&self) -> Option<u16>;
|
||||
|
@ -268,7 +268,7 @@ pub mod srd {
|
||||
}
|
||||
}
|
||||
impl SpHeader {
|
||||
pub fn new(apid: u16, ptype: PacketType, ssc: u16) -> Option<Self> {
|
||||
pub fn new(apid: u16, ptype: PacketType, ssc: u16, data_len: u16) -> Option<Self> {
|
||||
if ssc > num::pow(2, 14) - 1 || apid > num::pow(2, 11) - 1 {
|
||||
return None;
|
||||
}
|
||||
@ -276,15 +276,16 @@ pub mod srd {
|
||||
header.packet_id.apid = apid;
|
||||
header.packet_id.ptype = ptype;
|
||||
header.psc.ssc = ssc;
|
||||
header.data_len = data_len;
|
||||
Some(header)
|
||||
}
|
||||
|
||||
pub fn tm(apid: u16, ssc: u16) -> Option<Self> {
|
||||
Self::new(apid, PacketType::Tm, ssc)
|
||||
pub fn tm(apid: u16, ssc: u16, data_len: u16) -> Option<Self> {
|
||||
Self::new(apid, PacketType::Tm, ssc, data_len)
|
||||
}
|
||||
|
||||
pub fn tc(apid: u16, ssc: u16) -> Option<Self> {
|
||||
Self::new(apid, PacketType::Tc, ssc)
|
||||
pub fn tc(apid: u16, ssc: u16, data_len: u16) -> Option<Self> {
|
||||
Self::new(apid, PacketType::Tc, ssc, data_len)
|
||||
}
|
||||
}
|
||||
|
||||
@ -474,7 +475,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_serde_sph() {
|
||||
let sp_header = SpHeader::tc(0x42, 12).expect("Error creating SP header");
|
||||
let sp_header = SpHeader::tc(0x42, 12, 0).expect("Error creating SP header");
|
||||
assert_eq!(sp_header.ccsds_version(), 0b000);
|
||||
assert!(sp_header.is_tc());
|
||||
assert!(sp_header.sec_header_flag());
|
||||
@ -496,8 +497,7 @@ mod tests {
|
||||
assert_eq!(sp_header.ccsds_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;
|
||||
let sp_header = SpHeader::tm(0x7, 22, 36).expect("Error creating SP header");
|
||||
assert_eq!(sp_header.ccsds_version(), 0b000);
|
||||
assert!(sp_header.is_tm());
|
||||
assert!(sp_header.sec_header_flag());
|
||||
@ -531,7 +531,8 @@ mod tests {
|
||||
fn test_zc_sph() {
|
||||
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, 0).expect("Error creating SP header");
|
||||
assert_eq!(sp_header.ptype(), PacketType::Tc);
|
||||
assert_eq!(sp_header.apid(), 0x7FF);
|
||||
assert_eq!(sp_header.data_len(), 0);
|
||||
@ -572,7 +573,6 @@ mod tests {
|
||||
let sp_header = zc::SpHeader::from_bytes(slice);
|
||||
assert!(sp_header.is_some());
|
||||
let sp_header = sp_header.unwrap();
|
||||
println!("Header: {:?}", sp_header);
|
||||
assert_eq!(sp_header.ccsds_version(), 0b000);
|
||||
assert_eq!(sp_header.packet_id_raw(), 0x1FFF);
|
||||
assert_eq!(sp_header.apid(), 0x7FF);
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::ecss::{PusPacket, PusVersion};
|
||||
use crate::ecss::PusVersion;
|
||||
use crate::CCSDS_HEADER_LEN;
|
||||
use std::mem::size_of;
|
||||
|
||||
@ -30,24 +30,6 @@ pub trait PusTcSecondaryHeader {
|
||||
fn source_id(&self) -> u16;
|
||||
}
|
||||
|
||||
impl<T: PusPacket> PusTcSecondaryHeader for T {
|
||||
fn ack_flags(&self) -> u8 {
|
||||
self.ack_flags()
|
||||
}
|
||||
|
||||
fn service(&self) -> u8 {
|
||||
self.service()
|
||||
}
|
||||
|
||||
fn subservice(&self) -> u8 {
|
||||
self.subservice()
|
||||
}
|
||||
|
||||
fn source_id(&self) -> u16 {
|
||||
self.source_id()
|
||||
}
|
||||
}
|
||||
|
||||
pub mod zc {
|
||||
use crate::ecss::{PusError, PusVersion};
|
||||
use crate::tc::{srd, PusTcSecondaryHeader};
|
||||
@ -338,21 +320,20 @@ pub mod srd {
|
||||
PacketError::FromBytesZeroCopyError,
|
||||
))?;
|
||||
current_idx += PUC_TC_SECONDARY_HEADER_LEN;
|
||||
let app_data;
|
||||
if current_idx > total_len - 2 {
|
||||
return Err(PusError::RawDataTooShort(raw_data_len));
|
||||
} else if current_idx == total_len - 2 {
|
||||
app_data = None
|
||||
} else {
|
||||
app_data = Some(&slice_ref[current_idx..total_len - 2]);
|
||||
}
|
||||
let mut pus_tc = PusTc {
|
||||
sph: SpHeader::from(sph),
|
||||
data_field_header: PusTcDataFieldHeader::try_from(sec_header).unwrap(),
|
||||
raw_data: Some(slice_ref),
|
||||
app_data,
|
||||
app_data: match current_idx {
|
||||
_ if current_idx == total_len - 2 => None,
|
||||
_ if current_idx > total_len - 2 => {
|
||||
return Err(PusError::RawDataTooShort(raw_data_len))
|
||||
}
|
||||
_ => Some(&slice_ref[current_idx..total_len - 2]),
|
||||
},
|
||||
crc16: None,
|
||||
};
|
||||
pus_tc.crc_from_raw_data()?;
|
||||
pus_tc.verify()?;
|
||||
Ok((pus_tc, total_len))
|
||||
}
|
||||
@ -387,8 +368,6 @@ pub mod srd {
|
||||
delegate!(to self.data_field_header {
|
||||
fn service(&self) -> u8;
|
||||
fn subservice(&self) -> u8;
|
||||
fn source_id(&self) -> u16;
|
||||
fn ack_flags(&self) -> u8;
|
||||
});
|
||||
|
||||
fn user_data(&self) -> Option<&[u8]> {
|
||||
@ -399,6 +378,16 @@ pub mod srd {
|
||||
self.crc16
|
||||
}
|
||||
}
|
||||
|
||||
//noinspection RsTraitImplementation
|
||||
impl PusTcSecondaryHeader for PusTc<'_> {
|
||||
delegate!(to self.data_field_header {
|
||||
fn service(&self) -> u8;
|
||||
fn subservice(&self) -> u8;
|
||||
fn source_id(&self) -> u16;
|
||||
fn ack_flags(&self) -> u8;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@ -406,42 +395,80 @@ mod tests {
|
||||
use crate::ecss::PusPacket;
|
||||
use crate::srd::SpHeader;
|
||||
use crate::tc::srd::PusTc;
|
||||
use crate::tc::PusTcSecondaryHeader;
|
||||
use crate::tc::ACK_ALL;
|
||||
use crate::CcsdsPacket;
|
||||
use crate::{CcsdsPacket, PacketType};
|
||||
use postcard::to_stdvec;
|
||||
|
||||
#[test]
|
||||
fn test_tc() {
|
||||
let mut sph = SpHeader::tc(0x01, 0).unwrap();
|
||||
let mut sph = SpHeader::tc(0x01, 0, 0).unwrap();
|
||||
let mut pus_tc = PusTc::new(&mut sph, 17, 1, None);
|
||||
verify_test_tc(&pus_tc);
|
||||
let _out = to_stdvec(&pus_tc).unwrap();
|
||||
assert_eq!(pus_tc.crc16(), None);
|
||||
let mut test_buf: [u8; 32] = [0; 32];
|
||||
pus_tc.update_packet_fields();
|
||||
verify_test_tc(&pus_tc);
|
||||
assert_eq!(pus_tc.len_packed(), 13);
|
||||
let size = pus_tc
|
||||
.copy_to_buf(test_buf.as_mut_slice())
|
||||
.expect("Error writing TC to buffer");
|
||||
let (tc_from_raw, sz) = PusTc::new_from_raw_slice(&test_buf)
|
||||
assert_eq!(size, 13);
|
||||
let (tc_from_raw, mut size) = PusTc::new_from_raw_slice(&test_buf)
|
||||
.expect("Creating PUS TC struct from raw buffer failed");
|
||||
assert_eq!(sz, 13);
|
||||
assert_eq!(size, 13);
|
||||
verify_test_tc(&tc_from_raw);
|
||||
println!("Test buffer: {:02x?} with {size} written bytes", test_buf);
|
||||
verify_test_tc_raw(PacketType::Tm, &test_buf);
|
||||
|
||||
let mut test_vec = Vec::new();
|
||||
let size = pus_tc
|
||||
size = pus_tc
|
||||
.append_to_vec(&mut test_vec)
|
||||
.expect("Error writing TC to vector");
|
||||
println!("Test Vector: {:02x?} with {size} written bytes", test_vec);
|
||||
assert_eq!(size, 13);
|
||||
assert_eq!(&test_buf[0..pus_tc.len_packed()], test_vec.as_slice());
|
||||
verify_test_tc_raw(PacketType::Tm, &test_vec.as_slice());
|
||||
}
|
||||
|
||||
fn verify_test_tc(tc: &PusTc) {
|
||||
assert_eq!(tc.service(), 17);
|
||||
assert_eq!(tc.subservice(), 1);
|
||||
assert_eq!(PusPacket::service(tc), 17);
|
||||
assert_eq!(PusPacket::subservice(tc), 1);
|
||||
assert_eq!(tc.user_data(), None);
|
||||
assert_eq!(tc.source_id(), 0);
|
||||
assert_eq!(tc.apid(), 0x01);
|
||||
assert_eq!(tc.ack_flags(), ACK_ALL);
|
||||
assert_eq!(tc.crc16(), None);
|
||||
assert_eq!(tc.sph, SpHeader::tc(0x01, 0, 6).unwrap());
|
||||
}
|
||||
|
||||
fn verify_test_tc_raw(ptype: PacketType, slice: &impl AsRef<[u8]>) {
|
||||
// Reference comparison implementation:
|
||||
// https://github.com/robamu-org/py-spacepackets/blob/main/examples/example_pus.py
|
||||
let slice = slice.as_ref();
|
||||
// 0x1801 is the generic
|
||||
if ptype == PacketType::Tm {
|
||||
assert_eq!(slice[0], 0x18);
|
||||
} else {
|
||||
assert_eq!(slice[0], 0x08);
|
||||
}
|
||||
// APID is 0x01
|
||||
assert_eq!(slice[1], 0x01);
|
||||
// Unsegmented packets
|
||||
assert_eq!(slice[2], 0xc0);
|
||||
// Sequence count 0
|
||||
assert_eq!(slice[3], 0x00);
|
||||
assert_eq!(slice[4], 0x00);
|
||||
// Space data length of 6 equals total packet length of 13
|
||||
assert_eq!(slice[5], 0x06);
|
||||
// PUS Version C 0b0010 and ACK flags 0b1111
|
||||
assert_eq!(slice[6], 0x2f);
|
||||
// Service 17
|
||||
assert_eq!(slice[7], 0x11);
|
||||
// Subservice 1
|
||||
assert_eq!(slice[8], 0x01);
|
||||
// Source ID 0
|
||||
assert_eq!(slice[9], 0x00);
|
||||
assert_eq!(slice[10], 0x00);
|
||||
// CRC first byte assuming big endian format is 0x16 and 0x1d
|
||||
assert_eq!(slice[11], 0x16);
|
||||
assert_eq!(slice[12], 0x1d);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user