good coverage on TM module
This commit is contained in:
parent
30ab7f961a
commit
b066ea9003
@ -41,7 +41,7 @@ pub enum PusError {
|
|||||||
NoRawData,
|
NoRawData,
|
||||||
/// CRC16 needs to be calculated first
|
/// CRC16 needs to be calculated first
|
||||||
CrcCalculationMissing,
|
CrcCalculationMissing,
|
||||||
OtherPacketError(PacketError),
|
PacketError(PacketError),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait PusPacket: CcsdsPacket {
|
pub trait PusPacket: CcsdsPacket {
|
||||||
@ -75,12 +75,13 @@ pub(crate) fn calc_pus_crc16(bytes: &[u8]) -> u16 {
|
|||||||
pub(crate) fn crc_procedure(
|
pub(crate) fn crc_procedure(
|
||||||
calc_on_serialization: bool,
|
calc_on_serialization: bool,
|
||||||
cached_crc16: &Option<u16>,
|
cached_crc16: &Option<u16>,
|
||||||
|
start_idx: usize,
|
||||||
curr_idx: usize,
|
curr_idx: usize,
|
||||||
slice: &[u8],
|
slice: &[u8],
|
||||||
) -> Result<u16, PusError> {
|
) -> Result<u16, PusError> {
|
||||||
let crc16;
|
let crc16;
|
||||||
if calc_on_serialization {
|
if calc_on_serialization {
|
||||||
crc16 = calc_pus_crc16(&slice[0..curr_idx])
|
crc16 = calc_pus_crc16(&slice[start_idx..curr_idx])
|
||||||
} else if cached_crc16.is_none() {
|
} else if cached_crc16.is_none() {
|
||||||
return Err(PusError::CrcCalculationMissing);
|
return Err(PusError::CrcCalculationMissing);
|
||||||
} else {
|
} else {
|
||||||
|
46
src/tc.rs
46
src/tc.rs
@ -334,33 +334,35 @@ impl<'slice> PusTc<'slice> {
|
|||||||
let tc_header_len = size_of::<zc::PusTcSecondaryHeader>();
|
let tc_header_len = size_of::<zc::PusTcSecondaryHeader>();
|
||||||
let total_size = self.len_packed();
|
let total_size = self.len_packed();
|
||||||
if total_size > slice.len() {
|
if total_size > slice.len() {
|
||||||
return Err(PusError::OtherPacketError(
|
return Err(PusError::PacketError(PacketError::ToBytesSliceTooSmall(
|
||||||
PacketError::ToBytesSliceTooSmall(SizeMissmatch {
|
SizeMissmatch {
|
||||||
found: slice.len(),
|
found: slice.len(),
|
||||||
expected: total_size,
|
expected: total_size,
|
||||||
}),
|
},
|
||||||
));
|
)));
|
||||||
}
|
}
|
||||||
sph_zc
|
sph_zc
|
||||||
.to_bytes(&mut slice[curr_idx..curr_idx + CCSDS_HEADER_LEN])
|
.to_bytes(&mut slice[curr_idx..curr_idx + CCSDS_HEADER_LEN])
|
||||||
.ok_or(PusError::OtherPacketError(
|
.ok_or(PusError::PacketError(PacketError::ToBytesZeroCopyError))?;
|
||||||
PacketError::ToBytesZeroCopyError,
|
|
||||||
))?;
|
|
||||||
|
|
||||||
curr_idx += CCSDS_HEADER_LEN;
|
curr_idx += CCSDS_HEADER_LEN;
|
||||||
let sec_header = zc::PusTcSecondaryHeader::try_from(self.sec_header).unwrap();
|
let sec_header = zc::PusTcSecondaryHeader::try_from(self.sec_header).unwrap();
|
||||||
sec_header
|
sec_header
|
||||||
.to_bytes(&mut slice[curr_idx..curr_idx + tc_header_len])
|
.to_bytes(&mut slice[curr_idx..curr_idx + tc_header_len])
|
||||||
.ok_or(PusError::OtherPacketError(
|
.ok_or(PusError::PacketError(PacketError::ToBytesZeroCopyError))?;
|
||||||
PacketError::ToBytesZeroCopyError,
|
|
||||||
))?;
|
|
||||||
|
|
||||||
curr_idx += tc_header_len;
|
curr_idx += tc_header_len;
|
||||||
if let Some(app_data) = self.app_data {
|
if let Some(app_data) = self.app_data {
|
||||||
slice[curr_idx..curr_idx + app_data.len()].copy_from_slice(app_data);
|
slice[curr_idx..curr_idx + app_data.len()].copy_from_slice(app_data);
|
||||||
curr_idx += app_data.len();
|
curr_idx += app_data.len();
|
||||||
}
|
}
|
||||||
let crc16 = crc_procedure(self.calc_crc_on_serialization, &self.crc16, curr_idx, slice)?;
|
let crc16 = crc_procedure(
|
||||||
|
self.calc_crc_on_serialization,
|
||||||
|
&self.crc16,
|
||||||
|
0,
|
||||||
|
curr_idx,
|
||||||
|
slice,
|
||||||
|
)?;
|
||||||
slice[curr_idx..curr_idx + 2].copy_from_slice(crc16.to_be_bytes().as_slice());
|
slice[curr_idx..curr_idx + 2].copy_from_slice(crc16.to_be_bytes().as_slice());
|
||||||
curr_idx += 2;
|
curr_idx += 2;
|
||||||
Ok(curr_idx)
|
Ok(curr_idx)
|
||||||
@ -374,22 +376,23 @@ impl<'slice> PusTc<'slice> {
|
|||||||
appended_len += app_data.len();
|
appended_len += app_data.len();
|
||||||
};
|
};
|
||||||
let start_idx = vec.len();
|
let start_idx = vec.len();
|
||||||
let mut curr_idx = vec.len();
|
let mut ser_len = 0;
|
||||||
vec.extend_from_slice(sph_zc.as_bytes());
|
vec.extend_from_slice(sph_zc.as_bytes());
|
||||||
curr_idx += sph_zc.as_bytes().len();
|
ser_len += sph_zc.as_bytes().len();
|
||||||
// The PUS version is hardcoded to PUS C
|
// The PUS version is hardcoded to PUS C
|
||||||
let pus_tc_header = zc::PusTcSecondaryHeader::try_from(self.sec_header).unwrap();
|
let pus_tc_header = zc::PusTcSecondaryHeader::try_from(self.sec_header).unwrap();
|
||||||
vec.extend_from_slice(pus_tc_header.as_bytes());
|
vec.extend_from_slice(pus_tc_header.as_bytes());
|
||||||
curr_idx += pus_tc_header.as_bytes().len();
|
ser_len += pus_tc_header.as_bytes().len();
|
||||||
if let Some(app_data) = self.app_data {
|
if let Some(app_data) = self.app_data {
|
||||||
vec.extend_from_slice(app_data);
|
vec.extend_from_slice(app_data);
|
||||||
curr_idx += app_data.len();
|
ser_len += app_data.len();
|
||||||
}
|
}
|
||||||
let crc16 = crc_procedure(
|
let crc16 = crc_procedure(
|
||||||
self.calc_crc_on_serialization,
|
self.calc_crc_on_serialization,
|
||||||
&self.crc16,
|
&self.crc16,
|
||||||
curr_idx,
|
start_idx,
|
||||||
&vec[start_idx..curr_idx],
|
ser_len,
|
||||||
|
&vec[start_idx..ser_len],
|
||||||
)?;
|
)?;
|
||||||
vec.extend_from_slice(crc16.to_be_bytes().as_slice());
|
vec.extend_from_slice(crc16.to_be_bytes().as_slice());
|
||||||
Ok(appended_len)
|
Ok(appended_len)
|
||||||
@ -405,9 +408,7 @@ impl<'slice> PusTc<'slice> {
|
|||||||
let mut current_idx = 0;
|
let mut current_idx = 0;
|
||||||
let sph =
|
let sph =
|
||||||
crate::zc::SpHeader::from_bytes(&slice[current_idx..current_idx + CCSDS_HEADER_LEN])
|
crate::zc::SpHeader::from_bytes(&slice[current_idx..current_idx + CCSDS_HEADER_LEN])
|
||||||
.ok_or(PusError::OtherPacketError(
|
.ok_or(PusError::PacketError(PacketError::FromBytesZeroCopyError))?;
|
||||||
PacketError::FromBytesZeroCopyError,
|
|
||||||
))?;
|
|
||||||
current_idx += CCSDS_HEADER_LEN;
|
current_idx += CCSDS_HEADER_LEN;
|
||||||
let total_len = sph.total_len();
|
let total_len = sph.total_len();
|
||||||
if raw_data_len < total_len || total_len < PUS_TC_MIN_LEN_WITHOUT_APP_DATA {
|
if raw_data_len < total_len || total_len < PUS_TC_MIN_LEN_WITHOUT_APP_DATA {
|
||||||
@ -416,9 +417,7 @@ impl<'slice> PusTc<'slice> {
|
|||||||
let sec_header = crate::tc::zc::PusTcSecondaryHeader::from_bytes(
|
let sec_header = crate::tc::zc::PusTcSecondaryHeader::from_bytes(
|
||||||
&slice[current_idx..current_idx + PUC_TC_SECONDARY_HEADER_LEN],
|
&slice[current_idx..current_idx + PUC_TC_SECONDARY_HEADER_LEN],
|
||||||
)
|
)
|
||||||
.ok_or(PusError::OtherPacketError(
|
.ok_or(PusError::PacketError(PacketError::FromBytesZeroCopyError))?;
|
||||||
PacketError::FromBytesZeroCopyError,
|
|
||||||
))?;
|
|
||||||
current_idx += PUC_TC_SECONDARY_HEADER_LEN;
|
current_idx += PUC_TC_SECONDARY_HEADER_LEN;
|
||||||
let raw_data = &slice[0..total_len];
|
let raw_data = &slice[0..total_len];
|
||||||
let pus_tc = PusTc {
|
let pus_tc = PusTc {
|
||||||
@ -546,6 +545,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
#[cfg(feature = "alloc")]
|
||||||
fn test_vec_ser_deser() {
|
fn test_vec_ser_deser() {
|
||||||
let pus_tc = base_ping_tc_simple_ctor();
|
let pus_tc = base_ping_tc_simple_ctor();
|
||||||
let mut test_vec = Vec::new();
|
let mut test_vec = Vec::new();
|
||||||
|
196
src/tm.rs
196
src/tm.rs
@ -309,27 +309,23 @@ impl<'slice> PusTm<'slice> {
|
|||||||
let sph_zc = crate::zc::SpHeader::from(self.sp_header);
|
let sph_zc = crate::zc::SpHeader::from(self.sp_header);
|
||||||
let total_size = self.len_packed();
|
let total_size = self.len_packed();
|
||||||
if total_size > slice.len() {
|
if total_size > slice.len() {
|
||||||
return Err(PusError::OtherPacketError(
|
return Err(PusError::PacketError(PacketError::ToBytesSliceTooSmall(
|
||||||
PacketError::ToBytesSliceTooSmall(SizeMissmatch {
|
SizeMissmatch {
|
||||||
found: slice.len(),
|
found: slice.len(),
|
||||||
expected: total_size,
|
expected: total_size,
|
||||||
}),
|
},
|
||||||
));
|
)));
|
||||||
}
|
}
|
||||||
sph_zc
|
sph_zc
|
||||||
.to_bytes(&mut slice[curr_idx..curr_idx + CCSDS_HEADER_LEN])
|
.to_bytes(&mut slice[curr_idx..curr_idx + CCSDS_HEADER_LEN])
|
||||||
.ok_or(PusError::OtherPacketError(
|
.ok_or(PusError::PacketError(PacketError::ToBytesZeroCopyError))?;
|
||||||
PacketError::ToBytesZeroCopyError,
|
|
||||||
))?;
|
|
||||||
|
|
||||||
curr_idx += CCSDS_HEADER_LEN;
|
curr_idx += CCSDS_HEADER_LEN;
|
||||||
let sec_header_len = size_of::<zc::PusTmSecHeaderWithoutTimestamp>();
|
let sec_header_len = size_of::<zc::PusTmSecHeaderWithoutTimestamp>();
|
||||||
let sec_header = zc::PusTmSecHeaderWithoutTimestamp::try_from(self.sec_header).unwrap();
|
let sec_header = zc::PusTmSecHeaderWithoutTimestamp::try_from(self.sec_header).unwrap();
|
||||||
sec_header
|
sec_header
|
||||||
.to_bytes(&mut slice[curr_idx..curr_idx + sec_header_len])
|
.to_bytes(&mut slice[curr_idx..curr_idx + sec_header_len])
|
||||||
.ok_or(PusError::OtherPacketError(
|
.ok_or(PusError::PacketError(PacketError::ToBytesZeroCopyError))?;
|
||||||
PacketError::ToBytesZeroCopyError,
|
|
||||||
))?;
|
|
||||||
curr_idx += sec_header_len;
|
curr_idx += sec_header_len;
|
||||||
let timestamp_len = self.sec_header.time_stamp.len();
|
let timestamp_len = self.sec_header.time_stamp.len();
|
||||||
slice[curr_idx..curr_idx + timestamp_len].copy_from_slice(self.sec_header.time_stamp);
|
slice[curr_idx..curr_idx + timestamp_len].copy_from_slice(self.sec_header.time_stamp);
|
||||||
@ -338,7 +334,13 @@ impl<'slice> PusTm<'slice> {
|
|||||||
slice[curr_idx..curr_idx + src_data.len()].copy_from_slice(src_data);
|
slice[curr_idx..curr_idx + src_data.len()].copy_from_slice(src_data);
|
||||||
curr_idx += src_data.len();
|
curr_idx += src_data.len();
|
||||||
}
|
}
|
||||||
let crc16 = crc_procedure(self.calc_crc_on_serialization, &self.crc16, curr_idx, slice)?;
|
let crc16 = crc_procedure(
|
||||||
|
self.calc_crc_on_serialization,
|
||||||
|
&self.crc16,
|
||||||
|
0,
|
||||||
|
curr_idx,
|
||||||
|
slice,
|
||||||
|
)?;
|
||||||
slice[curr_idx..curr_idx + 2].copy_from_slice(crc16.to_be_bytes().as_slice());
|
slice[curr_idx..curr_idx + 2].copy_from_slice(crc16.to_be_bytes().as_slice());
|
||||||
curr_idx += 2;
|
curr_idx += 2;
|
||||||
Ok(curr_idx)
|
Ok(curr_idx)
|
||||||
@ -354,24 +356,25 @@ impl<'slice> PusTm<'slice> {
|
|||||||
appended_len += src_data.len();
|
appended_len += src_data.len();
|
||||||
};
|
};
|
||||||
let start_idx = vec.len();
|
let start_idx = vec.len();
|
||||||
let mut curr_idx = vec.len();
|
let mut ser_len = 0;
|
||||||
vec.extend_from_slice(sph_zc.as_bytes());
|
vec.extend_from_slice(sph_zc.as_bytes());
|
||||||
curr_idx += sph_zc.as_bytes().len();
|
ser_len += sph_zc.as_bytes().len();
|
||||||
// The PUS version is hardcoded to PUS C
|
// The PUS version is hardcoded to PUS C
|
||||||
let sec_header = zc::PusTmSecHeaderWithoutTimestamp::try_from(self.sec_header).unwrap();
|
let sec_header = zc::PusTmSecHeaderWithoutTimestamp::try_from(self.sec_header).unwrap();
|
||||||
vec.extend_from_slice(sec_header.as_bytes());
|
vec.extend_from_slice(sec_header.as_bytes());
|
||||||
curr_idx += sec_header.as_bytes().len();
|
ser_len += sec_header.as_bytes().len();
|
||||||
vec.extend_from_slice(self.sec_header.time_stamp);
|
vec.extend_from_slice(self.sec_header.time_stamp);
|
||||||
curr_idx += self.sec_header.time_stamp.len();
|
ser_len += self.sec_header.time_stamp.len();
|
||||||
if let Some(src_data) = self.source_data {
|
if let Some(src_data) = self.source_data {
|
||||||
vec.extend_from_slice(src_data);
|
vec.extend_from_slice(src_data);
|
||||||
curr_idx += src_data.len();
|
ser_len += src_data.len();
|
||||||
}
|
}
|
||||||
let crc16 = crc_procedure(
|
let crc16 = crc_procedure(
|
||||||
self.calc_crc_on_serialization,
|
self.calc_crc_on_serialization,
|
||||||
&self.crc16,
|
&self.crc16,
|
||||||
curr_idx,
|
start_idx,
|
||||||
&vec[start_idx..curr_idx],
|
ser_len,
|
||||||
|
&vec[start_idx..start_idx + ser_len],
|
||||||
)?;
|
)?;
|
||||||
vec.extend_from_slice(crc16.to_be_bytes().as_slice());
|
vec.extend_from_slice(crc16.to_be_bytes().as_slice());
|
||||||
Ok(appended_len)
|
Ok(appended_len)
|
||||||
@ -391,9 +394,7 @@ impl<'slice> PusTm<'slice> {
|
|||||||
let mut current_idx = 0;
|
let mut current_idx = 0;
|
||||||
let sph =
|
let sph =
|
||||||
crate::zc::SpHeader::from_bytes(&slice[current_idx..current_idx + CCSDS_HEADER_LEN])
|
crate::zc::SpHeader::from_bytes(&slice[current_idx..current_idx + CCSDS_HEADER_LEN])
|
||||||
.ok_or(PusError::OtherPacketError(
|
.ok_or(PusError::PacketError(PacketError::FromBytesZeroCopyError))?;
|
||||||
PacketError::FromBytesZeroCopyError,
|
|
||||||
))?;
|
|
||||||
current_idx += 6;
|
current_idx += 6;
|
||||||
let total_len = sph.total_len();
|
let total_len = sph.total_len();
|
||||||
if raw_data_len < total_len || total_len < PUS_TM_MIN_LEN_WITHOUT_SOURCE_DATA {
|
if raw_data_len < total_len || total_len < PUS_TM_MIN_LEN_WITHOUT_SOURCE_DATA {
|
||||||
@ -402,9 +403,7 @@ impl<'slice> PusTm<'slice> {
|
|||||||
let sec_header_zc = zc::PusTmSecHeaderWithoutTimestamp::from_bytes(
|
let sec_header_zc = zc::PusTmSecHeaderWithoutTimestamp::from_bytes(
|
||||||
&slice[current_idx..current_idx + PUC_TM_MIN_SEC_HEADER_LEN],
|
&slice[current_idx..current_idx + PUC_TM_MIN_SEC_HEADER_LEN],
|
||||||
)
|
)
|
||||||
.ok_or(PusError::OtherPacketError(
|
.ok_or(PusError::PacketError(PacketError::FromBytesZeroCopyError))?;
|
||||||
PacketError::FromBytesZeroCopyError,
|
|
||||||
))?;
|
|
||||||
current_idx += PUC_TM_MIN_SEC_HEADER_LEN;
|
current_idx += PUC_TM_MIN_SEC_HEADER_LEN;
|
||||||
let zc_sec_header_wrapper = zc::PusTmSecHeader {
|
let zc_sec_header_wrapper = zc::PusTmSecHeader {
|
||||||
zc_header: sec_header_zc,
|
zc_header: sec_header_zc,
|
||||||
@ -465,12 +464,18 @@ mod tests {
|
|||||||
use crate::ecss::PusVersion::PusC;
|
use crate::ecss::PusVersion::PusC;
|
||||||
use crate::SpHeader;
|
use crate::SpHeader;
|
||||||
|
|
||||||
fn base_ping_reply_full_ctor(time_stamp: &'static [u8]) -> PusTm<'static> {
|
fn base_ping_reply_full_ctor(time_stamp: &[u8]) -> PusTm {
|
||||||
let mut sph = SpHeader::tc(0x123, 0x234, 0).unwrap();
|
let mut sph = SpHeader::tm(0x123, 0x234, 0).unwrap();
|
||||||
let tc_header = PusTmSecondaryHeader::new_simple(17, 2, &time_stamp);
|
let tc_header = PusTmSecondaryHeader::new_simple(17, 2, &time_stamp);
|
||||||
PusTm::new(&mut sph, tc_header, None, true)
|
PusTm::new(&mut sph, tc_header, None, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn base_hk_reply<'a>(time_stamp: &'a [u8], src_data: &'a [u8]) -> PusTm<'a> {
|
||||||
|
let mut sph = SpHeader::tm(0x123, 0x234, 0).unwrap();
|
||||||
|
let tc_header = PusTmSecondaryHeader::new_simple(3, 5, &time_stamp);
|
||||||
|
PusTm::new(&mut sph, tc_header, Some(src_data), true)
|
||||||
|
}
|
||||||
|
|
||||||
fn dummy_time_stamp() -> &'static [u8] {
|
fn dummy_time_stamp() -> &'static [u8] {
|
||||||
return &[0, 1, 2, 3, 4, 5, 6];
|
return &[0, 1, 2, 3, 4, 5, 6];
|
||||||
}
|
}
|
||||||
@ -479,7 +484,7 @@ mod tests {
|
|||||||
fn test_basic() {
|
fn test_basic() {
|
||||||
let time_stamp = dummy_time_stamp();
|
let time_stamp = dummy_time_stamp();
|
||||||
let pus_tm = base_ping_reply_full_ctor(&time_stamp);
|
let pus_tm = base_ping_reply_full_ctor(&time_stamp);
|
||||||
verify_test_tm_0(&pus_tm, false, 22, dummy_time_stamp());
|
verify_ping_reply(&pus_tm, false, 22, dummy_time_stamp());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -489,6 +494,116 @@ mod tests {
|
|||||||
let mut buf: [u8; 32] = [0; 32];
|
let mut buf: [u8; 32] = [0; 32];
|
||||||
let ser_len = pus_tm.write_to(&mut buf).expect("Serialization failed");
|
let ser_len = pus_tm.write_to(&mut buf).expect("Serialization failed");
|
||||||
assert_eq!(ser_len, 22);
|
assert_eq!(ser_len, 22);
|
||||||
|
verify_raw_ping_reply(&buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_serialization_with_source_data() {
|
||||||
|
let src_data = [1, 2, 3];
|
||||||
|
let hk_reply = base_hk_reply(dummy_time_stamp(), &src_data);
|
||||||
|
let mut buf: [u8; 32] = [0; 32];
|
||||||
|
let ser_len = hk_reply.write_to(&mut buf).expect("Serialization failed");
|
||||||
|
assert_eq!(ser_len, 25);
|
||||||
|
assert_eq!(buf[20], 1);
|
||||||
|
assert_eq!(buf[21], 2);
|
||||||
|
assert_eq!(buf[22], 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_setters() {
|
||||||
|
let time_stamp = dummy_time_stamp();
|
||||||
|
let mut pus_tm = base_ping_reply_full_ctor(&time_stamp);
|
||||||
|
pus_tm.set_sc_time_ref_status(0b1010);
|
||||||
|
pus_tm.set_dest_id(0x7fff);
|
||||||
|
pus_tm.set_msg_counter(0x1f1f);
|
||||||
|
assert_eq!(pus_tm.sc_time_ref_status(), 0b1010);
|
||||||
|
assert_eq!(pus_tm.dest_id(), 0x7fff);
|
||||||
|
assert_eq!(pus_tm.msg_counter(), 0x1f1f);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_deserialization_no_source_data() {
|
||||||
|
let time_stamp = dummy_time_stamp();
|
||||||
|
let pus_tm = base_ping_reply_full_ctor(&time_stamp);
|
||||||
|
let mut buf: [u8; 32] = [0; 32];
|
||||||
|
let ser_len = pus_tm.write_to(&mut buf).expect("Serialization failed");
|
||||||
|
assert_eq!(ser_len, 22);
|
||||||
|
let (tm_deserialized, size) =
|
||||||
|
PusTm::new_from_raw_slice(&buf, 7).expect("Deserialization failed");
|
||||||
|
assert_eq!(ser_len, size);
|
||||||
|
verify_ping_reply(&tm_deserialized, false, 22, dummy_time_stamp());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_manual_field_update() {
|
||||||
|
let mut sph = SpHeader::tm(0x123, 0x234, 0).unwrap();
|
||||||
|
let tc_header = PusTmSecondaryHeader::new_simple(17, 2, dummy_time_stamp());
|
||||||
|
let mut tm = PusTm::new(&mut sph, tc_header, None, false);
|
||||||
|
tm.calc_crc_on_serialization = false;
|
||||||
|
assert_eq!(tm.data_len(), 0x00);
|
||||||
|
let mut buf: [u8; 32] = [0; 32];
|
||||||
|
let res = tm.write_to(&mut buf);
|
||||||
|
assert!(res.is_err());
|
||||||
|
assert!(matches!(res.unwrap_err(), PusError::CrcCalculationMissing));
|
||||||
|
tm.update_ccsds_data_len();
|
||||||
|
assert_eq!(tm.data_len(), 15);
|
||||||
|
tm.calc_own_crc16();
|
||||||
|
let res = tm.write_to(&mut buf);
|
||||||
|
assert!(res.is_ok());
|
||||||
|
tm.sp_header.data_len = 0;
|
||||||
|
tm.update_packet_fields();
|
||||||
|
assert_eq!(tm.data_len(), 15);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_target_buf_too_small() {
|
||||||
|
let time_stamp = dummy_time_stamp();
|
||||||
|
let pus_tm = base_ping_reply_full_ctor(&time_stamp);
|
||||||
|
let mut buf: [u8; 16] = [0; 16];
|
||||||
|
let res = pus_tm.write_to(&mut buf);
|
||||||
|
assert!(res.is_err());
|
||||||
|
let error = res.unwrap_err();
|
||||||
|
assert!(matches!(error, PusError::PacketError { .. }));
|
||||||
|
match error {
|
||||||
|
PusError::PacketError(err) => match err {
|
||||||
|
PacketError::ToBytesSliceTooSmall(size_missmatch) => {
|
||||||
|
assert_eq!(size_missmatch.expected, 22);
|
||||||
|
assert_eq!(size_missmatch.found, 16);
|
||||||
|
}
|
||||||
|
_ => panic!("Invalid PUS error {:?}", err),
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
panic!("Invalid error {:?}", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(feature = "alloc")]
|
||||||
|
fn test_append_to_vec() {
|
||||||
|
let time_stamp = dummy_time_stamp();
|
||||||
|
let pus_tm = base_ping_reply_full_ctor(&time_stamp);
|
||||||
|
let mut vec = Vec::new();
|
||||||
|
let res = pus_tm.append_to_vec(&mut vec);
|
||||||
|
assert!(res.is_ok());
|
||||||
|
assert_eq!(res.unwrap(), 22);
|
||||||
|
verify_raw_ping_reply(vec.as_slice());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(feature = "alloc")]
|
||||||
|
fn test_append_to_vec_with_src_data() {
|
||||||
|
let src_data = [1, 2, 3];
|
||||||
|
let hk_reply = base_hk_reply(dummy_time_stamp(), &src_data);
|
||||||
|
let mut vec = Vec::new();
|
||||||
|
vec.push(4);
|
||||||
|
let res = hk_reply.append_to_vec(&mut vec);
|
||||||
|
assert!(res.is_ok());
|
||||||
|
assert_eq!(res.unwrap(), 25);
|
||||||
|
assert_eq!(vec.len(), 26);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn verify_raw_ping_reply(buf: &[u8]) {
|
||||||
// Secondary header is set -> 0b0000_1001 , APID occupies last bit of first byte
|
// Secondary header is set -> 0b0000_1001 , APID occupies last bit of first byte
|
||||||
assert_eq!(buf[0], 0x09);
|
assert_eq!(buf[0], 0x09);
|
||||||
// Rest of APID 0x123
|
// Rest of APID 0x123
|
||||||
@ -516,32 +631,7 @@ mod tests {
|
|||||||
assert_eq!((crc16 & 0xff) as u8, buf[21]);
|
assert_eq!((crc16 & 0xff) as u8, buf[21]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
fn verify_ping_reply(
|
||||||
fn test_setters() {
|
|
||||||
let time_stamp = dummy_time_stamp();
|
|
||||||
let mut pus_tm = base_ping_reply_full_ctor(&time_stamp);
|
|
||||||
pus_tm.set_sc_time_ref_status(0b1010);
|
|
||||||
pus_tm.set_dest_id(0x7fff);
|
|
||||||
pus_tm.set_msg_counter(0x1f1f);
|
|
||||||
assert_eq!(pus_tm.sc_time_ref_status(), 0b1010);
|
|
||||||
assert_eq!(pus_tm.dest_id(), 0x7fff);
|
|
||||||
assert_eq!(pus_tm.msg_counter(), 0x1f1f);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_deserialization() {
|
|
||||||
let time_stamp = dummy_time_stamp();
|
|
||||||
let pus_tm = base_ping_reply_full_ctor(&time_stamp);
|
|
||||||
let mut buf: [u8; 32] = [0; 32];
|
|
||||||
let ser_len = pus_tm.write_to(&mut buf).expect("Serialization failed");
|
|
||||||
assert_eq!(ser_len, 22);
|
|
||||||
let (tm_deserialized, size) =
|
|
||||||
PusTm::new_from_raw_slice(&buf, 7).expect("Deserialization failed");
|
|
||||||
assert_eq!(ser_len, size);
|
|
||||||
verify_test_tm_0(&tm_deserialized, false, 22, dummy_time_stamp());
|
|
||||||
}
|
|
||||||
|
|
||||||
fn verify_test_tm_0(
|
|
||||||
tm: &PusTm,
|
tm: &PusTm,
|
||||||
has_user_data: bool,
|
has_user_data: bool,
|
||||||
exp_full_len: usize,
|
exp_full_len: usize,
|
||||||
|
Loading…
Reference in New Issue
Block a user