diff --git a/src/fsfw/cfdp/VarLenFields.h b/src/fsfw/cfdp/VarLenFields.h index 2b862d666..7f369e0c1 100644 --- a/src/fsfw/cfdp/VarLenFields.h +++ b/src/fsfw/cfdp/VarLenFields.h @@ -74,6 +74,7 @@ struct TransactionSeqNum : public VarLenField { }; struct TransactionId { + TransactionId() = default; TransactionId(EntityId entityId, TransactionSeqNum seqNum) : entityId(std::move(entityId)), seqNum(std::move(seqNum)) {} diff --git a/src/fsfw/cfdp/handler/DestHandler.cpp b/src/fsfw/cfdp/handler/DestHandler.cpp index 2d5c6aa02..aefa1aa37 100644 --- a/src/fsfw/cfdp/handler/DestHandler.cpp +++ b/src/fsfw/cfdp/handler/DestHandler.cpp @@ -3,14 +3,19 @@ #include #include "fsfw/cfdp/pdu/HeaderReader.h" -#include "fsfw/cfdp/pdu/MetadataPduReader.h" #include "fsfw/objectmanager.h" #include "fsfw/serviceinterface.h" using namespace returnvalue; cfdp::DestHandler::DestHandler(DestHandlerParams params, FsfwParams fsfwParams) - : dp(std::move(params)), fp(fsfwParams), tlvVec(params.maxTlvsInOnePdu) {} + : tlvVec(params.maxTlvsInOnePdu), + userTlvVec(params.maxTlvsInOnePdu), + dp(std::move(params)), + fp(fsfwParams), + tp(params.maxFilenameLen) { + tp.pduConf.direction = cfdp::Direction::TOWARDS_SENDER; +} ReturnValue_t cfdp::DestHandler::performStateMachine() { switch (step) { @@ -73,10 +78,9 @@ ReturnValue_t cfdp::DestHandler::handleMetadataPdu(const PacketInfo& info) { // TODO: This is not a CFDP error. Event and/or warning? return constAccessorPair.first; } - cfdp::FileSize fileSize; cfdp::StringLv sourceFileName; cfdp::StringLv destFileName; - MetadataInfo metadataInfo(fileSize, sourceFileName, destFileName); + MetadataInfo metadataInfo(tp.fileSize, sourceFileName, destFileName); cfdp::Tlv* tlvArrayAsPtr = tlvVec.data(); metadataInfo.setOptionsArray(&tlvArrayAsPtr, std::nullopt, tlvVec.size()); MetadataPduReader reader(constAccessorPair.second.data(), constAccessorPair.second.size(), @@ -89,7 +93,7 @@ ReturnValue_t cfdp::DestHandler::handleMetadataPdu(const PacketInfo& info) { return handleMetadataParseError(constAccessorPair.second.data(), constAccessorPair.second.size()); } - return result; + return startTransaction(reader, metadataInfo); } ReturnValue_t cfdp::DestHandler::handleMetadataParseError(const uint8_t* rawData, size_t maxSize) { @@ -126,3 +130,44 @@ ReturnValue_t cfdp::DestHandler::handleMetadataParseError(const uint8_t* rawData // TODO: Appropriate returnvalue? return returnvalue::FAILED; } + +ReturnValue_t cfdp::DestHandler::startTransaction(MetadataPduReader& reader, MetadataInfo& info) { + if (cfdpState != CfdpStates::IDLE) { + // According to standard, discard metadata PDU if we are busy + return returnvalue::OK; + } + step = TransactionStep::TRANSACTION_START; + if (reader.getTransmissionMode() == TransmissionModes::UNACKNOWLEDGED) { + cfdpState = CfdpStates::BUSY_CLASS_1_NACKED; + } else if (reader.getTransmissionMode() == TransmissionModes::ACKNOWLEDGED) { + cfdpState = CfdpStates::BUSY_CLASS_2_ACKED; + } + tp.checksumType = info.getChecksumType(); + tp.closureRequested = info.isClosureRequested(); + size_t sourceNameSize = 0; + const uint8_t* sourceNamePtr = info.getSourceFileName().getValue(&sourceNameSize); + if (sourceNameSize > tp.sourceName.size()) { + // TODO: Warning, event etc. + return FAILED; + } + std::memcpy(tp.sourceName.data(), sourceNamePtr, sourceNameSize); + tp.sourceName[sourceNameSize] = '\0'; + size_t destNameSize = 0; + const uint8_t* destNamePtr = info.getDestFileName().getValue(&destNameSize); + if (destNameSize > tp.destName.size()) { + // TODO: Warning, event etc. + return FAILED; + } + std::memcpy(tp.destName.data(), destNamePtr, destNameSize); + tp.destName[destNameSize] = '\0'; + reader.fillConfig(tp.pduConf); + tp.pduConf.direction = Direction::TOWARDS_SENDER; + tp.transactionId.entityId = tp.pduConf.sourceId; + tp.transactionId.seqNum = tp.pduConf.seqNum; + if (not dp.remoteCfgTable.getRemoteCfg(tp.pduConf.destId, &tp.remoteCfg)) { + // TODO: Warning, event etc. + return FAILED; + } + step = TransactionStep::RECEIVING_FILE_DATA_PDUS; + return OK; +} diff --git a/src/fsfw/cfdp/handler/DestHandler.h b/src/fsfw/cfdp/handler/DestHandler.h index d979f09b2..706752b2b 100644 --- a/src/fsfw/cfdp/handler/DestHandler.h +++ b/src/fsfw/cfdp/handler/DestHandler.h @@ -7,7 +7,9 @@ #include "RemoteConfigTableIF.h" #include "UserBase.h" +#include "defs.h" #include "fsfw/cfdp/handler/mib.h" +#include "fsfw/cfdp/pdu/MetadataPduReader.h" #include "fsfw/cfdp/pdu/PduConfig.h" #include "fsfw/container/DynamicFIFO.h" #include "fsfw/storagemanager/StorageManagerIF.h" @@ -28,7 +30,7 @@ struct PacketInfo { struct DestHandlerParams { DestHandlerParams(LocalEntityCfg cfg, UserBase& user, RemoteConfigTableIF& remoteCfgTable, - etl::ilist& packetList, uint8_t maxTlvsInOnePdu) + etl::ilist& packetList) : cfg(std::move(cfg)), user(user), remoteCfgTable(remoteCfgTable), @@ -39,7 +41,8 @@ struct DestHandlerParams { RemoteConfigTableIF& remoteCfgTable; etl::ilist& packetListRef; - uint8_t maxTlvsInOnePdu; + uint8_t maxTlvsInOnePdu = 10; + size_t maxFilenameLen = 255; }; struct FsfwParams { @@ -67,8 +70,6 @@ class DestHandler { ReturnValue_t handleMetadataParseError(const uint8_t* rawData, size_t maxSize); private: - DestHandlerParams dp; - FsfwParams fp; enum class TransactionStep { IDLE = 0, TRANSACTION_START = 1, @@ -77,8 +78,29 @@ class DestHandler { TRANSFER_COMPLETION = 4, SENDING_FINISHED_PDU = 5 }; + struct TransactionParams { + explicit TransactionParams(size_t maxFileNameLen) + : sourceName(maxFileNameLen), destName(maxFileNameLen) {} + + ChecksumType checksumType = ChecksumType::NULL_CHECKSUM; + bool closureRequested{}; + std::vector sourceName; + std::vector destName; + cfdp::FileSize fileSize; + TransactionId transactionId; + PduConfig pduConf; + RemoteEntityCfg* remoteCfg; + }; + TransactionStep step = TransactionStep::IDLE; + CfdpStates cfdpState = CfdpStates::IDLE; std::vector tlvVec; + std::vector userTlvVec; + DestHandlerParams dp; + FsfwParams fp; + TransactionParams tp; + + ReturnValue_t startTransaction(MetadataPduReader& reader, MetadataInfo& info); }; } // namespace cfdp diff --git a/src/fsfw/cfdp/handler/defs.h b/src/fsfw/cfdp/handler/defs.h new file mode 100644 index 000000000..9e837a96b --- /dev/null +++ b/src/fsfw/cfdp/handler/defs.h @@ -0,0 +1,9 @@ +#ifndef FSFW_CFDP_HANDLER_DEFS_H +#define FSFW_CFDP_HANDLER_DEFS_H + +namespace cfdp { + +enum class CfdpStates { IDLE, BUSY_CLASS_1_NACKED, BUSY_CLASS_2_ACKED, SUSPENDED }; + +} +#endif // FSFW_CFDP_HANDLER_DEFS_H diff --git a/src/fsfw/cfdp/pdu/HeaderReader.cpp b/src/fsfw/cfdp/pdu/HeaderReader.cpp index f220ccd3c..e2f070dbc 100644 --- a/src/fsfw/cfdp/pdu/HeaderReader.cpp +++ b/src/fsfw/cfdp/pdu/HeaderReader.cpp @@ -139,3 +139,13 @@ bool HeaderReader::isNull() const { } HeaderReader::operator bool() const { return not isNull(); } + +void HeaderReader::fillConfig(PduConfig &cfg) const { + cfg.largeFile = getLargeFileFlag(); + cfg.crcFlag = getCrcFlag(); + cfg.mode = getTransmissionMode(); + cfg.direction = getDirection(); + getTransactionSeqNum(cfg.seqNum); + getSourceId(cfg.sourceId); + getDestId(cfg.destId); +} diff --git a/src/fsfw/cfdp/pdu/HeaderReader.h b/src/fsfw/cfdp/pdu/HeaderReader.h index 9bf740a85..533320b7d 100644 --- a/src/fsfw/cfdp/pdu/HeaderReader.h +++ b/src/fsfw/cfdp/pdu/HeaderReader.h @@ -45,6 +45,12 @@ class HeaderReader : public RedirectableDataPointerIF, public PduHeaderIF { explicit operator bool() const; [[nodiscard]] bool isNull() const; + /** + * Fill the provided PDU configuration from the fields detected by this reader. + * @param cfg + */ + void fillConfig(PduConfig& cfg) const; + [[nodiscard]] virtual size_t getHeaderSize() const; [[nodiscard]] size_t getPduDataFieldLen() const override; diff --git a/src/fsfw/cfdp/pdu/PduConfig.h b/src/fsfw/cfdp/pdu/PduConfig.h index 2e5131592..368999cc1 100644 --- a/src/fsfw/cfdp/pdu/PduConfig.h +++ b/src/fsfw/cfdp/pdu/PduConfig.h @@ -6,16 +6,18 @@ class PduConfig { public: + PduConfig() = default; PduConfig(cfdp::EntityId sourceId, cfdp::EntityId destId, cfdp::TransmissionModes mode, cfdp::TransactionSeqNum seqNum, bool crcFlag = false, bool largeFile = false, cfdp::Direction direction = cfdp::Direction::TOWARDS_RECEIVER); - cfdp::TransmissionModes mode; + + cfdp::TransmissionModes mode = cfdp::TransmissionModes::ACKNOWLEDGED; cfdp::TransactionSeqNum seqNum; cfdp::EntityId sourceId; cfdp::EntityId destId; - bool crcFlag; - bool largeFile; - cfdp::Direction direction; + bool crcFlag = false; + bool largeFile = false; + cfdp::Direction direction = cfdp::Direction::TOWARDS_RECEIVER; }; #endif /* FSFW_SRC_FSFW_CFDP_PDU_PDUCONFIG_H_ */