PDU improvements and additions #24

Merged
muellerr merged 7 commits from pdu-additions into main 2023-08-28 16:52:26 +02:00
5 changed files with 69 additions and 41 deletions

View File

@ -18,6 +18,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
was created from a raw bytestream. was created from a raw bytestream.
- Added `MsgToUserTlv` helper class which wraps a regular `Tlv` and adds some useful functionality. - Added `MsgToUserTlv` helper class which wraps a regular `Tlv` and adds some useful functionality.
- `UnsignedByteField` and `GenericUnsignedByteField` `new` methods are `const` now. - `UnsignedByteField` and `GenericUnsignedByteField` `new` methods are `const` now.
- `PduError` variants which contained a tuple variant with multiple fields were converted to a
struct variant.
# Added
- Added `pdu_datafield_len` getter function for `PduHeader`
# [v0.7.0-beta.0] 2023-08-16 # [v0.7.0-beta.0] 2023-08-16

View File

@ -106,13 +106,16 @@ impl EofPdu {
} }
generic_length_checks_pdu_deserialization(buf, min_expected_len, full_len_without_crc)?; generic_length_checks_pdu_deserialization(buf, min_expected_len, full_len_without_crc)?;
let directive_type = FileDirectiveType::try_from(buf[current_idx]).map_err(|_| { let directive_type = FileDirectiveType::try_from(buf[current_idx]).map_err(|_| {
PduError::InvalidDirectiveType((buf[current_idx], FileDirectiveType::EofPdu)) PduError::InvalidDirectiveType {
found: buf[current_idx],
expected: Some(FileDirectiveType::EofPdu),
}
})?; })?;
if directive_type != FileDirectiveType::EofPdu { if directive_type != FileDirectiveType::EofPdu {
return Err(PduError::WrongDirectiveType(( return Err(PduError::WrongDirectiveType {
directive_type, found: directive_type,
FileDirectiveType::EofPdu, expected: FileDirectiveType::EofPdu,
))); });
} }
current_idx += 1; current_idx += 1;
let condition_code = ConditionCode::try_from((buf[current_idx] >> 4) & 0b1111) let condition_code = ConditionCode::try_from((buf[current_idx] >> 4) & 0b1111)

View File

@ -170,13 +170,16 @@ impl<'fs_responses> FinishedPdu<'fs_responses> {
let min_expected_len = current_idx + 2; let min_expected_len = current_idx + 2;
generic_length_checks_pdu_deserialization(buf, min_expected_len, full_len_without_crc)?; generic_length_checks_pdu_deserialization(buf, min_expected_len, full_len_without_crc)?;
let directive_type = FileDirectiveType::try_from(buf[current_idx]).map_err(|_| { let directive_type = FileDirectiveType::try_from(buf[current_idx]).map_err(|_| {
PduError::InvalidDirectiveType((buf[current_idx], FileDirectiveType::FinishedPdu)) PduError::InvalidDirectiveType {
found: buf[current_idx],
expected: Some(FileDirectiveType::FinishedPdu),
}
})?; })?;
if directive_type != FileDirectiveType::FinishedPdu { if directive_type != FileDirectiveType::FinishedPdu {
return Err(PduError::WrongDirectiveType(( return Err(PduError::WrongDirectiveType {
directive_type, found: directive_type,
FileDirectiveType::FinishedPdu, expected: FileDirectiveType::FinishedPdu,
))); });
} }
current_idx += 1; current_idx += 1;
let condition_code = ConditionCode::try_from((buf[current_idx] >> 4) & 0b1111) let condition_code = ConditionCode::try_from((buf[current_idx] >> 4) & 0b1111)

View File

@ -248,13 +248,16 @@ impl<'src_name, 'dest_name, 'opts> MetadataPdu<'src_name, 'dest_name, 'opts> {
} }
generic_length_checks_pdu_deserialization(buf, min_expected_len, full_len_without_crc)?; generic_length_checks_pdu_deserialization(buf, min_expected_len, full_len_without_crc)?;
let directive_type = FileDirectiveType::try_from(buf[current_idx]).map_err(|_| { let directive_type = FileDirectiveType::try_from(buf[current_idx]).map_err(|_| {
PduError::InvalidDirectiveType((buf[current_idx], FileDirectiveType::MetadataPdu)) PduError::InvalidDirectiveType {
found: buf[current_idx],
expected: Some(FileDirectiveType::MetadataPdu),
}
})?; })?;
if directive_type != FileDirectiveType::MetadataPdu { if directive_type != FileDirectiveType::MetadataPdu {
return Err(PduError::WrongDirectiveType(( return Err(PduError::WrongDirectiveType {
directive_type, found: directive_type,
FileDirectiveType::MetadataPdu, expected: FileDirectiveType::MetadataPdu,
))); });
} }
current_idx += 1; current_idx += 1;
let (fss_len, file_size) = let (fss_len, file_size) =

View File

