From f0536a9d771a9a0e99e77af8c2fa366af019ca90 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 15 Nov 2023 15:21:00 +0100 Subject: [PATCH 1/4] this should do the job --- .gitignore | 4 ++ mission/tmtc/PersistentTmStore.cpp | 28 ++++++++--- mission/tmtc/PersistentTmStore.h | 1 + mission/tmtc/Service15TmStorage.cpp | 73 +++++++++++++++++++---------- mission/tmtc/Service15TmStorage.h | 6 ++- tmtc | 2 +- 6 files changed, 80 insertions(+), 34 deletions(-) diff --git a/.gitignore b/.gitignore index 5419ca42..eb6a49fa 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,7 @@ __pycache__ !/.idea/cmake.xml generators/*.db + +# Clangd LSP +/compile_commands.json +/.cache diff --git a/mission/tmtc/PersistentTmStore.cpp b/mission/tmtc/PersistentTmStore.cpp index 160348cd..4bd82880 100644 --- a/mission/tmtc/PersistentTmStore.cpp +++ b/mission/tmtc/PersistentTmStore.cpp @@ -140,12 +140,25 @@ ReturnValue_t PersistentTmStore::handleCommandQueue(StorageManagerIF& ipcStore, Clock::getClock_timeval(¤tTv); 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); + if (size < 4) { + return returnvalue::FAILED; + } + const uint8_t* data = accessor.second.data(); + uint32_t deleteUpToUnixSeconds = 0; + if (size == 4) { + SerializeAdapter::deSerialize(&deleteUpToUnixSeconds, &data, &size, + SerializeIF::Endianness::NETWORK); + deleteUpTo(deleteUpToUnixSeconds); + } else if (size == 8) { + uint32_t deleteFromUnixSeconds = 0; + SerializeAdapter::deSerialize(&deleteFromUnixSeconds, &data, &size, + SerializeIF::Endianness::NETWORK); + SerializeAdapter::deSerialize(&deleteUpToUnixSeconds, &data, &size, + SerializeIF::Endianness::NETWORK); + deleteFromUpTo(deleteFromUnixSeconds, deleteUpToUnixSeconds); + } execCmd = cmd; - deleteUpTo(deleteUpToUnixSeconds); } else if (cmd == TmStoreMessage::DOWNLINK_STORE_CONTENT_TIME) { Clock::getClock_timeval(¤tTv); store_address_t storeId = TmStoreMessage::getStoreId(&cmdMessage); @@ -257,7 +270,9 @@ bool PersistentTmStore::updateBaseDir() { return true; } -void PersistentTmStore::deleteUpTo(uint32_t unixSeconds) { +void PersistentTmStore::deleteUpTo(uint32_t unixSeconds) { deleteFromUpTo(0, unixSeconds); } + +void PersistentTmStore::deleteFromUpTo(uint32_t startUnixTime, uint32_t endUnixTime) { using namespace std::filesystem; for (auto const& file : directory_iterator(basePath)) { if (file.is_directory() or (activeFile.has_value() and (activeFile.value() == file.path()))) { @@ -270,7 +285,8 @@ void PersistentTmStore::deleteUpTo(uint32_t unixSeconds) { continue; } time_t fileEpoch = timegm(&fileTime); - if (fileEpoch + rolloverDiffSeconds < unixSeconds) { + if (fileEpoch + rolloverDiffSeconds < endUnixTime and + static_cast(fileEpoch) >= startUnixTime) { std::error_code e; std::filesystem::remove(file.path(), e); } diff --git a/mission/tmtc/PersistentTmStore.h b/mission/tmtc/PersistentTmStore.h index e86acaaf..4255b9d4 100644 --- a/mission/tmtc/PersistentTmStore.h +++ b/mission/tmtc/PersistentTmStore.h @@ -60,6 +60,7 @@ class PersistentTmStore : public TmStoreFrontendSimpleIF, public SystemObject { ReturnValue_t handleCommandQueue(StorageManagerIF& ipcStore, Command_t& execCmd); void deleteUpTo(uint32_t unixSeconds); + void deleteFromUpTo(uint32_t startUnixTime, uint32_t endUnixTime); ReturnValue_t startDumpFrom(uint32_t fromUnixSeconds); ReturnValue_t startDumpFromUpTo(uint32_t fromUnixSeconds, uint32_t upToUnixSeconds); /** diff --git a/mission/tmtc/Service15TmStorage.cpp b/mission/tmtc/Service15TmStorage.cpp index 1c9b8611..273c406b 100644 --- a/mission/tmtc/Service15TmStorage.cpp +++ b/mission/tmtc/Service15TmStorage.cpp @@ -16,8 +16,8 @@ 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): { + case (Subservice::DELETE_UP_TO): + case (Subservice::START_BY_TIME_RANGE_RETRIEVAL): { return OK; } default: { @@ -45,34 +45,55 @@ 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) { - // TODO: Hardcoded to UNIX timestamps.. Should allow arbitrary timestamp and let receiver - // to time reading and reply handling - if (tcDataLen != 12) { - return INVALID_TC; + switch (subservice) { + case (Subservice::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 + 4, tcDataLen - 4); + if (result != OK) { + return result; + } + // Store timestamps + TmStoreMessage::setDownlinkContentTimeMessage(message, storeId); + return CommandingServiceBase::EXECUTION_COMPLETE; } - store_address_t storeId; - ReturnValue_t result = ipcStore->addData(&storeId, tcData + 4, tcDataLen - 4); - if (result != OK) { - return result; + case (Subservice::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 + 4, tcDataLen - 4); + if (result != OK) { + return result; + } + // Store timestamps + TmStoreMessage::setDeleteContentTimeMessage(message, storeId); + return CommandingServiceBase::EXECUTION_COMPLETE; } - // 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; + case (Subservice::DELETE_BY_TIME_RANGE): { + // TODO: Hardcoded two 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 + 4, tcDataLen - 4); + if (result != OK) { + return result; + } + // Store timestamps + TmStoreMessage::setDeleteContentTimeMessage(message, storeId); + return CommandingServiceBase::EXECUTION_COMPLETE; } - store_address_t storeId; - ReturnValue_t result = ipcStore->addData(&storeId, tcData + 4, tcDataLen - 4); - if (result != OK) { - return result; + default: { + return CommandingServiceBase::INVALID_SUBSERVICE; } - // Store timestamps - TmStoreMessage::setDeleteContentTimeMessage(message, storeId); - return CommandingServiceBase::EXECUTION_COMPLETE; } return OK; } diff --git a/mission/tmtc/Service15TmStorage.h b/mission/tmtc/Service15TmStorage.h index 33be0634..6da381ee 100644 --- a/mission/tmtc/Service15TmStorage.h +++ b/mission/tmtc/Service15TmStorage.h @@ -5,7 +5,11 @@ class Service15TmStorage : public CommandingServiceBase { public: - enum Subservices : uint8_t { START_BY_TIME_RANGE_RETRIEVAL = 9, DELETE_UP_TO = 11 }; + enum Subservice : uint8_t { + START_BY_TIME_RANGE_RETRIEVAL = 9, + DELETE_UP_TO = 11, + DELETE_BY_TIME_RANGE = 128 + }; explicit Service15TmStorage(object_id_t objectId, uint16_t apid, uint8_t numParallelCommands, uint16_t commandTimeoutSecs = 60, size_t queueDepth = 10); diff --git a/tmtc b/tmtc index 99c6c8bb..07b13c15 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 99c6c8bbd0d791d8b17720de481c6142091a54a4 +Subproject commit 07b13c153dab03c35ea3c7921f68c6ba77049d1e From 457acc3bdbfff50887ef060f3189756bd810d0e4 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 15 Nov 2023 15:27:12 +0100 Subject: [PATCH 2/4] improve structure --- mission/tmtc/PersistentTmStore.cpp | 93 +++++++++++++++++------------- mission/tmtc/PersistentTmStore.h | 3 + 2 files changed, 57 insertions(+), 39 deletions(-) diff --git a/mission/tmtc/PersistentTmStore.cpp b/mission/tmtc/PersistentTmStore.cpp index 4bd82880..0ba690c2 100644 --- a/mission/tmtc/PersistentTmStore.cpp +++ b/mission/tmtc/PersistentTmStore.cpp @@ -137,53 +137,68 @@ 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); - size_t size = accessor.second.size(); - if (size < 4) { - return returnvalue::FAILED; - } - const uint8_t* data = accessor.second.data(); - uint32_t deleteUpToUnixSeconds = 0; - if (size == 4) { - SerializeAdapter::deSerialize(&deleteUpToUnixSeconds, &data, &size, - SerializeIF::Endianness::NETWORK); - deleteUpTo(deleteUpToUnixSeconds); - } else if (size == 8) { - uint32_t deleteFromUnixSeconds = 0; - SerializeAdapter::deSerialize(&deleteFromUnixSeconds, &data, &size, - SerializeIF::Endianness::NETWORK); - SerializeAdapter::deSerialize(&deleteUpToUnixSeconds, &data, &size, - SerializeIF::Endianness::NETWORK); - deleteFromUpTo(deleteFromUnixSeconds, deleteUpToUnixSeconds); - } + result = handleDeletionCmd(ipcStore, cmdMessage); execCmd = cmd; } 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) { - return returnvalue::FAILED; - } - uint32_t dumpFromUnixSeconds = 0; - uint32_t dumpUntilUnixSeconds = 0; - size_t size = 8; - SerializeAdapter::deSerialize(&dumpFromUnixSeconds, accessor.second.data(), &size, - SerializeIF::Endianness::NETWORK); - SerializeAdapter::deSerialize(&dumpUntilUnixSeconds, accessor.second.data() + 4, &size, - SerializeIF::Endianness::NETWORK); - result = startDumpFromUpTo(dumpFromUnixSeconds, dumpUntilUnixSeconds); - if (result == BUSY_DUMPING) { - triggerEvent(persTmStore::BUSY_DUMPING_EVENT); - return result; - } + result = handleDumpCmd(ipcStore, cmdMessage); execCmd = cmd; } } return result; } +ReturnValue_t PersistentTmStore::handleDeletionCmd(StorageManagerIF& ipcStore, + CommandMessage& cmdMessage) { + Clock::getClock_timeval(¤tTv); + store_address_t storeId = TmStoreMessage::getStoreId(&cmdMessage); + auto accessor = ipcStore.getData(storeId); + size_t size = accessor.second.size(); + if (size < 4) { + return returnvalue::FAILED; + } + const uint8_t* data = accessor.second.data(); + uint32_t deleteUpToUnixSeconds = 0; + if (size == 4) { + SerializeAdapter::deSerialize(&deleteUpToUnixSeconds, &data, &size, + SerializeIF::Endianness::NETWORK); + deleteUpTo(deleteUpToUnixSeconds); + } else if (size == 8) { + uint32_t deleteFromUnixSeconds = 0; + SerializeAdapter::deSerialize(&deleteFromUnixSeconds, &data, &size, + SerializeIF::Endianness::NETWORK); + SerializeAdapter::deSerialize(&deleteUpToUnixSeconds, &data, &size, + SerializeIF::Endianness::NETWORK); + deleteFromUpTo(deleteFromUnixSeconds, deleteUpToUnixSeconds); + } else { + sif::warning << "PersistentTmStore: Unknown deletion time specification" << std::endl; + return returnvalue::FAILED; + } + return returnvalue::OK; +} + +ReturnValue_t PersistentTmStore::handleDumpCmd(StorageManagerIF& ipcStore, + CommandMessage& cmdMessage) { + Clock::getClock_timeval(¤tTv); + store_address_t storeId = TmStoreMessage::getStoreId(&cmdMessage); + auto accessor = ipcStore.getData(storeId); + if (accessor.second.size() < 8) { + return returnvalue::FAILED; + } + uint32_t dumpFromUnixSeconds = 0; + uint32_t dumpUntilUnixSeconds = 0; + size_t size = 8; + SerializeAdapter::deSerialize(&dumpFromUnixSeconds, accessor.second.data(), &size, + SerializeIF::Endianness::NETWORK); + SerializeAdapter::deSerialize(&dumpUntilUnixSeconds, accessor.second.data() + 4, &size, + SerializeIF::Endianness::NETWORK); + ReturnValue_t result = startDumpFromUpTo(dumpFromUnixSeconds, dumpUntilUnixSeconds); + if (result == BUSY_DUMPING) { + triggerEvent(persTmStore::BUSY_DUMPING_EVENT); + return result; + } + return returnvalue::OK; +} + ReturnValue_t PersistentTmStore::startDumpFrom(uint32_t fromUnixSeconds) { return startDumpFromUpTo(fromUnixSeconds, currentTv.tv_sec); } diff --git a/mission/tmtc/PersistentTmStore.h b/mission/tmtc/PersistentTmStore.h index 4255b9d4..ccd6cbe6 100644 --- a/mission/tmtc/PersistentTmStore.h +++ b/mission/tmtc/PersistentTmStore.h @@ -14,6 +14,7 @@ #include "eive/eventSubsystemIds.h" #include "eive/resultClassIds.h" +#include "fsfw/ipc/CommandMessage.h" enum class RolloverInterval { MINUTELY, HOURLY, DAILY }; @@ -146,6 +147,8 @@ class PersistentTmStore : public TmStoreFrontendSimpleIF, public SystemObject { std::optional extractSuffix(const std::string& pathStr); bool updateBaseDir(); ReturnValue_t assignAndOrCreateMostRecentFile(); + ReturnValue_t handleDeletionCmd(StorageManagerIF& ipcStore, CommandMessage& cmdMessage); + ReturnValue_t handleDumpCmd(StorageManagerIF& ipcStore, CommandMessage& cmdMessage); }; #endif /* MISSION_TMTC_TMSTOREBACKEND_H_ */ From 699cbb98ccbf07e01358d34564aa0086396bccaa Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 16 Nov 2023 11:01:56 +0100 Subject: [PATCH 3/4] add additional allowed subservice --- mission/tmtc/Service15TmStorage.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/mission/tmtc/Service15TmStorage.cpp b/mission/tmtc/Service15TmStorage.cpp index 273c406b..efc9f2a6 100644 --- a/mission/tmtc/Service15TmStorage.cpp +++ b/mission/tmtc/Service15TmStorage.cpp @@ -17,6 +17,7 @@ Service15TmStorage::Service15TmStorage(object_id_t objectId, uint16_t apid, ReturnValue_t Service15TmStorage::isValidSubservice(uint8_t subservice) { switch (subservice) { case (Subservice::DELETE_UP_TO): + case (Subservice::DELETE_BY_TIME_RANGE): case (Subservice::START_BY_TIME_RANGE_RETRIEVAL): { return OK; } From 5348188f6b4267f8666948369987a11de8d25e3c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 16 Nov 2023 17:11:19 +0100 Subject: [PATCH 4/4] changelog --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 74bd77e3..66473ad9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,11 @@ will consitute of a breaking change warranting a new major release: # [unreleased] +## Added + +- Added new PUS 15 subservice `DELETE_BY_TIME_RANGE` which allows to also specify a deletion + start time when deleting packets from the persistent TM store. + # [v7.3.0] 2023-11-07 ## Changed