Merge pull request 'systemctl helper' (#596) from feature_systemctl_helper into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #596 Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
This commit is contained in:
commit
a7c227f8ea
@ -25,6 +25,7 @@ will consitute of a breaking change warranting a new major release:
|
|||||||
bytes were not written properly.
|
bytes were not written properly.
|
||||||
- Bugfix for STR where an invalid reply was received for special requests
|
- Bugfix for STR where an invalid reply was received for special requests
|
||||||
like firmware updates.
|
like firmware updates.
|
||||||
|
- Bugfix for shell command executors in command controller which lead to a crash.
|
||||||
|
|
||||||
## Added
|
## Added
|
||||||
|
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
#include "fsfw/timemanager/Stopwatch.h"
|
#include "fsfw/timemanager/Stopwatch.h"
|
||||||
#include "fsfw/version.h"
|
#include "fsfw/version.h"
|
||||||
#include "mission/sysDefs.h"
|
|
||||||
#include "watchdog/definitions.h"
|
#include "watchdog/definitions.h"
|
||||||
#if OBSW_ADD_TMTC_UDP_SERVER == 1
|
#if OBSW_ADD_TMTC_UDP_SERVER == 1
|
||||||
#include "fsfw/osal/common/UdpTmTcBridge.h"
|
#include "fsfw/osal/common/UdpTmTcBridge.h"
|
||||||
@ -118,7 +117,7 @@ void CoreController::performControlOperation() {
|
|||||||
bool replyReceived = false;
|
bool replyReceived = false;
|
||||||
// TODO: We could read the data in the ring buffer and send it as an action data reply.
|
// TODO: We could read the data in the ring buffer and send it as an action data reply.
|
||||||
if (cmdExecutor.check(replyReceived) == CommandExecutor::EXECUTION_FINISHED) {
|
if (cmdExecutor.check(replyReceived) == CommandExecutor::EXECUTION_FINISHED) {
|
||||||
actionHelper.finish(true, successRecipient, core::EXECUTE_SHELL_CMD);
|
actionHelper.finish(true, successRecipient, core::EXECUTE_SHELL_CMD_BLOCKING);
|
||||||
shellCmdIsExecuting = false;
|
shellCmdIsExecuting = false;
|
||||||
cmdReplyBuf.clear();
|
cmdReplyBuf.clear();
|
||||||
while (not cmdRepliesSizes.empty()) {
|
while (not cmdRepliesSizes.empty()) {
|
||||||
@ -304,6 +303,41 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_
|
|||||||
// Completion will be reported by SD card state machine
|
// Completion will be reported by SD card state machine
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
case (SYSTEMCTL_CMD_EXECUTOR): {
|
||||||
|
// Expect one byte systemctl command type and a unit name with at least one byte as minimum.
|
||||||
|
if (size < 2) {
|
||||||
|
return HasActionsIF::INVALID_PARAMETERS;
|
||||||
|
}
|
||||||
|
if (data[0] >= core::SystemctlCmd::NUM_CMDS) {
|
||||||
|
return HasActionsIF::INVALID_PARAMETERS;
|
||||||
|
}
|
||||||
|
core::SystemctlCmd cmdType = static_cast<core::SystemctlCmd>(data[0]);
|
||||||
|
std::string unitName = std::string(reinterpret_cast<const char *>(data + 1), size - 1);
|
||||||
|
std::ostringstream oss("systemctl ", std::ostringstream::ate);
|
||||||
|
switch (cmdType) {
|
||||||
|
case (core::SystemctlCmd::START): {
|
||||||
|
oss << "start ";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (core::SystemctlCmd::STOP): {
|
||||||
|
oss << "stop ";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (core::SystemctlCmd::RESTART): {
|
||||||
|
oss << "restart ";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return HasActionsIF::INVALID_PARAMETERS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
oss << unitName;
|
||||||
|
int result = std::system(oss.str().c_str());
|
||||||
|
if (result != 0) {
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
return EXECUTION_FINISHED;
|
||||||
|
}
|
||||||
case (SWITCH_IMG_LOCK): {
|
case (SWITCH_IMG_LOCK): {
|
||||||
if (size != 3) {
|
if (size != 3) {
|
||||||
return HasActionsIF::INVALID_PARAMETERS;
|
return HasActionsIF::INVALID_PARAMETERS;
|
||||||
@ -334,13 +368,22 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_
|
|||||||
// Warning: This function will never return, because it reboots the system
|
// Warning: This function will never return, because it reboots the system
|
||||||
return actionReboot(data, size);
|
return actionReboot(data, size);
|
||||||
}
|
}
|
||||||
case (EXECUTE_SHELL_CMD): {
|
case (EXECUTE_SHELL_CMD_BLOCKING): {
|
||||||
std::string cmd = std::string(cmd, size);
|
std::string cmdToExecute = std::string(reinterpret_cast<const char*>(data), size);
|
||||||
|
int result = std::system(cmdToExecute.c_str());
|
||||||
|
if (result != 0) {
|
||||||
|
// TODO: Data reply with returnalue maybe?
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
return EXECUTION_FINISHED;
|
||||||
|
}
|
||||||
|
case (EXECUTE_SHELL_CMD_NON_BLOCKING): {
|
||||||
|
std::string cmdToExecute = std::string(reinterpret_cast<const char*>(data), size);
|
||||||
if (cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING or
|
if (cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING or
|
||||||
shellCmdIsExecuting) {
|
shellCmdIsExecuting) {
|
||||||
return HasActionsIF::IS_BUSY;
|
return HasActionsIF::IS_BUSY;
|
||||||
}
|
}
|
||||||
cmdExecutor.load(cmd, false, false);
|
cmdExecutor.load(cmdToExecute, false, false);
|
||||||
ReturnValue_t result = cmdExecutor.execute();
|
ReturnValue_t result = cmdExecutor.execute();
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
@ -1308,7 +1351,7 @@ void CoreController::performMountedSdCardOperations() {
|
|||||||
auto mountedSdCardOp = [&](sd::SdCard sdCard, std::string mntPoint) {
|
auto mountedSdCardOp = [&](sd::SdCard sdCard, std::string mntPoint) {
|
||||||
if (not performOneShotSdCardOpsSwitch) {
|
if (not performOneShotSdCardOpsSwitch) {
|
||||||
std::ostringstream path;
|
std::ostringstream path;
|
||||||
path << mntPoint << "/" << CONF_FOLDER;
|
path << mntPoint << "/" << core::CONF_FOLDER;
|
||||||
std::error_code e;
|
std::error_code e;
|
||||||
if (not std::filesystem::exists(path.str()), e) {
|
if (not std::filesystem::exists(path.str()), e) {
|
||||||
bool created = std::filesystem::create_directory(path.str(), e);
|
bool created = std::filesystem::create_directory(path.str(), e);
|
||||||
|
@ -18,17 +18,11 @@
|
|||||||
#include "bsp_q7s/fs/SdCardManager.h"
|
#include "bsp_q7s/fs/SdCardManager.h"
|
||||||
#include "events/subsystemIdRanges.h"
|
#include "events/subsystemIdRanges.h"
|
||||||
#include "fsfw/controller/ExtendedControllerBase.h"
|
#include "fsfw/controller/ExtendedControllerBase.h"
|
||||||
|
#include "mission/sysDefs.h"
|
||||||
|
|
||||||
class Timer;
|
class Timer;
|
||||||
class SdCardManager;
|
class SdCardManager;
|
||||||
|
|
||||||
namespace xsc {
|
|
||||||
|
|
||||||
enum Chip : int { CHIP_0, CHIP_1, NO_CHIP, SELF_CHIP, ALL_CHIP };
|
|
||||||
enum Copy : int { COPY_0, COPY_1, NO_COPY, SELF_COPY, ALL_COPY };
|
|
||||||
|
|
||||||
} // namespace xsc
|
|
||||||
|
|
||||||
struct RebootFile {
|
struct RebootFile {
|
||||||
static constexpr uint8_t DEFAULT_MAX_BOOT_CNT = 10;
|
static constexpr uint8_t DEFAULT_MAX_BOOT_CNT = 10;
|
||||||
|
|
||||||
@ -61,18 +55,12 @@ class CoreController : public ExtendedControllerBase, public ReceivesParameterMe
|
|||||||
static constexpr char CHIP_STATE_FILE[] = "/tmp/chip_prot_status.txt";
|
static constexpr char CHIP_STATE_FILE[] = "/tmp/chip_prot_status.txt";
|
||||||
static constexpr char CURR_COPY_FILE[] = "/tmp/curr_copy.txt";
|
static constexpr char CURR_COPY_FILE[] = "/tmp/curr_copy.txt";
|
||||||
|
|
||||||
static constexpr char CONF_FOLDER[] = "conf";
|
|
||||||
|
|
||||||
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";
|
|
||||||
|
|
||||||
const std::string VERSION_FILE =
|
const std::string VERSION_FILE =
|
||||||
"/" + std::string(CONF_FOLDER) + "/" + std::string(VERSION_FILE_NAME);
|
"/" + std::string(core::CONF_FOLDER) + "/" + std::string(core::VERSION_FILE_NAME);
|
||||||
const std::string REBOOT_FILE =
|
const std::string REBOOT_FILE =
|
||||||
"/" + std::string(CONF_FOLDER) + "/" + std::string(REBOOT_FILE_NAME);
|
"/" + std::string(core::CONF_FOLDER) + "/" + std::string(core::REBOOT_FILE_NAME);
|
||||||
const std::string BACKUP_TIME_FILE =
|
const std::string BACKUP_TIME_FILE =
|
||||||
"/" + std::string(CONF_FOLDER) + "/" + std::string(TIME_FILE_NAME);
|
"/" + std::string(core::CONF_FOLDER) + "/" + std::string(core::TIME_FILE_NAME);
|
||||||
|
|
||||||
static constexpr char CHIP_0_COPY_0_MOUNT_DIR[] = "/tmp/mntupdate-xdi-qspi0-nom-rootfs";
|
static constexpr char CHIP_0_COPY_0_MOUNT_DIR[] = "/tmp/mntupdate-xdi-qspi0-nom-rootfs";
|
||||||
static constexpr char CHIP_0_COPY_1_MOUNT_DIR[] = "/tmp/mntupdate-xdi-qspi0-gold-rootfs";
|
static constexpr char CHIP_0_COPY_1_MOUNT_DIR[] = "/tmp/mntupdate-xdi-qspi0-gold-rootfs";
|
||||||
|
@ -451,7 +451,7 @@ ReturnValue_t StrComHandler::performFlashWrite() {
|
|||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
result = writeNextSegment(idx);
|
result = writeNextSegment(idx);
|
||||||
if(result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (idx % 50 == 0) {
|
if (idx % 50 == 0) {
|
||||||
|
@ -13,7 +13,25 @@ enum Mode : Mode_t { BOOT = 5, SAFE = acs::AcsMode::SAFE, PTG_IDLE = acs::AcsMod
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace xsc {
|
||||||
|
|
||||||
|
enum Chip : int { CHIP_0, CHIP_1, NO_CHIP, SELF_CHIP, ALL_CHIP };
|
||||||
|
enum Copy : int { COPY_0, COPY_1, NO_COPY, SELF_COPY, ALL_COPY };
|
||||||
|
|
||||||
|
} // namespace xsc
|
||||||
|
|
||||||
namespace core {
|
namespace core {
|
||||||
|
|
||||||
|
// TODO: Support for status? Or maybe some command to quickly get information whether a unit
|
||||||
|
// is running.
|
||||||
|
enum SystemctlCmd : uint8_t { START = 0, STOP = 1, RESTART = 2, NUM_CMDS = 3 };
|
||||||
|
|
||||||
|
static constexpr char CONF_FOLDER[] = "conf";
|
||||||
|
|
||||||
|
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 LIST_DIRECTORY_INTO_FILE = 0;
|
||||||
static constexpr ActionId_t ANNOUNCE_VERSION = 1;
|
static constexpr ActionId_t ANNOUNCE_VERSION = 1;
|
||||||
static constexpr ActionId_t ANNOUNCE_CURRENT_IMAGE = 2;
|
static constexpr ActionId_t ANNOUNCE_CURRENT_IMAGE = 2;
|
||||||
@ -37,7 +55,9 @@ static constexpr ActionId_t MOUNT_OTHER_COPY = 33;
|
|||||||
//! Reboot using the reboot command
|
//! Reboot using the reboot command
|
||||||
static constexpr ActionId_t REBOOT_OBC = 34;
|
static constexpr ActionId_t REBOOT_OBC = 34;
|
||||||
|
|
||||||
static constexpr ActionId_t EXECUTE_SHELL_CMD = 40;
|
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 uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CORE;
|
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CORE;
|
||||||
|
|
||||||
|
2
tmtc
2
tmtc
@ -1 +1 @@
|
|||||||
Subproject commit 33fd280e517a55175072ea336c7f8e85bce6e55a
|
Subproject commit f8da9cff7c5d6d6bdd483f90ccefb67b2d1e11a4
|
@ -47,8 +47,8 @@ TEST_CASE("Thermal Controller", "[ThermalController]") {
|
|||||||
|
|
||||||
CommandMessage modeMessage;
|
CommandMessage modeMessage;
|
||||||
|
|
||||||
ModeMessage::setModeMessage(&modeMessage, ModeMessage::CMD_MODE_COMMAND,
|
ModeMessage::setModeMessage(&modeMessage, ModeMessage::CMD_MODE_COMMAND, HasModesIF::MODE_ON,
|
||||||
HasModesIF::MODE_ON, HasModesIF::SUBMODE_NONE);
|
HasModesIF::SUBMODE_NONE);
|
||||||
|
|
||||||
MessageQueueIF* commandQueue =
|
MessageQueueIF* commandQueue =
|
||||||
QueueFactory::instance()->createMessageQueue(5, MessageQueueMessage::MAX_MESSAGE_SIZE);
|
QueueFactory::instance()->createMessageQueue(5, MessageQueueMessage::MAX_MESSAGE_SIZE);
|
||||||
|
Loading…
Reference in New Issue
Block a user