CFDP extracted to library #201
@ -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"
|
||||||
|
@ -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(
|
||||||
|
Loading…
Reference in New Issue
Block a user