From 837fecf8599a54102c59ea549ac56a876ff5c32b Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 30 Jun 2020 21:22:26 +0200 Subject: [PATCH] added hk receiver obj id to dhb ctor --- datapoollocal/LocalDataPoolManager.cpp | 66 +++++++++++++----- datapoollocal/LocalDataPoolManager.h | 84 +++++++++++++++-------- devicehandlers/AcceptsDeviceResponsesIF.h | 17 ++--- devicehandlers/ChildHandlerBase.cpp | 7 +- devicehandlers/ChildHandlerBase.h | 6 +- devicehandlers/DeviceHandlerBase.cpp | 34 +++++---- devicehandlers/DeviceHandlerBase.h | 23 ++++--- housekeeping/AcceptsHkPacketsIF.h | 11 +++ tmtcservices/CommandingServiceBase.h | 2 +- 9 files changed, 169 insertions(+), 81 deletions(-) create mode 100644 housekeeping/AcceptsHkPacketsIF.h diff --git a/datapoollocal/LocalDataPoolManager.cpp b/datapoollocal/LocalDataPoolManager.cpp index 55d36a9a9..bb06206e3 100644 --- a/datapoollocal/LocalDataPoolManager.cpp +++ b/datapoollocal/LocalDataPoolManager.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -7,7 +8,7 @@ #include LocalDataPoolManager::LocalDataPoolManager(OwnsLocalDataPoolIF* owner, - uint32_t replyQueueDepth, bool appendValidityBuffer): + MessageQueueIF* queueToUse, bool appendValidityBuffer): appendValidityBuffer(appendValidityBuffer) { if(owner == nullptr) { sif::error << "HkManager: Invalid supplied owner!" << std::endl; @@ -24,16 +25,44 @@ LocalDataPoolManager::LocalDataPoolManager(OwnsLocalDataPoolIF* owner, sif::error << "LocalDataPoolManager::LocalDataPoolManager: " "Could not set IPC store." << std::endl; } - hkQueue = QueueFactory::instance()->createMessageQueue(replyQueueDepth, - HousekeepingMessage::HK_MESSAGE_SIZE); + hkQueue = queueToUse; +} + +ReturnValue_t LocalDataPoolManager::initialize(MessageQueueIF* queueToUse, + object_id_t hkDestination) { + if(queueToUse == nullptr) { + sif::error << "LocalDataPoolManager::initialize: Supplied queue " + "invalid!" << std::endl; + } + hkQueue = queueToUse; + + if(hkDestination == objects::NO_OBJECT) { + return initializeHousekeepingPoolEntriesOnce(); + } + + AcceptsHkPacketsIF* hkReceiver = + objectManager->get(hkDestination); + if(hkReceiver != nullptr) { + setHkPacketDestination(hkReceiver->getHkQueue()); + } + else { + sif::warning << "LocalDataPoolManager::initialize: Could not retrieve" + " queue ID from HK destination object ID. Make sure it exists" + " and the object impements AcceptsHkPacketsIF!" << std::endl; + } + return initializeHousekeepingPoolEntriesOnce(); +} + +void LocalDataPoolManager::setHkPacketDestination( + MessageQueueId_t hkDestination) { + this->hkDestination = hkDestination; } LocalDataPoolManager::~LocalDataPoolManager() {} ReturnValue_t LocalDataPoolManager::initializeHousekeepingPoolEntriesOnce() { if(not mapInitialized) { - ReturnValue_t result = - owner->initializePoolEntries(localDpMap); + ReturnValue_t result = owner->initializePoolEntries(localDpMap); if(result == HasReturnvaluesIF::RETURN_OK) { mapInitialized = true; } @@ -80,16 +109,12 @@ MutexIF* LocalDataPoolManager::getMutexHandle() { return mutex; } -void LocalDataPoolManager::setHkPacketDestination( - MessageQueueId_t destinationQueueId) { - this->currentHkPacketDestination = destinationQueueId; -} - const OwnsLocalDataPoolIF* LocalDataPoolManager::getOwner() const { return owner; } -ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid) { +ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid, + MessageQueueId_t sendTo) { LocalDataSet* dataSetToSerialize = dynamic_cast( owner->getDataSetHandle(sid)); if(dataSetToSerialize == nullptr) { @@ -108,14 +133,21 @@ ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid) { CommandMessage hkMessage; HousekeepingMessage::setHkReportMessage(&hkMessage, sid, storeId); if(hkQueue == nullptr) { - return QUEUE_NOT_SET; + return QUEUE_OR_DESTINATION_NOT_SET; } - if(currentHkPacketDestination != MessageQueueIF::NO_QUEUE) { - result = hkQueue->sendMessage(currentHkPacketDestination, &hkMessage); + if(sendTo != MessageQueueIF::NO_QUEUE) { + result = hkQueue->sendMessage(sendTo, &hkMessage); } else { - result = hkQueue->sendToDefault(&hkMessage); + if(hkDestination == MessageQueueIF::NO_QUEUE) { + sif::warning << "LocalDataPoolManager::generateHousekeepingPacket:" + " Destination is not set properly!" << std::endl; + return QUEUE_OR_DESTINATION_NOT_SET; + } + else { + result = hkQueue->sendMessage(hkDestination, &hkMessage); + } } return result; @@ -149,6 +181,9 @@ ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid) { return result; } +void LocalDataPoolManager::setMinimalSamplingFrequency(float frequencySeconds) { +} + ReturnValue_t LocalDataPoolManager::serializeHkPacketIntoStore( store_address_t *storeId, LocalDataSet* dataSet) { size_t hkSize = dataSet->getSerializedSize(); @@ -177,4 +212,3 @@ ReturnValue_t LocalDataPoolManager::serializeHkPacketIntoStore( } - diff --git a/datapoollocal/LocalDataPoolManager.h b/datapoollocal/LocalDataPoolManager.h index 9d072bf44..3841b99ce 100644 --- a/datapoollocal/LocalDataPoolManager.h +++ b/datapoollocal/LocalDataPoolManager.h @@ -44,18 +44,45 @@ public: static constexpr ReturnValue_t POOL_ENTRY_NOT_FOUND = MAKE_RETURN_CODE(0x0); static constexpr ReturnValue_t POOL_ENTRY_TYPE_CONFLICT = MAKE_RETURN_CODE(0x1); - static constexpr ReturnValue_t QUEUE_NOT_SET = MAKE_RETURN_CODE(0x2); + static constexpr ReturnValue_t QUEUE_OR_DESTINATION_NOT_SET = MAKE_RETURN_CODE(0x2); //static constexpr ReturnValue_t SET_NOT_FOUND = MAKE_RETURN_CODE(0x3); - LocalDataPoolManager(OwnsLocalDataPoolIF* owner, - uint32_t replyQueueDepth = 20, bool appendValidityBuffer = true); + /** + * This constructor is used by a class which wants to implement + * a personal local data pool. The queueToUse can be supplied if it + * is already known. + * + * initialize() has to be called in any case before using the object! + * @param owner + * @param queueToUse + * @param appendValidityBuffer + */ + LocalDataPoolManager(OwnsLocalDataPoolIF* owner, MessageQueueIF* queueToUse, + bool appendValidityBuffer = true); + /** + * Initializes the map by calling the map initialization function of the + * owner abd assigns the queue to use. + * @param queueToUse + * @return + */ + ReturnValue_t initialize(MessageQueueIF* queueToUse, + object_id_t hkDestination); + /** + * This function is used to set the default HK packet destination. + * This destination will usually only be set once. + * @param hkDestination + */ + void setHkPacketDestination(MessageQueueId_t hkDestination); + virtual~ LocalDataPoolManager(); - /* Copying forbidden */ - LocalDataPoolManager(const LocalDataPoolManager &) = delete; - LocalDataPoolManager operator=(const LocalDataPoolManager&) = delete; - - ReturnValue_t generateHousekeepingPacket(sid_t sid); + /** + * Generate a housekeeping packet with a given SID. + * @param sid + * @return + */ + ReturnValue_t generateHousekeepingPacket(sid_t sid, MessageQueueId_t sendTo + = MessageQueueIF::NO_QUEUE); ReturnValue_t generateSetStructurePacket(sid_t sid); ReturnValue_t handleHousekeepingMessage(CommandMessage* message); @@ -68,40 +95,43 @@ public: */ ReturnValue_t initializeHousekeepingPoolEntriesOnce(); - //! Set the queue for HK packets, which are sent unrequested. - void setHkPacketDestination(MessageQueueId_t destinationQueueId); - const OwnsLocalDataPoolIF* getOwner() const; ReturnValue_t printPoolEntry(lp_id_t localPoolId); + /* Copying forbidden */ + LocalDataPoolManager(const LocalDataPoolManager &) = delete; + LocalDataPoolManager operator=(const LocalDataPoolManager&) = delete; private: - //! This is the map holding the actual data. Should only be initialized - //! once ! + /** This is the map holding the actual data. Should only be initialized + * once ! */ bool mapInitialized = false; - //! This specifies whether a validity buffer is appended at the end - //! of generated housekeeping packets. + /** This specifies whether a validity buffer is appended at the end + * of generated housekeeping packets. */ bool appendValidityBuffer = true; LocalDataPool localDpMap; - //! Every housekeeping data manager has a mutex to protect access - //! to it's data pool. + /** Every housekeeping data manager has a mutex to protect access + * to it's data pool. */ MutexIF * mutex = nullptr; - - //! The class which actually owns the manager (and its datapool). + /** The class which actually owns the manager (and its datapool). */ OwnsLocalDataPoolIF* owner = nullptr; - - //! Queue used for communication, for example commands. - //! Is also used to send messages. + /** + * @brief Queue used for communication, for example commands. + * Is also used to send messages. Can be set either in the constructor + * or in the initialize() function. + */ MessageQueueIF* hkQueue = nullptr; - //! HK replies will always be a reply to the commander, but HK packet - //! can be sent to another destination by specifying this message queue - //! ID, for example to a dedicated housekeeping service implementation. - MessageQueueId_t currentHkPacketDestination = MessageQueueIF::NO_QUEUE; + /** + * HK replies will always be a reply to the commander, but HK packet + * can be sent to another destination by specifying this message queue + * ID, for example to a dedicated housekeeping service implementation. + */ + MessageQueueId_t hkDestination = MessageQueueIF::NO_QUEUE; - //! Global IPC store is used to store all packets. + /** Global IPC store is used to store all packets. */ StorageManagerIF* ipcStore = nullptr; /** * Get the pointer to the mutex. Can be used to lock the data pool diff --git a/devicehandlers/AcceptsDeviceResponsesIF.h b/devicehandlers/AcceptsDeviceResponsesIF.h index c811158f6..fcf5237d2 100644 --- a/devicehandlers/AcceptsDeviceResponsesIF.h +++ b/devicehandlers/AcceptsDeviceResponsesIF.h @@ -1,15 +1,12 @@ -/** - * @file AcceptsDeviceResponsesIF.h - * @brief This file defines the AcceptsDeviceResponsesIF class. - * @date 15.05.2013 - * @author baetz - */ - -#ifndef ACCEPTSDEVICERESPONSESIF_H_ -#define ACCEPTSDEVICERESPONSESIF_H_ +#ifndef FRAMEWORK_DEVICEHANDLERS_ACCEPTSDEVICERESPONSESIF_H_ +#define FRAMEWORK_DEVICEHANDLERS_ACCEPTSDEVICERESPONSESIF_H_ #include +/** + * This interface is used by the device handler to send a device response + * to the queue ID, which is returned in the implemented abstract method. + */ class AcceptsDeviceResponsesIF { public: /** @@ -19,4 +16,4 @@ public: virtual MessageQueueId_t getDeviceQueue() = 0; }; -#endif /* ACCEPTSDEVICERESPONSESIF_H_ */ +#endif /* FRAMEWORK_DEVICEHANDLERS_ACCEPTSDEVICERESPONSESIF_H_ */ diff --git a/devicehandlers/ChildHandlerBase.cpp b/devicehandlers/ChildHandlerBase.cpp index c34846769..3e5bcc608 100644 --- a/devicehandlers/ChildHandlerBase.cpp +++ b/devicehandlers/ChildHandlerBase.cpp @@ -5,10 +5,11 @@ ChildHandlerBase::ChildHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication, CookieIF * cookie, uint32_t maxDeviceReplyLen, uint8_t setDeviceSwitch, - uint32_t thermalStatePoolId, uint32_t thermalRequestPoolId, - uint32_t parent, FailureIsolationBase* customFdir, size_t cmdQueueSize) : + object_id_t hkDestination, uint32_t thermalStatePoolId, + uint32_t thermalRequestPoolId, uint32_t parent, + FailureIsolationBase* customFdir, size_t cmdQueueSize) : DeviceHandlerBase(setObjectId, deviceCommunication, cookie, - setDeviceSwitch, thermalStatePoolId, + hkDestination, setDeviceSwitch, thermalStatePoolId, thermalRequestPoolId, (customFdir == NULL? &childHandlerFdir : customFdir), cmdQueueSize), parentId(parent), childHandlerFdir(setObjectId) { diff --git a/devicehandlers/ChildHandlerBase.h b/devicehandlers/ChildHandlerBase.h index 493b22ee2..100216314 100644 --- a/devicehandlers/ChildHandlerBase.h +++ b/devicehandlers/ChildHandlerBase.h @@ -8,9 +8,9 @@ class ChildHandlerBase: public DeviceHandlerBase { public: ChildHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication, CookieIF * cookie, uint32_t maxDeviceReplyLen, uint8_t setDeviceSwitch, - uint32_t thermalStatePoolId, uint32_t thermalRequestPoolId, - uint32_t parent, FailureIsolationBase* customFdir = nullptr, - size_t cmdQueueSize = 20); + object_id_t hkDestination, uint32_t thermalStatePoolId, + uint32_t thermalRequestPoolId, uint32_t parent, + FailureIsolationBase* customFdir = nullptr, size_t cmdQueueSize = 20); virtual ~ChildHandlerBase(); virtual ReturnValue_t initialize(); diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index cebe89531..867bf415e 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -22,21 +22,21 @@ object_id_t DeviceHandlerBase::defaultFDIRParentId = 0; DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication, CookieIF * comCookie, - uint8_t setDeviceSwitch, uint32_t thermalStatePoolId, - uint32_t thermalRequestPoolId, FailureIsolationBase* fdirInstance, - size_t cmdQueueSize) : + uint8_t setDeviceSwitch, object_id_t hkDestination, + uint32_t thermalStatePoolId, uint32_t thermalRequestPoolId, + FailureIsolationBase* fdirInstance, size_t cmdQueueSize) : SystemObject(setObjectId), mode(MODE_OFF), submode(SUBMODE_NONE), wiretappingMode(OFF), storedRawData(StorageManagerIF::INVALID_ADDRESS), deviceCommunicationId(deviceCommunication), comCookie(comCookie), healthHelper(this,setObjectId), modeHelper(this), parameterHelper(this), - actionHelper(this, nullptr), hkManager(this), + actionHelper(this, nullptr), hkManager(this, nullptr), deviceThermalStatePoolId(thermalStatePoolId), deviceThermalRequestPoolId(thermalRequestPoolId), childTransitionFailure(RETURN_OK), fdirInstance(fdirInstance), hkSwitcher(this), defaultFDIRUsed(fdirInstance == nullptr), - switchOffWasReported(false), childTransitionDelay(5000), - transitionSourceMode(_MODE_POWER_DOWN), transitionSourceSubMode( - SUBMODE_NONE), deviceSwitch(setDeviceSwitch) { + switchOffWasReported(false), hkDestination(hkDestination), + childTransitionDelay(5000), transitionSourceMode(_MODE_POWER_DOWN), + transitionSourceSubMode(SUBMODE_NONE), deviceSwitch(setDeviceSwitch) { commandQueue = QueueFactory::instance()->createMessageQueue(cmdQueueSize, MessageQueueMessage::MAX_MESSAGE_SIZE); insertInCommandMap(RAW_COMMAND_ID); @@ -173,7 +173,7 @@ ReturnValue_t DeviceHandlerBase::initialize() { return result; } - result = hkManager.initializeHousekeepingPoolEntriesOnce(); + result = hkManager.initialize(commandQueue, hkDestination); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } @@ -315,6 +315,12 @@ void DeviceHandlerBase::doStateMachine() { case _MODE_WAIT_OFF: { uint32_t currentUptime; Clock::getUptime(¤tUptime); + + if(powerSwitcher == nullptr) { + setMode(MODE_OFF); + return; + } + if (currentUptime - timeoutStart >= powerSwitcher->getSwitchDelayMs()) { triggerEvent(MODE_TRANSITION_FAILED, PowerSwitchIF::SWITCH_TIMEOUT, 0); @@ -696,19 +702,23 @@ void DeviceHandlerBase::handleReply(const uint8_t* receivedData, if (info->delayCycles != 0) { - if (info->periodic != 0) { + if (info->periodic != false) { info->delayCycles = info->maxDelayCycles; - } else { + } + else { info->delayCycles = 0; } + result = interpretDeviceReply(foundId, receivedData); + if (result != RETURN_OK) { // Report failed interpretation to FDIR. replyRawReplyIfnotWiretapped(receivedData, foundLen); triggerEvent(DEVICE_INTERPRETING_REPLY_FAILED, result, foundId); } replyToReply(iter, result); - } else { + } + else { // Other completion failure messages are created by timeout. // Powering down the device might take some time during which periodic // replies may still come in. @@ -719,7 +729,7 @@ void DeviceHandlerBase::handleReply(const uint8_t* receivedData, } ReturnValue_t DeviceHandlerBase::getStorageData(store_address_t storageAddress, - uint8_t * *data, uint32_t * len) { + uint8_t** data, uint32_t * len) { size_t lenTmp; if (IPCStore == nullptr) { diff --git a/devicehandlers/DeviceHandlerBase.h b/devicehandlers/DeviceHandlerBase.h index b2b4798d6..3fdab9ed4 100644 --- a/devicehandlers/DeviceHandlerBase.h +++ b/devicehandlers/DeviceHandlerBase.h @@ -107,6 +107,7 @@ public: */ DeviceHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication, CookieIF * comCookie, uint8_t setDeviceSwitch, + object_id_t hkDestination = objects::NO_OBJECT, uint32_t thermalStatePoolId = PoolVariableIF::NO_PARAMETER, uint32_t thermalRequestPoolId = PoolVariableIF::NO_PARAMETER, FailureIsolationBase* fdirInstance = nullptr, @@ -652,11 +653,13 @@ protected: size_t replyLen = 0; //!< Expected size of the reply. //! if this is !=0, the delayCycles will not be reset to 0 but to //! maxDelayCycles - bool periodic; + bool periodic = false; //! The dataset used to access housekeeping data related to the //! respective device reply. Will point to a dataset held by //! the child handler (if one is specified) - DataSetIF* dataSet; + DataSetIF* dataSet = nullptr; + float collectionInterval = 0.0; + uint32_t intervalCounter = 0; //! The command that expects this reply. DeviceCommandMap::iterator command; }; @@ -1035,18 +1038,19 @@ private: }; /** - * Info about the #cookie - * + * @brief Info about the #cookie * Used to track the state of the communication */ CookieInfo cookieInfo; - /** the object used to set power switches*/ + /** the object used to set power switches */ PowerSwitchIF *powerSwitcher = nullptr; + /** Cached for initialize() */ + object_id_t hkDestination = objects::NO_OBJECT; + /** - * Used for timing out mode transitions. - * + * @brief Used for timing out mode transitions. * Set when setMode() is called. */ uint32_t timeoutStart = 0; @@ -1057,11 +1061,12 @@ private: uint32_t childTransitionDelay; /** - * 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 * - * IMPORTANT: This is not valid during _MODE_SHUT_DOWN and _MODE_START_UP!! (it is _MODE_POWER_DOWN during this modes) + * IMPORTANT: This is not valid during _MODE_SHUT_DOWN and _MODE_START_UP!! + * (it is _MODE_POWER_DOWN during this modes) * * is element of [MODE_ON, MODE_NORMAL, MODE_RAW] */ diff --git a/housekeeping/AcceptsHkPacketsIF.h b/housekeeping/AcceptsHkPacketsIF.h new file mode 100644 index 000000000..f44e1d950 --- /dev/null +++ b/housekeeping/AcceptsHkPacketsIF.h @@ -0,0 +1,11 @@ +#ifndef FRAMEWORK_HOUSEKEEPING_ACCEPTSHKPACKETSIF_H_ +#define FRAMEWORK_HOUSEKEEPING_ACCEPTSHKPACKETSIF_H_ +#include + +class AcceptsHkPacketsIF { +public: + virtual~ AcceptsHkPacketsIF() {}; + virtual MessageQueueId_t getHkQueue() const = 0; +}; + +#endif /* FRAMEWORK_HOUSEKEEPING_ACCEPTSHKPACKETSIF_H_ */ diff --git a/tmtcservices/CommandingServiceBase.h b/tmtcservices/CommandingServiceBase.h index 37fa0a040..700503c69 100644 --- a/tmtcservices/CommandingServiceBase.h +++ b/tmtcservices/CommandingServiceBase.h @@ -89,7 +89,7 @@ public: */ virtual MessageQueueId_t getCommandQueue(); - virtual ReturnValue_t initialize(); + virtual ReturnValue_t initialize() override; /** * Implementation of ExecutableObjectIF function