diff --git a/housekeeping/HasHkPoolParametersIF.h b/housekeeping/HasHkPoolParametersIF.h index ac248cf3..62715a3d 100644 --- a/housekeeping/HasHkPoolParametersIF.h +++ b/housekeeping/HasHkPoolParametersIF.h @@ -2,9 +2,11 @@ #define FRAMEWORK_DATAPOOL_HASHKPOOLPARAMETERSIF_H_ #include #include +#include #include class HousekeepingManager; +class DataSetIF; /** * @brief Type definition for local pool entries. */ @@ -13,17 +15,34 @@ using LocalDataPoolMap = std::map; using LocalDataPoolMapIter = LocalDataPoolMap::iterator; /** - * @brief + * @brief This interface is implemented by classes which posses a local + * data pool (not the managing class) + * @details + * Any class implementing this interface shall also have a HousekeepingManager + * member class which handles the retrieval of the local pool data. + * This is required because the pool entries are templates, which makes + * specifying an interface rather difficult. + * + * This could be circumvented by using a wrapper/accessor function, but + * the LocalPoolVariable classes are templates as well, so this just shifts + * the problem somewhere else. Interfaces are nice, but the most + * pragmatic solution I found was to offer the client the full interface + * of the housekeeping manager. */ class HasHkPoolParametersIF { public: virtual~ HasHkPoolParametersIF() {}; + static constexpr uint8_t INTERFACE_ID = CLASS_ID::HOUSEKEEPING; + static constexpr ReturnValue_t POOL_ENTRY_NOT_FOUND = MAKE_RETURN_CODE(0XA0); + static constexpr ReturnValue_t POOL_ENTRY_TYPE_CONFLICT = MAKE_RETURN_CODE(0xA1); + virtual MessageQueueId_t getCommandQueue() const = 0; virtual ReturnValue_t initializeHousekeepingPoolEntries( LocalDataPoolMap& localDataPoolMap) = 0; - virtual float setMinimalHkSamplingFrequency() = 0; + //virtual float setMinimalHkSamplingFrequency() = 0; virtual HousekeepingManager* getHkManagerHandle() = 0; + virtual DataSetIF* getDataSetHandle(sid_t sid) = 0; }; #endif /* FRAMEWORK_DATAPOOL_HASHKPOOLPARAMETERSIF_H_ */ diff --git a/housekeeping/HousekeepingManager.cpp b/housekeeping/HousekeepingManager.cpp index 05df0ffc..e8edcc39 100644 --- a/housekeeping/HousekeepingManager.cpp +++ b/housekeeping/HousekeepingManager.cpp @@ -1,17 +1,19 @@ +#include #include #include #include #include +#include + HousekeepingManager::HousekeepingManager(HasHkPoolParametersIF* owner) { - //todo :: nullptr check owner. if(owner == nullptr) { sif::error << "HkManager: Invalid supplied owner!" << std::endl; std::exit(0); } this->owner = owner; mutex = MutexFactory::instance()->createMutex(); - owner->setMinimalHkSamplingFrequency(); + //owner->setMinimalHkSamplingFrequency(); } HousekeepingManager::~HousekeepingManager() {} @@ -24,7 +26,7 @@ ReturnValue_t HousekeepingManager::initializeHousekeepingPoolEntriesOnce() { } return result; } - sif::warning << "hk manager says no" << std::endl; + sif::warning << "HousekeepingManager: The map" << std::endl; return HasReturnvaluesIF::RETURN_OK; } @@ -33,18 +35,48 @@ ReturnValue_t HousekeepingManager::handleHousekeepingMessage( return HasReturnvaluesIF::RETURN_OK; } +ReturnValue_t HousekeepingManager::printPoolEntry( + lp_id_t localPoolId) { + auto poolIter = localDpMap.find(localPoolId); + if (poolIter == localDpMap.end()) { + sif::debug << "HousekeepingManager::fechPoolEntry:" + " Pool entry not found." << std::endl; + return HasHkPoolParametersIF::POOL_ENTRY_NOT_FOUND; + } + poolIter->second->print(); + return HasReturnvaluesIF::RETURN_OK; +} + MutexIF* HousekeepingManager::getMutexHandle() { return mutex; } -void HousekeepingManager::setMinimalSamplingFrequency(float frequencySeconds) { - this->samplingFrequency = frequencySeconds; +//void HousekeepingManager::setMinimalSamplingFrequency(float frequencySeconds) { +// this->samplingFrequency = frequencySeconds; +// +//} -} +void HousekeepingManager::generateHousekeepingPacket(sid_t sid) { + LocalDataSet* dataSetToSerialize = dynamic_cast( + owner->getDataSetHandle(sid)); + if(dataSetToSerialize == nullptr) { + sif::warning << "HousekeepingManager::generateHousekeepingPacket:" + " Set ID not found" << std::endl; + return; + } + std::array testBuffer = {}; + uint8_t* dataPtr = testBuffer.data(); + size_t size = 0; + dataSetToSerialize->serialize(&dataPtr, &size, testBuffer.size(), + false); + // and now we send it to the TM funnel or somewhere else -void HousekeepingManager::generateHousekeepingPacket(DataSetIF *dataSet) { } void HousekeepingManager::setHkPacketQueue(MessageQueueIF *msgQueue) { this->hkPacketQueue = msgQueue; } + +const HasHkPoolParametersIF* HousekeepingManager::getOwner() const { + return owner; +} diff --git a/housekeeping/HousekeepingManager.h b/housekeeping/HousekeepingManager.h index feec69fc..43922ae6 100644 --- a/housekeeping/HousekeepingManager.h +++ b/housekeeping/HousekeepingManager.h @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -14,47 +15,36 @@ class HousekeepingManager { + template + friend class LocalPoolVar; + template + friend class LocalPoolVector; + friend class LocalDataSet; public: static constexpr float MINIMAL_SAMPLING_FREQUENCY = 0.2; HousekeepingManager(HasHkPoolParametersIF* owner); virtual~ HousekeepingManager(); - MutexIF* getMutexHandle(); // propably will just call respective local data set functions. - void generateHousekeepingPacket(DataSetIF* dataSet); + void generateHousekeepingPacket(sid_t sid); ReturnValue_t handleHousekeepingMessage(CommandMessage* message); - /** - * Read a variable by supplying its local pool ID and assign the pool - * entry to the supplied PoolEntry pointer. The type of the pool entry - * is deduced automatically. This call is not thread-safe! - * @tparam T Type of the pool entry - * @param localPoolId Pool ID of the variable to read - * @param poolVar [out] Corresponding pool entry will be assigned to the - * supplied pointer. - * @return - */ - template - ReturnValue_t fetchPoolEntry(lp_id_t localPoolId, PoolEntry *poolEntry); - void setMinimalSamplingFrequency(float frequencySeconds); - /** * This function is used to fill the local data pool map with pool - * entries. The default implementation is empty. + * entries. It should only be called once by the pool owner. * @param localDataPoolMap * @return */ ReturnValue_t initializeHousekeepingPoolEntriesOnce(); void setHkPacketQueue(MessageQueueIF* msgQueue); -private: - //! this depends on the PST frequency.. maybe it would be better to just - //! set this manually with a global configuration value which is also - //! passed to the PST. Or force setting this in device handler. - float samplingFrequency = MINIMAL_SAMPLING_FREQUENCY; + const HasHkPoolParametersIF* getOwner() const; + ReturnValue_t printPoolEntry(lp_id_t localPoolId); + +private: //! This is the map holding the actual data. Should only be initialized //! once ! bool mapInitialized = false; @@ -72,24 +62,53 @@ private: //! message..) MessageQueueIF* hkReplyQueue = nullptr; //! Used for HK packets, which are generated without requests. + //! Maybe this will just be the TM funnel. MessageQueueIF* hkPacketQueue = nullptr; + + /** + * Get the pointer to the mutex. Can be used to lock the data pool + * eternally. Use with care and don't forget to unlock locked mutexes! + * For now, only friend classes can accss this function. + * @return + */ + MutexIF* getMutexHandle(); + + /** + * Read a variable by supplying its local pool ID and assign the pool + * entry to the supplied PoolEntry pointer. The type of the pool entry + * is deduced automatically. This call is not thread-safe! + * For now, only friend classes like LocalPoolVar may access this + * function. + * @tparam T Type of the pool entry + * @param localPoolId Pool ID of the variable to read + * @param poolVar [out] Corresponding pool entry will be assigned to the + * supplied pointer. + * @return + */ + template + ReturnValue_t fetchPoolEntry(lp_id_t localPoolId, PoolEntry **poolEntry); + void setMinimalSamplingFrequency(float frequencySeconds); + }; template inline ReturnValue_t HousekeepingManager::fetchPoolEntry(lp_id_t localPoolId, - PoolEntry *poolEntry) { + PoolEntry **poolEntry) { auto poolIter = localDpMap.find(localPoolId); if (poolIter == localDpMap.end()) { - // todo: special returnvalue. - return HasReturnvaluesIF::RETURN_FAILED; + sif::debug << "HousekeepingManager::fechPoolEntry:" + " Pool entry not found." << std::endl; + return HasHkPoolParametersIF::POOL_ENTRY_NOT_FOUND; } - poolEntry = dynamic_cast< PoolEntry* >(poolIter->second); - if(poolEntry == nullptr) { - // todo: special returnvalue. - return HasReturnvaluesIF::RETURN_FAILED; + *poolEntry = dynamic_cast< PoolEntry* >(poolIter->second); + if(*poolEntry == nullptr) { + sif::debug << "HousekeepingManager::fetchPoolEntry:" + " Pool entry not found." << std::endl; + return HasHkPoolParametersIF::POOL_ENTRY_TYPE_CONFLICT; } return HasReturnvaluesIF::RETURN_OK; } + #endif /* FRAMEWORK_HK_HOUSEKEEPINGHELPER_H_ */ diff --git a/housekeeping/HousekeepingMessage.cpp b/housekeeping/HousekeepingMessage.cpp index 65d87e9e..b0109e5d 100644 --- a/housekeeping/HousekeepingMessage.cpp +++ b/housekeeping/HousekeepingMessage.cpp @@ -1,10 +1,10 @@ #include -void HousekeepingMessage::setAddHkReportStructMessage(CommandMessage *message, - set_t setId, store_address_t packet) { - message->setCommand(ADD_HK_REPORT_STRUCT); - message->setParameter(setId); - message->setParameter2(packet.raw); -} +//void HousekeepingMessage::setAddHkReportStructMessage(CommandMessage *message, +// set_t setId, store_address_t packet) { +// message->setCommand(ADD_HK_REPORT_STRUCT); +// message->setParameter(setId); +// message->setParameter2(packet.raw); +//} //void Housekeeping diff --git a/housekeeping/HousekeepingMessage.h b/housekeeping/HousekeepingMessage.h index 80dc83a6..e7ba68ba 100644 --- a/housekeeping/HousekeepingMessage.h +++ b/housekeeping/HousekeepingMessage.h @@ -4,20 +4,15 @@ #include #include -/** - * the sid consists of the target object ID and... something else I forgot. - * Propably a special HK id to distinguish multiple hk pool packages - * inside a handler or controller - */ -typedef uint32_t set_t; - union sid_t { static constexpr uint64_t INVALID_ADDRESS = std::numeric_limits::max(); sid_t(): raw(INVALID_ADDRESS) {} struct { object_id_t objectId ; - set_t hkId; + // A generic 32 bit ID to identify unique HK packets for a single object. + // For example, the DeviceCommandId_t is used for DeviceHandlers + uint32_t ownerSetId; }; /** * Alternative access to the raw value. @@ -79,8 +74,8 @@ public: static constexpr Command_t MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL = MAKE_COMMAND_ID(32); - static void setAddHkReportStructMessage(CommandMessage* message, - set_t setId, store_address_t packet); +// static void setAddHkReportStructMessage(CommandMessage* message, +// DevisetId, store_address_t packet); };