From 098741ffe6375a75c6248ec0c9c5f32100158c4d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 24 Oct 2022 10:14:58 +0200 Subject: [PATCH 01/87] start adding basic pus 15 components --- mission/tmtc/CMakeLists.txt | 3 ++- mission/tmtc/Service15TmStorage.cpp | 13 +++++++++++++ mission/tmtc/Service15TmStorage.h | 16 ++++++++++++++++ mission/tmtc/TmStoreBackend.cpp | 9 +++++++++ mission/tmtc/TmStoreBackend.h | 16 ++++++++++++++++ 5 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 mission/tmtc/Service15TmStorage.cpp create mode 100644 mission/tmtc/Service15TmStorage.h create mode 100644 mission/tmtc/TmStoreBackend.cpp create mode 100644 mission/tmtc/TmStoreBackend.h diff --git a/mission/tmtc/CMakeLists.txt b/mission/tmtc/CMakeLists.txt index f34f9ccc..2fdccc81 100644 --- a/mission/tmtc/CMakeLists.txt +++ b/mission/tmtc/CMakeLists.txt @@ -1,3 +1,4 @@ target_sources( ${LIB_EIVE_MISSION} PRIVATE CCSDSHandler.cpp VirtualChannel.cpp TmFunnel.cpp - CfdpTmFunnel.cpp PusTmFunnel.cpp) + CfdpTmFunnel.cpp PusTmFunnel.cpp Service15TmStorage.cpp + TmStoreBackend.cpp) diff --git a/mission/tmtc/Service15TmStorage.cpp b/mission/tmtc/Service15TmStorage.cpp new file mode 100644 index 00000000..1a441247 --- /dev/null +++ b/mission/tmtc/Service15TmStorage.cpp @@ -0,0 +1,13 @@ +#include "Service15TmStorage.h" + + +Service15TmStorage::Service15TmStorage(PsbParams params): PusServiceBase(params) { +} + +ReturnValue_t Service15TmStorage::handleRequest(uint8_t subservice) { + return returnvalue::OK; +} + +ReturnValue_t Service15TmStorage::performService() { + return returnvalue::OK; +} diff --git a/mission/tmtc/Service15TmStorage.h b/mission/tmtc/Service15TmStorage.h new file mode 100644 index 00000000..82856bec --- /dev/null +++ b/mission/tmtc/Service15TmStorage.h @@ -0,0 +1,16 @@ +#ifndef MISSION_TMTC_SERVICE15TMSTORAGE_H_ +#define MISSION_TMTC_SERVICE15TMSTORAGE_H_ + +#include "fsfw/tmtcservices/PusServiceBase.h" + +class Service15TmStorage: public PusServiceBase { +public: + explicit Service15TmStorage(PsbParams params); +private: + ReturnValue_t handleRequest(uint8_t subservice) override; + ReturnValue_t performService() override; +}; + + + +#endif /* MISSION_TMTC_SERVICE15TMSTORAGE_H_ */ diff --git a/mission/tmtc/TmStoreBackend.cpp b/mission/tmtc/TmStoreBackend.cpp new file mode 100644 index 00000000..4ffaa98b --- /dev/null +++ b/mission/tmtc/TmStoreBackend.cpp @@ -0,0 +1,9 @@ +#include "TmStoreBackend.h" + +const char* TmStoreBackend::getName() const { + return "TM Store Backend"; +} + +MessageQueueId_t TmStoreBackend::getReportReceptionQueue(uint8_t virtualChannel) const { + return MessageQueueIF::NO_QUEUE; +} diff --git a/mission/tmtc/TmStoreBackend.h b/mission/tmtc/TmStoreBackend.h new file mode 100644 index 00000000..d845d758 --- /dev/null +++ b/mission/tmtc/TmStoreBackend.h @@ -0,0 +1,16 @@ +#ifndef MISSION_TMTC_TMSTOREBACKEND_H_ +#define MISSION_TMTC_TMSTOREBACKEND_H_ + +#include + +class TmStoreBackend: public AcceptsTelemetryIF { +public: + + [[nodiscard]] const char* getName() const override; + [[nodiscard]] MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel) const override; +private: +}; + + + +#endif /* MISSION_TMTC_TMSTOREBACKEND_H_ */ From e897fb63d805a0f5859b46faeaf800fcb4c977b5 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 24 Oct 2022 10:26:00 +0200 Subject: [PATCH 02/87] use CSB backend instead --- mission/tmtc/CMakeLists.txt | 11 ++++++++--- mission/tmtc/Service15TmStorage.cpp | 28 +++++++++++++++++++++++----- mission/tmtc/Service15TmStorage.h | 25 ++++++++++++++++--------- mission/tmtc/TmStoreBackend.cpp | 4 +--- mission/tmtc/TmStoreBackend.h | 10 ++++------ 5 files changed, 52 insertions(+), 26 deletions(-) diff --git a/mission/tmtc/CMakeLists.txt b/mission/tmtc/CMakeLists.txt index 2fdccc81..d8dd4e1c 100644 --- a/mission/tmtc/CMakeLists.txt +++ b/mission/tmtc/CMakeLists.txt @@ -1,4 +1,9 @@ target_sources( - ${LIB_EIVE_MISSION} PRIVATE CCSDSHandler.cpp VirtualChannel.cpp TmFunnel.cpp - CfdpTmFunnel.cpp PusTmFunnel.cpp Service15TmStorage.cpp - TmStoreBackend.cpp) + ${LIB_EIVE_MISSION} + PRIVATE CCSDSHandler.cpp + VirtualChannel.cpp + TmFunnel.cpp + CfdpTmFunnel.cpp + PusTmFunnel.cpp + Service15TmStorage.cpp + TmStoreBackend.cpp) diff --git a/mission/tmtc/Service15TmStorage.cpp b/mission/tmtc/Service15TmStorage.cpp index 1a441247..590b6c8e 100644 --- a/mission/tmtc/Service15TmStorage.cpp +++ b/mission/tmtc/Service15TmStorage.cpp @@ -1,13 +1,31 @@ #include "Service15TmStorage.h" +using namespace returnvalue; -Service15TmStorage::Service15TmStorage(PsbParams params): PusServiceBase(params) { +Service15TmStorage::Service15TmStorage(object_id_t objectId, uint16_t apid, + uint8_t numParallelCommands, uint16_t commandTimeoutSecs, + size_t queueDepth) + : CommandingServiceBase(objectId, apid, "PUS Service 15", 15, numParallelCommands, + commandTimeoutSecs, queueDepth) {} + +ReturnValue_t Service15TmStorage::isValidSubservice(uint8_t subservice) { return OK; } + +ReturnValue_t Service15TmStorage::getMessageQueueAndObject(uint8_t subservice, + const uint8_t *tcData, size_t tcDataLen, + MessageQueueId_t *id, + object_id_t *objectId) { + return OK; } -ReturnValue_t Service15TmStorage::handleRequest(uint8_t subservice) { - return returnvalue::OK; +ReturnValue_t Service15TmStorage::prepareCommand(CommandMessage *message, uint8_t subservice, + const uint8_t *tcData, size_t tcDataLen, + uint32_t *state, object_id_t objectId) { + return OK; } -ReturnValue_t Service15TmStorage::performService() { - return returnvalue::OK; +ReturnValue_t Service15TmStorage::handleReply(const CommandMessage *reply, + Command_t previousCommand, uint32_t *state, + CommandMessage *optionalNextCommand, + object_id_t objectId, bool *isStep) { + return OK; } diff --git a/mission/tmtc/Service15TmStorage.h b/mission/tmtc/Service15TmStorage.h index 82856bec..0243fdb3 100644 --- a/mission/tmtc/Service15TmStorage.h +++ b/mission/tmtc/Service15TmStorage.h @@ -1,16 +1,23 @@ #ifndef MISSION_TMTC_SERVICE15TMSTORAGE_H_ #define MISSION_TMTC_SERVICE15TMSTORAGE_H_ -#include "fsfw/tmtcservices/PusServiceBase.h" +#include -class Service15TmStorage: public PusServiceBase { -public: - explicit Service15TmStorage(PsbParams params); -private: - ReturnValue_t handleRequest(uint8_t subservice) override; - ReturnValue_t performService() override; +class Service15TmStorage : public CommandingServiceBase { + public: + explicit Service15TmStorage(object_id_t objectId, uint16_t apid, uint8_t numParallelCommands, + uint16_t commandTimeoutSecs, size_t queueDepth); + + private: + ReturnValue_t isValidSubservice(uint8_t subservice) override; + ReturnValue_t getMessageQueueAndObject(uint8_t subservice, const uint8_t* tcData, + size_t tcDataLen, MessageQueueId_t* id, + object_id_t* objectId) override; + ReturnValue_t prepareCommand(CommandMessage* message, uint8_t subservice, const uint8_t* tcData, + size_t tcDataLen, uint32_t* state, object_id_t objectId) override; + ReturnValue_t handleReply(const CommandMessage* reply, Command_t previousCommand, uint32_t* state, + CommandMessage* optionalNextCommand, object_id_t objectId, + bool* isStep) override; }; - - #endif /* MISSION_TMTC_SERVICE15TMSTORAGE_H_ */ diff --git a/mission/tmtc/TmStoreBackend.cpp b/mission/tmtc/TmStoreBackend.cpp index 4ffaa98b..4362609d 100644 --- a/mission/tmtc/TmStoreBackend.cpp +++ b/mission/tmtc/TmStoreBackend.cpp @@ -1,8 +1,6 @@ #include "TmStoreBackend.h" -const char* TmStoreBackend::getName() const { - return "TM Store Backend"; -} +const char* TmStoreBackend::getName() const { return "TM Store Backend"; } MessageQueueId_t TmStoreBackend::getReportReceptionQueue(uint8_t virtualChannel) const { return MessageQueueIF::NO_QUEUE; diff --git a/mission/tmtc/TmStoreBackend.h b/mission/tmtc/TmStoreBackend.h index d845d758..f53b5227 100644 --- a/mission/tmtc/TmStoreBackend.h +++ b/mission/tmtc/TmStoreBackend.h @@ -3,14 +3,12 @@ #include -class TmStoreBackend: public AcceptsTelemetryIF { -public: - +class TmStoreBackend : public AcceptsTelemetryIF { + public: [[nodiscard]] const char* getName() const override; [[nodiscard]] MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel) const override; -private: + + private: }; - - #endif /* MISSION_TMTC_TMSTOREBACKEND_H_ */ From ed7606290456ee2bbaa1ce760cf34cbac63f3669 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 24 Oct 2022 10:40:01 +0200 Subject: [PATCH 03/87] bump fsfw --- fsfw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fsfw b/fsfw index 754b71a3..56e8e5a8 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 754b71a35fc27208d7c679ea58783cacda973996 +Subproject commit 56e8e5a8b34dee6fcf240111618109e53b77841f From 46a756b1ee4322ef219376ad85f9561eaf48f66f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 24 Oct 2022 10:57:30 +0200 Subject: [PATCH 04/87] some updates --- CMakeLists.txt | 1 + fsfw | 2 +- mission/tmtc/CMakeLists.txt | 2 +- mission/tmtc/TmStore.cpp | 32 ++++++++++++++++++++++++ mission/tmtc/TmStore.h | 44 +++++++++++++++++++++++++++++++++ mission/tmtc/TmStoreBackend.cpp | 7 ------ mission/tmtc/TmStoreBackend.h | 14 ----------- 7 files changed, 79 insertions(+), 23 deletions(-) create mode 100644 mission/tmtc/TmStore.cpp create mode 100644 mission/tmtc/TmStore.h delete mode 100644 mission/tmtc/TmStoreBackend.cpp delete mode 100644 mission/tmtc/TmStoreBackend.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 43336bdd..831a7064 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -210,6 +210,7 @@ set(LIB_JSON_PATH ${THIRD_PARTY_FOLDER}/json) set(FSFW_WARNING_SHADOW_LOCAL_GCC OFF) set(EIVE_ADD_LINUX_FILES False) +set(FSFW_ADD_TMSTORAGE ON) # Analyse different OS and architecture/target options, determine BSP_PATH, # display information about compiler etc. diff --git a/fsfw b/fsfw index 56e8e5a8..096af44e 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 56e8e5a8b34dee6fcf240111618109e53b77841f +Subproject commit 096af44e39c4a94b17ee051fbdf907ddb3026a00 diff --git a/mission/tmtc/CMakeLists.txt b/mission/tmtc/CMakeLists.txt index d8dd4e1c..0f77efcd 100644 --- a/mission/tmtc/CMakeLists.txt +++ b/mission/tmtc/CMakeLists.txt @@ -6,4 +6,4 @@ target_sources( CfdpTmFunnel.cpp PusTmFunnel.cpp Service15TmStorage.cpp - TmStoreBackend.cpp) + TmStore.cpp) diff --git a/mission/tmtc/TmStore.cpp b/mission/tmtc/TmStore.cpp new file mode 100644 index 00000000..f0940ef0 --- /dev/null +++ b/mission/tmtc/TmStore.cpp @@ -0,0 +1,32 @@ +#include "TmStore.h" + +using namespace returnvalue; + +const char* TmStore::getName() const { return "TM Store Backend"; } + +MessageQueueId_t TmStore::getReportReceptionQueue(uint8_t virtualChannel) const { + return MessageQueueIF::NO_QUEUE; +} + +MessageQueueId_t TmStore::getCommandQueue() const { return MessageQueueIF::NO_QUEUE; } + +TmStoreBackendIF* TmStore::getBackend() const { return nullptr; } + +ReturnValue_t TmStore::packetRetrieved(PusTmReader* packet, uint32_t address) { return OK; } + +void TmStore::noMorePacketsInStore() {} + +void TmStore::handleRetrievalFailed(ReturnValue_t errorCode, uint32_t parameter1, + uint32_t parameter2) {} + +ReturnValue_t TmStore::fetchPackets(ApidSsc start, ApidSsc end) { return OK; } + +ReturnValue_t TmStore::deletePackets(ApidSsc upTo) { return OK; } + +ReturnValue_t TmStore::checkPacket(SpacePacketReader* tmPacket) { return OK; } + +void TmStore::setEnabled(bool enabled) {} + +void TmStore::resetDownlinkedPacketCount() {} + +ReturnValue_t TmStore::setDumpTarget(object_id_t dumpTarget) { return OK; } diff --git a/mission/tmtc/TmStore.h b/mission/tmtc/TmStore.h new file mode 100644 index 00000000..870072d1 --- /dev/null +++ b/mission/tmtc/TmStore.h @@ -0,0 +1,44 @@ +#ifndef MISSION_TMTC_TMSTOREBACKEND_H_ +#define MISSION_TMTC_TMSTOREBACKEND_H_ + +#include +#include + +class TmStore : public TmStoreFrontendIF, public AcceptsTelemetryIF { + public: + [[nodiscard]] const char* getName() const override; + [[nodiscard]] MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel) const override; + + private: + /** + * To get the queue where commands shall be sent. + * @return Id of command queue. + */ + MessageQueueId_t getCommandQueue() const override; + + TmStoreBackendIF* getBackend() const override; + + /** + * Callback from the back-end to indicate a certain packet was received. + * front-end takes care of discarding/downloading the packet. + * @param packet Pointer to the newly received Space Packet. + * @param address Start address of the packet found + * @param isLastPacket Indicates if no more packets can be fetched. + * @return If more packets shall be fetched, returnvalue::OK must be returned. + * Any other code stops fetching packets. + */ + ReturnValue_t packetRetrieved(PusTmReader* packet, uint32_t address) override; + void noMorePacketsInStore() override; + void handleRetrievalFailed(ReturnValue_t errorCode, uint32_t parameter1 = 0, + uint32_t parameter2 = 0) override; + + ReturnValue_t fetchPackets(ApidSsc start, ApidSsc end) override; + ReturnValue_t deletePackets(ApidSsc upTo) override; + ReturnValue_t checkPacket(SpacePacketReader* tmPacket) override; + bool isEnabled() const = 0; + void setEnabled(bool enabled) override; + void resetDownlinkedPacketCount() override; + ReturnValue_t setDumpTarget(object_id_t dumpTarget) override; +}; + +#endif /* MISSION_TMTC_TMSTOREBACKEND_H_ */ diff --git a/mission/tmtc/TmStoreBackend.cpp b/mission/tmtc/TmStoreBackend.cpp deleted file mode 100644 index 4362609d..00000000 --- a/mission/tmtc/TmStoreBackend.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include "TmStoreBackend.h" - -const char* TmStoreBackend::getName() const { return "TM Store Backend"; } - -MessageQueueId_t TmStoreBackend::getReportReceptionQueue(uint8_t virtualChannel) const { - return MessageQueueIF::NO_QUEUE; -} diff --git a/mission/tmtc/TmStoreBackend.h b/mission/tmtc/TmStoreBackend.h deleted file mode 100644 index f53b5227..00000000 --- a/mission/tmtc/TmStoreBackend.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef MISSION_TMTC_TMSTOREBACKEND_H_ -#define MISSION_TMTC_TMSTOREBACKEND_H_ - -#include - -class TmStoreBackend : public AcceptsTelemetryIF { - public: - [[nodiscard]] const char* getName() const override; - [[nodiscard]] MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel) const override; - - private: -}; - -#endif /* MISSION_TMTC_TMSTOREBACKEND_H_ */ From d5867f104f6b503423987eb74f463eb77fe6751b Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 25 Oct 2022 18:20:21 +0200 Subject: [PATCH 05/87] continue tm store --- linux/fsfwconfig/FSFWConfig.h.in | 2 +- mission/tmtc/TmStore.cpp | 32 +++++------------------ mission/tmtc/TmStore.h | 44 ++++++++++++++------------------ 3 files changed, 27 insertions(+), 51 deletions(-) diff --git a/linux/fsfwconfig/FSFWConfig.h.in b/linux/fsfwconfig/FSFWConfig.h.in index 25772ce7..f3d3f0f4 100644 --- a/linux/fsfwconfig/FSFWConfig.h.in +++ b/linux/fsfwconfig/FSFWConfig.h.in @@ -42,7 +42,7 @@ //! When using the newlib nano library, C99 support for stdio facilities //! will not be provided. This define should be set to 1 if this is the case. -#define FSFW_NO_C99_IO 1 +#define FSFW_NO_C99_IO 0 //! Specify whether a special mode store is used for Subsystem components. #define FSFW_USE_MODESTORE 0 diff --git a/mission/tmtc/TmStore.cpp b/mission/tmtc/TmStore.cpp index f0940ef0..12e1f4d3 100644 --- a/mission/tmtc/TmStore.cpp +++ b/mission/tmtc/TmStore.cpp @@ -1,32 +1,14 @@ #include "TmStore.h" +#include + using namespace returnvalue; -const char* TmStore::getName() const { return "TM Store Backend"; } +TmStore::TmStore(object_id_t objectId, SdCardMountedIF& sdcMan) + : SystemObject(objectId), sdcMan(sdcMan) {} -MessageQueueId_t TmStore::getReportReceptionQueue(uint8_t virtualChannel) const { - return MessageQueueIF::NO_QUEUE; +ReturnValue_t TmStore::passPacket(PusTmReader& reader) { + return returnvalue::OK; } -MessageQueueId_t TmStore::getCommandQueue() const { return MessageQueueIF::NO_QUEUE; } - -TmStoreBackendIF* TmStore::getBackend() const { return nullptr; } - -ReturnValue_t TmStore::packetRetrieved(PusTmReader* packet, uint32_t address) { return OK; } - -void TmStore::noMorePacketsInStore() {} - -void TmStore::handleRetrievalFailed(ReturnValue_t errorCode, uint32_t parameter1, - uint32_t parameter2) {} - -ReturnValue_t TmStore::fetchPackets(ApidSsc start, ApidSsc end) { return OK; } - -ReturnValue_t TmStore::deletePackets(ApidSsc upTo) { return OK; } - -ReturnValue_t TmStore::checkPacket(SpacePacketReader* tmPacket) { return OK; } - -void TmStore::setEnabled(bool enabled) {} - -void TmStore::resetDownlinkedPacketCount() {} - -ReturnValue_t TmStore::setDumpTarget(object_id_t dumpTarget) { return OK; } +MessageQueueId_t TmStore::getCommandQueue() { return MessageQueueIF::NO_QUEUE; } diff --git a/mission/tmtc/TmStore.h b/mission/tmtc/TmStore.h index 870072d1..015feef6 100644 --- a/mission/tmtc/TmStore.h +++ b/mission/tmtc/TmStore.h @@ -1,44 +1,38 @@ #ifndef MISSION_TMTC_TMSTOREBACKEND_H_ #define MISSION_TMTC_TMSTOREBACKEND_H_ +#include + +#include #include +#include #include -class TmStore : public TmStoreFrontendIF, public AcceptsTelemetryIF { +struct PacketFilter { + std::optional apid; + std::optional service; + std::optional> serviceSubservice; +}; + +class TmStore : public SystemObject { public: - [[nodiscard]] const char* getName() const override; - [[nodiscard]] MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel) const override; + TmStore(object_id_t objectId, SdCardMountedIF& sdcMan); + + ReturnValue_t passPacket(PusTmReader& reader); private: /** * To get the queue where commands shall be sent. * @return Id of command queue. */ - MessageQueueId_t getCommandQueue() const override; + MessageQueueId_t getCommandQueue(); - TmStoreBackendIF* getBackend() const override; + SdCardMountedIF& sdcMan; - /** - * Callback from the back-end to indicate a certain packet was received. - * front-end takes care of discarding/downloading the packet. - * @param packet Pointer to the newly received Space Packet. - * @param address Start address of the packet found - * @param isLastPacket Indicates if no more packets can be fetched. - * @return If more packets shall be fetched, returnvalue::OK must be returned. - * Any other code stops fetching packets. - */ - ReturnValue_t packetRetrieved(PusTmReader* packet, uint32_t address) override; - void noMorePacketsInStore() override; - void handleRetrievalFailed(ReturnValue_t errorCode, uint32_t parameter1 = 0, - uint32_t parameter2 = 0) override; - ReturnValue_t fetchPackets(ApidSsc start, ApidSsc end) override; - ReturnValue_t deletePackets(ApidSsc upTo) override; - ReturnValue_t checkPacket(SpacePacketReader* tmPacket) override; - bool isEnabled() const = 0; - void setEnabled(bool enabled) override; - void resetDownlinkedPacketCount() override; - ReturnValue_t setDumpTarget(object_id_t dumpTarget) override; + std::vector apidToStore; + std::vector servicesToStore; + std::vector> serviceSubserviceCombinationToStore; }; #endif /* MISSION_TMTC_TMSTOREBACKEND_H_ */ From 31093c0d1314ee282188f850e3627203b18168f6 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 25 Oct 2022 18:21:08 +0200 Subject: [PATCH 06/87] bump fsfw --- fsfw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fsfw b/fsfw index 096af44e..819a2bfa 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 096af44e39c4a94b17ee051fbdf907ddb3026a00 +Subproject commit 819a2bfac49babfc6a78452bb83cd581bf902bc8 From 4ca892e9f3dd2c6f21442826b6b35857da565cf8 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 11 Nov 2022 11:29:41 +0100 Subject: [PATCH 07/87] bump fsfw --- fsfw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fsfw b/fsfw index 39946bff..4d2802a4 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 39946bff58db7c5ac9016ca3156abb059560d9cb +Subproject commit 4d2802a470e5386e2bc7765c7409a99835d0c046 From 608632fde343ee3f0a2d2e900e10054077b5352b Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 11 Nov 2022 11:38:37 +0100 Subject: [PATCH 08/87] bump fsfw --- bsp_q7s/core/ObjectFactory.cpp | 12 ++++++------ fsfw | 2 +- linux/ObjectFactory.cpp | 2 +- linux/boardtest/UartTestClass.cpp | 2 +- linux/boardtest/UartTestClass.h | 2 +- linux/devices/ScexUartReader.cpp | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index f5397e04..52e39cdd 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -572,8 +572,8 @@ void ObjectFactory::createSolarArrayDeploymentComponents(PowerSwitchIF& pwrSwitc } void ObjectFactory::createSyrlinksComponents(PowerSwitchIF* pwrSwitcher) { - UartCookie* syrlinksUartCookie = - new UartCookie(objects::SYRLINKS_HK_HANDLER, q7s::UART_SYRLINKS_DEV, uart::SYRLINKS_BAUD, + SerialCookie* syrlinksUartCookie = + new SerialCookie(objects::SYRLINKS_HK_HANDLER, q7s::UART_SYRLINKS_DEV, uart::SYRLINKS_BAUD, syrlinks::MAX_REPLY_SIZE, UartModes::NON_CANONICAL); syrlinksUartCookie->setParityEven(); @@ -602,7 +602,7 @@ void ObjectFactory::createPayloadComponents(LinuxLibgpioIF* gpioComIF, PowerSwit mpsocGpioCookie->addGpio(gpioIds::ENABLE_MPSOC_UART, gpioConfigMPSoC); gpioChecker(gpioComIF->addGpios(mpsocGpioCookie), "PLOC MPSoC"); auto mpsocCookie = - new UartCookie(objects::PLOC_MPSOC_HANDLER, q7s::UART_PLOC_MPSOC_DEV, uart::PLOC_MPSOC_BAUD, + new SerialCookie(objects::PLOC_MPSOC_HANDLER, q7s::UART_PLOC_MPSOC_DEV, uart::PLOC_MPSOC_BAUD, mpsoc::MAX_REPLY_SIZE, UartModes::NON_CANONICAL); mpsocCookie->setNoFixedSizeReply(); auto plocMpsocHelper = new PlocMPSoCHelper(objects::PLOC_MPSOC_HELPER); @@ -619,7 +619,7 @@ void ObjectFactory::createPayloadComponents(LinuxLibgpioIF* gpioComIF, PowerSwit supvGpioCookie->addGpio(gpioIds::ENABLE_SUPV_UART, gpioConfigSupv); gpioComIF->addGpios(supvGpioCookie); auto supervisorCookie = - new UartCookie(objects::PLOC_SUPERVISOR_HANDLER, q7s::UART_PLOC_SUPERVSIOR_DEV, + new SerialCookie(objects::PLOC_SUPERVISOR_HANDLER, q7s::UART_PLOC_SUPERVSIOR_DEV, uart::PLOC_SUPV_BAUD, supv::MAX_PACKET_SIZE * 20, UartModes::NON_CANONICAL); supervisorCookie->setNoFixedSizeReply(); auto supvHelper = new PlocSupvHelper(objects::PLOC_SUPERVISOR_HELPER); @@ -905,8 +905,8 @@ void ObjectFactory::createTestComponents(LinuxLibgpioIF* gpioComIF) { } void ObjectFactory::createStrComponents(PowerSwitchIF* pwrSwitcher) { - UartCookie* starTrackerCookie = - new UartCookie(objects::STAR_TRACKER, q7s::UART_STAR_TRACKER_DEV, uart::STAR_TRACKER_BAUD, + SerialCookie* starTrackerCookie = + new SerialCookie(objects::STAR_TRACKER, q7s::UART_STAR_TRACKER_DEV, uart::STAR_TRACKER_BAUD, startracker::MAX_FRAME_SIZE * 2 + 2, UartModes::NON_CANONICAL); starTrackerCookie->setNoFixedSizeReply(); StrHelper* strHelper = new StrHelper(objects::STR_HELPER); diff --git a/fsfw b/fsfw index 4d2802a4..046dbe1d 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 4d2802a470e5386e2bc7765c7409a99835d0c046 +Subproject commit 046dbe1deb8053f64d7ef85992dec22aea9a3a10 diff --git a/linux/ObjectFactory.cpp b/linux/ObjectFactory.cpp index 21f884f9..e35d7e96 100644 --- a/linux/ObjectFactory.cpp +++ b/linux/ObjectFactory.cpp @@ -326,7 +326,7 @@ void ObjectFactory::createRtdComponents(std::string spiDev, GpioIF* gpioComIF, void ObjectFactory::createScexComponents(std::string uartDev, PowerSwitchIF* pwrSwitcher, SdCardMountedIF& mountedIF, bool onImmediately, std::optional switchId) { - auto* cookie = new UartCookie(objects::SCEX, uartDev, uart::SCEX_BAUD, 4096); + auto* cookie = new SerialCookie(objects::SCEX, uartDev, uart::SCEX_BAUD, 4096); cookie->setTwoStopBits(); // cookie->setParityEven(); auto scexUartReader = new ScexUartReader(objects::SCEX_UART_READER); diff --git a/linux/boardtest/UartTestClass.cpp b/linux/boardtest/UartTestClass.cpp index 2c914d74..51ea237f 100644 --- a/linux/boardtest/UartTestClass.cpp +++ b/linux/boardtest/UartTestClass.cpp @@ -164,7 +164,7 @@ void UartTestClass::scexInit() { #else std::string devname = "/dev/ul-scex"; #endif - uartCookie = new UartCookie(this->getObjectId(), devname, UartBaudRate::RATE_57600, 4096); + uartCookie = new SerialCookie(this->getObjectId(), devname, UartBaudRate::RATE_57600, 4096); reader->setDebugMode(false); ReturnValue_t result = reader->initializeInterface(uartCookie); if (result != OK) { diff --git a/linux/boardtest/UartTestClass.h b/linux/boardtest/UartTestClass.h index 6304724b..05776bc0 100644 --- a/linux/boardtest/UartTestClass.h +++ b/linux/boardtest/UartTestClass.h @@ -57,7 +57,7 @@ class UartTestClass : public TestTask { scex::Cmds currCmd = scex::Cmds::PING; TestModes mode = TestModes::GPS; DleEncoder dleEncoder = DleEncoder(); - UartCookie* uartCookie = nullptr; + SerialCookie* uartCookie = nullptr; size_t encodedLen = 0; lwgps_t gpsData = {}; struct termios tty = {}; diff --git a/linux/devices/ScexUartReader.cpp b/linux/devices/ScexUartReader.cpp index ce59472d..6f615014 100644 --- a/linux/devices/ScexUartReader.cpp +++ b/linux/devices/ScexUartReader.cpp @@ -84,7 +84,7 @@ ReturnValue_t ScexUartReader::performOperation(uint8_t operationCode) { } ReturnValue_t ScexUartReader::initializeInterface(CookieIF *cookie) { - UartCookie *uartCookie = dynamic_cast(cookie); + SerialCookie *uartCookie = dynamic_cast(cookie); if (uartCookie == nullptr) { return FAILED; } From f60a80f308b9ef6159bf1d698c65314d5d25da12 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 11 Nov 2022 11:43:42 +0100 Subject: [PATCH 09/87] fix merge conflict --- bsp_q7s/core/ObjectFactory.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index 85c0fd9f..6dc08ca1 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -905,11 +905,7 @@ void ObjectFactory::createTestComponents(LinuxLibgpioIF* gpioComIF) { } void ObjectFactory::createStrComponents(PowerSwitchIF* pwrSwitcher) { -<<<<<<< HEAD - SerialCookie* starTrackerCookie = -======= auto* starTrackerCookie = ->>>>>>> origin/develop new SerialCookie(objects::STAR_TRACKER, q7s::UART_STAR_TRACKER_DEV, uart::STAR_TRACKER_BAUD, startracker::MAX_FRAME_SIZE * 2 + 2, UartModes::NON_CANONICAL); starTrackerCookie->setNoFixedSizeReply(); From c599714aea0834a98482e898389b313c4441916c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 11 Nov 2022 15:39:27 +0100 Subject: [PATCH 10/87] some sort of filter handling --- bsp_q7s/core/ObjectFactory.cpp | 8 +++---- fsfw | 2 +- mission/tmtc/CMakeLists.txt | 10 +++++++-- mission/tmtc/TmStore.cpp | 39 ++++++++++++++++++++++++++++++++-- mission/tmtc/TmStore.h | 19 ++++++----------- 5 files changed, 57 insertions(+), 21 deletions(-) diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index 6dc08ca1..b110e82a 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -574,7 +574,7 @@ void ObjectFactory::createSolarArrayDeploymentComponents(PowerSwitchIF& pwrSwitc void ObjectFactory::createSyrlinksComponents(PowerSwitchIF* pwrSwitcher) { auto* syrlinksUartCookie = new SerialCookie(objects::SYRLINKS_HK_HANDLER, q7s::UART_SYRLINKS_DEV, uart::SYRLINKS_BAUD, - syrlinks::MAX_REPLY_SIZE, UartModes::NON_CANONICAL); + syrlinks::MAX_REPLY_SIZE, UartModes::NON_CANONICAL); syrlinksUartCookie->setParityEven(); auto syrlinksFdir = new SyrlinksFdir(objects::SYRLINKS_HK_HANDLER); @@ -603,7 +603,7 @@ void ObjectFactory::createPayloadComponents(LinuxLibgpioIF* gpioComIF, PowerSwit gpioChecker(gpioComIF->addGpios(mpsocGpioCookie), "PLOC MPSoC"); auto mpsocCookie = new SerialCookie(objects::PLOC_MPSOC_HANDLER, q7s::UART_PLOC_MPSOC_DEV, uart::PLOC_MPSOC_BAUD, - mpsoc::MAX_REPLY_SIZE, UartModes::NON_CANONICAL); + mpsoc::MAX_REPLY_SIZE, UartModes::NON_CANONICAL); mpsocCookie->setNoFixedSizeReply(); auto plocMpsocHelper = new PlocMPSoCHelper(objects::PLOC_MPSOC_HELPER); auto* mpsocHandler = new PlocMPSoCHandler( @@ -620,7 +620,7 @@ void ObjectFactory::createPayloadComponents(LinuxLibgpioIF* gpioComIF, PowerSwit gpioComIF->addGpios(supvGpioCookie); auto supervisorCookie = new SerialCookie(objects::PLOC_SUPERVISOR_HANDLER, q7s::UART_PLOC_SUPERVSIOR_DEV, - uart::PLOC_SUPV_BAUD, supv::MAX_PACKET_SIZE * 20, UartModes::NON_CANONICAL); + uart::PLOC_SUPV_BAUD, supv::MAX_PACKET_SIZE * 20, UartModes::NON_CANONICAL); supervisorCookie->setNoFixedSizeReply(); auto supvHelper = new PlocSupvHelper(objects::PLOC_SUPERVISOR_HELPER); auto* supvHandler = new PlocSupervisorHandler( @@ -907,7 +907,7 @@ void ObjectFactory::createTestComponents(LinuxLibgpioIF* gpioComIF) { void ObjectFactory::createStrComponents(PowerSwitchIF* pwrSwitcher) { auto* starTrackerCookie = new SerialCookie(objects::STAR_TRACKER, q7s::UART_STAR_TRACKER_DEV, uart::STAR_TRACKER_BAUD, - startracker::MAX_FRAME_SIZE * 2 + 2, UartModes::NON_CANONICAL); + startracker::MAX_FRAME_SIZE * 2 + 2, UartModes::NON_CANONICAL); starTrackerCookie->setNoFixedSizeReply(); StrHelper* strHelper = new StrHelper(objects::STR_HELPER); auto starTracker = diff --git a/fsfw b/fsfw index 046dbe1d..2b6a33e7 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 046dbe1deb8053f64d7ef85992dec22aea9a3a10 +Subproject commit 2b6a33e718f896300ca08345a9211c2ae974d014 diff --git a/mission/tmtc/CMakeLists.txt b/mission/tmtc/CMakeLists.txt index 3c631be7..cc84aabb 100644 --- a/mission/tmtc/CMakeLists.txt +++ b/mission/tmtc/CMakeLists.txt @@ -1,4 +1,10 @@ target_sources( ${LIB_EIVE_MISSION} - PRIVATE CcsdsIpCoreHandler.cpp VirtualChannel.cpp TmFunnelHandler.cpp - TmFunnelBase.cpp CfdpTmFunnel.cpp Service15TmStorage.cpp TmStore.cpp PusTmFunnel.cpp) + PRIVATE CcsdsIpCoreHandler.cpp + VirtualChannel.cpp + TmFunnelHandler.cpp + TmFunnelBase.cpp + CfdpTmFunnel.cpp + Service15TmStorage.cpp + TmStore.cpp + PusTmFunnel.cpp) diff --git a/mission/tmtc/TmStore.cpp b/mission/tmtc/TmStore.cpp index 12e1f4d3..3033b001 100644 --- a/mission/tmtc/TmStore.cpp +++ b/mission/tmtc/TmStore.cpp @@ -1,14 +1,49 @@ #include "TmStore.h" + #include +#include using namespace returnvalue; -TmStore::TmStore(object_id_t objectId, SdCardMountedIF& sdcMan) - : SystemObject(objectId), sdcMan(sdcMan) {} +TmStore::TmStore(object_id_t objectId, std::string baseName, PacketFilter filter, SdCardMountedIF& sdcMan) + : SystemObject(objectId), filter(filter), sdcMan(sdcMan) {} ReturnValue_t TmStore::passPacket(PusTmReader& reader) { + bool inApidList = false; + if (filter.apid) { + auto& apidFilter = filter.apid.value(); + if (std::find(apidFilter.begin(), apidFilter.end(), reader.getApid()) != apidFilter.end()) { + if (not filter.serviceSubservices and not filter.services) { + return storePacket(reader); + } + inApidList = true; + } + } + std::pair serviceSubservice; + serviceSubservice.first = reader.getService(); + serviceSubservice.second = reader.getSubService(); + if (filter.services) { + auto& serviceFilter = filter.services.value(); + if (std::find(serviceFilter.begin(), serviceFilter.end(), serviceSubservice.first) != + serviceFilter.end()) { + if (filter.apid and inApidList) { + return storePacket(reader); + } + } + } + if (filter.serviceSubservices) { + auto& serviceSubserviceFilter = filter.serviceSubservices.value(); + if (std::find(serviceSubserviceFilter.begin(), serviceSubserviceFilter.end(), + serviceSubservice) != serviceSubserviceFilter.end()) { + if (filter.apid and inApidList) { + return storePacket(reader); + } + } + } return returnvalue::OK; } +ReturnValue_t TmStore::storePacket(PusTmReader& reader) { return returnvalue::OK; } + MessageQueueId_t TmStore::getCommandQueue() { return MessageQueueIF::NO_QUEUE; } diff --git a/mission/tmtc/TmStore.h b/mission/tmtc/TmStore.h index 015feef6..7d8cb144 100644 --- a/mission/tmtc/TmStore.h +++ b/mission/tmtc/TmStore.h @@ -1,24 +1,24 @@ #ifndef MISSION_TMTC_TMSTOREBACKEND_H_ #define MISSION_TMTC_TMSTOREBACKEND_H_ -#include - #include #include #include #include +#include struct PacketFilter { - std::optional apid; - std::optional service; - std::optional> serviceSubservice; + std::optional> apid; + std::optional> services; + std::optional>> serviceSubservices; }; class TmStore : public SystemObject { public: - TmStore(object_id_t objectId, SdCardMountedIF& sdcMan); + TmStore(object_id_t objectId, std::string baseName, PacketFilter filter, SdCardMountedIF& sdcMan); ReturnValue_t passPacket(PusTmReader& reader); + ReturnValue_t storePacket(PusTmReader& reader); private: /** @@ -26,13 +26,8 @@ class TmStore : public SystemObject { * @return Id of command queue. */ MessageQueueId_t getCommandQueue(); - + PacketFilter filter; SdCardMountedIF& sdcMan; - - - std::vector apidToStore; - std::vector servicesToStore; - std::vector> serviceSubserviceCombinationToStore; }; #endif /* MISSION_TMTC_TMSTOREBACKEND_H_ */ From da98cd77e89f0fc7f4f63dc703dc66cb6863fbff Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 24 Nov 2022 15:16:42 +0100 Subject: [PATCH 11/87] bump fsfw --- fsfw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fsfw b/fsfw index 160ff799..296bc56e 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 160ff799ace61e24708dcf1fdeaf5fafdf23a4ca +Subproject commit 296bc56e2a1acb0e4d84efd5189845192ddc1de2 From fba820a1c0db8e22125c75e432fed8e2258d762d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 12 Dec 2022 10:06:30 +0100 Subject: [PATCH 12/87] start storage algorithms --- bsp_hosted/scheduling.cpp | 2 +- .../devicedefinitions/GPSDefinitions.h | 2 +- mission/tmtc/TmStore.cpp | 37 +++++++++++++++++-- mission/tmtc/TmStore.h | 13 ++++++- unittest/controller/testThermalController.cpp | 2 +- 5 files changed, 49 insertions(+), 7 deletions(-) diff --git a/bsp_hosted/scheduling.cpp b/bsp_hosted/scheduling.cpp index 19df002f..2e73bbf5 100644 --- a/bsp_hosted/scheduling.cpp +++ b/bsp_hosted/scheduling.cpp @@ -185,7 +185,7 @@ void scheduling::initTasks() { #endif /* OBSW_ADD_TEST_CODE == 1 */ PeriodicTaskIF* dummyTask = factory->createPeriodicTask( - "DUMMY_TASK", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.0, missedDeadlineFunc); + "DUMMY_TASK", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.0, missedDeadlineFunc); dummyTask->addComponent(objects::SUS_0_N_LOC_XFYFZM_PT_XF); dummyTask->addComponent(objects::SUS_1_N_LOC_XBYFZM_PT_XB); dummyTask->addComponent(objects::SUS_2_N_LOC_XFYBZB_PT_YB); diff --git a/mission/devices/devicedefinitions/GPSDefinitions.h b/mission/devices/devicedefinitions/GPSDefinitions.h index 7653745f..387d08be 100644 --- a/mission/devices/devicedefinitions/GPSDefinitions.h +++ b/mission/devices/devicedefinitions/GPSDefinitions.h @@ -1,9 +1,9 @@ #ifndef MISSION_DEVICES_DEVICEDEFINITIONS_GPSDEFINITIONS_H_ #define MISSION_DEVICES_DEVICEDEFINITIONS_GPSDEFINITIONS_H_ +#include "eive/eventSubsystemIds.h" #include "fsfw/datapoollocal/StaticLocalDataSet.h" #include "fsfw/devicehandlers/DeviceHandlerIF.h" -#include "eive/eventSubsystemIds.h" namespace GpsHyperion { diff --git a/mission/tmtc/TmStore.cpp b/mission/tmtc/TmStore.cpp index 3033b001..8429491c 100644 --- a/mission/tmtc/TmStore.cpp +++ b/mission/tmtc/TmStore.cpp @@ -3,11 +3,18 @@ #include #include +#include using namespace returnvalue; -TmStore::TmStore(object_id_t objectId, std::string baseName, PacketFilter filter, SdCardMountedIF& sdcMan) - : SystemObject(objectId), filter(filter), sdcMan(sdcMan) {} +TmStore::TmStore(object_id_t objectId, std::string baseName, RolloverInterval interval, + uint8_t intervalFactor, PacketFilter filter, SdCardMountedIF& sdcMan) + : SystemObject(objectId), + filter(filter), + baseName(std::move(baseName)), + interval(interval), + intervalFactor(intervalFactor), + sdcMan(sdcMan) {} ReturnValue_t TmStore::passPacket(PusTmReader& reader) { bool inApidList = false; @@ -44,6 +51,30 @@ ReturnValue_t TmStore::passPacket(PusTmReader& reader) { return returnvalue::OK; } -ReturnValue_t TmStore::storePacket(PusTmReader& reader) { return returnvalue::OK; } +ReturnValue_t TmStore::storePacket(PusTmReader& reader) { + using namespace std::filesystem; + std::string currentPrefix = sdcMan.getCurrentMountPrefix(); + path baseDir = currentPrefix / baseName; + // It is assumed here that the filesystem is usable. + if (not exists(baseDir)) { + create_directory(baseDir); + } + if (not mostRecentFile) { + // TODO: Find most recent file by iterating through all files and remembering the file + // with the most recent timestamp. + for (auto const& file : directory_iterator(baseDir)) { + if (file.is_directory()) { + continue; + } + auto path = file.path(); + // TODO: Scan file timestamp from name somehow. Maybe use scanf or similar? + } + } + // TODO: Need to find the file of the most recent file. + // TODO: If file exists: Determine whether file rolls over: Maximum file size reached? Interval + // since last timestamp exceeds rollover interval? + // TODO: If file does not exist or rollover criteria met: Create new file with current timestamp. + return returnvalue::OK; +} MessageQueueId_t TmStore::getCommandQueue() { return MessageQueueIF::NO_QUEUE; } diff --git a/mission/tmtc/TmStore.h b/mission/tmtc/TmStore.h index 7d8cb144..7402921e 100644 --- a/mission/tmtc/TmStore.h +++ b/mission/tmtc/TmStore.h @@ -13,20 +13,31 @@ struct PacketFilter { std::optional>> serviceSubservices; }; +enum class RolloverInterval { HOURLY, DAILY }; + class TmStore : public SystemObject { public: - TmStore(object_id_t objectId, std::string baseName, PacketFilter filter, SdCardMountedIF& sdcMan); + TmStore(object_id_t objectId, std::string baseName, RolloverInterval interval, + uint8_t intervalFactor, PacketFilter filter, SdCardMountedIF& sdcMan); ReturnValue_t passPacket(PusTmReader& reader); ReturnValue_t storePacket(PusTmReader& reader); private: + static constexpr size_t MAX_FILESIZE = 8192; + /** * To get the queue where commands shall be sent. * @return Id of command queue. */ MessageQueueId_t getCommandQueue(); PacketFilter filter; + std::string baseName; + RolloverInterval interval; + uint8_t intervalFactor; + char NAME_BUF[524] = {}; + std::array fileBuf{}; + std::optional mostRecentFile; SdCardMountedIF& sdcMan; }; diff --git a/unittest/controller/testThermalController.cpp b/unittest/controller/testThermalController.cpp index 1c5f63fe..44fba918 100644 --- a/unittest/controller/testThermalController.cpp +++ b/unittest/controller/testThermalController.cpp @@ -13,7 +13,7 @@ TEST_CASE("Thermal Controller", "[ThermalController]") { const object_id_t THERMAL_CONTROLLER_ID = 0x123; new TemperatureSensorsDummy(); - //new SusDummy(); + // new SusDummy(); // testEnvironment::initialize(); From c493273a21196c45385c663e779a4c7da9178e14 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 12 Dec 2022 14:58:56 +0100 Subject: [PATCH 13/87] oh god sscanf --- mission/tmtc/TmStore.cpp | 12 +++++++++++- tmtc | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/mission/tmtc/TmStore.cpp b/mission/tmtc/TmStore.cpp index 8429491c..331348ab 100644 --- a/mission/tmtc/TmStore.cpp +++ b/mission/tmtc/TmStore.cpp @@ -4,6 +4,7 @@ #include #include +#include using namespace returnvalue; @@ -66,8 +67,17 @@ ReturnValue_t TmStore::storePacket(PusTmReader& reader) { if (file.is_directory()) { continue; } - auto path = file.path(); + auto pathStr = file.path().string(); + Clock::TimeOfDay_t tod; + if(pathStr.find(baseName) == std::string::npos) { + continue; + } + float seconds = 0.0; + char* prefix = nullptr; // TODO: Scan file timestamp from name somehow. Maybe use scanf or similar? + int count = sscanf(pathStr.c_str(), "%s%4" SCNu32 "-%2" SCNu32 "-%2" + SCNu32 "T%2" SCNu32 ":%2" SCNu32 ":%fZ", prefix, &tod.year, &tod.month, &tod.day, + &tod.hour, &tod.minute, &seconds); } } // TODO: Need to find the file of the most recent file. diff --git a/tmtc b/tmtc index 96e27e71..a55572db 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 96e27e716349bf01cac11c7e7b0b497a36149e87 +Subproject commit a55572db2890ef9e8276c95ba8ebfb2d74a88f7c From 6f1f92c9d13e7ab958f7249c91c341aaa6356bba Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 12 Dec 2022 16:04:38 +0100 Subject: [PATCH 14/87] i wonder if this even works --- mission/tmtc/TmStore.cpp | 5 +++-- tmtc | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/mission/tmtc/TmStore.cpp b/mission/tmtc/TmStore.cpp index 331348ab..960a2054 100644 --- a/mission/tmtc/TmStore.cpp +++ b/mission/tmtc/TmStore.cpp @@ -74,10 +74,11 @@ ReturnValue_t TmStore::storePacket(PusTmReader& reader) { } float seconds = 0.0; char* prefix = nullptr; - // TODO: Scan file timestamp from name somehow. Maybe use scanf or similar? - int count = sscanf(pathStr.c_str(), "%s%4" SCNu32 "-%2" SCNu32 "-%2" + int count = sscanf(pathStr.c_str(), "%s_%4" SCNu32 "-%2" SCNu32 "-%2" SCNu32 "T%2" SCNu32 ":%2" SCNu32 ":%fZ", prefix, &tod.year, &tod.month, &tod.day, &tod.hour, &tod.minute, &seconds); + tod.second = std::floor(seconds); + static_cast(count); } } // TODO: Need to find the file of the most recent file. diff --git a/tmtc b/tmtc index a55572db..30cf4736 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit a55572db2890ef9e8276c95ba8ebfb2d74a88f7c +Subproject commit 30cf47365fec68a4b78395de03ecb2ae95af4e7e From 279697b326eaaa9ec9805b322609fad0b2e636c9 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 12 Dec 2022 16:18:00 +0100 Subject: [PATCH 15/87] test stamp in filename --- mission/tmtc/TmStore.cpp | 14 +++++++------- unittest/CMakeLists.txt | 1 + unittest/testStampInFilename.cpp | 18 ++++++++++++++++++ 3 files changed, 26 insertions(+), 7 deletions(-) create mode 100644 unittest/testStampInFilename.cpp diff --git a/mission/tmtc/TmStore.cpp b/mission/tmtc/TmStore.cpp index 960a2054..a2aec09c 100644 --- a/mission/tmtc/TmStore.cpp +++ b/mission/tmtc/TmStore.cpp @@ -3,8 +3,8 @@ #include #include -#include #include +#include using namespace returnvalue; @@ -55,7 +55,7 @@ ReturnValue_t TmStore::passPacket(PusTmReader& reader) { ReturnValue_t TmStore::storePacket(PusTmReader& reader) { using namespace std::filesystem; std::string currentPrefix = sdcMan.getCurrentMountPrefix(); - path baseDir = currentPrefix / baseName; + path baseDir = path(currentPrefix) / baseName; // It is assumed here that the filesystem is usable. if (not exists(baseDir)) { create_directory(baseDir); @@ -69,14 +69,14 @@ ReturnValue_t TmStore::storePacket(PusTmReader& reader) { } auto pathStr = file.path().string(); Clock::TimeOfDay_t tod; - if(pathStr.find(baseName) == std::string::npos) { - continue; + if (pathStr.find(baseName) == std::string::npos) { + continue; } float seconds = 0.0; char* prefix = nullptr; - int count = sscanf(pathStr.c_str(), "%s_%4" SCNu32 "-%2" SCNu32 "-%2" - SCNu32 "T%2" SCNu32 ":%2" SCNu32 ":%fZ", prefix, &tod.year, &tod.month, &tod.day, - &tod.hour, &tod.minute, &seconds); + int count = sscanf(pathStr.c_str(), + "%s_%4" SCNu32 "-%2" SCNu32 "-%2" SCNu32 "T%2" SCNu32 ":%2" SCNu32 ":%fZ", + prefix, &tod.year, &tod.month, &tod.day, &tod.hour, &tod.minute, &seconds); tod.second = std::floor(seconds); static_cast(count); } diff --git a/unittest/CMakeLists.txt b/unittest/CMakeLists.txt index 1786b71e..977b794f 100644 --- a/unittest/CMakeLists.txt +++ b/unittest/CMakeLists.txt @@ -4,5 +4,6 @@ add_subdirectory(mocks) target_sources(${UNITTEST_NAME} PRIVATE main.cpp testEnvironment.cpp + testStampInFilename.cpp printChar.cpp ) \ No newline at end of file diff --git a/unittest/testStampInFilename.cpp b/unittest/testStampInFilename.cpp new file mode 100644 index 00000000..33a0f5a6 --- /dev/null +++ b/unittest/testStampInFilename.cpp @@ -0,0 +1,18 @@ + +#include +#include + +#include "fsfw/timemanager/Clock.h" + +TEST_CASE("Stamp in Filename", "[Stamp In Filename]") { + Clock::TimeOfDay_t tod; + std::string baseName = "verif"; + std::string pathStr = "verif_2022-05-25T16:55:23Z.bin"; + float seconds = 0.0; + char* prefix = nullptr; + int count = + sscanf(pathStr.c_str(), + "%s_%4" SCNu32 "-%2" SCNu32 "-%2" SCNu32 "T%2" SCNu32 ":%2" SCNu32 ":%2" SCNu32 "Z", + prefix, &tod.year, &tod.month, &tod.day, &tod.hour, &tod.minute, &tod.second); + static_cast(count); +} From a9699ad96910bc6ccb3fb95b0f5ce8e27e1ac20b Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 12 Dec 2022 16:30:16 +0100 Subject: [PATCH 16/87] this should work --- unittest/testStampInFilename.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/unittest/testStampInFilename.cpp b/unittest/testStampInFilename.cpp index 33a0f5a6..c66bdce6 100644 --- a/unittest/testStampInFilename.cpp +++ b/unittest/testStampInFilename.cpp @@ -8,11 +8,14 @@ TEST_CASE("Stamp in Filename", "[Stamp In Filename]") { Clock::TimeOfDay_t tod; std::string baseName = "verif"; std::string pathStr = "verif_2022-05-25T16:55:23Z.bin"; + unsigned int underscorePos = pathStr.find_last_of('_'); + std::string stampStr = pathStr.substr(underscorePos + 1); float seconds = 0.0; char* prefix = nullptr; int count = - sscanf(pathStr.c_str(), - "%s_%4" SCNu32 "-%2" SCNu32 "-%2" SCNu32 "T%2" SCNu32 ":%2" SCNu32 ":%2" SCNu32 "Z", - prefix, &tod.year, &tod.month, &tod.day, &tod.hour, &tod.minute, &tod.second); + sscanf(stampStr.c_str(), + "%4" SCNu32 "-%2" SCNu32 "-%2" SCNu32 "T%2" SCNu32 ":%2" SCNu32 ":%2" SCNu32 "Z", + &tod.year, &tod.month, &tod.day, &tod.hour, &tod.minute, &tod.second); static_cast(count); + CHECK(count == 6); } From 293082a7e8684f05dda81e29a51a235c8ab26cf2 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 12 Dec 2022 18:17:59 +0100 Subject: [PATCH 17/87] this logic should work --- mission/tmtc/TmStore.cpp | 24 +++++++++++++++--------- mission/tmtc/TmStore.h | 5 ++++- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/mission/tmtc/TmStore.cpp b/mission/tmtc/TmStore.cpp index a2aec09c..55a47347 100644 --- a/mission/tmtc/TmStore.cpp +++ b/mission/tmtc/TmStore.cpp @@ -61,8 +61,6 @@ ReturnValue_t TmStore::storePacket(PusTmReader& reader) { create_directory(baseDir); } if (not mostRecentFile) { - // TODO: Find most recent file by iterating through all files and remembering the file - // with the most recent timestamp. for (auto const& file : directory_iterator(baseDir)) { if (file.is_directory()) { continue; @@ -72,13 +70,21 @@ ReturnValue_t TmStore::storePacket(PusTmReader& reader) { if (pathStr.find(baseName) == std::string::npos) { continue; } - float seconds = 0.0; - char* prefix = nullptr; - int count = sscanf(pathStr.c_str(), - "%s_%4" SCNu32 "-%2" SCNu32 "-%2" SCNu32 "T%2" SCNu32 ":%2" SCNu32 ":%fZ", - prefix, &tod.year, &tod.month, &tod.day, &tod.hour, &tod.minute, &seconds); - tod.second = std::floor(seconds); - static_cast(count); + unsigned int underscorePos = pathStr.find_last_of('_'); + std::string stampStr = pathStr.substr(underscorePos + 1); + int count = + sscanf(stampStr.c_str(), + "%4" SCNu32 "-%2" SCNu32 "-%2" SCNu32 "T%2" SCNu32 ":%2" SCNu32 ":%2" SCNu32 "Z", + &tod.year, &tod.month, &tod.day, &tod.hour, &tod.minute, &tod.second); + if (count != 6) { + continue; + } + timeval tv{}; + Clock::convertTimeOfDayToTimeval(&tod, &tv); + if (not mostRecentTv || tv > mostRecentTv.value()) { + mostRecentTv = tv; + mostRecentFile = file.path(); + } } } // TODO: Need to find the file of the most recent file. diff --git a/mission/tmtc/TmStore.h b/mission/tmtc/TmStore.h index 7402921e..a2638d2b 100644 --- a/mission/tmtc/TmStore.h +++ b/mission/tmtc/TmStore.h @@ -7,6 +7,8 @@ #include #include +#include + struct PacketFilter { std::optional> apid; std::optional> services; @@ -37,7 +39,8 @@ class TmStore : public SystemObject { uint8_t intervalFactor; char NAME_BUF[524] = {}; std::array fileBuf{}; - std::optional mostRecentFile; + std::optional mostRecentTv; + std::optional mostRecentFile; SdCardMountedIF& sdcMan; }; From ed603f4e48914e7b7133340b266bfdb1c7df4e5d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 12 Dec 2022 18:27:01 +0100 Subject: [PATCH 18/87] continued TM store impl --- mission/tmtc/TmStore.cpp | 94 ++++++++++++++++++++++++---------------- mission/tmtc/TmStore.h | 13 ++++-- 2 files changed, 65 insertions(+), 42 deletions(-) diff --git a/mission/tmtc/TmStore.cpp b/mission/tmtc/TmStore.cpp index 55a47347..5c3f00c8 100644 --- a/mission/tmtc/TmStore.cpp +++ b/mission/tmtc/TmStore.cpp @@ -8,14 +8,11 @@ using namespace returnvalue; -TmStore::TmStore(object_id_t objectId, std::string baseName, RolloverInterval interval, - uint8_t intervalFactor, PacketFilter filter, SdCardMountedIF& sdcMan) - : SystemObject(objectId), - filter(filter), - baseName(std::move(baseName)), - interval(interval), - intervalFactor(intervalFactor), - sdcMan(sdcMan) {} +TmStore::TmStore(object_id_t objectId, std::string baseName, RolloverInterval intervalUnit, + uint32_t intervalCount, PacketFilter filter, SdCardMountedIF& sdcMan) + : SystemObject(objectId), filter(filter), baseName(std::move(baseName)), sdcMan(sdcMan) { + calcDiffSeconds(intervalUnit, intervalCount); +} ReturnValue_t TmStore::passPacket(PusTmReader& reader) { bool inApidList = false; @@ -54,38 +51,12 @@ ReturnValue_t TmStore::passPacket(PusTmReader& reader) { ReturnValue_t TmStore::storePacket(PusTmReader& reader) { using namespace std::filesystem; - std::string currentPrefix = sdcMan.getCurrentMountPrefix(); - path baseDir = path(currentPrefix) / baseName; - // It is assumed here that the filesystem is usable. - if (not exists(baseDir)) { - create_directory(baseDir); + if (baseDirUninitialized) { + updateBaseDir(); } + // It is assumed here that the filesystem is usable. if (not mostRecentFile) { - for (auto const& file : directory_iterator(baseDir)) { - if (file.is_directory()) { - continue; - } - auto pathStr = file.path().string(); - Clock::TimeOfDay_t tod; - if (pathStr.find(baseName) == std::string::npos) { - continue; - } - unsigned int underscorePos = pathStr.find_last_of('_'); - std::string stampStr = pathStr.substr(underscorePos + 1); - int count = - sscanf(stampStr.c_str(), - "%4" SCNu32 "-%2" SCNu32 "-%2" SCNu32 "T%2" SCNu32 ":%2" SCNu32 ":%2" SCNu32 "Z", - &tod.year, &tod.month, &tod.day, &tod.hour, &tod.minute, &tod.second); - if (count != 6) { - continue; - } - timeval tv{}; - Clock::convertTimeOfDayToTimeval(&tod, &tv); - if (not mostRecentTv || tv > mostRecentTv.value()) { - mostRecentTv = tv; - mostRecentFile = file.path(); - } - } + assignMostRecentFile(); } // TODO: Need to find the file of the most recent file. // TODO: If file exists: Determine whether file rolls over: Maximum file size reached? Interval @@ -95,3 +66,50 @@ ReturnValue_t TmStore::storePacket(PusTmReader& reader) { } MessageQueueId_t TmStore::getCommandQueue() { return MessageQueueIF::NO_QUEUE; } + +void TmStore::calcDiffSeconds(RolloverInterval intervalUnit, uint32_t intervalCount) { + if (intervalUnit == RolloverInterval::HOURLY) { + rolloverDiffSeconds = 60 * intervalCount; + } else if (intervalUnit == RolloverInterval::DAILY) { + rolloverDiffSeconds = 60 * 24 * intervalCount; + } +} + +void TmStore::updateBaseDir() { + using namespace std::filesystem; + std::string currentPrefix = sdcMan.getCurrentMountPrefix(); + baseDir = path(currentPrefix) / baseName; + if (not exists(baseDir)) { + create_directory(baseDir); + } + baseDirUninitialized = false; +} + +void TmStore::assignMostRecentFile() { + using namespace std::filesystem; + for (auto const& file : directory_iterator(baseDir)) { + if (file.is_directory()) { + continue; + } + auto pathStr = file.path().string(); + Clock::TimeOfDay_t tod; + if (pathStr.find(baseName) == std::string::npos) { + continue; + } + unsigned int underscorePos = pathStr.find_last_of('_'); + std::string stampStr = pathStr.substr(underscorePos + 1); + int count = + sscanf(stampStr.c_str(), + "%4" SCNu32 "-%2" SCNu32 "-%2" SCNu32 "T%2" SCNu32 ":%2" SCNu32 ":%2" SCNu32 "Z", + &tod.year, &tod.month, &tod.day, &tod.hour, &tod.minute, &tod.second); + if (count != 6) { + continue; + } + timeval tv{}; + Clock::convertTimeOfDayToTimeval(&tod, &tv); + if (not mostRecentTv || tv > mostRecentTv.value()) { + mostRecentTv = tv; + mostRecentFile = file.path(); + } + } +} diff --git a/mission/tmtc/TmStore.h b/mission/tmtc/TmStore.h index a2638d2b..f26461e7 100644 --- a/mission/tmtc/TmStore.h +++ b/mission/tmtc/TmStore.h @@ -19,8 +19,8 @@ enum class RolloverInterval { HOURLY, DAILY }; class TmStore : public SystemObject { public: - TmStore(object_id_t objectId, std::string baseName, RolloverInterval interval, - uint8_t intervalFactor, PacketFilter filter, SdCardMountedIF& sdcMan); + TmStore(object_id_t objectId, std::string baseName, RolloverInterval intervalUnit, + uint32_t intervalCount, PacketFilter filter, SdCardMountedIF& sdcMan); ReturnValue_t passPacket(PusTmReader& reader); ReturnValue_t storePacket(PusTmReader& reader); @@ -34,14 +34,19 @@ class TmStore : public SystemObject { */ MessageQueueId_t getCommandQueue(); PacketFilter filter; + bool baseDirUninitialized = true; std::string baseName; - RolloverInterval interval; - uint8_t intervalFactor; + std::filesystem::path baseDir; + uint32_t rolloverDiffSeconds = 0; char NAME_BUF[524] = {}; std::array fileBuf{}; std::optional mostRecentTv; std::optional mostRecentFile; SdCardMountedIF& sdcMan; + + void calcDiffSeconds(RolloverInterval intervalUnit, uint32_t intervalCount); + void updateBaseDir(); + void assignMostRecentFile(); }; #endif /* MISSION_TMTC_TMSTOREBACKEND_H_ */ From 1f381d9477291371108db02db2125684dfeeb7ab Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 12 Dec 2022 18:42:51 +0100 Subject: [PATCH 19/87] implemented core write --- mission/tmtc/TmStore.cpp | 21 +++++++++++++++++---- mission/tmtc/TmStore.h | 6 ++++-- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/mission/tmtc/TmStore.cpp b/mission/tmtc/TmStore.cpp index 5c3f00c8..d29538ed 100644 --- a/mission/tmtc/TmStore.cpp +++ b/mission/tmtc/TmStore.cpp @@ -5,6 +5,7 @@ #include #include #include +#include using namespace returnvalue; @@ -58,10 +59,18 @@ ReturnValue_t TmStore::storePacket(PusTmReader& reader) { if (not mostRecentFile) { assignMostRecentFile(); } - // TODO: Need to find the file of the most recent file. - // TODO: If file exists: Determine whether file rolls over: Maximum file size reached? Interval - // since last timestamp exceeds rollover interval? - // TODO: If file does not exist or rollover criteria met: Create new file with current timestamp. + + if (currentTv.tv_sec < mostRecentTv.value().tv_sec or + currentTv.tv_sec - mostRecentTv.value().tv_sec > static_cast(rolloverDiffSeconds)) { + if (file_size(mostRecentFile.value()) + reader.getFullPacketLen() > fileBuf.size()) { + // TODO: Rename old file to XYZ.1..z , create new file with the same name as old one, + // update most recent file with that name + } + } + + // Rollover conditions were handled, write to file now + std::ofstream of(mostRecentFile.value(), std::ios::app | std::ios::binary); + of.write(reinterpret_cast(reader.getFullData()), reader.getFullPacketLen()); return returnvalue::OK; } @@ -85,6 +94,8 @@ void TmStore::updateBaseDir() { baseDirUninitialized = false; } +ReturnValue_t TmStore::updateCurrentTimestamp() { return Clock::getClock_timeval(¤tTv); } + void TmStore::assignMostRecentFile() { using namespace std::filesystem; for (auto const& file : directory_iterator(baseDir)) { @@ -113,3 +124,5 @@ void TmStore::assignMostRecentFile() { } } } + +ReturnValue_t TmStore::storePacketInternal(PusTmReader& reader) { return returnvalue::OK; } diff --git a/mission/tmtc/TmStore.h b/mission/tmtc/TmStore.h index f26461e7..3151a818 100644 --- a/mission/tmtc/TmStore.h +++ b/mission/tmtc/TmStore.h @@ -22,6 +22,8 @@ class TmStore : public SystemObject { TmStore(object_id_t objectId, std::string baseName, RolloverInterval intervalUnit, uint32_t intervalCount, PacketFilter filter, SdCardMountedIF& sdcMan); + void updateBaseDir(); + ReturnValue_t updateCurrentTimestamp(); ReturnValue_t passPacket(PusTmReader& reader); ReturnValue_t storePacket(PusTmReader& reader); @@ -38,15 +40,15 @@ class TmStore : public SystemObject { std::string baseName; std::filesystem::path baseDir; uint32_t rolloverDiffSeconds = 0; - char NAME_BUF[524] = {}; std::array fileBuf{}; + timeval currentTv{}; std::optional mostRecentTv; std::optional mostRecentFile; SdCardMountedIF& sdcMan; void calcDiffSeconds(RolloverInterval intervalUnit, uint32_t intervalCount); - void updateBaseDir(); void assignMostRecentFile(); + ReturnValue_t storePacketInternal(PusTmReader& reader); }; #endif /* MISSION_TMTC_TMSTOREBACKEND_H_ */ From e62c527d05b095b1a7006a452792d365f0b71608 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 13 Dec 2022 10:07:36 +0100 Subject: [PATCH 20/87] create files as well --- mission/tmtc/TmStore.cpp | 31 +++++++++++++++++++++++++++---- mission/tmtc/TmStore.h | 2 +- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/mission/tmtc/TmStore.cpp b/mission/tmtc/TmStore.cpp index d29538ed..18a32cb7 100644 --- a/mission/tmtc/TmStore.cpp +++ b/mission/tmtc/TmStore.cpp @@ -57,14 +57,23 @@ ReturnValue_t TmStore::storePacket(PusTmReader& reader) { } // It is assumed here that the filesystem is usable. if (not mostRecentFile) { - assignMostRecentFile(); + assignAndOrCreateMostRecentFile(); } if (currentTv.tv_sec < mostRecentTv.value().tv_sec or currentTv.tv_sec - mostRecentTv.value().tv_sec > static_cast(rolloverDiffSeconds)) { if (file_size(mostRecentFile.value()) + reader.getFullPacketLen() > fileBuf.size()) { - // TODO: Rename old file to XYZ.1..z , create new file with the same name as old one, - // update most recent file with that name + uint8_t appendedCounter = 1; + path rolloverName; + while (true) { + rolloverName = path(mostRecentFile.value().string() + std::to_string(appendedCounter)); + if (not exists(rolloverName)) { + break; + } + appendedCounter++; + } + rename(mostRecentFile.value(), rolloverName); + std::ofstream of(mostRecentFile.value(), std::ios::binary); } } @@ -96,7 +105,7 @@ void TmStore::updateBaseDir() { ReturnValue_t TmStore::updateCurrentTimestamp() { return Clock::getClock_timeval(¤tTv); } -void TmStore::assignMostRecentFile() { +void TmStore::assignAndOrCreateMostRecentFile() { using namespace std::filesystem; for (auto const& file : directory_iterator(baseDir)) { if (file.is_directory()) { @@ -123,6 +132,20 @@ void TmStore::assignMostRecentFile() { mostRecentFile = file.path(); } } + if (not mostRecentFile) { + updateCurrentTimestamp(); + unsigned currentIdx = 0; + memcpy(fileBuf.data() + currentIdx, baseName.data(), baseName.size()); + currentIdx += baseName.size(); + Clock::TimeOfDay_t tod; + Clock::convertTimevalToTimeOfDay(¤tTv, &tod); + currentIdx += sprintf(reinterpret_cast(fileBuf.data() + currentIdx), + "%4" SCNu32 "-%2" SCNu32 "-%2" SCNu32 "T%2" SCNu32 ":%2" SCNu32 + ":%2" SCNu32 "Z.bin", + tod.year, tod.month, tod.day, tod.hour, tod.minute, tod.second); + path newPath(std::string(reinterpret_cast(fileBuf.data()), currentIdx)); + std::ofstream of(newPath, std::ios::binary); + } } ReturnValue_t TmStore::storePacketInternal(PusTmReader& reader) { return returnvalue::OK; } diff --git a/mission/tmtc/TmStore.h b/mission/tmtc/TmStore.h index 3151a818..98e7bc62 100644 --- a/mission/tmtc/TmStore.h +++ b/mission/tmtc/TmStore.h @@ -47,7 +47,7 @@ class TmStore : public SystemObject { SdCardMountedIF& sdcMan; void calcDiffSeconds(RolloverInterval intervalUnit, uint32_t intervalCount); - void assignMostRecentFile(); + void assignAndOrCreateMostRecentFile(); ReturnValue_t storePacketInternal(PusTmReader& reader); }; From 04b04ed8595fda148b692a9d661325777501e158 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 13 Dec 2022 10:08:31 +0100 Subject: [PATCH 21/87] update state as well --- mission/tmtc/TmStore.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mission/tmtc/TmStore.cpp b/mission/tmtc/TmStore.cpp index 18a32cb7..e5adc4a8 100644 --- a/mission/tmtc/TmStore.cpp +++ b/mission/tmtc/TmStore.cpp @@ -145,6 +145,8 @@ void TmStore::assignAndOrCreateMostRecentFile() { tod.year, tod.month, tod.day, tod.hour, tod.minute, tod.second); path newPath(std::string(reinterpret_cast(fileBuf.data()), currentIdx)); std::ofstream of(newPath, std::ios::binary); + mostRecentFile = newPath; + mostRecentTv = currentTv; } } From eddc620307622c3adddf9b24e03210d2cfeef36a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 13 Dec 2022 13:46:49 +0100 Subject: [PATCH 22/87] interval calculation bugfix --- mission/tmtc/TmStore.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mission/tmtc/TmStore.cpp b/mission/tmtc/TmStore.cpp index e5adc4a8..8863dfe6 100644 --- a/mission/tmtc/TmStore.cpp +++ b/mission/tmtc/TmStore.cpp @@ -87,9 +87,9 @@ MessageQueueId_t TmStore::getCommandQueue() { return MessageQueueIF::NO_QUEUE; } void TmStore::calcDiffSeconds(RolloverInterval intervalUnit, uint32_t intervalCount) { if (intervalUnit == RolloverInterval::HOURLY) { - rolloverDiffSeconds = 60 * intervalCount; + rolloverDiffSeconds = 60 * 60 * intervalCount; } else if (intervalUnit == RolloverInterval::DAILY) { - rolloverDiffSeconds = 60 * 24 * intervalCount; + rolloverDiffSeconds = 60 * 60 * 24 * intervalCount; } } From 3965c08bfb7afb2bacd37a5082d368c5ad5d2421 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 13 Dec 2022 14:19:43 +0100 Subject: [PATCH 23/87] add misc store --- bsp_q7s/fmObjectFactory.cpp | 3 ++- common/config/eive/objects.h | 1 + mission/core/GenericFactory.cpp | 4 ++-- mission/core/GenericFactory.h | 4 +++- mission/tmtc/PusTmFunnel.cpp | 7 +++++-- mission/tmtc/PusTmFunnel.h | 4 +++- mission/tmtc/TmStore.cpp | 19 ++++++++++++++++--- mission/tmtc/TmStore.h | 6 ++++-- 8 files changed, 36 insertions(+), 12 deletions(-) diff --git a/bsp_q7s/fmObjectFactory.cpp b/bsp_q7s/fmObjectFactory.cpp index c56dcf8d..e14dcbe6 100644 --- a/bsp_q7s/fmObjectFactory.cpp +++ b/bsp_q7s/fmObjectFactory.cpp @@ -18,7 +18,8 @@ void ObjectFactory::produce(void* args) { HealthTableIF* healthTable = nullptr; PusTmFunnel* pusFunnel = nullptr; CfdpTmFunnel* cfdpFunnel = nullptr; - ObjectFactory::produceGenericObjects(&healthTable, &pusFunnel, &cfdpFunnel); + ObjectFactory::produceGenericObjects(&healthTable, &pusFunnel, &cfdpFunnel, + *SdCardManager::instance()); LinuxLibgpioIF* gpioComIF = nullptr; SerialComIF* uartComIF = nullptr; diff --git a/common/config/eive/objects.h b/common/config/eive/objects.h index 9fb4aeff..0c592913 100644 --- a/common/config/eive/objects.h +++ b/common/config/eive/objects.h @@ -146,6 +146,7 @@ enum commonObjects : uint32_t { CFDP_TM_FUNNEL = 0x73000102, CFDP_HANDLER = 0x73000205, CFDP_DISTRIBUTOR = 0x73000206, + MISC_STORE = 0x73020001, }; } diff --git a/mission/core/GenericFactory.cpp b/mission/core/GenericFactory.cpp index cca48baf..c0e1eb43 100644 --- a/mission/core/GenericFactory.cpp +++ b/mission/core/GenericFactory.cpp @@ -68,7 +68,7 @@ EiveFaultHandler EIVE_FAULT_HANDLER; } // namespace cfdp void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFunnel** pusFunnel, - CfdpTmFunnel** cfdpFunnel) { + CfdpTmFunnel** cfdpFunnel, SdCardMountedIF& sdcMan) { // Framework objects new EventManager(objects::EVENT_MANAGER); auto healthTable = new HealthTable(objects::HEALTH_TABLE); @@ -122,7 +122,7 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun new PusDistributor(config::EIVE_PUS_APID, objects::PUS_PACKET_DISTRIBUTOR, ccsdsDistrib); *cfdpFunnel = new CfdpTmFunnel(objects::CFDP_TM_FUNNEL, config::EIVE_CFDP_APID, *tmStore, 50); - *pusFunnel = new PusTmFunnel(objects::PUS_TM_FUNNEL, *timeStamper, *tmStore, 80); + *pusFunnel = new PusTmFunnel(objects::PUS_TM_FUNNEL, *timeStamper, *tmStore, sdcMan, 80); #if OBSW_ADD_TCPIP_SERVERS == 1 #if OBSW_ADD_TMTC_UDP_SERVER == 1 (*cfdpFunnel)->addDestination(*udpBridge, 0); diff --git a/mission/core/GenericFactory.h b/mission/core/GenericFactory.h index 2e2b0748..050a316d 100644 --- a/mission/core/GenericFactory.h +++ b/mission/core/GenericFactory.h @@ -1,6 +1,8 @@ #ifndef MISSION_CORE_GENERICFACTORY_H_ #define MISSION_CORE_GENERICFACTORY_H_ +#include + class HealthTableIF; class PusTmFunnel; class CfdpTmFunnel; @@ -8,7 +10,7 @@ class CfdpTmFunnel; namespace ObjectFactory { void produceGenericObjects(HealthTableIF** healthTable, PusTmFunnel** pusFunnel, - CfdpTmFunnel** cfdpFunnel); + CfdpTmFunnel** cfdpFunnel, SdCardMountedIF& sdcMan); } diff --git a/mission/tmtc/PusTmFunnel.cpp b/mission/tmtc/PusTmFunnel.cpp index 5d6bbb4d..4a3b6588 100644 --- a/mission/tmtc/PusTmFunnel.cpp +++ b/mission/tmtc/PusTmFunnel.cpp @@ -1,12 +1,15 @@ #include "PusTmFunnel.h" +#include "eive/objects.h" #include "fsfw/ipc/QueueFactory.h" #include "fsfw/objectmanager.h" #include "fsfw/tmtcpacket/pus/tm/PusTmZcWriter.h" PusTmFunnel::PusTmFunnel(object_id_t objectId, TimeReaderIF &timeReader, StorageManagerIF &tmStore, - uint32_t messageDepth) - : TmFunnelBase(objectId, tmStore, messageDepth), timeReader(timeReader) {} + SdCardMountedIF &sdcMan, uint32_t messageDepth) + : TmFunnelBase(objectId, tmStore, messageDepth), + timeReader(timeReader), + miscStore(objects::MISC_STORE, "misc", RolloverInterval::HOURLY, 8, sdcMan) {} PusTmFunnel::~PusTmFunnel() = default; diff --git a/mission/tmtc/PusTmFunnel.h b/mission/tmtc/PusTmFunnel.h index ca9a6016..96a9d33d 100644 --- a/mission/tmtc/PusTmFunnel.h +++ b/mission/tmtc/PusTmFunnel.h @@ -10,6 +10,7 @@ #include +#include "TmStore.h" #include "fsfw/timemanager/TimeReaderIF.h" /** @@ -26,7 +27,7 @@ class PusTmFunnel : public TmFunnelBase { public: explicit PusTmFunnel(object_id_t objectId, TimeReaderIF &timeReader, StorageManagerIF &tmStore, - uint32_t messageDepth = 10); + SdCardMountedIF &sdcMan, uint32_t messageDepth = 10); [[nodiscard]] const char *getName() const override; ~PusTmFunnel() override; @@ -35,6 +36,7 @@ class PusTmFunnel : public TmFunnelBase { private: uint16_t sourceSequenceCount = 0; TimeReaderIF &timeReader; + TmStore miscStore; ReturnValue_t handlePacket(TmTcMessage &message); }; diff --git a/mission/tmtc/TmStore.cpp b/mission/tmtc/TmStore.cpp index 8863dfe6..40dbf726 100644 --- a/mission/tmtc/TmStore.cpp +++ b/mission/tmtc/TmStore.cpp @@ -10,8 +10,8 @@ using namespace returnvalue; TmStore::TmStore(object_id_t objectId, std::string baseName, RolloverInterval intervalUnit, - uint32_t intervalCount, PacketFilter filter, SdCardMountedIF& sdcMan) - : SystemObject(objectId), filter(filter), baseName(std::move(baseName)), sdcMan(sdcMan) { + uint32_t intervalCount, SdCardMountedIF& sdcMan) + : SystemObject(objectId), baseName(std::move(baseName)), sdcMan(sdcMan) { calcDiffSeconds(intervalUnit, intervalCount); } @@ -150,4 +150,17 @@ void TmStore::assignAndOrCreateMostRecentFile() { } } -ReturnValue_t TmStore::storePacketInternal(PusTmReader& reader) { return returnvalue::OK; } +void TmStore::addApid(uint16_t apid) { + if (not filter.apid) { + filter.apid = std::vector(apid); + return; + } + filter.apid.value().push_back(apid); +} + +void TmStore::addService(uint8_t service) { + if (not filter.services) { + filter.services = std::vector(service); + } + filter.services.value().push_back(service); +} diff --git a/mission/tmtc/TmStore.h b/mission/tmtc/TmStore.h index 98e7bc62..4a873750 100644 --- a/mission/tmtc/TmStore.h +++ b/mission/tmtc/TmStore.h @@ -20,7 +20,10 @@ enum class RolloverInterval { HOURLY, DAILY }; class TmStore : public SystemObject { public: TmStore(object_id_t objectId, std::string baseName, RolloverInterval intervalUnit, - uint32_t intervalCount, PacketFilter filter, SdCardMountedIF& sdcMan); + uint32_t intervalCount, SdCardMountedIF& sdcMan); + + void addApid(uint16_t apid); + void addService(uint8_t service); void updateBaseDir(); ReturnValue_t updateCurrentTimestamp(); @@ -48,7 +51,6 @@ class TmStore : public SystemObject { void calcDiffSeconds(RolloverInterval intervalUnit, uint32_t intervalCount); void assignAndOrCreateMostRecentFile(); - ReturnValue_t storePacketInternal(PusTmReader& reader); }; #endif /* MISSION_TMTC_TMSTOREBACKEND_H_ */ From 828d791da5fece7118e1eb29e443331efc3abc48 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 13 Dec 2022 14:26:20 +0100 Subject: [PATCH 24/87] add misc store --- mission/tmtc/PusTmFunnel.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/mission/tmtc/PusTmFunnel.cpp b/mission/tmtc/PusTmFunnel.cpp index 4a3b6588..1eb59ba4 100644 --- a/mission/tmtc/PusTmFunnel.cpp +++ b/mission/tmtc/PusTmFunnel.cpp @@ -1,5 +1,6 @@ #include "PusTmFunnel.h" +#include "eive/definitions.h" #include "eive/objects.h" #include "fsfw/ipc/QueueFactory.h" #include "fsfw/objectmanager.h" @@ -9,7 +10,10 @@ PusTmFunnel::PusTmFunnel(object_id_t objectId, TimeReaderIF &timeReader, Storage SdCardMountedIF &sdcMan, uint32_t messageDepth) : TmFunnelBase(objectId, tmStore, messageDepth), timeReader(timeReader), - miscStore(objects::MISC_STORE, "misc", RolloverInterval::HOURLY, 8, sdcMan) {} + miscStore(objects::MISC_STORE, "misc", RolloverInterval::HOURLY, 8, sdcMan) { + miscStore.addApid(config::EIVE_PUS_APID); + miscStore.addService(17); +} PusTmFunnel::~PusTmFunnel() = default; From fcc9858b66be492c1ffc854553917426c9e2fa72 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 13 Dec 2022 14:30:16 +0100 Subject: [PATCH 25/87] use new packet store --- mission/tmtc/PusTmFunnel.cpp | 12 ++++++++++-- mission/tmtc/PusTmFunnel.h | 1 + mission/tmtc/TmStore.h | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/mission/tmtc/PusTmFunnel.cpp b/mission/tmtc/PusTmFunnel.cpp index 1eb59ba4..f34ffb2b 100644 --- a/mission/tmtc/PusTmFunnel.cpp +++ b/mission/tmtc/PusTmFunnel.cpp @@ -11,8 +11,8 @@ PusTmFunnel::PusTmFunnel(object_id_t objectId, TimeReaderIF &timeReader, Storage : TmFunnelBase(objectId, tmStore, messageDepth), timeReader(timeReader), miscStore(objects::MISC_STORE, "misc", RolloverInterval::HOURLY, 8, sdcMan) { - miscStore.addApid(config::EIVE_PUS_APID); - miscStore.addService(17); + miscStore.addApid(config::EIVE_PUS_APID); + miscStore.addService(17); } PusTmFunnel::~PusTmFunnel() = default; @@ -55,6 +55,8 @@ ReturnValue_t PusTmFunnel::handlePacket(TmTcMessage &message) { sourceSequenceCount = sourceSequenceCount % ccsds::LIMIT_SEQUENCE_COUNT; packet.updateErrorControl(); + miscStore.passPacket(packet); + for (unsigned int idx = 0; idx < destinations.size(); idx++) { const auto &destVcidPair = destinations[idx]; if (destinations.size() > 1) { @@ -87,3 +89,9 @@ ReturnValue_t PusTmFunnel::handlePacket(TmTcMessage &message) { } const char *PusTmFunnel::getName() const { return "PUS TM Funnel"; } + +ReturnValue_t PusTmFunnel::initialize() { + miscStore.updateBaseDir(); + miscStore.updateCurrentTimestamp(); + return returnvalue::OK; +} diff --git a/mission/tmtc/PusTmFunnel.h b/mission/tmtc/PusTmFunnel.h index 96a9d33d..f4285375 100644 --- a/mission/tmtc/PusTmFunnel.h +++ b/mission/tmtc/PusTmFunnel.h @@ -39,6 +39,7 @@ class PusTmFunnel : public TmFunnelBase { TmStore miscStore; ReturnValue_t handlePacket(TmTcMessage &message); + ReturnValue_t initialize() override; }; #endif // FSFW_EXAMPLE_COMMON_PUSTMFUNNEL_H diff --git a/mission/tmtc/TmStore.h b/mission/tmtc/TmStore.h index 4a873750..954c3944 100644 --- a/mission/tmtc/TmStore.h +++ b/mission/tmtc/TmStore.h @@ -28,7 +28,6 @@ class TmStore : public SystemObject { void updateBaseDir(); ReturnValue_t updateCurrentTimestamp(); ReturnValue_t passPacket(PusTmReader& reader); - ReturnValue_t storePacket(PusTmReader& reader); private: static constexpr size_t MAX_FILESIZE = 8192; @@ -51,6 +50,7 @@ class TmStore : public SystemObject { void calcDiffSeconds(RolloverInterval intervalUnit, uint32_t intervalCount); void assignAndOrCreateMostRecentFile(); + ReturnValue_t storePacket(PusTmReader& reader); }; #endif /* MISSION_TMTC_TMSTOREBACKEND_H_ */ From 33ac72de835f2a7aa51f7d9352189a01744a40b5 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 13 Dec 2022 14:33:16 +0100 Subject: [PATCH 26/87] check whether SD card is usable --- mission/tmtc/PusTmFunnel.cpp | 7 +++++-- mission/tmtc/PusTmFunnel.h | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/mission/tmtc/PusTmFunnel.cpp b/mission/tmtc/PusTmFunnel.cpp index f34ffb2b..f506bbd6 100644 --- a/mission/tmtc/PusTmFunnel.cpp +++ b/mission/tmtc/PusTmFunnel.cpp @@ -10,7 +10,8 @@ PusTmFunnel::PusTmFunnel(object_id_t objectId, TimeReaderIF &timeReader, Storage SdCardMountedIF &sdcMan, uint32_t messageDepth) : TmFunnelBase(objectId, tmStore, messageDepth), timeReader(timeReader), - miscStore(objects::MISC_STORE, "misc", RolloverInterval::HOURLY, 8, sdcMan) { + miscStore(objects::MISC_STORE, "misc", RolloverInterval::HOURLY, 8, sdcMan), + sdcMan(sdcMan) { miscStore.addApid(config::EIVE_PUS_APID); miscStore.addService(17); } @@ -55,7 +56,9 @@ ReturnValue_t PusTmFunnel::handlePacket(TmTcMessage &message) { sourceSequenceCount = sourceSequenceCount % ccsds::LIMIT_SEQUENCE_COUNT; packet.updateErrorControl(); - miscStore.passPacket(packet); + if(sdcMan.isSdCardUsable(std::nullopt)) { + miscStore.passPacket(packet); + } for (unsigned int idx = 0; idx < destinations.size(); idx++) { const auto &destVcidPair = destinations[idx]; diff --git a/mission/tmtc/PusTmFunnel.h b/mission/tmtc/PusTmFunnel.h index f4285375..82d6a0cb 100644 --- a/mission/tmtc/PusTmFunnel.h +++ b/mission/tmtc/PusTmFunnel.h @@ -37,6 +37,7 @@ class PusTmFunnel : public TmFunnelBase { uint16_t sourceSequenceCount = 0; TimeReaderIF &timeReader; TmStore miscStore; + SdCardMountedIF& sdcMan; ReturnValue_t handlePacket(TmTcMessage &message); ReturnValue_t initialize() override; From 130a3ce727d4fb9fe13aac23fc84a1594e8c0730 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 13 Dec 2022 14:38:30 +0100 Subject: [PATCH 27/87] initialize stores as well --- mission/tmtc/PusTmFunnel.cpp | 18 +++++++++++++----- mission/tmtc/PusTmFunnel.h | 3 ++- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/mission/tmtc/PusTmFunnel.cpp b/mission/tmtc/PusTmFunnel.cpp index f506bbd6..920cb494 100644 --- a/mission/tmtc/PusTmFunnel.cpp +++ b/mission/tmtc/PusTmFunnel.cpp @@ -11,7 +11,7 @@ PusTmFunnel::PusTmFunnel(object_id_t objectId, TimeReaderIF &timeReader, Storage : TmFunnelBase(objectId, tmStore, messageDepth), timeReader(timeReader), miscStore(objects::MISC_STORE, "misc", RolloverInterval::HOURLY, 8, sdcMan), - sdcMan(sdcMan) { + sdcMan(sdcMan) { miscStore.addApid(config::EIVE_PUS_APID); miscStore.addService(17); } @@ -56,8 +56,13 @@ ReturnValue_t PusTmFunnel::handlePacket(TmTcMessage &message) { sourceSequenceCount = sourceSequenceCount % ccsds::LIMIT_SEQUENCE_COUNT; packet.updateErrorControl(); - if(sdcMan.isSdCardUsable(std::nullopt)) { - miscStore.passPacket(packet); + if (sdcMan.isSdCardUsable(std::nullopt)) { + if (not storesInitialized) { + miscStore.updateBaseDir(); + miscStore.updateCurrentTimestamp(); + storesInitialized = true; + } + miscStore.passPacket(packet); } for (unsigned int idx = 0; idx < destinations.size(); idx++) { @@ -94,7 +99,10 @@ ReturnValue_t PusTmFunnel::handlePacket(TmTcMessage &message) { const char *PusTmFunnel::getName() const { return "PUS TM Funnel"; } ReturnValue_t PusTmFunnel::initialize() { - miscStore.updateBaseDir(); - miscStore.updateCurrentTimestamp(); + if (not storesInitialized and sdcMan.isSdCardUsable(std::nullopt)) { + miscStore.updateBaseDir(); + miscStore.updateCurrentTimestamp(); + storesInitialized = true; + } return returnvalue::OK; } diff --git a/mission/tmtc/PusTmFunnel.h b/mission/tmtc/PusTmFunnel.h index 82d6a0cb..57045d91 100644 --- a/mission/tmtc/PusTmFunnel.h +++ b/mission/tmtc/PusTmFunnel.h @@ -36,8 +36,9 @@ class PusTmFunnel : public TmFunnelBase { private: uint16_t sourceSequenceCount = 0; TimeReaderIF &timeReader; + bool storesInitialized = false; TmStore miscStore; - SdCardMountedIF& sdcMan; + SdCardMountedIF &sdcMan; ReturnValue_t handlePacket(TmTcMessage &message); ReturnValue_t initialize() override; From 8c10cbe37b1a53147c50b6ab89cbf480e5fd8d8d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 13 Dec 2022 15:24:51 +0100 Subject: [PATCH 28/87] the stores only keep references to the current time --- common/config/eive/objects.h | 1 + mission/tmtc/PusTmFunnel.cpp | 11 ++++++++--- mission/tmtc/PusTmFunnel.h | 2 ++ mission/tmtc/TmStore.cpp | 7 ++----- mission/tmtc/TmStore.h | 5 ++--- 5 files changed, 15 insertions(+), 11 deletions(-) diff --git a/common/config/eive/objects.h b/common/config/eive/objects.h index 0c592913..83b103ce 100644 --- a/common/config/eive/objects.h +++ b/common/config/eive/objects.h @@ -147,6 +147,7 @@ enum commonObjects : uint32_t { CFDP_HANDLER = 0x73000205, CFDP_DISTRIBUTOR = 0x73000206, MISC_STORE = 0x73020001, + EVENT_STORE = 0x73020002, }; } diff --git a/mission/tmtc/PusTmFunnel.cpp b/mission/tmtc/PusTmFunnel.cpp index 920cb494..d7453f12 100644 --- a/mission/tmtc/PusTmFunnel.cpp +++ b/mission/tmtc/PusTmFunnel.cpp @@ -10,10 +10,14 @@ PusTmFunnel::PusTmFunnel(object_id_t objectId, TimeReaderIF &timeReader, Storage SdCardMountedIF &sdcMan, uint32_t messageDepth) : TmFunnelBase(objectId, tmStore, messageDepth), timeReader(timeReader), - miscStore(objects::MISC_STORE, "misc", RolloverInterval::HOURLY, 8, sdcMan), + miscStore(objects::MISC_STORE, "misc", RolloverInterval::HOURLY, 8, currentTv, sdcMan), + eventStore(objects::EVENT_STORE, "event", RolloverInterval::HOURLY, 1, currentTv, sdcMan), sdcMan(sdcMan) { + Clock::getClock_timeval(¤tTv); miscStore.addApid(config::EIVE_PUS_APID); miscStore.addService(17); + eventStore.addApid(config::EIVE_PUS_APID); + eventStore.addService(5); } PusTmFunnel::~PusTmFunnel() = default; @@ -59,10 +63,11 @@ ReturnValue_t PusTmFunnel::handlePacket(TmTcMessage &message) { if (sdcMan.isSdCardUsable(std::nullopt)) { if (not storesInitialized) { miscStore.updateBaseDir(); - miscStore.updateCurrentTimestamp(); + eventStore.updateBaseDir(); storesInitialized = true; } miscStore.passPacket(packet); + eventStore.passPacket(packet); } for (unsigned int idx = 0; idx < destinations.size(); idx++) { @@ -101,7 +106,7 @@ const char *PusTmFunnel::getName() const { return "PUS TM Funnel"; } ReturnValue_t PusTmFunnel::initialize() { if (not storesInitialized and sdcMan.isSdCardUsable(std::nullopt)) { miscStore.updateBaseDir(); - miscStore.updateCurrentTimestamp(); + eventStore.updateBaseDir(); storesInitialized = true; } return returnvalue::OK; diff --git a/mission/tmtc/PusTmFunnel.h b/mission/tmtc/PusTmFunnel.h index 57045d91..3e3c8545 100644 --- a/mission/tmtc/PusTmFunnel.h +++ b/mission/tmtc/PusTmFunnel.h @@ -37,7 +37,9 @@ class PusTmFunnel : public TmFunnelBase { uint16_t sourceSequenceCount = 0; TimeReaderIF &timeReader; bool storesInitialized = false; + timeval currentTv; TmStore miscStore; + TmStore eventStore; SdCardMountedIF &sdcMan; ReturnValue_t handlePacket(TmTcMessage &message); diff --git a/mission/tmtc/TmStore.cpp b/mission/tmtc/TmStore.cpp index 40dbf726..5ae6dcc7 100644 --- a/mission/tmtc/TmStore.cpp +++ b/mission/tmtc/TmStore.cpp @@ -10,8 +10,8 @@ using namespace returnvalue; TmStore::TmStore(object_id_t objectId, std::string baseName, RolloverInterval intervalUnit, - uint32_t intervalCount, SdCardMountedIF& sdcMan) - : SystemObject(objectId), baseName(std::move(baseName)), sdcMan(sdcMan) { + uint32_t intervalCount, timeval& currentTv, SdCardMountedIF& sdcMan) + : SystemObject(objectId), baseName(std::move(baseName)), currentTv(currentTv), sdcMan(sdcMan) { calcDiffSeconds(intervalUnit, intervalCount); } @@ -103,8 +103,6 @@ void TmStore::updateBaseDir() { baseDirUninitialized = false; } -ReturnValue_t TmStore::updateCurrentTimestamp() { return Clock::getClock_timeval(¤tTv); } - void TmStore::assignAndOrCreateMostRecentFile() { using namespace std::filesystem; for (auto const& file : directory_iterator(baseDir)) { @@ -133,7 +131,6 @@ void TmStore::assignAndOrCreateMostRecentFile() { } } if (not mostRecentFile) { - updateCurrentTimestamp(); unsigned currentIdx = 0; memcpy(fileBuf.data() + currentIdx, baseName.data(), baseName.size()); currentIdx += baseName.size(); diff --git a/mission/tmtc/TmStore.h b/mission/tmtc/TmStore.h index 954c3944..9d20bbe4 100644 --- a/mission/tmtc/TmStore.h +++ b/mission/tmtc/TmStore.h @@ -20,13 +20,12 @@ enum class RolloverInterval { HOURLY, DAILY }; class TmStore : public SystemObject { public: TmStore(object_id_t objectId, std::string baseName, RolloverInterval intervalUnit, - uint32_t intervalCount, SdCardMountedIF& sdcMan); + uint32_t intervalCount, timeval& currentTv, SdCardMountedIF& sdcMan); void addApid(uint16_t apid); void addService(uint8_t service); void updateBaseDir(); - ReturnValue_t updateCurrentTimestamp(); ReturnValue_t passPacket(PusTmReader& reader); private: @@ -43,7 +42,7 @@ class TmStore : public SystemObject { std::filesystem::path baseDir; uint32_t rolloverDiffSeconds = 0; std::array fileBuf{}; - timeval currentTv{}; + timeval& currentTv; std::optional mostRecentTv; std::optional mostRecentFile; SdCardMountedIF& sdcMan; From 283b897ae703b0d627ce06e54cb5200d57892776 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 13 Dec 2022 15:34:13 +0100 Subject: [PATCH 29/87] allow minutely rollover as well --- mission/tmtc/TmStore.cpp | 4 +++- mission/tmtc/TmStore.h | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/mission/tmtc/TmStore.cpp b/mission/tmtc/TmStore.cpp index 5ae6dcc7..6ec49da8 100644 --- a/mission/tmtc/TmStore.cpp +++ b/mission/tmtc/TmStore.cpp @@ -86,7 +86,9 @@ ReturnValue_t TmStore::storePacket(PusTmReader& reader) { MessageQueueId_t TmStore::getCommandQueue() { return MessageQueueIF::NO_QUEUE; } void TmStore::calcDiffSeconds(RolloverInterval intervalUnit, uint32_t intervalCount) { - if (intervalUnit == RolloverInterval::HOURLY) { + if (intervalUnit == RolloverInterval::MINUTELY) { + rolloverDiffSeconds = 60 * intervalCount; + } else if (intervalUnit == RolloverInterval::HOURLY) { rolloverDiffSeconds = 60 * 60 * intervalCount; } else if (intervalUnit == RolloverInterval::DAILY) { rolloverDiffSeconds = 60 * 60 * 24 * intervalCount; diff --git a/mission/tmtc/TmStore.h b/mission/tmtc/TmStore.h index 9d20bbe4..193a1db5 100644 --- a/mission/tmtc/TmStore.h +++ b/mission/tmtc/TmStore.h @@ -15,7 +15,7 @@ struct PacketFilter { std::optional>> serviceSubservices; }; -enum class RolloverInterval { HOURLY, DAILY }; +enum class RolloverInterval { MINUTELY, HOURLY, DAILY }; class TmStore : public SystemObject { public: @@ -41,7 +41,7 @@ class TmStore : public SystemObject { std::string baseName; std::filesystem::path baseDir; uint32_t rolloverDiffSeconds = 0; - std::array fileBuf{}; + std::array fileBuf{}; timeval& currentTv; std::optional mostRecentTv; std::optional mostRecentFile; From 8858084f6ef32948cfab2c226d95cde58712a89b Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 13 Dec 2022 15:35:39 +0100 Subject: [PATCH 30/87] introduce new second interval --- mission/tmtc/PusTmFunnel.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mission/tmtc/PusTmFunnel.h b/mission/tmtc/PusTmFunnel.h index 3e3c8545..683fcbd2 100644 --- a/mission/tmtc/PusTmFunnel.h +++ b/mission/tmtc/PusTmFunnel.h @@ -34,6 +34,9 @@ class PusTmFunnel : public TmFunnelBase { ReturnValue_t performOperation(uint8_t operationCode); private: + // Update TV stamp every 5 minutes + static constexpr dur_millis_t TV_UPDATE_INTERVAL_SECS = 60 * 5; + uint16_t sourceSequenceCount = 0; TimeReaderIF &timeReader; bool storesInitialized = false; From 3e17de0127cdfb54110eb4686af0e239caf70b04 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 13 Dec 2022 15:43:41 +0100 Subject: [PATCH 31/87] update clock every 5 minutes --- mission/tmtc/PusTmFunnel.cpp | 9 +++++++++ mission/tmtc/PusTmFunnel.h | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/mission/tmtc/PusTmFunnel.cpp b/mission/tmtc/PusTmFunnel.cpp index d7453f12..832656e7 100644 --- a/mission/tmtc/PusTmFunnel.cpp +++ b/mission/tmtc/PusTmFunnel.cpp @@ -14,6 +14,7 @@ PusTmFunnel::PusTmFunnel(object_id_t objectId, TimeReaderIF &timeReader, Storage eventStore(objects::EVENT_STORE, "event", RolloverInterval::HOURLY, 1, currentTv, sdcMan), sdcMan(sdcMan) { Clock::getClock_timeval(¤tTv); + Clock::getUptime(&lastTvUpdate); miscStore.addApid(config::EIVE_PUS_APID); miscStore.addService(17); eventStore.addApid(config::EIVE_PUS_APID); @@ -60,6 +61,14 @@ ReturnValue_t PusTmFunnel::handlePacket(TmTcMessage &message) { sourceSequenceCount = sourceSequenceCount % ccsds::LIMIT_SEQUENCE_COUNT; packet.updateErrorControl(); + timeval currentUptime; + Clock::getUptime(¤tUptime); + if (currentUptime.tv_sec - lastTvUpdate.tv_sec > + static_cast(TV_UPDATE_INTERVAL_SECS)) { + Clock::getClock_timeval(¤tTv); + lastTvUpdate = currentUptime; + } + if (sdcMan.isSdCardUsable(std::nullopt)) { if (not storesInitialized) { miscStore.updateBaseDir(); diff --git a/mission/tmtc/PusTmFunnel.h b/mission/tmtc/PusTmFunnel.h index 683fcbd2..c4132379 100644 --- a/mission/tmtc/PusTmFunnel.h +++ b/mission/tmtc/PusTmFunnel.h @@ -40,7 +40,8 @@ class PusTmFunnel : public TmFunnelBase { uint16_t sourceSequenceCount = 0; TimeReaderIF &timeReader; bool storesInitialized = false; - timeval currentTv; + timeval currentTv{}; + timeval lastTvUpdate{}; TmStore miscStore; TmStore eventStore; SdCardMountedIF &sdcMan; From d37f48336b922293575791da238b0a4f2f8f4c6d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 13 Dec 2022 15:56:40 +0100 Subject: [PATCH 32/87] ok im done --- common/config/eive/objects.h | 3 ++- mission/tmtc/PusTmFunnel.cpp | 13 +++++++------ mission/tmtc/PusTmFunnel.h | 3 ++- mission/tmtc/TmStore.cpp | 13 +++++++++++-- mission/tmtc/TmStore.h | 1 + 5 files changed, 23 insertions(+), 10 deletions(-) diff --git a/common/config/eive/objects.h b/common/config/eive/objects.h index 83b103ce..ede974fb 100644 --- a/common/config/eive/objects.h +++ b/common/config/eive/objects.h @@ -147,7 +147,8 @@ enum commonObjects : uint32_t { CFDP_HANDLER = 0x73000205, CFDP_DISTRIBUTOR = 0x73000206, MISC_STORE = 0x73020001, - EVENT_STORE = 0x73020002, + OK_STORE = 0x73020002, + NOT_OK_STORE = 0x73020003, }; } diff --git a/mission/tmtc/PusTmFunnel.cpp b/mission/tmtc/PusTmFunnel.cpp index 832656e7..c5c0b4eb 100644 --- a/mission/tmtc/PusTmFunnel.cpp +++ b/mission/tmtc/PusTmFunnel.cpp @@ -11,14 +11,15 @@ PusTmFunnel::PusTmFunnel(object_id_t objectId, TimeReaderIF &timeReader, Storage : TmFunnelBase(objectId, tmStore, messageDepth), timeReader(timeReader), miscStore(objects::MISC_STORE, "misc", RolloverInterval::HOURLY, 8, currentTv, sdcMan), - eventStore(objects::EVENT_STORE, "event", RolloverInterval::HOURLY, 1, currentTv, sdcMan), + okStore(objects::OK_STORE, "event", RolloverInterval::MINUTELY, 30, currentTv, sdcMan), + notOkStore(objects::NOT_OK_STORE, "event", RolloverInterval::MINUTELY, 30, currentTv, sdcMan), sdcMan(sdcMan) { Clock::getClock_timeval(¤tTv); Clock::getUptime(&lastTvUpdate); miscStore.addApid(config::EIVE_PUS_APID); miscStore.addService(17); - eventStore.addApid(config::EIVE_PUS_APID); - eventStore.addService(5); + okStore.addApid(config::EIVE_PUS_APID); + okStore.addServiceSubservice(5, 1); } PusTmFunnel::~PusTmFunnel() = default; @@ -72,11 +73,11 @@ ReturnValue_t PusTmFunnel::handlePacket(TmTcMessage &message) { if (sdcMan.isSdCardUsable(std::nullopt)) { if (not storesInitialized) { miscStore.updateBaseDir(); - eventStore.updateBaseDir(); + okStore.updateBaseDir(); storesInitialized = true; } miscStore.passPacket(packet); - eventStore.passPacket(packet); + okStore.passPacket(packet); } for (unsigned int idx = 0; idx < destinations.size(); idx++) { @@ -115,7 +116,7 @@ const char *PusTmFunnel::getName() const { return "PUS TM Funnel"; } ReturnValue_t PusTmFunnel::initialize() { if (not storesInitialized and sdcMan.isSdCardUsable(std::nullopt)) { miscStore.updateBaseDir(); - eventStore.updateBaseDir(); + okStore.updateBaseDir(); storesInitialized = true; } return returnvalue::OK; diff --git a/mission/tmtc/PusTmFunnel.h b/mission/tmtc/PusTmFunnel.h index c4132379..26bbfec2 100644 --- a/mission/tmtc/PusTmFunnel.h +++ b/mission/tmtc/PusTmFunnel.h @@ -43,7 +43,8 @@ class PusTmFunnel : public TmFunnelBase { timeval currentTv{}; timeval lastTvUpdate{}; TmStore miscStore; - TmStore eventStore; + TmStore okStore; + TmStore notOkStore; SdCardMountedIF &sdcMan; ReturnValue_t handlePacket(TmTcMessage &message); diff --git a/mission/tmtc/TmStore.cpp b/mission/tmtc/TmStore.cpp index 6ec49da8..82ccafe9 100644 --- a/mission/tmtc/TmStore.cpp +++ b/mission/tmtc/TmStore.cpp @@ -6,6 +6,7 @@ #include #include #include +#include using namespace returnvalue; @@ -151,7 +152,7 @@ void TmStore::assignAndOrCreateMostRecentFile() { void TmStore::addApid(uint16_t apid) { if (not filter.apid) { - filter.apid = std::vector(apid); + filter.apid = std::vector({apid}); return; } filter.apid.value().push_back(apid); @@ -159,7 +160,15 @@ void TmStore::addApid(uint16_t apid) { void TmStore::addService(uint8_t service) { if (not filter.services) { - filter.services = std::vector(service); + filter.services = std::vector({service}); } filter.services.value().push_back(service); } + +void TmStore::addServiceSubservice(uint8_t service, uint8_t subservice) { + if (not filter.serviceSubservices) { + filter.serviceSubservices = + std::vector>({std::pair(service, subservice)}); + } + filter.serviceSubservices.value().push_back({service, subservice}); +} diff --git a/mission/tmtc/TmStore.h b/mission/tmtc/TmStore.h index 193a1db5..ff141dd1 100644 --- a/mission/tmtc/TmStore.h +++ b/mission/tmtc/TmStore.h @@ -24,6 +24,7 @@ class TmStore : public SystemObject { void addApid(uint16_t apid); void addService(uint8_t service); + void addServiceSubservice(uint8_t service, uint8_t subservice); void updateBaseDir(); ReturnValue_t passPacket(PusTmReader& reader); From 9c217ad91e3f28d786b911e9d4edd94ff65c1c58 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 14 Dec 2022 09:53:38 +0100 Subject: [PATCH 33/87] now hosted should compile again --- bsp_hosted/ObjectFactory.cpp | 4 +++- bsp_linux_board/CMakeLists.txt | 2 +- bsp_linux_board/ObjectFactory.cpp | 2 +- bsp_linux_board/RPiSdCardManager.cpp | 13 ------------- mission/utility/CMakeLists.txt | 2 +- mission/utility/DummySdCardManager.cpp | 13 +++++++++++++ .../utility/DummySdCardManager.h | 6 +++--- 7 files changed, 22 insertions(+), 20 deletions(-) delete mode 100644 bsp_linux_board/RPiSdCardManager.cpp create mode 100644 mission/utility/DummySdCardManager.cpp rename bsp_linux_board/RPiSdCardManager.h => mission/utility/DummySdCardManager.h (74%) diff --git a/bsp_hosted/ObjectFactory.cpp b/bsp_hosted/ObjectFactory.cpp index 779bb006..ae768a7c 100644 --- a/bsp_hosted/ObjectFactory.cpp +++ b/bsp_hosted/ObjectFactory.cpp @@ -8,6 +8,7 @@ #include #include +#include "../mission/utility/DummySdCardManager.h" #include "OBSWConfig.h" #include "devConf.h" #include "eive/definitions.h" @@ -78,7 +79,8 @@ void ObjectFactory::produce(void* args) { Factory::setStaticFrameworkObjectIds(); PusTmFunnel* pusFunnel; CfdpTmFunnel* cfdpFunnel; - ObjectFactory::produceGenericObjects(nullptr, &pusFunnel, &cfdpFunnel); + auto sdcMan = new DummySdCardManager("/tmp"); + ObjectFactory::produceGenericObjects(nullptr, &pusFunnel, &cfdpFunnel, *sdcMan); DummyGpioIF* dummyGpioIF = new DummyGpioIF(); auto* dummySwitcher = new DummyPowerSwitcher(objects::PCDU_HANDLER, 18, 0); diff --git a/bsp_linux_board/CMakeLists.txt b/bsp_linux_board/CMakeLists.txt index 39f06401..9e3ec023 100644 --- a/bsp_linux_board/CMakeLists.txt +++ b/bsp_linux_board/CMakeLists.txt @@ -1,5 +1,5 @@ target_sources(${OBSW_NAME} PUBLIC InitMission.cpp main.cpp gpioInit.cpp - ObjectFactory.cpp RPiSdCardManager.cpp) + ObjectFactory.cpp) add_subdirectory(boardconfig) add_subdirectory(boardtest) diff --git a/bsp_linux_board/ObjectFactory.cpp b/bsp_linux_board/ObjectFactory.cpp index 53db052c..95ea87bb 100644 --- a/bsp_linux_board/ObjectFactory.cpp +++ b/bsp_linux_board/ObjectFactory.cpp @@ -82,7 +82,7 @@ void ObjectFactory::produce(void* args) { #endif #if OBSW_ADD_SCEX_DEVICE == 1 - auto* sdcMan = new RPiSdCardManager("/tmp"); + auto* sdcMan = new DummySdCardManager("/tmp"); createScexComponents(uart::DEV, pwrSwitcher, *sdcMan, true, std::nullopt); #endif diff --git a/bsp_linux_board/RPiSdCardManager.cpp b/bsp_linux_board/RPiSdCardManager.cpp deleted file mode 100644 index dfcae8da..00000000 --- a/bsp_linux_board/RPiSdCardManager.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include "RPiSdCardManager.h" - -RPiSdCardManager::RPiSdCardManager(std::string prefix) : prefix(std::move(prefix)) {} - -const std::string& RPiSdCardManager::getCurrentMountPrefix() const { return prefix; } - -bool RPiSdCardManager::isSdCardUsable(sd::SdCard sdCard) { return true; } - -std::optional RPiSdCardManager::getPreferredSdCard() const { return std::nullopt; } - -void RPiSdCardManager::setActiveSdCard(sd::SdCard sdCard) {} - -std::optional RPiSdCardManager::getActiveSdCard() const { return std::nullopt; } diff --git a/mission/utility/CMakeLists.txt b/mission/utility/CMakeLists.txt index e2459ed1..dadce33f 100644 --- a/mission/utility/CMakeLists.txt +++ b/mission/utility/CMakeLists.txt @@ -1,3 +1,3 @@ target_sources( ${LIB_EIVE_MISSION} PRIVATE Timestamp.cpp ProgressPrinter.cpp Filenaming.cpp - GlobalConfigHandler.cpp) + GlobalConfigHandler.cpp DummySdCardManager.cpp) diff --git a/mission/utility/DummySdCardManager.cpp b/mission/utility/DummySdCardManager.cpp new file mode 100644 index 00000000..1b2a45e1 --- /dev/null +++ b/mission/utility/DummySdCardManager.cpp @@ -0,0 +1,13 @@ +#include "DummySdCardManager.h" + +DummySdCardManager::DummySdCardManager(std::string prefix) : prefix(std::move(prefix)) {} + +const std::string& DummySdCardManager::getCurrentMountPrefix() const { return prefix; } + +bool DummySdCardManager::isSdCardUsable(std::optional sdCard) { return true; } + +std::optional DummySdCardManager::getPreferredSdCard() const { return std::nullopt; } + +void DummySdCardManager::setActiveSdCard(sd::SdCard sdCard) {} + +std::optional DummySdCardManager::getActiveSdCard() const { return std::nullopt; } diff --git a/bsp_linux_board/RPiSdCardManager.h b/mission/utility/DummySdCardManager.h similarity index 74% rename from bsp_linux_board/RPiSdCardManager.h rename to mission/utility/DummySdCardManager.h index 068471c1..1a74dc10 100644 --- a/bsp_linux_board/RPiSdCardManager.h +++ b/mission/utility/DummySdCardManager.h @@ -2,11 +2,11 @@ #define BSP_LINUX_BOARD_RPISDCARDMANAGER_H_ #include -class RPiSdCardManager : public SdCardMountedIF { +class DummySdCardManager : public SdCardMountedIF { public: - RPiSdCardManager(std::string prefix); + DummySdCardManager(std::string prefix); const std::string& getCurrentMountPrefix() const override; - bool isSdCardUsable(sd::SdCard sdCard) override; + bool isSdCardUsable(std::optional sdCard) override; std::optional getPreferredSdCard() const override; void setActiveSdCard(sd::SdCard sdCard) override; std::optional getActiveSdCard() const override; From 2d72942d471e3d39829fbabe73c559be303cf0fd Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 14 Dec 2022 10:14:53 +0100 Subject: [PATCH 34/87] important bugfix --- mission/tmtc/TmStore.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mission/tmtc/TmStore.cpp b/mission/tmtc/TmStore.cpp index 82ccafe9..8ba37693 100644 --- a/mission/tmtc/TmStore.cpp +++ b/mission/tmtc/TmStore.cpp @@ -161,6 +161,7 @@ void TmStore::addApid(uint16_t apid) { void TmStore::addService(uint8_t service) { if (not filter.services) { filter.services = std::vector({service}); + return; } filter.services.value().push_back(service); } @@ -169,6 +170,7 @@ void TmStore::addServiceSubservice(uint8_t service, uint8_t subservice) { if (not filter.serviceSubservices) { filter.serviceSubservices = std::vector>({std::pair(service, subservice)}); + return; } filter.serviceSubservices.value().push_back({service, subservice}); } From 8ee6a23229b2097a241ccfcdae656fc6ddd58df3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 14 Dec 2022 10:34:23 +0100 Subject: [PATCH 35/87] more fixes and improvements --- mission/tmtc/PusTmFunnel.cpp | 11 ++++++++--- mission/tmtc/TmStore.cpp | 21 +++++++++++---------- mission/tmtc/TmStore.h | 5 +++-- 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/mission/tmtc/PusTmFunnel.cpp b/mission/tmtc/PusTmFunnel.cpp index c5c0b4eb..236e68fa 100644 --- a/mission/tmtc/PusTmFunnel.cpp +++ b/mission/tmtc/PusTmFunnel.cpp @@ -10,9 +10,9 @@ PusTmFunnel::PusTmFunnel(object_id_t objectId, TimeReaderIF &timeReader, Storage SdCardMountedIF &sdcMan, uint32_t messageDepth) : TmFunnelBase(objectId, tmStore, messageDepth), timeReader(timeReader), - miscStore(objects::MISC_STORE, "misc", RolloverInterval::HOURLY, 8, currentTv, sdcMan), - okStore(objects::OK_STORE, "event", RolloverInterval::MINUTELY, 30, currentTv, sdcMan), - notOkStore(objects::NOT_OK_STORE, "event", RolloverInterval::MINUTELY, 30, currentTv, sdcMan), + miscStore(objects::MISC_STORE, "tm", "misc", RolloverInterval::HOURLY, 8, currentTv, sdcMan), + okStore(objects::OK_STORE, "tm", "ok", RolloverInterval::MINUTELY, 30, currentTv, sdcMan), + notOkStore(objects::NOT_OK_STORE,"tm", "nok", RolloverInterval::MINUTELY, 30, currentTv, sdcMan), sdcMan(sdcMan) { Clock::getClock_timeval(¤tTv); Clock::getUptime(&lastTvUpdate); @@ -20,6 +20,11 @@ PusTmFunnel::PusTmFunnel(object_id_t objectId, TimeReaderIF &timeReader, Storage miscStore.addService(17); okStore.addApid(config::EIVE_PUS_APID); okStore.addServiceSubservice(5, 1); + okStore.addApid(config::EIVE_PUS_APID); + okStore.addServiceSubservice(1, 1); + okStore.addServiceSubservice(1, 3); + okStore.addServiceSubservice(1, 5); + okStore.addServiceSubservice(1, 7); } PusTmFunnel::~PusTmFunnel() = default; diff --git a/mission/tmtc/TmStore.cpp b/mission/tmtc/TmStore.cpp index 8ba37693..16ae51a9 100644 --- a/mission/tmtc/TmStore.cpp +++ b/mission/tmtc/TmStore.cpp @@ -10,9 +10,9 @@ using namespace returnvalue; -TmStore::TmStore(object_id_t objectId, std::string baseName, RolloverInterval intervalUnit, - uint32_t intervalCount, timeval& currentTv, SdCardMountedIF& sdcMan) - : SystemObject(objectId), baseName(std::move(baseName)), currentTv(currentTv), sdcMan(sdcMan) { +TmStore::TmStore(object_id_t objectId, std::string baseDir, std::string baseName, + RolloverInterval intervalUnit, uint32_t intervalCount, timeval& currentTv, SdCardMountedIF& sdcMan) + : SystemObject(objectId), baseDir(std::move(baseDir)), baseName(std::move(baseName)), currentTv(currentTv), sdcMan(sdcMan) { calcDiffSeconds(intervalUnit, intervalCount); } @@ -99,16 +99,16 @@ void TmStore::calcDiffSeconds(RolloverInterval intervalUnit, uint32_t intervalCo void TmStore::updateBaseDir() { using namespace std::filesystem; std::string currentPrefix = sdcMan.getCurrentMountPrefix(); - baseDir = path(currentPrefix) / baseName; - if (not exists(baseDir)) { - create_directory(baseDir); + basePath = path(currentPrefix) / baseDir / baseName; + if (not exists(basePath)) { + create_directories(basePath); } baseDirUninitialized = false; } void TmStore::assignAndOrCreateMostRecentFile() { using namespace std::filesystem; - for (auto const& file : directory_iterator(baseDir)) { + for (auto const& file : directory_iterator(basePath)) { if (file.is_directory()) { continue; } @@ -135,13 +135,14 @@ void TmStore::assignAndOrCreateMostRecentFile() { } if (not mostRecentFile) { unsigned currentIdx = 0; - memcpy(fileBuf.data() + currentIdx, baseName.data(), baseName.size()); + path pathStart = basePath / baseName; + memcpy(fileBuf.data() + currentIdx, pathStart.c_str(), pathStart.string().length()); currentIdx += baseName.size(); Clock::TimeOfDay_t tod; Clock::convertTimevalToTimeOfDay(¤tTv, &tod); currentIdx += sprintf(reinterpret_cast(fileBuf.data() + currentIdx), - "%4" SCNu32 "-%2" SCNu32 "-%2" SCNu32 "T%2" SCNu32 ":%2" SCNu32 - ":%2" SCNu32 "Z.bin", + "_%4" PRIu32 "-%2" PRIu32 "-%2" PRIu32 "T%2" PRIu32 ":%2" PRIu32 + ":%2" PRIu32 "Z.bin", tod.year, tod.month, tod.day, tod.hour, tod.minute, tod.second); path newPath(std::string(reinterpret_cast(fileBuf.data()), currentIdx)); std::ofstream of(newPath, std::ios::binary); diff --git a/mission/tmtc/TmStore.h b/mission/tmtc/TmStore.h index ff141dd1..9fdaf462 100644 --- a/mission/tmtc/TmStore.h +++ b/mission/tmtc/TmStore.h @@ -19,7 +19,7 @@ enum class RolloverInterval { MINUTELY, HOURLY, DAILY }; class TmStore : public SystemObject { public: - TmStore(object_id_t objectId, std::string baseName, RolloverInterval intervalUnit, + TmStore(object_id_t objectId, std::string baseDir, std::string baseName, RolloverInterval intervalUnit, uint32_t intervalCount, timeval& currentTv, SdCardMountedIF& sdcMan); void addApid(uint16_t apid); @@ -39,8 +39,9 @@ class TmStore : public SystemObject { MessageQueueId_t getCommandQueue(); PacketFilter filter; bool baseDirUninitialized = true; + std::string baseDir; std::string baseName; - std::filesystem::path baseDir; + std::filesystem::path basePath; uint32_t rolloverDiffSeconds = 0; std::array fileBuf{}; timeval& currentTv; From 9cea0c50c343114a586ea8a80c81a741bfad1d0f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 14 Dec 2022 10:35:30 +0100 Subject: [PATCH 36/87] using const char* instead --- mission/tmtc/TmStore.cpp | 2 +- mission/tmtc/TmStore.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mission/tmtc/TmStore.cpp b/mission/tmtc/TmStore.cpp index 16ae51a9..d7f77a04 100644 --- a/mission/tmtc/TmStore.cpp +++ b/mission/tmtc/TmStore.cpp @@ -10,7 +10,7 @@ using namespace returnvalue; -TmStore::TmStore(object_id_t objectId, std::string baseDir, std::string baseName, +TmStore::TmStore(object_id_t objectId, const char* baseDir, std::string baseName, RolloverInterval intervalUnit, uint32_t intervalCount, timeval& currentTv, SdCardMountedIF& sdcMan) : SystemObject(objectId), baseDir(std::move(baseDir)), baseName(std::move(baseName)), currentTv(currentTv), sdcMan(sdcMan) { calcDiffSeconds(intervalUnit, intervalCount); diff --git a/mission/tmtc/TmStore.h b/mission/tmtc/TmStore.h index 9fdaf462..c048b385 100644 --- a/mission/tmtc/TmStore.h +++ b/mission/tmtc/TmStore.h @@ -19,7 +19,7 @@ enum class RolloverInterval { MINUTELY, HOURLY, DAILY }; class TmStore : public SystemObject { public: - TmStore(object_id_t objectId, std::string baseDir, std::string baseName, RolloverInterval intervalUnit, + TmStore(object_id_t objectId, const char* baseDir, std::string baseName, RolloverInterval intervalUnit, uint32_t intervalCount, timeval& currentTv, SdCardMountedIF& sdcMan); void addApid(uint16_t apid); @@ -39,7 +39,7 @@ class TmStore : public SystemObject { MessageQueueId_t getCommandQueue(); PacketFilter filter; bool baseDirUninitialized = true; - std::string baseDir; + const char* baseDir; std::string baseName; std::filesystem::path basePath; uint32_t rolloverDiffSeconds = 0; From 58d6b59b7cfab99d0cb6a979e08e2c326db16618 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 14 Dec 2022 10:42:16 +0100 Subject: [PATCH 37/87] it seems to work now --- mission/tmtc/PusTmFunnel.cpp | 3 ++- mission/tmtc/TmStore.cpp | 23 ++++++++++++++--------- mission/tmtc/TmStore.h | 5 +++-- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/mission/tmtc/PusTmFunnel.cpp b/mission/tmtc/PusTmFunnel.cpp index 236e68fa..39ef4bc5 100644 --- a/mission/tmtc/PusTmFunnel.cpp +++ b/mission/tmtc/PusTmFunnel.cpp @@ -12,7 +12,8 @@ PusTmFunnel::PusTmFunnel(object_id_t objectId, TimeReaderIF &timeReader, Storage timeReader(timeReader), miscStore(objects::MISC_STORE, "tm", "misc", RolloverInterval::HOURLY, 8, currentTv, sdcMan), okStore(objects::OK_STORE, "tm", "ok", RolloverInterval::MINUTELY, 30, currentTv, sdcMan), - notOkStore(objects::NOT_OK_STORE,"tm", "nok", RolloverInterval::MINUTELY, 30, currentTv, sdcMan), + notOkStore(objects::NOT_OK_STORE, "tm", "nok", RolloverInterval::MINUTELY, 30, currentTv, + sdcMan), sdcMan(sdcMan) { Clock::getClock_timeval(¤tTv); Clock::getUptime(&lastTvUpdate); diff --git a/mission/tmtc/TmStore.cpp b/mission/tmtc/TmStore.cpp index d7f77a04..4a0813b0 100644 --- a/mission/tmtc/TmStore.cpp +++ b/mission/tmtc/TmStore.cpp @@ -11,8 +11,13 @@ using namespace returnvalue; TmStore::TmStore(object_id_t objectId, const char* baseDir, std::string baseName, - RolloverInterval intervalUnit, uint32_t intervalCount, timeval& currentTv, SdCardMountedIF& sdcMan) - : SystemObject(objectId), baseDir(std::move(baseDir)), baseName(std::move(baseName)), currentTv(currentTv), sdcMan(sdcMan) { + RolloverInterval intervalUnit, uint32_t intervalCount, timeval& currentTv, + SdCardMountedIF& sdcMan) + : SystemObject(objectId), + baseDir(std::move(baseDir)), + baseName(std::move(baseName)), + currentTv(currentTv), + sdcMan(sdcMan) { calcDiffSeconds(intervalUnit, intervalCount); } @@ -119,10 +124,10 @@ void TmStore::assignAndOrCreateMostRecentFile() { } unsigned int underscorePos = pathStr.find_last_of('_'); std::string stampStr = pathStr.substr(underscorePos + 1); - int count = - sscanf(stampStr.c_str(), - "%4" SCNu32 "-%2" SCNu32 "-%2" SCNu32 "T%2" SCNu32 ":%2" SCNu32 ":%2" SCNu32 "Z", - &tod.year, &tod.month, &tod.day, &tod.hour, &tod.minute, &tod.second); + int count = sscanf(stampStr.c_str(), + "%04" SCNu32 "-%02" SCNu32 "-%02" SCNu32 "T%02" SCNu32 "-%02" SCNu32 + "-%02" SCNu32 "Z", + &tod.year, &tod.month, &tod.day, &tod.hour, &tod.minute, &tod.second); if (count != 6) { continue; } @@ -137,12 +142,12 @@ void TmStore::assignAndOrCreateMostRecentFile() { unsigned currentIdx = 0; path pathStart = basePath / baseName; memcpy(fileBuf.data() + currentIdx, pathStart.c_str(), pathStart.string().length()); - currentIdx += baseName.size(); + currentIdx += pathStart.string().length(); Clock::TimeOfDay_t tod; Clock::convertTimevalToTimeOfDay(¤tTv, &tod); currentIdx += sprintf(reinterpret_cast(fileBuf.data() + currentIdx), - "_%4" PRIu32 "-%2" PRIu32 "-%2" PRIu32 "T%2" PRIu32 ":%2" PRIu32 - ":%2" PRIu32 "Z.bin", + "_%04" PRIu32 "-%02" PRIu32 "-%02" PRIu32 "T%02" PRIu32 "-%02" PRIu32 + "-%02" PRIu32 "Z.bin", tod.year, tod.month, tod.day, tod.hour, tod.minute, tod.second); path newPath(std::string(reinterpret_cast(fileBuf.data()), currentIdx)); std::ofstream of(newPath, std::ios::binary); diff --git a/mission/tmtc/TmStore.h b/mission/tmtc/TmStore.h index c048b385..5c2f10b6 100644 --- a/mission/tmtc/TmStore.h +++ b/mission/tmtc/TmStore.h @@ -19,8 +19,9 @@ enum class RolloverInterval { MINUTELY, HOURLY, DAILY }; class TmStore : public SystemObject { public: - TmStore(object_id_t objectId, const char* baseDir, std::string baseName, RolloverInterval intervalUnit, - uint32_t intervalCount, timeval& currentTv, SdCardMountedIF& sdcMan); + TmStore(object_id_t objectId, const char* baseDir, std::string baseName, + RolloverInterval intervalUnit, uint32_t intervalCount, timeval& currentTv, + SdCardMountedIF& sdcMan); void addApid(uint16_t apid); void addService(uint8_t service); From ff9bcd6b1447a57a30b72437e53db50275b4423a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 14 Dec 2022 10:54:18 +0100 Subject: [PATCH 38/87] added remaining missing stores --- common/config/eive/objects.h | 7 ++++--- mission/tmtc/PusTmFunnel.cpp | 18 +++++++++++++++--- mission/tmtc/PusTmFunnel.h | 7 ++----- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/common/config/eive/objects.h b/common/config/eive/objects.h index ede974fb..fa5ebecc 100644 --- a/common/config/eive/objects.h +++ b/common/config/eive/objects.h @@ -146,9 +146,10 @@ enum commonObjects : uint32_t { CFDP_TM_FUNNEL = 0x73000102, CFDP_HANDLER = 0x73000205, CFDP_DISTRIBUTOR = 0x73000206, - MISC_STORE = 0x73020001, - OK_STORE = 0x73020002, - NOT_OK_STORE = 0x73020003, + MISC_TM_STORE = 0x73020001, + OK_TM_STORE = 0x73020002, + NOT_OK_TM_STORE = 0x73020003, + HK_TM_STORE = 0x73020004 }; } diff --git a/mission/tmtc/PusTmFunnel.cpp b/mission/tmtc/PusTmFunnel.cpp index 39ef4bc5..c0aabf89 100644 --- a/mission/tmtc/PusTmFunnel.cpp +++ b/mission/tmtc/PusTmFunnel.cpp @@ -10,22 +10,34 @@ PusTmFunnel::PusTmFunnel(object_id_t objectId, TimeReaderIF &timeReader, Storage SdCardMountedIF &sdcMan, uint32_t messageDepth) : TmFunnelBase(objectId, tmStore, messageDepth), timeReader(timeReader), - miscStore(objects::MISC_STORE, "tm", "misc", RolloverInterval::HOURLY, 8, currentTv, sdcMan), - okStore(objects::OK_STORE, "tm", "ok", RolloverInterval::MINUTELY, 30, currentTv, sdcMan), - notOkStore(objects::NOT_OK_STORE, "tm", "nok", RolloverInterval::MINUTELY, 30, currentTv, + miscStore(objects::MISC_TM_STORE, "tm", "misc", RolloverInterval::HOURLY, 2, currentTv, + sdcMan), + okStore(objects::OK_TM_STORE, "tm", "ok", RolloverInterval::MINUTELY, 30, currentTv, sdcMan), + notOkStore(objects::NOT_OK_TM_STORE, "tm", "nok", RolloverInterval::MINUTELY, 30, currentTv, sdcMan), + hkStore(objects::HK_TM_STORE, "tm", "hk", RolloverInterval::MINUTELY, 15, currentTv, sdcMan), sdcMan(sdcMan) { Clock::getClock_timeval(¤tTv); Clock::getUptime(&lastTvUpdate); miscStore.addApid(config::EIVE_PUS_APID); miscStore.addService(17); + miscStore.addService(200); okStore.addApid(config::EIVE_PUS_APID); okStore.addServiceSubservice(5, 1); okStore.addApid(config::EIVE_PUS_APID); + okStore.addService(8); okStore.addServiceSubservice(1, 1); okStore.addServiceSubservice(1, 3); okStore.addServiceSubservice(1, 5); okStore.addServiceSubservice(1, 7); + notOkStore.addApid(config::EIVE_PUS_APID); + notOkStore.addServiceSubservice(5, 2); + notOkStore.addServiceSubservice(5, 3); + notOkStore.addServiceSubservice(5, 4); + notOkStore.addServiceSubservice(1, 2); + notOkStore.addServiceSubservice(1, 4); + notOkStore.addServiceSubservice(1, 6); + notOkStore.addServiceSubservice(1, 8); } PusTmFunnel::~PusTmFunnel() = default; diff --git a/mission/tmtc/PusTmFunnel.h b/mission/tmtc/PusTmFunnel.h index 26bbfec2..d447e88b 100644 --- a/mission/tmtc/PusTmFunnel.h +++ b/mission/tmtc/PusTmFunnel.h @@ -16,11 +16,7 @@ /** * @brief TM Recipient. * @details - * TODO: Add support for TM storage by using the (or a) LIVE flag provided by the CCSDS or Syrlinks - * handler. If we are in LIVE TM mode, forward TM to downlink destination directly. Otherwise, - * forward to TM storage backend which stores TMs into files. - * Main telemetry receiver. All generated telemetry is funneled into - * this object. + * Main telemetry receiver. All generated telemetry is funneled into this object. * @ingroup utility * @author J. Meier, R. Mueller */ @@ -45,6 +41,7 @@ class PusTmFunnel : public TmFunnelBase { TmStore miscStore; TmStore okStore; TmStore notOkStore; + TmStore hkStore; SdCardMountedIF &sdcMan; ReturnValue_t handlePacket(TmTcMessage &message); From 5d67b896aaf232535096b5640e4e2948ab1cf285 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 14 Dec 2022 11:00:07 +0100 Subject: [PATCH 39/87] improve store init handling, add remaining stores --- mission/tmtc/PusTmFunnel.cpp | 21 +++++++++++++-------- mission/tmtc/PusTmFunnel.h | 1 + 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/mission/tmtc/PusTmFunnel.cpp b/mission/tmtc/PusTmFunnel.cpp index c0aabf89..5c4c8ead 100644 --- a/mission/tmtc/PusTmFunnel.cpp +++ b/mission/tmtc/PusTmFunnel.cpp @@ -19,6 +19,8 @@ PusTmFunnel::PusTmFunnel(object_id_t objectId, TimeReaderIF &timeReader, Storage sdcMan(sdcMan) { Clock::getClock_timeval(¤tTv); Clock::getUptime(&lastTvUpdate); + hkStore.addApid(config::EIVE_PUS_APID); + hkStore.addService(3); miscStore.addApid(config::EIVE_PUS_APID); miscStore.addService(17); miscStore.addService(200); @@ -88,12 +90,9 @@ ReturnValue_t PusTmFunnel::handlePacket(TmTcMessage &message) { lastTvUpdate = currentUptime; } - if (sdcMan.isSdCardUsable(std::nullopt)) { - if (not storesInitialized) { - miscStore.updateBaseDir(); - okStore.updateBaseDir(); - storesInitialized = true; - } + bool sdcUsable = sdcMan.isSdCardUsable(std::nullopt); + initStoresIfPossible(sdcUsable); + if (sdcUsable) { miscStore.passPacket(packet); okStore.passPacket(packet); } @@ -131,11 +130,17 @@ ReturnValue_t PusTmFunnel::handlePacket(TmTcMessage &message) { const char *PusTmFunnel::getName() const { return "PUS TM Funnel"; } -ReturnValue_t PusTmFunnel::initialize() { - if (not storesInitialized and sdcMan.isSdCardUsable(std::nullopt)) { +void PusTmFunnel::initStoresIfPossible(bool sdCardUsable) { + if (not storesInitialized and sdCardUsable) { miscStore.updateBaseDir(); okStore.updateBaseDir(); + hkStore.updateBaseDir(); + notOkStore.updateBaseDir(); storesInitialized = true; } +} + +ReturnValue_t PusTmFunnel::initialize() { + initStoresIfPossible(sdcMan.isSdCardUsable(std::nullopt)); return returnvalue::OK; } diff --git a/mission/tmtc/PusTmFunnel.h b/mission/tmtc/PusTmFunnel.h index d447e88b..b380ec79 100644 --- a/mission/tmtc/PusTmFunnel.h +++ b/mission/tmtc/PusTmFunnel.h @@ -45,6 +45,7 @@ class PusTmFunnel : public TmFunnelBase { SdCardMountedIF &sdcMan; ReturnValue_t handlePacket(TmTcMessage &message); + void initStoresIfPossible(bool sdCardUsable); ReturnValue_t initialize() override; }; From ec02332615bf0f823203996420410d997a781727 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 14 Dec 2022 11:29:32 +0100 Subject: [PATCH 40/87] start implementing the PUS Service --- mission/tmtc/Service15TmStorage.cpp | 12 +++++++++++- mission/tmtc/Service15TmStorage.h | 4 ++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/mission/tmtc/Service15TmStorage.cpp b/mission/tmtc/Service15TmStorage.cpp index 590b6c8e..ae2400b5 100644 --- a/mission/tmtc/Service15TmStorage.cpp +++ b/mission/tmtc/Service15TmStorage.cpp @@ -8,7 +8,17 @@ Service15TmStorage::Service15TmStorage(object_id_t objectId, uint16_t apid, : CommandingServiceBase(objectId, apid, "PUS Service 15", 15, numParallelCommands, commandTimeoutSecs, queueDepth) {} -ReturnValue_t Service15TmStorage::isValidSubservice(uint8_t subservice) { return OK; } +ReturnValue_t Service15TmStorage::isValidSubservice(uint8_t subservice) { + switch (subservice) { + case(Subservices::START_BY_TIME_RANGE_RETRIEVAL): { + return OK; + } + case(Subservices::DELETE_UP_TO): { + return OK; + } + } + return FAILED; +} ReturnValue_t Service15TmStorage::getMessageQueueAndObject(uint8_t subservice, const uint8_t *tcData, size_t tcDataLen, diff --git a/mission/tmtc/Service15TmStorage.h b/mission/tmtc/Service15TmStorage.h index 0243fdb3..92cab52a 100644 --- a/mission/tmtc/Service15TmStorage.h +++ b/mission/tmtc/Service15TmStorage.h @@ -5,6 +5,10 @@ class Service15TmStorage : public CommandingServiceBase { public: + enum Subservices: uint8_t { + START_BY_TIME_RANGE_RETRIEVAL = 9, + DELETE_UP_TO = 11 + }; explicit Service15TmStorage(object_id_t objectId, uint16_t apid, uint8_t numParallelCommands, uint16_t commandTimeoutSecs, size_t queueDepth); From 4d473315feecfb45c0dc9af18990e4962518d99d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 14 Dec 2022 13:19:14 +0100 Subject: [PATCH 41/87] allow sending TC requests to funnels --- mission/core/GenericFactory.cpp | 4 ++-- mission/tmtc/CfdpTmFunnel.cpp | 4 ++-- mission/tmtc/CfdpTmFunnel.h | 2 +- mission/tmtc/PusTmFunnel.cpp | 4 ++-- mission/tmtc/PusTmFunnel.h | 2 +- mission/tmtc/Service15TmStorage.cpp | 12 ++++++------ mission/tmtc/Service15TmStorage.h | 5 +---- mission/tmtc/TmFunnelBase.cpp | 6 +++++- mission/tmtc/TmFunnelBase.h | 11 +++++++++-- 9 files changed, 29 insertions(+), 21 deletions(-) diff --git a/mission/core/GenericFactory.cpp b/mission/core/GenericFactory.cpp index c0e1eb43..0e58e1ec 100644 --- a/mission/core/GenericFactory.cpp +++ b/mission/core/GenericFactory.cpp @@ -121,8 +121,8 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun new CcsdsDistributor(config::EIVE_PUS_APID, objects::CCSDS_PACKET_DISTRIBUTOR); new PusDistributor(config::EIVE_PUS_APID, objects::PUS_PACKET_DISTRIBUTOR, ccsdsDistrib); - *cfdpFunnel = new CfdpTmFunnel(objects::CFDP_TM_FUNNEL, config::EIVE_CFDP_APID, *tmStore, 50); - *pusFunnel = new PusTmFunnel(objects::PUS_TM_FUNNEL, *timeStamper, *tmStore, sdcMan, 80); + *cfdpFunnel = new CfdpTmFunnel(objects::CFDP_TM_FUNNEL, config::EIVE_CFDP_APID, *tmStore, 50, 15); + *pusFunnel = new PusTmFunnel(objects::PUS_TM_FUNNEL, *timeStamper, *tmStore, sdcMan, 80, 15); #if OBSW_ADD_TCPIP_SERVERS == 1 #if OBSW_ADD_TMTC_UDP_SERVER == 1 (*cfdpFunnel)->addDestination(*udpBridge, 0); diff --git a/mission/tmtc/CfdpTmFunnel.cpp b/mission/tmtc/CfdpTmFunnel.cpp index aff7c95d..e5080b71 100644 --- a/mission/tmtc/CfdpTmFunnel.cpp +++ b/mission/tmtc/CfdpTmFunnel.cpp @@ -5,8 +5,8 @@ #include "fsfw/tmtcservices/TmTcMessage.h" CfdpTmFunnel::CfdpTmFunnel(object_id_t objectId, uint16_t cfdpInCcsdsApid, - StorageManagerIF& tmStore, uint32_t messageDepth) - : TmFunnelBase(objectId, tmStore, messageDepth), cfdpInCcsdsApid(cfdpInCcsdsApid) {} + StorageManagerIF& tmStore, uint32_t tmMsgDepth, uint32_t tcMsgDepth) + : TmFunnelBase(objectId, tmStore, tmMsgDepth, tcMsgDepth), cfdpInCcsdsApid(cfdpInCcsdsApid) {} const char* CfdpTmFunnel::getName() const { return "CFDP TM Funnel"; } diff --git a/mission/tmtc/CfdpTmFunnel.h b/mission/tmtc/CfdpTmFunnel.h index e294956a..32d16975 100644 --- a/mission/tmtc/CfdpTmFunnel.h +++ b/mission/tmtc/CfdpTmFunnel.h @@ -13,7 +13,7 @@ class CfdpTmFunnel : public TmFunnelBase { public: CfdpTmFunnel(object_id_t objectId, uint16_t cfdpInCcsdsApid, StorageManagerIF& tmStore, - uint32_t messageDepth); + uint32_t tmMsgDepth, uint32_t tcMsgDepth); [[nodiscard]] const char* getName() const override; ReturnValue_t performOperation(uint8_t opCode); ReturnValue_t initialize() override; diff --git a/mission/tmtc/PusTmFunnel.cpp b/mission/tmtc/PusTmFunnel.cpp index 5c4c8ead..ff66f3c9 100644 --- a/mission/tmtc/PusTmFunnel.cpp +++ b/mission/tmtc/PusTmFunnel.cpp @@ -7,8 +7,8 @@ #include "fsfw/tmtcpacket/pus/tm/PusTmZcWriter.h" PusTmFunnel::PusTmFunnel(object_id_t objectId, TimeReaderIF &timeReader, StorageManagerIF &tmStore, - SdCardMountedIF &sdcMan, uint32_t messageDepth) - : TmFunnelBase(objectId, tmStore, messageDepth), + SdCardMountedIF &sdcMan, uint32_t tmMsgDepth, uint32_t tcMsgDepth) + : TmFunnelBase(objectId, tmStore, tmMsgDepth, tcMsgDepth), timeReader(timeReader), miscStore(objects::MISC_TM_STORE, "tm", "misc", RolloverInterval::HOURLY, 2, currentTv, sdcMan), diff --git a/mission/tmtc/PusTmFunnel.h b/mission/tmtc/PusTmFunnel.h index b380ec79..a54093c2 100644 --- a/mission/tmtc/PusTmFunnel.h +++ b/mission/tmtc/PusTmFunnel.h @@ -23,7 +23,7 @@ class PusTmFunnel : public TmFunnelBase { public: explicit PusTmFunnel(object_id_t objectId, TimeReaderIF &timeReader, StorageManagerIF &tmStore, - SdCardMountedIF &sdcMan, uint32_t messageDepth = 10); + SdCardMountedIF &sdcMan, uint32_t tmMsgDepth, uint32_t tcMsgDepth); [[nodiscard]] const char *getName() const override; ~PusTmFunnel() override; diff --git a/mission/tmtc/Service15TmStorage.cpp b/mission/tmtc/Service15TmStorage.cpp index ae2400b5..5bdec8e1 100644 --- a/mission/tmtc/Service15TmStorage.cpp +++ b/mission/tmtc/Service15TmStorage.cpp @@ -10,12 +10,12 @@ Service15TmStorage::Service15TmStorage(object_id_t objectId, uint16_t apid, ReturnValue_t Service15TmStorage::isValidSubservice(uint8_t subservice) { switch (subservice) { - case(Subservices::START_BY_TIME_RANGE_RETRIEVAL): { - return OK; - } - case(Subservices::DELETE_UP_TO): { - return OK; - } + case (Subservices::START_BY_TIME_RANGE_RETRIEVAL): { + return OK; + } + case (Subservices::DELETE_UP_TO): { + return OK; + } } return FAILED; } diff --git a/mission/tmtc/Service15TmStorage.h b/mission/tmtc/Service15TmStorage.h index 92cab52a..2074754a 100644 --- a/mission/tmtc/Service15TmStorage.h +++ b/mission/tmtc/Service15TmStorage.h @@ -5,10 +5,7 @@ class Service15TmStorage : public CommandingServiceBase { public: - enum Subservices: uint8_t { - START_BY_TIME_RANGE_RETRIEVAL = 9, - DELETE_UP_TO = 11 - }; + enum Subservices : uint8_t { START_BY_TIME_RANGE_RETRIEVAL = 9, DELETE_UP_TO = 11 }; explicit Service15TmStorage(object_id_t objectId, uint16_t apid, uint8_t numParallelCommands, uint16_t commandTimeoutSecs, size_t queueDepth); diff --git a/mission/tmtc/TmFunnelBase.cpp b/mission/tmtc/TmFunnelBase.cpp index fa0062e6..156e4664 100644 --- a/mission/tmtc/TmFunnelBase.cpp +++ b/mission/tmtc/TmFunnelBase.cpp @@ -2,11 +2,15 @@ #include "fsfw/ipc/QueueFactory.h" -TmFunnelBase::TmFunnelBase(object_id_t objectId, StorageManagerIF &tmStore, uint32_t tmMsgDepth) +TmFunnelBase::TmFunnelBase(object_id_t objectId, StorageManagerIF &tmStore, uint32_t tmMsgDepth, + uint32_t tcMsgDepth) : SystemObject(objectId), tmStore(tmStore) { tmQueue = QueueFactory::instance()->createMessageQueue(tmMsgDepth); + tcQueue = QueueFactory::instance()->createMessageQueue(tcMsgDepth); } +MessageQueueId_t TmFunnelBase::getCommandQueue() const { return tcQueue->getId(); } + TmFunnelBase::~TmFunnelBase() { QueueFactory::instance()->deleteMessageQueue(tmQueue); } MessageQueueId_t TmFunnelBase::getReportReceptionQueue(uint8_t virtualChannel) const { diff --git a/mission/tmtc/TmFunnelBase.h b/mission/tmtc/TmFunnelBase.h index c630fefd..271c17c0 100644 --- a/mission/tmtc/TmFunnelBase.h +++ b/mission/tmtc/TmFunnelBase.h @@ -3,14 +3,20 @@ #include #include +#include #include #include -class TmFunnelBase : public AcceptsTelemetryIF, public SystemObject { +class TmFunnelBase : public TmStoreFrontendSimpleIF, + public AcceptsTelemetryIF, + public SystemObject { public: - TmFunnelBase(object_id_t objectId, StorageManagerIF& tmStore, uint32_t tmMsgDepth); + TmFunnelBase(object_id_t objectId, StorageManagerIF& tmStore, uint32_t tmMsgDepth, + uint32_t tcMsgDepth); void addDestination(const AcceptsTelemetryIF& downlinkDestination, uint8_t vcid = 0); + + [[nodiscard]] MessageQueueId_t getCommandQueue() const override; [[nodiscard]] MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel) const override; virtual ~TmFunnelBase(); @@ -18,6 +24,7 @@ class TmFunnelBase : public AcceptsTelemetryIF, public SystemObject { protected: StorageManagerIF& tmStore; std::vector> destinations; + MessageQueueIF* tcQueue = nullptr; MessageQueueIF* tmQueue = nullptr; }; From 5431dfc9bdea0ecc342edc5123bab7062f7f4626 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 14 Dec 2022 13:51:24 +0100 Subject: [PATCH 42/87] basic packet routing --- common/config/eive/objects.h | 3 ++- fsfw | 2 +- mission/tmtc/Service15TmStorage.cpp | 18 ++++++++++++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/common/config/eive/objects.h b/common/config/eive/objects.h index fa5ebecc..6c2d87a1 100644 --- a/common/config/eive/objects.h +++ b/common/config/eive/objects.h @@ -149,7 +149,8 @@ enum commonObjects : uint32_t { MISC_TM_STORE = 0x73020001, OK_TM_STORE = 0x73020002, NOT_OK_TM_STORE = 0x73020003, - HK_TM_STORE = 0x73020004 + HK_TM_STORE = 0x73020004, + CFDP_TM_STORE = 0x73030000 }; } diff --git a/fsfw b/fsfw index 75fc7a05..2aa4af69 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 75fc7a056db2a4aee8c20c225fd3c2b79fce8ce3 +Subproject commit 2aa4af69742d932f09ec2a1d3d29b648295035d1 diff --git a/mission/tmtc/Service15TmStorage.cpp b/mission/tmtc/Service15TmStorage.cpp index 5bdec8e1..c4c9bc43 100644 --- a/mission/tmtc/Service15TmStorage.cpp +++ b/mission/tmtc/Service15TmStorage.cpp @@ -1,5 +1,10 @@ #include "Service15TmStorage.h" +#include +#include + +#include "eive/objects.h" + using namespace returnvalue; Service15TmStorage::Service15TmStorage(object_id_t objectId, uint16_t apid, @@ -24,6 +29,19 @@ ReturnValue_t Service15TmStorage::getMessageQueueAndObject(uint8_t subservice, const uint8_t *tcData, size_t tcDataLen, MessageQueueId_t *id, object_id_t *objectId) { + object_id_t targetObjectId; + SerializeAdapter::deSerialize(&targetObjectId, &tcData, &tcDataLen, + SerializeIF::Endianness::NETWORK); + if (targetObjectId == objects::CFDP_TM_STORE) { + *objectId = objects::CFDP_TM_FUNNEL; + } else { + *objectId = objects::PUS_TM_FUNNEL; + } + auto *frontendIF = ObjectManager::instance()->get(*objectId); + if (frontendIF == nullptr) { + return FAILED; + } + *id = frontendIF->getCommandQueue(); return OK; } From 62b3e16ac4ec45081ed1e2c92bd6d3ade829b3eb Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 14 Dec 2022 15:09:57 +0100 Subject: [PATCH 43/87] add service 2 --- mission/tmtc/PusTmFunnel.cpp | 1 + mission/tmtc/Service15TmStorage.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/mission/tmtc/PusTmFunnel.cpp b/mission/tmtc/PusTmFunnel.cpp index ff66f3c9..923150b3 100644 --- a/mission/tmtc/PusTmFunnel.cpp +++ b/mission/tmtc/PusTmFunnel.cpp @@ -23,6 +23,7 @@ PusTmFunnel::PusTmFunnel(object_id_t objectId, TimeReaderIF &timeReader, Storage hkStore.addService(3); miscStore.addApid(config::EIVE_PUS_APID); miscStore.addService(17); + miscStore.addService(2); miscStore.addService(200); okStore.addApid(config::EIVE_PUS_APID); okStore.addServiceSubservice(5, 1); diff --git a/mission/tmtc/Service15TmStorage.cpp b/mission/tmtc/Service15TmStorage.cpp index c4c9bc43..c44f226c 100644 --- a/mission/tmtc/Service15TmStorage.cpp +++ b/mission/tmtc/Service15TmStorage.cpp @@ -48,6 +48,7 @@ ReturnValue_t Service15TmStorage::getMessageQueueAndObject(uint8_t subservice, ReturnValue_t Service15TmStorage::prepareCommand(CommandMessage *message, uint8_t subservice, const uint8_t *tcData, size_t tcDataLen, uint32_t *state, object_id_t objectId) { + return OK; } From b6522c9fb352f4c90abedbc49b2f9e234387a5d8 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 14 Dec 2022 15:41:20 +0100 Subject: [PATCH 44/87] that should do the job --- mission/tmtc/Service15TmStorage.cpp | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/mission/tmtc/Service15TmStorage.cpp b/mission/tmtc/Service15TmStorage.cpp index c44f226c..d752bf00 100644 --- a/mission/tmtc/Service15TmStorage.cpp +++ b/mission/tmtc/Service15TmStorage.cpp @@ -4,6 +4,7 @@ #include #include "eive/objects.h" +#include "fsfw/tmstorage/TmStoreMessage.h" using namespace returnvalue; @@ -48,7 +49,29 @@ ReturnValue_t Service15TmStorage::getMessageQueueAndObject(uint8_t subservice, ReturnValue_t Service15TmStorage::prepareCommand(CommandMessage *message, uint8_t subservice, const uint8_t *tcData, size_t tcDataLen, uint32_t *state, object_id_t objectId) { - + if (subservice == Subservices::START_BY_TIME_RANGE_RETRIEVAL) { + if (tcDataLen != 12) { + return INVALID_TC; + } + store_address_t storeId; + ReturnValue_t result = ipcStore->addData(&storeId, tcData, tcDataLen); + if (result != OK) { + return result; + } + // Store timestamps + TmStoreMessage::setDownlinkContentTimeMessage(message, storeId); + } else if (subservice == Subservices::DELETE_UP_TO) { + if (tcDataLen != 8) { + return INVALID_TC; + } + store_address_t storeId; + ReturnValue_t result = ipcStore->addData(&storeId, tcData, tcDataLen); + if (result != OK) { + return result; + } + // Store timestamps + TmStoreMessage::setDeleteContentTimeMessage(message, storeId); + } return OK; } From bbf0def3ff9c7b07d6030a6db5cbeb937a075ce2 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 16 Dec 2022 13:26:20 +0100 Subject: [PATCH 45/87] add missing dot --- mission/tmtc/TmStore.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mission/tmtc/TmStore.cpp b/mission/tmtc/TmStore.cpp index 4a0813b0..07fddcf0 100644 --- a/mission/tmtc/TmStore.cpp +++ b/mission/tmtc/TmStore.cpp @@ -72,7 +72,8 @@ ReturnValue_t TmStore::storePacket(PusTmReader& reader) { uint8_t appendedCounter = 1; path rolloverName; while (true) { - rolloverName = path(mostRecentFile.value().string() + std::to_string(appendedCounter)); + rolloverName = + path(mostRecentFile.value().string() + "." + std::to_string(appendedCounter)); if (not exists(rolloverName)) { break; } From 74f116f2fa15a84e7fc12e66adb487349aa3c571 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 19 Dec 2022 13:25:45 +0100 Subject: [PATCH 46/87] that should be the basic interface --- mission/tmtc/PusTmFunnel.cpp | 31 ++++++++++++++++++++++++++----- mission/tmtc/TmStore.cpp | 6 ++++++ mission/tmtc/TmStore.h | 5 +++++ tmtc | 2 +- 4 files changed, 38 insertions(+), 6 deletions(-) diff --git a/mission/tmtc/PusTmFunnel.cpp b/mission/tmtc/PusTmFunnel.cpp index 923150b3..a3e6f144 100644 --- a/mission/tmtc/PusTmFunnel.cpp +++ b/mission/tmtc/PusTmFunnel.cpp @@ -2,8 +2,10 @@ #include "eive/definitions.h" #include "eive/objects.h" +#include "fsfw/ipc/CommandMessage.h" #include "fsfw/ipc/QueueFactory.h" #include "fsfw/objectmanager.h" +#include "fsfw/tmstorage/TmStoreMessage.h" #include "fsfw/tmtcpacket/pus/tm/PusTmZcWriter.h" PusTmFunnel::PusTmFunnel(object_id_t objectId, TimeReaderIF &timeReader, StorageManagerIF &tmStore, @@ -46,8 +48,31 @@ PusTmFunnel::PusTmFunnel(object_id_t objectId, TimeReaderIF &timeReader, Storage PusTmFunnel::~PusTmFunnel() = default; ReturnValue_t PusTmFunnel::performOperation(uint8_t) { + CommandMessage cmdMessage; + ReturnValue_t status = tcQueue->receiveMessage(&cmdMessage); + while (status == returnvalue::OK) { + if (cmdMessage.getCommand() == messagetypes::TM_STORE) { + object_id_t objectId = TmStoreMessage::getObjectId(&cmdMessage); + switch (objectId) { + case (objects::HK_TM_STORE): { + break; + } + case (objects::OK_TM_STORE): { + break; + } + case (objects::NOT_OK_TM_STORE): { + break; + } + case (objects::MISC_TM_STORE): { + break; + } + default: { + } + } + } + } TmTcMessage currentMessage; - ReturnValue_t status = tmQueue->receiveMessage(¤tMessage); + status = tmQueue->receiveMessage(¤tMessage); while (status == returnvalue::OK) { status = handlePacket(currentMessage); if (status != returnvalue::OK) { @@ -56,10 +81,6 @@ ReturnValue_t PusTmFunnel::performOperation(uint8_t) { } status = tmQueue->receiveMessage(¤tMessage); } - - if (status == MessageQueueIF::EMPTY) { - return returnvalue::OK; - } return status; } diff --git a/mission/tmtc/TmStore.cpp b/mission/tmtc/TmStore.cpp index 07fddcf0..2de1e818 100644 --- a/mission/tmtc/TmStore.cpp +++ b/mission/tmtc/TmStore.cpp @@ -181,3 +181,9 @@ void TmStore::addServiceSubservice(uint8_t service, uint8_t subservice) { } filter.serviceSubservices.value().push_back({service, subservice}); } + +void TmStore::deleteUpTo(uint32_t unixSeconds) {} + +void TmStore::dumpFromUpTo(uint32_t fromUnixSeconds, uint32_t upToUnixSeconds, + std::vector>& destinations, + MessageQueueIF* tmQueue) {} diff --git a/mission/tmtc/TmStore.h b/mission/tmtc/TmStore.h index 5c2f10b6..72071e02 100644 --- a/mission/tmtc/TmStore.h +++ b/mission/tmtc/TmStore.h @@ -27,6 +27,11 @@ class TmStore : public SystemObject { void addService(uint8_t service); void addServiceSubservice(uint8_t service, uint8_t subservice); + void deleteUpTo(uint32_t unixSeconds); + void dumpFromUpTo(uint32_t fromUnixSeconds, uint32_t upToUnixSeconds, + std::vector>& destinations, + MessageQueueIF* tmQueue); + void updateBaseDir(); ReturnValue_t passPacket(PusTmReader& reader); diff --git a/tmtc b/tmtc index 30cf4736..383b3214 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 30cf47365fec68a4b78395de03ecb2ae95af4e7e +Subproject commit 383b32141c8c382b84c587d6814fe9252dde0b4a From c4c1f09f2e751ea3c93478536984509b23e700e7 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 19 Dec 2022 13:57:05 +0100 Subject: [PATCH 47/87] continue request handling --- mission/core/GenericFactory.cpp | 9 ++++++--- mission/tmtc/CfdpTmFunnel.cpp | 6 ++++-- mission/tmtc/CfdpTmFunnel.h | 2 +- mission/tmtc/PusTmFunnel.cpp | 26 +++++++++++++++++++++++--- mission/tmtc/PusTmFunnel.h | 3 ++- mission/tmtc/TmFunnelBase.cpp | 4 ++-- mission/tmtc/TmFunnelBase.h | 3 ++- 7 files changed, 40 insertions(+), 13 deletions(-) diff --git a/mission/core/GenericFactory.cpp b/mission/core/GenericFactory.cpp index 0e58e1ec..ddd29bb9 100644 --- a/mission/core/GenericFactory.cpp +++ b/mission/core/GenericFactory.cpp @@ -80,6 +80,7 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun auto* timeStamper = new CdsShortTimeStamper(objects::TIME_STAMPER); StorageManagerIF* tcStore; StorageManagerIF* tmStore; + StorageManagerIF* ipcStore; { PoolManager::LocalPoolConfig poolCfg = {{250, 16}, {250, 32}, {250, 64}, {150, 128}, {120, 1024}, {120, 2048}}; @@ -95,7 +96,7 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun { PoolManager::LocalPoolConfig poolCfg = {{300, 16}, {200, 32}, {150, 64}, {150, 128}, {100, 256}, {50, 512}, {50, 1024}, {10, 2048}}; - new PoolManager(objects::IPC_STORE, poolCfg); + ipcStore = new PoolManager(objects::IPC_STORE, poolCfg); } #if OBSW_ADD_TCPIP_SERVERS == 1 @@ -121,8 +122,10 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun new CcsdsDistributor(config::EIVE_PUS_APID, objects::CCSDS_PACKET_DISTRIBUTOR); new PusDistributor(config::EIVE_PUS_APID, objects::PUS_PACKET_DISTRIBUTOR, ccsdsDistrib); - *cfdpFunnel = new CfdpTmFunnel(objects::CFDP_TM_FUNNEL, config::EIVE_CFDP_APID, *tmStore, 50, 15); - *pusFunnel = new PusTmFunnel(objects::PUS_TM_FUNNEL, *timeStamper, *tmStore, sdcMan, 80, 15); + *cfdpFunnel = new CfdpTmFunnel(objects::CFDP_TM_FUNNEL, config::EIVE_CFDP_APID, *tmStore, 50, 15, + *ipcStore); + *pusFunnel = + new PusTmFunnel(objects::PUS_TM_FUNNEL, *timeStamper, *tmStore, sdcMan, 80, 15, *ipcStore); #if OBSW_ADD_TCPIP_SERVERS == 1 #if OBSW_ADD_TMTC_UDP_SERVER == 1 (*cfdpFunnel)->addDestination(*udpBridge, 0); diff --git a/mission/tmtc/CfdpTmFunnel.cpp b/mission/tmtc/CfdpTmFunnel.cpp index e5080b71..f2d31a92 100644 --- a/mission/tmtc/CfdpTmFunnel.cpp +++ b/mission/tmtc/CfdpTmFunnel.cpp @@ -5,8 +5,10 @@ #include "fsfw/tmtcservices/TmTcMessage.h" CfdpTmFunnel::CfdpTmFunnel(object_id_t objectId, uint16_t cfdpInCcsdsApid, - StorageManagerIF& tmStore, uint32_t tmMsgDepth, uint32_t tcMsgDepth) - : TmFunnelBase(objectId, tmStore, tmMsgDepth, tcMsgDepth), cfdpInCcsdsApid(cfdpInCcsdsApid) {} + StorageManagerIF& tmStore, uint32_t tmMsgDepth, uint32_t tcMsgDepth, + StorageManagerIF& ipcStore) + : TmFunnelBase(objectId, tmStore, tmMsgDepth, tcMsgDepth, ipcStore), + cfdpInCcsdsApid(cfdpInCcsdsApid) {} const char* CfdpTmFunnel::getName() const { return "CFDP TM Funnel"; } diff --git a/mission/tmtc/CfdpTmFunnel.h b/mission/tmtc/CfdpTmFunnel.h index 32d16975..55917727 100644 --- a/mission/tmtc/CfdpTmFunnel.h +++ b/mission/tmtc/CfdpTmFunnel.h @@ -13,7 +13,7 @@ class CfdpTmFunnel : public TmFunnelBase { public: CfdpTmFunnel(object_id_t objectId, uint16_t cfdpInCcsdsApid, StorageManagerIF& tmStore, - uint32_t tmMsgDepth, uint32_t tcMsgDepth); + uint32_t tmMsgDepth, uint32_t tcMsgDepth, StorageManagerIF& ipcStore); [[nodiscard]] const char* getName() const override; ReturnValue_t performOperation(uint8_t opCode); ReturnValue_t initialize() override; diff --git a/mission/tmtc/PusTmFunnel.cpp b/mission/tmtc/PusTmFunnel.cpp index a3e6f144..ff662afd 100644 --- a/mission/tmtc/PusTmFunnel.cpp +++ b/mission/tmtc/PusTmFunnel.cpp @@ -9,8 +9,9 @@ #include "fsfw/tmtcpacket/pus/tm/PusTmZcWriter.h" PusTmFunnel::PusTmFunnel(object_id_t objectId, TimeReaderIF &timeReader, StorageManagerIF &tmStore, - SdCardMountedIF &sdcMan, uint32_t tmMsgDepth, uint32_t tcMsgDepth) - : TmFunnelBase(objectId, tmStore, tmMsgDepth, tcMsgDepth), + SdCardMountedIF &sdcMan, uint32_t tmMsgDepth, uint32_t tcMsgDepth, + StorageManagerIF &ipcStore) + : TmFunnelBase(objectId, tmStore, tmMsgDepth, tcMsgDepth, ipcStore), timeReader(timeReader), miscStore(objects::MISC_TM_STORE, "tm", "misc", RolloverInterval::HOURLY, 2, currentTv, sdcMan), @@ -51,24 +52,43 @@ ReturnValue_t PusTmFunnel::performOperation(uint8_t) { CommandMessage cmdMessage; ReturnValue_t status = tcQueue->receiveMessage(&cmdMessage); while (status == returnvalue::OK) { - if (cmdMessage.getCommand() == messagetypes::TM_STORE) { + if (cmdMessage.getMessageType() == messagetypes::TM_STORE) { + Command_t cmd = cmdMessage.getCommand(); object_id_t objectId = TmStoreMessage::getObjectId(&cmdMessage); + TmStore *tmStore = nullptr; switch (objectId) { case (objects::HK_TM_STORE): { + tmStore = &hkStore; break; } case (objects::OK_TM_STORE): { + tmStore = &okStore; break; } case (objects::NOT_OK_TM_STORE): { + tmStore = ¬OkStore; break; } case (objects::MISC_TM_STORE): { + tmStore = &miscStore; break; } default: { } } + if (tmStore == nullptr) { + continue; + } + if (cmd == TmStoreMessage::DELETE_STORE_CONTENT_TIME) { + store_address_t storeId = TmStoreMessage::getStoreId(&cmdMessage); + auto accessor = ipcStore.getData(storeId); + uint32_t deleteUpToUnixSeconds = 0; + size_t size = accessor.second.size(); + SerializeAdapter::deSerialize(&deleteUpToUnixSeconds, accessor.second.data(), &size, + SerializeIF::Endianness::NETWORK); + tmStore->deleteUpTo(deleteUpToUnixSeconds); + } else if (cmd == TmStoreMessage::DOWNLINK_STORE_CONTENT_TIME) { + } } } TmTcMessage currentMessage; diff --git a/mission/tmtc/PusTmFunnel.h b/mission/tmtc/PusTmFunnel.h index a54093c2..464db37c 100644 --- a/mission/tmtc/PusTmFunnel.h +++ b/mission/tmtc/PusTmFunnel.h @@ -23,7 +23,8 @@ class PusTmFunnel : public TmFunnelBase { public: explicit PusTmFunnel(object_id_t objectId, TimeReaderIF &timeReader, StorageManagerIF &tmStore, - SdCardMountedIF &sdcMan, uint32_t tmMsgDepth, uint32_t tcMsgDepth); + SdCardMountedIF &sdcMan, uint32_t tmMsgDepth, uint32_t tcMsgDepth, + StorageManagerIF &ipcStore); [[nodiscard]] const char *getName() const override; ~PusTmFunnel() override; diff --git a/mission/tmtc/TmFunnelBase.cpp b/mission/tmtc/TmFunnelBase.cpp index 156e4664..b4bf6c62 100644 --- a/mission/tmtc/TmFunnelBase.cpp +++ b/mission/tmtc/TmFunnelBase.cpp @@ -3,8 +3,8 @@ #include "fsfw/ipc/QueueFactory.h" TmFunnelBase::TmFunnelBase(object_id_t objectId, StorageManagerIF &tmStore, uint32_t tmMsgDepth, - uint32_t tcMsgDepth) - : SystemObject(objectId), tmStore(tmStore) { + uint32_t tcMsgDepth, StorageManagerIF &ipcStore) + : SystemObject(objectId), tmStore(tmStore), ipcStore(ipcStore) { tmQueue = QueueFactory::instance()->createMessageQueue(tmMsgDepth); tcQueue = QueueFactory::instance()->createMessageQueue(tcMsgDepth); } diff --git a/mission/tmtc/TmFunnelBase.h b/mission/tmtc/TmFunnelBase.h index 271c17c0..12453cc2 100644 --- a/mission/tmtc/TmFunnelBase.h +++ b/mission/tmtc/TmFunnelBase.h @@ -13,7 +13,7 @@ class TmFunnelBase : public TmStoreFrontendSimpleIF, public SystemObject { public: TmFunnelBase(object_id_t objectId, StorageManagerIF& tmStore, uint32_t tmMsgDepth, - uint32_t tcMsgDepth); + uint32_t tcMsgDepth, StorageManagerIF& ipcStore); void addDestination(const AcceptsTelemetryIF& downlinkDestination, uint8_t vcid = 0); [[nodiscard]] MessageQueueId_t getCommandQueue() const override; @@ -23,6 +23,7 @@ class TmFunnelBase : public TmStoreFrontendSimpleIF, protected: StorageManagerIF& tmStore; + StorageManagerIF& ipcStore; std::vector> destinations; MessageQueueIF* tcQueue = nullptr; MessageQueueIF* tmQueue = nullptr; From b9753dc5ba84dc097bac492bb13bb974dc27d854 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 19 Dec 2022 14:01:15 +0100 Subject: [PATCH 48/87] added dump command forwarding --- mission/tmtc/PusTmFunnel.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/mission/tmtc/PusTmFunnel.cpp b/mission/tmtc/PusTmFunnel.cpp index ff662afd..18706397 100644 --- a/mission/tmtc/PusTmFunnel.cpp +++ b/mission/tmtc/PusTmFunnel.cpp @@ -88,6 +88,17 @@ ReturnValue_t PusTmFunnel::performOperation(uint8_t) { SerializeIF::Endianness::NETWORK); tmStore->deleteUpTo(deleteUpToUnixSeconds); } else if (cmd == TmStoreMessage::DOWNLINK_STORE_CONTENT_TIME) { + store_address_t storeId = TmStoreMessage::getStoreId(&cmdMessage); + auto accessor = ipcStore.getData(storeId); + uint32_t dumpFromUnixSeconds; + uint32_t dumpUntilUnixSeconds; + size_t size = accessor.second.size(); + SerializeAdapter::deSerialize(&dumpFromUnixSeconds, accessor.second.data(), &size, + SerializeIF::Endianness::NETWORK); + SerializeAdapter::deSerialize(&dumpUntilUnixSeconds, accessor.second.data(), &size, + SerializeIF::Endianness::NETWORK); + // TODO: TM store missing, and maybe there is a better way to do this? + tmStore->dumpFromUpTo(dumpFromUnixSeconds, dumpUntilUnixSeconds, destinations, tmQueue); } } } From d9453c3b83f0129478d6f1afebfb098930f44d9a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 19 Dec 2022 14:40:27 +0100 Subject: [PATCH 49/87] absolutely magnificent --- mission/tmtc/PusTmFunnel.cpp | 33 ++----------------------------- mission/tmtc/TmFunnelBase.cpp | 37 +++++++++++++++++++++++++++++++++++ mission/tmtc/TmFunnelBase.h | 3 +++ mission/tmtc/TmStore.cpp | 9 +++++++-- mission/tmtc/TmStore.h | 6 +++--- 5 files changed, 52 insertions(+), 36 deletions(-) diff --git a/mission/tmtc/PusTmFunnel.cpp b/mission/tmtc/PusTmFunnel.cpp index 18706397..f79ac9b2 100644 --- a/mission/tmtc/PusTmFunnel.cpp +++ b/mission/tmtc/PusTmFunnel.cpp @@ -98,7 +98,7 @@ ReturnValue_t PusTmFunnel::performOperation(uint8_t) { SerializeAdapter::deSerialize(&dumpUntilUnixSeconds, accessor.second.data(), &size, SerializeIF::Endianness::NETWORK); // TODO: TM store missing, and maybe there is a better way to do this? - tmStore->dumpFromUpTo(dumpFromUnixSeconds, dumpUntilUnixSeconds, destinations, tmQueue); + tmStore->dumpFromUpTo(dumpFromUnixSeconds, dumpUntilUnixSeconds, *this); } } } @@ -149,36 +149,7 @@ ReturnValue_t PusTmFunnel::handlePacket(TmTcMessage &message) { miscStore.passPacket(packet); okStore.passPacket(packet); } - - for (unsigned int idx = 0; idx < destinations.size(); idx++) { - const auto &destVcidPair = destinations[idx]; - if (destinations.size() > 1) { - if (idx < destinations.size() - 1) { - // Create copy of data to ensure each TM recipient has its own copy. That way, we don't need - // to bother with send order and where the data is deleted. - store_address_t storeId; - result = tmStore.addData(&storeId, packetData, size); - if (result == returnvalue::OK) { - message.setStorageId(storeId); - } else { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "PusTmFunnel::handlePacket: Store too full to create data copy" - << std::endl; -#endif - } - } else { - message.setStorageId(origStoreId); - } - } - result = tmQueue->sendMessage(destVcidPair.first, &message); - if (result != returnvalue::OK) { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "PusTmFunnel::handlePacket: Error sending TM to downlink handler" << std::endl; -#endif - tmStore.deleteData(message.getStorageId()); - } - } - return result; + return sendPacketToDestinations(origStoreId, message, packetData, size); } const char *PusTmFunnel::getName() const { return "PUS TM Funnel"; } diff --git a/mission/tmtc/TmFunnelBase.cpp b/mission/tmtc/TmFunnelBase.cpp index b4bf6c62..0f600efe 100644 --- a/mission/tmtc/TmFunnelBase.cpp +++ b/mission/tmtc/TmFunnelBase.cpp @@ -1,5 +1,7 @@ #include "TmFunnelBase.h" +#include + #include "fsfw/ipc/QueueFactory.h" TmFunnelBase::TmFunnelBase(object_id_t objectId, StorageManagerIF &tmStore, uint32_t tmMsgDepth, @@ -21,3 +23,38 @@ void TmFunnelBase::addDestination(const AcceptsTelemetryIF &downlinkDestination, auto queueId = downlinkDestination.getReportReceptionQueue(vcid); destinations.emplace_back(queueId, vcid); } + +ReturnValue_t TmFunnelBase::sendPacketToDestinations(store_address_t origStoreId, + TmTcMessage &message, + const uint8_t *packetData, size_t size) { + ReturnValue_t result; + for (unsigned int idx = 0; idx < destinations.size(); idx++) { + const auto &destVcidPair = destinations[idx]; + if (destinations.size() > 1) { + if (idx < destinations.size() - 1) { + // Create copy of data to ensure each TM recipient has its own copy. That way, we don't need + // to bother with send order and where the data is deleted. + store_address_t storeId; + result = tmStore.addData(&storeId, packetData, size); + if (result == returnvalue::OK) { + message.setStorageId(storeId); + } else { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "PusTmFunnel::handlePacket: Store too full to create data copy" + << std::endl; +#endif + } + } else { + message.setStorageId(origStoreId); + } + } + result = tmQueue->sendMessage(destVcidPair.first, &message); + if (result != returnvalue::OK) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "PusTmFunnel::handlePacket: Error sending TM to downlink handler" << std::endl; +#endif + tmStore.deleteData(message.getStorageId()); + } + } + return result; +} diff --git a/mission/tmtc/TmFunnelBase.h b/mission/tmtc/TmFunnelBase.h index 12453cc2..bfff3440 100644 --- a/mission/tmtc/TmFunnelBase.h +++ b/mission/tmtc/TmFunnelBase.h @@ -5,6 +5,7 @@ #include #include #include +#include #include @@ -15,6 +16,8 @@ class TmFunnelBase : public TmStoreFrontendSimpleIF, TmFunnelBase(object_id_t objectId, StorageManagerIF& tmStore, uint32_t tmMsgDepth, uint32_t tcMsgDepth, StorageManagerIF& ipcStore); void addDestination(const AcceptsTelemetryIF& downlinkDestination, uint8_t vcid = 0); + ReturnValue_t sendPacketToDestinations(store_address_t origStoreId, TmTcMessage& message, + const uint8_t* packetData, size_t size); [[nodiscard]] MessageQueueId_t getCommandQueue() const override; [[nodiscard]] MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel) const override; diff --git a/mission/tmtc/TmStore.cpp b/mission/tmtc/TmStore.cpp index 2de1e818..a18f16d1 100644 --- a/mission/tmtc/TmStore.cpp +++ b/mission/tmtc/TmStore.cpp @@ -185,5 +185,10 @@ void TmStore::addServiceSubservice(uint8_t service, uint8_t subservice) { void TmStore::deleteUpTo(uint32_t unixSeconds) {} void TmStore::dumpFromUpTo(uint32_t fromUnixSeconds, uint32_t upToUnixSeconds, - std::vector>& destinations, - MessageQueueIF* tmQueue) {} + TmFunnelBase& funnel) { + store_address_t storeId; + TmTcMessage message; + const uint8_t* packetData = nullptr; + size_t size = 0; + funnel.sendPacketToDestinations(storeId, message, packetData, size); +} diff --git a/mission/tmtc/TmStore.h b/mission/tmtc/TmStore.h index 72071e02..0654052d 100644 --- a/mission/tmtc/TmStore.h +++ b/mission/tmtc/TmStore.h @@ -9,6 +9,8 @@ #include +#include "TmFunnelBase.h" + struct PacketFilter { std::optional> apid; std::optional> services; @@ -28,9 +30,7 @@ class TmStore : public SystemObject { void addServiceSubservice(uint8_t service, uint8_t subservice); void deleteUpTo(uint32_t unixSeconds); - void dumpFromUpTo(uint32_t fromUnixSeconds, uint32_t upToUnixSeconds, - std::vector>& destinations, - MessageQueueIF* tmQueue); + void dumpFromUpTo(uint32_t fromUnixSeconds, uint32_t upToUnixSeconds, TmFunnelBase& tmFunnel); void updateBaseDir(); ReturnValue_t passPacket(PusTmReader& reader); From 29fd2653f15a4a0ee59b9df2753ccdac27ce3569 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 19 Dec 2022 15:23:42 +0100 Subject: [PATCH 50/87] added TODO with steps --- mission/tmtc/TmStore.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/mission/tmtc/TmStore.cpp b/mission/tmtc/TmStore.cpp index a18f16d1..26b3b0a8 100644 --- a/mission/tmtc/TmStore.cpp +++ b/mission/tmtc/TmStore.cpp @@ -182,10 +182,17 @@ void TmStore::addServiceSubservice(uint8_t service, uint8_t subservice) { filter.serviceSubservices.value().push_back({service, subservice}); } -void TmStore::deleteUpTo(uint32_t unixSeconds) {} +void TmStore::deleteUpTo(uint32_t unixSeconds) { + +} void TmStore::dumpFromUpTo(uint32_t fromUnixSeconds, uint32_t upToUnixSeconds, TmFunnelBase& funnel) { + // TODO: + // 1. Find all files within the specified range + // 2. For each file, dump content into buffer, parse out space packets, + // 3. Store each packet into the TM store and send the message to all + // destinations store_address_t storeId; TmTcMessage message; const uint8_t* packetData = nullptr; From d14d7ae66d704eb849a6f55cc860e2fdb0e43ba9 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 11 Jan 2023 09:18:07 +0100 Subject: [PATCH 51/87] bump submodules --- fsfw | 2 +- tmtc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fsfw b/fsfw index 2aa4af69..041d1b87 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 2aa4af69742d932f09ec2a1d3d29b648295035d1 +Subproject commit 041d1b8795af8f57738171ad84a1c323b9d0c8d5 diff --git a/tmtc b/tmtc index 383b3214..b032defa 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 383b32141c8c382b84c587d6814fe9252dde0b4a +Subproject commit b032defa7c6450cbbf21ffe8cfc50f6d5d5bc614 From 650bfd1ad30c161ffc529dc369bb47ccecd061e0 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 7 Feb 2023 12:19:13 +0100 Subject: [PATCH 52/87] continued basic tm store impl --- common/config/eive/eventSubsystemIds.h | 1 + fsfw | 2 +- mission/tmtc/PusTmFunnel.cpp | 10 +-- mission/tmtc/TmStore.cpp | 94 +++++++++++++++++++++++--- mission/tmtc/TmStore.h | 15 +++- 5 files changed, 105 insertions(+), 17 deletions(-) diff --git a/common/config/eive/eventSubsystemIds.h b/common/config/eive/eventSubsystemIds.h index 40926b00..1af60bf8 100644 --- a/common/config/eive/eventSubsystemIds.h +++ b/common/config/eive/eventSubsystemIds.h @@ -36,6 +36,7 @@ enum : uint8_t { SCEX_HANDLER = 138, CONFIGHANDLER = 139, CORE = 140, + PERSISTENT_TM_STORE = 141, COMMON_SUBSYSTEM_ID_END }; diff --git a/fsfw b/fsfw index 6af5274b..2646707d 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 6af5274b688c2eb561a17d78e5417e6b843e4523 +Subproject commit 2646707d3fa1b568a6c99e8e0bd32585d729d162 diff --git a/mission/tmtc/PusTmFunnel.cpp b/mission/tmtc/PusTmFunnel.cpp index f79ac9b2..7da02bca 100644 --- a/mission/tmtc/PusTmFunnel.cpp +++ b/mission/tmtc/PusTmFunnel.cpp @@ -14,11 +14,13 @@ PusTmFunnel::PusTmFunnel(object_id_t objectId, TimeReaderIF &timeReader, Storage : TmFunnelBase(objectId, tmStore, tmMsgDepth, tcMsgDepth, ipcStore), timeReader(timeReader), miscStore(objects::MISC_TM_STORE, "tm", "misc", RolloverInterval::HOURLY, 2, currentTv, - sdcMan), - okStore(objects::OK_TM_STORE, "tm", "ok", RolloverInterval::MINUTELY, 30, currentTv, sdcMan), + tmStore, sdcMan), + okStore(objects::OK_TM_STORE, "tm", "ok", RolloverInterval::MINUTELY, 30, currentTv, tmStore, + sdcMan), notOkStore(objects::NOT_OK_TM_STORE, "tm", "nok", RolloverInterval::MINUTELY, 30, currentTv, - sdcMan), - hkStore(objects::HK_TM_STORE, "tm", "hk", RolloverInterval::MINUTELY, 15, currentTv, sdcMan), + tmStore, sdcMan), + hkStore(objects::HK_TM_STORE, "tm", "hk", RolloverInterval::MINUTELY, 15, currentTv, tmStore, + sdcMan), sdcMan(sdcMan) { Clock::getClock_timeval(¤tTv); Clock::getUptime(&lastTvUpdate); diff --git a/mission/tmtc/TmStore.cpp b/mission/tmtc/TmStore.cpp index c20df4f3..11fe0443 100644 --- a/mission/tmtc/TmStore.cpp +++ b/mission/tmtc/TmStore.cpp @@ -12,12 +12,13 @@ using namespace returnvalue; TmStore::TmStore(object_id_t objectId, const char* baseDir, std::string baseName, RolloverInterval intervalUnit, uint32_t intervalCount, timeval& currentTv, - SdCardMountedIF& sdcMan) + StorageManagerIF& tmStore, SdCardMountedIF& sdcMan) : SystemObject(objectId), baseDir(std::move(baseDir)), baseName(std::move(baseName)), currentTv(currentTv), - sdcMan(sdcMan) { + sdcMan(sdcMan), + tmStore(tmStore) { calcDiffSeconds(intervalUnit, intervalCount); } @@ -182,18 +183,89 @@ void TmStore::addServiceSubservice(uint8_t service, uint8_t subservice) { filter.serviceSubservices.value().push_back({service, subservice}); } -void TmStore::deleteUpTo(uint32_t unixSeconds) {} +void TmStore::deleteUpTo(uint32_t unixSeconds) { + using namespace std::filesystem; + for (auto const& file : directory_iterator(basePath)) { + if (file.is_directory() or + (mostRecentFile.has_value() and (mostRecentFile.value() == file.path()))) { + continue; + } + Clock::TimeOfDay_t tod; + pathToTod(file.path(), tod); + timeval time; + ReturnValue_t result = Clock::convertTimeOfDayToTimeval(&tod, &time); + if (result != returnvalue::OK) { + sif::error << "TOD to time conversion failed for file " << file << std::endl; + continue; + } + if (time.tv_sec + rolloverDiffSeconds < unixSeconds) { + std::filesystem::remove(file.path()); + } + } +} void TmStore::dumpFromUpTo(uint32_t fromUnixSeconds, uint32_t upToUnixSeconds, TmFunnelBase& funnel) { - // TODO: - // 1. Find all files within the specified range - // 2. For each file, dump content into buffer, parse out space packets, - // 3. Store each packet into the TM store and send the message to all - // destinations + using namespace std::filesystem; + for (auto const& file : directory_iterator(basePath)) { + if (file.is_directory() or + (mostRecentFile.has_value() and (mostRecentFile.value() == file.path()))) { + continue; + } + Clock::TimeOfDay_t tod; + pathToTod(file.path(), tod); + timeval time; + ReturnValue_t result = Clock::convertTimeOfDayToTimeval(&tod, &time); + if (result != returnvalue::OK) { + sif::error << "TOD to time conversion failed for file " << file << std::endl; + continue; + } + uint32_t timeUnsigned = static_cast(time.tv_sec); + if (timeUnsigned > fromUnixSeconds && timeUnsigned + rolloverDiffSeconds < upToUnixSeconds) { + fileToPackets(file, timeUnsigned, funnel); + } + } +} + +void TmStore::pathToTod(const std::filesystem::path& path, Clock::TimeOfDay_t& tod) { + auto pathStr = path.string(); + size_t splitChar = pathStr.find("_"); + auto timeOnlyStr = pathStr.substr(splitChar); + sscanf(timeOnlyStr.data(), + "%04" SCNu32 "-%02" SCNu32 "-%02" SCNu32 "T%02" SCNu32 "-%02" SCNu32 "-%02" SCNu32 "Z", + &tod.year, &tod.month, &tod.day, &tod.hour, &tod.minute, &tod.second); +} + +void TmStore::fileToPackets(const std::filesystem::path& path, uint32_t unixStamp, + TmFunnelBase& funnel) { store_address_t storeId; TmTcMessage message; - const uint8_t* packetData = nullptr; - size_t size = 0; - funnel.sendPacketToDestinations(storeId, message, packetData, size); + size_t size = std::filesystem::file_size(path); + if (size < 6) { + // Can't even read the CCSDS header + return; + } + std::ifstream ifile(path, std::ios::binary); + ifile.read(reinterpret_cast(fileBuf.data()), size); + size_t currentIdx = 0; + while (currentIdx < size) { + PusTmReader reader(&timeReader, fileBuf.data(), fileBuf.size()); + // CRC check to fully ensure this is a valid TM + ReturnValue_t result = reader.parseDataWithCrcCheck(); + if (result == returnvalue::OK) { + ReturnValue_t result = + tmStore.addData(&storeId, fileBuf.data() + currentIdx, reader.getFullPacketLen()); + if (result != returnvalue::OK) { + continue; + } + funnel.sendPacketToDestinations(storeId, message, fileBuf.data() + currentIdx, + reader.getFullPacketLen()); + currentIdx += reader.getFullPacketLen(); + } else { + sif::error << "Parsing of PUS TM failed with code " << result << std::endl; + triggerEvent(POSSIBLE_FILE_CORRUPTION, result, unixStamp); + // Stop for now, do not really know where to continue and we do not trust the file anymore. + break; + } + } } diff --git a/mission/tmtc/TmStore.h b/mission/tmtc/TmStore.h index 0654052d..91acb3a1 100644 --- a/mission/tmtc/TmStore.h +++ b/mission/tmtc/TmStore.h @@ -2,6 +2,7 @@ #define MISSION_TMTC_TMSTOREBACKEND_H_ #include +#include #include #include #include @@ -10,6 +11,7 @@ #include #include "TmFunnelBase.h" +#include "eive/eventSubsystemIds.h" struct PacketFilter { std::optional> apid; @@ -21,9 +23,16 @@ enum class RolloverInterval { MINUTELY, HOURLY, DAILY }; class TmStore : public SystemObject { public: + static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PERSISTENT_TM_STORE; + + //! [EXPORT] : [COMMENT] + //! P1: Result code of TM packet parser. + //! P2: Timestamp of possibly corrupt file as a unix timestamp. + static constexpr Event POSSIBLE_FILE_CORRUPTION = + event::makeEvent(SUBSYSTEM_ID, 0, severity::LOW); TmStore(object_id_t objectId, const char* baseDir, std::string baseName, RolloverInterval intervalUnit, uint32_t intervalCount, timeval& currentTv, - SdCardMountedIF& sdcMan); + StorageManagerIF& tmStore, SdCardMountedIF& sdcMan); void addApid(uint16_t apid); void addService(uint8_t service); @@ -44,6 +53,7 @@ class TmStore : public SystemObject { */ MessageQueueId_t getCommandQueue(); PacketFilter filter; + CdsShortTimeStamper timeReader; bool baseDirUninitialized = true; const char* baseDir; std::string baseName; @@ -54,9 +64,12 @@ class TmStore : public SystemObject { std::optional mostRecentTv; std::optional mostRecentFile; SdCardMountedIF& sdcMan; + StorageManagerIF& tmStore; void calcDiffSeconds(RolloverInterval intervalUnit, uint32_t intervalCount); void assignAndOrCreateMostRecentFile(); + void pathToTod(const std::filesystem::path& path, Clock::TimeOfDay_t& tod); + void fileToPackets(const std::filesystem::path& path, uint32_t unixStamp, TmFunnelBase& funnel); ReturnValue_t storePacket(PusTmReader& reader); }; From 94fee2d42941d9d0f548769d09e8da614adc3e3c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 7 Feb 2023 12:23:00 +0100 Subject: [PATCH 53/87] some more fixes and tweaks --- fsfw | 2 +- mission/tmtc/CMakeLists.txt | 2 +- mission/tmtc/{TmStore.cpp => PersistentTmStore.cpp} | 2 +- mission/tmtc/{TmStore.h => PersistentTmStore.h} | 0 mission/tmtc/PusTmFunnel.h | 2 +- 5 files changed, 4 insertions(+), 4 deletions(-) rename mission/tmtc/{TmStore.cpp => PersistentTmStore.cpp} (99%) rename mission/tmtc/{TmStore.h => PersistentTmStore.h} (100%) diff --git a/fsfw b/fsfw index 2646707d..a1567de9 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 2646707d3fa1b568a6c99e8e0bd32585d729d162 +Subproject commit a1567de9e8d84a044b4a33ccdaffd15f0f4f54f1 diff --git a/mission/tmtc/CMakeLists.txt b/mission/tmtc/CMakeLists.txt index cc84aabb..c4c93ab6 100644 --- a/mission/tmtc/CMakeLists.txt +++ b/mission/tmtc/CMakeLists.txt @@ -6,5 +6,5 @@ target_sources( TmFunnelBase.cpp CfdpTmFunnel.cpp Service15TmStorage.cpp - TmStore.cpp + PersistentTmStore.cpp PusTmFunnel.cpp) diff --git a/mission/tmtc/TmStore.cpp b/mission/tmtc/PersistentTmStore.cpp similarity index 99% rename from mission/tmtc/TmStore.cpp rename to mission/tmtc/PersistentTmStore.cpp index 11fe0443..d1bf054e 100644 --- a/mission/tmtc/TmStore.cpp +++ b/mission/tmtc/PersistentTmStore.cpp @@ -1,4 +1,4 @@ -#include "TmStore.h" +#include "PersistentTmStore.h" #include diff --git a/mission/tmtc/TmStore.h b/mission/tmtc/PersistentTmStore.h similarity index 100% rename from mission/tmtc/TmStore.h rename to mission/tmtc/PersistentTmStore.h diff --git a/mission/tmtc/PusTmFunnel.h b/mission/tmtc/PusTmFunnel.h index 464db37c..e47f5e96 100644 --- a/mission/tmtc/PusTmFunnel.h +++ b/mission/tmtc/PusTmFunnel.h @@ -10,7 +10,7 @@ #include -#include "TmStore.h" +#include "PersistentTmStore.h" #include "fsfw/timemanager/TimeReaderIF.h" /** From d82810d5e7aad212dd90181aa03782dd006d714d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 7 Feb 2023 15:22:01 +0100 Subject: [PATCH 54/87] add dumpFrom method --- mission/tmtc/PersistentTmStore.cpp | 12 ++++++++++-- mission/tmtc/PersistentTmStore.h | 1 + tmtc | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/mission/tmtc/PersistentTmStore.cpp b/mission/tmtc/PersistentTmStore.cpp index d1bf054e..8b0c4ee4 100644 --- a/mission/tmtc/PersistentTmStore.cpp +++ b/mission/tmtc/PersistentTmStore.cpp @@ -57,6 +57,10 @@ ReturnValue_t TmStore::passPacket(PusTmReader& reader) { return returnvalue::OK; } +void TmStore::dumpFrom(uint32_t fromUnixSeconds, TmFunnelBase &tmFunnel) { + return dumpFromUpTo(fromUnixSeconds, currentTv.tv_sec, tmFunnel); +} + ReturnValue_t TmStore::storePacket(PusTmReader& reader) { using namespace std::filesystem; if (baseDirUninitialized) { @@ -208,8 +212,12 @@ void TmStore::dumpFromUpTo(uint32_t fromUnixSeconds, uint32_t upToUnixSeconds, TmFunnelBase& funnel) { using namespace std::filesystem; for (auto const& file : directory_iterator(basePath)) { - if (file.is_directory() or - (mostRecentFile.has_value() and (mostRecentFile.value() == file.path()))) { + if (file.is_directory()) { + continue; + } + if (mostRecentFile.has_value() and mostRecentTv.has_value() and + (file.path() == mostRecentFile.value()) and + (upToUnixSeconds < static_cast(mostRecentTv.value().tv_sec))) { continue; } Clock::TimeOfDay_t tod; diff --git a/mission/tmtc/PersistentTmStore.h b/mission/tmtc/PersistentTmStore.h index 91acb3a1..8575f35f 100644 --- a/mission/tmtc/PersistentTmStore.h +++ b/mission/tmtc/PersistentTmStore.h @@ -39,6 +39,7 @@ class TmStore : public SystemObject { void addServiceSubservice(uint8_t service, uint8_t subservice); void deleteUpTo(uint32_t unixSeconds); + void dumpFrom(uint32_t fromUnixSeconds, TmFunnelBase& tmFunnel); void dumpFromUpTo(uint32_t fromUnixSeconds, uint32_t upToUnixSeconds, TmFunnelBase& tmFunnel); void updateBaseDir(); diff --git a/tmtc b/tmtc index d6445d38..2bd6caa3 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit d6445d38a8eb644a5e1bd27f0fc56d29e93c030d +Subproject commit 2bd6caa3c21255f2ab5a2773eb83d2fca78c2234 From 47e97ff1be65b6cec92053ec4ae1a6110fc3c315 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 17 Feb 2023 11:52:09 +0100 Subject: [PATCH 55/87] bump fsfw --- fsfw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fsfw b/fsfw index a6d707a7..70b78598 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit a6d707a7db589136ac2bd917cd8b3a3e2c16a0e4 +Subproject commit 70b785984c8af916fc96d8fc9e2627c20ee85461 From cb6a98b0d2ad956201c0ffbfa814f519a08d723f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 17 Feb 2023 11:52:29 +0100 Subject: [PATCH 56/87] bump fsfw --- fsfw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fsfw b/fsfw index 70b78598..dae5e988 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 70b785984c8af916fc96d8fc9e2627c20ee85461 +Subproject commit dae5e988fdad6250624517791fde8a6f2a9fac2d From 2bfc9bc565b036c776288e110b5dad247e525a2c Mon Sep 17 00:00:00 2001 From: Michael Steinert Date: Fri, 10 Feb 2023 11:49:04 +0100 Subject: [PATCH 57/87] added hook to automatically update submodules after checkout --- clone-submodules-no-privlibs.sh | 3 +++ hooks/post-checkout | 6 ++++++ 2 files changed, 9 insertions(+) create mode 100755 hooks/post-checkout diff --git a/clone-submodules-no-privlibs.sh b/clone-submodules-no-privlibs.sh index ae08a9ce..48d34bc2 100755 --- a/clone-submodules-no-privlibs.sh +++ b/clone-submodules-no-privlibs.sh @@ -1,3 +1,6 @@ #!/bin/bash +root="$(pwd)" +ln -s "$root/hooks" "$root/.git/hooks" + git submodule update --init fsfw thirdparty/rapidcsv thirdparty/lwgps thirdparty/json diff --git a/hooks/post-checkout b/hooks/post-checkout new file mode 100755 index 00000000..bfddad44 --- /dev/null +++ b/hooks/post-checkout @@ -0,0 +1,6 @@ +#!/bin/bash +# +# update submodules after checkout + +git submodule init +git submodule update From da898a3f1676898cbba07ea4841052337cb9fa86 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 17 Feb 2023 17:00:12 +0100 Subject: [PATCH 58/87] add CLion config for CMake --- .gitignore | 7 ++++++- .idea/cmake.xml | 16 ++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 .idea/cmake.xml diff --git a/.gitignore b/.gitignore index a5065673..5419ca42 100644 --- a/.gitignore +++ b/.gitignore @@ -12,8 +12,13 @@ #vscode /.vscode +# IntelliJ +/.idea/* + # Python __pycache__ -.idea + +# CLion +!/.idea/cmake.xml generators/*.db diff --git a/.idea/cmake.xml b/.idea/cmake.xml new file mode 100644 index 00000000..28d4d307 --- /dev/null +++ b/.idea/cmake.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file From 6f4c81117b1c4c8b4c1c1172d5dfcb820620cdbb Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 17 Feb 2023 17:05:39 +0100 Subject: [PATCH 59/87] add small clion section --- README.md | 17 +++++++++++++++++ mission/tmtc/PersistentTmStore.cpp | 3 +-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b6fa64e9..cd350386 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ 11. [Q7S OBC](#q7s) 12. [Static Code Analysis](#static-code-analysis) 13. [Eclipse](#eclipse) +14. [CLion](#clion) 14. [Running the OBSW on a Raspberry Pi](#rpi) 15. [Running OBSW on EGSE](#egse) 16. [Manually preparing sysroots to compile gpsd](#gpsd) @@ -1229,6 +1230,22 @@ Finally, you can convert the generated `.xml` file to HTML with the following co cppcheck-htmlreport --file=report.xml --report-dir=cppcheck --source-dir=.. ``` +# CLion + +CLion is the recommended IDE for the development of the hosted version of EIVE. +You can also set up CLion for cross-compilation of the primary OBSW. + +There is a shared `.idea/cmake.xml` file to get started with this. +To make cross-compilation work, two special environment variables +need to be set: + +- `ZYNQ_7020_ROOTFS` pointing to the root filesystem +- `CROSS_COMPILE` pointing to the the full path of the cross-compiler + without the specific tool suffix. For example, if the the cross-compiler + tools are located at `/opt/q7s-gcc/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin`, + this variable would be set + to `/opt/q7s-gcc/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/arm-linux-gnueabihf` + # Eclipse When using Eclipse, there are two special build variables in the project properties diff --git a/mission/tmtc/PersistentTmStore.cpp b/mission/tmtc/PersistentTmStore.cpp index 92cff08d..bb64850c 100644 --- a/mission/tmtc/PersistentTmStore.cpp +++ b/mission/tmtc/PersistentTmStore.cpp @@ -261,8 +261,7 @@ void TmStore::fileToPackets(const std::filesystem::path& path, uint32_t unixStam // CRC check to fully ensure this is a valid TM ReturnValue_t result = reader.parseDataWithCrcCheck(); if (result == returnvalue::OK) { - ReturnValue_t result = - tmStore.addData(&storeId, fileBuf.data() + currentIdx, reader.getFullPacketLen()); + result = tmStore.addData(&storeId, fileBuf.data() + currentIdx, reader.getFullPacketLen()); if (result != returnvalue::OK) { continue; } From 5abecd065c6a071027e225e9e9f755e0e23fe3c0 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 17 Feb 2023 17:32:15 +0100 Subject: [PATCH 60/87] add Q7S run config --- .run/Q7S FM.run.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 .run/Q7S FM.run.xml diff --git a/.run/Q7S FM.run.xml b/.run/Q7S FM.run.xml new file mode 100644 index 00000000..ea4ae083 --- /dev/null +++ b/.run/Q7S FM.run.xml @@ -0,0 +1,10 @@ + + + + + + + + + \ No newline at end of file From 10a18ba6af3d19f14901107a50d97ac3aa2ada83 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 17 Feb 2023 18:35:41 +0100 Subject: [PATCH 61/87] re-run generators --- .../fsfwconfig/events/translateEvents.cpp | 19 +++++++++++-------- .../fsfwconfig/objects/translateObjects.cpp | 19 +++++++++++++++++-- generators/bsp_hosted_events.csv | 15 ++++++++------- generators/bsp_hosted_objects.csv | 5 +++++ generators/bsp_q7s_events.csv | 15 ++++++++------- generators/bsp_q7s_objects.csv | 5 +++++ generators/events/translateEvents.cpp | 19 +++++++++++-------- generators/objects/translateObjects.cpp | 19 +++++++++++++++++-- linux/fsfwconfig/events/translateEvents.cpp | 19 +++++++++++-------- linux/fsfwconfig/objects/translateObjects.cpp | 19 +++++++++++++++++-- tmtc | 2 +- 11 files changed, 111 insertions(+), 45 deletions(-) diff --git a/bsp_hosted/fsfwconfig/events/translateEvents.cpp b/bsp_hosted/fsfwconfig/events/translateEvents.cpp index 794ae1d7..1c7762fa 100644 --- a/bsp_hosted/fsfwconfig/events/translateEvents.cpp +++ b/bsp_hosted/fsfwconfig/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 257 translations. + * @brief Auto-generated event translation file. Contains 258 translations. * @details - * Generated on: 2023-02-17 13:15:51 + * Generated on: 2023-02-17 18:35:08 */ #include "translateEvents.h" @@ -250,6 +250,7 @@ const char *REBOOT_HW_STRING = "REBOOT_HW"; const char *NO_SD_CARD_ACTIVE_STRING = "NO_SD_CARD_ACTIVE"; const char *VERSION_INFO_STRING = "VERSION_INFO"; const char *CURRENT_IMAGE_INFO_STRING = "CURRENT_IMAGE_INFO"; +const char *POSSIBLE_FILE_CORRUPTION_STRING = "POSSIBLE_FILE_CORRUPTION"; const char *NO_VALID_SENSOR_TEMPERATURE_STRING = "NO_VALID_SENSOR_TEMPERATURE"; const char *NO_HEALTHY_HEATER_AVAILABLE_STRING = "NO_HEALTHY_HEATER_AVAILABLE"; const char *SYRLINKS_OVERHEATING_STRING = "SYRLINKS_OVERHEATING"; @@ -751,18 +752,20 @@ const char *translateEvents(Event event) { case (14006): return CURRENT_IMAGE_INFO_STRING; case (14100): + return POSSIBLE_FILE_CORRUPTION_STRING; + case (14200): return NO_VALID_SENSOR_TEMPERATURE_STRING; - case (14101): + case (14201): return NO_HEALTHY_HEATER_AVAILABLE_STRING; - case (14102): + case (14202): return SYRLINKS_OVERHEATING_STRING; - case (14103): + case (14203): return PLOC_OVERHEATING_STRING; - case (14104): + case (14204): return OBC_OVERHEATING_STRING; - case (14105): + case (14205): return HPA_OVERHEATING_STRING; - case (14106): + case (14206): return PLPCDU_OVERHEATING_STRING; default: return "UNKNOWN_EVENT"; diff --git a/bsp_hosted/fsfwconfig/objects/translateObjects.cpp b/bsp_hosted/fsfwconfig/objects/translateObjects.cpp index ccd02791..4a0f7336 100644 --- a/bsp_hosted/fsfwconfig/objects/translateObjects.cpp +++ b/bsp_hosted/fsfwconfig/objects/translateObjects.cpp @@ -1,8 +1,8 @@ /** * @brief Auto-generated object translation file. * @details - * Contains 147 translations. - * Generated on: 2023-02-17 13:15:51 + * Contains 152 translations. + * Generated on: 2023-02-17 18:35:08 */ #include "translateObjects.h" @@ -149,6 +149,11 @@ const char *ACS_SUBSYSTEM_STRING = "ACS_SUBSYSTEM"; const char *PL_SUBSYSTEM_STRING = "PL_SUBSYSTEM"; const char *TCS_SUBSYSTEM_STRING = "TCS_SUBSYSTEM"; const char *COM_SUBSYSTEM_STRING = "COM_SUBSYSTEM"; +const char *MISC_TM_STORE_STRING = "MISC_TM_STORE"; +const char *OK_TM_STORE_STRING = "OK_TM_STORE"; +const char *NOT_OK_TM_STORE_STRING = "NOT_OK_TM_STORE"; +const char *HK_TM_STORE_STRING = "HK_TM_STORE"; +const char *CFDP_TM_STORE_STRING = "CFDP_TM_STORE"; const char *CCSDS_IP_CORE_BRIDGE_STRING = "CCSDS_IP_CORE_BRIDGE"; const char *THERMAL_TEMP_INSERTER_STRING = "THERMAL_TEMP_INSERTER"; const char *DUMMY_INTERFACE_STRING = "DUMMY_INTERFACE"; @@ -442,6 +447,16 @@ const char *translateObject(object_id_t object) { return TCS_SUBSYSTEM_STRING; case 0x73010004: return COM_SUBSYSTEM_STRING; + case 0x73020001: + return MISC_TM_STORE_STRING; + case 0x73020002: + return OK_TM_STORE_STRING; + case 0x73020003: + return NOT_OK_TM_STORE_STRING; + case 0x73020004: + return HK_TM_STORE_STRING; + case 0x73030000: + return CFDP_TM_STORE_STRING; case 0x73500000: return CCSDS_IP_CORE_BRIDGE_STRING; case 0x90000003: diff --git a/generators/bsp_hosted_events.csv b/generators/bsp_hosted_events.csv index 4d1488e3..52ba5023 100644 --- a/generators/bsp_hosted_events.csv +++ b/generators/bsp_hosted_events.csv @@ -249,10 +249,11 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path 14004;0x36b4;NO_SD_CARD_ACTIVE;HIGH;No SD card was active. Core controller will attempt to re-initialize a SD card.;bsp_q7s/core/CoreController.h 14005;0x36b5;VERSION_INFO;INFO;P1: Byte 0: Major, Byte 1: Minor, Byte 2: Patch, Byte 3: Has Git Hash P2: First four letters of Git SHA is the last byte of P1 is set.;bsp_q7s/core/CoreController.h 14006;0x36b6;CURRENT_IMAGE_INFO;INFO;P1: Current Chip, P2: Current Copy;bsp_q7s/core/CoreController.h -14100;0x3714;NO_VALID_SENSOR_TEMPERATURE;MEDIUM;;mission/controller/ThermalController.h -14101;0x3715;NO_HEALTHY_HEATER_AVAILABLE;MEDIUM;;mission/controller/ThermalController.h -14102;0x3716;SYRLINKS_OVERHEATING;HIGH;;mission/controller/ThermalController.h -14103;0x3717;PLOC_OVERHEATING;HIGH;;mission/controller/ThermalController.h -14104;0x3718;OBC_OVERHEATING;HIGH;;mission/controller/ThermalController.h -14105;0x3719;HPA_OVERHEATING;HIGH;;mission/controller/ThermalController.h -14106;0x371a;PLPCDU_OVERHEATING;HIGH;;mission/controller/ThermalController.h +14100;0x3714;POSSIBLE_FILE_CORRUPTION;LOW;P1: Result code of TM packet parser. P2: Timestamp of possibly corrupt file as a unix timestamp.;mission/tmtc/PersistentTmStore.h +14200;0x3778;NO_VALID_SENSOR_TEMPERATURE;MEDIUM;;mission/controller/ThermalController.h +14201;0x3779;NO_HEALTHY_HEATER_AVAILABLE;MEDIUM;;mission/controller/ThermalController.h +14202;0x377a;SYRLINKS_OVERHEATING;HIGH;;mission/controller/ThermalController.h +14203;0x377b;PLOC_OVERHEATING;HIGH;;mission/controller/ThermalController.h +14204;0x377c;OBC_OVERHEATING;HIGH;;mission/controller/ThermalController.h +14205;0x377d;HPA_OVERHEATING;HIGH;;mission/controller/ThermalController.h +14206;0x377e;PLPCDU_OVERHEATING;HIGH;;mission/controller/ThermalController.h diff --git a/generators/bsp_hosted_objects.csv b/generators/bsp_hosted_objects.csv index 59710edb..02cad67f 100644 --- a/generators/bsp_hosted_objects.csv +++ b/generators/bsp_hosted_objects.csv @@ -141,6 +141,11 @@ 0x73010002;PL_SUBSYSTEM 0x73010003;TCS_SUBSYSTEM 0x73010004;COM_SUBSYSTEM +0x73020001;MISC_TM_STORE +0x73020002;OK_TM_STORE +0x73020003;NOT_OK_TM_STORE +0x73020004;HK_TM_STORE +0x73030000;CFDP_TM_STORE 0x73500000;CCSDS_IP_CORE_BRIDGE 0x90000003;THERMAL_TEMP_INSERTER 0xCAFECAFE;DUMMY_INTERFACE diff --git a/generators/bsp_q7s_events.csv b/generators/bsp_q7s_events.csv index 4d1488e3..52ba5023 100644 --- a/generators/bsp_q7s_events.csv +++ b/generators/bsp_q7s_events.csv @@ -249,10 +249,11 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path 14004;0x36b4;NO_SD_CARD_ACTIVE;HIGH;No SD card was active. Core controller will attempt to re-initialize a SD card.;bsp_q7s/core/CoreController.h 14005;0x36b5;VERSION_INFO;INFO;P1: Byte 0: Major, Byte 1: Minor, Byte 2: Patch, Byte 3: Has Git Hash P2: First four letters of Git SHA is the last byte of P1 is set.;bsp_q7s/core/CoreController.h 14006;0x36b6;CURRENT_IMAGE_INFO;INFO;P1: Current Chip, P2: Current Copy;bsp_q7s/core/CoreController.h -14100;0x3714;NO_VALID_SENSOR_TEMPERATURE;MEDIUM;;mission/controller/ThermalController.h -14101;0x3715;NO_HEALTHY_HEATER_AVAILABLE;MEDIUM;;mission/controller/ThermalController.h -14102;0x3716;SYRLINKS_OVERHEATING;HIGH;;mission/controller/ThermalController.h -14103;0x3717;PLOC_OVERHEATING;HIGH;;mission/controller/ThermalController.h -14104;0x3718;OBC_OVERHEATING;HIGH;;mission/controller/ThermalController.h -14105;0x3719;HPA_OVERHEATING;HIGH;;mission/controller/ThermalController.h -14106;0x371a;PLPCDU_OVERHEATING;HIGH;;mission/controller/ThermalController.h +14100;0x3714;POSSIBLE_FILE_CORRUPTION;LOW;P1: Result code of TM packet parser. P2: Timestamp of possibly corrupt file as a unix timestamp.;mission/tmtc/PersistentTmStore.h +14200;0x3778;NO_VALID_SENSOR_TEMPERATURE;MEDIUM;;mission/controller/ThermalController.h +14201;0x3779;NO_HEALTHY_HEATER_AVAILABLE;MEDIUM;;mission/controller/ThermalController.h +14202;0x377a;SYRLINKS_OVERHEATING;HIGH;;mission/controller/ThermalController.h +14203;0x377b;PLOC_OVERHEATING;HIGH;;mission/controller/ThermalController.h +14204;0x377c;OBC_OVERHEATING;HIGH;;mission/controller/ThermalController.h +14205;0x377d;HPA_OVERHEATING;HIGH;;mission/controller/ThermalController.h +14206;0x377e;PLPCDU_OVERHEATING;HIGH;;mission/controller/ThermalController.h diff --git a/generators/bsp_q7s_objects.csv b/generators/bsp_q7s_objects.csv index 56dbacef..445a65c6 100644 --- a/generators/bsp_q7s_objects.csv +++ b/generators/bsp_q7s_objects.csv @@ -147,6 +147,11 @@ 0x73010002;PL_SUBSYSTEM 0x73010003;TCS_SUBSYSTEM 0x73010004;COM_SUBSYSTEM +0x73020001;MISC_TM_STORE +0x73020002;OK_TM_STORE +0x73020003;NOT_OK_TM_STORE +0x73020004;HK_TM_STORE +0x73030000;CFDP_TM_STORE 0x73500000;CCSDS_IP_CORE_BRIDGE 0x90000003;THERMAL_TEMP_INSERTER 0xFFFFFFFF;NO_OBJECT diff --git a/generators/events/translateEvents.cpp b/generators/events/translateEvents.cpp index 794ae1d7..1c7762fa 100644 --- a/generators/events/translateEvents.cpp +++ b/generators/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 257 translations. + * @brief Auto-generated event translation file. Contains 258 translations. * @details - * Generated on: 2023-02-17 13:15:51 + * Generated on: 2023-02-17 18:35:08 */ #include "translateEvents.h" @@ -250,6 +250,7 @@ const char *REBOOT_HW_STRING = "REBOOT_HW"; const char *NO_SD_CARD_ACTIVE_STRING = "NO_SD_CARD_ACTIVE"; const char *VERSION_INFO_STRING = "VERSION_INFO"; const char *CURRENT_IMAGE_INFO_STRING = "CURRENT_IMAGE_INFO"; +const char *POSSIBLE_FILE_CORRUPTION_STRING = "POSSIBLE_FILE_CORRUPTION"; const char *NO_VALID_SENSOR_TEMPERATURE_STRING = "NO_VALID_SENSOR_TEMPERATURE"; const char *NO_HEALTHY_HEATER_AVAILABLE_STRING = "NO_HEALTHY_HEATER_AVAILABLE"; const char *SYRLINKS_OVERHEATING_STRING = "SYRLINKS_OVERHEATING"; @@ -751,18 +752,20 @@ const char *translateEvents(Event event) { case (14006): return CURRENT_IMAGE_INFO_STRING; case (14100): + return POSSIBLE_FILE_CORRUPTION_STRING; + case (14200): return NO_VALID_SENSOR_TEMPERATURE_STRING; - case (14101): + case (14201): return NO_HEALTHY_HEATER_AVAILABLE_STRING; - case (14102): + case (14202): return SYRLINKS_OVERHEATING_STRING; - case (14103): + case (14203): return PLOC_OVERHEATING_STRING; - case (14104): + case (14204): return OBC_OVERHEATING_STRING; - case (14105): + case (14205): return HPA_OVERHEATING_STRING; - case (14106): + case (14206): return PLPCDU_OVERHEATING_STRING; default: return "UNKNOWN_EVENT"; diff --git a/generators/objects/translateObjects.cpp b/generators/objects/translateObjects.cpp index 9e461be6..69ed99bf 100644 --- a/generators/objects/translateObjects.cpp +++ b/generators/objects/translateObjects.cpp @@ -1,8 +1,8 @@ /** * @brief Auto-generated object translation file. * @details - * Contains 152 translations. - * Generated on: 2023-02-17 13:15:51 + * Contains 157 translations. + * Generated on: 2023-02-17 18:35:08 */ #include "translateObjects.h" @@ -155,6 +155,11 @@ const char *ACS_SUBSYSTEM_STRING = "ACS_SUBSYSTEM"; const char *PL_SUBSYSTEM_STRING = "PL_SUBSYSTEM"; const char *TCS_SUBSYSTEM_STRING = "TCS_SUBSYSTEM"; const char *COM_SUBSYSTEM_STRING = "COM_SUBSYSTEM"; +const char *MISC_TM_STORE_STRING = "MISC_TM_STORE"; +const char *OK_TM_STORE_STRING = "OK_TM_STORE"; +const char *NOT_OK_TM_STORE_STRING = "NOT_OK_TM_STORE"; +const char *HK_TM_STORE_STRING = "HK_TM_STORE"; +const char *CFDP_TM_STORE_STRING = "CFDP_TM_STORE"; const char *CCSDS_IP_CORE_BRIDGE_STRING = "CCSDS_IP_CORE_BRIDGE"; const char *THERMAL_TEMP_INSERTER_STRING = "THERMAL_TEMP_INSERTER"; const char *NO_OBJECT_STRING = "NO_OBJECT"; @@ -459,6 +464,16 @@ const char *translateObject(object_id_t object) { return TCS_SUBSYSTEM_STRING; case 0x73010004: return COM_SUBSYSTEM_STRING; + case 0x73020001: + return MISC_TM_STORE_STRING; + case 0x73020002: + return OK_TM_STORE_STRING; + case 0x73020003: + return NOT_OK_TM_STORE_STRING; + case 0x73020004: + return HK_TM_STORE_STRING; + case 0x73030000: + return CFDP_TM_STORE_STRING; case 0x73500000: return CCSDS_IP_CORE_BRIDGE_STRING; case 0x90000003: diff --git a/linux/fsfwconfig/events/translateEvents.cpp b/linux/fsfwconfig/events/translateEvents.cpp index 794ae1d7..1c7762fa 100644 --- a/linux/fsfwconfig/events/translateEvents.cpp +++ b/linux/fsfwconfig/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 257 translations. + * @brief Auto-generated event translation file. Contains 258 translations. * @details - * Generated on: 2023-02-17 13:15:51 + * Generated on: 2023-02-17 18:35:08 */ #include "translateEvents.h" @@ -250,6 +250,7 @@ const char *REBOOT_HW_STRING = "REBOOT_HW"; const char *NO_SD_CARD_ACTIVE_STRING = "NO_SD_CARD_ACTIVE"; const char *VERSION_INFO_STRING = "VERSION_INFO"; const char *CURRENT_IMAGE_INFO_STRING = "CURRENT_IMAGE_INFO"; +const char *POSSIBLE_FILE_CORRUPTION_STRING = "POSSIBLE_FILE_CORRUPTION"; const char *NO_VALID_SENSOR_TEMPERATURE_STRING = "NO_VALID_SENSOR_TEMPERATURE"; const char *NO_HEALTHY_HEATER_AVAILABLE_STRING = "NO_HEALTHY_HEATER_AVAILABLE"; const char *SYRLINKS_OVERHEATING_STRING = "SYRLINKS_OVERHEATING"; @@ -751,18 +752,20 @@ const char *translateEvents(Event event) { case (14006): return CURRENT_IMAGE_INFO_STRING; case (14100): + return POSSIBLE_FILE_CORRUPTION_STRING; + case (14200): return NO_VALID_SENSOR_TEMPERATURE_STRING; - case (14101): + case (14201): return NO_HEALTHY_HEATER_AVAILABLE_STRING; - case (14102): + case (14202): return SYRLINKS_OVERHEATING_STRING; - case (14103): + case (14203): return PLOC_OVERHEATING_STRING; - case (14104): + case (14204): return OBC_OVERHEATING_STRING; - case (14105): + case (14205): return HPA_OVERHEATING_STRING; - case (14106): + case (14206): return PLPCDU_OVERHEATING_STRING; default: return "UNKNOWN_EVENT"; diff --git a/linux/fsfwconfig/objects/translateObjects.cpp b/linux/fsfwconfig/objects/translateObjects.cpp index 9e461be6..69ed99bf 100644 --- a/linux/fsfwconfig/objects/translateObjects.cpp +++ b/linux/fsfwconfig/objects/translateObjects.cpp @@ -1,8 +1,8 @@ /** * @brief Auto-generated object translation file. * @details - * Contains 152 translations. - * Generated on: 2023-02-17 13:15:51 + * Contains 157 translations. + * Generated on: 2023-02-17 18:35:08 */ #include "translateObjects.h" @@ -155,6 +155,11 @@ const char *ACS_SUBSYSTEM_STRING = "ACS_SUBSYSTEM"; const char *PL_SUBSYSTEM_STRING = "PL_SUBSYSTEM"; const char *TCS_SUBSYSTEM_STRING = "TCS_SUBSYSTEM"; const char *COM_SUBSYSTEM_STRING = "COM_SUBSYSTEM"; +const char *MISC_TM_STORE_STRING = "MISC_TM_STORE"; +const char *OK_TM_STORE_STRING = "OK_TM_STORE"; +const char *NOT_OK_TM_STORE_STRING = "NOT_OK_TM_STORE"; +const char *HK_TM_STORE_STRING = "HK_TM_STORE"; +const char *CFDP_TM_STORE_STRING = "CFDP_TM_STORE"; const char *CCSDS_IP_CORE_BRIDGE_STRING = "CCSDS_IP_CORE_BRIDGE"; const char *THERMAL_TEMP_INSERTER_STRING = "THERMAL_TEMP_INSERTER"; const char *NO_OBJECT_STRING = "NO_OBJECT"; @@ -459,6 +464,16 @@ const char *translateObject(object_id_t object) { return TCS_SUBSYSTEM_STRING; case 0x73010004: return COM_SUBSYSTEM_STRING; + case 0x73020001: + return MISC_TM_STORE_STRING; + case 0x73020002: + return OK_TM_STORE_STRING; + case 0x73020003: + return NOT_OK_TM_STORE_STRING; + case 0x73020004: + return HK_TM_STORE_STRING; + case 0x73030000: + return CFDP_TM_STORE_STRING; case 0x73500000: return CCSDS_IP_CORE_BRIDGE_STRING; case 0x90000003: diff --git a/tmtc b/tmtc index 556060a3..2ef56ae8 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 556060a3f3e204e7a171385d31a3ec409755c6b1 +Subproject commit 2ef56ae8c4cbca4c5838d39597ee12849ea7d565 From 4fe14b464aab8944bbfcad4d6b8b93ff2e86ceac Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 20 Feb 2023 13:45:16 +0100 Subject: [PATCH 62/87] update cmake cfg --- .idea/cmake.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.idea/cmake.xml b/.idea/cmake.xml index 28d4d307..e8d9d9dd 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -2,7 +2,7 @@ - + From fd0da7379aac34b0b05e320391640aab0fa63573 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 20 Feb 2023 15:17:31 +0100 Subject: [PATCH 63/87] only process on TC request per cycle --- mission/core/GenericFactory.h | 2 +- mission/tmtc/CfdpTmFunnel.cpp | 6 +++--- mission/tmtc/PusTmFunnel.cpp | 12 ++++++------ 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/mission/core/GenericFactory.h b/mission/core/GenericFactory.h index 9db58f5d..5902ff7b 100644 --- a/mission/core/GenericFactory.h +++ b/mission/core/GenericFactory.h @@ -1,8 +1,8 @@ #ifndef MISSION_CORE_GENERICFACTORY_H_ #define MISSION_CORE_GENERICFACTORY_H_ -#include #include +#include #include "fsfw/objectmanager/SystemObjectIF.h" #include "fsfw/power/PowerSwitchIF.h" diff --git a/mission/tmtc/CfdpTmFunnel.cpp b/mission/tmtc/CfdpTmFunnel.cpp index 818de9a7..9d5bd8ed 100644 --- a/mission/tmtc/CfdpTmFunnel.cpp +++ b/mission/tmtc/CfdpTmFunnel.cpp @@ -54,8 +54,7 @@ ReturnValue_t CfdpTmFunnel::handlePacket(TmTcMessage& msg) { } size_t packetLen = 0; uint8_t* serPtr = newPacketData; - result = - spacePacketHeader.serializeBe(&serPtr, &packetLen, spacePacketHeader.getFullPacketLen()); + result = spacePacketHeader.serializeBe(&serPtr, &packetLen, spacePacketHeader.getFullPacketLen()); if (result != returnvalue::OK) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::error << "CfdpTmFunnel::handlePacket: Error serializing packet" << std::endl; @@ -82,7 +81,8 @@ ReturnValue_t CfdpTmFunnel::handlePacket(TmTcMessage& msg) { } else { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::error << "PusTmFunnel::handlePacket: Store too full to create data copy or store " - "error" << std::endl; + "error" + << std::endl; break; #endif } diff --git a/mission/tmtc/PusTmFunnel.cpp b/mission/tmtc/PusTmFunnel.cpp index ec6aa0f7..47131283 100644 --- a/mission/tmtc/PusTmFunnel.cpp +++ b/mission/tmtc/PusTmFunnel.cpp @@ -52,7 +52,7 @@ PusTmFunnel::~PusTmFunnel() = default; ReturnValue_t PusTmFunnel::performOperation(uint8_t) { CommandMessage cmdMessage; ReturnValue_t status = tcQueue->receiveMessage(&cmdMessage); - while (status == returnvalue::OK) { + if (status == returnvalue::OK) { if (cmdMessage.getMessageType() == messagetypes::TM_STORE) { Command_t cmd = cmdMessage.getCommand(); object_id_t objectId = TmStoreMessage::getObjectId(&cmdMessage); @@ -103,15 +103,15 @@ ReturnValue_t PusTmFunnel::performOperation(uint8_t) { } } } - TmTcMessage currentMessage; - status = tmQueue->receiveMessage(¤tMessage); + TmTcMessage tmMessage; + status = tmQueue->receiveMessage(&tmMessage); while (status == returnvalue::OK) { - status = handleTmPacket(currentMessage); + status = handleTmPacket(tmMessage); if (status != returnvalue::OK) { sif::warning << "TmFunnel packet handling failed" << std::endl; break; } - status = tmQueue->receiveMessage(¤tMessage); + status = tmQueue->receiveMessage(&tmMessage); } if (status == MessageQueueIF::EMPTY) { @@ -140,7 +140,7 @@ ReturnValue_t PusTmFunnel::handleTmPacket(TmTcMessage &message) { sourceSequenceCount = sourceSequenceCount % ccsds::LIMIT_SEQUENCE_COUNT; packet.updateErrorControl(); - timeval currentUptime; + timeval currentUptime{}; Clock::getUptime(¤tUptime); if (currentUptime.tv_sec - lastTvUpdate.tv_sec > static_cast(TV_UPDATE_INTERVAL_SECS)) { From a3f2219f9b3fdfb2596bf4661f36649a4a50816f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 20 Feb 2023 15:42:04 +0100 Subject: [PATCH 64/87] pass HK and not ok packets as well --- mission/tmtc/PusTmFunnel.cpp | 106 +++++++++++++++++++---------------- mission/tmtc/PusTmFunnel.h | 2 + tmtc | 2 +- 3 files changed, 61 insertions(+), 49 deletions(-) diff --git a/mission/tmtc/PusTmFunnel.cpp b/mission/tmtc/PusTmFunnel.cpp index 47131283..814dd24e 100644 --- a/mission/tmtc/PusTmFunnel.cpp +++ b/mission/tmtc/PusTmFunnel.cpp @@ -53,54 +53,9 @@ ReturnValue_t PusTmFunnel::performOperation(uint8_t) { CommandMessage cmdMessage; ReturnValue_t status = tcQueue->receiveMessage(&cmdMessage); if (status == returnvalue::OK) { - if (cmdMessage.getMessageType() == messagetypes::TM_STORE) { - Command_t cmd = cmdMessage.getCommand(); - object_id_t objectId = TmStoreMessage::getObjectId(&cmdMessage); - TmStore *tmStore = nullptr; - switch (objectId) { - case (objects::HK_TM_STORE): { - tmStore = &hkStore; - break; - } - case (objects::OK_TM_STORE): { - tmStore = &okStore; - break; - } - case (objects::NOT_OK_TM_STORE): { - tmStore = ¬OkStore; - break; - } - case (objects::MISC_TM_STORE): { - tmStore = &miscStore; - break; - } - default: { - } - } - if (tmStore == nullptr) { - continue; - } - if (cmd == TmStoreMessage::DELETE_STORE_CONTENT_TIME) { - store_address_t storeId = TmStoreMessage::getStoreId(&cmdMessage); - auto accessor = ipcStore.getData(storeId); - uint32_t deleteUpToUnixSeconds = 0; - size_t size = accessor.second.size(); - SerializeAdapter::deSerialize(&deleteUpToUnixSeconds, accessor.second.data(), &size, - SerializeIF::Endianness::NETWORK); - tmStore->deleteUpTo(deleteUpToUnixSeconds); - } else if (cmd == TmStoreMessage::DOWNLINK_STORE_CONTENT_TIME) { - store_address_t storeId = TmStoreMessage::getStoreId(&cmdMessage); - auto accessor = ipcStore.getData(storeId); - uint32_t dumpFromUnixSeconds; - uint32_t dumpUntilUnixSeconds; - size_t size = accessor.second.size(); - SerializeAdapter::deSerialize(&dumpFromUnixSeconds, accessor.second.data(), &size, - SerializeIF::Endianness::NETWORK); - SerializeAdapter::deSerialize(&dumpUntilUnixSeconds, accessor.second.data(), &size, - SerializeIF::Endianness::NETWORK); - // TODO: TM store missing, and maybe there is a better way to do this? - tmStore->dumpFromUpTo(dumpFromUnixSeconds, dumpUntilUnixSeconds, *this); - } + ReturnValue_t result = handleTcRequest(cmdMessage); + if(result != returnvalue::OK) { + sif::error << "PusTmFunnel::performOperation: Error handling TC request" << std::endl; } } TmTcMessage tmMessage; @@ -153,6 +108,8 @@ ReturnValue_t PusTmFunnel::handleTmPacket(TmTcMessage &message) { if (sdcUsable) { miscStore.passPacket(packet); okStore.passPacket(packet); + notOkStore.passPacket(packet); + hkStore.passPacket(packet); } return sendPacketToDestinations(origStoreId, message, packetData, size); } @@ -173,3 +130,56 @@ ReturnValue_t PusTmFunnel::initialize() { initStoresIfPossible(sdcMan.isSdCardUsable(std::nullopt)); return returnvalue::OK; } + +ReturnValue_t PusTmFunnel::handleTcRequest(CommandMessage &cmdMessage) { + if (cmdMessage.getMessageType() == messagetypes::TM_STORE) { + Command_t cmd = cmdMessage.getCommand(); + object_id_t objectId = TmStoreMessage::getObjectId(&cmdMessage); + TmStore *tmStore = nullptr; + switch (objectId) { + case (objects::HK_TM_STORE): { + tmStore = &hkStore; + break; + } + case (objects::OK_TM_STORE): { + tmStore = &okStore; + break; + } + case (objects::NOT_OK_TM_STORE): { + tmStore = ¬OkStore; + break; + } + case (objects::MISC_TM_STORE): { + tmStore = &miscStore; + break; + } + default: { + } + } + if (tmStore == nullptr) { + return returnvalue::FAILED; + } + if (cmd == TmStoreMessage::DELETE_STORE_CONTENT_TIME) { + store_address_t storeId = TmStoreMessage::getStoreId(&cmdMessage); + auto accessor = ipcStore.getData(storeId); + uint32_t deleteUpToUnixSeconds = 0; + size_t size = accessor.second.size(); + SerializeAdapter::deSerialize(&deleteUpToUnixSeconds, accessor.second.data(), &size, + SerializeIF::Endianness::NETWORK); + tmStore->deleteUpTo(deleteUpToUnixSeconds); + } else if (cmd == TmStoreMessage::DOWNLINK_STORE_CONTENT_TIME) { + store_address_t storeId = TmStoreMessage::getStoreId(&cmdMessage); + auto accessor = ipcStore.getData(storeId); + uint32_t dumpFromUnixSeconds; + uint32_t dumpUntilUnixSeconds; + size_t size = accessor.second.size(); + SerializeAdapter::deSerialize(&dumpFromUnixSeconds, accessor.second.data(), &size, + SerializeIF::Endianness::NETWORK); + SerializeAdapter::deSerialize(&dumpUntilUnixSeconds, accessor.second.data(), &size, + SerializeIF::Endianness::NETWORK); + // TODO: TM store missing, and maybe there is a better way to do this? + tmStore->dumpFromUpTo(dumpFromUnixSeconds, dumpUntilUnixSeconds, *this); + } + } + return returnvalue::OK; +} diff --git a/mission/tmtc/PusTmFunnel.h b/mission/tmtc/PusTmFunnel.h index 487931a3..615d36ea 100644 --- a/mission/tmtc/PusTmFunnel.h +++ b/mission/tmtc/PusTmFunnel.h @@ -6,6 +6,7 @@ #include #include #include +#include "fsfw/ipc/CommandMessage.h" #include #include @@ -43,6 +44,7 @@ class PusTmFunnel : public TmFunnelBase { TmStore hkStore; SdCardMountedIF &sdcMan; + ReturnValue_t handleTcRequest(CommandMessage& msg); ReturnValue_t handleTmPacket(TmTcMessage &message); void initStoresIfPossible(bool sdCardUsable); ReturnValue_t initialize() override; diff --git a/tmtc b/tmtc index db1dbe96..6a6d9c0a 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit db1dbe9661653cd566229e3b0da4666a76f3392c +Subproject commit 6a6d9c0a7a6342c23aa4c602ef33b5950f54409c From a7d3f2c3f83c4399248f40fb3a0d2bcf5840dd91 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 20 Feb 2023 16:10:35 +0100 Subject: [PATCH 65/87] add PUS TM store --- bsp_hosted/scheduling.cpp | 45 +++++++++++++------------------ common/config/tmtc/pusIds.h | 1 + fsfw | 2 +- mission/core/GenericFactory.cpp | 2 ++ mission/tmtc/Service15TmStorage.h | 2 +- tmtc | 2 +- 6 files changed, 24 insertions(+), 30 deletions(-) diff --git a/bsp_hosted/scheduling.cpp b/bsp_hosted/scheduling.cpp index 270de82e..9f859b6c 100644 --- a/bsp_hosted/scheduling.cpp +++ b/bsp_hosted/scheduling.cpp @@ -95,46 +95,43 @@ void scheduling::initTasks() { sif::error << "Add component UDP Polling failed" << std::endl; } - /* PUS Services */ - PeriodicTaskIF* pusVerification = factory->createPeriodicTask( - "PUS_VERIF", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); - result = pusVerification->addComponent(objects::PUS_SERVICE_1_VERIFICATION); + PeriodicTaskIF* pusHighPrio = factory->createPeriodicTask( + "PUS_HIGH_PRIO", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); + result = pusHighPrio->addComponent(objects::PUS_SERVICE_1_VERIFICATION); if (result != returnvalue::OK) { sif::error << "Object add component failed" << std::endl; } - - PeriodicTaskIF* eventHandling = factory->createPeriodicTask( - "EVENTS", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); - result = eventHandling->addComponent(objects::EVENT_MANAGER); + result = pusHighPrio->addComponent(objects::EVENT_MANAGER); if (result != returnvalue::OK) { - scheduling::printAddObjectError("EVENT_MNGR", objects::EVENT_MANAGER); + scheduling::printAddObjectError("EVENT_MGMT", objects::EVENT_MANAGER); } - result = eventHandling->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING); + result = pusHighPrio->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING); if (result != returnvalue::OK) { scheduling::printAddObjectError("PUS5", objects::PUS_SERVICE_5_EVENT_REPORTING); } - - PeriodicTaskIF* pusHighPrio = factory->createPeriodicTask( - "PUS_HIGH_PRIO", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); - result = pusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS); - if (result != returnvalue::OK) { - scheduling::printAddObjectError("PUS2", objects::PUS_SERVICE_2_DEVICE_ACCESS); - } result = pusHighPrio->addComponent(objects::PUS_SERVICE_9_TIME_MGMT); if (result != returnvalue::OK) { scheduling::printAddObjectError("PUS9", objects::PUS_SERVICE_9_TIME_MGMT); } + + PeriodicTaskIF* pusMedPrio = factory->createPeriodicTask( + "PUS_MED_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, missedDeadlineFunc); + result = pusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS); + if (result != returnvalue::OK) { + scheduling::printAddObjectError("PUS2", objects::PUS_SERVICE_2_DEVICE_ACCESS); + } result = pusHighPrio->addComponent(objects::PUS_SERVICE_3_HOUSEKEEPING); if (result != returnvalue::OK) { scheduling::printAddObjectError("PUS3", objects::PUS_SERVICE_3_HOUSEKEEPING); } - - PeriodicTaskIF* pusMedPrio = factory->createPeriodicTask( - "PUS_MED_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, missedDeadlineFunc); result = pusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT); if (result != returnvalue::OK) { scheduling::printAddObjectError("PUS8", objects::PUS_SERVICE_8_FUNCTION_MGMT); } + result = pusMedPrio->addComponent(objects::PUS_SERVICE_15_TM_STORAGE); + if (result != returnvalue::OK) { + scheduling::printAddObjectError("PUS15", objects::PUS_SERVICE_15_TM_STORAGE); + } result = pusMedPrio->addComponent(objects::PUS_SERVICE_200_MODE_MGMT); if (result != returnvalue::OK) { scheduling::printAddObjectError("PUS200", objects::PUS_SERVICE_200_MODE_MGMT); @@ -143,10 +140,7 @@ void scheduling::initTasks() { if (result != returnvalue::OK) { scheduling::printAddObjectError("PUS20", objects::PUS_SERVICE_20_PARAMETERS); } - - PeriodicTaskIF* pusLowPrio = factory->createPeriodicTask( - "PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.6, missedDeadlineFunc); - result = pusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST); + result = pusMedPrio->addComponent(objects::PUS_SERVICE_17_TEST); if (result != returnvalue::OK) { scheduling::printAddObjectError("PUS17", objects::PUS_SERVICE_17_TEST); } @@ -220,11 +214,8 @@ void scheduling::initTasks() { udpPollingTask->startTask(); tcpPollingTask->startTask(); - pusVerification->startTask(); - eventHandling->startTask(); pusHighPrio->startTask(); pusMedPrio->startTask(); - pusLowPrio->startTask(); pstTask->startTask(); thermalTask->startTask(); diff --git a/common/config/tmtc/pusIds.h b/common/config/tmtc/pusIds.h index 0891992d..b44d7e20 100644 --- a/common/config/tmtc/pusIds.h +++ b/common/config/tmtc/pusIds.h @@ -12,6 +12,7 @@ enum Ids { PUS_SERVICE_8 = 8, PUS_SERVICE_9 = 9, PUS_SERVICE_11 = 11, + PUS_SERVICE_15 = 15, PUS_SERVICE_17 = 17, PUS_SERVICE_19 = 19, PUS_SERVICE_20 = 20, diff --git a/fsfw b/fsfw index e1711f03..2a0c2444 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit e1711f0345bdcd471a308ebd080071f8974c8e91 +Subproject commit 2a0c244468e40c4d036a2c4d5eeec3af03a2f064 diff --git a/mission/core/GenericFactory.cpp b/mission/core/GenericFactory.cpp index 821af001..dcf19a7b 100644 --- a/mission/core/GenericFactory.cpp +++ b/mission/core/GenericFactory.cpp @@ -57,6 +57,7 @@ // TCP server includes #include "fsfw/osal/common/TcpTmTcBridge.h" #include "fsfw/osal/common/TcpTmTcServer.h" +#include "mission/tmtc/Service15TmStorage.h" #endif #endif @@ -173,6 +174,7 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun new Service11TelecommandScheduling( PsbParams(objects::PUS_SERVICE_11_TC_SCHEDULER, config::EIVE_PUS_APID, pus::PUS_SERVICE_11), ccsdsDistrib); + new Service15TmStorage(objects::PUS_SERVICE_15_TM_STORAGE, config::EIVE_PUS_APID, 10); new Service17Test( PsbParams(objects::PUS_SERVICE_17_TEST, config::EIVE_PUS_APID, pus::PUS_SERVICE_17)); new Service20ParameterManagement(objects::PUS_SERVICE_20_PARAMETERS, config::EIVE_PUS_APID, diff --git a/mission/tmtc/Service15TmStorage.h b/mission/tmtc/Service15TmStorage.h index 2074754a..33be0634 100644 --- a/mission/tmtc/Service15TmStorage.h +++ b/mission/tmtc/Service15TmStorage.h @@ -7,7 +7,7 @@ class Service15TmStorage : public CommandingServiceBase { public: enum Subservices : uint8_t { START_BY_TIME_RANGE_RETRIEVAL = 9, DELETE_UP_TO = 11 }; explicit Service15TmStorage(object_id_t objectId, uint16_t apid, uint8_t numParallelCommands, - uint16_t commandTimeoutSecs, size_t queueDepth); + uint16_t commandTimeoutSecs = 60, size_t queueDepth = 10); private: ReturnValue_t isValidSubservice(uint8_t subservice) override; diff --git a/tmtc b/tmtc index 6a6d9c0a..8f5f7064 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 6a6d9c0a7a6342c23aa4c602ef33b5950f54409c +Subproject commit 8f5f7064e934f9cf325548b9d05dd87e77d9be61 From 67e9dc90907a4d2e398dc2e3650d85d4c73b6f0e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 20 Feb 2023 16:12:56 +0100 Subject: [PATCH 66/87] small clang tidy stuff --- mission/tmtc/PusTmFunnel.cpp | 4 ++-- mission/tmtc/PusTmFunnel.h | 4 ++-- mission/tmtc/Service15TmStorage.cpp | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/mission/tmtc/PusTmFunnel.cpp b/mission/tmtc/PusTmFunnel.cpp index 814dd24e..87aa8840 100644 --- a/mission/tmtc/PusTmFunnel.cpp +++ b/mission/tmtc/PusTmFunnel.cpp @@ -53,8 +53,8 @@ ReturnValue_t PusTmFunnel::performOperation(uint8_t) { CommandMessage cmdMessage; ReturnValue_t status = tcQueue->receiveMessage(&cmdMessage); if (status == returnvalue::OK) { - ReturnValue_t result = handleTcRequest(cmdMessage); - if(result != returnvalue::OK) { + ReturnValue_t result = handleTcRequest(cmdMessage); + if (result != returnvalue::OK) { sif::error << "PusTmFunnel::performOperation: Error handling TC request" << std::endl; } } diff --git a/mission/tmtc/PusTmFunnel.h b/mission/tmtc/PusTmFunnel.h index 615d36ea..2067be51 100644 --- a/mission/tmtc/PusTmFunnel.h +++ b/mission/tmtc/PusTmFunnel.h @@ -6,12 +6,12 @@ #include #include #include -#include "fsfw/ipc/CommandMessage.h" #include #include #include "PersistentTmStore.h" +#include "fsfw/ipc/CommandMessage.h" #include "fsfw/timemanager/TimeReaderIF.h" /** @@ -44,7 +44,7 @@ class PusTmFunnel : public TmFunnelBase { TmStore hkStore; SdCardMountedIF &sdcMan; - ReturnValue_t handleTcRequest(CommandMessage& msg); + ReturnValue_t handleTcRequest(CommandMessage &msg); ReturnValue_t handleTmPacket(TmTcMessage &message); void initStoresIfPossible(bool sdCardUsable); ReturnValue_t initialize() override; diff --git a/mission/tmtc/Service15TmStorage.cpp b/mission/tmtc/Service15TmStorage.cpp index d752bf00..ce753f66 100644 --- a/mission/tmtc/Service15TmStorage.cpp +++ b/mission/tmtc/Service15TmStorage.cpp @@ -16,14 +16,14 @@ Service15TmStorage::Service15TmStorage(object_id_t objectId, uint16_t apid, ReturnValue_t Service15TmStorage::isValidSubservice(uint8_t subservice) { switch (subservice) { + case (Subservices::DELETE_UP_TO): case (Subservices::START_BY_TIME_RANGE_RETRIEVAL): { return OK; } - case (Subservices::DELETE_UP_TO): { - return OK; + default: { + return FAILED; } } - return FAILED; } ReturnValue_t Service15TmStorage::getMessageQueueAndObject(uint8_t subservice, From 82c97656f1d468ff5b980292b03a3bacad71e9cb Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 20 Feb 2023 17:57:18 +0100 Subject: [PATCH 67/87] clangtidy --- mission/tmtc/PersistentTmStore.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mission/tmtc/PersistentTmStore.cpp b/mission/tmtc/PersistentTmStore.cpp index bb64850c..fc29384a 100644 --- a/mission/tmtc/PersistentTmStore.cpp +++ b/mission/tmtc/PersistentTmStore.cpp @@ -14,7 +14,7 @@ TmStore::TmStore(object_id_t objectId, const char* baseDir, std::string baseName RolloverInterval intervalUnit, uint32_t intervalCount, timeval& currentTv, StorageManagerIF& tmStore, SdCardMountedIF& sdcMan) : SystemObject(objectId), - baseDir(std::move(baseDir)), + baseDir(baseDir), baseName(std::move(baseName)), currentTv(currentTv), sdcMan(sdcMan), From e416d94224d6dc12b58592eea49813280a70f7f9 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 21 Feb 2023 20:43:16 +0100 Subject: [PATCH 68/87] each store has own tc queue now --- linux/devices/CMakeLists.txt | 5 +- mission/core/GenericFactory.cpp | 4 +- mission/devices/ImtqHandler.cpp | 2 +- mission/tmtc/CfdpTmFunnel.cpp | 2 +- mission/tmtc/PersistentTmStore.cpp | 58 ++++++++++++++++--- mission/tmtc/PersistentTmStore.h | 20 ++++--- mission/tmtc/PusTmFunnel.cpp | 90 ++++++++--------------------- mission/tmtc/PusTmFunnel.h | 1 - mission/tmtc/Service15TmStorage.cpp | 10 +--- mission/tmtc/TmFunnelBase.cpp | 3 - mission/tmtc/TmFunnelBase.h | 20 ++----- mission/tmtc/VirtualChannel.cpp | 2 +- 12 files changed, 101 insertions(+), 116 deletions(-) diff --git a/linux/devices/CMakeLists.txt b/linux/devices/CMakeLists.txt index 17d842ea..22b39840 100644 --- a/linux/devices/CMakeLists.txt +++ b/linux/devices/CMakeLists.txt @@ -3,8 +3,9 @@ if(EIVE_BUILD_GPSD_GPS_HANDLER) endif() target_sources( - ${OBSW_NAME} PRIVATE Max31865RtdPolling.cpp ScexUartReader.cpp ImtqPollingTask.cpp - ScexDleParser.cpp ScexHelper.cpp RwPollingTask.cpp) + ${OBSW_NAME} + PRIVATE Max31865RtdPolling.cpp ScexUartReader.cpp ImtqPollingTask.cpp + ScexDleParser.cpp ScexHelper.cpp RwPollingTask.cpp) add_subdirectory(ploc) diff --git a/mission/core/GenericFactory.cpp b/mission/core/GenericFactory.cpp index fea6e74a..306e4527 100644 --- a/mission/core/GenericFactory.cpp +++ b/mission/core/GenericFactory.cpp @@ -139,10 +139,10 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun new CcsdsDistributor(config::EIVE_PUS_APID, objects::CCSDS_PACKET_DISTRIBUTOR); new PusDistributor(config::EIVE_PUS_APID, objects::PUS_PACKET_DISTRIBUTOR, ccsdsDistrib); - PusTmFunnel::FunnelCfg cfdpFunnelCfg(objects::CFDP_TM_FUNNEL, *tmStore, *ipcStore, 50, 15); + PusTmFunnel::FunnelCfg cfdpFunnelCfg(objects::CFDP_TM_FUNNEL, *tmStore, *ipcStore, 50); *cfdpFunnel = new CfdpTmFunnel(cfdpFunnelCfg, config::EIVE_CFDP_APID); PusTmFunnel::FunnelCfg pusFunnelCfg(objects::PUS_TM_FUNNEL, *tmStore, *ipcStore, - config::MAX_PUS_FUNNEL_QUEUE_DEPTH, 15); + config::MAX_PUS_FUNNEL_QUEUE_DEPTH); *pusFunnel = new PusTmFunnel(pusFunnelCfg, *timeStamper, sdcMan); #if OBSW_ADD_TCPIP_SERVERS == 1 #if OBSW_ADD_TMTC_UDP_SERVER == 1 diff --git a/mission/devices/ImtqHandler.cpp b/mission/devices/ImtqHandler.cpp index 18c002c4..aa935ce5 100644 --- a/mission/devices/ImtqHandler.cpp +++ b/mission/devices/ImtqHandler.cpp @@ -256,7 +256,7 @@ ReturnValue_t ImtqHandler::scanForReply(const uint8_t* start, size_t remainingSi ReturnValue_t ImtqHandler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t* packet) { ReturnValue_t result; ReturnValue_t status = returnvalue::OK; - if(getMode() != MODE_NORMAL) { + if (getMode() != MODE_NORMAL) { // Ignore replies during transitions. return returnvalue::OK; } diff --git a/mission/tmtc/CfdpTmFunnel.cpp b/mission/tmtc/CfdpTmFunnel.cpp index 3955aa84..89d7c105 100644 --- a/mission/tmtc/CfdpTmFunnel.cpp +++ b/mission/tmtc/CfdpTmFunnel.cpp @@ -20,7 +20,7 @@ ReturnValue_t CfdpTmFunnel::performOperation(uint8_t) { break; } count++; - if(count == 500) { + if (count == 500) { sif::error << "CfdpTmFunnel: Possible message storm detected" << std::endl; break; } diff --git a/mission/tmtc/PersistentTmStore.cpp b/mission/tmtc/PersistentTmStore.cpp index fc29384a..156ae6f0 100644 --- a/mission/tmtc/PersistentTmStore.cpp +++ b/mission/tmtc/PersistentTmStore.cpp @@ -8,6 +8,10 @@ #include #include +#include "fsfw/ipc/CommandMessage.h" +#include "fsfw/ipc/QueueFactory.h" +#include "fsfw/tmstorage/TmStoreMessage.h" + using namespace returnvalue; TmStore::TmStore(object_id_t objectId, const char* baseDir, std::string baseName, @@ -19,9 +23,46 @@ TmStore::TmStore(object_id_t objectId, const char* baseDir, std::string baseName currentTv(currentTv), sdcMan(sdcMan), tmStore(tmStore) { + tcQueue = QueueFactory::instance()->createMessageQueue(); calcDiffSeconds(intervalUnit, intervalCount); } +ReturnValue_t TmStore::handleCommandQueue(StorageManagerIF& ipcStore, TmFunnelBase& tmFunnel) { + CommandMessage cmdMessage; + ReturnValue_t result = tcQueue->receiveMessage(&cmdMessage); + if (result == MessageQueueIF::EMPTY) { + return returnvalue::OK; + } + if (result != returnvalue::OK) { + return result; + } + if (cmdMessage.getMessageType() == messagetypes::TM_STORE) { + Command_t cmd = cmdMessage.getCommand(); + if (cmd == TmStoreMessage::DELETE_STORE_CONTENT_TIME) { + store_address_t storeId = TmStoreMessage::getStoreId(&cmdMessage); + auto accessor = ipcStore.getData(storeId); + uint32_t deleteUpToUnixSeconds = 0; + size_t size = accessor.second.size(); + SerializeAdapter::deSerialize(&deleteUpToUnixSeconds, accessor.second.data(), &size, + SerializeIF::Endianness::NETWORK); + deleteUpTo(deleteUpToUnixSeconds); + } else if (cmd == TmStoreMessage::DOWNLINK_STORE_CONTENT_TIME) { + store_address_t storeId = TmStoreMessage::getStoreId(&cmdMessage); + auto accessor = ipcStore.getData(storeId); + uint32_t dumpFromUnixSeconds; + uint32_t dumpUntilUnixSeconds; + size_t size = accessor.second.size(); + SerializeAdapter::deSerialize(&dumpFromUnixSeconds, accessor.second.data(), &size, + SerializeIF::Endianness::NETWORK); + SerializeAdapter::deSerialize(&dumpUntilUnixSeconds, accessor.second.data(), &size, + SerializeIF::Endianness::NETWORK); + // TODO: TM store missing, and maybe there is a better way to do this? + dumpFromUpTo(dumpFromUnixSeconds, dumpUntilUnixSeconds, tmFunnel); + } + } + return returnvalue::OK; +} + ReturnValue_t TmStore::passPacket(PusTmReader& reader) { bool inApidList = false; if (filter.apid) { @@ -91,11 +132,12 @@ ReturnValue_t TmStore::storePacket(PusTmReader& reader) { // Rollover conditions were handled, write to file now std::ofstream of(mostRecentFile.value(), std::ios::app | std::ios::binary); - of.write(reinterpret_cast(reader.getFullData()), reader.getFullPacketLen()); + of.write(reinterpret_cast(reader.getFullData()), + static_cast(reader.getFullPacketLen())); return returnvalue::OK; } -MessageQueueId_t TmStore::getCommandQueue() { return MessageQueueIF::NO_QUEUE; } +MessageQueueId_t TmStore::getCommandQueue() const { return tcQueue->getId(); } void TmStore::calcDiffSeconds(RolloverInterval intervalUnit, uint32_t intervalCount) { if (intervalUnit == RolloverInterval::MINUTELY) { @@ -184,7 +226,7 @@ void TmStore::addServiceSubservice(uint8_t service, uint8_t subservice) { std::vector>({std::pair(service, subservice)}); return; } - filter.serviceSubservices.value().push_back({service, subservice}); + filter.serviceSubservices.value().emplace_back(service, subservice); } void TmStore::deleteUpTo(uint32_t unixSeconds) { @@ -196,7 +238,7 @@ void TmStore::deleteUpTo(uint32_t unixSeconds) { } Clock::TimeOfDay_t tod; pathToTod(file.path(), tod); - timeval time; + timeval time{}; ReturnValue_t result = Clock::convertTimeOfDayToTimeval(&tod, &time); if (result != returnvalue::OK) { sif::error << "TOD to time conversion failed for file " << file << std::endl; @@ -222,13 +264,13 @@ void TmStore::dumpFromUpTo(uint32_t fromUnixSeconds, uint32_t upToUnixSeconds, } Clock::TimeOfDay_t tod; pathToTod(file.path(), tod); - timeval time; + timeval time{}; ReturnValue_t result = Clock::convertTimeOfDayToTimeval(&tod, &time); if (result != returnvalue::OK) { sif::error << "TOD to time conversion failed for file " << file << std::endl; continue; } - uint32_t timeUnsigned = static_cast(time.tv_sec); + auto timeUnsigned = static_cast(time.tv_sec); if (timeUnsigned > fromUnixSeconds && timeUnsigned + rolloverDiffSeconds < upToUnixSeconds) { fileToPackets(file, timeUnsigned, funnel); } @@ -237,7 +279,7 @@ void TmStore::dumpFromUpTo(uint32_t fromUnixSeconds, uint32_t upToUnixSeconds, void TmStore::pathToTod(const std::filesystem::path& path, Clock::TimeOfDay_t& tod) { auto pathStr = path.string(); - size_t splitChar = pathStr.find("_"); + size_t splitChar = pathStr.find('_'); auto timeOnlyStr = pathStr.substr(splitChar); sscanf(timeOnlyStr.data(), "%04" SCNu32 "-%02" SCNu32 "-%02" SCNu32 "T%02" SCNu32 "-%02" SCNu32 "-%02" SCNu32 "Z", @@ -254,7 +296,7 @@ void TmStore::fileToPackets(const std::filesystem::path& path, uint32_t unixStam return; } std::ifstream ifile(path, std::ios::binary); - ifile.read(reinterpret_cast(fileBuf.data()), size); + ifile.read(reinterpret_cast(fileBuf.data()), static_cast(size)); size_t currentIdx = 0; while (currentIdx < size) { PusTmReader reader(&timeReader, fileBuf.data(), fileBuf.size()); diff --git a/mission/tmtc/PersistentTmStore.h b/mission/tmtc/PersistentTmStore.h index 8575f35f..a1c88e1a 100644 --- a/mission/tmtc/PersistentTmStore.h +++ b/mission/tmtc/PersistentTmStore.h @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include #include @@ -21,7 +21,7 @@ struct PacketFilter { enum class RolloverInterval { MINUTELY, HOURLY, DAILY }; -class TmStore : public SystemObject { +class TmStore : public TmStoreFrontendSimpleIF, public SystemObject { public: static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PERSISTENT_TM_STORE; @@ -34,6 +34,8 @@ class TmStore : public SystemObject { RolloverInterval intervalUnit, uint32_t intervalCount, timeval& currentTv, StorageManagerIF& tmStore, SdCardMountedIF& sdcMan); + ReturnValue_t handleCommandQueue(StorageManagerIF& ipcStore, TmFunnelBase& tmFunnel); + void addApid(uint16_t apid); void addService(uint8_t service); void addServiceSubservice(uint8_t service, uint8_t subservice); @@ -48,11 +50,7 @@ class TmStore : public SystemObject { private: static constexpr size_t MAX_FILESIZE = 8192; - /** - * To get the queue where commands shall be sent. - * @return Id of command queue. - */ - MessageQueueId_t getCommandQueue(); + MessageQueueIF* tcQueue; PacketFilter filter; CdsShortTimeStamper timeReader; bool baseDirUninitialized = true; @@ -67,9 +65,15 @@ class TmStore : public SystemObject { SdCardMountedIF& sdcMan; StorageManagerIF& tmStore; + /** + * To get the queue where commands shall be sent. + * @return Id of command queue. + */ + [[nodiscard]] MessageQueueId_t getCommandQueue() const override; + void calcDiffSeconds(RolloverInterval intervalUnit, uint32_t intervalCount); void assignAndOrCreateMostRecentFile(); - void pathToTod(const std::filesystem::path& path, Clock::TimeOfDay_t& tod); + static void pathToTod(const std::filesystem::path& path, Clock::TimeOfDay_t& tod); void fileToPackets(const std::filesystem::path& path, uint32_t unixStamp, TmFunnelBase& funnel); ReturnValue_t storePacket(PusTmReader& reader); }; diff --git a/mission/tmtc/PusTmFunnel.cpp b/mission/tmtc/PusTmFunnel.cpp index b88032d7..2b61e19a 100644 --- a/mission/tmtc/PusTmFunnel.cpp +++ b/mission/tmtc/PusTmFunnel.cpp @@ -51,35 +51,44 @@ PusTmFunnel::~PusTmFunnel() = default; ReturnValue_t PusTmFunnel::performOperation(uint8_t) { CommandMessage cmdMessage; - ReturnValue_t status = tcQueue->receiveMessage(&cmdMessage); - if (status == returnvalue::OK) { - ReturnValue_t result = handleTcRequest(cmdMessage); - if (result != returnvalue::OK) { - sif::error << "PusTmFunnel::performOperation: Error handling TC request" << std::endl; - } + ReturnValue_t result = okStore.handleCommandQueue(ipcStore, *this); + if (result != returnvalue::OK) { + sif::error << "PusTmFunnel::performOperation: Issue handling OK store command" << std::endl; + } + result = notOkStore.handleCommandQueue(ipcStore, *this); + if (result != returnvalue::OK) { + sif::error << "PusTmFunnel::performOperation: Issue handling NOT OK store command" << std::endl; + } + result = hkStore.handleCommandQueue(ipcStore, *this); + if (result != returnvalue::OK) { + sif::error << "PusTmFunnel::performOperation: Issue handling HK store command" << std::endl; + } + result = miscStore.handleCommandQueue(ipcStore, *this); + if (result != returnvalue::OK) { + sif::error << "PusTmFunnel::performOperation: Issue handling MISC store command" << std::endl; } TmTcMessage currentMessage; unsigned int count = 0; - ReturnValue_t status = tmQueue->receiveMessage(¤tMessage); - while (status == returnvalue::OK) { - status = handleTmPacket(tmMessage); - if (status != returnvalue::OK) { + result = tmQueue->receiveMessage(¤tMessage); + while (result == returnvalue::OK) { + result = handleTmPacket(currentMessage); + if (result != returnvalue::OK) { sif::warning << "TmFunnel packet handling failed" << std::endl; break; } count++; - if(count == 500) { + if (count == 500) { sif::error << "PusTmFunnel: Possible message storm detected" << std::endl; break; } - status = tmQueue->receiveMessage(¤tMessage); + result = tmQueue->receiveMessage(¤tMessage); } - if (status == MessageQueueIF::EMPTY) { + if (result == MessageQueueIF::EMPTY) { return returnvalue::OK; } - return status; + return result; } ReturnValue_t PusTmFunnel::handleTmPacket(TmTcMessage &message) { @@ -137,56 +146,3 @@ ReturnValue_t PusTmFunnel::initialize() { initStoresIfPossible(sdcMan.isSdCardUsable(std::nullopt)); return returnvalue::OK; } - -ReturnValue_t PusTmFunnel::handleTcRequest(CommandMessage &cmdMessage) { - if (cmdMessage.getMessageType() == messagetypes::TM_STORE) { - Command_t cmd = cmdMessage.getCommand(); - object_id_t objectId = TmStoreMessage::getObjectId(&cmdMessage); - TmStore *tmStore = nullptr; - switch (objectId) { - case (objects::HK_TM_STORE): { - tmStore = &hkStore; - break; - } - case (objects::OK_TM_STORE): { - tmStore = &okStore; - break; - } - case (objects::NOT_OK_TM_STORE): { - tmStore = ¬OkStore; - break; - } - case (objects::MISC_TM_STORE): { - tmStore = &miscStore; - break; - } - default: { - } - } - if (tmStore == nullptr) { - return returnvalue::FAILED; - } - if (cmd == TmStoreMessage::DELETE_STORE_CONTENT_TIME) { - store_address_t storeId = TmStoreMessage::getStoreId(&cmdMessage); - auto accessor = ipcStore.getData(storeId); - uint32_t deleteUpToUnixSeconds = 0; - size_t size = accessor.second.size(); - SerializeAdapter::deSerialize(&deleteUpToUnixSeconds, accessor.second.data(), &size, - SerializeIF::Endianness::NETWORK); - tmStore->deleteUpTo(deleteUpToUnixSeconds); - } else if (cmd == TmStoreMessage::DOWNLINK_STORE_CONTENT_TIME) { - store_address_t storeId = TmStoreMessage::getStoreId(&cmdMessage); - auto accessor = ipcStore.getData(storeId); - uint32_t dumpFromUnixSeconds; - uint32_t dumpUntilUnixSeconds; - size_t size = accessor.second.size(); - SerializeAdapter::deSerialize(&dumpFromUnixSeconds, accessor.second.data(), &size, - SerializeIF::Endianness::NETWORK); - SerializeAdapter::deSerialize(&dumpUntilUnixSeconds, accessor.second.data(), &size, - SerializeIF::Endianness::NETWORK); - // TODO: TM store missing, and maybe there is a better way to do this? - tmStore->dumpFromUpTo(dumpFromUnixSeconds, dumpUntilUnixSeconds, *this); - } - } - return returnvalue::OK; -} diff --git a/mission/tmtc/PusTmFunnel.h b/mission/tmtc/PusTmFunnel.h index 2067be51..95facfa3 100644 --- a/mission/tmtc/PusTmFunnel.h +++ b/mission/tmtc/PusTmFunnel.h @@ -44,7 +44,6 @@ class PusTmFunnel : public TmFunnelBase { TmStore hkStore; SdCardMountedIF &sdcMan; - ReturnValue_t handleTcRequest(CommandMessage &msg); ReturnValue_t handleTmPacket(TmTcMessage &message); void initStoresIfPossible(bool sdCardUsable); ReturnValue_t initialize() override; diff --git a/mission/tmtc/Service15TmStorage.cpp b/mission/tmtc/Service15TmStorage.cpp index ce753f66..9864b566 100644 --- a/mission/tmtc/Service15TmStorage.cpp +++ b/mission/tmtc/Service15TmStorage.cpp @@ -30,14 +30,10 @@ ReturnValue_t Service15TmStorage::getMessageQueueAndObject(uint8_t subservice, const uint8_t *tcData, size_t tcDataLen, MessageQueueId_t *id, object_id_t *objectId) { - object_id_t targetObjectId; - SerializeAdapter::deSerialize(&targetObjectId, &tcData, &tcDataLen, - SerializeIF::Endianness::NETWORK); - if (targetObjectId == objects::CFDP_TM_STORE) { - *objectId = objects::CFDP_TM_FUNNEL; - } else { - *objectId = objects::PUS_TM_FUNNEL; + if (tcDataLen < 4) { + return CommandingServiceBase::INVALID_TC; } + SerializeAdapter::deSerialize(objectId, &tcData, &tcDataLen, SerializeIF::Endianness::NETWORK); auto *frontendIF = ObjectManager::instance()->get(*objectId); if (frontendIF == nullptr) { return FAILED; diff --git a/mission/tmtc/TmFunnelBase.cpp b/mission/tmtc/TmFunnelBase.cpp index 2489186d..bbb5bcc3 100644 --- a/mission/tmtc/TmFunnelBase.cpp +++ b/mission/tmtc/TmFunnelBase.cpp @@ -7,7 +7,6 @@ TmFunnelBase::TmFunnelBase(FunnelCfg cfg) : SystemObject(cfg.objectId), tmStore(cfg.tmStore), ipcStore(cfg.ipcStore) { tmQueue = QueueFactory::instance()->createMessageQueue(cfg.tmMsgDepth); - tcQueue = QueueFactory::instance()->createMessageQueue(cfg.tcMsgDepth); } TmFunnelBase::~TmFunnelBase() { QueueFactory::instance()->deleteMessageQueue(tmQueue); } @@ -56,5 +55,3 @@ ReturnValue_t TmFunnelBase::sendPacketToDestinations(store_address_t origStoreId } return result; } - -MessageQueueId_t TmFunnelBase::getCommandQueue() const { return tcQueue->getId(); } diff --git a/mission/tmtc/TmFunnelBase.h b/mission/tmtc/TmFunnelBase.h index 97b627b4..af65771f 100644 --- a/mission/tmtc/TmFunnelBase.h +++ b/mission/tmtc/TmFunnelBase.h @@ -9,32 +9,25 @@ #include -class TmFunnelBase : public TmStoreFrontendSimpleIF, - public AcceptsTelemetryIF, - public SystemObject { +class TmFunnelBase : public AcceptsTelemetryIF, public SystemObject { public: struct FunnelCfg { FunnelCfg(object_id_t objId, StorageManagerIF& tmStore, StorageManagerIF& ipcStore, - uint32_t tmMsgDepth, uint32_t tcMsgDepth) - : objectId(objId), - tmStore(tmStore), - ipcStore(ipcStore), - tmMsgDepth(tmMsgDepth), - tcMsgDepth(tcMsgDepth) {} + uint32_t tmMsgDepth) + : objectId(objId), tmStore(tmStore), ipcStore(ipcStore), tmMsgDepth(tmMsgDepth) {} object_id_t objectId; StorageManagerIF& tmStore; StorageManagerIF& ipcStore; uint32_t tmMsgDepth; - uint32_t tcMsgDepth; }; - TmFunnelBase(FunnelCfg cfg); + explicit TmFunnelBase(FunnelCfg cfg); void addDestination(const char* name, const AcceptsTelemetryIF& downlinkDestination, uint8_t vcid = 0); ReturnValue_t sendPacketToDestinations(store_address_t origStoreId, TmTcMessage& message, const uint8_t* packetData, size_t size); [[nodiscard]] MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel) const override; - virtual ~TmFunnelBase(); + ~TmFunnelBase() override; protected: StorageManagerIF& tmStore; @@ -52,9 +45,6 @@ class TmFunnelBase : public TmStoreFrontendSimpleIF, std::vector destinations; MessageQueueIF* tmQueue = nullptr; - MessageQueueIF* tcQueue = nullptr; - - MessageQueueId_t getCommandQueue() const override; }; #endif /* MISSION_TMTC_TMFUNNELBASE_H_ */ diff --git a/mission/tmtc/VirtualChannel.cpp b/mission/tmtc/VirtualChannel.cpp index 64c7b006..6a24cc09 100644 --- a/mission/tmtc/VirtualChannel.cpp +++ b/mission/tmtc/VirtualChannel.cpp @@ -50,7 +50,7 @@ ReturnValue_t VirtualChannel::performOperation() { } count++; - if(count == 500) { + if (count == 500) { sif::error << "VirtualChannel: Possible message storm detected" << std::endl; break; } From a1cb4fb549a5b5f63147b6c802021cee94c42e42 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 21 Feb 2023 21:37:30 +0100 Subject: [PATCH 69/87] fix for host build --- dummies/PduDummy.cpp | 5 +++- dummies/PduDummy.h | 6 +++++ mission/tmtc/PersistentTmStore.cpp | 42 ++++++++++++++++-------------- mission/tmtc/PersistentTmStore.h | 8 +++--- mission/tmtc/PusTmFunnel.h | 8 +++--- 5 files changed, 40 insertions(+), 29 deletions(-) diff --git a/dummies/PduDummy.cpp b/dummies/PduDummy.cpp index 1c26728c..42147222 100644 --- a/dummies/PduDummy.cpp +++ b/dummies/PduDummy.cpp @@ -3,7 +3,8 @@ #include PduDummy::PduDummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie) - : DeviceHandlerBase(objectId, comif, comCookie) {} + : DeviceHandlerBase(objectId, comif, comCookie), + coreHk(this, static_cast(P60System::SetIds::CORE)) {} PduDummy::~PduDummy() {} @@ -38,5 +39,7 @@ uint32_t PduDummy::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return ReturnValue_t PduDummy::initializeLocalDataPool(localpool::DataPool &localDataPoolMap, LocalDataPoolManager &poolManager) { localDataPoolMap.emplace(PDU::pool::PDU_TEMPERATURE, new PoolEntry({0})); + localDataPoolMap.emplace(PDU::pool::PDU_VOLTAGES, &pduVoltages); + localDataPoolMap.emplace(PDU::pool::PDU_CURRENTS, &pduCurrents); return returnvalue::OK; } diff --git a/dummies/PduDummy.h b/dummies/PduDummy.h index 3e193e7c..751896cd 100644 --- a/dummies/PduDummy.h +++ b/dummies/PduDummy.h @@ -3,6 +3,8 @@ #include +#include "mission/devices/devicedefinitions/GomspaceDefinitions.h" + class PduDummy : public DeviceHandlerBase { public: static const DeviceCommandId_t SIMPLE_COMMAND = 1; @@ -15,6 +17,10 @@ class PduDummy : public DeviceHandlerBase { virtual ~PduDummy(); protected: + PDU::PduCoreHk coreHk; + PoolEntry pduVoltages = PoolEntry(9); + PoolEntry pduCurrents = PoolEntry(9); + void doStartUp() override; void doShutDown() override; ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t *id) override; diff --git a/mission/tmtc/PersistentTmStore.cpp b/mission/tmtc/PersistentTmStore.cpp index 156ae6f0..c6f59007 100644 --- a/mission/tmtc/PersistentTmStore.cpp +++ b/mission/tmtc/PersistentTmStore.cpp @@ -14,9 +14,10 @@ using namespace returnvalue; -TmStore::TmStore(object_id_t objectId, const char* baseDir, std::string baseName, - RolloverInterval intervalUnit, uint32_t intervalCount, timeval& currentTv, - StorageManagerIF& tmStore, SdCardMountedIF& sdcMan) +PersistentTmStore::PersistentTmStore(object_id_t objectId, const char* baseDir, + std::string baseName, RolloverInterval intervalUnit, + uint32_t intervalCount, timeval& currentTv, + StorageManagerIF& tmStore, SdCardMountedIF& sdcMan) : SystemObject(objectId), baseDir(baseDir), baseName(std::move(baseName)), @@ -27,7 +28,8 @@ TmStore::TmStore(object_id_t objectId, const char* baseDir, std::string baseName calcDiffSeconds(intervalUnit, intervalCount); } -ReturnValue_t TmStore::handleCommandQueue(StorageManagerIF& ipcStore, TmFunnelBase& tmFunnel) { +ReturnValue_t PersistentTmStore::handleCommandQueue(StorageManagerIF& ipcStore, + TmFunnelBase& tmFunnel) { CommandMessage cmdMessage; ReturnValue_t result = tcQueue->receiveMessage(&cmdMessage); if (result == MessageQueueIF::EMPTY) { @@ -63,7 +65,7 @@ ReturnValue_t TmStore::handleCommandQueue(StorageManagerIF& ipcStore, TmFunnelBa return returnvalue::OK; } -ReturnValue_t TmStore::passPacket(PusTmReader& reader) { +ReturnValue_t PersistentTmStore::passPacket(PusTmReader& reader) { bool inApidList = false; if (filter.apid) { auto& apidFilter = filter.apid.value(); @@ -98,11 +100,11 @@ ReturnValue_t TmStore::passPacket(PusTmReader& reader) { return returnvalue::OK; } -void TmStore::dumpFrom(uint32_t fromUnixSeconds, TmFunnelBase& tmFunnel) { +void PersistentTmStore::dumpFrom(uint32_t fromUnixSeconds, TmFunnelBase& tmFunnel) { return dumpFromUpTo(fromUnixSeconds, currentTv.tv_sec, tmFunnel); } -ReturnValue_t TmStore::storePacket(PusTmReader& reader) { +ReturnValue_t PersistentTmStore::storePacket(PusTmReader& reader) { using namespace std::filesystem; if (baseDirUninitialized) { updateBaseDir(); @@ -137,9 +139,9 @@ ReturnValue_t TmStore::storePacket(PusTmReader& reader) { return returnvalue::OK; } -MessageQueueId_t TmStore::getCommandQueue() const { return tcQueue->getId(); } +MessageQueueId_t PersistentTmStore::getCommandQueue() const { return tcQueue->getId(); } -void TmStore::calcDiffSeconds(RolloverInterval intervalUnit, uint32_t intervalCount) { +void PersistentTmStore::calcDiffSeconds(RolloverInterval intervalUnit, uint32_t intervalCount) { if (intervalUnit == RolloverInterval::MINUTELY) { rolloverDiffSeconds = 60 * intervalCount; } else if (intervalUnit == RolloverInterval::HOURLY) { @@ -149,7 +151,7 @@ void TmStore::calcDiffSeconds(RolloverInterval intervalUnit, uint32_t intervalCo } } -void TmStore::updateBaseDir() { +void PersistentTmStore::updateBaseDir() { using namespace std::filesystem; std::string currentPrefix = sdcMan.getCurrentMountPrefix(); basePath = path(currentPrefix) / baseDir / baseName; @@ -159,7 +161,7 @@ void TmStore::updateBaseDir() { baseDirUninitialized = false; } -void TmStore::assignAndOrCreateMostRecentFile() { +void PersistentTmStore::assignAndOrCreateMostRecentFile() { using namespace std::filesystem; for (auto const& file : directory_iterator(basePath)) { if (file.is_directory()) { @@ -204,7 +206,7 @@ void TmStore::assignAndOrCreateMostRecentFile() { } } -void TmStore::addApid(uint16_t apid) { +void PersistentTmStore::addApid(uint16_t apid) { if (not filter.apid) { filter.apid = std::vector({apid}); return; @@ -212,7 +214,7 @@ void TmStore::addApid(uint16_t apid) { filter.apid.value().push_back(apid); } -void TmStore::addService(uint8_t service) { +void PersistentTmStore::addService(uint8_t service) { if (not filter.services) { filter.services = std::vector({service}); return; @@ -220,7 +222,7 @@ void TmStore::addService(uint8_t service) { filter.services.value().push_back(service); } -void TmStore::addServiceSubservice(uint8_t service, uint8_t subservice) { +void PersistentTmStore::addServiceSubservice(uint8_t service, uint8_t subservice) { if (not filter.serviceSubservices) { filter.serviceSubservices = std::vector>({std::pair(service, subservice)}); @@ -229,7 +231,7 @@ void TmStore::addServiceSubservice(uint8_t service, uint8_t subservice) { filter.serviceSubservices.value().emplace_back(service, subservice); } -void TmStore::deleteUpTo(uint32_t unixSeconds) { +void PersistentTmStore::deleteUpTo(uint32_t unixSeconds) { using namespace std::filesystem; for (auto const& file : directory_iterator(basePath)) { if (file.is_directory() or @@ -250,8 +252,8 @@ void TmStore::deleteUpTo(uint32_t unixSeconds) { } } -void TmStore::dumpFromUpTo(uint32_t fromUnixSeconds, uint32_t upToUnixSeconds, - TmFunnelBase& funnel) { +void PersistentTmStore::dumpFromUpTo(uint32_t fromUnixSeconds, uint32_t upToUnixSeconds, + TmFunnelBase& funnel) { using namespace std::filesystem; for (auto const& file : directory_iterator(basePath)) { if (file.is_directory()) { @@ -277,7 +279,7 @@ void TmStore::dumpFromUpTo(uint32_t fromUnixSeconds, uint32_t upToUnixSeconds, } } -void TmStore::pathToTod(const std::filesystem::path& path, Clock::TimeOfDay_t& tod) { +void PersistentTmStore::pathToTod(const std::filesystem::path& path, Clock::TimeOfDay_t& tod) { auto pathStr = path.string(); size_t splitChar = pathStr.find('_'); auto timeOnlyStr = pathStr.substr(splitChar); @@ -286,8 +288,8 @@ void TmStore::pathToTod(const std::filesystem::path& path, Clock::TimeOfDay_t& t &tod.year, &tod.month, &tod.day, &tod.hour, &tod.minute, &tod.second); } -void TmStore::fileToPackets(const std::filesystem::path& path, uint32_t unixStamp, - TmFunnelBase& funnel) { +void PersistentTmStore::fileToPackets(const std::filesystem::path& path, uint32_t unixStamp, + TmFunnelBase& funnel) { store_address_t storeId; TmTcMessage message; size_t size = std::filesystem::file_size(path); diff --git a/mission/tmtc/PersistentTmStore.h b/mission/tmtc/PersistentTmStore.h index a1c88e1a..4285d146 100644 --- a/mission/tmtc/PersistentTmStore.h +++ b/mission/tmtc/PersistentTmStore.h @@ -21,7 +21,7 @@ struct PacketFilter { enum class RolloverInterval { MINUTELY, HOURLY, DAILY }; -class TmStore : public TmStoreFrontendSimpleIF, public SystemObject { +class PersistentTmStore : public TmStoreFrontendSimpleIF, public SystemObject { public: static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PERSISTENT_TM_STORE; @@ -30,9 +30,9 @@ class TmStore : public TmStoreFrontendSimpleIF, public SystemObject { //! P2: Timestamp of possibly corrupt file as a unix timestamp. static constexpr Event POSSIBLE_FILE_CORRUPTION = event::makeEvent(SUBSYSTEM_ID, 0, severity::LOW); - TmStore(object_id_t objectId, const char* baseDir, std::string baseName, - RolloverInterval intervalUnit, uint32_t intervalCount, timeval& currentTv, - StorageManagerIF& tmStore, SdCardMountedIF& sdcMan); + PersistentTmStore(object_id_t objectId, const char* baseDir, std::string baseName, + RolloverInterval intervalUnit, uint32_t intervalCount, timeval& currentTv, + StorageManagerIF& tmStore, SdCardMountedIF& sdcMan); ReturnValue_t handleCommandQueue(StorageManagerIF& ipcStore, TmFunnelBase& tmFunnel); diff --git a/mission/tmtc/PusTmFunnel.h b/mission/tmtc/PusTmFunnel.h index 95facfa3..ab6a9480 100644 --- a/mission/tmtc/PusTmFunnel.h +++ b/mission/tmtc/PusTmFunnel.h @@ -38,10 +38,10 @@ class PusTmFunnel : public TmFunnelBase { bool storesInitialized = false; timeval currentTv{}; timeval lastTvUpdate{}; - TmStore miscStore; - TmStore okStore; - TmStore notOkStore; - TmStore hkStore; + PersistentTmStore miscStore; + PersistentTmStore okStore; + PersistentTmStore notOkStore; + PersistentTmStore hkStore; SdCardMountedIF &sdcMan; ReturnValue_t handleTmPacket(TmTcMessage &message); From 1803b2c650761e76de10a3fbb79a17c22bcd5d33 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 22 Feb 2023 13:27:16 +0100 Subject: [PATCH 70/87] seems to work now --- mission/tmtc/PersistentTmStore.cpp | 192 +++++++++++++++------------- mission/tmtc/PersistentTmStore.h | 14 +- mission/tmtc/PusTmFunnel.cpp | 46 ++++--- mission/tmtc/Service15TmStorage.cpp | 10 +- tmtc | 2 +- 5 files changed, 150 insertions(+), 114 deletions(-) diff --git a/mission/tmtc/PersistentTmStore.cpp b/mission/tmtc/PersistentTmStore.cpp index c6f59007..91a8be48 100644 --- a/mission/tmtc/PersistentTmStore.cpp +++ b/mission/tmtc/PersistentTmStore.cpp @@ -28,6 +28,42 @@ PersistentTmStore::PersistentTmStore(object_id_t objectId, const char* baseDir, calcDiffSeconds(intervalUnit, intervalCount); } +ReturnValue_t PersistentTmStore::assignAndOrCreateMostRecentFile() { + using namespace std::filesystem; + for (auto const& file : directory_iterator(basePath)) { + if (file.is_directory()) { + continue; + } + auto pathStr = file.path().string(); + if (pathStr.find(baseName) == std::string::npos) { + continue; + } + unsigned int underscorePos = pathStr.find_last_of('_'); + std::string stampStr = pathStr.substr(underscorePos + 1); + struct tm time {}; + if (nullptr == strptime(stampStr.c_str(), FILE_DATE_FORMAT, &time)) { + sif::error << "PersistentTmStore::assignOrCreateMostRecentFile: Error reading timestamp" + << std::endl; + // Delete the file and re-create it. + activeFile = std::nullopt; + std::filesystem::remove(file.path()); + break; + } + time_t fileEpoch = timegm(&time); + // There is still a file within the active time window, so re-use that file for new TMs to + // store. + if (fileEpoch + rolloverDiffSeconds > currentTv.tv_sec) { + activeFileTv.tv_sec = fileEpoch; + activeFile = file.path(); + break; + } + } + if (not activeFile.has_value()) { + return createMostRecentFile(); + } + return returnvalue::OK; +} + ReturnValue_t PersistentTmStore::handleCommandQueue(StorageManagerIF& ipcStore, TmFunnelBase& tmFunnel) { CommandMessage cmdMessage; @@ -51,14 +87,16 @@ ReturnValue_t PersistentTmStore::handleCommandQueue(StorageManagerIF& ipcStore, } else if (cmd == TmStoreMessage::DOWNLINK_STORE_CONTENT_TIME) { store_address_t storeId = TmStoreMessage::getStoreId(&cmdMessage); auto accessor = ipcStore.getData(storeId); + if (accessor.second.size() < 8) { + return returnvalue::FAILED; + } uint32_t dumpFromUnixSeconds; uint32_t dumpUntilUnixSeconds; - size_t size = accessor.second.size(); + size_t size = 8; SerializeAdapter::deSerialize(&dumpFromUnixSeconds, accessor.second.data(), &size, SerializeIF::Endianness::NETWORK); - SerializeAdapter::deSerialize(&dumpUntilUnixSeconds, accessor.second.data(), &size, + SerializeAdapter::deSerialize(&dumpUntilUnixSeconds, accessor.second.data() + 4, &size, SerializeIF::Endianness::NETWORK); - // TODO: TM store missing, and maybe there is a better way to do this? dumpFromUpTo(dumpFromUnixSeconds, dumpUntilUnixSeconds, tmFunnel); } } @@ -110,30 +148,32 @@ ReturnValue_t PersistentTmStore::storePacket(PusTmReader& reader) { updateBaseDir(); } // It is assumed here that the filesystem is usable. - if (not mostRecentFile) { - assignAndOrCreateMostRecentFile(); + if (not activeFile.has_value()) { + ReturnValue_t result = assignAndOrCreateMostRecentFile(); + if (result != returnvalue::OK) { + return result; + } } - if (currentTv.tv_sec < mostRecentTv.value().tv_sec or - currentTv.tv_sec - mostRecentTv.value().tv_sec > static_cast(rolloverDiffSeconds)) { - if (file_size(mostRecentFile.value()) + reader.getFullPacketLen() > fileBuf.size()) { + if (currentTv.tv_sec < activeFileTv.tv_sec or + currentTv.tv_sec - activeFileTv.tv_sec > static_cast(rolloverDiffSeconds)) { + if (file_size(activeFile.value()) + reader.getFullPacketLen() > fileBuf.size()) { uint8_t appendedCounter = 1; path rolloverName; while (true) { - rolloverName = - path(mostRecentFile.value().string() + "." + std::to_string(appendedCounter)); + rolloverName = path(activeFile.value().string() + "." + std::to_string(appendedCounter)); if (not exists(rolloverName)) { break; } appendedCounter++; } - rename(mostRecentFile.value(), rolloverName); - std::ofstream of(mostRecentFile.value(), std::ios::binary); + rename(activeFile.value(), rolloverName); + std::ofstream of(activeFile.value(), std::ios::binary); } } // Rollover conditions were handled, write to file now - std::ofstream of(mostRecentFile.value(), std::ios::app | std::ios::binary); + std::ofstream of(activeFile.value(), std::ios::app | std::ios::binary); of.write(reinterpret_cast(reader.getFullData()), static_cast(reader.getFullPacketLen())); return returnvalue::OK; @@ -161,51 +201,6 @@ void PersistentTmStore::updateBaseDir() { baseDirUninitialized = false; } -void PersistentTmStore::assignAndOrCreateMostRecentFile() { - using namespace std::filesystem; - for (auto const& file : directory_iterator(basePath)) { - if (file.is_directory()) { - continue; - } - auto pathStr = file.path().string(); - Clock::TimeOfDay_t tod; - if (pathStr.find(baseName) == std::string::npos) { - continue; - } - unsigned int underscorePos = pathStr.find_last_of('_'); - std::string stampStr = pathStr.substr(underscorePos + 1); - int count = sscanf(stampStr.c_str(), - "%04" SCNu32 "-%02" SCNu32 "-%02" SCNu32 "T%02" SCNu32 "-%02" SCNu32 - "-%02" SCNu32 "Z", - &tod.year, &tod.month, &tod.day, &tod.hour, &tod.minute, &tod.second); - if (count != 6) { - continue; - } - timeval tv{}; - Clock::convertTimeOfDayToTimeval(&tod, &tv); - if (not mostRecentTv || tv > mostRecentTv.value()) { - mostRecentTv = tv; - mostRecentFile = file.path(); - } - } - if (not mostRecentFile) { - unsigned currentIdx = 0; - path pathStart = basePath / baseName; - memcpy(fileBuf.data() + currentIdx, pathStart.c_str(), pathStart.string().length()); - currentIdx += pathStart.string().length(); - Clock::TimeOfDay_t tod; - Clock::convertTimevalToTimeOfDay(¤tTv, &tod); - currentIdx += sprintf(reinterpret_cast(fileBuf.data() + currentIdx), - "_%04" PRIu32 "-%02" PRIu32 "-%02" PRIu32 "T%02" PRIu32 "-%02" PRIu32 - "-%02" PRIu32 "Z.bin", - tod.year, tod.month, tod.day, tod.hour, tod.minute, tod.second); - path newPath(std::string(reinterpret_cast(fileBuf.data()), currentIdx)); - std::ofstream of(newPath, std::ios::binary); - mostRecentFile = newPath; - mostRecentTv = currentTv; - } -} - void PersistentTmStore::addApid(uint16_t apid) { if (not filter.apid) { filter.apid = std::vector({apid}); @@ -234,19 +229,17 @@ void PersistentTmStore::addServiceSubservice(uint8_t service, uint8_t subservice void PersistentTmStore::deleteUpTo(uint32_t unixSeconds) { using namespace std::filesystem; for (auto const& file : directory_iterator(basePath)) { - if (file.is_directory() or - (mostRecentFile.has_value() and (mostRecentFile.value() == file.path()))) { + if (file.is_directory() or (activeFile.has_value() and (activeFile.value() == file.path()))) { continue; } - Clock::TimeOfDay_t tod; - pathToTod(file.path(), tod); - timeval time{}; - ReturnValue_t result = Clock::convertTimeOfDayToTimeval(&tod, &time); - if (result != returnvalue::OK) { - sif::error << "TOD to time conversion failed for file " << file << std::endl; + // Convert file time to the UNIX epoch + struct tm fileTime {}; + if (pathToTm(file.path(), fileTime) != returnvalue::OK) { + sif::error << "Time extraction for " << file << "failed" << std::endl; continue; } - if (time.tv_sec + rolloverDiffSeconds < unixSeconds) { + time_t epoch = timegm(&fileTime); + if (epoch + rolloverDiffSeconds < unixSeconds) { std::filesystem::remove(file.path()); } } @@ -259,33 +252,26 @@ void PersistentTmStore::dumpFromUpTo(uint32_t fromUnixSeconds, uint32_t upToUnix if (file.is_directory()) { continue; } - if (mostRecentFile.has_value() and mostRecentTv.has_value() and - (file.path() == mostRecentFile.value()) and - (upToUnixSeconds < static_cast(mostRecentTv.value().tv_sec))) { + struct tm fileTime {}; + if (pathToTm(file.path(), fileTime) != returnvalue::OK) { + sif::error << "Time extraction for file " << file << "failed" << std::endl; continue; } - Clock::TimeOfDay_t tod; - pathToTod(file.path(), tod); - timeval time{}; - ReturnValue_t result = Clock::convertTimeOfDayToTimeval(&tod, &time); - if (result != returnvalue::OK) { - sif::error << "TOD to time conversion failed for file " << file << std::endl; - continue; - } - auto timeUnsigned = static_cast(time.tv_sec); - if (timeUnsigned > fromUnixSeconds && timeUnsigned + rolloverDiffSeconds < upToUnixSeconds) { - fileToPackets(file, timeUnsigned, funnel); + auto fileEpoch = static_cast(timegm(&fileTime)); + if ((fileEpoch > fromUnixSeconds) and (fileEpoch + rolloverDiffSeconds <= upToUnixSeconds)) { + fileToPackets(file, fileEpoch, funnel); } } } -void PersistentTmStore::pathToTod(const std::filesystem::path& path, Clock::TimeOfDay_t& tod) { +ReturnValue_t PersistentTmStore::pathToTm(const std::filesystem::path& path, struct tm& time) { auto pathStr = path.string(); size_t splitChar = pathStr.find('_'); - auto timeOnlyStr = pathStr.substr(splitChar); - sscanf(timeOnlyStr.data(), - "%04" SCNu32 "-%02" SCNu32 "-%02" SCNu32 "T%02" SCNu32 "-%02" SCNu32 "-%02" SCNu32 "Z", - &tod.year, &tod.month, &tod.day, &tod.hour, &tod.minute, &tod.second); + auto timeOnlyStr = pathStr.substr(splitChar + 1); + if (nullptr == strptime(timeOnlyStr.c_str(), FILE_DATE_FORMAT, &time)) { + return returnvalue::FAILED; + } + return returnvalue::OK; } void PersistentTmStore::fileToPackets(const std::filesystem::path& path, uint32_t unixStamp, @@ -320,3 +306,37 @@ void PersistentTmStore::fileToPackets(const std::filesystem::path& path, uint32_ } } } + +ReturnValue_t PersistentTmStore::createMostRecentFile() { + using namespace std::filesystem; + unsigned currentIdx = 0; + path pathStart = basePath / baseName; + memcpy(fileBuf.data() + currentIdx, pathStart.c_str(), pathStart.string().length()); + currentIdx += pathStart.string().length(); + fileBuf[currentIdx] = '_'; + currentIdx += 1; + time_t epoch = currentTv.tv_sec; + struct tm* time = gmtime(&epoch); + size_t writtenBytes = strftime(reinterpret_cast(fileBuf.data() + currentIdx), + fileBuf.size(), FILE_DATE_FORMAT, time); + if (writtenBytes == 0) { + sif::error << "PersistentTmStore::createMostRecentFile: Could not create file timestamp" + << std::endl; + return returnvalue::FAILED; + } + currentIdx += writtenBytes; + strncpy(reinterpret_cast(fileBuf.data() + currentIdx), ".bin", + fileBuf.size() - currentIdx); + currentIdx += 4; + + path newPath(std::string(reinterpret_cast(fileBuf.data()), currentIdx)); + std::ofstream of(newPath, std::ios::binary); + activeFile = newPath; + activeFileTv = currentTv; + return returnvalue::OK; +} + +ReturnValue_t PersistentTmStore::initializeTmStore() { + updateBaseDir(); + return assignAndOrCreateMostRecentFile(); +} diff --git a/mission/tmtc/PersistentTmStore.h b/mission/tmtc/PersistentTmStore.h index 4285d146..bcd83a71 100644 --- a/mission/tmtc/PersistentTmStore.h +++ b/mission/tmtc/PersistentTmStore.h @@ -34,6 +34,7 @@ class PersistentTmStore : public TmStoreFrontendSimpleIF, public SystemObject { RolloverInterval intervalUnit, uint32_t intervalCount, timeval& currentTv, StorageManagerIF& tmStore, SdCardMountedIF& sdcMan); + ReturnValue_t initializeTmStore(); ReturnValue_t handleCommandQueue(StorageManagerIF& ipcStore, TmFunnelBase& tmFunnel); void addApid(uint16_t apid); @@ -44,11 +45,12 @@ class PersistentTmStore : public TmStoreFrontendSimpleIF, public SystemObject { void dumpFrom(uint32_t fromUnixSeconds, TmFunnelBase& tmFunnel); void dumpFromUpTo(uint32_t fromUnixSeconds, uint32_t upToUnixSeconds, TmFunnelBase& tmFunnel); - void updateBaseDir(); ReturnValue_t passPacket(PusTmReader& reader); private: static constexpr size_t MAX_FILESIZE = 8192; + // ISO8601 timestamp. + static constexpr char FILE_DATE_FORMAT[] = "%FT%H%M%SZ"; MessageQueueIF* tcQueue; PacketFilter filter; @@ -60,8 +62,8 @@ class PersistentTmStore : public TmStoreFrontendSimpleIF, public SystemObject { uint32_t rolloverDiffSeconds = 0; std::array fileBuf{}; timeval& currentTv; - std::optional mostRecentTv; - std::optional mostRecentFile; + timeval activeFileTv{}; + std::optional activeFile; SdCardMountedIF& sdcMan; StorageManagerIF& tmStore; @@ -72,9 +74,11 @@ class PersistentTmStore : public TmStoreFrontendSimpleIF, public SystemObject { [[nodiscard]] MessageQueueId_t getCommandQueue() const override; void calcDiffSeconds(RolloverInterval intervalUnit, uint32_t intervalCount); - void assignAndOrCreateMostRecentFile(); - static void pathToTod(const std::filesystem::path& path, Clock::TimeOfDay_t& tod); + ReturnValue_t createMostRecentFile(); + static ReturnValue_t pathToTm(const std::filesystem::path& path, struct tm& time); void fileToPackets(const std::filesystem::path& path, uint32_t unixStamp, TmFunnelBase& funnel); + void updateBaseDir(); + ReturnValue_t assignAndOrCreateMostRecentFile(); ReturnValue_t storePacket(PusTmReader& reader); }; diff --git a/mission/tmtc/PusTmFunnel.cpp b/mission/tmtc/PusTmFunnel.cpp index 2b61e19a..db645042 100644 --- a/mission/tmtc/PusTmFunnel.cpp +++ b/mission/tmtc/PusTmFunnel.cpp @@ -29,9 +29,9 @@ PusTmFunnel::PusTmFunnel(TmFunnelBase::FunnelCfg cfg, TimeReaderIF &timeReader, miscStore.addService(17); miscStore.addService(2); miscStore.addService(200); + miscStore.addService(201); okStore.addApid(config::EIVE_PUS_APID); okStore.addServiceSubservice(5, 1); - okStore.addApid(config::EIVE_PUS_APID); okStore.addService(8); okStore.addServiceSubservice(1, 1); okStore.addServiceSubservice(1, 3); @@ -51,21 +51,27 @@ PusTmFunnel::~PusTmFunnel() = default; ReturnValue_t PusTmFunnel::performOperation(uint8_t) { CommandMessage cmdMessage; - ReturnValue_t result = okStore.handleCommandQueue(ipcStore, *this); - if (result != returnvalue::OK) { - sif::error << "PusTmFunnel::performOperation: Issue handling OK store command" << std::endl; - } - result = notOkStore.handleCommandQueue(ipcStore, *this); - if (result != returnvalue::OK) { - sif::error << "PusTmFunnel::performOperation: Issue handling NOT OK store command" << std::endl; - } - result = hkStore.handleCommandQueue(ipcStore, *this); - if (result != returnvalue::OK) { - sif::error << "PusTmFunnel::performOperation: Issue handling HK store command" << std::endl; - } - result = miscStore.handleCommandQueue(ipcStore, *this); - if (result != returnvalue::OK) { - sif::error << "PusTmFunnel::performOperation: Issue handling MISC store command" << std::endl; + ReturnValue_t result; + try { + result = okStore.handleCommandQueue(ipcStore, *this); + if (result != returnvalue::OK) { + sif::error << "PusTmFunnel::performOperation: Issue handling OK store command" << std::endl; + } + result = notOkStore.handleCommandQueue(ipcStore, *this); + if (result != returnvalue::OK) { + sif::error << "PusTmFunnel::performOperation: Issue handling NOT OK store command" + << std::endl; + } + result = hkStore.handleCommandQueue(ipcStore, *this); + if (result != returnvalue::OK) { + sif::error << "PusTmFunnel::performOperation: Issue handling HK store command" << std::endl; + } + result = miscStore.handleCommandQueue(ipcStore, *this); + if (result != returnvalue::OK) { + sif::error << "PusTmFunnel::performOperation: Issue handling MISC store command" << std::endl; + } + } catch (const std::bad_optional_access &e) { + sif::error << e.what() << "when handling TM store command" << std::endl; } TmTcMessage currentMessage; @@ -134,10 +140,10 @@ const char *PusTmFunnel::getName() const { return "PUS TM Funnel"; } void PusTmFunnel::initStoresIfPossible(bool sdCardUsable) { if (not storesInitialized and sdCardUsable) { - miscStore.updateBaseDir(); - okStore.updateBaseDir(); - hkStore.updateBaseDir(); - notOkStore.updateBaseDir(); + miscStore.initializeTmStore(); + okStore.initializeTmStore(); + hkStore.initializeTmStore(); + notOkStore.initializeTmStore(); storesInitialized = true; } } diff --git a/mission/tmtc/Service15TmStorage.cpp b/mission/tmtc/Service15TmStorage.cpp index 9864b566..d61d587d 100644 --- a/mission/tmtc/Service15TmStorage.cpp +++ b/mission/tmtc/Service15TmStorage.cpp @@ -46,27 +46,33 @@ ReturnValue_t Service15TmStorage::prepareCommand(CommandMessage *message, uint8_ const uint8_t *tcData, size_t tcDataLen, uint32_t *state, object_id_t objectId) { if (subservice == Subservices::START_BY_TIME_RANGE_RETRIEVAL) { + // TODO: Hardcoded to UNIX timestamps.. Should allow arbitrary timestamp and let receiver + // to time reading and reply handling if (tcDataLen != 12) { return INVALID_TC; } store_address_t storeId; - ReturnValue_t result = ipcStore->addData(&storeId, tcData, tcDataLen); + ReturnValue_t result = ipcStore->addData(&storeId, tcData + 4, tcDataLen - 4); if (result != OK) { return result; } // Store timestamps TmStoreMessage::setDownlinkContentTimeMessage(message, storeId); + return CommandingServiceBase::EXECUTION_COMPLETE; } else if (subservice == Subservices::DELETE_UP_TO) { + // TODO: Hardcoded to UNIX timestamps.. Should allow arbitrary timestamp and let receiver + // to time reading and reply handling if (tcDataLen != 8) { return INVALID_TC; } store_address_t storeId; - ReturnValue_t result = ipcStore->addData(&storeId, tcData, tcDataLen); + ReturnValue_t result = ipcStore->addData(&storeId, tcData + 4, tcDataLen - 4); if (result != OK) { return result; } // Store timestamps TmStoreMessage::setDeleteContentTimeMessage(message, storeId); + return CommandingServiceBase::EXECUTION_COMPLETE; } return OK; } diff --git a/tmtc b/tmtc index 4917ddbb..fb676dc9 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 4917ddbbe4abd03ca7c7bb4ca5c80970e9b3b6bf +Subproject commit fb676dc90fe77585959297c36c828a7e852637c8 From 6c16238cc7cf2a266f207b0198e6ce9517f5e670 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 22 Feb 2023 14:21:24 +0100 Subject: [PATCH 71/87] small tweaks --- mission/tmtc/PersistentTmStore.cpp | 4 +-- mission/tmtc/PusTmFunnel.cpp | 40 ++++++++++++++++-------------- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/mission/tmtc/PersistentTmStore.cpp b/mission/tmtc/PersistentTmStore.cpp index 91a8be48..100767b9 100644 --- a/mission/tmtc/PersistentTmStore.cpp +++ b/mission/tmtc/PersistentTmStore.cpp @@ -238,8 +238,8 @@ void PersistentTmStore::deleteUpTo(uint32_t unixSeconds) { sif::error << "Time extraction for " << file << "failed" << std::endl; continue; } - time_t epoch = timegm(&fileTime); - if (epoch + rolloverDiffSeconds < unixSeconds) { + time_t fileEpoch = timegm(&fileTime); + if (fileEpoch + rolloverDiffSeconds < unixSeconds) { std::filesystem::remove(file.path()); } } diff --git a/mission/tmtc/PusTmFunnel.cpp b/mission/tmtc/PusTmFunnel.cpp index db645042..b135b776 100644 --- a/mission/tmtc/PusTmFunnel.cpp +++ b/mission/tmtc/PusTmFunnel.cpp @@ -1,11 +1,13 @@ #include "PusTmFunnel.h" #include "eive/definitions.h" +#include "fsfw/pus/Service5EventReporting.h" #include "eive/objects.h" #include "fsfw/ipc/CommandMessage.h" #include "fsfw/ipc/QueueFactory.h" #include "fsfw/objectmanager.h" #include "fsfw/tmstorage/TmStoreMessage.h" +#include "tmtc/pusIds.h" #include "fsfw/tmtcpacket/pus/tm/PusTmZcWriter.h" PusTmFunnel::PusTmFunnel(TmFunnelBase::FunnelCfg cfg, TimeReaderIF &timeReader, @@ -24,27 +26,29 @@ PusTmFunnel::PusTmFunnel(TmFunnelBase::FunnelCfg cfg, TimeReaderIF &timeReader, Clock::getClock_timeval(¤tTv); Clock::getUptime(&lastTvUpdate); hkStore.addApid(config::EIVE_PUS_APID); - hkStore.addService(3); + hkStore.addService(pus::PUS_SERVICE_3); miscStore.addApid(config::EIVE_PUS_APID); - miscStore.addService(17); - miscStore.addService(2); - miscStore.addService(200); - miscStore.addService(201); + miscStore.addService(pus::PUS_SERVICE_17); + miscStore.addService(pus::PUS_SERVICE_2); + miscStore.addService(pus::PUS_SERVICE_200); + miscStore.addService(pus::PUS_SERVICE_201); + miscStore.addService(pus::PUS_SERVICE_9); + miscStore.addService(pus::PUS_SERVICE_20); okStore.addApid(config::EIVE_PUS_APID); - okStore.addServiceSubservice(5, 1); - okStore.addService(8); - okStore.addServiceSubservice(1, 1); - okStore.addServiceSubservice(1, 3); - okStore.addServiceSubservice(1, 5); - okStore.addServiceSubservice(1, 7); + okStore.addServiceSubservice(pus::PUS_SERVICE_5, Service5EventReporting::Subservice::NORMAL_REPORT); + okStore.addService(pus::PUS_SERVICE_8); + okStore.addServiceSubservice(pus::PUS_SERVICE_1, 1); + okStore.addServiceSubservice(pus::PUS_SERVICE_1, 3); + okStore.addServiceSubservice(pus::PUS_SERVICE_1, 5); + okStore.addServiceSubservice(pus::PUS_SERVICE_1, 7); notOkStore.addApid(config::EIVE_PUS_APID); - notOkStore.addServiceSubservice(5, 2); - notOkStore.addServiceSubservice(5, 3); - notOkStore.addServiceSubservice(5, 4); - notOkStore.addServiceSubservice(1, 2); - notOkStore.addServiceSubservice(1, 4); - notOkStore.addServiceSubservice(1, 6); - notOkStore.addServiceSubservice(1, 8); + notOkStore.addServiceSubservice(pus::PUS_SERVICE_5, 2); + notOkStore.addServiceSubservice(pus::PUS_SERVICE_5, 3); + notOkStore.addServiceSubservice(pus::PUS_SERVICE_5, 4); + notOkStore.addServiceSubservice(pus::PUS_SERVICE_1, 2); + notOkStore.addServiceSubservice(pus::PUS_SERVICE_1, 4); + notOkStore.addServiceSubservice(pus::PUS_SERVICE_1, 6); + notOkStore.addServiceSubservice(pus::PUS_SERVICE_1, 8); } PusTmFunnel::~PusTmFunnel() = default; From 2ee70d53d943bfbdd061f93b7e4309a2939fa8a0 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 22 Feb 2023 14:27:50 +0100 Subject: [PATCH 72/87] more tweaks --- mission/core/GenericFactory.cpp | 8 ++++---- mission/tmtc/PusTmFunnel.cpp | 7 ++++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/mission/core/GenericFactory.cpp b/mission/core/GenericFactory.cpp index 306e4527..9e929e83 100644 --- a/mission/core/GenericFactory.cpp +++ b/mission/core/GenericFactory.cpp @@ -237,7 +237,7 @@ void ObjectFactory::createRwAssy(PowerSwitchIF& pwrSwitcher, power::Switch_t the std::array rwIds) { RwHelper rwHelper(rwIds); auto* rwAss = new RwAssembly(objects::RW_ASS, &pwrSwitcher, theSwitch, rwHelper); - for (uint8_t idx = 0; idx < rwIds.size(); idx++) { + for (size_t idx = 0; idx < rwIds.size(); idx++) { ReturnValue_t result = rws[idx]->connectModeTreeParent(*rwAss); if (result != returnvalue::OK) { sif::error << "Connecting RW " << static_cast(idx) << " to RW assembly failed" @@ -256,7 +256,7 @@ void ObjectFactory::createSusAssy(PowerSwitchIF& pwrSwitcher, objects::SUS_6_R_LOC_XFYBZM_PT_XF, objects::SUS_7_R_LOC_XBYBZM_PT_XB, objects::SUS_8_R_LOC_XBYBZB_PT_YB, objects::SUS_9_R_LOC_XBYBZB_PT_YF, objects::SUS_10_N_LOC_XMYBZF_PT_ZF, objects::SUS_11_R_LOC_XBYMZB_PT_ZB}; - SusAssHelper susAssHelper = SusAssHelper(susIds); + auto susAssHelper = SusAssHelper(susIds); auto susAss = new SusAssembly(objects::SUS_BOARD_ASS, &pwrSwitcher, susAssHelper); for (auto& sus : suses) { if (sus != nullptr) { @@ -292,8 +292,8 @@ void ObjectFactory::createAcsBoardAssy(PowerSwitchIF& pwrSwitcher, TcsBoardAssembly* ObjectFactory::createTcsBoardAssy(PowerSwitchIF& pwrSwitcher) { TcsBoardHelper helper(RTD_INFOS); - TcsBoardAssembly* tcsBoardAss = new TcsBoardAssembly( - objects::TCS_BOARD_ASS, &pwrSwitcher, pcdu::Switches::PDU1_CH0_TCS_BOARD_3V3, helper); + auto* tcsBoardAss = new TcsBoardAssembly(objects::TCS_BOARD_ASS, &pwrSwitcher, + pcdu::Switches::PDU1_CH0_TCS_BOARD_3V3, helper); tcsBoardAss->connectModeTreeParent(satsystem::tcs::SUBSYSTEM); return tcsBoardAss; } diff --git a/mission/tmtc/PusTmFunnel.cpp b/mission/tmtc/PusTmFunnel.cpp index b135b776..a0f345cb 100644 --- a/mission/tmtc/PusTmFunnel.cpp +++ b/mission/tmtc/PusTmFunnel.cpp @@ -1,14 +1,14 @@ #include "PusTmFunnel.h" #include "eive/definitions.h" -#include "fsfw/pus/Service5EventReporting.h" #include "eive/objects.h" #include "fsfw/ipc/CommandMessage.h" #include "fsfw/ipc/QueueFactory.h" #include "fsfw/objectmanager.h" +#include "fsfw/pus/Service5EventReporting.h" #include "fsfw/tmstorage/TmStoreMessage.h" -#include "tmtc/pusIds.h" #include "fsfw/tmtcpacket/pus/tm/PusTmZcWriter.h" +#include "tmtc/pusIds.h" PusTmFunnel::PusTmFunnel(TmFunnelBase::FunnelCfg cfg, TimeReaderIF &timeReader, SdCardMountedIF &sdcMan) @@ -35,7 +35,8 @@ PusTmFunnel::PusTmFunnel(TmFunnelBase::FunnelCfg cfg, TimeReaderIF &timeReader, miscStore.addService(pus::PUS_SERVICE_9); miscStore.addService(pus::PUS_SERVICE_20); okStore.addApid(config::EIVE_PUS_APID); - okStore.addServiceSubservice(pus::PUS_SERVICE_5, Service5EventReporting::Subservice::NORMAL_REPORT); + okStore.addServiceSubservice(pus::PUS_SERVICE_5, + Service5EventReporting::Subservice::NORMAL_REPORT); okStore.addService(pus::PUS_SERVICE_8); okStore.addServiceSubservice(pus::PUS_SERVICE_1, 1); okStore.addServiceSubservice(pus::PUS_SERVICE_1, 3); From 8b45786e5dd1f94c53bb9fd8595fb499e2dfa928 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 22 Feb 2023 14:49:54 +0100 Subject: [PATCH 73/87] changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f01acdc..69041a24 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,12 @@ change warranting a new major release: # [unreleased] +## Added + +- Added basic persistent TM store for PUS telemetry and basic interface to dump and delete + telemetry. + PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/320/files + # [v1.29.1] ## Fixed From 5f6f806b888565971853de3e3fa85724a2a155ce Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 22 Feb 2023 15:17:08 +0100 Subject: [PATCH 74/87] update release checklist --- release_checklist.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/release_checklist.md b/release_checklist.md index b4f08165..2e0247c7 100644 --- a/release_checklist.md +++ b/release_checklist.md @@ -4,8 +4,10 @@ OBSW Release Checklist # Pre-Release 1. Update version in `CMakeLists.txt` -2. Verify that the Q7S, Q7S EM and Host build are working -3. Wait for CI/CD results +2. Re-run the auto-formatters with the `scripts/auto-formatter.sh` script +3. Re-run the generators with `generators/gen.py all` +4. Verify that the Q7S, Q7S EM and Host build are working +5. Wait for CI/CD results # Post-Release From ee811371c5ffb9c4cf62a02fd9f64c8e058d070d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 22 Feb 2023 15:28:24 +0100 Subject: [PATCH 75/87] make EM build work --- bsp_q7s/em/emObjectFactory.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bsp_q7s/em/emObjectFactory.cpp b/bsp_q7s/em/emObjectFactory.cpp index 1ab86196..8eb1bc5f 100644 --- a/bsp_q7s/em/emObjectFactory.cpp +++ b/bsp_q7s/em/emObjectFactory.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "OBSWConfig.h" #include "bsp_q7s/core/CoreController.h" @@ -22,7 +23,7 @@ void ObjectFactory::produce(void* args) { HealthTableIF* healthTable = nullptr; PusTmFunnel* pusFunnel = nullptr; CfdpTmFunnel* cfdpFunnel = nullptr; - ObjectFactory::produceGenericObjects(&healthTable, &pusFunnel, &cfdpFunnel); + ObjectFactory::produceGenericObjects(&healthTable, &pusFunnel, &cfdpFunnel, *SdCardManager::instance()); LinuxLibgpioIF* gpioComIF = nullptr; SerialComIF* uartComIF = nullptr; From 9633359db369a2da387144fc30bc9fcc14f9c8d9 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 22 Feb 2023 15:46:03 +0100 Subject: [PATCH 76/87] spi RTD Polling dummy --- dummies/RtdPollingDummy.cpp | 3 +++ dummies/RtdPollingDummy.h | 11 +++++++++++ dummies/helpers.cpp | 2 ++ fsfw | 2 +- 4 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 dummies/RtdPollingDummy.cpp create mode 100644 dummies/RtdPollingDummy.h diff --git a/dummies/RtdPollingDummy.cpp b/dummies/RtdPollingDummy.cpp new file mode 100644 index 00000000..f1cd1155 --- /dev/null +++ b/dummies/RtdPollingDummy.cpp @@ -0,0 +1,3 @@ +#include "RtdPollingDummy.h" + +RtdPollingDummy::RtdPollingDummy(object_id_t objectId): SystemObject(objectId) {} diff --git a/dummies/RtdPollingDummy.h b/dummies/RtdPollingDummy.h new file mode 100644 index 00000000..0228123b --- /dev/null +++ b/dummies/RtdPollingDummy.h @@ -0,0 +1,11 @@ +#ifndef DUMMIES_RTDPOLLINGDUMMY_H_ +#define DUMMIES_RTDPOLLINGDUMMY_H_ + +#include + +class RtdPollingDummy: public SystemObject { +public: + RtdPollingDummy(object_id_t objectId); +}; + +#endif /* DUMMIES_RTDPOLLINGDUMMY_H_ */ diff --git a/dummies/helpers.cpp b/dummies/helpers.cpp index a5b84451..e6faab32 100644 --- a/dummies/helpers.cpp +++ b/dummies/helpers.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -192,6 +193,7 @@ void dummy::createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitcher, GpioIF* gpio objects::TMP1075_HANDLER_IF_BOARD, new Tmp1075Dummy(objects::TMP1075_HANDLER_IF_BOARD, objects::DUMMY_COM_IF, comCookieDummy)); + new RtdPollingDummy(objects::SPI_RTD_COM_IF); new TemperatureSensorInserter(objects::THERMAL_TEMP_INSERTER, rtdSensorDummies, tmpSensorDummies); TcsBoardAssembly* tcsBoardAssy = ObjectFactory::createTcsBoardAssy(pwrSwitcher); diff --git a/fsfw b/fsfw index 206af00c..d373c45d 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 206af00c8bc7edbae6ac8c12fd8c17f38b55d911 +Subproject commit d373c45d36ef1c817e1a849afd91dbd81bdb5e32 From 90c1d45f20ddd6182f17e1d33aac3d05661b2117 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 22 Feb 2023 18:06:34 +0100 Subject: [PATCH 77/87] correction for prefix handling on Q7S --- CHANGELOG.md | 4 ++++ bsp_q7s/core/CoreController.cpp | 3 +++ bsp_q7s/em/emObjectFactory.cpp | 3 ++- bsp_q7s/fs/SdCardManager.cpp | 7 ++++-- bsp_q7s/fs/SdCardManager.h | 4 ++-- bsp_q7s/fs/helpers.cpp | 3 +++ dummies/CMakeLists.txt | 1 + dummies/RtdPollingDummy.cpp | 4 +++- dummies/RtdPollingDummy.h | 6 +++-- dummies/helpers.cpp | 3 +-- linux/devices/ploc/PlocSupervisorHandler.cpp | 11 +++++---- mission/devices/PayloadPcduHandler.cpp | 3 +++ mission/devices/ScexDeviceHandler.cpp | 24 +++++++++++++------- mission/memory/SdCardMountedIF.h | 2 +- mission/tmtc/PersistentTmStore.cpp | 10 +++++--- mission/tmtc/PersistentTmStore.h | 2 +- mission/tmtc/PusTmFunnel.cpp | 2 +- mission/utility/DummySdCardManager.cpp | 2 +- mission/utility/DummySdCardManager.h | 2 +- 19 files changed, 66 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f89175d2..bfce5b76 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,10 @@ will consitute of a breaking change warranting a new major release: telemetry. PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/320/files +## Changed + +- Changed format of `getCurrentMountPrefix` to return a `const char*`. + # [v1.30.0] eive-tmtc: v2.14.0 diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index d3264b73..2c74b063 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -159,6 +159,9 @@ ReturnValue_t CoreController::initializeAfterTaskCreation() { } sdcMan->setActiveSdCard(sdInfo.active); currMntPrefix = sdcMan->getCurrentMountPrefix(); + if (currMntPrefix == "") { + return ObjectManagerIF::CHILD_INIT_FAILED; + } if (BLOCKING_SD_INIT) { result = initSdCardBlocking(); if (result != returnvalue::OK and result != SdCardManager::ALREADY_MOUNTED) { diff --git a/bsp_q7s/em/emObjectFactory.cpp b/bsp_q7s/em/emObjectFactory.cpp index 8eb1bc5f..8364533a 100644 --- a/bsp_q7s/em/emObjectFactory.cpp +++ b/bsp_q7s/em/emObjectFactory.cpp @@ -23,7 +23,8 @@ void ObjectFactory::produce(void* args) { HealthTableIF* healthTable = nullptr; PusTmFunnel* pusFunnel = nullptr; CfdpTmFunnel* cfdpFunnel = nullptr; - ObjectFactory::produceGenericObjects(&healthTable, &pusFunnel, &cfdpFunnel, *SdCardManager::instance()); + ObjectFactory::produceGenericObjects(&healthTable, &pusFunnel, &cfdpFunnel, + *SdCardManager::instance()); LinuxLibgpioIF* gpioComIF = nullptr; SerialComIF* uartComIF = nullptr; diff --git a/bsp_q7s/fs/SdCardManager.cpp b/bsp_q7s/fs/SdCardManager.cpp index c0b1184e..9e5d05bc 100644 --- a/bsp_q7s/fs/SdCardManager.cpp +++ b/bsp_q7s/fs/SdCardManager.cpp @@ -410,9 +410,12 @@ ReturnValue_t SdCardManager::updateSdCardStateFile() { return result; } -const std::string& SdCardManager::getCurrentMountPrefix() const { +const char* SdCardManager::getCurrentMountPrefix() const { MutexGuard mg(mutex); - return currentPrefix; + if (currentPrefix.has_value()) { + return currentPrefix.value().c_str(); + } + return nullptr; } SdCardManager::OpStatus SdCardManager::checkCurrentOp(Operations& currentOp) { diff --git a/bsp_q7s/fs/SdCardManager.h b/bsp_q7s/fs/SdCardManager.h index 749cae62..77055589 100644 --- a/bsp_q7s/fs/SdCardManager.h +++ b/bsp_q7s/fs/SdCardManager.h @@ -187,7 +187,7 @@ class SdCardManager : public SystemObject, public SdCardMountedIF { * @param prefSdCardPtr * @return */ - const std::string& getCurrentMountPrefix() const override; + const char* getCurrentMountPrefix() const override; OpStatus checkCurrentOp(Operations& currentOp); @@ -232,7 +232,7 @@ class SdCardManager : public SystemObject, public SdCardMountedIF { void processSdStatusLine(SdStatePair& active, std::string& line, uint8_t& idx, sd::SdCard& currentSd); - std::string currentPrefix; + std::optional currentPrefix; static SdCardManager* INSTANCE; }; diff --git a/bsp_q7s/fs/helpers.cpp b/bsp_q7s/fs/helpers.cpp index f1f31eba..19c2f67e 100644 --- a/bsp_q7s/fs/helpers.cpp +++ b/bsp_q7s/fs/helpers.cpp @@ -3,6 +3,9 @@ std::filesystem::path fshelpers::getPrefixedPath(SdCardManager &man, std::filesystem::path pathWihtoutPrefix) { auto prefix = man.getCurrentMountPrefix(); + if (prefix == nullptr) { + return pathWihtoutPrefix; + } auto resPath = prefix / pathWihtoutPrefix; return resPath; } diff --git a/dummies/CMakeLists.txt b/dummies/CMakeLists.txt index 810cc048..9040fbb0 100644 --- a/dummies/CMakeLists.txt +++ b/dummies/CMakeLists.txt @@ -25,5 +25,6 @@ target_sources( PlocMpsocDummy.cpp PlocSupervisorDummy.cpp helpers.cpp + RtdPollingDummy.cpp MgmRm3100Dummy.cpp Tmp1075Dummy.cpp) diff --git a/dummies/RtdPollingDummy.cpp b/dummies/RtdPollingDummy.cpp index f1cd1155..82eb3ec6 100644 --- a/dummies/RtdPollingDummy.cpp +++ b/dummies/RtdPollingDummy.cpp @@ -1,3 +1,5 @@ #include "RtdPollingDummy.h" -RtdPollingDummy::RtdPollingDummy(object_id_t objectId): SystemObject(objectId) {} +RtdPollingDummy::RtdPollingDummy(object_id_t objectId) : SystemObject(objectId) {} + +ReturnValue_t RtdPollingDummy::performOperation(uint8_t operationCode) { return returnvalue::OK; } diff --git a/dummies/RtdPollingDummy.h b/dummies/RtdPollingDummy.h index 0228123b..b5ffb5f2 100644 --- a/dummies/RtdPollingDummy.h +++ b/dummies/RtdPollingDummy.h @@ -2,10 +2,12 @@ #define DUMMIES_RTDPOLLINGDUMMY_H_ #include +#include -class RtdPollingDummy: public SystemObject { -public: +class RtdPollingDummy : public ExecutableObjectIF, public SystemObject { + public: RtdPollingDummy(object_id_t objectId); + ReturnValue_t performOperation(uint8_t operationCode = 0) override; }; #endif /* DUMMIES_RTDPOLLINGDUMMY_H_ */ diff --git a/dummies/helpers.cpp b/dummies/helpers.cpp index e6faab32..8a49a592 100644 --- a/dummies/helpers.cpp +++ b/dummies/helpers.cpp @@ -46,7 +46,7 @@ void dummy::createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitcher, GpioIF* gpio new CoreControllerDummy(objects::CORE_CONTROLLER); } if (cfg.addRtdComIFDummy) { - new ComIFDummy(objects::SPI_RTD_COM_IF); + new RtdPollingDummy(objects::SPI_RTD_COM_IF); } std::array rwIds = {objects::RW1, objects::RW2, objects::RW3, objects::RW4}; std::array rws; @@ -193,7 +193,6 @@ void dummy::createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitcher, GpioIF* gpio objects::TMP1075_HANDLER_IF_BOARD, new Tmp1075Dummy(objects::TMP1075_HANDLER_IF_BOARD, objects::DUMMY_COM_IF, comCookieDummy)); - new RtdPollingDummy(objects::SPI_RTD_COM_IF); new TemperatureSensorInserter(objects::THERMAL_TEMP_INSERTER, rtdSensorDummies, tmpSensorDummies); TcsBoardAssembly* tcsBoardAssy = ObjectFactory::createTcsBoardAssy(pwrSwitcher); diff --git a/linux/devices/ploc/PlocSupervisorHandler.cpp b/linux/devices/ploc/PlocSupervisorHandler.cpp index 086ef661..06a4cf07 100644 --- a/linux/devices/ploc/PlocSupervisorHandler.cpp +++ b/linux/devices/ploc/PlocSupervisorHandler.cpp @@ -1742,18 +1742,21 @@ ReturnValue_t PlocSupervisorHandler::createMramDumpFile() { std::string filename = "mram-dump--" + timeStamp + ".bin"; #ifdef XIPHOS_Q7S - std::string currentMountPrefix = sdcMan->getCurrentMountPrefix(); + const char* currentMountPrefix = sdcMan->getCurrentMountPrefix(); #else - std::string currentMountPrefix("/mnt/sd0"); + const char* currentMountPrefix = "/mnt/sd0"; #endif /* BOARD_TE0720 == 0 */ + if (currentMountPrefix == nullptr) { + return returnvalue::FAILED; + } // Check if path to PLOC directory exists - if (not std::filesystem::exists(std::string(currentMountPrefix + "/" + supervisorFilePath))) { + if (not std::filesystem::exists(std::string(currentMountPrefix) + "/" + supervisorFilePath)) { sif::warning << "PlocSupervisorHandler::createMramDumpFile: Supervisor path does not exist" << std::endl; return result::PATH_DOES_NOT_EXIST; } - activeMramFile = currentMountPrefix + "/" + supervisorFilePath + "/" + filename; + activeMramFile = std::string(currentMountPrefix) + "/" + supervisorFilePath + "/" + filename; // Create new file std::ofstream file(activeMramFile, std::ios_base::out); file.close(); diff --git a/mission/devices/PayloadPcduHandler.cpp b/mission/devices/PayloadPcduHandler.cpp index 44dd667c..48880c6e 100644 --- a/mission/devices/PayloadPcduHandler.cpp +++ b/mission/devices/PayloadPcduHandler.cpp @@ -517,6 +517,9 @@ void PayloadPcduHandler::checkJsonFileInit() { if (not jsonFileInitComplete) { auto activeSd = sdcMan->getActiveSdCard(); if (activeSd and sdcMan->isSdCardUsable(activeSd.value())) { + if (sdcMan->getCurrentMountPrefix() == nullptr) { + return; + } params.initialize(sdcMan->getCurrentMountPrefix()); jsonFileInitComplete = true; } diff --git a/mission/devices/ScexDeviceHandler.cpp b/mission/devices/ScexDeviceHandler.cpp index 8da6d229..e2061a6b 100644 --- a/mission/devices/ScexDeviceHandler.cpp +++ b/mission/devices/ScexDeviceHandler.cpp @@ -214,6 +214,9 @@ ReturnValue_t ScexDeviceHandler::interpretDeviceReply(DeviceCommandId_t id, cons fileId = date_time_string(); std::ostringstream oss; auto prefix = sdcMan.getCurrentMountPrefix(); + if (prefix == nullptr) { + return returnvalue::FAILED; + } oss << prefix << "/scex/scex-" << cmdName << fileId << ".bin"; fileName = oss.str(); ofstream out(fileName, ofstream::binary); @@ -234,6 +237,9 @@ ReturnValue_t ScexDeviceHandler::interpretDeviceReply(DeviceCommandId_t id, cons fileId = date_time_string(); std::ostringstream oss; auto prefix = sdcMan.getCurrentMountPrefix(); + if (prefix == nullptr) { + return returnvalue::FAILED; + } oss << prefix << "/scex/scex-" << cmdName << fileId << ".bin"; fileName = oss.str(); fileNameSet = true; @@ -310,6 +316,16 @@ ReturnValue_t ScexDeviceHandler::interpretDeviceReply(DeviceCommandId_t id, cons } void ScexDeviceHandler::performOperationHook() { + auto mntPrefix = sdcMan.getCurrentMountPrefix(); + if (mntPrefix != nullptr) { + std::filesystem::path fullFilePath = mntPrefix; + fullFilePath /= "scex"; + bool fileExists = std::filesystem::exists(fullFilePath); + + if (not fileExists) { + std::filesystem::create_directory(fullFilePath); + } + } uint32_t remainingMillis = finishCountdown.getRemainingMillis(); if (commandActive and finishCountdown.hasTimedOut()) { triggerEvent(scex::EXPERIMENT_TIMEDOUT, currCmd, 0); @@ -373,13 +389,5 @@ void ScexDeviceHandler::setPowerSwitcher(PowerSwitchIF& powerSwitcher, power::Sw } ReturnValue_t ScexDeviceHandler::initializeAfterTaskCreation() { - auto mntPrefix = sdcMan.getCurrentMountPrefix(); - std::filesystem::path fullFilePath = mntPrefix; - fullFilePath /= "scex"; - bool fileExists = std::filesystem::exists(fullFilePath); - - if (not fileExists) { - std::filesystem::create_directory(fullFilePath); - } return DeviceHandlerBase::initializeAfterTaskCreation(); } diff --git a/mission/memory/SdCardMountedIF.h b/mission/memory/SdCardMountedIF.h index ac705e8d..1e76b9b7 100644 --- a/mission/memory/SdCardMountedIF.h +++ b/mission/memory/SdCardMountedIF.h @@ -9,7 +9,7 @@ class SdCardMountedIF { public: virtual ~SdCardMountedIF(){}; - virtual const std::string& getCurrentMountPrefix() const = 0; + virtual const char* getCurrentMountPrefix() const = 0; virtual bool isSdCardUsable(std::optional sdCard) = 0; virtual std::optional getPreferredSdCard() const = 0; virtual void setActiveSdCard(sd::SdCard sdCard) = 0; diff --git a/mission/tmtc/PersistentTmStore.cpp b/mission/tmtc/PersistentTmStore.cpp index 100767b9..b8f24462 100644 --- a/mission/tmtc/PersistentTmStore.cpp +++ b/mission/tmtc/PersistentTmStore.cpp @@ -52,7 +52,7 @@ ReturnValue_t PersistentTmStore::assignAndOrCreateMostRecentFile() { time_t fileEpoch = timegm(&time); // There is still a file within the active time window, so re-use that file for new TMs to // store. - if (fileEpoch + rolloverDiffSeconds > currentTv.tv_sec) { + if (fileEpoch + static_cast(rolloverDiffSeconds) > currentTv.tv_sec) { activeFileTv.tv_sec = fileEpoch; activeFile = file.path(); break; @@ -191,14 +191,18 @@ void PersistentTmStore::calcDiffSeconds(RolloverInterval intervalUnit, uint32_t } } -void PersistentTmStore::updateBaseDir() { +bool PersistentTmStore::updateBaseDir() { using namespace std::filesystem; - std::string currentPrefix = sdcMan.getCurrentMountPrefix(); + const char* currentPrefix = sdcMan.getCurrentMountPrefix(); + if (currentPrefix == nullptr) { + return false; + } basePath = path(currentPrefix) / baseDir / baseName; if (not exists(basePath)) { create_directories(basePath); } baseDirUninitialized = false; + return true; } void PersistentTmStore::addApid(uint16_t apid) { diff --git a/mission/tmtc/PersistentTmStore.h b/mission/tmtc/PersistentTmStore.h index bcd83a71..54c3b4d4 100644 --- a/mission/tmtc/PersistentTmStore.h +++ b/mission/tmtc/PersistentTmStore.h @@ -77,7 +77,7 @@ class PersistentTmStore : public TmStoreFrontendSimpleIF, public SystemObject { ReturnValue_t createMostRecentFile(); static ReturnValue_t pathToTm(const std::filesystem::path& path, struct tm& time); void fileToPackets(const std::filesystem::path& path, uint32_t unixStamp, TmFunnelBase& funnel); - void updateBaseDir(); + bool updateBaseDir(); ReturnValue_t assignAndOrCreateMostRecentFile(); ReturnValue_t storePacket(PusTmReader& reader); }; diff --git a/mission/tmtc/PusTmFunnel.cpp b/mission/tmtc/PusTmFunnel.cpp index a0f345cb..524b2e6d 100644 --- a/mission/tmtc/PusTmFunnel.cpp +++ b/mission/tmtc/PusTmFunnel.cpp @@ -144,7 +144,7 @@ ReturnValue_t PusTmFunnel::handleTmPacket(TmTcMessage &message) { const char *PusTmFunnel::getName() const { return "PUS TM Funnel"; } void PusTmFunnel::initStoresIfPossible(bool sdCardUsable) { - if (not storesInitialized and sdCardUsable) { + if (not storesInitialized and sdCardUsable and sdcMan.getCurrentMountPrefix() != nullptr) { miscStore.initializeTmStore(); okStore.initializeTmStore(); hkStore.initializeTmStore(); diff --git a/mission/utility/DummySdCardManager.cpp b/mission/utility/DummySdCardManager.cpp index 1b2a45e1..17d7ba2b 100644 --- a/mission/utility/DummySdCardManager.cpp +++ b/mission/utility/DummySdCardManager.cpp @@ -2,7 +2,7 @@ DummySdCardManager::DummySdCardManager(std::string prefix) : prefix(std::move(prefix)) {} -const std::string& DummySdCardManager::getCurrentMountPrefix() const { return prefix; } +const char* DummySdCardManager::getCurrentMountPrefix() const { return prefix.c_str(); } bool DummySdCardManager::isSdCardUsable(std::optional sdCard) { return true; } diff --git a/mission/utility/DummySdCardManager.h b/mission/utility/DummySdCardManager.h index 1a74dc10..4c985056 100644 --- a/mission/utility/DummySdCardManager.h +++ b/mission/utility/DummySdCardManager.h @@ -5,7 +5,7 @@ class DummySdCardManager : public SdCardMountedIF { public: DummySdCardManager(std::string prefix); - const std::string& getCurrentMountPrefix() const override; + const char* getCurrentMountPrefix() const override; bool isSdCardUsable(std::optional sdCard) override; std::optional getPreferredSdCard() const override; void setActiveSdCard(sd::SdCard sdCard) override; From 95ce2c79b99593fe88f2dc5dcb651fcc4bb8d283 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 24 Feb 2023 18:10:43 +0100 Subject: [PATCH 78/87] this might be over-engineered --- dummies/helpers.cpp | 1 - mission/controller/acs/SusConverter.cpp | 1 + mission/tmtc/PersistentTmStore.cpp | 58 ++++++++++++++++--------- mission/tmtc/PersistentTmStore.h | 8 ++-- mission/tmtc/PusTmFunnel.cpp | 13 +++--- 5 files changed, 48 insertions(+), 33 deletions(-) diff --git a/dummies/helpers.cpp b/dummies/helpers.cpp index 344ee611..f93a8127 100644 --- a/dummies/helpers.cpp +++ b/dummies/helpers.cpp @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include diff --git a/mission/controller/acs/SusConverter.cpp b/mission/controller/acs/SusConverter.cpp index 3856789a..1a645270 100644 --- a/mission/controller/acs/SusConverter.cpp +++ b/mission/controller/acs/SusConverter.cpp @@ -4,6 +4,7 @@ #include #include #include + #include bool SusConverter::checkSunSensorData(const uint16_t susChannel[6]) { diff --git a/mission/tmtc/PersistentTmStore.cpp b/mission/tmtc/PersistentTmStore.cpp index b8f24462..b16069dc 100644 --- a/mission/tmtc/PersistentTmStore.cpp +++ b/mission/tmtc/PersistentTmStore.cpp @@ -16,12 +16,11 @@ using namespace returnvalue; PersistentTmStore::PersistentTmStore(object_id_t objectId, const char* baseDir, std::string baseName, RolloverInterval intervalUnit, - uint32_t intervalCount, timeval& currentTv, - StorageManagerIF& tmStore, SdCardMountedIF& sdcMan) + uint32_t intervalCount, StorageManagerIF& tmStore, + SdCardMountedIF& sdcMan) : SystemObject(objectId), baseDir(baseDir), baseName(std::move(baseName)), - currentTv(currentTv), sdcMan(sdcMan), tmStore(tmStore) { tcQueue = QueueFactory::instance()->createMessageQueue(); @@ -59,7 +58,7 @@ ReturnValue_t PersistentTmStore::assignAndOrCreateMostRecentFile() { } } if (not activeFile.has_value()) { - return createMostRecentFile(); + return createMostRecentFile(std::nullopt); } return returnvalue::OK; } @@ -77,6 +76,7 @@ ReturnValue_t PersistentTmStore::handleCommandQueue(StorageManagerIF& ipcStore, if (cmdMessage.getMessageType() == messagetypes::TM_STORE) { Command_t cmd = cmdMessage.getCommand(); if (cmd == TmStoreMessage::DELETE_STORE_CONTENT_TIME) { + Clock::getClock_timeval(¤tTv); store_address_t storeId = TmStoreMessage::getStoreId(&cmdMessage); auto accessor = ipcStore.getData(storeId); uint32_t deleteUpToUnixSeconds = 0; @@ -85,6 +85,7 @@ ReturnValue_t PersistentTmStore::handleCommandQueue(StorageManagerIF& ipcStore, SerializeIF::Endianness::NETWORK); deleteUpTo(deleteUpToUnixSeconds); } else if (cmd == TmStoreMessage::DOWNLINK_STORE_CONTENT_TIME) { + Clock::getClock_timeval(¤tTv); store_address_t storeId = TmStoreMessage::getStoreId(&cmdMessage); auto accessor = ipcStore.getData(storeId); if (accessor.second.size() < 8) { @@ -147,6 +148,7 @@ ReturnValue_t PersistentTmStore::storePacket(PusTmReader& reader) { if (baseDirUninitialized) { updateBaseDir(); } + Clock::getClock_timeval(¤tTv); // It is assumed here that the filesystem is usable. if (not activeFile.has_value()) { ReturnValue_t result = assignAndOrCreateMostRecentFile(); @@ -155,21 +157,25 @@ ReturnValue_t PersistentTmStore::storePacket(PusTmReader& reader) { } } - if (currentTv.tv_sec < activeFileTv.tv_sec or - currentTv.tv_sec - activeFileTv.tv_sec > static_cast(rolloverDiffSeconds)) { - if (file_size(activeFile.value()) + reader.getFullPacketLen() > fileBuf.size()) { - uint8_t appendedCounter = 1; - path rolloverName; - while (true) { - rolloverName = path(activeFile.value().string() + "." + std::to_string(appendedCounter)); - if (not exists(rolloverName)) { - break; - } - appendedCounter++; - } - rename(activeFile.value(), rolloverName); - std::ofstream of(activeFile.value(), std::ios::binary); + bool createNewFile = false; + std::optional suffix = std::nullopt; + if (currentTv.tv_sec > activeFileTv.tv_sec + static_cast(rolloverDiffSeconds)) { + createNewFile = true; + currentSameSecNumber = 0; + } else if (file_size(activeFile.value()) + reader.getFullPacketLen() > fileBuf.size()) { + createNewFile = true; + if (currentSameSecNumber >= MAX_FILES_IN_ONE_SECOND) { + currentSameSecNumber = 0; } + if (currentTv.tv_sec == activeFileTv.tv_sec) { + suffix = currentSameSecNumber++; + + } else { + currentSameSecNumber = 0; + } + } + if (createNewFile) { + createMostRecentFile(currentSameSecNumber++); } // Rollover conditions were handled, write to file now @@ -311,7 +317,7 @@ void PersistentTmStore::fileToPackets(const std::filesystem::path& path, uint32_ } } -ReturnValue_t PersistentTmStore::createMostRecentFile() { +ReturnValue_t PersistentTmStore::createMostRecentFile(std::optional suffix) { using namespace std::filesystem; unsigned currentIdx = 0; path pathStart = basePath / baseName; @@ -329,9 +335,19 @@ ReturnValue_t PersistentTmStore::createMostRecentFile() { return returnvalue::FAILED; } currentIdx += writtenBytes; - strncpy(reinterpret_cast(fileBuf.data() + currentIdx), ".bin", - fileBuf.size() - currentIdx); + char* res = strcpy(reinterpret_cast(fileBuf.data() + currentIdx), ".bin"); + if (res == nullptr) { + return returnvalue::FAILED; + } currentIdx += 4; + if (suffix.has_value()) { + std::string fullSuffix = "." + std::to_string(suffix.value()); + res = strcpy(reinterpret_cast(fileBuf.data() + currentIdx), fullSuffix.c_str()); + if (res == nullptr) { + return returnvalue::FAILED; + } + currentIdx += fullSuffix.size(); + } path newPath(std::string(reinterpret_cast(fileBuf.data()), currentIdx)); std::ofstream of(newPath, std::ios::binary); diff --git a/mission/tmtc/PersistentTmStore.h b/mission/tmtc/PersistentTmStore.h index 54c3b4d4..d8bc9acf 100644 --- a/mission/tmtc/PersistentTmStore.h +++ b/mission/tmtc/PersistentTmStore.h @@ -31,7 +31,7 @@ class PersistentTmStore : public TmStoreFrontendSimpleIF, public SystemObject { static constexpr Event POSSIBLE_FILE_CORRUPTION = event::makeEvent(SUBSYSTEM_ID, 0, severity::LOW); PersistentTmStore(object_id_t objectId, const char* baseDir, std::string baseName, - RolloverInterval intervalUnit, uint32_t intervalCount, timeval& currentTv, + RolloverInterval intervalUnit, uint32_t intervalCount, StorageManagerIF& tmStore, SdCardMountedIF& sdcMan); ReturnValue_t initializeTmStore(); @@ -48,6 +48,7 @@ class PersistentTmStore : public TmStoreFrontendSimpleIF, public SystemObject { ReturnValue_t passPacket(PusTmReader& reader); private: + static constexpr uint8_t MAX_FILES_IN_ONE_SECOND = 10; static constexpr size_t MAX_FILESIZE = 8192; // ISO8601 timestamp. static constexpr char FILE_DATE_FORMAT[] = "%FT%H%M%SZ"; @@ -58,10 +59,11 @@ class PersistentTmStore : public TmStoreFrontendSimpleIF, public SystemObject { bool baseDirUninitialized = true; const char* baseDir; std::string baseName; + uint8_t currentSameSecNumber = 0; std::filesystem::path basePath; uint32_t rolloverDiffSeconds = 0; std::array fileBuf{}; - timeval& currentTv; + timeval currentTv; timeval activeFileTv{}; std::optional activeFile; SdCardMountedIF& sdcMan; @@ -74,7 +76,7 @@ class PersistentTmStore : public TmStoreFrontendSimpleIF, public SystemObject { [[nodiscard]] MessageQueueId_t getCommandQueue() const override; void calcDiffSeconds(RolloverInterval intervalUnit, uint32_t intervalCount); - ReturnValue_t createMostRecentFile(); + ReturnValue_t createMostRecentFile(std::optional suffix); static ReturnValue_t pathToTm(const std::filesystem::path& path, struct tm& time); void fileToPackets(const std::filesystem::path& path, uint32_t unixStamp, TmFunnelBase& funnel); bool updateBaseDir(); diff --git a/mission/tmtc/PusTmFunnel.cpp b/mission/tmtc/PusTmFunnel.cpp index 524b2e6d..08a047a0 100644 --- a/mission/tmtc/PusTmFunnel.cpp +++ b/mission/tmtc/PusTmFunnel.cpp @@ -14,14 +14,11 @@ PusTmFunnel::PusTmFunnel(TmFunnelBase::FunnelCfg cfg, TimeReaderIF &timeReader, SdCardMountedIF &sdcMan) : TmFunnelBase(cfg), timeReader(timeReader), - miscStore(objects::MISC_TM_STORE, "tm", "misc", RolloverInterval::HOURLY, 2, currentTv, - tmStore, sdcMan), - okStore(objects::OK_TM_STORE, "tm", "ok", RolloverInterval::MINUTELY, 30, currentTv, tmStore, - sdcMan), - notOkStore(objects::NOT_OK_TM_STORE, "tm", "nok", RolloverInterval::MINUTELY, 30, currentTv, - tmStore, sdcMan), - hkStore(objects::HK_TM_STORE, "tm", "hk", RolloverInterval::MINUTELY, 15, currentTv, tmStore, - sdcMan), + miscStore(objects::MISC_TM_STORE, "tm", "misc", RolloverInterval::HOURLY, 2, tmStore, sdcMan), + okStore(objects::OK_TM_STORE, "tm", "ok", RolloverInterval::MINUTELY, 30, tmStore, sdcMan), + notOkStore(objects::NOT_OK_TM_STORE, "tm", "nok", RolloverInterval::MINUTELY, 30, tmStore, + sdcMan), + hkStore(objects::HK_TM_STORE, "tm", "hk", RolloverInterval::MINUTELY, 15, tmStore, sdcMan), sdcMan(sdcMan) { Clock::getClock_timeval(¤tTv); Clock::getUptime(&lastTvUpdate); From cbb6a45407ff8283089eabf2a30abc181ac09323 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 24 Feb 2023 18:18:35 +0100 Subject: [PATCH 79/87] remove newline --- mission/tmtc/PersistentTmStore.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/mission/tmtc/PersistentTmStore.cpp b/mission/tmtc/PersistentTmStore.cpp index b16069dc..901bac16 100644 --- a/mission/tmtc/PersistentTmStore.cpp +++ b/mission/tmtc/PersistentTmStore.cpp @@ -169,7 +169,6 @@ ReturnValue_t PersistentTmStore::storePacket(PusTmReader& reader) { } if (currentTv.tv_sec == activeFileTv.tv_sec) { suffix = currentSameSecNumber++; - } else { currentSameSecNumber = 0; } From aae4d019e7c25f8a89c5f0fa5f1fbaf12800431f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 24 Feb 2023 18:20:32 +0100 Subject: [PATCH 80/87] bugfix --- mission/tmtc/PersistentTmStore.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mission/tmtc/PersistentTmStore.cpp b/mission/tmtc/PersistentTmStore.cpp index 901bac16..35b15789 100644 --- a/mission/tmtc/PersistentTmStore.cpp +++ b/mission/tmtc/PersistentTmStore.cpp @@ -174,7 +174,7 @@ ReturnValue_t PersistentTmStore::storePacket(PusTmReader& reader) { } } if (createNewFile) { - createMostRecentFile(currentSameSecNumber++); + createMostRecentFile(suffix); } // Rollover conditions were handled, write to file now From 66b4fc629480b4ad2886d155e346ade435133c98 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 24 Feb 2023 18:22:36 +0100 Subject: [PATCH 81/87] use correct retval --- mission/tmtc/Service15TmStorage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mission/tmtc/Service15TmStorage.cpp b/mission/tmtc/Service15TmStorage.cpp index d61d587d..1c9b8611 100644 --- a/mission/tmtc/Service15TmStorage.cpp +++ b/mission/tmtc/Service15TmStorage.cpp @@ -36,7 +36,7 @@ ReturnValue_t Service15TmStorage::getMessageQueueAndObject(uint8_t subservice, SerializeAdapter::deSerialize(objectId, &tcData, &tcDataLen, SerializeIF::Endianness::NETWORK); auto *frontendIF = ObjectManager::instance()->get(*objectId); if (frontendIF == nullptr) { - return FAILED; + return CommandingServiceBase::INVALID_OBJECT; } *id = frontendIF->getCommandQueue(); return OK; From 13f2f393255cce0828ead7021fea4658bc767275 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 24 Feb 2023 18:45:04 +0100 Subject: [PATCH 82/87] improve backup file handling --- bsp_q7s/core/CoreController.cpp | 19 ++++++++++++------- bsp_q7s/core/CoreController.h | 9 ++++++--- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 2c74b063..a04ef355 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -49,6 +49,8 @@ CoreController::CoreController(object_id_t objectId) } getCurrentBootCopy(CURRENT_CHIP, CURRENT_COPY); + + initClockFromTimeFile(); } catch (const std::filesystem::filesystem_error &e) { sif::error << "CoreController::CoreController: Failed with exception " << e.what() << std::endl; } @@ -1269,10 +1271,12 @@ void CoreController::performMountedSdCardOperations() { if (result != returnvalue::OK) { sif::warning << "CoreController::CoreController: Boot copy init" << std::endl; } - initClockFromTimeFile(); + if (not timeFileInitDone) { + initClockFromTimeFile(); + } performRebootFileHandling(false); } - timeFileHandler(); + backupTimeFileHandler(); }; bool someSdCardActive = false; if (sdInfo.active == sd::SdCard::SLOT_0 and sdcMan->isSdCardUsable(sd::SdCard::SLOT_0)) { @@ -1786,7 +1790,7 @@ void CoreController::setRebootMechanismLock(bool lock, xsc::Chip tgtChip, xsc::C rewriteRebootFile(rebootFile); } -ReturnValue_t CoreController::timeFileHandler() { +ReturnValue_t CoreController::backupTimeFileHandler() { // Always set time. We could only set it if it is updated by GPS, but then the backup time would // become obsolete on GPS problems. if (opDivider10.check()) { @@ -1796,14 +1800,14 @@ ReturnValue_t CoreController::timeFileHandler() { if (result != returnvalue::OK) { return result; } - std::string fileName = currMntPrefix + TIME_FILE; + std::string fileName = currMntPrefix + BACKUP_TIME_FILE; std::ofstream timeFile(fileName); if (not timeFile.good()) { sif::error << "CoreController::timeFileHandler: Error opening time file: " << strerror(errno) << std::endl; return returnvalue::FAILED; } - timeFile << "UNIX SECONDS: " << currentTime.tv_sec << std::endl; + timeFile << "UNIX SECONDS: " << currentTime.tv_sec + BOOT_OFFSET_SECONDS << std::endl; } return returnvalue::OK; } @@ -1811,8 +1815,8 @@ ReturnValue_t CoreController::timeFileHandler() { ReturnValue_t CoreController::initClockFromTimeFile() { using namespace GpsHyperion; using namespace std; - std::string fileName = currMntPrefix + TIME_FILE; - if (std::filesystem::exists(fileName) and + std::string fileName = currMntPrefix + BACKUP_TIME_FILE; + if (sdcMan->isSdCardUsable(std::nullopt) and std::filesystem::exists(fileName) and ((gpsFix == FixMode::UNKNOWN or gpsFix == FixMode::NOT_SEEN) or not utility::timeSanityCheck())) { ifstream timeFile(fileName); @@ -1840,6 +1844,7 @@ ReturnValue_t CoreController::initClockFromTimeFile() { sif::info << "Setting system time from time files: " << std::put_time(time, "%c %Z") << std::endl; #endif + timeFileInitDone = true; return Clock::setClock(¤tTime); } return returnvalue::OK; diff --git a/bsp_q7s/core/CoreController.h b/bsp_q7s/core/CoreController.h index 65ee20ef..1376c0a8 100644 --- a/bsp_q7s/core/CoreController.h +++ b/bsp_q7s/core/CoreController.h @@ -58,13 +58,14 @@ class CoreController : public ExtendedControllerBase { static constexpr char VERSION_FILE_NAME[] = "version.txt"; static constexpr char REBOOT_FILE_NAME[] = "reboot.txt"; - static constexpr char TIME_FILE_NAME[] = "time.txt"; + static constexpr char TIME_FILE_NAME[] = "time_backup.txt"; const std::string VERSION_FILE = "/" + std::string(CONF_FOLDER) + "/" + std::string(VERSION_FILE_NAME); const std::string REBOOT_FILE = "/" + std::string(CONF_FOLDER) + "/" + std::string(REBOOT_FILE_NAME); - const std::string TIME_FILE = "/" + std::string(CONF_FOLDER) + "/" + std::string(TIME_FILE_NAME); + const std::string BACKUP_TIME_FILE = + "/" + std::string(CONF_FOLDER) + "/" + std::string(TIME_FILE_NAME); static constexpr char CHIP_0_COPY_0_MOUNT_DIR[] = "/tmp/mntupdate-xdi-qspi0-nom-rootfs"; static constexpr char CHIP_0_COPY_1_MOUNT_DIR[] = "/tmp/mntupdate-xdi-qspi0-gold-rootfs"; @@ -160,6 +161,7 @@ class CoreController : public ExtendedControllerBase { bool sdInitFinished() const; private: + static constexpr uint32_t BOOT_OFFSET_SECONDS = 15; static constexpr MutexIF::TimeoutType TIMEOUT_TYPE = MutexIF::TimeoutType::WAITING; static constexpr uint32_t MUTEX_TIMEOUT = 20; // Designated value for rechecking FIFO open @@ -221,6 +223,7 @@ class CoreController : public ExtendedControllerBase { RebootFile rebootFile = {}; std::string currMntPrefix; + bool timeFileInitDone = false; bool performOneShotSdCardOpsSwitch = false; uint8_t shortSdCardCdCounter = 0; #if OBSW_THREAD_TRACING == 1 @@ -258,7 +261,7 @@ class CoreController : public ExtendedControllerBase { ReturnValue_t initClockFromTimeFile(); ReturnValue_t performSdCardCheck(); - ReturnValue_t timeFileHandler(); + ReturnValue_t backupTimeFileHandler(); ReturnValue_t initBootCopyFile(); ReturnValue_t initWatchdogFifo(); ReturnValue_t initSdCardBlocking(); From be3c778fee951f8bce03145f78cd9232a6e9131a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 24 Feb 2023 18:59:48 +0100 Subject: [PATCH 83/87] bugfix --- mission/tmtc/PersistentTmStore.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/mission/tmtc/PersistentTmStore.cpp b/mission/tmtc/PersistentTmStore.cpp index 35b15789..6ceed609 100644 --- a/mission/tmtc/PersistentTmStore.cpp +++ b/mission/tmtc/PersistentTmStore.cpp @@ -356,6 +356,7 @@ ReturnValue_t PersistentTmStore::createMostRecentFile(std::optional suf } ReturnValue_t PersistentTmStore::initializeTmStore() { + Clock::getClock_timeval(¤tTv); updateBaseDir(); return assignAndOrCreateMostRecentFile(); } From 9501d0802fd31074f5f47682a260a51157c6519c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 24 Feb 2023 19:03:03 +0100 Subject: [PATCH 84/87] changelog --- CHANGELOG.md | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c999804b..3d0593a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,16 +16,6 @@ will consitute of a breaking change warranting a new major release: # [unreleased] -## Added - -- Added basic persistent TM store for PUS telemetry and basic interface to dump and delete - telemetry. - PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/320/files - -## Changed - -- Changed format of `getCurrentMountPrefix` to return a `const char*`. - ## Fixed - ADIS1650X: Added missing MDL_RANG pool entry for configuration set @@ -39,13 +29,22 @@ will consitute of a breaking change warranting a new major release: ## Changed +- Added basic persistent TM store for PUS telemetry and basic interface to dump and delete + telemetry. Implementation is based on a timed rotating files, with the addition that files + might be generated more often if the maximum file size of 8192 bytes is exceeded. + PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/320/files - Commented out commanding of actuators as part of the `AcsController` - Collection sets of the `AcsController` now get updated before running the actual ACS algorithm - `GpsController` now always gets scheduled +- The `CoreController` now initializes the initial clock from the time file as early as possible + (in the constructor) if possible, which should usually be the case. ## Added +- Added basic persistent TM store for PUS telemetry and basic interface to dump and delete + telemetry. + PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/320/files - `ExecutableComIfDummy` class to have a dummy for classes like the RTD polling class. - Added `AcsController` action command to confirm solar array deployment, which then deletes two files From 746f288f1e47e673b35a1bdc8dee3c06355b5649 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 24 Feb 2023 19:05:54 +0100 Subject: [PATCH 85/87] bump fsfw --- fsfw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fsfw b/fsfw index 216f603d..bdfe31db 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 216f603d62892356cb16e4ee4a35a59399c92ceb +Subproject commit bdfe31dba48039b60fe700e7d03bfb95e9549688 From c99b9f5afaf13d1bf083bc2265d2e2877e670f0a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 24 Feb 2023 19:13:00 +0100 Subject: [PATCH 86/87] v1.32.0 --- CHANGELOG.md | 4 ++++ tmtc | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d0593a3..8b1b2ed5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,10 @@ will consitute of a breaking change warranting a new major release: # [unreleased] +# [v1.32.0] + +eive-tmtc: v2.16.1 + ## Fixed - ADIS1650X: Added missing MDL_RANG pool entry for configuration set diff --git a/tmtc b/tmtc index d47e9039..13014eb2 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit d47e9039a5286cd7bbe67679f09f095863911b7e +Subproject commit 13014eb25053368f4fb9a445788aba71ff98de19 From e41f8901c56a4f33cb32678d73a2adffd7804664 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 24 Feb 2023 19:13:20 +0100 Subject: [PATCH 87/87] v1.32.0 version --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b597a566..a9eef222 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,8 +10,8 @@ cmake_minimum_required(VERSION 3.13) set(OBSW_VERSION_MAJOR 1) -set(OBSW_VERSION_MINOR 31) -set(OBSW_VERSION_REVISION 1) +set(OBSW_VERSION_MINOR 32) +set(OBSW_VERSION_REVISION 0) # set(CMAKE_VERBOSE TRUE)