Persistent Tm Store now has dump state
This commit is contained in:
@ -1,6 +1,7 @@
|
||||
#include "PersistentTmStore.h"
|
||||
|
||||
#include <mission/memory/SdCardMountedIF.h>
|
||||
#include <mission/tmtc/DirectTmSinkIF.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cinttypes>
|
||||
@ -172,60 +173,122 @@ ReturnValue_t PersistentTmStore::startDumpFromUpTo(uint32_t fromUnixSeconds,
|
||||
if (state == State::DUMPING) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
activeDumpDirIter = directory_iterator(basePath);
|
||||
dumpParams.dirIter = directory_iterator(basePath);
|
||||
dumpParams.fromUnixTime = fromUnixSeconds;
|
||||
dumpParams.untilUnixTime = upToUnixSeconds;
|
||||
state = State::DUMPING;
|
||||
if (loadNextDumpFile() == DUMP_DONE) {
|
||||
// State will be set inside the function loading the next file.
|
||||
return DUMP_DONE;
|
||||
}
|
||||
return returnvalue::OK;
|
||||
// for (auto const& file : directory_iterator(basePath)) {
|
||||
// if (file.is_directory()) {
|
||||
// continue;
|
||||
// }
|
||||
// struct tm fileTime {};
|
||||
// if (pathToTm(file.path(), fileTime) != returnvalue::OK) {
|
||||
// sif::error << "Time extraction for file " << file << "failed" << std::endl;
|
||||
// continue;
|
||||
// }
|
||||
// auto fileEpoch = static_cast<uint32_t>(timegm(&fileTime));
|
||||
// if ((fileEpoch > fromUnixSeconds) and (fileEpoch + rolloverDiffSeconds <= upToUnixSeconds))
|
||||
// {
|
||||
// fileToPackets(file, fileEpoch);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
void PersistentTmStore::fileToPackets(const std::filesystem::path& path, uint32_t unixStamp) {
|
||||
store_address_t storeId;
|
||||
TmTcMessage message;
|
||||
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<char*>(fileBuf.data()), static_cast<std::streamsize>(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) {
|
||||
// TODO: Blow the data out to the VC directly. Use IF function to do this.
|
||||
// result = tmStore.addData(&storeId, fileBuf.data() + currentIdx,
|
||||
// reader.getFullPacketLen()); if (result != returnvalue::OK) {
|
||||
// continue;
|
||||
// }
|
||||
// funnel.sendPacketToLiveDestinations(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.
|
||||
ReturnValue_t PersistentTmStore::loadNextDumpFile() {
|
||||
using namespace std::filesystem;
|
||||
std::error_code e;
|
||||
for (; dumpParams.dirIter != directory_iterator(); dumpParams.dirIter++) {
|
||||
if (dumpParams.dirEntry.is_directory(e)) {
|
||||
continue;
|
||||
}
|
||||
dumpParams.fileSize = std::filesystem::file_size(dumpParams.dirEntry.path());
|
||||
// Can't even read CCSDS header.
|
||||
if (dumpParams.fileSize <= 6) {
|
||||
continue;
|
||||
}
|
||||
if (dumpParams.fileSize > fileBuf.size()) {
|
||||
sif::error << "PersistentTmStore: File too large, is deleted" << std::endl;
|
||||
triggerEvent(FILE_TOO_LARGE, dumpParams.fileSize, fileBuf.size());
|
||||
std::remove(dumpParams.dirEntry.path().c_str());
|
||||
continue;
|
||||
}
|
||||
const path& file = dumpParams.dirEntry.path();
|
||||
struct tm fileTime {};
|
||||
if (pathToTime(file, fileTime) != returnvalue::OK) {
|
||||
sif::error << "Time extraction for file " << file << "failed" << std::endl;
|
||||
continue;
|
||||
}
|
||||
auto fileEpoch = static_cast<uint32_t>(timegm(&fileTime));
|
||||
if ((fileEpoch > dumpParams.fromUnixTime) and
|
||||
(fileEpoch + rolloverDiffSeconds <= dumpParams.untilUnixTime)) {
|
||||
dumpParams.currentSize = 0;
|
||||
dumpParams.currentFileUnixStamp = fileEpoch;
|
||||
std::ifstream ifile(file, std::ios::binary);
|
||||
ifile.read(reinterpret_cast<char*>(fileBuf.data()),
|
||||
static_cast<std::streamsize>(dumpParams.fileSize));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (dumpParams.dirIter == directory_iterator()) {
|
||||
state = State::IDLE;
|
||||
return DUMP_DONE;
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t PersistentTmStore::dumpNextPacket(size_t& dumpedLen) {}
|
||||
// void PersistentTmStore::fileToPackets(const std::filesystem::path& path, uint32_t unixStamp) {
|
||||
// store_address_t storeId;
|
||||
// TmTcMessage message;
|
||||
// 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<char*>(fileBuf.data()), static_cast<std::streamsize>(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) {
|
||||
// // TODO: Blow the data out to the VC directly. Use IF function to do this.
|
||||
// // result = tmStore.addData(&storeId, fileBuf.data() + currentIdx,
|
||||
// // reader.getFullPacketLen()); if (result != returnvalue::OK) {
|
||||
// // continue;
|
||||
// // }
|
||||
// // funnel.sendPacketToLiveDestinations(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;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
ReturnValue_t PersistentTmStore::dumpNextPacket(DirectTmSinkIF& tmSink, size_t& dumpedLen) {
|
||||
if (state == State::IDLE) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
PusTmReader reader(&timeReader, fileBuf.data() + dumpParams.currentSize,
|
||||
fileBuf.size() - dumpParams.currentSize);
|
||||
// CRC check to fully ensure this is a valid TM
|
||||
ReturnValue_t result = reader.parseDataWithCrcCheck();
|
||||
if (result == returnvalue::OK) {
|
||||
result = tmSink.write(fileBuf.data() + dumpParams.currentSize, reader.getFullPacketLen());
|
||||
if (result != returnvalue::OK) {
|
||||
// TODO: Event?
|
||||
sif::error << "PersistentTmStore: Writing to TM sink failed" << std::endl;
|
||||
}
|
||||
dumpParams.currentSize += reader.getFullPacketLen();
|
||||
dumpedLen = reader.getFullPacketLen();
|
||||
if (dumpParams.currentSize >= dumpParams.fileSize) {
|
||||
return loadNextDumpFile();
|
||||
}
|
||||
} else {
|
||||
sif::error << "Parsing of PUS TM failed with code " << result << std::endl;
|
||||
triggerEvent(POSSIBLE_FILE_CORRUPTION, result, dumpParams.currentFileUnixStamp);
|
||||
// Delete the file and load next. Could use better algorithm to partially
|
||||
// restore the file dump, but for now do not trust the file.
|
||||
dumpedLen = 0;
|
||||
std::remove(dumpParams.dirEntry.path().c_str());
|
||||
return loadNextDumpFile();
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t PersistentTmStore::pathToTime(const std::filesystem::path& path, struct tm& time) {
|
||||
auto pathStr = path.string();
|
||||
|
Reference in New Issue
Block a user