From c0fd981360dbb7d16018e9803a2a9a0f97de32f9 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 8 Jan 2021 16:14:11 +0100 Subject: [PATCH] improved DHB error handling --- datapoollocal/LocalDataPoolManager.cpp | 48 +++--- datapoollocal/LocalDataPoolManager.h | 12 +- devicehandlers/DeviceHandlerBase.cpp | 143 ++++++++++++------ devicehandlers/DeviceHandlerBase.h | 20 ++- serviceinterface/ServiceInterface.h | 1 + serviceinterface/ServiceInterfacePrinter.h | 8 +- serviceinterface/serviceInterfaceDefintions.h | 7 + 7 files changed, 152 insertions(+), 87 deletions(-) diff --git a/datapoollocal/LocalDataPoolManager.cpp b/datapoollocal/LocalDataPoolManager.cpp index d1ab553d..0ab6f150 100644 --- a/datapoollocal/LocalDataPoolManager.cpp +++ b/datapoollocal/LocalDataPoolManager.cpp @@ -20,7 +20,7 @@ LocalDataPoolManager::LocalDataPoolManager(HasLocalDataPoolIF* owner, MessageQueueIF* queueToUse, bool appendValidityBuffer): appendValidityBuffer(appendValidityBuffer) { if(owner == nullptr) { - printWarningOrError(ErrorTypes::WARNING_TYPE, + printWarningOrError(fsfw::OutputTypes::OUT_WARNING, "LocalDataPoolManager", HasReturnvaluesIF::RETURN_FAILED, "Invalid supplied owner"); return; @@ -28,7 +28,7 @@ LocalDataPoolManager::LocalDataPoolManager(HasLocalDataPoolIF* owner, this->owner = owner; mutex = MutexFactory::instance()->createMutex(); if(mutex == nullptr) { - printWarningOrError(ErrorTypes::ERROR_TYPE, + printWarningOrError(fsfw::OutputTypes::OUT_ERROR, "LocalDataPoolManager", HasReturnvaluesIF::RETURN_FAILED, "Could not create mutex"); } @@ -41,7 +41,7 @@ LocalDataPoolManager::~LocalDataPoolManager() {} ReturnValue_t LocalDataPoolManager::initialize(MessageQueueIF* queueToUse) { if(queueToUse == nullptr) { // error, all destinations invalid - printWarningOrError(ErrorTypes::ERROR_TYPE, + printWarningOrError(fsfw::OutputTypes::OUT_ERROR, "initialize", QUEUE_OR_DESTINATION_INVALID); } hkQueue = queueToUse; @@ -49,7 +49,7 @@ ReturnValue_t LocalDataPoolManager::initialize(MessageQueueIF* queueToUse) { ipcStore = objectManager->get(objects::IPC_STORE); if(ipcStore == nullptr) { // error, all destinations invalid - printWarningOrError(ErrorTypes::ERROR_TYPE, + printWarningOrError(fsfw::OutputTypes::OUT_ERROR, "initialize", HasReturnvaluesIF::RETURN_FAILED, "Could not set IPC store."); return HasReturnvaluesIF::RETURN_FAILED; @@ -63,7 +63,7 @@ ReturnValue_t LocalDataPoolManager::initialize(MessageQueueIF* queueToUse) { hkDestinationId = hkPacketReceiver->getHkQueue(); } else { - printWarningOrError(ErrorTypes::ERROR_TYPE, + printWarningOrError(fsfw::OutputTypes::OUT_ERROR, "initialize", QUEUE_OR_DESTINATION_INVALID); return QUEUE_OR_DESTINATION_INVALID; } @@ -88,7 +88,7 @@ ReturnValue_t LocalDataPoolManager::initializeHousekeepingPoolEntriesOnce() { return result; } - printWarningOrError(ErrorTypes::WARNING_TYPE, + printWarningOrError(fsfw::OutputTypes::OUT_WARNING, "initialize", HasReturnvaluesIF::RETURN_FAILED, "The map should only be initialized once"); return HasReturnvaluesIF::RETURN_OK; @@ -155,7 +155,7 @@ ReturnValue_t LocalDataPoolManager::handleNotificationUpdate( LocalPoolObjectBase* poolObj = owner->getPoolObjectHandle( receiver.dataId.localPoolId); if(poolObj == nullptr) { - printWarningOrError(ErrorTypes::WARNING_TYPE, + printWarningOrError(fsfw::OutputTypes::OUT_WARNING, "handleNotificationUpdate", POOLOBJECT_NOT_FOUND); return POOLOBJECT_NOT_FOUND; } @@ -177,7 +177,7 @@ ReturnValue_t LocalDataPoolManager::handleNotificationUpdate( LocalPoolDataSetBase* dataSet = owner->getDataSetHandle( receiver.dataId.sid); if(dataSet == nullptr) { - printWarningOrError(ErrorTypes::WARNING_TYPE, + printWarningOrError(fsfw::OutputTypes::OUT_WARNING, "handleNotificationUpdate", DATASET_NOT_FOUND); return DATASET_NOT_FOUND; } @@ -209,7 +209,7 @@ ReturnValue_t LocalDataPoolManager::handleNotificationSnapshot( LocalPoolObjectBase* poolObj = owner->getPoolObjectHandle( receiver.dataId.localPoolId); if(poolObj == nullptr) { - printWarningOrError(ErrorTypes::WARNING_TYPE, + printWarningOrError(fsfw::OutputTypes::OUT_WARNING, "handleNotificationSnapshot", POOLOBJECT_NOT_FOUND); return POOLOBJECT_NOT_FOUND; } @@ -247,7 +247,7 @@ ReturnValue_t LocalDataPoolManager::handleNotificationSnapshot( LocalPoolDataSetBase* dataSet = owner->getDataSetHandle( receiver.dataId.sid); if(dataSet == nullptr) { - printWarningOrError(ErrorTypes::WARNING_TYPE, + printWarningOrError(fsfw::OutputTypes::OUT_WARNING, "handleNotificationSnapshot", DATASET_NOT_FOUND); return DATASET_NOT_FOUND; } @@ -351,7 +351,7 @@ ReturnValue_t LocalDataPoolManager::subscribeForPeriodicPacket(sid_t sid, AcceptsHkPacketsIF* hkReceiverObject = objectManager->get(packetDestination); if(hkReceiverObject == nullptr) { - printWarningOrError(ErrorTypes::WARNING_TYPE, + printWarningOrError(fsfw::OutputTypes::OUT_WARNING, "subscribeForPeriodicPacket", QUEUE_OR_DESTINATION_INVALID); return QUEUE_OR_DESTINATION_INVALID; } @@ -381,7 +381,7 @@ ReturnValue_t LocalDataPoolManager::subscribeForUpdatePackets(sid_t sid, AcceptsHkPacketsIF* hkReceiverObject = objectManager->get(packetDestination); if(hkReceiverObject == nullptr) { - printWarningOrError(ErrorTypes::WARNING_TYPE, + printWarningOrError(fsfw::OutputTypes::OUT_WARNING, "subscribeForPeriodicPacket", QUEUE_OR_DESTINATION_INVALID); return QUEUE_OR_DESTINATION_INVALID; } @@ -587,7 +587,7 @@ ReturnValue_t LocalDataPoolManager::printPoolEntry( lp_id_t localPoolId) { auto poolIter = localPoolMap.find(localPoolId); if (poolIter == localPoolMap.end()) { - printWarningOrError(ErrorTypes::WARNING_TYPE, "printPoolEntry", + printWarningOrError(fsfw::OutputTypes::OUT_WARNING, "printPoolEntry", HasLocalDataPoolIF::POOL_ENTRY_NOT_FOUND); return HasLocalDataPoolIF::POOL_ENTRY_NOT_FOUND; } @@ -608,7 +608,7 @@ ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid, MessageQueueId_t destination) { if(dataSet == nullptr) { // Configuration error. - printWarningOrError(ErrorTypes::WARNING_TYPE, + printWarningOrError(fsfw::OutputTypes::OUT_WARNING, "generateHousekeepingPacket", DATASET_NOT_FOUND); return DATASET_NOT_FOUND; @@ -634,7 +634,7 @@ ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid, if(hkQueue == nullptr) { // error, all destinations invalid - printWarningOrError(ErrorTypes::WARNING_TYPE, + printWarningOrError(fsfw::OutputTypes::OUT_WARNING, "generateHousekeepingPacket", QUEUE_OR_DESTINATION_INVALID); return QUEUE_OR_DESTINATION_INVALID; @@ -642,7 +642,7 @@ ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid, if(destination == MessageQueueIF::NO_QUEUE) { if(hkDestinationId == MessageQueueIF::NO_QUEUE) { // error, all destinations invalid - printWarningOrError(ErrorTypes::WARNING_TYPE, + printWarningOrError(fsfw::OutputTypes::OUT_WARNING, "generateHousekeepingPacket", QUEUE_OR_DESTINATION_INVALID); } @@ -681,7 +681,7 @@ void LocalDataPoolManager::performPeriodicHkGeneration(HkReceiver& receiver) { sid_t sid = receiver.dataId.sid; LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(sid); if(dataSet == nullptr) { - printWarningOrError(ErrorTypes::WARNING_TYPE, + printWarningOrError(fsfw::OutputTypes::OUT_WARNING, "performPeriodicHkGeneration", DATASET_NOT_FOUND); return; @@ -755,7 +755,7 @@ ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid, // Get and check dataset first. LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(sid); if(dataSet == nullptr) { - printWarningOrError(ErrorTypes::WARNING_TYPE, + printWarningOrError(fsfw::OutputTypes::OUT_WARNING, "performPeriodicHkGeneration", DATASET_NOT_FOUND); return DATASET_NOT_FOUND; @@ -782,7 +782,7 @@ ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid, ReturnValue_t result = ipcStore->getFreeElement(&storeId, expectedSize,&storePtr); if(result != HasReturnvaluesIF::RETURN_OK) { - printWarningOrError(ErrorTypes::ERROR_TYPE, + printWarningOrError(fsfw::OutputTypes::OUT_ERROR, "generateSetStructurePacket", HasReturnvaluesIF::RETURN_FAILED, "Could not get free element from IPC store."); return result; @@ -793,7 +793,7 @@ ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid, result = setPacket.serialize(&storePtr, &size, expectedSize, SerializeIF::Endianness::BIG); if(expectedSize != size) { - printWarningOrError(ErrorTypes::WARNING_TYPE, + printWarningOrError(fsfw::OutputTypes::OUT_WARNING, "generateSetStructurePacket", HasReturnvaluesIF::RETURN_FAILED, "Expected size is not equal to serialized size"); } @@ -813,7 +813,7 @@ ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid, return result; } -void LocalDataPoolManager::printWarningOrError(ErrorTypes errorType, +void LocalDataPoolManager::printWarningOrError(fsfw::OutputTypes outputType, const char* functionName, ReturnValue_t error, const char* errorPrint) { if(errorPrint == nullptr) { if(error == DATASET_NOT_FOUND) { @@ -823,7 +823,7 @@ void LocalDataPoolManager::printWarningOrError(ErrorTypes errorType, errorPrint = "Pool Object not found"; } else if(error == HasReturnvaluesIF::RETURN_FAILED) { - if(errorType == ErrorTypes::WARNING_TYPE) { + if(outputType == fsfw::OutputTypes::OUT_WARNING) { errorPrint = "Generic Warning"; } else { @@ -844,7 +844,7 @@ void LocalDataPoolManager::printWarningOrError(ErrorTypes errorType, } } - if(errorType == ErrorTypes::WARNING_TYPE) { + if(outputType == fsfw::OutputTypes::OUT_WARNING) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "LocalDataPoolManager::" << functionName << ": Object ID " << std::setw(8) << std::setfill('0') @@ -855,7 +855,7 @@ void LocalDataPoolManager::printWarningOrError(ErrorTypes errorType, owner->getObjectId(), errorPrint); #endif } - else if(errorType == ErrorTypes::ERROR_TYPE) { + else if(outputType == fsfw::OutputTypes::OUT_ERROR) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::error << "LocalDataPoolManager::" << functionName << ": Object ID " << std::setw(8) << std::setfill('0') diff --git a/datapoollocal/LocalDataPoolManager.h b/datapoollocal/LocalDataPoolManager.h index 730e03e4..eee4c593 100644 --- a/datapoollocal/LocalDataPoolManager.h +++ b/datapoollocal/LocalDataPoolManager.h @@ -371,12 +371,8 @@ private: ReturnValue_t addUpdateToStore(HousekeepingPacketUpdate& updatePacket, store_address_t& storeId); - enum class ErrorTypes { - WARNING_TYPE, - ERROR_TYPE - }; - - void printWarningOrError(ErrorTypes errorType, const char* functionName, + void printWarningOrError(fsfw::OutputTypes outputType, + const char* functionName, ReturnValue_t errorCode = HasReturnvaluesIF::RETURN_FAILED, const char* errorPrint = nullptr); }; @@ -387,14 +383,14 @@ ReturnValue_t LocalDataPoolManager::fetchPoolEntry(lp_id_t localPoolId, PoolEntry **poolEntry) { auto poolIter = localPoolMap.find(localPoolId); if (poolIter == localPoolMap.end()) { - printWarningOrError(ErrorTypes::ERROR_TYPE, "fetchPoolEntry", + printWarningOrError(fsfw::OutputTypes::OUT_ERROR, "fetchPoolEntry", HasLocalDataPoolIF::POOL_ENTRY_NOT_FOUND); return HasLocalDataPoolIF::POOL_ENTRY_NOT_FOUND; } *poolEntry = dynamic_cast< PoolEntry* >(poolIter->second); if(*poolEntry == nullptr) { - printWarningOrError(ErrorTypes::ERROR_TYPE, "fetchPoolEntry", + printWarningOrError(fsfw::OutputTypes::OUT_ERROR, "fetchPoolEntry", HasLocalDataPoolIF::POOL_ENTRY_TYPE_CONFLICT); return HasLocalDataPoolIF::POOL_ENTRY_TYPE_CONFLICT; } diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index 580f8c0d..7ca9922a 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -39,13 +39,8 @@ DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, cookieInfo.state = COOKIE_UNUSED; cookieInfo.pendingCommand = deviceCommandMap.end(); if (comCookie == nullptr) { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "DeviceHandlerBase: ObjectID 0x" << std::hex - << std::setw(8) << std::setfill('0') << this->getObjectId() - << std::dec << ": Do not pass nullptr as a cookie, consider " - << std::setfill(' ') << "passing a dummy cookie instead!" - << std::endl; -#endif + printWarningOrError(fsfw::OutputTypes::OUT_ERROR, "DeviceHandlerBase", + HasReturnvaluesIF::RETURN_FAILED, "Invalid cookie"); } if (this->fdirInstance == nullptr) { this->fdirInstance = new DeviceHandlerFailureIsolation(setObjectId, @@ -132,30 +127,24 @@ ReturnValue_t DeviceHandlerBase::initialize() { communicationInterface = objectManager->get( deviceCommunicationId); if (communicationInterface == nullptr) { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "DeviceHandlerBase::initialize: Communication interface " - "invalid." << std::endl; - sif::error << "Make sure it is set up properly and implements" - " DeviceCommunicationIF" << std::endl; -#endif + printWarningOrError(fsfw::OutputTypes::OUT_ERROR, "initialize", + ObjectManagerIF::CHILD_INIT_FAILED, + "Passed communication IF invalid"); return ObjectManagerIF::CHILD_INIT_FAILED; } result = communicationInterface->initializeInterface(comCookie); if (result != RETURN_OK) { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "DeviceHandlerBase::initialize: Initializing " - "communication interface failed!" << std::endl; -#endif + printWarningOrError(fsfw::OutputTypes::OUT_ERROR, "initialize", + ObjectManagerIF::CHILD_INIT_FAILED, + "ComIF initialization failed"); return result; } IPCStore = objectManager->get(objects::IPC_STORE); if (IPCStore == nullptr) { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "DeviceHandlerBase::initialize: IPC store not set up in " - "factory." << std::endl; -#endif + printWarningOrError(fsfw::OutputTypes::OUT_ERROR, "initialize", + ObjectManagerIF::CHILD_INIT_FAILED, "IPC Store not set up"); return ObjectManagerIF::CHILD_INIT_FAILED; } @@ -164,11 +153,15 @@ ReturnValue_t DeviceHandlerBase::initialize() { AcceptsDeviceResponsesIF>(rawDataReceiverId); if (rawReceiver == nullptr) { + printWarningOrError(fsfw::OutputTypes::OUT_ERROR, + "initialize", ObjectManagerIF::CHILD_INIT_FAILED, + "Raw receiver object ID set but no valid object found."); #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "DeviceHandlerBase::initialize: Raw receiver object " - "ID set but no valid object found." << std::endl; sif::error << "Make sure the raw receiver object is set up properly" " and implements AcceptsDeviceResponsesIF" << std::endl; +#else + fsfw::printError("Make sure the raw receiver object is set up " + "properly and implements AcceptsDeviceResponsesIF\n"); #endif return ObjectManagerIF::CHILD_INIT_FAILED; } @@ -178,11 +171,15 @@ ReturnValue_t DeviceHandlerBase::initialize() { if(powerSwitcherId != objects::NO_OBJECT) { powerSwitcher = objectManager->get(powerSwitcherId); if (powerSwitcher == nullptr) { + printWarningOrError(fsfw::OutputTypes::OUT_ERROR, + "initialize", ObjectManagerIF::CHILD_INIT_FAILED, + "Power switcher set but no valid object found."); #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "DeviceHandlerBase::initialize: Power switcher " - << "object ID set but no valid object found." << std::endl; - sif::error << "Make sure the raw receiver object is set up properly" - << " and implements PowerSwitchIF" << std::endl; + sif::error << "Make sure the power switcher object is set up " + << "properly and implements PowerSwitchIF" << std::endl; +#else + fsfw::printError("Make sure the power switcher object is set up " + "properly and implements PowerSwitchIF\n"); #endif return ObjectManagerIF::CHILD_INIT_FAILED; } @@ -556,17 +553,17 @@ void DeviceHandlerBase::replyReturnvalueToCommand(ReturnValue_t status, void DeviceHandlerBase::replyToCommand(ReturnValue_t status, uint32_t parameter) { -//Check if we reply to a raw command. + // Check if we reply to a raw command. if (cookieInfo.pendingCommand->first == RAW_COMMAND_ID) { if (status == NO_REPLY_EXPECTED) { status = RETURN_OK; } replyReturnvalueToCommand(status, parameter); - //Always delete data from a raw command. + // Always delete data from a raw command. IPCStore->deleteData(storedRawData); return; } -//Check if we were externally commanded. + // Check if we were externally commanded. if (cookieInfo.pendingCommand->second.sendReplyTo != NO_COMMANDER) { MessageQueueId_t queueId = cookieInfo.pendingCommand->second.sendReplyTo; if (status == NO_REPLY_EXPECTED) { @@ -581,15 +578,17 @@ void DeviceHandlerBase::replyToCommand(ReturnValue_t status, void DeviceHandlerBase::replyToReply(DeviceReplyMap::iterator iter, ReturnValue_t status) { -//No need to check if iter exists, as this is checked by callers. If someone else uses the method, add check. + // No need to check if iter exists, as this is checked by callers. + // If someone else uses the method, add check. if (iter->second.command == deviceCommandMap.end()) { //Is most likely periodic reply. Silent return. return; } -//Check if more replies are expected. If so, do nothing. + // Check if more replies are expected. If so, do nothing. DeviceCommandInfo* info = &(iter->second.command->second); if (--info->expectedReplies == 0) { - //Check if it was transition or internal command. Don't send any replies in that case. + // Check if it was transition or internal command. + // Don't send any replies in that case. if (info->sendReplyTo != NO_COMMANDER) { actionHelper.finish(info->sendReplyTo, iter->first, status); } @@ -606,7 +605,7 @@ void DeviceHandlerBase::doSendWrite() { if (result == RETURN_OK) { cookieInfo.state = COOKIE_WRITE_SENT; } else { - //always generate a failure event, so that FDIR knows what's up + // always generate a failure event, so that FDIR knows what's up triggerEvent(DEVICE_SENDING_COMMAND_FAILED, result, cookieInfo.pendingCommand->first); replyToCommand(result); @@ -735,6 +734,9 @@ void DeviceHandlerBase::parseReply(const uint8_t* receivedData, foundId); } if(foundLen == 0) { + printWarningOrError(fsfw::OutputTypes::OUT_ERROR, + "parseReply", ObjectManagerIF::CHILD_INIT_FAILED, + "Power switcher set but no valid object found."); #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "DeviceHandlerBase::parseReply: foundLen is 0!" " Packet parsing will be stuck." << std::endl; @@ -968,7 +970,8 @@ ReturnValue_t DeviceHandlerBase::getStateOfSwitches(void) { } Mode_t DeviceHandlerBase::getBaseMode(Mode_t transitionMode) { -//only child action special modes are handled, as a child should never see any base action modes + // only child action special modes are handled, as a child should + // never see any base action modes if (transitionMode == _MODE_START_UP) { return _MODE_TO_ON; } @@ -1291,12 +1294,11 @@ void DeviceHandlerBase::buildInternalCommand(void) { if (mode == MODE_NORMAL) { result = buildNormalDeviceCommand(&deviceCommandId); if (result == BUSY) { - //so we can track misconfigurations -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::debug << std::hex << getObjectId() - << ": DHB::buildInternalCommand: Busy" << std::dec - << std::endl; -#endif + // so we can track misconfigurations + printWarningOrError(fsfw::OutputTypes::OUT_WARNING, + "buildInternalCommand", + HasReturnvaluesIF::RETURN_FAILED, + "Busy."); result = NOTHING_TO_SEND; //no need to report this } } @@ -1320,13 +1322,13 @@ void DeviceHandlerBase::buildInternalCommand(void) { if (iter == deviceCommandMap.end()) { result = COMMAND_NOT_SUPPORTED; } else if (iter->second.isExecuting) { - //so we can track misconfigurations -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::debug << std::hex << getObjectId() - << ": DHB::buildInternalCommand: Command " - << deviceCommandId << " isExecuting" << std::dec - << std::endl; -#endif + char* output = nullptr; + sprintf(output, "Command %lu is executing", deviceCommandId); + // so we can track misconfigurations + printWarningOrError(fsfw::OutputTypes::OUT_WARNING, + "buildInternalCommand", + HasReturnvaluesIF::RETURN_FAILED, + output); // this is an internal command, no need to report a failure here, // missed reply will track if a reply is too late, otherwise, it's ok return; @@ -1485,3 +1487,48 @@ void DeviceHandlerBase::setNormalDatapoolEntriesInvalid() { } } } + +void DeviceHandlerBase::printWarningOrError(fsfw::OutputTypes errorType, + const char *functionName, ReturnValue_t errorCode, + const char *errorPrint) { + if(errorPrint == nullptr) { + if(errorCode == ObjectManagerIF::CHILD_INIT_FAILED) { + errorPrint = "Initialization error"; + } + if(errorCode == HasReturnvaluesIF::RETURN_FAILED) { + if(errorType == fsfw::OutputTypes::OUT_WARNING) { + errorPrint = "Generic Warning"; + } + else { + errorPrint = "Generic Error"; + } + } + else { + errorPrint = "Unknown error"; + } + } + + if(errorType == fsfw::OutputTypes::OUT_WARNING) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "DeviceHandlerBase::" << functionName << ": Object ID " + << std::hex << std::setw(8) << std::setfill('0') + << this->getObjectId() << " | " << errorPrint << std::dec + << std::setfill(' ') << std::endl; +#else + fsfw::printWarning("DeviceHandlerBase::%s: Object ID 0x%08x | %s\n", + this->getObjectId(), errorPrint); +#endif + } + else if(errorType == fsfw::OutputTypes::OUT_ERROR) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "DeviceHandlerBase::" << functionName << ": Object ID " + << std::hex << std::setw(8) << std::setfill('0') + << this->getObjectId() << " | " << errorPrint << std::dec + << std::setfill(' ') << std::endl; +#else + fsfw::printError("DeviceHandlerBase::%s: Object ID 0x%08x | %s\n", + this->getObjectId(), errorPrint); +#endif + } + +} diff --git a/devicehandlers/DeviceHandlerBase.h b/devicehandlers/DeviceHandlerBase.h index 24ba0372..4c745b4f 100644 --- a/devicehandlers/DeviceHandlerBase.h +++ b/devicehandlers/DeviceHandlerBase.h @@ -6,6 +6,8 @@ #include "DeviceHandlerFailureIsolation.h" #include "DeviceHandlerThermalSet.h" +#include "../serviceinterface/ServiceInterface.h" +#include "../serviceinterface/serviceInterfaceDefintions.h" #include "../objectmanager/SystemObject.h" #include "../tasks/ExecutableObjectIF.h" #include "../returnvalues/HasReturnvaluesIF.h" @@ -1111,7 +1113,7 @@ private: /** * @brief The mode the current transition originated from * - * This is private so the child can not change it and fuck up the timeouts + * This is private so the child can not change it and mess up the timeouts * * IMPORTANT: This is not valid during _MODE_SHUT_DOWN and _MODE_START_UP!! * (it is _MODE_POWER_DOWN during this modes) @@ -1190,7 +1192,8 @@ private: * Check if the RMAP sendWrite action was successful. * * Depending on the result, the following is done - * - if the device command was external commanded, a reply is sent indicating the result + * - if the device command was external commanded, a reply is sent + * indicating the result * - if the action was successful, the reply timout counter is initialized */ void doGetWrite(void); @@ -1206,9 +1209,9 @@ private: /** * Check the getRead reply and the contained data. * - * If data was received scanForReply() and, if successful, handleReply() are called. - * If the current mode is @c MODE_RAW, the received packet is sent to the commanding object - * via commandQueue. + * If data was received scanForReply() and, if successful, handleReply() + * are called. If the current mode is @c MODE_RAW, the received packet + * is sent to the commanding object via commandQueue. */ void doGetRead(void); @@ -1227,7 +1230,7 @@ private: uint32_t *len); /** - * @param modeTo either @c MODE_ON, MODE_NORMAL or MODE_RAW NOTHING ELSE!!! + * @param modeTo either @c MODE_ON, MODE_NORMAL or MODE_RAW, nothing else! */ void setTransition(Mode_t modeTo, Submode_t submodeTo); @@ -1247,6 +1250,11 @@ private: void handleTransitionToOnMode(Mode_t commandedMode, Submode_t commandedSubmode); + + void printWarningOrError(fsfw::OutputTypes errorType, + const char* functionName, + ReturnValue_t errorCode = HasReturnvaluesIF::RETURN_FAILED, + const char* errorPrint = nullptr); }; #endif /* FSFW_DEVICEHANDLERS_DEVICEHANDLERBASE_H_ */ diff --git a/serviceinterface/ServiceInterface.h b/serviceinterface/ServiceInterface.h index 0c7c4383..1f7e5e84 100644 --- a/serviceinterface/ServiceInterface.h +++ b/serviceinterface/ServiceInterface.h @@ -2,6 +2,7 @@ #define FSFW_SERVICEINTERFACE_SERVICEINTERFACE_H_ #include +#include "serviceInterfaceDefintions.h" #if FSFW_CPP_OSTREAM_ENABLED == 1 #include diff --git a/serviceinterface/ServiceInterfacePrinter.h b/serviceinterface/ServiceInterfacePrinter.h index 1f82ba98..9a84f629 100644 --- a/serviceinterface/ServiceInterfacePrinter.h +++ b/serviceinterface/ServiceInterfacePrinter.h @@ -4,7 +4,7 @@ namespace fsfw { -enum class PrintLevel { +enum PrintLevel { NONE = 0, //! Strange error when using just ERROR.. ERROR_TYPE = 1, @@ -13,6 +13,12 @@ enum class PrintLevel { DEBUG = 4 }; +/** + * Set the print level. All print types with a smaller level will be printed + * as well. For example, set to PrintLevel::WARNING to only enable error + * and warning output. + * @param printLevel + */ void setPrintLevel(PrintLevel printLevel); PrintLevel getPrintLevel(); diff --git a/serviceinterface/serviceInterfaceDefintions.h b/serviceinterface/serviceInterfaceDefintions.h index 684c7366..de445907 100644 --- a/serviceinterface/serviceInterfaceDefintions.h +++ b/serviceinterface/serviceInterfaceDefintions.h @@ -3,6 +3,13 @@ namespace fsfw { +enum class OutputTypes { + OUT_INFO, + OUT_DEBUG, + OUT_WARNING, + OUT_ERROR +}; + static const char* const ANSI_COLOR_RED = "\x1b[31m"; static const char* const ANSI_COLOR_GREEN = "\x1b[32m"; static const char* const ANSI_COLOR_YELLOW = "\x1b[33m";