From 3b9a03590ad927562e0cd928a63f08d680c03bec Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 5 Aug 2022 00:24:29 +0200 Subject: [PATCH] ready for release --- Cargo.toml | 2 - src/tc.rs | 30 +++++++++++- src/time.rs | 129 +++++++++++++++++++++++++++++++++++++++++++++++++--- src/tm.rs | 2 + 4 files changed, 154 insertions(+), 9 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4268a7e..ae0f070 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,8 +23,6 @@ chrono = "0.4.19" version = "0.7.14" optional = true -[dev-dependencies] - [dev-dependencies.postcard] version = "0.7.3" features = ["use-std"] diff --git a/src/tc.rs b/src/tc.rs index c100118..9d5ac5c 100644 --- a/src/tc.rs +++ b/src/tc.rs @@ -472,8 +472,8 @@ mod tests { use crate::ecss::{PusError, PusPacket}; use crate::tc::ACK_ALL; use crate::tc::{PusTc, PusTcSecondaryHeader, PusTcSecondaryHeaderT}; - use crate::SpHeader; use crate::{CcsdsPacket, SequenceFlags}; + use crate::{PacketError, SpHeader}; use alloc::vec::Vec; fn base_ping_tc_full_ctor() -> PusTc<'static> { @@ -526,6 +526,15 @@ mod tests { verify_crc_no_app_data(&test_buf); } + #[test] + fn test_update_func() { + let mut sph = SpHeader::tc(0x02, 0x34, 0).unwrap(); + let mut tc = PusTc::new_simple(&mut sph, 17, 1, None, false); + tc.calc_crc_on_serialization = false; + assert_eq!(tc.data_len(), 0); + tc.update_packet_fields(); + assert_eq!(tc.data_len(), 6); + } #[test] fn test_deserialization_with_app_data() { let pus_tc = base_ping_tc_simple_ctor_with_app_data(&[1, 2, 3]); @@ -609,6 +618,25 @@ mod tests { assert_eq!(size, 16); } + #[test] + fn test_write_buf_too_msall() { + let pus_tc = base_ping_tc_simple_ctor(); + let mut test_buf = [0; 12]; + let res = pus_tc.write_to(test_buf.as_mut_slice()); + assert!(res.is_err()); + let err = res.unwrap_err(); + match err { + PusError::PacketError(err) => match err { + PacketError::ToBytesSliceTooSmall(missmatch) => { + assert_eq!(missmatch.expected, pus_tc.len_packed()); + assert_eq!(missmatch.found, 12); + } + _ => panic!("Unexpected error"), + }, + _ => panic!("Unexpected error"), + } + } + #[test] fn test_with_application_data_buf() { let pus_tc = base_ping_tc_simple_ctor_with_app_data(&[1, 2, 3]); diff --git a/src/time.rs b/src/time.rs index 131a60c..eb68a48 100644 --- a/src/time.rs +++ b/src/time.rs @@ -10,6 +10,7 @@ pub const CDS_SHORT_LEN: usize = 7; pub const DAYS_CCSDS_TO_UNIX: i32 = -4383; pub const SECONDS_PER_DAY: u32 = 86400; +#[derive(Debug, PartialEq, Copy, Clone)] pub enum CcsdsTimeCodes { None = 0, CucCcsdsEpoch = 0b001, @@ -32,9 +33,13 @@ impl TryFrom for CcsdsTimeCodes { } } } + +#[derive(Debug, PartialEq)] pub enum TimestampError { + /// Contains tuple where first value is the expected time code and the second + /// value is the found raw value InvalidTimeCode(CcsdsTimeCodes, u8), - PacketError(PacketError), + OtherPacketError(PacketError), } #[cfg(feature = "std")] @@ -194,7 +199,7 @@ impl TimeWriter for CdsShortTimeProvider { } buf[0] = self.pfield; buf[1..3].copy_from_slice(self.ccsds_days.to_be_bytes().as_slice()); - buf[4..].copy_from_slice(self.ms_of_day.to_be_bytes().as_slice()); + buf[3..7].copy_from_slice(self.ms_of_day.to_be_bytes().as_slice()); Ok(()) } } @@ -202,7 +207,7 @@ impl TimeWriter for CdsShortTimeProvider { impl TimeReader for CdsShortTimeProvider { fn from_bytes(buf: &[u8]) -> Result { if buf.len() < CDS_SHORT_LEN { - return Err(TimestampError::PacketError( + return Err(TimestampError::OtherPacketError( PacketError::FromBytesSliceTooSmall(SizeMissmatch { expected: CDS_SHORT_LEN, found: buf.len(), @@ -228,7 +233,7 @@ impl TimeReader for CdsShortTimeProvider { } }; let ccsds_days: u16 = u16::from_be_bytes(buf[1..3].try_into().unwrap()); - let ms_of_day: u32 = u32::from_be_bytes(buf[4..].try_into().unwrap()); + let ms_of_day: u32 = u32::from_be_bytes(buf[3..7].try_into().unwrap()); Ok(Self::new(ccsds_days, ms_of_day)) } } @@ -236,6 +241,9 @@ impl TimeReader for CdsShortTimeProvider { #[cfg(test)] mod tests { use super::*; + use crate::time::TimestampError::{InvalidTimeCode, OtherPacketError}; + use crate::PacketError::{FromBytesSliceTooSmall, ToBytesSliceTooSmall}; + use alloc::format; use chrono::{Datelike, Timelike}; #[test] @@ -258,6 +266,11 @@ mod tests { time_stamper.unix_seconds(), (DAYS_CCSDS_TO_UNIX * SECONDS_PER_DAY as i32) as i64 ); + assert_eq!(time_stamper.ccdsd_time_code(), CcsdsTimeCodes::Cds); + assert_eq!( + time_stamper.p_field(), + (1, [(CcsdsTimeCodes::Cds as u8) << 4, 0]) + ); let date_time = time_stamper.date_time(); assert_eq!(date_time.year(), 1958); assert_eq!(date_time.month(), 1); @@ -281,10 +294,114 @@ mod tests { } #[test] - fn test_packing() {} + fn test_write() { + let mut buf = [0; 16]; + let time_stamper_0 = CdsShortTimeProvider::new(0, 0); + let mut res = time_stamper_0.write_to_bytes(&mut buf); + assert!(res.is_ok()); + assert_eq!(buf[0], (CcsdsTimeCodes::Cds as u8) << 4); + assert_eq!( + u16::from_be_bytes(buf[1..3].try_into().expect("Byte conversion failed")), + 0 + ); + assert_eq!( + u32::from_be_bytes(buf[3..7].try_into().expect("Byte conversion failed")), + 0 + ); + let time_stamper_1 = CdsShortTimeProvider::new(u16::MAX - 1, u32::MAX - 1); + res = time_stamper_1.write_to_bytes(&mut buf); + assert!(res.is_ok()); + assert_eq!(buf[0], (CcsdsTimeCodes::Cds as u8) << 4); + assert_eq!( + u16::from_be_bytes(buf[1..3].try_into().expect("Byte conversion failed")), + u16::MAX - 1 + ); + assert_eq!( + u32::from_be_bytes(buf[3..7].try_into().expect("Byte conversion failed")), + u32::MAX - 1 + ); + } #[test] - fn test_reading() {} + fn test_faulty_write_buf_too_small() { + let mut buf = [0; 7]; + let time_stamper = CdsShortTimeProvider::new(u16::MAX - 1, u32::MAX - 1); + for i in 0..6 { + let res = time_stamper.write_to_bytes(&mut buf[0..i]); + assert!(res.is_err()); + match res.unwrap_err() { + ToBytesSliceTooSmall(missmatch) => { + assert_eq!(missmatch.found, i); + assert_eq!(missmatch.expected, 7); + } + _ => panic!( + "{}", + format!("Invalid error {:?} detected", res.unwrap_err()) + ), + } + } + } + + #[test] + fn test_faulty_read_buf_too_small() { + let buf = [0; 7]; + for i in 0..6 { + let res = CdsShortTimeProvider::from_bytes(&buf[0..i]); + assert!(res.is_err()); + match res.unwrap_err() { + InvalidTimeCode(_, _) => { + panic!("Unexpected error"); + } + OtherPacketError(e) => match e { + FromBytesSliceTooSmall(missmatch) => { + assert_eq!(missmatch.found, i); + assert_eq!(missmatch.expected, 7); + } + _ => panic!("{}", format!("Invalid error {:?} detected", e)), + }, + } + } + } + + #[test] + fn test_faulty_invalid_pfield() { + let mut buf = [0; 16]; + let time_stamper_0 = CdsShortTimeProvider::new(0, 0); + let res = time_stamper_0.write_to_bytes(&mut buf); + assert!(res.is_ok()); + buf[0] = 0; + let res = CdsShortTimeProvider::from_bytes(&buf); + assert!(res.is_err()); + let err = res.unwrap_err(); + match err { + InvalidTimeCode(code, raw) => { + assert_eq!(code, CcsdsTimeCodes::Cds); + assert_eq!(raw, 0); + } + OtherPacketError(_) => {} + } + } + + #[test] + fn test_reading() { + let mut buf = [0; 16]; + let time_stamper = CdsShortTimeProvider::new(u16::MAX - 1, u32::MAX - 1); + let res = time_stamper.write_to_bytes(&mut buf); + assert!(res.is_ok()); + assert_eq!(buf[0], (CcsdsTimeCodes::Cds as u8) << 4); + assert_eq!( + u16::from_be_bytes(buf[1..3].try_into().expect("Byte conversion failed")), + u16::MAX - 1 + ); + assert_eq!( + u32::from_be_bytes(buf[3..7].try_into().expect("Byte conversion failed")), + u32::MAX - 1 + ); + + let read_stamp = CdsShortTimeProvider::from_bytes(&buf).expect("Reading timestamp failed"); + assert_eq!(read_stamp.ccsds_days, u16::MAX - 1); + assert_eq!(read_stamp.ms_of_day, u32::MAX - 1); + } #[cfg(feature = "std")] #[test] diff --git a/src/tm.rs b/src/tm.rs index 7f61f15..f1511ac 100644 --- a/src/tm.rs +++ b/src/tm.rs @@ -519,6 +519,8 @@ mod tests { assert_eq!(pus_tm.sc_time_ref_status(), 0b1010); assert_eq!(pus_tm.dest_id(), 0x7fff); assert_eq!(pus_tm.msg_counter(), 0x1f1f); + assert!(pus_tm.set_apid(0x7ff)); + assert_eq!(pus_tm.apid(), 0x7ff); } #[test]