diff --git a/container/ArrayList.h b/container/ArrayList.h index bda60433..ae983171 100644 --- a/container/ArrayList.h +++ b/container/ArrayList.h @@ -140,7 +140,11 @@ public: //SHOULDDO this should be implemented as non-member bool operator!=(const typename ArrayList::Iterator& other) const { - return !(*this == other); + // POSSIBLY BUGGY ! Also this is really confusing. Why does + // the operator above use the value while this one + // dereferences itself? + //return not (value == other.value); + return !(*this == other); } }; diff --git a/container/FixedMap.h b/container/FixedMap.h index 475d4091..e5fbb3be 100644 --- a/container/FixedMap.h +++ b/container/FixedMap.h @@ -143,6 +143,15 @@ public: return HasReturnvaluesIF::RETURN_OK; } + bool empty() { + if(_size == 0) { + return true; + } + else { + return false; + } + } + bool full() { if(_size >= theMap.maxSize()) { return true; diff --git a/datapoollocal/HasLocalDataPoolIF.h b/datapoollocal/HasLocalDataPoolIF.h index 4b49ee11..e078f01e 100644 --- a/datapoollocal/HasLocalDataPoolIF.h +++ b/datapoollocal/HasLocalDataPoolIF.h @@ -9,7 +9,8 @@ #include class LocalDataPoolManager; -class DataSetIF; +class LocalPoolDataSetBase; + /** * @brief Type definition for local pool entries. */ @@ -76,7 +77,7 @@ public: * @param sid Corresponding structure ID * @return */ - virtual DataSetIF* getDataSetHandle(sid_t sid) = 0; + virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) = 0; /* These function can be implemented by pool owner, as they are required * by the housekeeping message interface */ diff --git a/datapoollocal/LocalDataPoolManager.cpp b/datapoollocal/LocalDataPoolManager.cpp index 48d57a91..f9a64777 100644 --- a/datapoollocal/LocalDataPoolManager.cpp +++ b/datapoollocal/LocalDataPoolManager.cpp @@ -56,9 +56,6 @@ ReturnValue_t LocalDataPoolManager::initialize(MessageQueueIF* queueToUse) { ReturnValue_t LocalDataPoolManager::initializeAfterTaskCreation( uint8_t nonDiagInvlFactor) { setNonDiagnosticIntervalFactor(nonDiagInvlFactor); - diagnosticMinimumInterval = owner->getPeriodicOperationFrequency(); - regularMinimumInterval = diagnosticMinimumInterval * - nonDiagnosticIntervalFactor; return initializeHousekeepingPoolEntriesOnce(); } @@ -77,12 +74,12 @@ ReturnValue_t LocalDataPoolManager::initializeHousekeepingPoolEntriesOnce() { } ReturnValue_t LocalDataPoolManager::performHkOperation() { - for(auto& hkReceiversIter: hkReceiversMap) { - HkReceiver* receiver = &hkReceiversIter.second; + for(auto& receiver: hkReceiversMap) { + //HkReceiver* receiver = &hkReceiversIter.second; - switch(receiver->reportingType) { + switch(receiver.reportingType) { case(ReportingType::PERIODIC): { - if(receiver->dataId.dataSetSid.notSet()) { + if(receiver.dataType == DataType::LOCAL_POOL_VARIABLE) { // Periodic packets shall only be generated from datasets. continue; } @@ -113,30 +110,19 @@ ReturnValue_t LocalDataPoolManager::subscribeForPeriodicPacket(sid_t sid, } struct HkReceiver hkReceiver; - hkReceiver.dataId.dataSetSid = sid; + hkReceiver.dataId.sid = sid; hkReceiver.reportingType = ReportingType::PERIODIC; hkReceiver.destinationQueue = hkReceiverObject->getHkQueue(); - if(not isDiagnostics) { - hkReceiver.hkParameter.collectionIntervalTicks = - intervalSecondsToInterval(isDiagnostics, collectionInterval * - nonDiagnosticIntervalFactor); - } - else { - hkReceiver.hkParameter.collectionIntervalTicks = - intervalSecondsToInterval(isDiagnostics, collectionInterval); - } - - LocalPoolDataSetBase* dataSet = dynamic_cast( - owner->getDataSetHandle(sid)); + LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(sid); if(dataSet != nullptr) { dataSet->setReportingEnabled(enableReporting); - dataSet->setIsDiagnostic(isDiagnostics); + dataSet->setDiagnostic(isDiagnostics); + dataSet->initializePeriodicHelper(collectionInterval, + owner->getPeriodicOperationFrequency(), isDiagnostics); } - hkReceiver.intervalCounter = 1; - - hkReceiversMap.emplace(packetDestination, hkReceiver); + hkReceiversMap.push_back(hkReceiver); return HasReturnvaluesIF::RETURN_OK; } @@ -153,7 +139,6 @@ ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage( return togglePeriodicGeneration(sid, true, false); case(HousekeepingMessage::DISABLE_PERIODIC_HK_REPORT_GENERATION): return togglePeriodicGeneration(sid, false, false); - case(HousekeepingMessage::REPORT_DIAGNOSTICS_REPORT_STRUCTURES): case(HousekeepingMessage::REPORT_HK_REPORT_STRUCTURES): //return generateSetStructurePacket(sid, ); @@ -174,14 +159,13 @@ ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage( case(HousekeepingMessage::GENERATE_ONE_PARAMETER_REPORT): case(HousekeepingMessage::GENERATE_ONE_DIAGNOSTICS_REPORT): { - LocalPoolDataSetBase* dataSet = dynamic_cast( - owner->getDataSetHandle(sid)); + LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(sid); if(command == HousekeepingMessage::GENERATE_ONE_PARAMETER_REPORT - and dataSet->getIsDiagnostics()) { + and dataSet->isDiagnostics()) { return WRONG_HK_PACKET_TYPE; } else if(command == HousekeepingMessage::GENERATE_ONE_DIAGNOSTICS_REPORT - and not dataSet->getIsDiagnostics()) { + and not dataSet->isDiagnostics()) { return WRONG_HK_PACKET_TYPE; } return generateHousekeepingPacket(HousekeepingMessage::getSid(message), @@ -234,7 +218,7 @@ ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid, // and now we set a HK message and send it the HK packet destination. CommandMessage hkMessage; - if(dataSet->getIsDiagnostics()) { + if(dataSet->isDiagnostics()) { HousekeepingMessage::setHkDiagnosticsReply(&hkMessage, sid, storeId); } else { @@ -280,62 +264,40 @@ void LocalDataPoolManager::setNonDiagnosticIntervalFactor( this->nonDiagnosticIntervalFactor = nonDiagInvlFactor; } -void LocalDataPoolManager::performPeriodicHkGeneration(HkReceiver* receiver) { - if(receiver->intervalCounter >= - receiver->hkParameter.collectionIntervalTicks) { - sid_t sid = receiver->dataId.dataSetSid; - LocalPoolDataSetBase* dataSet = dynamic_cast( - owner->getDataSetHandle(sid)); - if(not dataSet->getReportingEnabled()) { - return; - } +void LocalDataPoolManager::performPeriodicHkGeneration(HkReceiver& receiver) { + sid_t sid = receiver.dataId.sid; + LocalPoolDataSetBase* dataSet = owner->getDataSetHandle(sid); + if(not dataSet->getReportingEnabled()) { + return; + } - ReturnValue_t result = generateHousekeepingPacket( - sid, dataSet, true); - if(result != HasReturnvaluesIF::RETURN_OK) { - // configuration error - sif::debug << "LocalDataPoolManager::performHkOperation:" - << "0x" << std::setfill('0') << std::setw(8) - << owner->getObjectId() << " Error generating " - << "HK packet" << std::setfill(' ') << std::endl; - } - receiver->intervalCounter = 1; - } - else { - receiver->intervalCounter++; - } + if(dataSet->periodicHelper == nullptr) { + // Configuration error. + return; + } + + if(not dataSet->periodicHelper->checkOpNecessary()) { + return; + } + + ReturnValue_t result = generateHousekeepingPacket( + sid, dataSet, true); + if(result != HasReturnvaluesIF::RETURN_OK) { + // configuration error + sif::debug << "LocalDataPoolManager::performHkOperation:" + << "0x" << std::setfill('0') << std::setw(8) + << owner->getObjectId() << " Error generating " + << "HK packet" << std::setfill(' ') << std::endl; + } } -uint32_t LocalDataPoolManager::intervalSecondsToInterval(bool isDiagnostics, - float collectionIntervalSeconds) { - if(isDiagnostics) { - return std::ceil(collectionIntervalSeconds * 1000 - /diagnosticMinimumInterval); - } - else { - return std::ceil(collectionIntervalSeconds * 1000 - /regularMinimumInterval); - } -} - -float LocalDataPoolManager::intervalToIntervalSeconds(bool isDiagnostics, - uint32_t collectionInterval) { - if(isDiagnostics) { - return static_cast(collectionInterval * - diagnosticMinimumInterval); - } - else { - return static_cast(collectionInterval * - regularMinimumInterval); - } -} ReturnValue_t LocalDataPoolManager::togglePeriodicGeneration(sid_t sid, bool enable, bool isDiagnostics) { LocalPoolDataSetBase* dataSet = dynamic_cast( owner->getDataSetHandle(sid)); - if((dataSet->getIsDiagnostics() and not isDiagnostics) or - (not dataSet->getIsDiagnostics() and isDiagnostics)) { + if((dataSet->isDiagnostics() and not isDiagnostics) or + (not dataSet->isDiagnostics() and isDiagnostics)) { return WRONG_HK_PACKET_TYPE; } @@ -352,7 +314,7 @@ ReturnValue_t LocalDataPoolManager::changeCollectionInterval(sid_t sid, float newCollectionInterval, bool isDiagnostics) { LocalPoolDataSetBase* dataSet = dynamic_cast( owner->getDataSetHandle(sid)); - bool targetIsDiagnostics = dataSet->getIsDiagnostics(); + bool targetIsDiagnostics = dataSet->isDiagnostics(); if((targetIsDiagnostics and not isDiagnostics) or (not targetIsDiagnostics and isDiagnostics)) { return WRONG_HK_PACKET_TYPE; @@ -364,50 +326,49 @@ ReturnValue_t LocalDataPoolManager::changeCollectionInterval(sid_t sid, } dataSet->periodicHelper->changeCollectionInterval(newCollectionInterval); -// for(auto& receiver: hkReceiversMap) { -// if(receiver.second.reportingType != ReportingType::PERIODIC) { -// continue; -// } -// -// uint32_t newInterval = intervalSecondsToInterval(isDiagnostics, -// newCollectionInterval); -// receiver.second.hkParameter.collectionIntervalTicks = newInterval; -// } return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid, - float collectionInterval, bool isDiagnostics) { - LocalPoolDataSetBase* dataSet = dynamic_cast( - owner->getDataSetHandle(sid)); - if(dataSet == nullptr) { - sif::warning << "HousekeepingManager::generateHousekeepingPacket:" - " Set ID not found" << std::endl; - return HasReturnvaluesIF::RETURN_FAILED; - } + bool isDiagnostics) { + LocalPoolDataSetBase* dataSet = dynamic_cast( + owner->getDataSetHandle(sid)); + if(dataSet == nullptr) { + sif::warning << "HousekeepingManager::generateHousekeepingPacket:" + " Set ID not found" << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } - bool valid = dataSet->isValid(); - bool targetIsDiagnostics = dataSet->getIsDiagnostics(); - bool reportingEnabled = dataSet->getReportingEnabled(); + bool targetIsDiagnostics = dataSet->isDiagnostics(); + if((targetIsDiagnostics and not isDiagnostics) or + (not targetIsDiagnostics and isDiagnostics)) { + return WRONG_HK_PACKET_TYPE; + } - size_t expectedSize = dataSet->getFillCount() * sizeof(lp_id_t); - uint8_t* storePtr = nullptr; - store_address_t storeId; - HousekeepingSetPacket setPacket = HousekeepingSetPacket(sid, reportingEnabled, - valid, collectionInterval, dataSet); - ReturnValue_t result = ipcStore->getFreeElement(&storeId, - expectedSize,&storePtr); - if(result != HasReturnvaluesIF::RETURN_OK) { - sif::error << "HousekeepingManager::generateHousekeepingPacket: " - "Could not get free element from IPC store." << std::endl; - return result; - } - size_t size = 0; - result = dataSet->serializeLocalPoolIds(&storePtr, &size, - expectedSize, SerializeIF::Endianness::BIG); - if(expectedSize != size) { - sif::error << "HousekeepingManager::generateSetStructurePacket: " - "Expected size is not equal to serialized size" << std::endl; - } - return result; + bool valid = dataSet->isValid(); + bool reportingEnabled = dataSet->getReportingEnabled(); + float collectionInterval = + dataSet->periodicHelper->getCollectionIntervalInSeconds(); + + HousekeepingSetPacket setPacket = HousekeepingSetPacket(sid, + reportingEnabled, valid, collectionInterval, dataSet); + size_t expectedSize = setPacket.getSerializedSize(); + uint8_t* storePtr = nullptr; + store_address_t storeId; + ReturnValue_t result = ipcStore->getFreeElement(&storeId, + expectedSize,&storePtr); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "HousekeepingManager::generateHousekeepingPacket: " + "Could not get free element from IPC store." << std::endl; + return result; + } + + size_t size = 0; + result = setPacket.serialize(&storePtr, &size, expectedSize, + SerializeIF::Endianness::BIG); + if(expectedSize != size) { + sif::error << "HousekeepingManager::generateSetStructurePacket: " + "Expected size is not equal to serialized size" << std::endl; + } + return result; } diff --git a/datapoollocal/LocalDataPoolManager.h b/datapoollocal/LocalDataPoolManager.h index 2a5c68b5..505b9b1a 100644 --- a/datapoollocal/LocalDataPoolManager.h +++ b/datapoollocal/LocalDataPoolManager.h @@ -5,6 +5,7 @@ #include "../housekeeping/HousekeepingPacketDownlink.h" #include "../housekeeping/HousekeepingMessage.h" +#include "../housekeeping/PeriodicHousekeepingHelper.h" #include "../datapool/DataSetIF.h" #include "../datapool/PoolEntry.h" #include "../objectmanager/SystemObjectIF.h" @@ -131,16 +132,15 @@ public: /** * Different types of housekeeping reporting are possible. - * 1. PERIODIC: HK packets are generated in fixed intervals and sent to + * 1. PERIODIC: + * HK packets are generated in fixed intervals and sent to * destination. Fromat will be raw. - * 2. UPDATED: Notification will be sent out if HK data has changed. - * Question: Send Raw data directly or just the message? - * 3. REQUESTED: HK packets are only generated if explicitely requested. + * 2. UPDATE_NOTIFICATION: + * Notification will be sent out if HK data has changed. + * 3. UPDATE_SNAPSHOT: + * HK packets are only generated if explicitely requested. * Propably not necessary, just use multiple local data sets or * shared datasets. - * - * Notifications should also be possible for single variables instead of - * full dataset updates. */ enum class ReportingType: uint8_t { //! Periodic generation of HK packets. @@ -152,6 +152,17 @@ public: UPDATE_SNAPSHOT, }; + /** + * Different data types are possible in the HK receiver map. + * For example, updates can be requested for full datasets or + * for single pool variables. Periodic reporting is only possible for + * data sets. + */ + enum class DataType: uint8_t { + LOCAL_POOL_VARIABLE, + DATA_SET + }; + /* Copying forbidden */ LocalDataPoolManager(const LocalDataPoolManager &) = delete; LocalDataPoolManager operator=(const LocalDataPoolManager&) = delete; @@ -165,8 +176,6 @@ private: HasLocalDataPoolIF* owner = nullptr; uint8_t nonDiagnosticIntervalFactor = 0; - dur_millis_t regularMinimumInterval = 0; - dur_millis_t diagnosticMinimumInterval = 0; /** Default receiver for periodic HK packets */ static object_id_t defaultHkDestination; @@ -174,40 +183,25 @@ private: /** The data pool manager will keep an internal map of HK receivers. */ struct HkReceiver { - /** Different member of this union will be used depending on the - type of data the receiver is interested in (full datasets or - single data variables. */ + /** Object ID of receiver */ + object_id_t objectId = objects::NO_OBJECT; + + DataType dataType = DataType::DATA_SET; union DataId { - DataId(): dataSetSid() {} - /** Will be initialized to INVALID_ADDRESS */ - sid_t dataSetSid; - lp_id_t localPoolId = HasLocalDataPoolIF::NO_POOL_ID; + DataId(): sid() {}; + sid_t sid; + lp_id_t localPoolId; }; DataId dataId; ReportingType reportingType = ReportingType::PERIODIC; - // SHOULDDO: it would be nice to also have the object ID instead of - // a queue (or in addition).. but the FSFW is not ready for that yet. - // Also, an object can have multiple queues. MessageQueueId_t destinationQueue = MessageQueueIF::NO_QUEUE; - - /** Different members of this union will be used depending on reporting - type */ - union HkParameter { - /** This parameter will be used for the PERIODIC type */ - uint32_t collectionIntervalTicks = 0; - /** This parameter will be used for the ON_UPDATE type */ - bool hkDataChanged; - }; - HkParameter hkParameter; - /** General purpose counter which is used for periodic generation. */ - uint32_t intervalCounter; }; - /** Using a multimap as the same object might request multiple datasets */ - using HkReceiversMap = std::multimap; + /** This vector will contain the list of HK receivers. */ + using HkReceivers = std::vector; - HkReceiversMap hkReceiversMap; + HkReceivers hkReceiversMap; /** This is the map holding the actual data. Should only be initialized * once ! */ @@ -252,18 +246,12 @@ private: HousekeepingPacketDownlink& hkPacket, store_address_t& storeId, bool forDownlink, size_t* serializedSize); - uint32_t intervalSecondsToInterval(bool isDiagnostics, - float collectionIntervalSeconds); - float intervalToIntervalSeconds(bool isDiagnostics, - uint32_t collectionInterval); - - void performPeriodicHkGeneration(HkReceiver* hkReceiver); + void performPeriodicHkGeneration(HkReceiver& hkReceiver); ReturnValue_t togglePeriodicGeneration(sid_t sid, bool enable, bool isDiagnostics); ReturnValue_t changeCollectionInterval(sid_t sid, float newCollectionInterval, bool isDiagnostics); - ReturnValue_t generateSetStructurePacket(sid_t sid, - float collectionInterval, bool isDiagnostics); + ReturnValue_t generateSetStructurePacket(sid_t sid, bool isDiagnostics); }; diff --git a/datapoollocal/LocalPoolDataSetBase.cpp b/datapoollocal/LocalPoolDataSetBase.cpp index e0fc6b68..6832005b 100644 --- a/datapoollocal/LocalPoolDataSetBase.cpp +++ b/datapoollocal/LocalPoolDataSetBase.cpp @@ -1,5 +1,6 @@ #include "LocalPoolDataSetBase.h" #include "../datapoollocal/LocalDataPoolManager.h" +#include "../housekeeping/PeriodicHousekeepingHelper.h" #include "../serialize/SerializeAdapter.h" #include @@ -7,13 +8,14 @@ LocalPoolDataSetBase::LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner, uint32_t setId, PoolVariableIF** registeredVariablesArray, - const size_t maxNumberOfVariables): - PoolDataSetBase(registeredVariablesArray, maxNumberOfVariables) { - if(hkOwner == nullptr) { - sif::error << "LocalDataSet::LocalDataSet: Owner can't be nullptr!" - << std::endl; - return; - } + const size_t maxNumberOfVariables): + PoolDataSetBase(registeredVariablesArray, maxNumberOfVariables) { + if(hkOwner == nullptr) { + // Configuration error. + sif::error << "LocalPoolDataSetBase::LocalPoolDataSetBase: Owner " + << "invalid!" << std::endl; + return; + } hkManager = hkOwner->getHkManagerHandle(); this->sid.objectId = hkOwner->getObjectId(); this->sid.ownerSetId = setId; @@ -29,8 +31,9 @@ LocalPoolDataSetBase::LocalPoolDataSetBase(sid_t sid, HasLocalDataPoolIF* hkOwner = objectManager->get( sid.objectId); if(hkOwner == nullptr) { - sif::error << "LocalDataSet::LocalDataSet: Owner can't be nullptr!" - << std::endl; + // Configuration error. + sif::error << "LocalPoolDataSetBase::LocalPoolDataSetBase: Owner " + << "invalid!" << std::endl; return; } hkManager = hkOwner->getHkManagerHandle(); @@ -178,12 +181,12 @@ void LocalPoolDataSetBase::bitSetter(uint8_t* byte, uint8_t position) const { *byte |= 1 << shiftNumber; } -void LocalPoolDataSetBase::setIsDiagnostic(bool isDiagnostics) { - this->isDiagnostics = isDiagnostics; +void LocalPoolDataSetBase::setDiagnostic(bool isDiagnostics) { + this->diagnostic = isDiagnostics; } -bool LocalPoolDataSetBase::getIsDiagnostics() const { - return isDiagnostics; +bool LocalPoolDataSetBase::isDiagnostics() const { + return diagnostic; } void LocalPoolDataSetBase::setReportingEnabled(bool reportingEnabled) { @@ -194,6 +197,25 @@ bool LocalPoolDataSetBase::getReportingEnabled() const { return reportingEnabled; } +void LocalPoolDataSetBase::initializePeriodicHelper( + float collectionInterval, dur_millis_t minimumPeriodicInterval, + bool isDiagnostics, uint8_t nonDiagIntervalFactor) { + periodicHelper->initialize(collectionInterval, minimumPeriodicInterval, + isDiagnostics, nonDiagIntervalFactor); +} + +void LocalPoolDataSetBase::setChanged(bool changed) { + this->changed = changed; +} + +bool LocalPoolDataSetBase::isChanged() const { + return changed; +} + +sid_t LocalPoolDataSetBase::getSid() const { + return sid; +} + bool LocalPoolDataSetBase::bitGetter(const uint8_t* byte, uint8_t position) const { if(position > 7) { diff --git a/datapoollocal/LocalPoolDataSetBase.h b/datapoollocal/LocalPoolDataSetBase.h index 2f7db9fb..1b58a211 100644 --- a/datapoollocal/LocalPoolDataSetBase.h +++ b/datapoollocal/LocalPoolDataSetBase.h @@ -1,7 +1,7 @@ #ifndef FSFW_DATAPOOLLOCAL_LOCALPOOLDATASETBASE_H_ #define FSFW_DATAPOOLLOCAL_LOCALPOOLDATASETBASE_H_ -#include + #include "HasLocalDataPoolIF.h" #include "../datapool/DataSetIF.h" #include "../datapool/PoolDataSetBase.h" @@ -10,6 +10,7 @@ #include class LocalDataPoolManager; +class PeriodicHousekeepingHelper; /** * @brief The LocalDataSet class manages a set of locally checked out @@ -38,14 +39,16 @@ class LocalPoolDataSetBase: public PoolDataSetBase { public: /** * @brief Constructor for the creator of local pool data. + * @details + * This constructor also initializes the components required for + * periodic handling. */ LocalPoolDataSetBase(HasLocalDataPoolIF *hkOwner, uint32_t setId, PoolVariableIF** registeredVariablesArray, const size_t maxNumberOfVariables); /** - * @brief Constructor for users of local pool data. The passed pool - * owner should implement the HasHkPoolParametersIF. + * @brief Constructor for users of local pool data. * @details * @param sid Unique identifier of dataset consisting of object ID and * set ID. @@ -67,6 +70,8 @@ public: void setValidityBufferGeneration(bool withValidityBuffer); + sid_t getSid() const; + ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize, SerializeIF::Endianness streamEndianness) const override; ReturnValue_t deSerialize(const uint8_t** buffer, size_t *size, @@ -102,12 +107,15 @@ public: void setValidity(bool valid, bool setEntriesRecursively); bool isValid() const override; + void setChanged(bool changed); + bool isChanged() const; + protected: sid_t sid; - bool isDiagnostics = false; - void setIsDiagnostic(bool diagnostics); - bool getIsDiagnostics() const; + bool diagnostic = false; + void setDiagnostic(bool diagnostics); + bool isDiagnostics() const; /** * Used for periodic generation. @@ -116,12 +124,22 @@ protected: void setReportingEnabled(bool enabled); bool getReportingEnabled() const; + void initializePeriodicHelper(float collectionInterval, + dur_millis_t minimumPeriodicInterval, + bool isDiagnostics, uint8_t nonDiagIntervalFactor = 5); + /** * If the valid state of a dataset is always relevant to the whole * data set we can use this flag. */ bool valid = false; + /** + * Can be used to mark the dataset as changed, which is used + * by the LocalDataPoolManager to send out update messages. + */ + bool changed = false; + bool withValidityBuffer = true; /** @@ -147,7 +165,7 @@ protected: */ void bitSetter(uint8_t* byte, uint8_t position) const; bool bitGetter(const uint8_t* byte, uint8_t position) const; -private: + PeriodicHousekeepingHelper* periodicHelper = nullptr; }; diff --git a/datapoollocal/StaticLocalDataSet.h b/datapoollocal/StaticLocalDataSet.h index 7c2f0039..2f306898 100644 --- a/datapoollocal/StaticLocalDataSet.h +++ b/datapoollocal/StaticLocalDataSet.h @@ -17,6 +17,24 @@ template class StaticLocalDataSet: public LocalPoolDataSetBase { public: + /** + * Constructor used by data owner and creator like device handlers. + * This constructor also initialized the components required for + * periodic handling. + * @param hkOwner + * @param setId + */ + StaticLocalDataSet(HasLocalDataPoolIF* hkOwner, + uint32_t setId): LocalPoolDataSetBase(hkOwner, setId, nullptr, + NUM_VARIABLES) { + this->setContainer(poolVarList.data()); + } + + /** + * Constructor used by data users like controllers. + * @param hkOwner + * @param setId + */ StaticLocalDataSet(sid_t sid): LocalPoolDataSetBase(sid, nullptr, NUM_VARIABLES) { this->setContainer(poolVarList.data()); diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index 0a3aec6d..227d5b6d 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -391,7 +391,7 @@ ReturnValue_t DeviceHandlerBase::isModeCombinationValid(Mode_t mode, ReturnValue_t DeviceHandlerBase::insertInCommandAndReplyMap( DeviceCommandId_t deviceCommand, uint16_t maxDelayCycles, - PoolDataSetIF* replyDataSet, size_t replyLen, bool periodic, + LocalPoolDataSetBase* replyDataSet, size_t replyLen, bool periodic, bool hasDifferentReplyId, DeviceCommandId_t replyId) { //No need to check, as we may try to insert multiple times. insertInCommandMap(deviceCommand); @@ -405,7 +405,7 @@ ReturnValue_t DeviceHandlerBase::insertInCommandAndReplyMap( } ReturnValue_t DeviceHandlerBase::insertInReplyMap(DeviceCommandId_t replyId, - uint16_t maxDelayCycles, PoolDataSetIF* dataSet, + uint16_t maxDelayCycles, LocalPoolDataSetBase* dataSet, size_t replyLen, bool periodic) { DeviceReplyInfo info; info.maxDelayCycles = maxDelayCycles; @@ -455,7 +455,7 @@ ReturnValue_t DeviceHandlerBase::updateReplyMapEntry(DeviceCommandId_t deviceRep ReturnValue_t DeviceHandlerBase::setReplyDataset(DeviceCommandId_t replyId, - PoolDataSetIF *dataSet) { + LocalPoolDataSetBase *dataSet) { auto replyIter = deviceReplyMap.find(replyId); if(replyIter == deviceReplyMap.end()) { return HasReturnvaluesIF::RETURN_FAILED; @@ -1396,7 +1396,7 @@ ReturnValue_t DeviceHandlerBase::initializeAfterTaskCreation() { return HasReturnvaluesIF::RETURN_OK; } -DataSetIF* DeviceHandlerBase::getDataSetHandle(sid_t sid) { +LocalPoolDataSetBase* DeviceHandlerBase::getDataSetHandle(sid_t sid) { auto iter = deviceReplyMap.find(sid.ownerSetId); if(iter != deviceReplyMap.end()) { return iter->second.dataSet; diff --git a/devicehandlers/DeviceHandlerBase.h b/devicehandlers/DeviceHandlerBase.h index 752f7352..8f1b135b 100644 --- a/devicehandlers/DeviceHandlerBase.h +++ b/devicehandlers/DeviceHandlerBase.h @@ -389,7 +389,8 @@ protected: * - @c RETURN_FAILED else. */ ReturnValue_t insertInCommandAndReplyMap(DeviceCommandId_t deviceCommand, - uint16_t maxDelayCycles, PoolDataSetIF* replyDataSet = nullptr, + uint16_t maxDelayCycles, + LocalPoolDataSetBase* replyDataSet = nullptr, size_t replyLen = 0, bool periodic = false, bool hasDifferentReplyId = false, DeviceCommandId_t replyId = 0); @@ -404,7 +405,7 @@ protected: * - @c RETURN_FAILED else. */ ReturnValue_t insertInReplyMap(DeviceCommandId_t deviceCommand, - uint16_t maxDelayCycles, PoolDataSetIF* dataSet = nullptr, + uint16_t maxDelayCycles, LocalPoolDataSetBase* dataSet = nullptr, size_t replyLen = 0, bool periodic = false); /** @@ -434,7 +435,7 @@ protected: bool periodic = false); ReturnValue_t setReplyDataset(DeviceCommandId_t replyId, - PoolDataSetIF* dataset); + LocalPoolDataSetBase* dataset); /** * @brief Can be implemented by child handler to @@ -663,7 +664,7 @@ protected: //! 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) - PoolDataSetIF* dataSet = nullptr; + LocalPoolDataSetBase* dataSet; //! The command that expects this reply. DeviceCommandMap::iterator command; }; @@ -1198,7 +1199,7 @@ private: ReturnValue_t handleDeviceHandlerMessage(CommandMessage *message); - virtual DataSetIF* getDataSetHandle(sid_t sid) override; + virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override; virtual dur_millis_t getPeriodicOperationFrequency() const override; diff --git a/housekeeping/HousekeepingMessage.h b/housekeeping/HousekeepingMessage.h index 6a3ca616..e2e894b4 100644 --- a/housekeeping/HousekeepingMessage.h +++ b/housekeeping/HousekeepingMessage.h @@ -3,14 +3,15 @@ #include "../ipc/CommandMessage.h" #include "../ipc/FwMessageTypes.h" +#include "../objectmanager/frameworkObjects.h" #include "../objectmanager/SystemObjectIF.h" #include "../storagemanager/StorageManagerIF.h" -#include union sid_t { - static constexpr uint64_t INVALID_ADDRESS = - std::numeric_limits::max(); - sid_t(): raw(INVALID_ADDRESS) {} + static constexpr uint64_t INVALID_SID = -1; + static constexpr uint32_t INVALID_SET_ID = -1; + static constexpr uint32_t INVALID_OBJECT_ID = objects::NO_OBJECT; + sid_t(): raw(INVALID_SID) {} sid_t(object_id_t objectId, uint32_t setId): objectId(objectId), @@ -31,7 +32,7 @@ union sid_t { uint64_t raw; bool notSet() const { - return raw == INVALID_ADDRESS; + return raw == INVALID_SID; } bool operator==(const sid_t& other) const { diff --git a/housekeeping/PeriodicHousekeepingHelper.cpp b/housekeeping/PeriodicHousekeepingHelper.cpp index c2ae8126..d184489b 100644 --- a/housekeeping/PeriodicHousekeepingHelper.cpp +++ b/housekeeping/PeriodicHousekeepingHelper.cpp @@ -10,10 +10,11 @@ void PeriodicHousekeepingHelper::initialize(float collectionInterval, dur_millis_t minimumPeriodicInterval, bool isDiagnostics, uint8_t nonDiagIntervalFactor) { this->minimumPeriodicInterval = minimumPeriodicInterval; - if(not owner->getIsDiagnostics()) { + if(isDiagnostics) { this->minimumPeriodicInterval = this->minimumPeriodicInterval * nonDiagIntervalFactor; } + collectionIntervalTicks = intervalSecondsToInterval(collectionInterval); } float PeriodicHousekeepingHelper::getCollectionIntervalInSeconds() { diff --git a/housekeeping/PeriodicHousekeepingHelper.h b/housekeeping/PeriodicHousekeepingHelper.h index 982e8cf6..d96eae1d 100644 --- a/housekeeping/PeriodicHousekeepingHelper.h +++ b/housekeeping/PeriodicHousekeepingHelper.h @@ -20,7 +20,6 @@ public: private: LocalPoolDataSetBase* owner = nullptr; - uint32_t intervalSecondsToInterval(float collectionIntervalSeconds); float intervalToIntervalSeconds(uint32_t collectionInterval); @@ -30,6 +29,4 @@ private: }; - - #endif /* FSFW_HOUSEKEEPING_PERIODICHOUSEKEEPINGHELPER_H_ */ diff --git a/pus/Service3Housekeeping.cpp b/pus/Service3Housekeeping.cpp index 0d63a4e2..ebfa4be9 100644 --- a/pus/Service3Housekeeping.cpp +++ b/pus/Service3Housekeeping.cpp @@ -6,7 +6,7 @@ Service3Housekeeping::Service3Housekeeping(object_id_t objectId, uint16_t apid, uint8_t serviceId): CommandingServiceBase(objectId, apid, serviceId, - NUM_OF_PARALLEL_COMMANDS, COMMAND_TIMEOUT_SECONDS) {} + NUM_OF_PARALLEL_COMMANDS, 5) {} Service3Housekeeping::~Service3Housekeeping() {} diff --git a/tmtcservices/CommandingServiceBase.cpp b/tmtcservices/CommandingServiceBase.cpp index 4cead0e9..3a204703 100644 --- a/tmtcservices/CommandingServiceBase.cpp +++ b/tmtcservices/CommandingServiceBase.cpp @@ -387,7 +387,7 @@ void CommandingServiceBase::acceptPacket(uint8_t reportId, void CommandingServiceBase::checkAndExecuteFifo(CommandMapIter iter) { store_address_t address; if (iter->second.fifo.retrieve(&address) != RETURN_OK) { - commandMap.erase(&iter); + commandMap.erase(iter->first); } else { TcPacketStored newPacket(address); startExecution(&newPacket, iter); @@ -411,8 +411,14 @@ void CommandingServiceBase::checkTimeout() { uint32_t uptime; Clock::getUptime(&uptime); CommandMapIter iter; + // TODO: BUG HERE! Problems with comparison operator of iterator. for (iter = commandMap.begin(); iter != commandMap.end(); ++iter) { + if(commandMap.empty()) { + // intermediate solution. + break; + } if ((iter->second.uptimeOfStart + (timeoutSeconds * 1000)) < uptime) { + sif::info << "test" << std::endl; verificationReporter.sendFailureReport( TC_VERIFY::COMPLETION_FAILURE, iter->second.tcInfo.ackFlags, iter->second.tcInfo.tcPacketId, iter->second.tcInfo.tcSequenceControl, diff --git a/tmtcservices/VerificationReporter.cpp b/tmtcservices/VerificationReporter.cpp index 4f9f4e54..0c53e1a4 100644 --- a/tmtcservices/VerificationReporter.cpp +++ b/tmtcservices/VerificationReporter.cpp @@ -63,8 +63,8 @@ void VerificationReporter::sendFailureReport(uint8_t report_id, ReturnValue_t status = MessageQueueSenderIF::sendMessage(acknowledgeQueue, &message); if (status != HasReturnvaluesIF::RETURN_OK) { - sif::error << "VerificationReporter::sendFailureReport Error writing " - << "to queue. Code: " << std::hex << status << std::dec + sif::error << "VerificationReporter::sendFailureReport: Error writing " + << "to queue. Code: " << std::hex << "0x" << status << std::dec << std::endl; } } @@ -81,8 +81,8 @@ void VerificationReporter::sendFailureReport(uint8_t report_id, ReturnValue_t status = MessageQueueSenderIF::sendMessage(acknowledgeQueue, &message); if (status != HasReturnvaluesIF::RETURN_OK) { - sif::error << "VerificationReporter::sendFailureReport Error writing " - << "to queue. Code: " << std::hex << status << std::dec + sif::error << "VerificationReporter::sendFailureReport: Error writing " + << "to queue. Code: " << std::hex << "0x" << status << std::dec << std::endl; } }