From 9e4f2add7d62f322213e205d243d97c609ec1785 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 15 Sep 2022 16:53:28 +0200 Subject: [PATCH] move generic handler to framework --- bsp_hosted/core/CMakeLists.txt | 3 +- bsp_hosted/core/CfdpHandler.cpp | 139 ------------------------------ bsp_hosted/core/CfdpHandler.h | 72 ---------------- bsp_hosted/core/ObjectFactory.cpp | 39 +++++++-- example_common | 2 +- fsfw | 2 +- 6 files changed, 34 insertions(+), 223 deletions(-) delete mode 100644 bsp_hosted/core/CfdpHandler.cpp delete mode 100644 bsp_hosted/core/CfdpHandler.h diff --git a/bsp_hosted/core/CMakeLists.txt b/bsp_hosted/core/CMakeLists.txt index f8167bd..5edc79a 100644 --- a/bsp_hosted/core/CMakeLists.txt +++ b/bsp_hosted/core/CMakeLists.txt @@ -1,2 +1 @@ -target_sources(${TARGET_NAME} PRIVATE InitMission.cpp ObjectFactory.cpp - CfdpHandler.cpp) +target_sources(${TARGET_NAME} PRIVATE InitMission.cpp ObjectFactory.cpp) diff --git a/bsp_hosted/core/CfdpHandler.cpp b/bsp_hosted/core/CfdpHandler.cpp deleted file mode 100644 index 1b1d466..0000000 --- a/bsp_hosted/core/CfdpHandler.cpp +++ /dev/null @@ -1,139 +0,0 @@ -#include "CfdpHandler.h" - -#include "fsfw/cfdp/pdu/AckPduReader.h" -#include "fsfw/cfdp/pdu/PduHeaderReader.h" -#include "fsfw/globalfunctions/arrayprinter.h" -#include "fsfw/ipc/QueueFactory.h" -#include "fsfw/tmtcservices/TmTcMessage.h" - -using namespace returnvalue; -using namespace cfdp; - -CfdpHandler::CfdpHandler(const FsfwHandlerParams& fsfwParams, const CfdpHandlerCfg& cfdpCfg) - : SystemObject(fsfwParams.objectId), - destHandler(DestHandlerParams(LocalEntityCfg(cfdpCfg.id, cfdpCfg.indicCfg, *this), cfdpCfg.userHandler, - cfdpCfg.remoteCfgProvider, cfdpCfg.packetInfoList, - cfdpCfg.lostSegmentsList), - FsfwParams(fsfwParams.packetDest, nullptr, this, fsfwParams.tcStore, - fsfwParams.tmStore)) { - // TODO: Make queue params configurable, or better yet, expect it to be passed externally - msgQueue = QueueFactory::instance()->createMessageQueue(); - destHandler.setMsgQueue(*msgQueue); -} - -[[nodiscard]] const char* CfdpHandler::getName() const { return "CFDP Handler"; } - -[[nodiscard]] uint32_t CfdpHandler::getIdentifier() const { - return destHandler.getDestHandlerParams().cfg.localId.getValue(); -} - -[[nodiscard]] MessageQueueId_t CfdpHandler::getRequestQueue() const { return msgQueue->getId(); } - -ReturnValue_t CfdpHandler::initialize() { - ReturnValue_t result = destHandler.initialize(); - if (result != OK) { - return result; - } - tcStore = destHandler.getTcStore(); - tmStore = destHandler.getTmStore(); - - return SystemObject::initialize(); -} - -ReturnValue_t CfdpHandler::performOperation(uint8_t operationCode) { - // TODO: Receive TC packets and route them to source and dest handler, depending on which is - // correct or more appropriate - ReturnValue_t status; - ReturnValue_t result = OK; - TmTcMessage tmtcMsg; - for (status = msgQueue->receiveMessage(&tmtcMsg); status == returnvalue::OK; - status = msgQueue->receiveMessage(&tmtcMsg)) { - result = handleCfdpPacket(tmtcMsg); - if (result != OK) { - status = result; - } - } - auto& fsmRes = destHandler.performStateMachine(); - // TODO: Error handling? - while (fsmRes.callStatus == CallStatus::CALL_AGAIN) { - destHandler.performStateMachine(); - // TODO: Error handling? - } - return status; -} - -ReturnValue_t CfdpHandler::handleCfdpPacket(TmTcMessage& msg) { - auto accessorPair = tcStore->getData(msg.getStorageId()); - if(accessorPair.first != OK) { - return accessorPair.first; - } - PduHeaderReader reader(accessorPair.second.data(), accessorPair.second.size()); - ReturnValue_t result = reader.parseData(); - if (result != returnvalue::OK) { - return INVALID_PDU_FORMAT; - } - // The CFDP distributor should have taken care of ensuring the destination ID is correct - PduTypes type = reader.getPduType(); - // Only the destination handler can process these PDUs - if (type == PduTypes::FILE_DATA) { - // Disable auto-deletion of packet - accessorPair.second.release(); - PacketInfo info(type, msg.getStorageId()); - result = destHandler.passPacket(info); - } else { - // Route depending on PDU type and directive type if applicable. It retrieves directive type - // from the raw stream for better performance (with sanity and directive code check). - // The routing is based on section 4.5 of the CFDP standard which specifies the PDU forwarding - // procedure. - - // PDU header only. Invalid supplied data. A directive packet should have a valid data field - // with at least one byte being the directive code - const uint8_t* pduDataField = reader.getPduDataField(); - if (pduDataField == nullptr) { - return INVALID_PDU_FORMAT; - } - if (not FileDirectiveReader::checkFileDirective(pduDataField[0])) { - return INVALID_DIRECTIVE_FIELD; - } - auto directive = static_cast(pduDataField[0]); - - auto passToDestHandler = [&]() { - accessorPair.second.release(); - PacketInfo info(type, msg.getStorageId(), directive); - result = destHandler.passPacket(info); - }; - auto passToSourceHandler = [&]() { - - }; - if (directive == FileDirectives::METADATA or directive == FileDirectives::EOF_DIRECTIVE or - directive == FileDirectives::PROMPT) { - // Section b) of 4.5.3: These PDUs should always be targeted towards the file receiver a.k.a. - // the destination handler - passToDestHandler(); - } else if (directive == FileDirectives::FINISH or directive == FileDirectives::NAK or - directive == FileDirectives::KEEP_ALIVE) { - // Section c) of 4.5.3: These PDUs should always be targeted towards the file sender a.k.a. - // the source handler - passToSourceHandler(); - } else if (directive == FileDirectives::ACK) { - // Section a): Recipient depends of the type of PDU that is being acknowledged. We can simply - // extract the PDU type from the raw stream. If it is an EOF PDU, this packet is passed to - // the source handler, for a Finished PDU, it is passed to the destination handler. - FileDirectives ackedDirective; - if (not AckPduReader::checkAckedDirectiveField(pduDataField[1], ackedDirective)) { - return INVALID_ACK_DIRECTIVE_FIELDS; - } - if (ackedDirective == FileDirectives::EOF_DIRECTIVE) { - passToSourceHandler(); - } else if (ackedDirective == FileDirectives::FINISH) { - passToDestHandler(); - } - } - } - return result; -} - -void CfdpHandler::noticeOfSuspensionCb(cfdp::ConditionCode code) {} -void CfdpHandler::noticeOfCancellationCb(cfdp::ConditionCode code) {} -void CfdpHandler::abandonCb(cfdp::ConditionCode code) {} -void CfdpHandler::ignoreCb(cfdp::ConditionCode code) {} diff --git a/bsp_hosted/core/CfdpHandler.h b/bsp_hosted/core/CfdpHandler.h deleted file mode 100644 index 20bcd7f..0000000 --- a/bsp_hosted/core/CfdpHandler.h +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef FSFW_EXAMPLE_HOSTED_CFDPHANDLER_H -#define FSFW_EXAMPLE_HOSTED_CFDPHANDLER_H - -#include - -#include "fsfw/cfdp/handler/DestHandler.h" -#include "fsfw/objectmanager/SystemObject.h" -#include "fsfw/tasks/ExecutableObjectIF.h" -#include "fsfw/tmtcservices/AcceptsTelecommandsIF.h" -#include "fsfw/tmtcservices/TmTcMessage.h" - -struct FsfwHandlerParams { - FsfwHandlerParams(object_id_t objectId, HasFileSystemIF& vfs, AcceptsTelemetryIF& packetDest, - StorageManagerIF& tcStore, StorageManagerIF& tmStore) - : objectId(objectId), vfs(vfs), packetDest(packetDest), tcStore(tcStore), tmStore(tmStore) {} - object_id_t objectId{}; - HasFileSystemIF& vfs; - AcceptsTelemetryIF& packetDest; - StorageManagerIF& tcStore; - StorageManagerIF& tmStore; -}; - -struct CfdpHandlerCfg { - CfdpHandlerCfg(cfdp::EntityId localId, cfdp::IndicationCfg indicationCfg, - cfdp::UserBase &userHandler, - cfdp::PacketInfoListBase& packetInfo, - cfdp::LostSegmentsListBase& lostSegmentsList, - cfdp::RemoteConfigTableIF& remoteCfgProvider) - : id(std::move(localId)), - indicCfg(indicationCfg), - packetInfoList(packetInfo), - lostSegmentsList(lostSegmentsList), - remoteCfgProvider(remoteCfgProvider), - userHandler(userHandler) {} - - cfdp::EntityId id; - cfdp::IndicationCfg indicCfg; - cfdp::PacketInfoListBase& packetInfoList; - cfdp::LostSegmentsListBase& lostSegmentsList; - cfdp::RemoteConfigTableIF& remoteCfgProvider; - cfdp::UserBase& userHandler; -}; - -class CfdpHandler : public SystemObject, - public cfdp::FaultHandlerBase, - public ExecutableObjectIF, - public AcceptsTelecommandsIF { - public: - explicit CfdpHandler(const FsfwHandlerParams& fsfwParams, const CfdpHandlerCfg& cfdpCfg); - - [[nodiscard]] const char* getName() const override; - [[nodiscard]] uint32_t getIdentifier() const override; - [[nodiscard]] MessageQueueId_t getRequestQueue() const override; - - ReturnValue_t initialize() override; - ReturnValue_t performOperation(uint8_t operationCode) override; - - void noticeOfSuspensionCb(cfdp::ConditionCode code) override; - void noticeOfCancellationCb(cfdp::ConditionCode code) override; - void abandonCb(cfdp::ConditionCode code) override; - void ignoreCb(cfdp::ConditionCode code) override; - - private: - MessageQueueIF* msgQueue = nullptr; - cfdp::DestHandler destHandler; - StorageManagerIF* tcStore = nullptr; - StorageManagerIF* tmStore = nullptr; - - ReturnValue_t handleCfdpPacket(TmTcMessage& msg); -}; - -#endif // FSFW_EXAMPLE_HOSTED_CFDPHANDLER_H diff --git a/bsp_hosted/core/ObjectFactory.cpp b/bsp_hosted/core/ObjectFactory.cpp index c89d775..6536e50 100644 --- a/bsp_hosted/core/ObjectFactory.cpp +++ b/bsp_hosted/core/ObjectFactory.cpp @@ -1,6 +1,5 @@ #include "ObjectFactory.h" -#include "CfdpHandler.h" #include "OBSWConfig.h" #include "bsp_hosted/fsfwconfig/objects/systemObjectList.h" #include "common/definitions.h" @@ -8,11 +7,12 @@ #include "example/core/GenericFactory.h" #include "example/test/FsfwTestTask.h" #include "example/utility/TmFunnel.h" +#include "fsfw/cfdp.h" #include "fsfw/storagemanager/PoolManager.h" +#include "fsfw/tcdistribution/CcsdsDistributor.h" #include "fsfw/tcdistribution/CcsdsDistributorIF.h" #include "fsfw/tmtcservices/CommandingServiceBase.h" #include "fsfw_hal/host/HostFilesystem.h" -#include "fsfw/tcdistribution/CcsdsDistributor.h" #if OBSW_USE_TCP_SERVER == 0 #include @@ -22,9 +22,9 @@ #include "fsfw/osal/common/TcpTmTcServer.h" #endif -class CfdpExampleUserHandler: public cfdp::UserBase { +class CfdpExampleUserHandler : public cfdp::UserBase { public: - explicit CfdpExampleUserHandler(HasFileSystemIF& vfs): cfdp::UserBase(vfs) {} + explicit CfdpExampleUserHandler(HasFileSystemIF& vfs) : cfdp::UserBase(vfs) {} void transactionIndication(const cfdp::TransactionId& id) override {} void eofSentIndication(const cfdp::TransactionId& id) override {} @@ -36,17 +36,38 @@ class CfdpExampleUserHandler: public cfdp::UserBase { } void fileSegmentRecvdIndication(const cfdp::FileSegmentRecvdParams& params) override {} void reportIndication(const cfdp::TransactionId& id, cfdp::StatusReportIF& report) override {} - void suspendedIndication(const cfdp::TransactionId& id, cfdp::ConditionCode code) override {} + void suspendedIndication(const cfdp::TransactionId& id, cfdp::ConditionCodes code) override {} void resumedIndication(const cfdp::TransactionId& id, size_t progress) override {} - void faultIndication(const cfdp::TransactionId& id, cfdp::ConditionCode code, + void faultIndication(const cfdp::TransactionId& id, cfdp::ConditionCodes code, size_t progress) override {} - void abandonedIndication(const cfdp::TransactionId& id, cfdp::ConditionCode code, + void abandonedIndication(const cfdp::TransactionId& id, cfdp::ConditionCodes code, size_t progress) override {} void eofRecvIndication(const cfdp::TransactionId& id) override { sif::info << "EOF PDU received for transaction with " << id << std::endl; } }; +class CfdpExampleFaultHandler : public cfdp::FaultHandlerBase { + public: + void noticeOfSuspensionCb(cfdp::TransactionId& id, cfdp::ConditionCodes code) override { + sif::warning << "Notice of suspension detected for transaction " << id + << " with condition code: " << cfdp::getConditionCodeString(code) << std::endl; + } + void noticeOfCancellationCb(cfdp::TransactionId& id, cfdp::ConditionCodes code) override { + sif::warning << "Notice of suspension detected for transaction " << id + << " with condition code: " << cfdp::getConditionCodeString(code) << std::endl; + } + void abandonCb(cfdp::TransactionId& id, cfdp::ConditionCodes code) override { + sif::warning << "Transaction " << id + << " was abandoned, condition code : " << cfdp::getConditionCodeString(code) + << std::endl; + } + void ignoreCb(cfdp::TransactionId& id, cfdp::ConditionCodes code) override { + sif::warning << "Fault ignored for transaction " << id + << ", condition code: " << cfdp::getConditionCodeString(code) << std::endl; + } +}; + void ObjectFactory::produce(void* args) { Factory::setStaticFrameworkObjectIds(); StorageManagerIF* tcStore = nullptr; @@ -105,9 +126,11 @@ void ObjectFactory::produce(void* args) { remoteCfg.defaultChecksum = cfdp::ChecksumTypes::CRC_32; auto* remoteCfgProvider = new cfdp::OneRemoteConfigProvider(remoteCfg); auto* cfdpUserHandler = new CfdpExampleUserHandler(*hostFs); + auto* cfdpFaultHandler = new CfdpExampleFaultHandler(); cfdp::PacketInfoList<64> packetList; cfdp::LostSegmentsList<128> lostSegments; - CfdpHandlerCfg cfg(localId, indicationCfg, *cfdpUserHandler, packetList, lostSegments, *remoteCfgProvider); + CfdpHandlerCfg cfg(localId, indicationCfg, *cfdpUserHandler, *cfdpFaultHandler, packetList, + lostSegments, *remoteCfgProvider); auto* cfdpHandler = new CfdpHandler(params, cfg); CcsdsDistributorIF::DestInfo info("CFDP Destination", common::COMMON_CFDP_APID, cfdpHandler->getRequestQueue(), true); diff --git a/example_common b/example_common index 6b914a2..29593e3 160000 --- a/example_common +++ b/example_common @@ -1 +1 @@ -Subproject commit 6b914a21fd52fe184784b90984bb4bc2db82544d +Subproject commit 29593e31420fa85cb67b8f2b10020ebde5c05ca2 diff --git a/fsfw b/fsfw index 4fb7375..ed68268 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 4fb7375492b27ef51a93c27e08022cfcc59f445a +Subproject commit ed68268c0cd69fd0932ed09fd34000c7d129371d