require this for less duplicate code
Some checks failed
Rust/spacepackets/pipeline/head There was a failure building this commit
Some checks failed
Rust/spacepackets/pipeline/head There was a failure building this commit
This commit is contained in:
parent
1ddfc432f3
commit
ec5d98a9b5
@ -16,7 +16,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
- `GenericUnsignedByteField<TYPE>` and helper typedefs `UnsignedU8`, `UnsignedU16`, `UnsignedU32`
|
- `GenericUnsignedByteField<TYPE>` and helper typedefs `UnsignedU8`, `UnsignedU16`, `UnsignedU32`
|
||||||
and `UnsignedU64` as helper types implementing `UnsignedEnum`
|
and `UnsignedU64` as helper types implementing `UnsignedEnum`
|
||||||
- `UnsignedByteField` as a type-erased helper.
|
- `UnsignedByteField` as a type-erased helper.
|
||||||
- Initial CFDP support: Added PDU packet implementation.
|
- Added `SerializablePusPacket` as a generic abstraction for PUS packets which are
|
||||||
|
writable.
|
||||||
|
|
||||||
## Changed
|
## Changed
|
||||||
|
|
||||||
|
@ -349,6 +349,10 @@ pub type EcssEnumU16 = GenericEcssEnumWrapper<u16>;
|
|||||||
pub type EcssEnumU32 = GenericEcssEnumWrapper<u32>;
|
pub type EcssEnumU32 = GenericEcssEnumWrapper<u32>;
|
||||||
pub type EcssEnumU64 = GenericEcssEnumWrapper<u64>;
|
pub type EcssEnumU64 = GenericEcssEnumWrapper<u64>;
|
||||||
|
|
||||||
|
pub trait SerializablePusPacket {
|
||||||
|
fn write_to_bytes(&self, slice: &mut [u8]) -> Result<usize, PusError>;
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::ecss::{EcssEnumU16, EcssEnumU32, EcssEnumU8, UnsignedEnum};
|
use crate::ecss::{EcssEnumU16, EcssEnumU32, EcssEnumU8, UnsignedEnum};
|
||||||
|
75
src/tc.rs
75
src/tc.rs
@ -34,6 +34,7 @@
|
|||||||
use crate::ecss::{
|
use crate::ecss::{
|
||||||
ccsds_impl, crc_from_raw_data, crc_procedure, sp_header_impls, user_data_from_raw,
|
ccsds_impl, crc_from_raw_data, crc_procedure, sp_header_impls, user_data_from_raw,
|
||||||
verify_crc16_ccitt_false_from_raw, CrcType, PusError, PusPacket, PusVersion,
|
verify_crc16_ccitt_false_from_raw, CrcType, PusError, PusPacket, PusVersion,
|
||||||
|
SerializablePusPacket,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
ByteConversionError, CcsdsPacket, PacketType, SequenceFlags, SizeMissmatch, CCSDS_HEADER_LEN,
|
ByteConversionError, CcsdsPacket, PacketType, SequenceFlags, SizeMissmatch, CCSDS_HEADER_LEN,
|
||||||
@ -342,42 +343,6 @@ impl<'raw_data> PusTc<'raw_data> {
|
|||||||
self.calc_own_crc16();
|
self.calc_own_crc16();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write the raw PUS byte representation to a provided buffer.
|
|
||||||
pub fn write_to_bytes(&self, slice: &mut [u8]) -> Result<usize, PusError> {
|
|
||||||
let mut curr_idx = 0;
|
|
||||||
let tc_header_len = size_of::<zc::PusTcSecondaryHeader>();
|
|
||||||
let total_size = self.len_packed();
|
|
||||||
if total_size > slice.len() {
|
|
||||||
return Err(ByteConversionError::ToSliceTooSmall(SizeMissmatch {
|
|
||||||
found: slice.len(),
|
|
||||||
expected: total_size,
|
|
||||||
})
|
|
||||||
.into());
|
|
||||||
}
|
|
||||||
self.sp_header.write_to_be_bytes(slice)?;
|
|
||||||
curr_idx += CCSDS_HEADER_LEN;
|
|
||||||
let sec_header = zc::PusTcSecondaryHeader::try_from(self.sec_header).unwrap();
|
|
||||||
sec_header
|
|
||||||
.write_to_bytes(&mut slice[curr_idx..curr_idx + tc_header_len])
|
|
||||||
.ok_or(ByteConversionError::ZeroCopyToError)?;
|
|
||||||
|
|
||||||
curr_idx += tc_header_len;
|
|
||||||
if let Some(app_data) = self.app_data {
|
|
||||||
slice[curr_idx..curr_idx + app_data.len()].copy_from_slice(app_data);
|
|
||||||
curr_idx += app_data.len();
|
|
||||||
}
|
|
||||||
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());
|
|
||||||
curr_idx += 2;
|
|
||||||
Ok(curr_idx)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
|
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
|
||||||
pub fn append_to_vec(&self, vec: &mut Vec<u8>) -> Result<usize, PusError> {
|
pub fn append_to_vec(&self, vec: &mut Vec<u8>) -> Result<usize, PusError> {
|
||||||
@ -453,6 +418,44 @@ impl<'raw_data> PusTc<'raw_data> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SerializablePusPacket for PusTc<'_> {
|
||||||
|
/// Write the raw PUS byte representation to a provided buffer.
|
||||||
|
fn write_to_bytes(&self, slice: &mut [u8]) -> Result<usize, PusError> {
|
||||||
|
let mut curr_idx = 0;
|
||||||
|
let tc_header_len = size_of::<zc::PusTcSecondaryHeader>();
|
||||||
|
let total_size = self.len_packed();
|
||||||
|
if total_size > slice.len() {
|
||||||
|
return Err(ByteConversionError::ToSliceTooSmall(SizeMissmatch {
|
||||||
|
found: slice.len(),
|
||||||
|
expected: total_size,
|
||||||
|
})
|
||||||
|
.into());
|
||||||
|
}
|
||||||
|
self.sp_header.write_to_be_bytes(slice)?;
|
||||||
|
curr_idx += CCSDS_HEADER_LEN;
|
||||||
|
let sec_header = zc::PusTcSecondaryHeader::try_from(self.sec_header).unwrap();
|
||||||
|
sec_header
|
||||||
|
.write_to_bytes(&mut slice[curr_idx..curr_idx + tc_header_len])
|
||||||
|
.ok_or(ByteConversionError::ZeroCopyToError)?;
|
||||||
|
|
||||||
|
curr_idx += tc_header_len;
|
||||||
|
if let Some(app_data) = self.app_data {
|
||||||
|
slice[curr_idx..curr_idx + app_data.len()].copy_from_slice(app_data);
|
||||||
|
curr_idx += app_data.len();
|
||||||
|
}
|
||||||
|
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());
|
||||||
|
curr_idx += 2;
|
||||||
|
Ok(curr_idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl PartialEq for PusTc<'_> {
|
impl PartialEq for PusTc<'_> {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self.sp_header == other.sp_header
|
self.sp_header == other.sp_header
|
||||||
|
85
src/tm.rs
85
src/tm.rs
@ -3,6 +3,7 @@
|
|||||||
use crate::ecss::{
|
use crate::ecss::{
|
||||||
ccsds_impl, crc_from_raw_data, crc_procedure, sp_header_impls, user_data_from_raw,
|
ccsds_impl, crc_from_raw_data, crc_procedure, sp_header_impls, user_data_from_raw,
|
||||||
verify_crc16_ccitt_false_from_raw, CrcType, PusError, PusPacket, PusVersion,
|
verify_crc16_ccitt_false_from_raw, CrcType, PusError, PusPacket, PusVersion,
|
||||||
|
SerializablePusPacket,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
ByteConversionError, CcsdsPacket, PacketType, SequenceFlags, SizeMissmatch, SpHeader,
|
ByteConversionError, CcsdsPacket, PacketType, SequenceFlags, SizeMissmatch, SpHeader,
|
||||||
@ -318,47 +319,6 @@ impl<'raw_data> PusTm<'raw_data> {
|
|||||||
self.calc_own_crc16();
|
self.calc_own_crc16();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write the raw PUS byte representation to a provided buffer.
|
|
||||||
pub fn write_to_bytes(&self, slice: &mut [u8]) -> Result<usize, PusError> {
|
|
||||||
let mut curr_idx = 0;
|
|
||||||
let total_size = self.len_packed();
|
|
||||||
if total_size > slice.len() {
|
|
||||||
return Err(ByteConversionError::ToSliceTooSmall(SizeMissmatch {
|
|
||||||
found: slice.len(),
|
|
||||||
expected: total_size,
|
|
||||||
})
|
|
||||||
.into());
|
|
||||||
}
|
|
||||||
self.sp_header
|
|
||||||
.write_to_be_bytes(&mut slice[0..CCSDS_HEADER_LEN])?;
|
|
||||||
curr_idx += CCSDS_HEADER_LEN;
|
|
||||||
let sec_header_len = size_of::<zc::PusTmSecHeaderWithoutTimestamp>();
|
|
||||||
let sec_header = zc::PusTmSecHeaderWithoutTimestamp::try_from(self.sec_header).unwrap();
|
|
||||||
sec_header
|
|
||||||
.write_to_bytes(&mut slice[curr_idx..curr_idx + sec_header_len])
|
|
||||||
.ok_or(ByteConversionError::ZeroCopyToError)?;
|
|
||||||
curr_idx += sec_header_len;
|
|
||||||
if let Some(timestamp) = self.sec_header.timestamp {
|
|
||||||
let timestamp_len = timestamp.len();
|
|
||||||
slice[curr_idx..curr_idx + timestamp_len].copy_from_slice(timestamp);
|
|
||||||
curr_idx += timestamp_len;
|
|
||||||
}
|
|
||||||
if let Some(src_data) = self.source_data {
|
|
||||||
slice[curr_idx..curr_idx + src_data.len()].copy_from_slice(src_data);
|
|
||||||
curr_idx += src_data.len();
|
|
||||||
}
|
|
||||||
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());
|
|
||||||
curr_idx += 2;
|
|
||||||
Ok(curr_idx)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Append the raw PUS byte representation to a provided [alloc::vec::Vec]
|
/// Append the raw PUS byte representation to a provided [alloc::vec::Vec]
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
|
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
|
||||||
@ -450,6 +410,49 @@ impl<'raw_data> PusTm<'raw_data> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SerializablePusPacket for PusTm<'_> {
|
||||||
|
/// Write the raw PUS byte representation to a provided buffer.
|
||||||
|
fn write_to_bytes(&self, slice: &mut [u8]) -> Result<usize, PusError> {
|
||||||
|
let mut curr_idx = 0;
|
||||||
|
let total_size = self.len_packed();
|
||||||
|
if total_size > slice.len() {
|
||||||
|
return Err(ByteConversionError::ToSliceTooSmall(SizeMissmatch {
|
||||||
|
found: slice.len(),
|
||||||
|
expected: total_size,
|
||||||
|
})
|
||||||
|
.into());
|
||||||
|
}
|
||||||
|
self.sp_header
|
||||||
|
.write_to_be_bytes(&mut slice[0..CCSDS_HEADER_LEN])?;
|
||||||
|
curr_idx += CCSDS_HEADER_LEN;
|
||||||
|
let sec_header_len = size_of::<zc::PusTmSecHeaderWithoutTimestamp>();
|
||||||
|
let sec_header = zc::PusTmSecHeaderWithoutTimestamp::try_from(self.sec_header).unwrap();
|
||||||
|
sec_header
|
||||||
|
.write_to_bytes(&mut slice[curr_idx..curr_idx + sec_header_len])
|
||||||
|
.ok_or(ByteConversionError::ZeroCopyToError)?;
|
||||||
|
curr_idx += sec_header_len;
|
||||||
|
if let Some(timestamp) = self.sec_header.timestamp {
|
||||||
|
let timestamp_len = timestamp.len();
|
||||||
|
slice[curr_idx..curr_idx + timestamp_len].copy_from_slice(timestamp);
|
||||||
|
curr_idx += timestamp_len;
|
||||||
|
}
|
||||||
|
if let Some(src_data) = self.source_data {
|
||||||
|
slice[curr_idx..curr_idx + src_data.len()].copy_from_slice(src_data);
|
||||||
|
curr_idx += src_data.len();
|
||||||
|
}
|
||||||
|
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());
|
||||||
|
curr_idx += 2;
|
||||||
|
Ok(curr_idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl PartialEq for PusTm<'_> {
|
impl PartialEq for PusTm<'_> {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self.sp_header == other.sp_header
|
self.sp_header == other.sp_header
|
||||||
|
Loading…
Reference in New Issue
Block a user