diff --git a/config/commonObjects.h b/config/commonObjects.h index 76b3483..d4480f1 100644 --- a/config/commonObjects.h +++ b/config/commonObjects.h @@ -27,6 +27,8 @@ enum commonObjects : object_id_t { TM_FUNNEL = 0x63000002, CFDP_DISTRIBUTOR = 0x63000003, CFDP_HANDLER = 0x63000004, + PUS_TM_FUNNEL = 0x63000005, + CFDP_TM_FUNNEL = 0x64000006, /* 0x74 ('t') for test and example objects */ TEST_TASK = 0x7400CAFE, diff --git a/example/core/GenericFactory.cpp b/example/core/GenericFactory.cpp index e6e7efa..ef7d9bc 100644 --- a/example/core/GenericFactory.cpp +++ b/example/core/GenericFactory.cpp @@ -5,6 +5,7 @@ #include "example/cfdp/Config.h" #include "example/test/FsfwExampleTask.h" #include "example/test/FsfwReaderTask.h" +#include "example/utility/CfdpTmFunnel.h" #include "example/utility/TmFunnel.h" #include "fsfw/FSFW.h" #include "fsfw/cfdp.h" @@ -48,7 +49,9 @@ ExampleFaultHandler EXAMPLE_FAULT_HANDLER; } // namespace cfdp #endif -void ObjectFactory::produceGenericObjects(TmFunnel **tmFunnel, CcsdsDistributor **ccsdsDistrib, +void ObjectFactory::produceGenericObjects(PusTmFunnel **pusFunnel, + const AcceptsTelemetryIF &tmtcBridge, + CcsdsDistributor **ccsdsDistrib, StorageManagerIF &tcStore, StorageManagerIF &tmStore) { #if OBSW_ADD_CORE_COMPONENTS == 1 /* Framework objects */ @@ -60,13 +63,15 @@ void ObjectFactory::produceGenericObjects(TmFunnel **tmFunnel, CcsdsDistributor *ccsdsDistrib = new CcsdsDistributor(common::COMMON_PUS_APID, objects::CCSDS_DISTRIBUTOR, &tcStore); new PusDistributor(common::COMMON_PUS_APID, objects::PUS_DISTRIBUTOR, *ccsdsDistrib); - *tmFunnel = new TmFunnel(*stamperAndReader, objects::TM_FUNNEL); + *pusFunnel = new PusTmFunnel(objects::PUS_TM_FUNNEL, tmtcBridge, *stamperAndReader); + auto *cfdpFunnel = new CfdpTmFunnel(objects::CFDP_TM_FUNNEL, tmtcBridge); + new TmFunnel(objects::TM_FUNNEL, **pusFunnel, *cfdpFunnel); #endif /* OBSW_ADD_CORE_COMPONENTS == 1 */ /* PUS stack */ #if OBSW_ADD_PUS_STACK == 1 new Service1TelecommandVerification(objects::PUS_SERVICE_1_VERIFICATION, common::COMMON_PUS_APID, - pus::PUS_SERVICE_1, objects::TM_FUNNEL, 5); + pus::PUS_SERVICE_1, objects::PUS_TM_FUNNEL, 5); new Service2DeviceAccess(objects::PUS_SERVICE_2_DEVICE_ACCESS, common::COMMON_PUS_APID, pus::PUS_SERVICE_2, 3, 10); new Service3Housekeeping(objects::PUS_SERVICE_3_HOUSEKEEPING, common::COMMON_PUS_APID, @@ -160,7 +165,8 @@ void ObjectFactory::produceGenericObjects(TmFunnel **tmFunnel, CcsdsDistributor cfdp::EntityId remoteId(remoteEntityId); cfdp::RemoteEntityCfg remoteCfg(remoteId); remoteCfg.defaultChecksum = cfdp::ChecksumType::CRC_32; - FsfwHandlerParams params(objects::CFDP_HANDLER, HOST_FS, **tmFunnel, tcStore, tmStore, *msgQueue); + FsfwHandlerParams params(objects::CFDP_HANDLER, HOST_FS, *cfdpFunnel, tcStore, tmStore, + *msgQueue); cfdp::IndicationCfg indicationCfg; UnsignedByteField apid(common::COMMON_CFDP_APID); cfdp::EntityId localId(apid); @@ -185,15 +191,11 @@ void Factory::setStaticFrameworkObjectIds() { MonitoringReportContent::timeStamperId = objects::TIME_STAMPER; MonitoringReportContent::timeStamperId = objects::TIME_STAMPER; - TmFunnel::downlinkDestination = objects::DOWNLINK_DESTINATION; - // No storage object for now. - TmFunnel::storageDestination = objects::NO_OBJECT; - PusServiceBase::PUS_DISTRIBUTOR = objects::PUS_DISTRIBUTOR; - PusServiceBase::PACKET_DESTINATION = objects::TM_FUNNEL; + PusServiceBase::PACKET_DESTINATION = objects::PUS_TM_FUNNEL; CommandingServiceBase::defaultPacketSource = objects::PUS_DISTRIBUTOR; - CommandingServiceBase::defaultPacketDestination = objects::TM_FUNNEL; + CommandingServiceBase::defaultPacketDestination = objects::PUS_TM_FUNNEL; VerificationReporter::DEFAULT_RECEIVER = objects::PUS_SERVICE_1_VERIFICATION; } diff --git a/example/core/GenericFactory.h b/example/core/GenericFactory.h index d894219..680ede3 100644 --- a/example/core/GenericFactory.h +++ b/example/core/GenericFactory.h @@ -4,6 +4,7 @@ #include #include "OBSWConfig.h" +#include "example/utility/PusTmFunnel.h" #include "fsfw/cfdp/handler/DestHandler.h" #include "fsfw/storagemanager/StorageManagerIF.h" @@ -16,8 +17,9 @@ namespace ObjectFactory { * @brief Produce hardware independant objects. Called by bsp specific * object factory. */ -void produceGenericObjects(TmFunnel** funnel, CcsdsDistributor** ccsdsDistributor, - StorageManagerIF& tcStore, StorageManagerIF& tmStore); +void produceGenericObjects(PusTmFunnel** pusFunnel, const AcceptsTelemetryIF& tmtcBridge, + CcsdsDistributor** ccsdsDistributor, StorageManagerIF& tcStore, + StorageManagerIF& tmStore); } // namespace ObjectFactory diff --git a/example/utility/CMakeLists.txt b/example/utility/CMakeLists.txt index 94333d1..ba3a68f 100644 --- a/example/utility/CMakeLists.txt +++ b/example/utility/CMakeLists.txt @@ -1 +1,2 @@ -target_sources(${TARGET_NAME} PRIVATE utility.cpp TmFunnel.cpp) +target_sources(${TARGET_NAME} PRIVATE utility.cpp TmFunnel.cpp PusTmFunnel.cpp + CfdpTmFunnel.cpp) diff --git a/example/utility/CfdpTmFunnel.cpp b/example/utility/CfdpTmFunnel.cpp new file mode 100644 index 0000000..f2b3ec1 --- /dev/null +++ b/example/utility/CfdpTmFunnel.cpp @@ -0,0 +1,18 @@ +#include "CfdpTmFunnel.h" + +#include "fsfw/ipc/QueueFactory.h" + +CfdpTmFunnel::CfdpTmFunnel(object_id_t objectId, const AcceptsTelemetryIF& downlinkDestination) + : SystemObject(objectId) { + msgQueue = QueueFactory::instance()->createMessageQueue(5); +} + +const char* CfdpTmFunnel::getName() const { return "CFDP TM Funnel"; } + +MessageQueueId_t CfdpTmFunnel::getReportReceptionQueue(uint8_t virtualChannel) const { + return msgQueue->getId(); +} + +ReturnValue_t CfdpTmFunnel::performOperation(uint8_t opCode) { return returnvalue::OK; } + +ReturnValue_t CfdpTmFunnel::initialize() { return returnvalue::OK; } \ No newline at end of file diff --git a/example/utility/CfdpTmFunnel.h b/example/utility/CfdpTmFunnel.h new file mode 100644 index 0000000..bf61c54 --- /dev/null +++ b/example/utility/CfdpTmFunnel.h @@ -0,0 +1,19 @@ +#ifndef FSFW_EXAMPLE_COMMON_CFDPTMFUNNEL_H +#define FSFW_EXAMPLE_COMMON_CFDPTMFUNNEL_H + +#include "fsfw/objectmanager/SystemObject.h" +#include "fsfw/tmtcservices/AcceptsTelemetryIF.h" + +class CfdpTmFunnel : public AcceptsTelemetryIF, public SystemObject { + public: + CfdpTmFunnel(object_id_t objectId, const AcceptsTelemetryIF& downlinkDestination); + [[nodiscard]] const char* getName() const override; + [[nodiscard]] MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel) const override; + + ReturnValue_t performOperation(uint8_t opCode); + ReturnValue_t initialize() override; + + private: + MessageQueueIF* msgQueue; +}; +#endif // FSFW_EXAMPLE_COMMON_CFDPTMFUNNEL_H diff --git a/example/utility/PusTmFunnel.cpp b/example/utility/PusTmFunnel.cpp new file mode 100644 index 0000000..7470045 --- /dev/null +++ b/example/utility/PusTmFunnel.cpp @@ -0,0 +1,82 @@ +#include "PusTmFunnel.h" + +#include "fsfw/ipc/QueueFactory.h" +#include "fsfw/objectmanager.h" +#include "fsfw/tmtcpacket/pus/tm/PusTmZcWriter.h" + +PusTmFunnel::PusTmFunnel(object_id_t objectId, const AcceptsTelemetryIF &downlinkDestination, + TimeReaderIF &timeReader, uint32_t messageDepth) + : SystemObject(objectId), timeReader(timeReader) { + tmQueue = QueueFactory::instance()->createMessageQueue(messageDepth, + MessageQueueMessage::MAX_MESSAGE_SIZE); + tmQueue->setDefaultDestination(downlinkDestination.getReportReceptionQueue()); +} + +PusTmFunnel::~PusTmFunnel() = default; + +MessageQueueId_t PusTmFunnel::getReportReceptionQueue(uint8_t virtualChannel) const { + return tmQueue->getId(); +} + +ReturnValue_t PusTmFunnel::performOperation(uint8_t) { + TmTcMessage currentMessage; + ReturnValue_t status = tmQueue->receiveMessage(¤tMessage); + while (status == returnvalue::OK) { + status = handlePacket(¤tMessage); + if (status != returnvalue::OK) { + sif::warning << "TmFunnel packet handling failed" << std::endl; + break; + } + status = tmQueue->receiveMessage(¤tMessage); + } + + if (status == MessageQueueIF::EMPTY) { + return returnvalue::OK; + } else { + return status; + } +} + +ReturnValue_t PusTmFunnel::handlePacket(TmTcMessage *message) { + uint8_t *packetData = nullptr; + size_t size = 0; + ReturnValue_t result = tmPool->modifyData(message->getStorageId(), &packetData, &size); + if (result != returnvalue::OK) { + return result; + } + PusTmZeroCopyWriter packet(timeReader, packetData, size); + result = packet.parseDataWithoutCrcCheck(); + if (result != returnvalue::OK) { + return result; + } + packet.setSequenceCount(sourceSequenceCount++); + sourceSequenceCount = sourceSequenceCount % ccsds::LIMIT_SEQUENCE_COUNT; + packet.updateErrorControl(); + + result = tmQueue->sendToDefault(message); + if (result != returnvalue::OK) { + tmPool->deleteData(message->getStorageId()); +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "TmFunnel::handlePacket: Error sending TM to downlink handler" << std::endl; +#endif + return result; + } + + return result; +} + +ReturnValue_t PusTmFunnel::initialize() { + tmPool = ObjectManager::instance()->get(objects::TM_STORE); + if (tmPool == nullptr) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "TmFunnel::initialize: TM store not set." << std::endl; + sif::error << "Make sure the tm store is set up properly and implements " + "StorageManagerIF" + << std::endl; +#endif + return ObjectManagerIF::CHILD_INIT_FAILED; + } + return SystemObject::initialize(); +} + +const char *PusTmFunnel::getName() const { return "PUS TM Funnel"; } diff --git a/example/utility/PusTmFunnel.h b/example/utility/PusTmFunnel.h new file mode 100644 index 0000000..c0b50f2 --- /dev/null +++ b/example/utility/PusTmFunnel.h @@ -0,0 +1,40 @@ +#ifndef FSFW_EXAMPLE_COMMON_PUSTMFUNNEL_H +#define FSFW_EXAMPLE_COMMON_PUSTMFUNNEL_H + +#include +#include +#include +#include +#include + +#include "fsfw/timemanager/TimeReaderIF.h" + +/** + * @brief TM Recipient. + * @details + * Main telemetry receiver. All generated telemetry is funneled into + * this object. + * @ingroup utility + * @author J. Meier + */ +class PusTmFunnel : public AcceptsTelemetryIF, public SystemObject { + public: + explicit PusTmFunnel(object_id_t objectId, const AcceptsTelemetryIF &downlinkDestination, + TimeReaderIF &timeReader, uint32_t messageDepth = 20); + [[nodiscard]] const char *getName() const override; + ~PusTmFunnel() override; + + [[nodiscard]] MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel) const override; + ReturnValue_t performOperation(uint8_t operationCode); + ReturnValue_t initialize() override; + + private: + uint16_t sourceSequenceCount = 0; + TimeReaderIF &timeReader; + MessageQueueIF *tmQueue = nullptr; + StorageManagerIF *tmPool = nullptr; + + ReturnValue_t handlePacket(TmTcMessage *message); +}; + +#endif // FSFW_EXAMPLE_COMMON_PUSTMFUNNEL_H diff --git a/example/utility/TmFunnel.cpp b/example/utility/TmFunnel.cpp index 82dbec3..01bf043 100644 --- a/example/utility/TmFunnel.cpp +++ b/example/utility/TmFunnel.cpp @@ -1,122 +1,16 @@ #include "TmFunnel.h" #include -#include -#include -#include -#include "fsfw/tmtcpacket/pus/tm.h" - -object_id_t TmFunnel::downlinkDestination = objects::NO_OBJECT; -object_id_t TmFunnel::storageDestination = objects::NO_OBJECT; - -TmFunnel::TmFunnel(TimeReaderIF &timeReader, object_id_t objectId, uint32_t messageDepth) - : SystemObject(objectId), timeReader(timeReader), messageDepth(messageDepth) { - tmQueue = QueueFactory::instance()->createMessageQueue(messageDepth, - MessageQueueMessage::MAX_MESSAGE_SIZE); - storageQueue = QueueFactory::instance()->createMessageQueue( - messageDepth, MessageQueueMessage::MAX_MESSAGE_SIZE); -} +TmFunnel::TmFunnel(object_id_t objectId, PusTmFunnel& pusFunnel, CfdpTmFunnel& cfdpFunnel) + : SystemObject(objectId), pusFunnel(pusFunnel), cfdpFunnel(cfdpFunnel) {} TmFunnel::~TmFunnel() = default; -MessageQueueId_t TmFunnel::getReportReceptionQueue(uint8_t virtualChannel) { - return tmQueue->getId(); -} - ReturnValue_t TmFunnel::performOperation(uint8_t operationCode) { - TmTcMessage currentMessage; - ReturnValue_t status = tmQueue->receiveMessage(¤tMessage); - while (status == returnvalue::OK) { - status = handlePacket(¤tMessage); - if (status != returnvalue::OK) { - sif::warning << "TmFunnel packet handling failed" << std::endl; - break; - } - status = tmQueue->receiveMessage(¤tMessage); - } - - if (status == MessageQueueIF::EMPTY) { - return returnvalue::OK; - } else { - return status; - } + pusFunnel.performOperation(operationCode); + cfdpFunnel.performOperation(operationCode); + return returnvalue::OK; } -ReturnValue_t TmFunnel::handlePacket(TmTcMessage *message) { - uint8_t *packetData = nullptr; - size_t size = 0; - ReturnValue_t result = tmPool->modifyData(message->getStorageId(), &packetData, &size); - if (result != returnvalue::OK) { - return result; - } - PusTmZeroCopyWriter packet(timeReader, packetData, size); - result = packet.parseDataWithoutCrcCheck(); - if (result != returnvalue::OK) { - return result; - } - packet.setSequenceCount(sourceSequenceCount++); - sourceSequenceCount = sourceSequenceCount % ccsds::LIMIT_SEQUENCE_COUNT; - packet.updateErrorControl(); - - result = tmQueue->sendToDefault(message); - if (result != returnvalue::OK) { - tmPool->deleteData(message->getStorageId()); -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "TmFunnel::handlePacket: Error sending TM to downlink handler" << std::endl; -#endif - return result; - } - - if (storageDestination != objects::NO_OBJECT) { - result = storageQueue->sendToDefault(message); - if (result != returnvalue::OK) { - tmPool->deleteData(message->getStorageId()); -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "TmFunnel::handlePacket: Error sending to storage handler" << std::endl; -#endif - return result; - } - } - return result; -} - -ReturnValue_t TmFunnel::initialize() { - tmPool = ObjectManager::instance()->get(objects::TM_STORE); - if (tmPool == nullptr) { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "TmFunnel::initialize: TM store not set." << std::endl; - sif::error << "Make sure the tm store is set up properly and implements " - "StorageManagerIF" - << std::endl; -#endif - return ObjectManagerIF::CHILD_INIT_FAILED; - } - - auto *tmTarget = ObjectManager::instance()->get(downlinkDestination); - if (tmTarget == nullptr) { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "TmFunnel::initialize: Downlink Destination not set." << std::endl; - sif::error << "Make sure the downlink destination object is set up " - "properly and implements " - "AcceptsTelemetryIF" - << std::endl; -#endif - return ObjectManagerIF::CHILD_INIT_FAILED; - } - tmQueue->setDefaultDestination(tmTarget->getReportReceptionQueue()); - - // Storage destination is optional. - if (storageDestination == objects::NO_OBJECT) { - return SystemObject::initialize(); - } - - auto *storageTarget = ObjectManager::instance()->get(storageDestination); - if (storageTarget != nullptr) { - storageQueue->setDefaultDestination(storageTarget->getReportReceptionQueue()); - } - - return SystemObject::initialize(); -} - -const char *TmFunnel::getName() const { return "TM Funnel"; } +ReturnValue_t TmFunnel::initialize() { return returnvalue::OK; } diff --git a/example/utility/TmFunnel.h b/example/utility/TmFunnel.h index e74e48e..7f0adf7 100644 --- a/example/utility/TmFunnel.h +++ b/example/utility/TmFunnel.h @@ -7,12 +7,10 @@ #include #include +#include "CfdpTmFunnel.h" +#include "PusTmFunnel.h" #include "fsfw/timemanager/TimeReaderIF.h" -namespace Factory { -void setStaticFrameworkObjectIds(); -} - /** * @brief TM Recipient. * @details @@ -21,32 +19,17 @@ void setStaticFrameworkObjectIds(); * @ingroup utility * @author J. Meier */ -class TmFunnel : public AcceptsTelemetryIF, public ExecutableObjectIF, public SystemObject { - friend void(Factory::setStaticFrameworkObjectIds)(); - +class TmFunnel : public ExecutableObjectIF, public SystemObject { public: - explicit TmFunnel(TimeReaderIF &timeReader, object_id_t objectId, uint32_t messageDepth = 20); - const char *getName() const override; + TmFunnel(object_id_t objectId, PusTmFunnel& pusFunnel, CfdpTmFunnel& cfdpFunnel); ~TmFunnel() override; - MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel) override; ReturnValue_t performOperation(uint8_t operationCode) override; ReturnValue_t initialize() override; - protected: - static object_id_t downlinkDestination; - static object_id_t storageDestination; - private: - uint16_t sourceSequenceCount = 0; - TimeReaderIF &timeReader; - MessageQueueIF *tmQueue = nullptr; - MessageQueueIF *storageQueue = nullptr; - - StorageManagerIF *tmPool = nullptr; - uint32_t messageDepth = 0; - - ReturnValue_t handlePacket(TmTcMessage *message); + PusTmFunnel& pusFunnel; + CfdpTmFunnel& cfdpFunnel; }; #endif /* MISSION_UTILITY_TMFUNNEL_H_ */