From b8d6cf9d85676268714aba379dbff10b1cf56bf8 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 24 Nov 2023 16:15:46 +0100 Subject: [PATCH 1/4] improvements for writable abstractions --- CHANGELOG.md | 11 ++++++++++- src/cfdp/pdu/eof.rs | 14 +++++++------- src/cfdp/pdu/file_data.rs | 17 +++++++++-------- src/cfdp/pdu/finished.rs | 12 ++++++------ src/cfdp/pdu/metadata.rs | 14 +++++++------- src/cfdp/pdu/mod.rs | 12 ++++++++++++ src/ecss/mod.rs | 6 +++--- src/ecss/tc.rs | 24 ++++++++++++------------ src/ecss/tm.rs | 34 +++++++++++++++++----------------- 9 files changed, 83 insertions(+), 61 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 676f31e..e3a0020 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,11 +8,20 @@ and this project adheres to [Semantic Versioning](http://semver.org/). # [unreleased] +## Added + +- Add `WritablePduPacket` trait which is a common trait of all CFDP PDU implementations. + ## Fixed -- Set the directtion field inside the PDU header field correctl explicitely for all CFDP PDU +- Set the direction field inside the PDU header field correctly explicitely for all CFDP PDU packets. +## Changed + +- Renamed `SerializablePusPacket` to `WritablePusPacket`. +- Renamed `WritablePduPacket.written_len` and `SerializablePusPacket.written_len` to `len_written`. + # [v0.7.0-beta.2] 2023-09-26 ## Added diff --git a/src/cfdp/pdu/eof.rs b/src/cfdp/pdu/eof.rs index 84484a4..df96286 100644 --- a/src/cfdp/pdu/eof.rs +++ b/src/cfdp/pdu/eof.rs @@ -42,10 +42,6 @@ impl EofPdu { &self.pdu_header } - pub fn written_len(&self) -> usize { - self.pdu_header.header_len() + self.calc_pdu_datafield_len() - } - pub fn condition_code(&self) -> ConditionCode { self.condition_code } @@ -117,7 +113,7 @@ impl EofPdu { impl WritablePduPacket for EofPdu { fn write_to_bytes(&self, buf: &mut [u8]) -> Result { - let expected_len = self.written_len(); + let expected_len = self.len_written(); if buf.len() < expected_len { return Err(ByteConversionError::ToSliceTooSmall { found: buf.len(), @@ -145,6 +141,10 @@ impl WritablePduPacket for EofPdu { } Ok(current_idx) } + + fn len_written(&self) -> usize { + self.pdu_header.header_len() + self.calc_pdu_datafield_len() + } } #[cfg(test)] @@ -159,7 +159,7 @@ mod tests { let pdu_conf = common_pdu_conf(CrcFlag::NoCrc, LargeFileFlag::Normal); let pdu_header = PduHeader::new_no_file_data(pdu_conf, 0); let eof_pdu = EofPdu::new_no_error(pdu_header, 0x01020304, 12); - assert_eq!(eof_pdu.written_len(), pdu_header.header_len() + 2 + 4 + 4); + assert_eq!(eof_pdu.len_written(), pdu_header.header_len() + 2 + 4 + 4); assert_eq!(eof_pdu.file_checksum(), 0x01020304); assert_eq!(eof_pdu.file_size(), 12); assert_eq!(eof_pdu.condition_code(), ConditionCode::NoError); @@ -174,7 +174,7 @@ mod tests { let res = eof_pdu.write_to_bytes(&mut buf); assert!(res.is_ok()); let written = res.unwrap(); - assert_eq!(written, eof_pdu.written_len()); + assert_eq!(written, eof_pdu.len_written()); verify_raw_header(eof_pdu.pdu_header(), &buf); let mut current_idx = eof_pdu.pdu_header().header_len(); buf[current_idx] = FileDirectiveType::EofPdu as u8; diff --git a/src/cfdp/pdu/file_data.rs b/src/cfdp/pdu/file_data.rs index dd8476e..d6090cb 100644 --- a/src/cfdp/pdu/file_data.rs +++ b/src/cfdp/pdu/file_data.rs @@ -149,9 +149,6 @@ impl<'seg_meta, 'file_data> FileDataPdu<'seg_meta, 'file_data> { } len } - pub fn written_len(&self) -> usize { - self.pdu_header.header_len() + self.calc_pdu_datafield_len() - } pub fn offset(&self) -> u64 { self.offset @@ -197,10 +194,10 @@ impl<'seg_meta, 'file_data> FileDataPdu<'seg_meta, 'file_data> { impl WritablePduPacket for FileDataPdu<'_, '_> { fn write_to_bytes(&self, buf: &mut [u8]) -> Result { - if buf.len() < self.written_len() { + if buf.len() < self.len_written() { return Err(ByteConversionError::ToSliceTooSmall { found: buf.len(), - expected: self.written_len(), + expected: self.len_written(), } .into()); } @@ -224,6 +221,10 @@ impl WritablePduPacket for FileDataPdu<'_, '_> { } Ok(current_idx) } + + fn len_written(&self) -> usize { + self.pdu_header.header_len() + self.calc_pdu_datafield_len() + } } #[cfg(test)] @@ -247,7 +248,7 @@ mod tests { assert_eq!(fd_pdu.offset(), 10); assert!(fd_pdu.segment_metadata().is_none()); assert_eq!( - fd_pdu.written_len(), + fd_pdu.len_written(), fd_pdu.pdu_header.header_len() + core::mem::size_of::() + 4 ); } @@ -327,7 +328,7 @@ mod tests { assert!(fd_pdu.segment_metadata().is_some()); assert_eq!(*fd_pdu.segment_metadata().unwrap(), segment_meta); assert_eq!( - fd_pdu.written_len(), + fd_pdu.len_written(), fd_pdu.pdu_header.header_len() + 1 + seg_metadata.len() @@ -367,7 +368,7 @@ mod tests { current_idx += 1; assert_eq!(buf[current_idx], 4); current_idx += 1; - assert_eq!(current_idx, fd_pdu.written_len()); + assert_eq!(current_idx, fd_pdu.len_written()); } #[test] diff --git a/src/cfdp/pdu/finished.rs b/src/cfdp/pdu/finished.rs index cb25a98..b68aef5 100644 --- a/src/cfdp/pdu/finished.rs +++ b/src/cfdp/pdu/finished.rs @@ -102,10 +102,6 @@ impl<'fs_responses> FinishedPdu<'fs_responses> { &self.pdu_header } - pub fn written_len(&self) -> usize { - self.pdu_header.header_len() + self.calc_pdu_datafield_len() - } - pub fn condition_code(&self) -> ConditionCode { self.condition_code } @@ -220,7 +216,7 @@ impl<'fs_responses> FinishedPdu<'fs_responses> { impl WritablePduPacket for FinishedPdu<'_> { fn write_to_bytes(&self, buf: &mut [u8]) -> Result { - let expected_len = self.written_len(); + let expected_len = self.len_written(); if buf.len() < expected_len { return Err(ByteConversionError::ToSliceTooSmall { found: buf.len(), @@ -248,6 +244,10 @@ impl WritablePduPacket for FinishedPdu<'_> { } Ok(current_idx) } + + fn len_written(&self) -> usize { + self.pdu_header.header_len() + self.calc_pdu_datafield_len() + } } #[cfg(test)] @@ -298,7 +298,7 @@ mod tests { let written = finished_pdu.write_to_bytes(&mut buf); assert!(written.is_ok()); let written = written.unwrap(); - assert_eq!(written, finished_pdu.written_len()); + assert_eq!(written, finished_pdu.len_written()); assert_eq!(written, finished_pdu.pdu_header().header_len() + 2); assert_eq!( finished_pdu.pdu_header().pdu_conf.direction, diff --git a/src/cfdp/pdu/metadata.rs b/src/cfdp/pdu/metadata.rs index 84d1275..2246edc 100644 --- a/src/cfdp/pdu/metadata.rs +++ b/src/cfdp/pdu/metadata.rs @@ -174,10 +174,6 @@ impl<'src_name, 'dest_name, 'opts> MetadataPdu<'src_name, 'dest_name, 'opts> { }) } - pub fn written_len(&self) -> usize { - self.pdu_header.header_len() + self.calc_pdu_datafield_len() - } - fn calc_pdu_datafield_len(&self) -> usize { // One directve type octet and one byte of the directive parameter field. let mut len = 2; @@ -256,7 +252,7 @@ impl<'src_name, 'dest_name, 'opts> MetadataPdu<'src_name, 'dest_name, 'opts> { impl WritablePduPacket for MetadataPdu<'_, '_, '_> { fn write_to_bytes(&self, buf: &mut [u8]) -> Result { - let expected_len = self.written_len(); + let expected_len = self.len_written(); if buf.len() < expected_len { return Err(ByteConversionError::ToSliceTooSmall { found: buf.len(), @@ -291,17 +287,21 @@ impl WritablePduPacket for MetadataPdu<'_, '_, '_> { } Ok(current_idx) } + + fn len_written(&self) -> usize { + self.pdu_header.header_len() + self.calc_pdu_datafield_len() + } } #[cfg(test)] pub mod tests { - use super::*; use crate::cfdp::lv::Lv; use crate::cfdp::pdu::metadata::{ build_metadata_opts_from_slice, build_metadata_opts_from_vec, MetadataGenericParams, MetadataPdu, }; use crate::cfdp::pdu::tests::{common_pdu_conf, verify_raw_header}; + use crate::cfdp::pdu::WritablePduPacket; use crate::cfdp::pdu::{FileDirectiveType, PduHeader}; use crate::cfdp::tlv::{Tlv, TlvType}; use crate::cfdp::{ @@ -340,7 +340,7 @@ pub mod tests { let (src_filename, dest_filename, metadata_pdu) = generic_metadata_pdu(CrcFlag::NoCrc, LargeFileFlag::Normal, None); assert_eq!( - metadata_pdu.written_len(), + metadata_pdu.len_written(), metadata_pdu.pdu_header().header_len() + 1 + 1 diff --git a/src/cfdp/pdu/mod.rs b/src/cfdp/pdu/mod.rs index 048d515..fbb2e10 100644 --- a/src/cfdp/pdu/mod.rs +++ b/src/cfdp/pdu/mod.rs @@ -3,6 +3,8 @@ use crate::cfdp::*; use crate::util::{UnsignedByteField, UnsignedByteFieldU8, UnsignedEnum}; use crate::ByteConversionError; use crate::CRC_CCITT_FALSE; +#[cfg(feature = "alloc")] +use alloc::vec::Vec; use core::fmt::{Display, Formatter}; #[cfg(feature = "std")] use std::error::Error; @@ -150,7 +152,17 @@ impl From for PduError { } pub trait WritablePduPacket { + fn len_written(&self) -> usize; fn write_to_bytes(&self, buf: &mut [u8]) -> Result; + #[cfg(feature = "alloc")] + fn to_vec(&self) -> Result, PduError> { + // This is the correct way to do this. See + // [this issue](https://github.com/rust-lang/rust-clippy/issues/4483) for caveats of more + // "efficient" implementations. + let mut vec = alloc::vec![0; self.len_written()]; + self.write_to_bytes(&mut vec)?; + Ok(vec) + } } /// Common configuration fields for a PDU. diff --git a/src/ecss/mod.rs b/src/ecss/mod.rs index 983ad02..ab03582 100644 --- a/src/ecss/mod.rs +++ b/src/ecss/mod.rs @@ -360,15 +360,15 @@ pub type EcssEnumU64 = GenericEcssEnumWrapper; /// Generic trait for PUS packet abstractions which can written to a raw slice as their raw /// byte representation. This is especially useful for generic abstractions which depend only /// on the serialization of those packets. -pub trait SerializablePusPacket { - fn len_packed(&self) -> usize; +pub trait WritablePusPacket { + fn len_written(&self) -> usize; fn write_to_bytes(&self, slice: &mut [u8]) -> Result; #[cfg(feature = "alloc")] fn to_vec(&self) -> Result, PusError> { // This is the correct way to do this. See // [this issue](https://github.com/rust-lang/rust-clippy/issues/4483) for caveats of more // "efficient" implementations. - let mut vec = alloc::vec![0; self.len_packed()]; + let mut vec = alloc::vec![0; self.len_written()]; self.write_to_bytes(&mut vec)?; Ok(vec) } diff --git a/src/ecss/tc.rs b/src/ecss/tc.rs index 1a55433..258c475 100644 --- a/src/ecss/tc.rs +++ b/src/ecss/tc.rs @@ -34,7 +34,7 @@ use crate::ecss::{ ccsds_impl, crc_from_raw_data, sp_header_impls, user_data_from_raw, verify_crc16_ccitt_false_from_raw_to_pus_error, CrcType, PusError, PusPacket, PusVersion, - SerializablePusPacket, + WritablePusPacket, }; use crate::{ByteConversionError, CcsdsPacket, PacketType, SequenceFlags, CCSDS_HEADER_LEN}; use crate::{SpHeader, CRC_CCITT_FALSE}; @@ -216,7 +216,7 @@ pub mod legacy_tc { }; use crate::ecss::{ ccsds_impl, crc_from_raw_data, crc_procedure, sp_header_impls, - verify_crc16_ccitt_false_from_raw_to_pus_error, PusError, PusPacket, SerializablePusPacket, + verify_crc16_ccitt_false_from_raw_to_pus_error, PusError, PusPacket, WritablePusPacket, CCSDS_HEADER_LEN, }; use crate::ecss::{user_data_from_raw, PusVersion}; @@ -347,7 +347,7 @@ pub mod legacy_tc { /// is set correctly. pub fn update_ccsds_data_len(&mut self) { self.sp_header.data_len = - self.len_packed() as u16 - size_of::() as u16 - 1; + self.len_written() as u16 - size_of::() as u16 - 1; } /// This function should be called before the TC packet is serialized if @@ -447,8 +447,8 @@ pub mod legacy_tc { } } - impl SerializablePusPacket for PusTc<'_> { - fn len_packed(&self) -> usize { + impl WritablePusPacket for PusTc<'_> { + fn len_written(&self) -> usize { PUS_TC_MIN_LEN_WITHOUT_APP_DATA + self.app_data.len() } @@ -456,7 +456,7 @@ pub mod legacy_tc { fn write_to_bytes(&self, slice: &mut [u8]) -> Result { let mut curr_idx = 0; let tc_header_len = size_of::(); - let total_size = self.len_packed(); + let total_size = self.len_written(); if total_size > slice.len() { return Err(ByteConversionError::ToSliceTooSmall { found: slice.len(), @@ -619,7 +619,7 @@ impl<'raw_data> PusTcCreator<'raw_data> { /// is set correctly. pub fn update_ccsds_data_len(&mut self) { self.sp_header.data_len = - self.len_packed() as u16 - size_of::() as u16 - 1; + self.len_written() as u16 - size_of::() as u16 - 1; } /// This function should be called before the TC packet is serialized if @@ -653,8 +653,8 @@ impl<'raw_data> PusTcCreator<'raw_data> { } } -impl SerializablePusPacket for PusTcCreator<'_> { - fn len_packed(&self) -> usize { +impl WritablePusPacket for PusTcCreator<'_> { + fn len_written(&self) -> usize { PUS_TC_MIN_LEN_WITHOUT_APP_DATA + self.app_data.len() } @@ -662,7 +662,7 @@ impl SerializablePusPacket for PusTcCreator<'_> { fn write_to_bytes(&self, slice: &mut [u8]) -> Result { let mut curr_idx = 0; let tc_header_len = size_of::(); - let total_size = self.len_packed(); + let total_size = self.len_written(); if total_size > slice.len() { return Err(ByteConversionError::ToSliceTooSmall { found: slice.len(), @@ -851,7 +851,7 @@ mod tests { GenericPusTcSecondaryHeader, PusTcCreator, PusTcReader, PusTcSecondaryHeader, ACK_ALL, }; use crate::ecss::PusVersion::PusC; - use crate::ecss::{PusError, PusPacket, SerializablePusPacket}; + use crate::ecss::{PusError, PusPacket, WritablePusPacket}; use crate::{ByteConversionError, SpHeader}; use crate::{CcsdsPacket, SequenceFlags}; use alloc::vec::Vec; @@ -993,7 +993,7 @@ mod tests { match err { PusError::ByteConversion(err) => match err { ByteConversionError::ToSliceTooSmall { found, expected } => { - assert_eq!(expected, pus_tc.len_packed()); + assert_eq!(expected, pus_tc.len_written()); assert_eq!(found, 12); } _ => panic!("Unexpected error"), diff --git a/src/ecss/tm.rs b/src/ecss/tm.rs index 4ea54d0..bb8e84e 100644 --- a/src/ecss/tm.rs +++ b/src/ecss/tm.rs @@ -3,7 +3,7 @@ use crate::ecss::{ calc_pus_crc16, ccsds_impl, crc_from_raw_data, sp_header_impls, user_data_from_raw, verify_crc16_ccitt_false_from_raw_to_pus_error, CrcType, PusError, PusPacket, PusVersion, - SerializablePusPacket, + WritablePusPacket, }; use crate::{ ByteConversionError, CcsdsPacket, PacketType, SequenceFlags, SpHeader, CCSDS_HEADER_LEN, @@ -203,7 +203,7 @@ pub mod legacy_tm { use crate::ecss::PusVersion; use crate::ecss::{ ccsds_impl, crc_from_raw_data, crc_procedure, sp_header_impls, user_data_from_raw, - verify_crc16_ccitt_false_from_raw_to_pus_error, PusError, PusPacket, SerializablePusPacket, + verify_crc16_ccitt_false_from_raw_to_pus_error, PusError, PusPacket, WritablePusPacket, CCSDS_HEADER_LEN, }; use crate::SequenceFlags; @@ -314,7 +314,7 @@ pub mod legacy_tm { /// is set correctly pub fn update_ccsds_data_len(&mut self) { self.sp_header.data_len = - self.len_packed() as u16 - size_of::() as u16 - 1; + self.len_written() as u16 - size_of::() as u16 - 1; } /// This function should be called before the TM packet is serialized if @@ -423,8 +423,8 @@ pub mod legacy_tm { } } - impl SerializablePusPacket for PusTm<'_> { - fn len_packed(&self) -> usize { + impl WritablePusPacket for PusTm<'_> { + fn len_written(&self) -> usize { PUS_TM_MIN_LEN_WITHOUT_SOURCE_DATA + self.sec_header.timestamp.len() + self.source_data.len() @@ -432,7 +432,7 @@ pub mod legacy_tm { /// Write the raw PUS byte representation to a provided buffer. fn write_to_bytes(&self, slice: &mut [u8]) -> Result { let mut curr_idx = 0; - let total_size = self.len_packed(); + let total_size = self.len_written(); if total_size > slice.len() { return Err(ByteConversionError::ToSliceTooSmall { found: slice.len(), @@ -608,7 +608,7 @@ impl<'raw_data> PusTmCreator<'raw_data> { /// is set correctly pub fn update_ccsds_data_len(&mut self) { self.sp_header.data_len = - self.len_packed() as u16 - size_of::() as u16 - 1; + self.len_written() as u16 - size_of::() as u16 - 1; } /// This function should be called before the TM packet is serialized if @@ -650,8 +650,8 @@ impl<'raw_data> PusTmCreator<'raw_data> { } } -impl SerializablePusPacket for PusTmCreator<'_> { - fn len_packed(&self) -> usize { +impl WritablePusPacket for PusTmCreator<'_> { + fn len_written(&self) -> usize { PUS_TM_MIN_LEN_WITHOUT_SOURCE_DATA + self.sec_header.timestamp.len() + self.source_data.len() @@ -659,7 +659,7 @@ impl SerializablePusPacket for PusTmCreator<'_> { /// Write the raw PUS byte representation to a provided buffer. fn write_to_bytes(&self, slice: &mut [u8]) -> Result { let mut curr_idx = 0; - let total_size = self.len_packed(); + let total_size = self.len_written(); if total_size > slice.len() { return Err(ByteConversionError::ToSliceTooSmall { found: slice.len(), @@ -949,31 +949,31 @@ mod tests { fn base_ping_reply_full_ctor(timestamp: &[u8]) -> PusTmCreator { let mut sph = SpHeader::tm_unseg(0x123, 0x234, 0).unwrap(); - let tm_header = PusTmSecondaryHeader::new_simple(17, 2, ×tamp); + let tm_header = PusTmSecondaryHeader::new_simple(17, 2, timestamp); PusTmCreator::new(&mut sph, tm_header, None, true) } 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 tc_header = PusTmSecondaryHeader::new_simple(3, 5, ×tamp); + let tc_header = PusTmSecondaryHeader::new_simple(3, 5, timestamp); PusTmCreator::new(&mut sph, tc_header, Some(src_data), true) } fn dummy_timestamp() -> &'static [u8] { - return &[0, 1, 2, 3, 4, 5, 6]; + &[0, 1, 2, 3, 4, 5, 6] } #[test] fn test_basic() { let timestamp = dummy_timestamp(); - let pus_tm = base_ping_reply_full_ctor(×tamp); + let pus_tm = base_ping_reply_full_ctor(timestamp); verify_ping_reply(&pus_tm, false, 22, dummy_timestamp()); } #[test] fn test_serialization_no_source_data() { let timestamp = dummy_timestamp(); - let pus_tm = base_ping_reply_full_ctor(×tamp); + 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) @@ -1069,7 +1069,7 @@ mod tests { #[cfg(feature = "alloc")] fn test_append_to_vec() { let timestamp = dummy_timestamp(); - let pus_tm = base_ping_reply_full_ctor(×tamp); + let pus_tm = base_ping_reply_full_ctor(timestamp); let mut vec = Vec::new(); let res = pus_tm.append_to_vec(&mut vec); assert!(res.is_ok()); @@ -1124,7 +1124,7 @@ mod tests { exp_full_len: usize, exp_timestamp: &[u8], ) { - assert_eq!(tm.len_packed(), exp_full_len); + assert_eq!(tm.len_written(), exp_full_len); assert_eq!(tm.timestamp(), exp_timestamp); verify_ping_reply_generic(tm, has_user_data, exp_full_len); } From 48c9b12ee2c993c3b53f7e8e113bd491d2886661 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 24 Nov 2023 16:16:30 +0100 Subject: [PATCH 2/4] changelog fix --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e3a0020..0952f2a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,7 +20,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## Changed - Renamed `SerializablePusPacket` to `WritablePusPacket`. -- Renamed `WritablePduPacket.written_len` and `SerializablePusPacket.written_len` to `len_written`. +- Renamed `WritablePduPacket.written_len` and `SerializablePusPacket.len_packed` to `len_written`. # [v0.7.0-beta.2] 2023-09-26 From 4e90bbdc04c3d44b982c2b5770dc1b8a1439e65a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 24 Nov 2023 16:19:59 +0100 Subject: [PATCH 3/4] fix doctest --- src/ecss/tc.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ecss/tc.rs b/src/ecss/tc.rs index 258c475..06ee7bc 100644 --- a/src/ecss/tc.rs +++ b/src/ecss/tc.rs @@ -5,7 +5,7 @@ //! //! ```rust //! use spacepackets::{CcsdsPacket, SpHeader}; -//! use spacepackets::ecss::{PusPacket, SerializablePusPacket}; +//! use spacepackets::ecss::{PusPacket, WritablePusPacket}; //! use spacepackets::ecss::tc::{PusTcCreator, PusTcReader, PusTcSecondaryHeader}; //! //! // Create a ping telecommand with no user application data From b82a93757c18dfd01f5690d5eb933dbfeca654d3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 24 Nov 2023 16:34:06 +0100 Subject: [PATCH 4/4] add unittests for vec conversion --- src/cfdp/pdu/eof.rs | 13 ++++++++++++- src/cfdp/pdu/file_data.rs | 34 +++++++++++++++++++--------------- src/cfdp/pdu/finished.rs | 14 ++++++++++++++ src/cfdp/pdu/metadata.rs | 10 ++++++++++ src/ecss/tc.rs | 14 ++++++++++++++ src/ecss/tm.rs | 17 ++++++++++++++--- 6 files changed, 83 insertions(+), 19 deletions(-) diff --git a/src/cfdp/pdu/eof.rs b/src/cfdp/pdu/eof.rs index df96286..b251f47 100644 --- a/src/cfdp/pdu/eof.rs +++ b/src/cfdp/pdu/eof.rs @@ -205,11 +205,22 @@ mod tests { let mut buf: [u8; 64] = [0; 64]; eof_pdu.write_to_bytes(&mut buf).unwrap(); let eof_read_back = EofPdu::from_bytes(&buf); - if !eof_read_back.is_ok() { + if eof_read_back.is_err() { let e = eof_read_back.unwrap_err(); panic!("deserialization failed with: {e}") } let eof_read_back = eof_read_back.unwrap(); assert_eq!(eof_read_back, eof_pdu); } + + #[test] + fn test_write_to_vec() { + let pdu_conf = common_pdu_conf(CrcFlag::NoCrc, LargeFileFlag::Normal); + let pdu_header = PduHeader::new_no_file_data(pdu_conf, 0); + let eof_pdu = EofPdu::new_no_error(pdu_header, 0x01020304, 12); + let mut buf: [u8; 64] = [0; 64]; + let written = eof_pdu.write_to_bytes(&mut buf).unwrap(); + let pdu_vec = eof_pdu.to_vec().unwrap(); + assert_eq!(buf[0..written], pdu_vec); + } } diff --git a/src/cfdp/pdu/file_data.rs b/src/cfdp/pdu/file_data.rs index d6090cb..4c334a6 100644 --- a/src/cfdp/pdu/file_data.rs +++ b/src/cfdp/pdu/file_data.rs @@ -234,13 +234,13 @@ mod tests { use crate::cfdp::{SegmentMetadataFlag, SegmentationControl}; use crate::util::UbfU8; + const SRC_ID: UbfU8 = UbfU8::new(1); + const DEST_ID: UbfU8 = UbfU8::new(2); + const SEQ_NUM: UbfU8 = UbfU8::new(3); + #[test] fn test_basic() { - let src_id = UbfU8::new(1); - let dest_id = UbfU8::new(2); - let transaction_seq_num = UbfU8::new(3); - let common_conf = - CommonPduConfig::new_with_byte_fields(src_id, dest_id, transaction_seq_num).unwrap(); + let common_conf = CommonPduConfig::new_with_byte_fields(SRC_ID, DEST_ID, SEQ_NUM).unwrap(); let pdu_header = PduHeader::new_for_file_data_default(common_conf, 0); let file_data: [u8; 4] = [1, 2, 3, 4]; let fd_pdu = FileDataPdu::new_no_seg_metadata(pdu_header, 10, &file_data); @@ -255,11 +255,7 @@ mod tests { #[test] fn test_serialization() { - let src_id = UbfU8::new(1); - let dest_id = UbfU8::new(2); - let transaction_seq_num = UbfU8::new(3); - let common_conf = - CommonPduConfig::new_with_byte_fields(src_id, dest_id, transaction_seq_num).unwrap(); + let common_conf = CommonPduConfig::new_with_byte_fields(SRC_ID, DEST_ID, SEQ_NUM).unwrap(); let pdu_header = PduHeader::new_for_file_data_default(common_conf, 0); let file_data: [u8; 4] = [1, 2, 3, 4]; let fd_pdu = FileDataPdu::new_no_seg_metadata(pdu_header, 10, &file_data); @@ -288,13 +284,21 @@ mod tests { assert_eq!(buf[current_idx], 4); } + #[test] + fn test_write_to_vec() { + let common_conf = CommonPduConfig::new_with_byte_fields(SRC_ID, DEST_ID, SEQ_NUM).unwrap(); + let pdu_header = PduHeader::new_for_file_data_default(common_conf, 0); + let file_data: [u8; 4] = [1, 2, 3, 4]; + let fd_pdu = FileDataPdu::new_no_seg_metadata(pdu_header, 10, &file_data); + let mut buf: [u8; 64] = [0; 64]; + let written = fd_pdu.write_to_bytes(&mut buf).unwrap(); + let pdu_vec = fd_pdu.to_vec().unwrap(); + assert_eq!(buf[0..written], pdu_vec); + } + #[test] fn test_deserialization() { - let src_id = UbfU8::new(1); - let dest_id = UbfU8::new(2); - let transaction_seq_num = UbfU8::new(3); - let common_conf = - CommonPduConfig::new_with_byte_fields(src_id, dest_id, transaction_seq_num).unwrap(); + let common_conf = CommonPduConfig::new_with_byte_fields(SRC_ID, DEST_ID, SEQ_NUM).unwrap(); let pdu_header = PduHeader::new_for_file_data_default(common_conf, 0); let file_data: [u8; 4] = [1, 2, 3, 4]; let fd_pdu = FileDataPdu::new_no_seg_metadata(pdu_header, 10, &file_data); diff --git a/src/cfdp/pdu/finished.rs b/src/cfdp/pdu/finished.rs index b68aef5..d56d5a0 100644 --- a/src/cfdp/pdu/finished.rs +++ b/src/cfdp/pdu/finished.rs @@ -335,6 +335,20 @@ mod tests { generic_serialization_test_no_error(DeliveryCode::Incomplete, FileStatus::Unreported); } + #[test] + fn test_write_to_vec() { + let finished_pdu = generic_finished_pdu( + CrcFlag::NoCrc, + LargeFileFlag::Normal, + DeliveryCode::Complete, + FileStatus::Retained, + ); + let mut buf: [u8; 64] = [0; 64]; + let written = finished_pdu.write_to_bytes(&mut buf).unwrap(); + let pdu_vec = finished_pdu.to_vec().unwrap(); + assert_eq!(buf[0..written], pdu_vec); + } + #[test] fn test_deserialization_simple() { let finished_pdu = generic_finished_pdu( diff --git a/src/cfdp/pdu/metadata.rs b/src/cfdp/pdu/metadata.rs index 2246edc..d68444c 100644 --- a/src/cfdp/pdu/metadata.rs +++ b/src/cfdp/pdu/metadata.rs @@ -388,6 +388,16 @@ pub mod tests { assert_eq!(current_idx, written); } + #[test] + fn test_write_to_vec() { + let (_, _, metadata_pdu) = + generic_metadata_pdu(CrcFlag::NoCrc, LargeFileFlag::Normal, None); + let mut buf: [u8; 64] = [0; 64]; + let pdu_vec = metadata_pdu.to_vec().unwrap(); + let written = metadata_pdu.write_to_bytes(&mut buf).unwrap(); + assert_eq!(buf[0..written], pdu_vec); + } + #[test] fn test_deserialization() { let (_, _, metadata_pdu) = diff --git a/src/ecss/tc.rs b/src/ecss/tc.rs index 06ee7bc..6e7bc53 100644 --- a/src/ecss/tc.rs +++ b/src/ecss/tc.rs @@ -905,6 +905,20 @@ mod tests { verify_crc_no_app_data(&test_buf); } + #[test] + fn test_writing_into_vec() { + let pus_tc = base_ping_tc_simple_ctor(); + let tc_vec = pus_tc.to_vec().expect("Error writing TC to buffer"); + assert_eq!(tc_vec.len(), 13); + let (tc_from_raw, size) = PusTcReader::new(tc_vec.as_slice()) + .expect("Creating PUS TC struct from raw buffer failed"); + assert_eq!(size, 13); + verify_test_tc_with_reader(&tc_from_raw, false, 13); + assert!(tc_from_raw.user_data().is_empty()); + verify_test_tc_raw(&tc_vec); + verify_crc_no_app_data(&tc_vec); + } + #[test] fn test_update_func() { let mut sph = SpHeader::tc_unseg(0x02, 0x34, 0).unwrap(); diff --git a/src/ecss/tm.rs b/src/ecss/tm.rs index bb8e84e..a12db61 100644 --- a/src/ecss/tm.rs +++ b/src/ecss/tm.rs @@ -999,7 +999,7 @@ mod tests { #[test] fn test_setters() { let timestamp = dummy_timestamp(); - let mut pus_tm = base_ping_reply_full_ctor(×tamp); + let mut pus_tm = base_ping_reply_full_ctor(timestamp); pus_tm.set_sc_time_ref_status(0b1010); pus_tm.set_dest_id(0x7fff); pus_tm.set_msg_counter(0x1f1f); @@ -1010,10 +1010,21 @@ mod tests { assert_eq!(pus_tm.apid(), 0x7ff); } + #[test] + fn test_write_into_vec() { + let timestamp = dummy_timestamp(); + let pus_tm = base_ping_reply_full_ctor(timestamp); + let tm_vec = pus_tm.to_vec().expect("Serialization failed"); + assert_eq!(tm_vec.len(), 22); + let (tm_deserialized, size) = + PusTmReader::new(tm_vec.as_slice(), 7).expect("Deserialization failed"); + assert_eq!(tm_vec.len(), size); + verify_ping_reply_with_reader(&tm_deserialized, false, 22, dummy_timestamp()); + } #[test] fn test_deserialization_no_source_data() { let timestamp = dummy_timestamp(); - let pus_tm = base_ping_reply_full_ctor(×tamp); + 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) @@ -1045,7 +1056,7 @@ mod tests { #[test] fn test_target_buf_too_small() { let timestamp = dummy_timestamp(); - let pus_tm = base_ping_reply_full_ctor(×tamp); + let pus_tm = base_ping_reply_full_ctor(timestamp); let mut buf: [u8; 16] = [0; 16]; let res = pus_tm.write_to_bytes(&mut buf); assert!(res.is_err());