dir listing dump state machine
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-v3.0.0-dev This commit looks good

This commit is contained in:
Robin Müller 2023-06-07 14:20:58 +02:00
parent 5ca96b2dd3
commit 06b381d965
No known key found for this signature in database
GPG Key ID: 11D4952C8CCEF814
3 changed files with 87 additions and 20 deletions

View File

@ -112,6 +112,9 @@ void CoreController::performControlOperation() {
sdStateMachine(); sdStateMachine();
performMountedSdCardOperations(); performMountedSdCardOperations();
readHkData(); readHkData();
if (dumpContext.active) {
dirListingDumpHandler();
}
if (shellCmdIsExecuting) { if (shellCmdIsExecuting) {
bool replyReceived = false; bool replyReceived = false;
@ -1038,7 +1041,6 @@ ReturnValue_t CoreController::actionListDirectoryDumpDirectly(ActionId_t actionI
return returnvalue::FAILED; return returnvalue::FAILED;
} }
} }
std::array<uint8_t, 1024> dirListingBuf{};
dirListingBuf[8] = parser.compressionOptionSet(); dirListingBuf[8] = parser.compressionOptionSet();
// First four bytes reserved for segment index. One byte for compression option information // First four bytes reserved for segment index. One byte for compression option information
std::strcpy(reinterpret_cast<char *>(dirListingBuf.data() + 2 * sizeof(uint32_t) + 1), repoName); std::strcpy(reinterpret_cast<char *>(dirListingBuf.data() + 2 * sizeof(uint32_t) + 1), repoName);
@ -1047,38 +1049,46 @@ ReturnValue_t CoreController::actionListDirectoryDumpDirectly(ActionId_t actionI
return returnvalue::FAILED; return returnvalue::FAILED;
} }
std::error_code e; std::error_code e;
size_t totalFileSize = std::filesystem::file_size(LIST_DIR_DUMP_WORK_FILE, e); dumpContext.totalFileSize = std::filesystem::file_size(LIST_DIR_DUMP_WORK_FILE, e);
uint32_t segmentIdx = 0; dumpContext.segmentIdx = 0;
size_t dumpedBytes = 0; dumpContext.dumpedBytes = 0;
size_t nextDumpLen = 0; size_t nextDumpLen = 0;
size_t dummy = 0; size_t dummy = 0;
size_t maxDumpLen = dirListingBuf.size() - 2 * sizeof(uint32_t) - 1 - repoNameLen - 1; dumpContext.maxDumpLen = dirListingBuf.size() - 2 * sizeof(uint32_t) - 1 - repoNameLen - 1;
size_t listingDataOffset = 2 * sizeof(uint32_t) + 1 + repoNameLen + 1; dumpContext.listingDataOffset = 2 * sizeof(uint32_t) + 1 + repoNameLen + 1;
uint32_t chunks = totalFileSize / maxDumpLen; uint32_t chunks = dumpContext.totalFileSize / dumpContext.maxDumpLen;
if (totalFileSize % maxDumpLen != 0) { if (dumpContext.totalFileSize % dumpContext.maxDumpLen != 0) {
chunks++; chunks++;
} }
SerializeAdapter::serialize(&chunks, dirListingBuf.data() + sizeof(uint32_t), &dummy, SerializeAdapter::serialize(&chunks, dirListingBuf.data() + sizeof(uint32_t), &dummy,
dirListingBuf.size() - sizeof(uint32_t), dirListingBuf.size() - sizeof(uint32_t),
SerializeIF::Endianness::NETWORK); SerializeIF::Endianness::NETWORK);
while (dumpedBytes < totalFileSize) { while (dumpContext.dumpedBytes < dumpContext.totalFileSize) {
ifile.seekg(dumpedBytes, std::ios::beg); ifile.seekg(dumpContext.dumpedBytes, std::ios::beg);
nextDumpLen = maxDumpLen; nextDumpLen = dumpContext.maxDumpLen;
if (totalFileSize - dumpedBytes < maxDumpLen) { if (dumpContext.totalFileSize - dumpContext.dumpedBytes < dumpContext.maxDumpLen) {
nextDumpLen = totalFileSize - dumpedBytes; nextDumpLen = dumpContext.totalFileSize - dumpContext.dumpedBytes;
} }
SerializeAdapter::serialize(&segmentIdx, dirListingBuf.data(), &dummy, dirListingBuf.size(), SerializeAdapter::serialize(&dumpContext.segmentIdx, dirListingBuf.data(), &dummy,
SerializeIF::Endianness::NETWORK); dirListingBuf.size(), SerializeIF::Endianness::NETWORK);
ifile.read(reinterpret_cast<char *>(dirListingBuf.data() + listingDataOffset), nextDumpLen); ifile.read(reinterpret_cast<char *>(dirListingBuf.data() + dumpContext.listingDataOffset),
nextDumpLen);
result = actionHelper.reportData(commandedBy, actionId, dirListingBuf.data(), result = actionHelper.reportData(commandedBy, actionId, dirListingBuf.data(),
listingDataOffset + nextDumpLen); dumpContext.listingDataOffset + nextDumpLen);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
// Remove work file when we are done // Remove work file when we are done
std::filesystem::remove(LIST_DIR_DUMP_WORK_FILE, e); std::filesystem::remove(LIST_DIR_DUMP_WORK_FILE, e);
return result; return result;
} }
segmentIdx++; dumpContext.segmentIdx++;
dumpedBytes += nextDumpLen; dumpContext.dumpedBytes += nextDumpLen;
// Dump takes multiple task cycles, so cache the dump state and continue dump the next cycles.
if (dumpContext.segmentIdx == 25) {
dumpContext.active = true;
dumpContext.commander = commandedBy;
dumpContext.actionId = actionId;
return returnvalue::OK;
}
} }
// Remove work file when we are done // Remove work file when we are done
std::filesystem::remove(LIST_DIR_DUMP_WORK_FILE, e); std::filesystem::remove(LIST_DIR_DUMP_WORK_FILE, e);
@ -2346,6 +2356,50 @@ MessageQueueId_t CoreController::getCommandQueue() const {
return ExtendedControllerBase::getCommandQueue(); return ExtendedControllerBase::getCommandQueue();
} }
void CoreController::dirListingDumpHandler() {
size_t nextDumpLen = 0;
size_t dummy = 0;
ReturnValue_t result;
std::error_code e;
std::ifstream ifile(LIST_DIR_DUMP_WORK_FILE, std::ios::binary);
if (ifile.bad()) {
return;
}
while (dumpContext.dumpedBytes < dumpContext.totalFileSize) {
ifile.seekg(dumpContext.dumpedBytes, std::ios::beg);
nextDumpLen = dumpContext.maxDumpLen;
if (dumpContext.totalFileSize - dumpContext.dumpedBytes < dumpContext.maxDumpLen) {
nextDumpLen = dumpContext.totalFileSize - dumpContext.dumpedBytes;
}
SerializeAdapter::serialize(&dumpContext.segmentIdx, dirListingBuf.data(), &dummy,
dirListingBuf.size(), SerializeIF::Endianness::NETWORK);
ifile.read(reinterpret_cast<char *>(dirListingBuf.data() + dumpContext.listingDataOffset),
nextDumpLen);
result =
actionHelper.reportData(dumpContext.commander, dumpContext.actionId, dirListingBuf.data(),
dumpContext.listingDataOffset + nextDumpLen);
if (result != returnvalue::OK) {
// Remove work file when we are done
std::filesystem::remove(LIST_DIR_DUMP_WORK_FILE, e);
dumpContext.active = false;
actionHelper.finish(false, dumpContext.commander, dumpContext.actionId, result);
return;
}
dumpContext.segmentIdx++;
dumpContext.dumpedBytes += nextDumpLen;
// Dump takes multiple task cycles, so cache the dump state and continue dump the next cycles.
if (dumpContext.segmentIdx == 25) {
break;
}
}
if (dumpContext.dumpedBytes >= dumpContext.totalFileSize) {
actionHelper.finish(true, dumpContext.commander, dumpContext.actionId, result);
dumpContext.active = false;
// Remove work file when we are done
std::filesystem::remove(LIST_DIR_DUMP_WORK_FILE, e);
}
}
bool CoreController::isNumber(const std::string &s) { bool CoreController::isNumber(const std::string &s) {
return !s.empty() && std::find_if(s.begin(), s.end(), return !s.empty() && std::find_if(s.begin(), s.end(),
[](unsigned char c) { return !std::isdigit(c); }) == s.end(); [](unsigned char c) { return !std::isdigit(c); }) == s.end();

View File

@ -177,6 +177,19 @@ class CoreController : public ExtendedControllerBase, public ReceivesParameterMe
DeviceCommandId_t actionId; DeviceCommandId_t actionId;
} sdCommandingInfo; } sdCommandingInfo;
struct DirListingDumpContext {
bool active;
size_t dumpedBytes;
size_t totalFileSize;
size_t listingDataOffset;
size_t maxDumpLen;
uint32_t segmentIdx;
MessageQueueId_t commander = MessageQueueIF::NO_QUEUE;
DeviceCommandId_t actionId;
};
std::array<uint8_t, 1024> dirListingBuf{};
DirListingDumpContext dumpContext{};
RebootFile rebootFile = {}; RebootFile rebootFile = {};
CommandExecutor cmdExecutor; CommandExecutor cmdExecutor;
@ -274,6 +287,7 @@ class CoreController : public ExtendedControllerBase, public ReceivesParameterMe
void rewriteRebootFile(RebootFile file); void rewriteRebootFile(RebootFile file);
void announceBootCounts(); void announceBootCounts();
void readHkData(); void readHkData();
void dirListingDumpHandler();
bool isNumber(const std::string& s); bool isNumber(const std::string& s);
}; };

View File

@ -3,7 +3,6 @@
#include <cmath> #include <cmath>
class ActuatorCmd { class ActuatorCmd {
public: public:
ActuatorCmd(); ActuatorCmd();