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;
281 status = this->sCheckAndRespondNak(&nakProcessed);
309 return this->m_engine->
sendEof(
this);
340 *bytes_processed = 0;
356 FileSize max_data_bytes = bytes_to_read;
357 if (max_data_bytes > outgoing_file_chunk_size) {
358 max_data_bytes = outgoing_file_chunk_size;
360 if (max_data_bytes > maxDataCapacity) {
361 max_data_bytes = maxDataCapacity;
377 Os::File::Status fileStatus = this->m_fd.
read(fileDataBuffer, actual_bytes, Os::File::WaitType::WAIT);
396 static_cast<U16
>(actual_bytes),
400 status = this->m_engine->
sendFd(
this, fdPdu);
405 FW_ASSERT((foffs + actual_bytes) <= this->m_fsize, static_cast<FwAssertArgType>(foffs),
406 static_cast<FwAssertArgType>(actual_bytes), static_cast<FwAssertArgType>(this->m_fsize));
409 this->m_crc.
update(fileDataBuffer, foffs, static_cast<U32>(actual_bytes));
412 *bytes_processed =
static_cast<U32
>(actual_bytes);
420 Status::T status = this->sSendFileData(this->m_foffs, (this->m_fsize - this->m_foffs), 1, &bytes_processed);
436 }
else if (bytes_processed > 0) {
437 this->m_foffs += bytes_processed;
438 if (this->m_foffs == this->m_fsize) {
447 Status::T Transaction::sCheckAndRespondNak(
bool* nakProcessed) {
454 *nakProcessed =
false;
460 sret = this->m_engine->
sendMd(
this);
473 *nakProcessed =
true;
478 if (chunk !=
nullptr) {
479 ret = this->sSendFileData(chunk->
offset, chunk->
size, 0, &bytes_processed);
485 *nakProcessed =
true;
490 }
else if (bytes_processed > 0) {
492 *nakProcessed =
true;
502 bool nakProcessed =
false;
504 status = this->sCheckAndRespondNak(&nakProcessed);
524 if (
false == this->m_fd.
isOpen()) {
528 this->m_history->seq_num,
529 this->m_history->fnames.src_filename, fileStatus);
536 fileStatus = this->m_fd.
size(file_size);
537 this->m_fsize =
static_cast<FileSize>(file_size);
540 this->m_history->seq_num, fileStatus);
543 }
else if (this->m_fsize == 0) {
546 this->m_history->seq_num,
547 this->m_history->fnames.src_filename);
555 status = this->m_engine->
sendMd(
this);
559 this->m_history->seq_num);
567 this->m_history->fnames.src_filename, this->m_history->peer_eid, this->m_history->fnames.dst_filename,
568 static_cast<U32>(this->m_fsize));
588 static_cast<ConditionCode>(this->m_state_data.
send.
s2.
fin_cc),
589 this->m_history->peer_eid, this->m_history->seq_num);
604 this->m_history->seq_num);
629 static_cast<I32>(deserStatus));
636 if (!this->m_engine->
recvFin(
this, fin)) {
674 static_cast<I32>(deserStatus));
707 this->m_history->seq_num, bad_sr);
711 this->m_history->seq_num);
732 static_cast<I32>(deserStatus));
746 if (this->m_flags.
com.
canceled || this->m_flags.tx.fin_recv) {
767 selected_handler =
nullptr;
771 this->m_history->seq_num);
781 U8 directiveCodeByte;
788 if (substate_tbl !=
nullptr) {
789 selected_handler = substate_tbl->
fdirective[
static_cast<U32
>(directiveCode)];
793 this->
getClass(), this->m_history->
src_eid, this->m_history->seq_num, directiveCodeByte,
794 static_cast<U8>(this->m_state_data.send.sub_state));
806 if (selected_handler) {
807 (this->*selected_handler)(buffer);
815 if (selected_handler !=
nullptr) {
816 (this->*selected_handler)();
826 selected_handler = dispatch->
tx[
static_cast<U32
>(this->m_state)];
827 if (selected_handler !=
nullptr) {
828 (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.
bool s2DeserializeFin(const Fw::Buffer &pdu, FinPdu &fin)
Deserialize a received FIN PDU.
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
SerializeStatus setBuffLen(Serializable::SizeType length) override
Set buffer length manually.
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.
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 s2HandleFin(const FinPdu &fin)
S2 handling of a successfully deserialized 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