fsfw/src/fsfw/modes/ModeHelper.cpp

138 lines
5.0 KiB
C++
Raw Normal View History

2021-07-13 20:22:54 +02:00
#include "fsfw/modes/ModeHelper.h"
2020-09-26 14:58:53 +02:00
2021-07-13 20:22:54 +02:00
#include "fsfw/ipc/MessageQueueSenderIF.h"
2022-02-02 10:29:30 +01:00
#include "fsfw/modes/HasModesIF.h"
2021-07-13 20:22:54 +02:00
#include "fsfw/serviceinterface/ServiceInterface.h"
2022-08-25 22:39:21 +02:00
ModeHelper::ModeHelper(HasModesIF *owner)
2022-02-02 10:29:30 +01:00
: commandedMode(HasModesIF::MODE_OFF),
commandedSubmode(HasModesIF::SUBMODE_NONE),
owner(owner),
forced(false) {}
2022-02-02 10:29:30 +01:00
ModeHelper::~ModeHelper() {}
2022-08-25 22:39:21 +02:00
ReturnValue_t ModeHelper::handleModeCommand(CommandMessage *command) {
2022-02-02 10:29:30 +01:00
CommandMessage reply;
Mode_t mode;
Submode_t submode;
switch (command->getCommand()) {
case ModeMessage::CMD_MODE_COMMAND_FORCED:
forced = true;
/* NO BREAK falls through*/
case ModeMessage::CMD_MODE_COMMAND: {
mode = ModeMessage::getMode(command);
submode = ModeMessage::getSubmode(command);
uint32_t timeout;
ReturnValue_t result = owner->checkModeCommand(mode, submode, &timeout);
2022-08-16 01:08:26 +02:00
if (result != returnvalue::OK) {
2022-02-02 10:29:30 +01:00
ModeMessage::setCantReachMode(&reply, result);
MessageQueueSenderIF::sendMessage(command->getSender(), &reply, owner->getCommandQueue());
break;
}
// Free to start transition
theOneWhoCommandedAMode = command->getSender();
commandedMode = mode;
commandedSubmode = submode;
if ((parentQueueId != MessageQueueIF::NO_QUEUE) &&
(theOneWhoCommandedAMode != parentQueueId)) {
owner->setToExternalControl();
}
countdown.setTimeout(timeout);
owner->startTransition(mode, submode);
} break;
case ModeMessage::CMD_MODE_READ: {
owner->getMode(&mode, &submode);
ModeMessage::setModeMessage(&reply, ModeMessage::REPLY_MODE_REPLY, mode, submode);
MessageQueueSenderIF::sendMessage(command->getSender(), &reply, owner->getCommandQueue());
} break;
case ModeMessage::CMD_MODE_ANNOUNCE:
owner->announceMode(false);
break;
case ModeMessage::CMD_MODE_ANNOUNCE_RECURSIVELY:
owner->announceMode(true);
break;
default:
2022-08-16 01:08:26 +02:00
return returnvalue::FAILED;
2022-02-02 10:29:30 +01:00
}
2022-08-16 01:08:26 +02:00
return returnvalue::OK;
}
ReturnValue_t ModeHelper::initialize(MessageQueueId_t parentQueueId) {
2022-02-02 10:29:30 +01:00
setParentQueue(parentQueueId);
return initialize();
}
2020-09-26 14:51:00 +02:00
void ModeHelper::modeChanged(Mode_t ownerMode, Submode_t ownerSubmode) {
2022-02-02 10:29:30 +01:00
forced = false;
sendModeReplyMessage(ownerMode, ownerSubmode);
sendModeInfoMessage(ownerMode, ownerSubmode);
theOneWhoCommandedAMode = MessageQueueIF::NO_QUEUE;
2020-09-26 14:51:00 +02:00
}
2022-02-02 10:29:30 +01:00
void ModeHelper::sendModeReplyMessage(Mode_t ownerMode, Submode_t ownerSubmode) {
CommandMessage reply;
if (theOneWhoCommandedAMode != MessageQueueIF::NO_QUEUE) {
if (ownerMode != commandedMode or ownerSubmode != commandedSubmode) {
ModeMessage::setModeMessage(&reply, ModeMessage::REPLY_WRONG_MODE_REPLY, ownerMode,
ownerSubmode);
} else {
ModeMessage::setModeMessage(&reply, ModeMessage::REPLY_MODE_REPLY, ownerMode, ownerSubmode);
}
MessageQueueSenderIF::sendMessage(theOneWhoCommandedAMode, &reply, owner->getCommandQueue());
}
2020-09-26 14:51:00 +02:00
}
2022-02-02 10:29:30 +01:00
void ModeHelper::sendModeInfoMessage(Mode_t ownerMode, Submode_t ownerSubmode) {
CommandMessage reply;
if (theOneWhoCommandedAMode != parentQueueId and parentQueueId != MessageQueueIF::NO_QUEUE) {
ModeMessage::setModeMessage(&reply, ModeMessage::REPLY_MODE_INFO, ownerMode, ownerSubmode);
MessageQueueSenderIF::sendMessage(parentQueueId, &reply, owner->getCommandQueue());
}
}
2022-02-02 10:29:30 +01:00
void ModeHelper::startTimer(uint32_t timeoutMs) { countdown.setTimeout(timeoutMs); }
void ModeHelper::setParentQueue(MessageQueueId_t parentQueueId) {
2022-02-02 10:29:30 +01:00
this->parentQueueId = parentQueueId;
}
2022-08-16 01:08:26 +02:00
ReturnValue_t ModeHelper::initialize(void) { return returnvalue::OK; }
2022-02-02 10:29:30 +01:00
bool ModeHelper::isTimedOut() { return countdown.hasTimedOut(); }
2022-02-02 10:29:30 +01:00
bool ModeHelper::isForced() { return forced; }
2022-02-02 10:29:30 +01:00
void ModeHelper::setForced(bool forced) { this->forced = forced; }
2022-08-25 22:29:20 +02:00
#ifdef FSFW_INTROSPECTION
2022-08-25 22:39:21 +02:00
std::vector<std::pair<Mode_t, const char *>> ModeHelper::getModes() const {
std::vector<std::pair<Mode_t, const char *>> modeVector;
auto modeDefinitionHelper = owner->getModeDefinitionHelper();
EnumIF *mode = modeDefinitionHelper.mode;
for (size_t i = 0; i < mode->getSize(); i++) {
modeVector.push_back(
std::pair<Mode_t, const char *>(mode->getElements()[i], mode->getDescriptions()[i]));
2022-08-25 22:29:20 +02:00
}
2022-08-25 22:39:21 +02:00
modeDefinitionHelper.free();
return modeVector;
}
2022-08-25 22:29:20 +02:00
2022-08-25 22:39:21 +02:00
std::vector<std::pair<Submode_t, const char *>> ModeHelper::getSubmodes(Mode_t mode) const {
auto modeDefinitionHelper = owner->getModeDefinitionHelper();
EnumIF *submode = modeDefinitionHelper.submode;
std::vector<std::pair<Submode_t, const char *>> submodeVector;
for (size_t i = 0; i < submode->getSize(); i++) {
uint32_t ignored;
if (owner->checkModeCommand(mode, submode->getElements()[i], &ignored) ==
HasReturnvaluesIF::RETURN_OK) {
submodeVector.push_back(std::pair<Submode_t, const char *>(submode->getElements()[i],
submode->getDescriptions()[i]));
2022-08-25 22:29:20 +02:00
}
}
2022-08-25 22:39:21 +02:00
modeDefinitionHelper.free();
return submodeVector;
}
2022-08-25 22:29:20 +02:00
#endif