#include "GomspacePowerFdir.h" #include #include "fsfw/devicehandlers/DeviceHandlerIF.h" #include "fsfw/health/HealthTableIF.h" #include "fsfw/modes/HasModesIF.h" #include "fsfw/objectmanager/ObjectManager.h" #include "fsfw/power/Fuse.h" #include "fsfw/serviceinterface/ServiceInterfaceStream.h" #include "fsfw/thermal/ThermalComponentIF.h" GomspacePowerFdir::GomspacePowerFdir(object_id_t devId, object_id_t parentId) : DeviceHandlerFailureIsolation(devId, parentId) {} ReturnValue_t GomspacePowerFdir::eventReceived(EventMessage* event) { if (isFdirInActionOrAreWeFaulty(event)) { return returnvalue::OK; } ReturnValue_t result = returnvalue::FAILED; switch (event->getEvent()) { case HasModesIF::MODE_TRANSITION_FAILED: case HasModesIF::OBJECT_IN_INVALID_MODE: case DeviceHandlerIF::DEVICE_WANTS_HARD_REBOOT: // We'll try a recovery as long as defined in MAX_REBOOT. // Might cause some AssemblyBase cycles, so keep number low. // handleRecovery(event->getEvent()); triggerEvent(power::FDIR_REACTION_IGNORED, event->getEvent(), 0); 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()); triggerEvent(power::FDIR_REACTION_IGNORED, event->getEvent(), 0); } 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 == returnvalue::OK) { break; } // else if (missedReplyCount.incrementAndCheck()) { // handleRecovery(event->getEvent()); triggerEvent(power::FDIR_REACTION_IGNORED, event->getEvent(), 0); } 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 == returnvalue::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()); triggerEvent(power::FDIR_REACTION_IGNORED, event->getEvent(), 0); 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 returnvalue::FAILED; } return returnvalue::OK; } void GomspacePowerFdir::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()); triggerEvent(power::FDIR_REACTION_IGNORED, event->getEvent(), 0); } break; case PowerSwitchIF::SWITCH_WENT_OFF: // This means the switch went off only for one device. // handleRecovery(event->getEvent()); triggerEvent(power::FDIR_REACTION_IGNORED, event->getEvent(), 0); break; default: break; } }