restructure repository
This commit is contained in:
273
src/core/devicehandlers/AssemblyBase.cpp
Normal file
273
src/core/devicehandlers/AssemblyBase.cpp
Normal file
@ -0,0 +1,273 @@
|
||||
#include "AssemblyBase.h"
|
||||
|
||||
AssemblyBase::AssemblyBase(object_id_t objectId, object_id_t parentId,
|
||||
uint16_t commandQueueDepth) :
|
||||
SubsystemBase(objectId, parentId, MODE_OFF, commandQueueDepth),
|
||||
internalState(STATE_NONE), recoveryState(RECOVERY_IDLE),
|
||||
recoveringDevice(childrenMap.end()), targetMode(MODE_OFF),
|
||||
targetSubmode(SUBMODE_NONE) {
|
||||
recoveryOffTimer.setTimeout(POWER_OFF_TIME_MS);
|
||||
}
|
||||
|
||||
AssemblyBase::~AssemblyBase() {
|
||||
}
|
||||
|
||||
ReturnValue_t AssemblyBase::handleCommandMessage(CommandMessage* message) {
|
||||
return handleHealthReply(message);
|
||||
}
|
||||
|
||||
void AssemblyBase::performChildOperation() {
|
||||
if (isInTransition()) {
|
||||
handleChildrenTransition();
|
||||
} else {
|
||||
handleChildrenChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void AssemblyBase::startTransition(Mode_t mode, Submode_t submode) {
|
||||
doStartTransition(mode, submode);
|
||||
if (modeHelper.isForced()) {
|
||||
triggerEvent(FORCING_MODE, mode, submode);
|
||||
} else {
|
||||
triggerEvent(CHANGING_MODE, mode, submode);
|
||||
}
|
||||
}
|
||||
|
||||
void AssemblyBase::doStartTransition(Mode_t mode, Submode_t submode) {
|
||||
targetMode = mode;
|
||||
targetSubmode = submode;
|
||||
internalState = STATE_SINGLE_STEP;
|
||||
ReturnValue_t result = commandChildren(mode, submode);
|
||||
if (result == NEED_SECOND_STEP) {
|
||||
internalState = STATE_NEED_SECOND_STEP;
|
||||
}
|
||||
}
|
||||
|
||||
bool AssemblyBase::isInTransition() {
|
||||
return (internalState != STATE_NONE) || (recoveryState != RECOVERY_IDLE);
|
||||
}
|
||||
|
||||
bool AssemblyBase::handleChildrenChanged() {
|
||||
if (childrenChangedMode) {
|
||||
ReturnValue_t result = checkChildrenState();
|
||||
if (result != RETURN_OK) {
|
||||
handleChildrenLostMode(result);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return handleChildrenChangedHealth();
|
||||
}
|
||||
}
|
||||
|
||||
void AssemblyBase::handleChildrenLostMode(ReturnValue_t result) {
|
||||
triggerEvent(CANT_KEEP_MODE, mode, submode);
|
||||
startTransition(MODE_OFF, SUBMODE_NONE);
|
||||
}
|
||||
|
||||
bool AssemblyBase::handleChildrenChangedHealth() {
|
||||
auto iter = childrenMap.begin();
|
||||
for (; iter != childrenMap.end(); iter++) {
|
||||
if (iter->second.healthChanged) {
|
||||
iter->second.healthChanged = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (iter == childrenMap.end()) {
|
||||
return false;
|
||||
}
|
||||
HealthState healthState = healthHelper.healthTable->getHealth(iter->first);
|
||||
if (healthState == HasHealthIF::NEEDS_RECOVERY) {
|
||||
triggerEvent(TRYING_RECOVERY);
|
||||
recoveryState = RECOVERY_STARTED;
|
||||
recoveringDevice = iter;
|
||||
doStartTransition(targetMode, targetSubmode);
|
||||
} else {
|
||||
triggerEvent(CHILD_CHANGED_HEALTH);
|
||||
doStartTransition(mode, submode);
|
||||
}
|
||||
if (modeHelper.isForced()) {
|
||||
triggerEvent(FORCING_MODE, targetMode, targetSubmode);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void AssemblyBase::handleChildrenTransition() {
|
||||
if (commandsOutstanding <= 0) {
|
||||
switch (internalState) {
|
||||
case STATE_NEED_SECOND_STEP:
|
||||
internalState = STATE_SECOND_STEP;
|
||||
commandChildren(targetMode, targetSubmode);
|
||||
return;
|
||||
case STATE_OVERWRITE_HEALTH: {
|
||||
internalState = STATE_SINGLE_STEP;
|
||||
ReturnValue_t result = commandChildren(mode, submode);
|
||||
if (result == NEED_SECOND_STEP) {
|
||||
internalState = STATE_NEED_SECOND_STEP;
|
||||
}
|
||||
return;
|
||||
}
|
||||
case STATE_NONE:
|
||||
//Valid state, used in recovery.
|
||||
case STATE_SINGLE_STEP:
|
||||
case STATE_SECOND_STEP:
|
||||
if (checkAndHandleRecovery()) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
ReturnValue_t result = checkChildrenState();
|
||||
if (result == RETURN_OK) {
|
||||
handleModeReached();
|
||||
} else {
|
||||
handleModeTransitionFailed(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AssemblyBase::handleModeReached() {
|
||||
internalState = STATE_NONE;
|
||||
setMode(targetMode, targetSubmode);
|
||||
}
|
||||
|
||||
void AssemblyBase::handleModeTransitionFailed(ReturnValue_t result) {
|
||||
//always accept transition to OFF, there is nothing we can do except sending an info event
|
||||
//In theory this should never happen, but we would risk an infinite loop otherwise
|
||||
if (targetMode == MODE_OFF) {
|
||||
triggerEvent(CHILD_PROBLEMS, result);
|
||||
internalState = STATE_NONE;
|
||||
setMode(targetMode, targetSubmode);
|
||||
} else {
|
||||
if (handleChildrenChangedHealth()) {
|
||||
//If any health change is pending, handle that first.
|
||||
return;
|
||||
}
|
||||
triggerEvent(MODE_TRANSITION_FAILED, result);
|
||||
startTransition(MODE_OFF, SUBMODE_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
void AssemblyBase::sendHealthCommand(MessageQueueId_t sendTo,
|
||||
HealthState health) {
|
||||
CommandMessage command;
|
||||
HealthMessage::setHealthMessage(&command, HealthMessage::HEALTH_SET,
|
||||
health);
|
||||
if (commandQueue->sendMessage(sendTo, &command) == RETURN_OK) {
|
||||
commandsOutstanding++;
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t AssemblyBase::checkChildrenState() {
|
||||
if (targetMode == MODE_OFF) {
|
||||
return checkChildrenStateOff();
|
||||
} else {
|
||||
return checkChildrenStateOn(targetMode, targetSubmode);
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t AssemblyBase::checkChildrenStateOff() {
|
||||
for (const auto& childIter: childrenMap) {
|
||||
if (checkChildOff(childIter.first) != RETURN_OK) {
|
||||
return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE;
|
||||
}
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t AssemblyBase::checkChildOff(uint32_t objectId) {
|
||||
ChildInfo childInfo = childrenMap.find(objectId)->second;
|
||||
if (healthHelper.healthTable->isCommandable(objectId)) {
|
||||
if (childInfo.submode != SUBMODE_NONE) {
|
||||
return RETURN_FAILED;
|
||||
} else {
|
||||
if ((childInfo.mode != MODE_OFF)
|
||||
&& (childInfo.mode != DeviceHandlerIF::MODE_ERROR_ON)) {
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t AssemblyBase::checkModeCommand(Mode_t mode, Submode_t submode,
|
||||
uint32_t* msToReachTheMode) {
|
||||
|
||||
//always accept transition to OFF
|
||||
if (mode == MODE_OFF) {
|
||||
if (submode != SUBMODE_NONE) {
|
||||
return INVALID_SUBMODE;
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
if ((mode != MODE_ON) && (mode != DeviceHandlerIF::MODE_NORMAL)) {
|
||||
return INVALID_MODE;
|
||||
}
|
||||
|
||||
if (internalState != STATE_NONE) {
|
||||
return IN_TRANSITION;
|
||||
}
|
||||
|
||||
return isModeCombinationValid(mode, submode);
|
||||
}
|
||||
|
||||
ReturnValue_t AssemblyBase::handleHealthReply(CommandMessage* message) {
|
||||
if (message->getCommand() == HealthMessage::HEALTH_INFO) {
|
||||
HealthState health = HealthMessage::getHealth(message);
|
||||
if (health != EXTERNAL_CONTROL) {
|
||||
updateChildChangedHealth(message->getSender(), true);
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
if (message->getCommand() == HealthMessage::REPLY_HEALTH_SET
|
||||
|| (message->getCommand() == CommandMessage::REPLY_REJECTED
|
||||
&& message->getParameter2() == HealthMessage::HEALTH_SET)) {
|
||||
if (isInTransition()) {
|
||||
commandsOutstanding--;
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
|
||||
bool AssemblyBase::checkAndHandleRecovery() {
|
||||
switch (recoveryState) {
|
||||
case RECOVERY_STARTED:
|
||||
recoveryState = RECOVERY_WAIT;
|
||||
recoveryOffTimer.resetTimer();
|
||||
return true;
|
||||
case RECOVERY_WAIT:
|
||||
if (recoveryOffTimer.isBusy()) {
|
||||
return true;
|
||||
}
|
||||
triggerEvent(RECOVERY_STEP, 0);
|
||||
sendHealthCommand(recoveringDevice->second.commandQueue, HEALTHY);
|
||||
internalState = STATE_NONE;
|
||||
recoveryState = RECOVERY_ONGOING;
|
||||
//Don't check state!
|
||||
return true;
|
||||
case RECOVERY_ONGOING:
|
||||
triggerEvent(RECOVERY_STEP, 1);
|
||||
recoveryState = RECOVERY_ONGOING_2;
|
||||
recoveringDevice->second.healthChanged = false;
|
||||
//Device should be healthy again, so restart a transition.
|
||||
//Might be including second step, but that's already handled.
|
||||
doStartTransition(targetMode, targetSubmode);
|
||||
return true;
|
||||
case RECOVERY_ONGOING_2:
|
||||
triggerEvent(RECOVERY_DONE);
|
||||
//Now we're through, but not sure if it was successful.
|
||||
recoveryState = RECOVERY_IDLE;
|
||||
return false;
|
||||
case RECOVERY_IDLE:
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void AssemblyBase::overwriteDeviceHealth(object_id_t objectId,
|
||||
HasHealthIF::HealthState oldHealth) {
|
||||
triggerEvent(OVERWRITING_HEALTH, objectId, oldHealth);
|
||||
internalState = STATE_OVERWRITE_HEALTH;
|
||||
modeHelper.setForced(true);
|
||||
sendHealthCommand(childrenMap[objectId].commandQueue, EXTERNAL_CONTROL);
|
||||
}
|
46
src/core/devicehandlers/ChildHandlerBase.cpp
Normal file
46
src/core/devicehandlers/ChildHandlerBase.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
#include "ChildHandlerBase.h"
|
||||
#include "../subsystem/SubsystemBase.h"
|
||||
|
||||
ChildHandlerBase::ChildHandlerBase(object_id_t setObjectId,
|
||||
object_id_t deviceCommunication, CookieIF * cookie,
|
||||
object_id_t hkDestination, uint32_t thermalStatePoolId,
|
||||
uint32_t thermalRequestPoolId,
|
||||
object_id_t parent,
|
||||
FailureIsolationBase* customFdir, size_t cmdQueueSize) :
|
||||
DeviceHandlerBase(setObjectId, deviceCommunication, cookie,
|
||||
(customFdir == nullptr? &childHandlerFdir : customFdir),
|
||||
cmdQueueSize),
|
||||
parentId(parent), childHandlerFdir(setObjectId) {
|
||||
this->setHkDestination(hkDestination);
|
||||
this->setThermalStateRequestPoolIds(thermalStatePoolId,
|
||||
thermalRequestPoolId);
|
||||
|
||||
}
|
||||
|
||||
ChildHandlerBase::~ChildHandlerBase() {
|
||||
}
|
||||
|
||||
ReturnValue_t ChildHandlerBase::initialize() {
|
||||
ReturnValue_t result = DeviceHandlerBase::initialize();
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
MessageQueueId_t parentQueue = 0;
|
||||
|
||||
if (parentId != objects::NO_OBJECT) {
|
||||
SubsystemBase *parent = ObjectManager::instance()->get<SubsystemBase>(parentId);
|
||||
if (parent == NULL) {
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
parentQueue = parent->getCommandQueue();
|
||||
|
||||
parent->registerChild(getObjectId());
|
||||
}
|
||||
|
||||
healthHelper.setParentQueue(parentQueue);
|
||||
|
||||
modeHelper.setParentQueue(parentQueue);
|
||||
|
||||
return RETURN_OK;
|
||||
}
|
11
src/core/devicehandlers/ChildHandlerFDIR.cpp
Normal file
11
src/core/devicehandlers/ChildHandlerFDIR.cpp
Normal file
@ -0,0 +1,11 @@
|
||||
#include "ChildHandlerFDIR.h"
|
||||
|
||||
ChildHandlerFDIR::ChildHandlerFDIR(object_id_t owner,
|
||||
object_id_t faultTreeParent, uint32_t recoveryCount) :
|
||||
DeviceHandlerFailureIsolation(owner, faultTreeParent) {
|
||||
recoveryCounter.setFailureThreshold(recoveryCount);
|
||||
}
|
||||
|
||||
ChildHandlerFDIR::~ChildHandlerFDIR() {
|
||||
}
|
||||
|
1559
src/core/devicehandlers/DeviceHandlerBase.cpp
Normal file
1559
src/core/devicehandlers/DeviceHandlerBase.cpp
Normal file
File diff suppressed because it is too large
Load Diff
269
src/core/devicehandlers/DeviceHandlerFailureIsolation.cpp
Normal file
269
src/core/devicehandlers/DeviceHandlerFailureIsolation.cpp
Normal file
@ -0,0 +1,269 @@
|
||||
#include "DeviceHandlerFailureIsolation.h"
|
||||
|
||||
#include "../devicehandlers/DeviceHandlerIF.h"
|
||||
#include "../objectmanager/ObjectManager.h"
|
||||
#include "../modes/HasModesIF.h"
|
||||
#include "../health/HealthTableIF.h"
|
||||
#include "../power/Fuse.h"
|
||||
#include "../serviceinterface/ServiceInterfaceStream.h"
|
||||
#include "../thermal/ThermalComponentIF.h"
|
||||
|
||||
object_id_t DeviceHandlerFailureIsolation::powerConfirmationId =
|
||||
objects::NO_OBJECT;
|
||||
|
||||
DeviceHandlerFailureIsolation::DeviceHandlerFailureIsolation(object_id_t owner,
|
||||
object_id_t parent) :
|
||||
FailureIsolationBase(owner, parent),
|
||||
strangeReplyCount(DEFAULT_MAX_STRANGE_REPLIES,
|
||||
DEFAULT_STRANGE_REPLIES_TIME_MS,
|
||||
parameterDomainBase++),
|
||||
missedReplyCount( DEFAULT_MAX_MISSED_REPLY_COUNT,
|
||||
DEFAULT_MISSED_REPLY_TIME_MS,
|
||||
parameterDomainBase++),
|
||||
recoveryCounter(DEFAULT_MAX_REBOOT, DEFAULT_REBOOT_TIME_MS,
|
||||
parameterDomainBase++),
|
||||
fdirState(NONE) {
|
||||
}
|
||||
|
||||
DeviceHandlerFailureIsolation::~DeviceHandlerFailureIsolation() {
|
||||
}
|
||||
|
||||
ReturnValue_t DeviceHandlerFailureIsolation::eventReceived(EventMessage* event) {
|
||||
if(isFdirInActionOrAreWeFaulty(event)) {
|
||||
return RETURN_OK;
|
||||
}
|
||||
ReturnValue_t result = RETURN_FAILED;
|
||||
switch (event->getEvent()) {
|
||||
case HasModesIF::MODE_TRANSITION_FAILED:
|
||||
case HasModesIF::OBJECT_IN_INVALID_MODE:
|
||||
//We'll try a recovery as long as defined in MAX_REBOOT.
|
||||
//Might cause some AssemblyBase cycles, so keep number low.
|
||||
handleRecovery(event->getEvent());
|
||||
break;
|
||||
case DeviceHandlerIF::DEVICE_INTERPRETING_REPLY_FAILED:
|
||||
case DeviceHandlerIF::DEVICE_READING_REPLY_FAILED:
|
||||
case DeviceHandlerIF::DEVICE_UNREQUESTED_REPLY:
|
||||
case DeviceHandlerIF::DEVICE_UNKNOWN_REPLY: //Some DH's generate generic reply-ids.
|
||||
case DeviceHandlerIF::DEVICE_BUILDING_COMMAND_FAILED:
|
||||
//These faults all mean that there were stupid replies from a device.
|
||||
if (strangeReplyCount.incrementAndCheck()) {
|
||||
handleRecovery(event->getEvent());
|
||||
}
|
||||
break;
|
||||
case DeviceHandlerIF::DEVICE_SENDING_COMMAND_FAILED:
|
||||
case DeviceHandlerIF::DEVICE_REQUESTING_REPLY_FAILED:
|
||||
//The two above should never be confirmed.
|
||||
case DeviceHandlerIF::DEVICE_MISSED_REPLY:
|
||||
result = sendConfirmationRequest(event);
|
||||
if (result == HasReturnvaluesIF::RETURN_OK) {
|
||||
break;
|
||||
}
|
||||
//else
|
||||
if (missedReplyCount.incrementAndCheck()) {
|
||||
handleRecovery(event->getEvent());
|
||||
}
|
||||
break;
|
||||
case StorageManagerIF::GET_DATA_FAILED:
|
||||
case StorageManagerIF::STORE_DATA_FAILED:
|
||||
//Rather strange bugs, occur in RAW mode only. Ignore.
|
||||
break;
|
||||
case DeviceHandlerIF::INVALID_DEVICE_COMMAND:
|
||||
//Ignore, is bad configuration. We can't do anything in flight.
|
||||
break;
|
||||
case HasHealthIF::HEALTH_INFO:
|
||||
case HasModesIF::MODE_INFO:
|
||||
case HasModesIF::CHANGING_MODE:
|
||||
//Do nothing, but mark as handled.
|
||||
break;
|
||||
//****Power*****
|
||||
case PowerSwitchIF::SWITCH_WENT_OFF:
|
||||
if(powerConfirmation != MessageQueueIF::NO_QUEUE) {
|
||||
result = sendConfirmationRequest(event, powerConfirmation);
|
||||
if (result == RETURN_OK) {
|
||||
setFdirState(DEVICE_MIGHT_BE_OFF);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Fuse::FUSE_WENT_OFF:
|
||||
//Not so good, because PCDU reacted.
|
||||
case Fuse::POWER_ABOVE_HIGH_LIMIT:
|
||||
//Better, because software detected over-current.
|
||||
setFaulty(event->getEvent());
|
||||
break;
|
||||
case Fuse::POWER_BELOW_LOW_LIMIT:
|
||||
//Device might got stuck during boot, retry.
|
||||
handleRecovery(event->getEvent());
|
||||
break;
|
||||
//****Thermal*****
|
||||
case ThermalComponentIF::COMPONENT_TEMP_LOW:
|
||||
case ThermalComponentIF::COMPONENT_TEMP_HIGH:
|
||||
case ThermalComponentIF::COMPONENT_TEMP_OOL_LOW:
|
||||
case ThermalComponentIF::COMPONENT_TEMP_OOL_HIGH:
|
||||
//Well, the device is not really faulty, but it is required to stay off as long as possible.
|
||||
setFaulty(event->getEvent());
|
||||
break;
|
||||
case ThermalComponentIF::TEMP_NOT_IN_OP_RANGE:
|
||||
//Ignore, is information only.
|
||||
break;
|
||||
//*******Default monitoring variables. Are currently not used.*****
|
||||
// case DeviceHandlerIF::MONITORING_LIMIT_EXCEEDED:
|
||||
// setFaulty(event->getEvent());
|
||||
// break;
|
||||
// case DeviceHandlerIF::MONITORING_AMBIGUOUS:
|
||||
// break;
|
||||
default:
|
||||
//We don't know the event, someone else should handle it.
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
void DeviceHandlerFailureIsolation::eventConfirmed(EventMessage* event) {
|
||||
switch (event->getEvent()) {
|
||||
case DeviceHandlerIF::DEVICE_SENDING_COMMAND_FAILED:
|
||||
case DeviceHandlerIF::DEVICE_REQUESTING_REPLY_FAILED:
|
||||
case DeviceHandlerIF::DEVICE_MISSED_REPLY:
|
||||
if (missedReplyCount.incrementAndCheck()) {
|
||||
handleRecovery(event->getEvent());
|
||||
}
|
||||
break;
|
||||
case PowerSwitchIF::SWITCH_WENT_OFF:
|
||||
//This means the switch went off only for one device.
|
||||
handleRecovery(event->getEvent());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceHandlerFailureIsolation::decrementFaultCounters() {
|
||||
strangeReplyCount.checkForDecrement();
|
||||
missedReplyCount.checkForDecrement();
|
||||
recoveryCounter.checkForDecrement();
|
||||
}
|
||||
|
||||
void DeviceHandlerFailureIsolation::handleRecovery(Event reason) {
|
||||
clearFaultCounters();
|
||||
if (not recoveryCounter.incrementAndCheck()) {
|
||||
startRecovery(reason);
|
||||
} else {
|
||||
setFaulty(reason);
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceHandlerFailureIsolation::wasParentsFault(EventMessage* event) {
|
||||
//We'll better ignore the SWITCH_WENT_OFF event and await a system-wide reset.
|
||||
//This means, no fault message will come through until a MODE_ or
|
||||
//HEALTH_INFO message comes through -> Is that ok?
|
||||
//Same issue in TxFailureIsolation!
|
||||
// if ((event->getEvent() == PowerSwitchIF::SWITCH_WENT_OFF)
|
||||
// && (fdirState != RECOVERY_ONGOING)) {
|
||||
// setFdirState(NONE);
|
||||
// }
|
||||
}
|
||||
|
||||
void DeviceHandlerFailureIsolation::clearFaultCounters() {
|
||||
strangeReplyCount.clear();
|
||||
missedReplyCount.clear();
|
||||
}
|
||||
|
||||
ReturnValue_t DeviceHandlerFailureIsolation::initialize() {
|
||||
ReturnValue_t result = FailureIsolationBase::initialize();
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "DeviceHandlerFailureIsolation::initialize: Could not"
|
||||
" initialize FailureIsolationBase." << std::endl;
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
ConfirmsFailuresIF* power = ObjectManager::instance()->get<ConfirmsFailuresIF>(
|
||||
powerConfirmationId);
|
||||
if (power != nullptr) {
|
||||
powerConfirmation = power->getEventReceptionQueue();
|
||||
}
|
||||
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
void DeviceHandlerFailureIsolation::setFdirState(FDIRState state) {
|
||||
FailureIsolationBase::throwFdirEvent(FDIR_CHANGED_STATE, state, fdirState);
|
||||
fdirState = state;
|
||||
}
|
||||
|
||||
void DeviceHandlerFailureIsolation::triggerEvent(Event event, uint32_t parameter1,
|
||||
uint32_t parameter2) {
|
||||
//Do not throw error events if fdirState != none.
|
||||
//This will still forward MODE and HEALTH INFO events in any case.
|
||||
if (fdirState == NONE || event::getSeverity(event) == severity::INFO) {
|
||||
FailureIsolationBase::triggerEvent(event, parameter1, parameter2);
|
||||
}
|
||||
}
|
||||
|
||||
bool DeviceHandlerFailureIsolation::isFdirActionInProgress() {
|
||||
return (fdirState != NONE);
|
||||
}
|
||||
|
||||
void DeviceHandlerFailureIsolation::startRecovery(Event reason) {
|
||||
throwFdirEvent(FDIR_STARTS_RECOVERY, event::getEventId(reason));
|
||||
setOwnerHealth(HasHealthIF::NEEDS_RECOVERY);
|
||||
setFdirState(RECOVERY_ONGOING);
|
||||
}
|
||||
|
||||
ReturnValue_t DeviceHandlerFailureIsolation::getParameter(uint8_t domainId,
|
||||
uint8_t uniqueId, ParameterWrapper* parameterWrapper,
|
||||
const ParameterWrapper* newValues, uint16_t startAtIndex) {
|
||||
ReturnValue_t result = strangeReplyCount.getParameter(domainId, uniqueId,
|
||||
parameterWrapper, newValues, startAtIndex);
|
||||
if (result != INVALID_DOMAIN_ID) {
|
||||
return result;
|
||||
}
|
||||
result = missedReplyCount.getParameter(domainId, uniqueId, parameterWrapper, newValues,
|
||||
startAtIndex);
|
||||
if (result != INVALID_DOMAIN_ID) {
|
||||
return result;
|
||||
}
|
||||
result = recoveryCounter.getParameter(domainId, uniqueId, parameterWrapper, newValues,
|
||||
startAtIndex);
|
||||
if (result != INVALID_DOMAIN_ID) {
|
||||
return result;
|
||||
}
|
||||
return INVALID_DOMAIN_ID;
|
||||
}
|
||||
|
||||
void DeviceHandlerFailureIsolation::setFaulty(Event reason) {
|
||||
throwFdirEvent(FDIR_TURNS_OFF_DEVICE, event::getEventId(reason));
|
||||
setOwnerHealth(HasHealthIF::FAULTY);
|
||||
setFdirState(AWAIT_SHUTDOWN);
|
||||
}
|
||||
|
||||
bool DeviceHandlerFailureIsolation::isFdirInActionOrAreWeFaulty(
|
||||
EventMessage* event) {
|
||||
if (fdirState != NONE) {
|
||||
//Only wait for those events, ignore all others.
|
||||
if (event->getParameter1() == HasHealthIF::HEALTHY
|
||||
&& event->getEvent() == HasHealthIF::HEALTH_INFO) {
|
||||
setFdirState(NONE);
|
||||
}
|
||||
if (event->getEvent() == HasModesIF::MODE_INFO
|
||||
&& fdirState != RECOVERY_ONGOING) {
|
||||
setFdirState(NONE);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (owner == nullptr) {
|
||||
// Configuration error.
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "DeviceHandlerFailureIsolation::"
|
||||
<< "isFdirInActionOrAreWeFaulty: Owner not set!" << std::endl;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
if (owner->getHealth() == HasHealthIF::FAULTY
|
||||
|| owner->getHealth() == HasHealthIF::PERMANENT_FAULTY) {
|
||||
//Ignore all events in case device is already faulty.
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
88
src/core/devicehandlers/DeviceHandlerMessage.cpp
Normal file
88
src/core/devicehandlers/DeviceHandlerMessage.cpp
Normal file
@ -0,0 +1,88 @@
|
||||
#include "DeviceHandlerMessage.h"
|
||||
#include "../objectmanager/ObjectManager.h"
|
||||
|
||||
store_address_t DeviceHandlerMessage::getStoreAddress(
|
||||
const CommandMessage* message) {
|
||||
return store_address_t(message->getParameter2());
|
||||
}
|
||||
|
||||
uint32_t DeviceHandlerMessage::getDeviceCommandId(
|
||||
const CommandMessage* message) {
|
||||
return message->getParameter();
|
||||
}
|
||||
|
||||
object_id_t DeviceHandlerMessage::getIoBoardObjectId(
|
||||
const CommandMessage* message) {
|
||||
return message->getParameter();
|
||||
}
|
||||
|
||||
uint8_t DeviceHandlerMessage::getWiretappingMode(
|
||||
const CommandMessage* message) {
|
||||
return message->getParameter();
|
||||
}
|
||||
|
||||
void DeviceHandlerMessage::setDeviceHandlerRawCommandMessage(
|
||||
CommandMessage* message, store_address_t rawPacketStoreId) {
|
||||
message->setCommand(CMD_RAW);
|
||||
message->setParameter2(rawPacketStoreId.raw);
|
||||
}
|
||||
|
||||
void DeviceHandlerMessage::setDeviceHandlerWiretappingMessage(
|
||||
CommandMessage* message, uint8_t wiretappingMode) {
|
||||
message->setCommand(CMD_WIRETAPPING);
|
||||
message->setParameter(wiretappingMode);
|
||||
}
|
||||
|
||||
void DeviceHandlerMessage::setDeviceHandlerSwitchIoBoardMessage(
|
||||
CommandMessage* message, uint32_t ioBoardIdentifier) {
|
||||
message->setCommand(CMD_SWITCH_ADDRESS);
|
||||
message->setParameter(ioBoardIdentifier);
|
||||
}
|
||||
|
||||
object_id_t DeviceHandlerMessage::getDeviceObjectId(
|
||||
const CommandMessage* message) {
|
||||
return message->getParameter();
|
||||
}
|
||||
|
||||
void DeviceHandlerMessage::setDeviceHandlerRawReplyMessage(
|
||||
CommandMessage* message, object_id_t deviceObjectid,
|
||||
store_address_t rawPacketStoreId, bool isCommand) {
|
||||
if (isCommand) {
|
||||
message->setCommand(REPLY_RAW_COMMAND);
|
||||
} else {
|
||||
message->setCommand(REPLY_RAW_REPLY);
|
||||
}
|
||||
message->setParameter(deviceObjectid);
|
||||
message->setParameter2(rawPacketStoreId.raw);
|
||||
}
|
||||
|
||||
void DeviceHandlerMessage::setDeviceHandlerDirectCommandReply(
|
||||
CommandMessage* message, object_id_t deviceObjectid,
|
||||
store_address_t commandParametersStoreId) {
|
||||
message->setCommand(REPLY_DIRECT_COMMAND_DATA);
|
||||
message->setParameter(deviceObjectid);
|
||||
message->setParameter2(commandParametersStoreId.raw);
|
||||
}
|
||||
|
||||
void DeviceHandlerMessage::clear(CommandMessage* message) {
|
||||
switch (message->getCommand()) {
|
||||
case CMD_RAW:
|
||||
case REPLY_RAW_COMMAND:
|
||||
case REPLY_RAW_REPLY:
|
||||
case REPLY_DIRECT_COMMAND_DATA: {
|
||||
StorageManagerIF *ipcStore = ObjectManager::instance()->get<StorageManagerIF>(
|
||||
objects::IPC_STORE);
|
||||
if (ipcStore != nullptr) {
|
||||
ipcStore->deleteData(getStoreAddress(message));
|
||||
}
|
||||
}
|
||||
/* NO BREAK falls through*/
|
||||
case CMD_SWITCH_ADDRESS:
|
||||
case CMD_WIRETAPPING:
|
||||
message->setCommand(CommandMessage::CMD_NONE);
|
||||
message->setParameter(0);
|
||||
message->setParameter2(0);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
45
src/core/devicehandlers/DeviceTmReportingWrapper.cpp
Normal file
45
src/core/devicehandlers/DeviceTmReportingWrapper.cpp
Normal file
@ -0,0 +1,45 @@
|
||||
#include "DeviceTmReportingWrapper.h"
|
||||
#include "../serialize/SerializeAdapter.h"
|
||||
|
||||
DeviceTmReportingWrapper::DeviceTmReportingWrapper(object_id_t objectId,
|
||||
ActionId_t actionId, SerializeIF* data) :
|
||||
objectId(objectId), actionId(actionId), data(data) {
|
||||
}
|
||||
|
||||
DeviceTmReportingWrapper::~DeviceTmReportingWrapper() {
|
||||
|
||||
}
|
||||
|
||||
ReturnValue_t DeviceTmReportingWrapper::serialize(uint8_t** buffer,
|
||||
size_t* size, size_t maxSize, Endianness streamEndianness) const {
|
||||
ReturnValue_t result = SerializeAdapter::serialize(&objectId,
|
||||
buffer, size, maxSize, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = SerializeAdapter::serialize(&actionId, buffer,
|
||||
size, maxSize, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
return data->serialize(buffer, size, maxSize, streamEndianness);
|
||||
}
|
||||
|
||||
size_t DeviceTmReportingWrapper::getSerializedSize() const {
|
||||
return sizeof(objectId) + sizeof(ActionId_t) + data->getSerializedSize();
|
||||
}
|
||||
|
||||
ReturnValue_t DeviceTmReportingWrapper::deSerialize(const uint8_t** buffer,
|
||||
size_t* size, Endianness streamEndianness) {
|
||||
ReturnValue_t result = SerializeAdapter::deSerialize(&objectId,
|
||||
buffer, size, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = SerializeAdapter::deSerialize(&actionId, buffer,
|
||||
size, streamEndianness);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
return data->deSerialize(buffer, size, streamEndianness);
|
||||
}
|
59
src/core/devicehandlers/HealthDevice.cpp
Normal file
59
src/core/devicehandlers/HealthDevice.cpp
Normal file
@ -0,0 +1,59 @@
|
||||
#include "HealthDevice.h"
|
||||
#include "../ipc/QueueFactory.h"
|
||||
|
||||
HealthDevice::HealthDevice(object_id_t setObjectId,
|
||||
MessageQueueId_t parentQueue) :
|
||||
SystemObject(setObjectId), lastHealth(HEALTHY), parentQueue(
|
||||
parentQueue), commandQueue(), healthHelper(this, setObjectId) {
|
||||
commandQueue = QueueFactory::instance()->createMessageQueue(3);
|
||||
}
|
||||
|
||||
HealthDevice::~HealthDevice() {
|
||||
QueueFactory::instance()->deleteMessageQueue(commandQueue);
|
||||
}
|
||||
|
||||
ReturnValue_t HealthDevice::performOperation(uint8_t opCode) {
|
||||
CommandMessage command;
|
||||
ReturnValue_t result = commandQueue->receiveMessage(&command);
|
||||
if (result == HasReturnvaluesIF::RETURN_OK) {
|
||||
result = healthHelper.handleHealthCommand(&command);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t HealthDevice::initialize() {
|
||||
ReturnValue_t result = SystemObject::initialize();
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
if (parentQueue != 0) {
|
||||
return healthHelper.initialize(parentQueue);
|
||||
} else {
|
||||
return healthHelper.initialize();
|
||||
}
|
||||
}
|
||||
|
||||
MessageQueueId_t HealthDevice::getCommandQueue() const {
|
||||
return commandQueue->getId();
|
||||
}
|
||||
|
||||
void HealthDevice::setParentQueue(MessageQueueId_t parentQueue) {
|
||||
healthHelper.setParentQueue(parentQueue);
|
||||
}
|
||||
|
||||
bool HealthDevice::hasHealthChanged() {
|
||||
bool changed;
|
||||
HealthState currentHealth = healthHelper.getHealth();
|
||||
changed = currentHealth != lastHealth;
|
||||
lastHealth = currentHealth;
|
||||
return changed;
|
||||
}
|
||||
|
||||
ReturnValue_t HealthDevice::setHealth(HealthState health) {
|
||||
healthHelper.setHealth(health);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
HasHealthIF::HealthState HealthDevice::getHealth() {
|
||||
return healthHelper.getHealth();
|
||||
}
|
Reference in New Issue
Block a user