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);