62 m_channels[i] =
nullptr;
70 if (m_channels[i] !=
nullptr) {
72 m_channels[i]->
cleanup(*m_allocator, m_allocatorId);
78 m_allocator->
deallocate(m_allocatorId, m_channels[i]);
79 m_channels[i] =
nullptr;
90 m_allocator = &allocator;
91 m_allocatorId = memId;
96 void* channelMem = allocator.
allocate(memId, channelSize);
100 m_channels[i] =
new (channelMem)
Channel(
this, i, this->m_manager, allocator, memId);
110 U32 timerDuration = 0;
127 txn->m_inactivity_timer.
setTimer(timerDuration);
133 bool needsDispatch =
true;
134 while (needsDispatch) {
135 needsDispatch =
false;
138 switch (txn->m_state) {
140 needsDispatch = this->recvInit(txn, buffer);
155 this->recvDrop(txn, buffer);
158 this->recvHold(txn, buffer);
186 static_cast<U8>(txn->m_state));
211 return serializeAndSendPdu(txn, md);
215 Status::T status = serializeAndSendPdu(txn, fdPdu);
254 return serializeAndSendPdu(txn, eof);
265 static_cast<U8>(dir_code));
297 return serializeAndSendPdu(txn, ack);
314 static_cast<FinFileStatus>(fs)
324 return serializeAndSendPdu(txn, fin);
332 return serializeAndSendPdu(txn, nakPdu);
337 return this->serializeAndSendPduOnChannel(*txn->m_chan, pdu);
340 Status::T Engine::serializeAndSendPduOnChannel(Channel& chan, PduBase& pdu) {
346 status = m_manager->
getPduBuffer(buffer, chan, bufferSize);
357 static_cast<I32
>(serStatus));
371 Status::T Engine::sendFinAckStateless(Channel& chan,
397 return this->serializeAndSendPduOnChannel(chan, ack);
474 void Engine::recvHold(Transaction* txn,
const Fw::Buffer& buffer) {
506 fin.getConditionCode(), txn->m_history->peer_eid, txn->m_history->seq_num);
513 bool Engine::recvInit(Transaction* txn,
const Fw::Buffer& buffer) {
522 Cfdp::PduHeader header;
527 EntityId sourceEid = header.getSourceEid();
528 Class::T txmMode = header.getTxmMode();
531 txn->m_history->seq_num = transactionSeq;
535 txn->m_history->peer_eid = sourceEid;
536 txn->m_history->src_eid = sourceEid;
539 if (txn->m_chunks ==
nullptr) {
542 if (txn->m_chunks ==
nullptr) {
573 txn->m_txn_class = txmMode;
574 txn->m_flags.rx.md_recv =
true;
578 static_cast<I32
>(deserStatus));
603 chan = m_channels[chan_id];
626 if (txn ==
nullptr) {
639 this->sendFinAckStateless(*chan, transactionSeq, sourceEid, destEid, fin.
getConditionCode());
651 if (txn ==
nullptr) {
659 if (txn !=
nullptr) {
661 this->dispatchRecv(txn, buffer);
684 Channel* chan = m_channels[channelId];
687 if (txn !=
nullptr) {
700 Channel* chan = m_channels[channelId];
703 if (txn !=
nullptr) {
704 this->cancelTransaction(txn);
716 Channel* chan = m_channels[channelId];
719 if (txn !=
nullptr) {
733 txn->
initTxFile(cfdp_class, keep, chan, priority);
739 txn->m_history->
seq_num = this->m_seqNum;
758 chan = m_channels[chan_num];
768 if (txn ==
nullptr) {
776 this->
txFileInitiate(txn, cfdp_class, keep, chan_num, priority, dest_id);
782 txn->m_initType = initType;
796 chan = m_channels[chan_num];
809 if (txn !=
nullptr) {
878 status = this->
playbackDirInitiate(pb, src_filename, dst_filename, cfdp_class, keep, chan, priority, dest_id);
998 if (
true == txn->m_fd.
isOpen()) {
1002 this->handleNotKeepFile(txn);
1006 if (txn->m_history !=
nullptr) {
1011 txn->m_txn_class, txn->m_history->
seq_num, txn->m_history->
src_eid,
1013 static_cast<U32>(txn->m_fsize));
1016 txn->m_txn_class, txn->m_history->
seq_num, txn->m_history->
src_eid,
1024 txn->m_txn_class, txn->m_history->
seq_num, txn->m_history->
src_eid,
1026 static_cast<U8>(txn->m_history->
txn_stat));
1029 txn->m_txn_class, txn->m_history->
seq_num, txn->m_history->
src_eid,
1031 static_cast<U8>(txn->m_history->
txn_stat));
1072 txn->m_history->
txn_stat = txn_stat;
1076 void Engine::cancelTransaction(
Transaction* txn) {
1088 (txn->*fns[
static_cast<U32
>(txn->m_history->
dir)])();
1094 bool return_code =
false;
1101 bool foundSlash =
false;
1103 if (src_file.
toChar()[pos] ==
'/') {
1110 src_dir.
format(
"%.*s", static_cast<int>(lastSlashPos), src_file.
toChar());
1115 if (src_dir == pd->srcDir) {
1124 void Engine::handleNotKeepFile(Transaction* txn) {
1134 if (moveDir.
length() > 0) {
1151 if (this->isPollingDir(txn->m_history->fnames.src_filename, txn->getChannelId())) {
1154 if (failDir.
length() > 0) {
void incrementSentPdu(U8 chanId)
Increment sent PDU counter.
Status::T recvFd(Transaction *txn, const FileDataPdu &pdu)
Unpack a file data PDU from a received message.
Serialization/Deserialization operation was successful.
CfdpTxnFilenames fnames
file names associated with this history entry
void s1Recv(const Fw::Buffer &buffer)
S1 receive PDU processing.
Status::T sendEof(Transaction *txn)
Create, encode, and send an EOF (End of File) PDU.
TransactionInitType
Transaction initiation method.
void sendFileComplete(Svc::SendFileStatus::T status)
void incrementRecvErrors(U8 chanId)
Increment receive error counter.
Fw::String dstDir
path to destination dir
U8 getChannelId() const
Get the channel ID.
Status::T txFile(const Fw::String &src, const Fw::String &dst, Class::T cfdp_class, Keep::T keep, U8 chan_num, U8 priority, EntityId dest_id, TransactionInitType initType=TransactionInitType::INIT_BY_COMMAND)
Begin transmit of a file.
virtual void * allocate(const FwEnumStoreType identifier, FwSizeType &size, bool &recoverable, FwSizeType alignment=alignof(std::max_align_t))=0
Status::T stopPollDir(U8 chanId, U8 pollId)
Stop polling a directory.
A variable-length serializable buffer.
~Channel()
Destruct a Channel.
void log_WARNING_LO_FailPollFileMove(const Fw::StringBase &srcFile, const Fw::StringBase &failDir, I32 status) const
Log event FailPollFileMove.
CFDP Transaction state machine class.
Status::T cancelTransactionBySeq(U8 channelId, TransactionSeq transactionSeq, EntityId entityId)
Cancel a transaction with graceful close-out.
PlatformSizeType FwSizeType
static Status moveFile(const char *sourcePath, const char *destPath)
Move a file from sourcePath to destPath.
void setSize(FwSizeType size)
U16 num_ts
number of transactions
void init(Fw::MemAllocator &allocator, FwEnumStoreType memId)
Initialize the CFDP engine.
State assigned to a newly allocated transaction object.
void rCancel()
Cancel an R transaction.
void initialize(PduDirection direction, Cfdp::Class::T txmMode, EntityId sourceEid, TransactionSeq transactionSeq, EntityId destEid, ConditionCode conditionCode, U32 checksum, FileSize fileSize)
Initialize an EOF PDU.
bool cmd_tx
indicates transaction is commanded (ground) tx
void recvMd(Transaction *txn, const MetadataPdu &pdu)
Handle receipt of metadata PDU.
U32 EntityId
Entity id size.
first one on this list is active
void r2Recv(const Fw::Buffer &buffer)
R2 receive PDU processing.
void initialize(PduDirection direction, Cfdp::Class::T txmMode, EntityId sourceEid, TransactionSeq transactionSeq, EntityId destEid, FileDirective directiveCode, U8 directiveSubtypeCode, ConditionCode conditionCode, AckTxnStatus transactionStatus)
Initialize an ACK PDU.
void log_WARNING_LO_InvalidDestinationEid(U32 destEid) const
Log event InvalidDestinationEid.
void s2Tx()
S2 dispatch function.
void disableTimer(void)
Disables a CFDP timer.
void log_WARNING_LO_TxFileTransferFailed(const Svc::Ccsds::Cfdp::Class &cfdpClass, U32 seqNum, U32 srcEid, const Fw::StringBase &srcFile, U32 destEid, const Fw::StringBase &destFile, U8 conditionCode) const
Log event TxFileTransferFailed.
ConditionCode getConditionCode() const
Get condition code.
bool appendTlv(const Tlv &tlv)
U8 priority
priority to use when placing transactions on the pending queue
virtual const CHAR * toChar() const =0
Convert to a C-style char*.
void log_WARNING_LO_ChunklistUnavailable(U32 transactionSeq) const
Log event ChunklistUnavailable.
Fw::String getFailDirParam(U8 channelIndex)
const Tlv & getTlv(U8 index) const
Deserialization data had incorrect values (unexpected data types)
void incrementFaultDirectoryRead(U8 chanId)
Increment fault directory read counter.
CFDP class 2 - Reliable transfer (Acknowledged)
CFDP class 1 - Unreliable transfer (Unacknowledged)
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 incrementRecvDropped(U8 chanId)
Increment receive dropped counter.
void processPollingDirectories()
Process all polling directories for this channel.
void sendPduBuffer(Channel &channel, Fw::Buffer &pduBuffer)
U32 intervalSec
number of seconds to wait before trying a new directory
TxnStatus
Values for Transaction Status code.
Status::T startPollDir(U8 chanId, U8 pollId, const Fw::String &srcDir, const Fw::String &dstDir, Class::T cfdp_class, U8 priority, EntityId destEid, U32 intervalSec)
Start polling a directory.
void s2Recv(const Fw::Buffer &buffer)
S2 receive PDU processing.
void log_ACTIVITY_HI_TxFileTransferCompleted(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 TxFileTransferCompleted.
bool appendTlv(const Tlv &tlv)
void incrementCmdTxCounter()
Increment the command TX counter for this channel.
SerializeStatus
forward declaration for string
void incrementRecvSpurious(U8 chanId)
Increment receive spurious counter.
void log_ACTIVITY_LO_MetadataReceived(const Fw::StringBase &srcFile, const Fw::StringBase &destFile, U32 transactionSeq) const
Log event MetadataReceived.
void finishTransaction(Transaction *txn, bool keep_history)
Finish a transaction.
U32 TransactionSeq
transaction sequence number size
Flow::T getFlowState() const
Get the flow state for this channel.
void returnPduBuffer(Channel &channel, Fw::Buffer &pduBuffer)
State assigned to a transaction after freeing it.
void log_WARNING_LO_MaxTxTransactionsReached() const
Log event MaxTxTransactionsReached.
U8 getChannelId() const
Get channel ID.
bool keep_history
whether history should be preserved during recycle
void cycleTx()
Cycle the TX side of this channel.
virtual ~Engine()
Destroy the Engine object.
The type of a File Data PDU.
void setChannelFlowState(U8 channelId, Flow::T flowState)
Set channel flow state.
Fw::SerializeStatus deserializeFrom(Fw::SerialBufferBase &buffer, Fw::Endianness mode=Fw::Endianness::BIG) override
Fw::Serializable interface - deserialize from buffer.
Status::T sendNak(Transaction *txn, NakPdu &nakPdu)
Encode and send a NAK (Negative Acknowledgment) PDU.
Engine(CfdpManager *manager)
Construct a new Engine object.
Status::T getPduBuffer(Fw::Buffer &buffer, Channel &channel, FwSizeType size)
void log_WARNING_LO_FileDataSegmentMetadata() const
Log event FileDataSegmentMetadata.
void resetOutgoingCounter()
Reset the outgoing PDU counter to zero.
virtual Status::T sendMd(Transaction *txn)
Create, encode, and send a Metadata PDU.
void receivePdu(U8 chan_id, const Fw::Buffer &buffer)
Receive and process a PDU.
void log_WARNING_LO_RxFileTransferFailed(const Svc::Ccsds::Cfdp::Class &cfdpClass, U32 seqNum, U32 srcEid, const Fw::StringBase &srcFile, U32 destEid, const Fw::StringBase &destFile, U8 conditionCode) const
Log event RxFileTransferFailed.
Status::T recvNak(Transaction *txn, const NakPdu &pdu)
Unpack a NAK PDU from a received message.
void armInactTimer(Transaction *txn)
Arm the inactivity timer for a transaction.
void clearCurrentIfMatch(Transaction *txn)
Check if current transaction matches and clear if so.
ConditionCode TxnStatusToConditionCode(TxnStatus txn_stat)
Converts the internal transaction status to a CFDP condition code.
History * getHistory() const
Get transaction history.
void s1Tx()
S1 dispatch function.
void tickTransactions()
Tick all transactions on this channel.
Direction dir
direction of this history entry
void dequeueTransaction(Transaction *txn)
Free a transaction from the queue it's on.
The type of a Finished PDU.
void dispatchTx(Transaction *txn)
Dispatch TX state machine for a transaction.
void setTimer(U32 timerDuration)
Initialize a CFDP timer and start its execution.
U16 getDataSize() const
Get the data size.
void incrementRecvPdu(U8 chanId)
Increment received PDU counter.
void txFileInitiate(Transaction *txn, Class::T cfdp_class, Keep::T keep, U8 chan, U8 priority, EntityId dest_id)
Initiate a file transfer transaction.
void setTxnStatus(Transaction *txn, TxnStatus txn_stat)
Helper function to store transaction status code only.
void close() override
close the file, if not opened then do nothing
Generic CFDP error return code.
const TlvList & getTlvList() const
Get TLV list.
Status::T sendFd(Transaction *txn, FileDataPdu &fdPdu)
Encode and send a File Data PDU.
void incrementSentEofCanceled(U8 chanId)
Increment sent EOF canceled counter.
const char * toChar() const
Convert to a C-style char*.
void addSentFileDataBytes(U8 chanId, U32 bytes)
Add sent file data bytes.
U32 getValue() const
Get the checksum value.
Status::T playbackDirInitiate(Playback *pb, const Fw::String &src_filename, const Fw::String &dst_filename, Class::T cfdp_class, Keep::T keep, U8 chan, U8 priority, EntityId dest_id)
Initiate playback of a directory.
Fw::String srcDir
path to source dir
const TlvList & getTlvList() const
Get TLV list.
void decrementCmdTxCounter()
Decrement the command TX counter for this channel.
FormatStatus format(const CHAR *formatString,...)
write formatted string to buffer
void log_WARNING_LO_RxTransactionLimitReached(U32 srcEid, U32 transactionSeq) const
Log event RxTransactionLimitReached.
void log_WARNING_LO_FailKeepFileMove(const Fw::StringBase &srcFile, const Fw::StringBase &moveDir, I32 status) const
Log event FailKeepFileMove.
uint8_t U8
8-bit unsigned integer
void processPlaybackDirectories()
Process all playback directories for this channel.
CFDP operation has been successful.
void insertSortPrio(Transaction *txn, QueueId::T queue)
Insert a transaction into a priority sorted transaction queue.
EntityId getLocalEidParam(void)
FwSizeType getSize() const
U32 getAckTimerParam(U8 channelIndex)
Cfdp::ChannelTelemetry & getChannelTelemetryRef(U8 channelId)
Get reference to channel telemetry for Channel class.
U32 getInactivityTimerParam(U8 channelIndex)
State where all PDUs are dropped.
Transaction * findUnusedTransaction(Direction direction)
Find an unused transaction on this channel.
Class::T getClass() const
Get transaction class (CLASS_1 or CLASS_2)
static constexpr FwSizeType PACKET_DESCRIPTOR_SIZE
Size of packet descriptor prepended to PDUs for ComQueue.
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 initialize(PduDirection direction, Cfdp::Class::T txmMode, EntityId sourceEid, TransactionSeq transactionSeq, EntityId destEid, ConditionCode conditionCode, FinDeliveryCode deliveryCode, FinFileStatus fileStatus)
Initialize a Finished PDU.
void cycle()
Cycle the engine once per scheduler call.
void cleanup(Fw::MemAllocator &allocator, FwEnumStoreType memId)
Clean up dynamically allocated resources.
Memory Allocation base class.
CFDP channel operations are executing nominally.
void log_ACTIVITY_LO_TxFileQueued(const Fw::StringBase &sourceFileName, U32 transactionSeq) const
Log event TxFileQueued.
void log_WARNING_LO_PlaybackDirSlotUnavailable() const
Log event PlaybackDirSlotUnavailable.
void insertBackInQueue(QueueId::T queueidx, CListNode *node)
Insert a node at the back of a channel queue.
void log_WARNING_LO_UnhandledPduInIdleState() const
Log event UnhandledPduInIdleState.
Class::T cfdpClass
the CFDP class to send
Status::T recvFin(Transaction *txn, const FinPdu &pdu)
Unpack an FIN PDU from a received message.
Operation was successful.
PduTypeEnum::T peekPduType(const Fw::Buffer &buffer)
Transaction initiated via port interface.
void sCancel()
Cancel an S transaction.
Fw::Enabled enabled
Enabled flag.
void log_WARNING_LO_FailPduSerialization(U8 channelId, const Svc::Ccsds::Cfdp::PduTypeEnum &pduType, I32 status) const
Log event FailPduSerialization.
void incrementFaultTxEofError(U8 chanId)
Increment sent EOF error counter (any condition code that is not no-error or cancel) ...
void log_ACTIVITY_HI_RxFileTransferCompleted(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 RxFileTransferCompleted.
CfdpFlagsTx tx
applies to only send file transactions
Status open(const char *path, OpenMode mode) override
Open or create a directory.
Transaction * findTransactionBySequenceNumber(TransactionSeq transaction_sequence_number, EntityId src_eid)
Finds an active transaction by sequence number.
Timer intervalTimer
Timer object used to poll the directory.
Structure for the telemetry array of CFDP channels.
RateGroupDivider component implementation.
CfdpPollDir * getPollDir(U32 index)
Get a polling directory entry.
virtual SizeType length() const
Get the length of the string.
U32 getNumCmdTx() const
Get the number of commanded TX transactions.
CfdpFlagsCommon com
applies to all transactions
Status::T setSuspendResumeTransaction(U8 channelId, TransactionSeq transactionSeq, EntityId entityId, SuspendResume::T action)
Set transaction suspend state.
TxnStatus txn_stat
final status of operation
Operation was successful.
void log_WARNING_LO_FileRemoveFailed(const Fw::StringBase &filename, I32 status) const
Log event FileRemoveFailed.
void txStateDispatch(const TxnSendDispatchTable *dispatch)
Top-level Dispatch function to send a PDU based on current state.
void log_WARNING_LO_PlaybackDirOpenFailed(const Fw::StringBase &directory, I32 status) const
Log event PlaybackDirOpenFailed.
EntityId src_eid
the source eid of the transaction
Fw::String getMoveDirParam(U8 channelIndex)
virtual void deallocate(const FwEnumStoreType identifier, void *ptr)=0
A table of transmit handler functions based on transaction state.
Status::T sendFin(Transaction *txn, FinDeliveryCode dc, FinFileStatus fs, ConditionCode cc)
Create, encode, and send a FIN (Finished) PDU.
Cfdp::ChannelTelemetry & getChannelTelemetryRef(U8 chanId)
Get reference to channel telemetry for queue depth updates.
SerializeStatus setBuffLen(Serializable::SizeType length) override
Set buffer length manually.
void log_WARNING_LO_PollDirNotActive(U8 channelId, U8 pollId) const
Log event PollDirNotActive.
Status::T abandonTransaction(U8 channelId, TransactionSeq transactionSeq, EntityId entityId)
Abandon a transaction immediately.
void log_WARNING_LO_FailPduHeaderDeserialization(U8 channelId, I32 status) const
Log event FailPduHeaderDeserialization.
CfdpRxStateData receive
applies to only receive file transactions
void log_DIAGNOSTIC_ResetFreedTransaction() const
Log event ResetFreedTransaction.
EntityId destEid
destination entity id
U8 q_index
Q index this is in.
AckTxnStatus GetTxnStatus(Transaction *txn)
Gets the status of this transaction.
void log_WARNING_LO_PollDirBusy(U8 channelId, U8 pollId) const
Log event PollDirBusy.
void setFlowState(Flow::T flowState)
Set the flow state for this channel.
void armAckTimer(Transaction *txn)
Arm the ACK timer for a transaction.
Status::T playbackDir(const Fw::String &src, const Fw::String &dst, Class::T cfdp_class, Keep::T keep, U8 chan, U8 priority, EntityId dest_id)
Begin transmit of a directory.
void log_DIAGNOSTIC_TxLateFinAcked(Svc::Ccsds::Cfdp::EntityId srcEid, Svc::Ccsds::Cfdp::TransactionSeq seqNum) const
const PduHeader & asHeader() const
Get this as a Header.
static Status removeFile(const char *path)
Remove a file at the specified path.
bool isOpen() const
determine if the file is open
bool TxnStatusIsError(TxnStatus txn_stat)
Check if the internal transaction status represents an error.
Playback * getPlayback(U32 index)
Get a playback directory entry.
void r1Recv(const Fw::Buffer &buffer)
R1 receive PDU processing.
Error if directory doesn't exist.
void initialize(EntityId eid)
void log_WARNING_LO_FailFinPduDeserialization(U8 channelId, I32 status) const
Log event FailFinPduDeserialization.
EntityId peer_eid
peer_eid is always the "other guy", same src_eid for RX
void log_WARNING_LO_FailMetadataPduDeserialization(U8 channelId, I32 status) const
Log event FailMetadataPduDeserialization.
Status::T recvEof(Transaction *txn, const EofPdu &pdu)
Unpack an EOF PDU from a received message.