continue
This commit is contained in:
190
src/dest.rs
190
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, PduSendProvider, 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::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},
|
||||
};
|
||||
@@ -334,9 +334,9 @@ pub enum DestError {
|
||||
/// in different concurrent contexts. For example, you can dynamically create new handlers and
|
||||
/// run them inside a thread pool, or move the newly created handler to a new thread."""
|
||||
pub struct DestinationHandler<
|
||||
PduSender: PduSendProvider,
|
||||
PduSenderInstance: PduSender,
|
||||
UserFaultHookInstance: UserFaultHook,
|
||||
Vfs: VirtualFilestore,
|
||||
VirtualFileStoreInstance: VirtualFilestore,
|
||||
RemoteConfigStoreInstance: RemoteConfigStore,
|
||||
TimerCreatorInstance: TimerCreator<Countdown = CountdownInstance>,
|
||||
CountdownInstance: Countdown,
|
||||
@@ -347,8 +347,8 @@ pub struct DestinationHandler<
|
||||
state: State,
|
||||
transaction_params: TransactionParams<CountdownInstance>,
|
||||
pdu_and_cksum_buffer: RefCell<alloc::vec::Vec<u8>>,
|
||||
pub pdu_sender: PduSender,
|
||||
pub vfs: Vfs,
|
||||
pub pdu_sender: PduSenderInstance,
|
||||
pub vfs: VirtualFileStoreInstance,
|
||||
pub remote_cfg_table: RemoteConfigStoreInstance,
|
||||
pub check_timer_creator: TimerCreatorInstance,
|
||||
lost_segment_tracker: LostSegmentTracker,
|
||||
@@ -366,14 +366,14 @@ pub type StdDestinationHandler<PduSender, UserFaultHook> = DestinationHandler<
|
||||
>;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl<PduSender: PduSendProvider, UserFaultHookInstance: UserFaultHook>
|
||||
StdDestinationHandler<PduSender, UserFaultHookInstance>
|
||||
impl<PduSenderInstance: PduSender, UserFaultHookInstance: UserFaultHook>
|
||||
StdDestinationHandler<PduSenderInstance, UserFaultHookInstance>
|
||||
{
|
||||
#[cfg(feature = "std")]
|
||||
pub fn new_std(
|
||||
local_cfg: LocalEntityConfig<UserFaultHookInstance>,
|
||||
pdu_and_cksum_buf_size: usize,
|
||||
pdu_sender: PduSender,
|
||||
pdu_sender: PduSenderInstance,
|
||||
) -> Self {
|
||||
Self::new(
|
||||
local_cfg,
|
||||
@@ -388,18 +388,18 @@ impl<PduSender: PduSendProvider, UserFaultHookInstance: UserFaultHook>
|
||||
}
|
||||
|
||||
impl<
|
||||
PduSender: PduSendProvider,
|
||||
UserFaultHookInstance: UserFaultHook,
|
||||
Vfs: VirtualFilestore,
|
||||
RemoteConfigStoreInstance: RemoteConfigStore,
|
||||
TimerCreatorInstance: TimerCreator<Countdown = CountdownInstance>,
|
||||
CountdownInstance: Countdown,
|
||||
LostSegmentTracker: LostSegmentStore,
|
||||
>
|
||||
PduSenderInstance: PduSender,
|
||||
UserFaultHookInstance: UserFaultHook,
|
||||
VirtualFilestoreInstance: VirtualFilestore,
|
||||
RemoteConfigStoreInstance: RemoteConfigStore,
|
||||
TimerCreatorInstance: TimerCreator<Countdown = CountdownInstance>,
|
||||
CountdownInstance: Countdown,
|
||||
LostSegmentTracker: LostSegmentStore,
|
||||
>
|
||||
DestinationHandler<
|
||||
PduSender,
|
||||
PduSenderInstance,
|
||||
UserFaultHookInstance,
|
||||
Vfs,
|
||||
VirtualFilestoreInstance,
|
||||
RemoteConfigStoreInstance,
|
||||
TimerCreatorInstance,
|
||||
CountdownInstance,
|
||||
@@ -429,8 +429,8 @@ impl<
|
||||
pub fn new(
|
||||
local_cfg: LocalEntityConfig<UserFaultHookInstance>,
|
||||
pdu_and_cksum_buf_size: usize,
|
||||
pdu_sender: PduSender,
|
||||
vfs: Vfs,
|
||||
pdu_sender: PduSenderInstance,
|
||||
vfs: VirtualFilestoreInstance,
|
||||
remote_cfg_table: RemoteConfigStoreInstance,
|
||||
timer_creator: TimerCreatorInstance,
|
||||
lost_segment_tracker: LostSegmentTracker,
|
||||
@@ -987,20 +987,110 @@ impl<
|
||||
})
|
||||
}
|
||||
}
|
||||
self.transaction_params.deferred_procedure_timer = Some(
|
||||
self.check_timer_creator
|
||||
.create_countdown(TimerContext::NakActivity {
|
||||
expiry_time: self
|
||||
.transaction_params
|
||||
.remote_cfg
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.nak_timer_interval,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
fn deferred_lost_segment_handling(&mut self) {
|
||||
assert!(
|
||||
self.transaction_params.acked_params.is_some(),
|
||||
"acknowledged parameters unexpectedly None"
|
||||
);
|
||||
let acked_params = self.transaction_params.acked_params.as_mut().unwrap();
|
||||
if self.lost_segment_tracker.is_empty() && !acked_params.metadata_missing {
|
||||
// We are done and have received everything.
|
||||
match self.checksum_verify(
|
||||
self.transaction_params.progress,
|
||||
self.transaction_params.checksum,
|
||||
) {
|
||||
true => {
|
||||
self.transaction_params
|
||||
.finished_params
|
||||
.condition_code
|
||||
.set(ConditionCode::NoError);
|
||||
self.transaction_params
|
||||
.finished_params
|
||||
.delivery_code
|
||||
.set(DeliveryCode::Complete);
|
||||
}
|
||||
false => {
|
||||
self.transaction_params
|
||||
.finished_params
|
||||
.condition_code
|
||||
.set(ConditionCode::FileChecksumFailure);
|
||||
self.transaction_params
|
||||
.finished_params
|
||||
.delivery_code
|
||||
.set(DeliveryCode::Incomplete);
|
||||
}
|
||||
}
|
||||
self.set_step(TransactionStep::TransferCompletion);
|
||||
acked_params.deferred_procedure_active = false;
|
||||
return;
|
||||
}
|
||||
|
||||
let mut first_nak_issuance = self.transaction_params.deferred_procedure_timer.is_none();
|
||||
if first_nak_issuance {
|
||||
self.transaction_params.deferred_procedure_timer = Some(
|
||||
self.check_timer_creator
|
||||
.create_countdown(TimerContext::NakActivity {
|
||||
expiry_time: self
|
||||
.transaction_params
|
||||
.remote_cfg
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.nak_timer_interval,
|
||||
}),
|
||||
);
|
||||
} else if !self
|
||||
.transaction_params
|
||||
.deferred_procedure_timer
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.has_expired()
|
||||
{
|
||||
return;
|
||||
}
|
||||
if !first_nak_issuance
|
||||
&& acked_params.nak_activity_counter + 1
|
||||
== self
|
||||
.transaction_params
|
||||
.remote_cfg
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.nak_timer_expiration_limit
|
||||
{
|
||||
self.transaction_params.finished_params.delivery_code = DeliveryCode::Incomplete;
|
||||
if self.declare_fault(ConditionCode::NakLimitReached)
|
||||
== FaultHandlerCode::AbandonTransaction
|
||||
{
|
||||
self.abandon_transaction();
|
||||
}
|
||||
return;
|
||||
}
|
||||
let pdu_header = PduHeader::new_no_file_data(self.transaction_params.pdu_conf, 0);
|
||||
let max_segment_reqs = NakPduCreatorWithReservedSeqReqsBuf::calculate_max_segment_requests(
|
||||
self.transaction_params
|
||||
.remote_cfg
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.max_packet_len,
|
||||
&pdu_header,
|
||||
);
|
||||
let mut segments_to_send = self.lost_segment_tracker.number_of_segments();
|
||||
if acked_params.metadata_missing {
|
||||
segments_to_send += 1;
|
||||
}
|
||||
if segments_to_send <= max_segment_reqs {
|
||||
|
||||
}
|
||||
|
||||
let mut nak_pdu_creator = NakPduCreatorWithReservedSeqReqsBuf::new(
|
||||
self.pdu_and_cksum_buffer.get_mut(),
|
||||
pdu_header,
|
||||
core::cmp::min(segments_to_send as usize, max_segment_reqs),
|
||||
)
|
||||
for index in 0..segments_to_send {
|
||||
|
||||
}
|
||||
// TODO.
|
||||
}
|
||||
|
||||
@@ -1511,21 +1601,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},
|
||||
};
|
||||
|
||||
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::*;
|
||||
@@ -1842,14 +1932,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);
|
||||
|
||||
@@ -693,7 +693,7 @@ pub enum GenericSendError {
|
||||
Other,
|
||||
}
|
||||
|
||||
pub trait PduSendProvider {
|
||||
pub trait PduSender {
|
||||
fn send_pdu(
|
||||
&self,
|
||||
pdu_type: PduType,
|
||||
@@ -716,7 +716,7 @@ pub mod std_mod {
|
||||
|
||||
use super::*;
|
||||
|
||||
impl PduSendProvider for mpsc::Sender<PduOwnedWithInfo> {
|
||||
impl PduSender for mpsc::Sender<PduOwnedWithInfo> {
|
||||
fn send_pdu(
|
||||
&self,
|
||||
pdu_type: PduType,
|
||||
@@ -1471,7 +1471,7 @@ pub(crate) mod tests {
|
||||
pub packet_queue: RefCell<VecDeque<SentPdu>>,
|
||||
}
|
||||
|
||||
impl PduSendProvider for TestCfdpSender {
|
||||
impl PduSender for TestCfdpSender {
|
||||
fn send_pdu(
|
||||
&self,
|
||||
pdu_type: PduType,
|
||||
|
||||
@@ -72,7 +72,7 @@ use crate::{
|
||||
};
|
||||
|
||||
use super::{
|
||||
LocalEntityConfig, PacketTarget, PduSendProvider, RemoteConfigStore, RemoteEntityConfig, State,
|
||||
LocalEntityConfig, PacketTarget, PduSender, RemoteConfigStore, RemoteEntityConfig, State,
|
||||
TransactionId, UserFaultHook,
|
||||
filestore::{FilestoreError, VirtualFilestore},
|
||||
request::{ReadablePutRequest, StaticPutRequestCacher},
|
||||
@@ -242,7 +242,7 @@ pub enum FsmContext {
|
||||
/// is required, it is recommended to create a new handler and run all active handlers inside a
|
||||
/// thread pool, or move the newly created handler to a new thread.
|
||||
pub struct SourceHandler<
|
||||
PduSender: PduSendProvider,
|
||||
PduSenderInstance: PduSender,
|
||||
UserFaultHookInstance: UserFaultHook,
|
||||
Vfs: VirtualFilestore,
|
||||
RemoteConfigStoreInstance: RemoteConfigStore,
|
||||
@@ -251,7 +251,7 @@ pub struct SourceHandler<
|
||||
SequenceCounterInstance: SequenceCounter,
|
||||
> {
|
||||
local_cfg: LocalEntityConfig<UserFaultHookInstance>,
|
||||
pdu_sender: PduSender,
|
||||
pdu_sender: PduSenderInstance,
|
||||
pdu_and_cksum_buffer: RefCell<alloc::vec::Vec<u8>>,
|
||||
put_request_cacher: StaticPutRequestCacher,
|
||||
remote_cfg_table: RemoteConfigStoreInstance,
|
||||
@@ -271,7 +271,7 @@ pub struct SourceHandler<
|
||||
}
|
||||
|
||||
impl<
|
||||
PduSender: PduSendProvider,
|
||||
PduSenderInstance: PduSender,
|
||||
UserFaultHookInstance: UserFaultHook,
|
||||
Vfs: VirtualFilestore,
|
||||
RemoteConfigStoreInstance: RemoteConfigStore,
|
||||
@@ -280,7 +280,7 @@ impl<
|
||||
SequenceCounterInstance: SequenceCounter,
|
||||
>
|
||||
SourceHandler<
|
||||
PduSender,
|
||||
PduSenderInstance,
|
||||
UserFaultHookInstance,
|
||||
Vfs,
|
||||
RemoteConfigStoreInstance,
|
||||
@@ -314,7 +314,7 @@ impl<
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
cfg: LocalEntityConfig<UserFaultHookInstance>,
|
||||
pdu_sender: PduSender,
|
||||
pdu_sender: PduSenderInstance,
|
||||
vfs: Vfs,
|
||||
put_request_cacher: StaticPutRequestCacher,
|
||||
pdu_and_cksum_buf_size: usize,
|
||||
|
||||
Reference in New Issue
Block a user