improved DHB error handling

This commit is contained in:
Robin Müller 2021-01-08 16:14:11 +01:00
parent 541478e4d5
commit c0fd981360
7 changed files with 152 additions and 87 deletions

View File

@ -20,7 +20,7 @@ LocalDataPoolManager::LocalDataPoolManager(HasLocalDataPoolIF* owner,
MessageQueueIF* queueToUse, bool appendValidityBuffer): MessageQueueIF* queueToUse, bool appendValidityBuffer):
appendValidityBuffer(appendValidityBuffer) { appendValidityBuffer(appendValidityBuffer) {
if(owner == nullptr) { if(owner == nullptr) {
printWarningOrError(ErrorTypes::WARNING_TYPE, printWarningOrError(fsfw::OutputTypes::OUT_WARNING,
"LocalDataPoolManager", HasReturnvaluesIF::RETURN_FAILED, "LocalDataPoolManager", HasReturnvaluesIF::RETURN_FAILED,
"Invalid supplied owner"); "Invalid supplied owner");
return; return;
@ -28,7 +28,7 @@ LocalDataPoolManager::LocalDataPoolManager(HasLocalDataPoolIF* owner,
this->owner = owner; this->owner = owner;
mutex = MutexFactory::instance()->createMutex(); mutex = MutexFactory::instance()->createMutex();
if(mutex == nullptr) { if(mutex == nullptr) {
printWarningOrError(ErrorTypes::ERROR_TYPE, printWarningOrError(fsfw::OutputTypes::OUT_ERROR,
"LocalDataPoolManager", HasReturnvaluesIF::RETURN_FAILED, "LocalDataPoolManager", HasReturnvaluesIF::RETURN_FAILED,
"Could not create mutex"); "Could not create mutex");
} }
@ -41,7 +41,7 @@ LocalDataPoolManager::~LocalDataPoolManager() {}
ReturnValue_t LocalDataPoolManager::initialize(MessageQueueIF* queueToUse) { ReturnValue_t LocalDataPoolManager::initialize(MessageQueueIF* queueToUse) {
if(queueToUse == nullptr) { if(queueToUse == nullptr) {
// error, all destinations invalid // error, all destinations invalid
printWarningOrError(ErrorTypes::ERROR_TYPE, printWarningOrError(fsfw::OutputTypes::OUT_ERROR,
"initialize", QUEUE_OR_DESTINATION_INVALID); "initialize", QUEUE_OR_DESTINATION_INVALID);
} }
hkQueue = queueToUse; hkQueue = queueToUse;
@ -49,7 +49,7 @@ ReturnValue_t LocalDataPoolManager::initialize(MessageQueueIF* queueToUse) {
ipcStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE); ipcStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
if(ipcStore == nullptr) { if(ipcStore == nullptr) {
// error, all destinations invalid // error, all destinations invalid
printWarningOrError(ErrorTypes::ERROR_TYPE, printWarningOrError(fsfw::OutputTypes::OUT_ERROR,
"initialize", HasReturnvaluesIF::RETURN_FAILED, "initialize", HasReturnvaluesIF::RETURN_FAILED,
"Could not set IPC store."); "Could not set IPC store.");
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
@ -63,7 +63,7 @@ ReturnValue_t LocalDataPoolManager::initialize(MessageQueueIF* queueToUse) {
hkDestinationId = hkPacketReceiver->getHkQueue(); hkDestinationId = hkPacketReceiver->getHkQueue();
} }
else { else {
printWarningOrError(ErrorTypes::ERROR_TYPE, printWarningOrError(fsfw::OutputTypes::OUT_ERROR,
"initialize", QUEUE_OR_DESTINATION_INVALID); "initialize", QUEUE_OR_DESTINATION_INVALID);
return QUEUE_OR_DESTINATION_INVALID; return QUEUE_OR_DESTINATION_INVALID;
} }
@ -88,7 +88,7 @@ ReturnValue_t LocalDataPoolManager::initializeHousekeepingPoolEntriesOnce() {
return result; return result;
} }
printWarningOrError(ErrorTypes::WARNING_TYPE, printWarningOrError(fsfw::OutputTypes::OUT_WARNING,
"initialize", HasReturnvaluesIF::RETURN_FAILED, "initialize", HasReturnvaluesIF::RETURN_FAILED,
"The map should only be initialized once"); "The map should only be initialized once");
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
@ -155,7 +155,7 @@ ReturnValue_t LocalDataPoolManager::handleNotificationUpdate(
LocalPoolObjectBase* poolObj = owner->getPoolObjectHandle( LocalPoolObjectBase* poolObj = owner->getPoolObjectHandle(
receiver.dataId.localPoolId); receiver.dataId.localPoolId);
if(poolObj == nullptr) { if(poolObj == nullptr) {
printWarningOrError(ErrorTypes::WARNING_TYPE, printWarningOrError(fsfw::OutputTypes::OUT_WARNING,
"handleNotificationUpdate", POOLOBJECT_NOT_FOUND); "handleNotificationUpdate", POOLOBJECT_NOT_FOUND);
return POOLOBJECT_NOT_FOUND; return POOLOBJECT_NOT_FOUND;
} }
@ -177,7 +177,7 @@ ReturnValue_t LocalDataPoolManager::handleNotificationUpdate(
LocalPoolDataSetBase* dataSet = owner->getDataSetHandle( LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(
receiver.dataId.sid); receiver.dataId.sid);
if(dataSet == nullptr) { if(dataSet == nullptr) {
printWarningOrError(ErrorTypes::WARNING_TYPE, printWarningOrError(fsfw::OutputTypes::OUT_WARNING,
"handleNotificationUpdate", DATASET_NOT_FOUND); "handleNotificationUpdate", DATASET_NOT_FOUND);
return DATASET_NOT_FOUND; return DATASET_NOT_FOUND;
} }
@ -209,7 +209,7 @@ ReturnValue_t LocalDataPoolManager::handleNotificationSnapshot(
LocalPoolObjectBase* poolObj = owner->getPoolObjectHandle( LocalPoolObjectBase* poolObj = owner->getPoolObjectHandle(
receiver.dataId.localPoolId); receiver.dataId.localPoolId);
if(poolObj == nullptr) { if(poolObj == nullptr) {
printWarningOrError(ErrorTypes::WARNING_TYPE, printWarningOrError(fsfw::OutputTypes::OUT_WARNING,
"handleNotificationSnapshot", POOLOBJECT_NOT_FOUND); "handleNotificationSnapshot", POOLOBJECT_NOT_FOUND);
return POOLOBJECT_NOT_FOUND; return POOLOBJECT_NOT_FOUND;
} }
@ -247,7 +247,7 @@ ReturnValue_t LocalDataPoolManager::handleNotificationSnapshot(
LocalPoolDataSetBase* dataSet = owner->getDataSetHandle( LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(
receiver.dataId.sid); receiver.dataId.sid);
if(dataSet == nullptr) { if(dataSet == nullptr) {
printWarningOrError(ErrorTypes::WARNING_TYPE, printWarningOrError(fsfw::OutputTypes::OUT_WARNING,
"handleNotificationSnapshot", DATASET_NOT_FOUND); "handleNotificationSnapshot", DATASET_NOT_FOUND);
return DATASET_NOT_FOUND; return DATASET_NOT_FOUND;
} }
@ -351,7 +351,7 @@ ReturnValue_t LocalDataPoolManager::subscribeForPeriodicPacket(sid_t sid,
AcceptsHkPacketsIF* hkReceiverObject = AcceptsHkPacketsIF* hkReceiverObject =
objectManager->get<AcceptsHkPacketsIF>(packetDestination); objectManager->get<AcceptsHkPacketsIF>(packetDestination);
if(hkReceiverObject == nullptr) { if(hkReceiverObject == nullptr) {
printWarningOrError(ErrorTypes::WARNING_TYPE, printWarningOrError(fsfw::OutputTypes::OUT_WARNING,
"subscribeForPeriodicPacket", QUEUE_OR_DESTINATION_INVALID); "subscribeForPeriodicPacket", QUEUE_OR_DESTINATION_INVALID);
return QUEUE_OR_DESTINATION_INVALID; return QUEUE_OR_DESTINATION_INVALID;
} }
@ -381,7 +381,7 @@ ReturnValue_t LocalDataPoolManager::subscribeForUpdatePackets(sid_t sid,
AcceptsHkPacketsIF* hkReceiverObject = AcceptsHkPacketsIF* hkReceiverObject =
objectManager->get<AcceptsHkPacketsIF>(packetDestination); objectManager->get<AcceptsHkPacketsIF>(packetDestination);
if(hkReceiverObject == nullptr) { if(hkReceiverObject == nullptr) {
printWarningOrError(ErrorTypes::WARNING_TYPE, printWarningOrError(fsfw::OutputTypes::OUT_WARNING,
"subscribeForPeriodicPacket", QUEUE_OR_DESTINATION_INVALID); "subscribeForPeriodicPacket", QUEUE_OR_DESTINATION_INVALID);
return QUEUE_OR_DESTINATION_INVALID; return QUEUE_OR_DESTINATION_INVALID;
} }
@ -587,7 +587,7 @@ ReturnValue_t LocalDataPoolManager::printPoolEntry(
lp_id_t localPoolId) { lp_id_t localPoolId) {
auto poolIter = localPoolMap.find(localPoolId); auto poolIter = localPoolMap.find(localPoolId);
if (poolIter == localPoolMap.end()) { if (poolIter == localPoolMap.end()) {
printWarningOrError(ErrorTypes::WARNING_TYPE, "printPoolEntry", printWarningOrError(fsfw::OutputTypes::OUT_WARNING, "printPoolEntry",
HasLocalDataPoolIF::POOL_ENTRY_NOT_FOUND); HasLocalDataPoolIF::POOL_ENTRY_NOT_FOUND);
return 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) { MessageQueueId_t destination) {
if(dataSet == nullptr) { if(dataSet == nullptr) {
// Configuration error. // Configuration error.
printWarningOrError(ErrorTypes::WARNING_TYPE, printWarningOrError(fsfw::OutputTypes::OUT_WARNING,
"generateHousekeepingPacket", "generateHousekeepingPacket",
DATASET_NOT_FOUND); DATASET_NOT_FOUND);
return DATASET_NOT_FOUND; return DATASET_NOT_FOUND;
@ -634,7 +634,7 @@ ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid,
if(hkQueue == nullptr) { if(hkQueue == nullptr) {
// error, all destinations invalid // error, all destinations invalid
printWarningOrError(ErrorTypes::WARNING_TYPE, printWarningOrError(fsfw::OutputTypes::OUT_WARNING,
"generateHousekeepingPacket", "generateHousekeepingPacket",
QUEUE_OR_DESTINATION_INVALID); QUEUE_OR_DESTINATION_INVALID);
return 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(destination == MessageQueueIF::NO_QUEUE) {
if(hkDestinationId == MessageQueueIF::NO_QUEUE) { if(hkDestinationId == MessageQueueIF::NO_QUEUE) {
// error, all destinations invalid // error, all destinations invalid
printWarningOrError(ErrorTypes::WARNING_TYPE, printWarningOrError(fsfw::OutputTypes::OUT_WARNING,
"generateHousekeepingPacket", "generateHousekeepingPacket",
QUEUE_OR_DESTINATION_INVALID); QUEUE_OR_DESTINATION_INVALID);
} }
@ -681,7 +681,7 @@ void LocalDataPoolManager::performPeriodicHkGeneration(HkReceiver& receiver) {
sid_t sid = receiver.dataId.sid; sid_t sid = receiver.dataId.sid;
LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(sid); LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(sid);
if(dataSet == nullptr) { if(dataSet == nullptr) {
printWarningOrError(ErrorTypes::WARNING_TYPE, printWarningOrError(fsfw::OutputTypes::OUT_WARNING,
"performPeriodicHkGeneration", "performPeriodicHkGeneration",
DATASET_NOT_FOUND); DATASET_NOT_FOUND);
return; return;
@ -755,7 +755,7 @@ ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid,
// Get and check dataset first. // Get and check dataset first.
LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(sid); LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(sid);
if(dataSet == nullptr) { if(dataSet == nullptr) {
printWarningOrError(ErrorTypes::WARNING_TYPE, printWarningOrError(fsfw::OutputTypes::OUT_WARNING,
"performPeriodicHkGeneration", "performPeriodicHkGeneration",
DATASET_NOT_FOUND); DATASET_NOT_FOUND);
return DATASET_NOT_FOUND; return DATASET_NOT_FOUND;
@ -782,7 +782,7 @@ ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid,
ReturnValue_t result = ipcStore->getFreeElement(&storeId, ReturnValue_t result = ipcStore->getFreeElement(&storeId,
expectedSize,&storePtr); expectedSize,&storePtr);
if(result != HasReturnvaluesIF::RETURN_OK) { if(result != HasReturnvaluesIF::RETURN_OK) {
printWarningOrError(ErrorTypes::ERROR_TYPE, printWarningOrError(fsfw::OutputTypes::OUT_ERROR,
"generateSetStructurePacket", HasReturnvaluesIF::RETURN_FAILED, "generateSetStructurePacket", HasReturnvaluesIF::RETURN_FAILED,
"Could not get free element from IPC store."); "Could not get free element from IPC store.");
return result; return result;
@ -793,7 +793,7 @@ ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid,
result = setPacket.serialize(&storePtr, &size, expectedSize, result = setPacket.serialize(&storePtr, &size, expectedSize,
SerializeIF::Endianness::BIG); SerializeIF::Endianness::BIG);
if(expectedSize != size) { if(expectedSize != size) {
printWarningOrError(ErrorTypes::WARNING_TYPE, printWarningOrError(fsfw::OutputTypes::OUT_WARNING,
"generateSetStructurePacket", HasReturnvaluesIF::RETURN_FAILED, "generateSetStructurePacket", HasReturnvaluesIF::RETURN_FAILED,
"Expected size is not equal to serialized size"); "Expected size is not equal to serialized size");
} }
@ -813,7 +813,7 @@ ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid,
return result; return result;
} }
void LocalDataPoolManager::printWarningOrError(ErrorTypes errorType, void LocalDataPoolManager::printWarningOrError(fsfw::OutputTypes outputType,
const char* functionName, ReturnValue_t error, const char* errorPrint) { const char* functionName, ReturnValue_t error, const char* errorPrint) {
if(errorPrint == nullptr) { if(errorPrint == nullptr) {
if(error == DATASET_NOT_FOUND) { if(error == DATASET_NOT_FOUND) {
@ -823,7 +823,7 @@ void LocalDataPoolManager::printWarningOrError(ErrorTypes errorType,
errorPrint = "Pool Object not found"; errorPrint = "Pool Object not found";
} }
else if(error == HasReturnvaluesIF::RETURN_FAILED) { else if(error == HasReturnvaluesIF::RETURN_FAILED) {
if(errorType == ErrorTypes::WARNING_TYPE) { if(outputType == fsfw::OutputTypes::OUT_WARNING) {
errorPrint = "Generic Warning"; errorPrint = "Generic Warning";
} }
else { 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 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "LocalDataPoolManager::" << functionName sif::warning << "LocalDataPoolManager::" << functionName
<< ": Object ID " << std::setw(8) << std::setfill('0') << ": Object ID " << std::setw(8) << std::setfill('0')
@ -855,7 +855,7 @@ void LocalDataPoolManager::printWarningOrError(ErrorTypes errorType,
owner->getObjectId(), errorPrint); owner->getObjectId(), errorPrint);
#endif #endif
} }
else if(errorType == ErrorTypes::ERROR_TYPE) { else if(outputType == fsfw::OutputTypes::OUT_ERROR) {
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "LocalDataPoolManager::" << functionName sif::error << "LocalDataPoolManager::" << functionName
<< ": Object ID " << std::setw(8) << std::setfill('0') << ": Object ID " << std::setw(8) << std::setfill('0')

View File

@ -371,12 +371,8 @@ private:
ReturnValue_t addUpdateToStore(HousekeepingPacketUpdate& updatePacket, ReturnValue_t addUpdateToStore(HousekeepingPacketUpdate& updatePacket,
store_address_t& storeId); store_address_t& storeId);
enum class ErrorTypes { void printWarningOrError(fsfw::OutputTypes outputType,
WARNING_TYPE, const char* functionName,
ERROR_TYPE
};
void printWarningOrError(ErrorTypes errorType, const char* functionName,
ReturnValue_t errorCode = HasReturnvaluesIF::RETURN_FAILED, ReturnValue_t errorCode = HasReturnvaluesIF::RETURN_FAILED,
const char* errorPrint = nullptr); const char* errorPrint = nullptr);
}; };
@ -387,14 +383,14 @@ ReturnValue_t LocalDataPoolManager::fetchPoolEntry(lp_id_t localPoolId,
PoolEntry<T> **poolEntry) { PoolEntry<T> **poolEntry) {
auto poolIter = localPoolMap.find(localPoolId); auto poolIter = localPoolMap.find(localPoolId);
if (poolIter == localPoolMap.end()) { if (poolIter == localPoolMap.end()) {
printWarningOrError(ErrorTypes::ERROR_TYPE, "fetchPoolEntry", printWarningOrError(fsfw::OutputTypes::OUT_ERROR, "fetchPoolEntry",
HasLocalDataPoolIF::POOL_ENTRY_NOT_FOUND); HasLocalDataPoolIF::POOL_ENTRY_NOT_FOUND);
return HasLocalDataPoolIF::POOL_ENTRY_NOT_FOUND; return HasLocalDataPoolIF::POOL_ENTRY_NOT_FOUND;
} }
*poolEntry = dynamic_cast< PoolEntry<T>* >(poolIter->second); *poolEntry = dynamic_cast< PoolEntry<T>* >(poolIter->second);
if(*poolEntry == nullptr) { if(*poolEntry == nullptr) {
printWarningOrError(ErrorTypes::ERROR_TYPE, "fetchPoolEntry", printWarningOrError(fsfw::OutputTypes::OUT_ERROR, "fetchPoolEntry",
HasLocalDataPoolIF::POOL_ENTRY_TYPE_CONFLICT); HasLocalDataPoolIF::POOL_ENTRY_TYPE_CONFLICT);
return HasLocalDataPoolIF::POOL_ENTRY_TYPE_CONFLICT; return HasLocalDataPoolIF::POOL_ENTRY_TYPE_CONFLICT;
} }

View File

@ -39,13 +39,8 @@ DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId,
cookieInfo.state = COOKIE_UNUSED; cookieInfo.state = COOKIE_UNUSED;
cookieInfo.pendingCommand = deviceCommandMap.end(); cookieInfo.pendingCommand = deviceCommandMap.end();
if (comCookie == nullptr) { if (comCookie == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1 printWarningOrError(fsfw::OutputTypes::OUT_ERROR, "DeviceHandlerBase",
sif::error << "DeviceHandlerBase: ObjectID 0x" << std::hex HasReturnvaluesIF::RETURN_FAILED, "Invalid cookie");
<< 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
} }
if (this->fdirInstance == nullptr) { if (this->fdirInstance == nullptr) {
this->fdirInstance = new DeviceHandlerFailureIsolation(setObjectId, this->fdirInstance = new DeviceHandlerFailureIsolation(setObjectId,
@ -132,30 +127,24 @@ ReturnValue_t DeviceHandlerBase::initialize() {
communicationInterface = objectManager->get<DeviceCommunicationIF>( communicationInterface = objectManager->get<DeviceCommunicationIF>(
deviceCommunicationId); deviceCommunicationId);
if (communicationInterface == nullptr) { if (communicationInterface == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1 printWarningOrError(fsfw::OutputTypes::OUT_ERROR, "initialize",
sif::error << "DeviceHandlerBase::initialize: Communication interface " ObjectManagerIF::CHILD_INIT_FAILED,
"invalid." << std::endl; "Passed communication IF invalid");
sif::error << "Make sure it is set up properly and implements"
" DeviceCommunicationIF" << std::endl;
#endif
return ObjectManagerIF::CHILD_INIT_FAILED; return ObjectManagerIF::CHILD_INIT_FAILED;
} }
result = communicationInterface->initializeInterface(comCookie); result = communicationInterface->initializeInterface(comCookie);
if (result != RETURN_OK) { if (result != RETURN_OK) {
#if FSFW_CPP_OSTREAM_ENABLED == 1 printWarningOrError(fsfw::OutputTypes::OUT_ERROR, "initialize",
sif::error << "DeviceHandlerBase::initialize: Initializing " ObjectManagerIF::CHILD_INIT_FAILED,
"communication interface failed!" << std::endl; "ComIF initialization failed");
#endif
return result; return result;
} }
IPCStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE); IPCStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
if (IPCStore == nullptr) { if (IPCStore == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1 printWarningOrError(fsfw::OutputTypes::OUT_ERROR, "initialize",
sif::error << "DeviceHandlerBase::initialize: IPC store not set up in " ObjectManagerIF::CHILD_INIT_FAILED, "IPC Store not set up");
"factory." << std::endl;
#endif
return ObjectManagerIF::CHILD_INIT_FAILED; return ObjectManagerIF::CHILD_INIT_FAILED;
} }
@ -164,11 +153,15 @@ ReturnValue_t DeviceHandlerBase::initialize() {
AcceptsDeviceResponsesIF>(rawDataReceiverId); AcceptsDeviceResponsesIF>(rawDataReceiverId);
if (rawReceiver == nullptr) { 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 #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" sif::error << "Make sure the raw receiver object is set up properly"
" and implements AcceptsDeviceResponsesIF" << std::endl; " and implements AcceptsDeviceResponsesIF" << std::endl;
#else
fsfw::printError("Make sure the raw receiver object is set up "
"properly and implements AcceptsDeviceResponsesIF\n");
#endif #endif
return ObjectManagerIF::CHILD_INIT_FAILED; return ObjectManagerIF::CHILD_INIT_FAILED;
} }
@ -178,11 +171,15 @@ ReturnValue_t DeviceHandlerBase::initialize() {
if(powerSwitcherId != objects::NO_OBJECT) { if(powerSwitcherId != objects::NO_OBJECT) {
powerSwitcher = objectManager->get<PowerSwitchIF>(powerSwitcherId); powerSwitcher = objectManager->get<PowerSwitchIF>(powerSwitcherId);
if (powerSwitcher == nullptr) { 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 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "DeviceHandlerBase::initialize: Power switcher " sif::error << "Make sure the power switcher object is set up "
<< "object ID set but no valid object found." << std::endl; << "properly and implements PowerSwitchIF" << std::endl;
sif::error << "Make sure the raw receiver object is set up properly" #else
<< " and implements PowerSwitchIF" << std::endl; fsfw::printError("Make sure the power switcher object is set up "
"properly and implements PowerSwitchIF\n");
#endif #endif
return ObjectManagerIF::CHILD_INIT_FAILED; return ObjectManagerIF::CHILD_INIT_FAILED;
} }
@ -556,17 +553,17 @@ void DeviceHandlerBase::replyReturnvalueToCommand(ReturnValue_t status,
void DeviceHandlerBase::replyToCommand(ReturnValue_t status, void DeviceHandlerBase::replyToCommand(ReturnValue_t status,
uint32_t parameter) { 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 (cookieInfo.pendingCommand->first == RAW_COMMAND_ID) {
if (status == NO_REPLY_EXPECTED) { if (status == NO_REPLY_EXPECTED) {
status = RETURN_OK; status = RETURN_OK;
} }
replyReturnvalueToCommand(status, parameter); replyReturnvalueToCommand(status, parameter);
//Always delete data from a raw command. // Always delete data from a raw command.
IPCStore->deleteData(storedRawData); IPCStore->deleteData(storedRawData);
return; return;
} }
//Check if we were externally commanded. // Check if we were externally commanded.
if (cookieInfo.pendingCommand->second.sendReplyTo != NO_COMMANDER) { if (cookieInfo.pendingCommand->second.sendReplyTo != NO_COMMANDER) {
MessageQueueId_t queueId = cookieInfo.pendingCommand->second.sendReplyTo; MessageQueueId_t queueId = cookieInfo.pendingCommand->second.sendReplyTo;
if (status == NO_REPLY_EXPECTED) { if (status == NO_REPLY_EXPECTED) {
@ -581,15 +578,17 @@ void DeviceHandlerBase::replyToCommand(ReturnValue_t status,
void DeviceHandlerBase::replyToReply(DeviceReplyMap::iterator iter, void DeviceHandlerBase::replyToReply(DeviceReplyMap::iterator iter,
ReturnValue_t status) { 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()) { if (iter->second.command == deviceCommandMap.end()) {
//Is most likely periodic reply. Silent return. //Is most likely periodic reply. Silent return.
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); DeviceCommandInfo* info = &(iter->second.command->second);
if (--info->expectedReplies == 0) { 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) { if (info->sendReplyTo != NO_COMMANDER) {
actionHelper.finish(info->sendReplyTo, iter->first, status); actionHelper.finish(info->sendReplyTo, iter->first, status);
} }
@ -606,7 +605,7 @@ void DeviceHandlerBase::doSendWrite() {
if (result == RETURN_OK) { if (result == RETURN_OK) {
cookieInfo.state = COOKIE_WRITE_SENT; cookieInfo.state = COOKIE_WRITE_SENT;
} else { } 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, triggerEvent(DEVICE_SENDING_COMMAND_FAILED, result,
cookieInfo.pendingCommand->first); cookieInfo.pendingCommand->first);
replyToCommand(result); replyToCommand(result);
@ -735,6 +734,9 @@ void DeviceHandlerBase::parseReply(const uint8_t* receivedData,
foundId); foundId);
} }
if(foundLen == 0) { 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 #if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "DeviceHandlerBase::parseReply: foundLen is 0!" sif::warning << "DeviceHandlerBase::parseReply: foundLen is 0!"
" Packet parsing will be stuck." << std::endl; " Packet parsing will be stuck." << std::endl;
@ -968,7 +970,8 @@ ReturnValue_t DeviceHandlerBase::getStateOfSwitches(void) {
} }
Mode_t DeviceHandlerBase::getBaseMode(Mode_t transitionMode) { 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) { if (transitionMode == _MODE_START_UP) {
return _MODE_TO_ON; return _MODE_TO_ON;
} }
@ -1291,12 +1294,11 @@ void DeviceHandlerBase::buildInternalCommand(void) {
if (mode == MODE_NORMAL) { if (mode == MODE_NORMAL) {
result = buildNormalDeviceCommand(&deviceCommandId); result = buildNormalDeviceCommand(&deviceCommandId);
if (result == BUSY) { if (result == BUSY) {
//so we can track misconfigurations // so we can track misconfigurations
#if FSFW_CPP_OSTREAM_ENABLED == 1 printWarningOrError(fsfw::OutputTypes::OUT_WARNING,
sif::debug << std::hex << getObjectId() "buildInternalCommand",
<< ": DHB::buildInternalCommand: Busy" << std::dec HasReturnvaluesIF::RETURN_FAILED,
<< std::endl; "Busy.");
#endif
result = NOTHING_TO_SEND; //no need to report this result = NOTHING_TO_SEND; //no need to report this
} }
} }
@ -1320,13 +1322,13 @@ void DeviceHandlerBase::buildInternalCommand(void) {
if (iter == deviceCommandMap.end()) { if (iter == deviceCommandMap.end()) {
result = COMMAND_NOT_SUPPORTED; result = COMMAND_NOT_SUPPORTED;
} else if (iter->second.isExecuting) { } else if (iter->second.isExecuting) {
//so we can track misconfigurations char* output = nullptr;
#if FSFW_CPP_OSTREAM_ENABLED == 1 sprintf(output, "Command %lu is executing", deviceCommandId);
sif::debug << std::hex << getObjectId() // so we can track misconfigurations
<< ": DHB::buildInternalCommand: Command " printWarningOrError(fsfw::OutputTypes::OUT_WARNING,
<< deviceCommandId << " isExecuting" << std::dec "buildInternalCommand",
<< std::endl; HasReturnvaluesIF::RETURN_FAILED,
#endif output);
// this is an internal command, no need to report a failure here, // 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 // missed reply will track if a reply is too late, otherwise, it's ok
return; 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
}
}

View File

@ -6,6 +6,8 @@
#include "DeviceHandlerFailureIsolation.h" #include "DeviceHandlerFailureIsolation.h"
#include "DeviceHandlerThermalSet.h" #include "DeviceHandlerThermalSet.h"
#include "../serviceinterface/ServiceInterface.h"
#include "../serviceinterface/serviceInterfaceDefintions.h"
#include "../objectmanager/SystemObject.h" #include "../objectmanager/SystemObject.h"
#include "../tasks/ExecutableObjectIF.h" #include "../tasks/ExecutableObjectIF.h"
#include "../returnvalues/HasReturnvaluesIF.h" #include "../returnvalues/HasReturnvaluesIF.h"
@ -1111,7 +1113,7 @@ private:
/** /**
* @brief The mode the current transition originated from * @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!! * IMPORTANT: This is not valid during _MODE_SHUT_DOWN and _MODE_START_UP!!
* (it is _MODE_POWER_DOWN during this modes) * (it is _MODE_POWER_DOWN during this modes)
@ -1190,7 +1192,8 @@ private:
* Check if the RMAP sendWrite action was successful. * Check if the RMAP sendWrite action was successful.
* *
* Depending on the result, the following is done * 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 * - if the action was successful, the reply timout counter is initialized
*/ */
void doGetWrite(void); void doGetWrite(void);
@ -1206,9 +1209,9 @@ private:
/** /**
* Check the getRead reply and the contained data. * Check the getRead reply and the contained data.
* *
* If data was received scanForReply() and, if successful, handleReply() are called. * If data was received scanForReply() and, if successful, handleReply()
* If the current mode is @c MODE_RAW, the received packet is sent to the commanding object * are called. If the current mode is @c MODE_RAW, the received packet
* via commandQueue. * is sent to the commanding object via commandQueue.
*/ */
void doGetRead(void); void doGetRead(void);
@ -1227,7 +1230,7 @@ private:
uint32_t *len); 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); void setTransition(Mode_t modeTo, Submode_t submodeTo);
@ -1247,6 +1250,11 @@ private:
void handleTransitionToOnMode(Mode_t commandedMode, void handleTransitionToOnMode(Mode_t commandedMode,
Submode_t commandedSubmode); 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_ */ #endif /* FSFW_DEVICEHANDLERS_DEVICEHANDLERBASE_H_ */

View File

@ -2,6 +2,7 @@
#define FSFW_SERVICEINTERFACE_SERVICEINTERFACE_H_ #define FSFW_SERVICEINTERFACE_SERVICEINTERFACE_H_
#include <FSFWConfig.h> #include <FSFWConfig.h>
#include "serviceInterfaceDefintions.h"
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
#include <fsfw/serviceinterface/ServiceInterfaceStream.h> #include <fsfw/serviceinterface/ServiceInterfaceStream.h>

View File

@ -4,7 +4,7 @@
namespace fsfw { namespace fsfw {
enum class PrintLevel { enum PrintLevel {
NONE = 0, NONE = 0,
//! Strange error when using just ERROR.. //! Strange error when using just ERROR..
ERROR_TYPE = 1, ERROR_TYPE = 1,
@ -13,6 +13,12 @@ enum class PrintLevel {
DEBUG = 4 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); void setPrintLevel(PrintLevel printLevel);
PrintLevel getPrintLevel(); PrintLevel getPrintLevel();

View File

@ -3,6 +3,13 @@
namespace fsfw { 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_RED = "\x1b[31m";
static const char* const ANSI_COLOR_GREEN = "\x1b[32m"; static const char* const ANSI_COLOR_GREEN = "\x1b[32m";
static const char* const ANSI_COLOR_YELLOW = "\x1b[33m"; static const char* const ANSI_COLOR_YELLOW = "\x1b[33m";