PDU improvements and additions #24
@ -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
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
|
@ -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) =
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user