#include "XiphosWdtHandler.h" #include "fsfw/ipc/QueueFactory.h" XiphosWdtHandler::XiphosWdtHandler(object_id_t objectId) : SystemObject(objectId), requestQueue(QueueFactory::instance()->createMessageQueue()), actionHelper(this, requestQueue) {} ReturnValue_t XiphosWdtHandler::initialize() { ReturnValue_t result = actionHelper.initialize(); if (result != returnvalue::OK) { return result; } int retval = xsc_watchdog_init(&wdtHandle); if (retval != 0) { sif::error << "XiphosWdtHandler: Initiating watchdog failed with code " << retval << ": " << strerror(retval) << std::endl; return ObjectManagerIF::CHILD_INIT_FAILED; } if (wdtHandle == nullptr) { sif::error << "XiphosWdtHandler: WDT handle is nullptr!" << std::endl; return ObjectManagerIF::CHILD_INIT_FAILED; } retval = xsc_watchdog_set_timeout(wdtHandle, timeoutSeconds); if (retval != 0) { // This propably means that the default timeout is used. Still continue with task init. sif::warning << "XiphosWdtHandler: Setting WDT timeout of " << timeoutSeconds << " seconds failed with code " << result << ": " << strerror(retval) << std::endl; } return enableWdt(); } ReturnValue_t XiphosWdtHandler::performOperation(uint8_t opCode) { CommandMessage command; ReturnValue_t result; for (result = requestQueue->receiveMessage(&command); result == returnvalue::OK; result = requestQueue->receiveMessage(&command)) { result = actionHelper.handleActionMessage(&command); if (result == returnvalue::OK) { continue; } sif::warning << "Can not handle message with message type " << command.getMessageType() << std::endl; } if (enabled) { int retval = xsc_watchdog_keepalive(wdtHandle); if (retval != 0) { sif::warning << "XiphosWdtHandler: Feeding WDT failed with code " << retval << ": " << strerror(retval) << std::endl; return returnvalue::FAILED; } } return returnvalue::OK; } ReturnValue_t XiphosWdtHandler::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, const uint8_t *data, size_t size) { switch (actionId) { case (ActionId::ENABLE): { ReturnValue_t result = enableWdt(); if (result != returnvalue::OK) { return result; } return EXECUTION_FINISHED; } case (ActionId::DISABLE): { ReturnValue_t result = disableWdt(); if (result != returnvalue::OK) { return result; } return EXECUTION_FINISHED; } } return HasActionsIF::INVALID_ACTION_ID; } ReturnValue_t XiphosWdtHandler::enableWdt() { int nowayout = 0; int status = 0; int retval = xsc_watchdog_get_status(&nowayout, &status); // If this fails for whatever reason, just try enabling in any case. if (retval != 0) { sif::warning << "XiphosWdtHandler: Getting WDT status failed" << std::endl; } // Of course the enable API will fail if the device is already on, just perfect, love me some // good C API... :))) if (retval != 0 or status == 0) { retval = xsc_watchdog_enable(wdtHandle); if (retval != 0) { sif::error << "XiphosWdtHandler: Enabling WDT failed with code " << retval << ": " << strerror(retval) << std::endl; return returnvalue::FAILED; } } enabled = true; return returnvalue::OK; } ReturnValue_t XiphosWdtHandler::disableWdt() { int nowayout = 0; int status = 0; int retval = xsc_watchdog_get_status(&nowayout, &status); // If this fails for whatever reason, just try disabling in any case. if (retval != 0) { sif::warning << "XiphosWdtHandler: Getting WDT status failed" << std::endl; } // Of course the disable API will fail if the device is already off, just perfect, love me some // good C API... :))) if (retval != 0 or status == 1) { retval = xsc_watchdog_disable(wdtHandle); if (retval != 0) { sif::error << "XiphosWdtHandler: Disabling WDT failed with code " << retval << ": " << strerror(retval) << std::endl; return returnvalue::FAILED; } } enabled = false; return returnvalue::OK; } MessageQueueId_t XiphosWdtHandler::getCommandQueue() const { return requestQueue->getId(); }