Merge pull request 'Persistent TM store delete time range' (#823) from persistent-tm-store-delete-time-range into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #823 Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
This commit is contained in:
commit
f23debceac
4
.gitignore
vendored
4
.gitignore
vendored
@ -22,3 +22,7 @@ __pycache__
|
||||
!/.idea/cmake.xml
|
||||
|
||||
generators/*.db
|
||||
|
||||
# Clangd LSP
|
||||
/compile_commands.json
|
||||
/.cache
|
||||
|
@ -24,6 +24,8 @@ will consitute of a breaking change warranting a new major release:
|
||||
|
||||
## 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.
|
||||
- Introduced a new `RELOAD_JSON_CFG_FILE` command for the STR to reload the JSON configuration
|
||||
data based on the current output of the config file path getter function. A reboot of the
|
||||
device is still necessary to load the configuration to the STR.
|
||||
|
@ -137,40 +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);
|
||||
uint32_t deleteUpToUnixSeconds = 0;
|
||||
size_t size = accessor.second.size();
|
||||
SerializeAdapter::deSerialize(&deleteUpToUnixSeconds, accessor.second.data(), &size,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
result = handleDeletionCmd(ipcStore, cmdMessage);
|
||||
execCmd = cmd;
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
@ -257,7 +285,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 +300,8 @@ void PersistentTmStore::deleteUpTo(uint32_t unixSeconds) {
|
||||
continue;
|
||||
}
|
||||
time_t fileEpoch = timegm(&fileTime);
|
||||
if (fileEpoch + rolloverDiffSeconds < unixSeconds) {
|
||||
if (fileEpoch + rolloverDiffSeconds < endUnixTime and
|
||||
static_cast<uint32_t>(fileEpoch) >= startUnixTime) {
|
||||
std::error_code e;
|
||||
std::filesystem::remove(file.path(), e);
|
||||
}
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
#include "eive/eventSubsystemIds.h"
|
||||
#include "eive/resultClassIds.h"
|
||||
#include "fsfw/ipc/CommandMessage.h"
|
||||
|
||||
enum class RolloverInterval { MINUTELY, HOURLY, DAILY };
|
||||
|
||||
@ -60,6 +61,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);
|
||||
/**
|
||||
@ -145,6 +147,8 @@ class PersistentTmStore : public TmStoreFrontendSimpleIF, public SystemObject {
|
||||
std::optional<uint8_t> 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_ */
|
||||
|
@ -16,8 +16,9 @@ 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::DELETE_BY_TIME_RANGE):
|
||||
case (Subservice::START_BY_TIME_RANGE_RETRIEVAL): {
|
||||
return OK;
|
||||
}
|
||||
default: {
|
||||
@ -45,34 +46,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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
2
tmtc
2
tmtc
@ -1 +1 @@
|
||||
Subproject commit 99c6c8bbd0d791d8b17720de481c6142091a54a4
|
||||
Subproject commit 0a417a89e9e7f0447d35c70950685df59bf5c062
|
Loading…
Reference in New Issue
Block a user