CFDP initial packet support #14

Merged
muellerr merged 49 commits from cfdp_first_support into main 2023-07-02 17:31:17 +02:00
Showing only changes of commit 0ad8dd6eef - Show all commits

View File

@ -19,13 +19,28 @@ pub enum RecordContinuationState {
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct SegmentMetadata<'seg_meta> { pub struct SegmentMetadata<'seg_meta> {
record_continuation_state: RecordContinuationState, record_continuation_state: RecordContinuationState,
seg_metadata_len: u8,
metadata: Option<&'seg_meta [u8]>, metadata: Option<&'seg_meta [u8]>,
} }
impl<'seg_meta> SegmentMetadata<'seg_meta> { impl<'seg_meta> SegmentMetadata<'seg_meta> {
pub fn new(
record_continuation_state: RecordContinuationState,
metadata: Option<&'seg_meta [u8]>,
) -> Option<Self> {
if let Some(metadata) = metadata {
if metadata.len() > 2_usize.pow(6) - 1 {
return None;
}
}
Some(Self {
record_continuation_state,
metadata,
})
}
pub fn written_len(&self) -> usize { pub fn written_len(&self) -> usize {
1 + self.seg_metadata_len as usize // Map empty metadata to 0 and slice to its length.
1 + self.metadata.map_or(0, |meta| meta.len())
} }
pub(crate) fn write_to_bytes(&self, buf: &mut [u8]) -> Result<usize, ByteConversionError> { pub(crate) fn write_to_bytes(&self, buf: &mut [u8]) -> Result<usize, ByteConversionError> {
@ -35,7 +50,8 @@ impl<'seg_meta> SegmentMetadata<'seg_meta> {
expected: self.written_len(), expected: self.written_len(),
})); }));
} }
buf[0] = ((self.record_continuation_state as u8) << 6) | self.seg_metadata_len; buf[0] = ((self.record_continuation_state as u8) << 6)
| self.metadata.map_or(0, |meta| meta.len() as u8);
if self.metadata.is_some() { if self.metadata.is_some() {
buf[1..].copy_from_slice(self.metadata.unwrap()) buf[1..].copy_from_slice(self.metadata.unwrap())
} }
@ -58,7 +74,6 @@ impl<'seg_meta> SegmentMetadata<'seg_meta> {
// Can't fail, only 2 bits // Can't fail, only 2 bits
record_continuation_state: RecordContinuationState::try_from((buf[0] >> 6) & 0b11) record_continuation_state: RecordContinuationState::try_from((buf[0] >> 6) & 0b11)
.unwrap(), .unwrap(),
seg_metadata_len: seg_metadata_len as u8,
metadata, metadata,
}) })
} }
@ -207,8 +222,9 @@ impl<'seg_meta, 'file_data> FileDataPdu<'seg_meta, 'file_data> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::cfdp::pdu::file_data::FileDataPdu; use crate::cfdp::pdu::file_data::{FileDataPdu, RecordContinuationState, SegmentMetadata};
use crate::cfdp::pdu::{CommonPduConfig, PduHeader}; use crate::cfdp::pdu::{CommonPduConfig, PduHeader};
use crate::cfdp::{SegmentMetadataFlag, SegmentationControl};
use crate::util::UbfU8; use crate::util::UbfU8;
#[test] #[test]
@ -282,4 +298,27 @@ mod tests {
let fd_pdu_read_back = fd_pdu_read_back.unwrap(); let fd_pdu_read_back = fd_pdu_read_back.unwrap();
assert_eq!(fd_pdu_read_back, fd_pdu); assert_eq!(fd_pdu_read_back, fd_pdu);
} }
#[test]
fn test_with_seg_metadata() {
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_defaults(src_id, dest_id, transaction_seq_num).unwrap();
let pdu_header = PduHeader::new_for_file_data(
common_conf,
0,
SegmentMetadataFlag::Present,
SegmentationControl::WithRecordBoundaryPreservation,
);
let file_data: [u8; 4] = [1, 2, 3, 4];
let seg_metadata: [u8; 4] = [4, 3, 2, 1];
let segment_meta =
SegmentMetadata::new(RecordContinuationState::StartAndEnd, Some(&seg_metadata))
.unwrap();
let fd_pdu = FileDataPdu::new_with_seg_metadata(pdu_header, segment_meta, 10, &file_data);
assert!(fd_pdu.segment_metadata().is_some());
assert_eq!(*fd_pdu.segment_metadata().unwrap(), segment_meta);
}
} }