diff --git a/src/dest.rs b/src/dest.rs index 3648ddc..b631be6 100644 --- a/src/dest.rs +++ b/src/dest.rs @@ -30,36 +30,36 @@ //! 4. A Finished PDU has been sent back to the remote side. //! 5. A Finished PDU ACK was received. use crate::{ - DummyPduProvider, GenericSendError, IndicationConfig, PduProvider, PositiveAckParams, lost_segments::{LostSegmentError, LostSegmentStore}, user::TransactionFinishedParams, + DummyPduProvider, GenericSendError, IndicationConfig, PduProvider, PositiveAckParams, }; use core::{ cell::{Cell, RefCell}, - str::{Utf8Error, from_utf8, from_utf8_unchecked}, + str::{from_utf8, from_utf8_unchecked, Utf8Error}, }; use super::{ - Countdown, EntityType, LocalEntityConfig, PacketTarget, PduSender, RemoteConfigStore, - RemoteEntityConfig, State, TimerContext, TimerCreator, TransactionId, UserFaultHook, filestore::{FilestoreError, VirtualFilestore}, user::{CfdpUser, FileSegmentRecvdParams, MetadataReceivedParams}, + Countdown, EntityType, LocalEntityConfig, PacketTarget, PduSender, RemoteConfigStore, + RemoteEntityConfig, State, TimerContext, TimerCreator, TransactionId, UserFaultHook, }; use smallvec::SmallVec; use spacepackets::{ cfdp::{ - ChecksumType, ConditionCode, FaultHandlerCode, LargeFileFlag, PduType, TransactionStatus, - TransmissionMode, pdu::{ - CfdpPdu, CommonPduConfig, FileDirectiveType, PduError, PduHeader, ack::AckPdu, eof::EofPdu, file_data::FileDataPdu, finished::{DeliveryCode, FileStatus, FinishedPduCreator}, metadata::{MetadataGenericParams, MetadataPduReader}, nak::{NakPduCreator, NakPduCreatorWithReservedSeqReqsBuf}, + CfdpPdu, CommonPduConfig, FileDirectiveType, PduError, PduHeader, }, - tlv::{EntityIdTlv, GenericTlv, ReadableTlv, TlvType, msg_to_user::MsgToUserTlv}, + tlv::{msg_to_user::MsgToUserTlv, EntityIdTlv, GenericTlv, ReadableTlv, TlvType}, + ChecksumType, ConditionCode, FaultHandlerCode, LargeFileFlag, PduType, TransactionStatus, + TransmissionMode, }, util::{UnsignedByteField, UnsignedEnum}, }; @@ -392,14 +392,14 @@ impl } impl< - PduSenderInstance: PduSender, - UserFaultHookInstance: UserFaultHook, - VirtualFilestoreInstance: VirtualFilestore, - RemoteConfigStoreInstance: RemoteConfigStore, - TimerCreatorInstance: TimerCreator, - CountdownInstance: Countdown, - LostSegmentTracker: LostSegmentStore, -> + PduSenderInstance: PduSender, + UserFaultHookInstance: UserFaultHook, + VirtualFilestoreInstance: VirtualFilestore, + RemoteConfigStoreInstance: RemoteConfigStore, + TimerCreatorInstance: TimerCreator, + CountdownInstance: Countdown, + LostSegmentTracker: LostSegmentStore, + > DestinationHandler< PduSenderInstance, UserFaultHookInstance, @@ -1807,21 +1807,21 @@ mod tests { use rand::Rng; use spacepackets::{ cfdp::{ - ChecksumType, TransmissionMode, lv::Lv, - pdu::{WritablePduPacket, finished::FinishedPduReader, metadata::MetadataPduCreator}, + pdu::{finished::FinishedPduReader, metadata::MetadataPduCreator, WritablePduPacket}, + ChecksumType, TransmissionMode, }, - util::{UbfU16, UnsignedByteFieldU8}, + util::{UnsignedByteFieldU8}, }; use crate::{ - CRC_32, FaultHandler, IndicationConfig, PduRawWithInfo, RemoteConfigStoreStd, filestore::NativeFilestore, lost_segments::LostSegmentsList, tests::{ - LOCAL_ID, REMOTE_ID, SentPdu, TestCfdpSender, TestCfdpUser, TestCheckTimer, - TestCheckTimerCreator, TestFaultHandler, TimerExpiryControl, basic_remote_cfg_table, + basic_remote_cfg_table, SentPdu, TestCfdpSender, TestCfdpUser, TestCheckTimer, + TestCheckTimerCreator, TestFaultHandler, TimerExpiryControl, LOCAL_ID, REMOTE_ID, }, + FaultHandler, IndicationConfig, PduRawWithInfo, RemoteConfigStoreStd, CRC_32, }; use super::*; @@ -1844,7 +1844,8 @@ mod tests { check_dest_file: bool, check_handler_idle_at_drop: bool, closure_requested: bool, - pdu_header: PduHeader, + //pdu_header: PduHeader, + pdu_conf: CommonPduConfig, expected_full_data: Vec, expected_file_size: u64, buf: [u8; 512], @@ -1876,7 +1877,7 @@ mod tests { check_dest_file, check_handler_idle_at_drop: true, expected_file_size: 0, - pdu_header: create_pdu_header(UbfU16::new(0)), + pdu_conf: CommonPduConfig::default(), expected_full_data: Vec::new(), buf: [0; 512], }; @@ -1928,12 +1929,14 @@ mod tests { &mut self, user: &mut TestCfdpUser, file_size: u64, + transmission_mode: TransmissionMode, ) -> Result { self.expected_file_size = file_size; assert_eq!(user.transaction_indication_call_count, 0); assert_eq!(user.metadata_recv_queue.len(), 0); + let pdu_header = PduHeader::new_no_file_data(self.pdu_conf, 0); let metadata_pdu = create_metadata_pdu( - &self.pdu_header, + &pdu_header, self.src_path.as_path(), self.dest_path.as_path(), file_size, @@ -1942,10 +1945,7 @@ mod tests { let packet_info = create_packet_info(&metadata_pdu, &mut self.buf); self.handler.state_machine(user, Some(&packet_info))?; assert_eq!(user.metadata_recv_queue.len(), 1); - assert_eq!( - self.handler.transmission_mode().unwrap(), - TransmissionMode::Unacknowledged - ); + assert_eq!(self.handler.transmission_mode().unwrap(), transmission_mode); assert_eq!(user.transaction_indication_call_count, 0); assert_eq!(user.metadata_recv_queue.len(), 1); let metadata_recvd = user.metadata_recv_queue.pop_front().unwrap(); @@ -1970,8 +1970,9 @@ mod tests { offset: u64, file_data_chunk: &[u8], ) -> Result { + let pdu_header = PduHeader::new_for_file_data_default(self.pdu_conf, 0); let filedata_pdu = - FileDataPdu::new_no_seg_metadata(self.pdu_header, offset, file_data_chunk); + FileDataPdu::new_no_seg_metadata(pdu_header, offset, file_data_chunk); filedata_pdu .write_to_bytes(&mut self.buf) .expect("writing file data PDU failed"); @@ -1993,7 +1994,8 @@ mod tests { ) -> Result { self.expected_full_data = expected_full_data; assert_eq!(user.finished_indic_queue.len(), 0); - let eof_pdu = create_no_error_eof(&self.expected_full_data, &self.pdu_header); + let pdu_header = PduHeader::new_no_file_data(self.pdu_conf, 0); + let eof_pdu = create_no_error_eof(&self.expected_full_data, &pdu_header); let packet_info = create_packet_info(&eof_pdu, &mut self.buf); self.check_handler_idle_at_drop = true; self.check_dest_file = true; @@ -2081,13 +2083,6 @@ mod tests { ) } - fn create_pdu_header(seq_num: impl Into) -> PduHeader { - let mut pdu_conf = - CommonPduConfig::new_with_byte_fields(LOCAL_ID, REMOTE_ID, seq_num).unwrap(); - pdu_conf.trans_mode = TransmissionMode::Unacknowledged; - PduHeader::new_no_file_data(pdu_conf, 0) - } - fn create_metadata_pdu<'filename>( pdu_header: &PduHeader, src_name: &'filename Path, @@ -2138,14 +2133,12 @@ mod tests { let dest_handler = default_dest_handler(fault_handler, test_sender, &TimerExpiryControl::default()); assert!(dest_handler.transmission_mode().is_none()); - assert!( - dest_handler - .local_cfg - .fault_handler - .user_hook - .borrow() - .all_queues_empty() - ); + assert!(dest_handler + .local_cfg + .fault_handler + .user_hook + .borrow() + .all_queues_empty()); assert!(dest_handler.pdu_sender.queue_empty()); assert_eq!(dest_handler.state(), State::Idle); assert_eq!(dest_handler.step(), TransactionStep::Idle); @@ -2168,7 +2161,21 @@ mod tests { let fault_handler = TestFaultHandler::default(); let mut tb = DestHandlerTestbench::new_with_fixed_paths(fault_handler, false); let mut test_user = tb.test_user_from_cached_paths(0); - tb.generic_transfer_init(&mut test_user, 0) + tb.generic_transfer_init(&mut test_user, 0, TransmissionMode::Unacknowledged) + .expect("transfer init failed"); + tb.state_check(State::Busy, TransactionStep::ReceivingFileDataPdus); + tb.generic_eof_no_error(&mut test_user, Vec::new()) + .expect("EOF no error insertion failed"); + tb.check_completion_indication_success(&mut test_user); + assert!(test_user.indication_queues_empty()); + } + + #[test] + fn test_empty_file_transfer_acked() { + let fault_handler = TestFaultHandler::default(); + let mut tb = DestHandlerTestbench::new_with_fixed_paths(fault_handler, false); + let mut test_user = tb.test_user_from_cached_paths(0); + tb.generic_transfer_init(&mut test_user, 0, TransmissionMode::Acknowledged) .expect("transfer init failed"); tb.state_check(State::Busy, TransactionStep::ReceivingFileDataPdus); tb.generic_eof_no_error(&mut test_user, Vec::new()) @@ -2186,7 +2193,7 @@ mod tests { let mut tb = DestHandlerTestbench::new_with_fixed_paths(fault_handler, false); let mut test_user = tb.test_user_from_cached_paths(file_size); - tb.generic_transfer_init(&mut test_user, file_size) + tb.generic_transfer_init(&mut test_user, 0, TransmissionMode::Unacknowledged) .expect("transfer init failed"); tb.state_check(State::Busy, TransactionStep::ReceivingFileDataPdus); tb.generic_file_data_insert(&mut test_user, 0, file_data) @@ -2208,7 +2215,7 @@ mod tests { let mut tb = DestHandlerTestbench::new_with_fixed_paths(fault_handler, false); let mut test_user = tb.test_user_from_cached_paths(file_size); - tb.generic_transfer_init(&mut test_user, file_size) + tb.generic_transfer_init(&mut test_user, 0, TransmissionMode::Unacknowledged) .expect("transfer init failed"); tb.state_check(State::Busy, TransactionStep::ReceivingFileDataPdus); tb.generic_file_data_insert(&mut test_user, 0, &random_data[0..segment_len]) @@ -2237,7 +2244,7 @@ mod tests { let mut tb = DestHandlerTestbench::new_with_fixed_paths(fault_handler, false); let mut test_user = tb.test_user_from_cached_paths(file_size); let transaction_id = tb - .generic_transfer_init(&mut test_user, file_size) + .generic_transfer_init(&mut test_user, 0, TransmissionMode::Unacknowledged) .expect("transfer init failed"); tb.state_check(State::Busy, TransactionStep::ReceivingFileDataPdus); @@ -2298,7 +2305,7 @@ mod tests { let mut testbench = DestHandlerTestbench::new_with_fixed_paths(fault_handler, false); let mut test_user = testbench.test_user_from_cached_paths(file_size); let transaction_id = testbench - .generic_transfer_init(&mut test_user, file_size) + .generic_transfer_init(&mut test_user, 0, TransmissionMode::Unacknowledged) .expect("transfer init failed"); testbench.state_check(State::Busy, TransactionStep::ReceivingFileDataPdus); @@ -2386,7 +2393,7 @@ mod tests { let fault_handler = TestFaultHandler::default(); let mut tb = DestHandlerTestbench::new_with_fixed_paths(fault_handler, true); let mut test_user = tb.test_user_from_cached_paths(0); - tb.generic_transfer_init(&mut test_user, 0) + tb.generic_transfer_init(&mut test_user, 0, TransmissionMode::Unacknowledged) .expect("transfer init failed"); tb.state_check(State::Busy, TransactionStep::ReceivingFileDataPdus); let sent_packets = tb @@ -2434,12 +2441,13 @@ mod tests { let fault_handler = TestFaultHandler::default(); let mut tb = DestHandlerTestbench::new_with_fixed_paths(fault_handler, true); let mut user = tb.test_user_from_cached_paths(0); - tb.generic_transfer_init(&mut user, 0) + tb.generic_transfer_init(&mut user, 0, TransmissionMode::Unacknowledged) .expect("transfer init failed"); tb.check_handler_idle_at_drop = false; tb.state_check(State::Busy, TransactionStep::ReceivingFileDataPdus); + let pdu_header = PduHeader::new_no_file_data(tb.pdu_conf, 0); let metadata_pdu = create_metadata_pdu( - &tb.pdu_header, + &pdu_header, tb.src_path.as_path(), tb.dest_path.as_path(), 0, @@ -2463,7 +2471,7 @@ mod tests { let fault_handler = TestFaultHandler::default(); let mut tb = DestHandlerTestbench::new_with_fixed_paths(fault_handler, true); let mut user = tb.test_user_from_cached_paths(file_size); - tb.generic_transfer_init(&mut user, file_size) + tb.generic_transfer_init(&mut user, 0, TransmissionMode::Unacknowledged) .expect("transfer init failed"); let faulty_file_data = b"Hemlo World!"; assert_eq!( @@ -2578,7 +2586,7 @@ mod tests { dest_path_buf.push(src_path.file_name().unwrap()); tb.dest_path = dest_path_buf; let mut user = tb.test_user_from_cached_paths(0); - tb.generic_transfer_init(&mut user, 0) + tb.generic_transfer_init(&mut user, 0, TransmissionMode::Unacknowledged) .expect("transfer init failed"); tb.state_check(State::Busy, TransactionStep::ReceivingFileDataPdus); tb.generic_eof_no_error(&mut user, Vec::new()) @@ -2592,11 +2600,12 @@ mod tests { let mut tb = DestHandlerTestbench::new_with_fixed_paths(fault_handler, false); let mut user = tb.test_user_from_cached_paths(0); let id = tb - .generic_transfer_init(&mut user, 0) + .generic_transfer_init(&mut user, 0, TransmissionMode::Unacknowledged) .expect("transfer init failed"); tb.state_check(State::Busy, TransactionStep::ReceivingFileDataPdus); + let pdu_header = PduHeader::new_no_file_data(tb.pdu_conf, 0); let cancel_eof = EofPdu::new( - tb.pdu_header, + pdu_header, ConditionCode::CancelRequestReceived, 0, 0, @@ -2629,7 +2638,7 @@ mod tests { let mut tb = DestHandlerTestbench::new_with_fixed_paths(fault_handler, with_closure); let mut user = tb.test_user_from_cached_paths(file_size); let id = tb - .generic_transfer_init(&mut user, file_size) + .generic_transfer_init(&mut user, 0, TransmissionMode::Unacknowledged) .expect("transfer init failed"); tb.state_check(State::Busy, TransactionStep::ReceivingFileDataPdus); if insert_packet { @@ -2639,8 +2648,9 @@ mod tests { let mut digest = CRC_32.digest(); digest.update(&file_data[0..5]); let checksum = digest.finalize(); + let pdu_header = PduHeader::new_no_file_data(tb.pdu_conf, 0); let cancel_eof = EofPdu::new( - tb.pdu_header, + pdu_header, ConditionCode::CancelRequestReceived, checksum, 5, @@ -2730,7 +2740,7 @@ mod tests { let mut tb = DestHandlerTestbench::new_with_fixed_paths(fault_handler, false); let mut user = tb.test_user_from_cached_paths(0); let id = tb - .generic_transfer_init(&mut user, 0) + .generic_transfer_init(&mut user, 0, TransmissionMode::Unacknowledged) .expect("transfer init failed"); tb.state_check(State::Busy, TransactionStep::ReceivingFileDataPdus); tb.handler.cancel_request(&id); @@ -2752,7 +2762,7 @@ mod tests { let mut tb = DestHandlerTestbench::new_with_fixed_paths(fault_handler, true); let mut user = tb.test_user_from_cached_paths(0); let id = tb - .generic_transfer_init(&mut user, 0) + .generic_transfer_init(&mut user, 0, TransmissionMode::Unacknowledged) .expect("transfer init failed"); tb.state_check(State::Busy, TransactionStep::ReceivingFileDataPdus); tb.handler.cancel_request(&id); @@ -2797,7 +2807,7 @@ mod tests { let mut tb = DestHandlerTestbench::new_with_fixed_paths(fault_handler, true); let mut user = tb.test_user_from_cached_paths(file_size); let id = tb - .generic_transfer_init(&mut user, file_size) + .generic_transfer_init(&mut user, 0, TransmissionMode::Unacknowledged) .expect("transfer init failed"); tb.state_check(State::Busy, TransactionStep::ReceivingFileDataPdus); tb.generic_file_data_insert(&mut user, 0, &file_data[0..5]) @@ -2849,7 +2859,7 @@ mod tests { remote_cfg_mut.disposition_on_cancellation = true; let mut user = tb.test_user_from_cached_paths(0); let id = tb - .generic_transfer_init(&mut user, 0) + .generic_transfer_init(&mut user, 0, TransmissionMode::Unacknowledged) .expect("transfer init failed"); tb.state_check(State::Busy, TransactionStep::ReceivingFileDataPdus); @@ -2883,7 +2893,7 @@ mod tests { remote_cfg_mut.disposition_on_cancellation = true; let mut user = tb.test_user_from_cached_paths(file_size); let transaction_id = tb - .generic_transfer_init(&mut user, file_size) + .generic_transfer_init(&mut user, 0, TransmissionMode::Unacknowledged) .expect("transfer init failed"); tb.state_check(State::Busy, TransactionStep::ReceivingFileDataPdus); tb.generic_file_data_insert(&mut user, 0, &file_data[0..5])