CHANGELOG + FS helpers
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-develop This commit looks good

This commit is contained in:
2023-04-15 13:01:41 +02:00
parent 22370e3e1e
commit b8d010cd39
4 changed files with 379 additions and 42 deletions

View File

@ -32,7 +32,6 @@ static constexpr char VERSION_FILE_NAME[] = "version.txt";
static constexpr char REBOOT_FILE_NAME[] = "reboot.txt";
static constexpr char TIME_FILE_NAME[] = "time_backup.txt";
static constexpr ActionId_t LIST_DIRECTORY_INTO_FILE = 0;
static constexpr ActionId_t ANNOUNCE_VERSION = 1;
static constexpr ActionId_t ANNOUNCE_CURRENT_IMAGE = 2;
static constexpr ActionId_t ANNOUNCE_BOOT_COUNTS = 3;
@ -59,6 +58,12 @@ static constexpr ActionId_t EXECUTE_SHELL_CMD_BLOCKING = 40;
static constexpr ActionId_t EXECUTE_SHELL_CMD_NON_BLOCKING = 41;
static constexpr ActionId_t SYSTEMCTL_CMD_EXECUTOR = 42;
static constexpr ActionId_t LIST_DIRECTORY_INTO_FILE = 50;
static constexpr ActionId_t LIST_DIRECTORY_DUMP_DIRECTLY = 51;
static constexpr ActionId_t CP_HELPER = 52;
static constexpr ActionId_t MV_HELPER = 53;
static constexpr ActionId_t RM_HELPER = 54;
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CORE;
static constexpr Event ALLOC_FAILURE = event::makeEvent(SUBSYSTEM_ID, 0, severity::MEDIUM);
@ -96,6 +101,198 @@ static constexpr Event I2C_REBOOT = event::makeEvent(SUBSYSTEM_ID, 11, severity:
//! [EXPORT] : [COMMENT] PDEC recovery through reset was not possible, performing full reboot.
static constexpr Event PDEC_REBOOT = event::makeEvent(SUBSYSTEM_ID, 12, severity::HIGH);
class ListDirectoryCmdBase {
public: // TODO: Packet definition for clean deserialization
// 3 bytes for a and R flag, at least 5 bytes for minimum valid path /tmp with
// null termination
static constexpr size_t MIN_DATA_LEN = 8;
ListDirectoryCmdBase(const uint8_t* data, size_t maxSize) : data(data), maxSize(maxSize) {}
virtual ~ListDirectoryCmdBase() = default;
virtual ReturnValue_t parse() {
if (maxSize < MIN_DATA_LEN) {
return SerializeIF::STREAM_TOO_SHORT;
}
aFlag = data[0];
rFlag = data[1];
compressOption = data[2];
repoNameLen = strnlen(reinterpret_cast<const char*>(data + 3), maxSize - 3);
// Last byte MUST be null terminated!
if (repoNameLen >= maxSize - 3) {
return HasActionsIF::INVALID_PARAMETERS;
}
repoName = reinterpret_cast<const char*>(data + 3);
return returnvalue::OK;
}
bool aFlagSet() const { return this->aFlag; }
bool rFlagSet() const { return this->rFlag; }
bool compressionOptionSet() const { return this->compressOption; }
const char* getRepoName(size_t& repoNameLen) const {
return this->repoName;
repoNameLen = this->repoNameLen;
}
size_t getBaseSize() {
// Include NULL termination
if (repoName != nullptr) {
return 3 + repoNameLen + 1;
}
return 0;
}
protected:
const uint8_t* data;
size_t maxSize;
bool aFlag = false;
bool rFlag = false;
bool compressOption = false;
const char* repoName = nullptr;
size_t repoNameLen = 0;
};
class ListDirectoryIntoFile : public ListDirectoryCmdBase {
public:
// TODO: Packet definition for clean deserialization
// 3 bytes for a and R flag, at least 5 bytes for minimum valid path /tmp with
// null termination, at least 7 bytes for minimum target file name /tmp/a with
// null termination.
static constexpr size_t MIN_DATA_LEN = 15;
ListDirectoryIntoFile(const uint8_t* data, size_t maxSize)
: ListDirectoryCmdBase(data, maxSize) {}
ReturnValue_t parse() override {
if (maxSize < MIN_DATA_LEN) {
return SerializeIF::STREAM_TOO_SHORT;
}
ReturnValue_t result = ListDirectoryCmdBase::parse();
if (result != returnvalue::OK) {
return result;
}
targetNameLen =
strnlen(reinterpret_cast<const char*>(data + getBaseSize()), maxSize - getBaseSize());
if (targetNameLen >= maxSize - getBaseSize()) {
// Again: String MUST be null terminated.
return HasActionsIF::INVALID_PARAMETERS;
}
targetName = reinterpret_cast<const char*>(data + getBaseSize());
return result;
}
const char* getTargetName(size_t& targetNameLen) const {
return this->targetName;
targetNameLen = this->targetNameLen;
}
private:
const char* targetName = nullptr;
size_t targetNameLen = 0;
};
struct SourceTargetPair {
const char* sourceName = nullptr;
size_t sourceNameSize = 0;
const char* targetName = nullptr;
size_t targetNameSize = 0;
};
static ReturnValue_t parseDestTargetString(const uint8_t* data, size_t maxLen,
SourceTargetPair& destTgt) {
if (maxLen < 4) {
return SerializeIF::STREAM_TOO_SHORT;
}
destTgt.sourceNameSize = strnlen(reinterpret_cast<const char*>(data), maxLen);
if (destTgt.sourceNameSize >= maxLen) {
return HasActionsIF::INVALID_PARAMETERS;
}
destTgt.sourceName = reinterpret_cast<const char*>(data);
size_t remainingLen = maxLen - destTgt.sourceNameSize + 1;
if (remainingLen == 0) {
return HasActionsIF::INVALID_PARAMETERS;
}
destTgt.targetNameSize =
strnlen(reinterpret_cast<const char*>(data + destTgt.sourceNameSize + 1), remainingLen);
if (destTgt.targetNameSize >= remainingLen) {
return HasActionsIF::INVALID_PARAMETERS;
}
destTgt.targetName = reinterpret_cast<const char*>(data + destTgt.targetNameSize + 1);
return returnvalue::OK;
}
class CpHelperParser {
public:
CpHelperParser(const uint8_t* data, size_t maxLen) : data(data), maxLen(maxLen) {}
ReturnValue_t parse() {
if (maxLen < 1) {
return SerializeIF::STREAM_TOO_SHORT;
}
recursiveOpt = data[0];
return parseDestTargetString(data + 1, maxLen - 1, destTgt);
}
const SourceTargetPair& destTgtPair() const { return destTgt; }
bool isRecursiveOptSet() const { return recursiveOpt; }
private:
const uint8_t* data;
size_t maxLen;
bool recursiveOpt = false;
SourceTargetPair destTgt;
};
class MvHelperParser {
public:
MvHelperParser(const uint8_t* data, size_t maxLen) : data(data), maxLen(maxLen) {}
ReturnValue_t parse() { return parseDestTargetString(data, maxLen, destTgt); }
const SourceTargetPair& destTgtPair() const { return destTgt; }
private:
const uint8_t* data;
size_t maxLen;
SourceTargetPair destTgt;
};
class RmHelperParser {
public:
RmHelperParser(const uint8_t* data, size_t maxLen) : data(data), maxLen(maxLen) {}
ReturnValue_t parse() {
if (maxLen < 2) {
return SerializeIF::STREAM_TOO_SHORT;
}
recursiveOpt = data[0];
forceOpt = data[1];
removeTargetSize = strnlen(reinterpret_cast<const char*>(data + 2), maxLen - 2);
// Must be null-terminated
if (removeTargetSize >= maxLen - 2) {
return HasActionsIF::INVALID_PARAMETERS;
}
removeTarget = reinterpret_cast<const char*>(data + 2);
return returnvalue::OK;
}
bool isRecursiveOptSet() const { return recursiveOpt; }
bool isForceOptSet() const { return forceOpt; }
const char* getRemoveTarget(size_t& removeTargetSize) {
removeTargetSize = this->removeTargetSize;
return removeTarget;
}
private:
const uint8_t* data;
size_t maxLen;
bool recursiveOpt = false;
bool forceOpt = false;
const char* removeTarget = nullptr;
size_t removeTargetSize = 0;
};
} // namespace core
#endif /* MISSION_SYSDEFS_H_ */