CFDP initial packet support #14
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user