diff --git a/src/dest.rs b/src/dest.rs index 209162a..971c899 100644 --- a/src/dest.rs +++ b/src/dest.rs @@ -2223,7 +2223,7 @@ mod tests { ); assert_eq!(finished_pdu.fs_responses_raw(), &[]); assert!(tb.handler.pdu_sender.queue_empty()); - user.verify_finished_indication( + user.verify_finished_indication_retained( DeliveryCode::Incomplete, ConditionCode::CheckLimitReached, transaction_id, @@ -2279,7 +2279,7 @@ mod tests { ) .expect("state machine call with EOF insertion failed"); assert_eq!(packets, 0); - user.verify_finished_indication( + user.verify_finished_indication_retained( DeliveryCode::Complete, ConditionCode::CancelRequestReceived, id, @@ -2338,7 +2338,7 @@ mod tests { if insert_packet { // Checksum success, so data is complete. assert_eq!(finished_pdu.delivery_code(), DeliveryCode::Complete); - user.verify_finished_indication( + user.verify_finished_indication_retained( DeliveryCode::Complete, ConditionCode::CancelRequestReceived, id, @@ -2353,7 +2353,7 @@ mod tests { assert_eq!(ignored.0, id); assert_eq!(ignored.1, ConditionCode::FileChecksumFailure); assert_eq!(ignored.2, 5); - user.verify_finished_indication( + user.verify_finished_indication_retained( DeliveryCode::Incomplete, ConditionCode::CancelRequestReceived, id, @@ -2367,7 +2367,7 @@ mod tests { EntityIdTlv::new(LOCAL_ID.into()) ); } else { - user.verify_finished_indication( + user.verify_finished_indication_retained( DeliveryCode::Complete, ConditionCode::CancelRequestReceived, id, @@ -2407,7 +2407,7 @@ mod tests { .handler .state_machine_no_packet(&mut user) .expect("state machine call with EOF insertion failed"); - user.verify_finished_indication( + user.verify_finished_indication_retained( DeliveryCode::Complete, ConditionCode::CancelRequestReceived, id, @@ -2449,7 +2449,7 @@ mod tests { finished_pdu.fault_location(), Some(EntityIdTlv::new(REMOTE_ID.into())) ); - user.verify_finished_indication( + user.verify_finished_indication_retained( DeliveryCode::Complete, ConditionCode::CancelRequestReceived, id, @@ -2498,7 +2498,7 @@ mod tests { ); tb.expected_file_size = file_size; tb.expected_full_data = file_data[0..file_size as usize].to_vec(); - user.verify_finished_indication( + user.verify_finished_indication_retained( DeliveryCode::Incomplete, ConditionCode::CancelRequestReceived, id, @@ -2528,10 +2528,11 @@ mod tests { .state_machine_no_packet(&mut user) .expect("state machine call with EOF insertion failed"); assert_eq!(packets, 0); - user.verify_finished_indication( + user.verify_finished_indication_retained( DeliveryCode::Complete, ConditionCode::CancelRequestReceived, id, + ); } @@ -2567,10 +2568,11 @@ mod tests { // File was disposed. assert!(!Path::exists(tb.dest_path())); assert_eq!(user.finished_indic_queue.len(), 1); - let finished_indication = user.finished_indic_queue.pop_front().unwrap(); - assert_eq!(finished_indication.id, transaction_id); - assert_eq!(finished_indication.condition_code, ConditionCode::CancelRequestReceived); - assert_eq!(finished_indication.delivery_code, DeliveryCode::Incomplete); - assert_eq!(finished_indication.file_status, FileStatus::DiscardDeliberately); + user.verify_finished_indication( + DeliveryCode::Incomplete, + ConditionCode::CancelRequestReceived, + transaction_id, + FileStatus::DiscardDeliberately + ); } } diff --git a/src/lost_segments.rs b/src/lost_segments.rs index 796fbde..d2114d5 100644 --- a/src/lost_segments.rs +++ b/src/lost_segments.rs @@ -9,6 +9,9 @@ //! * [LostSegmentsListHeapless]: A fixed-size list based implementation where the size //! of the lost segment list is statically known at compile-time. Suitable for resource //! constrained devices where dyanamic allocation is not allowed or possible. + +use spacepackets::{cfdp::{pdu::nak::NakPduCreatorWithReservedSeqReqsBuf, LargeFileFlag}, ByteConversionError}; + #[derive(Debug, PartialEq, Eq, thiserror::Error)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -26,6 +29,18 @@ pub enum LostSegmentError { InvalidSegmentBoundary(u64, u64), } +#[derive(Debug, PartialEq, Eq, thiserror::Error)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[non_exhaustive] +pub enum LostSegmentWriteError { + #[error("number of segments mismatch: expected {expected}, actual {actual}")] + NumSegmentsMismatch { expected: usize, actual: usize }, + #[error("byte conversion error: {0}")] + ByteConversion(ByteConversionError), + +} + /// Generic trait to model a lost segment store. /// /// The destination handler can use this store to keep track of lost segments and re-requesting @@ -81,6 +96,25 @@ pub trait LostSegmentStore { fn is_empty(&self) -> bool { self.len() == 0 } + + fn write_to_nak_segment_list(&self, nak_builder: &mut NakPduCreatorWithReservedSeqReqsBuf) -> Result { + if nak_builder.num_segment_reqs() != self.len() { + return Err(LostSegmentWriteError::NumSegmentsMismatch { expected: self.len(), actual: nak_builder.num_segment_reqs() }); + } + let len_per_segment = if nak_builder.pdu_header().common_pdu_conf().file_flag == LargeFileFlag::Large { + 16 + } else { + 8 + }; + let written_len = self.len() * len_per_segment; + let segment_buf= nak_builder.segment_request_buffer_mut(); + let mut current_index = 0; + for segment in self.iter() { + + + } + + } } /// Implementation based on a [hashbrown::HashSet] which can grow dynamically. diff --git a/src/source.rs b/src/source.rs index 42f42da..0205cf2 100644 --- a/src/source.rs +++ b/src/source.rs @@ -1698,7 +1698,7 @@ mod tests { DeliveryCode::Complete, ConditionCode::NoError, transfer_info.id, - FileStatus::Unreported + FileStatus::Unreported, ); } @@ -1727,6 +1727,11 @@ mod tests { tb.acknowledge_eof_pdu(&mut user, &transaction_info); tb.finish_handling(&mut user, &transaction_info); tb.common_finished_pdu_ack_check(); + user.verify_finished_indication_retained( + DeliveryCode::Complete, + ConditionCode::NoError, + transaction_info.id, + ); } #[test]