CFDP extracted to library #201

Closed
muellerr wants to merge 18 commits from continue-cfsp-source-handler into main
2 changed files with 61 additions and 8 deletions
Showing only changes of commit a451868a1c - Show all commits

View File

@ -31,7 +31,7 @@ default-features = false
version = "0.12" version = "0.12"
default-features = false default-features = false
git = "https://egit.irs.uni-stuttgart.de/rust/spacepackets" git = "https://egit.irs.uni-stuttgart.de/rust/spacepackets"
branch = "file-data-pdu-update" branch = "eof-pdu-update"
[dependencies.cobs] [dependencies.cobs]
git = "https://github.com/robamu/cobs.rs.git" git = "https://github.com/robamu/cobs.rs.git"

View File

@ -4,11 +4,13 @@ use spacepackets::{
cfdp::{ cfdp::{
lv::Lv, lv::Lv,
pdu::{ pdu::{
eof::EofPdu,
file_data::FileDataPduCreatorWithReservedDatafield, file_data::FileDataPduCreatorWithReservedDatafield,
metadata::{MetadataGenericParams, MetadataPduCreator}, metadata::{MetadataGenericParams, MetadataPduCreator},
CfdpPdu, CommonPduConfig, FileDirectiveType, PduError, PduHeader, WritablePduPacket, CfdpPdu, CommonPduConfig, FileDirectiveType, PduError, PduHeader, WritablePduPacket,
}, },
Direction, LargeFileFlag, PduType, SegmentMetadataFlag, SegmentationControl, ConditionCode, Direction, LargeFileFlag, PduType, SegmentMetadataFlag, SegmentationControl,
NULL_CHECKSUM_U32,
}, },
util::{UnsignedByteField, UnsignedEnum}, util::{UnsignedByteField, UnsignedEnum},
ByteConversionError, ByteConversionError,
@ -44,12 +46,23 @@ pub enum TransactionStep {
pub struct FileParams { pub struct FileParams {
pub progress: u64, pub progress: u64,
pub segment_len: u64, pub segment_len: u64,
//pub crc32: Option<[u8; 4]>, pub crc32: [u8; 4],
pub metadata_only: bool, pub metadata_only: bool,
pub file_size: u64, pub file_size: u64,
pub empty_file: bool, pub empty_file: bool,
} }
impl FileParams {
pub fn reset(&mut self) {
self.progress = 0;
self.segment_len = 0;
self.crc32 = NULL_CHECKSUM_U32;
self.metadata_only = false;
self.file_size = 0;
self.empty_file = false;
}
}
pub struct StateHelper { pub struct StateHelper {
state: super::State, state: super::State,
step: TransactionStep, step: TransactionStep,
@ -62,6 +75,7 @@ pub struct TransferState {
remote_cfg: RemoteEntityConfig, remote_cfg: RemoteEntityConfig,
transmission_mode: super::TransmissionMode, transmission_mode: super::TransmissionMode,
closure_requested: bool, closure_requested: bool,
cond_code_eof: Option<ConditionCode>,
} }
impl Default for StateHelper { impl Default for StateHelper {
@ -272,6 +286,7 @@ impl<
*remote_cfg, *remote_cfg,
transmission_mode, transmission_mode,
closure_requested, closure_requested,
None,
)); ));
Ok(()) Ok(())
} }
@ -299,6 +314,10 @@ impl<
return Ok(result); return Ok(result);
} }
} }
if self.state_helper.step == TransactionStep::SendingEof {
// TODO: Checksum calculation using VFS.
self.prepare_and_send_eof_pdu(0)?;
}
Ok(0) Ok(0)
} }
@ -306,6 +325,7 @@ impl<
&mut self, &mut self,
cfdp_user: &mut impl CfdpUser, cfdp_user: &mut impl CfdpUser,
) -> Result<(), SourceError> { ) -> Result<(), SourceError> {
self.fparams.reset();
let tstate = &self.tstate.expect("transfer state unexpectedly empty"); let tstate = &self.tstate.expect("transfer state unexpectedly empty");
if !self.put_request_cacher.has_source_file() { if !self.put_request_cacher.has_source_file() {
self.fparams.metadata_only = true; self.fparams.metadata_only = true;
@ -361,7 +381,10 @@ impl<
} }
fn prepare_and_send_metadata_pdu(&mut self) -> Result<(), PduError> { fn prepare_and_send_metadata_pdu(&mut self) -> Result<(), PduError> {
let tstate = &self.tstate.expect("transfer state unexpectedly empty"); let tstate = self
.tstate
.as_ref()
.expect("transfer state unexpectedly empty");
let metadata_params = MetadataGenericParams::new( let metadata_params = MetadataGenericParams::new(
tstate.closure_requested, tstate.closure_requested,
tstate.remote_cfg.default_crc_type, tstate.remote_cfg.default_crc_type,
@ -375,7 +398,7 @@ impl<
Lv::new_empty(), Lv::new_empty(),
self.put_request_cacher.opts_slice(), self.put_request_cacher.opts_slice(),
); );
return self.pdu_send_helper(metadata_pdu); return self.pdu_send_helper(&metadata_pdu);
} }
let metadata_pdu = MetadataPduCreator::new( let metadata_pdu = MetadataPduCreator::new(
PduHeader::new_no_file_data(self.pdu_conf, 0), PduHeader::new_no_file_data(self.pdu_conf, 0),
@ -384,7 +407,7 @@ impl<
Lv::new_from_str(self.put_request_cacher.dest_file().unwrap()).unwrap(), Lv::new_from_str(self.put_request_cacher.dest_file().unwrap()).unwrap(),
self.put_request_cacher.opts_slice(), self.put_request_cacher.opts_slice(),
); );
self.pdu_send_helper(metadata_pdu) self.pdu_send_helper(&metadata_pdu)
} }
fn file_data_fsm(&mut self) -> Result<ControlFlow<u32>, SourceError> { fn file_data_fsm(&mut self) -> Result<ControlFlow<u32>, SourceError> {
@ -397,9 +420,10 @@ impl<
{ {
return Ok(ControlFlow::Break(1)); return Ok(ControlFlow::Break(1));
} }
if self.fparams.empty_file { if self.fparams.empty_file || self.fparams.progress >= self.fparams.file_size {
// EOF is still expected. // EOF is still expected.
self.state_helper.step = TransactionStep::SendingEof; self.state_helper.step = TransactionStep::SendingEof;
self.tstate.as_mut().unwrap().cond_code_eof = Some(ConditionCode::NoError);
} else if self.fparams.metadata_only { } else if self.fparams.metadata_only {
// Special case: Metadata Only, no EOF required. // Special case: Metadata Only, no EOF required.
if self.tstate.as_ref().unwrap().closure_requested { if self.tstate.as_ref().unwrap().closure_requested {
@ -492,7 +516,36 @@ impl<
Ok(true) Ok(true)
} }
fn pdu_send_helper(&self, pdu: impl WritablePduPacket + CfdpPdu) -> Result<(), PduError> { fn prepare_and_send_eof_pdu(&mut self, checksum: u32) -> Result<(), PduError> {
let tstate = self
.tstate
.as_ref()
.expect("transfer state unexpectedly empty");
//let checksum_u32 = u32::from_be_bytes(self.fparams.crc32);
let eof_pdu = EofPdu::new(
PduHeader::new_no_file_data(self.pdu_conf, 0),
tstate.cond_code_eof.unwrap_or(ConditionCode::NoError),
checksum,
self.fparams.file_size,
None,
);
self.pdu_send_helper(&eof_pdu)?;
/*
*
assert self._params.cond_code_eof is not None
self._add_packet_to_be_sent(
EofPdu(
file_checksum=checksum,
file_size=self._params.fp.progress,
pdu_conf=self._params.pdu_conf,
condition_code=self._params.cond_code_eof,
)
)
*/
Ok(())
}
fn pdu_send_helper(&self, pdu: &(impl WritablePduPacket + CfdpPdu)) -> Result<(), PduError> {
let mut pdu_buffer_mut = self.pdu_buffer.borrow_mut(); let mut pdu_buffer_mut = self.pdu_buffer.borrow_mut();
let written_len = pdu.write_to_bytes(&mut pdu_buffer_mut)?; let written_len = pdu.write_to_bytes(&mut pdu_buffer_mut)?;
self.pdu_sender.send_pdu( self.pdu_sender.send_pdu(