diff --git a/CHANGELOG.md b/CHANGELOG.md index dd1f57a2..7f9681d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,10 @@ will consitute of a breaking change warranting a new major release: # [unreleased] +## Added + +- Added `EXECUTE_SHELL_CMD` action command for `CoreController` to execute arbitrary Linux commands. + ## Fixed - Pointing control of the `AcsController` was still expecting submodes instead of modes. diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 5c4710d4..702264ab 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -32,7 +32,9 @@ xsc::Chip CoreController::CURRENT_CHIP = xsc::Chip::NO_CHIP; xsc::Copy CoreController::CURRENT_COPY = xsc::Copy::NO_COPY; CoreController::CoreController(object_id_t objectId) - : ExtendedControllerBase(objectId, 5), opDivider5(5), opDivider10(10), hkSet(this) { + : ExtendedControllerBase(objectId, 5), cmdExecutor(4096), cmdReplyBuf(4096, true), cmdRepliesSizes(128), + opDivider5(5), opDivider10(10), hkSet(this) { + cmdExecutor.setRingBuffer(&cmdReplyBuf, &cmdRepliesSizes); try { sdcMan = SdCardManager::instance(); if (sdcMan == nullptr) { @@ -100,6 +102,19 @@ void CoreController::performControlOperation() { sdStateMachine(); performMountedSdCardOperations(); readHkData(); + if(shellCmdIsExecuting) { + bool replyReceived = false; + // 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) { + actionHelper.finish(true, successRecipient, EXECUTE_SHELL_CMD); + shellCmdIsExecuting = false; + cmdReplyBuf.clear(); + while(not cmdRepliesSizes.empty()) { + cmdRepliesSizes.pop(); + } + successRecipient = MessageQueueIF::NO_QUEUE; + } + } opDivider5.checkAndIncrement(); opDivider10.checkAndIncrement(); } @@ -301,6 +316,20 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_ // Warning: This function will never return, because it reboots the system return actionReboot(data, size); } + case(EXECUTE_SHELL_CMD): { + std::string cmd = std::string(cmd, size); + if(cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING or shellCmdIsExecuting) { + return HasActionsIF::IS_BUSY; + } + cmdExecutor.load(cmd, false, false); + ReturnValue_t result = cmdExecutor.execute(); + if(result != returnvalue::OK) { + return result; + } + shellCmdIsExecuting = true; + successRecipient = commandedBy; + return returnvalue::OK; + } default: { return HasActionsIF::INVALID_ACTION_ID; } diff --git a/bsp_q7s/core/CoreController.h b/bsp_q7s/core/CoreController.h index c5e23d48..fa07ec59 100644 --- a/bsp_q7s/core/CoreController.h +++ b/bsp_q7s/core/CoreController.h @@ -1,6 +1,8 @@ #ifndef BSP_Q7S_CORE_CORECONTROLLER_H_ #define BSP_Q7S_CORE_CORECONTROLLER_H_ +#include +#include #include #include @@ -98,6 +100,8 @@ class CoreController : public ExtendedControllerBase { //! Reboot using the reboot command static constexpr ActionId_t REBOOT_OBC = 34; + static constexpr ActionId_t EXECUTE_SHELL_CMD = 40; + static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CORE; static constexpr Event ALLOC_FAILURE = event::makeEvent(SUBSYSTEM_ID, 0, severity::MEDIUM); @@ -227,6 +231,13 @@ class CoreController : public ExtendedControllerBase { } sdCommandingInfo; RebootFile rebootFile = {}; + + CommandExecutor cmdExecutor; + SimpleRingBuffer cmdReplyBuf; + DynamicFIFO cmdRepliesSizes; + bool shellCmdIsExecuting = false; + MessageQueueId_t successRecipient = MessageQueueIF::NO_QUEUE; + std::string currMntPrefix; bool timeFileInitDone = false; bool performOneShotSdCardOpsSwitch = false; diff --git a/fsfw b/fsfw index 4d6f6e6b..9a8d775e 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 4d6f6e6b23b5c0486dad6be8abba7681114a05fe +Subproject commit 9a8d775eb1a8788ad844215bf2a42d9f707767c0