60 FileDirectiveDispatchTable table = {};
61 memset(&table, 0,
sizeof(table));
104 m_priority = priority;
106 m_txn_class = cfdp_class;
142 if (this->m_ack_timer.
getStatus() == Timer::Status::RUNNING) {
143 this->m_ack_timer.
run();
149 this->m_history->seq_num);
163 if (!this->m_flags.
tx.
eof_ack_recv && !this->m_flags.tx.fin_recv) {
189 if (this->m_inactivity_timer.
getStatus() == Timer::Status::RUNNING) {
190 this->m_inactivity_timer.
run();
192 if (this->m_inactivity_timer.
getStatus() == Timer::Status::EXPIRED) {
201 this->m_history->seq_num);
218 pending_send =
false;
226 pending_send =
false;
229 pending_send =
false;
247 bool retries_exhausted =
false;
250 this->m_cfdpManager->getPostInactivitySendRetriesParam()) {
251 retries_exhausted =
true;
256 bool should_recycle = this->m_flags.
com.
inactivity_fired && (!pending_send || retries_exhausted);
258 if (should_recycle) {
274 bool nakProcessed =
false;
279 status = this->sCheckAndRespondNak(&nakProcessed);
307 return this->m_engine->
sendEof(
this);
338 *bytes_processed = 0;
354 FileSize max_data_bytes = bytes_to_read;
355 if (max_data_bytes > outgoing_file_chunk_size) {
356 max_data_bytes = outgoing_file_chunk_size;
358 if (max_data_bytes > maxDataCapacity) {
359 max_data_bytes = maxDataCapacity;
375 Os::File::Status fileStatus = this->m_fd.
read(fileDataBuffer, actual_bytes, Os::File::WaitType::WAIT);
394 static_cast<U16
>(actual_bytes),
398 status = this->m_engine->
sendFd(
this, fdPdu);
403 FW_ASSERT((foffs + actual_bytes) <= this->m_fsize, static_cast<FwAssertArgType>(foffs),
404 static_cast<FwAssertArgType>(actual_bytes), static_cast<FwAssertArgType>(this->m_fsize));
407 this->m_crc.
update(fileDataBuffer, foffs, static_cast<U32>(actual_bytes));
410 *bytes_processed =
static_cast<U32
>(actual_bytes);
418 Status::T status = this->sSendFileData(this->m_foffs, (this->m_fsize - this->m_foffs), 1, &bytes_processed);
434 }
else if (bytes_processed > 0) {
435 this->m_foffs += bytes_processed;
436 if (this->m_foffs == this->m_fsize) {
445 Status::T Transaction::sCheckAndRespondNak(
bool* nakProcessed) {
452 *nakProcessed =
false;
458 sret = this->m_engine->
sendMd(
this);
467 *nakProcessed =
true;
472 if (chunk !=
nullptr) {
473 ret = this->sSendFileData(chunk->
offset, chunk->
size, 0, &bytes_processed);
477 }
else if (bytes_processed > 0) {
479 *nakProcessed =
true;
489 bool nakProcessed =
false;
491 status = this->sCheckAndRespondNak(&nakProcessed);
511 if (
false == this->m_fd.
isOpen()) {
515 this->m_history->seq_num,
516 this->m_history->fnames.src_filename, fileStatus);
523 fileStatus = this->m_fd.
size(file_size);
524 this->m_fsize =
static_cast<FileSize>(file_size);
527 this->m_history->seq_num, fileStatus);
530 }
else if (this->m_fsize == 0) {
533 this->m_history->seq_num,
534 this->m_history->fnames.src_filename);
542 status = this->m_engine->
sendMd(
this);
546 this->m_history->seq_num);
554 this->m_history->fnames.src_filename, this->m_history->peer_eid, this->m_history->fnames.dst_filename,
555 static_cast<U32>(this->m_fsize));
572 static_cast<ConditionCode>(this->m_state_data.
send.
s2.
fin_cc),
573 this->m_history->peer_eid, this->m_history->seq_num);
580 this->m_history->seq_num);
600 static_cast<I32>(deserStatus));
604 if (!this->m_engine->
recvFin(
this, fin)) {
642 static_cast<I32>(deserStatus));
675 this->m_history->seq_num, bad_sr);
679 this->m_history->seq_num);
700 static_cast<I32>(deserStatus));
714 if (this->m_flags.
com.
canceled || this->m_flags.tx.fin_recv) {
735 selected_handler =
nullptr;
739 this->m_history->seq_num);
749 U8 directiveCodeByte;
756 if (substate_tbl !=
nullptr) {
757 selected_handler = substate_tbl->
fdirective[
static_cast<U32
>(directiveCode)];
761 this->
getClass(), this->m_history->
src_eid, this->m_history->seq_num, directiveCodeByte,
762 static_cast<U8>(this->m_state_data.send.sub_state));
774 if (selected_handler) {
775 (this->*selected_handler)(buffer);
783 if (selected_handler !=
nullptr) {
784 (this->*selected_handler)();
794 selected_handler = dispatch->
tx[
static_cast<U32
>(this->m_state)];
795 if (selected_handler !=
nullptr) {
796 (this->*selected_handler)();
Serialization/Deserialization operation was successful.
CfdpTxnFilenames fnames
file names associated with this history entry
const FileDirectiveDispatchTable * substate[static_cast< U32 >(TxSubState::TX_SUB_STATE_NUM_STATES)]
void s1Recv(const Fw::Buffer &buffer)
S1 receive PDU processing.
void s2EofAck(const Fw::Buffer &pdu)
S2 received ACK PDU.
Status::T sendEof(Transaction *txn)
Create, encode, and send an EOF (End of File) PDU.
void incrementRecvErrors(U8 chanId)
Increment receive error counter.
void sAckTimerTick()
Perform acknowledgement timer tick (time-based) processing for S transactions.
A variable-length serializable buffer.
void log_WARNING_LO_FailAckPduDeserialization(U8 channelId, I32 status) const
Log event FailAckPduDeserialization.
void s2Fin(const Fw::Buffer &pdu)
S2 received FIN, so set flag to send FIN-ACK.
void log_WARNING_LO_TxFileSeekFailed(const Svc::Ccsds::Cfdp::Class &cfdpClass, U32 srcEid, U32 seqNum, I32 status) const
Log event TxFileSeekFailed.
Segment request structure for NAK PDU.
void addRecvNakSegmentRequests(U8 chanId, U32 count)
Add to received NAK segment requests.
PlatformSizeType FwSizeType
void sDispatchTransmit(const SSubstateSendDispatchTable *dispatch)
Dispatch function to send/generate PDUs on send-file transactions.
void setCurrentTxn(const Transaction *txn)
Set current transaction.
void log_WARNING_LO_TxSendMetadataFailed(const Svc::Ccsds::Cfdp::Class &cfdpClass, U32 srcEid, U32 seqNum) const
Log event TxSendMetadataFailed.
StateSendFunc tx[static_cast< U32 >(TxnState::TXN_STATE_INVALID)]
Transmit handler function.
U8 getNumSegments() const
Get number of segments.
void log_WARNING_LO_TxInactivityTimeout(const Svc::Ccsds::Cfdp::Class &cfdpClass, U32 srcEid, U32 seqNum) const
Log event TxInactivityTimeout.
void sSubstateSendFileData()
Standard state function to send the next file data PDU for active transaction.
void removeFromFirst(FileSize size)
Remove a specified size from the first chunk.
void s2Tx()
S2 dispatch function.
void sTickNak(I32 *cont)
Perform NAK response for TX transactions.
void log_WARNING_LO_TxAckLimitReached(const Svc::Ccsds::Cfdp::Class &cfdpClass, U32 srcEid, U32 seqNum) const
Log event TxAckLimitReached.
Status size(FwSizeType &size_result) override
get size of currently open file
ConditionCode getConditionCode() const
Get condition code.
CfdpChunkList chunks
Chunk list for gap tracking.
CFDP class 2 - Reliable transfer (Acknowledged)
StateRecvFunc fdirective[static_cast< U32 >(FileDirective::FILE_DIRECTIVE_INVALID_MAX)]
a separate recv handler for each possible file directive PDU in this state
void s2NakArm(const Fw::Buffer &pdu)
S2 NAK handling but with arming the NAK timer.
U8 post_inactivity_send_retries
terminal-send retries attempted after inactivity fired
Status::T sendAck(Transaction *txn, AckTxnStatus ts, FileDirective dir_code, ConditionCode cc, EntityId peer_eid, TransactionSeq tsn)
Create, encode, and send an ACK (Acknowledgment) PDU.
void s2Recv(const Fw::Buffer &buffer)
S2 receive PDU processing.
A dispatch table for send file transactions, receive side.
void s2EarlyFin(const Fw::Buffer &pdu)
A FIN was received before file complete, so abandon the transaction.
SerializeStatus
forward declaration for string
void log_WARNING_LO_TxInvalidSegmentRequests(const Svc::Ccsds::Cfdp::Class &cfdpClass, U32 srcEid, U32 seqNum, U32 badCount) const
Log event TxInvalidSegmentRequests.
FileSize size
The size of the chunk.
FileDirective getDirectiveCode() const
Get directive code.
void finishTransaction(Transaction *txn, bool keep_history)
Finish a transaction.
Os::FileInterface::Status open(const char *path, Mode mode)
open file with supplied path and mode
A dispatch table for send file transactions, transmit side.
State assigned to a transaction after freeing it.
U8 getChannelId() const
Get channel ID.
void incrementFaultFileSeek(U8 chanId)
Increment fault file seek counter.
U8 getAckLimitParam(U8 channelIndex)
void add(FileSize offset, FileSize size)
Add a chunk (file segment) to the list.
Status getStatus(void)
Get the status of a CFDP timer.
void s1SubstateSendEof()
Sends an EOF for S1.
The type of a File Data PDU.
void log_WARNING_LO_TxZeroLengthFile(const Svc::Ccsds::Cfdp::Class &cfdpClass, U32 srcEid, U32 seqNum, const Fw::StringBase &filename) const
Log event TxZeroLengthFile.
Fw::SerializeStatus deserializeFrom(Fw::SerialBufferBase &buffer, Fw::Endianness mode=Fw::Endianness::BIG) override
Fw::Serializable interface - deserialize from buffer.
void log_ACTIVITY_HI_TxFileTransferStarted(const Svc::Ccsds::Cfdp::Class &cfdpClass, U32 seqNum, U32 srcEid, const Fw::StringBase &srcFile, U32 destEid, const Fw::StringBase &destFile, U32 fileSize) const
Log event TxFileTransferStarted.
void incrementFaultFileOpen(U8 chanId)
Increment fault file open counter.
virtual Status::T sendMd(Transaction *txn)
Create, encode, and send a Metadata PDU.
Status seek(FwSignedSizeType offset, SeekType seekType) override
seek the file pointer to the given offset
FileSize offsetEnd
End offset of missing data.
Status::T recvNak(Transaction *txn, const NakPdu &pdu)
Unpack a NAK PDU from a received message.
void log_WARNING_LO_TxInvalidNakPdu(const Svc::Ccsds::Cfdp::Class &cfdpClass, U32 srcEid, U32 seqNum) const
Log event TxInvalidNakPdu.
void sDispatchRecv(const Fw::Buffer &buffer, const SSubstateRecvDispatchTable *dispatch)
Dispatch function for received PDUs on send-file transactions.
StateSendFunc substate[static_cast< U32 >(TxSubState::TX_SUB_STATE_NUM_STATES)]
void s2SubstateSendEof()
Triggers tick processing to send an EOF and wait for EOF-ACK for S2.
void s1Tx()
S1 dispatch function.
void dequeueTransaction(Transaction *txn)
Free a transaction from the queue it's on.
The type of a Finished PDU.
void setTxnStatus(Transaction *txn, TxnStatus txn_stat)
Helper function to store transaction status code only.
Generic CFDP error return code.
void update(const U8 *const data, const U32 offset, const U32 length)
Status::T sendFd(Transaction *txn, FileDataPdu &fdPdu)
Encode and send a File Data PDU.
void incrementFaultInactivityTimer(U8 chanId)
Increment fault inactivity timer counter.
CfdpTxStateData send
applies to only send file transactions
FileSize offset
The start offset of the chunk within the file.
const char * toChar() const
Convert to a C-style char*.
void s2SubstateSendFileData()
Send filedata handling for S2.
void(Transaction::*)() StateSendFunc
A member function pointer for dispatching actions to a handler, without existing PDU data...
void log_WARNING_LO_TxNonFileDirectivePduReceived(const Svc::Ccsds::Cfdp::Class &cfdpClass, U32 srcEid, U32 seqNum) const
Log event TxNonFileDirectivePduReceived.
U32 FileSize
File size and offset type.
uint8_t U8
8-bit unsigned integer
CFDP operation has been successful.
void insertSortPrio(Transaction *txn, QueueId::T queue)
Insert a transaction into a priority sorted transaction queue.
Status read(U8 *buffer, FwSizeType &size)
read data from this file into supplied buffer bounded by size
void sTick(I32 *cont)
Perform tick (time-based) processing for S transactions.
EntityId getLocalEidParam(void)
FwSizeType getSize() const
FileSize offsetStart
Start offset of missing data.
void sSubstateSendMetadata()
Send metadata PDU.
Class::T getClass() const
Get transaction class (CLASS_1 or CLASS_2)
TransactionSeq seq_num
transaction identifier, stays constant for entire transfer
void initTxFile(Class::T cfdp_class, Keep::T keep, U8 chan, U8 priority)
Initialize transaction for outgoing file transfer.
void log_WARNING_LO_TxFileOpenFailed(const Svc::Ccsds::Cfdp::Class &cfdpClass, U32 srcEid, U32 seqNum, const Fw::StringBase &filename, I32 status) const
Log event TxFileOpenFailed.
void log_WARNING_LO_TxInvalidDirectiveCode(const Svc::Ccsds::Cfdp::Class &cfdpClass, U32 srcEid, U32 seqNum, U8 directiveCode, U8 substate) const
Log event TxInvalidDirectiveCode.
Operation was successful.
Fw::SerializeStatus deserializeFrom(Fw::SerialBufferBase &buffer, Fw::Endianness mode=Fw::Endianness::BIG) override
Fw::Serializable interface - deserialize from buffer.
Status::T recvFin(Transaction *txn, const FinPdu &pdu)
Unpack an FIN PDU from a received message.
void run(void)
Runs a one second increment of the CFDP timers.
PduTypeEnum::T peekPduType(const Fw::Buffer &buffer)
U32 getOutgoingFileChunkSizeParam(void)
void sCancel()
Cancel an S transaction.
CfdpFlagsTx tx
applies to only send file transactions
bool inactivity_fired
set whenever the inactivity timeout expires
Marker value for the highest possible state number.
RateGroupDivider component implementation.
CfdpFlagsCommon com
applies to all transactions
A table of receive handler functions based on file directive code.
void txStateDispatch(const TxnSendDispatchTable *dispatch)
Top-level Dispatch function to send a PDU based on current state.
EntityId src_eid
the source eid of the transaction
const Chunk * getFirstChunk() const
Get the first chunk in the list.
A table of transmit handler functions based on transaction state.
SerializeStatus setBuffLen(Serializable::SizeType length) override
Set buffer length manually.
void incrementFaultFileSizeMismatch(U8 chanId)
Increment fault file size mismatch counter.
const SegmentRequest & getSegment(U8 index) const
Get segment at index (no bounds checking - caller must verify index < getNumSegments()) ...
AckTxnStatus GetTxnStatus(Transaction *txn)
Gets the status of this transaction.
Send PDU: No send buffer available, throttling limit reached.
Fw::SerializeStatus deserializeFrom(Fw::SerialBufferBase &buffer, Fw::Endianness mode=Fw::Endianness::BIG) override
Fw::Serializable interface - deserialize from buffer.
void initialize(PduDirection direction, Cfdp::Class::T txmMode, EntityId sourceEid, TransactionSeq transactionSeq, EntityId destEid, FileSize offset, U16 dataSize, const U8 *data)
Initialize a File Data PDU.
U8 fin_cc
remember the cc in the received FIN PDU to echo in eof-fin
void(Transaction::*)(const Fw::Buffer &buffer) StateRecvFunc
A member function pointer for dispatching actions to a handler, with existing PDU data...
void armAckTimer(Transaction *txn)
Arm the ACK timer for a transaction.
void recycleTransaction(Transaction *txn)
Recover resources associated with a transaction.
void s2Nak(const Fw::Buffer &pdu)
S2 NAK PDU received handling.
void incrementFaultAckLimit(U8 chanId)
Increment fault ACK limit counter.
bool isOpen() const
determine if the file is open
void log_WARNING_LO_TxEarlyFinReceived(const Svc::Ccsds::Cfdp::Class &cfdpClass, U32 srcEid, U32 seqNum) const
Log event TxEarlyFinReceived.
void log_WARNING_LO_FailFinPduDeserialization(U8 channelId, I32 status) const
Log event FailFinPduDeserialization.
Pairs an offset with a size to identify a specific piece of a file.
void log_WARNING_LO_FailNakPduDeserialization(U8 channelId, I32 status) const
Log event FailNakPduDeserialization.
EntityId peer_eid
peer_eid is always the "other guy", same src_eid for RX