Added OBSW Watchdog #67
@ -15,8 +15,12 @@
|
|||||||
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
|
CoreController::Chip CoreController::currentChip = Chip::NO_CHIP;
|
||||||
|
CoreController::Copy CoreController::currentCopy = Copy::NO_COPY;
|
||||||
|
|
||||||
CoreController::CoreController(object_id_t objectId):
|
CoreController::CoreController(object_id_t objectId):
|
||||||
ExtendedControllerBase(objectId, objects::NO_OBJECT, 5) {
|
ExtendedControllerBase(objectId, objects::NO_OBJECT, 5) {
|
||||||
|
initBootCopy();
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t CoreController::handleCommandMessage(CommandMessage *message) {
|
ReturnValue_t CoreController::handleCommandMessage(CommandMessage *message) {
|
||||||
@ -136,51 +140,11 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_
|
|||||||
const uint8_t *data, size_t size) {
|
const uint8_t *data, size_t size) {
|
||||||
switch(actionId) {
|
switch(actionId) {
|
||||||
case(LIST_DIRECTORY_INTO_FILE): {
|
case(LIST_DIRECTORY_INTO_FILE): {
|
||||||
// TODO: Packet definition for clean deserialization
|
return actionListDirectoryIntoFile(actionId, commandedBy, data, size);
|
||||||
// 2 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.
|
|
||||||
if(size < 14) {
|
|
||||||
return HasActionsIF::INVALID_PARAMETERS;
|
|
||||||
}
|
}
|
||||||
// We could also make -l optional, but I can't think of a reason why to not use -l..
|
case(REBOOT_OBC): {
|
||||||
|
|
||||||
// This flag specifies to run ls with -a
|
|
||||||
bool aFlag = data[0];
|
|
||||||
data += 1;
|
|
||||||
// This flag specifies to run ls with -R
|
|
||||||
bool RFlag = data[1];
|
|
||||||
data += 1;
|
|
||||||
|
|
||||||
size_t remainingSize = size - 2;
|
|
||||||
// One larger for null termination, which prevents undefined behaviour if the sent
|
|
||||||
// strings are not 0 terminated properly
|
|
||||||
std::vector<uint8_t> repoAndTargetFileBuffer(remainingSize + 1, 0);
|
|
||||||
std::memcpy(repoAndTargetFileBuffer.data(), data, remainingSize);
|
|
||||||
const char* currentCharPtr = reinterpret_cast<const char*>(repoAndTargetFileBuffer.data());
|
|
||||||
// Full target file name
|
|
||||||
std::string repoName(currentCharPtr);
|
|
||||||
size_t repoLength = repoName.length();
|
|
||||||
// The other string needs to be at least one letter plus NULL termination to be valid at all
|
|
||||||
// The first string also needs to be NULL terminated, but the termination is not included
|
|
||||||
// in the string length, so this is subtracted from the remaining size as well
|
|
||||||
if(repoLength > remainingSize - 3) {
|
|
||||||
return HasActionsIF::INVALID_PARAMETERS;
|
|
||||||
}
|
|
||||||
// The file length will not include the NULL termination, so we skip it
|
|
||||||
currentCharPtr += repoLength + 1;
|
|
||||||
std::string targetFileName(currentCharPtr);
|
|
||||||
std::ostringstream oss;
|
|
||||||
oss << "ls -l";
|
|
||||||
if(aFlag) {
|
|
||||||
oss << "a";
|
|
||||||
}
|
|
||||||
if(RFlag) {
|
|
||||||
oss << "R";
|
|
||||||
}
|
|
||||||
oss << " " << repoName << " > " << targetFileName;
|
|
||||||
std::system(oss.str().c_str());
|
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
return HasActionsIF::INVALID_ACTION_ID;
|
return HasActionsIF::INVALID_ACTION_ID;
|
||||||
@ -189,7 +153,7 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t CoreController::initializeAfterTaskCreation() {
|
ReturnValue_t CoreController::initializeAfterTaskCreation() {
|
||||||
ReturnValue_t result = versionFileInit();
|
ReturnValue_t result = initVersionFile();
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
sif::warning << "CoreController::initialize: Version initialization failed" << std::endl;
|
sif::warning << "CoreController::initialize: Version initialization failed" << std::endl;
|
||||||
}
|
}
|
||||||
@ -272,7 +236,7 @@ ReturnValue_t CoreController::incrementAllocationFailureCount() {
|
|||||||
return scratch::writeNumber(scratch::ALLOC_FAILURE_COUNT, count);
|
return scratch::writeNumber(scratch::ALLOC_FAILURE_COUNT, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t CoreController::versionFileInit() {
|
ReturnValue_t CoreController::initVersionFile() {
|
||||||
|
|
||||||
std::string unameFileName = "/tmp/uname_version.txt";
|
std::string unameFileName = "/tmp/uname_version.txt";
|
||||||
// TODO: No -v flag for now. If the kernel version is used, need to cut off first few letters
|
// TODO: No -v flag for now. If the kernel version is used, need to cut off first few letters
|
||||||
@ -356,6 +320,86 @@ ReturnValue_t CoreController::versionFileInit() {
|
|||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReturnValue_t CoreController::actionListDirectoryIntoFile(ActionId_t actionId,
|
||||||
|
MessageQueueId_t commandedBy, const uint8_t *data, size_t size) {
|
||||||
|
// TODO: Packet definition for clean deserialization
|
||||||
|
// 2 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.
|
||||||
|
if(size < 14) {
|
||||||
|
return HasActionsIF::INVALID_PARAMETERS;
|
||||||
|
}
|
||||||
|
// We could also make -l optional, but I can't think of a reason why to not use -l..
|
||||||
|
|
||||||
|
// This flag specifies to run ls with -a
|
||||||
|
bool aFlag = data[0];
|
||||||
|
data += 1;
|
||||||
|
// This flag specifies to run ls with -R
|
||||||
|
bool RFlag = data[1];
|
||||||
|
data += 1;
|
||||||
|
|
||||||
|
size_t remainingSize = size - 2;
|
||||||
|
// One larger for null termination, which prevents undefined behaviour if the sent
|
||||||
|
// strings are not 0 terminated properly
|
||||||
|
std::vector<uint8_t> repoAndTargetFileBuffer(remainingSize + 1, 0);
|
||||||
|
std::memcpy(repoAndTargetFileBuffer.data(), data, remainingSize);
|
||||||
|
const char* currentCharPtr = reinterpret_cast<const char*>(repoAndTargetFileBuffer.data());
|
||||||
|
// Full target file name
|
||||||
|
std::string repoName(currentCharPtr);
|
||||||
|
size_t repoLength = repoName.length();
|
||||||
|
// The other string needs to be at least one letter plus NULL termination to be valid at all
|
||||||
|
// The first string also needs to be NULL terminated, but the termination is not included
|
||||||
|
// in the string length, so this is subtracted from the remaining size as well
|
||||||
|
if(repoLength > remainingSize - 3) {
|
||||||
|
return HasActionsIF::INVALID_PARAMETERS;
|
||||||
|
}
|
||||||
|
// The file length will not include the NULL termination, so we skip it
|
||||||
|
currentCharPtr += repoLength + 1;
|
||||||
|
std::string targetFileName(currentCharPtr);
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << "ls -l";
|
||||||
|
if(aFlag) {
|
||||||
|
oss << "a";
|
||||||
|
}
|
||||||
|
if(RFlag) {
|
||||||
|
oss << "R";
|
||||||
|
}
|
||||||
|
oss << " " << repoName << " > " << targetFileName;
|
||||||
|
int result = std::system(oss.str().c_str());
|
||||||
|
if(result != 0) {
|
||||||
|
utility::handleSystemError(result, "CoreController::actionListDirectoryIntoFile");
|
||||||
|
actionHelper.finish(false, commandedBy, actionId);
|
||||||
|
}
|
||||||
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t CoreController::initBootCopy() {
|
||||||
|
std::string fileName = "/tmp/curr_copy.txt";
|
||||||
|
std::string cmd = "xsc_boot_copy > " + fileName;
|
||||||
|
int result = std::system(cmd.c_str());
|
||||||
|
if(result != 0) {
|
||||||
|
utility::handleSystemError(result, "CoreController::initBootCopy");
|
||||||
|
}
|
||||||
|
std::ifstream file(fileName);
|
||||||
|
std::string line;
|
||||||
|
std::getline(file, line);
|
||||||
|
std::istringstream iss(line);
|
||||||
|
int value = 0;
|
||||||
|
iss >> value;
|
||||||
|
currentChip = static_cast<Chip>(value);
|
||||||
|
sif::debug << "Current chip: " << currentChip << std::endl;
|
||||||
|
iss >> value;
|
||||||
|
currentCopy = static_cast<Copy>(value);
|
||||||
|
sif::debug << "Current chip: " << currentCopy << std::endl;
|
||||||
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CoreController::getCurrentBootCopy(Chip &chip, Copy ©) {
|
||||||
|
// Not really thread-safe but it does not need to be
|
||||||
|
chip = currentChip;
|
||||||
|
copy = currentCopy;
|
||||||
|
}
|
||||||
|
|
||||||
void CoreController::initPrint() {
|
void CoreController::initPrint() {
|
||||||
#if OBSW_VERBOSE_LEVEL >= 1
|
#if OBSW_VERBOSE_LEVEL >= 1
|
||||||
#if OBSW_USE_TMTC_TCP_BRIDGE == 0
|
#if OBSW_USE_TMTC_TCP_BRIDGE == 0
|
||||||
|
@ -6,14 +6,30 @@
|
|||||||
|
|
||||||
#include "events/subsystemIdRanges.h"
|
#include "events/subsystemIdRanges.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class CoreController: public ExtendedControllerBase {
|
class CoreController: public ExtendedControllerBase {
|
||||||
public:
|
public:
|
||||||
|
enum Chip: uint8_t {
|
||||||
|
CHIP_0,
|
||||||
|
CHIP_1,
|
||||||
|
NO_CHIP
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Copy: uint8_t {
|
||||||
|
COPY_0,
|
||||||
|
COPY_1,
|
||||||
|
NO_COPY
|
||||||
|
};
|
||||||
|
|
||||||
static constexpr ActionId_t LIST_DIRECTORY_INTO_FILE = 0;
|
static constexpr ActionId_t LIST_DIRECTORY_INTO_FILE = 0;
|
||||||
|
static constexpr ActionId_t REBOOT_OBC = 1;
|
||||||
|
|
||||||
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CORE;
|
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CORE;
|
||||||
|
|
||||||
static constexpr Event ALLOC_FAILURE = event::makeEvent(SUBSYSTEM_ID, 0, severity::MEDIUM);
|
static constexpr Event ALLOC_FAILURE = event::makeEvent(SUBSYSTEM_ID, 0, severity::MEDIUM);
|
||||||
|
|
||||||
|
|
||||||
CoreController(object_id_t objectId);
|
CoreController(object_id_t objectId);
|
||||||
|
|
||||||
ReturnValue_t initialize() override;
|
ReturnValue_t initialize() override;
|
||||||
@ -27,7 +43,12 @@ public:
|
|||||||
void performControlOperation() override;
|
void performControlOperation() override;
|
||||||
|
|
||||||
static ReturnValue_t incrementAllocationFailureCount();
|
static ReturnValue_t incrementAllocationFailureCount();
|
||||||
|
static void getCurrentBootCopy(Chip& chip, Copy& copy);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static Chip currentChip;
|
||||||
|
static Copy currentCopy;
|
||||||
|
|
||||||
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||||
LocalDataPoolManager& poolManager) override;
|
LocalDataPoolManager& poolManager) override;
|
||||||
LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
|
LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
|
||||||
@ -40,7 +61,12 @@ private:
|
|||||||
ReturnValue_t sdCardColdRedundantInit(SdCardManager* sdcMan,
|
ReturnValue_t sdCardColdRedundantInit(SdCardManager* sdcMan,
|
||||||
SdCardManager::SdStatusPair& statusPair);
|
SdCardManager::SdStatusPair& statusPair);
|
||||||
|
|
||||||
ReturnValue_t versionFileInit();
|
ReturnValue_t initVersionFile();
|
||||||
|
ReturnValue_t initBootCopy();
|
||||||
|
|
||||||
|
ReturnValue_t actionListDirectoryIntoFile(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||||
|
const uint8_t *data, size_t size);
|
||||||
|
|
||||||
void initPrint();
|
void initPrint();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user