@ -35,16 +35,19 @@ pub enum PduError {
InvalidEntityLen(u8), InvalidEntityLen(u8),
/// Invalid length for the entity ID detected. Only the values 1, 2, 4 and 8 are supported. /// Invalid length for the entity ID detected. Only the values 1, 2, 4 and 8 are supported.
InvalidTransactionSeqNumLen(u8), InvalidTransactionSeqNumLen(u8),
/// The first entry will be the source entity ID length, the second one the destination entity SourceDestIdLenMissmatch {
/// ID length. src_id_len: usize,
SourceDestIdLenMissmatch((usize, usize)), dest_id_len: usize,
/// The first tuple entry will be the found directive type, the second entry the expected entry },
/// type. WrongDirectiveType {
WrongDirectiveType((FileDirectiveType, FileDirectiveType)), found: FileDirectiveType,
expected: FileDirectiveType,
},
/// The directive type field contained a value not in the range of permitted values. /// The directive type field contained a value not in the range of permitted values.
/// The first tuple entry will be the found raw number, the second entry the expected entry InvalidDirectiveType {
/// type. found: u8,
InvalidDirectiveType((u8, FileDirectiveType)), expected: Option<FileDirectiveType>,
},
/// Invalid condition code. Contains the raw detected value. /// Invalid condition code. Contains the raw detected value.
InvalidConditionCode(u8), InvalidConditionCode(u8),
/// Invalid checksum type which is not part of the checksums listed in the /// Invalid checksum type which is not part of the checksums listed in the
@ -80,10 +83,13 @@ impl Display for PduError {
"cfdp version missmatch, found {raw}, expected {CFDP_VERSION_2}" "cfdp version missmatch, found {raw}, expected {CFDP_VERSION_2}"
) )
} }
PduError::SourceDestIdLenMissmatch((src_len, dest_len)) => { PduError::SourceDestIdLenMissmatch {
src_id_len,
dest_id_len,
} => {
write!( write!(
f, f,
"missmatch of PDU source length {src_len} and destination length {dest_len}" "missmatch of PDU source length {src_id_len} and destination length {dest_id_len}"
) )
} }
PduError::ByteConversionError(e) => { PduError::ByteConversionError(e) => {
@ -92,17 +98,16 @@ impl Display for PduError {
PduError::FileSizeTooLarge(value) => { PduError::FileSizeTooLarge(value) => {
write!(f, "file size value {value} exceeds allowed 32 bit width") write!(f, "file size value {value} exceeds allowed 32 bit width")
} }
PduError::WrongDirectiveType((found, expected)) => { PduError::WrongDirectiveType { found, expected } => {
write!(f, "found directive type {found:?}, expected {expected:?}") write!(f, "found directive type {found:?}, expected {expected:?}")
} }
PduError::InvalidConditionCode(raw_code) => { PduError::InvalidConditionCode(raw_code) => {
write!(f, "found invalid condition code with raw value {raw_code}") write!(f, "found invalid condition code with raw value {raw_code}")
} }
PduError::InvalidDirectiveType((found, expected)) => { PduError::InvalidDirectiveType { found, expected } => {
write!( write!(
f, f,
"invalid directive type value {found}, expected {expected:?} ({})", "invalid directive type value {found}, expected {expected:?}"
*expected as u8
) )
} }
PduError::InvalidChecksumType(checksum_type) => { PduError::InvalidChecksumType(checksum_type) => {
@ -217,10 +222,10 @@ impl CommonPduConfig {
let source_id = source_id.into(); let source_id = source_id.into();
let dest_id = dest_id.into(); let dest_id = dest_id.into();
if source_id.size() != dest_id.size() { if source_id.size() != dest_id.size() {
return Err(PduError::SourceDestIdLenMissmatch(( return Err(PduError::SourceDestIdLenMissmatch {
source_id.size(), src_id_len: source_id.size(),
dest_id.size(), dest_id_len: dest_id.size(),
))); });
} }
if source_id.size() != 1 if source_id.size() != 1
&& source_id.size() != 2 && source_id.size() != 2
@ -340,6 +345,10 @@ impl PduHeader {
+ self.pdu_conf.dest_entity_id.size() + self.pdu_conf.dest_entity_id.size()
} }
pub fn pdu_datafield_len(&self) -> usize {
self.pdu_datafield_len.into()
}
/// Returns the full length of the PDU when written to a raw buffer, which is the header length /// Returns the full length of the PDU when written to a raw buffer, which is the header length
/// plus the PDU datafield length. /// plus the PDU datafield length.
pub fn pdu_len(&self) -> usize { pub fn pdu_len(&self) -> usize {
@ -350,10 +359,10 @@ impl PduHeader {
// Internal note: There is currently no way to pass a PDU configuration like this, but // Internal note: There is currently no way to pass a PDU configuration like this, but
// this check is still kept for defensive programming. // this check is still kept for defensive programming.
if self.pdu_conf.source_entity_id.size() != self.pdu_conf.dest_entity_id.size() { if self.pdu_conf.source_entity_id.size() != self.pdu_conf.dest_entity_id.size() {
return Err(PduError::SourceDestIdLenMissmatch(( return Err(PduError::SourceDestIdLenMissmatch {
self.pdu_conf.source_entity_id.size(), src_id_len: self.pdu_conf.source_entity_id.size(),
self.pdu_conf.dest_entity_id.size(), dest_id_len: self.pdu_conf.dest_entity_id.size(),
))); });
} }
if buf.len() if buf.len()
< FIXED_HEADER_LEN < FIXED_HEADER_LEN
@ -922,9 +931,13 @@ mod tests {
CommonPduConfig::new_with_byte_fields(src_id, dest_id, transaction_seq_id); CommonPduConfig::new_with_byte_fields(src_id, dest_id, transaction_seq_id);
assert!(pdu_conf_res.is_err()); assert!(pdu_conf_res.is_err());
let error = pdu_conf_res.unwrap_err(); let error = pdu_conf_res.unwrap_err();
if let PduError::SourceDestIdLenMissmatch((src_len, dest_len)) = error { if let PduError::SourceDestIdLenMissmatch {
assert_eq!(src_len, 1); src_id_len,
assert_eq!(dest_len, 2); dest_id_len,
} = error
{
assert_eq!(src_id_len, 1);
assert_eq!(dest_id_len, 2);
} }
} }