CFDP extracted to library #201

Closed
muellerr wants to merge 18 commits from continue-cfsp-source-handler into main
Showing only changes of commit 1646aac004 - Show all commits

View File

@ -1,5 +1,4 @@
use core::{cell::RefCell, ops::ControlFlow, str::Utf8Error}; use core::{cell::RefCell, ops::ControlFlow, str::Utf8Error};
use std::println;
use spacepackets::{ use spacepackets::{
cfdp::{ cfdp::{
@ -748,11 +747,14 @@ impl<
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::path::PathBuf; use std::{path::PathBuf, string::ToString};
use alloc::string::String; use alloc::string::String;
use spacepackets::{ use spacepackets::{
cfdp::{pdu::metadata::MetadataPduReader, ChecksumType, CrcFlag}, cfdp::{
pdu::{finished::FinishedPduCreator, metadata::MetadataPduReader},
ChecksumType, CrcFlag,
},
util::UnsignedByteFieldU16, util::UnsignedByteFieldU16,
}; };
use tempfile::TempPath; use tempfile::TempPath;
@ -790,8 +792,8 @@ mod tests {
struct SourceHandlerTestbench { struct SourceHandlerTestbench {
handler: TestSourceHandler, handler: TestSourceHandler,
// src_path: PathBuf, srcfile: Option<String>,
// dest_path: PathBuf, destfile: Option<String>,
} }
impl SourceHandlerTestbench { impl SourceHandlerTestbench {
@ -816,9 +818,22 @@ mod tests {
basic_remote_cfg_table(REMOTE_ID, crc_on_transmission_by_default), basic_remote_cfg_table(REMOTE_ID, crc_on_transmission_by_default),
SeqCountProviderSimple::default(), SeqCountProviderSimple::default(),
), ),
srcfile: None,
destfile: None,
} }
} }
fn put_request(
&mut self,
put_request: &impl ReadablePutRequest,
) -> Result<(), PutRequestError> {
if self.srcfile.is_some() || self.destfile.is_some() {
self.srcfile = Some(put_request.source_file().unwrap().to_string());
self.destfile = Some(put_request.dest_file().unwrap().to_string());
}
self.handler.put_request(put_request)
}
fn all_fault_queues_empty(&self) -> bool { fn all_fault_queues_empty(&self) -> bool {
self.handler self.handler
.local_cfg .local_cfg
@ -834,6 +849,33 @@ mod tests {
fn get_next_sent_pdu(&self) -> Option<SentPdu> { fn get_next_sent_pdu(&self) -> Option<SentPdu> {
self.handler.pdu_sender.retrieve_next_pdu() self.handler.pdu_sender.retrieve_next_pdu()
} }
fn common_pdu_check_for_file_transfer(&self, pdu_header: &PduHeader, crc_flag: CrcFlag) {
assert_eq!(
pdu_header.seg_ctrl(),
SegmentationControl::NoRecordBoundaryPreservation
);
assert_eq!(
pdu_header.seg_metadata_flag(),
SegmentMetadataFlag::NotPresent
);
assert_eq!(pdu_header.common_pdu_conf().source_id(), LOCAL_ID.into());
assert_eq!(pdu_header.common_pdu_conf().dest_id(), REMOTE_ID.into());
assert_eq!(pdu_header.common_pdu_conf().crc_flag, crc_flag);
assert_eq!(
pdu_header.common_pdu_conf().trans_mode,
TransmissionMode::Unacknowledged
);
assert_eq!(
pdu_header.common_pdu_conf().direction,
Direction::TowardsReceiver
);
assert_eq!(
pdu_header.common_pdu_conf().file_flag,
LargeFileFlag::Normal
);
assert_eq!(pdu_header.common_pdu_conf().transaction_seq_num.size(), 2);
}
} }
#[test] #[test]
@ -848,31 +890,21 @@ mod tests {
assert_eq!(tb.handler.step(), TransactionStep::Idle); assert_eq!(tb.handler.step(), TransactionStep::Idle);
} }
#[test] fn common_no_acked_file_transfer(
fn test_empty_file_transfer_not_acked_no_closure() { tb: &mut SourceHandlerTestbench,
let fault_handler = TestFaultHandler::default(); cfdp_user: &mut TestCfdpUser,
let test_sender = TestCfdpSender::default(); put_request: PutRequestOwned,
let mut tb = SourceHandlerTestbench::new(false, fault_handler, test_sender); srcfile_str: String,
let (srcfile, destfile) = init_full_filepaths_textfile(); destfile_str: String,
let srcfile_str = String::from(srcfile.to_str().unwrap()); ) -> PduHeader {
let destfile_str = String::from(destfile.to_str().unwrap());
let put_request = PutRequestOwned::new_regular_request(
REMOTE_ID.into(),
&srcfile_str,
&destfile_str,
Some(TransmissionMode::Unacknowledged),
Some(false),
)
.expect("creating put request failed");
tb.handler tb.handler
.put_request(&put_request) .put_request(&put_request)
.expect("put_request call failed"); .expect("put_request call failed");
assert_eq!(tb.handler.state(), State::Busy); assert_eq!(tb.handler.state(), State::Busy);
assert_eq!(tb.handler.step(), TransactionStep::Idle); assert_eq!(tb.handler.step(), TransactionStep::Idle);
let mut cfdp_user = TestCfdpUser::new(0, srcfile_str.clone(), destfile_str.clone(), 0);
let sent_packets = tb let sent_packets = tb
.handler .handler
.state_machine(&mut cfdp_user, None) .state_machine(cfdp_user, None)
.expect("source handler FSM failure"); .expect("source handler FSM failure");
assert_eq!(sent_packets, 2); assert_eq!(sent_packets, 2);
assert!(!tb.pdu_queue_empty()); assert!(!tb.pdu_queue_empty());
@ -885,6 +917,8 @@ mod tests {
); );
let metadata_pdu = let metadata_pdu =
MetadataPduReader::new(&next_pdu.raw_pdu).expect("invalid metadata PDU format"); MetadataPduReader::new(&next_pdu.raw_pdu).expect("invalid metadata PDU format");
let pdu_header = metadata_pdu.pdu_header();
tb.common_pdu_check_for_file_transfer(metadata_pdu.pdu_header(), CrcFlag::NoCrc);
assert_eq!( assert_eq!(
metadata_pdu metadata_pdu
.src_file_name() .src_file_name()
@ -906,7 +940,16 @@ mod tests {
metadata_pdu.metadata_params().checksum_type, metadata_pdu.metadata_params().checksum_type,
ChecksumType::Crc32 ChecksumType::Crc32
); );
assert!(!metadata_pdu.metadata_params().closure_requested); let closure_requested = if let Some(closure_requested) = put_request.closure_requested {
assert_eq!(
metadata_pdu.metadata_params().closure_requested,
closure_requested
);
closure_requested
} else {
assert!(metadata_pdu.metadata_params().closure_requested);
metadata_pdu.metadata_params().closure_requested
};
assert_eq!(metadata_pdu.options(), &[]); assert_eq!(metadata_pdu.options(), &[]);
let next_pdu = tb.get_next_sent_pdu().unwrap(); let next_pdu = tb.get_next_sent_pdu().unwrap();
@ -916,33 +959,10 @@ mod tests {
Some(FileDirectiveType::EofPdu) Some(FileDirectiveType::EofPdu)
); );
let eof_pdu = EofPdu::from_bytes(&next_pdu.raw_pdu).expect("invalid metadata PDU format"); let eof_pdu = EofPdu::from_bytes(&next_pdu.raw_pdu).expect("invalid metadata PDU format");
tb.common_pdu_check_for_file_transfer(eof_pdu.pdu_header(), CrcFlag::NoCrc);
assert_eq!(eof_pdu.condition_code(), ConditionCode::NoError); assert_eq!(eof_pdu.condition_code(), ConditionCode::NoError);
assert_eq!(eof_pdu.file_size(), 0); assert_eq!(eof_pdu.file_size(), 0);
assert_eq!(eof_pdu.file_checksum(), CRC_32.digest().finalize()); assert_eq!(eof_pdu.file_checksum(), CRC_32.digest().finalize());
assert_eq!(
eof_pdu.pdu_header().common_pdu_conf().source_id(),
LOCAL_ID.into()
);
assert_eq!(
eof_pdu.pdu_header().common_pdu_conf().dest_id(),
REMOTE_ID.into()
);
assert_eq!(
eof_pdu.pdu_header().common_pdu_conf().crc_flag,
CrcFlag::NoCrc
);
assert_eq!(
eof_pdu.pdu_header().common_pdu_conf().direction,
Direction::TowardsReceiver
);
assert_eq!(
eof_pdu.pdu_header().common_pdu_conf().file_flag,
LargeFileFlag::Normal
);
assert_eq!(
eof_pdu.pdu_header().common_pdu_conf().trans_mode,
TransmissionMode::Unacknowledged
);
assert_eq!( assert_eq!(
eof_pdu eof_pdu
.pdu_header() .pdu_header()
@ -951,14 +971,76 @@ mod tests {
.value_const(), .value_const(),
0 0
); );
assert_eq!( if !closure_requested {
eof_pdu assert_eq!(tb.handler.state(), State::Idle);
.pdu_header() assert_eq!(tb.handler.step(), TransactionStep::Idle);
.common_pdu_conf() } else {
.transaction_seq_num assert_eq!(tb.handler.state(), State::Busy);
.size(), assert_eq!(tb.handler.step(), TransactionStep::WaitingForFinished);
2 }
*pdu_header
}
#[test]
fn test_empty_file_transfer_not_acked_no_closure() {
let fault_handler = TestFaultHandler::default();
let test_sender = TestCfdpSender::default();
let mut tb = SourceHandlerTestbench::new(false, fault_handler, test_sender);
let (srcfile, destfile) = init_full_filepaths_textfile();
let srcfile_str = String::from(srcfile.to_str().unwrap());
let destfile_str = String::from(destfile.to_str().unwrap());
let put_request = PutRequestOwned::new_regular_request(
REMOTE_ID.into(),
&srcfile_str,
&destfile_str,
Some(TransmissionMode::Unacknowledged),
Some(false),
)
.expect("creating put request failed");
let mut cfdp_user = TestCfdpUser::new(0, srcfile_str.clone(), destfile_str.clone(), 0);
common_no_acked_file_transfer(
&mut tb,
&mut cfdp_user,
put_request,
srcfile_str,
destfile_str,
); );
}
#[test]
fn test_empty_file_transfer_not_acked_with_closure() {
let fault_handler = TestFaultHandler::default();
let test_sender = TestCfdpSender::default();
let mut tb = SourceHandlerTestbench::new(false, fault_handler, test_sender);
let (srcfile, destfile) = init_full_filepaths_textfile();
let srcfile_str = String::from(srcfile.to_str().unwrap());
let destfile_str = String::from(destfile.to_str().unwrap());
let put_request = PutRequestOwned::new_regular_request(
REMOTE_ID.into(),
&srcfile_str,
&destfile_str,
Some(TransmissionMode::Unacknowledged),
Some(true),
)
.expect("creating put request failed");
let mut cfdp_user = TestCfdpUser::new(0, srcfile_str.clone(), destfile_str.clone(), 0);
let pdu_header = common_no_acked_file_transfer(
&mut tb,
&mut cfdp_user,
put_request,
srcfile_str,
destfile_str,
);
let finished_pdu = FinishedPduCreator::new_default(
pdu_header,
DeliveryCode::Complete,
FileStatus::Retained,
);
let finished_pdu_vec = finished_pdu.to_vec().unwrap();
let packet_info = PacketInfo::new(&finished_pdu_vec).unwrap();
tb.handler
.state_machine(&mut cfdp_user, Some(&packet_info))
.unwrap();
assert_eq!(tb.handler.state(), State::Idle); assert_eq!(tb.handler.state(), State::Idle);
assert_eq!(tb.handler.step(), TransactionStep::Idle); assert_eq!(tb.handler.step(), TransactionStep::Idle);
} }