diff --git a/datapoollocal/LocalDataPoolManager.cpp b/datapoollocal/LocalDataPoolManager.cpp index b7b203b8..7c41ff2a 100644 --- a/datapoollocal/LocalDataPoolManager.cpp +++ b/datapoollocal/LocalDataPoolManager.cpp @@ -236,7 +236,7 @@ ReturnValue_t LocalDataPoolManager::performHkOperation() { switch(receiver->reportingType) { case(ReportingType::PERIODIC): { - if(receiver->dataId.dataSetSid == sid_t::INVALID_ADDRESS) { + if(receiver->dataId.dataSetSid.notSet()) { // Periodic packets shall only be generated from datasets. continue; } diff --git a/datapoollocal/LocalPoolDataSetBase.cpp b/datapoollocal/LocalPoolDataSetBase.cpp index f5273cfe..d24ffd18 100644 --- a/datapoollocal/LocalPoolDataSetBase.cpp +++ b/datapoollocal/LocalPoolDataSetBase.cpp @@ -72,6 +72,36 @@ ReturnValue_t LocalPoolDataSetBase::serializeWithValidityBuffer(uint8_t **buffer return result; } +ReturnValue_t LocalPoolDataSetBase::deSerializeWithValidityBuffer( + const uint8_t **buffer, size_t *size, + SerializeIF::Endianness streamEndianness) { + ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED; + for (uint16_t count = 0; count < fillCount; count++) { + result = registeredVariables[count]->deSerialize(buffer, size, + streamEndianness); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + } + uint8_t validBufferIndex = 0; + uint8_t validBufferIndexBit = 0; + // could be made more efficient but make it work first + for (uint16_t count = 0; count < fillCount; count++) { + // set validity buffer here. + bool nextVarValid = this->bitGetter(*buffer + + validBufferIndex, validBufferIndexBit); + registeredVariables[count]->setValid(nextVarValid); + + if(validBufferIndexBit == 7) { + validBufferIndex ++; + validBufferIndexBit = 0; + } + else { + validBufferIndexBit ++; + } + } + return result; +} ReturnValue_t LocalPoolDataSetBase::unlockDataPool() { MutexIF* mutex = hkManager->getMutexHandle(); return mutex->unlockMutex(); @@ -102,6 +132,55 @@ void LocalPoolDataSetBase::bitSetter(uint8_t* byte, uint8_t position) const { *byte |= 1 << shiftNumber; } +size_t LocalPoolDataSetBase::getSerializedSize() const { + if(withValidityBuffer) { + uint8_t validityMaskSize = std::ceil(static_cast(fillCount)/8.0); + return validityMaskSize + PoolDataSetBase::getSerializedSize(); + } + else { + return PoolDataSetBase::getSerializedSize(); + } +} + +void LocalPoolDataSetBase::setValidityBufferGeneration( + bool withValidityBuffer) { + this->withValidityBuffer = withValidityBuffer; +} + +ReturnValue_t LocalPoolDataSetBase::deSerialize(const uint8_t **buffer, + size_t *size, SerializeIF::Endianness streamEndianness) { + if(withValidityBuffer) { + return this->deSerializeWithValidityBuffer(buffer, size, + streamEndianness); + } + else { + return PoolDataSetBase::deSerialize(buffer, size, streamEndianness); + } +} + +ReturnValue_t LocalPoolDataSetBase::serialize(uint8_t **buffer, size_t *size, + size_t maxSize, SerializeIF::Endianness streamEndianness) const { + if(withValidityBuffer) { + return this->serializeWithValidityBuffer(buffer, size, + maxSize, streamEndianness); + } + else { + return PoolDataSetBase::serialize(buffer, size, maxSize, + streamEndianness); + } +} + +bool LocalPoolDataSetBase::bitGetter(const uint8_t* byte, uint8_t position) const { + if(position > 7) { + sif::debug << "Pool Raw Access: Bit setting invalid position" << std::endl; + return false; + } + uint8_t shiftNumber = position + (7 - 2 * position); + return *byte & (1 << shiftNumber); +} + bool LocalPoolDataSetBase::isValid() const { return this->valid; } + + diff --git a/datapoollocal/LocalPoolDataSetBase.h b/datapoollocal/LocalPoolDataSetBase.h index 1034fc29..e9baeea3 100644 --- a/datapoollocal/LocalPoolDataSetBase.h +++ b/datapoollocal/LocalPoolDataSetBase.h @@ -30,6 +30,7 @@ class LocalDataPoolManager; * * @ingroup data_pool */ +// todo: make withValidityBuffer a member class LocalPoolDataSetBase: public PoolDataSetBase { public: /** @@ -63,6 +64,14 @@ public: */ ~LocalPoolDataSetBase(); + void setValidityBufferGeneration(bool withValidityBuffer); + + 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, + SerializeIF::Endianness streamEndianness) override; + size_t getSerializedSize() const override; + /** * Special version of the serilization function which appends a * validity buffer at the end. Each bit of this validity buffer @@ -78,7 +87,8 @@ public: ReturnValue_t serializeWithValidityBuffer(uint8_t** buffer, size_t* size, size_t maxSize, SerializeIF::Endianness streamEndianness) const; - + ReturnValue_t deSerializeWithValidityBuffer(const uint8_t** buffer, + size_t *size, SerializeIF::Endianness streamEndianness); ReturnValue_t serializeLocalPoolIds(uint8_t** buffer, size_t* size, size_t maxSize, SerializeIF::Endianness streamEndianness) const; @@ -92,6 +102,8 @@ protected: */ bool valid = false; + bool withValidityBuffer = true; + /** * @brief This is a small helper function to facilitate locking * the global data pool. @@ -114,7 +126,7 @@ protected: * (most significant bit) to 7 (least significant bit) */ void bitSetter(uint8_t* byte, uint8_t position) const; - + bool bitGetter(const uint8_t* byte, uint8_t position) const; private: diff --git a/housekeeping/HousekeepingMessage.h b/housekeeping/HousekeepingMessage.h index e2a69805..db6d3ab8 100644 --- a/housekeeping/HousekeepingMessage.h +++ b/housekeeping/HousekeepingMessage.h @@ -25,6 +25,10 @@ union sid_t { * Alternative access to the raw value. This is also the size of the type. */ uint64_t raw; + + bool notSet() const { + return raw == INVALID_ADDRESS; + } }; diff --git a/housekeeping/InternalHousekeepingPacket.h b/housekeeping/InternalHousekeepingPacket.h new file mode 100644 index 00000000..2a9a5564 --- /dev/null +++ b/housekeeping/InternalHousekeepingPacket.h @@ -0,0 +1,73 @@ +#ifndef FRAMEWORK_HOUSEKEEPING_INTERNALHOUSEKEEPINGPACKET_H_ +#define FRAMEWORK_HOUSEKEEPING_INTERNALHOUSEKEEPINGPACKET_H_ + +#include +#include +#include + +/** + * @brief This helper class will be used to serialize and deserialize + * internal housekeeping packets into the store. + */ +class InternalHousekeepingPacket: public SerializeIF { +public: + /** + * @param timeStamp + * @param timeStampSize + * @param hkData + * @param hkDataSize + */ + InternalHousekeepingPacket(uint8_t* timeStamp, size_t timeStampSize, + LocalPoolDataSetBase* dataSetPtr): + timeStamp(timeStamp), timeStampSize(timeStampSize), + dataSetPtr(dataSetPtr) {}; + + virtual ReturnValue_t serialize(uint8_t **buffer, size_t *size, + size_t maxSize, Endianness streamEndianness) const { + if(timeStamp != nullptr) { + // Endianness will always be MACHINE, so we can simply use memcpy + // here. + std::memcpy(*buffer, timeStamp, timeStampSize); + *size += timeStampSize; + *buffer += timeStampSize; + } + if(dataSetPtr == nullptr) { + return HasReturnvaluesIF::RETURN_FAILED; + } + + return dataSetPtr->serialize(buffer, size, maxSize, streamEndianness); + } + + virtual size_t getSerializedSize() const { + if(dataSetPtr == nullptr) { + return 0; + } + return timeStampSize + dataSetPtr->getSerializedSize(); + } + + virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + SerializeIF::Endianness streamEndianness) override { + if(timeStamp != nullptr) { + // Endianness will always be MACHINE, so we can simply use memcpy + // here. + std::memcpy(timeStamp, *buffer, timeStampSize); + *size += timeStampSize; + *buffer += timeStampSize; + } + + if(dataSetPtr == nullptr) { + return HasReturnvaluesIF::RETURN_FAILED; + } + return dataSetPtr->deSerialize(buffer, size, streamEndianness); + } + +private: + uint8_t* timeStamp; + size_t timeStampSize; + + LocalPoolDataSetBase* dataSetPtr = nullptr; +}; + + + +#endif /* FRAMEWORK_HOUSEKEEPING_INTERNALHOUSEKEEPINGPACKET_H_ */