Coverage Update #47
@ -152,8 +152,7 @@ pub enum RealPfc {
|
|||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
pub enum PusError {
|
pub enum PusError {
|
||||||
VersionNotSupported(PusVersion),
|
VersionNotSupported(PusVersion),
|
||||||
IncorrectCrc(u16),
|
ChecksumFailure(u16),
|
||||||
NoRawData,
|
|
||||||
/// CRC16 needs to be calculated first
|
/// CRC16 needs to be calculated first
|
||||||
CrcCalculationMissing,
|
CrcCalculationMissing,
|
||||||
ByteConversion(ByteConversionError),
|
ByteConversion(ByteConversionError),
|
||||||
@ -165,11 +164,8 @@ impl Display for PusError {
|
|||||||
PusError::VersionNotSupported(v) => {
|
PusError::VersionNotSupported(v) => {
|
||||||
write!(f, "PUS version {v:?} not supported")
|
write!(f, "PUS version {v:?} not supported")
|
||||||
}
|
}
|
||||||
PusError::IncorrectCrc(crc) => {
|
PusError::ChecksumFailure(crc) => {
|
||||||
write!(f, "crc16 {crc:#04x} is incorrect")
|
write!(f, "checksum verification for crc16 {crc:#06x} failed")
|
||||||
}
|
|
||||||
PusError::NoRawData => {
|
|
||||||
write!(f, "no raw data provided")
|
|
||||||
}
|
}
|
||||||
PusError::CrcCalculationMissing => {
|
PusError::CrcCalculationMissing => {
|
||||||
write!(f, "crc16 was not calculated")
|
write!(f, "crc16 was not calculated")
|
||||||
@ -269,7 +265,7 @@ pub(crate) fn verify_crc16_ccitt_false_from_raw_to_pus_error(
|
|||||||
) -> Result<(), PusError> {
|
) -> Result<(), PusError> {
|
||||||
verify_crc16_ccitt_false_from_raw(raw_data)
|
verify_crc16_ccitt_false_from_raw(raw_data)
|
||||||
.then(|| ())
|
.then(|| ())
|
||||||
.ok_or(PusError::IncorrectCrc(crc16))
|
.ok_or(PusError::ChecksumFailure(crc16))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn verify_crc16_ccitt_false_from_raw(raw_data: &[u8]) -> bool {
|
pub(crate) fn verify_crc16_ccitt_false_from_raw(raw_data: &[u8]) -> bool {
|
||||||
@ -391,6 +387,9 @@ mod tests {
|
|||||||
fn test_enum_u8() {
|
fn test_enum_u8() {
|
||||||
let mut buf = [0, 0, 0];
|
let mut buf = [0, 0, 0];
|
||||||
let my_enum = EcssEnumU8::new(1);
|
let my_enum = EcssEnumU8::new(1);
|
||||||
|
assert_eq!(EcssEnumU8::ptc(), Ptc::Enumerated);
|
||||||
|
assert_eq!(my_enum.size(), 1);
|
||||||
|
assert_eq!(my_enum.pfc(), 8);
|
||||||
my_enum
|
my_enum
|
||||||
.write_to_be_bytes(&mut buf[1..2])
|
.write_to_be_bytes(&mut buf[1..2])
|
||||||
.expect("To byte conversion of u8 failed");
|
.expect("To byte conversion of u8 failed");
|
||||||
@ -404,6 +403,8 @@ mod tests {
|
|||||||
my_enum
|
my_enum
|
||||||
.write_to_be_bytes(&mut buf[1..3])
|
.write_to_be_bytes(&mut buf[1..3])
|
||||||
.expect("To byte conversion of u8 failed");
|
.expect("To byte conversion of u8 failed");
|
||||||
|
assert_eq!(my_enum.size(), 2);
|
||||||
|
assert_eq!(my_enum.pfc(), 16);
|
||||||
assert_eq!(buf[1], 0x1f);
|
assert_eq!(buf[1], 0x1f);
|
||||||
assert_eq!(buf[2], 0x2f);
|
assert_eq!(buf[2], 0x2f);
|
||||||
}
|
}
|
||||||
@ -477,4 +478,18 @@ mod tests {
|
|||||||
let ptc = Ptc::try_from(ptc_raw).unwrap();
|
let ptc = Ptc::try_from(ptc_raw).unwrap();
|
||||||
assert_eq!(ptc, Ptc::AbsoluteTime);
|
assert_eq!(ptc, Ptc::AbsoluteTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_unsigned_pfc_from_u8() {
|
||||||
|
let pfc_raw = UnsignedPfc::OneByte as u8;
|
||||||
|
let pfc = UnsignedPfc::try_from(pfc_raw).unwrap();
|
||||||
|
assert_eq!(pfc, UnsignedPfc::OneByte);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_real_pfc_from_u8() {
|
||||||
|
let pfc_raw = RealPfc::Double as u8;
|
||||||
|
let pfc = RealPfc::try_from(pfc_raw).unwrap();
|
||||||
|
assert_eq!(pfc, RealPfc::Double);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -878,6 +878,7 @@ mod tests {
|
|||||||
use crate::ecss::{PusError, PusPacket, WritablePusPacket};
|
use crate::ecss::{PusError, PusPacket, WritablePusPacket};
|
||||||
use crate::{ByteConversionError, SpHeader};
|
use crate::{ByteConversionError, SpHeader};
|
||||||
use crate::{CcsdsPacket, SequenceFlags};
|
use crate::{CcsdsPacket, SequenceFlags};
|
||||||
|
use alloc::string::ToString;
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
|
|
||||||
fn base_ping_tc_full_ctor() -> PusTcCreator<'static> {
|
fn base_ping_tc_full_ctor() -> PusTcCreator<'static> {
|
||||||
@ -1013,10 +1014,19 @@ mod tests {
|
|||||||
.write_to_bytes(test_buf.as_mut_slice())
|
.write_to_bytes(test_buf.as_mut_slice())
|
||||||
.expect("Error writing TC to buffer");
|
.expect("Error writing TC to buffer");
|
||||||
test_buf[12] = 0;
|
test_buf[12] = 0;
|
||||||
|
test_buf[11] = 0;
|
||||||
let res = PusTcReader::new(&test_buf);
|
let res = PusTcReader::new(&test_buf);
|
||||||
assert!(res.is_err());
|
assert!(res.is_err());
|
||||||
let err = res.unwrap_err();
|
let err = res.unwrap_err();
|
||||||
assert!(matches!(err, PusError::IncorrectCrc { .. }));
|
if let PusError::ChecksumFailure(crc) = err {
|
||||||
|
assert_eq!(crc, 0);
|
||||||
|
assert_eq!(
|
||||||
|
err.to_string(),
|
||||||
|
"checksum verification for crc16 0x0000 failed"
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
panic!("unexpected error {err}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
152
src/ecss/tm.rs
152
src/ecss/tm.rs
@ -556,21 +556,21 @@ impl<'raw_data> PusTmCreator<'raw_data> {
|
|||||||
/// automatically
|
/// automatically
|
||||||
/// * `sec_header` - Information contained in the secondary header, including the service
|
/// * `sec_header` - Information contained in the secondary header, including the service
|
||||||
/// and subservice type
|
/// and subservice type
|
||||||
/// * `app_data` - Custom application data
|
/// * `source_data` - Custom application data
|
||||||
/// * `set_ccsds_len` - Can be used to automatically update the CCSDS space packet data length
|
/// * `set_ccsds_len` - Can be used to automatically update the CCSDS space packet data length
|
||||||
/// field. If this is not set to true, [PusTm::update_ccsds_data_len] can be called to set
|
/// field. If this is not set to true, [PusTm::update_ccsds_data_len] can be called to set
|
||||||
/// the correct value to this field manually
|
/// the correct value to this field manually
|
||||||
pub fn new(
|
pub fn new(
|
||||||
sp_header: &mut SpHeader,
|
sp_header: &mut SpHeader,
|
||||||
sec_header: PusTmSecondaryHeader<'raw_data>,
|
sec_header: PusTmSecondaryHeader<'raw_data>,
|
||||||
source_data: Option<&'raw_data [u8]>,
|
source_data: &'raw_data [u8],
|
||||||
set_ccsds_len: bool,
|
set_ccsds_len: bool,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
sp_header.set_packet_type(PacketType::Tm);
|
sp_header.set_packet_type(PacketType::Tm);
|
||||||
sp_header.set_sec_header_flag();
|
sp_header.set_sec_header_flag();
|
||||||
let mut pus_tm = Self {
|
let mut pus_tm = Self {
|
||||||
sp_header: *sp_header,
|
sp_header: *sp_header,
|
||||||
source_data: source_data.unwrap_or(&[]),
|
source_data,
|
||||||
sec_header,
|
sec_header,
|
||||||
calc_crc_on_serialization: true,
|
calc_crc_on_serialization: true,
|
||||||
};
|
};
|
||||||
@ -586,7 +586,7 @@ impl<'raw_data> PusTmCreator<'raw_data> {
|
|||||||
subservice: u8,
|
subservice: u8,
|
||||||
time_provider: &impl TimeWriter,
|
time_provider: &impl TimeWriter,
|
||||||
stamp_buf: &'raw_data mut [u8],
|
stamp_buf: &'raw_data mut [u8],
|
||||||
source_data: Option<&'raw_data [u8]>,
|
source_data: &'raw_data [u8],
|
||||||
set_ccsds_len: bool,
|
set_ccsds_len: bool,
|
||||||
) -> Result<Self, TimestampError> {
|
) -> Result<Self, TimestampError> {
|
||||||
let stamp_size = time_provider.write_to_bytes(stamp_buf)?;
|
let stamp_size = time_provider.write_to_bytes(stamp_buf)?;
|
||||||
@ -594,6 +594,25 @@ impl<'raw_data> PusTmCreator<'raw_data> {
|
|||||||
PusTmSecondaryHeader::new_simple(service, subservice, &stamp_buf[0..stamp_size]);
|
PusTmSecondaryHeader::new_simple(service, subservice, &stamp_buf[0..stamp_size]);
|
||||||
Ok(Self::new(sp_header, sec_header, source_data, set_ccsds_len))
|
Ok(Self::new(sp_header, sec_header, source_data, set_ccsds_len))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new_no_source_data(
|
||||||
|
sp_header: &mut SpHeader,
|
||||||
|
sec_header: PusTmSecondaryHeader<'raw_data>,
|
||||||
|
set_ccsds_len: bool,
|
||||||
|
) -> Self {
|
||||||
|
sp_header.set_packet_type(PacketType::Tm);
|
||||||
|
sp_header.set_sec_header_flag();
|
||||||
|
let mut pus_tm = Self {
|
||||||
|
sp_header: *sp_header,
|
||||||
|
source_data: &[],
|
||||||
|
sec_header,
|
||||||
|
calc_crc_on_serialization: true,
|
||||||
|
};
|
||||||
|
if set_ccsds_len {
|
||||||
|
pus_tm.update_ccsds_data_len();
|
||||||
|
}
|
||||||
|
pus_tm
|
||||||
|
}
|
||||||
pub fn timestamp(&self) -> &[u8] {
|
pub fn timestamp(&self) -> &[u8] {
|
||||||
self.sec_header.timestamp
|
self.sec_header.timestamp
|
||||||
}
|
}
|
||||||
@ -973,20 +992,23 @@ impl<'raw> PusTmZeroCopyWriter<'raw> {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use alloc::string::ToString;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::ecss::PusVersion::PusC;
|
use crate::ecss::PusVersion::PusC;
|
||||||
|
use crate::time::cds::TimeProvider;
|
||||||
use crate::SpHeader;
|
use crate::SpHeader;
|
||||||
|
|
||||||
fn base_ping_reply_full_ctor(timestamp: &[u8]) -> PusTmCreator {
|
fn base_ping_reply_full_ctor(timestamp: &[u8]) -> PusTmCreator {
|
||||||
let mut sph = SpHeader::tm_unseg(0x123, 0x234, 0).unwrap();
|
let mut sph = SpHeader::tm_unseg(0x123, 0x234, 0).unwrap();
|
||||||
let tm_header = PusTmSecondaryHeader::new_simple(17, 2, timestamp);
|
let tm_header = PusTmSecondaryHeader::new_simple(17, 2, timestamp);
|
||||||
PusTmCreator::new(&mut sph, tm_header, None, true)
|
PusTmCreator::new_no_source_data(&mut sph, tm_header, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn base_hk_reply<'a>(timestamp: &'a [u8], src_data: &'a [u8]) -> PusTmCreator<'a> {
|
fn base_hk_reply<'a>(timestamp: &'a [u8], src_data: &'a [u8]) -> PusTmCreator<'a> {
|
||||||
let mut sph = SpHeader::tm_unseg(0x123, 0x234, 0).unwrap();
|
let mut sph = SpHeader::tm_unseg(0x123, 0x234, 0).unwrap();
|
||||||
let tc_header = PusTmSecondaryHeader::new_simple(3, 5, timestamp);
|
let tc_header = PusTmSecondaryHeader::new_simple(3, 5, timestamp);
|
||||||
PusTmCreator::new(&mut sph, tc_header, Some(src_data), true)
|
PusTmCreator::new(&mut sph, tc_header, src_data, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dummy_timestamp() -> &'static [u8] {
|
fn dummy_timestamp() -> &'static [u8] {
|
||||||
@ -999,6 +1021,16 @@ mod tests {
|
|||||||
let pus_tm = base_ping_reply_full_ctor(timestamp);
|
let pus_tm = base_ping_reply_full_ctor(timestamp);
|
||||||
verify_ping_reply(&pus_tm, false, 22, dummy_timestamp());
|
verify_ping_reply(&pus_tm, false, 22, dummy_timestamp());
|
||||||
}
|
}
|
||||||
|
#[test]
|
||||||
|
fn test_basic_simple_api() {
|
||||||
|
let mut sph = SpHeader::tm_unseg(0x123, 0x234, 0).unwrap();
|
||||||
|
let time_provider = TimeProvider::new_with_u16_days(0, 0);
|
||||||
|
let mut stamp_buf: [u8; 8] = [0; 8];
|
||||||
|
let pus_tm =
|
||||||
|
PusTmCreator::new_simple(&mut sph, 17, 2, &time_provider, &mut stamp_buf, &[], true)
|
||||||
|
.unwrap();
|
||||||
|
verify_ping_reply(&pus_tm, false, 22, &[64, 0, 0, 0, 0, 0, 0]);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_serialization_no_source_data() {
|
fn test_serialization_no_source_data() {
|
||||||
@ -1009,7 +1041,7 @@ mod tests {
|
|||||||
.write_to_bytes(&mut buf)
|
.write_to_bytes(&mut buf)
|
||||||
.expect("Serialization failed");
|
.expect("Serialization failed");
|
||||||
assert_eq!(ser_len, 22);
|
assert_eq!(ser_len, 22);
|
||||||
verify_raw_ping_reply(&buf);
|
verify_raw_ping_reply(pus_tm.crc16().unwrap(), &buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -1062,14 +1094,39 @@ mod tests {
|
|||||||
assert_eq!(ser_len, 22);
|
assert_eq!(ser_len, 22);
|
||||||
let (tm_deserialized, size) = PusTmReader::new(&buf, 7).expect("Deserialization failed");
|
let (tm_deserialized, size) = PusTmReader::new(&buf, 7).expect("Deserialization failed");
|
||||||
assert_eq!(ser_len, size);
|
assert_eq!(ser_len, size);
|
||||||
|
assert_eq!(tm_deserialized.user_data(), tm_deserialized.source_data());
|
||||||
|
assert_eq!(tm_deserialized.raw_data(), &buf[..ser_len]);
|
||||||
|
assert_eq!(tm_deserialized.crc16().unwrap(), pus_tm.crc16().unwrap());
|
||||||
verify_ping_reply_with_reader(&tm_deserialized, false, 22, dummy_timestamp());
|
verify_ping_reply_with_reader(&tm_deserialized, false, 22, dummy_timestamp());
|
||||||
}
|
}
|
||||||
|
#[test]
|
||||||
|
fn test_deserialization_faulty_crc() {
|
||||||
|
let timestamp = dummy_timestamp();
|
||||||
|
let pus_tm = base_ping_reply_full_ctor(timestamp);
|
||||||
|
let mut buf: [u8; 32] = [0; 32];
|
||||||
|
let ser_len = pus_tm
|
||||||
|
.write_to_bytes(&mut buf)
|
||||||
|
.expect("Serialization failed");
|
||||||
|
assert_eq!(ser_len, 22);
|
||||||
|
buf[ser_len - 2] = 0;
|
||||||
|
buf[ser_len - 1] = 0;
|
||||||
|
let tm_error = PusTmReader::new(&buf, 7);
|
||||||
|
assert!(tm_error.is_err());
|
||||||
|
let tm_error = tm_error.unwrap_err();
|
||||||
|
if let PusError::ChecksumFailure(crc) = tm_error {
|
||||||
|
assert_eq!(crc, 0);
|
||||||
|
assert_eq!(
|
||||||
|
tm_error.to_string(),
|
||||||
|
"checksum verification for crc16 0x0000 failed"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_manual_field_update() {
|
fn test_manual_field_update() {
|
||||||
let mut sph = SpHeader::tm_unseg(0x123, 0x234, 0).unwrap();
|
let mut sph = SpHeader::tm_unseg(0x123, 0x234, 0).unwrap();
|
||||||
let tc_header = PusTmSecondaryHeader::new_simple(17, 2, dummy_timestamp());
|
let tc_header = PusTmSecondaryHeader::new_simple(17, 2, dummy_timestamp());
|
||||||
let mut tm = PusTmCreator::new(&mut sph, tc_header, None, false);
|
let mut tm = PusTmCreator::new_no_source_data(&mut sph, tc_header, false);
|
||||||
tm.calc_crc_on_serialization = false;
|
tm.calc_crc_on_serialization = false;
|
||||||
assert_eq!(tm.data_len(), 0x00);
|
assert_eq!(tm.data_len(), 0x00);
|
||||||
let mut buf: [u8; 32] = [0; 32];
|
let mut buf: [u8; 32] = [0; 32];
|
||||||
@ -1115,7 +1172,7 @@ mod tests {
|
|||||||
let res = pus_tm.append_to_vec(&mut vec);
|
let res = pus_tm.append_to_vec(&mut vec);
|
||||||
assert!(res.is_ok());
|
assert!(res.is_ok());
|
||||||
assert_eq!(res.unwrap(), 22);
|
assert_eq!(res.unwrap(), 22);
|
||||||
verify_raw_ping_reply(vec.as_slice());
|
verify_raw_ping_reply(pus_tm.crc16().unwrap(), vec.as_slice());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -1131,7 +1188,7 @@ mod tests {
|
|||||||
assert_eq!(vec.len(), 26);
|
assert_eq!(vec.len(), 26);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify_raw_ping_reply(buf: &[u8]) {
|
fn verify_raw_ping_reply(crc16: u16, 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
|
||||||
@ -1154,9 +1211,10 @@ mod tests {
|
|||||||
assert_eq!(&buf[13..20], dummy_timestamp());
|
assert_eq!(&buf[13..20], dummy_timestamp());
|
||||||
let mut digest = CRC_CCITT_FALSE.digest();
|
let mut digest = CRC_CCITT_FALSE.digest();
|
||||||
digest.update(&buf[0..20]);
|
digest.update(&buf[0..20]);
|
||||||
let crc16 = digest.finalize();
|
let crc16_calced = digest.finalize();
|
||||||
assert_eq!(((crc16 >> 8) & 0xff) as u8, buf[20]);
|
assert_eq!(((crc16 >> 8) & 0xff) as u8, buf[20]);
|
||||||
assert_eq!((crc16 & 0xff) as u8, buf[21]);
|
assert_eq!((crc16 & 0xff) as u8, buf[21]);
|
||||||
|
assert_eq!(crc16, crc16_calced);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify_ping_reply(
|
fn verify_ping_reply(
|
||||||
@ -1167,6 +1225,7 @@ mod tests {
|
|||||||
) {
|
) {
|
||||||
assert_eq!(tm.len_written(), exp_full_len);
|
assert_eq!(tm.len_written(), exp_full_len);
|
||||||
assert_eq!(tm.timestamp(), exp_timestamp);
|
assert_eq!(tm.timestamp(), exp_timestamp);
|
||||||
|
assert_eq!(tm.source_data(), tm.user_data());
|
||||||
verify_ping_reply_generic(tm, has_user_data, exp_full_len);
|
verify_ping_reply_generic(tm, has_user_data, exp_full_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1188,7 +1247,9 @@ mod tests {
|
|||||||
) {
|
) {
|
||||||
assert!(tm.is_tm());
|
assert!(tm.is_tm());
|
||||||
assert_eq!(PusPacket::service(tm), 17);
|
assert_eq!(PusPacket::service(tm), 17);
|
||||||
|
assert_eq!(GenericPusTmSecondaryHeader::service(tm), 17);
|
||||||
assert_eq!(PusPacket::subservice(tm), 2);
|
assert_eq!(PusPacket::subservice(tm), 2);
|
||||||
|
assert_eq!(GenericPusTmSecondaryHeader::subservice(tm), 2);
|
||||||
assert!(tm.sec_header_flag());
|
assert!(tm.sec_header_flag());
|
||||||
if has_user_data {
|
if has_user_data {
|
||||||
assert!(!tm.user_data().is_empty());
|
assert!(!tm.user_data().is_empty());
|
||||||
@ -1196,6 +1257,11 @@ mod tests {
|
|||||||
assert_eq!(PusPacket::pus_version(tm), PusC);
|
assert_eq!(PusPacket::pus_version(tm), PusC);
|
||||||
assert_eq!(tm.apid(), 0x123);
|
assert_eq!(tm.apid(), 0x123);
|
||||||
assert_eq!(tm.seq_count(), 0x234);
|
assert_eq!(tm.seq_count(), 0x234);
|
||||||
|
assert_eq!(PusPacket::pus_version(tm), PusVersion::PusC);
|
||||||
|
assert_eq!(
|
||||||
|
GenericPusTmSecondaryHeader::pus_version(tm),
|
||||||
|
PusVersion::PusC
|
||||||
|
);
|
||||||
assert_eq!(tm.data_len(), exp_full_len as u16 - 7);
|
assert_eq!(tm.data_len(), exp_full_len as u16 - 7);
|
||||||
assert_eq!(tm.dest_id(), 0x0000);
|
assert_eq!(tm.dest_id(), 0x0000);
|
||||||
assert_eq!(tm.msg_counter(), 0x0000);
|
assert_eq!(tm.msg_counter(), 0x0000);
|
||||||
@ -1232,6 +1298,10 @@ mod tests {
|
|||||||
writer.set_msg_count(100);
|
writer.set_msg_count(100);
|
||||||
writer.set_seq_count(MAX_SEQ_COUNT);
|
writer.set_seq_count(MAX_SEQ_COUNT);
|
||||||
writer.set_apid(MAX_APID);
|
writer.set_apid(MAX_APID);
|
||||||
|
assert!(!writer.set_apid(MAX_APID + 1));
|
||||||
|
assert!(!writer.set_apid(MAX_SEQ_COUNT + 1));
|
||||||
|
assert_eq!(writer.service(), 17);
|
||||||
|
assert_eq!(writer.subservice(), 2);
|
||||||
writer.finish();
|
writer.finish();
|
||||||
// This performs all necessary checks, including the CRC check.
|
// This performs all necessary checks, including the CRC check.
|
||||||
let (tm_read_back, tm_size_read_back) =
|
let (tm_read_back, tm_size_read_back) =
|
||||||
@ -1242,4 +1312,64 @@ mod tests {
|
|||||||
assert_eq!(tm_read_back.seq_count(), MAX_SEQ_COUNT);
|
assert_eq!(tm_read_back.seq_count(), MAX_SEQ_COUNT);
|
||||||
assert_eq!(tm_read_back.apid(), MAX_APID);
|
assert_eq!(tm_read_back.apid(), MAX_APID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_sec_header_without_stamp() {
|
||||||
|
let sec_header = PusTmSecondaryHeader::new_simple_no_timestamp(17, 1);
|
||||||
|
assert_eq!(sec_header.timestamp, &[]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_reader_partial_eq() {
|
||||||
|
let timestamp = dummy_timestamp();
|
||||||
|
let pus_tm = base_ping_reply_full_ctor(timestamp);
|
||||||
|
let mut buf = [0; 32];
|
||||||
|
pus_tm.write_to_bytes(&mut buf).unwrap();
|
||||||
|
let (tm_0, _) = PusTmReader::new(&buf, timestamp.len()).unwrap();
|
||||||
|
let (tm_1, _) = PusTmReader::new(&buf, timestamp.len()).unwrap();
|
||||||
|
assert_eq!(tm_0, tm_1);
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn test_reader_buf_too_small_2() {
|
||||||
|
let timestamp = dummy_timestamp();
|
||||||
|
let pus_tm = base_ping_reply_full_ctor(timestamp);
|
||||||
|
let mut buf = [0; 32];
|
||||||
|
let written = pus_tm.write_to_bytes(&mut buf).unwrap();
|
||||||
|
let tm_error = PusTmReader::new(
|
||||||
|
&buf[0..PUS_TM_MIN_LEN_WITHOUT_SOURCE_DATA + 1],
|
||||||
|
timestamp.len(),
|
||||||
|
);
|
||||||
|
assert!(tm_error.is_err());
|
||||||
|
let tm_error = tm_error.unwrap_err();
|
||||||
|
if let PusError::ByteConversion(ByteConversionError::FromSliceTooSmall {
|
||||||
|
found,
|
||||||
|
expected,
|
||||||
|
}) = tm_error
|
||||||
|
{
|
||||||
|
assert_eq!(found, PUS_TM_MIN_LEN_WITHOUT_SOURCE_DATA + 1);
|
||||||
|
assert_eq!(expected, written);
|
||||||
|
} else {
|
||||||
|
panic!("unexpected error {tm_error}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn test_reader_buf_too_small() {
|
||||||
|
let timestamp = dummy_timestamp();
|
||||||
|
let pus_tm = base_ping_reply_full_ctor(timestamp);
|
||||||
|
let mut buf = [0; 32];
|
||||||
|
pus_tm.write_to_bytes(&mut buf).unwrap();
|
||||||
|
let tm_error = PusTmReader::new(&buf[0..5], timestamp.len());
|
||||||
|
assert!(tm_error.is_err());
|
||||||
|
let tm_error = tm_error.unwrap_err();
|
||||||
|
if let PusError::ByteConversion(ByteConversionError::FromSliceTooSmall {
|
||||||
|
found,
|
||||||
|
expected,
|
||||||
|
}) = tm_error
|
||||||
|
{
|
||||||
|
assert_eq!(found, 5);
|
||||||
|
assert_eq!(expected, PUS_TM_MIN_LEN_WITHOUT_SOURCE_DATA);
|
||||||
|
} else {
|
||||||
|
panic!("unexpected error {tm_error}")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user