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.
- Added `MsgToUserTlv` helper class which wraps a regular `Tlv` and adds some useful functionality.
- `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

View File

@ -106,13 +106,16 @@ impl EofPdu {
}
generic_length_checks_pdu_deserialization(buf, min_expected_len, full_len_without_crc)?;
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 {
return Err(PduError::WrongDirectiveType((
directive_type,
FileDirectiveType::EofPdu,
)));
return Err(PduError::WrongDirectiveType {
found: directive_type,
expected: FileDirectiveType::EofPdu,
});
}
current_idx += 1;
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;
generic_length_checks_pdu_deserialization(buf, min_expected_len, full_len_without_crc)?;
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 {
return Err(PduError::WrongDirectiveType((
directive_type,
FileDirectiveType::FinishedPdu,
)));
return Err(PduError::WrongDirectiveType {
found: directive_type,
expected: FileDirectiveType::FinishedPdu,
});
}
current_idx += 1;
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)?;
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 {
return Err(PduError::WrongDirectiveType((
directive_type,
FileDirectiveType::MetadataPdu,
)));
return Err(PduError::WrongDirectiveType {
found: directive_type,
expected: FileDirectiveType::MetadataPdu,
});
}
current_idx += 1;
let (fss_len, file_size) =

View File

@ -35,16 +35,19 @@ pub enum PduError {
InvalidEntityLen(u8),
/// Invalid length for the entity ID detected. Only the values 1, 2, 4 and 8 are supported.
InvalidTransactionSeqNumLen(u8),
/// The first entry will be the source entity ID length, the second one the destination entity
/// ID length.
SourceDestIdLenMissmatch((usize, usize)),
/// The first tuple entry will be the found directive type, the second entry the expected entry
/// type.
WrongDirectiveType((FileDirectiveType, FileDirectiveType)),
SourceDestIdLenMissmatch {
src_id_len: usize,
dest_id_len: usize,
},
WrongDirectiveType {
found: FileDirectiveType,
expected: FileDirectiveType,
},
/// 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
/// type.
InvalidDirectiveType((u8, FileDirectiveType)),
InvalidDirectiveType {
found: u8,
expected: Option<FileDirectiveType>,
},
/// Invalid condition code. Contains the raw detected value.
InvalidConditionCode(u8),
/// 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}"
)
}
PduError::SourceDestIdLenMissmatch((src_len, dest_len)) => {
PduError::SourceDestIdLenMissmatch {
src_id_len,
dest_id_len,
} => {
write!(
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) => {
@ -92,17 +98,16 @@ impl Display for PduError {
PduError::FileSizeTooLarge(value) => {
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:?}")
}
PduError::InvalidConditionCode(raw_code) => {
write!(f, "found invalid condition code with raw value {raw_code}")
}
PduError::InvalidDirectiveType((found, expected)) => {
PduError::InvalidDirectiveType { found, expected } => {
write!(
f,
"invalid directive type value {found}, expected {expected:?} ({})",
*expected as u8
"invalid directive type value {found}, expected {expected:?}"
)
}
PduError::InvalidChecksumType(checksum_type) => {
@ -217,10 +222,10 @@ impl CommonPduConfig {
let source_id = source_id.into();
let dest_id = dest_id.into();
if source_id.size() != dest_id.size() {
return Err(PduError::SourceDestIdLenMissmatch((
source_id.size(),
dest_id.size(),
)));
return Err(PduError::SourceDestIdLenMissmatch {
src_id_len: source_id.size(),
dest_id_len: dest_id.size(),
});
}
if source_id.size() != 1
&& source_id.size() != 2
@ -340,6 +345,10 @@ impl PduHeader {
+ 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
/// plus the PDU datafield length.
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
// this check is still kept for defensive programming.
if self.pdu_conf.source_entity_id.size() != self.pdu_conf.dest_entity_id.size() {
return Err(PduError::SourceDestIdLenMissmatch((
self.pdu_conf.source_entity_id.size(),
self.pdu_conf.dest_entity_id.size(),
)));
return Err(PduError::SourceDestIdLenMissmatch {
src_id_len: self.pdu_conf.source_entity_id.size(),
dest_id_len: self.pdu_conf.dest_entity_id.size(),
});
}
if buf.len()
< FIXED_HEADER_LEN
@ -922,9 +931,13 @@ mod tests {
CommonPduConfig::new_with_byte_fields(src_id, dest_id, transaction_seq_id);
assert!(pdu_conf_res.is_err());
let error = pdu_conf_res.unwrap_err();
if let PduError::SourceDestIdLenMissmatch((src_len, dest_len)) = error {
assert_eq!(src_len, 1);
assert_eq!(dest_len, 2);
if let PduError::SourceDestIdLenMissmatch {
src_id_len,
dest_id_len,
} = error
{
assert_eq!(src_id_len, 1);
assert_eq!(dest_id_len, 2);
}
}