#ifndef MISSION_TMTC_TMSTOREBACKEND_H_ #define MISSION_TMTC_TMSTOREBACKEND_H_ #include #include #include #include #include #include #include #include #include "eive/eventSubsystemIds.h" #include "eive/resultClassIds.h" enum class RolloverInterval { MINUTELY, HOURLY, DAILY }; struct PersistentTmStoreArgs { PersistentTmStoreArgs(object_id_t objectId, const char* baseDir, std::string baseName, RolloverInterval intervalUnit, uint32_t intervalCount, StorageManagerIF& tmStore, SdCardMountedIF& sdcMan) : objectId(objectId), baseDir(baseDir), baseName(baseName), intervalUnit(intervalUnit), intervalCount(intervalCount), tmStore(tmStore), sdcMan(sdcMan) {} object_id_t objectId; const char* baseDir; std::string baseName; RolloverInterval intervalUnit; uint32_t intervalCount; StorageManagerIF& tmStore; SdCardMountedIF& sdcMan; }; class PersistentTmStore : public TmStoreFrontendSimpleIF, public SystemObject { public: enum class State { IDLE, DUMPING }; static constexpr uint8_t INTERFACE_ID = CLASS_ID::PERSISTENT_TM_STORE; static constexpr ReturnValue_t DUMP_DONE = returnvalue::makeCode(INTERFACE_ID, 0); static constexpr ReturnValue_t BUSY_DUMPING = returnvalue::makeCode(INTERFACE_ID, 1); PersistentTmStore(PersistentTmStoreArgs args); ReturnValue_t initializeTmStore(); State getState() const; ReturnValue_t handleCommandQueue(StorageManagerIF& ipcStore, Command_t& execCmd); void deleteUpTo(uint32_t unixSeconds); ReturnValue_t startDumpFrom(uint32_t fromUnixSeconds); ReturnValue_t startDumpFromUpTo(uint32_t fromUnixSeconds, uint32_t upToUnixSeconds); /** * * @param tmReader: Next packet will be loaded into the PUS TM reader. A CRC check will be * performed on the packet. If that check fails, the file is considered corrupted and will * be deleted for now. * @param fileHasSwapped: If the CRC check fails, the file will be deleted and a new one has to * be loaded. The dump can reach completion during that process. If a file is swapped, this * boolean is set to true * @return DUMP_DONE if dump is finished, returnvalue::OK if the next packet was loaded into the * TM reader, and the returnvalue of the file swap operation if the CRC check failed and * a new file was loaded. */ ReturnValue_t getNextDumpPacket(PusTmReader& tmReader, bool& fileHasSwapped); /** * Confirm the dump to advance the dump state machine. * @param tmReader * @param fileHasSwapped: If the confirmed dumps completes the current file, a new file will * be loaded and this parameter will be set to true. * @return If a file is swapped, the retrunvalue of the file swap operation. */ ReturnValue_t confirmDump(const PusTmReader& tmReader, bool& fileHasSwapped); void getStartAndEndTimeCurrentOrLastDump(uint32_t& startTime, uint32_t& endTime) const; ReturnValue_t storePacket(PusTmReader& reader); ReturnValue_t cancelDump(); protected: StorageManagerIF& tmStore; 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"; //! [EXPORT] : [SKIP] static constexpr ReturnValue_t INVALID_FILE_DETECTED_AND_DELETED = returnvalue::makeCode(2, 1); MessageQueueIF* tcQueue; State state = State::IDLE; 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 activeFileTv{}; struct ActiveDumpParams { bool pendingPacketDump = false; uint32_t fromUnixTime = 0; uint32_t untilUnixTime = 0; uint32_t currentFileUnixStamp = 0; std::filesystem::directory_iterator dirIter; std::filesystem::directory_entry dirEntry; size_t fileSize = 0; size_t currentSize = 0; }; ActiveDumpParams dumpParams; std::optional activeFile; SdCardMountedIF& sdcMan; /** * 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); ReturnValue_t createMostRecentFile(std::optional suffix); static ReturnValue_t pathToTime(const std::filesystem::path& path, struct tm& time); void fileToPackets(const std::filesystem::path& path, uint32_t unixStamp); ReturnValue_t loadNextDumpFile(); bool updateBaseDir(); ReturnValue_t assignAndOrCreateMostRecentFile(); }; #endif /* MISSION_TMTC_TMSTOREBACKEND_H_ */