diff --git a/health/HasHealthIF.h b/health/HasHealthIF.h index ac404300..86863ea8 100644 --- a/health/HasHealthIF.h +++ b/health/HasHealthIF.h @@ -1,5 +1,5 @@ -#ifndef HASHEALTHIF_H_ -#define HASHEALTHIF_H_ +#ifndef FSFW_HEALTH_HASHEALTHIF_H_ +#define FSFW_HEALTH_HASHEALTHIF_H_ #include "../events/Event.h" #include "../returnvalues/HasReturnvaluesIF.h" @@ -8,9 +8,13 @@ class HasHealthIF { public: - typedef enum { - HEALTHY = 1, FAULTY = 0, EXTERNAL_CONTROL = 2, NEEDS_RECOVERY = 3, PERMANENT_FAULTY = 4 - } HealthState; + enum HealthState: uint8_t { + HEALTHY = 1, + FAULTY = 0, + EXTERNAL_CONTROL = 2, + NEEDS_RECOVERY = 3, + PERMANENT_FAULTY = 4 + }; static const uint8_t INTERFACE_ID = CLASS_ID::HAS_HEALTH_IF; static const ReturnValue_t OBJECT_NOT_HEALTHY = MAKE_RETURN_CODE(1); @@ -31,20 +35,17 @@ public: virtual MessageQueueId_t getCommandQueue() const = 0; /** - * set the Health State - * + * @brief Set the Health State * The parent will be informed, if the Health changes - * * @param health */ virtual ReturnValue_t setHealth(HealthState health) = 0; /** - * get Health State - * - * @return Health State of the object + * @brief Get Health State + * @return Health State of the object */ virtual HasHealthIF::HealthState getHealth() = 0; }; -#endif /* HASHEALTHIF_H_ */ +#endif /* FSFW_HEALTH_HASHEALTHIF_H_ */ diff --git a/health/HealthHelper.h b/health/HealthHelper.h index d1f1945c..08889fba 100644 --- a/health/HealthHelper.h +++ b/health/HealthHelper.h @@ -12,13 +12,15 @@ #include "../returnvalues/HasReturnvaluesIF.h" /** - * Helper class for Objects that implement HasHealthIF + * @brief Helper class for Objects that implement HasHealthIF + * @details + * It takes care of registering with the Health Table as well as handling + * health commands (including replying to the sender) and updating + * the Health Table. * - * It takes care of registering with the Health Table as well as handling health commands - * (including replying to the sender) and updating the Health Table. - * - * If a parent is set in the ctor, the parent will be informed with a @c HEALTH_INFO message - * about changes in the health state. Note that a @c HEALTH_INFO is only generated if the Health + * If a parent is set in the ctor, the parent will be informed with a + * @c HEALTH_INFO message about changes in the health state. + * Note that a @c HEALTH_INFO is only generated if the Health * changes, not for all @c HEALTH_SET commands received. * * It does NOT handle @c HEALTH_INFO messages @@ -27,10 +29,9 @@ class HealthHelper { public: /** - * ctor - * * @param owner - * @param objectId the object Id to use when communication with the HealthTable + * @param objectId The object Id to use when communication with + * the HealthTable */ HealthHelper(HasHealthIF* owner, object_id_t objectId); @@ -56,8 +57,9 @@ public: * * @param message * @return - * -@c RETURN_OK if the message was handled - * -@c RETURN_FAILED if the message could not be handled (ie it was not a @c HEALTH_SET or @c HEALTH_READ message) + * -@c RETURN_OK if the message was handled + * -@c RETURN_FAILED if the message could not be handled + * (ie it was not a @c HEALTH_SET or @c HEALTH_READ message) */ ReturnValue_t handleHealthCommand(CommandMessage *message); @@ -78,16 +80,19 @@ public: HasHealthIF::HealthState getHealth(); /** - * @param parentQueue the Queue id of the parent object. Set to 0 if no parent present + * @param parentQueue The queue ID of the parent object. + * Set to 0 if no parent present */ void setParentQueue(MessageQueueId_t parentQueue); /** * - * @param parentQueue the Queue id of the parent object. Set to 0 if no parent present + * @param parentQueue The queue ID of the parent object. + * Set to 0 if no parent present * @return - * -@c RETURN_OK if the Health Table was found and the object could be registered - * -@c RETURN_FAILED else + * -@c RETURN_OK if the Health Table was found and the object + * could be registered + * -@c RETURN_FAILED else */ ReturnValue_t initialize(MessageQueueId_t parentQueue ); @@ -110,11 +115,15 @@ private: HasHealthIF* owner; /** - * if the #parentQueue is not NULL, a @c HEALTH_INFO message will be sent to this queue - * @param health the health is passed as parameter so that the number of calls to the health table can be minimized + * if the #parentQueue is not NULL, a @c HEALTH_INFO message + * will be sent to this queue + * @param health + * The health is passed as parameter so that the number of + * calls to the health table can be minimized * @param oldHealth information of the previous health state. */ - void informParent(HasHealthIF::HealthState health, HasHealthIF::HealthState oldHealth); + void informParent(HasHealthIF::HealthState health, + HasHealthIF::HealthState oldHealth); void handleSetHealthCommand(CommandMessage *message); }; diff --git a/health/HealthMessage.cpp b/health/HealthMessage.cpp index 1bb29526..52479c26 100644 --- a/health/HealthMessage.cpp +++ b/health/HealthMessage.cpp @@ -7,11 +7,13 @@ void HealthMessage::setHealthMessage(CommandMessage* message, Command_t command, message->setParameter2(oldHealth); } -void HealthMessage::setHealthMessage(CommandMessage* message, Command_t command) { +void HealthMessage::setHealthMessage(CommandMessage* message, + Command_t command) { message->setCommand(command); } -HasHealthIF::HealthState HealthMessage::getHealth(const CommandMessage* message) { +HasHealthIF::HealthState HealthMessage::getHealth( + const CommandMessage* message) { return (HasHealthIF::HealthState) message->getParameter(); } diff --git a/health/HealthMessage.h b/health/HealthMessage.h index db2a7719..fb979c66 100644 --- a/health/HealthMessage.h +++ b/health/HealthMessage.h @@ -1,5 +1,5 @@ -#ifndef HEALTHMESSAGE_H_ -#define HEALTHMESSAGE_H_ +#ifndef FSFW_HEALTH_HEALTHMESSAGE_H_ +#define FSFW_HEALTH_HEALTHMESSAGE_H_ #include "HasHealthIF.h" #include "../ipc/CommandMessage.h" @@ -7,14 +7,20 @@ class HealthMessage { public: static const uint8_t MESSAGE_ID = messagetypes::HEALTH_COMMAND; - static const Command_t HEALTH_SET = MAKE_COMMAND_ID(1);//REPLY_COMMAND_OK/REPLY_REJECTED - static const Command_t HEALTH_ANNOUNCE = MAKE_COMMAND_ID(3); //NO REPLY! + + static const Command_t HEALTH_SET = MAKE_COMMAND_ID(1); + // No reply expected, health will be announced as event! + static const Command_t HEALTH_ANNOUNCE = MAKE_COMMAND_ID(2); + // Same as before, but all objects in health table will + // announce their health as events. + static const Command_t HEALTH_ANNOUNCE_ALL = MAKE_COMMAND_ID(3); + static const Command_t HEALTH_INFO = MAKE_COMMAND_ID(5); static const Command_t REPLY_HEALTH_SET = MAKE_COMMAND_ID(6); static void setHealthMessage(CommandMessage *message, Command_t command, - HasHealthIF::HealthState health, HasHealthIF::HealthState oldHealth = HasHealthIF::FAULTY); - + HasHealthIF::HealthState health, + HasHealthIF::HealthState oldHealth = HasHealthIF::FAULTY); static void setHealthMessage(CommandMessage *message, Command_t command); static HasHealthIF::HealthState getHealth(const CommandMessage *message); @@ -27,4 +33,4 @@ private: HealthMessage(); }; -#endif /* HEALTHMESSAGE_H_ */ +#endif /* FSFW_HEALTH_HEALTHMESSAGE_H_ */ diff --git a/health/HealthTable.cpp b/health/HealthTable.cpp index 4d2564a3..2b8b6712 100644 --- a/health/HealthTable.cpp +++ b/health/HealthTable.cpp @@ -1,6 +1,7 @@ #include "HealthTable.h" -#include "../serialize/SerializeAdapter.h" +#include "../ipc/MutexHelper.h" #include "../ipc/MutexFactory.h" +#include "../serialize/SerializeAdapter.h" HealthTable::HealthTable(object_id_t objectid) : SystemObject(objectid) { @@ -9,6 +10,12 @@ HealthTable::HealthTable(object_id_t objectid) : mapIterator = healthMap.begin(); } +void HealthTable::setMutexTimeout(MutexIF::TimeoutType timeoutType, + uint32_t timeoutMs) { + this->timeoutType = timeoutType; + this->mutexTimeoutMs = timeoutMs; +} + HealthTable::~HealthTable() { MutexFactory::instance()->deleteMutex(mutex); } @@ -18,74 +25,63 @@ ReturnValue_t HealthTable::registerObject(object_id_t object, if (healthMap.count(object) != 0) { return HasReturnvaluesIF::RETURN_FAILED; } - healthMap.insert( - std::pair(object, - initilialState)); + healthMap.emplace(object, initilialState); return HasReturnvaluesIF::RETURN_OK; } void HealthTable::setHealth(object_id_t object, HasHealthIF::HealthState newState) { - mutex->lockMutex(MutexIF::BLOCKING); + MutexHelper(mutex, timeoutType, mutexTimeoutMs); HealthMap::iterator iter = healthMap.find(object); if (iter != healthMap.end()) { iter->second = newState; } - mutex->unlockMutex(); } HasHealthIF::HealthState HealthTable::getHealth(object_id_t object) { HasHealthIF::HealthState state = HasHealthIF::HEALTHY; - mutex->lockMutex(MutexIF::BLOCKING); + MutexHelper(mutex, timeoutType, mutexTimeoutMs); HealthMap::iterator iter = healthMap.find(object); if (iter != healthMap.end()) { state = iter->second; } - mutex->unlockMutex(); return state; } -uint32_t HealthTable::getPrintSize() { - mutex->lockMutex(MutexIF::BLOCKING); - uint32_t size = healthMap.size() * 5 + 2; - mutex->unlockMutex(); - return size; -} - bool HealthTable::hasHealth(object_id_t object) { - bool exits = false; - mutex->lockMutex(MutexIF::BLOCKING); + MutexHelper(mutex, timeoutType, mutexTimeoutMs); HealthMap::iterator iter = healthMap.find(object); if (iter != healthMap.end()) { - exits = true; + return true; } - mutex->unlockMutex(); - return exits; + return false; +} + +size_t HealthTable::getPrintSize() { + MutexHelper(mutex, timeoutType, mutexTimeoutMs); + uint32_t size = healthMap.size() * sizeof(object_id_t) + + sizeof(HasHealthIF::HealthState) + sizeof(uint16_t); + return size; } void HealthTable::printAll(uint8_t* pointer, size_t maxSize) { - mutex->lockMutex(MutexIF::BLOCKING); + MutexHelper(mutex, timeoutType, mutexTimeoutMs); size_t size = 0; uint16_t count = healthMap.size(); - ReturnValue_t result = SerializeAdapter::serialize(&count, + SerializeAdapter::serialize(&count, &pointer, &size, maxSize, SerializeIF::Endianness::BIG); - HealthMap::iterator iter; - for (iter = healthMap.begin(); - iter != healthMap.end() && result == HasReturnvaluesIF::RETURN_OK; - ++iter) { - result = SerializeAdapter::serialize(&iter->first, + for (const auto& health: healthMap) { + SerializeAdapter::serialize(&health.first, &pointer, &size, maxSize, SerializeIF::Endianness::BIG); - uint8_t health = iter->second; - result = SerializeAdapter::serialize(&health, &pointer, &size, + uint8_t healthValue = health.second; + SerializeAdapter::serialize(&healthValue, &pointer, &size, maxSize, SerializeIF::Endianness::BIG); } - mutex->unlockMutex(); } -ReturnValue_t HealthTable::iterate( - std::pair *value, bool reset) { +ReturnValue_t HealthTable::iterate(HealthEntry *value, bool reset) { ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; - mutex->lockMutex(MutexIF::BLOCKING); + MutexHelper(mutex, timeoutType, mutexTimeoutMs); if (reset) { mapIterator = healthMap.begin(); } @@ -94,7 +90,5 @@ ReturnValue_t HealthTable::iterate( } *value = *mapIterator; mapIterator++; - mutex->unlockMutex(); - return result; } diff --git a/health/HealthTable.h b/health/HealthTable.h index 6f5dd18d..cea34f68 100644 --- a/health/HealthTable.h +++ b/health/HealthTable.h @@ -1,35 +1,47 @@ -#ifndef HEALTHTABLE_H_ -#define HEALTHTABLE_H_ +#ifndef FSFW_HEALTH_HEALTHTABLE_H_ +#define FSFW_HEALTH_HEALTHTABLE_H_ #include "HealthTableIF.h" #include "../objectmanager/SystemObject.h" #include "../ipc/MutexIF.h" #include -typedef std::map HealthMap; class HealthTable: public HealthTableIF, public SystemObject { public: HealthTable(object_id_t objectid); virtual ~HealthTable(); - virtual ReturnValue_t registerObject(object_id_t object, - HasHealthIF::HealthState initilialState = HasHealthIF::HEALTHY); + void setMutexTimeout(MutexIF::TimeoutType timeoutType, uint32_t timeoutMs); - virtual bool hasHealth(object_id_t object); - virtual void setHealth(object_id_t object, HasHealthIF::HealthState newState); - virtual HasHealthIF::HealthState getHealth(object_id_t); + /** HealthTableIF overrides */ + virtual ReturnValue_t registerObject(object_id_t object, + HasHealthIF::HealthState initilialState = + HasHealthIF::HEALTHY) override; + virtual size_t getPrintSize() override; + virtual void printAll(uint8_t *pointer, size_t maxSize) override; - virtual uint32_t getPrintSize(); - virtual void printAll(uint8_t *pointer, size_t maxSize); + /** ManagesHealthIF overrides */ + virtual bool hasHealth(object_id_t object) override; + virtual void setHealth(object_id_t object, + HasHealthIF::HealthState newState) override; + virtual HasHealthIF::HealthState getHealth(object_id_t) override; protected: + using HealthMap = std::map; + using HealthEntry = std::pair; + MutexIF* mutex; + MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING; + uint32_t mutexTimeoutMs = 20; + HealthMap healthMap; HealthMap::iterator mapIterator; - virtual ReturnValue_t iterate(std::pair *value, bool reset = false); + virtual ReturnValue_t iterate( + HealthEntry* value, + bool reset = false) override; }; -#endif /* HEALTHTABLE_H_ */ +#endif /* FSFW_HEALTH_HEALTHTABLE_H_ */ diff --git a/health/HealthTableIF.h b/health/HealthTableIF.h index 404c03e4..d61e6761 100644 --- a/health/HealthTableIF.h +++ b/health/HealthTableIF.h @@ -1,26 +1,24 @@ -#ifndef HEALTHTABLEIF_H_ -#define HEALTHTABLEIF_H_ +#ifndef FSFW_HEALTH_HEALTHTABLEIF_H_ +#define FSFW_HEALTH_HEALTHTABLEIF_H_ #include "ManagesHealthIF.h" #include "../objectmanager/ObjectManagerIF.h" #include "../returnvalues/HasReturnvaluesIF.h" -#include - class HealthTableIF: public ManagesHealthIF { - friend class HealthCommandingService; public: - virtual ~HealthTableIF() { - } + virtual ~HealthTableIF() {} virtual ReturnValue_t registerObject(object_id_t object, HasHealthIF::HealthState initilialState = HasHealthIF::HEALTHY) = 0; - virtual uint32_t getPrintSize() = 0; + virtual size_t getPrintSize() = 0; virtual void printAll(uint8_t *pointer, size_t maxSize) = 0; protected: - virtual ReturnValue_t iterate(std::pair *value, bool reset = false) = 0; + virtual ReturnValue_t iterate( + std::pair *value, + bool reset = false) = 0; }; -#endif /* HEALTHTABLEIF_H_ */ +#endif /* FRAMEWORK_HEALTH_HEALTHTABLEIF_H_ */ diff --git a/health/ManagesHealthIF.h b/health/ManagesHealthIF.h index 42d4c4f0..2edfceca 100644 --- a/health/ManagesHealthIF.h +++ b/health/ManagesHealthIF.h @@ -1,8 +1,9 @@ -#ifndef FRAMEWORK_HEALTH_MANAGESHEALTHIF_H_ -#define FRAMEWORK_HEALTH_MANAGESHEALTHIF_H_ +#ifndef FSFW_HEALTH_MANAGESHEALTHIF_H_ +#define FSFW_HEALTH_MANAGESHEALTHIF_H_ #include "HasHealthIF.h" #include "../objectmanager/ObjectManagerIF.h" + class ManagesHealthIF { public: virtual ~ManagesHealthIF() { @@ -49,4 +50,4 @@ public: } }; -#endif /* FRAMEWORK_HEALTH_MANAGESHEALTHIF_H_ */ +#endif /* FSFW_HEALTH_MANAGESHEALTHIF_H_ */