1
0
forked from fsfw/fsfw
Files
action
container
contrib
controller
coordinates
datalinklayer
datapool
devicehandlers
events
fdir
globalfunctions
health
internalError
ipc
memory
modes
HasModesIF.h
ModeHelper.cpp
ModeHelper.h
ModeMessage.cpp
ModeMessage.h
monitoring
objectmanager
osal
parameters
power
pus
returnvalues
rmap
serialize
serviceinterface
storagemanager
subsystem
tasks
tcdistribution
thermal
timemanager
tmstorage
tmtcpacket
tmtcservices
.gitignore
LICENSE
NOTICE
fsfw.mk
fsfw/modes/ModeHelper.cpp
2020-08-13 20:53:35 +02:00

120 lines
3.3 KiB
C++

#include "HasModesIF.h"
#include "ModeHelper.h"
#include "../ipc/MessageQueueSenderIF.h"
ModeHelper::ModeHelper(HasModesIF *owner) :
theOneWhoCommandedAMode(0), commandedMode(HasModesIF::MODE_OFF), commandedSubmode(
HasModesIF::SUBMODE_NONE), owner(owner), parentQueueId(0), forced(
false) {
}
ModeHelper::~ModeHelper() {
}
ReturnValue_t ModeHelper::handleModeCommand(CommandMessage* message) {
CommandMessage reply;
Mode_t mode;
Submode_t submode;
switch (message->getCommand()) {
case ModeMessage::CMD_MODE_COMMAND_FORCED:
forced = true;
/* NO BREAK falls through*/
case ModeMessage::CMD_MODE_COMMAND: {
mode = ModeMessage::getMode(message);
submode = ModeMessage::getSubmode(message);
uint32_t timeout;
ReturnValue_t result = owner->checkModeCommand(mode, submode, &timeout);
if (result != HasReturnvaluesIF::RETURN_OK) {
ModeMessage::cantReachMode(&reply, result);
MessageQueueSenderIF::sendMessage(message->getSender(), &reply,
owner->getCommandQueue());
break;
}
//Free to start transition
theOneWhoCommandedAMode = message->getSender();
commandedMode = mode;
commandedSubmode = submode;
if ((parentQueueId != MessageQueueSenderIF::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(message->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:
return HasReturnvaluesIF::RETURN_FAILED;
}
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t ModeHelper::initialize(MessageQueueId_t parentQueueId) {
setParentQueue(parentQueueId);
return initialize();
}
void ModeHelper::modeChanged(Mode_t mode, Submode_t submode) {
forced = false;
CommandMessage reply;
if (theOneWhoCommandedAMode != MessageQueueSenderIF::NO_QUEUE) {
if ((mode != commandedMode) || (submode != commandedSubmode)) {
ModeMessage::setModeMessage(&reply,
ModeMessage::REPLY_WRONG_MODE_REPLY, mode, submode);
} else {
ModeMessage::setModeMessage(&reply, ModeMessage::REPLY_MODE_REPLY,
mode, submode);
}
MessageQueueSenderIF::sendMessage(theOneWhoCommandedAMode, &reply,
owner->getCommandQueue());
}
if (theOneWhoCommandedAMode != parentQueueId
&& parentQueueId != MessageQueueSenderIF::NO_QUEUE) {
ModeMessage::setModeMessage(&reply, ModeMessage::REPLY_MODE_INFO, mode,
submode);
MessageQueueSenderIF::sendMessage(parentQueueId, &reply, owner->getCommandQueue());
}
theOneWhoCommandedAMode = MessageQueueSenderIF::NO_QUEUE;
}
void ModeHelper::startTimer(uint32_t timeoutMs) {
countdown.setTimeout(timeoutMs);
}
void ModeHelper::setParentQueue(MessageQueueId_t parentQueueId) {
this->parentQueueId = parentQueueId;
}
ReturnValue_t ModeHelper::initialize(void) {
return HasReturnvaluesIF::RETURN_OK;
}
bool ModeHelper::isTimedOut() {
return countdown.hasTimedOut();
}
bool ModeHelper::isForced() {
return forced;
}
void ModeHelper::setForced(bool forced) {
this->forced = forced;
}