From a42832ca01d9b5554b3e6b7c274bf16ce5d13f58 Mon Sep 17 00:00:00 2001 From: Uli Date: Tue, 21 Apr 2020 21:34:03 +0200 Subject: [PATCH 001/307] working on updating SerializeIF, to quote Basti: This is going to be horrible --- container/FixedMap.h | 16 +- container/IndexedRingMemoryArray.h | 32 +-- datapool/DataPoolParameterWrapper.cpp | 6 +- datapool/PIDReader.h | 34 ++-- datapool/PoolRawAccess.cpp | 22 ++- datapool/PoolRawAccess.h | 16 +- datapool/PoolVariable.h | 30 +-- datapool/PoolVector.h | 6 +- devicehandlers/DeviceTmReportingWrapper.cpp | 8 +- globalfunctions/Type.cpp | 10 +- globalfunctions/Type.h | 16 +- globalfunctions/matching/MatchTree.h | 2 +- globalfunctions/matching/RangeMatcher.h | 29 +-- health/HealthTable.cpp | 6 +- memory/MemoryHelper.cpp | 6 +- osal/rtems/CpuUsage.cpp | 16 +- parameters/ParameterWrapper.cpp | 16 +- parameters/ParameterWrapper.h | 2 +- power/PowerComponent.cpp | 8 +- serialize/EndianSwapper.h | 46 ++++- serialize/SerialArrayListAdapter.h | 10 +- serialize/SerialBufferAdapter.cpp | 8 +- serialize/SerialLinkedListAdapter.h | 36 ++-- serialize/SerializeAdapter.h | 198 +++++++++---------- serialize/SerializeElement.h | 34 ++-- serialize/SerializeIF.h | 15 +- subsystem/Subsystem.cpp | 2 +- subsystem/modes/ModeDefinitions.h | 16 +- thermal/ThermalComponent.cpp | 8 +- tmstorage/TmStorePackets.h | 38 ++-- tmtcpacket/packetmatcher/ApidMatcher.h | 6 +- tmtcpacket/packetmatcher/ServiceMatcher.h | 6 +- tmtcpacket/packetmatcher/SubserviceMatcher.h | 6 +- tmtcservices/CommandingServiceBase.cpp | 2 +- tmtcservices/PusVerificationReport.cpp | 18 +- 35 files changed, 389 insertions(+), 341 deletions(-) diff --git a/container/FixedMap.h b/container/FixedMap.h index 0b84bf4e..eaf8a24c 100644 --- a/container/FixedMap.h +++ b/container/FixedMap.h @@ -150,13 +150,13 @@ public: virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, const uint32_t max_size, bool bigEndian) const { - ReturnValue_t result = SerializeAdapter::serialize(&this->_size, + ReturnValue_t result = SerializeAdapter::serialize(&this->_size, buffer, size, max_size, bigEndian); uint32_t i = 0; while ((result == HasReturnvaluesIF::RETURN_OK) && (i < this->_size)) { - result = SerializeAdapter::serialize(&theMap[i].first, buffer, + result = SerializeAdapter::serialize(&theMap[i].first, buffer, size, max_size, bigEndian); - result = SerializeAdapter::serialize(&theMap[i].second, buffer, size, + result = SerializeAdapter::serialize(&theMap[i].second, buffer, size, max_size, bigEndian); ++i; } @@ -168,9 +168,9 @@ public: uint32_t i = 0; for (i = 0; i < _size; ++i) { - printSize += SerializeAdapter::getSerializedSize( + printSize += SerializeAdapter::getSerializedSize( &theMap[i].first); - printSize += SerializeAdapter::getSerializedSize(&theMap[i].second); + printSize += SerializeAdapter::getSerializedSize(&theMap[i].second); } return printSize; @@ -178,16 +178,16 @@ public: virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, bool bigEndian) { - ReturnValue_t result = SerializeAdapter::deSerialize(&this->_size, + ReturnValue_t result = SerializeAdapter::deSerialize(&this->_size, buffer, size, bigEndian); if (this->_size > theMap.maxSize()) { return SerializeIF::TOO_MANY_ELEMENTS; } uint32_t i = 0; while ((result == HasReturnvaluesIF::RETURN_OK) && (i < this->_size)) { - result = SerializeAdapter::deSerialize(&theMap[i].first, buffer, + result = SerializeAdapter::deSerialize(&theMap[i].first, buffer, size, bigEndian); - result = SerializeAdapter::deSerialize(&theMap[i].second, buffer, size, + result = SerializeAdapter::deSerialize(&theMap[i].second, buffer, size, bigEndian); ++i; } diff --git a/container/IndexedRingMemoryArray.h b/container/IndexedRingMemoryArray.h index 992b7489..32b61c2d 100644 --- a/container/IndexedRingMemoryArray.h +++ b/container/IndexedRingMemoryArray.h @@ -70,7 +70,7 @@ public: ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, const uint32_t max_size, bool bigEndian) const { - ReturnValue_t result = AutoSerializeAdapter::serialize(&blockStartAddress,buffer,size,max_size,bigEndian); + ReturnValue_t result = SerializeAdapter::serialize(&blockStartAddress,buffer,size,max_size,bigEndian); if(result != HasReturnvaluesIF::RETURN_OK){ return result; } @@ -78,17 +78,17 @@ public: if(result != HasReturnvaluesIF::RETURN_OK){ return result; } - result = AutoSerializeAdapter::serialize(&this->size,buffer,size,max_size,bigEndian); + result = SerializeAdapter::serialize(&this->size,buffer,size,max_size,bigEndian); if(result != HasReturnvaluesIF::RETURN_OK){ return result; } - result = AutoSerializeAdapter::serialize(&this->storedPackets,buffer,size,max_size,bigEndian); + result = SerializeAdapter::serialize(&this->storedPackets,buffer,size,max_size,bigEndian); return result; } ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, bool bigEndian){ - ReturnValue_t result = AutoSerializeAdapter::deSerialize(&blockStartAddress,buffer,size,bigEndian); + ReturnValue_t result = SerializeAdapter::deSerialize(&blockStartAddress,buffer,size,bigEndian); if(result != HasReturnvaluesIF::RETURN_OK){ return result; } @@ -96,11 +96,11 @@ public: if(result != HasReturnvaluesIF::RETURN_OK){ return result; } - result = AutoSerializeAdapter::deSerialize(&this->size,buffer,size,bigEndian); + result = SerializeAdapter::deSerialize(&this->size,buffer,size,bigEndian); if(result != HasReturnvaluesIF::RETURN_OK){ return result; } - result = AutoSerializeAdapter::deSerialize(&this->storedPackets,buffer,size,bigEndian); + result = SerializeAdapter::deSerialize(&this->storedPackets,buffer,size,bigEndian); if(result != HasReturnvaluesIF::RETURN_OK){ return result; } @@ -108,10 +108,10 @@ public: } uint32_t getSerializedSize() const { - uint32_t size = AutoSerializeAdapter::getSerializedSize(&blockStartAddress); + uint32_t size = SerializeAdapter::getSerializedSize(&blockStartAddress); size += indexType.getSerializedSize(); - size += AutoSerializeAdapter::getSerializedSize(&this->size); - size += AutoSerializeAdapter::getSerializedSize(&this->storedPackets); + size += SerializeAdapter::getSerializedSize(&this->size); + size += SerializeAdapter::getSerializedSize(&this->storedPackets); return size; } @@ -500,14 +500,14 @@ public: if(result != HasReturnvaluesIF::RETURN_OK){ return result; } - result = AutoSerializeAdapter::serialize(&this->size,buffer,size,max_size,bigEndian); + result = SerializeAdapter::serialize(&this->size,buffer,size,max_size,bigEndian); if(result != HasReturnvaluesIF::RETURN_OK){ return result; } uint32_t i = 0; while ((result == HasReturnvaluesIF::RETURN_OK) && (i < this->size)) { - result = SerializeAdapter >::serialize(&this->entries[i], buffer, size, + result = SerializeAdapter::serialize(&this->entries[i], buffer, size, max_size, bigEndian); ++i; } @@ -515,7 +515,7 @@ public: return result; } uint16_t crc = Calculate_CRC(crcBuffer,(*size-oldSize)); - result = AutoSerializeAdapter::serialize(&crc,buffer,size,max_size,bigEndian); + result = SerializeAdapter::serialize(&crc,buffer,size,max_size,bigEndian); return result; } @@ -531,10 +531,10 @@ public: size += additionalInfo->getSerializedSize(); } size += currentWriteBlock->getSerializedSize(); - size += AutoSerializeAdapter::getSerializedSize(&this->size); + size += SerializeAdapter::getSerializedSize(&this->size); size += (this->entries[0].getSerializedSize()) * this->size; uint16_t crc = 0; - size += AutoSerializeAdapter::getSerializedSize(&crc); + size += SerializeAdapter::getSerializedSize(&crc); return size; } /** @@ -563,7 +563,7 @@ public: return result; } uint32_t tempSize = 0; - result = AutoSerializeAdapter::deSerialize(&tempSize,buffer,size,bigEndian); + result = SerializeAdapter::deSerialize(&tempSize,buffer,size,bigEndian); if(result != HasReturnvaluesIF::RETURN_OK){ return result; } @@ -572,7 +572,7 @@ public: } uint32_t i = 0; while ((result == HasReturnvaluesIF::RETURN_OK) && (i < this->size)) { - result = SerializeAdapter >::deSerialize( + result = SerializeAdapter::deSerialize( &this->entries[i], buffer, size, bigEndian); ++i; diff --git a/datapool/DataPoolParameterWrapper.cpp b/datapool/DataPoolParameterWrapper.cpp index 0ff2121d..10fb5392 100644 --- a/datapool/DataPoolParameterWrapper.cpp +++ b/datapool/DataPoolParameterWrapper.cpp @@ -39,18 +39,18 @@ ReturnValue_t DataPoolParameterWrapper::serialize(uint8_t** buffer, uint32_t* size, const uint32_t max_size, bool bigEndian) const { ReturnValue_t result; - result = SerializeAdapter::serialize(&type, buffer, size, max_size, + result = SerializeAdapter::serialize(&type, buffer, size, max_size, bigEndian); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::serialize(&columns, buffer, size, + result = SerializeAdapter::serialize(&columns, buffer, size, max_size, bigEndian); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::serialize(&rows, buffer, size, max_size, + result = SerializeAdapter::serialize(&rows, buffer, size, max_size, bigEndian); if (result != HasReturnvaluesIF::RETURN_OK) { return result; diff --git a/datapool/PIDReader.h b/datapool/PIDReader.h index 299cc2fe..ac1d169e 100644 --- a/datapool/PIDReader.h +++ b/datapool/PIDReader.h @@ -17,7 +17,7 @@ protected: uint8_t valid; ReturnValue_t read() { uint8_t arrayIndex = DataPool::PIDToArrayIndex(parameterId); - PoolEntry* read_out = ::dataPool.getData( + PoolEntry *read_out = ::dataPool.getData( DataPool::PIDToDataPoolId(parameterId), arrayIndex); if (read_out != NULL) { valid = read_out->valid; @@ -43,7 +43,8 @@ protected: * Empty ctor for List initialization */ PIDReader() : - parameterId(PoolVariableIF::NO_PARAMETER), valid(PoolVariableIF::INVALID), value(0) { + parameterId(PoolVariableIF::NO_PARAMETER), valid( + PoolVariableIF::INVALID), value(0) { } public: @@ -63,9 +64,9 @@ public: * \param setWritable If this flag is set to true, changes in the value attribute can be * written back to the data pool, otherwise not. */ - PIDReader(uint32_t setParameterId, DataSetIF* dataSet) : - parameterId(setParameterId), valid( - PoolVariableIF::INVALID), value(0) { + PIDReader(uint32_t setParameterId, DataSetIF *dataSet) : + parameterId(setParameterId), valid(PoolVariableIF::INVALID), value( + 0) { if (dataSet != NULL) { dataSet->registerVariable(this); } @@ -74,7 +75,7 @@ public: /** * Copy ctor to copy classes containing Pool Variables. */ - PIDReader(const PIDReader& rhs) : + PIDReader(const PIDReader &rhs) : parameterId(rhs.parameterId), valid(rhs.valid), value(rhs.value) { } @@ -121,24 +122,25 @@ public: return value; } - PIDReader &operator=(T newValue) { + PIDReader& operator=(T newValue) { value = newValue; return *this; } - virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { - return SerializeAdapter::serialize(&value, buffer, size, max_size, - bigEndian); + virtual ReturnValue_t serialize(uint8_t **buffer, size_t *size, + size_t maxSize, Endianness streamEndianness) const override { + return SerializeAdapter::serialize(&value, buffer, size, maxSize, + streamEndianness); } - virtual uint32_t getSerializedSize() const { - return SerializeAdapter::getSerializedSize(&value); + virtual size_t getSerializedSize() const override { + return SerializeAdapter::getSerializedSize(&value); } - virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian) { - return SerializeAdapter::deSerialize(&value, buffer, size, bigEndian); + virtual ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size, + Endianness streamEndianness) override { + return SerializeAdapter::deSerialize(&value, buffer, size, + streamEndianness); } }; diff --git a/datapool/PoolRawAccess.cpp b/datapool/PoolRawAccess.cpp index 555896bb..2053498b 100644 --- a/datapool/PoolRawAccess.cpp +++ b/datapool/PoolRawAccess.cpp @@ -145,10 +145,12 @@ uint16_t PoolRawAccess::getSizeTillEnd() const { return sizeTillEnd; } -ReturnValue_t PoolRawAccess::serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { - if (typeSize + *size <= max_size) { - if (bigEndian) { +ReturnValue_t PoolRawAccess::serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const { + //TODO integer overflow + if (typeSize + *size <= maxSize) { +#error use endian swapper + if (1) { #ifndef BYTE_ORDER_SYSTEM #error BYTE_ORDER_SYSTEM not defined #elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN @@ -169,16 +171,16 @@ ReturnValue_t PoolRawAccess::serialize(uint8_t** buffer, uint32_t* size, } } -uint32_t PoolRawAccess::getSerializedSize() const { +size_t PoolRawAccess::getSerializedSize() const { return typeSize; } -ReturnValue_t PoolRawAccess::deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian) { - *size -= typeSize; - if (*size >= 0) { +ReturnValue_t PoolRawAccess::deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) { - if (bigEndian) { + if (*size >= typeSize) { + *size -= typeSize; + if (1) { #ifndef BYTE_ORDER_SYSTEM #error BYTE_ORDER_SYSTEM not defined #elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN diff --git a/datapool/PoolRawAccess.h b/datapool/PoolRawAccess.h index 3e2bd7ae..190c38a9 100644 --- a/datapool/PoolRawAccess.h +++ b/datapool/PoolRawAccess.h @@ -70,7 +70,7 @@ public: static const ReturnValue_t DATA_POOL_ACCESS_FAILED = MAKE_RETURN_CODE(0x02); uint8_t value[RAW_MAX_SIZE]; PoolRawAccess(uint32_t data_pool_id, uint8_t arrayEntry, - DataSetIF* data_set, ReadWriteMode_t setReadWriteMode = + DataSetIF *data_set, ReadWriteMode_t setReadWriteMode = PoolVariableIF::VAR_READ); /** * \brief The classes destructor is empty. If commit() was not called, the local value is @@ -97,7 +97,7 @@ public: * \return - \c RETURN_OK if entry could be acquired * - \c RETURN_FAILED else. */ - ReturnValue_t getEntryEndianSafe(uint8_t* buffer, uint32_t* size, + ReturnValue_t getEntryEndianSafe(uint8_t *buffer, uint32_t *size, uint32_t max_size); /** * With this method, the content can be set from a big endian buffer safely. @@ -106,7 +106,7 @@ public: * @return - \c RETURN_OK on success * - \c RETURN_FAILED on failure */ - ReturnValue_t setEntryFromBigEndian(const uint8_t* buffer, + ReturnValue_t setEntryFromBigEndian(const uint8_t *buffer, uint32_t setSize); /** * \brief This operation returns the type of the entry currently stored. @@ -140,13 +140,13 @@ public: */ uint16_t getSizeTillEnd() const; - ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const; + ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize, + Endianness streamEndianness) const override; - uint32_t getSerializedSize() const; + size_t getSerializedSize() const override; - ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian); + ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size, + Endianness streamEndianness) override; }; #endif /* POOLRAWACCESS_H_ */ diff --git a/datapool/PoolVariable.h b/datapool/PoolVariable.h index 25345c0a..ce073426 100644 --- a/datapool/PoolVariable.h +++ b/datapool/PoolVariable.h @@ -58,7 +58,7 @@ protected: * The operation does NOT provide any mutual exclusive protection by itself. */ ReturnValue_t read() { - PoolEntry* read_out = ::dataPool.getData(dataPoolId, 1); + PoolEntry *read_out = ::dataPool.getData < T > (dataPoolId, 1); if (read_out != NULL) { valid = read_out->valid; value = *(read_out->address); @@ -79,7 +79,7 @@ protected: * */ ReturnValue_t commit() { - PoolEntry* write_back = ::dataPool.getData(dataPoolId, 1); + PoolEntry *write_back = ::dataPool.getData < T > (dataPoolId, 1); if ((write_back != NULL) && (readWriteMode != VAR_READ)) { write_back->valid = valid; *(write_back->address) = value; @@ -115,7 +115,7 @@ public: * \param setWritable If this flag is set to true, changes in the value attribute can be * written back to the data pool, otherwise not. */ - PoolVariable(uint32_t set_id, DataSetIF* dataSet, + PoolVariable(uint32_t set_id, DataSetIF *dataSet, ReadWriteMode_t setReadWriteMode) : dataPoolId(set_id), valid(PoolVariableIF::INVALID), readWriteMode( setReadWriteMode), value(0) { @@ -126,7 +126,7 @@ public: /** * Copy ctor to copy classes containing Pool Variables. */ - PoolVariable(const PoolVariable& rhs) : + PoolVariable(const PoolVariable &rhs) : dataPoolId(rhs.dataPoolId), valid(rhs.valid), readWriteMode( rhs.readWriteMode), value(rhs.value) { } @@ -184,29 +184,29 @@ public: return value; } - PoolVariable &operator=(T newValue) { + PoolVariable& operator=(T newValue) { value = newValue; return *this; } - PoolVariable &operator=(PoolVariable newPoolVariable) { + PoolVariable& operator=(PoolVariable newPoolVariable) { value = newPoolVariable.value; return *this; } - virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { - return SerializeAdapter::serialize(&value, buffer, size, max_size, - bigEndian); + virtual ReturnValue_t serialize(uint8_t **buffer, size_t *size, + size_t max_size, Endianness streamEndianness) const override { + return SerializeAdapter::serialize(&value, buffer, size, max_size, + streamEndianness); } - virtual uint32_t getSerializedSize() const { - return SerializeAdapter::getSerializedSize(&value); + virtual uint32_t getSerializedSize() const override { + return SerializeAdapter::getSerializedSize(&value); } - virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian) { - return SerializeAdapter::deSerialize(&value, buffer, size, bigEndian); + virtual ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size, + Endianness streamEndianness) override { + return SerializeAdapter::deSerialize(&value, buffer, size, streamEndianness); } }; diff --git a/datapool/PoolVector.h b/datapool/PoolVector.h index d3617d17..3809f93b 100644 --- a/datapool/PoolVector.h +++ b/datapool/PoolVector.h @@ -202,7 +202,7 @@ public: uint16_t i; ReturnValue_t result; for (i = 0; i < vector_size; i++) { - result = SerializeAdapter::serialize(&(value[i]), buffer, size, + result = SerializeAdapter::serialize(&(value[i]), buffer, size, max_size, bigEndian); if (result != HasReturnvaluesIF::RETURN_OK) { return result; @@ -212,7 +212,7 @@ public: } virtual uint32_t getSerializedSize() const { - return vector_size * SerializeAdapter::getSerializedSize(value); + return vector_size * SerializeAdapter::getSerializedSize(value); } virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, @@ -220,7 +220,7 @@ public: uint16_t i; ReturnValue_t result; for (i = 0; i < vector_size; i++) { - result = SerializeAdapter::deSerialize(&(value[i]), buffer, size, + result = SerializeAdapter::deSerialize(&(value[i]), buffer, size, bigEndian); if (result != HasReturnvaluesIF::RETURN_OK) { return result; diff --git a/devicehandlers/DeviceTmReportingWrapper.cpp b/devicehandlers/DeviceTmReportingWrapper.cpp index 2c9e820f..55861c3c 100644 --- a/devicehandlers/DeviceTmReportingWrapper.cpp +++ b/devicehandlers/DeviceTmReportingWrapper.cpp @@ -13,12 +13,12 @@ DeviceTmReportingWrapper::~DeviceTmReportingWrapper() { ReturnValue_t DeviceTmReportingWrapper::serialize(uint8_t** buffer, uint32_t* size, const uint32_t max_size, bool bigEndian) const { - ReturnValue_t result = SerializeAdapter::serialize(&objectId, + ReturnValue_t result = SerializeAdapter::serialize(&objectId, buffer, size, max_size, bigEndian); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::serialize(&actionId, buffer, + result = SerializeAdapter::serialize(&actionId, buffer, size, max_size, bigEndian); if (result != HasReturnvaluesIF::RETURN_OK) { return result; @@ -32,12 +32,12 @@ uint32_t DeviceTmReportingWrapper::getSerializedSize() const { ReturnValue_t DeviceTmReportingWrapper::deSerialize(const uint8_t** buffer, int32_t* size, bool bigEndian) { - ReturnValue_t result = SerializeAdapter::deSerialize(&objectId, + ReturnValue_t result = SerializeAdapter::deSerialize(&objectId, buffer, size, bigEndian); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::deSerialize(&actionId, buffer, + result = SerializeAdapter::deSerialize(&actionId, buffer, size, bigEndian); if (result != HasReturnvaluesIF::RETURN_OK) { return result; diff --git a/globalfunctions/Type.cpp b/globalfunctions/Type.cpp index 814d26f4..b7b7fd82 100644 --- a/globalfunctions/Type.cpp +++ b/globalfunctions/Type.cpp @@ -68,13 +68,13 @@ ReturnValue_t Type::serialize(uint8_t** buffer, uint32_t* size, return result; } - result = SerializeAdapter::serialize(&ptc, buffer, size, max_size, + result = SerializeAdapter::serialize(&ptc, buffer, size, max_size, bigEndian); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::serialize(&pfc, buffer, size, max_size, + result = SerializeAdapter::serialize(&pfc, buffer, size, max_size, bigEndian); return result; @@ -83,20 +83,20 @@ ReturnValue_t Type::serialize(uint8_t** buffer, uint32_t* size, uint32_t Type::getSerializedSize() const { uint8_t dontcare = 0; - return 2 * SerializeAdapter::getSerializedSize(&dontcare); + return 2 * SerializeAdapter::getSerializedSize(&dontcare); } ReturnValue_t Type::deSerialize(const uint8_t** buffer, int32_t* size, bool bigEndian) { uint8_t ptc; uint8_t pfc; - ReturnValue_t result = SerializeAdapter::deSerialize(&ptc, buffer, + ReturnValue_t result = SerializeAdapter::deSerialize(&ptc, buffer, size, bigEndian); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::deSerialize(&pfc, buffer, size, + result = SerializeAdapter::deSerialize(&pfc, buffer, size, bigEndian); if (result != HasReturnvaluesIF::RETURN_OK) { return result; diff --git a/globalfunctions/Type.h b/globalfunctions/Type.h index 88df07b6..3ec250b0 100644 --- a/globalfunctions/Type.h +++ b/globalfunctions/Type.h @@ -22,7 +22,7 @@ public: Type(ActualType_t actualType); - Type(const Type& type); + Type(const Type &type); Type& operator=(Type rhs); @@ -30,8 +30,8 @@ public: operator ActualType_t() const; - bool operator==(const Type& rhs); - bool operator!=(const Type& rhs); + bool operator==(const Type &rhs); + bool operator!=(const Type &rhs); uint8_t getSize() const; @@ -39,13 +39,13 @@ public: static ActualType_t getActualType(uint8_t ptc, uint8_t pfc); - virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const; + virtual ReturnValue_t serialize(uint8_t **buffer, size_t *size, + size_t maxSize, Endianness streamEndianness) const override; - virtual uint32_t getSerializedSize() const; + virtual size_t getSerializedSize() const override; - virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian); + virtual ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size, + Endianness streamEndianness) override; private: ActualType_t actualType; diff --git a/globalfunctions/matching/MatchTree.h b/globalfunctions/matching/MatchTree.h index 398cf3f0..0ee3890b 100644 --- a/globalfunctions/matching/MatchTree.h +++ b/globalfunctions/matching/MatchTree.h @@ -49,7 +49,7 @@ public: const uint32_t max_size, bool bigEndian) const { iterator iter = this->begin(); uint8_t count = this->countRight(iter); - ReturnValue_t result = SerializeAdapter::serialize(&count, + ReturnValue_t result = SerializeAdapter::serialize(&count, buffer, size, max_size, bigEndian); if (result != HasReturnvaluesIF::RETURN_OK) { return result; diff --git a/globalfunctions/matching/RangeMatcher.h b/globalfunctions/matching/RangeMatcher.h index 10e07173..c30406f6 100644 --- a/globalfunctions/matching/RangeMatcher.h +++ b/globalfunctions/matching/RangeMatcher.h @@ -4,7 +4,6 @@ #include #include - template class RangeMatcher: public SerializeableMatcherIF { public: @@ -27,34 +26,40 @@ public: } } - ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { - ReturnValue_t result = SerializeAdapter::serialize(&lowerBound, buffer, size, max_size, bigEndian); + ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t max_size, + SerializeIF::Endianness streamEndianness) const override { + ReturnValue_t result = SerializeAdapter::serialize(&lowerBound, buffer, + size, max_size, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::serialize(&upperBound, buffer, size, max_size, bigEndian); + result = SerializeAdapter::serialize(&upperBound, buffer, size, + max_size, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - return SerializeAdapter::serialize(&inverted, buffer, size, max_size, bigEndian); + return SerializeAdapter::serialize(&inverted, buffer, size, max_size, + streamEndianness); } - uint32_t getSerializedSize() const { + uint32_t getSerializedSize() const override { return sizeof(lowerBound) + sizeof(upperBound) + sizeof(bool); } - ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian) { - ReturnValue_t result = SerializeAdapter::deSerialize(&lowerBound, buffer, size, bigEndian); + ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size, + SerializeIF::Endianness streamEndianness) override { + ReturnValue_t result = SerializeAdapter::deSerialize(&lowerBound, + buffer, size, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::deSerialize(&upperBound, buffer, size, bigEndian); + result = SerializeAdapter::deSerialize(&upperBound, buffer, size, + streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - return SerializeAdapter::deSerialize(&inverted, buffer, size, bigEndian); + return SerializeAdapter::deSerialize(&inverted, buffer, size, + streamEndianness); } protected: bool doMatch(T input) { diff --git a/health/HealthTable.cpp b/health/HealthTable.cpp index a575b282..48ee6679 100644 --- a/health/HealthTable.cpp +++ b/health/HealthTable.cpp @@ -67,16 +67,16 @@ void HealthTable::printAll(uint8_t* pointer, uint32_t maxSize) { mutex->lockMutex(MutexIF::NO_TIMEOUT); uint32_t size = 0; uint16_t count = healthMap.size(); - ReturnValue_t result = SerializeAdapter::serialize(&count, + ReturnValue_t result = SerializeAdapter::serialize(&count, &pointer, &size, maxSize, true); HealthMap::iterator iter; for (iter = healthMap.begin(); iter != healthMap.end() && result == HasReturnvaluesIF::RETURN_OK; ++iter) { - result = SerializeAdapter::serialize(&iter->first, + result = SerializeAdapter::serialize(&iter->first, &pointer, &size, maxSize, true); uint8_t health = iter->second; - result = SerializeAdapter::serialize(&health, &pointer, &size, + result = SerializeAdapter::serialize(&health, &pointer, &size, maxSize, true); } mutex->unlockMutex(); diff --git a/memory/MemoryHelper.cpp b/memory/MemoryHelper.cpp index 69830084..c89fd5a4 100644 --- a/memory/MemoryHelper.cpp +++ b/memory/MemoryHelper.cpp @@ -53,7 +53,7 @@ void MemoryHelper::completeLoad(ReturnValue_t errorCode, memcpy(copyHere, dataToCopy, size); break; case HasMemoryIF::POINTS_TO_VARIABLE: - EndianSwapper::swap(copyHere, dataToCopy, size); + EndianConverter::convertBigEndian(copyHere, dataToCopy, size); break; case HasMemoryIF::ACTIVITY_COMPLETED: case RETURN_OK: @@ -86,7 +86,7 @@ void MemoryHelper::completeDump(ReturnValue_t errorCode, case HasMemoryIF::POINTS_TO_VARIABLE: //"data" must be valid pointer! if (errorCode == HasMemoryIF::POINTS_TO_VARIABLE) { - EndianSwapper::swap(reservedSpaceInIPC, dataToCopy, size); + EndianConverter::convertBigEndian(reservedSpaceInIPC, dataToCopy, size); } else { memcpy(reservedSpaceInIPC, dataToCopy, size); } @@ -136,7 +136,7 @@ void MemoryHelper::swapMatrixCopy(uint8_t* out, const uint8_t *in, } while (totalSize > 0){ - EndianSwapper::swap(out,in,datatypeSize); + EndianConverter::convertBigEndian(out,in,datatypeSize); out += datatypeSize; in += datatypeSize; totalSize -= datatypeSize; diff --git a/osal/rtems/CpuUsage.cpp b/osal/rtems/CpuUsage.cpp index 9fc34ff1..903a4d0e 100644 --- a/osal/rtems/CpuUsage.cpp +++ b/osal/rtems/CpuUsage.cpp @@ -91,7 +91,7 @@ void CpuUsage::clear() { ReturnValue_t CpuUsage::serialize(uint8_t** buffer, uint32_t* size, const uint32_t max_size, bool bigEndian) const { - ReturnValue_t result = SerializeAdapter::serialize( + ReturnValue_t result = SerializeAdapter::serialize( &timeSinceLastReset, buffer, size, max_size, bigEndian); if (result != HasReturnvaluesIF::RETURN_OK) { return result; @@ -111,7 +111,7 @@ uint32_t CpuUsage::getSerializedSize() const { ReturnValue_t CpuUsage::deSerialize(const uint8_t** buffer, int32_t* size, bool bigEndian) { - ReturnValue_t result = SerializeAdapter::deSerialize( + ReturnValue_t result = SerializeAdapter::deSerialize( &timeSinceLastReset, buffer, size, bigEndian); if (result != HasReturnvaluesIF::RETURN_OK) { return result; @@ -122,7 +122,7 @@ ReturnValue_t CpuUsage::deSerialize(const uint8_t** buffer, int32_t* size, ReturnValue_t CpuUsage::ThreadData::serialize(uint8_t** buffer, uint32_t* size, const uint32_t max_size, bool bigEndian) const { - ReturnValue_t result = SerializeAdapter::serialize(&id, buffer, + ReturnValue_t result = SerializeAdapter::serialize(&id, buffer, size, max_size, bigEndian); if (result != HasReturnvaluesIF::RETURN_OK) { return result; @@ -133,12 +133,12 @@ ReturnValue_t CpuUsage::ThreadData::serialize(uint8_t** buffer, uint32_t* size, memcpy(*buffer, name, MAX_LENGTH_OF_THREAD_NAME); *size += MAX_LENGTH_OF_THREAD_NAME; *buffer += MAX_LENGTH_OF_THREAD_NAME; - result = SerializeAdapter::serialize(&timeRunning, + result = SerializeAdapter::serialize(&timeRunning, buffer, size, max_size, bigEndian); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::serialize(&percentUsage, + result = SerializeAdapter::serialize(&percentUsage, buffer, size, max_size, bigEndian); if (result != HasReturnvaluesIF::RETURN_OK) { return result; @@ -159,7 +159,7 @@ uint32_t CpuUsage::ThreadData::getSerializedSize() const { ReturnValue_t CpuUsage::ThreadData::deSerialize(const uint8_t** buffer, int32_t* size, bool bigEndian) { - ReturnValue_t result = SerializeAdapter::deSerialize(&id, buffer, + ReturnValue_t result = SerializeAdapter::deSerialize(&id, buffer, size, bigEndian); if (result != HasReturnvaluesIF::RETURN_OK) { return result; @@ -169,12 +169,12 @@ ReturnValue_t CpuUsage::ThreadData::deSerialize(const uint8_t** buffer, } memcpy(name, *buffer, MAX_LENGTH_OF_THREAD_NAME); *buffer -= MAX_LENGTH_OF_THREAD_NAME; - result = SerializeAdapter::deSerialize(&timeRunning, + result = SerializeAdapter::deSerialize(&timeRunning, buffer, size, bigEndian); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::deSerialize(&percentUsage, + result = SerializeAdapter::deSerialize(&percentUsage, buffer, size, bigEndian); if (result != HasReturnvaluesIF::RETURN_OK) { return result; diff --git a/parameters/ParameterWrapper.cpp b/parameters/ParameterWrapper.cpp index 8f661bb3..9dcbc6d5 100644 --- a/parameters/ParameterWrapper.cpp +++ b/parameters/ParameterWrapper.cpp @@ -24,18 +24,18 @@ ReturnValue_t ParameterWrapper::serialize(uint8_t** buffer, uint32_t* size, const uint32_t max_size, bool bigEndian) const { ReturnValue_t result; - result = SerializeAdapter::serialize(&type, buffer, size, max_size, + result = SerializeAdapter::serialize(&type, buffer, size, max_size, bigEndian); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::serialize(&columns, buffer, size, + result = SerializeAdapter::serialize(&columns, buffer, size, max_size, bigEndian); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::serialize(&rows, buffer, size, max_size, + result = SerializeAdapter::serialize(&rows, buffer, size, max_size, bigEndian); if (result != HasReturnvaluesIF::RETURN_OK) { return result; @@ -94,7 +94,7 @@ ReturnValue_t ParameterWrapper::serializeData(uint8_t** buffer, uint32_t* size, ReturnValue_t result; uint16_t dataSize = columns * rows; while (dataSize != 0) { - result = SerializeAdapter::serialize(element, buffer, size, max_size, + result = SerializeAdapter::serialize(element, buffer, size, max_size, bigEndian); if (result != HasReturnvaluesIF::RETURN_OK) { return result; @@ -123,7 +123,7 @@ ReturnValue_t ParameterWrapper::deSerializeData(uint8_t startingRow, + (((startingRow + fromRow) * columns) + startingColumn); for (uint8_t fromColumn = 0; fromColumn < fromColumns; fromColumn++) { - result = SerializeAdapter::deSerialize( + result = SerializeAdapter::deSerialize( dataWithDataType + fromColumn, &fromAsStream, &streamSize, true); if (result != HasReturnvaluesIF::RETURN_OK) { @@ -155,18 +155,18 @@ ReturnValue_t ParameterWrapper::deSerialize(const uint8_t** buffer, ReturnValue_t ParameterWrapper::set(const uint8_t* stream, int32_t streamSize, const uint8_t **remainingStream, int32_t *remainingSize) { - ReturnValue_t result = SerializeAdapter::deSerialize(&type, &stream, + ReturnValue_t result = SerializeAdapter::deSerialize(&type, &stream, &streamSize, true); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::deSerialize(&columns, &stream, + result = SerializeAdapter::deSerialize(&columns, &stream, &streamSize, true); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::deSerialize(&rows, &stream, &streamSize, + result = SerializeAdapter::deSerialize(&rows, &stream, &streamSize, true); if (result != HasReturnvaluesIF::RETURN_OK) { return result; diff --git a/parameters/ParameterWrapper.h b/parameters/ParameterWrapper.h index f61786b8..e6d29c59 100644 --- a/parameters/ParameterWrapper.h +++ b/parameters/ParameterWrapper.h @@ -54,7 +54,7 @@ public: const uint8_t *streamWithtype = (const uint8_t *) readonlyData; streamWithtype += (row * columns + column) * type.getSize(); int32_t size = type.getSize(); - return SerializeAdapter::deSerialize(value, &streamWithtype, + return SerializeAdapter::deSerialize(value, &streamWithtype, &size, true); } else { const T *dataWithType = (const T *) readonlyData; diff --git a/power/PowerComponent.cpp b/power/PowerComponent.cpp index 6a87d88b..53bb06c8 100644 --- a/power/PowerComponent.cpp +++ b/power/PowerComponent.cpp @@ -19,12 +19,12 @@ PowerComponent::PowerComponent(object_id_t setId, uint8_t moduleId, float min, f ReturnValue_t PowerComponent::serialize(uint8_t** buffer, uint32_t* size, const uint32_t max_size, bool bigEndian) const { - ReturnValue_t result = SerializeAdapter::serialize(&min, buffer, + ReturnValue_t result = SerializeAdapter::serialize(&min, buffer, size, max_size, bigEndian); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - return SerializeAdapter::serialize(&max, buffer, size, max_size, + return SerializeAdapter::serialize(&max, buffer, size, max_size, bigEndian); } @@ -58,12 +58,12 @@ float PowerComponent::getMax() { ReturnValue_t PowerComponent::deSerialize(const uint8_t** buffer, int32_t* size, bool bigEndian) { - ReturnValue_t result = SerializeAdapter::deSerialize(&min, buffer, + ReturnValue_t result = SerializeAdapter::deSerialize(&min, buffer, size, bigEndian); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - return SerializeAdapter::deSerialize(&max, buffer, size, bigEndian); + return SerializeAdapter::deSerialize(&max, buffer, size, bigEndian); } ReturnValue_t PowerComponent::getParameter(uint8_t domainId, diff --git a/serialize/EndianSwapper.h b/serialize/EndianSwapper.h index 6ff54444..e142c2a1 100644 --- a/serialize/EndianSwapper.h +++ b/serialize/EndianSwapper.h @@ -5,20 +5,20 @@ #include #include -class EndianSwapper { +class EndianConverter { private: - EndianSwapper() { + EndianConverter() { } ; public: template - static T swap(T in) { + static T convertBigEndian(T in) { #ifndef BYTE_ORDER_SYSTEM #error BYTE_ORDER_SYSTEM not defined #elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN T tmp; - uint8_t *pointerOut = (uint8_t *) &tmp; - uint8_t *pointerIn = (uint8_t *) ∈ + uint8_t *pointerOut = (uint8_t*) &tmp; + uint8_t *pointerIn = (uint8_t*) ∈ for (uint8_t count = 0; count < sizeof(T); count++) { pointerOut[sizeof(T) - count - 1] = pointerIn[count]; } @@ -29,7 +29,8 @@ public: #error Unknown Byte Order #endif } - static void swap(uint8_t* out, const uint8_t* in, uint32_t size) { + static void convertBigEndian(uint8_t *out, const uint8_t *in, + uint32_t size) { #ifndef BYTE_ORDER_SYSTEM #error BYTE_ORDER_SYSTEM not defined #elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN @@ -40,6 +41,39 @@ public: #elif BYTE_ORDER_SYSTEM == BIG_ENDIAN memcpy(out, in, size); return; +#endif + } + + template + static T convertLittleEndian(T in) { +#ifndef BYTE_ORDER_SYSTEM + #error BYTE_ORDER_SYSTEM not defined + #elif BYTE_ORDER_SYSTEM == BIG_ENDIAN + T tmp; + uint8_t *pointerOut = (uint8_t *) &tmp; + uint8_t *pointerIn = (uint8_t *) ∈ + for (uint8_t count = 0; count < sizeof(T); count++) { + pointerOut[sizeof(T) - count - 1] = pointerIn[count]; + } + return tmp; + #elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN + return in; +#else + #error Unknown Byte Order + #endif + } + static void convertLittleEndian(uint8_t *out, const uint8_t *in, + uint32_t size) { +#ifndef BYTE_ORDER_SYSTEM + #error BYTE_ORDER_SYSTEM not defined + #elif BYTE_ORDER_SYSTEM == BIG_ENDIAN + for (uint8_t count = 0; count < size; count++) { + out[size - count - 1] = in[count]; + } + return; + #elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN + memcpy(out, in, size); + return; #endif } }; diff --git a/serialize/SerialArrayListAdapter.h b/serialize/SerialArrayListAdapter.h index 5ffbc375..ab0c6c6f 100644 --- a/serialize/SerialArrayListAdapter.h +++ b/serialize/SerialArrayListAdapter.h @@ -27,11 +27,11 @@ public: static ReturnValue_t serialize(const ArrayList* list, uint8_t** buffer, uint32_t* size, const uint32_t max_size, bool bigEndian) { - ReturnValue_t result = SerializeAdapter::serialize(&list->size, + ReturnValue_t result = SerializeAdapter::serialize(&list->size, buffer, size, max_size, bigEndian); count_t i = 0; while ((result == HasReturnvaluesIF::RETURN_OK) && (i < list->size)) { - result = SerializeAdapter::serialize(&list->entries[i], buffer, size, + result = SerializeAdapter::serialize(&list->entries[i], buffer, size, max_size, bigEndian); ++i; } @@ -47,7 +47,7 @@ public: count_t i = 0; for (i = 0; i < list->size; ++i) { - printSize += SerializeAdapter::getSerializedSize(&list->entries[i]); + printSize += SerializeAdapter::getSerializedSize(&list->entries[i]); } return printSize; @@ -61,7 +61,7 @@ public: static ReturnValue_t deSerialize(ArrayList* list, const uint8_t** buffer, int32_t* size, bool bigEndian) { count_t tempSize = 0; - ReturnValue_t result = SerializeAdapter::deSerialize(&tempSize, + ReturnValue_t result = SerializeAdapter::deSerialize(&tempSize, buffer, size, bigEndian); if (tempSize > list->maxSize()) { return SerializeIF::TOO_MANY_ELEMENTS; @@ -69,7 +69,7 @@ public: list->size = tempSize; count_t i = 0; while ((result == HasReturnvaluesIF::RETURN_OK) && (i < list->size)) { - result = SerializeAdapter::deSerialize( + result = SerializeAdapter::deSerialize( &list->front()[i], buffer, size, bigEndian); ++i; diff --git a/serialize/SerialBufferAdapter.cpp b/serialize/SerialBufferAdapter.cpp index 3ed083bf..f78ec8ac 100644 --- a/serialize/SerialBufferAdapter.cpp +++ b/serialize/SerialBufferAdapter.cpp @@ -26,14 +26,14 @@ ReturnValue_t SerialBufferAdapter::serialize(uint8_t** buffer, uint32_t* size const uint32_t max_size, bool bigEndian) const { uint32_t serializedLength = bufferLength; if (serializeLength) { - serializedLength += AutoSerializeAdapter::getSerializedSize( + serializedLength += SerializeAdapter::getSerializedSize( &bufferLength); } if (*size + serializedLength > max_size) { return BUFFER_TOO_SHORT; } else { if (serializeLength) { - AutoSerializeAdapter::serialize(&bufferLength, buffer, size, + SerializeAdapter::serialize(&bufferLength, buffer, size, max_size, bigEndian); } if (this->constBuffer != NULL) { @@ -52,7 +52,7 @@ ReturnValue_t SerialBufferAdapter::serialize(uint8_t** buffer, uint32_t* size template uint32_t SerialBufferAdapter::getSerializedSize() const { if (serializeLength) { - return bufferLength + AutoSerializeAdapter::getSerializedSize(&bufferLength); + return bufferLength + SerializeAdapter::getSerializedSize(&bufferLength); } else { return bufferLength; } @@ -63,7 +63,7 @@ ReturnValue_t SerialBufferAdapter::deSerialize(const uint8_t** buffer, //TODO Ignores Endian flag! if (buffer != NULL) { if(serializeLength){ - T serializedSize = AutoSerializeAdapter::getSerializedSize( + T serializedSize = SerializeAdapter::getSerializedSize( &bufferLength); if((*size - bufferLength - serializedSize) >= 0){ *buffer += serializedSize; diff --git a/serialize/SerialLinkedListAdapter.h b/serialize/SerialLinkedListAdapter.h index 29952c4a..7b10e331 100644 --- a/serialize/SerialLinkedListAdapter.h +++ b/serialize/SerialLinkedListAdapter.h @@ -31,32 +31,32 @@ public: SinglyLinkedList(), printCount(printCount) { } - virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { + virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const override { if (printCount) { count_t mySize = SinglyLinkedList::getSize(); - ReturnValue_t result = SerializeAdapter::serialize(&mySize, - buffer, size, max_size, bigEndian); + ReturnValue_t result = SerializeAdapter::serialize(&mySize, + buffer, size, maxSize, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } } - return serialize(SinglyLinkedList::start, buffer, size, max_size, - bigEndian); + return serialize(SinglyLinkedList::start, buffer, size, maxSize, + streamEndianness); } static ReturnValue_t serialize(const LinkedElement* element, - uint8_t** buffer, uint32_t* size, const uint32_t max_size, - bool bigEndian) { + uint8_t** buffer, size_t* size, size_t maxSize, + Endianness streamEndianness) { ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; while ((result == HasReturnvaluesIF::RETURN_OK) && (element != NULL)) { - result = element->value->serialize(buffer, size, max_size, - bigEndian); + result = element->value->serialize(buffer, size, maxSize, + streamEndianness); element = element->getNext(); } return result; } - virtual uint32_t getSerializedSize() const { + virtual size_t getSerializedSize() const override { if (printCount) { return SerialLinkedListAdapter::getSerializedSize() + sizeof(count_t); @@ -64,8 +64,8 @@ public: return getSerializedSize(SinglyLinkedList::start); } } - static uint32_t getSerializedSize(const LinkedElement *element) { - uint32_t size = 0; + static size_t getSerializedSize(const LinkedElement *element) { + size_t size = 0; while (element != NULL) { size += element->value->getSerializedSize(); element = element->getNext(); @@ -73,16 +73,16 @@ public: return size; } - virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian) { - return deSerialize(SinglyLinkedList::start, buffer, size, bigEndian); + virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) override { + return deSerialize(SinglyLinkedList::start, buffer, size, streamEndianness); } static ReturnValue_t deSerialize(LinkedElement* element, - const uint8_t** buffer, int32_t* size, bool bigEndian) { + const uint8_t** buffer, size_t* size, Endianness streamEndianness) { ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; while ((result == HasReturnvaluesIF::RETURN_OK) && (element != NULL)) { - result = element->value->deSerialize(buffer, size, bigEndian); + result = element->value->deSerialize(buffer, size, streamEndianness); element = element->getNext(); } return result; diff --git a/serialize/SerializeAdapter.h b/serialize/SerializeAdapter.h index fd9e1b6a..73323c2a 100644 --- a/serialize/SerializeAdapter.h +++ b/serialize/SerializeAdapter.h @@ -10,116 +10,114 @@ /** * \ingroup serialize */ -template -class SerializeAdapter_ { -public: - static ReturnValue_t serialize(const T* object, uint8_t** buffer, - uint32_t* size, const uint32_t max_size, bool bigEndian) { - uint32_t ignoredSize = 0; - if (size == NULL) { - size = &ignoredSize; - } - if (sizeof(T) + *size <= max_size) { - T tmp; - if (bigEndian) { - tmp = EndianSwapper::swap(*object); - } else { - tmp = *object; - } - memcpy(*buffer, &tmp, sizeof(T)); - *size += sizeof(T); - (*buffer) += sizeof(T); - return HasReturnvaluesIF::RETURN_OK; - } else { - return SerializeIF::BUFFER_TOO_SHORT; - } - } - ReturnValue_t deSerialize(T* object, const uint8_t** buffer, int32_t* size, - bool bigEndian) { - T tmp; - *size -= sizeof(T); - if (*size >= 0) { - memcpy(&tmp, *buffer, sizeof(T)); - if (bigEndian) { - *object = EndianSwapper::swap(tmp); - } else { - *object = tmp; - } - *buffer += sizeof(T); - return HasReturnvaluesIF::RETURN_OK; - } else { - return SerializeIF::STREAM_TOO_SHORT; - } - } - - uint32_t getSerializedSize(const T * object) { - return sizeof(T); - } - -}; - -template -class SerializeAdapter_ { -public: - ReturnValue_t serialize(const T* object, uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { - uint32_t ignoredSize = 0; - if (size == NULL) { - size = &ignoredSize; - } - return object->serialize(buffer, size, max_size, bigEndian); - } - uint32_t getSerializedSize(const T* object) const { - return object->getSerializedSize(); - } - - ReturnValue_t deSerialize(T* object, const uint8_t** buffer, int32_t* size, - bool bigEndian) { - return object->deSerialize(buffer, size, bigEndian); - } -}; - -template class SerializeAdapter { -public: - static ReturnValue_t serialize(const T* object, uint8_t** buffer, - uint32_t* size, const uint32_t max_size, bool bigEndian) { - SerializeAdapter_::Is> adapter; - return adapter.serialize(object, buffer, size, max_size, bigEndian); - } - static uint32_t getSerializedSize(const T* object) { - SerializeAdapter_::Is> adapter; - return adapter.getSerializedSize(object); - } - - static ReturnValue_t deSerialize(T* object, const uint8_t** buffer, - int32_t* size, bool bigEndian) { - SerializeAdapter_::Is> adapter; - return adapter.deSerialize(object, buffer, size, bigEndian); - } -}; - - -class AutoSerializeAdapter { public: template - static ReturnValue_t serialize(const T* object, uint8_t** buffer, - uint32_t* size, const uint32_t max_size, bool bigEndian) { - SerializeAdapter_::Is> adapter; - return adapter.serialize(object, buffer, size, max_size, bigEndian); + static ReturnValue_t serialize(const T *object, uint8_t **buffer, + size_t *size, size_t maxSize, SerializeIF::Endianness streamEndianness) { + InternalSerializeAdapter::Is> adapter; + return adapter.serialize(object, buffer, size, maxSize, + streamEndianness); } template - static uint32_t getSerializedSize(const T* object) { - SerializeAdapter_::Is> adapter; + static uint32_t getSerializedSize(const T *object) { + InternalSerializeAdapter::Is> adapter; return adapter.getSerializedSize(object); } template - static ReturnValue_t deSerialize(T* object, const uint8_t** buffer, - int32_t* size, bool bigEndian) { - SerializeAdapter_::Is> adapter; - return adapter.deSerialize(object, buffer, size, bigEndian); + static ReturnValue_t deSerialize(T *object, const uint8_t **buffer, + size_t *size, SerializeIF::Endianness streamEndianness) { + InternalSerializeAdapter::Is> adapter; + return adapter.deSerialize(object, buffer, size, streamEndianness); } +private: + template + class InternalSerializeAdapter { + public: + static ReturnValue_t serialize(const T *object, uint8_t **buffer, + size_t *size, size_t max_size, SerializeIF::Endianness streamEndianness) { + size_t ignoredSize = 0; + if (size == NULL) { + size = &ignoredSize; + } + //TODO check integer overflow of *size + if (sizeof(T) + *size <= max_size) { + T tmp; + switch (streamEndianness) { + case SerializeIF::Endianness::BIG: + tmp = EndianConverter::convertBigEndian(*object); + break; + case SerializeIF::Endianness::LITTLE: + tmp = EndianConverter::convertLittleEndian(*object); + break; + default: + case SerializeIF::Endianness::MACHINE: + tmp = *object; + break; + } + memcpy(*buffer, &tmp, sizeof(T)); + *size += sizeof(T); + (*buffer) += sizeof(T); + return HasReturnvaluesIF::RETURN_OK; + } else { + return SerializeIF::BUFFER_TOO_SHORT; + } + } + + ReturnValue_t deSerialize(T *object, const uint8_t **buffer, + size_t *size, SerializeIF::Endianness streamEndianness) { + T tmp; + if (*size >= sizeof(T)) { + *size -= sizeof(T); + memcpy(&tmp, *buffer, sizeof(T)); + switch (streamEndianness) { + case SerializeIF::Endianness::BIG: + *object = EndianConverter::convertBigEndian(tmp); + break; + case SerializeIF::Endianness::LITTLE: + *object = EndianConverter::convertLittleEndian(tmp); + break; + default: + case SerializeIF::Endianness::MACHINE: + *object = tmp; + break; + } + + *buffer += sizeof(T); + return HasReturnvaluesIF::RETURN_OK; + } else { + return SerializeIF::STREAM_TOO_SHORT; + } + } + + uint32_t getSerializedSize(const T *object) { + return sizeof(T); + } + + }; + + template + class InternalSerializeAdapter { + public: + ReturnValue_t serialize(const T *object, uint8_t **buffer, + size_t *size, size_t max_size, + SerializeIF::Endianness streamEndianness) const { + size_t ignoredSize = 0; + if (size == NULL) { + size = &ignoredSize; + } + return object->serialize(buffer, size, max_size, streamEndianness); + } + uint32_t getSerializedSize(const T *object) const { + return object->getSerializedSize(); + } + + ReturnValue_t deSerialize(T *object, const uint8_t **buffer, + size_t *size, SerializeIF::Endianness streamEndianness) { + return object->deSerialize(buffer, size, streamEndianness); + } + }; }; #endif /* SERIALIZEADAPTER_H_ */ diff --git a/serialize/SerializeElement.h b/serialize/SerializeElement.h index db7db20a..22e9838c 100644 --- a/serialize/SerializeElement.h +++ b/serialize/SerializeElement.h @@ -9,41 +9,43 @@ * \ingroup serialize */ template -class SerializeElement : public SerializeIF, public LinkedElement { +class SerializeElement: public SerializeIF, public LinkedElement { public: - template - SerializeElement(Args... args) : LinkedElement(this), entry(std::forward(args)...) { + template + SerializeElement(Args ... args) : + LinkedElement(this), entry(std::forward(args)...) { } - SerializeElement() : LinkedElement(this) { + SerializeElement() : + LinkedElement(this) { } T entry; - ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { - return SerializeAdapter::serialize(&entry, buffer, size, max_size, bigEndian); + ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize, + Endianness streamEndianness) const override { + return SerializeAdapter::serialize(&entry, buffer, size, maxSize, + streamEndianness); } - uint32_t getSerializedSize() const { - return SerializeAdapter::getSerializedSize(&entry); + uint32_t getSerializedSize() const override { + return SerializeAdapter::getSerializedSize(&entry); } - virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian) { - return SerializeAdapter::deSerialize(&entry, buffer, size, bigEndian); + virtual ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size, + Endianness streamEndianness) override { + return SerializeAdapter::deSerialize(&entry, buffer, size, + streamEndianness); } operator T() { return entry; } - SerializeElement &operator=(T newValue) { + SerializeElement& operator=(T newValue) { entry = newValue; return *this; } - T *operator->() { + T* operator->() { return &entry; } }; - - #endif /* SERIALIZEELEMENT_H_ */ diff --git a/serialize/SerializeIF.h b/serialize/SerializeIF.h index 701fbf56..6c875a5c 100644 --- a/serialize/SerializeIF.h +++ b/serialize/SerializeIF.h @@ -2,6 +2,7 @@ #define SERIALIZEIF_H_ #include +#include /** * \defgroup serialize Serialization @@ -14,6 +15,10 @@ */ class SerializeIF { public: + enum class Endianness : uint8_t { + BIG, LITTLE, MACHINE + }; + static const uint8_t INTERFACE_ID = CLASS_ID::SERIALIZE_IF; static const ReturnValue_t BUFFER_TOO_SHORT = MAKE_RETURN_CODE(1); static const ReturnValue_t STREAM_TOO_SHORT = MAKE_RETURN_CODE(2); @@ -22,13 +27,13 @@ public: virtual ~SerializeIF() { } - virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const = 0; + virtual ReturnValue_t serialize(uint8_t **buffer, size_t *size, + size_t max_size, Endianness streamEndianness) const = 0; - virtual uint32_t getSerializedSize() const = 0; + virtual size_t getSerializedSize() const = 0; - virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian) = 0; + virtual ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size, + Endianness streamEndianness) = 0; }; diff --git a/subsystem/Subsystem.cpp b/subsystem/Subsystem.cpp index e1ec544b..ef706dd7 100644 --- a/subsystem/Subsystem.cpp +++ b/subsystem/Subsystem.cpp @@ -169,7 +169,7 @@ ReturnValue_t Subsystem::handleCommandMessage(CommandMessage* message) { if (result == RETURN_OK) { Mode_t fallbackId; int32_t size = sizeRead; - result = SerializeAdapter::deSerialize(&fallbackId, + result = SerializeAdapter::deSerialize(&fallbackId, &pointer, &size, true); if (result == RETURN_OK) { result = SerialArrayListAdapter::deSerialize( diff --git a/subsystem/modes/ModeDefinitions.h b/subsystem/modes/ModeDefinitions.h index 8e7531f3..3e749dd8 100644 --- a/subsystem/modes/ModeDefinitions.h +++ b/subsystem/modes/ModeDefinitions.h @@ -23,26 +23,26 @@ public: ReturnValue_t result; - result = SerializeAdapter::serialize(&value1, buffer, size, + result = SerializeAdapter::serialize(&value1, buffer, size, max_size, bigEndian); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::serialize(&value2, buffer, size, + result = SerializeAdapter::serialize(&value2, buffer, size, max_size, bigEndian); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::serialize(&value3, buffer, size, + result = SerializeAdapter::serialize(&value3, buffer, size, max_size, bigEndian); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::serialize(&value4, buffer, size, + result = SerializeAdapter::serialize(&value4, buffer, size, max_size, bigEndian); return result; @@ -57,25 +57,25 @@ public: bool bigEndian) { ReturnValue_t result; - result = SerializeAdapter::deSerialize(&value1, buffer, size, + result = SerializeAdapter::deSerialize(&value1, buffer, size, bigEndian); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::deSerialize(&value2, buffer, size, + result = SerializeAdapter::deSerialize(&value2, buffer, size, bigEndian); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::deSerialize(&value3, buffer, size, + result = SerializeAdapter::deSerialize(&value3, buffer, size, bigEndian); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::deSerialize(&value4, buffer, size, + result = SerializeAdapter::deSerialize(&value4, buffer, size, bigEndian); return result; diff --git a/thermal/ThermalComponent.cpp b/thermal/ThermalComponent.cpp index bf6f7398..93513e16 100644 --- a/thermal/ThermalComponent.cpp +++ b/thermal/ThermalComponent.cpp @@ -47,13 +47,13 @@ ReturnValue_t ThermalComponent::setLimits(const uint8_t* data, uint32_t size) { return MonitoringIF::INVALID_SIZE; } int32_t readSize = size; - SerializeAdapter::deSerialize(&nopParameters.lowerNopLimit, &data, + SerializeAdapter::deSerialize(&nopParameters.lowerNopLimit, &data, &readSize, true); - SerializeAdapter::deSerialize(¶meters.lowerOpLimit, &data, + SerializeAdapter::deSerialize(¶meters.lowerOpLimit, &data, &readSize, true); - SerializeAdapter::deSerialize(¶meters.upperOpLimit, &data, + SerializeAdapter::deSerialize(¶meters.upperOpLimit, &data, &readSize, true); - SerializeAdapter::deSerialize(&nopParameters.upperNopLimit, &data, + SerializeAdapter::deSerialize(&nopParameters.upperNopLimit, &data, &readSize, true); return HasReturnvaluesIF::RETURN_OK; } diff --git a/tmstorage/TmStorePackets.h b/tmstorage/TmStorePackets.h index 6eea6f58..4e7160fb 100644 --- a/tmstorage/TmStorePackets.h +++ b/tmstorage/TmStorePackets.h @@ -34,12 +34,12 @@ public: uint16_t ssc; ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, const uint32_t max_size, bool bigEndian) const { - ReturnValue_t result = SerializeAdapter::serialize(&apid, + ReturnValue_t result = SerializeAdapter::serialize(&apid, buffer, size, max_size, bigEndian); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - return SerializeAdapter::serialize(&ssc, buffer, size, + return SerializeAdapter::serialize(&ssc, buffer, size, max_size, bigEndian); } @@ -50,12 +50,12 @@ public: ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, bool bigEndian) { - ReturnValue_t result = SerializeAdapter::deSerialize(&apid, + ReturnValue_t result = SerializeAdapter::deSerialize(&apid, buffer, size, bigEndian); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - return SerializeAdapter::deSerialize(&ssc, buffer, size, + return SerializeAdapter::deSerialize(&ssc, buffer, size, bigEndian); } }; @@ -220,23 +220,23 @@ public: ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, const uint32_t max_size, bool bigEndian) const { - ReturnValue_t result = AutoSerializeAdapter::serialize(&apid,buffer,size,max_size,bigEndian); + ReturnValue_t result = SerializeAdapter::serialize(&apid,buffer,size,max_size,bigEndian); if(result!=HasReturnvaluesIF::RETURN_OK){ return result; } - result = AutoSerializeAdapter::serialize(&sourceSequenceCount,buffer,size,max_size,bigEndian); + result = SerializeAdapter::serialize(&sourceSequenceCount,buffer,size,max_size,bigEndian); if(result!=HasReturnvaluesIF::RETURN_OK){ return result; } - result = AutoSerializeAdapter::serialize(&serviceType,buffer,size,max_size,bigEndian); + result = SerializeAdapter::serialize(&serviceType,buffer,size,max_size,bigEndian); if(result!=HasReturnvaluesIF::RETURN_OK){ return result; } - result = AutoSerializeAdapter::serialize(&serviceSubtype,buffer,size,max_size,bigEndian); + result = SerializeAdapter::serialize(&serviceSubtype,buffer,size,max_size,bigEndian); if(result!=HasReturnvaluesIF::RETURN_OK){ return result; } - result = AutoSerializeAdapter::serialize(&subCounter,buffer,size,max_size,bigEndian); + result = SerializeAdapter::serialize(&subCounter,buffer,size,max_size,bigEndian); if(result!=HasReturnvaluesIF::RETURN_OK){ return result; } @@ -246,11 +246,11 @@ public: uint32_t getSerializedSize() const { uint32_t size = 0; - size += AutoSerializeAdapter::getSerializedSize(&apid); - size += AutoSerializeAdapter::getSerializedSize(&sourceSequenceCount); - size += AutoSerializeAdapter::getSerializedSize(&serviceType); - size += AutoSerializeAdapter::getSerializedSize(&serviceSubtype); - size += AutoSerializeAdapter::getSerializedSize(&subCounter); + size += SerializeAdapter::getSerializedSize(&apid); + size += SerializeAdapter::getSerializedSize(&sourceSequenceCount); + size += SerializeAdapter::getSerializedSize(&serviceType); + size += SerializeAdapter::getSerializedSize(&serviceSubtype); + size += SerializeAdapter::getSerializedSize(&subCounter); SerialBufferAdapter adapter(rawTimestamp,sizeof(rawTimestamp)); size += adapter.getSerializedSize(); return size; @@ -259,27 +259,27 @@ public: ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, bool bigEndian) { - ReturnValue_t result = AutoSerializeAdapter::deSerialize(&apid, buffer, + ReturnValue_t result = SerializeAdapter::deSerialize(&apid, buffer, size, bigEndian); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = AutoSerializeAdapter::deSerialize(&sourceSequenceCount, buffer, + result = SerializeAdapter::deSerialize(&sourceSequenceCount, buffer, size, bigEndian); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = AutoSerializeAdapter::deSerialize(&serviceType, buffer, size, + result = SerializeAdapter::deSerialize(&serviceType, buffer, size, bigEndian); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = AutoSerializeAdapter::deSerialize(&serviceSubtype, buffer, + result = SerializeAdapter::deSerialize(&serviceSubtype, buffer, size, bigEndian); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = AutoSerializeAdapter::deSerialize(&subCounter, buffer, size, + result = SerializeAdapter::deSerialize(&subCounter, buffer, size, bigEndian); if (result != HasReturnvaluesIF::RETURN_OK) { return result; diff --git a/tmtcpacket/packetmatcher/ApidMatcher.h b/tmtcpacket/packetmatcher/ApidMatcher.h index 1f194968..d5d96f2d 100644 --- a/tmtcpacket/packetmatcher/ApidMatcher.h +++ b/tmtcpacket/packetmatcher/ApidMatcher.h @@ -24,14 +24,14 @@ public: } ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, const uint32_t max_size, bool bigEndian) const { - return SerializeAdapter::serialize(&apid, buffer, size, max_size, bigEndian); + return SerializeAdapter::serialize(&apid, buffer, size, max_size, bigEndian); } uint32_t getSerializedSize() const { - return SerializeAdapter::getSerializedSize(&apid); + return SerializeAdapter::getSerializedSize(&apid); } ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, bool bigEndian) { - return SerializeAdapter::deSerialize(&apid, buffer, size, bigEndian); + return SerializeAdapter::deSerialize(&apid, buffer, size, bigEndian); } }; diff --git a/tmtcpacket/packetmatcher/ServiceMatcher.h b/tmtcpacket/packetmatcher/ServiceMatcher.h index 1a6781b4..b0623780 100644 --- a/tmtcpacket/packetmatcher/ServiceMatcher.h +++ b/tmtcpacket/packetmatcher/ServiceMatcher.h @@ -24,14 +24,14 @@ public: } ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, const uint32_t max_size, bool bigEndian) const { - return SerializeAdapter::serialize(&service, buffer, size, max_size, bigEndian); + return SerializeAdapter::serialize(&service, buffer, size, max_size, bigEndian); } uint32_t getSerializedSize() const { - return SerializeAdapter::getSerializedSize(&service); + return SerializeAdapter::getSerializedSize(&service); } ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, bool bigEndian) { - return SerializeAdapter::deSerialize(&service, buffer, size, bigEndian); + return SerializeAdapter::deSerialize(&service, buffer, size, bigEndian); } }; diff --git a/tmtcpacket/packetmatcher/SubserviceMatcher.h b/tmtcpacket/packetmatcher/SubserviceMatcher.h index 1b589b20..90370af1 100644 --- a/tmtcpacket/packetmatcher/SubserviceMatcher.h +++ b/tmtcpacket/packetmatcher/SubserviceMatcher.h @@ -22,14 +22,14 @@ public: } ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, const uint32_t max_size, bool bigEndian) const { - return SerializeAdapter::serialize(&subService, buffer, size, max_size, bigEndian); + return SerializeAdapter::serialize(&subService, buffer, size, max_size, bigEndian); } uint32_t getSerializedSize() const { - return SerializeAdapter::getSerializedSize(&subService); + return SerializeAdapter::getSerializedSize(&subService); } ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, bool bigEndian) { - return SerializeAdapter::deSerialize(&subService, buffer, size, bigEndian); + return SerializeAdapter::deSerialize(&subService, buffer, size, bigEndian); } private: uint8_t subService; diff --git a/tmtcservices/CommandingServiceBase.cpp b/tmtcservices/CommandingServiceBase.cpp index d70b9042..5b9e7b68 100644 --- a/tmtcservices/CommandingServiceBase.cpp +++ b/tmtcservices/CommandingServiceBase.cpp @@ -236,7 +236,7 @@ void CommandingServiceBase::sendTmPacket(uint8_t subservice, uint8_t buffer[sizeof(object_id_t)]; uint8_t* pBuffer = buffer; uint32_t size = 0; - SerializeAdapter::serialize(&objectId, &pBuffer, &size, + SerializeAdapter::serialize(&objectId, &pBuffer, &size, sizeof(object_id_t), true); TmPacketStored tmPacketStored(this->apid, this->service, subservice, this->tmPacketCounter, data, dataLen, buffer, size); diff --git a/tmtcservices/PusVerificationReport.cpp b/tmtcservices/PusVerificationReport.cpp index 1bc53c2a..e1dad2be 100644 --- a/tmtcservices/PusVerificationReport.cpp +++ b/tmtcservices/PusVerificationReport.cpp @@ -108,12 +108,12 @@ PusSuccessReport::PusSuccessReport(uint16_t setPacketId, uint16_t setSequenceControl, uint8_t setStep) : reportSize(0), pBuffer(reportBuffer) { //Serialization won't fail, because we know the necessary max-size of the buffer. - SerializeAdapter::serialize(&setPacketId, &pBuffer, &reportSize, + SerializeAdapter::serialize(&setPacketId, &pBuffer, &reportSize, sizeof(reportBuffer), true); - SerializeAdapter::serialize(&setSequenceControl, &pBuffer, + SerializeAdapter::serialize(&setSequenceControl, &pBuffer, &reportSize, sizeof(reportBuffer), true); if (setStep != 0) { - SerializeAdapter::serialize(&setStep, &pBuffer, &reportSize, + SerializeAdapter::serialize(&setStep, &pBuffer, &reportSize, sizeof(reportBuffer), true); } } @@ -135,19 +135,19 @@ PusFailureReport::PusFailureReport(uint16_t setPacketId, uint8_t setStep, uint32_t parameter1, uint32_t parameter2) : reportSize(0), pBuffer(reportBuffer) { //Serialization won't fail, because we know the necessary max-size of the buffer. - SerializeAdapter::serialize(&setPacketId, &pBuffer, &reportSize, + SerializeAdapter::serialize(&setPacketId, &pBuffer, &reportSize, sizeof(reportBuffer), true); - SerializeAdapter::serialize(&setSequenceControl, &pBuffer, + SerializeAdapter::serialize(&setSequenceControl, &pBuffer, &reportSize, sizeof(reportBuffer), true); if (setStep != 0) { - SerializeAdapter::serialize(&setStep, &pBuffer, &reportSize, + SerializeAdapter::serialize(&setStep, &pBuffer, &reportSize, sizeof(reportBuffer), true); } - SerializeAdapter::serialize(&setErrorCode, &pBuffer, + SerializeAdapter::serialize(&setErrorCode, &pBuffer, &reportSize, sizeof(reportBuffer), true); - SerializeAdapter::serialize(¶meter1, &pBuffer, &reportSize, + SerializeAdapter::serialize(¶meter1, &pBuffer, &reportSize, sizeof(reportBuffer), true); - SerializeAdapter::serialize(¶meter2, &pBuffer, &reportSize, + SerializeAdapter::serialize(¶meter2, &pBuffer, &reportSize, sizeof(reportBuffer), true); } From 6553450b4b85ea7ec53e88850195af35d76d85b2 Mon Sep 17 00:00:00 2001 From: Uli Date: Tue, 21 Apr 2020 22:28:43 +0200 Subject: [PATCH 002/307] Actually, not that horrible, thanks to sed --- action/ActionHelper.cpp | 6 +- action/CommandActionHelper.cpp | 39 ++++--- container/FixedMap.h | 22 ++-- container/IndexedRingMemoryArray.h | 60 +++++------ datapool/DataPool.cpp | 4 +- datapool/DataPoolAdmin.cpp | 6 +- datapool/DataPoolParameterWrapper.cpp | 20 ++-- datapool/DataPoolParameterWrapper.h | 10 +- datapool/DataSet.cpp | 18 ++-- datapool/DataSet.h | 10 +- datapool/PoolRawAccess.cpp | 6 +- datapool/PoolRawAccess.h | 6 +- datapool/PoolVariable.h | 6 +- datapool/PoolVector.h | 14 +-- devicehandlers/DeviceTmReportingWrapper.cpp | 18 ++-- devicehandlers/DeviceTmReportingWrapper.h | 10 +- events/eventmatching/EventRangeMatcherBase.h | 14 +-- globalfunctions/Type.cpp | 22 ++-- globalfunctions/conversion.cpp | 104 ------------------- globalfunctions/conversion.h | 24 ----- globalfunctions/matching/MatchTree.h | 20 ++-- globalfunctions/matching/RangeMatcher.h | 10 +- health/HealthTable.cpp | 10 +- health/HealthTable.h | 2 +- monitoring/LimitViolationReporter.cpp | 6 +- osal/rtems/CpuUsage.cpp | 36 +++---- osal/rtems/CpuUsage.h | 20 ++-- parameters/ParameterHelper.cpp | 6 +- parameters/ParameterWrapper.cpp | 92 ++++++++-------- parameters/ParameterWrapper.h | 22 ++-- power/Fuse.cpp | 14 +-- power/Fuse.h | 27 ++--- power/PowerComponent.cpp | 20 ++-- power/PowerComponent.h | 10 +- serialize/SerialArrayListAdapter.h | 30 +++--- serialize/SerialBufferAdapter.cpp | 12 +-- serialize/SerialBufferAdapter.h | 10 +- serialize/SerialFixedArrayListAdapter.h | 14 +-- serialize/SerializeElement.h | 2 +- serialize/SerializeIF.h | 2 +- subsystem/Subsystem.cpp | 39 ++++--- subsystem/modes/ModeDefinitions.h | 26 ++--- thermal/ThermalComponent.cpp | 10 +- tmstorage/TmStorePackets.h | 52 +++++----- tmtcpacket/packetmatcher/ApidMatcher.h | 14 +-- tmtcpacket/packetmatcher/ServiceMatcher.h | 14 +-- tmtcpacket/packetmatcher/SubserviceMatcher.h | 14 +-- tmtcpacket/pus/TmPacketStored.cpp | 33 +++--- tmtcservices/CommandingServiceBase.cpp | 4 +- tmtcservices/PusVerificationReport.cpp | 28 ++--- tmtcservices/PusVerificationReport.h | 6 +- 51 files changed, 458 insertions(+), 566 deletions(-) delete mode 100644 globalfunctions/conversion.cpp delete mode 100644 globalfunctions/conversion.h diff --git a/action/ActionHelper.cpp b/action/ActionHelper.cpp index 9c1475f1..f93afaa8 100644 --- a/action/ActionHelper.cpp +++ b/action/ActionHelper.cpp @@ -71,18 +71,18 @@ ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo, ActionId_t rep CommandMessage reply; store_address_t storeAddress; uint8_t *dataPtr; - uint32_t maxSize = data->getSerializedSize(); + size_t maxSize = data->getSerializedSize(); if (maxSize == 0) { //No error, there's simply nothing to report. return HasReturnvaluesIF::RETURN_OK; } - uint32_t size = 0; + size_t size = 0; ReturnValue_t result = ipcStore->getFreeElement(&storeAddress, maxSize, &dataPtr); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = data->serialize(&dataPtr, &size, maxSize, true); + result = data->serialize(&dataPtr, &size, maxSize, SerializeIF::Endianness::BIG); if (result != HasReturnvaluesIF::RETURN_OK) { ipcStore->deleteData(storeAddress); return result; diff --git a/action/CommandActionHelper.cpp b/action/CommandActionHelper.cpp index 05eb9346..6a26453c 100644 --- a/action/CommandActionHelper.cpp +++ b/action/CommandActionHelper.cpp @@ -4,30 +4,31 @@ #include #include -CommandActionHelper::CommandActionHelper(CommandsActionsIF* setOwner) : +CommandActionHelper::CommandActionHelper(CommandsActionsIF *setOwner) : owner(setOwner), queueToUse(NULL), ipcStore( - NULL), commandCount(0), lastTarget(0) { + NULL), commandCount(0), lastTarget(0) { } CommandActionHelper::~CommandActionHelper() { } ReturnValue_t CommandActionHelper::commandAction(object_id_t commandTo, - ActionId_t actionId, SerializeIF* data) { - HasActionsIF* receiver = objectManager->get(commandTo); + ActionId_t actionId, SerializeIF *data) { + HasActionsIF *receiver = objectManager->get(commandTo); if (receiver == NULL) { return CommandsActionsIF::OBJECT_HAS_NO_FUNCTIONS; } store_address_t storeId; - uint8_t* storePointer; - uint32_t maxSize = data->getSerializedSize(); + uint8_t *storePointer; + size_t maxSize = data->getSerializedSize(); ReturnValue_t result = ipcStore->getFreeElement(&storeId, maxSize, &storePointer); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - uint32_t size = 0; - result = data->serialize(&storePointer, &size, maxSize, true); + size_t size = 0; + result = data->serialize(&storePointer, &size, maxSize, + SerializeIF::Endianness::BIG); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } @@ -35,11 +36,11 @@ ReturnValue_t CommandActionHelper::commandAction(object_id_t commandTo, } ReturnValue_t CommandActionHelper::commandAction(object_id_t commandTo, - ActionId_t actionId, const uint8_t* data, uint32_t size) { + ActionId_t actionId, const uint8_t *data, uint32_t size) { // if (commandCount != 0) { // return CommandsFunctionsIF::ALREADY_COMMANDING; // } - HasActionsIF* receiver = objectManager->get(commandTo); + HasActionsIF *receiver = objectManager->get(commandTo); if (receiver == NULL) { return CommandsActionsIF::OBJECT_HAS_NO_FUNCTIONS; } @@ -71,13 +72,13 @@ ReturnValue_t CommandActionHelper::initialize() { } queueToUse = owner->getCommandQueuePtr(); - if(queueToUse == NULL){ + if (queueToUse == NULL) { return HasReturnvaluesIF::RETURN_FAILED; } return HasReturnvaluesIF::RETURN_OK; } -ReturnValue_t CommandActionHelper::handleReply(CommandMessage* reply) { +ReturnValue_t CommandActionHelper::handleReply(CommandMessage *reply) { if (reply->getSender() != lastTarget) { return HasReturnvaluesIF::RETURN_FAILED; } @@ -88,7 +89,8 @@ ReturnValue_t CommandActionHelper::handleReply(CommandMessage* reply) { return HasReturnvaluesIF::RETURN_OK; case ActionMessage::COMPLETION_FAILED: commandCount--; - owner->completionFailedReceived(ActionMessage::getActionId(reply), ActionMessage::getReturnCode(reply)); + owner->completionFailedReceived(ActionMessage::getActionId(reply), + ActionMessage::getReturnCode(reply)); return HasReturnvaluesIF::RETURN_OK; case ActionMessage::STEP_SUCCESS: owner->stepSuccessfulReceived(ActionMessage::getActionId(reply), @@ -96,11 +98,13 @@ ReturnValue_t CommandActionHelper::handleReply(CommandMessage* reply) { return HasReturnvaluesIF::RETURN_OK; case ActionMessage::STEP_FAILED: commandCount--; - owner->stepFailedReceived(ActionMessage::getActionId(reply), ActionMessage::getStep(reply), + owner->stepFailedReceived(ActionMessage::getActionId(reply), + ActionMessage::getStep(reply), ActionMessage::getReturnCode(reply)); return HasReturnvaluesIF::RETURN_OK; case ActionMessage::DATA_REPLY: - extractDataForOwner(ActionMessage::getActionId(reply), ActionMessage::getStoreId(reply)); + extractDataForOwner(ActionMessage::getActionId(reply), + ActionMessage::getStoreId(reply)); return HasReturnvaluesIF::RETURN_OK; default: return HasReturnvaluesIF::RETURN_FAILED; @@ -111,8 +115,9 @@ uint8_t CommandActionHelper::getCommandCount() const { return commandCount; } -void CommandActionHelper::extractDataForOwner(ActionId_t actionId, store_address_t storeId) { - const uint8_t * data = NULL; +void CommandActionHelper::extractDataForOwner(ActionId_t actionId, + store_address_t storeId) { + const uint8_t *data = NULL; uint32_t size = 0; ReturnValue_t result = ipcStore->getData(storeId, &data, &size); if (result != HasReturnvaluesIF::RETURN_OK) { diff --git a/container/FixedMap.h b/container/FixedMap.h index eaf8a24c..ac170bd2 100644 --- a/container/FixedMap.h +++ b/container/FixedMap.h @@ -148,22 +148,22 @@ public: return theMap.maxSize(); } - virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { + virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const { ReturnValue_t result = SerializeAdapter::serialize(&this->_size, - buffer, size, max_size, bigEndian); + buffer, size, maxSize, streamEndianness); uint32_t i = 0; while ((result == HasReturnvaluesIF::RETURN_OK) && (i < this->_size)) { result = SerializeAdapter::serialize(&theMap[i].first, buffer, - size, max_size, bigEndian); + size, maxSize, streamEndianness); result = SerializeAdapter::serialize(&theMap[i].second, buffer, size, - max_size, bigEndian); + maxSize, streamEndianness); ++i; } return result; } - virtual uint32_t getSerializedSize() const { + virtual size_t getSerializedSize() const { uint32_t printSize = sizeof(_size); uint32_t i = 0; @@ -176,19 +176,19 @@ public: return printSize; } - virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian) { + virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) { ReturnValue_t result = SerializeAdapter::deSerialize(&this->_size, - buffer, size, bigEndian); + buffer, size, streamEndianness); if (this->_size > theMap.maxSize()) { return SerializeIF::TOO_MANY_ELEMENTS; } uint32_t i = 0; while ((result == HasReturnvaluesIF::RETURN_OK) && (i < this->_size)) { result = SerializeAdapter::deSerialize(&theMap[i].first, buffer, - size, bigEndian); + size, streamEndianness); result = SerializeAdapter::deSerialize(&theMap[i].second, buffer, size, - bigEndian); + streamEndianness); ++i; } return result; diff --git a/container/IndexedRingMemoryArray.h b/container/IndexedRingMemoryArray.h index 32b61c2d..6e7f330c 100644 --- a/container/IndexedRingMemoryArray.h +++ b/container/IndexedRingMemoryArray.h @@ -68,46 +68,46 @@ public: return this->storedPackets; } - ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { - ReturnValue_t result = SerializeAdapter::serialize(&blockStartAddress,buffer,size,max_size,bigEndian); + ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const { + ReturnValue_t result = SerializeAdapter::serialize(&blockStartAddress,buffer,size,maxSize,streamEndianness); if(result != HasReturnvaluesIF::RETURN_OK){ return result; } - result = indexType.serialize(buffer,size,max_size,bigEndian); + result = indexType.serialize(buffer,size,maxSize,streamEndianness); if(result != HasReturnvaluesIF::RETURN_OK){ return result; } - result = SerializeAdapter::serialize(&this->size,buffer,size,max_size,bigEndian); + result = SerializeAdapter::serialize(&this->size,buffer,size,maxSize,streamEndianness); if(result != HasReturnvaluesIF::RETURN_OK){ return result; } - result = SerializeAdapter::serialize(&this->storedPackets,buffer,size,max_size,bigEndian); + result = SerializeAdapter::serialize(&this->storedPackets,buffer,size,maxSize,streamEndianness); return result; } - ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian){ - ReturnValue_t result = SerializeAdapter::deSerialize(&blockStartAddress,buffer,size,bigEndian); + ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness){ + ReturnValue_t result = SerializeAdapter::deSerialize(&blockStartAddress,buffer,size,streamEndianness); if(result != HasReturnvaluesIF::RETURN_OK){ return result; } - result = indexType.deSerialize(buffer,size,bigEndian); + result = indexType.deSerialize(buffer,size,streamEndianness); if(result != HasReturnvaluesIF::RETURN_OK){ return result; } - result = SerializeAdapter::deSerialize(&this->size,buffer,size,bigEndian); + result = SerializeAdapter::deSerialize(&this->size,buffer,size,streamEndianness); if(result != HasReturnvaluesIF::RETURN_OK){ return result; } - result = SerializeAdapter::deSerialize(&this->storedPackets,buffer,size,bigEndian); + result = SerializeAdapter::deSerialize(&this->storedPackets,buffer,size,streamEndianness); if(result != HasReturnvaluesIF::RETURN_OK){ return result; } return result; } - uint32_t getSerializedSize() const { + size_t getSerializedSize() const { uint32_t size = SerializeAdapter::getSerializedSize(&blockStartAddress); size += indexType.getSerializedSize(); size += SerializeAdapter::getSerializedSize(&this->size); @@ -485,22 +485,22 @@ public: * Parameters according to HasSerializeIF * @param buffer * @param size - * @param max_size - * @param bigEndian + * @param maxSize + * @param streamEndianness * @return */ - ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const{ + ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const{ uint8_t* crcBuffer = *buffer; uint32_t oldSize = *size; if(additionalInfo!=NULL){ - additionalInfo->serialize(buffer,size,max_size,bigEndian); + additionalInfo->serialize(buffer,size,maxSize,streamEndianness); } - ReturnValue_t result = currentWriteBlock->serialize(buffer,size,max_size,bigEndian); + ReturnValue_t result = currentWriteBlock->serialize(buffer,size,maxSize,streamEndianness); if(result != HasReturnvaluesIF::RETURN_OK){ return result; } - result = SerializeAdapter::serialize(&this->size,buffer,size,max_size,bigEndian); + result = SerializeAdapter::serialize(&this->size,buffer,size,maxSize,streamEndianness); if(result != HasReturnvaluesIF::RETURN_OK){ return result; } @@ -508,14 +508,14 @@ public: uint32_t i = 0; while ((result == HasReturnvaluesIF::RETURN_OK) && (i < this->size)) { result = SerializeAdapter::serialize(&this->entries[i], buffer, size, - max_size, bigEndian); + maxSize, streamEndianness); ++i; } if(result != HasReturnvaluesIF::RETURN_OK){ return result; } uint16_t crc = Calculate_CRC(crcBuffer,(*size-oldSize)); - result = SerializeAdapter::serialize(&crc,buffer,size,max_size,bigEndian); + result = SerializeAdapter::serialize(&crc,buffer,size,maxSize,streamEndianness); return result; } @@ -524,7 +524,7 @@ public: * Get the serialized Size of the index * @return The serialized size of the index */ - uint32_t getSerializedSize() const { + size_t getSerializedSize() const { uint32_t size = 0; if(additionalInfo!=NULL){ @@ -542,28 +542,28 @@ public: * CRC Has to be checked before! * @param buffer * @param size - * @param bigEndian + * @param streamEndianness * @return */ - ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian){ + ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness){ ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; if(additionalInfo!=NULL){ - result = additionalInfo->deSerialize(buffer,size,bigEndian); + result = additionalInfo->deSerialize(buffer,size,streamEndianness); } if(result != HasReturnvaluesIF::RETURN_OK){ return result; } Index tempIndex; - result = tempIndex.deSerialize(buffer,size,bigEndian); + result = tempIndex.deSerialize(buffer,size,streamEndianness); if(result != HasReturnvaluesIF::RETURN_OK){ return result; } uint32_t tempSize = 0; - result = SerializeAdapter::deSerialize(&tempSize,buffer,size,bigEndian); + result = SerializeAdapter::deSerialize(&tempSize,buffer,size,streamEndianness); if(result != HasReturnvaluesIF::RETURN_OK){ return result; } @@ -574,7 +574,7 @@ public: while ((result == HasReturnvaluesIF::RETURN_OK) && (i < this->size)) { result = SerializeAdapter::deSerialize( &this->entries[i], buffer, size, - bigEndian); + streamEndianness); ++i; } if(result != HasReturnvaluesIF::RETURN_OK){ diff --git a/datapool/DataPool.cpp b/datapool/DataPool.cpp index 89543d77..6604dc23 100644 --- a/datapool/DataPool.cpp +++ b/datapool/DataPool.cpp @@ -39,10 +39,10 @@ PoolEntryIF* DataPool::getRawData( uint32_t data_pool_id ) { } } -//uint8_t DataPool::getRawData( uint32_t data_pool_id, uint8_t* address, uint16_t* size, uint32_t max_size ) { +//uint8_t DataPool::getRawData( uint32_t data_pool_id, uint8_t* address, uint16_t* size, uint32_t maxSize ) { // std::map::iterator it = this->data_pool.find( data_pool_id ); // if ( it != this->data_pool.end() ) { -// if ( it->second->getByteSize() <= max_size ) { +// if ( it->second->getByteSize() <= maxSize ) { // *size = it->second->getByteSize(); // memcpy( address, it->second->getRawData(), *size ); // return DP_SUCCESSFUL; diff --git a/datapool/DataPoolAdmin.cpp b/datapool/DataPoolAdmin.cpp index fe6b9215..8bf7f6b3 100644 --- a/datapool/DataPoolAdmin.cpp +++ b/datapool/DataPoolAdmin.cpp @@ -261,7 +261,7 @@ ReturnValue_t DataPoolAdmin::handleParameterCommand(CommandMessage* command) { //identical to ParameterHelper::sendParameter() ReturnValue_t DataPoolAdmin::sendParameter(MessageQueueId_t to, uint32_t id, const DataPoolParameterWrapper* wrapper) { - uint32_t serializedSize = wrapper->getSerializedSize(); + size_t serializedSize = wrapper->getSerializedSize(); uint8_t *storeElement; store_address_t address; @@ -272,10 +272,10 @@ ReturnValue_t DataPoolAdmin::sendParameter(MessageQueueId_t to, uint32_t id, return result; } - uint32_t storeElementSize = 0; + size_t storeElementSize = 0; result = wrapper->serialize(&storeElement, &storeElementSize, - serializedSize, true); + serializedSize, SerializeIF::Endianness::BIG); if (result != HasReturnvaluesIF::RETURN_OK) { storage->deleteData(address); diff --git a/datapool/DataPoolParameterWrapper.cpp b/datapool/DataPoolParameterWrapper.cpp index 10fb5392..e08eba5b 100644 --- a/datapool/DataPoolParameterWrapper.cpp +++ b/datapool/DataPoolParameterWrapper.cpp @@ -36,22 +36,22 @@ ReturnValue_t DataPoolParameterWrapper::set(uint8_t domainId, } ReturnValue_t DataPoolParameterWrapper::serialize(uint8_t** buffer, - uint32_t* size, const uint32_t max_size, bool bigEndian) const { + size_t* size, size_t maxSize, Endianness streamEndianness) const { ReturnValue_t result; - result = SerializeAdapter::serialize(&type, buffer, size, max_size, - bigEndian); + result = SerializeAdapter::serialize(&type, buffer, size, maxSize, + streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } result = SerializeAdapter::serialize(&columns, buffer, size, - max_size, bigEndian); + maxSize, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::serialize(&rows, buffer, size, max_size, - bigEndian); + result = SerializeAdapter::serialize(&rows, buffer, size, maxSize, + streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } @@ -60,7 +60,7 @@ ReturnValue_t DataPoolParameterWrapper::serialize(uint8_t** buffer, DataSet mySet; PoolRawAccess raw(poolId, index, &mySet,PoolVariableIF::VAR_READ); mySet.read(); - result = raw.serialize(buffer,size,max_size,bigEndian); + result = raw.serialize(buffer,size,maxSize,streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK){ return result; } @@ -69,8 +69,8 @@ ReturnValue_t DataPoolParameterWrapper::serialize(uint8_t** buffer, } //same as ParameterWrapper -uint32_t DataPoolParameterWrapper::getSerializedSize() const { - uint32_t serializedSize = 0; +size_t DataPoolParameterWrapper::getSerializedSize() const { + size_t serializedSize = 0; serializedSize += type.getSerializedSize(); serializedSize += sizeof(rows); serializedSize += sizeof(columns); @@ -80,7 +80,7 @@ uint32_t DataPoolParameterWrapper::getSerializedSize() const { } ReturnValue_t DataPoolParameterWrapper::deSerialize(const uint8_t** buffer, - int32_t* size, bool bigEndian) { + size_t* size, Endianness streamEndianness) { return HasReturnvaluesIF::RETURN_FAILED; } diff --git a/datapool/DataPoolParameterWrapper.h b/datapool/DataPoolParameterWrapper.h index faadf659..a3dbdc04 100644 --- a/datapool/DataPoolParameterWrapper.h +++ b/datapool/DataPoolParameterWrapper.h @@ -11,13 +11,13 @@ public: ReturnValue_t set(uint8_t domainId, uint16_t parameterId); - virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const; + virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const override; - virtual uint32_t getSerializedSize() const; + virtual size_t getSerializedSize() const override; - virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian); + virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) override; ReturnValue_t copyFrom(const ParameterWrapper *from, uint16_t startWritingAtIndex); diff --git a/datapool/DataSet.cpp b/datapool/DataSet.cpp index b4725c73..94cdcf0c 100644 --- a/datapool/DataSet.cpp +++ b/datapool/DataSet.cpp @@ -106,12 +106,12 @@ uint8_t DataSet::lockDataPool() { return ::dataPool.lockDataPool(); } -ReturnValue_t DataSet::serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { +ReturnValue_t DataSet::serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const { ReturnValue_t result = RETURN_FAILED; for (uint16_t count = 0; count < fill_count; count++) { - result = registeredVariables[count]->serialize(buffer, size, max_size, - bigEndian); + result = registeredVariables[count]->serialize(buffer, size, maxSize, + streamEndianness); if (result != RETURN_OK) { return result; } @@ -119,8 +119,8 @@ ReturnValue_t DataSet::serialize(uint8_t** buffer, uint32_t* size, return result; } -uint32_t DataSet::getSerializedSize() const { - uint32_t size = 0; +size_t DataSet::getSerializedSize() const { + size_t size = 0; for (uint16_t count = 0; count < fill_count; count++) { size += registeredVariables[count]->getSerializedSize(); } @@ -136,12 +136,12 @@ void DataSet::setValid(uint8_t valid) { } } -ReturnValue_t DataSet::deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian) { +ReturnValue_t DataSet::deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) { ReturnValue_t result = RETURN_FAILED; for (uint16_t count = 0; count < fill_count; count++) { result = registeredVariables[count]->deSerialize(buffer, size, - bigEndian); + streamEndianness); if (result != RETURN_OK) { return result; } diff --git a/datapool/DataSet.h b/datapool/DataSet.h index 982be692..3d211537 100644 --- a/datapool/DataSet.h +++ b/datapool/DataSet.h @@ -146,13 +146,13 @@ public: */ void setValid(uint8_t valid); - ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const; + ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const override; - uint32_t getSerializedSize() const; + size_t getSerializedSize() const override; - ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian); + ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) override; }; diff --git a/datapool/PoolRawAccess.cpp b/datapool/PoolRawAccess.cpp index 2053498b..94766d87 100644 --- a/datapool/PoolRawAccess.cpp +++ b/datapool/PoolRawAccess.cpp @@ -69,12 +69,12 @@ uint8_t* PoolRawAccess::getEntry() { } ReturnValue_t PoolRawAccess::getEntryEndianSafe(uint8_t* buffer, - uint32_t* writtenBytes, uint32_t max_size) { + uint32_t* writtenBytes, uint32_t maxSize) { uint8_t* data_ptr = getEntry(); // debug << "PoolRawAccess::getEntry: Array position: " << index * size_of_type << " Size of T: " << (int)size_of_type << " ByteSize: " << byte_size << " Position: " << *size << std::endl; if (typeSize == 0) return DATA_POOL_ACCESS_FAILED; - if (typeSize > max_size) + if (typeSize > maxSize) return INCORRECT_SIZE; #ifndef BYTE_ORDER_SYSTEM #error BYTE_ORDER_SYSTEM not defined @@ -149,7 +149,7 @@ ReturnValue_t PoolRawAccess::serialize(uint8_t** buffer, size_t* size, size_t maxSize, Endianness streamEndianness) const { //TODO integer overflow if (typeSize + *size <= maxSize) { -#error use endian swapper +#warning use endian swapper if (1) { #ifndef BYTE_ORDER_SYSTEM #error BYTE_ORDER_SYSTEM not defined diff --git a/datapool/PoolRawAccess.h b/datapool/PoolRawAccess.h index 190c38a9..8cc8f3f0 100644 --- a/datapool/PoolRawAccess.h +++ b/datapool/PoolRawAccess.h @@ -90,15 +90,15 @@ public: * \details It makes use of the getEntry call of this function, but additionally flips the * bytes to big endian, which is the default for external communication (as House- * keeping telemetry). To achieve this, the data is copied directly to the passed - * buffer, if it fits in the given max_size. + * buffer, if it fits in the given maxSize. * \param buffer A pointer to a buffer to write to * \param writtenBytes The number of bytes written is returned with this value. - * \param max_size The maximum size that the function may write to buffer. + * \param maxSize The maximum size that the function may write to buffer. * \return - \c RETURN_OK if entry could be acquired * - \c RETURN_FAILED else. */ ReturnValue_t getEntryEndianSafe(uint8_t *buffer, uint32_t *size, - uint32_t max_size); + uint32_t maxSize); /** * With this method, the content can be set from a big endian buffer safely. * @param buffer Pointer to the data to set diff --git a/datapool/PoolVariable.h b/datapool/PoolVariable.h index ce073426..c1a57539 100644 --- a/datapool/PoolVariable.h +++ b/datapool/PoolVariable.h @@ -195,12 +195,12 @@ public: } virtual ReturnValue_t serialize(uint8_t **buffer, size_t *size, - size_t max_size, Endianness streamEndianness) const override { - return SerializeAdapter::serialize(&value, buffer, size, max_size, + size_t maxSize, Endianness streamEndianness) const override { + return SerializeAdapter::serialize(&value, buffer, size, maxSize, streamEndianness); } - virtual uint32_t getSerializedSize() const override { + virtual size_t getSerializedSize() const override { return SerializeAdapter::getSerializedSize(&value); } diff --git a/datapool/PoolVector.h b/datapool/PoolVector.h index 3809f93b..50724054 100644 --- a/datapool/PoolVector.h +++ b/datapool/PoolVector.h @@ -197,13 +197,13 @@ public: return *this; } - virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { + virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const { uint16_t i; ReturnValue_t result; for (i = 0; i < vector_size; i++) { result = SerializeAdapter::serialize(&(value[i]), buffer, size, - max_size, bigEndian); + maxSize, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } @@ -211,17 +211,17 @@ public: return result; } - virtual uint32_t getSerializedSize() const { + virtual size_t getSerializedSize() const { return vector_size * SerializeAdapter::getSerializedSize(value); } - virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian) { + virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) { uint16_t i; ReturnValue_t result; for (i = 0; i < vector_size; i++) { result = SerializeAdapter::deSerialize(&(value[i]), buffer, size, - bigEndian); + streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } diff --git a/devicehandlers/DeviceTmReportingWrapper.cpp b/devicehandlers/DeviceTmReportingWrapper.cpp index 55861c3c..ce5eb109 100644 --- a/devicehandlers/DeviceTmReportingWrapper.cpp +++ b/devicehandlers/DeviceTmReportingWrapper.cpp @@ -12,35 +12,35 @@ DeviceTmReportingWrapper::~DeviceTmReportingWrapper() { } ReturnValue_t DeviceTmReportingWrapper::serialize(uint8_t** buffer, - uint32_t* size, const uint32_t max_size, bool bigEndian) const { + size_t* size, size_t maxSize, Endianness streamEndianness) const { ReturnValue_t result = SerializeAdapter::serialize(&objectId, - buffer, size, max_size, bigEndian); + buffer, size, maxSize, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } result = SerializeAdapter::serialize(&actionId, buffer, - size, max_size, bigEndian); + size, maxSize, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - return data->serialize(buffer, size, max_size, bigEndian); + return data->serialize(buffer, size, maxSize, streamEndianness); } -uint32_t DeviceTmReportingWrapper::getSerializedSize() const { +size_t DeviceTmReportingWrapper::getSerializedSize() const { return sizeof(objectId) + sizeof(ActionId_t) + data->getSerializedSize(); } ReturnValue_t DeviceTmReportingWrapper::deSerialize(const uint8_t** buffer, - int32_t* size, bool bigEndian) { + size_t* size, Endianness streamEndianness) { ReturnValue_t result = SerializeAdapter::deSerialize(&objectId, - buffer, size, bigEndian); + buffer, size, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } result = SerializeAdapter::deSerialize(&actionId, buffer, - size, bigEndian); + size, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - return data->deSerialize(buffer, size, bigEndian); + return data->deSerialize(buffer, size, streamEndianness); } diff --git a/devicehandlers/DeviceTmReportingWrapper.h b/devicehandlers/DeviceTmReportingWrapper.h index 1cd9470d..4432b7f1 100644 --- a/devicehandlers/DeviceTmReportingWrapper.h +++ b/devicehandlers/DeviceTmReportingWrapper.h @@ -11,13 +11,13 @@ public: SerializeIF *data); virtual ~DeviceTmReportingWrapper(); - virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const; + virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const override; - virtual uint32_t getSerializedSize() const; + virtual size_t getSerializedSize() const override; - virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian); + virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) override; private: object_id_t objectId; ActionId_t actionId; diff --git a/events/eventmatching/EventRangeMatcherBase.h b/events/eventmatching/EventRangeMatcherBase.h index 921a5d6a..587669ba 100644 --- a/events/eventmatching/EventRangeMatcherBase.h +++ b/events/eventmatching/EventRangeMatcherBase.h @@ -11,16 +11,16 @@ class EventRangeMatcherBase: public SerializeableMatcherIF { public: EventRangeMatcherBase(T from, T till, bool inverted) : rangeMatcher(from, till, inverted) { } virtual ~EventRangeMatcherBase() { } - ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { - return rangeMatcher.serialize(buffer, size, max_size, bigEndian); + ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const { + return rangeMatcher.serialize(buffer, size, maxSize, streamEndianness); } - uint32_t getSerializedSize() const { + size_t getSerializedSize() const { return rangeMatcher.getSerializedSize(); } - ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian) { - return rangeMatcher.deSerialize(buffer, size, bigEndian); + ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) { + return rangeMatcher.deSerialize(buffer, size, streamEndianness); } protected: RangeMatcher rangeMatcher; diff --git a/globalfunctions/Type.cpp b/globalfunctions/Type.cpp index b7b7fd82..a481f768 100644 --- a/globalfunctions/Type.cpp +++ b/globalfunctions/Type.cpp @@ -59,8 +59,8 @@ uint8_t Type::getSize() const { } } -ReturnValue_t Type::serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { +ReturnValue_t Type::serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const { uint8_t ptc; uint8_t pfc; ReturnValue_t result = getPtcPfc(&ptc, &pfc); @@ -68,36 +68,36 @@ ReturnValue_t Type::serialize(uint8_t** buffer, uint32_t* size, return result; } - result = SerializeAdapter::serialize(&ptc, buffer, size, max_size, - bigEndian); + result = SerializeAdapter::serialize(&ptc, buffer, size, maxSize, + streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::serialize(&pfc, buffer, size, max_size, - bigEndian); + result = SerializeAdapter::serialize(&pfc, buffer, size, maxSize, + streamEndianness); return result; } -uint32_t Type::getSerializedSize() const { +size_t Type::getSerializedSize() const { uint8_t dontcare = 0; return 2 * SerializeAdapter::getSerializedSize(&dontcare); } -ReturnValue_t Type::deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian) { +ReturnValue_t Type::deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) { uint8_t ptc; uint8_t pfc; ReturnValue_t result = SerializeAdapter::deSerialize(&ptc, buffer, - size, bigEndian); + size, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } result = SerializeAdapter::deSerialize(&pfc, buffer, size, - bigEndian); + streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } diff --git a/globalfunctions/conversion.cpp b/globalfunctions/conversion.cpp deleted file mode 100644 index d4f542bd..00000000 --- a/globalfunctions/conversion.cpp +++ /dev/null @@ -1,104 +0,0 @@ -#include -#include -#include - - - -//SHOULDDO: This shall be optimized (later)! -void convertToByteStream( uint16_t value, uint8_t* buffer, uint32_t* size ) { - buffer[0] = (value & 0xFF00) >> 8; - buffer[1] = (value & 0x00FF); - *size += 2; -} - -void convertToByteStream( uint32_t value, uint8_t* buffer, uint32_t* size ) { - buffer[0] = (value & 0xFF000000) >> 24; - buffer[1] = (value & 0x00FF0000) >> 16; - buffer[2] = (value & 0x0000FF00) >> 8; - buffer[3] = (value & 0x000000FF); - *size +=4; -} - -void convertToByteStream( int16_t value, uint8_t* buffer, uint32_t* size ) { - buffer[0] = (value & 0xFF00) >> 8; - buffer[1] = (value & 0x00FF); - *size += 2; -} - -void convertToByteStream( int32_t value, uint8_t* buffer, uint32_t* size ) { - buffer[0] = (value & 0xFF000000) >> 24; - buffer[1] = (value & 0x00FF0000) >> 16; - buffer[2] = (value & 0x0000FF00) >> 8; - buffer[3] = (value & 0x000000FF); - *size += 4; -} - -//void convertToByteStream( uint64_t value, uint8_t* buffer, uint32_t* size ) { -// buffer[0] = (value & 0xFF00000000000000) >> 56; -// buffer[1] = (value & 0x00FF000000000000) >> 48; -// buffer[2] = (value & 0x0000FF0000000000) >> 40; -// buffer[3] = (value & 0x000000FF00000000) >> 32; -// buffer[4] = (value & 0x00000000FF000000) >> 24; -// buffer[5] = (value & 0x0000000000FF0000) >> 16; -// buffer[6] = (value & 0x000000000000FF00) >> 8; -// buffer[7] = (value & 0x00000000000000FF); -// *size+=8; -//} -// -//void convertToByteStream( int64_t value, uint8_t* buffer, uint32_t* size ) { -// buffer[0] = (value & 0xFF00000000000000) >> 56; -// buffer[1] = (value & 0x00FF000000000000) >> 48; -// buffer[2] = (value & 0x0000FF0000000000) >> 40; -// buffer[3] = (value & 0x000000FF00000000) >> 32; -// buffer[4] = (value & 0x00000000FF000000) >> 24; -// buffer[5] = (value & 0x0000000000FF0000) >> 16; -// buffer[6] = (value & 0x000000000000FF00) >> 8; -// buffer[7] = (value & 0x00000000000000FF); -// *size+=8; -//} - -void convertToByteStream( float in_value, uint8_t* buffer, uint32_t* size ) { -#ifndef BYTE_ORDER_SYSTEM - #error BYTE_ORDER_SYSTEM not defined -#elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN - union float_union { - float value; - uint8_t chars[4]; - }; - float_union temp; - temp.value = in_value; - buffer[0] = temp.chars[3]; - buffer[1] = temp.chars[2]; - buffer[2] = temp.chars[1]; - buffer[3] = temp.chars[0]; - *size += 4; -#elif BYTE_ORDER_SYSTEM == BIG_ENDIAN - memcpy(buffer, &in_value, sizeof(in_value)); - *size += sizeof(in_value); -#endif -} - -void convertToByteStream( double in_value, uint8_t* buffer, uint32_t* size ) { -#ifndef BYTE_ORDER_SYSTEM - #error BYTE_ORDER_SYSTEM not defined -#elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN - union double_union { - double value; - uint8_t chars[8]; - }; - double_union temp; - temp.value = in_value; - buffer[0] = temp.chars[7]; - buffer[1] = temp.chars[6]; - buffer[2] = temp.chars[5]; - buffer[3] = temp.chars[4]; - buffer[4] = temp.chars[3]; - buffer[5] = temp.chars[2]; - buffer[6] = temp.chars[1]; - buffer[7] = temp.chars[0]; - *size += 8; -#elif BYTE_ORDER_SYSTEM == BIG_ENDIAN - memcpy(buffer, &in_value, sizeof(in_value)); - *size += sizeof(in_value); -#endif -} diff --git a/globalfunctions/conversion.h b/globalfunctions/conversion.h deleted file mode 100644 index 0d1ca1a6..00000000 --- a/globalfunctions/conversion.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef CONVERSION_H_ -#define CONVERSION_H_ - - -#include - - -void convertToByteStream( uint16_t value, uint8_t* buffer, uint32_t* size ); - -void convertToByteStream( uint32_t value, uint8_t* buffer, uint32_t* size ); - -void convertToByteStream( int16_t value, uint8_t* buffer, uint32_t* size ); - -void convertToByteStream( int32_t value, uint8_t* buffer, uint32_t* size ); - -//void convertToByteStream( uint64_t value, uint8_t* buffer, uint32_t* size ); -// -//void convertToByteStream( int64_t value, uint8_t* buffer, uint32_t* size ); - -void convertToByteStream( float value, uint8_t* buffer, uint32_t* size ); - -void convertToByteStream( double value, uint8_t* buffer, uint32_t* size ); - -#endif /* CONVERSION_H_ */ diff --git a/globalfunctions/matching/MatchTree.h b/globalfunctions/matching/MatchTree.h index 0ee3890b..b54f5492 100644 --- a/globalfunctions/matching/MatchTree.h +++ b/globalfunctions/matching/MatchTree.h @@ -45,38 +45,38 @@ public: return matchSubtree(iter, number); } - ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { + ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, SerializeIF::Endianness streamEndianness) const override { iterator iter = this->begin(); uint8_t count = this->countRight(iter); ReturnValue_t result = SerializeAdapter::serialize(&count, - buffer, size, max_size, bigEndian); + buffer, size, maxSize, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } if (iter == this->end()) { return HasReturnvaluesIF::RETURN_OK; } - result = iter->serialize(buffer, size, max_size, bigEndian); + result = iter->serialize(buffer, size, maxSize, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } if (maxDepth > 0) { MatchTree temp(iter.left(), maxDepth - 1); - result = temp.serialize(buffer, size, max_size, bigEndian); + result = temp.serialize(buffer, size, maxSize, streamEndianness); } if (result != HasReturnvaluesIF::RETURN_OK) { return result; } iter = iter.right(); while (iter != this->end()) { - result = iter->serialize(buffer, size, max_size, bigEndian); + result = iter->serialize(buffer, size, maxSize, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } if (maxDepth > 0) { MatchTree temp(iter.left(), maxDepth - 1); - result = temp.serialize(buffer, size, max_size, bigEndian); + result = temp.serialize(buffer, size, maxSize, streamEndianness); } if (result != HasReturnvaluesIF::RETURN_OK) { return result; @@ -86,7 +86,7 @@ public: return result; } - uint32_t getSerializedSize() const { + size_t getSerializedSize() const override { //Analogous to serialize! uint32_t size = 1; //One for count iterator iter = this->begin(); @@ -115,8 +115,8 @@ public: return size; } - ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian) { + ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + SerializeIF::Endianness streamEndianness) override { return HasReturnvaluesIF::RETURN_OK; } diff --git a/globalfunctions/matching/RangeMatcher.h b/globalfunctions/matching/RangeMatcher.h index c30406f6..6fee1f52 100644 --- a/globalfunctions/matching/RangeMatcher.h +++ b/globalfunctions/matching/RangeMatcher.h @@ -26,23 +26,23 @@ public: } } - ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t max_size, + ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize, SerializeIF::Endianness streamEndianness) const override { ReturnValue_t result = SerializeAdapter::serialize(&lowerBound, buffer, - size, max_size, streamEndianness); + size, maxSize, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } result = SerializeAdapter::serialize(&upperBound, buffer, size, - max_size, streamEndianness); + maxSize, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - return SerializeAdapter::serialize(&inverted, buffer, size, max_size, + return SerializeAdapter::serialize(&inverted, buffer, size, maxSize, streamEndianness); } - uint32_t getSerializedSize() const override { + size_t getSerializedSize() const override { return sizeof(lowerBound) + sizeof(upperBound) + sizeof(bool); } diff --git a/health/HealthTable.cpp b/health/HealthTable.cpp index 48ee6679..bd6606db 100644 --- a/health/HealthTable.cpp +++ b/health/HealthTable.cpp @@ -63,21 +63,21 @@ bool HealthTable::hasHealth(object_id_t object) { return exits; } -void HealthTable::printAll(uint8_t* pointer, uint32_t maxSize) { +void HealthTable::printAll(uint8_t* pointer, size_t maxSize) { mutex->lockMutex(MutexIF::NO_TIMEOUT); - uint32_t size = 0; + size_t size = 0; uint16_t count = healthMap.size(); ReturnValue_t result = SerializeAdapter::serialize(&count, - &pointer, &size, maxSize, true); + &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, - &pointer, &size, maxSize, true); + &pointer, &size, maxSize, SerializeIF::Endianness::BIG); uint8_t health = iter->second; result = SerializeAdapter::serialize(&health, &pointer, &size, - maxSize, true); + maxSize, SerializeIF::Endianness::BIG); } mutex->unlockMutex(); } diff --git a/health/HealthTable.h b/health/HealthTable.h index 32a7eee2..2c74bda4 100644 --- a/health/HealthTable.h +++ b/health/HealthTable.h @@ -21,7 +21,7 @@ public: virtual HasHealthIF::HealthState getHealth(object_id_t); virtual uint32_t getPrintSize(); - virtual void printAll(uint8_t *pointer, uint32_t maxSize); + virtual void printAll(uint8_t *pointer, size_t maxSize); protected: MutexIF* mutex; diff --git a/monitoring/LimitViolationReporter.cpp b/monitoring/LimitViolationReporter.cpp index 760e8b93..489a8f9e 100644 --- a/monitoring/LimitViolationReporter.cpp +++ b/monitoring/LimitViolationReporter.cpp @@ -17,7 +17,7 @@ ReturnValue_t LimitViolationReporter::sendLimitViolationReport(const SerializeIF } store_address_t storeId; uint8_t* dataTarget = NULL; - uint32_t maxSize = data->getSerializedSize(); + size_t maxSize = data->getSerializedSize(); if (maxSize > MonitoringIF::VIOLATION_REPORT_MAX_SIZE) { return MonitoringIF::INVALID_SIZE; } @@ -26,8 +26,8 @@ ReturnValue_t LimitViolationReporter::sendLimitViolationReport(const SerializeIF if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - uint32_t size = 0; - result = data->serialize(&dataTarget, &size, maxSize, true); + size_t size = 0; + result = data->serialize(&dataTarget, &size, maxSize, SerializeIF::Endianness::BIG); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } diff --git a/osal/rtems/CpuUsage.cpp b/osal/rtems/CpuUsage.cpp index 903a4d0e..61b66c3d 100644 --- a/osal/rtems/CpuUsage.cpp +++ b/osal/rtems/CpuUsage.cpp @@ -89,15 +89,15 @@ void CpuUsage::clear() { threadData.clear(); } -ReturnValue_t CpuUsage::serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { +ReturnValue_t CpuUsage::serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const { ReturnValue_t result = SerializeAdapter::serialize( - &timeSinceLastReset, buffer, size, max_size, bigEndian); + &timeSinceLastReset, buffer, size, maxSize, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } return SerialArrayListAdapter::serialize(&threadData, buffer, - size, max_size, bigEndian); + size, maxSize, streamEndianness); } uint32_t CpuUsage::getSerializedSize() const { @@ -109,37 +109,37 @@ uint32_t CpuUsage::getSerializedSize() const { return size; } -ReturnValue_t CpuUsage::deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian) { +ReturnValue_t CpuUsage::deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) { ReturnValue_t result = SerializeAdapter::deSerialize( - &timeSinceLastReset, buffer, size, bigEndian); + &timeSinceLastReset, buffer, size, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } return SerialArrayListAdapter::deSerialize(&threadData, buffer, - size, bigEndian); + size, streamEndianness); } -ReturnValue_t CpuUsage::ThreadData::serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { +ReturnValue_t CpuUsage::ThreadData::serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const { ReturnValue_t result = SerializeAdapter::serialize(&id, buffer, - size, max_size, bigEndian); + size, maxSize, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - if (*size + MAX_LENGTH_OF_THREAD_NAME > max_size) { + if (*size + MAX_LENGTH_OF_THREAD_NAME > maxSize) { return BUFFER_TOO_SHORT; } memcpy(*buffer, name, MAX_LENGTH_OF_THREAD_NAME); *size += MAX_LENGTH_OF_THREAD_NAME; *buffer += MAX_LENGTH_OF_THREAD_NAME; result = SerializeAdapter::serialize(&timeRunning, - buffer, size, max_size, bigEndian); + buffer, size, maxSize, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } result = SerializeAdapter::serialize(&percentUsage, - buffer, size, max_size, bigEndian); + buffer, size, maxSize, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } @@ -158,9 +158,9 @@ uint32_t CpuUsage::ThreadData::getSerializedSize() const { } ReturnValue_t CpuUsage::ThreadData::deSerialize(const uint8_t** buffer, - int32_t* size, bool bigEndian) { + int32_t* size, Endianness streamEndianness) { ReturnValue_t result = SerializeAdapter::deSerialize(&id, buffer, - size, bigEndian); + size, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } @@ -170,12 +170,12 @@ ReturnValue_t CpuUsage::ThreadData::deSerialize(const uint8_t** buffer, memcpy(name, *buffer, MAX_LENGTH_OF_THREAD_NAME); *buffer -= MAX_LENGTH_OF_THREAD_NAME; result = SerializeAdapter::deSerialize(&timeRunning, - buffer, size, bigEndian); + buffer, size, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } result = SerializeAdapter::deSerialize(&percentUsage, - buffer, size, bigEndian); + buffer, size, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } diff --git a/osal/rtems/CpuUsage.h b/osal/rtems/CpuUsage.h index 3d317e4e..eb03c5e3 100644 --- a/osal/rtems/CpuUsage.h +++ b/osal/rtems/CpuUsage.h @@ -18,13 +18,13 @@ public: float timeRunning; float percentUsage; - virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const; + virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const override; - virtual uint32_t getSerializedSize() const; + virtual size_t getSerializedSize() const override; - virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian); + virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) override; }; CpuUsage(); @@ -41,13 +41,13 @@ public: void clear(); - virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const; + virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const override; - virtual uint32_t getSerializedSize() const; + virtual size_t getSerializedSize() const override; - virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian); + virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) override; }; #endif /* CPUUSAGE_H_ */ diff --git a/parameters/ParameterHelper.cpp b/parameters/ParameterHelper.cpp index 75b71a7e..725fa1d7 100644 --- a/parameters/ParameterHelper.cpp +++ b/parameters/ParameterHelper.cpp @@ -83,7 +83,7 @@ ReturnValue_t ParameterHelper::handleParameterMessage(CommandMessage *message) { ReturnValue_t ParameterHelper::sendParameter(MessageQueueId_t to, uint32_t id, const ParameterWrapper* description) { - uint32_t serializedSize = description->getSerializedSize(); + size_t serializedSize = description->getSerializedSize(); uint8_t *storeElement; store_address_t address; @@ -94,10 +94,10 @@ ReturnValue_t ParameterHelper::sendParameter(MessageQueueId_t to, uint32_t id, return result; } - uint32_t storeElementSize = 0; + size_t storeElementSize = 0; result = description->serialize(&storeElement, &storeElementSize, - serializedSize, true); + serializedSize, SerializeIF::Endianness::BIG); if (result != HasReturnvaluesIF::RETURN_OK) { storage->deleteData(address); diff --git a/parameters/ParameterWrapper.cpp b/parameters/ParameterWrapper.cpp index 9dcbc6d5..602ec361 100644 --- a/parameters/ParameterWrapper.cpp +++ b/parameters/ParameterWrapper.cpp @@ -2,41 +2,41 @@ ParameterWrapper::ParameterWrapper() : pointsToStream(false), type(Type::UNKNOWN_TYPE), rows(0), columns(0), data( - NULL), readonlyData(NULL) { + NULL), readonlyData(NULL) { } ParameterWrapper::ParameterWrapper(Type type, uint8_t rows, uint8_t columns, - void* data) : + void *data) : pointsToStream(false), type(type), rows(rows), columns(columns), data( data), readonlyData(data) { } ParameterWrapper::ParameterWrapper(Type type, uint8_t rows, uint8_t columns, - const void* data) : + const void *data) : pointsToStream(false), type(type), rows(rows), columns(columns), data( - NULL), readonlyData(data) { + NULL), readonlyData(data) { } ParameterWrapper::~ParameterWrapper() { } -ReturnValue_t ParameterWrapper::serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { +ReturnValue_t ParameterWrapper::serialize(uint8_t **buffer, size_t *size, + size_t maxSize, Endianness streamEndianness) const { ReturnValue_t result; - result = SerializeAdapter::serialize(&type, buffer, size, max_size, - bigEndian); + result = SerializeAdapter::serialize(&type, buffer, size, maxSize, + streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::serialize(&columns, buffer, size, - max_size, bigEndian); + result = SerializeAdapter::serialize(&columns, buffer, size, maxSize, + streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::serialize(&rows, buffer, size, max_size, - bigEndian); + result = SerializeAdapter::serialize(&rows, buffer, size, maxSize, + streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } @@ -47,28 +47,33 @@ ReturnValue_t ParameterWrapper::serialize(uint8_t** buffer, uint32_t* size, } switch (type) { case Type::UINT8_T: - result = serializeData(buffer, size, max_size, bigEndian); + result = serializeData(buffer, size, maxSize, + streamEndianness); break; case Type::INT8_T: - result = serializeData(buffer, size, max_size, bigEndian); + result = serializeData(buffer, size, maxSize, streamEndianness); break; case Type::UINT16_T: - result = serializeData(buffer, size, max_size, bigEndian); + result = serializeData(buffer, size, maxSize, + streamEndianness); break; case Type::INT16_T: - result = serializeData(buffer, size, max_size, bigEndian); + result = serializeData(buffer, size, maxSize, + streamEndianness); break; case Type::UINT32_T: - result = serializeData(buffer, size, max_size, bigEndian); + result = serializeData(buffer, size, maxSize, + streamEndianness); break; case Type::INT32_T: - result = serializeData(buffer, size, max_size, bigEndian); + result = serializeData(buffer, size, maxSize, + streamEndianness); break; case Type::FLOAT: - result = serializeData(buffer, size, max_size, bigEndian); + result = serializeData(buffer, size, maxSize, streamEndianness); break; case Type::DOUBLE: - result = serializeData(buffer, size, max_size, bigEndian); + result = serializeData(buffer, size, maxSize, streamEndianness); break; default: result = UNKNOW_DATATYPE; @@ -77,7 +82,7 @@ ReturnValue_t ParameterWrapper::serialize(uint8_t** buffer, uint32_t* size, return result; } -uint32_t ParameterWrapper::getSerializedSize() const { +size_t ParameterWrapper::getSerializedSize() const { uint32_t serializedSize = 0; serializedSize += type.getSerializedSize(); serializedSize += sizeof(rows); @@ -88,14 +93,14 @@ uint32_t ParameterWrapper::getSerializedSize() const { } template -ReturnValue_t ParameterWrapper::serializeData(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { +ReturnValue_t ParameterWrapper::serializeData(uint8_t **buffer, size_t *size, + size_t maxSize, Endianness streamEndianness) const { const T *element = (const T*) readonlyData; ReturnValue_t result; uint16_t dataSize = columns * rows; while (dataSize != 0) { - result = SerializeAdapter::serialize(element, buffer, size, max_size, - bigEndian); + result = SerializeAdapter::serialize(element, buffer, size, maxSize, + streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } @@ -111,21 +116,21 @@ ReturnValue_t ParameterWrapper::deSerializeData(uint8_t startingRow, uint8_t fromColumns) { //treat from as a continuous Stream as we copy all of it - const uint8_t *fromAsStream = (const uint8_t *) from; - int32_t streamSize = fromRows * fromColumns * sizeof(T); + const uint8_t *fromAsStream = (const uint8_t*) from; + size_t streamSize = fromRows * fromColumns * sizeof(T); ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; for (uint8_t fromRow = 0; fromRow < fromRows; fromRow++) { //get the start element of this row in data - T *dataWithDataType = ((T *) data) + T *dataWithDataType = ((T*) data) + (((startingRow + fromRow) * columns) + startingColumn); for (uint8_t fromColumn = 0; fromColumn < fromColumns; fromColumn++) { result = SerializeAdapter::deSerialize( dataWithDataType + fromColumn, &fromAsStream, &streamSize, - true); + SerializeIF::Endianness::BIG); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } @@ -136,13 +141,14 @@ ReturnValue_t ParameterWrapper::deSerializeData(uint8_t startingRow, } -ReturnValue_t ParameterWrapper::deSerialize(const uint8_t** buffer, - int32_t* size, bool bigEndian) { - return deSerialize(buffer, size, bigEndian, 0); +ReturnValue_t ParameterWrapper::deSerialize(const uint8_t **buffer, + size_t *size, Endianness streamEndianness) { + return deSerialize(buffer, size, streamEndianness, 0); } -ReturnValue_t ParameterWrapper::deSerialize(const uint8_t** buffer, - int32_t* size, bool bigEndian, uint16_t startWritingAtIndex) { +ReturnValue_t ParameterWrapper::deSerialize(const uint8_t **buffer, + size_t *size, Endianness streamEndianness, + uint16_t startWritingAtIndex) { ParameterWrapper streamDescription; ReturnValue_t result = streamDescription.set(*buffer, *size, buffer, size); @@ -153,26 +159,26 @@ ReturnValue_t ParameterWrapper::deSerialize(const uint8_t** buffer, return copyFrom(&streamDescription, startWritingAtIndex); } -ReturnValue_t ParameterWrapper::set(const uint8_t* stream, int32_t streamSize, - const uint8_t **remainingStream, int32_t *remainingSize) { +ReturnValue_t ParameterWrapper::set(const uint8_t *stream, size_t streamSize, + const uint8_t **remainingStream, size_t *remainingSize) { ReturnValue_t result = SerializeAdapter::deSerialize(&type, &stream, - &streamSize, true); + &streamSize, SerializeIF::Endianness::BIG); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - result = SerializeAdapter::deSerialize(&columns, &stream, - &streamSize, true); + result = SerializeAdapter::deSerialize(&columns, &stream, &streamSize, + SerializeIF::Endianness::BIG); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } result = SerializeAdapter::deSerialize(&rows, &stream, &streamSize, - true); + SerializeIF::Endianness::BIG); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - int32_t dataSize = type.getSize() * rows * columns; + size_t dataSize = type.getSize() * rows * columns; if (streamSize < dataSize) { return SerializeIF::STREAM_TOO_SHORT; @@ -194,7 +200,7 @@ ReturnValue_t ParameterWrapper::set(const uint8_t* stream, int32_t streamSize, return HasReturnvaluesIF::RETURN_OK; } -ReturnValue_t ParameterWrapper::copyFrom(const ParameterWrapper* from, +ReturnValue_t ParameterWrapper::copyFrom(const ParameterWrapper *from, uint16_t startWritingAtIndex) { if (data == NULL) { return READONLY; @@ -261,7 +267,7 @@ ReturnValue_t ParameterWrapper::copyFrom(const ParameterWrapper* from, } } else { //need a type to do arithmetic - uint8_t *toDataWithType = (uint8_t *) data; + uint8_t *toDataWithType = (uint8_t*) data; for (uint8_t fromRow = 0; fromRow < from->rows; fromRow++) { memcpy( toDataWithType diff --git a/parameters/ParameterWrapper.h b/parameters/ParameterWrapper.h index e6d29c59..a00c997c 100644 --- a/parameters/ParameterWrapper.h +++ b/parameters/ParameterWrapper.h @@ -25,16 +25,16 @@ public: const void *data); virtual ~ParameterWrapper(); - virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const; + virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const override; - virtual uint32_t getSerializedSize() const; + virtual size_t getSerializedSize() const override; - virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian); + virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) override; - virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian, uint16_t startWritingAtIndex = 0); + virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness, uint16_t startWritingAtIndex = 0); template ReturnValue_t getElement(T *value, uint8_t row = 0, uint8_t column = 0) const { @@ -111,8 +111,8 @@ public: void setMatrix(const T& member) { this->set(member[0], sizeof(member)/sizeof(member[0]), sizeof(member[0])/sizeof(member[0][0])); } - ReturnValue_t set(const uint8_t *stream, int32_t streamSize, - const uint8_t **remainingStream = NULL, int32_t *remainingSize = + ReturnValue_t set(const uint8_t *stream, size_t streamSize, + const uint8_t **remainingStream = NULL, size_t *remainingSize = NULL); ReturnValue_t copyFrom(const ParameterWrapper *from, @@ -128,8 +128,8 @@ private: const void *readonlyData; template - ReturnValue_t serializeData(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const; + ReturnValue_t serializeData(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const; template ReturnValue_t deSerializeData(uint8_t startingRow, uint8_t startingColumn, diff --git a/power/Fuse.cpp b/power/Fuse.cpp index dd5d3e3f..db24100b 100644 --- a/power/Fuse.cpp +++ b/power/Fuse.cpp @@ -86,12 +86,12 @@ ReturnValue_t Fuse::check() { return result; } -ReturnValue_t Fuse::serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { +ReturnValue_t Fuse::serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const { ReturnValue_t result = RETURN_FAILED; for (DeviceList::const_iterator iter = devices.begin(); iter != devices.end(); iter++) { - result = (*iter)->serialize(buffer, size, max_size, bigEndian); + result = (*iter)->serialize(buffer, size, maxSize, streamEndianness); if (result != RETURN_OK) { return result; } @@ -99,7 +99,7 @@ ReturnValue_t Fuse::serialize(uint8_t** buffer, uint32_t* size, return RETURN_OK; } -uint32_t Fuse::getSerializedSize() const { +size_t Fuse::getSerializedSize() const { uint32_t size = 0; for (DeviceList::const_iterator iter = devices.begin(); iter != devices.end(); iter++) { @@ -108,12 +108,12 @@ uint32_t Fuse::getSerializedSize() const { return size; } -ReturnValue_t Fuse::deSerialize(const uint8_t** buffer, int32_t* size, -bool bigEndian) { +ReturnValue_t Fuse::deSerialize(const uint8_t** buffer, size_t* size, +Endianness streamEndianness) { ReturnValue_t result = RETURN_FAILED; for (DeviceList::iterator iter = devices.begin(); iter != devices.end(); iter++) { - result = (*iter)->deSerialize(buffer, size, bigEndian); + result = (*iter)->deSerialize(buffer, size, streamEndianness); if (result != RETURN_OK) { return result; } diff --git a/power/Fuse.h b/power/Fuse.h index 6da24178..4e22e3ed 100644 --- a/power/Fuse.h +++ b/power/Fuse.h @@ -11,14 +11,15 @@ #include #include -namespace Factory{ +namespace Factory { void setStaticFrameworkObjectIds(); } class Fuse: public SystemObject, public HasHealthIF, public HasReturnvaluesIF, - public ReceivesParameterMessagesIF { + public ReceivesParameterMessagesIF, + public SerializeIF { friend void (Factory::setStaticFrameworkObjectIds)(); private: static constexpr float RESIDUAL_POWER = 0.005 * 28.5; //!< This is the upper limit of residual power lost by fuses and switches. Worst case is Fuse and one of two switches on. See PCDU ICD 1.9 p29 bottom @@ -40,7 +41,7 @@ public: Fuse(object_id_t fuseObjectId, uint8_t fuseId, VariableIds ids, float maxCurrent, uint16_t confirmationCount = 2); virtual ~Fuse(); - void addDevice(PowerComponentIF* set); + void addDevice(PowerComponentIF *set); float getPower(); bool isPowerValid(); @@ -49,11 +50,11 @@ public: uint8_t getFuseId() const; ReturnValue_t initialize(); DeviceList devices; - ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const; - uint32_t getSerializedSize() const; - ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian); + ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize, + SerializeIF::Endianness streamEndianness) const override; + size_t getSerializedSize() const override; + ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size, + SerializeIF::Endianness streamEndianness) override; void setAllMonitorsToUnchecked(); ReturnValue_t performOperation(uint8_t opCode); MessageQueueId_t getCommandQueue() const; @@ -62,13 +63,13 @@ public: HasHealthIF::HealthState getHealth(); ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId, - ParameterWrapper *parameterWrapper, - const ParameterWrapper *newValues, uint16_t startAtIndex); + ParameterWrapper *parameterWrapper, + const ParameterWrapper *newValues, uint16_t startAtIndex); private: uint8_t oldFuseState; uint8_t fuseId; - PowerSwitchIF* powerIF; //could be static in our case. + PowerSwitchIF *powerIF; //could be static in our case. AbsLimitMonitor currentLimit; class PowerMonitor: public MonitorReporter { public: @@ -88,11 +89,11 @@ private: PIDReader current; PIDReader state; db_float_t power; - MessageQueueIF* commandQueue; + MessageQueueIF *commandQueue; ParameterHelper parameterHelper; HealthHelper healthHelper; static object_id_t powerSwitchId; - void calculatePowerLimits(float* low, float* high); + void calculatePowerLimits(float *low, float *high); void calculateFusePower(); void checkFuseState(); void reportEvents(Event event); diff --git a/power/PowerComponent.cpp b/power/PowerComponent.cpp index 53bb06c8..cd116a86 100644 --- a/power/PowerComponent.cpp +++ b/power/PowerComponent.cpp @@ -17,18 +17,18 @@ PowerComponent::PowerComponent(object_id_t setId, uint8_t moduleId, float min, f twoSwitches), min(min), max(max), moduleId(moduleId) { } -ReturnValue_t PowerComponent::serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { +ReturnValue_t PowerComponent::serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const { ReturnValue_t result = SerializeAdapter::serialize(&min, buffer, - size, max_size, bigEndian); + size, maxSize, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - return SerializeAdapter::serialize(&max, buffer, size, max_size, - bigEndian); + return SerializeAdapter::serialize(&max, buffer, size, maxSize, + streamEndianness); } -uint32_t PowerComponent::getSerializedSize() const { +size_t PowerComponent::getSerializedSize() const { return sizeof(min) + sizeof(max); } @@ -56,14 +56,14 @@ float PowerComponent::getMax() { return max; } -ReturnValue_t PowerComponent::deSerialize(const uint8_t** buffer, int32_t* size, -bool bigEndian) { +ReturnValue_t PowerComponent::deSerialize(const uint8_t** buffer, size_t* size, +Endianness streamEndianness) { ReturnValue_t result = SerializeAdapter::deSerialize(&min, buffer, - size, bigEndian); + size, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - return SerializeAdapter::deSerialize(&max, buffer, size, bigEndian); + return SerializeAdapter::deSerialize(&max, buffer, size, streamEndianness); } ReturnValue_t PowerComponent::getParameter(uint8_t domainId, diff --git a/power/PowerComponent.h b/power/PowerComponent.h index a82fe1d7..61ab3674 100644 --- a/power/PowerComponent.h +++ b/power/PowerComponent.h @@ -19,13 +19,13 @@ public: float getMin(); float getMax(); - ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const; + ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const override; - uint32_t getSerializedSize() const; + size_t getSerializedSize() const override; - ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian); + ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) override; ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId, ParameterWrapper *parameterWrapper, diff --git a/serialize/SerialArrayListAdapter.h b/serialize/SerialArrayListAdapter.h index ab0c6c6f..bcd99818 100644 --- a/serialize/SerialArrayListAdapter.h +++ b/serialize/SerialArrayListAdapter.h @@ -20,25 +20,25 @@ public: SerialArrayListAdapter(ArrayList *adaptee) : adaptee(adaptee) { } - virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { - return serialize(adaptee, buffer, size, max_size, bigEndian); + virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const { + return serialize(adaptee, buffer, size, maxSize, streamEndianness); } - static ReturnValue_t serialize(const ArrayList* list, uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) { + static ReturnValue_t serialize(const ArrayList* list, uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) { ReturnValue_t result = SerializeAdapter::serialize(&list->size, - buffer, size, max_size, bigEndian); + buffer, size, maxSize, streamEndianness); count_t i = 0; while ((result == HasReturnvaluesIF::RETURN_OK) && (i < list->size)) { result = SerializeAdapter::serialize(&list->entries[i], buffer, size, - max_size, bigEndian); + maxSize, streamEndianness); ++i; } return result; } - virtual uint32_t getSerializedSize() const { + virtual size_t getSerializedSize() const { return getSerializedSize(adaptee); } @@ -53,16 +53,16 @@ public: return printSize; } - virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian) { - return deSerialize(adaptee, buffer, size, bigEndian); + virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) { + return deSerialize(adaptee, buffer, size, streamEndianness); } - static ReturnValue_t deSerialize(ArrayList* list, const uint8_t** buffer, int32_t* size, - bool bigEndian) { + static ReturnValue_t deSerialize(ArrayList* list, const uint8_t** buffer, size_t* size, + Endianness streamEndianness) { count_t tempSize = 0; ReturnValue_t result = SerializeAdapter::deSerialize(&tempSize, - buffer, size, bigEndian); + buffer, size, streamEndianness); if (tempSize > list->maxSize()) { return SerializeIF::TOO_MANY_ELEMENTS; } @@ -71,7 +71,7 @@ public: while ((result == HasReturnvaluesIF::RETURN_OK) && (i < list->size)) { result = SerializeAdapter::deSerialize( &list->front()[i], buffer, size, - bigEndian); + streamEndianness); ++i; } return result; diff --git a/serialize/SerialBufferAdapter.cpp b/serialize/SerialBufferAdapter.cpp index f78ec8ac..d4d8d1c7 100644 --- a/serialize/SerialBufferAdapter.cpp +++ b/serialize/SerialBufferAdapter.cpp @@ -22,19 +22,19 @@ SerialBufferAdapter::~SerialBufferAdapter() { } template -ReturnValue_t SerialBufferAdapter::serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { +ReturnValue_t SerialBufferAdapter::serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const { uint32_t serializedLength = bufferLength; if (serializeLength) { serializedLength += SerializeAdapter::getSerializedSize( &bufferLength); } - if (*size + serializedLength > max_size) { + if (*size + serializedLength > maxSize) { return BUFFER_TOO_SHORT; } else { if (serializeLength) { SerializeAdapter::serialize(&bufferLength, buffer, size, - max_size, bigEndian); + maxSize, streamEndianness); } if (this->constBuffer != NULL) { memcpy(*buffer, this->constBuffer, bufferLength); @@ -50,7 +50,7 @@ ReturnValue_t SerialBufferAdapter::serialize(uint8_t** buffer, uint32_t* size } template -uint32_t SerialBufferAdapter::getSerializedSize() const { +size_t SerialBufferAdapter::getSerializedSize() const { if (serializeLength) { return bufferLength + SerializeAdapter::getSerializedSize(&bufferLength); } else { @@ -59,7 +59,7 @@ uint32_t SerialBufferAdapter::getSerializedSize() const { } template ReturnValue_t SerialBufferAdapter::deSerialize(const uint8_t** buffer, - int32_t* size, bool bigEndian) { + size_t* size, Endianness streamEndianness) { //TODO Ignores Endian flag! if (buffer != NULL) { if(serializeLength){ diff --git a/serialize/SerialBufferAdapter.h b/serialize/SerialBufferAdapter.h index 7cd75d55..78d42b80 100644 --- a/serialize/SerialBufferAdapter.h +++ b/serialize/SerialBufferAdapter.h @@ -16,13 +16,13 @@ public: virtual ~SerialBufferAdapter(); - virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const; + virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const override; - virtual uint32_t getSerializedSize() const; + virtual size_t getSerializedSize() const override; - virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian); + virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) override; private: bool serializeLength; const uint8_t *constBuffer; diff --git a/serialize/SerialFixedArrayListAdapter.h b/serialize/SerialFixedArrayListAdapter.h index 16919b62..a2e683bf 100644 --- a/serialize/SerialFixedArrayListAdapter.h +++ b/serialize/SerialFixedArrayListAdapter.h @@ -13,16 +13,16 @@ public: template SerialFixedArrayListAdapter(Args... args) : FixedArrayList(std::forward(args)...) { } - ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { - return SerialArrayListAdapter::serialize(this, buffer, size, max_size, bigEndian); + ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const { + return SerialArrayListAdapter::serialize(this, buffer, size, maxSize, streamEndianness); } - uint32_t getSerializedSize() const { + size_t getSerializedSize() const { return SerialArrayListAdapter::getSerializedSize(this); } - ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian) { - return SerialArrayListAdapter::deSerialize(this, buffer, size, bigEndian); + ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) { + return SerialArrayListAdapter::deSerialize(this, buffer, size, streamEndianness); } }; diff --git a/serialize/SerializeElement.h b/serialize/SerializeElement.h index 22e9838c..3941e9fb 100644 --- a/serialize/SerializeElement.h +++ b/serialize/SerializeElement.h @@ -26,7 +26,7 @@ public: streamEndianness); } - uint32_t getSerializedSize() const override { + size_t getSerializedSize() const override { return SerializeAdapter::getSerializedSize(&entry); } diff --git a/serialize/SerializeIF.h b/serialize/SerializeIF.h index 6c875a5c..14244a7a 100644 --- a/serialize/SerializeIF.h +++ b/serialize/SerializeIF.h @@ -28,7 +28,7 @@ public: } virtual ReturnValue_t serialize(uint8_t **buffer, size_t *size, - size_t max_size, Endianness streamEndianness) const = 0; + size_t maxSize, Endianness streamEndianness) const = 0; virtual size_t getSerializedSize() const = 0; diff --git a/subsystem/Subsystem.cpp b/subsystem/Subsystem.cpp index ef706dd7..2e8a325a 100644 --- a/subsystem/Subsystem.cpp +++ b/subsystem/Subsystem.cpp @@ -13,7 +13,7 @@ Subsystem::Subsystem(object_id_t setObjectId, object_id_t parent, false), uptimeStartTable(0), currentTargetTable(), targetMode( 0), targetSubmode(SUBMODE_NONE), initialMode(0), currentSequenceIterator(), modeTables( maxNumberOfTables), modeSequences(maxNumberOfSequences), IPCStore( - NULL) + NULL) #ifdef USE_MODESTORE ,modeStore(NULL) #endif @@ -75,7 +75,8 @@ void Subsystem::performChildOperation() { if (isInTransition) { if (commandsOutstanding <= 0) { //all children of the current table were commanded and replied if (currentSequenceIterator.value == NULL) { //we're through with this sequence - if (checkStateAgainstTable(currentTargetTable, targetSubmode) == RETURN_OK) { + if (checkStateAgainstTable(currentTargetTable, targetSubmode) + == RETURN_OK) { setMode(targetMode, targetSubmode); isInTransition = false; return; @@ -86,7 +87,8 @@ void Subsystem::performChildOperation() { } } if (currentSequenceIterator->checkSuccess()) { - if (checkStateAgainstTable(getCurrentTable(), targetSubmode) != RETURN_OK) { + if (checkStateAgainstTable(getCurrentTable(), targetSubmode) + != RETURN_OK) { transitionFailed(TABLE_CHECK_FAILED, currentSequenceIterator->getTableId()); return; @@ -117,7 +119,8 @@ void Subsystem::performChildOperation() { childrenChangedHealth = false; startTransition(mode, submode); } else if (childrenChangedMode) { - if (checkStateAgainstTable(currentTargetTable, submode) != RETURN_OK) { + if (checkStateAgainstTable(currentTargetTable, submode) + != RETURN_OK) { triggerEvent(CANT_KEEP_MODE, mode, submode); cantKeepMode(); } @@ -147,7 +150,7 @@ HybridIterator Subsystem::getTable(Mode_t id) { } } -ReturnValue_t Subsystem::handleCommandMessage(CommandMessage* message) { +ReturnValue_t Subsystem::handleCommandMessage(CommandMessage *message) { ReturnValue_t result; switch (message->getCommand()) { case HealthMessage::HEALTH_INFO: { @@ -168,12 +171,13 @@ ReturnValue_t Subsystem::handleCommandMessage(CommandMessage* message) { &sizeRead); if (result == RETURN_OK) { Mode_t fallbackId; - int32_t size = sizeRead; - result = SerializeAdapter::deSerialize(&fallbackId, - &pointer, &size, true); + size_t size = sizeRead; + result = SerializeAdapter::deSerialize(&fallbackId, &pointer, &size, + SerializeIF::Endianness::BIG); if (result == RETURN_OK) { result = SerialArrayListAdapter::deSerialize( - &sequence, &pointer, &size, true); + &sequence, &pointer, &size, + SerializeIF::Endianness::BIG); if (result == RETURN_OK) { result = addSequence(&sequence, ModeSequenceMessage::getSequenceId(message), @@ -193,9 +197,9 @@ ReturnValue_t Subsystem::handleCommandMessage(CommandMessage* message) { ModeSequenceMessage::getStoreAddress(message), &pointer, &sizeRead); if (result == RETURN_OK) { - int32_t size = sizeRead; + size_t size = sizeRead; result = SerialArrayListAdapter::deSerialize(&table, - &pointer, &size, true); + &pointer, &size, SerializeIF::Endianness::BIG); if (result == RETURN_OK) { result = addTable(&table, ModeSequenceMessage::getSequenceId(message)); @@ -339,7 +343,7 @@ void Subsystem::replyToCommand(ReturnValue_t status, uint32_t parameter) { } } -ReturnValue_t Subsystem::addSequence(ArrayList* sequence, +ReturnValue_t Subsystem::addSequence(ArrayList *sequence, Mode_t id, Mode_t fallbackSequence, bool inStore, bool preInit) { ReturnValue_t result; @@ -507,7 +511,7 @@ MessageQueueId_t Subsystem::getSequenceCommandQueue() const { } ReturnValue_t Subsystem::checkModeCommand(Mode_t mode, Submode_t submode, - uint32_t* msToReachTheMode) { + uint32_t *msToReachTheMode) { //Need to accept all submodes to be able to inherit submodes // if (submode != SUBMODE_NONE) { // return INVALID_SUBMODE; @@ -599,15 +603,15 @@ void Subsystem::transitionFailed(ReturnValue_t failureCode, } void Subsystem::sendSerializablesAsCommandMessage(Command_t command, - SerializeIF** elements, uint8_t count) { + SerializeIF **elements, uint8_t count) { ReturnValue_t result; - uint32_t maxSize = 0; + size_t maxSize = 0; for (uint8_t i = 0; i < count; i++) { maxSize += elements[i]->getSerializedSize(); } uint8_t *storeBuffer; store_address_t address; - uint32_t size = 0; + size_t size = 0; result = IPCStore->getFreeElement(&address, maxSize, &storeBuffer); if (result != HasReturnvaluesIF::RETURN_OK) { @@ -615,7 +619,8 @@ void Subsystem::sendSerializablesAsCommandMessage(Command_t command, return; } for (uint8_t i = 0; i < count; i++) { - elements[i]->serialize(&storeBuffer, &size, maxSize, true); + elements[i]->serialize(&storeBuffer, &size, maxSize, + SerializeIF::Endianness::BIG); } CommandMessage reply; ModeSequenceMessage::setModeSequenceMessage(&reply, command, address); diff --git a/subsystem/modes/ModeDefinitions.h b/subsystem/modes/ModeDefinitions.h index 3e749dd8..153710af 100644 --- a/subsystem/modes/ModeDefinitions.h +++ b/subsystem/modes/ModeDefinitions.h @@ -18,65 +18,65 @@ public: uint8_t value3; uint8_t value4; - virtual ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { + virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const { ReturnValue_t result; result = SerializeAdapter::serialize(&value1, buffer, size, - max_size, bigEndian); + maxSize, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } result = SerializeAdapter::serialize(&value2, buffer, size, - max_size, bigEndian); + maxSize, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } result = SerializeAdapter::serialize(&value3, buffer, size, - max_size, bigEndian); + maxSize, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } result = SerializeAdapter::serialize(&value4, buffer, size, - max_size, bigEndian); + maxSize, streamEndianness); return result; } - virtual uint32_t getSerializedSize() const { + virtual size_t getSerializedSize() const { return sizeof(value1) + sizeof(value2) + sizeof(value3) + sizeof(value4); } - virtual ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian) { + virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) { ReturnValue_t result; result = SerializeAdapter::deSerialize(&value1, buffer, size, - bigEndian); + streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } result = SerializeAdapter::deSerialize(&value2, buffer, size, - bigEndian); + streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } result = SerializeAdapter::deSerialize(&value3, buffer, size, - bigEndian); + streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } result = SerializeAdapter::deSerialize(&value4, buffer, size, - bigEndian); + streamEndianness); return result; } diff --git a/thermal/ThermalComponent.cpp b/thermal/ThermalComponent.cpp index 93513e16..5dcd0bc6 100644 --- a/thermal/ThermalComponent.cpp +++ b/thermal/ThermalComponent.cpp @@ -46,15 +46,15 @@ ReturnValue_t ThermalComponent::setLimits(const uint8_t* data, uint32_t size) { if (size != 4 * sizeof(parameters.lowerOpLimit)) { return MonitoringIF::INVALID_SIZE; } - int32_t readSize = size; + size_t readSize = size; SerializeAdapter::deSerialize(&nopParameters.lowerNopLimit, &data, - &readSize, true); + &readSize, SerializeIF::Endianness::BIG); SerializeAdapter::deSerialize(¶meters.lowerOpLimit, &data, - &readSize, true); + &readSize, SerializeIF::Endianness::BIG); SerializeAdapter::deSerialize(¶meters.upperOpLimit, &data, - &readSize, true); + &readSize, SerializeIF::Endianness::BIG); SerializeAdapter::deSerialize(&nopParameters.upperNopLimit, &data, - &readSize, true); + &readSize, SerializeIF::Endianness::BIG); return HasReturnvaluesIF::RETURN_OK; } diff --git a/tmstorage/TmStorePackets.h b/tmstorage/TmStorePackets.h index 4e7160fb..16768e68 100644 --- a/tmstorage/TmStorePackets.h +++ b/tmstorage/TmStorePackets.h @@ -32,31 +32,31 @@ public: } uint16_t apid; uint16_t ssc; - ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { + ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const { ReturnValue_t result = SerializeAdapter::serialize(&apid, - buffer, size, max_size, bigEndian); + buffer, size, maxSize, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } return SerializeAdapter::serialize(&ssc, buffer, size, - max_size, bigEndian); + maxSize, streamEndianness); } - uint32_t getSerializedSize() const { + size_t getSerializedSize() const { return sizeof(apid) + sizeof(ssc); } - ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian) { + ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) { ReturnValue_t result = SerializeAdapter::deSerialize(&apid, - buffer, size, bigEndian); + buffer, size, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } return SerializeAdapter::deSerialize(&ssc, buffer, size, - bigEndian); + streamEndianness); } }; @@ -218,33 +218,33 @@ public: } - ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { - ReturnValue_t result = SerializeAdapter::serialize(&apid,buffer,size,max_size,bigEndian); + ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const { + ReturnValue_t result = SerializeAdapter::serialize(&apid,buffer,size,maxSize,streamEndianness); if(result!=HasReturnvaluesIF::RETURN_OK){ return result; } - result = SerializeAdapter::serialize(&sourceSequenceCount,buffer,size,max_size,bigEndian); + result = SerializeAdapter::serialize(&sourceSequenceCount,buffer,size,maxSize,streamEndianness); if(result!=HasReturnvaluesIF::RETURN_OK){ return result; } - result = SerializeAdapter::serialize(&serviceType,buffer,size,max_size,bigEndian); + result = SerializeAdapter::serialize(&serviceType,buffer,size,maxSize,streamEndianness); if(result!=HasReturnvaluesIF::RETURN_OK){ return result; } - result = SerializeAdapter::serialize(&serviceSubtype,buffer,size,max_size,bigEndian); + result = SerializeAdapter::serialize(&serviceSubtype,buffer,size,maxSize,streamEndianness); if(result!=HasReturnvaluesIF::RETURN_OK){ return result; } - result = SerializeAdapter::serialize(&subCounter,buffer,size,max_size,bigEndian); + result = SerializeAdapter::serialize(&subCounter,buffer,size,maxSize,streamEndianness); if(result!=HasReturnvaluesIF::RETURN_OK){ return result; } SerialBufferAdapter adapter(rawTimestamp,sizeof(rawTimestamp)); - return adapter.serialize(buffer,size,max_size,bigEndian); + return adapter.serialize(buffer,size,maxSize,streamEndianness); } - uint32_t getSerializedSize() const { + size_t getSerializedSize() const { uint32_t size = 0; size += SerializeAdapter::getSerializedSize(&apid); size += SerializeAdapter::getSerializedSize(&sourceSequenceCount); @@ -257,35 +257,35 @@ public: }; - ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian) { + ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) { ReturnValue_t result = SerializeAdapter::deSerialize(&apid, buffer, - size, bigEndian); + size, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } result = SerializeAdapter::deSerialize(&sourceSequenceCount, buffer, - size, bigEndian); + size, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } result = SerializeAdapter::deSerialize(&serviceType, buffer, size, - bigEndian); + streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } result = SerializeAdapter::deSerialize(&serviceSubtype, buffer, - size, bigEndian); + size, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } result = SerializeAdapter::deSerialize(&subCounter, buffer, size, - bigEndian); + streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } SerialBufferAdapter adapter(rawTimestamp,sizeof(rawTimestamp)); - return adapter.deSerialize(buffer,size,bigEndian); + return adapter.deSerialize(buffer,size,streamEndianness); } private: diff --git a/tmtcpacket/packetmatcher/ApidMatcher.h b/tmtcpacket/packetmatcher/ApidMatcher.h index d5d96f2d..3080ffef 100644 --- a/tmtcpacket/packetmatcher/ApidMatcher.h +++ b/tmtcpacket/packetmatcher/ApidMatcher.h @@ -22,16 +22,16 @@ public: return false; } } - ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { - return SerializeAdapter::serialize(&apid, buffer, size, max_size, bigEndian); + ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const { + return SerializeAdapter::serialize(&apid, buffer, size, maxSize, streamEndianness); } - uint32_t getSerializedSize() const { + size_t getSerializedSize() const { return SerializeAdapter::getSerializedSize(&apid); } - ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian) { - return SerializeAdapter::deSerialize(&apid, buffer, size, bigEndian); + ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) { + return SerializeAdapter::deSerialize(&apid, buffer, size, streamEndianness); } }; diff --git a/tmtcpacket/packetmatcher/ServiceMatcher.h b/tmtcpacket/packetmatcher/ServiceMatcher.h index b0623780..f6e9e360 100644 --- a/tmtcpacket/packetmatcher/ServiceMatcher.h +++ b/tmtcpacket/packetmatcher/ServiceMatcher.h @@ -22,16 +22,16 @@ public: return false; } } - ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { - return SerializeAdapter::serialize(&service, buffer, size, max_size, bigEndian); + ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const { + return SerializeAdapter::serialize(&service, buffer, size, maxSize, streamEndianness); } - uint32_t getSerializedSize() const { + size_t getSerializedSize() const { return SerializeAdapter::getSerializedSize(&service); } - ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian) { - return SerializeAdapter::deSerialize(&service, buffer, size, bigEndian); + ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) { + return SerializeAdapter::deSerialize(&service, buffer, size, streamEndianness); } }; diff --git a/tmtcpacket/packetmatcher/SubserviceMatcher.h b/tmtcpacket/packetmatcher/SubserviceMatcher.h index 90370af1..2e8b82b2 100644 --- a/tmtcpacket/packetmatcher/SubserviceMatcher.h +++ b/tmtcpacket/packetmatcher/SubserviceMatcher.h @@ -20,16 +20,16 @@ public: return false; } } - ReturnValue_t serialize(uint8_t** buffer, uint32_t* size, - const uint32_t max_size, bool bigEndian) const { - return SerializeAdapter::serialize(&subService, buffer, size, max_size, bigEndian); + ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const { + return SerializeAdapter::serialize(&subService, buffer, size, maxSize, streamEndianness); } - uint32_t getSerializedSize() const { + size_t getSerializedSize() const { return SerializeAdapter::getSerializedSize(&subService); } - ReturnValue_t deSerialize(const uint8_t** buffer, int32_t* size, - bool bigEndian) { - return SerializeAdapter::deSerialize(&subService, buffer, size, bigEndian); + ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) { + return SerializeAdapter::deSerialize(&subService, buffer, size, streamEndianness); } private: uint8_t subService; diff --git a/tmtcpacket/pus/TmPacketStored.cpp b/tmtcpacket/pus/TmPacketStored.cpp index f2c1eb28..32f9c431 100644 --- a/tmtcpacket/pus/TmPacketStored.cpp +++ b/tmtcpacket/pus/TmPacketStored.cpp @@ -10,14 +10,14 @@ TmPacketStored::TmPacketStored(store_address_t setAddress) : } TmPacketStored::TmPacketStored(uint16_t apid, uint8_t service, - uint8_t subservice, uint8_t packetSubcounter, const uint8_t* data, - uint32_t size, const uint8_t* headerData, uint32_t headerSize) : + uint8_t subservice, uint8_t packetSubcounter, const uint8_t *data, + uint32_t size, const uint8_t *headerData, uint32_t headerSize) : TmPacketBase(NULL) { storeAddress.raw = StorageManagerIF::INVALID_ADDRESS; if (!checkAndSetStore()) { return; } - uint8_t* pData = NULL; + uint8_t *pData = NULL; ReturnValue_t returnValue = store->getFreeElement(&storeAddress, (TmPacketBase::TM_PACKET_MIN_SIZE + size + headerSize), &pData); @@ -34,21 +34,21 @@ TmPacketStored::TmPacketStored(uint16_t apid, uint8_t service, } TmPacketStored::TmPacketStored(uint16_t apid, uint8_t service, - uint8_t subservice, uint8_t packetSubcounter, SerializeIF* content, - SerializeIF* header) : + uint8_t subservice, uint8_t packetSubcounter, SerializeIF *content, + SerializeIF *header) : TmPacketBase(NULL) { storeAddress.raw = StorageManagerIF::INVALID_ADDRESS; if (!checkAndSetStore()) { return; } - uint32_t sourceDataSize = 0; + size_t sourceDataSize = 0; if (content != NULL) { sourceDataSize += content->getSerializedSize(); } if (header != NULL) { sourceDataSize += header->getSerializedSize(); } - uint8_t* p_data = NULL; + uint8_t *p_data = NULL; ReturnValue_t returnValue = store->getFreeElement(&storeAddress, (TmPacketBase::TM_PACKET_MIN_SIZE + sourceDataSize), &p_data); if (returnValue != store->RETURN_OK) { @@ -56,13 +56,15 @@ TmPacketStored::TmPacketStored(uint16_t apid, uint8_t service, } setData(p_data); initializeTmPacket(apid, service, subservice, packetSubcounter); - uint8_t* putDataHere = getSourceData(); - uint32_t size = 0; + uint8_t *putDataHere = getSourceData(); + size_t size = 0; if (header != NULL) { - header->serialize(&putDataHere, &size, sourceDataSize, true); + header->serialize(&putDataHere, &size, sourceDataSize, + SerializeIF::Endianness::BIG); } if (content != NULL) { - content->serialize(&putDataHere, &size, sourceDataSize, true); + content->serialize(&putDataHere, &size, sourceDataSize, + SerializeIF::Endianness::BIG); } setPacketDataLength( sourceDataSize + sizeof(PUSTmDataFieldHeader) + CRC_SIZE - 1); @@ -80,7 +82,7 @@ void TmPacketStored::deletePacket() { void TmPacketStored::setStoreAddress(store_address_t setAddress) { storeAddress = setAddress; - const uint8_t* temp_data = NULL; + const uint8_t *temp_data = NULL; uint32_t temp_size; if (!checkAndSetStore()) { return; @@ -106,8 +108,8 @@ bool TmPacketStored::checkAndSetStore() { return true; } -StorageManagerIF* TmPacketStored::store = NULL; -InternalErrorReporterIF* TmPacketStored::internalErrorReporter = NULL; +StorageManagerIF *TmPacketStored::store = NULL; +InternalErrorReporterIF *TmPacketStored::internalErrorReporter = NULL; ReturnValue_t TmPacketStored::sendPacket(MessageQueueId_t destination, MessageQueueId_t sentFrom, bool doErrorReporting) { @@ -116,7 +118,8 @@ ReturnValue_t TmPacketStored::sendPacket(MessageQueueId_t destination, return HasReturnvaluesIF::RETURN_FAILED; } TmTcMessage tmMessage(getStoreAddress()); - ReturnValue_t result = MessageQueueSenderIF::sendMessage(destination, &tmMessage, sentFrom); + ReturnValue_t result = MessageQueueSenderIF::sendMessage(destination, + &tmMessage, sentFrom); if (result != HasReturnvaluesIF::RETURN_OK) { deletePacket(); if (doErrorReporting) { diff --git a/tmtcservices/CommandingServiceBase.cpp b/tmtcservices/CommandingServiceBase.cpp index 5b9e7b68..aa41f334 100644 --- a/tmtcservices/CommandingServiceBase.cpp +++ b/tmtcservices/CommandingServiceBase.cpp @@ -235,9 +235,9 @@ void CommandingServiceBase::sendTmPacket(uint8_t subservice, object_id_t objectId, const uint8_t *data, uint32_t dataLen) { uint8_t buffer[sizeof(object_id_t)]; uint8_t* pBuffer = buffer; - uint32_t size = 0; + size_t size = 0; SerializeAdapter::serialize(&objectId, &pBuffer, &size, - sizeof(object_id_t), true); + sizeof(object_id_t), SerializeIF::Endianness::BIG); TmPacketStored tmPacketStored(this->apid, this->service, subservice, this->tmPacketCounter, data, dataLen, buffer, size); ReturnValue_t result = tmPacketStored.sendPacket( diff --git a/tmtcservices/PusVerificationReport.cpp b/tmtcservices/PusVerificationReport.cpp index e1dad2be..07631801 100644 --- a/tmtcservices/PusVerificationReport.cpp +++ b/tmtcservices/PusVerificationReport.cpp @@ -33,7 +33,7 @@ PusVerificationMessage::PusVerificationMessage(uint8_t set_report_id, uint8_t ackFlags, uint16_t tcPacketId, uint16_t tcSequenceControl, ReturnValue_t set_error_code, uint8_t set_step, uint32_t parameter1, uint32_t parameter2) { - uint8_t* data = this->getBuffer(); + uint8_t *data = this->getBuffer(); data[messageSize] = set_report_id; messageSize += sizeof(set_report_id); data[messageSize] = ackFlags; @@ -109,12 +109,12 @@ PusSuccessReport::PusSuccessReport(uint16_t setPacketId, reportSize(0), pBuffer(reportBuffer) { //Serialization won't fail, because we know the necessary max-size of the buffer. SerializeAdapter::serialize(&setPacketId, &pBuffer, &reportSize, - sizeof(reportBuffer), true); - SerializeAdapter::serialize(&setSequenceControl, &pBuffer, - &reportSize, sizeof(reportBuffer), true); + sizeof(reportBuffer), SerializeIF::Endianness::BIG); + SerializeAdapter::serialize(&setSequenceControl, &pBuffer, &reportSize, + sizeof(reportBuffer), SerializeIF::Endianness::BIG); if (setStep != 0) { SerializeAdapter::serialize(&setStep, &pBuffer, &reportSize, - sizeof(reportBuffer), true); + sizeof(reportBuffer), SerializeIF::Endianness::BIG); } } @@ -136,25 +136,25 @@ PusFailureReport::PusFailureReport(uint16_t setPacketId, reportSize(0), pBuffer(reportBuffer) { //Serialization won't fail, because we know the necessary max-size of the buffer. SerializeAdapter::serialize(&setPacketId, &pBuffer, &reportSize, - sizeof(reportBuffer), true); - SerializeAdapter::serialize(&setSequenceControl, &pBuffer, - &reportSize, sizeof(reportBuffer), true); + sizeof(reportBuffer), SerializeIF::Endianness::BIG); + SerializeAdapter::serialize(&setSequenceControl, &pBuffer, &reportSize, + sizeof(reportBuffer), SerializeIF::Endianness::BIG); if (setStep != 0) { SerializeAdapter::serialize(&setStep, &pBuffer, &reportSize, - sizeof(reportBuffer), true); + sizeof(reportBuffer), SerializeIF::Endianness::BIG); } - SerializeAdapter::serialize(&setErrorCode, &pBuffer, - &reportSize, sizeof(reportBuffer), true); + SerializeAdapter::serialize(&setErrorCode, &pBuffer, &reportSize, + sizeof(reportBuffer), SerializeIF::Endianness::BIG); SerializeAdapter::serialize(¶meter1, &pBuffer, &reportSize, - sizeof(reportBuffer), true); + sizeof(reportBuffer), SerializeIF::Endianness::BIG); SerializeAdapter::serialize(¶meter2, &pBuffer, &reportSize, - sizeof(reportBuffer), true); + sizeof(reportBuffer), SerializeIF::Endianness::BIG); } PusFailureReport::~PusFailureReport() { } -uint32_t PusFailureReport::getSize() { +size_t PusFailureReport::getSize() { return reportSize; } diff --git a/tmtcservices/PusVerificationReport.h b/tmtcservices/PusVerificationReport.h index 7a173be9..ee84f0c1 100644 --- a/tmtcservices/PusVerificationReport.h +++ b/tmtcservices/PusVerificationReport.h @@ -49,7 +49,7 @@ class PusSuccessReport { private: static const uint16_t MAX_SIZE = 7; uint8_t reportBuffer[MAX_SIZE]; - uint32_t reportSize; + size_t reportSize; uint8_t * pBuffer; public: PusSuccessReport(uint16_t setPacketId, uint16_t setSequenceControl, @@ -63,14 +63,14 @@ class PusFailureReport { private: static const uint16_t MAX_SIZE = 16; uint8_t reportBuffer[MAX_SIZE]; - uint32_t reportSize; + size_t reportSize; uint8_t * pBuffer; public: PusFailureReport(uint16_t setPacketId, uint16_t setSequenceControl, ReturnValue_t setErrorCode, uint8_t setStep = 0, uint32_t parameter1 = 0, uint32_t parameter2 = 0); ~PusFailureReport(); - uint32_t getSize(); + size_t getSize(); uint8_t* getReport(); }; From 1158c9d675278db0dcecf80d711073b8ad625932 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 4 May 2020 17:01:48 +0200 Subject: [PATCH 003/307] storagemanager refactoring --- storagemanager/LocalPool.h | 368 +++++------------------------- storagemanager/LocalPool.tpp | 260 +++++++++++++++++++++ storagemanager/PoolManager.h | 84 ++----- storagemanager/PoolManager.tpp | 50 ++++ storagemanager/StorageManagerIF.h | 22 +- 5 files changed, 407 insertions(+), 377 deletions(-) create mode 100644 storagemanager/LocalPool.tpp create mode 100644 storagemanager/PoolManager.tpp diff --git a/storagemanager/LocalPool.h b/storagemanager/LocalPool.h index 08cb017f..3af37371 100644 --- a/storagemanager/LocalPool.h +++ b/storagemanager/LocalPool.h @@ -39,7 +39,64 @@ public: * @brief This definition generally sets the number of different sized pools. * @details This must be less than the maximum number of pools (currently 0xff). */ -// static const uint32_t NUMBER_OF_POOLS; + // static const uint32_t NUMBER_OF_POOLS; + /** + * @brief This is the default constructor for a pool manager instance. + * @details By passing two arrays of size NUMBER_OF_POOLS, the constructor + * allocates memory (with \c new) for store and size_list. These + * regions are all set to zero on start up. + * @param setObjectId The object identifier to be set. This allows for + * multiple instances of LocalPool in the system. + * @param element_sizes An array of size NUMBER_OF_POOLS in which the size + * of a single element in each pool is determined. + * The sizes must be provided in ascending order. + * + * @param n_elements An array of size NUMBER_OF_POOLS in which the + * number of elements for each pool is determined. + * The position of these values correspond to those in + * element_sizes. + * @param registered Register the pool in object manager or not. Default is false (local pool). + * @param spillsToHigherPools + * A variable to determine whether higher n pools are used if the store is full. + */ + LocalPool(object_id_t setObjectId, + const uint16_t element_sizes[NUMBER_OF_POOLS], + const uint16_t n_elements[NUMBER_OF_POOLS], + bool registered = false, + bool spillsToHigherPools = false); + /** + * @brief In the LocalPool's destructor all allocated memory is freed. + */ + virtual ~LocalPool(void); + + /** + * Documentation: See StorageManagerIF.h + */ + ReturnValue_t addData(store_address_t* storageId, const uint8_t * data, + size_t size, bool ignoreFault = false) override; + ReturnValue_t getFreeElement(store_address_t* storageId,const size_t size, + uint8_t** p_data, bool ignoreFault = false) override; + ReturnValue_t getData(store_address_t packet_id, const uint8_t** packet_ptr, + size_t * size) override; + ReturnValue_t modifyData(store_address_t packet_id, uint8_t** packet_ptr, + size_t * size) override; + virtual ReturnValue_t deleteData(store_address_t) override; + virtual ReturnValue_t deleteData(uint8_t* ptr, size_t size, + store_address_t* storeId = NULL) override; + void clearStore() override; + ReturnValue_t initialize() override; +protected: + /** + * With this helper method, a free element of \c size is reserved. + * @param size The minimum packet size that shall be reserved. + * @param[out] address Storage ID of the reserved data. + * @return - #RETURN_OK on success, + * - the return codes of #getPoolIndex or #findEmpty otherwise. + */ + virtual ReturnValue_t reserveSpace(const uint32_t size, + store_address_t* address, bool ignoreFault); + + InternalErrorReporterIF *internalErrorReporter; private: /** * Indicates that this element is free. @@ -78,7 +135,7 @@ private: * @param data The data to be stored. * @param size The size of the data to be stored. */ - void write(store_address_t packet_id, const uint8_t* data, uint32_t size); + void write(store_address_t packet_id, const uint8_t* data, size_t size); /** * @brief A helper method to read the element size of a certain pool. * @param pool_index The pool in which to look. @@ -101,7 +158,8 @@ private: * @return - #RETURN_OK on success, * - #DATA_TOO_LARGE otherwise. */ - ReturnValue_t getPoolIndex(uint32_t packet_size, uint16_t* poolIndex, uint16_t startAtIndex = 0); + ReturnValue_t getPoolIndex(size_t packet_size, uint16_t* poolIndex, + uint16_t startAtIndex = 0); /** * @brief This helper method calculates the true array position in store * of a given packet id. @@ -121,310 +179,8 @@ private: * - #DATA_STORAGE_FULL if the store is full */ ReturnValue_t findEmpty(uint16_t pool_index, uint16_t* element); -protected: - /** - * With this helper method, a free element of \c size is reserved. - * @param size The minimum packet size that shall be reserved. - * @param[out] address Storage ID of the reserved data. - * @return - #RETURN_OK on success, - * - the return codes of #getPoolIndex or #findEmpty otherwise. - */ - virtual ReturnValue_t reserveSpace(const uint32_t size, store_address_t* address, bool ignoreFault); - - InternalErrorReporterIF *internalErrorReporter; -public: - /** - * @brief This is the default constructor for a pool manager instance. - * @details By passing two arrays of size NUMBER_OF_POOLS, the constructor - * allocates memory (with \c new) for store and size_list. These - * regions are all set to zero on start up. - * @param setObjectId The object identifier to be set. This allows for - * multiple instances of LocalPool in the system. - * @param element_sizes An array of size NUMBER_OF_POOLS in which the size - * of a single element in each pool is determined. - * The sizes must be provided in ascending order. - * - * @param n_elements An array of size NUMBER_OF_POOLS in which the - * number of elements for each pool is determined. - * The position of these values correspond to those in - * element_sizes. - * @param registered Register the pool in object manager or not. Default is false (local pool). - */ - LocalPool(object_id_t setObjectId, - const uint16_t element_sizes[NUMBER_OF_POOLS], - const uint16_t n_elements[NUMBER_OF_POOLS], - bool registered = false, - bool spillsToHigherPools = false); - /** - * @brief In the LocalPool's destructor all allocated memory is freed. - */ - virtual ~LocalPool(void); - ReturnValue_t addData(store_address_t* storageId, const uint8_t * data, - uint32_t size, bool ignoreFault = false); - - /** - * With this helper method, a free element of \c size is reserved. - * - * @param size The minimum packet size that shall be reserved. - * @return Returns the storage identifier within the storage or - * StorageManagerIF::INVALID_ADDRESS (in raw). - */ - ReturnValue_t getFreeElement(store_address_t* storageId, - const uint32_t size, uint8_t** p_data, bool ignoreFault = false); - ReturnValue_t getData(store_address_t packet_id, const uint8_t** packet_ptr, - uint32_t* size); - ReturnValue_t modifyData(store_address_t packet_id, uint8_t** packet_ptr, - uint32_t* size); - virtual ReturnValue_t deleteData(store_address_t); - virtual ReturnValue_t deleteData(uint8_t* ptr, uint32_t size, - store_address_t* storeId = NULL); - void clearStore(); - ReturnValue_t initialize(); }; -template -inline ReturnValue_t LocalPool::findEmpty(uint16_t pool_index, - uint16_t* element) { - ReturnValue_t status = DATA_STORAGE_FULL; - for (uint16_t foundElement = 0; foundElement < n_elements[pool_index]; - foundElement++) { - if (size_list[pool_index][foundElement] == STORAGE_FREE) { - *element = foundElement; - status = RETURN_OK; - break; - } - } - return status; -} - -template -inline void LocalPool::write(store_address_t packet_id, - const uint8_t* data, uint32_t size) { - uint8_t* ptr; - uint32_t packet_position = getRawPosition(packet_id); - - //check size? -> Not necessary, because size is checked before calling this function. - ptr = &store[packet_id.pool_index][packet_position]; - memcpy(ptr, data, size); - size_list[packet_id.pool_index][packet_id.packet_index] = size; -} - -//Returns page size of 0 in case store_index is illegal -template -inline uint32_t LocalPool::getPageSize(uint16_t pool_index) { - if (pool_index < NUMBER_OF_POOLS) { - return element_sizes[pool_index]; - } else { - return 0; - } -} - -template -inline ReturnValue_t LocalPool::getPoolIndex( - uint32_t packet_size, uint16_t* poolIndex, uint16_t startAtIndex) { - for (uint16_t n = startAtIndex; n < NUMBER_OF_POOLS; n++) { -// debug << "LocalPool " << getObjectId() << "::getPoolIndex: Pool: " << n << ", Element Size: " << element_sizes[n] << std::endl; - if (element_sizes[n] >= packet_size) { - *poolIndex = n; - return RETURN_OK; - } - } - return DATA_TOO_LARGE; -} - -template -inline uint32_t LocalPool::getRawPosition( - store_address_t packet_id) { - return packet_id.packet_index * element_sizes[packet_id.pool_index]; -} - -template -inline ReturnValue_t LocalPool::reserveSpace( - const uint32_t size, store_address_t* address, bool ignoreFault) { - ReturnValue_t status = getPoolIndex(size, &address->pool_index); - if (status != RETURN_OK) { - error << "LocalPool( " << std::hex << getObjectId() << std::dec - << " )::reserveSpace: Packet too large." << std::endl; - return status; - } - status = findEmpty(address->pool_index, &address->packet_index); - while (status != RETURN_OK && spillsToHigherPools) { - status = getPoolIndex(size, &address->pool_index, address->pool_index + 1); - if (status != RETURN_OK) { - //We don't find any fitting pool anymore. - break; - } - status = findEmpty(address->pool_index, &address->packet_index); - } - if (status == RETURN_OK) { -// if (getObjectId() == objects::IPC_STORE && address->pool_index >= 3) { -// debug << "Reserve: Pool: " << std::dec << address->pool_index << " Index: " << address->packet_index << std::endl; -// } - - size_list[address->pool_index][address->packet_index] = size; - } else { - if (!ignoreFault) { - internalErrorReporter->storeFull(); - } -// error << "LocalPool( " << std::hex << getObjectId() << std::dec -// << " )::reserveSpace: Packet store is full." << std::endl; - } - return status; -} - -template -inline LocalPool::LocalPool(object_id_t setObjectId, - const uint16_t element_sizes[NUMBER_OF_POOLS], - const uint16_t n_elements[NUMBER_OF_POOLS], bool registered, bool spillsToHigherPools) : - SystemObject(setObjectId, registered), spillsToHigherPools(spillsToHigherPools), internalErrorReporter(NULL) { - for (uint16_t n = 0; n < NUMBER_OF_POOLS; n++) { - this->element_sizes[n] = element_sizes[n]; - this->n_elements[n] = n_elements[n]; - store[n] = new uint8_t[n_elements[n] * element_sizes[n]]; - size_list[n] = new uint32_t[n_elements[n]]; - memset(store[n], 0x00, (n_elements[n] * element_sizes[n])); - memset(size_list[n], STORAGE_FREE, (n_elements[n] * sizeof(**size_list))); //TODO checkme - } -} - -template -inline LocalPool::~LocalPool(void) { - for (uint16_t n = 0; n < NUMBER_OF_POOLS; n++) { - delete[] store[n]; - delete[] size_list[n]; - } -} - -template -inline ReturnValue_t LocalPool::addData( - store_address_t* storageId, const uint8_t* data, uint32_t size, bool ignoreFault) { - ReturnValue_t status = reserveSpace(size, storageId, ignoreFault); - if (status == RETURN_OK) { - write(*storageId, data, size); - } - return status; -} - -template -inline ReturnValue_t LocalPool::getFreeElement( - store_address_t* storageId, const uint32_t size, uint8_t** p_data, bool ignoreFault) { - ReturnValue_t status = reserveSpace(size, storageId, ignoreFault); - if (status == RETURN_OK) { - *p_data = &store[storageId->pool_index][getRawPosition(*storageId)]; - } else { - *p_data = NULL; - } - return status; -} - -template -inline ReturnValue_t LocalPool::getData( - store_address_t packet_id, const uint8_t** packet_ptr, uint32_t* size) { - uint8_t* tempData = NULL; - ReturnValue_t status = modifyData(packet_id, &tempData, size); - *packet_ptr = tempData; - return status; -} - -template -inline ReturnValue_t LocalPool::modifyData(store_address_t packet_id, - uint8_t** packet_ptr, uint32_t* size) { - ReturnValue_t status = RETURN_FAILED; - if (packet_id.pool_index >= NUMBER_OF_POOLS) { - return ILLEGAL_STORAGE_ID; - } - if ((packet_id.packet_index >= n_elements[packet_id.pool_index])) { - return ILLEGAL_STORAGE_ID; - } - if (size_list[packet_id.pool_index][packet_id.packet_index] - != STORAGE_FREE) { - uint32_t packet_position = getRawPosition(packet_id); - *packet_ptr = &store[packet_id.pool_index][packet_position]; - *size = size_list[packet_id.pool_index][packet_id.packet_index]; - status = RETURN_OK; - } else { - status = DATA_DOES_NOT_EXIST; - } - return status; -} - -template -inline ReturnValue_t LocalPool::deleteData( - store_address_t packet_id) { - -// if (getObjectId() == objects::IPC_STORE && packet_id.pool_index >= 3) { -// debug << "Delete: Pool: " << std::dec << packet_id.pool_index << " Index: " << packet_id.packet_index << std::endl; -// } - ReturnValue_t status = RETURN_OK; - uint32_t page_size = getPageSize(packet_id.pool_index); - if ((page_size != 0) - && (packet_id.packet_index < n_elements[packet_id.pool_index])) { - uint16_t packet_position = getRawPosition(packet_id); - uint8_t* ptr = &store[packet_id.pool_index][packet_position]; - memset(ptr, 0, page_size); - //Set free list - size_list[packet_id.pool_index][packet_id.packet_index] = STORAGE_FREE; - } else { - //pool_index or packet_index is too large - error << "LocalPool:deleteData failed." << std::endl; - status = ILLEGAL_STORAGE_ID; - } - return status; -} - -template -inline void LocalPool::clearStore() { - for (uint16_t n = 0; n < NUMBER_OF_POOLS; n++) { - memset(size_list[n], STORAGE_FREE, (n_elements[n] * sizeof(**size_list)));//TODO checkme - } -} - -template -inline ReturnValue_t LocalPool::deleteData(uint8_t* ptr, - uint32_t size, store_address_t* storeId) { - store_address_t localId; - ReturnValue_t result = ILLEGAL_ADDRESS; - for (uint16_t n = 0; n < NUMBER_OF_POOLS; n++) { - //Not sure if new allocates all stores in order. so better be careful. - if ((store[n] <= ptr) && (&store[n][n_elements[n]*element_sizes[n]]) > ptr) { - localId.pool_index = n; - uint32_t deltaAddress = ptr - store[n]; - //Getting any data from the right "block" is ok. This is necessary, as IF's sometimes don't point to the first element of an object. - localId.packet_index = deltaAddress / element_sizes[n]; - result = deleteData(localId); -// if (deltaAddress % element_sizes[n] != 0) { -// error << "Pool::deleteData: address not aligned!" << std::endl; -// } - break; - } - } - if (storeId != NULL) { - *storeId = localId; - } - return result; -} - -template -inline ReturnValue_t LocalPool::initialize() { - ReturnValue_t result = SystemObject::initialize(); - if (result != RETURN_OK) { - return result; - } - internalErrorReporter = objectManager->get(objects::INTERNAL_ERROR_REPORTER); - if (internalErrorReporter == NULL){ - return RETURN_FAILED; - } - - //Check if any pool size is large than the maximum allowed. - for (uint8_t count = 0; count < NUMBER_OF_POOLS; count++) { - if (element_sizes[count] >= STORAGE_FREE) { - error - << "LocalPool::initialize: Pool is too large! Max. allowed size is: " - << (STORAGE_FREE - 1) << std::endl; - return RETURN_FAILED; - } - } - return RETURN_OK; -} +#include #endif /* FRAMEWORK_STORAGEMANAGER_LOCALPOOL_H_ */ diff --git a/storagemanager/LocalPool.tpp b/storagemanager/LocalPool.tpp new file mode 100644 index 00000000..649ec88a --- /dev/null +++ b/storagemanager/LocalPool.tpp @@ -0,0 +1,260 @@ +#ifndef LOCALPOOL_TPP +#define LOCALPOOL_TPP + +template +inline LocalPool::LocalPool(object_id_t setObjectId, + const uint16_t element_sizes[NUMBER_OF_POOLS], + const uint16_t n_elements[NUMBER_OF_POOLS], bool registered, + bool spillsToHigherPools) : + SystemObject(setObjectId, registered), internalErrorReporter(nullptr), + spillsToHigherPools(spillsToHigherPools) +{ + for (uint16_t n = 0; n < NUMBER_OF_POOLS; n++) { + this->element_sizes[n] = element_sizes[n]; + this->n_elements[n] = n_elements[n]; + store[n] = new uint8_t[n_elements[n] * element_sizes[n]]; + size_list[n] = new uint32_t[n_elements[n]]; + memset(store[n], 0x00, (n_elements[n] * element_sizes[n])); + //TODO checkme + memset(size_list[n], STORAGE_FREE, (n_elements[n] * sizeof(**size_list))); + } +} + + +template +inline ReturnValue_t LocalPool::findEmpty(uint16_t pool_index, + uint16_t* element) { + ReturnValue_t status = DATA_STORAGE_FULL; + for (uint16_t foundElement = 0; foundElement < n_elements[pool_index]; + foundElement++) { + if (size_list[pool_index][foundElement] == STORAGE_FREE) { + *element = foundElement; + status = RETURN_OK; + break; + } + } + return status; +} + +template +inline void LocalPool::write(store_address_t packet_id, + const uint8_t* data, size_t size) { + uint8_t* ptr; + uint32_t packet_position = getRawPosition(packet_id); + + //check size? -> Not necessary, because size is checked before calling this function. + ptr = &store[packet_id.pool_index][packet_position]; + memcpy(ptr, data, size); + size_list[packet_id.pool_index][packet_id.packet_index] = size; +} + +//Returns page size of 0 in case store_index is illegal +template +inline uint32_t LocalPool::getPageSize(uint16_t pool_index) { + if (pool_index < NUMBER_OF_POOLS) { + return element_sizes[pool_index]; + } else { + return 0; + } +} + +template +inline ReturnValue_t LocalPool::getPoolIndex( + size_t packet_size, uint16_t* poolIndex, uint16_t startAtIndex) { + for (uint16_t n = startAtIndex; n < NUMBER_OF_POOLS; n++) { + //debug << "LocalPool " << getObjectId() << "::getPoolIndex: Pool: " << + // n << ", Element Size: " << element_sizes[n] << std::endl; + if (element_sizes[n] >= packet_size) { + *poolIndex = n; + return RETURN_OK; + } + } + return DATA_TOO_LARGE; +} + +template +inline uint32_t LocalPool::getRawPosition( + store_address_t packet_id) { + return packet_id.packet_index * element_sizes[packet_id.pool_index]; +} + +template +inline ReturnValue_t LocalPool::reserveSpace( + const uint32_t size, store_address_t* address, bool ignoreFault) { + ReturnValue_t status = getPoolIndex(size, &address->pool_index); + if (status != RETURN_OK) { + error << "LocalPool( " << std::hex << getObjectId() << std::dec + << " )::reserveSpace: Packet too large." << std::endl; + return status; + } + status = findEmpty(address->pool_index, &address->packet_index); + while (status != RETURN_OK && spillsToHigherPools) { + status = getPoolIndex(size, &address->pool_index, address->pool_index + 1); + if (status != RETURN_OK) { + //We don't find any fitting pool anymore. + break; + } + status = findEmpty(address->pool_index, &address->packet_index); + } + if (status == RETURN_OK) { + // if (getObjectId() == objects::IPC_STORE && address->pool_index >= 3) { + // debug << "Reserve: Pool: " << std::dec << address->pool_index << + // " Index: " << address->packet_index << std::endl; + // } + + size_list[address->pool_index][address->packet_index] = size; + } else { + if (!ignoreFault and internalErrorReporter != nullptr) { + internalErrorReporter->storeFull(); + } + // error << "LocalPool( " << std::hex << getObjectId() << std::dec + // << " )::reserveSpace: Packet store is full." << std::endl; + } + return status; +} + +template +inline LocalPool::~LocalPool(void) { + for (uint16_t n = 0; n < NUMBER_OF_POOLS; n++) { + delete[] store[n]; + delete[] size_list[n]; + } +} + +template +inline ReturnValue_t LocalPool::addData(store_address_t* storageId, + const uint8_t* data, size_t size, bool ignoreFault) { + ReturnValue_t status = reserveSpace(size, storageId, ignoreFault); + if (status == RETURN_OK) { + write(*storageId, data, size); + } + return status; +} + +template +inline ReturnValue_t LocalPool::getFreeElement( + store_address_t* storageId, const size_t size, + uint8_t** p_data, bool ignoreFault) { + ReturnValue_t status = reserveSpace(size, storageId, ignoreFault); + if (status == RETURN_OK) { + *p_data = &store[storageId->pool_index][getRawPosition(*storageId)]; + } else { + *p_data = NULL; + } + return status; +} + +template +inline ReturnValue_t LocalPool::getData( + store_address_t packet_id, const uint8_t** packet_ptr, size_t* size) { + uint8_t* tempData = NULL; + ReturnValue_t status = modifyData(packet_id, &tempData, size); + *packet_ptr = tempData; + return status; +} + +template +inline ReturnValue_t LocalPool::modifyData( + store_address_t packet_id, uint8_t** packet_ptr, size_t* size) { + ReturnValue_t status = RETURN_FAILED; + if (packet_id.pool_index >= NUMBER_OF_POOLS) { + return ILLEGAL_STORAGE_ID; + } + if ((packet_id.packet_index >= n_elements[packet_id.pool_index])) { + return ILLEGAL_STORAGE_ID; + } + if (size_list[packet_id.pool_index][packet_id.packet_index] + != STORAGE_FREE) { + uint32_t packet_position = getRawPosition(packet_id); + *packet_ptr = &store[packet_id.pool_index][packet_position]; + *size = size_list[packet_id.pool_index][packet_id.packet_index]; + status = RETURN_OK; + } else { + status = DATA_DOES_NOT_EXIST; + } + return status; +} + +template +inline ReturnValue_t LocalPool::deleteData( + store_address_t packet_id) { + //if (getObjectId() == objects::IPC_STORE && packet_id.pool_index >= 3) { + // debug << "Delete: Pool: " << std::dec << packet_id.pool_index << " Index: " + // << packet_id.packet_index << std::endl; + //} + ReturnValue_t status = RETURN_OK; + uint32_t page_size = getPageSize(packet_id.pool_index); + if ((page_size != 0) + && (packet_id.packet_index < n_elements[packet_id.pool_index])) { + uint16_t packet_position = getRawPosition(packet_id); + uint8_t* ptr = &store[packet_id.pool_index][packet_position]; + memset(ptr, 0, page_size); + //Set free list + size_list[packet_id.pool_index][packet_id.packet_index] = STORAGE_FREE; + } else { + //pool_index or packet_index is too large + error << "LocalPool:deleteData failed." << std::endl; + status = ILLEGAL_STORAGE_ID; + } + return status; +} + +template +inline void LocalPool::clearStore() { + for (uint16_t n = 0; n < NUMBER_OF_POOLS; n++) { + //TODO checkme + memset(size_list[n], STORAGE_FREE, (n_elements[n] * sizeof(**size_list))); + } +} + +template +inline ReturnValue_t LocalPool::deleteData(uint8_t* ptr, + size_t size, store_address_t* storeId) { + store_address_t localId; + ReturnValue_t result = ILLEGAL_ADDRESS; + for (uint16_t n = 0; n < NUMBER_OF_POOLS; n++) { + //Not sure if new allocates all stores in order. so better be careful. + if ((store[n] <= ptr) && (&store[n][n_elements[n]*element_sizes[n]]) > ptr) { + localId.pool_index = n; + uint32_t deltaAddress = ptr - store[n]; + // Getting any data from the right "block" is ok. + // This is necessary, as IF's sometimes don't point to the first + // element of an object. + localId.packet_index = deltaAddress / element_sizes[n]; + result = deleteData(localId); + //if (deltaAddress % element_sizes[n] != 0) { + // error << "Pool::deleteData: address not aligned!" << std::endl; + //} + break; + } + } + if (storeId != NULL) { + *storeId = localId; + } + return result; +} + +template +inline ReturnValue_t LocalPool::initialize() { + ReturnValue_t result = SystemObject::initialize(); + if (result != RETURN_OK) { + return result; + } + internalErrorReporter = objectManager->get( + objects::INTERNAL_ERROR_REPORTER); + if (internalErrorReporter == NULL){ + return RETURN_FAILED; + } + + //Check if any pool size is large than the maximum allowed. + for (uint8_t count = 0; count < NUMBER_OF_POOLS; count++) { + if (element_sizes[count] >= STORAGE_FREE) { + error << "LocalPool::initialize: Pool is too large! " + "Max. allowed size is: " << (STORAGE_FREE - 1) << std::endl; + return RETURN_FAILED; + } + } + return RETURN_OK; +} + +#endif diff --git a/storagemanager/PoolManager.h b/storagemanager/PoolManager.h index 68a7addc..6e6c7613 100644 --- a/storagemanager/PoolManager.h +++ b/storagemanager/PoolManager.h @@ -1,12 +1,3 @@ -/** - * @file PoolManager - * - * @date 02.02.2012 - * @author Bastian Baetz - * - * @brief This file contains the definition of the PoolManager class. - */ - #ifndef POOLMANAGER_H_ #define POOLMANAGER_H_ @@ -17,70 +8,39 @@ /** * @brief The PoolManager class provides an intermediate data storage with * a fixed pool size policy for inter-process communication. - * \details Uses local pool, but is thread-safe. + * @details Uses local pool calls but is thread safe by protecting the call + * with a lock. */ template class PoolManager : public LocalPool { -protected: - /** - * Overwritten for thread safety. - * Locks during execution. - */ - virtual ReturnValue_t reserveSpace(const uint32_t size, store_address_t* address, bool ignoreFault); - - /** - * \brief The mutex is created in the constructor and makes access mutual exclusive. - * \details Locking and unlocking is done during searching for free slots and deleting existing slots. - */ - MutexIF* mutex; public: - PoolManager( object_id_t setObjectId, const uint16_t element_sizes[NUMBER_OF_POOLS], const uint16_t n_elements[NUMBER_OF_POOLS] ); + PoolManager( object_id_t setObjectId, const uint16_t element_sizes[NUMBER_OF_POOLS], + const uint16_t n_elements[NUMBER_OF_POOLS] ); /** * @brief In the PoolManager's destructor all allocated memory is freed. */ - virtual ~PoolManager( void ); + virtual ~PoolManager(); + + ReturnValue_t deleteData(store_address_t) override; + ReturnValue_t deleteData(uint8_t* buffer, size_t size, + store_address_t* storeId = NULL) override; + + ReturnValue_t modifyData(store_address_t packet_id, uint8_t** packet_ptr, + size_t* size) override; +protected: + ReturnValue_t reserveSpace(const uint32_t size, store_address_t* address, + bool ignoreFault) override; + /** - * Overwritten for thread safety. + * @brief The mutex is created in the constructor and makes + * access mutual exclusive. + * @details Locking and unlocking is done during searching for free slots + * and deleting existing slots. */ - virtual ReturnValue_t deleteData(store_address_t); - virtual ReturnValue_t deleteData(uint8_t* buffer, uint32_t size, store_address_t* storeId = NULL); + MutexIF* mutex; }; -template -inline ReturnValue_t PoolManager::reserveSpace(const uint32_t size, store_address_t* address, bool ignoreFault) { - MutexHelper mutexHelper(mutex,MutexIF::NO_TIMEOUT); - ReturnValue_t status = LocalPool::reserveSpace(size,address,ignoreFault); - return status; -} - -template -inline PoolManager::PoolManager(object_id_t setObjectId, - const uint16_t element_sizes[NUMBER_OF_POOLS], - const uint16_t n_elements[NUMBER_OF_POOLS]) : LocalPool(setObjectId, element_sizes, n_elements, true) { - mutex = MutexFactory::instance()->createMutex(); -} - -template -inline PoolManager::~PoolManager(void) { - MutexFactory::instance()->deleteMutex(mutex); -} - -template -inline ReturnValue_t PoolManager::deleteData( - store_address_t packet_id) { - // debug << "PoolManager( " << translateObject(getObjectId()) << " )::deleteData from store " << packet_id.pool_index << ". id is " << packet_id.packet_index << std::endl; - MutexHelper mutexHelper(mutex,MutexIF::NO_TIMEOUT); - ReturnValue_t status = LocalPool::deleteData(packet_id); - return status; -} - -template -inline ReturnValue_t PoolManager::deleteData(uint8_t* buffer, uint32_t size, - store_address_t* storeId) { - MutexHelper mutexHelper(mutex,MutexIF::NO_TIMEOUT); - ReturnValue_t status = LocalPool::deleteData(buffer, size, storeId); - return status; -} +#include "PoolManager.tpp" #endif /* POOLMANAGER_H_ */ diff --git a/storagemanager/PoolManager.tpp b/storagemanager/PoolManager.tpp new file mode 100644 index 00000000..ed340b91 --- /dev/null +++ b/storagemanager/PoolManager.tpp @@ -0,0 +1,50 @@ +template +inline PoolManager::PoolManager(object_id_t setObjectId, + const uint16_t element_sizes[NUMBER_OF_POOLS], + const uint16_t n_elements[NUMBER_OF_POOLS]) : + LocalPool(setObjectId, element_sizes, n_elements, true) { + mutex = MutexFactory::instance()->createMutex(); +} + +template +inline PoolManager::~PoolManager(void) { + MutexFactory::instance()->deleteMutex(mutex); +} + +template +inline ReturnValue_t PoolManager::reserveSpace( + const uint32_t size, store_address_t* address, bool ignoreFault) { + MutexHelper mutexHelper(mutex,MutexIF::NO_TIMEOUT); + ReturnValue_t status = LocalPool::reserveSpace(size, + address,ignoreFault); + return status; +} + +template +inline ReturnValue_t PoolManager::deleteData( + store_address_t packet_id) { + // debug << "PoolManager( " << translateObject(getObjectId()) << + // " )::deleteData from store " << packet_id.pool_index << + // ". id is "<< packet_id.packet_index << std::endl; + MutexHelper mutexHelper(mutex,MutexIF::NO_TIMEOUT); + ReturnValue_t status = LocalPool::deleteData(packet_id); + return status; +} + +template +inline ReturnValue_t PoolManager::deleteData(uint8_t* buffer, + size_t size, store_address_t* storeId) { + MutexHelper mutexHelper(mutex,MutexIF::NO_TIMEOUT); + ReturnValue_t status = LocalPool::deleteData(buffer, + size, storeId); + return status; +} + +template +inline ReturnValue_t PoolManager::modifyData( + store_address_t packet_id, uint8_t** packet_ptr, size_t* size) { + MutexHelper mutexHelper(mutex,MutexIF::NO_TIMEOUT); + ReturnValue_t status = LocalPool::modifyData(packet_id, + packet_ptr, size); + return status; +} diff --git a/storagemanager/StorageManagerIF.h b/storagemanager/StorageManagerIF.h index 575e9caa..d85fe86f 100644 --- a/storagemanager/StorageManagerIF.h +++ b/storagemanager/StorageManagerIF.h @@ -6,9 +6,9 @@ #include /** - * This union defines the type that identifies where a data packet is stored in the store. - * It comprises of a raw part to read it as raw value and a structured part to use it in - * pool-like stores. + * This union defines the type that identifies where a data packet is + * stored in the store. It comprises of a raw part to read it as raw value and + * a structured part to use it in pool-like stores. */ union store_address_t { /** @@ -94,7 +94,8 @@ public: * @li RETURN_FAILED if data could not be added. * storageId is unchanged then. */ - virtual ReturnValue_t addData(store_address_t* storageId, const uint8_t * data, uint32_t size, bool ignoreFault = false) = 0; + virtual ReturnValue_t addData(store_address_t* storageId, + const uint8_t * data, size_t size, bool ignoreFault = false) = 0; /** * @brief With deleteData, the storageManager frees the memory region * identified by packet_id. @@ -105,14 +106,16 @@ public: */ virtual ReturnValue_t deleteData(store_address_t packet_id) = 0; /** - * @brief Another deleteData which uses the pointer and size of the stored data to delete the content. + * @brief Another deleteData which uses the pointer and size of the + * stored data to delete the content. * @param buffer Pointer to the data. * @param size Size of data to be stored. * @param storeId Store id of the deleted element (optional) * @return @li RETURN_OK on success. * @li failure code if deletion did not work */ - virtual ReturnValue_t deleteData(uint8_t* buffer, uint32_t size, store_address_t* storeId = NULL) = 0; + virtual ReturnValue_t deleteData(uint8_t* buffer, size_t size, + store_address_t* storeId = nullptr) = 0; /** * @brief getData returns an address to data and the size of the data * for a given packet_id. @@ -125,12 +128,12 @@ public: * (e.g. an illegal packet_id was passed). */ virtual ReturnValue_t getData(store_address_t packet_id, - const uint8_t** packet_ptr, uint32_t* size) = 0; + const uint8_t** packet_ptr, size_t* size) = 0; /** * Same as above, but not const and therefore modifiable. */ virtual ReturnValue_t modifyData(store_address_t packet_id, - uint8_t** packet_ptr, uint32_t* size) = 0; + uint8_t** packet_ptr, size_t* size) = 0; /** * This method reserves an element of \c size. * @@ -144,7 +147,8 @@ public: * @li RETURN_FAILED if data could not be added. * storageId is unchanged then. */ - virtual ReturnValue_t getFreeElement(store_address_t* storageId, const uint32_t size, uint8_t** p_data, bool ignoreFault = false ) = 0; + virtual ReturnValue_t getFreeElement(store_address_t* storageId, + const size_t size, uint8_t** p_data, bool ignoreFault = false ) = 0; /** * Clears the whole store. * Use with care! From c7856da81c77fca6caa31873f942e0998f9b4586 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 4 May 2020 16:53:04 +0200 Subject: [PATCH 004/307] size_t replacements --- action/ActionHelper.cpp | 2 +- action/CommandActionHelper.cpp | 2 +- action/SimpleActionHelper.cpp | 2 +- datapool/DataPoolAdmin.cpp | 2 +- devicehandlers/DeviceHandlerBase.cpp | 2 +- memory/MemoryHelper.cpp | 2 +- parameters/ParameterHelper.cpp | 2 +- subsystem/Subsystem.cpp | 4 ++-- tcdistribution/CCSDSDistributor.cpp | 2 +- tmtcpacket/pus/TcPacketStored.cpp | 4 ++-- tmtcpacket/pus/TmPacketStored.cpp | 2 +- 11 files changed, 13 insertions(+), 13 deletions(-) diff --git a/action/ActionHelper.cpp b/action/ActionHelper.cpp index 9c1475f1..18e46fba 100644 --- a/action/ActionHelper.cpp +++ b/action/ActionHelper.cpp @@ -49,7 +49,7 @@ void ActionHelper::setQueueToUse(MessageQueueIF* queue) { void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId, store_address_t dataAddress) { const uint8_t* dataPtr = NULL; - uint32_t size = 0; + size_t size = 0; ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size); if (result != HasReturnvaluesIF::RETURN_OK) { CommandMessage reply; diff --git a/action/CommandActionHelper.cpp b/action/CommandActionHelper.cpp index 05eb9346..ceb97d3b 100644 --- a/action/CommandActionHelper.cpp +++ b/action/CommandActionHelper.cpp @@ -113,7 +113,7 @@ uint8_t CommandActionHelper::getCommandCount() const { void CommandActionHelper::extractDataForOwner(ActionId_t actionId, store_address_t storeId) { const uint8_t * data = NULL; - uint32_t size = 0; + size_t size = 0; ReturnValue_t result = ipcStore->getData(storeId, &data, &size); if (result != HasReturnvaluesIF::RETURN_OK) { return; diff --git a/action/SimpleActionHelper.cpp b/action/SimpleActionHelper.cpp index 6de372fb..6861fc28 100644 --- a/action/SimpleActionHelper.cpp +++ b/action/SimpleActionHelper.cpp @@ -44,7 +44,7 @@ void SimpleActionHelper::prepareExecution(MessageQueueId_t commandedBy, queueToUse->sendMessage(commandedBy, &reply); } const uint8_t* dataPtr = NULL; - uint32_t size = 0; + size_t size = 0; ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size); if (result != HasReturnvaluesIF::RETURN_OK) { ActionMessage::setStepReply(&reply, actionId, 0, result); diff --git a/datapool/DataPoolAdmin.cpp b/datapool/DataPoolAdmin.cpp index fe6b9215..99d2b51b 100644 --- a/datapool/DataPoolAdmin.cpp +++ b/datapool/DataPoolAdmin.cpp @@ -215,7 +215,7 @@ ReturnValue_t DataPoolAdmin::handleParameterCommand(CommandMessage* command) { ParameterMessage::getParameterId(command)); const uint8_t *storedStream; - uint32_t storedStreamSize; + size_t storedStreamSize; result = storage->getData(ParameterMessage::getStoreId(command), &storedStream, &storedStreamSize); if (result != HasReturnvaluesIF::RETURN_OK) { diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index 22d49d37..aa2305fe 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -558,7 +558,7 @@ void DeviceHandlerBase::doGetRead() { ReturnValue_t DeviceHandlerBase::getStorageData(store_address_t storageAddress, uint8_t * *data, uint32_t * len) { - uint32_t lenTmp; + size_t lenTmp; if (IPCStore == NULL) { *data = NULL; diff --git a/memory/MemoryHelper.cpp b/memory/MemoryHelper.cpp index 69830084..b204ea42 100644 --- a/memory/MemoryHelper.cpp +++ b/memory/MemoryHelper.cpp @@ -152,7 +152,7 @@ void MemoryHelper::handleMemoryLoad(CommandMessage* message) { ipcAddress = MemoryMessage::getStoreID(message); const uint8_t* p_data = NULL; uint8_t* dataPointer = NULL; - uint32_t size = 0; + size_t size = 0; ReturnValue_t returnCode = ipcStore->getData(ipcAddress, &p_data, &size); if (returnCode == RETURN_OK) { returnCode = workOnThis->handleMemoryLoad(address, p_data, size, diff --git a/parameters/ParameterHelper.cpp b/parameters/ParameterHelper.cpp index 75b71a7e..9e4fc493 100644 --- a/parameters/ParameterHelper.cpp +++ b/parameters/ParameterHelper.cpp @@ -37,7 +37,7 @@ ReturnValue_t ParameterHelper::handleParameterMessage(CommandMessage *message) { ParameterMessage::getParameterId(message)); const uint8_t *storedStream; - uint32_t storedStreamSize; + size_t storedStreamSize; result = storage->getData( ParameterMessage::getStoreId(message), &storedStream, &storedStreamSize); diff --git a/subsystem/Subsystem.cpp b/subsystem/Subsystem.cpp index e1ec544b..2d7d9c44 100644 --- a/subsystem/Subsystem.cpp +++ b/subsystem/Subsystem.cpp @@ -162,7 +162,7 @@ ReturnValue_t Subsystem::handleCommandMessage(CommandMessage* message) { case ModeSequenceMessage::ADD_SEQUENCE: { FixedArrayList sequence; const uint8_t *pointer; - uint32_t sizeRead; + size_t sizeRead; result = IPCStore->getData( ModeSequenceMessage::getStoreAddress(message), &pointer, &sizeRead); @@ -188,7 +188,7 @@ ReturnValue_t Subsystem::handleCommandMessage(CommandMessage* message) { case ModeSequenceMessage::ADD_TABLE: { FixedArrayList table; const uint8_t *pointer; - uint32_t sizeRead; + size_t sizeRead; result = IPCStore->getData( ModeSequenceMessage::getStoreAddress(message), &pointer, &sizeRead); diff --git a/tcdistribution/CCSDSDistributor.cpp b/tcdistribution/CCSDSDistributor.cpp index ecd7702e..878b8f7d 100644 --- a/tcdistribution/CCSDSDistributor.cpp +++ b/tcdistribution/CCSDSDistributor.cpp @@ -13,7 +13,7 @@ CCSDSDistributor::~CCSDSDistributor() { iterator_t CCSDSDistributor::selectDestination() { // debug << "CCSDSDistributor::selectDestination received: " << this->currentMessage.getStorageId().pool_index << ", " << this->currentMessage.getStorageId().packet_index << std::endl; const uint8_t* p_packet = NULL; - uint32_t size = 0; + size_t size = 0; //TODO check returncode? this->tcStore->getData( this->currentMessage.getStorageId(), &p_packet, &size ); SpacePacketBase current_packet( p_packet ); diff --git a/tmtcpacket/pus/TcPacketStored.cpp b/tmtcpacket/pus/TcPacketStored.cpp index 1f31a763..4bfd0e37 100644 --- a/tmtcpacket/pus/TcPacketStored.cpp +++ b/tmtcpacket/pus/TcPacketStored.cpp @@ -59,7 +59,7 @@ bool TcPacketStored::checkAndSetStore() { void TcPacketStored::setStoreAddress(store_address_t setAddress) { this->storeAddress = setAddress; const uint8_t* temp_data = NULL; - uint32_t temp_size; + size_t temp_size; ReturnValue_t status = StorageManagerIF::RETURN_FAILED; if (this->checkAndSetStore()) { status = this->store->getData(this->storeAddress, &temp_data, @@ -79,7 +79,7 @@ store_address_t TcPacketStored::getStoreAddress() { bool TcPacketStored::isSizeCorrect() { const uint8_t* temp_data = NULL; - uint32_t temp_size; + size_t temp_size; ReturnValue_t status = this->store->getData(this->storeAddress, &temp_data, &temp_size); if (status == StorageManagerIF::RETURN_OK) { diff --git a/tmtcpacket/pus/TmPacketStored.cpp b/tmtcpacket/pus/TmPacketStored.cpp index f2c1eb28..529f8f8d 100644 --- a/tmtcpacket/pus/TmPacketStored.cpp +++ b/tmtcpacket/pus/TmPacketStored.cpp @@ -81,7 +81,7 @@ void TmPacketStored::deletePacket() { void TmPacketStored::setStoreAddress(store_address_t setAddress) { storeAddress = setAddress; const uint8_t* temp_data = NULL; - uint32_t temp_size; + size_t temp_size; if (!checkAndSetStore()) { return; } From 3ebc25796881bc8b2b75e6bfdba30ce5dc705d8f Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 7 May 2020 23:00:09 +0200 Subject: [PATCH 005/307] some little formatting stuff --- storagemanager/LocalPool.h | 19 ++++++++----------- storagemanager/PoolManager.h | 12 ++++++------ storagemanager/StorageManagerIF.h | 11 ++++++----- 3 files changed, 20 insertions(+), 22 deletions(-) diff --git a/storagemanager/LocalPool.h b/storagemanager/LocalPool.h index 3af37371..3ddcc491 100644 --- a/storagemanager/LocalPool.h +++ b/storagemanager/LocalPool.h @@ -1,14 +1,11 @@ -#ifndef FRAMEWORK_STORAGEMANAGER_LOCALPOOL_H_ -#define FRAMEWORK_STORAGEMANAGER_LOCALPOOL_H_ - /** * @file LocalPool - * * @date 02.02.2012 * @author Bastian Baetz - * * @brief This file contains the definition of the LocalPool class. */ +#ifndef FRAMEWORK_STORAGEMANAGER_LOCALPOOL_H_ +#define FRAMEWORK_STORAGEMANAGER_LOCALPOOL_H_ #include #include @@ -20,7 +17,7 @@ /** * @brief The LocalPool class provides an intermediate data storage with * a fixed pool size policy. - * \details The class implements the StorageManagerIF interface. While the + * @details The class implements the StorageManagerIF interface. While the * total number of pools is fixed, the element sizes in one pool and * the number of pool elements per pool are set on construction. * The full amount of memory is allocated on construction. @@ -31,7 +28,6 @@ * It is possible to store empty packets in the pool. * The local pool is NOT thread-safe. */ - template class LocalPool: public SystemObject, public StorageManagerIF { public: @@ -55,9 +51,10 @@ public: * number of elements for each pool is determined. * The position of these values correspond to those in * element_sizes. - * @param registered Register the pool in object manager or not. Default is false (local pool). - * @param spillsToHigherPools - * A variable to determine whether higher n pools are used if the store is full. + * @param registered Register the pool in object manager or not. + * Default is false (local pool). + * @param spillsToHigherPools A variable to determine whether + * higher n pools are used if the store is full. */ LocalPool(object_id_t setObjectId, const uint16_t element_sizes[NUMBER_OF_POOLS], @@ -117,7 +114,7 @@ private: /** * @brief store represents the actual memory pool. * @details It is an array of pointers to memory, which was allocated with - * a \c new call on construction. + * a @c new call on construction. */ uint8_t* store[NUMBER_OF_POOLS]; /** diff --git a/storagemanager/PoolManager.h b/storagemanager/PoolManager.h index 6e6c7613..67534cc5 100644 --- a/storagemanager/PoolManager.h +++ b/storagemanager/PoolManager.h @@ -15,17 +15,17 @@ template class PoolManager : public LocalPool { public: - PoolManager( object_id_t setObjectId, const uint16_t element_sizes[NUMBER_OF_POOLS], - const uint16_t n_elements[NUMBER_OF_POOLS] ); - /** - * @brief In the PoolManager's destructor all allocated memory is freed. - */ + PoolManager(object_id_t setObjectId, + const uint16_t element_sizes[NUMBER_OF_POOLS], + const uint16_t n_elements[NUMBER_OF_POOLS]); + + //! @brief In the PoolManager's destructor all allocated memory is freed. virtual ~PoolManager(); + //! @brief LocalPool overrides for thread-safety. ReturnValue_t deleteData(store_address_t) override; ReturnValue_t deleteData(uint8_t* buffer, size_t size, store_address_t* storeId = NULL) override; - ReturnValue_t modifyData(store_address_t packet_id, uint8_t** packet_ptr, size_t* size) override; protected: diff --git a/storagemanager/StorageManagerIF.h b/storagemanager/StorageManagerIF.h index d85fe86f..c29ffb70 100644 --- a/storagemanager/StorageManagerIF.h +++ b/storagemanager/StorageManagerIF.h @@ -6,8 +6,9 @@ #include /** - * This union defines the type that identifies where a data packet is - * stored in the store. It comprises of a raw part to read it as raw value and + * @brief This union defines the type that identifies where a data packet is + * stored in the store. + * It consists of a raw part to read it as raw value and * a structured part to use it in pool-like stores. */ union store_address_t { @@ -15,9 +16,9 @@ union store_address_t { * Default Constructor, initializing to INVALID_ADDRESS */ store_address_t():raw(0xFFFFFFFF){} + /** * Constructor to create an address object using the raw address - * * @param rawAddress */ store_address_t(uint32_t rawAddress):raw(rawAddress){} @@ -30,7 +31,8 @@ union store_address_t { * @param packetIndex */ store_address_t(uint16_t poolIndex, uint16_t packetIndex): - pool_index(poolIndex),packet_index(packetIndex){} + pool_index(poolIndex),packet_index(packetIndex) {} + /** * A structure with two elements to access the store address pool-like. */ @@ -154,7 +156,6 @@ public: * Use with care! */ virtual void clearStore() = 0; - }; #endif /* STORAGEMANAGERIF_H_ */ From 3f79450b19a2ae9ae07e4e02743cb16dde2751fc Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 11 May 2020 12:00:30 +0200 Subject: [PATCH 006/307] removed config include, new retvals, nullptr check --- objectmanager/ObjectManagerIF.h | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/objectmanager/ObjectManagerIF.h b/objectmanager/ObjectManagerIF.h index aca24a24..3575fc16 100644 --- a/objectmanager/ObjectManagerIF.h +++ b/objectmanager/ObjectManagerIF.h @@ -9,9 +9,9 @@ #define OBJECTMANAGERIF_H_ #include -#include #include #include +#include /** * @brief This class provides an interface to the global object manager. @@ -24,9 +24,12 @@ */ class ObjectManagerIF : public HasReturnvaluesIF { public: - static const uint8_t INTERFACE_ID = CLASS_ID::OBJECT_MANAGER_IF; - static const ReturnValue_t INSERTION_FAILED = MAKE_RETURN_CODE( 1 ); - static const ReturnValue_t NOT_FOUND = MAKE_RETURN_CODE( 2 ); + static constexpr uint8_t INTERFACE_ID = CLASS_ID::OBJECT_MANAGER_IF; + static constexpr ReturnValue_t INSERTION_FAILED = MAKE_RETURN_CODE( 1 ); + static constexpr ReturnValue_t NOT_FOUND = MAKE_RETURN_CODE( 2 ); + static constexpr ReturnValue_t CHILD_INIT_FAILED = MAKE_RETURN_CODE( 3 ); + static constexpr ReturnValue_t INTERNAL_ERR_REPORTER_UNINIT = MAKE_RETURN_CODE( 4 ); + protected: /** * @brief This method is used to hide the template-based get call from @@ -78,15 +81,22 @@ public: virtual void printList() = 0; }; -template -T* ObjectManagerIF::get( object_id_t id ) { - SystemObjectIF* temp = this->getSystemObject(id); - return dynamic_cast(temp); -} /** * @brief This is the forward declaration of the global objectManager instance. */ extern ObjectManagerIF *objectManager; +/*Documentation can be found in the class method declaration above.*/ +template +T* ObjectManagerIF::get( object_id_t id ) { + if(objectManager == nullptr) { + sif::error << "ObjectManagerIF: Global object manager has not " + "been initialized yet!" << std::endl; + std::exit(0); + } + SystemObjectIF* temp = this->getSystemObject(id); + return dynamic_cast(temp); +} + #endif /* OBJECTMANAGERIF_H_ */ From a6e0ab61eaf221b8ff6d25b5fa80dd50284653c6 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 15 May 2020 18:54:14 +0200 Subject: [PATCH 007/307] printer fixes --- globalfunctions/printer.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/globalfunctions/printer.cpp b/globalfunctions/printer.cpp index df98568e..5af4346b 100644 --- a/globalfunctions/printer.cpp +++ b/globalfunctions/printer.cpp @@ -20,15 +20,17 @@ void printer::printHex(uint8_t *data, size_t size) { } } sif::info << std::dec; - sif::info << " ] " << std::endl; + sif::info << "]" << std::endl; } void printer::printDec(uint8_t *data, size_t size) { + sif::info << std::dec; for(size_t i = 0; i < size; i++) { sif::info << "0x" << static_cast(data[i]); if(i < size - 1){ sif::info << " , "; } } + sif::info << "]" << std::endl; } From d6cc0892619b86bd8356e14dd210a1e8022bd840 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 15 May 2020 18:56:39 +0200 Subject: [PATCH 008/307] removed StorageAccessor prefiremoved StorageAccessor prefixx --- globalfunctions/printer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/globalfunctions/printer.cpp b/globalfunctions/printer.cpp index 5af4346b..bf4c5848 100644 --- a/globalfunctions/printer.cpp +++ b/globalfunctions/printer.cpp @@ -2,7 +2,7 @@ #include void printer::print(uint8_t *data, size_t size, OutputType type) { - sif::info << "StorageAccessor: Printing data with size " << size << ": ["; + sif::info << "Printing data with size " << size << ": ["; if(type == OutputType::HEX) { printer::printHex(data, size); } From a0cb3a9b6b620d883d996713aaf7a27ced1e2b01 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 17 May 2020 17:13:43 +0200 Subject: [PATCH 009/307] changed cast to be comptaible with newer freeRTOS --- osal/FreeRTOS/MessageQueue.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osal/FreeRTOS/MessageQueue.cpp b/osal/FreeRTOS/MessageQueue.cpp index e5da0442..18e7aa3d 100644 --- a/osal/FreeRTOS/MessageQueue.cpp +++ b/osal/FreeRTOS/MessageQueue.cpp @@ -97,7 +97,8 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, bool ignoreFault) { message->setSender(sentFrom); - BaseType_t result = xQueueSendToBack(reinterpret_cast(sendTo),reinterpret_cast(message->getBuffer()), 0); + BaseType_t result = xQueueSendToBack(reinterpret_cast(sendTo), + reinterpret_cast(message->getBuffer()), 0); if (result != pdPASS) { if (!ignoreFault) { InternalErrorReporterIF* internalErrorReporter = objectManager->get( From 5482b71b3cec697fc7becf3aae6925feea6c394c Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 19 May 2020 19:52:35 +0200 Subject: [PATCH 010/307] improved printer --- globalfunctions/printer.cpp | 24 +++++++++++++++++------- globalfunctions/printer.h | 7 ++++--- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/globalfunctions/printer.cpp b/globalfunctions/printer.cpp index bf4c5848..01ec532c 100644 --- a/globalfunctions/printer.cpp +++ b/globalfunctions/printer.cpp @@ -1,36 +1,46 @@ #include #include -void printer::print(uint8_t *data, size_t size, OutputType type) { - sif::info << "Printing data with size " << size << ": ["; +void printer::print(uint8_t *data, size_t size, OutputType type, bool printInfo, + size_t maxCharPerLine) { + if(printInfo) { + sif::info << "Printing data with size " << size << ": "; + } + sif::info << "["; if(type == OutputType::HEX) { - printer::printHex(data, size); + printer::printHex(data, size, maxCharPerLine); } else { - printer::printDec(data, size); + printer::printDec(data, size, maxCharPerLine); } } -void printer::printHex(uint8_t *data, size_t size) { +void printer::printHex(uint8_t *data, size_t size, size_t maxCharPerLine) { sif::info << std::hex; for(size_t i = 0; i < size; i++) { sif::info << "0x" << static_cast(data[i]); if(i < size - 1){ sif::info << " , "; + if(i > 0 and i % maxCharPerLine == 0) { + sif::info << std::endl; + } } + } sif::info << std::dec; sif::info << "]" << std::endl; } -void printer::printDec(uint8_t *data, size_t size) { +void printer::printDec(uint8_t *data, size_t size, size_t maxCharPerLine) { sif::info << std::dec; for(size_t i = 0; i < size; i++) { sif::info << "0x" << static_cast(data[i]); if(i < size - 1){ sif::info << " , "; + if(i > 0 and i % maxCharPerLine == 0) { + sif::info << std::endl; + } } } sif::info << "]" << std::endl; } - diff --git a/globalfunctions/printer.h b/globalfunctions/printer.h index 3c9d6aa0..db9f343f 100644 --- a/globalfunctions/printer.h +++ b/globalfunctions/printer.h @@ -10,9 +10,10 @@ enum class OutputType { HEX }; -void print(uint8_t* data, size_t size, OutputType type = OutputType::HEX); -void printHex(uint8_t* data, size_t size); -void printDec(uint8_t* data, size_t size); +void print(uint8_t* data, size_t size, OutputType type = OutputType::HEX, + bool printInfo = true, size_t maxCharPerLine = 12); +void printHex(uint8_t* data, size_t size, size_t maxCharPerLine = 12); +void printDec(uint8_t* data, size_t size, size_t maxCharPerLine = 12); } #endif /* FRAMEWORK_GLOBALFUNCTIONS_PRINTER_H_ */ From e2e6ec28c0cac7f79ff301481cd803fbfe8bbc7f Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 19 May 2020 20:26:12 +0200 Subject: [PATCH 011/307] printer fixes and improvements --- globalfunctions/printer.cpp | 12 +++++++----- globalfunctions/printer.h | 6 +++--- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/globalfunctions/printer.cpp b/globalfunctions/printer.cpp index 01ec532c..b71d70b8 100644 --- a/globalfunctions/printer.cpp +++ b/globalfunctions/printer.cpp @@ -1,8 +1,8 @@ #include #include -void printer::print(uint8_t *data, size_t size, OutputType type, bool printInfo, - size_t maxCharPerLine) { +void printer::print(const uint8_t *data, size_t size, OutputType type, + bool printInfo, size_t maxCharPerLine) { if(printInfo) { sif::info << "Printing data with size " << size << ": "; } @@ -15,7 +15,8 @@ void printer::print(uint8_t *data, size_t size, OutputType type, bool printInfo, } } -void printer::printHex(uint8_t *data, size_t size, size_t maxCharPerLine) { +void printer::printHex(const uint8_t *data, size_t size, + size_t maxCharPerLine) { sif::info << std::hex; for(size_t i = 0; i < size; i++) { sif::info << "0x" << static_cast(data[i]); @@ -31,10 +32,11 @@ void printer::printHex(uint8_t *data, size_t size, size_t maxCharPerLine) { sif::info << "]" << std::endl; } -void printer::printDec(uint8_t *data, size_t size, size_t maxCharPerLine) { +void printer::printDec(const uint8_t *data, size_t size, + size_t maxCharPerLine) { sif::info << std::dec; for(size_t i = 0; i < size; i++) { - sif::info << "0x" << static_cast(data[i]); + sif::info << static_cast(data[i]); if(i < size - 1){ sif::info << " , "; if(i > 0 and i % maxCharPerLine == 0) { diff --git a/globalfunctions/printer.h b/globalfunctions/printer.h index db9f343f..76d28e5f 100644 --- a/globalfunctions/printer.h +++ b/globalfunctions/printer.h @@ -10,10 +10,10 @@ enum class OutputType { HEX }; -void print(uint8_t* data, size_t size, OutputType type = OutputType::HEX, +void print(const uint8_t* data, size_t size, OutputType type = OutputType::HEX, bool printInfo = true, size_t maxCharPerLine = 12); -void printHex(uint8_t* data, size_t size, size_t maxCharPerLine = 12); -void printDec(uint8_t* data, size_t size, size_t maxCharPerLine = 12); +void printHex(const uint8_t* data, size_t size, size_t maxCharPerLine = 12); +void printDec(const uint8_t* data, size_t size, size_t maxCharPerLine = 12); } #endif /* FRAMEWORK_GLOBALFUNCTIONS_PRINTER_H_ */ From 6961b5e8663df1775b994553a1b7d5a63d01f318 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 19 May 2020 23:08:17 +0200 Subject: [PATCH 012/307] bin printer added --- globalfunctions/printer.cpp | 15 ++++++++++++++- globalfunctions/printer.h | 4 +++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/globalfunctions/printer.cpp b/globalfunctions/printer.cpp index b71d70b8..a68a91ee 100644 --- a/globalfunctions/printer.cpp +++ b/globalfunctions/printer.cpp @@ -1,5 +1,6 @@ #include #include +#include void printer::print(const uint8_t *data, size_t size, OutputType type, bool printInfo, size_t maxCharPerLine) { @@ -10,9 +11,12 @@ void printer::print(const uint8_t *data, size_t size, OutputType type, if(type == OutputType::HEX) { printer::printHex(data, size, maxCharPerLine); } - else { + else if (type == OutputType::DEC) { printer::printDec(data, size, maxCharPerLine); } + else if(type == OutputType::BIN) { + printer::printBin(data, size); + } } void printer::printHex(const uint8_t *data, size_t size, @@ -46,3 +50,12 @@ void printer::printDec(const uint8_t *data, size_t size, } sif::info << "]" << std::endl; } + +void printer::printBin(const uint8_t *data, size_t size) { + sif::info << "\n" << std::flush; + for(size_t i = 0; i < size; i++) { + sif::info << "Byte " << i + 1 << ": 0b"<< + std::bitset<8>(data[i]) << ",\n" << std::flush; + } + sif::info << "]" << std::endl; +} diff --git a/globalfunctions/printer.h b/globalfunctions/printer.h index 76d28e5f..33a382ec 100644 --- a/globalfunctions/printer.h +++ b/globalfunctions/printer.h @@ -7,13 +7,15 @@ namespace printer { enum class OutputType { DEC, - HEX + HEX, + BIN }; void print(const uint8_t* data, size_t size, OutputType type = OutputType::HEX, bool printInfo = true, size_t maxCharPerLine = 12); void printHex(const uint8_t* data, size_t size, size_t maxCharPerLine = 12); void printDec(const uint8_t* data, size_t size, size_t maxCharPerLine = 12); +void printBin(const uint8_t* data, size_t size); } #endif /* FRAMEWORK_GLOBALFUNCTIONS_PRINTER_H_ */ From 71e103e2b6ce2623fba150aa77c907719863d5ed Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 20 May 2020 14:40:50 +0200 Subject: [PATCH 013/307] better include guards --- storagemanager/LocalPool.tpp | 4 ++-- storagemanager/PoolManager.tpp | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/storagemanager/LocalPool.tpp b/storagemanager/LocalPool.tpp index 649ec88a..6c4a7d6a 100644 --- a/storagemanager/LocalPool.tpp +++ b/storagemanager/LocalPool.tpp @@ -1,5 +1,5 @@ -#ifndef LOCALPOOL_TPP -#define LOCALPOOL_TPP +#ifndef FRAMEWORK_STORAGEMANAGER_LOCALPOOL_H_ +#define FRAMEWORK_STORAGEMANAGER_LOCALPOOL_H_ template inline LocalPool::LocalPool(object_id_t setObjectId, diff --git a/storagemanager/PoolManager.tpp b/storagemanager/PoolManager.tpp index ed340b91..26eb2270 100644 --- a/storagemanager/PoolManager.tpp +++ b/storagemanager/PoolManager.tpp @@ -1,3 +1,6 @@ +#ifndef FRAMEWORK_STORAGEMANAGER_POOLMANAGER_TPP_ +#define FRAMEWORK_STORAGEMANAGER_POOLMANAGER_TPP_ + template inline PoolManager::PoolManager(object_id_t setObjectId, const uint16_t element_sizes[NUMBER_OF_POOLS], @@ -48,3 +51,5 @@ inline ReturnValue_t PoolManager::modifyData( packet_ptr, size); return status; } + +#endif From 3a6b7f48959ca8648cc5f770873283dcea37ed81 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 20 May 2020 14:42:52 +0200 Subject: [PATCH 014/307] added new cast for MQ --- osal/FreeRTOS/MessageQueue.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osal/FreeRTOS/MessageQueue.cpp b/osal/FreeRTOS/MessageQueue.cpp index e5da0442..18e7aa3d 100644 --- a/osal/FreeRTOS/MessageQueue.cpp +++ b/osal/FreeRTOS/MessageQueue.cpp @@ -97,7 +97,8 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, bool ignoreFault) { message->setSender(sentFrom); - BaseType_t result = xQueueSendToBack(reinterpret_cast(sendTo),reinterpret_cast(message->getBuffer()), 0); + BaseType_t result = xQueueSendToBack(reinterpret_cast(sendTo), + reinterpret_cast(message->getBuffer()), 0); if (result != pdPASS) { if (!ignoreFault) { InternalErrorReporterIF* internalErrorReporter = objectManager->get( From 91acc471b64a337c3d87fe90022f48deb662368c Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 20 May 2020 14:47:58 +0200 Subject: [PATCH 015/307] include guard fix, sif replacements --- storagemanager/LocalPool.tpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/storagemanager/LocalPool.tpp b/storagemanager/LocalPool.tpp index 6c4a7d6a..08685de2 100644 --- a/storagemanager/LocalPool.tpp +++ b/storagemanager/LocalPool.tpp @@ -1,5 +1,5 @@ -#ifndef FRAMEWORK_STORAGEMANAGER_LOCALPOOL_H_ -#define FRAMEWORK_STORAGEMANAGER_LOCALPOOL_H_ +#ifndef FRAMEWORK_STORAGEMANAGER_LOCALPOOL_TPP_ +#define FRAMEWORK_STORAGEMANAGER_LOCALPOOL_TPP_ template inline LocalPool::LocalPool(object_id_t setObjectId, @@ -83,7 +83,7 @@ inline ReturnValue_t LocalPool::reserveSpace( const uint32_t size, store_address_t* address, bool ignoreFault) { ReturnValue_t status = getPoolIndex(size, &address->pool_index); if (status != RETURN_OK) { - error << "LocalPool( " << std::hex << getObjectId() << std::dec + sif::error << "LocalPool( " << std::hex << getObjectId() << std::dec << " )::reserveSpace: Packet too large." << std::endl; return status; } @@ -193,7 +193,7 @@ inline ReturnValue_t LocalPool::deleteData( size_list[packet_id.pool_index][packet_id.packet_index] = STORAGE_FREE; } else { //pool_index or packet_index is too large - error << "LocalPool:deleteData failed." << std::endl; + sif::error << "LocalPool:deleteData failed." << std::endl; status = ILLEGAL_STORAGE_ID; } return status; @@ -249,7 +249,7 @@ inline ReturnValue_t LocalPool::initialize() { //Check if any pool size is large than the maximum allowed. for (uint8_t count = 0; count < NUMBER_OF_POOLS; count++) { if (element_sizes[count] >= STORAGE_FREE) { - error << "LocalPool::initialize: Pool is too large! " + sif::error << "LocalPool::initialize: Pool is too large! " "Max. allowed size is: " << (STORAGE_FREE - 1) << std::endl; return RETURN_FAILED; } From 2030415adbb8b18cda2337beaa5686e6219b8be5 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 29 May 2020 17:17:46 +0200 Subject: [PATCH 016/307] added back include, but header needs to be included from build system now, which allows multiple config folders --- objectmanager/ObjectManagerIF.h | 1 + 1 file changed, 1 insertion(+) diff --git a/objectmanager/ObjectManagerIF.h b/objectmanager/ObjectManagerIF.h index 3575fc16..b5cab408 100644 --- a/objectmanager/ObjectManagerIF.h +++ b/objectmanager/ObjectManagerIF.h @@ -8,6 +8,7 @@ #ifndef OBJECTMANAGERIF_H_ #define OBJECTMANAGERIF_H_ +#include "systemObjectList.h" #include #include #include From c8a36a79de45c228e7071cc827423e0b4a383998 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 31 May 2020 00:23:38 +0200 Subject: [PATCH 017/307] corrected doc for task factory interface --- osal/FreeRTOS/FixedTimeslotTask.h | 19 +++++++++------- tasks/TaskFactory.h | 36 ++++++++++++++----------------- 2 files changed, 27 insertions(+), 28 deletions(-) diff --git a/osal/FreeRTOS/FixedTimeslotTask.h b/osal/FreeRTOS/FixedTimeslotTask.h index 1ab8724f..fe93daff 100644 --- a/osal/FreeRTOS/FixedTimeslotTask.h +++ b/osal/FreeRTOS/FixedTimeslotTask.h @@ -10,15 +10,18 @@ class FixedTimeslotTask: public FixedTimeslotTaskIF { public: + /** - * @brief The standard constructor of the class. - * - * @details This is the general constructor of the class. In addition to the TaskBase parameters, - * the following variables are passed: - * - * @param (*setDeadlineMissedFunc)() The function pointer to the deadline missed function that shall be assigned. - * - * @param getPst The object id of the completely initialized polling sequence. + * Keep in Mind that you need to call before this vTaskStartScheduler()! + * A lot of task parameters are set in "FreeRTOSConfig.h". + * @param name Name of the task, lenght limited by configMAX_TASK_NAME_LEN + * @param setPriority Number of priorities specified by + * configMAX_PRIORITIES. High taskPriority_ number means high priority. + * @param setStack Stack size in words (not bytes!). + * Lower limit specified by configMINIMAL_STACK_SIZE + * @param overallPeriod Period in seconds. + * @param setDeadlineMissedFunc Callback if a deadline was missed. + * @return Pointer to the newly created task. */ FixedTimeslotTask(const char *name, TaskPriority setPriority, TaskStackSize setStack, TaskPeriod overallPeriod, diff --git a/tasks/TaskFactory.h b/tasks/TaskFactory.h index f7afa4a2..e1e2f5e2 100644 --- a/tasks/TaskFactory.h +++ b/tasks/TaskFactory.h @@ -19,16 +19,14 @@ public: static TaskFactory* instance(); /** - * Keep in Mind that you need to call before this vTaskStartScheduler()! - * A lot of task parameters are set in "FreeRTOSConfig.h". - * @param name_ Name of the task, lenght limited by configMAX_TASK_NAME_LEN - * @param taskPriority_ Number of priorities specified by - * configMAX_PRIORITIES. High taskPriority_ number means high priority. - * @param stackSize_ Stack size in words (not bytes!). - * Lower limit specified by configMINIMAL_STACK_SIZE - * @param period_ Period in seconds. - * @param deadLineMissedFunction_ Callback if a deadline was missed. - * @return Pointer to the newly created task. + * Generic interface to create a periodic task + * @param name_ Name of the task + * @param taskPriority_ Priority of the task + * @param stackSize_ Stack size if the task + * @param periodInSeconds_ Period in seconds + * @param deadLineMissedFunction_ This function is called if a deadline was + * missed + * @return Pointer to the created periodic task class */ PeriodicTaskIF* createPeriodicTask(TaskName name_, TaskPriority taskPriority_, TaskStackSize stackSize_, @@ -36,16 +34,14 @@ public: TaskDeadlineMissedFunction deadLineMissedFunction_); /** - * Keep in Mind that you need to call before this vTaskStartScheduler()! - * A lot of task parameters are set in "FreeRTOSConfig.h". - * @param name_ Name of the task, lenght limited by configMAX_TASK_NAME_LEN - * @param taskPriority_ Number of priorities specified by - * configMAX_PRIORITIES. High taskPriority_ number means high priority. - * @param stackSize_ Stack size in words (not bytes!). - * Lower limit specified by configMINIMAL_STACK_SIZE - * @param period_ Period in seconds. - * @param deadLineMissedFunction_ Callback if a deadline was missed. - * @return Pointer to the newly created task. + * Generic interface to create a fixed timeslot task + * @param name_ Name of the task + * @param taskPriority_ Priority of the task + * @param stackSize_ Stack size if the task + * @param periodInSeconds_ Period in seconds + * @param deadLineMissedFunction_ This function is called if a deadline was + * missed + * @return Pointer to the created periodic task class */ FixedTimeslotTaskIF* createFixedTimeslotTask(TaskName name_, TaskPriority taskPriority_, TaskStackSize stackSize_, From 42f0687a6bcf0f1c947ef00dfeea95fa3e060af8 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 31 May 2020 23:28:51 +0200 Subject: [PATCH 018/307] self deletion nullptr --- osal/FreeRTOS/TaskFactory.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osal/FreeRTOS/TaskFactory.cpp b/osal/FreeRTOS/TaskFactory.cpp index 6b18d7a8..663b0531 100644 --- a/osal/FreeRTOS/TaskFactory.cpp +++ b/osal/FreeRTOS/TaskFactory.cpp @@ -34,9 +34,9 @@ FixedTimeslotTaskIF* TaskFactory::createFixedTimeslotTask(TaskName name_, } ReturnValue_t TaskFactory::deleteTask(PeriodicTaskIF* task) { - if (task == NULL) { + if (task == nullptr) { //delete self - vTaskDelete(NULL); + vTaskDelete(nullptr); return HasReturnvaluesIF::RETURN_OK; } else { //TODO not implemented From de6ed5c0859e528b798fdb214cf62b7a3143762e Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 2 Jun 2020 15:57:04 +0200 Subject: [PATCH 019/307] improved include guard and removed old comment --- osal/FreeRTOS/PeriodicTask.h | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/osal/FreeRTOS/PeriodicTask.h b/osal/FreeRTOS/PeriodicTask.h index 4ece20b3..a449328e 100644 --- a/osal/FreeRTOS/PeriodicTask.h +++ b/osal/FreeRTOS/PeriodicTask.h @@ -1,5 +1,5 @@ -#ifndef PERIODICTASK_H_ -#define PERIODICTASK_H_ +#ifndef FRAMEWORK_OSAL_FREERTOS_PERIODICTASK_H_ +#define FRAMEWORK_OSAL_FREERTOS_PERIODICTASK_H_ #include #include @@ -17,8 +17,6 @@ class ExecutableObjectIF; /** * @brief This class represents a specialized task for * periodic activities of multiple objects. - * @details - * * @ingroup task_handling */ class PeriodicTask: public PeriodicTaskIF { @@ -26,24 +24,25 @@ public: /** * @brief Standard constructor of the class. * @details - * The class is initialized without allocated objects. These need to be added - * with #addComponent. In the underlying TaskBase class, a new operating - * system task is created. In addition to the TaskBase parameters, - * the period, the pointer to the aforementioned initialization function and - * an optional "deadline-missed" function pointer is passed. - * @param priority Sets the priority of a task. Values depend on - * freeRTOS configuration, high number means high priority. - * @param stack_size The stack size reserved by the operating system for the task. - * @param setPeriod The length of the period with which the task's + * The class is initialized without allocated objects. + * These need to be added with #addComponent. + * @param priority + * Sets the priority of a task. Values depend on freeRTOS configuration, + * high number means high priority. + * @param stack_size + * The stack size reserved by the operating system for the task. + * @param setPeriod + * The length of the period with which the task's * functionality will be executed. It is expressed in clock ticks. * @param setDeadlineMissedFunc - * The function pointer to the deadline missed function that shall be assigned. + * The function pointer to the deadline missed function that shall + * be assigned. */ PeriodicTask(const char *name, TaskPriority setPriority, TaskStackSize setStack, TaskPeriod setPeriod,void (*setDeadlineMissedFunc)()); /** - * @brief Currently, the executed object's lifetime is not coupled with the task object's - * lifetime, so the destructor is empty. + * @brief Currently, the executed object's lifetime is not coupled with + * the task object's lifetime, so the destructor is empty. */ virtual ~PeriodicTask(void); From f0a25b5e2b0e26e549145ff429fc707a5f7c6bb3 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 2 Jun 2020 22:10:34 +0200 Subject: [PATCH 020/307] new timeout values for MUtexIF and SemaphIF --- ipc/MutexIF.h | 17 +++++++++++++++-- tasks/SemaphoreIF.h | 19 +++++++++++++++---- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/ipc/MutexIF.h b/ipc/MutexIF.h index dcb1cf33..29e59e58 100644 --- a/ipc/MutexIF.h +++ b/ipc/MutexIF.h @@ -12,8 +12,21 @@ */ class MutexIF { public: - static const uint32_t NO_TIMEOUT; //!< Needs to be defined in implementation. - static const uint32_t MAX_TIMEOUT; + /** + * @brief Timeout value used for polling lock attempt. + * @details + * If the lock is not successfull, MUTEX_TIMEOUT will be returned + * immediately. Value needs to be defined in implementation. + */ + static const uint32_t POLLING; + /** + * @brief Timeout value used for permanent blocking lock attempt. + * @details + * The task will be blocked (indefinitely) until the mutex is unlocked. + * Value needs to be defined in implementation. + */ + static const uint32_t BLOCKING; + static const uint8_t INTERFACE_ID = CLASS_ID::MUTEX_IF; /** * The system lacked the necessary resources (other than memory) to initialize another mutex. diff --git a/tasks/SemaphoreIF.h b/tasks/SemaphoreIF.h index a7c5a97b..4fc92ebd 100644 --- a/tasks/SemaphoreIF.h +++ b/tasks/SemaphoreIF.h @@ -21,10 +21,21 @@ class SemaphoreIF { public: virtual~ SemaphoreIF() {}; - //! Needs to be defined in implementation. No blocking time - static const uint32_t NO_TIMEOUT; - //! Needs to be defined in implementation. Blocks indefinitely. - static const uint32_t MAX_TIMEOUT; + /** + * @brief Timeout value used for polling lock attempt. + * @details + * If the lock is not successfull, MUTEX_TIMEOUT will be returned + * immediately. Value needs to be defined in implementation. + */ + static const uint32_t POLLING; + /** + * @brief Timeout value used for permanent blocking lock attempt. + * @details + * The task will be blocked (indefinitely) until the mutex is unlocked. + * Value needs to be defined in implementation. + */ + static const uint32_t BLOCKING; + static const uint8_t INTERFACE_ID = CLASS_ID::SEMAPHORE_IF; //! Semaphore timeout static constexpr ReturnValue_t SEMAPHORE_TIMEOUT = MAKE_RETURN_CODE(1); From 986dc2047e7ef0f52ebe8bd54fdf7f0fd565a518 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 2 Jun 2020 22:19:48 +0200 Subject: [PATCH 021/307] replaced mutexIF and semaphoreIF name for timeouts --- datapoolglob/GlobalDataPool.cpp | 2 +- events/EventManager.cpp | 2 +- health/HealthTable.cpp | 12 ++++++------ internalError/InternalErrorReporter.cpp | 18 +++++++++--------- osal/FreeRTOS/BinSemaphUsingTask.cpp | 8 ++++---- osal/FreeRTOS/BinSemaphUsingTask.h | 4 ++-- osal/FreeRTOS/BinarySemaphore.cpp | 8 ++++---- osal/FreeRTOS/BinarySemaphore.h | 4 ++-- osal/FreeRTOS/Clock.cpp | 4 ++-- osal/FreeRTOS/CountingSemaphUsingTask.cpp | 8 ++++---- osal/FreeRTOS/CountingSemaphUsingTask.h | 4 ++-- osal/FreeRTOS/Mutex.cpp | 12 ++++++------ osal/FreeRTOS/Mutex.h | 2 +- osal/FreeRTOS/SemaphoreFactory.cpp | 4 ++-- storagemanager/PoolManager.tpp | 6 +++--- 15 files changed, 49 insertions(+), 49 deletions(-) diff --git a/datapoolglob/GlobalDataPool.cpp b/datapoolglob/GlobalDataPool.cpp index e13765ba..18780904 100644 --- a/datapoolglob/GlobalDataPool.cpp +++ b/datapoolglob/GlobalDataPool.cpp @@ -54,7 +54,7 @@ ReturnValue_t GlobalDataPool::freeDataPoolLock() { } ReturnValue_t GlobalDataPool::lockDataPool() { - ReturnValue_t status = mutex->lockMutex(MutexIF::NO_TIMEOUT); + ReturnValue_t status = mutex->lockMutex(MutexIF::BLOCKING); if ( status != RETURN_OK ) { sif::error << "DataPool::DataPool: lock of mutex failed " "with error code: " << status << std::endl; diff --git a/events/EventManager.cpp b/events/EventManager.cpp index bff15e3c..73e77e94 100644 --- a/events/EventManager.cpp +++ b/events/EventManager.cpp @@ -151,7 +151,7 @@ void EventManager::printEvent(EventMessage* message) { #endif void EventManager::lockMutex() { - mutex->lockMutex(MutexIF::NO_TIMEOUT); + mutex->lockMutex(MutexIF::BLOCKING); } void EventManager::unlockMutex() { diff --git a/health/HealthTable.cpp b/health/HealthTable.cpp index 94b7cf0b..5d9f5c61 100644 --- a/health/HealthTable.cpp +++ b/health/HealthTable.cpp @@ -26,7 +26,7 @@ ReturnValue_t HealthTable::registerObject(object_id_t object, void HealthTable::setHealth(object_id_t object, HasHealthIF::HealthState newState) { - mutex->lockMutex(MutexIF::NO_TIMEOUT); + mutex->lockMutex(MutexIF::BLOCKING); HealthMap::iterator iter = healthMap.find(object); if (iter != healthMap.end()) { iter->second = newState; @@ -36,7 +36,7 @@ void HealthTable::setHealth(object_id_t object, HasHealthIF::HealthState HealthTable::getHealth(object_id_t object) { HasHealthIF::HealthState state = HasHealthIF::HEALTHY; - mutex->lockMutex(MutexIF::NO_TIMEOUT); + mutex->lockMutex(MutexIF::BLOCKING); HealthMap::iterator iter = healthMap.find(object); if (iter != healthMap.end()) { state = iter->second; @@ -46,7 +46,7 @@ HasHealthIF::HealthState HealthTable::getHealth(object_id_t object) { } uint32_t HealthTable::getPrintSize() { - mutex->lockMutex(MutexIF::NO_TIMEOUT); + mutex->lockMutex(MutexIF::BLOCKING); uint32_t size = healthMap.size() * 5 + 2; mutex->unlockMutex(); return size; @@ -54,7 +54,7 @@ uint32_t HealthTable::getPrintSize() { bool HealthTable::hasHealth(object_id_t object) { bool exits = false; - mutex->lockMutex(MutexIF::NO_TIMEOUT); + mutex->lockMutex(MutexIF::BLOCKING); HealthMap::iterator iter = healthMap.find(object); if (iter != healthMap.end()) { exits = true; @@ -64,7 +64,7 @@ bool HealthTable::hasHealth(object_id_t object) { } void HealthTable::printAll(uint8_t* pointer, uint32_t maxSize) { - mutex->lockMutex(MutexIF::NO_TIMEOUT); + mutex->lockMutex(MutexIF::BLOCKING); size_t size = 0; uint16_t count = healthMap.size(); ReturnValue_t result = SerializeAdapter::serialize(&count, @@ -85,7 +85,7 @@ void HealthTable::printAll(uint8_t* pointer, uint32_t maxSize) { ReturnValue_t HealthTable::iterate( std::pair *value, bool reset) { ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; - mutex->lockMutex(MutexIF::NO_TIMEOUT); + mutex->lockMutex(MutexIF::BLOCKING); if (reset) { mapIterator = healthMap.begin(); } diff --git a/internalError/InternalErrorReporter.cpp b/internalError/InternalErrorReporter.cpp index 30a02b44..8944553d 100644 --- a/internalError/InternalErrorReporter.cpp +++ b/internalError/InternalErrorReporter.cpp @@ -53,7 +53,7 @@ void InternalErrorReporter::lostTm() { uint32_t InternalErrorReporter::getAndResetQueueHits() { uint32_t value; - mutex->lockMutex(MutexIF::NO_TIMEOUT); + mutex->lockMutex(MutexIF::BLOCKING); value = queueHits; queueHits = 0; mutex->unlockMutex(); @@ -62,21 +62,21 @@ uint32_t InternalErrorReporter::getAndResetQueueHits() { uint32_t InternalErrorReporter::getQueueHits() { uint32_t value; - mutex->lockMutex(MutexIF::NO_TIMEOUT); + mutex->lockMutex(MutexIF::BLOCKING); value = queueHits; mutex->unlockMutex(); return value; } void InternalErrorReporter::incrementQueueHits() { - mutex->lockMutex(MutexIF::NO_TIMEOUT); + mutex->lockMutex(MutexIF::BLOCKING); queueHits++; mutex->unlockMutex(); } uint32_t InternalErrorReporter::getAndResetTmHits() { uint32_t value; - mutex->lockMutex(MutexIF::NO_TIMEOUT); + mutex->lockMutex(MutexIF::BLOCKING); value = tmHits; tmHits = 0; mutex->unlockMutex(); @@ -85,14 +85,14 @@ uint32_t InternalErrorReporter::getAndResetTmHits() { uint32_t InternalErrorReporter::getTmHits() { uint32_t value; - mutex->lockMutex(MutexIF::NO_TIMEOUT); + mutex->lockMutex(MutexIF::BLOCKING); value = tmHits; mutex->unlockMutex(); return value; } void InternalErrorReporter::incrementTmHits() { - mutex->lockMutex(MutexIF::NO_TIMEOUT); + mutex->lockMutex(MutexIF::BLOCKING); tmHits++; mutex->unlockMutex(); } @@ -103,7 +103,7 @@ void InternalErrorReporter::storeFull() { uint32_t InternalErrorReporter::getAndResetStoreHits() { uint32_t value; - mutex->lockMutex(MutexIF::NO_TIMEOUT); + mutex->lockMutex(MutexIF::BLOCKING); value = storeHits; storeHits = 0; mutex->unlockMutex(); @@ -112,14 +112,14 @@ uint32_t InternalErrorReporter::getAndResetStoreHits() { uint32_t InternalErrorReporter::getStoreHits() { uint32_t value; - mutex->lockMutex(MutexIF::NO_TIMEOUT); + mutex->lockMutex(MutexIF::BLOCKING); value = storeHits; mutex->unlockMutex(); return value; } void InternalErrorReporter::incrementStoreHits() { - mutex->lockMutex(MutexIF::NO_TIMEOUT); + mutex->lockMutex(MutexIF::BLOCKING); storeHits++; mutex->unlockMutex(); } diff --git a/osal/FreeRTOS/BinSemaphUsingTask.cpp b/osal/FreeRTOS/BinSemaphUsingTask.cpp index 8f5fd4d8..d3351888 100644 --- a/osal/FreeRTOS/BinSemaphUsingTask.cpp +++ b/osal/FreeRTOS/BinSemaphUsingTask.cpp @@ -17,11 +17,11 @@ BinarySemaphoreUsingTask::~BinarySemaphoreUsingTask() { } ReturnValue_t BinarySemaphoreUsingTask::acquire(uint32_t timeoutMs) { - TickType_t timeout = SemaphoreIF::NO_TIMEOUT; - if(timeoutMs == SemaphoreIF::MAX_TIMEOUT) { - timeout = SemaphoreIF::MAX_TIMEOUT; + TickType_t timeout = SemaphoreIF::POLLING; + if(timeoutMs == SemaphoreIF::BLOCKING) { + timeout = SemaphoreIF::BLOCKING; } - else if(timeoutMs > SemaphoreIF::NO_TIMEOUT){ + else if(timeoutMs > SemaphoreIF::POLLING){ timeout = pdMS_TO_TICKS(timeoutMs); } return acquireWithTickTimeout(timeout); diff --git a/osal/FreeRTOS/BinSemaphUsingTask.h b/osal/FreeRTOS/BinSemaphUsingTask.h index 48c1cd12..43772e5a 100644 --- a/osal/FreeRTOS/BinSemaphUsingTask.h +++ b/osal/FreeRTOS/BinSemaphUsingTask.h @@ -26,7 +26,7 @@ public: virtual~ BinarySemaphoreUsingTask(); ReturnValue_t acquire(uint32_t timeoutMs = - SemaphoreIF::NO_TIMEOUT) override; + SemaphoreIF::BLOCKING) override; ReturnValue_t release() override; uint8_t getSemaphoreCounter() const override; static uint8_t getSemaphoreCounter(TaskHandle_t taskHandle); @@ -40,7 +40,7 @@ public: * - @c RETURN_FAILED on failure */ ReturnValue_t acquireWithTickTimeout(TickType_t timeoutTicks = - SemaphoreIF::NO_TIMEOUT); + SemaphoreIF::BLOCKING); /** * Get handle to the task related to the semaphore. diff --git a/osal/FreeRTOS/BinarySemaphore.cpp b/osal/FreeRTOS/BinarySemaphore.cpp index b6687bb7..e6d2f92f 100644 --- a/osal/FreeRTOS/BinarySemaphore.cpp +++ b/osal/FreeRTOS/BinarySemaphore.cpp @@ -36,11 +36,11 @@ BinarySemaphore& BinarySemaphore::operator =( } ReturnValue_t BinarySemaphore::acquire(uint32_t timeoutMs) { - TickType_t timeout = SemaphoreIF::NO_TIMEOUT; - if(timeoutMs == SemaphoreIF::MAX_TIMEOUT) { - timeout = SemaphoreIF::MAX_TIMEOUT; + TickType_t timeout = SemaphoreIF::POLLING; + if(timeoutMs == SemaphoreIF::BLOCKING) { + timeout = SemaphoreIF::BLOCKING; } - else if(timeoutMs > SemaphoreIF::NO_TIMEOUT){ + else if(timeoutMs > SemaphoreIF::POLLING){ timeout = pdMS_TO_TICKS(timeoutMs); } return acquireWithTickTimeout(timeout); diff --git a/osal/FreeRTOS/BinarySemaphore.h b/osal/FreeRTOS/BinarySemaphore.h index 0938dee6..2a372cd2 100644 --- a/osal/FreeRTOS/BinarySemaphore.h +++ b/osal/FreeRTOS/BinarySemaphore.h @@ -53,7 +53,7 @@ public: * -@c SemaphoreIF::SEMAPHORE_TIMEOUT on timeout */ ReturnValue_t acquire(uint32_t timeoutMs = - SemaphoreIF::NO_TIMEOUT) override; + SemaphoreIF::BLOCKING) override; /** * Same as lockBinarySemaphore() with timeout in FreeRTOS ticks. @@ -62,7 +62,7 @@ public: * -@c SemaphoreIF::SEMAPHORE_TIMEOUT on timeout */ ReturnValue_t acquireWithTickTimeout(TickType_t timeoutTicks = - BinarySemaphore::NO_TIMEOUT); + SemaphoreIF::BLOCKING); /** * Release the binary semaphore. diff --git a/osal/FreeRTOS/Clock.cpp b/osal/FreeRTOS/Clock.cpp index dce20265..ec07b662 100644 --- a/osal/FreeRTOS/Clock.cpp +++ b/osal/FreeRTOS/Clock.cpp @@ -155,7 +155,7 @@ ReturnValue_t Clock::setLeapSeconds(const uint16_t leapSeconds_) { if (checkOrCreateClockMutex() != HasReturnvaluesIF::RETURN_OK) { return HasReturnvaluesIF::RETURN_FAILED; } - ReturnValue_t result = timeMutex->lockMutex(MutexIF::NO_TIMEOUT); + ReturnValue_t result = timeMutex->lockMutex(MutexIF::BLOCKING); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } @@ -170,7 +170,7 @@ ReturnValue_t Clock::getLeapSeconds(uint16_t* leapSeconds_) { if (timeMutex == NULL) { return HasReturnvaluesIF::RETURN_FAILED; } - ReturnValue_t result = timeMutex->lockMutex(MutexIF::NO_TIMEOUT); + ReturnValue_t result = timeMutex->lockMutex(MutexIF::BLOCKING); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } diff --git a/osal/FreeRTOS/CountingSemaphUsingTask.cpp b/osal/FreeRTOS/CountingSemaphUsingTask.cpp index d0f63f3f..f33c7a0d 100644 --- a/osal/FreeRTOS/CountingSemaphUsingTask.cpp +++ b/osal/FreeRTOS/CountingSemaphUsingTask.cpp @@ -38,11 +38,11 @@ CountingSemaphoreUsingTask::~CountingSemaphoreUsingTask() { } ReturnValue_t CountingSemaphoreUsingTask::acquire(uint32_t timeoutMs) { - TickType_t timeout = SemaphoreIF::NO_TIMEOUT; - if(timeoutMs == SemaphoreIF::MAX_TIMEOUT) { - timeout = SemaphoreIF::MAX_TIMEOUT; + TickType_t timeout = SemaphoreIF::POLLING; + if(timeoutMs == SemaphoreIF::BLOCKING) { + timeout = SemaphoreIF::BLOCKING; } - else if(timeoutMs > SemaphoreIF::NO_TIMEOUT){ + else if(timeoutMs > SemaphoreIF::POLLING){ timeout = pdMS_TO_TICKS(timeoutMs); } return acquireWithTickTimeout(timeout); diff --git a/osal/FreeRTOS/CountingSemaphUsingTask.h b/osal/FreeRTOS/CountingSemaphUsingTask.h index 797e864b..f1d82c1d 100644 --- a/osal/FreeRTOS/CountingSemaphUsingTask.h +++ b/osal/FreeRTOS/CountingSemaphUsingTask.h @@ -31,7 +31,7 @@ public: * @return -@c RETURN_OK on success * -@c SemaphoreIF::SEMAPHORE_TIMEOUT on timeout */ - ReturnValue_t acquire(uint32_t timeoutMs = SemaphoreIF::NO_TIMEOUT) override; + ReturnValue_t acquire(uint32_t timeoutMs = SemaphoreIF::BLOCKING) override; /** * Release a semaphore, increasing the number of available counting @@ -61,7 +61,7 @@ public: * -@c SemaphoreIF::SEMAPHORE_TIMEOUT on timeout */ ReturnValue_t acquireWithTickTimeout( - TickType_t timeoutTicks = SemaphoreIF::NO_TIMEOUT); + TickType_t timeoutTicks = SemaphoreIF::BLOCKING); /** * Get handle to the task related to the semaphore. diff --git a/osal/FreeRTOS/Mutex.cpp b/osal/FreeRTOS/Mutex.cpp index cc2f865f..6d90c3f6 100644 --- a/osal/FreeRTOS/Mutex.cpp +++ b/osal/FreeRTOS/Mutex.cpp @@ -2,8 +2,8 @@ #include -const uint32_t MutexIF::NO_TIMEOUT = 0; -const uint32_t MutexIF::MAX_TIMEOUT = portMAX_DELAY; +const uint32_t MutexIF::POLLING = 0; +const uint32_t MutexIF::BLOCKING = portMAX_DELAY; Mutex::Mutex() { handle = xSemaphoreCreateMutex(); @@ -23,11 +23,11 @@ ReturnValue_t Mutex::lockMutex(uint32_t timeoutMs) { if (handle == nullptr) { return MutexIF::MUTEX_NOT_FOUND; } - TickType_t timeout = MutexIF::NO_TIMEOUT; - if(timeoutMs == MutexIF::MAX_TIMEOUT) { - timeout = MutexIF::MAX_TIMEOUT; + TickType_t timeout = MutexIF::POLLING; + if(timeoutMs == MutexIF::BLOCKING) { + timeout = MutexIF::BLOCKING; } - else if(timeoutMs > MutexIF::NO_TIMEOUT){ + else if(timeoutMs > MutexIF::POLLING){ timeout = pdMS_TO_TICKS(timeoutMs); } diff --git a/osal/FreeRTOS/Mutex.h b/osal/FreeRTOS/Mutex.h index 90e82467..d6e0aab9 100644 --- a/osal/FreeRTOS/Mutex.h +++ b/osal/FreeRTOS/Mutex.h @@ -18,7 +18,7 @@ class Mutex : public MutexIF { public: Mutex(); ~Mutex(); - ReturnValue_t lockMutex(uint32_t timeoutMs = MutexIF::MAX_TIMEOUT) override; + ReturnValue_t lockMutex(uint32_t timeoutMs = MutexIF::BLOCKING) override; ReturnValue_t unlockMutex() override; private: SemaphoreHandle_t handle; diff --git a/osal/FreeRTOS/SemaphoreFactory.cpp b/osal/FreeRTOS/SemaphoreFactory.cpp index 05a898cd..caf984f2 100644 --- a/osal/FreeRTOS/SemaphoreFactory.cpp +++ b/osal/FreeRTOS/SemaphoreFactory.cpp @@ -6,8 +6,8 @@ #include SemaphoreFactory* SemaphoreFactory::factoryInstance = nullptr; -const uint32_t SemaphoreIF::NO_TIMEOUT = 0; -const uint32_t SemaphoreIF::MAX_TIMEOUT = portMAX_DELAY; +const uint32_t SemaphoreIF::POLLING= 0; +const uint32_t SemaphoreIF::BLOCKING = portMAX_DELAY; static const uint32_t USE_REGULAR_SEMAPHORES = 0; static const uint32_t USE_TASK_NOTIFICATIONS = 1; diff --git a/storagemanager/PoolManager.tpp b/storagemanager/PoolManager.tpp index 29b2b82a..9fb11776 100644 --- a/storagemanager/PoolManager.tpp +++ b/storagemanager/PoolManager.tpp @@ -21,7 +21,7 @@ inline PoolManager::~PoolManager(void) { template inline ReturnValue_t PoolManager::reserveSpace( const uint32_t size, store_address_t* address, bool ignoreFault) { - MutexHelper mutexHelper(mutex,MutexIF::NO_TIMEOUT); + MutexHelper mutexHelper(mutex,MutexIF::BLOCKING); ReturnValue_t status = LocalPool::reserveSpace(size, address,ignoreFault); return status; @@ -33,7 +33,7 @@ inline ReturnValue_t PoolManager::deleteData( // debug << "PoolManager( " << translateObject(getObjectId()) << // " )::deleteData from store " << packet_id.pool_index << // ". id is "<< packet_id.packet_index << std::endl; - MutexHelper mutexHelper(mutex,MutexIF::NO_TIMEOUT); + MutexHelper mutexHelper(mutex,MutexIF::BLOCKING); ReturnValue_t status = LocalPool::deleteData(packet_id); return status; } @@ -41,7 +41,7 @@ inline ReturnValue_t PoolManager::deleteData( template inline ReturnValue_t PoolManager::deleteData(uint8_t* buffer, size_t size, store_address_t* storeId) { - MutexHelper mutexHelper(mutex,MutexIF::NO_TIMEOUT); + MutexHelper mutexHelper(mutex,MutexIF::BLOCKING); ReturnValue_t status = LocalPool::deleteData(buffer, size, storeId); return status; From 54edeacb2d20dcd5a01c0a11e3337b18fb3cf364 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 2 Jun 2020 22:25:28 +0200 Subject: [PATCH 022/307] changed names for linux --- osal/FreeRTOS/SemaphoreFactory.cpp | 2 +- osal/linux/BinarySemaphore.cpp | 6 +++--- osal/linux/BinarySemaphore.h | 2 +- osal/linux/Clock.cpp | 4 ++-- osal/linux/Mutex.cpp | 5 +++-- osal/linux/SemaphoreFactory.cpp | 4 ++-- 6 files changed, 12 insertions(+), 11 deletions(-) diff --git a/osal/FreeRTOS/SemaphoreFactory.cpp b/osal/FreeRTOS/SemaphoreFactory.cpp index caf984f2..78427f6c 100644 --- a/osal/FreeRTOS/SemaphoreFactory.cpp +++ b/osal/FreeRTOS/SemaphoreFactory.cpp @@ -6,7 +6,7 @@ #include SemaphoreFactory* SemaphoreFactory::factoryInstance = nullptr; -const uint32_t SemaphoreIF::POLLING= 0; +const uint32_t SemaphoreIF::POLLING = 0; const uint32_t SemaphoreIF::BLOCKING = portMAX_DELAY; static const uint32_t USE_REGULAR_SEMAPHORES = 0; diff --git a/osal/linux/BinarySemaphore.cpp b/osal/linux/BinarySemaphore.cpp index 7c76a5c4..e2ad9b58 100644 --- a/osal/linux/BinarySemaphore.cpp +++ b/osal/linux/BinarySemaphore.cpp @@ -27,13 +27,13 @@ BinarySemaphore& BinarySemaphore::operator =( ReturnValue_t BinarySemaphore::acquire(uint32_t timeoutMs) { int result = 0; - if(timeoutMs == SemaphoreIF::NO_TIMEOUT) { + if(timeoutMs == SemaphoreIF::POLLING) { result = sem_trywait(&handle); } - else if(timeoutMs == SemaphoreIF::MAX_TIMEOUT) { + else if(timeoutMs == SemaphoreIF::BLOCKING) { result = sem_wait(&handle); } - else if(timeoutMs > SemaphoreIF::NO_TIMEOUT){ + else if(timeoutMs > SemaphoreIF::POLLING){ timespec timeOut; clock_gettime(CLOCK_REALTIME, &timeOut); uint64_t nseconds = timeOut.tv_sec * 1000000000 + timeOut.tv_nsec; diff --git a/osal/linux/BinarySemaphore.h b/osal/linux/BinarySemaphore.h index 7836cd41..9d4ed1cd 100644 --- a/osal/linux/BinarySemaphore.h +++ b/osal/linux/BinarySemaphore.h @@ -50,7 +50,7 @@ public: * -@c SemaphoreIF::SEMAPHORE_TIMEOUT on timeout */ ReturnValue_t acquire(uint32_t timeoutMs = - SemaphoreIF::NO_TIMEOUT) override; + SemaphoreIF::BLOCKING) override; /** * Release the binary semaphore. diff --git a/osal/linux/Clock.cpp b/osal/linux/Clock.cpp index 630b2cf4..eda5b7af 100644 --- a/osal/linux/Clock.cpp +++ b/osal/linux/Clock.cpp @@ -179,7 +179,7 @@ ReturnValue_t Clock::setLeapSeconds(const uint16_t leapSeconds_) { if(checkOrCreateClockMutex()!=HasReturnvaluesIF::RETURN_OK){ return HasReturnvaluesIF::RETURN_FAILED; } - ReturnValue_t result = timeMutex->lockMutex(MutexIF::NO_TIMEOUT); + ReturnValue_t result = timeMutex->lockMutex(MutexIF::BLOCKING); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } @@ -194,7 +194,7 @@ ReturnValue_t Clock::getLeapSeconds(uint16_t* leapSeconds_) { if(timeMutex==NULL){ return HasReturnvaluesIF::RETURN_FAILED; } - ReturnValue_t result = timeMutex->lockMutex(MutexIF::NO_TIMEOUT); + ReturnValue_t result = timeMutex->lockMutex(MutexIF::BLOCKING); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } diff --git a/osal/linux/Mutex.cpp b/osal/linux/Mutex.cpp index b4773267..bdcf3439 100644 --- a/osal/linux/Mutex.cpp +++ b/osal/linux/Mutex.cpp @@ -2,7 +2,8 @@ #include #include -const uint32_t MutexIF::NO_TIMEOUT = 0; +const uint32_t MutexIF::BLOCKING = 0xffffffff; +const uint32_t MutexIF::POLLING = 0; uint8_t Mutex::count = 0; @@ -41,7 +42,7 @@ Mutex::~Mutex() { ReturnValue_t Mutex::lockMutex(uint32_t timeoutMs) { int status = 0; - if (timeoutMs != MutexIF::NO_TIMEOUT) { + if (timeoutMs != MutexIF::BLOCKING) { timespec timeOut; clock_gettime(CLOCK_REALTIME, &timeOut); uint64_t nseconds = timeOut.tv_sec * 1000000000 + timeOut.tv_nsec; diff --git a/osal/linux/SemaphoreFactory.cpp b/osal/linux/SemaphoreFactory.cpp index 5aec84ea..4fbd60d9 100644 --- a/osal/linux/SemaphoreFactory.cpp +++ b/osal/linux/SemaphoreFactory.cpp @@ -3,8 +3,8 @@ #include #include -const uint32_t SemaphoreIF::NO_TIMEOUT = 0; -const uint32_t SemaphoreIF::MAX_TIMEOUT = 0xFFFFFFFF; +const uint32_t SemaphoreIF::POLLING = 0; +const uint32_t SemaphoreIF::BLOCKING = 0xffffffff; SemaphoreFactory* SemaphoreFactory::factoryInstance = nullptr; From 6972e72fbf2a1a5f9dd1adae9c8274ecb1119581 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 2 Jun 2020 23:52:31 +0200 Subject: [PATCH 023/307] fixed order --- ipc/FwMessageTypes.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ipc/FwMessageTypes.h b/ipc/FwMessageTypes.h index 07e3d245..b59319aa 100644 --- a/ipc/FwMessageTypes.h +++ b/ipc/FwMessageTypes.h @@ -14,8 +14,9 @@ enum FW_MESSAGE_TYPE { MONITORING, MEMORY, PARAMETER, + FILE_SYSTEM_MESSAGE, FW_MESSAGES_COUNT, - FILE_SYSTEM_MESSAGE + }; } From 5036cdbef3f23cc878c2ce09f66fc648fd34bbe5 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 2 Jun 2020 23:54:24 +0200 Subject: [PATCH 024/307] queue factory first param uint32_t again --- ipc/QueueFactory.h | 2 +- osal/FreeRTOS/QueueFactory.cpp | 2 +- osal/linux/QueueFactory.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ipc/QueueFactory.h b/ipc/QueueFactory.h index 9a883fd8..09259ae3 100644 --- a/ipc/QueueFactory.h +++ b/ipc/QueueFactory.h @@ -18,7 +18,7 @@ public: */ static QueueFactory* instance(); - MessageQueueIF* createMessageQueue(size_t messageDepth = 3, + MessageQueueIF* createMessageQueue(uint32_t messageDepth = 3, size_t maxMessageSize = MessageQueueMessage::MAX_MESSAGE_SIZE); void deleteMessageQueue(MessageQueueIF* queue); diff --git a/osal/FreeRTOS/QueueFactory.cpp b/osal/FreeRTOS/QueueFactory.cpp index a4ee5cf3..372d0d41 100644 --- a/osal/FreeRTOS/QueueFactory.cpp +++ b/osal/FreeRTOS/QueueFactory.cpp @@ -26,7 +26,7 @@ QueueFactory::QueueFactory() { QueueFactory::~QueueFactory() { } -MessageQueueIF* QueueFactory::createMessageQueue(size_t messageDepth, +MessageQueueIF* QueueFactory::createMessageQueue(uint32_t messageDepth, size_t maxMessageSize) { return new MessageQueue(messageDepth, maxMessageSize); } diff --git a/osal/linux/QueueFactory.cpp b/osal/linux/QueueFactory.cpp index 2bacb815..268d0b99 100644 --- a/osal/linux/QueueFactory.cpp +++ b/osal/linux/QueueFactory.cpp @@ -28,7 +28,7 @@ QueueFactory::QueueFactory() { QueueFactory::~QueueFactory() { } -MessageQueueIF* QueueFactory::createMessageQueue(size_t messageDepth, +MessageQueueIF* QueueFactory::createMessageQueue(uint32_t messageDepth, size_t maxMessageSize) { return new MessageQueue(messageDepth, maxMessageSize); } From 3483dff2abf171f85f61e498c6ce3c10131783ff Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 3 Jun 2020 22:56:03 +0200 Subject: [PATCH 025/307] some more interface improvements --- serviceinterface/ServiceInterfaceBuffer.cpp | 87 ++++++++++++--------- serviceinterface/ServiceInterfaceBuffer.h | 50 ++++++++---- serviceinterface/ServiceInterfaceStream.cpp | 12 ++- serviceinterface/ServiceInterfaceStream.h | 29 +++++-- 4 files changed, 119 insertions(+), 59 deletions(-) diff --git a/serviceinterface/ServiceInterfaceBuffer.cpp b/serviceinterface/ServiceInterfaceBuffer.cpp index 2a97ab90..b0abb929 100644 --- a/serviceinterface/ServiceInterfaceBuffer.cpp +++ b/serviceinterface/ServiceInterfaceBuffer.cpp @@ -3,9 +3,42 @@ #include // to be implemented by bsp -extern "C" void printChar(const char*); +extern "C" void printChar(const char*, bool errStream); + +#ifndef UT699 + +ServiceInterfaceBuffer::ServiceInterfaceBuffer(std::string setMessage, + bool errStream, bool addCrToPreamble, uint16_t port): + isActive(true), logMessage(setMessage), + addCrToPreamble(addCrToPreamble), errStream(errStream) { + if(not errStream) { + // Set pointers if the stream is buffered. + setp( buf, buf + BUF_SIZE ); + } +} + +void ServiceInterfaceBuffer::putChars(char const* begin, char const* end) { + char array[BUF_SIZE]; + uint32_t length = end - begin; + if (length > sizeof(array)) { + length = sizeof(array); + } + memcpy(array, begin, length); + + for(; begin != end; begin++){ + printChar(begin, false); + } +} + +#endif int ServiceInterfaceBuffer::overflow(int c) { + if(errStream) { + if (c != Traits::eof()) { + printChar(reinterpret_cast(&c), true); + } + return 0; + } // Handle output putChars(pbase(), pptr()); if (c != Traits::eof()) { @@ -20,18 +53,13 @@ int ServiceInterfaceBuffer::overflow(int c) { } int ServiceInterfaceBuffer::sync(void) { + if(errStream) { + return 0; + } + if (this->isActive) { - Clock::TimeOfDay_t loggerTime; - Clock::getDateAndTime(&loggerTime); - std::string preamble; - if(addCrToPreamble) { - preamble += "\r"; - } - preamble += log_message + ": | " + zero_padded(loggerTime.hour, 2) - + ":" + zero_padded(loggerTime.minute, 2) + ":" - + zero_padded(loggerTime.second, 2) + "." - + zero_padded(loggerTime.usecond/1000, 3) + " | "; - // Write log_message and time + auto preamble = getPreamble(); + // Write logMessage and time this->putChars(preamble.c_str(), preamble.c_str() + preamble.size()); // Handle output this->putChars(pbase(), pptr()); @@ -42,31 +70,20 @@ int ServiceInterfaceBuffer::sync(void) { } - -#ifndef UT699 - -ServiceInterfaceBuffer::ServiceInterfaceBuffer(std::string set_message, - uint16_t port, bool addCrToPreamble) { - this->addCrToPreamble = addCrToPreamble; - this->log_message = set_message; - this->isActive = true; - setp( buf, buf + BUF_SIZE ); +std::string ServiceInterfaceBuffer::getPreamble() { + Clock::TimeOfDay_t loggerTime; + Clock::getDateAndTime(&loggerTime); + std::string preamble; + if(addCrToPreamble) { + preamble += "\r"; + } + preamble += logMessage + ": | " + zero_padded(loggerTime.hour, 2) + + ":" + zero_padded(loggerTime.minute, 2) + ":" + + zero_padded(loggerTime.second, 2) + "." + + zero_padded(loggerTime.usecond/1000, 3) + " | "; + return preamble; } -void ServiceInterfaceBuffer::putChars(char const* begin, char const* end) { - char array[BUF_SIZE]; - uint32_t length = end - begin; - if (length > sizeof(array)) { - length = sizeof(array); - } - memcpy(array, begin, length); - - for(; begin != end; begin++){ - printChar(begin); - } - -} -#endif #ifdef UT699 diff --git a/serviceinterface/ServiceInterfaceBuffer.h b/serviceinterface/ServiceInterfaceBuffer.h index a2bc4f4b..74facafe 100644 --- a/serviceinterface/ServiceInterfaceBuffer.h +++ b/serviceinterface/ServiceInterfaceBuffer.h @@ -3,43 +3,64 @@ #include #include -#include #include #ifndef UT699 + +/** + * @brief This is the underlying stream buffer which implements the + * streambuf class and overloads the overflow() and sync() methods + * @details + * This class is used to modify the output of the stream, for example by adding. + * It also calls the char printing function which is implemented in the + * board supply package (BSP). + */ class ServiceInterfaceBuffer: - public std::basic_streambuf> { + public std::streambuf { friend class ServiceInterfaceStream; public: - ServiceInterfaceBuffer(std::string set_message, uint16_t port, - bool addCrToPreamble); + ServiceInterfaceBuffer(std::string setMessage, bool errStream, + bool addCrToPreamble, uint16_t port); + protected: bool isActive; - // This is called when buffer becomes full. If - // buffer is not used, then this is called every - // time when characters are put to stream. + //! This is called when buffer becomes full. If + //! buffer is not used, then this is called every + //! time when characters are put to stream. int overflow(int c = Traits::eof()) override; - // This function is called when stream is flushed, - // for example when std::endl is put to stream. + //! This function is called when stream is flushed, + //! for example when std::endl is put to stream. int sync(void) override; private: - // For additional message information - std::string log_message; + //! For additional message information + std::string logMessage; // For EOF detection typedef std::char_traits Traits; - // This is useful for some terminal programs which do not have - // implicit carriage return with newline characters. + //! This is useful for some terminal programs which do not have + //! implicit carriage return with newline characters. bool addCrToPreamble; + //! This specifies to print to stderr and work in unbuffered mode. + bool errStream; // Work in buffer mode. It is also possible to work without buffer. static size_t const BUF_SIZE = 128; char buf[BUF_SIZE]; - // In this function, the characters are parsed. + //! In this function, the characters are parsed. void putChars(char const* begin, char const* end); + std::string getPreamble(); + + /** + * This helper function returns the zero padded string version of a number. + * The type is deduced automatically. + * @tparam T + * @param num + * @param width + * @return + */ template std::string zero_padded(const T& num, uint8_t width) { std::ostringstream string_to_pad; @@ -52,6 +73,7 @@ private: return result; } }; + #endif diff --git a/serviceinterface/ServiceInterfaceStream.cpp b/serviceinterface/ServiceInterfaceStream.cpp index 40f52f1f..78371548 100644 --- a/serviceinterface/ServiceInterfaceStream.cpp +++ b/serviceinterface/ServiceInterfaceStream.cpp @@ -1,11 +1,15 @@ #include +ServiceInterfaceStream::ServiceInterfaceStream(std::string setMessage, + bool errStream, bool addCrToPreamble, uint16_t port) : + std::ostream(&buf), + buf(setMessage, errStream, addCrToPreamble, port) { +} + void ServiceInterfaceStream::setActive( bool myActive) { this->buf.isActive = myActive; } -ServiceInterfaceStream::ServiceInterfaceStream(std::string set_message, - bool addCrToPreamble, uint16_t port) : - std::basic_ostream>(&buf), - buf(set_message, port, addCrToPreamble) { +std::string ServiceInterfaceStream::getPreamble() { + return buf.getPreamble(); } diff --git a/serviceinterface/ServiceInterfaceStream.h b/serviceinterface/ServiceInterfaceStream.h index a445dced..52ac1310 100644 --- a/serviceinterface/ServiceInterfaceStream.h +++ b/serviceinterface/ServiceInterfaceStream.h @@ -3,11 +3,9 @@ #include #include -#include -#include #include -// Unfortunately, there must be a forward declaration of log_fe +// Unfortunately, there must be a forward declaration of the log front end // (MUST be defined in main), to let the system know where to write to. namespace sif { extern std::ostream debug; @@ -18,13 +16,32 @@ extern std::ostream error; class ServiceInterfaceStream : - public std::basic_ostream> { + public std::ostream { protected: ServiceInterfaceBuffer buf; public: - ServiceInterfaceStream( std::string set_message, - bool addCrToPreamble = false, uint16_t port = 1234); + /** + * This constructor is used by specifying the preamble message. + * Optionally, the output can be directed to stderr and a CR character + * can be prepended to the preamble. + * @param set_message + * @param errStream + * @param addCrToPreamble + * @param port + */ + ServiceInterfaceStream(std::string setMessage, + bool errStream = false, bool addCrToPreamble = false, + uint16_t port = 1234); + + //! An inactive stream will not print anything. void setActive( bool ); + + /** + * This can be used to retrieve the preamble in case it should be printed in + * the unbuffered mode. + * @return Preamle consisting of log message and timestamp. + */ + std::string getPreamble(); }; From 1c0ca4c329c99caa75f438745b53a53f2978cd30 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 3 Jun 2020 23:02:23 +0200 Subject: [PATCH 026/307] some changes to take care of activity --- serviceinterface/ServiceInterfaceBuffer.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/serviceinterface/ServiceInterfaceBuffer.cpp b/serviceinterface/ServiceInterfaceBuffer.cpp index b0abb929..93de88b3 100644 --- a/serviceinterface/ServiceInterfaceBuffer.cpp +++ b/serviceinterface/ServiceInterfaceBuffer.cpp @@ -33,7 +33,7 @@ void ServiceInterfaceBuffer::putChars(char const* begin, char const* end) { #endif int ServiceInterfaceBuffer::overflow(int c) { - if(errStream) { + if(errStream and this->isActive) { if (c != Traits::eof()) { printChar(reinterpret_cast(&c), true); } @@ -53,17 +53,18 @@ int ServiceInterfaceBuffer::overflow(int c) { } int ServiceInterfaceBuffer::sync(void) { - if(errStream) { + if(not this->isActive or errStream) { + if(not errStream) { + setp(buf, buf + BUF_SIZE - 1); + } return 0; } - if (this->isActive) { - auto preamble = getPreamble(); - // Write logMessage and time - this->putChars(preamble.c_str(), preamble.c_str() + preamble.size()); - // Handle output - this->putChars(pbase(), pptr()); - } + auto preamble = getPreamble(); + // Write logMessage and time + this->putChars(preamble.c_str(), preamble.c_str() + preamble.size()); + // Handle output + this->putChars(pbase(), pptr()); // This tells that buffer is empty again setp(buf, buf + BUF_SIZE - 1); return 0; From 5b93799ea659b0b93bd769657c0d00c390786e26 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 3 Jun 2020 23:10:04 +0200 Subject: [PATCH 027/307] added forward declarations for service interface streams --- serviceinterface/ServiceInterfaceStream.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/serviceinterface/ServiceInterfaceStream.h b/serviceinterface/ServiceInterfaceStream.h index 52ac1310..aecd45c3 100644 --- a/serviceinterface/ServiceInterfaceStream.h +++ b/serviceinterface/ServiceInterfaceStream.h @@ -44,5 +44,13 @@ public: std::string getPreamble(); }; +// Forward declaration of interface streams. These are needed so the public +// functions can be used by including this header +namespace sif { +extern ServiceInterfaceStream debugStream; +extern ServiceInterfaceStream infoStream; +extern ServiceInterfaceStream warningStream; +extern ServiceInterfaceStream errorStream; +} #endif /* FRAMEWORK_SERVICEINTERFACE_SERVICEINTERFACESTREAM_H_ */ From 0a512abc3364855116a4756e42aeac33c0aa2fe2 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 3 Jun 2020 23:26:27 +0200 Subject: [PATCH 028/307] additional clarification comment --- serviceinterface/ServiceInterfaceStream.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/serviceinterface/ServiceInterfaceStream.h b/serviceinterface/ServiceInterfaceStream.h index aecd45c3..32437d81 100644 --- a/serviceinterface/ServiceInterfaceStream.h +++ b/serviceinterface/ServiceInterfaceStream.h @@ -7,6 +7,9 @@ // Unfortunately, there must be a forward declaration of the log front end // (MUST be defined in main), to let the system know where to write to. +// The ServiceInterfaceStream instances (declared below and instantiated in main) +// can be passed to these front ends by passing their underlying buffers +// with .rdbuf() namespace sif { extern std::ostream debug; extern std::ostream info; From 5eb3d77bdbb1f4537c95d5c6919a0792b8f274e6 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 3 Jun 2020 23:29:00 +0200 Subject: [PATCH 029/307] clarfiying comment --- serviceinterface/ServiceInterfaceStream.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/serviceinterface/ServiceInterfaceStream.h b/serviceinterface/ServiceInterfaceStream.h index 32437d81..375a1875 100644 --- a/serviceinterface/ServiceInterfaceStream.h +++ b/serviceinterface/ServiceInterfaceStream.h @@ -5,11 +5,11 @@ #include #include -// Unfortunately, there must be a forward declaration of the log front end -// (MUST be defined in main), to let the system know where to write to. -// The ServiceInterfaceStream instances (declared below and instantiated in main) -// can be passed to these front ends by passing their underlying buffers -// with .rdbuf() +/* Unfortunately, there must be a forward declaration of the log front end + * (MUST be defined in main), to let the system know where to write to. + * The ServiceInterfaceStream instances, which are declared below and + * can instantaited somewhere else can be passed to these front ends by passing + * their underlying buffers with .rdbuf() */ namespace sif { extern std::ostream debug; extern std::ostream info; From 17ed9b77967f6a8ba2deb281a730df3b33fdadb3 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 3 Jun 2020 23:38:02 +0200 Subject: [PATCH 030/307] OS renamed to OS_FSFW (nameclash with system variable) --- framework.mk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/framework.mk b/framework.mk index cb3e4f22..f2107a4c 100644 --- a/framework.mk +++ b/framework.mk @@ -28,11 +28,11 @@ CXXSRC += $(wildcard $(FRAMEWORK_PATH)/objectmanager/*.cpp) CXXSRC += $(wildcard $(FRAMEWORK_PATH)/osal/*.cpp) # select the OS -ifeq ($(OS),rtems) +ifeq ($(OS_FSFW),rtems) CXXSRC += $(wildcard $(FRAMEWORK_PATH)/osal/rtems/*.cpp) -else ifeq ($(OS),linux) +else ifeq ($(OS_FSFW),linux) CXXSRC += $(wildcard $(FRAMEWORK_PATH)/osal/linux/*.cpp) -else ifeq ($(OS),freeRTOS) +else ifeq ($(OS_FSFW),freeRTOS) CXXSRC += $(wildcard $(FRAMEWORK_PATH)/osal/FreeRTOS/*.cpp) else $(error invalid OS specified, valid OS are rtems, linux, freeRTOS) From 925a54dec965b0c52d312616f9f42902fd5fac2e Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 4 Jun 2020 01:06:03 +0200 Subject: [PATCH 031/307] more improvements for servicei nterface --- serviceinterface/ServiceInterfaceBuffer.cpp | 28 +++++++---- serviceinterface/ServiceInterfaceBuffer.h | 5 +- serviceinterface/ServiceInterfaceStream.cpp | 22 ++++++++- serviceinterface/ServiceInterfaceStream.h | 51 +++++++++++---------- 4 files changed, 69 insertions(+), 37 deletions(-) diff --git a/serviceinterface/ServiceInterfaceBuffer.cpp b/serviceinterface/ServiceInterfaceBuffer.cpp index 93de88b3..92f08cae 100644 --- a/serviceinterface/ServiceInterfaceBuffer.cpp +++ b/serviceinterface/ServiceInterfaceBuffer.cpp @@ -8,10 +8,11 @@ extern "C" void printChar(const char*, bool errStream); #ifndef UT699 ServiceInterfaceBuffer::ServiceInterfaceBuffer(std::string setMessage, - bool errStream, bool addCrToPreamble, uint16_t port): + bool addCrToPreamble, bool buffered , bool errStream, uint16_t port): isActive(true), logMessage(setMessage), - addCrToPreamble(addCrToPreamble), errStream(errStream) { - if(not errStream) { + addCrToPreamble(addCrToPreamble), buffered(buffered), + errStream(errStream) { + if(buffered) { // Set pointers if the stream is buffered. setp( buf, buf + BUF_SIZE ); } @@ -26,16 +27,27 @@ void ServiceInterfaceBuffer::putChars(char const* begin, char const* end) { memcpy(array, begin, length); for(; begin != end; begin++){ - printChar(begin, false); + if(errStream) { + printChar(begin, true); + } + else { + printChar(begin, false); + } + } } #endif int ServiceInterfaceBuffer::overflow(int c) { - if(errStream and this->isActive) { + if(not buffered and this->isActive) { if (c != Traits::eof()) { - printChar(reinterpret_cast(&c), true); + if(errStream) { + printChar(reinterpret_cast(&c), true); + } + else { + printChar(reinterpret_cast(&c), false); + } } return 0; } @@ -53,8 +65,8 @@ int ServiceInterfaceBuffer::overflow(int c) { } int ServiceInterfaceBuffer::sync(void) { - if(not this->isActive or errStream) { - if(not errStream) { + if(not this->isActive) { + if(not buffered) { setp(buf, buf + BUF_SIZE - 1); } return 0; diff --git a/serviceinterface/ServiceInterfaceBuffer.h b/serviceinterface/ServiceInterfaceBuffer.h index 74facafe..e3927007 100644 --- a/serviceinterface/ServiceInterfaceBuffer.h +++ b/serviceinterface/ServiceInterfaceBuffer.h @@ -19,8 +19,8 @@ class ServiceInterfaceBuffer: public std::streambuf { friend class ServiceInterfaceStream; public: - ServiceInterfaceBuffer(std::string setMessage, bool errStream, - bool addCrToPreamble, uint16_t port); + ServiceInterfaceBuffer(std::string setMessage, bool addCrToPreamble, + bool buffered, bool errStream, uint16_t port); protected: bool isActive; @@ -41,6 +41,7 @@ private: //! This is useful for some terminal programs which do not have //! implicit carriage return with newline characters. bool addCrToPreamble; + bool buffered; //! This specifies to print to stderr and work in unbuffered mode. bool errStream; diff --git a/serviceinterface/ServiceInterfaceStream.cpp b/serviceinterface/ServiceInterfaceStream.cpp index 78371548..bef8136e 100644 --- a/serviceinterface/ServiceInterfaceStream.cpp +++ b/serviceinterface/ServiceInterfaceStream.cpp @@ -1,9 +1,9 @@ #include ServiceInterfaceStream::ServiceInterfaceStream(std::string setMessage, - bool errStream, bool addCrToPreamble, uint16_t port) : + bool addCrToPreamble, bool buffered, bool errStream, uint16_t port) : std::ostream(&buf), - buf(setMessage, errStream, addCrToPreamble, port) { + buf(setMessage, addCrToPreamble, buffered, errStream, port) { } void ServiceInterfaceStream::setActive( bool myActive) { @@ -13,3 +13,21 @@ void ServiceInterfaceStream::setActive( bool myActive) { std::string ServiceInterfaceStream::getPreamble() { return buf.getPreamble(); } + +void ServiceInterfaceStream::print(std::string error, + bool withPreamble, bool withNewline, bool flush) { + if(not buffered and withPreamble) { + *this << getPreamble() << error; + } + else { + *this << error; + } + + if(withNewline) { + *this << "\n"; + } + // if mode is non-buffered, no need to flush. + if(flush and buffered) { + this->flush(); + } +} diff --git a/serviceinterface/ServiceInterfaceStream.h b/serviceinterface/ServiceInterfaceStream.h index 375a1875..9b8b5b6e 100644 --- a/serviceinterface/ServiceInterfaceStream.h +++ b/serviceinterface/ServiceInterfaceStream.h @@ -5,19 +5,11 @@ #include #include -/* Unfortunately, there must be a forward declaration of the log front end - * (MUST be defined in main), to let the system know where to write to. - * The ServiceInterfaceStream instances, which are declared below and - * can instantaited somewhere else can be passed to these front ends by passing - * their underlying buffers with .rdbuf() */ -namespace sif { -extern std::ostream debug; -extern std::ostream info; -extern std::ostream warning; -extern std::ostream error; -} - - +/** + * Generic service interface stream which can be used like std::cout or + * std::cerr but has additional capability. Add preamble and timestamp + * to output. Can be run in buffered or unbuffered mode. + */ class ServiceInterfaceStream : public std::ostream { protected: @@ -27,14 +19,14 @@ public: * This constructor is used by specifying the preamble message. * Optionally, the output can be directed to stderr and a CR character * can be prepended to the preamble. - * @param set_message - * @param errStream - * @param addCrToPreamble - * @param port + * @param setMessage message of preamble. + * @param addCrToPreamble Useful for applications like Puttty. + * @param buffered specify whether to use buffered mode. + * @param errStream specify which output stream to use (stderr or stdout). */ ServiceInterfaceStream(std::string setMessage, - bool errStream = false, bool addCrToPreamble = false, - uint16_t port = 1234); + bool addCrToPreamble = false, bool buffered = true, + bool errStream = false, uint16_t port = 1234); //! An inactive stream will not print anything. void setActive( bool ); @@ -45,15 +37,24 @@ public: * @return Preamle consisting of log message and timestamp. */ std::string getPreamble(); + + /** + * This prints an error with a preamble. Useful if using the unbuffered + * mode. Flushes in default mode (prints immediately). + */ + void print(std::string error, bool withPreamble = true, + bool withNewline = true, bool flush = true); + + bool buffered = false; }; -// Forward declaration of interface streams. These are needed so the public -// functions can be used by including this header +// Forward declaration of interface streams. These should be instantiated in +// main. They can then be used like std::cout or std::cerr. namespace sif { -extern ServiceInterfaceStream debugStream; -extern ServiceInterfaceStream infoStream; -extern ServiceInterfaceStream warningStream; -extern ServiceInterfaceStream errorStream; +extern ServiceInterfaceStream debug; +extern ServiceInterfaceStream info; +extern ServiceInterfaceStream warning; +extern ServiceInterfaceStream error; } #endif /* FRAMEWORK_SERVICEINTERFACE_SERVICEINTERFACESTREAM_H_ */ From 05435a3ea3d4775b856debfbaa9f8ae487bc3f20 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 4 Jun 2020 14:11:08 +0200 Subject: [PATCH 032/307] includde removed --- objectmanager/ObjectManagerIF.h | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/objectmanager/ObjectManagerIF.h b/objectmanager/ObjectManagerIF.h index b5cab408..57b2faa7 100644 --- a/objectmanager/ObjectManagerIF.h +++ b/objectmanager/ObjectManagerIF.h @@ -1,14 +1,6 @@ -/** - * @file ObjectManagerIF.h - * @brief This file contains the implementation of the ObjectManagerIF interface - * @date 19.09.2012 - * @author Bastian Baetz - */ +#ifndef FRAMEWORK_OBJECTMANAGER_OBJECTMANAGERIF_H_ +#define FRAMEWORK_OBJECTMANAGER_OBJECTMANAGERIF_H_ -#ifndef OBJECTMANAGERIF_H_ -#define OBJECTMANAGERIF_H_ - -#include "systemObjectList.h" #include #include #include @@ -21,7 +13,8 @@ * inserted, removed and retrieved from the list. On getting the * object, the call checks if the object implements the requested * interface. - * \ingroup system_objects + * @author Bastian Baetz + * @ingroup system_objects */ class ObjectManagerIF : public HasReturnvaluesIF { public: From 93ef4eb56b8fbd172bfba25ebe0b3616c2d99f9d Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 4 Jun 2020 14:13:24 +0200 Subject: [PATCH 033/307] exti code is one --- objectmanager/ObjectManagerIF.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/objectmanager/ObjectManagerIF.h b/objectmanager/ObjectManagerIF.h index 57b2faa7..0dfb7f30 100644 --- a/objectmanager/ObjectManagerIF.h +++ b/objectmanager/ObjectManagerIF.h @@ -87,7 +87,7 @@ T* ObjectManagerIF::get( object_id_t id ) { if(objectManager == nullptr) { sif::error << "ObjectManagerIF: Global object manager has not " "been initialized yet!" << std::endl; - std::exit(0); + std::exit(1); } SystemObjectIF* temp = this->getSystemObject(id); return dynamic_cast(temp); From a115bf1186d075ea8c6b98c03ba847f22d41251b Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 4 Jun 2020 14:43:33 +0200 Subject: [PATCH 034/307] store access improvements --- storagemanager/LocalPool.h | 10 +++++----- storagemanager/PoolManager.h | 3 ++- storagemanager/PoolManager.tpp | 1 - storagemanager/StorageManagerIF.h | 3 ++- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/storagemanager/LocalPool.h b/storagemanager/LocalPool.h index 2d61dea5..bb94a3be 100644 --- a/storagemanager/LocalPool.h +++ b/storagemanager/LocalPool.h @@ -24,7 +24,6 @@ * The local pool is NOT thread-safe. * @author Bastian Baetz */ - template class LocalPool: public SystemObject, public StorageManagerIF { public: @@ -48,9 +47,10 @@ public: * number of elements for each pool is determined. * The position of these values correspond to those in * element_sizes. - * @param registered Register the pool in object manager or not. Default is false (local pool). - * @param spillsToHigherPools - * A variable to determine whether higher n pools are used if the store is full. + * @param registered Register the pool in object manager or not. + * Default is false (local pool). + * @param spillsToHigherPools A variable to determine whether + * higher n pools are used if the store is full. */ LocalPool(object_id_t setObjectId, const uint16_t element_sizes[NUMBER_OF_POOLS], @@ -117,7 +117,7 @@ private: /** * @brief store represents the actual memory pool. * @details It is an array of pointers to memory, which was allocated with - * a \c new call on construction. + * a @c new call on construction. */ uint8_t* store[NUMBER_OF_POOLS]; /** diff --git a/storagemanager/PoolManager.h b/storagemanager/PoolManager.h index c74e95c0..7c2e8a71 100644 --- a/storagemanager/PoolManager.h +++ b/storagemanager/PoolManager.h @@ -12,7 +12,7 @@ * with a lock. * @author Bastian Baetz */ -template +template class PoolManager : public LocalPool { public: PoolManager(object_id_t setObjectId, @@ -27,6 +27,7 @@ public: ReturnValue_t deleteData(store_address_t) override; ReturnValue_t deleteData(uint8_t* buffer, size_t size, store_address_t* storeId = nullptr) override; + protected: ReturnValue_t reserveSpace(const uint32_t size, store_address_t* address, bool ignoreFault) override; diff --git a/storagemanager/PoolManager.tpp b/storagemanager/PoolManager.tpp index 9fb11776..a35b810c 100644 --- a/storagemanager/PoolManager.tpp +++ b/storagemanager/PoolManager.tpp @@ -48,4 +48,3 @@ inline ReturnValue_t PoolManager::deleteData(uint8_t* buffer, } #endif - diff --git a/storagemanager/StorageManagerIF.h b/storagemanager/StorageManagerIF.h index d5ac5818..f8aee819 100644 --- a/storagemanager/StorageManagerIF.h +++ b/storagemanager/StorageManagerIF.h @@ -11,7 +11,6 @@ using AccessorPair = std::pair; using ConstAccessorPair = std::pair; - /** * @brief This class provides an interface for intermediate data storage. * @details The Storage manager classes shall be used to store larger chunks of @@ -80,6 +79,7 @@ public: virtual ReturnValue_t deleteData(uint8_t* buffer, size_t size, store_address_t* storeId = nullptr) = 0; + /** * @brief Access the data by supplying a store ID. * @details @@ -100,6 +100,7 @@ public: virtual ReturnValue_t getData(store_address_t storeId, ConstStorageAccessor& constAccessor) = 0; + /** * @brief getData returns an address to data and the size of the data * for a given packet_id. From 6ff1cf46c5cda5e6c9ecb85926acc68c8825b1ad Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 4 Jun 2020 19:40:43 +0200 Subject: [PATCH 035/307] new service interface stream --- serviceinterface/ServiceInterfaceBuffer.cpp | 46 ++++++++++++++++----- serviceinterface/ServiceInterfaceBuffer.h | 36 +++------------- serviceinterface/ServiceInterfaceStream.cpp | 13 +++--- serviceinterface/ServiceInterfaceStream.h | 32 +++++++------- 4 files changed, 63 insertions(+), 64 deletions(-) diff --git a/serviceinterface/ServiceInterfaceBuffer.cpp b/serviceinterface/ServiceInterfaceBuffer.cpp index 92f08cae..f1332637 100644 --- a/serviceinterface/ServiceInterfaceBuffer.cpp +++ b/serviceinterface/ServiceInterfaceBuffer.cpp @@ -1,6 +1,7 @@ #include #include #include +#include // to be implemented by bsp extern "C" void printChar(const char*, bool errStream); @@ -16,6 +17,8 @@ ServiceInterfaceBuffer::ServiceInterfaceBuffer(std::string setMessage, // Set pointers if the stream is buffered. setp( buf, buf + BUF_SIZE ); } + preamble.reserve(96); + preamble.resize(96); } void ServiceInterfaceBuffer::putChars(char const* begin, char const* end) { @@ -65,16 +68,22 @@ int ServiceInterfaceBuffer::overflow(int c) { } int ServiceInterfaceBuffer::sync(void) { - if(not this->isActive) { + if(not this->isActive and not buffered) { if(not buffered) { setp(buf, buf + BUF_SIZE - 1); } return 0; } + if(not buffered) { + return 0; + } - auto preamble = getPreamble(); + size_t preambleSize = 0; + auto preamble = getPreamble(&preambleSize); + uint8_t debugArray[96]; + memcpy(debugArray, preamble.data(), preambleSize); // Write logMessage and time - this->putChars(preamble.c_str(), preamble.c_str() + preamble.size()); + this->putChars(preamble.data(), preamble.data() + preambleSize); // Handle output this->putChars(pbase(), pptr()); // This tells that buffer is empty again @@ -82,18 +91,35 @@ int ServiceInterfaceBuffer::sync(void) { return 0; } +bool ServiceInterfaceBuffer::isBuffered() const { + return buffered; +} -std::string ServiceInterfaceBuffer::getPreamble() { +std::string ServiceInterfaceBuffer::getPreamble(size_t * preambleSize) { Clock::TimeOfDay_t loggerTime; Clock::getDateAndTime(&loggerTime); - std::string preamble; + std::string preamble (96, 0); + size_t currentSize = 0; + char* parsePosition = &preamble[0]; if(addCrToPreamble) { - preamble += "\r"; + preamble[0] = '\r'; + currentSize += 1; + parsePosition += 1; + } + int32_t charCount = sprintf(parsePosition, + "%s: | %02" SCNu32 ":%02" SCNu32 ":%02" SCNu32 ".%03" SCNu32 " | ", + this->logMessage.c_str(), loggerTime.hour, + loggerTime.minute, + loggerTime.second, + loggerTime.usecond /1000); + if(charCount < 0) { + printf("ServiceInterfaceBuffer: Failure parsing preamble"); + return ""; + } + currentSize += charCount; + if(preambleSize != nullptr) { + *preambleSize = currentSize; } - preamble += logMessage + ": | " + zero_padded(loggerTime.hour, 2) - + ":" + zero_padded(loggerTime.minute, 2) + ":" - + zero_padded(loggerTime.second, 2) + "." - + zero_padded(loggerTime.usecond/1000, 3) + " | "; return preamble; } diff --git a/serviceinterface/ServiceInterfaceBuffer.h b/serviceinterface/ServiceInterfaceBuffer.h index e3927007..00a8e74a 100644 --- a/serviceinterface/ServiceInterfaceBuffer.h +++ b/serviceinterface/ServiceInterfaceBuffer.h @@ -1,6 +1,7 @@ #ifndef FRAMEWORK_SERVICEINTERFACE_SERVICEINTERFACEBUFFER_H_ #define FRAMEWORK_SERVICEINTERFACE_SERVICEINTERFACEBUFFER_H_ +#include #include #include #include @@ -33,18 +34,20 @@ protected: //! for example when std::endl is put to stream. int sync(void) override; + bool isBuffered() const; private: //! For additional message information std::string logMessage; + std::string preamble; // For EOF detection typedef std::char_traits Traits; //! This is useful for some terminal programs which do not have //! implicit carriage return with newline characters. bool addCrToPreamble; - bool buffered; + //! This specifies to print to stderr and work in unbuffered mode. bool errStream; - + bool buffered; // Work in buffer mode. It is also possible to work without buffer. static size_t const BUF_SIZE = 128; char buf[BUF_SIZE]; @@ -52,39 +55,12 @@ private: //! In this function, the characters are parsed. void putChars(char const* begin, char const* end); - std::string getPreamble(); - - /** - * This helper function returns the zero padded string version of a number. - * The type is deduced automatically. - * @tparam T - * @param num - * @param width - * @return - */ - template - std::string zero_padded(const T& num, uint8_t width) { - std::ostringstream string_to_pad; - string_to_pad << std::setw(width) << std::setfill('0') << num; - std::string result = string_to_pad.str(); - if (result.length() > width) - { - result.erase(0, result.length() - width); - } - return result; - } + std::string getPreamble(size_t * preambleSize = nullptr); }; #endif - - - - - - - #ifdef UT699 class ServiceInterfaceBuffer: public std::basic_streambuf > { diff --git a/serviceinterface/ServiceInterfaceStream.cpp b/serviceinterface/ServiceInterfaceStream.cpp index bef8136e..76481ed1 100644 --- a/serviceinterface/ServiceInterfaceStream.cpp +++ b/serviceinterface/ServiceInterfaceStream.cpp @@ -2,21 +2,20 @@ ServiceInterfaceStream::ServiceInterfaceStream(std::string setMessage, bool addCrToPreamble, bool buffered, bool errStream, uint16_t port) : - std::ostream(&buf), - buf(setMessage, addCrToPreamble, buffered, errStream, port) { -} + std::ostream(&streambuf), + streambuf(setMessage, addCrToPreamble, buffered, errStream, port) {} void ServiceInterfaceStream::setActive( bool myActive) { - this->buf.isActive = myActive; + this->streambuf.isActive = myActive; } std::string ServiceInterfaceStream::getPreamble() { - return buf.getPreamble(); + return streambuf.getPreamble(); } void ServiceInterfaceStream::print(std::string error, bool withPreamble, bool withNewline, bool flush) { - if(not buffered and withPreamble) { + if(not streambuf.isBuffered() and withPreamble) { *this << getPreamble() << error; } else { @@ -27,7 +26,7 @@ void ServiceInterfaceStream::print(std::string error, *this << "\n"; } // if mode is non-buffered, no need to flush. - if(flush and buffered) { + if(flush and streambuf.isBuffered()) { this->flush(); } } diff --git a/serviceinterface/ServiceInterfaceStream.h b/serviceinterface/ServiceInterfaceStream.h index 9b8b5b6e..9e19c228 100644 --- a/serviceinterface/ServiceInterfaceStream.h +++ b/serviceinterface/ServiceInterfaceStream.h @@ -10,25 +10,22 @@ * std::cerr but has additional capability. Add preamble and timestamp * to output. Can be run in buffered or unbuffered mode. */ -class ServiceInterfaceStream : - public std::ostream { -protected: - ServiceInterfaceBuffer buf; +class ServiceInterfaceStream : public std::ostream { public: - /** - * This constructor is used by specifying the preamble message. - * Optionally, the output can be directed to stderr and a CR character - * can be prepended to the preamble. - * @param setMessage message of preamble. - * @param addCrToPreamble Useful for applications like Puttty. - * @param buffered specify whether to use buffered mode. - * @param errStream specify which output stream to use (stderr or stdout). - */ - ServiceInterfaceStream(std::string setMessage, - bool addCrToPreamble = false, bool buffered = true, + /** + * This constructor is used by specifying the preamble message. + * Optionally, the output can be directed to stderr and a CR character + * can be prepended to the preamble. + * @param setMessage message of preamble. + * @param addCrToPreamble Useful for applications like Puttty. + * @param buffered specify whether to use buffered mode. + * @param errStream specify which output stream to use (stderr or stdout). + */ + ServiceInterfaceStream(std::string setMessage, + bool addCrToPreamble = false, bool buffered = true, bool errStream = false, uint16_t port = 1234); - //! An inactive stream will not print anything. + //! An inactive stream will not print anything. void setActive( bool ); /** @@ -45,7 +42,8 @@ public: void print(std::string error, bool withPreamble = true, bool withNewline = true, bool flush = true); - bool buffered = false; +protected: + ServiceInterfaceBuffer streambuf; }; // Forward declaration of interface streams. These should be instantiated in From 4d59ddc3db6d9382e61bc4492e51c63283174489 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 4 Jun 2020 19:50:26 +0200 Subject: [PATCH 036/307] some fixes, check for preamble size --- serviceinterface/ServiceInterfaceBuffer.cpp | 15 ++++++++------- serviceinterface/ServiceInterfaceBuffer.h | 9 +++++++-- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/serviceinterface/ServiceInterfaceBuffer.cpp b/serviceinterface/ServiceInterfaceBuffer.cpp index f1332637..5c80862c 100644 --- a/serviceinterface/ServiceInterfaceBuffer.cpp +++ b/serviceinterface/ServiceInterfaceBuffer.cpp @@ -17,8 +17,8 @@ ServiceInterfaceBuffer::ServiceInterfaceBuffer(std::string setMessage, // Set pointers if the stream is buffered. setp( buf, buf + BUF_SIZE ); } - preamble.reserve(96); - preamble.resize(96); + preamble.reserve(MAX_PREAMBLE_SIZE); + preamble.resize(MAX_PREAMBLE_SIZE); } void ServiceInterfaceBuffer::putChars(char const* begin, char const* end) { @@ -36,7 +36,6 @@ void ServiceInterfaceBuffer::putChars(char const* begin, char const* end) { else { printChar(begin, false); } - } } @@ -80,8 +79,6 @@ int ServiceInterfaceBuffer::sync(void) { size_t preambleSize = 0; auto preamble = getPreamble(&preambleSize); - uint8_t debugArray[96]; - memcpy(debugArray, preamble.data(), preambleSize); // Write logMessage and time this->putChars(preamble.data(), preamble.data() + preambleSize); // Handle output @@ -98,7 +95,6 @@ bool ServiceInterfaceBuffer::isBuffered() const { std::string ServiceInterfaceBuffer::getPreamble(size_t * preambleSize) { Clock::TimeOfDay_t loggerTime; Clock::getDateAndTime(&loggerTime); - std::string preamble (96, 0); size_t currentSize = 0; char* parsePosition = &preamble[0]; if(addCrToPreamble) { @@ -113,7 +109,12 @@ std::string ServiceInterfaceBuffer::getPreamble(size_t * preambleSize) { loggerTime.second, loggerTime.usecond /1000); if(charCount < 0) { - printf("ServiceInterfaceBuffer: Failure parsing preamble"); + printf("ServiceInterfaceBuffer: Failure parsing preamble\r\n"); + return ""; + } + if(charCount > MAX_PREAMBLE_SIZE) { + printf("ServiceInterfaceBuffer: Char count too large for maximum " + "preamble size"); return ""; } currentSize += charCount; diff --git a/serviceinterface/ServiceInterfaceBuffer.h b/serviceinterface/ServiceInterfaceBuffer.h index 00a8e74a..39ea25c2 100644 --- a/serviceinterface/ServiceInterfaceBuffer.h +++ b/serviceinterface/ServiceInterfaceBuffer.h @@ -20,6 +20,8 @@ class ServiceInterfaceBuffer: public std::streambuf { friend class ServiceInterfaceStream; public: + static constexpr uint8_t MAX_PREAMBLE_SIZE = 40; + ServiceInterfaceBuffer(std::string setMessage, bool addCrToPreamble, bool buffered, bool errStream, uint16_t port); @@ -41,14 +43,17 @@ private: std::string preamble; // For EOF detection typedef std::char_traits Traits; + //! This is useful for some terminal programs which do not have //! implicit carriage return with newline characters. bool addCrToPreamble; + //! Specifies whether the stream operates in buffered or unbuffered mode. + bool buffered; //! This specifies to print to stderr and work in unbuffered mode. bool errStream; - bool buffered; - // Work in buffer mode. It is also possible to work without buffer. + + //! Needed for buffered mode. static size_t const BUF_SIZE = 128; char buf[BUF_SIZE]; From 3eca16ff785b928f7015444d987a5dbed0ce99dd Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 4 Jun 2020 20:59:52 +0200 Subject: [PATCH 037/307] removed exit clause --- objectmanager/ObjectManagerIF.h | 1 - 1 file changed, 1 deletion(-) diff --git a/objectmanager/ObjectManagerIF.h b/objectmanager/ObjectManagerIF.h index 3575fc16..b523727c 100644 --- a/objectmanager/ObjectManagerIF.h +++ b/objectmanager/ObjectManagerIF.h @@ -93,7 +93,6 @@ T* ObjectManagerIF::get( object_id_t id ) { if(objectManager == nullptr) { sif::error << "ObjectManagerIF: Global object manager has not " "been initialized yet!" << std::endl; - std::exit(0); } SystemObjectIF* temp = this->getSystemObject(id); return dynamic_cast(temp); From 71487d60ca524042c95dffdf1582252f028f35e2 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 4 Jun 2020 21:01:09 +0200 Subject: [PATCH 038/307] onj managerIF update --- objectmanager/ObjectManagerIF.h | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/objectmanager/ObjectManagerIF.h b/objectmanager/ObjectManagerIF.h index b523727c..90a1ce3b 100644 --- a/objectmanager/ObjectManagerIF.h +++ b/objectmanager/ObjectManagerIF.h @@ -1,12 +1,5 @@ -/** - * @file ObjectManagerIF.h - * @brief This file contains the implementation of the ObjectManagerIF interface - * @date 19.09.2012 - * @author Bastian Baetz - */ - -#ifndef OBJECTMANAGERIF_H_ -#define OBJECTMANAGERIF_H_ +#ifndef FRAMEWORK_OBJECTMANAGER_OBJECTMANAGERIF_H_ +#define FRAMEWORK_OBJECTMANAGER_OBJECTMANAGERIF_H_ #include #include @@ -20,7 +13,8 @@ * inserted, removed and retrieved from the list. On getting the * object, the call checks if the object implements the requested * interface. - * \ingroup system_objects + * @author Bastian Baetz + * @ingroup system_objects */ class ObjectManagerIF : public HasReturnvaluesIF { public: From 849053b830d92ccd463779569cb6c450033b47c1 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 4 Jun 2020 21:04:24 +0200 Subject: [PATCH 039/307] small fix for object manager.cpp --- objectmanager/ObjectManager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/objectmanager/ObjectManager.cpp b/objectmanager/ObjectManager.cpp index 1912715d..67cf5c1c 100644 --- a/objectmanager/ObjectManager.cpp +++ b/objectmanager/ObjectManager.cpp @@ -23,8 +23,8 @@ ReturnValue_t ObjectManager::insert( object_id_t id, SystemObjectIF* object) { } else { sif::error << "ObjectManager::insert: Object id " << std::hex << (int)id << std::dec << " is already in use!" << std::endl; - exit(0); //This is very severe and difficult to handle in other places. - return this->INSERTION_FAILED; + //This is very severe and difficult to handle in other places. + std::exit(INSERTION_FAILED); } } From 365f9f8434f4811b2681612793e222b430a21c8a Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 4 Jun 2020 21:05:08 +0200 Subject: [PATCH 040/307] small improvements for object manager.cpp exit removed for get function --- objectmanager/ObjectManager.cpp | 10 +++++----- objectmanager/ObjectManagerIF.h | 1 - 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/objectmanager/ObjectManager.cpp b/objectmanager/ObjectManager.cpp index 2f99e1a5..67cf5c1c 100644 --- a/objectmanager/ObjectManager.cpp +++ b/objectmanager/ObjectManager.cpp @@ -23,8 +23,8 @@ ReturnValue_t ObjectManager::insert( object_id_t id, SystemObjectIF* object) { } else { sif::error << "ObjectManager::insert: Object id " << std::hex << (int)id << std::dec << " is already in use!" << std::endl; - exit(0); //This is very severe and difficult to handle in other places. - return this->INSERTION_FAILED; + //This is very severe and difficult to handle in other places. + std::exit(INSERTION_FAILED); } } @@ -67,9 +67,9 @@ void ObjectManager::initialize() { return_value = it->second->initialize(); if ( return_value != RETURN_OK ) { object_id_t var = it->first; - sif::error << "Object " << std::hex << (int) var - << " failed to initialize with code 0x" << return_value - << std::dec << std::endl; + sif::error << "Object 0x" << std::hex << std::setw(8) << + std::setfill('0')<< var << " failed to initialize " << + "with code 0x" << return_value << std::dec << std::endl; error_count++; } } diff --git a/objectmanager/ObjectManagerIF.h b/objectmanager/ObjectManagerIF.h index 0dfb7f30..90a1ce3b 100644 --- a/objectmanager/ObjectManagerIF.h +++ b/objectmanager/ObjectManagerIF.h @@ -87,7 +87,6 @@ T* ObjectManagerIF::get( object_id_t id ) { if(objectManager == nullptr) { sif::error << "ObjectManagerIF: Global object manager has not " "been initialized yet!" << std::endl; - std::exit(1); } SystemObjectIF* temp = this->getSystemObject(id); return dynamic_cast(temp); From a37a2197d1622cc99b3bb2841b17f033e4e77138 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 4 Jun 2020 21:10:56 +0200 Subject: [PATCH 041/307] some form improvements for object manager .cpp --- objectmanager/ObjectManager.cpp | 34 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/objectmanager/ObjectManager.cpp b/objectmanager/ObjectManager.cpp index 67cf5c1c..3e0bfed6 100644 --- a/objectmanager/ObjectManager.cpp +++ b/objectmanager/ObjectManager.cpp @@ -2,21 +2,19 @@ #include #include -ObjectManager::ObjectManager( void (*setProducer)() ) : produceObjects(setProducer) { +ObjectManager::ObjectManager( void (*setProducer)() ): + produceObjects(setProducer) { //There's nothing special to do in the constructor. } ObjectManager::~ObjectManager() { - std::map::iterator it; - for (it = this->objectList.begin(); it != this->objectList.end(); it++) { - delete it->second; - } + // Map is STL object and deletes its own pointers. } ReturnValue_t ObjectManager::insert( object_id_t id, SystemObjectIF* object) { - bool insert_return = this->objectList.insert( std::pair< object_id_t, SystemObjectIF* >( id, object ) ).second; - if (insert_return == true) { + auto returnPair = objectList.emplace(id, object); + if (returnPair.second) { // sif::debug << "ObjectManager::insert: Object " << std::hex // << (int)id << std::dec << " inserted." << std::endl; return this->RETURN_OK; @@ -44,18 +42,15 @@ ReturnValue_t ObjectManager::remove( object_id_t id ) { SystemObjectIF* ObjectManager::getSystemObject( object_id_t id ) { - std::map::iterator it = this->objectList.find( id ); - if (it == this->objectList.end() ) { - //Changed for testing different method. -// SystemObjectIF* object = this->produceObjects( id ); -// return object; - return NULL; + auto listIter = this->objectList.find( id ); + if (listIter == this->objectList.end() ) { + return nullptr; } else { - return it->second; + return listIter->second; } } -ObjectManager::ObjectManager( ) : produceObjects(NULL) { +ObjectManager::ObjectManager() : produceObjects(nullptr) { } @@ -63,7 +58,7 @@ void ObjectManager::initialize() { this->produceObjects(); ReturnValue_t return_value = RETURN_FAILED; uint32_t error_count = 0; - for (std::map::iterator it = this->objectList.begin(); it != objectList.end(); it++ ) { + for (auto it = this->objectList.begin(); it != objectList.end(); it++ ) { return_value = it->second->initialize(); if ( return_value != RETURN_OK ) { object_id_t var = it->first; @@ -79,10 +74,11 @@ void ObjectManager::initialize() { } //Init was successful. Now check successful interconnections. error_count = 0; - for (std::map::iterator it = this->objectList.begin(); it != objectList.end(); it++ ) { - return_value = it->second->checkObjectConnections(); + for (auto listIter = this->objectList.begin(); + listIter != objectList.end(); listIter++ ) { + return_value = listIter->second->checkObjectConnections(); if ( return_value != RETURN_OK ) { - sif::error << "Object " << std::hex << (int) it->first + sif::error << "Object " << std::hex << (int) listIter->first << " connection check failed with code 0x" << return_value << std::dec << std::endl; error_count++; From 569724843e7196d5c7ca0b324cd575b6aa9aa9ba Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 4 Jun 2020 21:11:49 +0200 Subject: [PATCH 042/307] object manager improvements --- objectmanager/ObjectManager.cpp | 34 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/objectmanager/ObjectManager.cpp b/objectmanager/ObjectManager.cpp index 67cf5c1c..3e0bfed6 100644 --- a/objectmanager/ObjectManager.cpp +++ b/objectmanager/ObjectManager.cpp @@ -2,21 +2,19 @@ #include #include -ObjectManager::ObjectManager( void (*setProducer)() ) : produceObjects(setProducer) { +ObjectManager::ObjectManager( void (*setProducer)() ): + produceObjects(setProducer) { //There's nothing special to do in the constructor. } ObjectManager::~ObjectManager() { - std::map::iterator it; - for (it = this->objectList.begin(); it != this->objectList.end(); it++) { - delete it->second; - } + // Map is STL object and deletes its own pointers. } ReturnValue_t ObjectManager::insert( object_id_t id, SystemObjectIF* object) { - bool insert_return = this->objectList.insert( std::pair< object_id_t, SystemObjectIF* >( id, object ) ).second; - if (insert_return == true) { + auto returnPair = objectList.emplace(id, object); + if (returnPair.second) { // sif::debug << "ObjectManager::insert: Object " << std::hex // << (int)id << std::dec << " inserted." << std::endl; return this->RETURN_OK; @@ -44,18 +42,15 @@ ReturnValue_t ObjectManager::remove( object_id_t id ) { SystemObjectIF* ObjectManager::getSystemObject( object_id_t id ) { - std::map::iterator it = this->objectList.find( id ); - if (it == this->objectList.end() ) { - //Changed for testing different method. -// SystemObjectIF* object = this->produceObjects( id ); -// return object; - return NULL; + auto listIter = this->objectList.find( id ); + if (listIter == this->objectList.end() ) { + return nullptr; } else { - return it->second; + return listIter->second; } } -ObjectManager::ObjectManager( ) : produceObjects(NULL) { +ObjectManager::ObjectManager() : produceObjects(nullptr) { } @@ -63,7 +58,7 @@ void ObjectManager::initialize() { this->produceObjects(); ReturnValue_t return_value = RETURN_FAILED; uint32_t error_count = 0; - for (std::map::iterator it = this->objectList.begin(); it != objectList.end(); it++ ) { + for (auto it = this->objectList.begin(); it != objectList.end(); it++ ) { return_value = it->second->initialize(); if ( return_value != RETURN_OK ) { object_id_t var = it->first; @@ -79,10 +74,11 @@ void ObjectManager::initialize() { } //Init was successful. Now check successful interconnections. error_count = 0; - for (std::map::iterator it = this->objectList.begin(); it != objectList.end(); it++ ) { - return_value = it->second->checkObjectConnections(); + for (auto listIter = this->objectList.begin(); + listIter != objectList.end(); listIter++ ) { + return_value = listIter->second->checkObjectConnections(); if ( return_value != RETURN_OK ) { - sif::error << "Object " << std::hex << (int) it->first + sif::error << "Object " << std::hex << (int) listIter->first << " connection check failed with code 0x" << return_value << std::dec << std::endl; error_count++; From d423c001156916fe62b3113c539dee9931f359fb Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 4 Jun 2020 21:14:35 +0200 Subject: [PATCH 043/307] additional nullptr check --- objectmanager/ObjectManager.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/objectmanager/ObjectManager.cpp b/objectmanager/ObjectManager.cpp index 3e0bfed6..a5895098 100644 --- a/objectmanager/ObjectManager.cpp +++ b/objectmanager/ObjectManager.cpp @@ -55,6 +55,11 @@ ObjectManager::ObjectManager() : produceObjects(nullptr) { } void ObjectManager::initialize() { + if(produceObjects == nullptr) { + sif::error << "ObjectManager: Passed produceObjects functions is" + "nullptr!" << std::endl; + return; + } this->produceObjects(); ReturnValue_t return_value = RETURN_FAILED; uint32_t error_count = 0; From 5d3b3bae168667f86b53c034ed0d9b8f2bf3bc1a Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 4 Jun 2020 21:14:53 +0200 Subject: [PATCH 044/307] addtiional nullptr check --- objectmanager/ObjectManager.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/objectmanager/ObjectManager.cpp b/objectmanager/ObjectManager.cpp index 3e0bfed6..a5895098 100644 --- a/objectmanager/ObjectManager.cpp +++ b/objectmanager/ObjectManager.cpp @@ -55,6 +55,11 @@ ObjectManager::ObjectManager() : produceObjects(nullptr) { } void ObjectManager::initialize() { + if(produceObjects == nullptr) { + sif::error << "ObjectManager: Passed produceObjects functions is" + "nullptr!" << std::endl; + return; + } this->produceObjects(); ReturnValue_t return_value = RETURN_FAILED; uint32_t error_count = 0; From e4944a067c3624a669c4703bfa0d5dce5f1b4119 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 4 Jun 2020 21:24:44 +0200 Subject: [PATCH 045/307] change made was wrong (pointers in map are not deleted!) --- objectmanager/ObjectManager.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/objectmanager/ObjectManager.cpp b/objectmanager/ObjectManager.cpp index a5895098..b12c66d9 100644 --- a/objectmanager/ObjectManager.cpp +++ b/objectmanager/ObjectManager.cpp @@ -9,7 +9,9 @@ ObjectManager::ObjectManager( void (*setProducer)() ): ObjectManager::~ObjectManager() { - // Map is STL object and deletes its own pointers. + for (auto const& iter : objectList) { + delete iter.second; + } } ReturnValue_t ObjectManager::insert( object_id_t id, SystemObjectIF* object) { @@ -99,7 +101,7 @@ void ObjectManager::initialize() { void ObjectManager::printList() { std::map::iterator it; sif::debug << "ObjectManager: Object List contains:" << std::endl; - for (it = this->objectList.begin(); it != this->objectList.end(); it++) { - sif::debug << std::hex << it->first << " | " << it->second << std::endl; + for (auto const& it : objectList) { + sif::debug << std::hex << it.first << " | " << it.second << std::endl; } } From 0ac3cf8fadd15d155ecc3df9ca2ba0344bbd3859 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 4 Jun 2020 21:25:14 +0200 Subject: [PATCH 046/307] reverted wrong change --- objectmanager/ObjectManager.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/objectmanager/ObjectManager.cpp b/objectmanager/ObjectManager.cpp index a5895098..b12c66d9 100644 --- a/objectmanager/ObjectManager.cpp +++ b/objectmanager/ObjectManager.cpp @@ -9,7 +9,9 @@ ObjectManager::ObjectManager( void (*setProducer)() ): ObjectManager::~ObjectManager() { - // Map is STL object and deletes its own pointers. + for (auto const& iter : objectList) { + delete iter.second; + } } ReturnValue_t ObjectManager::insert( object_id_t id, SystemObjectIF* object) { @@ -99,7 +101,7 @@ void ObjectManager::initialize() { void ObjectManager::printList() { std::map::iterator it; sif::debug << "ObjectManager: Object List contains:" << std::endl; - for (it = this->objectList.begin(); it != this->objectList.end(); it++) { - sif::debug << std::hex << it->first << " | " << it->second << std::endl; + for (auto const& it : objectList) { + sif::debug << std::hex << it.first << " | " << it.second << std::endl; } } From fd0cc2a8ca84c2eba0aac60cf62e7d9747f94427 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 4 Jun 2020 21:26:56 +0200 Subject: [PATCH 047/307] simplified all iterations through obj list --- objectmanager/ObjectManager.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/objectmanager/ObjectManager.cpp b/objectmanager/ObjectManager.cpp index b12c66d9..2f47950f 100644 --- a/objectmanager/ObjectManager.cpp +++ b/objectmanager/ObjectManager.cpp @@ -65,10 +65,10 @@ void ObjectManager::initialize() { this->produceObjects(); ReturnValue_t return_value = RETURN_FAILED; uint32_t error_count = 0; - for (auto it = this->objectList.begin(); it != objectList.end(); it++ ) { - return_value = it->second->initialize(); + for (auto const& it : objectList) { + return_value = it.second->initialize(); if ( return_value != RETURN_OK ) { - object_id_t var = it->first; + object_id_t var = it.first; sif::error << "Object 0x" << std::hex << std::setw(8) << std::setfill('0')<< var << " failed to initialize " << "with code 0x" << return_value << std::dec << std::endl; @@ -81,11 +81,10 @@ void ObjectManager::initialize() { } //Init was successful. Now check successful interconnections. error_count = 0; - for (auto listIter = this->objectList.begin(); - listIter != objectList.end(); listIter++ ) { - return_value = listIter->second->checkObjectConnections(); + for (auto const& it : objectList) { + return_value = it.second->checkObjectConnections(); if ( return_value != RETURN_OK ) { - sif::error << "Object " << std::hex << (int) listIter->first + sif::error << "Object " << std::hex << (int) it.first << " connection check failed with code 0x" << return_value << std::dec << std::endl; error_count++; From dd193fd64d302e5592dfddc8a4395101d921b61b Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 4 Jun 2020 21:27:37 +0200 Subject: [PATCH 048/307] obj manager.cpp improvements --- objectmanager/ObjectManager.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/objectmanager/ObjectManager.cpp b/objectmanager/ObjectManager.cpp index b12c66d9..2f47950f 100644 --- a/objectmanager/ObjectManager.cpp +++ b/objectmanager/ObjectManager.cpp @@ -65,10 +65,10 @@ void ObjectManager::initialize() { this->produceObjects(); ReturnValue_t return_value = RETURN_FAILED; uint32_t error_count = 0; - for (auto it = this->objectList.begin(); it != objectList.end(); it++ ) { - return_value = it->second->initialize(); + for (auto const& it : objectList) { + return_value = it.second->initialize(); if ( return_value != RETURN_OK ) { - object_id_t var = it->first; + object_id_t var = it.first; sif::error << "Object 0x" << std::hex << std::setw(8) << std::setfill('0')<< var << " failed to initialize " << "with code 0x" << return_value << std::dec << std::endl; @@ -81,11 +81,10 @@ void ObjectManager::initialize() { } //Init was successful. Now check successful interconnections. error_count = 0; - for (auto listIter = this->objectList.begin(); - listIter != objectList.end(); listIter++ ) { - return_value = listIter->second->checkObjectConnections(); + for (auto const& it : objectList) { + return_value = it.second->checkObjectConnections(); if ( return_value != RETURN_OK ) { - sif::error << "Object " << std::hex << (int) listIter->first + sif::error << "Object " << std::hex << (int) it.first << " connection check failed with code 0x" << return_value << std::dec << std::endl; error_count++; From 904721cc3638ffac5a1c4758e84395726d2a415b Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 5 Jun 2020 13:44:11 +0200 Subject: [PATCH 049/307] improved pool entry iF --- datapool/PoolEntry.cpp | 38 ++++++++------ datapool/PoolEntry.h | 115 ++++++++++++++++++++++++++--------------- datapool/PoolEntryIF.h | 32 ++++++------ 3 files changed, 110 insertions(+), 75 deletions(-) diff --git a/datapool/PoolEntry.cpp b/datapool/PoolEntry.cpp index d07c516d..a87a6c4e 100644 --- a/datapool/PoolEntry.cpp +++ b/datapool/PoolEntry.cpp @@ -1,30 +1,37 @@ #include #include +#include +#include template -PoolEntry::PoolEntry(std::initializer_list initValue, uint8_t set_length, - uint8_t set_valid ) : length(set_length), valid(set_valid) { +PoolEntry::PoolEntry(std::initializer_list initValue, uint8_t setLength, + bool setValid ) : length(setLength), valid(setValid) { this->address = new T[this->length]; if(initValue.size() == 0) { - memset(this->address, 0, this->getByteSize()); + std::memset(this->address, 0, this->getByteSize()); + } + else if (initValue.size() != setLength){ + sif::warning << "PoolEntry: setLength is not equal to initializer list" + "length! Performing zero initialization with given setLength" + << std::endl; + std::memset(this->address, 0, this->getByteSize()); } else { - memcpy(this->address, initValue.begin(), this->getByteSize()); + std::copy(initValue.begin(), initValue.end(), this->address); } } template -PoolEntry::PoolEntry( T* initValue, uint8_t set_length, uint8_t set_valid ) : - length(set_length), valid(set_valid) { +PoolEntry::PoolEntry( T* initValue, uint8_t setLength, bool setValid ) : + length(setLength), valid(setValid) { this->address = new T[this->length]; - if (initValue != NULL) { - memcpy(this->address, initValue, this->getByteSize() ); + if (initValue != nullptr) { + std::memcpy(this->address, initValue, this->getByteSize() ); } else { - memset(this->address, 0, this->getByteSize() ); + std::memset(this->address, 0, this->getByteSize() ); } } - //As the data pool is global, this dtor is only be called on program exit. //Warning! Never copy pool entries! template @@ -48,21 +55,20 @@ void* PoolEntry::getRawData() { } template -void PoolEntry::setValid( uint8_t isValid ) { +void PoolEntry::setValid(bool isValid) { this->valid = isValid; } template -uint8_t PoolEntry::getValid() { +bool PoolEntry::getValid() { return valid; } template void PoolEntry::print() { - for (uint8_t size = 0; size < this->length; size++ ) { - sif::debug << "| " << std::hex << (double)this->address[size] - << (this->valid? " (valid) " : " (invalid) "); - } + sif::debug << "Pool Entry Validity: " << + (this->valid? " (valid) " : " (invalid) ") << std::endl; + printer::print(reinterpret_cast(address), length); sif::debug << std::dec << std::endl; } diff --git a/datapool/PoolEntry.h b/datapool/PoolEntry.h index 4971ee45..1a22bb63 100644 --- a/datapool/PoolEntry.h +++ b/datapool/PoolEntry.h @@ -1,95 +1,126 @@ -#ifndef POOLENTRY_H_ -#define POOLENTRY_H_ - +#ifndef FRAMEWORK_DATAPOOL_POOLENTRY_H_ +#define FRAMEWORK_DATAPOOL_POOLENTRY_H_ #include -#include -#include + #include #include +#include + /** * @brief This is a small helper class that defines a single data pool entry. * @details * The helper is used to store all information together with the data as a - * single data pool entry.The content's type is defined by the template argument. - * It is prepared for use with plain old data types, but may be extended to - * complex types if necessary. It can be initialized with a certain value, - * size and validity flag. It holds a pointer to the real data and offers - * methods to access this data and to acquire additional information - * (such as validity and array/byte size). It is NOT intended to be used - * outside the DataPool class. - * @author Bastian Baetz - * @ingroup data_pool + * single data pool entry. The content's type is defined by the template + * argument. * + * It is prepared for use with plain old data types, but may be + * extended to complex types if necessary. It can be initialized with a + * certain value, size and validity flag. + * + * It holds a pointer to the real data and offers methods to access this data + * and to acquire additional information (such as validity and array/byte size). + * It is NOT intended to be used outside DataPool implementations as it performs + * dynamic memory allocation. + * + * @ingroup data_pool */ template class PoolEntry : public PoolEntryIF { public: static_assert(not std::is_same::value, - "Do not use boolean for the PoolEntry type, use uint8_t instead!" - "Warum? Darum :-)"); + "Do not use boolean for the PoolEntry type, use uint8_t " + "instead! The ECSS standard defines a boolean as a one bit " + "field. Therefore it is preferred to store a boolean as an " + "uint8_t"); /** * @brief In the classe's constructor, space is allocated on the heap and * potential init values are copied to that space. - * @param initValue Initializer list with values to initialize with - * @param set_length Defines the array length of this entry. - * @param set_valid Sets the initialization flag. It is invalid (0) by default. + * @details + * Not passing any arguments will initialize an non-array pool entry + * (setLength = 1) with an initial invalid state. + * Please note that if an initializer list is passed, the correct + * corresponding length should be passed too, otherwise a zero + * initialization will be performed with the given setLength. + * @param initValue + * Initializer list with values to initialize with, for example {0,0} to + * initialize the two entries to zero. + * @param setLength + * Defines the array length of this entry. Should be equal to the + * intializer list length. + * @param setValid + * Sets the initialization flag. It is invalid by default. */ - PoolEntry( std::initializer_list initValue = {}, uint8_t set_length = 1, uint8_t set_valid = 0 ); + PoolEntry(std::initializer_list initValue = {}, uint8_t setLength = 1, + bool setValid = false); /** * @brief In the classe's constructor, space is allocated on the heap and * potential init values are copied to that space. - * @param initValue A pointer to the single value or array that holds the init value. - * With the default value (NULL), the entry is initalized with all 0. - * @param set_length Defines the array length of this entry. - * @param set_valid Sets the initialization flag. It is invalid (0) by default. + * @param initValue + * A pointer to the single value or array that holds the init value. + * With the default value (nullptr), the entry is initalized with all 0. + * @param setLength + * Defines the array length of this entry. + * @param setValid + * Sets the initialization flag. It is invalid by default. */ - PoolEntry( T* initValue = NULL, uint8_t set_length = 1, uint8_t set_valid = 0 ); + PoolEntry(T* initValue, uint8_t setLength = 1, bool setValid = false); + + //! Explicitely deleted copy ctor, copying is not allowed! + PoolEntry(const PoolEntry&) = delete; + //! Explicitely deleted copy assignment, copying is not allowed! + PoolEntry& operator=(const PoolEntry&) = delete; /** - * \brief The allocated memory for the variable is freed in the destructor. - * \details As the data pool is global, this dtor is only called on program exit. - * PoolEntries shall never be copied, as a copy might delete the variable on the heap. + * @brief The allocated memory for the variable is freed + * in the destructor. + * @details + * As the data pool is global, this dtor is only called on program exit. + * PoolEntries shall never be copied, as a copy might delete the variable + * on the heap. */ ~PoolEntry(); + /** - * \brief This is the address pointing to the allocated memory. + * @brief This is the address pointing to the allocated memory. */ T* address; /** - * \brief This attribute stores the length information. + * @brief This attribute stores the length information. */ uint8_t length; /** - * \brief Here, the validity information for a variable is stored. + * @brief Here, the validity information for a variable is stored. * Every entry (single variable or vector) has one valid flag. */ uint8_t valid; /** - * \brief getSize returns the array size of the entry. - * \details A single parameter has size 1. + * @brief getSize returns the array size of the entry. + * @details A single parameter has size 1. */ uint8_t getSize(); /** - * \brief This operation returns the size in bytes. - * \details The size is calculated by sizeof(type) * array_size. + * @brief This operation returns the size in bytes. + * @details The size is calculated by sizeof(type) * array_size. */ uint16_t getByteSize(); /** - * \brief This operation returns a the address pointer casted to void*. + * @brief This operation returns a the address pointer casted to void*. */ void* getRawData(); /** - * \brief This method allows to set the valid information of the pool entry. + * @brief This method allows to set the valid information + * of the pool entry. */ - void setValid( uint8_t isValid ); + void setValid( bool isValid ); /** - * \brief This method allows to get the valid information of the pool entry. + * @brief This method allows to get the valid information + * of the pool entry. */ - uint8_t getValid(); + bool getValid(); /** - * \brief This is a debug method that prints all values and the valid information to the screen. - * It prints all array entries in a row. + * @brief This is a debug method that prints all values and the valid + * information to the screen. It prints all array entries in a row. */ void print(); diff --git a/datapool/PoolEntryIF.h b/datapool/PoolEntryIF.h index d24d553a..a075436e 100644 --- a/datapool/PoolEntryIF.h +++ b/datapool/PoolEntryIF.h @@ -1,5 +1,5 @@ -#ifndef POOLENTRYIF_H_ -#define POOLENTRYIF_H_ +#ifndef FRAMEWORK_DATAPOOL_POOLENTRYIF_H_ +#define FRAMEWORK_DATAPOOL_POOLENTRYIF_H_ #include #include @@ -9,55 +9,53 @@ * single data pool entry. * @details * The interface provides methods to determine the size and the validity - * information of a value. It also defines a method to receive a pointer to - * the raw data content. It is mainly used by DataPool itself, but also as a + * information of a value. It also defines a method to receive a pointer to the + * raw data content. It is mainly used by DataPool itself, but also as a * return pointer. - * @author Bastian Baetz + * + * @author Bastian Baetz * @ingroup data_pool + * */ class PoolEntryIF { public: /** * @brief This is an empty virtual destructor, - * as it is proposed for C++ interfaces. + * as it is required for C++ interfaces. */ - virtual ~PoolEntryIF() {} - + virtual ~PoolEntryIF() { + } /** * @brief getSize returns the array size of the entry. * A single variable parameter has size 1. */ virtual uint8_t getSize() = 0; - /** * @brief This operation returns the size in bytes, which is calculated by * sizeof(type) * array_size. */ virtual uint16_t getByteSize() = 0; - /** * @brief This operation returns a the address pointer casted to void*. */ virtual void* getRawData() = 0; - /** * @brief This method allows to set the valid information of the pool entry. */ - virtual void setValid(uint8_t isValid) = 0; - + virtual void setValid(bool isValid) = 0; /** * @brief This method allows to set the valid information of the pool entry. */ - virtual uint8_t getValid() = 0; - + virtual bool getValid() = 0; /** * @brief This is a debug method that prints all values and the valid * information to the screen. It prints all array entries in a row. + * @details + * Also displays whether the pool entry is valid or invalid. */ virtual void print() = 0; - /** - * @brief Returns the type of the entry. + * Returns the type of the entry. */ virtual Type getType() = 0; }; From dd210e99af8ece3866bc898ec3daa631d90b8d9d Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 5 Jun 2020 13:45:18 +0200 Subject: [PATCH 050/307] additional include which was missing --- datapoolglob/PoolRawAccess.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/datapoolglob/PoolRawAccess.cpp b/datapoolglob/PoolRawAccess.cpp index cc04f9b9..b10ee04c 100644 --- a/datapoolglob/PoolRawAccess.cpp +++ b/datapoolglob/PoolRawAccess.cpp @@ -3,6 +3,8 @@ #include #include +#include + PoolRawAccess::PoolRawAccess(uint32_t set_id, uint8_t setArrayEntry, DataSetIF* dataSet, ReadWriteMode_t setReadWriteMode) : dataPoolId(set_id), arrayEntry(setArrayEntry), valid(false), From d7036edb94e7d64626e3cacf3d205c2b9db143a9 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 5 Jun 2020 15:53:20 +0200 Subject: [PATCH 051/307] hotfix --- serialize/SerialBufferAdapter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/serialize/SerialBufferAdapter.cpp b/serialize/SerialBufferAdapter.cpp index 3df2abe9..e13e7eb6 100644 --- a/serialize/SerialBufferAdapter.cpp +++ b/serialize/SerialBufferAdapter.cpp @@ -82,7 +82,7 @@ ReturnValue_t SerialBufferAdapter::deSerialize(const uint8_t** buffer, } } //No Else If, go on with buffer - if (bufferLength >= *size) { + if (bufferLength <= *size) { *size -= bufferLength; memcpy(m_buffer, *buffer, bufferLength); (*buffer) += bufferLength; From b20ee0965a264dacfbc1299f0dffd79338e697bf Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 5 Jun 2020 16:44:00 +0200 Subject: [PATCH 052/307] renamed printer to arrayprinter --- .../{printer.cpp => arrayprinter.cpp} | 16 ++++++++-------- globalfunctions/{printer.h => arrayprinter.h} | 9 ++++----- 2 files changed, 12 insertions(+), 13 deletions(-) rename globalfunctions/{printer.cpp => arrayprinter.cpp} (71%) rename globalfunctions/{printer.h => arrayprinter.h} (70%) diff --git a/globalfunctions/printer.cpp b/globalfunctions/arrayprinter.cpp similarity index 71% rename from globalfunctions/printer.cpp rename to globalfunctions/arrayprinter.cpp index a68a91ee..e8fce56c 100644 --- a/globalfunctions/printer.cpp +++ b/globalfunctions/arrayprinter.cpp @@ -1,25 +1,25 @@ -#include +#include #include #include -void printer::print(const uint8_t *data, size_t size, OutputType type, +void arrayprinter::print(const uint8_t *data, size_t size, OutputType type, bool printInfo, size_t maxCharPerLine) { if(printInfo) { sif::info << "Printing data with size " << size << ": "; } sif::info << "["; if(type == OutputType::HEX) { - printer::printHex(data, size, maxCharPerLine); + arrayprinter::printHex(data, size, maxCharPerLine); } else if (type == OutputType::DEC) { - printer::printDec(data, size, maxCharPerLine); + arrayprinter::printDec(data, size, maxCharPerLine); } else if(type == OutputType::BIN) { - printer::printBin(data, size); + arrayprinter::printBin(data, size); } } -void printer::printHex(const uint8_t *data, size_t size, +void arrayprinter::printHex(const uint8_t *data, size_t size, size_t maxCharPerLine) { sif::info << std::hex; for(size_t i = 0; i < size; i++) { @@ -36,7 +36,7 @@ void printer::printHex(const uint8_t *data, size_t size, sif::info << "]" << std::endl; } -void printer::printDec(const uint8_t *data, size_t size, +void arrayprinter::printDec(const uint8_t *data, size_t size, size_t maxCharPerLine) { sif::info << std::dec; for(size_t i = 0; i < size; i++) { @@ -51,7 +51,7 @@ void printer::printDec(const uint8_t *data, size_t size, sif::info << "]" << std::endl; } -void printer::printBin(const uint8_t *data, size_t size) { +void arrayprinter::printBin(const uint8_t *data, size_t size) { sif::info << "\n" << std::flush; for(size_t i = 0; i < size; i++) { sif::info << "Byte " << i + 1 << ": 0b"<< diff --git a/globalfunctions/printer.h b/globalfunctions/arrayprinter.h similarity index 70% rename from globalfunctions/printer.h rename to globalfunctions/arrayprinter.h index 33a382ec..e57d8e04 100644 --- a/globalfunctions/printer.h +++ b/globalfunctions/arrayprinter.h @@ -1,16 +1,15 @@ -#ifndef FRAMEWORK_GLOBALFUNCTIONS_PRINTER_H_ -#define FRAMEWORK_GLOBALFUNCTIONS_PRINTER_H_ +#ifndef FRAMEWORK_GLOBALFUNCTIONS_ARRAYPRINTER_H_ +#define FRAMEWORK_GLOBALFUNCTIONS_ARRAYPRINTER_H_ #include #include -namespace printer { - enum class OutputType { DEC, HEX, BIN }; +namespace arrayprinter { void print(const uint8_t* data, size_t size, OutputType type = OutputType::HEX, bool printInfo = true, size_t maxCharPerLine = 12); void printHex(const uint8_t* data, size_t size, size_t maxCharPerLine = 12); @@ -18,4 +17,4 @@ void printDec(const uint8_t* data, size_t size, size_t maxCharPerLine = 12); void printBin(const uint8_t* data, size_t size); } -#endif /* FRAMEWORK_GLOBALFUNCTIONS_PRINTER_H_ */ +#endif /* FRAMEWORK_GLOBALFUNCTIONS_ARRAYPRINTER_H_ */ From abcd818f2f48f6805ca1bfadf9d9694078e6a963 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 5 Jun 2020 16:44:31 +0200 Subject: [PATCH 053/307] printer renamed to arrayprinter --- globalfunctions/arrayprinter.cpp | 61 ++++++++++++++++++++++++++++++++ globalfunctions/arrayprinter.h | 20 +++++++++++ 2 files changed, 81 insertions(+) create mode 100644 globalfunctions/arrayprinter.cpp create mode 100644 globalfunctions/arrayprinter.h diff --git a/globalfunctions/arrayprinter.cpp b/globalfunctions/arrayprinter.cpp new file mode 100644 index 00000000..e8fce56c --- /dev/null +++ b/globalfunctions/arrayprinter.cpp @@ -0,0 +1,61 @@ +#include +#include +#include + +void arrayprinter::print(const uint8_t *data, size_t size, OutputType type, + bool printInfo, size_t maxCharPerLine) { + if(printInfo) { + sif::info << "Printing data with size " << size << ": "; + } + sif::info << "["; + if(type == OutputType::HEX) { + arrayprinter::printHex(data, size, maxCharPerLine); + } + else if (type == OutputType::DEC) { + arrayprinter::printDec(data, size, maxCharPerLine); + } + else if(type == OutputType::BIN) { + arrayprinter::printBin(data, size); + } +} + +void arrayprinter::printHex(const uint8_t *data, size_t size, + size_t maxCharPerLine) { + sif::info << std::hex; + for(size_t i = 0; i < size; i++) { + sif::info << "0x" << static_cast(data[i]); + if(i < size - 1){ + sif::info << " , "; + if(i > 0 and i % maxCharPerLine == 0) { + sif::info << std::endl; + } + } + + } + sif::info << std::dec; + sif::info << "]" << std::endl; +} + +void arrayprinter::printDec(const uint8_t *data, size_t size, + size_t maxCharPerLine) { + sif::info << std::dec; + for(size_t i = 0; i < size; i++) { + sif::info << static_cast(data[i]); + if(i < size - 1){ + sif::info << " , "; + if(i > 0 and i % maxCharPerLine == 0) { + sif::info << std::endl; + } + } + } + sif::info << "]" << std::endl; +} + +void arrayprinter::printBin(const uint8_t *data, size_t size) { + sif::info << "\n" << std::flush; + for(size_t i = 0; i < size; i++) { + sif::info << "Byte " << i + 1 << ": 0b"<< + std::bitset<8>(data[i]) << ",\n" << std::flush; + } + sif::info << "]" << std::endl; +} diff --git a/globalfunctions/arrayprinter.h b/globalfunctions/arrayprinter.h new file mode 100644 index 00000000..e57d8e04 --- /dev/null +++ b/globalfunctions/arrayprinter.h @@ -0,0 +1,20 @@ +#ifndef FRAMEWORK_GLOBALFUNCTIONS_ARRAYPRINTER_H_ +#define FRAMEWORK_GLOBALFUNCTIONS_ARRAYPRINTER_H_ +#include +#include + +enum class OutputType { + DEC, + HEX, + BIN +}; + +namespace arrayprinter { +void print(const uint8_t* data, size_t size, OutputType type = OutputType::HEX, + bool printInfo = true, size_t maxCharPerLine = 12); +void printHex(const uint8_t* data, size_t size, size_t maxCharPerLine = 12); +void printDec(const uint8_t* data, size_t size, size_t maxCharPerLine = 12); +void printBin(const uint8_t* data, size_t size); +} + +#endif /* FRAMEWORK_GLOBALFUNCTIONS_ARRAYPRINTER_H_ */ From 4ebd937fe036e5a9427f2bda8683bfca58d5207b Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 5 Jun 2020 16:47:46 +0200 Subject: [PATCH 054/307] deleted old printer file --- datapool/PoolEntry.cpp | 4 +-- globalfunctions/printer.cpp | 61 ------------------------------------- globalfunctions/printer.h | 21 ------------- 3 files changed, 2 insertions(+), 84 deletions(-) delete mode 100644 globalfunctions/printer.cpp delete mode 100644 globalfunctions/printer.h diff --git a/datapool/PoolEntry.cpp b/datapool/PoolEntry.cpp index a87a6c4e..d535a72b 100644 --- a/datapool/PoolEntry.cpp +++ b/datapool/PoolEntry.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #include template @@ -68,7 +68,7 @@ template void PoolEntry::print() { sif::debug << "Pool Entry Validity: " << (this->valid? " (valid) " : " (invalid) ") << std::endl; - printer::print(reinterpret_cast(address), length); + arrayprinter::print(reinterpret_cast(address), length); sif::debug << std::dec << std::endl; } diff --git a/globalfunctions/printer.cpp b/globalfunctions/printer.cpp deleted file mode 100644 index a68a91ee..00000000 --- a/globalfunctions/printer.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include -#include -#include - -void printer::print(const uint8_t *data, size_t size, OutputType type, - bool printInfo, size_t maxCharPerLine) { - if(printInfo) { - sif::info << "Printing data with size " << size << ": "; - } - sif::info << "["; - if(type == OutputType::HEX) { - printer::printHex(data, size, maxCharPerLine); - } - else if (type == OutputType::DEC) { - printer::printDec(data, size, maxCharPerLine); - } - else if(type == OutputType::BIN) { - printer::printBin(data, size); - } -} - -void printer::printHex(const uint8_t *data, size_t size, - size_t maxCharPerLine) { - sif::info << std::hex; - for(size_t i = 0; i < size; i++) { - sif::info << "0x" << static_cast(data[i]); - if(i < size - 1){ - sif::info << " , "; - if(i > 0 and i % maxCharPerLine == 0) { - sif::info << std::endl; - } - } - - } - sif::info << std::dec; - sif::info << "]" << std::endl; -} - -void printer::printDec(const uint8_t *data, size_t size, - size_t maxCharPerLine) { - sif::info << std::dec; - for(size_t i = 0; i < size; i++) { - sif::info << static_cast(data[i]); - if(i < size - 1){ - sif::info << " , "; - if(i > 0 and i % maxCharPerLine == 0) { - sif::info << std::endl; - } - } - } - sif::info << "]" << std::endl; -} - -void printer::printBin(const uint8_t *data, size_t size) { - sif::info << "\n" << std::flush; - for(size_t i = 0; i < size; i++) { - sif::info << "Byte " << i + 1 << ": 0b"<< - std::bitset<8>(data[i]) << ",\n" << std::flush; - } - sif::info << "]" << std::endl; -} diff --git a/globalfunctions/printer.h b/globalfunctions/printer.h deleted file mode 100644 index 33a382ec..00000000 --- a/globalfunctions/printer.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef FRAMEWORK_GLOBALFUNCTIONS_PRINTER_H_ -#define FRAMEWORK_GLOBALFUNCTIONS_PRINTER_H_ -#include -#include - -namespace printer { - -enum class OutputType { - DEC, - HEX, - BIN -}; - -void print(const uint8_t* data, size_t size, OutputType type = OutputType::HEX, - bool printInfo = true, size_t maxCharPerLine = 12); -void printHex(const uint8_t* data, size_t size, size_t maxCharPerLine = 12); -void printDec(const uint8_t* data, size_t size, size_t maxCharPerLine = 12); -void printBin(const uint8_t* data, size_t size); -} - -#endif /* FRAMEWORK_GLOBALFUNCTIONS_PRINTER_H_ */ From dbeb04895b2d86731be07c4f6af7b1f7f09316fc Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 5 Jun 2020 17:55:03 +0200 Subject: [PATCH 055/307] added hosted OSAL --- framework.mk | 4 +- osal/host/Clock.cpp | 227 ++++++++++++++++++++++++++++++++ osal/host/MessageQueue.cpp | 144 +++++++++++++++++++++ osal/host/MessageQueue.h | 230 +++++++++++++++++++++++++++++++++ osal/host/Mutex.cpp | 40 ++++++ osal/host/Mutex.h | 28 ++++ osal/host/MutexFactory.cpp | 28 ++++ osal/host/PeriodicTask.cpp | 176 +++++++++++++++++++++++++ osal/host/PeriodicTask.h | 122 +++++++++++++++++ osal/host/QueueFactory.cpp | 41 ++++++ osal/host/QueueMapManager.cpp | 46 +++++++ osal/host/QueueMapManager.h | 47 +++++++ osal/host/SemaphoreFactory.cpp | 40 ++++++ osal/host/TaskFactory.cpp | 55 ++++++++ 14 files changed, 1227 insertions(+), 1 deletion(-) create mode 100644 osal/host/Clock.cpp create mode 100644 osal/host/MessageQueue.cpp create mode 100644 osal/host/MessageQueue.h create mode 100644 osal/host/Mutex.cpp create mode 100644 osal/host/Mutex.h create mode 100644 osal/host/MutexFactory.cpp create mode 100644 osal/host/PeriodicTask.cpp create mode 100644 osal/host/PeriodicTask.h create mode 100644 osal/host/QueueFactory.cpp create mode 100644 osal/host/QueueMapManager.cpp create mode 100644 osal/host/QueueMapManager.h create mode 100644 osal/host/SemaphoreFactory.cpp create mode 100644 osal/host/TaskFactory.cpp diff --git a/framework.mk b/framework.mk index f2107a4c..2092c2fe 100644 --- a/framework.mk +++ b/framework.mk @@ -34,8 +34,10 @@ else ifeq ($(OS_FSFW),linux) CXXSRC += $(wildcard $(FRAMEWORK_PATH)/osal/linux/*.cpp) else ifeq ($(OS_FSFW),freeRTOS) CXXSRC += $(wildcard $(FRAMEWORK_PATH)/osal/FreeRTOS/*.cpp) +else ifeq ($(OS_FSFW),host) +CXXSRC += $(wildcard $(FRAMEWORK_PATH)/osal/host/*.cpp) else -$(error invalid OS specified, valid OS are rtems, linux, freeRTOS) +$(error invalid OS specified, valid OS are rtems, linux, freeRTOS, host) endif CXXSRC += $(wildcard $(FRAMEWORK_PATH)/parameters/*.cpp) diff --git a/osal/host/Clock.cpp b/osal/host/Clock.cpp new file mode 100644 index 00000000..78bbc58a --- /dev/null +++ b/osal/host/Clock.cpp @@ -0,0 +1,227 @@ +#include +#include + +#include +#if defined(WIN32) +#include +#elif defined(LINUX) +#include +#endif + +uint16_t Clock::leapSeconds = 0; +MutexIF* Clock::timeMutex = NULL; + +using SystemClock = std::chrono::system_clock; + +uint32_t Clock::getTicksPerSecond(void){ + sif::warning << "Clock::getTicksPerSecond: not implemented yet" << std::endl; + return 0; + //return CLOCKS_PER_SEC; + //uint32_t ticks = sysconf(_SC_CLK_TCK); + //return ticks; +} + +ReturnValue_t Clock::setClock(const TimeOfDay_t* time) { + // do some magic with chrono + sif::warning << "Clock::setClock: not implemented yet" << std::endl; + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t Clock::setClock(const timeval* time) { + // do some magic with chrono +#if defined(WIN32) + return HasReturnvaluesIF::RETURN_OK; +#elif defined(LINUX) + return HasReturnvaluesIF::RETURN_OK; +#else + +#endif + sif::warning << "Clock::getUptime: Not implemented for found OS" << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; +} + +ReturnValue_t Clock::getClock_timeval(timeval* time) { +#if defined(WIN32) + auto now = std::chrono::system_clock::now(); + auto secondsChrono = std::chrono::time_point_cast(now); + auto epoch = now.time_since_epoch(); + time->tv_sec = std::chrono::duration_cast(epoch).count(); + auto fraction = now - secondsChrono; + time->tv_usec = std::chrono::duration_cast( + fraction).count(); + return HasReturnvaluesIF::RETURN_OK; +#elif defined(LINUX) + timespec timeUnix; + int status = clock_gettime(CLOCK_REALTIME,&timeUnix); + if(status!=0){ + return HasReturnvaluesIF::RETURN_FAILED; + } + time->tv_sec = timeUnix.tv_sec; + time->tv_usec = timeUnix.tv_nsec / 1000.0; + return HasReturnvaluesIF::RETURN_OK; +#else + sif::warning << "Clock::getUptime: Not implemented for found OS" << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; +#endif + +} + +ReturnValue_t Clock::getClock_usecs(uint64_t* time) { + // do some magic with chrono + sif::warning << "Clock::gerClock_usecs: not implemented yet" << std::endl; + return HasReturnvaluesIF::RETURN_OK; +} + +timeval Clock::getUptime() { + timeval timeval; +#if defined(WIN32) + auto uptime = std::chrono::milliseconds(GetTickCount64()); + auto secondsChrono = std::chrono::duration_cast(uptime); + timeval.tv_sec = secondsChrono.count(); + auto fraction = uptime - secondsChrono; + timeval.tv_usec = std::chrono::duration_cast( + fraction).count(); +#elif defined(LINUX) + double uptimeSeconds; + if (std::ifstream("/proc/uptime", std::ios::in) >> uptimeSeconds) + { + // value is rounded down automatically + timeval.tv_sec = uptimeSeconds; + timeval.tv_usec = uptimeSeconds *(double) 1e6 - (timeval.tv_sec *1e6); + } +#else + sif::warning << "Clock::getUptime: Not implemented for found OS" << std::endl; +#endif + return timeval; +} + +ReturnValue_t Clock::getUptime(timeval* uptime) { + *uptime = getUptime(); + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t Clock::getUptime(uint32_t* uptimeMs) { + timeval uptime = getUptime(); + *uptimeMs = uptime.tv_sec * 1000 + uptime.tv_usec / 1000; + return HasReturnvaluesIF::RETURN_OK; +} + + +ReturnValue_t Clock::getDateAndTime(TimeOfDay_t* time) { + // do some magic with chrono (C++20!) + // Right now, the library doesn't have the new features yet. + // so we work around that for now. + auto now = SystemClock::now(); + auto seconds = std::chrono::time_point_cast(now); + auto fraction = now - seconds; + time_t tt = SystemClock::to_time_t(now); + struct tm* timeInfo; + timeInfo = gmtime(&tt); + time->year = timeInfo->tm_year + 1900; + time->month = timeInfo->tm_mon+1; + time->day = timeInfo->tm_mday; + time->hour = timeInfo->tm_hour; + time->minute = timeInfo->tm_min; + time->second = timeInfo->tm_sec; + auto usecond = std::chrono::duration_cast(fraction); + time->usecond = usecond.count(); + + //sif::warning << "Clock::getDateAndTime: not implemented yet" << std::endl; + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t Clock::convertTimeOfDayToTimeval(const TimeOfDay_t* from, + timeval* to) { + struct tm time_tm; + + time_tm.tm_year = from->year - 1900; + time_tm.tm_mon = from->month - 1; + time_tm.tm_mday = from->day; + + time_tm.tm_hour = from->hour; + time_tm.tm_min = from->minute; + time_tm.tm_sec = from->second; + + time_t seconds = mktime(&time_tm); + + to->tv_sec = seconds; + to->tv_usec = from->usecond; + //Fails in 2038.. + return HasReturnvaluesIF::RETURN_OK; + sif::warning << "Clock::convertTimeBla: not implemented yet" << std::endl; + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t Clock::convertTimevalToJD2000(timeval time, double* JD2000) { + *JD2000 = (time.tv_sec - 946728000. + time.tv_usec / 1000000.) / 24. + / 3600.; + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t Clock::convertUTCToTT(timeval utc, timeval* tt) { + //SHOULDDO: works not for dates in the past (might have less leap seconds) + if (timeMutex == NULL) { + return HasReturnvaluesIF::RETURN_FAILED; + } + + uint16_t leapSeconds; + ReturnValue_t result = getLeapSeconds(&leapSeconds); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + timeval leapSeconds_timeval = { 0, 0 }; + leapSeconds_timeval.tv_sec = leapSeconds; + + //initial offset between UTC and TAI + timeval UTCtoTAI1972 = { 10, 0 }; + + timeval TAItoTT = { 32, 184000 }; + + *tt = utc + leapSeconds_timeval + UTCtoTAI1972 + TAItoTT; + + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t Clock::setLeapSeconds(const uint16_t leapSeconds_) { + if(checkOrCreateClockMutex()!=HasReturnvaluesIF::RETURN_OK){ + return HasReturnvaluesIF::RETURN_FAILED; + } + ReturnValue_t result = timeMutex->lockMutex(MutexIF::NO_TIMEOUT); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + + leapSeconds = leapSeconds_; + + result = timeMutex->unlockMutex(); + return result; +} + +ReturnValue_t Clock::getLeapSeconds(uint16_t* leapSeconds_) { + if(timeMutex == nullptr){ + return HasReturnvaluesIF::RETURN_FAILED; + } + ReturnValue_t result = timeMutex->lockMutex(MutexIF::NO_TIMEOUT); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + + *leapSeconds_ = leapSeconds; + + result = timeMutex->unlockMutex(); + return result; +} + +ReturnValue_t Clock::checkOrCreateClockMutex(){ + if(timeMutex == nullptr){ + MutexFactory* mutexFactory = MutexFactory::instance(); + if (mutexFactory == nullptr) { + return HasReturnvaluesIF::RETURN_FAILED; + } + timeMutex = mutexFactory->createMutex(); + if (timeMutex == nullptr) { + return HasReturnvaluesIF::RETURN_FAILED; + } + } + return HasReturnvaluesIF::RETURN_OK; +} diff --git a/osal/host/MessageQueue.cpp b/osal/host/MessageQueue.cpp new file mode 100644 index 00000000..7d5e4d97 --- /dev/null +++ b/osal/host/MessageQueue.cpp @@ -0,0 +1,144 @@ +#include +#include +#include +#include +#include + +MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize): + messageSize(maxMessageSize), messageDepth(messageDepth) { + queueLock = MutexFactory::instance()->createMutex(); + auto result = QueueMapManager::instance()->addMessageQueue(this, &mqId); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "MessageQueue: Could not be created" << std::endl; + } +} + +MessageQueue::~MessageQueue() { + MutexFactory::instance()->deleteMutex(queueLock); +} + +ReturnValue_t MessageQueue::sendMessage(MessageQueueId_t sendTo, + MessageQueueMessage* message, bool ignoreFault) { + return sendMessageFrom(sendTo, message, this->getId(), ignoreFault); +} + +ReturnValue_t MessageQueue::sendToDefault(MessageQueueMessage* message) { + return sendToDefaultFrom(message, this->getId()); +} + +ReturnValue_t MessageQueue::sendToDefaultFrom(MessageQueueMessage* message, + MessageQueueId_t sentFrom, bool ignoreFault) { + return sendMessageFrom(defaultDestination,message,sentFrom,ignoreFault); +} + +ReturnValue_t MessageQueue::reply(MessageQueueMessage* message) { + if (this->lastPartner != 0) { + return sendMessageFrom(this->lastPartner, message, this->getId()); + } else { + return MessageQueueIF::NO_REPLY_PARTNER; + } +} + +ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo, + MessageQueueMessage* message, MessageQueueId_t sentFrom, + bool ignoreFault) { + return sendMessageFromMessageQueue(sendTo, message, sentFrom, + ignoreFault); +} + +ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message, + MessageQueueId_t* receivedFrom) { + ReturnValue_t status = this->receiveMessage(message); + if(status == HasReturnvaluesIF::RETURN_OK) { + *receivedFrom = this->lastPartner; + } + return status; +} + +ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message) { + if(messageQueue.empty()) { + return MessageQueueIF::EMPTY; + } + // not sure this will work.. + //*message = std::move(messageQueue.front()); + MessageQueueMessage* currentMessage = &messageQueue.front(); + std::copy(currentMessage->getBuffer(), + currentMessage->getBuffer() + messageSize, message->getBuffer()); + messageQueue.pop(); + // The last partner is the first uint32_t field in the message + this->lastPartner = message->getSender(); + return HasReturnvaluesIF::RETURN_OK; +} + +MessageQueueId_t MessageQueue::getLastPartner() const { + return lastPartner; +} + +ReturnValue_t MessageQueue::flush(uint32_t* count) { + *count = messageQueue.size(); + // Clears the queue. + messageQueue = std::queue(); + return HasReturnvaluesIF::RETURN_OK; +} + +MessageQueueId_t MessageQueue::getId() const { + return mqId; +} + +void MessageQueue::setDefaultDestination(MessageQueueId_t defaultDestination) { + defaultDestinationSet = true; + this->defaultDestination = defaultDestination; +} + +MessageQueueId_t MessageQueue::getDefaultDestination() const { + return defaultDestination; +} + +bool MessageQueue::isDefaultDestinationSet() const { + return defaultDestinationSet; +} + + +// static core function to send messages. +ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, + MessageQueueMessage *message, MessageQueueId_t sentFrom, + bool ignoreFault) { + if(message->messageSize > MessageQueueMessage::MAX_DATA_SIZE) { + // Actually, this should never happen or an error will be emitted + // in MessageQueueMessage. + // But I will still return a failure here. + return HasReturnvaluesIF::RETURN_FAILED; + } + MessageQueue* targetQueue = dynamic_cast( + QueueMapManager::instance()->getMessageQueue(sendTo)); + if(targetQueue == nullptr) { + if(not ignoreFault) { + InternalErrorReporterIF* internalErrorReporter = + objectManager->get( + objects::INTERNAL_ERROR_REPORTER); + if (internalErrorReporter != nullptr) { + internalErrorReporter->queueMessageNotSent(); + } + } + // TODO: Better returnvalue + return HasReturnvaluesIF::RETURN_FAILED; + } + + if(targetQueue->messageQueue.size() < targetQueue->messageDepth) { + MutexHelper mutexLock(targetQueue->queueLock, 20); + targetQueue->messageQueue.push(*message); + } + else { + return MessageQueueIF::FULL; + } + message->setSender(sentFrom); + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t MessageQueue::lockQueue(millis_t lockTimeout) { + return queueLock->lockMutex(lockTimeout); +} + +ReturnValue_t MessageQueue::unlockQueue() { + return queueLock->unlockMutex(); +} diff --git a/osal/host/MessageQueue.h b/osal/host/MessageQueue.h new file mode 100644 index 00000000..a0cce001 --- /dev/null +++ b/osal/host/MessageQueue.h @@ -0,0 +1,230 @@ +#ifndef FRAMEWORK_OSAL_HOST_MESSAGEQUEUE_H_ +#define FRAMEWORK_OSAL_HOST_MESSAGEQUEUE_H_ + +#include +#include +#include +#include +#include + +#include +#include + +/** + * @brief This class manages sending and receiving of + * message queue messages. + * @details + * Message queues are used to pass asynchronous messages between processes. + * They work like post boxes, where all incoming messages are stored in FIFO + * order. This class creates a new receiving queue and provides methods to fetch + * received messages. Being a child of MessageQueueSender, this class also + * provides methods to send a message to a user-defined or a default destination. + * In addition it also provides a reply method to answer to the queue it + * received its last message from. + * + * The MessageQueue should be used as "post box" for a single owning object. + * So all message queue communication is "n-to-one". + * For creating the queue, as well as sending and receiving messages, the class + * makes use of the operating system calls provided. + * + * Please keep in mind that FreeRTOS offers different calls for message queue + * operations if called from an ISR. + * For now, the system context needs to be switched manually. + * @ingroup osal + * @ingroup message_queue + */ +class MessageQueue : public MessageQueueIF { + friend class MessageQueueSenderIF; +public: + /** + * @brief The constructor initializes and configures the message queue. + * @details + * By making use of the according operating system call, a message queue is + * created and initialized. The message depth - the maximum number of + * messages to be buffered - may be set with the help of a parameter, + * whereas the message size is automatically set to the maximum message + * queue message size. The operating system sets the message queue id, or + * in case of failure, it is set to zero. + * @param message_depth + * The number of messages to be buffered before passing an error to the + * sender. Default is three. + * @param max_message_size + * With this parameter, the maximum message size can be adjusted. + * This should be left default. + */ + MessageQueue(size_t messageDepth = 3, + size_t maxMessageSize = MessageQueueMessage::MAX_MESSAGE_SIZE); + + /** Copying message queues forbidden */ + MessageQueue(const MessageQueue&) = delete; + MessageQueue& operator=(const MessageQueue&) = delete; + + /** + * @brief The destructor deletes the formerly created message queue. + * @details This is accomplished by using the delete call provided + * by the operating system. + */ + virtual ~MessageQueue(); + + /** + * @brief This operation sends a message to the given destination. + * @details It directly uses the sendMessage call of the MessageQueueSender + * parent, but passes its queue id as "sentFrom" parameter. + * @param sendTo This parameter specifies the message queue id of the + * destination message queue. + * @param message A pointer to a previously created message, which is sent. + * @param ignoreFault If set to true, the internal software fault counter + * is not incremented if queue is full. + */ + ReturnValue_t sendMessage(MessageQueueId_t sendTo, + MessageQueueMessage* message, bool ignoreFault = false) override; + /** + * @brief This operation sends a message to the default destination. + * @details As in the sendMessage method, this function uses the + * sendToDefault call of the MessageQueueSender parent class and adds its + * queue id as "sentFrom" information. + * @param message A pointer to a previously created message, which is sent. + */ + ReturnValue_t sendToDefault(MessageQueueMessage* message) override; + /** + * @brief This operation sends a message to the last communication partner. + * @details This operation simplifies answering an incoming message by using + * the stored lastPartner information as destination. If there was no + * message received yet (i.e. lastPartner is zero), an error code is returned. + * @param message A pointer to a previously created message, which is sent. + */ + ReturnValue_t reply(MessageQueueMessage* message) override; + + /** + * @brief With the sendMessage call, a queue message is sent to a + * receiving queue. + * @details + * This method takes the message provided, adds the sentFrom information and + * passes it on to the destination provided with an operating system call. + * The OS's return value is returned. + * @param sendTo This parameter specifies the message queue id to send + * the message to. + * @param message This is a pointer to a previously created message, + * which is sent. + * @param sentFrom The sentFrom information can be set to inject the + * sender's queue id into the message. This variable is set to zero by + * default. + * @param ignoreFault If set to true, the internal software fault counter + * is not incremented if queue is full. + */ + virtual ReturnValue_t sendMessageFrom( MessageQueueId_t sendTo, + MessageQueueMessage* message, MessageQueueId_t sentFrom = NO_QUEUE, + bool ignoreFault = false) override; + + /** + * @brief The sendToDefault method sends a queue message to the default + * destination. + * @details + * In all other aspects, it works identical to the sendMessage method. + * @param message This is a pointer to a previously created message, + * which is sent. + * @param sentFrom The sentFrom information can be set to inject the + * sender's queue id into the message. This variable is set to zero by + * default. + */ + virtual ReturnValue_t sendToDefaultFrom( MessageQueueMessage* message, + MessageQueueId_t sentFrom = NO_QUEUE, + bool ignoreFault = false) override; + + /** + * @brief This function reads available messages from the message queue + * and returns the sender. + * @details + * It works identically to the other receiveMessage call, but in addition + * returns the sender's queue id. + * @param message A pointer to a message in which the received data is stored. + * @param receivedFrom A pointer to a queue id in which the sender's id is stored. + */ + ReturnValue_t receiveMessage(MessageQueueMessage* message, + MessageQueueId_t *receivedFrom) override; + + /** + * @brief This function reads available messages from the message queue. + * @details + * If data is available it is stored in the passed message pointer. + * The message's original content is overwritten and the sendFrom + * information is stored in the lastPartner attribute. Else, the lastPartner + * information remains untouched, the message's content is cleared and the + * function returns immediately. + * @param message A pointer to a message in which the received data is stored. + */ + ReturnValue_t receiveMessage(MessageQueueMessage* message) override; + /** + * Deletes all pending messages in the queue. + * @param count The number of flushed messages. + * @return RETURN_OK on success. + */ + ReturnValue_t flush(uint32_t* count) override; + /** + * @brief This method returns the message queue id of the last + * communication partner. + */ + MessageQueueId_t getLastPartner() const override; + /** + * @brief This method returns the message queue id of this class's + * message queue. + */ + MessageQueueId_t getId() const override; + + /** + * @brief This method is a simple setter for the default destination. + */ + void setDefaultDestination(MessageQueueId_t defaultDestination) override; + /** + * @brief This method is a simple getter for the default destination. + */ + MessageQueueId_t getDefaultDestination() const override; + + bool isDefaultDestinationSet() const override; + + ReturnValue_t lockQueue(millis_t lockTimeout); + ReturnValue_t unlockQueue(); +protected: + /** + * @brief Implementation to be called from any send Call within + * MessageQueue and MessageQueueSenderIF. + * @details + * This method takes the message provided, adds the sentFrom information and + * passes it on to the destination provided with an operating system call. + * The OS's return value is returned. + * @param sendTo + * This parameter specifies the message queue id to send the message to. + * @param message + * This is a pointer to a previously created message, which is sent. + * @param sentFrom + * The sentFrom information can be set to inject the sender's queue id into + * the message. This variable is set to zero by default. + * @param ignoreFault + * If set to true, the internal software fault counter is not incremented + * if queue is full. + * @param context Specify whether call is made from task or from an ISR. + */ + static ReturnValue_t sendMessageFromMessageQueue(MessageQueueId_t sendTo, + MessageQueueMessage* message, MessageQueueId_t sentFrom = NO_QUEUE, + bool ignoreFault=false); + + //static ReturnValue_t handleSendResult(BaseType_t result, bool ignoreFault); + +private: + std::queue messageQueue; + /** + * @brief The class stores the queue id it got assigned. + * If initialization fails, the queue id is set to zero. + */ + MessageQueueId_t mqId = 0; + size_t messageSize = 0; + size_t messageDepth = 0; + + MutexIF* queueLock; + + bool defaultDestinationSet = false; + MessageQueueId_t defaultDestination = 0; + MessageQueueId_t lastPartner = 0; +}; + +#endif /* FRAMEWORK_OSAL_HOST_MESSAGEQUEUE_H_ */ diff --git a/osal/host/Mutex.cpp b/osal/host/Mutex.cpp new file mode 100644 index 00000000..0e6e652d --- /dev/null +++ b/osal/host/Mutex.cpp @@ -0,0 +1,40 @@ +#include +#include + +const uint32_t MutexIF::NO_TIMEOUT = 0; +const uint32_t MutexIF::MAX_TIMEOUT = 0xffffffff; + +ReturnValue_t Mutex::lockMutex(uint32_t timeoutMs) { + if(timeoutMs == MutexIF::MAX_TIMEOUT) { + mutex.lock(); + locked = true; + return HasReturnvaluesIF::RETURN_OK; + } + else if(timeoutMs == MutexIF::NO_TIMEOUT) { + if(mutex.try_lock()) { + locked = true; + return HasReturnvaluesIF::RETURN_OK; + } + } + else if(timeoutMs > MutexIF::NO_TIMEOUT){ + auto chronoMs = std::chrono::milliseconds(timeoutMs); + if(mutex.try_lock_for(chronoMs)) { + locked = true; + return HasReturnvaluesIF::RETURN_OK; + } + } + return MutexIF::MUTEX_TIMEOUT; +} + +ReturnValue_t Mutex::unlockMutex() { + if(not locked) { + return MutexIF::CURR_THREAD_DOES_NOT_OWN_MUTEX; + } + mutex.unlock(); + locked = false; + return HasReturnvaluesIF::RETURN_OK; +} + +std::timed_mutex* Mutex::getMutexHandle() { + return &mutex; +} diff --git a/osal/host/Mutex.h b/osal/host/Mutex.h new file mode 100644 index 00000000..dce2a9dc --- /dev/null +++ b/osal/host/Mutex.h @@ -0,0 +1,28 @@ +#ifndef FRAMEWORK_OSAL_FREERTOS_MUTEX_H_ +#define FRAMEWORK_OSAL_FREERTOS_MUTEX_H_ + +#include + +#include + +/** + * @brief OS component to implement MUTual EXclusion + * + * @details + * Mutexes are binary semaphores which include a priority inheritance mechanism. + * Documentation: https://www.freertos.org/Real-time-embedded-RTOS-mutexes.html + * @ingroup osal + */ +class Mutex : public MutexIF { +public: + Mutex() = default; + ReturnValue_t lockMutex(uint32_t timeoutMs = MutexIF::MAX_TIMEOUT) override; + ReturnValue_t unlockMutex() override; + + std::timed_mutex* getMutexHandle(); +private: + bool locked = false; + std::timed_mutex mutex; +}; + +#endif /* FRAMEWORK_FREERTOS_MUTEX_H_ */ diff --git a/osal/host/MutexFactory.cpp b/osal/host/MutexFactory.cpp new file mode 100644 index 00000000..25d9fa46 --- /dev/null +++ b/osal/host/MutexFactory.cpp @@ -0,0 +1,28 @@ +#include +#include + +//TODO: Different variant than the lazy loading in QueueFactory. +//What's better and why? -> one is on heap the other on bss/data +//MutexFactory* MutexFactory::factoryInstance = new MutexFactory(); +MutexFactory* MutexFactory::factoryInstance = nullptr; + +MutexFactory::MutexFactory() { +} + +MutexFactory::~MutexFactory() { +} + +MutexFactory* MutexFactory::instance() { + if (factoryInstance == nullptr){ + factoryInstance = new MutexFactory(); + } + return MutexFactory::factoryInstance; +} + +MutexIF* MutexFactory::createMutex() { + return new Mutex(); +} + +void MutexFactory::deleteMutex(MutexIF* mutex) { + delete mutex; +} diff --git a/osal/host/PeriodicTask.cpp b/osal/host/PeriodicTask.cpp new file mode 100644 index 00000000..57898ac2 --- /dev/null +++ b/osal/host/PeriodicTask.cpp @@ -0,0 +1,176 @@ +#include +#include +#include + +#include +#include + +#include +#include + +#if defined(WIN32) +#include +#elif defined(LINUX) +#include +#endif + +PeriodicTask::PeriodicTask(const char *name, TaskPriority setPriority, + TaskStackSize setStack, TaskPeriod setPeriod, + void (*setDeadlineMissedFunc)()) : + started(false), taskName(name), period(setPeriod), + deadlineMissedFunc(setDeadlineMissedFunc) { + // It is propably possible to set task priorities by using the native + // task handles for Windows / Linux + mainThread = std::thread(&PeriodicTask::taskEntryPoint, this, this); +#if defined(WIN32) + /* List of possible priority classes: + * https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/ + * nf-processthreadsapi-setpriorityclass + * And respective thread priority numbers: + * https://docs.microsoft.com/en-us/windows/ + * win32/procthread/scheduling-priorities */ + int result = SetPriorityClass( + reinterpret_cast(mainThread.native_handle()), + ABOVE_NORMAL_PRIORITY_CLASS); + if(result != 0) { + sif::error << "PeriodicTask: Windows SetPriorityClass failed with code " + << GetLastError() << std::endl; + } + result = SetThreadPriority( + reinterpret_cast(mainThread.native_handle()), + THREAD_PRIORITY_NORMAL); + if(result != 0) { + sif::error << "PeriodicTask: Windows SetPriorityClass failed with code " + << GetLastError() << std::endl; + } +#elif defined(LINUX) + // we can just copy and paste the code from linux here. +#endif +} + +PeriodicTask::~PeriodicTask(void) { + //Do not delete objects, we were responsible for ptrs only. + terminateThread = true; + if(mainThread.joinable()) { + mainThread.join(); + } + delete this; +} + +void PeriodicTask::taskEntryPoint(void* argument) { + PeriodicTask *originalTask(reinterpret_cast(argument)); + + + if (not originalTask->started) { + // we have to suspend/block here until the task is started. + // if semaphores are implemented, use them here. + std::unique_lock lock(initMutex); + initCondition.wait(lock); + } + + this->taskFunctionality(); + sif::debug << "PeriodicTask::taskEntryPoint: " + "Returned from taskFunctionality." << std::endl; +} + +ReturnValue_t PeriodicTask::startTask() { + started = true; + + // Notify task to start. + std::lock_guard lock(initMutex); + initCondition.notify_one(); + + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t PeriodicTask::sleepFor(uint32_t ms) { + std::this_thread::sleep_for(std::chrono::milliseconds(ms)); + return HasReturnvaluesIF::RETURN_OK; +} + +void PeriodicTask::taskFunctionality() { + std::chrono::milliseconds periodChrono(static_cast(period*1000)); + auto currentStartTime { + std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()) + }; + auto nextStartTime{ currentStartTime }; + + /* Enter the loop that defines the task behavior. */ + for (;;) { + if(terminateThread.load()) { + break; + } + for (ObjectList::iterator it = objectList.begin(); + it != objectList.end(); ++it) { + (*it)->performOperation(); + } + if(not delayUntil(¤tStartTime, periodChrono)) { + sif::warning << "PeriodicTask: " << taskName << + " missed deadline!\n" << std::flush; + if(deadlineMissedFunc != nullptr) { + this->deadlineMissedFunc(); + } + } + } +} + +ReturnValue_t PeriodicTask::addComponent(object_id_t object) { + ExecutableObjectIF* newObject = objectManager->get( + object); + if (newObject == nullptr) { + return HasReturnvaluesIF::RETURN_FAILED; + } + objectList.push_back(newObject); + return HasReturnvaluesIF::RETURN_OK; +} + +uint32_t PeriodicTask::getPeriodMs() const { + return period * 1000; +} + +bool PeriodicTask::delayUntil(std::chrono::milliseconds * previousWakeTimeMs, + const std::chrono::milliseconds interval) { + bool shouldDelay = false; + //Get current wakeup time + auto currentStartTime = + std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()); + /* Generate the tick time at which the task wants to wake. */ + auto nextTimeToWake_ms = (*previousWakeTimeMs) + interval; + + if (currentStartTime < *previousWakeTimeMs) { + /* The tick count has overflowed since this function was + lasted called. In this case the only time we should ever + actually delay is if the wake time has also overflowed, + and the wake time is greater than the tick time. When this + is the case it is as if neither time had overflowed. */ + if ((nextTimeToWake_ms < *previousWakeTimeMs) + && (nextTimeToWake_ms > currentStartTime)) { + shouldDelay = true; + } + } else { + /* The tick time has not overflowed. In this case we will + delay if either the wake time has overflowed, and/or the + tick time is less than the wake time. */ + if ((nextTimeToWake_ms < *previousWakeTimeMs) + || (nextTimeToWake_ms > currentStartTime)) { + shouldDelay = true; + } + } + + /* Update the wake time ready for the next call. */ + + (*previousWakeTimeMs) = nextTimeToWake_ms; + + if (shouldDelay) { + auto sleepTime = std::chrono::duration_cast( + nextTimeToWake_ms - currentStartTime); + std::this_thread::sleep_for(sleepTime); + return true; + } + //We are shifting the time in case the deadline was missed like rtems + (*previousWakeTimeMs) = currentStartTime; + return false; + +} diff --git a/osal/host/PeriodicTask.h b/osal/host/PeriodicTask.h new file mode 100644 index 00000000..19c06b52 --- /dev/null +++ b/osal/host/PeriodicTask.h @@ -0,0 +1,122 @@ +#ifndef FRAMEWORK_OSAL_HOST_PERIODICTASK_H_ +#define FRAMEWORK_OSAL_HOST_PERIODICTASK_H_ + +#include +#include +#include + +#include +#include +#include +#include + +class ExecutableObjectIF; + +/** + * @brief This class represents a specialized task for + * periodic activities of multiple objects. + * @details + * + * @ingroup task_handling + */ +class PeriodicTask: public PeriodicTaskIF { +public: + /** + * @brief Standard constructor of the class. + * @details + * The class is initialized without allocated objects. These need to be + * added with #addComponent. + * @param priority + * @param stack_size + * @param setPeriod + * @param setDeadlineMissedFunc + * The function pointer to the deadline missed function that shall be + * assigned. + */ + PeriodicTask(const char *name, TaskPriority setPriority, TaskStackSize setStack, + TaskPeriod setPeriod,void (*setDeadlineMissedFunc)()); + /** + * @brief Currently, the executed object's lifetime is not coupled with + * the task object's lifetime, so the destructor is empty. + */ + virtual ~PeriodicTask(void); + + /** + * @brief The method to start the task. + * @details The method starts the task with the respective system call. + * Entry point is the taskEntryPoint method described below. + * The address of the task object is passed as an argument + * to the system call. + */ + ReturnValue_t startTask(void); + /** + * Adds an object to the list of objects to be executed. + * The objects are executed in the order added. + * @param object Id of the object to add. + * @return + * -@c RETURN_OK on success + * -@c RETURN_FAILED if the object could not be added. + */ + ReturnValue_t addComponent(object_id_t object); + + uint32_t getPeriodMs() const; + + ReturnValue_t sleepFor(uint32_t ms); + +protected: + bool started; + //!< Typedef for the List of objects. + typedef std::vector ObjectList; + std::thread mainThread; + std::atomic terminateThread = false; + + /** + * @brief This attribute holds a list of objects to be executed. + */ + ObjectList objectList; + + std::condition_variable initCondition; + std::mutex initMutex; + std::string taskName; + /** + * @brief The period of the task. + * @details + * The period determines the frequency of the task's execution. + * It is expressed in clock ticks. + */ + TaskPeriod period; + /** + * @brief The pointer to the deadline-missed function. + * @details + * This pointer stores the function that is executed if the task's deadline + * is missed. So, each may react individually on a timing failure. + * The pointer may be NULL, then nothing happens on missing the deadline. + * The deadline is equal to the next execution of the periodic task. + */ + void (*deadlineMissedFunc)(void); + /** + * @brief This is the function executed in the new task's context. + * @details + * It converts the argument back to the thread object type and copies the + * class instance to the task context. + * The taskFunctionality method is called afterwards. + * @param A pointer to the task object itself is passed as argument. + */ + + void taskEntryPoint(void* argument); + /** + * @brief The function containing the actual functionality of the task. + * @details + * The method sets and starts the task's period, then enters a loop that is + * repeated as long as the isRunning attribute is true. Within the loop, + * all performOperation methods of the added objects are called. Afterwards + * the checkAndRestartPeriod system call blocks the task until the next + * period. On missing the deadline, the deadlineMissedFunction is executed. + */ + void taskFunctionality(void); + + bool delayUntil(std::chrono::milliseconds * previousWakeTimeMs, + const std::chrono::milliseconds interval); +}; + +#endif /* PERIODICTASK_H_ */ diff --git a/osal/host/QueueFactory.cpp b/osal/host/QueueFactory.cpp new file mode 100644 index 00000000..691249c3 --- /dev/null +++ b/osal/host/QueueFactory.cpp @@ -0,0 +1,41 @@ +#include +#include +#include +#include + +QueueFactory* QueueFactory::factoryInstance = nullptr; + + +ReturnValue_t MessageQueueSenderIF::sendMessage(MessageQueueId_t sendTo, + MessageQueueMessage* message, MessageQueueId_t sentFrom, + bool ignoreFault) { + return MessageQueue::sendMessageFromMessageQueue(sendTo,message, + sentFrom,ignoreFault); + return HasReturnvaluesIF::RETURN_OK; +} + +QueueFactory* QueueFactory::instance() { + if (factoryInstance == nullptr) { + factoryInstance = new QueueFactory; + } + return factoryInstance; +} + +QueueFactory::QueueFactory() { +} + +QueueFactory::~QueueFactory() { +} + +MessageQueueIF* QueueFactory::createMessageQueue(size_t messageDepth, + size_t maxMessageSize) { + // A thread-safe queue can be implemented by using a combination + // of std::queue and std::mutex. This uses dynamic memory allocation + // which could be alleviated by using a custom allocator, external library + // (etl::queue) or simply using std::queue, we're on a host machine anyway. + return new MessageQueue(messageDepth, maxMessageSize); +} + +void QueueFactory::deleteMessageQueue(MessageQueueIF* queue) { + delete queue; +} diff --git a/osal/host/QueueMapManager.cpp b/osal/host/QueueMapManager.cpp new file mode 100644 index 00000000..a57d2c0c --- /dev/null +++ b/osal/host/QueueMapManager.cpp @@ -0,0 +1,46 @@ +#include +#include +#include + +QueueMapManager* QueueMapManager::mqManagerInstance = nullptr; + +QueueMapManager::QueueMapManager() {} + +QueueMapManager* QueueMapManager::instance() { + if (mqManagerInstance == nullptr){ + mqManagerInstance = new QueueMapManager(); + } + return QueueMapManager::mqManagerInstance; +} + +ReturnValue_t QueueMapManager::addMessageQueue( + MessageQueueIF* queueToInsert, MessageQueueId_t* id) { + uint32_t currentId = queueCounter++; + auto returnPair = queueMap.emplace(currentId, queueToInsert); + if(not returnPair.second) { + // this should never happen for the atomic variable. + sif::error << "QueueMapManager: This ID is already inside the map!" + << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + if (id != nullptr) { + *id = currentId; + } + mapLock = MutexFactory::instance()->createMutex(); + return HasReturnvaluesIF::RETURN_OK; +} + +MessageQueueIF* QueueMapManager::getMessageQueue( + MessageQueueId_t messageQueueId) const { + MutexHelper(mapLock, 50); + auto queueIter = queueMap.find(messageQueueId); + if(queueIter != queueMap.end()) { + return queueIter->second; + } + else { + sif::warning << "QueueMapManager::getQueueHandle: The ID" << + messageQueueId << " does not exists in the map" << std::endl; + return nullptr; + } +} + diff --git a/osal/host/QueueMapManager.h b/osal/host/QueueMapManager.h new file mode 100644 index 00000000..34f0fc95 --- /dev/null +++ b/osal/host/QueueMapManager.h @@ -0,0 +1,47 @@ +#ifndef FRAMEWORK_OSAL_HOST_QUEUEMAP_H_ +#define FRAMEWORK_OSAL_HOST_QUEUEMAP_H_ + +#include +#include +#include +#include + +using QueueMap = std::unordered_map; + + +/** + * An internal map to map message queue IDs to message queues. + * This propably should be a singleton.. + */ +class QueueMapManager { +public: + //! Returns the single instance of SemaphoreFactory. + static QueueMapManager* instance(); + + /** + * Insert a message queue into the map and returns a message queue ID + * @param queue The message queue to insert. + * @param id The passed value will be set unless a nullptr is passed + * @return + */ + ReturnValue_t addMessageQueue(MessageQueueIF* queue, MessageQueueId_t* + id = nullptr); + /** + * Get the message queue handle by providing a message queue ID. + * @param messageQueueId + * @return + */ + MessageQueueIF* getMessageQueue(MessageQueueId_t messageQueueId) const; + +private: + //! External instantiation is forbidden. + QueueMapManager(); + std::atomic queueCounter = MessageQueueIF::NO_QUEUE + 1; + MutexIF* mapLock; + QueueMap queueMap; + static QueueMapManager* mqManagerInstance; +}; + + + +#endif /* FRAMEWORK_OSAL_HOST_QUEUEMAP_H_ */ diff --git a/osal/host/SemaphoreFactory.cpp b/osal/host/SemaphoreFactory.cpp new file mode 100644 index 00000000..3719a883 --- /dev/null +++ b/osal/host/SemaphoreFactory.cpp @@ -0,0 +1,40 @@ +#include +#include +#include +#include + +const uint32_t SemaphoreIF::NO_TIMEOUT = 0; +const uint32_t SemaphoreIF::MAX_TIMEOUT = 0xFFFFFFFF; + +SemaphoreFactory* SemaphoreFactory::factoryInstance = nullptr; + +SemaphoreFactory::SemaphoreFactory() { +} + +SemaphoreFactory::~SemaphoreFactory() { + delete factoryInstance; +} + +SemaphoreFactory* SemaphoreFactory::instance() { + if (factoryInstance == nullptr){ + factoryInstance = new SemaphoreFactory(); + } + return SemaphoreFactory::factoryInstance; +} + +SemaphoreIF* SemaphoreFactory::createBinarySemaphore(uint32_t arguments) { + sif::error << "SemaphoreFactory: Binary Semaphore not implemented yet." + " Returning nullptr!\n" << std::flush; + return nullptr; +} + +SemaphoreIF* SemaphoreFactory::createCountingSemaphore(const uint8_t maxCount, + uint8_t initCount, uint32_t arguments) { + sif::error << "SemaphoreFactory: Counting Semaphore not implemented yet." + " Returning nullptr!\n" << std::flush; + return nullptr; +} + +void SemaphoreFactory::deleteSemaphore(SemaphoreIF* semaphore) { + delete semaphore; +} diff --git a/osal/host/TaskFactory.cpp b/osal/host/TaskFactory.cpp new file mode 100644 index 00000000..a13844c4 --- /dev/null +++ b/osal/host/TaskFactory.cpp @@ -0,0 +1,55 @@ +#include +#include +#include +#include + +#include + +TaskFactory* TaskFactory::factoryInstance = new TaskFactory(); + +// Will propably not be used for hosted implementation +const size_t PeriodicTaskIF::MINIMUM_STACK_SIZE = 0; + +TaskFactory::TaskFactory() { +} + +TaskFactory::~TaskFactory() { +} + +TaskFactory* TaskFactory::instance() { + return TaskFactory::factoryInstance; +} + +PeriodicTaskIF* TaskFactory::createPeriodicTask(TaskName name_, + TaskPriority taskPriority_,TaskStackSize stackSize_, + TaskPeriod periodInSeconds_, + TaskDeadlineMissedFunction deadLineMissedFunction_) { + // This is going to be interesting. Time now learn the C++ threading library + // :-) + return new PeriodicTask(name_, taskPriority_, stackSize_, periodInSeconds_, + deadLineMissedFunction_); +} + +FixedTimeslotTaskIF* TaskFactory::createFixedTimeslotTask(TaskName name_, + TaskPriority taskPriority_,TaskStackSize stackSize_, + TaskPeriod periodInSeconds_, + TaskDeadlineMissedFunction deadLineMissedFunction_) { + // This is going to be interesting. Time now learn the C++ threading library + // :-) + sif::warning << "TaskFactory::createFixedTimeslotTask: Not implemented " + "yet" << std::endl; + return nullptr; +} + +ReturnValue_t TaskFactory::deleteTask(PeriodicTaskIF* task) { + // This might block for some time! + delete task; + return HasReturnvaluesIF::RETURN_FAILED; +} + +ReturnValue_t TaskFactory::delayTask(uint32_t delayMs){ + std::this_thread::sleep_for(std::chrono::milliseconds(delayMs)); + return HasReturnvaluesIF::RETURN_OK; +} + + From ef3e5c4582df70896758e775bed5383b7c415689 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 5 Jun 2020 18:20:21 +0200 Subject: [PATCH 056/307] very important bugfix for serial buffer adapter --- serialize/SerialBufferAdapter.cpp | 39 ++++++++++++------------------- serialize/SerialBufferAdapter.h | 9 +++---- 2 files changed, 20 insertions(+), 28 deletions(-) diff --git a/serialize/SerialBufferAdapter.cpp b/serialize/SerialBufferAdapter.cpp index e13e7eb6..db91a93f 100644 --- a/serialize/SerialBufferAdapter.cpp +++ b/serialize/SerialBufferAdapter.cpp @@ -3,22 +3,17 @@ #include template -SerialBufferAdapter::SerialBufferAdapter(const void* buffer, +SerialBufferAdapter::SerialBufferAdapter(const uint8_t* buffer, count_t bufferLength, bool serializeLength) : serializeLength(serializeLength), - constBuffer(static_cast(buffer)), m_buffer(nullptr), - bufferLength(bufferLength) { - -} + constBuffer(buffer), buffer(nullptr), + bufferLength(bufferLength) {} template -SerialBufferAdapter::SerialBufferAdapter(void* buffer, +SerialBufferAdapter::SerialBufferAdapter(uint8_t* buffer, count_t bufferLength, bool serializeLength) : - serializeLength(serializeLength), bufferLength(bufferLength) { - uint8_t * member_buffer = static_cast(buffer); - m_buffer = member_buffer; - constBuffer = member_buffer; -} + serializeLength(serializeLength), buffer(buffer), constBuffer(buffer), + bufferLength(bufferLength) {} template @@ -42,8 +37,8 @@ ReturnValue_t SerialBufferAdapter::serialize(uint8_t** buffer, } if (constBuffer != nullptr) { memcpy(*buffer, constBuffer, bufferLength); - } else if (m_buffer != nullptr) { - memcpy(*buffer, m_buffer, bufferLength); + } else if (buffer != nullptr) { + memcpy(*buffer, buffer, bufferLength); } else { return HasReturnvaluesIF::RETURN_FAILED; } @@ -66,14 +61,11 @@ template ReturnValue_t SerialBufferAdapter::deSerialize(const uint8_t** buffer, size_t* size, bool bigEndian) { //TODO Ignores Endian flag! - // (Robin) the one of the buffer? wouldn't that be an issue for serialize - // as well? SerialFixedArrayListAdapter implements swapping of buffer - // fields (if buffer type is not uint8_t) if (buffer != nullptr) { if(serializeLength) { count_t serializedSize = AutoSerializeAdapter::getSerializedSize( &bufferLength); - if(bufferLength + serializedSize >= *size) { + if(bufferLength + serializedSize <= *size) { *buffer += serializedSize; *size -= serializedSize; } @@ -84,7 +76,7 @@ ReturnValue_t SerialBufferAdapter::deSerialize(const uint8_t** buffer, //No Else If, go on with buffer if (bufferLength <= *size) { *size -= bufferLength; - memcpy(m_buffer, *buffer, bufferLength); + memcpy(buffer, *buffer, bufferLength); (*buffer) += bufferLength; return HasReturnvaluesIF::RETURN_OK; } @@ -99,28 +91,27 @@ ReturnValue_t SerialBufferAdapter::deSerialize(const uint8_t** buffer, template uint8_t * SerialBufferAdapter::getBuffer() { - if(m_buffer == nullptr) { + if(buffer == nullptr) { sif::error << "Wrong access function for stored type !" " Use getConstBuffer()" << std::endl; return nullptr; } - return m_buffer; + return buffer; } template const uint8_t * SerialBufferAdapter::getConstBuffer() { if(constBuffer == nullptr) { - sif::error << "Wrong access function for stored type !" - " Use getBuffer()" << std::endl; + sif::error << "SerialBufferAdapter: Buffers are unitialized!" << std::endl; return nullptr; } return constBuffer; } template -void SerialBufferAdapter::setBuffer(void * buffer, +void SerialBufferAdapter::setBuffer(uint8_t* buffer, count_t buffer_length) { - m_buffer = static_cast(buffer); + this->buffer = buffer; bufferLength = buffer_length; } diff --git a/serialize/SerialBufferAdapter.h b/serialize/SerialBufferAdapter.h index d414573c..cb799be5 100644 --- a/serialize/SerialBufferAdapter.h +++ b/serialize/SerialBufferAdapter.h @@ -29,7 +29,7 @@ public: * @param bufferLength * @param serializeLength */ - SerialBufferAdapter(const void* buffer, count_t bufferLength, + SerialBufferAdapter(const uint8_t* buffer, count_t bufferLength, bool serializeLength = false); /** @@ -40,7 +40,8 @@ public: * @param bufferLength * @param serializeLength Length field will be serialized with size count_t */ - SerialBufferAdapter(void* buffer, count_t bufferLength, bool serializeLength = false); + SerialBufferAdapter(uint8_t* buffer, count_t bufferLength, + bool serializeLength = false); virtual ~SerialBufferAdapter(); @@ -66,11 +67,11 @@ public: uint8_t * getBuffer(); const uint8_t * getConstBuffer(); - void setBuffer(void* buffer_, count_t bufferLength_); + void setBuffer(uint8_t* buffer_, count_t bufferLength_); private: bool serializeLength = false; const uint8_t *constBuffer = nullptr; - uint8_t *m_buffer = nullptr; + uint8_t *buffer = nullptr; count_t bufferLength = 0; }; From 872c350a9296999af94ad2c275fd2bf34abec1b0 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 5 Jun 2020 18:36:22 +0200 Subject: [PATCH 057/307] another small bugfix (this-> was missing) --- serialize/SerialBufferAdapter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/serialize/SerialBufferAdapter.cpp b/serialize/SerialBufferAdapter.cpp index db91a93f..ad4ec358 100644 --- a/serialize/SerialBufferAdapter.cpp +++ b/serialize/SerialBufferAdapter.cpp @@ -76,7 +76,7 @@ ReturnValue_t SerialBufferAdapter::deSerialize(const uint8_t** buffer, //No Else If, go on with buffer if (bufferLength <= *size) { *size -= bufferLength; - memcpy(buffer, *buffer, bufferLength); + memcpy(this->buffer, *buffer, bufferLength); (*buffer) += bufferLength; return HasReturnvaluesIF::RETURN_OK; } From 8d3ac33b0ef0b22e35dc102f9d715878780d50df Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 5 Jun 2020 20:18:38 +0200 Subject: [PATCH 058/307] reordering init list for compiler --- serialize/SerialBufferAdapter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/serialize/SerialBufferAdapter.cpp b/serialize/SerialBufferAdapter.cpp index ad4ec358..e409686f 100644 --- a/serialize/SerialBufferAdapter.cpp +++ b/serialize/SerialBufferAdapter.cpp @@ -12,7 +12,7 @@ SerialBufferAdapter::SerialBufferAdapter(const uint8_t* buffer, template SerialBufferAdapter::SerialBufferAdapter(uint8_t* buffer, count_t bufferLength, bool serializeLength) : - serializeLength(serializeLength), buffer(buffer), constBuffer(buffer), + serializeLength(serializeLength), constBuffer(buffer), buffer(buffer), bufferLength(bufferLength) {} From 9fd5ef0194ebad3e2fe1bfc90b705fe7438ac29b Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 5 Jun 2020 20:28:06 +0200 Subject: [PATCH 059/307] updated datapool files --- datapool/DataSetBase.cpp | 65 ++++++++++++++++++++++----------------- datapool/DataSetBase.h | 48 ++++++++++++++++++----------- datapool/DataSetIF.h | 8 +++-- datapool/PoolVariableIF.h | 52 +++++++++++++++++++++++-------- 4 files changed, 112 insertions(+), 61 deletions(-) diff --git a/datapool/DataSetBase.cpp b/datapool/DataSetBase.cpp index 6ff2fc83..9104c8e7 100644 --- a/datapool/DataSetBase.cpp +++ b/datapool/DataSetBase.cpp @@ -31,20 +31,14 @@ ReturnValue_t DataSetBase::registerVariable( return HasReturnvaluesIF::RETURN_OK; } -ReturnValue_t DataSetBase::read() { +ReturnValue_t DataSetBase::read(uint32_t lockTimeout) { ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; if (state == States::DATA_SET_UNINITIALISED) { - lockDataPool(); + lockDataPool(lockTimeout); for (uint16_t count = 0; count < fillCount; count++) { - if (registeredVariables[count]->getReadWriteMode() - != PoolVariableIF::VAR_WRITE - && registeredVariables[count]->getDataPoolId() - != PoolVariableIF::NO_PARAMETER) { - ReturnValue_t status = registeredVariables[count]->read(); - if (status != HasReturnvaluesIF::RETURN_OK) { - result = INVALID_PARAMETER_DEFINITION; - break; - } + ReturnValue_t result = readVariable(count); + if(result != RETURN_OK) { + break; } } state = States::DATA_SET_WAS_READ; @@ -58,47 +52,53 @@ ReturnValue_t DataSetBase::read() { return result; } -ReturnValue_t DataSetBase::commit() { +ReturnValue_t DataSetBase::readVariable(uint16_t count) { + ReturnValue_t result = DataSetIF::INVALID_PARAMETER_DEFINITION; + // These checks are often performed by the respective + // variable implementation too, but I guess a double check does not hurt. + if (registeredVariables[count]->getReadWriteMode() != + PoolVariableIF::VAR_WRITE and + registeredVariables[count]->getDataPoolId() + != PoolVariableIF::NO_PARAMETER) + { + result = registeredVariables[count]->readWithoutLock(); + } + return result; +} + +ReturnValue_t DataSetBase::commit(uint32_t lockTimeout) { if (state == States::DATA_SET_WAS_READ) { - handleAlreadyReadDatasetCommit(); + handleAlreadyReadDatasetCommit(lockTimeout); return HasReturnvaluesIF::RETURN_OK; } else { - return handleUnreadDatasetCommit(); + return handleUnreadDatasetCommit(lockTimeout); } } -ReturnValue_t DataSetBase::lockDataPool() { - return HasReturnvaluesIF::RETURN_OK; -} - -ReturnValue_t DataSetBase::unlockDataPool() { - return HasReturnvaluesIF::RETURN_FAILED; -} - -void DataSetBase::handleAlreadyReadDatasetCommit() { - lockDataPool(); +void DataSetBase::handleAlreadyReadDatasetCommit(uint32_t lockTimeout) { + lockDataPool(lockTimeout); for (uint16_t count = 0; count < fillCount; count++) { if (registeredVariables[count]->getReadWriteMode() != PoolVariableIF::VAR_READ && registeredVariables[count]->getDataPoolId() != PoolVariableIF::NO_PARAMETER) { - registeredVariables[count]->commit(); + registeredVariables[count]->commitWithoutLock(); } } state = States::DATA_SET_UNINITIALISED; unlockDataPool(); } -ReturnValue_t DataSetBase::handleUnreadDatasetCommit() { +ReturnValue_t DataSetBase::handleUnreadDatasetCommit(uint32_t lockTimeout) { ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; - lockDataPool(); + lockDataPool(lockTimeout); for (uint16_t count = 0; count < fillCount; count++) { if (registeredVariables[count]->getReadWriteMode() == PoolVariableIF::VAR_WRITE && registeredVariables[count]->getDataPoolId() != PoolVariableIF::NO_PARAMETER) { - registeredVariables[count]->commit(); + registeredVariables[count]->commitWithoutLock(); } else if (registeredVariables[count]->getDataPoolId() != PoolVariableIF::NO_PARAMETER) { if (result != COMMITING_WITHOUT_READING) { @@ -113,6 +113,15 @@ ReturnValue_t DataSetBase::handleUnreadDatasetCommit() { return result; } + +ReturnValue_t DataSetBase::lockDataPool(uint32_t timeoutMs) { + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t DataSetBase::unlockDataPool() { + return HasReturnvaluesIF::RETURN_OK; +} + ReturnValue_t DataSetBase::serialize(uint8_t** buffer, size_t* size, const size_t maxSize, bool bigEndian) const { ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED; diff --git a/datapool/DataSetBase.h b/datapool/DataSetBase.h index 6b468c11..8bf9a99a 100644 --- a/datapool/DataSetBase.h +++ b/datapool/DataSetBase.h @@ -2,6 +2,7 @@ #define FRAMEWORK_DATAPOOL_DATASETBASE_H_ #include #include +#include /** * @brief The DataSetBase class manages a set of locally checked out variables. @@ -21,7 +22,8 @@ * of the set, the DataSet class automatically sets the valid flag in the * data pool to invalid (without) changing the variable's value. * - * The base class lockDataPo + * The base class lockDataPool und unlockDataPool implementation are empty + * and should be implemented to protect the underlying pool type. * @author Bastian Baetz * @ingroup data_pool */ @@ -49,14 +51,15 @@ public: * * The data pool is locked during the whole read operation and * freed afterwards.The state changes to "was written" after this operation. - * @return - @c RETURN_OK if all variables were read successfully. - * - @c INVALID_PARAMETER_DEFINITION if PID, size or type of the - * requested variable is invalid. - * - @c SET_WAS_ALREADY_READ if read() is called twice without calling - * commit() in between + * @return + * - @c RETURN_OK if all variables were read successfully. + * - @c INVALID_PARAMETER_DEFINITION if PID, size or type of the + * requested variable is invalid. + * - @c SET_WAS_ALREADY_READ if read() is called twice without calling + * commit() in between */ - virtual ReturnValue_t read(); - + virtual ReturnValue_t read(uint32_t lockTimeout = + MutexIF::BLOCKING) override; /** * @brief The commit call initializes writing back the registered variables. * @details @@ -67,23 +70,30 @@ public: * The data pool is locked during the whole commit operation and * freed afterwards. The state changes to "was committed" after this operation. * - * If the set does contain at least one variable which is not write-only commit() - * can only be called after read(). If the set only contains variables which are - * write only, commit() can be called without a preceding read() call. + * If the set does contain at least one variable which is not write-only + * commit() can only be called after read(). If the set only contains + * variables which are write only, commit() can be called without a + * preceding read() call. * @return - @c RETURN_OK if all variables were read successfully. * - @c COMMITING_WITHOUT_READING if set was not read yet and * contains non write-only variables */ - virtual ReturnValue_t commit(); + virtual ReturnValue_t commit(uint32_t lockTimeout = + MutexIF::BLOCKING) override; - /* DataSetIF implementation */ + /** + * Register the passed pool variable instance into the data set. + * @param variable + * @return + */ virtual ReturnValue_t registerVariable( PoolVariableIF* variable) override; /** * Provides the means to lock the underlying data structure to ensure * thread-safety. Default implementation is empty * @return Always returns -@c RETURN_OK */ - virtual ReturnValue_t lockDataPool() override; + virtual ReturnValue_t lockDataPool(uint32_t timeoutMs = + MutexIF::BLOCKING) override; /** * Provides the means to unlock the underlying data structure to ensure * thread-safety. Default implementation is empty @@ -98,12 +108,12 @@ public: virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, bool bigEndian) override; - //SHOULDDO we could use a linked list of datapool variables + // SHOULDDO we could use a linked list of datapool variables //!< This definition sets the maximum number of variables to //! register in one DataSet. static const uint8_t DATA_SET_MAX_SIZE = 63; -protected: +protected: /** * @brief The fill_count attribute ensures that the variables * register in the correct array position and that the maximum @@ -128,8 +138,10 @@ protected: */ PoolVariableIF* registeredVariables[DATA_SET_MAX_SIZE] = { }; - void handleAlreadyReadDatasetCommit(); - ReturnValue_t handleUnreadDatasetCommit(); +private: + ReturnValue_t readVariable(uint16_t count); + void handleAlreadyReadDatasetCommit(uint32_t lockTimeout); + ReturnValue_t handleUnreadDatasetCommit(uint32_t lockTimeout); }; #endif /* FRAMEWORK_DATAPOOL_DATASETBASE_H_ */ diff --git a/datapool/DataSetIF.h b/datapool/DataSetIF.h index d9cc4966..9c5b13c8 100644 --- a/datapool/DataSetIF.h +++ b/datapool/DataSetIF.h @@ -2,6 +2,7 @@ #define DATASETIF_H_ #include +#include class PoolVariableIF; /** @@ -33,20 +34,23 @@ public: */ virtual ~DataSetIF() {} + virtual ReturnValue_t read(uint32_t lockTimeout) = 0; + virtual ReturnValue_t commit(uint32_t lockTimeout) = 0; /** * @brief This operation provides a method to register local data pool * variables to register in a data set by passing itself * to this DataSet operation. */ - virtual ReturnValue_t registerVariable( PoolVariableIF* variable ) = 0; + virtual ReturnValue_t registerVariable(PoolVariableIF* variable) = 0; +private: /** * @brief Most underlying data structures will have a pool like structure * and will require a lock and unlock mechanism to ensure * thread-safety * @return Lock operation result */ - virtual ReturnValue_t lockDataPool() = 0; + virtual ReturnValue_t lockDataPool(uint32_t timeoutMs) = 0; /** * @brief Unlock call corresponding to the lock call. * @return Unlock operation result diff --git a/datapool/PoolVariableIF.h b/datapool/PoolVariableIF.h index 0cbc18c5..3086bbe8 100644 --- a/datapool/PoolVariableIF.h +++ b/datapool/PoolVariableIF.h @@ -21,18 +21,10 @@ class PoolVariableIF : public SerializeIF { friend class DataSetBase; friend class GlobDataSet; friend class LocalDataSet; -protected: - /** - * @brief The commit call shall write back a newly calculated local - * value to the data pool. - */ - virtual ReturnValue_t commit() = 0; - /** - * @brief The read call shall read the value of this parameter from - * the data pool and store the content locally. - */ - virtual ReturnValue_t read() = 0; public: + static constexpr uint8_t INTERFACE_ID = CLASS_ID::POOL_VARIABLE_IF; + static constexpr ReturnValue_t INVALID_READ_WRITE_MODE = MAKE_RETURN_CODE(0xA0); + static constexpr bool VALID = 1; static constexpr bool INVALID = 0; static constexpr uint32_t NO_PARAMETER = 0; @@ -61,9 +53,43 @@ public: /** * @brief With this call, the valid information of the variable is set. */ - // why not just use a boolean here? - virtual void setValid(uint8_t validity) = 0; + virtual void setValid(bool validity) = 0; + /** + * @brief The commit call shall write back a newly calculated local + * value to the data pool. + * @details + * It is assumed that these calls are implemented in a thread-safe manner! + */ + virtual ReturnValue_t commit(uint32_t lockTimeout) = 0; + /** + * @brief The read call shall read the value of this parameter from + * the data pool and store the content locally. + * @details + * It is assumbed that these calls are implemented in a thread-safe manner! + */ + virtual ReturnValue_t read(uint32_t lockTimeout) = 0; + +protected: + + /** + * @brief Same as commit with the difference that comitting will be + * performed without a lock + * @return + * This can be used if the lock protection is handled externally + * to avoid the overhead of locking and unlocking consecutively. + * Declared protected to avoid free public usage. + */ + virtual ReturnValue_t readWithoutLock() = 0; + /** + * @brief Same as commit with the difference that comitting will be + * performed without a lock + * @return + * This can be used if the lock protection is handled externally + * to avoid the overhead of locking and unlocking consecutively. + * Declared protected to avoid free public usage. + */ + virtual ReturnValue_t commitWithoutLock() = 0; }; using pool_rwm_t = PoolVariableIF::ReadWriteMode_t; From e04e6a6f1506ca90498803bbce49e854e5ed5d4b Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 5 Jun 2020 20:33:57 +0200 Subject: [PATCH 060/307] datapoolglob update --- datapoolglob/GlobalDataPool.cpp | 10 ++--- datapoolglob/GlobalDataPool.h | 4 +- datapoolglob/GlobalDataSet.cpp | 14 +++---- datapoolglob/GlobalDataSet.h | 7 ++-- datapoolglob/GlobalPoolVariable.h | 64 +++++++++++++++++++---------- datapoolglob/GlobalPoolVariable.tpp | 36 ++++++++++++++-- datapoolglob/GlobalPoolVector.h | 40 ++++++++++++++---- datapoolglob/GlobalPoolVector.tpp | 36 +++++++++++++++- datapoolglob/PIDReader.h | 24 +++++++++-- datapoolglob/PoolRawAccess.cpp | 34 +++++++++++++-- datapoolglob/PoolRawAccess.h | 48 +++++++++++++++------- 11 files changed, 244 insertions(+), 73 deletions(-) diff --git a/datapoolglob/GlobalDataPool.cpp b/datapoolglob/GlobalDataPool.cpp index 18780904..25acaab3 100644 --- a/datapoolglob/GlobalDataPool.cpp +++ b/datapoolglob/GlobalDataPool.cpp @@ -44,18 +44,18 @@ PoolEntryIF* GlobalDataPool::getRawData( uint32_t data_pool_id ) { } } -ReturnValue_t GlobalDataPool::freeDataPoolLock() { +ReturnValue_t GlobalDataPool::unlockDataPool() { ReturnValue_t status = mutex->unlockMutex(); - if ( status != RETURN_OK ) { + if(status != RETURN_OK) { sif::error << "DataPool::DataPool: unlock of mutex failed with" " error code: " << status << std::endl; } return status; } -ReturnValue_t GlobalDataPool::lockDataPool() { - ReturnValue_t status = mutex->lockMutex(MutexIF::BLOCKING); - if ( status != RETURN_OK ) { +ReturnValue_t GlobalDataPool::lockDataPool(uint32_t timeoutMs) { + ReturnValue_t status = mutex->lockMutex(timeoutMs); + if(status != RETURN_OK) { sif::error << "DataPool::DataPool: lock of mutex failed " "with error code: " << status << std::endl; } diff --git a/datapoolglob/GlobalDataPool.h b/datapoolglob/GlobalDataPool.h index 42921a77..b9c1436f 100644 --- a/datapoolglob/GlobalDataPool.h +++ b/datapoolglob/GlobalDataPool.h @@ -95,12 +95,12 @@ public: * @brief This is a small helper function to facilitate locking the global data pool. * @details It fetches the pool's mutex id and tries to acquire the mutex. */ - ReturnValue_t lockDataPool(); + ReturnValue_t lockDataPool(uint32_t timeoutMs = MutexIF::BLOCKING); /** * @brief This is a small helper function to facilitate unlocking the global data pool. * @details It fetches the pool's mutex id and tries to free the mutex. */ - ReturnValue_t freeDataPoolLock(); + ReturnValue_t unlockDataPool(); /** * @brief The print call is a simple debug method. * @details It prints the current content of the data pool. diff --git a/datapoolglob/GlobalDataSet.cpp b/datapoolglob/GlobalDataSet.cpp index 503d068e..9da8d524 100644 --- a/datapoolglob/GlobalDataSet.cpp +++ b/datapoolglob/GlobalDataSet.cpp @@ -8,22 +8,22 @@ GlobDataSet::GlobDataSet(): DataSetBase() {} // (Destructor is already called) GlobDataSet::~GlobDataSet() {} -ReturnValue_t GlobDataSet::commit(bool valid) { +ReturnValue_t GlobDataSet::commit(bool valid, uint32_t lockTimeout) { setEntriesValid(valid); setSetValid(valid); - return commit(); + return commit(lockTimeout); } -ReturnValue_t GlobDataSet::commit() { - return DataSetBase::commit(); +ReturnValue_t GlobDataSet::commit(uint32_t lockTimeout) { + return DataSetBase::commit(lockTimeout); } ReturnValue_t GlobDataSet::unlockDataPool() { - return glob::dataPool.freeDataPoolLock(); + return glob::dataPool.unlockDataPool(); } -ReturnValue_t GlobDataSet::lockDataPool() { - return glob::dataPool.lockDataPool(); +ReturnValue_t GlobDataSet::lockDataPool(uint32_t timeoutMs) { + return glob::dataPool.lockDataPool(timeoutMs); } void GlobDataSet::setEntriesValid(bool valid) { diff --git a/datapoolglob/GlobalDataSet.h b/datapoolglob/GlobalDataSet.h index c2e0b577..f0bf7daa 100644 --- a/datapoolglob/GlobalDataSet.h +++ b/datapoolglob/GlobalDataSet.h @@ -44,8 +44,8 @@ public: * - @c COMMITING_WITHOUT_READING if set was not read yet and * contains non write-only variables */ - ReturnValue_t commit(bool valid); - ReturnValue_t commit() override; + ReturnValue_t commit(bool valid, uint32_t lockTimeout = MutexIF::BLOCKING); + ReturnValue_t commit(uint32_t lockTimeout = MutexIF::BLOCKING) override; /** * Set all entries @@ -74,8 +74,7 @@ private: * @details * It makes use of the lockDataPool method offered by the DataPool class. */ - ReturnValue_t lockDataPool() override; - + ReturnValue_t lockDataPool(uint32_t timeoutMs) override; /** * @brief This is a small helper function to facilitate * unlocking the global data pool diff --git a/datapoolglob/GlobalPoolVariable.h b/datapoolglob/GlobalPoolVariable.h index eb44c307..9e3eea0c 100644 --- a/datapoolglob/GlobalPoolVariable.h +++ b/datapoolglob/GlobalPoolVariable.h @@ -72,7 +72,49 @@ public: */ ~GlobPoolVar() {} + /** + * @brief This is a call to read the value from the global data pool. + * @details + * When executed, this operation tries to fetch the pool entry with matching + * data pool id from the global data pool and copies the value and the valid + * information to its local attributes. In case of a failure (wrong type or + * pool id not found), the variable is set to zero and invalid. + * The read call is protected with a lock. + * It is recommended to use DataSets to read and commit multiple variables + * at once to avoid the overhead of unnecessary lock und unlock operations. + */ + ReturnValue_t read(uint32_t lockTimeout) override; + /** + * @brief The commit call writes back the variable's value to the data pool. + * @details + * It checks type and size, as well as if the variable is writable. If so, + * the value is copied and the valid flag is automatically set to "valid". + * The operation does NOT provide any mutual exclusive protection by itself. + * The commit call is protected with a lock. + * It is recommended to use DataSets to read and commit multiple variables + * at once to avoid the overhead of unnecessary lock und unlock operations. + */ + ReturnValue_t commit(uint32_t lockTimeout) override; + protected: + /** + * @brief Like #read, but without a lock protection of the global pool. + * @details + * The operation does NOT provide any mutual exclusive protection by itself. + * This can be used if the lock is handled externally to avoid the overhead + * of consecutive lock und unlock operations. + * Declared protected to discourage free public usage. + */ + ReturnValue_t readWithoutLock() override; + /** + * @brief Like #commit, but without a lock protection of the global pool. + * @details + * The operation does NOT provide any mutual exclusive protection by itself. + * This can be used if the lock is handled externally to avoid the overhead + * of consecutive lock und unlock operations. + * Declared protected to discourage free public usage. + */ + ReturnValue_t commitWithoutLock() override; /** * @brief To access the correct data pool entry on read and commit calls, * the data pool is stored. @@ -91,26 +133,6 @@ protected: */ pool_rwm_t readWriteMode; - /** - * @brief This is a call to read the value from the global data pool. - * @details - * When executed, this operation tries to fetch the pool entry with matching - * data pool id from the global data pool and copies the value and the valid - * information to its local attributes. In case of a failure (wrong type or - * pool id not found), the variable is set to zero and invalid. - * The operation does NOT provide any mutual exclusive protection by itself. - */ - ReturnValue_t read() override; - - /** - * @brief The commit call writes back the variable's value to the data pool. - * @details It checks type and size, as well as if the variable is writable. If so, - * the value is copied and the valid flag is automatically set to "valid". - * The operation does NOT provide any mutual exclusive protection by itself. - * - */ - ReturnValue_t commit() override; - /** * Empty ctor for List initialization */ @@ -138,7 +160,7 @@ public: uint8_t getValid(); - void setValid(uint8_t valid); + void setValid(bool valid) override; operator T() { return value; diff --git a/datapoolglob/GlobalPoolVariable.tpp b/datapoolglob/GlobalPoolVariable.tpp index d55ea4e0..d61d605d 100644 --- a/datapoolglob/GlobalPoolVariable.tpp +++ b/datapoolglob/GlobalPoolVariable.tpp @@ -12,8 +12,38 @@ inline GlobPoolVar::GlobPoolVar(uint32_t set_id, } } +template +inline ReturnValue_t GlobPoolVar::read(uint32_t lockTimeout) { + ReturnValue_t result = glob::dataPool.lockDataPool(lockTimeout); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = readWithoutLock(); + ReturnValue_t unlockResult = glob::dataPool.unlockDataPool(); + if(unlockResult != HasReturnvaluesIF::RETURN_OK) { + sif::error << "GlobPoolVar::read: Could not unlock global data pool" + << std::endl; + } + return result; +} + +template +inline ReturnValue_t GlobPoolVar::commit(uint32_t lockTimeout) { + ReturnValue_t result = glob::dataPool.lockDataPool(lockTimeout); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = commitWithoutLock(); + ReturnValue_t unlockResult = glob::dataPool.unlockDataPool(); + if(unlockResult != HasReturnvaluesIF::RETURN_OK) { + sif::error << "GlobPoolVar::read: Could not unlock global data pool" + << std::endl; + } + return result; +} + template -inline ReturnValue_t GlobPoolVar::read() { +inline ReturnValue_t GlobPoolVar::readWithoutLock() { PoolEntry* read_out = glob::dataPool.getData(dataPoolId, 1); if (read_out != NULL) { valid = read_out->valid; @@ -29,7 +59,7 @@ inline ReturnValue_t GlobPoolVar::read() { } template -inline ReturnValue_t GlobPoolVar::commit() { +inline ReturnValue_t GlobPoolVar::commitWithoutLock() { PoolEntry* write_back = glob::dataPool.getData(dataPoolId, 1); if ((write_back != NULL) && (readWriteMode != VAR_READ)) { write_back->valid = valid; @@ -80,7 +110,7 @@ inline uint8_t GlobPoolVar::getValid() { } template -inline void GlobPoolVar::setValid(uint8_t valid) { +inline void GlobPoolVar::setValid(bool valid) { this->valid = valid; } diff --git a/datapoolglob/GlobalPoolVector.h b/datapoolglob/GlobalPoolVector.h index 24303457..93092228 100644 --- a/datapoolglob/GlobalPoolVector.h +++ b/datapoolglob/GlobalPoolVector.h @@ -102,7 +102,7 @@ public: else return false; } - void setValid(uint8_t valid) {this->valid = valid;} + void setValid(bool valid) {this->valid = valid;} uint8_t getValid() {return valid;} T &operator [](int i) {return value[i];} @@ -113,7 +113,7 @@ public: virtual size_t getSerializedSize() const override; virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, bool bigEndian) override; -protected: + /** * @brief This is a call to read the array's values * from the global data pool. @@ -122,19 +122,43 @@ protected: * data pool id from the global data pool and copies all array values * and the valid information to its local attributes. * In case of a failure (wrong type, size or pool id not found), the - * variable is set to zero and invalid. The operation does NOT provide - * any mutual exclusive protection by itself. + * variable is set to zero and invalid. + * The read call is protected by a lock of the global data pool. + * It is recommended to use DataSets to read and commit multiple variables + * at once to avoid the overhead of unnecessary lock und unlock operations. */ - ReturnValue_t read(); - + ReturnValue_t read(uint32_t lockTimeout = MutexIF::BLOCKING) override; /** * @brief The commit call copies the array values back to the data pool. * @details * It checks type and size, as well as if the variable is writable. If so, * the value is copied and the valid flag is automatically set to "valid". - * The operation does NOT provide any mutual exclusive protection by itself. + * The commit call is protected by a lock of the global data pool. + * It is recommended to use DataSets to read and commit multiple variables + * at once to avoid the overhead of unnecessary lock und unlock operations. */ - ReturnValue_t commit(); + ReturnValue_t commit(uint32_t lockTimeout = MutexIF::BLOCKING) override; + +protected: + /** + * @brief Like #read, but without a lock protection of the global pool. + * @details + * The operation does NOT provide any mutual exclusive protection by itself. + * This can be used if the lock is handled externally to avoid the overhead + * of consecutive lock und unlock operations. + * Declared protected to discourage free public usage. + */ + ReturnValue_t readWithoutLock() override; + /** + * @brief Like #commit, but without a lock protection of the global pool. + * @details + * The operation does NOT provide any mutual exclusive protection by itself. + * This can be used if the lock is handled externally to avoid the overhead + * of consecutive lock und unlock operations. + * Declared protected to discourage free public usage. + */ + ReturnValue_t commitWithoutLock() override; + private: /** * @brief To access the correct data pool entry on read and commit calls, diff --git a/datapoolglob/GlobalPoolVector.tpp b/datapoolglob/GlobalPoolVector.tpp index 0b43191b..5710da57 100644 --- a/datapoolglob/GlobalPoolVector.tpp +++ b/datapoolglob/GlobalPoolVector.tpp @@ -12,8 +12,40 @@ inline GlobPoolVector::GlobPoolVector(uint32_t set_id, } } + template -inline ReturnValue_t GlobPoolVector::read() { +inline ReturnValue_t GlobPoolVector::read(uint32_t lockTimeout) { + ReturnValue_t result = glob::dataPool.lockDataPool(lockTimeout); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = readWithoutLock(); + ReturnValue_t unlockResult = glob::dataPool.unlockDataPool(); + if(unlockResult != HasReturnvaluesIF::RETURN_OK) { + sif::error << "GlobPoolVar::read: Could not unlock global data pool" + << std::endl; + } + return result; +} + +template +inline ReturnValue_t GlobPoolVector::commit( + uint32_t lockTimeout) { + ReturnValue_t result = glob::dataPool.lockDataPool(lockTimeout); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = commitWithoutLock(); + ReturnValue_t unlockResult = glob::dataPool.unlockDataPool(); + if(unlockResult != HasReturnvaluesIF::RETURN_OK) { + sif::error << "GlobPoolVar::read: Could not unlock global data pool" + << std::endl; + } + return result; +} + +template +inline ReturnValue_t GlobPoolVector::readWithoutLock() { PoolEntry* read_out = glob::dataPool.getData(this->dataPoolId, vectorSize); if (read_out != nullptr) { @@ -33,7 +65,7 @@ inline ReturnValue_t GlobPoolVector::read() { } template -inline ReturnValue_t GlobPoolVector::commit() { +inline ReturnValue_t GlobPoolVector::commitWithoutLock() { PoolEntry* writeBack = glob::dataPool.getData(this->dataPoolId, vectorSize); if ((writeBack != nullptr) && (this->readWriteMode != VAR_READ)) { diff --git a/datapoolglob/PIDReader.h b/datapoolglob/PIDReader.h index 11206611..359b871f 100644 --- a/datapoolglob/PIDReader.h +++ b/datapoolglob/PIDReader.h @@ -15,7 +15,8 @@ class PIDReader: public PoolVariableIF { protected: uint32_t parameterId; uint8_t valid; - ReturnValue_t read() { + + ReturnValue_t readWithoutLock() { uint8_t arrayIndex = GlobalDataPool::PIDToArrayIndex(parameterId); PoolEntry* read_out = glob::dataPool.getData( GlobalDataPool::PIDToDataPoolId(parameterId), arrayIndex); @@ -36,9 +37,13 @@ protected: * Reason is the possibility to access a single DP vector element, but if we commit, * we set validity of the whole vector. */ - ReturnValue_t commit() { + ReturnValue_t commit(uint32_t lockTimeout) override { return HasReturnvaluesIF::RETURN_FAILED; } + ReturnValue_t commitWithoutLock() override { + return HasReturnvaluesIF::RETURN_FAILED; + } + /** * Empty ctor for List initialization */ @@ -71,6 +76,19 @@ public: } } + ReturnValue_t read(uint32_t lockTimeout) override { + ReturnValue_t result = glob::dataPool.lockDataPool(); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = readWithoutLock(); + ReturnValue_t unlockResult = glob::dataPool.unlockDataPool(); + if(unlockResult != HasReturnvaluesIF::RETURN_OK) { + sif::error << "PIDReader::read: Could not unlock data pool!" + << std::endl; + } + return result; + } /** * Copy ctor to copy classes containing Pool Variables. */ @@ -113,7 +131,7 @@ public: return valid; } - void setValid(uint8_t valid) { + void setValid(bool valid) { this->valid = valid; } diff --git a/datapoolglob/PoolRawAccess.cpp b/datapoolglob/PoolRawAccess.cpp index b10ee04c..39cfd58c 100644 --- a/datapoolglob/PoolRawAccess.cpp +++ b/datapoolglob/PoolRawAccess.cpp @@ -18,7 +18,21 @@ PoolRawAccess::PoolRawAccess(uint32_t set_id, uint8_t setArrayEntry, PoolRawAccess::~PoolRawAccess() {} -ReturnValue_t PoolRawAccess::read() { +ReturnValue_t PoolRawAccess::read(uint32_t lockTimeout) { + ReturnValue_t result = glob::dataPool.lockDataPool(lockTimeout); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = readWithoutLock(); + ReturnValue_t unlockResult = glob::dataPool.unlockDataPool(); + if(unlockResult != HasReturnvaluesIF::RETURN_OK) { + sif::error << "GlobPoolVar::read: Could not unlock global data pool" + << std::endl; + } + return result; +} + +ReturnValue_t PoolRawAccess::readWithoutLock() { ReturnValue_t result = RETURN_FAILED; PoolEntryIF* readOut = glob::dataPool.getRawData(dataPoolId); if (readOut != nullptr) { @@ -75,7 +89,21 @@ void PoolRawAccess::handleReadError(ReturnValue_t result) { memset(value, 0, sizeof(value)); } -ReturnValue_t PoolRawAccess::commit() { +ReturnValue_t PoolRawAccess::commit(uint32_t lockTimeout) { + ReturnValue_t result = glob::dataPool.lockDataPool(lockTimeout); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = commitWithoutLock(); + ReturnValue_t unlockResult = glob::dataPool.unlockDataPool(); + if(unlockResult != HasReturnvaluesIF::RETURN_OK) { + sif::error << "GlobPoolVar::read: Could not unlock global data pool" + << std::endl; + } + return result; +} + +ReturnValue_t PoolRawAccess::commitWithoutLock() { PoolEntryIF* write_back = glob::dataPool.getRawData(dataPoolId); if ((write_back != NULL) && (readWriteMode != VAR_READ)) { write_back->setValid(valid); @@ -189,7 +217,7 @@ bool PoolRawAccess::isValid() const { return false; } -void PoolRawAccess::setValid(uint8_t valid) { +void PoolRawAccess::setValid(bool valid) { this->valid = valid; } diff --git a/datapoolglob/PoolRawAccess.h b/datapoolglob/PoolRawAccess.h index 452b5397..60e3c71e 100644 --- a/datapoolglob/PoolRawAccess.h +++ b/datapoolglob/PoolRawAccess.h @@ -124,7 +124,7 @@ public: */ bool isValid() const; - void setValid(uint8_t valid); + void setValid(bool valid); /** * Getter for the remaining size. */ @@ -135,31 +135,49 @@ public: ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, bool bigEndian); -protected: /** * @brief This is a call to read the value from the global data pool. - * @details When executed, this operation tries to fetch the pool entry with matching - * data pool id from the global data pool and copies the value and the valid - * information to its local attributes. In case of a failure (wrong type or - * pool id not found), the variable is set to zero and invalid. - * The operation does NOT provide any mutual exclusive protection by itself ! - * If reading from the data pool without information about the type is desired, - * initialize the raw pool access by supplying a data set and using the data set - * read function, which calls this read function. + * @details + * When executed, this operation tries to fetch the pool entry with matching + * data pool id from the global data pool and copies the value and the valid + * information to its local attributes. In case of a failure (wrong type or + * pool id not found), the variable is set to zero and invalid. + * The call is protected by a lock of the global data pool. * @return -@c RETURN_OK Read successfull * -@c READ_TYPE_TOO_LARGE * -@c READ_INDEX_TOO_LARGE * -@c READ_ENTRY_NON_EXISTENT */ - ReturnValue_t read(); + ReturnValue_t read(uint32_t lockTimeout = MutexIF::BLOCKING) override; /** * @brief The commit call writes back the variable's value to the data pool. - * @details It checks type and size, as well as if the variable is writable. If so, - * the value is copied and the valid flag is automatically set to "valid". - * The operation does NOT provide any mutual exclusive protection by itself. + * @details + * It checks type and size, as well as if the variable is writable. If so, + * the value is copied and the valid flag is automatically set to "valid". + * The call is protected by a lock of the global data pool. * */ - ReturnValue_t commit(); + ReturnValue_t commit(uint32_t lockTimeout = MutexIF::BLOCKING) override; + +protected: + /** + * @brief Like #read, but without a lock protection of the global pool. + * @details + * The operation does NOT provide any mutual exclusive protection by itself. + * This can be used if the lock is handled externally to avoid the overhead + * of consecutive lock und unlock operations. + * Declared protected to discourage free public usage. + */ + ReturnValue_t readWithoutLock() override; + /** + * @brief Like #commit, but without a lock protection of the global pool. + * @details + * The operation does NOT provide any mutual exclusive protection by itself. + * This can be used if the lock is handled externally to avoid the overhead + * of consecutive lock und unlock operations. + * Declared protected to discourage free public usage. + */ + ReturnValue_t commitWithoutLock() override; ReturnValue_t handleReadOut(PoolEntryIF* read_out); void handleReadError(ReturnValue_t result); From 319fa9ddb6237c58d9fe8b0e5763b0b463ec82a4 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 5 Jun 2020 20:34:34 +0200 Subject: [PATCH 061/307] datapoollocal update --- datapoollocal/LocalDataSet.cpp | 69 +++------- datapoollocal/LocalDataSet.h | 141 +++------------------ datapoollocal/LocalPoolVariable.h | 143 +++++++++++++++------ datapoollocal/LocalPoolVariable.tpp | 83 +++++++++--- datapoollocal/LocalPoolVector.h | 189 ++++++++++++++++++++++++++++ datapoollocal/LocalPoolVector.tpp | 185 +++++++++++++++++++++++++++ 6 files changed, 582 insertions(+), 228 deletions(-) create mode 100644 datapoollocal/LocalPoolVector.h create mode 100644 datapoollocal/LocalPoolVector.tpp diff --git a/datapoollocal/LocalDataSet.cpp b/datapoollocal/LocalDataSet.cpp index 07f86e18..988f254a 100644 --- a/datapoollocal/LocalDataSet.cpp +++ b/datapoollocal/LocalDataSet.cpp @@ -1,66 +1,35 @@ #include +#include -LocalDataSet::LocalDataSet(): - fill_count(0), state(DATA_SET_UNINITIALISED) -{ - for (unsigned count = 0; count < DATA_SET_MAX_SIZE; count++) { - registeredVariables[count] = nullptr; +LocalDataSet::LocalDataSet(HasHkPoolParametersIF *hkOwner): DataSetBase() { + if(hkOwner != nullptr) { + hkManager = hkOwner->getHkManagerHandle(); + } + else { + // config error, error output here. } } -// who has the responsibility to lock the mutex? the local pool variable -// has access to the HK manager and could call its mutex lock function. -ReturnValue_t LocalDataSet::registerVariable( - PoolVariableIF *variable) { - return RETURN_OK; +LocalDataSet::LocalDataSet(object_id_t ownerId): DataSetBase() { + HasHkPoolParametersIF* hkOwner = objectManager->get( + ownerId); + if(hkOwner == nullptr) { + // config error, error output here. + } + hkManager = hkOwner->getHkManagerHandle(); } LocalDataSet::~LocalDataSet() { } -ReturnValue_t LocalDataSet::read() { - return RETURN_OK; -} - -ReturnValue_t LocalDataSet::commit(void) { - return RETURN_OK; -} - -ReturnValue_t LocalDataSet::commit(bool valid) { - return RETURN_OK; -} - -void LocalDataSet::setSetValid(bool valid) { -} - -void LocalDataSet::setEntriesValid(bool valid) { -} - -ReturnValue_t LocalDataSet::serialize(uint8_t **buffer, - size_t *size, const size_t max_size, bool bigEndian) const { - return RETURN_OK; -} - -size_t LocalDataSet::getSerializedSize() const { - return 0; -} - -ReturnValue_t LocalDataSet::deSerialize(const uint8_t **buffer, - size_t *size, bool bigEndian) { - return RETURN_OK; -} - -ReturnValue_t LocalDataSet::lockDataPool() { - return RETURN_OK; +ReturnValue_t LocalDataSet::lockDataPool(uint32_t timeoutMs) { + MutexIF* mutex = hkManager->getMutexHandle(); + return mutex->lockMutex(timeoutMs); } ReturnValue_t LocalDataSet::unlockDataPool() { - return RETURN_OK; + MutexIF* mutex = hkManager->getMutexHandle(); + return mutex->unlockMutex(); } -void LocalDataSet::handleAlreadyReadDatasetCommit() { -} -ReturnValue_t LocalDataSet::handleUnreadDatasetCommit() { - return RETURN_OK; -} diff --git a/datapoollocal/LocalDataSet.h b/datapoollocal/LocalDataSet.h index 6110175c..607d10b3 100644 --- a/datapoollocal/LocalDataSet.h +++ b/datapoollocal/LocalDataSet.h @@ -1,8 +1,12 @@ #ifndef FRAMEWORK_DATAPOOLLOCAL_LOCALDATASET_H_ #define FRAMEWORK_DATAPOOLLOCAL_LOCALDATASET_H_ +#include #include +#include #include +class HousekeepingManager; + /** * @brief The LocalDataSet class manages a set of locally checked out variables * for local data pools @@ -24,32 +28,22 @@ * * @ingroup data_pool */ -class LocalDataSet: - public DataSetIF, - public HasReturnvaluesIF, - public SerializeIF { +class LocalDataSet: public DataSetBase { public: - static constexpr uint8_t INTERFACE_ID = CLASS_ID::DATA_SET_CLASS; - static constexpr ReturnValue_t INVALID_PARAMETER_DEFINITION = - MAKE_RETURN_CODE( 0x01 ); - static constexpr ReturnValue_t SET_WAS_ALREADY_READ = MAKE_RETURN_CODE( 0x02 ); - static constexpr ReturnValue_t COMMITING_WITHOUT_READING = - MAKE_RETURN_CODE(0x03); - - static constexpr ReturnValue_t DATA_SET_UNINITIALIZED = MAKE_RETURN_CODE( 0x04 ); - static constexpr ReturnValue_t DATA_SET_FULL = MAKE_RETURN_CODE( 0x05 ); - static constexpr ReturnValue_t POOL_VAR_NULL = MAKE_RETURN_CODE( 0x06 ); /** - * @brief The constructor simply sets the fill_count to zero and sets + * @brief Constructor for the creator of local pool data. + * The constructor simply sets the fill_count to zero and sets * the state to "uninitialized". */ - LocalDataSet(); + LocalDataSet(HasHkPoolParametersIF* hkOwner); /** - * @brief This operation is used to register the local variables in the set. - * @details It stores the pool variable pointer in a variable list. + * @brief Constructor for users of local pool data. The passed pool + * owner should implement the HasHkPoolParametersIF. + * The constructor simply sets the fill_count to zero and sets + * the state to "uninitialized". */ - ReturnValue_t registerVariable(PoolVariableIF* variable) override; + LocalDataSet(object_id_t ownerId); /** * @brief The destructor automatically manages writing the valid @@ -61,127 +55,30 @@ public: */ ~LocalDataSet(); - /** - * @brief The read call initializes reading out all registered variables. - * @details - * It iterates through the list of registered variables and calls all read() - * functions of the registered pool variables (which read out their values - * from the data pool) which are not write-only. - * In case of an error (e.g. a wrong data type, or an invalid data pool id), - * the operation is aborted and @c INVALID_PARAMETER_DEFINITION returned. - * - * The data pool is locked during the whole read operation and - * freed afterwards.The state changes to "was written" after this operation. - * @return - @c RETURN_OK if all variables were read successfully. - * - @c INVALID_PARAMETER_DEFINITION if PID, size or type of the - * requested variable is invalid. - * - @c SET_WAS_ALREADY_READ if read() is called twice without - * calling commit() in between - */ - ReturnValue_t read(); - - /** - * @brief The commit call initializes writing back the registered variables. - * @details - * It iterates through the list of registered variables and calls the - * commit() method of the remaining registered variables (which write back - * their values to the pool). - * - * The data pool is locked during the whole commit operation and - * freed afterwards. The state changes to "was committed" after this operation. - * - * If the set does contain at least one variable which is not write-only commit() - * can only be called after read(). If the set only contains variables which are - * write only, commit() can be called without a preceding read() call. - * @return - @c RETURN_OK if all variables were read successfully. - * - @c COMMITING_WITHOUT_READING if set was not read yet and - * contains non write-only variables - */ - ReturnValue_t commit(void); - - /** - * Variant of method above which sets validity of all elements of the set. - * @param valid Validity information from PoolVariableIF. - * @return - @c RETURN_OK if all variables were read successfully. - * - @c COMMITING_WITHOUT_READING if set was not read yet and - * contains non write-only variables - */ - ReturnValue_t commit(bool valid); - - /** - * Set all entries - * @param valid - */ - void setSetValid(bool valid); - - /** - * Set the valid information of all variables contained in the set which - * are not read-only - * - * @param valid Validity information from PoolVariableIF. - */ - void setEntriesValid(bool valid); - - ReturnValue_t serialize(uint8_t** buffer, size_t* size, - const size_t max_size, bool bigEndian) const override; - - size_t getSerializedSize() const override; - - ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, - bool bigEndian) override; +protected: private: - // SHOULDDO we could use a linked list of datapool variables - //! This definition sets the maximum number of variables - //! to register in one DataSet. - static const uint8_t DATA_SET_MAX_SIZE = 63; - /** - * @brief This array represents all pool variables registered in this set. - */ - PoolVariableIF* registeredVariables[DATA_SET_MAX_SIZE]; - /** - * @brief The fill_count attribute ensures that the variables register in - * the correct array position and that the maximum number of - * variables is not exceeded. - */ - uint16_t fill_count; - - /** - * States of the seet. - */ - enum States { - DATA_SET_UNINITIALISED, //!< DATA_SET_UNINITIALISED - DATA_SET_WAS_READ //!< DATA_SET_WAS_READ - }; - - /** - * @brief state manages the internal state of the data set, - * which is important e.g. for the behavior on destruction. - */ - States state; - /** * If the valid state of a dataset is always relevant to the whole * data set we can use this flag. */ bool valid = false; + /** * @brief This is a small helper function to facilitate locking - * the underlying data data pool structure + * the global data pool. * @details * It makes use of the lockDataPool method offered by the DataPool class. */ - ReturnValue_t lockDataPool() override; - + ReturnValue_t lockDataPool(uint32_t timeoutMs) override; /** * @brief This is a small helper function to facilitate - * unlocking the underlying data data pool structure + * unlocking the global data pool * @details * It makes use of the freeDataPoolLock method offered by the DataPool class. */ ReturnValue_t unlockDataPool() override; - void handleAlreadyReadDatasetCommit(); - ReturnValue_t handleUnreadDatasetCommit(); + HousekeepingManager* hkManager; }; #endif /* FRAMEWORK_DATAPOOLLOCAL_LOCALDATASET_H_ */ diff --git a/datapoollocal/LocalPoolVariable.h b/datapoollocal/LocalPoolVariable.h index 39c92f60..cb373a71 100644 --- a/datapoollocal/LocalPoolVariable.h +++ b/datapoollocal/LocalPoolVariable.h @@ -3,56 +3,63 @@ #include #include +#include +#include +#include #include -#include -/** - * @brief This is the access class for non-array local data pool entries. - * - * @details - * - * @tparam T The template parameter sets the type of the variable. - * Currently, all plain data types are supported, but in principle - * any type is possible. - * @ingroup data_pool - */ - /** * @brief Local Pool Variable class which is used to access the local pools. - * @details This class is not stored in the map. Instead, it is used to access - * the pool entries by using a pointer to the map storing the pool - * entries. It can also be used to organize these pool entries - * into data sets. - * @tparam T + * @details + * This class is not stored in the map. Instead, it is used to access + * the pool entries by using a pointer to the map storing the pool + * entries. It can also be used to organize these pool entries into data sets. + * + * @tparam T The template parameter sets the type of the variable. Currently, + * all plain data types are supported, but in principle any type is possible. + * @ingroup data_pool */ template class LocalPoolVar: public PoolVariableIF, HasReturnvaluesIF { public: - static constexpr lp_id_t INVALID_POOL_ID = 0xFFFFFFFF; + //! Default ctor is forbidden. + LocalPoolVar() = delete; /** * This constructor is used by the data creators to have pool variable * instances which can also be stored in datasets. - * @param set_id - * @param setReadWriteMode - * @param localPoolMap - * @param dataSet + * It does not fetch the current value from the data pool. This is performed + * by the read() operation (which is not thread-safe). + * Datasets can be used to access local pool entires in a thread-safe way. + * @param poolId ID of the local pool entry. + * @param hkOwner Pointer of the owner. This will generally be the calling + * class itself which passes "this". + * @param setReadWriteMode Specify the read-write mode of the pool variable. + * @param dataSet The data set in which the variable shall register itself. + * If nullptr, the variable is not registered. */ LocalPoolVar(lp_id_t poolId, HasHkPoolParametersIF* hkOwner, - pool_rwm_t setReadWriteMode, DataSetIF* dataSet = nullptr); + pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE, + DataSetIF* dataSet = nullptr); /** * This constructor is used by data users like controllers to have * access to the local pool variables of data creators by supplying * the respective creator object ID. - * @param poolId - * @param poolOwner - * @param setReadWriteMode - * @param dataSet + * It does not fetch the current value from the data pool. This is performed + * by the read() operation (which is not thread-safe). + * Datasets can be used to access local pool entires in a thread-safe way. + * @param poolId ID of the local pool entry. + * @param hkOwner Pointer of the owner. This will generally be the calling + * class itself which passes "this". + * @param setReadWriteMode Specify the read-write mode of the pool variable. + * @param dataSet The data set in which the variable shall register itself. + * If nullptr, the variable is not registered. */ LocalPoolVar(lp_id_t poolId, object_id_t poolOwner, - pool_rwm_t setReadWriteMode, DataSetIF* dataSet = nullptr); + pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE, + DataSetIF* dataSet = nullptr); virtual~ LocalPoolVar() {}; @@ -63,33 +70,91 @@ public: */ T value = 0; - ReturnValue_t commit() override; - ReturnValue_t read() override; pool_rwm_t getReadWriteMode() const override; - uint32_t getDataPoolId() const override; + + lp_id_t getDataPoolId() const override; + void setDataPoolId(lp_id_t poolId); + bool isValid() const override; - void setValid(uint8_t validity) override; + void setValid(bool validity) override; + uint8_t getValid() const; ReturnValue_t serialize(uint8_t** buffer, size_t* size, - const size_t max_size, bool bigEndian) const override; + const size_t max_size, bool bigEndian) const override; virtual size_t getSerializedSize() const override; virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, - bool bigEndian) override; + bool bigEndian) override; + + /** + * @brief This is a call to read the array's values + * from the global data pool. + * @details + * When executed, this operation tries to fetch the pool entry with matching + * data pool id from the data pool and copies all array values and the valid + * information to its local attributes. + * In case of a failure (wrong type, size or pool id not found), the + * variable is set to zero and invalid. + * The read call is protected with a lock. + * It is recommended to use DataSets to read and commit multiple variables + * at once to avoid the overhead of unnecessary lock und unlock operations. + * + */ + ReturnValue_t read(uint32_t lockTimeout = MutexIF::BLOCKING) override; + /** + * @brief The commit call copies the array values back to the data pool. + * @details + * It checks type and size, as well as if the variable is writable. If so, + * the value is copied and the local valid flag is written back as well. + * The read call is protected with a lock. + * It is recommended to use DataSets to read and commit multiple variables + * at once to avoid the overhead of unnecessary lock und unlock operations. + */ + ReturnValue_t commit(uint32_t lockTimeout = MutexIF::BLOCKING) override; +protected: + /** + * @brief Like #read, but without a lock protection of the global pool. + * @details + * The operation does NOT provide any mutual exclusive protection by itself. + * This can be used if the lock is handled externally to avoid the overhead + * of consecutive lock und unlock operations. + * Declared protected to discourage free public usage. + */ + ReturnValue_t readWithoutLock() override; + /** + * @brief Like #commit, but without a lock protection of the global pool. + * @details + * The operation does NOT provide any mutual exclusive protection by itself. + * This can be used if the lock is handled externally to avoid the overhead + * of consecutive lock und unlock operations. + * Declared protected to discourage free public usage. + */ + ReturnValue_t commitWithoutLock() override; + + // std::ostream is the type for object std::cout +// friend std::ostream& operator<< (std::ostream &out, +// const LocalPoolVar &var) { +// out << static_cast(value); +// return out; +// } + private: - lp_id_t localPoolId = INVALID_POOL_ID; + //! @brief Pool ID of pool entry inside the used local pool. + lp_id_t localPoolId = PoolVariableIF::NO_PARAMETER; + //! @brief Read-write mode of the pool variable pool_rwm_t readWriteMode = pool_rwm_t::VAR_READ_WRITE; + //! @brief Specifies whether the entry is valid or invalid. bool valid = false; - bool objectValid = true; //! Pointer to the class which manages the HK pool. HousekeepingManager* hkManager; }; #include -template -using lp_variable = LocalPoolVar; -using lp_bool_t = LocalPoolVar; +template +using lp_var_t = LocalPoolVar; + +using lp_bool_t = LocalPoolVar; using lp_uint8_t = LocalPoolVar; using lp_uint16_t = LocalPoolVar; using lp_uint32_t = LocalPoolVar; diff --git a/datapoollocal/LocalPoolVariable.tpp b/datapoollocal/LocalPoolVariable.tpp index 4bc4c662..b7a0e837 100644 --- a/datapoollocal/LocalPoolVariable.tpp +++ b/datapoollocal/LocalPoolVariable.tpp @@ -1,16 +1,24 @@ #ifndef FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLVARIABLE_TPP_ #define FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLVARIABLE_TPP_ -#include -#include - -#include +#ifndef FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLVARIABLE_H_ +#error Include LocalPoolVariable.h before LocalPoolVariable.tpp! +#endif template inline LocalPoolVar::LocalPoolVar(lp_id_t poolId, HasHkPoolParametersIF* hkOwner, pool_rwm_t setReadWriteMode, DataSetIF* dataSet): localPoolId(poolId),readWriteMode(setReadWriteMode) { + if(poolId == PoolVariableIF::NO_PARAMETER) { + sif::warning << "LocalPoolVector: 0 passed as pool ID, which is the " + "NO_PARAMETER value!" << std::endl; + } + if(hkOwner == nullptr) { + sif::error << "LocalPoolVariable: The supplied pool owner is a nullptr!" + << std::endl; + return; + } hkManager = hkOwner->getHkManagerHandle(); if(dataSet != nullptr) { dataSet->registerVariable(this); @@ -21,12 +29,15 @@ template inline LocalPoolVar::LocalPoolVar(lp_id_t poolId, object_id_t poolOwner, pool_rwm_t setReadWriteMode, DataSetIF *dataSet): readWriteMode(readWriteMode) { + if(poolId == PoolVariableIF::NO_PARAMETER) { + sif::warning << "LocalPoolVector: 0 passed as pool ID, which is the " + "NO_PARAMETER value!" << std::endl; + } HasHkPoolParametersIF* hkOwner = objectManager->get(poolOwner); if(hkOwner == nullptr) { sif::error << "LocalPoolVariable: The supplied pool owner did not implement" "the correct interface HasHkPoolParametersIF!" << std::endl; - objectValid = false; return; } hkManager = hkOwner->getHkManagerHandle(); @@ -36,38 +47,59 @@ inline LocalPoolVar::LocalPoolVar(lp_id_t poolId, object_id_t poolOwner, } template -inline ReturnValue_t LocalPoolVar::read() { +inline ReturnValue_t LocalPoolVar::read(millis_t lockTimeout) { + MutexHelper(hkManager->getMutexHandle(), lockTimeout); + return readWithoutLock(); +} + +template +inline ReturnValue_t LocalPoolVar::readWithoutLock() { if(readWriteMode == pool_rwm_t::VAR_WRITE) { sif::debug << "LocalPoolVar: Invalid read write " "mode for read() call." << std::endl; - // TODO: special return value - return HasReturnvaluesIF::RETURN_FAILED; + return PoolVariableIF::INVALID_READ_WRITE_MODE; } - MutexHelper(hkManager->getMutexHandle(), MutexIF::NO_TIMEOUT); + PoolEntry* poolEntry = nullptr; - ReturnValue_t result = hkManager->fetchPoolEntry(localPoolId, poolEntry); - if(result != RETURN_OK) { + ReturnValue_t result = hkManager->fetchPoolEntry(localPoolId, &poolEntry); + if(result != RETURN_OK and poolEntry != nullptr) { + sif::error << "PoolVector: Read of local pool variable of object " + "0x" << std::hex << std::setw(8) << std::setfill('0') << + hkManager->getOwner() << " and lp ID 0x" << localPoolId << + std::dec << " failed.\n" << std::flush; return result; } this->value = *(poolEntry->address); + this->valid = poolEntry->valid; return RETURN_OK; } template -inline ReturnValue_t LocalPoolVar::commit() { +inline ReturnValue_t LocalPoolVar::commit(millis_t lockTimeout) { + MutexHelper(hkManager->getMutexHandle(), lockTimeout); + return commitWithoutLock(); +} + +template +inline ReturnValue_t LocalPoolVar::commitWithoutLock() { if(readWriteMode == pool_rwm_t::VAR_READ) { sif::debug << "LocalPoolVar: Invalid read write " "mode for commit() call." << std::endl; - // TODO: special return value - return HasReturnvaluesIF::RETURN_FAILED; + return PoolVariableIF::INVALID_READ_WRITE_MODE; } - MutexHelper(hkManager->getMutexHandle(), MutexIF::NO_TIMEOUT); + // Wait maximum of 50 milliseconds. + MutexHelper(hkManager->getMutexHandle(), 50); PoolEntry* poolEntry = nullptr; - ReturnValue_t result = hkManager->fetchPoolEntry(localPoolId, poolEntry); + ReturnValue_t result = hkManager->fetchPoolEntry(localPoolId, &poolEntry); if(result != RETURN_OK) { + sif::error << "PoolVector: Read of local pool variable of object " + "0x" << std::hex << std::setw(8) << std::setfill('0') << + hkManager->getOwner() << " and lp ID 0x" << localPoolId << + std::dec << " failed.\n" << std::flush; return result; } *(poolEntry->address) = this->value; + poolEntry->valid = this->valid; return RETURN_OK; } @@ -81,16 +113,26 @@ inline lp_id_t LocalPoolVar::getDataPoolId() const { return localPoolId; } +template +inline void LocalPoolVar::setDataPoolId(lp_id_t poolId) { + this->localPoolId = poolId; +} + template inline bool LocalPoolVar::isValid() const { return valid; } template -inline void LocalPoolVar::setValid(uint8_t validity) { +inline void LocalPoolVar::setValid(bool validity) { this->valid = validity; } +template +inline uint8_t LocalPoolVar::getValid() const { + return valid; +} + template inline ReturnValue_t LocalPoolVar::serialize(uint8_t** buffer, size_t* size, const size_t max_size, bool bigEndian) const { @@ -109,4 +151,11 @@ inline ReturnValue_t LocalPoolVar::deSerialize(const uint8_t** buffer, return AutoSerializeAdapter::deSerialize(&value, buffer, size, bigEndian); } +//template +//inline friend std::ostream& LocalPoolVar::operator<< (std::ostream &out, +// const LocalPoolVar &var) { +// out << static_cast(out); +//} + + #endif diff --git a/datapoollocal/LocalPoolVector.h b/datapoollocal/LocalPoolVector.h new file mode 100644 index 00000000..02c47113 --- /dev/null +++ b/datapoollocal/LocalPoolVector.h @@ -0,0 +1,189 @@ +#ifndef FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLVECTOR_H_ +#define FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLVECTOR_H_ + +#include +#include +#include +#include +#include + + +/** + * @brief This is the access class for array-type data pool entries. + * @details + * To ensure safe usage of the data pool, operation is not done directly on the + * data pool entries, but on local copies. This class provides simple type- + * and length-safe access to vector-style data pool entries (i.e. entries with + * length > 1). The class can be instantiated as read-write and read only. + * + * It provides a commit-and-roll-back semantic, which means that no array + * entry in the data pool is changed until the commit call is executed. + * There are two template parameters: + * @tparam T + * This template parameter specifies the data type of an array entry. Currently, + * all plain data types are supported, but in principle any type is possible. + * @tparam vector_size + * This template parameter specifies the vector size of this entry. Using a + * template parameter for this is not perfect, but avoids + * dynamic memory allocation. + * @ingroup data_pool + */ +template +class LocalPoolVector: public PoolVariableIF, public HasReturnvaluesIF { +public: + LocalPoolVector() = delete; + /** + * This constructor is used by the data creators to have pool variable + * instances which can also be stored in datasets. + * It does not fetch the current value from the data pool. This is performed + * by the read() operation (which is not thread-safe). + * Datasets can be used to access local pool entires in a thread-safe way. + * @param poolId ID of the local pool entry. + * @param hkOwner Pointer of the owner. This will generally be the calling + * class itself which passes "this". + * @param setReadWriteMode Specify the read-write mode of the pool variable. + * @param dataSet The data set in which the variable shall register itself. + * If nullptr, the variable is not registered. + */ + LocalPoolVector(lp_id_t poolId, HasHkPoolParametersIF* hkOwner, + pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE, + DataSetIF* dataSet = nullptr); + + /** + * This constructor is used by data users like controllers to have + * access to the local pool variables of data creators by supplying + * the respective creator object ID. + * It does not fetch the current value from the data pool. This is performed + * by the read() operation (which is not thread-safe). + * Datasets can be used to access local pool entires in a thread-safe way. + * @param poolId ID of the local pool entry. + * @param hkOwner Pointer of the owner. This will generally be the calling + * class itself which passes "this". + * @param setReadWriteMode Specify the read-write mode of the pool variable. + * @param dataSet The data set in which the variable shall register itself. + * If nullptr, the variable is not registered. + */ + LocalPoolVector(lp_id_t poolId, object_id_t poolOwner, + pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE, + DataSetIF* dataSet = nullptr); + + /** + * @brief This is the local copy of the data pool entry. + * @details The user can work on this attribute + * just like he would on a local array of this type. + */ + T value[vectorSize]; + /** + * @brief The classes destructor is empty. + * @details If commit() was not called, the local value is + * discarded and not written back to the data pool. + */ + ~LocalPoolVector() {}; + /** + * @brief The operation returns the number of array entries + * in this variable. + */ + uint8_t getSize() { + return vectorSize; + } + + uint32_t getDataPoolId() const override; + /** + * @brief This operation sets the data pool ID of the variable. + * @details + * The method is necessary to set id's of data pool member variables + * with bad initialization. + */ + void setDataPoolId(uint32_t poolId); + + /** + * This method returns if the variable is write-only, read-write or read-only. + */ + pool_rwm_t getReadWriteMode() const; + + /** + * @brief With this call, the valid information of the variable is returned. + */ + bool isValid() const override; + void setValid(bool valid) override; + uint8_t getValid() const; + + T &operator [](int i); + const T &operator [](int i) const; + + virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, + const size_t max_size, bool bigEndian) const override; + virtual size_t getSerializedSize() const override; + virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + bool bigEndian) override; + + /** + * @brief This is a call to read the array's values + * from the global data pool. + * @details + * When executed, this operation tries to fetch the pool entry with matching + * data pool id from the data pool and copies all array values and the valid + * information to its local attributes. + * In case of a failure (wrong type, size or pool id not found), the + * variable is set to zero and invalid. + * The read call is protected with a lock. + * It is recommended to use DataSets to read and commit multiple variables + * at once to avoid the overhead of unnecessary lock und unlock operations. + */ + ReturnValue_t read(uint32_t lockTimeout = MutexIF::BLOCKING) override; + /** + * @brief The commit call copies the array values back to the data pool. + * @details + * It checks type and size, as well as if the variable is writable. If so, + * the value is copied and the local valid flag is written back as well. + * The read call is protected with a lock. + * It is recommended to use DataSets to read and commit multiple variables + * at once to avoid the overhead of unnecessary lock und unlock operations. + */ + ReturnValue_t commit(uint32_t lockTimeout = MutexIF::BLOCKING) override; +protected: + /** + * @brief Like #read, but without a lock protection of the global pool. + * @details + * The operation does NOT provide any mutual exclusive protection by itself. + * This can be used if the lock is handled externally to avoid the overhead + * of consecutive lock und unlock operations. + * Declared protected to discourage free public usage. + */ + ReturnValue_t readWithoutLock() override; + /** + * @brief Like #commit, but without a lock protection of the global pool. + * @details + * The operation does NOT provide any mutual exclusive protection by itself. + * This can be used if the lock is handled externally to avoid the overhead + * of consecutive lock und unlock operations. + * Declared protected to discourage free public usage. + */ + ReturnValue_t commitWithoutLock() override; + +private: + /** + * @brief To access the correct data pool entry on read and commit calls, + * the data pool id is stored. + */ + uint32_t localPoolId; + /** + * @brief The valid information as it was stored in the data pool + * is copied to this attribute. + */ + bool valid; + /** + * @brief The information whether the class is read-write or + * read-only is stored here. + */ + ReadWriteMode_t readWriteMode; + //! @brief Pointer to the class which manages the HK pool. + HousekeepingManager* hkManager; +}; + +#include + +template +using lp_vec_t = LocalPoolVector; + +#endif /* FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLVECTOR_H_ */ diff --git a/datapoollocal/LocalPoolVector.tpp b/datapoollocal/LocalPoolVector.tpp new file mode 100644 index 00000000..78637eff --- /dev/null +++ b/datapoollocal/LocalPoolVector.tpp @@ -0,0 +1,185 @@ +#ifndef FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLVECTOR_TPP_ +#define FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLVECTOR_TPP_ + +#ifndef FRAMEWORK_DATAPOOLLOCAL_LOCALPOOLVECTOR_H_ +#error Include LocalPoolVector.h before LocalPoolVector.tpp! +#endif + +template +inline LocalPoolVector::LocalPoolVector(lp_id_t poolId, + HasHkPoolParametersIF* hkOwner, pool_rwm_t setReadWriteMode, + DataSetIF* dataSet) : + localPoolId(poolId), valid(false), readWriteMode(setReadWriteMode) { + if(poolId == PoolVariableIF::NO_PARAMETER) { + sif::warning << "LocalPoolVector: 0 passed as pool ID, which is the " + "NO_PARAMETER value!" << std::endl; + } + memset(this->value, 0, vectorSize * sizeof(T)); + if (dataSet != nullptr) { + dataSet->registerVariable(this); + } +} + +template +inline LocalPoolVector::LocalPoolVector(lp_id_t poolId, + object_id_t poolOwner, pool_rwm_t setReadWriteMode, DataSetIF *dataSet): + readWriteMode(readWriteMode) { + if(poolId == PoolVariableIF::NO_PARAMETER) { + sif::warning << "LocalPoolVector: 0 passed as pool ID, which is the " + "NO_PARAMETER value!" << std::endl; + } + HasHkPoolParametersIF* hkOwner = + objectManager->get(poolOwner); + if(hkOwner == nullptr) { + sif::error << "LocalPoolVariable: The supplied pool owner did not implement" + "the correct interface HasHkPoolParametersIF!" << std::endl; + return; + } + hkManager = hkOwner->getHkManagerHandle(); + if(dataSet != nullptr) { + dataSet->registerVariable(this); + } +} + +template +inline ReturnValue_t LocalPoolVector::read(uint32_t lockTimeout) { + MutexHelper(hkManager->getMutexHandle(), lockTimeout); + return readWithoutLock(); +} +template +inline ReturnValue_t LocalPoolVector::readWithoutLock() { + if(readWriteMode == pool_rwm_t::VAR_WRITE) { + sif::debug << "LocalPoolVar: Invalid read write " + "mode for read() call." << std::endl; + return PoolVariableIF::INVALID_READ_WRITE_MODE; + } + + PoolEntry* poolEntry = nullptr; + ReturnValue_t result = hkManager->fetchPoolEntry(localPoolId, &poolEntry); + memset(this->value, 0, vectorSize * sizeof(T)); + + if(result != RETURN_OK) { + sif::error << "PoolVector: Read of local pool variable of object " + "0x" << std::hex << std::setw(8) << std::setfill('0') << + hkManager->getOwner() << "and lp ID 0x" << localPoolId << + std::dec << " failed." << std::endl; + return result; + } + memcpy(this->value, poolEntry->address, poolEntry->getByteSize()); + this->valid = poolEntry->valid; + return RETURN_OK; +} + +template +inline ReturnValue_t LocalPoolVector::commit( + uint32_t lockTimeout) { + MutexHelper(hkManager->getMutexHandle(), lockTimeout); + return commitWithoutLock(); +} + +template +inline ReturnValue_t LocalPoolVector::commitWithoutLock() { + if(readWriteMode == pool_rwm_t::VAR_READ) { + sif::debug << "LocalPoolVar: Invalid read write " + "mode for commit() call." << std::endl; + return PoolVariableIF::INVALID_READ_WRITE_MODE; + } + // Wait maximum of 50 milliseconds. + MutexHelper(hkManager->getMutexHandle(), 50); + PoolEntry* poolEntry = nullptr; + ReturnValue_t result = hkManager->fetchPoolEntry(localPoolId, &poolEntry); + if(result != RETURN_OK) { + sif::error << "PoolVector: Read of local pool variable of object " + "0x" << std::hex << std::setw(8) << std::setfill('0') << + hkManager->getOwner() << " and lp ID 0x" << localPoolId << + std::dec << " failed.\n" << std::flush; + return result; + } + memcpy(poolEntry->address, this->value, poolEntry->getByteSize()); + poolEntry->valid = this->valid; + return RETURN_OK; +} + +template +inline T& LocalPoolVector::operator [](int i) { + if(i <= vectorSize) { + return value[i]; + } + sif::warning << "LocalPoolVector: Invalid index" << std::endl; + return 0; +} + +template +inline const T& LocalPoolVector::operator [](int i) const { + if(i <= vectorSize) { + return value[i]; + } + sif::warning << "LocalPoolVector: Invalid index" << std::endl; + return 0; +} + +template +inline ReturnValue_t LocalPoolVector::serialize(uint8_t** buffer, + size_t* size, const size_t max_size, bool bigEndian) const { + ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED; + for (uint16_t i = 0; i < vectorSize; i++) { + result = SerializeAdapter::serialize(&(value[i]), buffer, size, + max_size, bigEndian); + if (result != HasReturnvaluesIF::RETURN_OK) { + break; + } + } + return result; +} + +template +inline size_t LocalPoolVector::getSerializedSize() const { + return vectorSize * SerializeAdapter::getSerializedSize(value); +} + +template +inline ReturnValue_t LocalPoolVector::deSerialize( + const uint8_t** buffer, size_t* size, bool bigEndian) { + ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED; + for (uint16_t i = 0; i < vectorSize; i++) { + result = SerializeAdapter::deSerialize(&(value[i]), buffer, size, + bigEndian); + if (result != HasReturnvaluesIF::RETURN_OK) { + break; + } + } + return result; +} + +template +inline pool_rwm_t LocalPoolVector::getReadWriteMode() const { + return this->readWriteMode; +} + + +template +inline uint32_t LocalPoolVector::getDataPoolId() const { + return localPoolId; +} + +template +inline void LocalPoolVector::setDataPoolId(uint32_t poolId) { + this->localPoolId = poolId; +} + +template +inline void LocalPoolVector::setValid(bool valid) { + this->valid = valid; +} + +template +inline uint8_t LocalPoolVector::getValid() const { + return valid; +} + +template +inline bool LocalPoolVector::isValid() const { + return valid; +} + +#endif From 9ec2283d1397b5699796517cc47e3f82e327757a Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 5 Jun 2020 20:35:08 +0200 Subject: [PATCH 062/307] hk folder update --- housekeeping/HasHkPoolParametersIF.h | 23 ++++++++- housekeeping/HousekeepingManager.cpp | 46 ++++++++++++++--- housekeeping/HousekeepingManager.h | 77 +++++++++++++++++----------- housekeeping/HousekeepingMessage.cpp | 12 ++--- housekeeping/HousekeepingMessage.h | 15 ++---- 5 files changed, 119 insertions(+), 54 deletions(-) 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); }; From 7247a1af7efde551f6e7d619e66917d9d4717562 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 5 Jun 2020 20:36:25 +0200 Subject: [PATCH 063/307] new class ids --- returnvalues/FwClassIds.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/returnvalues/FwClassIds.h b/returnvalues/FwClassIds.h index 120d8b8c..870efb46 100644 --- a/returnvalues/FwClassIds.h +++ b/returnvalues/FwClassIds.h @@ -55,12 +55,14 @@ enum { HAS_ACTIONS_IF, //HF DEVICE_COMMUNICATION_IF, //DC BSP, //BSP - TIME_STAMPER_IF, //TSI 52 + TIME_STAMPER_IF, //TSI 53 //TODO This will shift all IDs for FLP - SGP4PROPAGATOR_CLASS, //SGP4 53 - MUTEX_IF, //MUX 54 - MESSAGE_QUEUE_IF,//MQI 55 - SEMAPHORE_IF, //SPH 56 + SGP4PROPAGATOR_CLASS, //SGP4 54 + MUTEX_IF, //MUX 55 + MESSAGE_QUEUE_IF,//MQI 56 + SEMAPHORE_IF, //SPH 57 + HOUSEKEEPING, //HK 58 + POOL_VARIABLE_IF, //PVA 59 FW_CLASS_ID_COUNT //is actually count + 1 ! }; From 0d4d4123ab28a10376c8ba6c6cc7bd3be5c54e74 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 5 Jun 2020 20:37:46 +0200 Subject: [PATCH 064/307] added new message type (hk) --- ipc/FwMessageTypes.h | 1 + 1 file changed, 1 insertion(+) diff --git a/ipc/FwMessageTypes.h b/ipc/FwMessageTypes.h index b59319aa..7daf8767 100644 --- a/ipc/FwMessageTypes.h +++ b/ipc/FwMessageTypes.h @@ -15,6 +15,7 @@ enum FW_MESSAGE_TYPE { MEMORY, PARAMETER, FILE_SYSTEM_MESSAGE, + HOUSEKEEPING, FW_MESSAGES_COUNT, }; From e9a9a543ce3fbf8a9ff57e337513e050e6004c8e Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 5 Jun 2020 20:38:59 +0200 Subject: [PATCH 065/307] fw message count one line further --- ipc/FwMessageTypes.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ipc/FwMessageTypes.h b/ipc/FwMessageTypes.h index 7daf8767..1665747e 100644 --- a/ipc/FwMessageTypes.h +++ b/ipc/FwMessageTypes.h @@ -16,8 +16,8 @@ enum FW_MESSAGE_TYPE { PARAMETER, FILE_SYSTEM_MESSAGE, HOUSEKEEPING, - FW_MESSAGES_COUNT, + FW_MESSAGES_COUNT, }; } From 2b646551e96882aac5c62232b9c88a0271209440 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 5 Jun 2020 20:40:22 +0200 Subject: [PATCH 066/307] mutex helper new output error --- ipc/MutexHelper.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ipc/MutexHelper.h b/ipc/MutexHelper.h index 671cd5a6..20760b32 100644 --- a/ipc/MutexHelper.h +++ b/ipc/MutexHelper.h @@ -9,8 +9,12 @@ public: MutexHelper(MutexIF* mutex, uint32_t timeoutMs) : internalMutex(mutex) { ReturnValue_t status = mutex->lockMutex(timeoutMs); - if(status != HasReturnvaluesIF::RETURN_OK){ - sif::error << "MutexHelper: Lock of Mutex failed " << + if(status == MutexIF::MUTEX_TIMEOUT) { + sif::error << "MutexHelper: Lock of mutex failed with timeout of" + << timeoutMs << " milliseconds!" << std::endl; + } + else if(status != HasReturnvaluesIF::RETURN_OK){ + sif::error << "MutexHelper: Lock of Mutex failed with code " << status << std::endl; } } From 4b5bb0b3be6e6c14c647800d7ab928a468de02aa Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 5 Jun 2020 20:59:07 +0200 Subject: [PATCH 067/307] reset setfill --- objectmanager/ObjectManager.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/objectmanager/ObjectManager.cpp b/objectmanager/ObjectManager.cpp index 2f47950f..55f7d964 100644 --- a/objectmanager/ObjectManager.cpp +++ b/objectmanager/ObjectManager.cpp @@ -70,8 +70,9 @@ void ObjectManager::initialize() { if ( return_value != RETURN_OK ) { object_id_t var = it.first; sif::error << "Object 0x" << std::hex << std::setw(8) << - std::setfill('0')<< var << " failed to initialize " << - "with code 0x" << return_value << std::dec << std::endl; + std::setfill('0') << var << " failed to initialize " << + "with code 0x" << return_value << std::dec << + std::setfill('') << std::endl; error_count++; } } From 579115f904e5287ad0bd8d15038b6d707a72523f Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 5 Jun 2020 21:36:50 +0200 Subject: [PATCH 068/307] adapting host osal --- osal/host/Clock.cpp | 4 ++-- osal/host/Mutex.cpp | 10 +++++----- osal/host/Mutex.h | 2 +- osal/host/QueueFactory.cpp | 2 +- osal/host/SemaphoreFactory.cpp | 4 ++-- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/osal/host/Clock.cpp b/osal/host/Clock.cpp index 78bbc58a..57f2572b 100644 --- a/osal/host/Clock.cpp +++ b/osal/host/Clock.cpp @@ -186,7 +186,7 @@ ReturnValue_t Clock::setLeapSeconds(const uint16_t leapSeconds_) { if(checkOrCreateClockMutex()!=HasReturnvaluesIF::RETURN_OK){ return HasReturnvaluesIF::RETURN_FAILED; } - ReturnValue_t result = timeMutex->lockMutex(MutexIF::NO_TIMEOUT); + ReturnValue_t result = timeMutex->lockMutex(MutexIF::BLOCKING); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } @@ -201,7 +201,7 @@ ReturnValue_t Clock::getLeapSeconds(uint16_t* leapSeconds_) { if(timeMutex == nullptr){ return HasReturnvaluesIF::RETURN_FAILED; } - ReturnValue_t result = timeMutex->lockMutex(MutexIF::NO_TIMEOUT); + ReturnValue_t result = timeMutex->lockMutex(MutexIF::BLOCKING); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } diff --git a/osal/host/Mutex.cpp b/osal/host/Mutex.cpp index 0e6e652d..03948c4c 100644 --- a/osal/host/Mutex.cpp +++ b/osal/host/Mutex.cpp @@ -1,22 +1,22 @@ #include #include -const uint32_t MutexIF::NO_TIMEOUT = 0; -const uint32_t MutexIF::MAX_TIMEOUT = 0xffffffff; +const uint32_t MutexIF::POLLING = 0; +const uint32_t MutexIF::BLOCKING = 0xffffffff; ReturnValue_t Mutex::lockMutex(uint32_t timeoutMs) { - if(timeoutMs == MutexIF::MAX_TIMEOUT) { + if(timeoutMs == MutexIF::BLOCKING) { mutex.lock(); locked = true; return HasReturnvaluesIF::RETURN_OK; } - else if(timeoutMs == MutexIF::NO_TIMEOUT) { + else if(timeoutMs == MutexIF::POLLING) { if(mutex.try_lock()) { locked = true; return HasReturnvaluesIF::RETURN_OK; } } - else if(timeoutMs > MutexIF::NO_TIMEOUT){ + else if(timeoutMs > MutexIF::POLLING){ auto chronoMs = std::chrono::milliseconds(timeoutMs); if(mutex.try_lock_for(chronoMs)) { locked = true; diff --git a/osal/host/Mutex.h b/osal/host/Mutex.h index dce2a9dc..d882c457 100644 --- a/osal/host/Mutex.h +++ b/osal/host/Mutex.h @@ -16,7 +16,7 @@ class Mutex : public MutexIF { public: Mutex() = default; - ReturnValue_t lockMutex(uint32_t timeoutMs = MutexIF::MAX_TIMEOUT) override; + ReturnValue_t lockMutex(uint32_t timeoutMs = MutexIF::BLOCKING) override; ReturnValue_t unlockMutex() override; std::timed_mutex* getMutexHandle(); diff --git a/osal/host/QueueFactory.cpp b/osal/host/QueueFactory.cpp index 691249c3..60274c84 100644 --- a/osal/host/QueueFactory.cpp +++ b/osal/host/QueueFactory.cpp @@ -27,7 +27,7 @@ QueueFactory::QueueFactory() { QueueFactory::~QueueFactory() { } -MessageQueueIF* QueueFactory::createMessageQueue(size_t messageDepth, +MessageQueueIF* QueueFactory::createMessageQueue(uint32_t messageDepth, size_t maxMessageSize) { // A thread-safe queue can be implemented by using a combination // of std::queue and std::mutex. This uses dynamic memory allocation diff --git a/osal/host/SemaphoreFactory.cpp b/osal/host/SemaphoreFactory.cpp index 3719a883..8712d866 100644 --- a/osal/host/SemaphoreFactory.cpp +++ b/osal/host/SemaphoreFactory.cpp @@ -3,8 +3,8 @@ #include #include -const uint32_t SemaphoreIF::NO_TIMEOUT = 0; -const uint32_t SemaphoreIF::MAX_TIMEOUT = 0xFFFFFFFF; +const uint32_t SemaphoreIF::POLLING = 0; +const uint32_t SemaphoreIF::BLOCKING = 0xFFFFFFFF; SemaphoreFactory* SemaphoreFactory::factoryInstance = nullptr; From d74f2c7560452a9b82ddfa4020335b73d971b8a5 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 5 Jun 2020 21:40:06 +0200 Subject: [PATCH 069/307] housekeeping folder added to .mk file --- framework.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework.mk b/framework.mk index 2092c2fe..404055ee 100644 --- a/framework.mk +++ b/framework.mk @@ -10,11 +10,11 @@ CXXSRC += $(wildcard $(FRAMEWORK_PATH)/datalinklayer/*.cpp) CXXSRC += $(wildcard $(FRAMEWORK_PATH)/datapool/*.cpp) CXXSRC += $(wildcard $(FRAMEWORK_PATH)/datapoolglob/*.cpp) CXXSRC += $(wildcard $(FRAMEWORK_PATH)/datapoollocal/*.cpp) +CXXSRC += $(wildcard $(FRAMEWORK_PATH)/housekeeping/*.cpp) CXXSRC += $(wildcard $(FRAMEWORK_PATH)/devicehandlers/*.cpp) CXXSRC += $(wildcard $(FRAMEWORK_PATH)/events/*.cpp) CXXSRC += $(wildcard $(FRAMEWORK_PATH)/events/eventmatching/*.cpp) CXXSRC += $(wildcard $(FRAMEWORK_PATH)/fdir/*.cpp) -CXXSRC += $(wildcard $(FRAMEWORK_PATH)/framework.mk/*.cpp) CXXSRC += $(wildcard $(FRAMEWORK_PATH)/globalfunctions/*.cpp) CXXSRC += $(wildcard $(FRAMEWORK_PATH)/globalfunctions/matching/*.cpp) CXXSRC += $(wildcard $(FRAMEWORK_PATH)/globalfunctions/math/*.cpp) From 87f64d99cd1b7eae59b601140d13a5b92565f384 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 5 Jun 2020 23:18:00 +0200 Subject: [PATCH 070/307] implemented fixed timeslot task --- osal/host/FixedTimeslotTask.cpp | 191 ++++++++++++++++++++++++++++++++ osal/host/FixedTimeslotTask.h | 130 ++++++++++++++++++++++ osal/host/PeriodicTask.cpp | 6 +- osal/host/PeriodicTask.h | 5 +- osal/host/TaskFactory.cpp | 6 +- 5 files changed, 330 insertions(+), 8 deletions(-) create mode 100644 osal/host/FixedTimeslotTask.cpp create mode 100644 osal/host/FixedTimeslotTask.h diff --git a/osal/host/FixedTimeslotTask.cpp b/osal/host/FixedTimeslotTask.cpp new file mode 100644 index 00000000..48d11843 --- /dev/null +++ b/osal/host/FixedTimeslotTask.cpp @@ -0,0 +1,191 @@ +#include + +#include +#include +#include + +#include +#include + +#include +#include + +#if defined(WIN32) +#include +#elif defined(LINUX) +#include +#endif + +FixedTimeslotTask::FixedTimeslotTask(const char *name, TaskPriority setPriority, + TaskStackSize setStack, TaskPeriod setPeriod, + void (*setDeadlineMissedFunc)()) : + started(false), pollingSeqTable(setPeriod*1000), taskName(name), + period(setPeriod), deadlineMissedFunc(setDeadlineMissedFunc) { + // It is propably possible to set task priorities by using the native + // task handles for Windows / Linux + mainThread = std::thread(&FixedTimeslotTask::taskEntryPoint, this, this); +#if defined(WIN32) + /* List of possible priority classes: + * https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/ + * nf-processthreadsapi-setpriorityclass + * And respective thread priority numbers: + * https://docs.microsoft.com/en-us/windows/ + * win32/procthread/scheduling-priorities */ + int result = SetPriorityClass( + reinterpret_cast(mainThread.native_handle()), + ABOVE_NORMAL_PRIORITY_CLASS); + if(result != 0) { + sif::error << "FixedTimeslotTask: Windows SetPriorityClass failed with code " + << GetLastError() << std::endl; + } + result = SetThreadPriority( + reinterpret_cast(mainThread.native_handle()), + THREAD_PRIORITY_NORMAL); + if(result != 0) { + sif::error << "FixedTimeslotTask: Windows SetPriorityClass failed with code " + << GetLastError() << std::endl; + } +#elif defined(LINUX) + // we can just copy and paste the code from linux here. +#endif +} + +FixedTimeslotTask::~FixedTimeslotTask(void) { + //Do not delete objects, we were responsible for ptrs only. + terminateThread = true; + if(mainThread.joinable()) { + mainThread.join(); + } + delete this; +} + +void FixedTimeslotTask::taskEntryPoint(void* argument) { + FixedTimeslotTask *originalTask(reinterpret_cast(argument)); + + if (not originalTask->started) { + // we have to suspend/block here until the task is started. + // if semaphores are implemented, use them here. + std::unique_lock lock(initMutex); + initCondition.wait(lock); + } + + this->taskFunctionality(); + sif::debug << "FixedTimeslotTask::taskEntryPoint: " + "Returned from taskFunctionality." << std::endl; +} + +ReturnValue_t FixedTimeslotTask::startTask() { + started = true; + + // Notify task to start. + std::lock_guard lock(initMutex); + initCondition.notify_one(); + + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t FixedTimeslotTask::sleepFor(uint32_t ms) { + std::this_thread::sleep_for(std::chrono::milliseconds(ms)); + return HasReturnvaluesIF::RETURN_OK; +} + +void FixedTimeslotTask::taskFunctionality() { + // A local iterator for the Polling Sequence Table is created to + // find the start time for the first entry. + SlotListIter slotListIter = pollingSeqTable.current; + // Get start time for first entry. + chron_ms interval(slotListIter->pollingTimeMs); + auto currentStartTime { + std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()) + }; + if(interval.count() > 0) { + delayForInterval(¤tStartTime, interval); + } + + /* Enter the loop that defines the task behavior. */ + for (;;) { + if(terminateThread.load()) { + break; + } + //The component for this slot is executed and the next one is chosen. + this->pollingSeqTable.executeAndAdvance(); + if (not pollingSeqTable.slotFollowsImmediately()) { + // we need to wait before executing the current slot + //this gives us the time to wait: + interval = chron_ms(this->pollingSeqTable.getIntervalToPreviousSlotMs()); + delayForInterval(¤tStartTime, interval); + //TODO deadline missed check + } + } +} + +ReturnValue_t FixedTimeslotTask::addSlot(object_id_t componentId, + uint32_t slotTimeMs, int8_t executionStep) { + if (objectManager->get(componentId) != nullptr) { + pollingSeqTable.addSlot(componentId, slotTimeMs, executionStep, this); + return HasReturnvaluesIF::RETURN_OK; + } + + sif::error << "Component " << std::hex << componentId << + " not found, not adding it to pst" << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; +} + +ReturnValue_t FixedTimeslotTask::checkSequence() const { + return pollingSeqTable.checkSequence(); +} + +uint32_t FixedTimeslotTask::getPeriodMs() const { + return period * 1000; +} + +bool FixedTimeslotTask::delayForInterval(chron_ms * previousWakeTimeMs, + const chron_ms interval) { + bool shouldDelay = false; + //Get current wakeup time + auto currentStartTime = + std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()); + /* Generate the tick time at which the task wants to wake. */ + auto nextTimeToWake_ms = (*previousWakeTimeMs) + interval; + + if (currentStartTime < *previousWakeTimeMs) { + /* The tick count has overflowed since this function was + lasted called. In this case the only time we should ever + actually delay is if the wake time has also overflowed, + and the wake time is greater than the tick time. When this + is the case it is as if neither time had overflowed. */ + if ((nextTimeToWake_ms < *previousWakeTimeMs) + && (nextTimeToWake_ms > currentStartTime)) { + shouldDelay = true; + } + } else { + /* The tick time has not overflowed. In this case we will + delay if either the wake time has overflowed, and/or the + tick time is less than the wake time. */ + if ((nextTimeToWake_ms < *previousWakeTimeMs) + || (nextTimeToWake_ms > currentStartTime)) { + shouldDelay = true; + } + } + + /* Update the wake time ready for the next call. */ + + (*previousWakeTimeMs) = nextTimeToWake_ms; + + if (shouldDelay) { + auto sleepTime = std::chrono::duration_cast( + nextTimeToWake_ms - currentStartTime); + std::this_thread::sleep_for(sleepTime); + return true; + } + //We are shifting the time in case the deadline was missed like rtems + (*previousWakeTimeMs) = currentStartTime; + return false; + +} + + + + diff --git a/osal/host/FixedTimeslotTask.h b/osal/host/FixedTimeslotTask.h new file mode 100644 index 00000000..bb2f757a --- /dev/null +++ b/osal/host/FixedTimeslotTask.h @@ -0,0 +1,130 @@ +#ifndef FRAMEWORK_OSAL_HOST_FIXEDTIMESLOTTASK_H_ +#define FRAMEWORK_OSAL_HOST_FIXEDTIMESLOTTASK_H_ + +#include +#include +#include +#include + +#include +#include +#include +#include + +class ExecutableObjectIF; + +/** + * @brief This class represents a task for periodic activities with multiple + * steps and strict timeslot requirements for these steps. + * @details + * @ingroup task_handling + */ +class FixedTimeslotTask: public FixedTimeslotTaskIF { +public: + /** + * @brief Standard constructor of the class. + * @details + * The class is initialized without allocated objects. These need to be + * added with #addComponent. + * @param priority + * @param stack_size + * @param setPeriod + * @param setDeadlineMissedFunc + * The function pointer to the deadline missed function that shall be + * assigned. + */ + FixedTimeslotTask(const char *name, TaskPriority setPriority, + TaskStackSize setStack, TaskPeriod setPeriod, + void (*setDeadlineMissedFunc)()); + /** + * @brief Currently, the executed object's lifetime is not coupled with + * the task object's lifetime, so the destructor is empty. + */ + virtual ~FixedTimeslotTask(void); + + /** + * @brief The method to start the task. + * @details The method starts the task with the respective system call. + * Entry point is the taskEntryPoint method described below. + * The address of the task object is passed as an argument + * to the system call. + */ + ReturnValue_t startTask(void); + + /** + * Add timeslot to the polling sequence table. + * @param componentId + * @param slotTimeMs + * @param executionStep + * @return + */ + ReturnValue_t addSlot(object_id_t componentId, + uint32_t slotTimeMs, int8_t executionStep); + + ReturnValue_t checkSequence() const; + + uint32_t getPeriodMs() const; + + ReturnValue_t sleepFor(uint32_t ms); + +protected: + using chron_ms = std::chrono::milliseconds; + + bool started; + //!< Typedef for the List of objects. + typedef std::vector ObjectList; + std::thread mainThread; + std::atomic terminateThread = false; + + //! Polling sequence table which contains the object to execute + //! and information like the timeslots and the passed execution step. + FixedSlotSequence pollingSeqTable; + + std::condition_variable initCondition; + std::mutex initMutex; + std::string taskName; + /** + * @brief The period of the task. + * @details + * The period determines the frequency of the task's execution. + * It is expressed in clock ticks. + */ + TaskPeriod period; + + /** + * @brief The pointer to the deadline-missed function. + * @details + * This pointer stores the function that is executed if the task's deadline + * is missed. So, each may react individually on a timing failure. + * The pointer may be NULL, then nothing happens on missing the deadline. + * The deadline is equal to the next execution of the periodic task. + */ + void (*deadlineMissedFunc)(void); + /** + * @brief This is the function executed in the new task's context. + * @details + * It converts the argument back to the thread object type and copies the + * class instance to the task context. + * The taskFunctionality method is called afterwards. + * @param A pointer to the task object itself is passed as argument. + */ + + void taskEntryPoint(void* argument); + /** + * @brief The function containing the actual functionality of the task. + * @details + * The method sets and starts the task's period, then enters a loop that is + * repeated as long as the isRunning attribute is true. Within the loop, + * all performOperation methods of the added objects are called. Afterwards + * the checkAndRestartPeriod system call blocks the task until the next + * period. On missing the deadline, the deadlineMissedFunction is executed. + */ + void taskFunctionality(void); + + bool delayForInterval(chron_ms * previousWakeTimeMs, + const chron_ms interval); +}; + + + +#endif /* FRAMEWORK_OSAL_HOST_FIXEDTIMESLOTTASK_H_ */ diff --git a/osal/host/PeriodicTask.cpp b/osal/host/PeriodicTask.cpp index 57898ac2..1a5024ab 100644 --- a/osal/host/PeriodicTask.cpp +++ b/osal/host/PeriodicTask.cpp @@ -105,7 +105,7 @@ void PeriodicTask::taskFunctionality() { it != objectList.end(); ++it) { (*it)->performOperation(); } - if(not delayUntil(¤tStartTime, periodChrono)) { + if(not delayForInterval(¤tStartTime, periodChrono)) { sif::warning << "PeriodicTask: " << taskName << " missed deadline!\n" << std::flush; if(deadlineMissedFunc != nullptr) { @@ -129,8 +129,8 @@ uint32_t PeriodicTask::getPeriodMs() const { return period * 1000; } -bool PeriodicTask::delayUntil(std::chrono::milliseconds * previousWakeTimeMs, - const std::chrono::milliseconds interval) { +bool PeriodicTask::delayForInterval(chron_ms* previousWakeTimeMs, + const chron_ms interval) { bool shouldDelay = false; //Get current wakeup time auto currentStartTime = diff --git a/osal/host/PeriodicTask.h b/osal/host/PeriodicTask.h index 19c06b52..d97bf089 100644 --- a/osal/host/PeriodicTask.h +++ b/osal/host/PeriodicTask.h @@ -64,6 +64,7 @@ public: ReturnValue_t sleepFor(uint32_t ms); protected: + using chron_ms = std::chrono::milliseconds; bool started; //!< Typedef for the List of objects. typedef std::vector ObjectList; @@ -115,8 +116,8 @@ protected: */ void taskFunctionality(void); - bool delayUntil(std::chrono::milliseconds * previousWakeTimeMs, - const std::chrono::milliseconds interval); + bool delayForInterval(chron_ms * previousWakeTimeMs, + const chron_ms interval); }; #endif /* PERIODICTASK_H_ */ diff --git a/osal/host/TaskFactory.cpp b/osal/host/TaskFactory.cpp index a13844c4..9db8ac4d 100644 --- a/osal/host/TaskFactory.cpp +++ b/osal/host/TaskFactory.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -36,9 +37,8 @@ FixedTimeslotTaskIF* TaskFactory::createFixedTimeslotTask(TaskName name_, TaskDeadlineMissedFunction deadLineMissedFunction_) { // This is going to be interesting. Time now learn the C++ threading library // :-) - sif::warning << "TaskFactory::createFixedTimeslotTask: Not implemented " - "yet" << std::endl; - return nullptr; + return new FixedTimeslotTask(name_, taskPriority_, stackSize_, + periodInSeconds_, deadLineMissedFunction_); } ReturnValue_t TaskFactory::deleteTask(PeriodicTaskIF* task) { From d600d488167c891407e27b3d3f545d02e319fb2e Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 6 Jun 2020 01:31:08 +0200 Subject: [PATCH 071/307] added the decoupling of DHB from powerSwitcher + some first hk maanger changes, might comment them out --- devicehandlers/DeviceHandlerBase.cpp | 232 +++++++++++------- devicehandlers/DeviceHandlerBase.h | 215 ++++++++-------- .../DeviceHandlerFailureIsolation.cpp | 34 +-- .../DeviceHandlerFailureIsolation.h | 1 + 4 files changed, 273 insertions(+), 209 deletions(-) diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index 02c94129..1e3bb16e 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -14,7 +14,7 @@ #include -object_id_t DeviceHandlerBase::powerSwitcherId = 0; +object_id_t DeviceHandlerBase::powerSwitcherId = objects::NO_OBJECT; object_id_t DeviceHandlerBase::rawDataReceiverId = 0; object_id_t DeviceHandlerBase::defaultFDIRParentId = 0; @@ -26,12 +26,13 @@ DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, 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), deviceThermalStatePoolId(thermalStatePoolId), deviceThermalRequestPoolId(thermalRequestPoolId), - healthHelper(this,setObjectId), modeHelper(this), parameterHelper(this), childTransitionFailure(RETURN_OK), fdirInstance(fdirInstance), hkSwitcher(this), defaultFDIRUsed(fdirInstance == nullptr), - switchOffWasReported(false), actionHelper(this, nullptr), cookieInfo(), + switchOffWasReported(false), cookieInfo(), childTransitionDelay(5000), transitionSourceMode(_MODE_POWER_DOWN), transitionSourceSubMode( SUBMODE_NONE), deviceSwitch(setDeviceSwitch) { @@ -52,7 +53,7 @@ DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, } DeviceHandlerBase::~DeviceHandlerBase() { - //communicationInterface->close(cookie); + delete comCookie; if (defaultFDIRUsed) { delete fdirInstance; } @@ -129,9 +130,11 @@ ReturnValue_t DeviceHandlerBase::initialize() { defaultRawReceiver = rawReceiver->getDeviceQueue(); - powerSwitcher = objectManager->get(powerSwitcherId); - if (powerSwitcher == NULL) { - return RETURN_FAILED; + if(powerSwitcherId != objects::NO_OBJECT) { + powerSwitcher = objectManager->get(powerSwitcherId); + if (powerSwitcher == NULL) { + return RETURN_FAILED; + } } result = healthHelper.initialize(); @@ -162,6 +165,11 @@ ReturnValue_t DeviceHandlerBase::initialize() { return result; } + result = hkManager.initializeHousekeepingPoolEntriesOnce(); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + fillCommandAndReplyMap(); //Set temperature target state to NON_OP. @@ -271,7 +279,8 @@ void DeviceHandlerBase::doStateMachine() { case _MODE_WAIT_ON: { uint32_t currentUptime; Clock::getUptime(¤tUptime); - if (currentUptime - timeoutStart >= powerSwitcher->getSwitchDelayMs()) { + if (powerSwitcher != nullptr and currentUptime - timeoutStart >= + powerSwitcher->getSwitchDelayMs()) { triggerEvent(MODE_TRANSITION_FAILED, PowerSwitchIF::SWITCH_TIMEOUT, 0); setMode(_MODE_POWER_DOWN); @@ -341,9 +350,10 @@ ReturnValue_t DeviceHandlerBase::isModeCombinationValid(Mode_t mode, } } -ReturnValue_t DeviceHandlerBase::insertInCommandAndReplyMap(DeviceCommandId_t deviceCommand, - uint16_t maxDelayCycles, size_t replyLen, uint8_t periodic, - bool hasDifferentReplyId, DeviceCommandId_t replyId) { +ReturnValue_t DeviceHandlerBase::insertInCommandAndReplyMap( + DeviceCommandId_t deviceCommand, uint16_t maxDelayCycles, + size_t replyLen, bool periodic, bool hasDifferentReplyId, + DeviceCommandId_t replyId) { //No need to check, as we may try to insert multiple times. insertInCommandMap(deviceCommand); if (hasDifferentReplyId) { @@ -354,7 +364,7 @@ ReturnValue_t DeviceHandlerBase::insertInCommandAndReplyMap(DeviceCommandId_t de } ReturnValue_t DeviceHandlerBase::insertInReplyMap(DeviceCommandId_t replyId, - uint16_t maxDelayCycles, size_t replyLen, uint8_t periodic) { + uint16_t maxDelayCycles, size_t replyLen, bool periodic) { DeviceReplyInfo info; info.maxDelayCycles = maxDelayCycles; info.periodic = periodic; @@ -369,7 +379,8 @@ ReturnValue_t DeviceHandlerBase::insertInReplyMap(DeviceCommandId_t replyId, } } -ReturnValue_t DeviceHandlerBase::insertInCommandMap(DeviceCommandId_t deviceCommand) { +ReturnValue_t DeviceHandlerBase::insertInCommandMap( + DeviceCommandId_t deviceCommand) { DeviceCommandInfo info; info.expectedReplies = 0; info.isExecuting = false; @@ -383,7 +394,7 @@ ReturnValue_t DeviceHandlerBase::insertInCommandMap(DeviceCommandId_t deviceComm } ReturnValue_t DeviceHandlerBase::updateReplyMapEntry(DeviceCommandId_t deviceReply, - uint16_t delayCycles, uint16_t maxDelayCycles, uint8_t periodic) { + uint16_t delayCycles, uint16_t maxDelayCycles, bool periodic) { std::map::iterator iter = deviceReplyMap.find(deviceReply); if (iter == deviceReplyMap.end()) { @@ -576,11 +587,8 @@ void DeviceHandlerBase::doSendRead() { } void DeviceHandlerBase::doGetRead() { - size_t receivedDataLen; - uint8_t *receivedData; - DeviceCommandId_t foundId = 0xFFFFFFFF; - size_t foundLen = 0; - ReturnValue_t result; + size_t receivedDataLen = 0; + uint8_t *receivedData = nullptr; if (cookieInfo.state != COOKIE_READ_SENT) { cookieInfo.state = COOKIE_UNUSED; @@ -589,8 +597,8 @@ void DeviceHandlerBase::doGetRead() { cookieInfo.state = COOKIE_UNUSED; - result = communicationInterface->readReceivedMessage(comCookie, - &receivedData, &receivedDataLen); + ReturnValue_t result = communicationInterface->readReceivedMessage( + comCookie, &receivedData, &receivedDataLen); if (result != RETURN_OK) { triggerEvent(DEVICE_REQUESTING_REPLY_FAILED, result); @@ -608,44 +616,90 @@ void DeviceHandlerBase::doGetRead() { if (mode == MODE_RAW) { replyRawReplyIfnotWiretapped(receivedData, receivedDataLen); - } else { - //The loop may not execute more often than the number of received bytes (worst case). - //This approach avoids infinite loops due to buggy scanForReply routines (seen in bug 1077). - uint32_t remainingLength = receivedDataLen; - for (uint32_t count = 0; count < receivedDataLen; count++) { - result = scanForReply(receivedData, remainingLength, &foundId, - &foundLen); - switch (result) { - case RETURN_OK: - handleReply(receivedData, foundId, foundLen); - break; - case APERIODIC_REPLY: { - result = interpretDeviceReply(foundId, receivedData); - if (result != RETURN_OK) { - replyRawReplyIfnotWiretapped(receivedData, foundLen); - triggerEvent(DEVICE_INTERPRETING_REPLY_FAILED, result, - foundId); - } - } - break; - case IGNORE_REPLY_DATA: - break; - case IGNORE_FULL_PACKET: - return; - default: - //We need to wait for timeout.. don't know what command failed and who sent it. + } + else { + parseReply(receivedData, receivedDataLen); + } +} + +void DeviceHandlerBase::parseReply(const uint8_t* receivedData, + size_t receivedDataLen) { + ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED; + DeviceCommandId_t foundId = 0xFFFFFFFF; + size_t foundLen = 0; + // The loop may not execute more often than the number of received bytes + // (worst case). This approach avoids infinite loops due to buggy + // scanForReply routines. + uint32_t remainingLength = receivedDataLen; + for (uint32_t count = 0; count < receivedDataLen; count++) { + result = scanForReply(receivedData, remainingLength, &foundId, + &foundLen); + switch (result) { + case RETURN_OK: + handleReply(receivedData, foundId, foundLen); + break; + case APERIODIC_REPLY: { + result = interpretDeviceReply(foundId, receivedData); + if (result != RETURN_OK) { replyRawReplyIfnotWiretapped(receivedData, foundLen); - triggerEvent(DEVICE_READING_REPLY_FAILED, result, foundLen); - break; - } - receivedData += foundLen; - if (remainingLength > foundLen) { - remainingLength -= foundLen; - } else { - return; + triggerEvent(DEVICE_INTERPRETING_REPLY_FAILED, result, + foundId); } } + break; + case IGNORE_REPLY_DATA: + break; + case IGNORE_FULL_PACKET: + return; + default: + //We need to wait for timeout.. don't know what command failed and who sent it. + replyRawReplyIfnotWiretapped(receivedData, foundLen); + triggerEvent(DEVICE_READING_REPLY_FAILED, result, foundLen); + break; + } + receivedData += foundLen; + if (remainingLength > foundLen) { + remainingLength -= foundLen; + } else { + return; + } + } +} +void DeviceHandlerBase::handleReply(const uint8_t* receivedData, + DeviceCommandId_t foundId, uint32_t foundLen) { + ReturnValue_t result; + DeviceReplyMap::iterator iter = deviceReplyMap.find(foundId); + + if (iter == deviceReplyMap.end()) { + replyRawReplyIfnotWiretapped(receivedData, foundLen); + triggerEvent(DEVICE_UNKNOWN_REPLY, foundId); + return; + } + + DeviceReplyInfo *info = &(iter->second); + + if (info->delayCycles != 0) { + + if (info->periodic != 0) { + info->delayCycles = info->maxDelayCycles; + } 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 { + // Other completion failure messages are created by timeout. + // Powering down the device might take some time during which periodic + // replies may still come in. + if (mode != _MODE_WAIT_OFF) { + triggerEvent(DEVICE_UNREQUESTED_REPLY, foundId); + } } } @@ -724,42 +778,6 @@ MessageQueueId_t DeviceHandlerBase::getCommandQueue() const { return commandQueue->getId(); } -void DeviceHandlerBase::handleReply(const uint8_t* receivedData, - DeviceCommandId_t foundId, uint32_t foundLen) { - ReturnValue_t result; - DeviceReplyMap::iterator iter = deviceReplyMap.find(foundId); - - if (iter == deviceReplyMap.end()) { - replyRawReplyIfnotWiretapped(receivedData, foundLen); - triggerEvent(DEVICE_UNKNOWN_REPLY, foundId); - return; - } - - DeviceReplyInfo *info = &(iter->second); - - if (info->delayCycles != 0) { - - if (info->periodic != 0) { - info->delayCycles = info->maxDelayCycles; - } 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 { - //Other completion failure messages are created by timeout. - //Powering down the device might take some time during which periodic replies may still come in. - if (mode != _MODE_WAIT_OFF) { - triggerEvent(DEVICE_UNREQUESTED_REPLY, foundId); - } - } -} - //ReturnValue_t DeviceHandlerBase::switchCookieChannel(object_id_t newChannelId) { // DeviceCommunicationIF *newCommunication = objectManager->get< // DeviceCommunicationIF>(newChannelId); @@ -791,6 +809,9 @@ void DeviceHandlerBase::buildRawDeviceCommand(CommandMessage* commandMessage) { } void DeviceHandlerBase::commandSwitch(ReturnValue_t onOff) { + if(powerSwitcher == nullptr) { + return; + } const uint8_t *switches; uint8_t numberOfSwitches = 0; ReturnValue_t result = getSwitches(&switches, &numberOfSwitches); @@ -805,9 +826,7 @@ void DeviceHandlerBase::commandSwitch(ReturnValue_t onOff) { ReturnValue_t DeviceHandlerBase::getSwitches(const uint8_t **switches, uint8_t *numberOfSwitches) { - *switches = &deviceSwitch; - *numberOfSwitches = 1; - return RETURN_OK; + return DeviceHandlerBase::NO_SWITCH; } void DeviceHandlerBase::modeChanged(void) { @@ -843,6 +862,9 @@ uint32_t DeviceHandlerBase::getTransitionDelayMs(Mode_t modeFrom, } ReturnValue_t DeviceHandlerBase::getStateOfSwitches(void) { + if(powerSwitcher == nullptr) { + return NO_SWITCH; + } uint8_t numberOfSwitches = 0; const uint8_t *switches; @@ -1286,4 +1308,24 @@ void DeviceHandlerBase::setTaskIF(PeriodicTaskIF* task_){ void DeviceHandlerBase::debugInterface(uint8_t positionTracker, object_id_t objectId, uint32_t parameter) {} -void DeviceHandlerBase::performOperationHook() {} +void DeviceHandlerBase::performOperationHook() { +} + +ReturnValue_t DeviceHandlerBase::initializeHousekeepingPoolEntries( + LocalDataPoolMap &localDataPoolMap) { + return RETURN_OK; +} + +HousekeepingManager* DeviceHandlerBase::getHkManagerHandle() { + return &hkManager; +} + +DataSetIF* DeviceHandlerBase::getDataSetHandle(sid_t sid) { + auto iter = deviceReplyMap.find(sid.ownerSetId); + if(iter != deviceReplyMap.end()) { + return iter->second.dataSet; + } + else { + return nullptr; + } +} diff --git a/devicehandlers/DeviceHandlerBase.h b/devicehandlers/DeviceHandlerBase.h index 1debcdcb..47cf0284 100644 --- a/devicehandlers/DeviceHandlerBase.h +++ b/devicehandlers/DeviceHandlerBase.h @@ -1,5 +1,5 @@ -#ifndef DEVICEHANDLERBASE_H_ -#define DEVICEHANDLERBASE_H_ +#ifndef DEVICEHANDLERS_DEVICEHANDLERBASE_H_ +#define DEVICEHANDLERS_DEVICEHANDLERBASE_H_ #include #include @@ -11,12 +11,14 @@ #include #include #include +#include #include #include #include #include #include +#include #include @@ -46,14 +48,16 @@ class StorageManagerIF; * If data has been received (GET_READ), the data will be interpreted. * The action for each step can be defined by the child class but as most * device handlers share a 4-call (sendRead-getRead-sendWrite-getWrite) structure, - * a default implementation is provided. NOTE: RMAP is a standard which is used for FLP. + * a default implementation is provided. + * NOTE: RMAP is a standard which is used for FLP. * RMAP communication is not mandatory for projects implementing the FSFW. * However, the communication principles are similar to RMAP as there are * two write and two send calls involved. * - * Device handler instances should extend this class and implement the abstract functions. - * Components and drivers can send so called cookies which are used for communication - * and contain information about the communcation (e.g. slave address for I2C or RMAP structs). + * Device handler instances should extend this class and implement the abstract + * functions. Components and drivers can send so called cookies which are used + * for communication and contain information about the communcation (e.g. slave + * address for I2C or RMAP structs). * The following abstract methods must be implemented by a device handler: * 1. doStartUp() * 2. doShutDown() @@ -82,7 +86,8 @@ class DeviceHandlerBase: public DeviceHandlerIF, public HasModesIF, public HasHealthIF, public HasActionsIF, - public ReceivesParameterMessagesIF { + public ReceivesParameterMessagesIF, + public HasHkPoolParametersIF { friend void (Factory::setStaticFrameworkObjectIds)(); public: /** @@ -150,11 +155,9 @@ public: * @return */ virtual ReturnValue_t initialize(); - - /** - * Destructor. - */ + /** Destructor. */ virtual ~DeviceHandlerBase(); + protected: /** * @brief This is used to let the child class handle the transition from @@ -322,12 +325,11 @@ protected: * - @c RETURN_FAILED when the reply could not be interpreted, * e.g. logical errors or range violations occurred */ - virtual ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) = 0; /** - * @brief fill the #deviceCommandMap + * @brief fill the #DeviceCommandMap and #DeviceReplyMap * called by the initialize() of the base class * @details * This is used to let the base class know which replies are expected. @@ -382,7 +384,7 @@ protected: * - @c RETURN_FAILED else. */ ReturnValue_t insertInCommandAndReplyMap(DeviceCommandId_t deviceCommand, - uint16_t maxDelayCycles, size_t replyLen = 0, uint8_t periodic = 0, + uint16_t maxDelayCycles, size_t replyLen = 0, bool periodic = 0, bool hasDifferentReplyId = false, DeviceCommandId_t replyId = 0); /** @@ -396,7 +398,7 @@ protected: * - @c RETURN_FAILED else. */ ReturnValue_t insertInReplyMap(DeviceCommandId_t deviceCommand, - uint16_t maxDelayCycles, size_t replyLen = 0, uint8_t periodic = 0); + uint16_t maxDelayCycles, size_t replyLen = 0, bool periodic = 0); /** * @brief A simple command to add a command to the commandList. @@ -422,7 +424,7 @@ protected: */ ReturnValue_t updateReplyMapEntry(DeviceCommandId_t deviceReply, uint16_t delayCycles, uint16_t maxDelayCycles, - uint8_t periodic = 0); + bool periodic = 0); /** * @brief Can be implemented by child handler to @@ -471,6 +473,18 @@ protected: virtual ReturnValue_t getSwitches(const uint8_t **switches, uint8_t *numberOfSwitches); + /** + * This function is used to initialize the local housekeeping pool + * entries. The default implementation leaves the pool empty. + * @param localDataPoolMap + * @return + */ + virtual ReturnValue_t initializeHousekeepingPoolEntries( + LocalDataPoolMap& localDataPoolMap) override; + + /** Get the HK manager object handle */ + virtual HousekeepingManager* getHkManagerHandle() override; + /** * @brief Hook function for child handlers which is called once per * performOperation(). Default implementation is empty. @@ -528,114 +542,136 @@ protected: static const DeviceCommandId_t NO_COMMAND_ID = -2; static const MessageQueueId_t NO_COMMANDER = 0; - /** - * Pointer to the raw packet that will be sent. - */ + /** Pointer to the raw packet that will be sent.*/ uint8_t *rawPacket = nullptr; - /** - * Size of the #rawPacket. - */ + /** Size of the #rawPacket. */ uint32_t rawPacketLen = 0; /** * The mode the device handler is currently in. - * * This should never be changed directly but only with setMode() */ Mode_t mode; - /** * The submode the device handler is currently in. - * * This should never be changed directly but only with setMode() */ Submode_t submode; - /** - * This is the counter value from performOperation(). - */ + /** This is the counter value from performOperation(). */ uint8_t pstStep = 0; - /** - * wiretapping flag: + * Wiretapping flag: * - * indicates either that all raw messages to and from the device should be sent to #theOneWhoWantsToReadRawTraffic - * or that all device TM should be downlinked to #theOneWhoWantsToReadRawTraffic + * indicates either that all raw messages to and from the device should be + * sent to #defaultRawReceiver + * or that all device TM should be downlinked to #defaultRawReceiver. */ enum WiretappingMode { OFF = 0, RAW = 1, TM = 2 } wiretappingMode; - /** - * A message queue that accepts raw replies + * @brief A message queue that accepts raw replies * - * Statically initialized in initialize() to a configurable object. Used when there is no method - * of finding a recipient, ie raw mode and reporting erreonous replies + * Statically initialized in initialize() to a configurable object. + * Used when there is no method of finding a recipient, ie raw mode and + * reporting erroneous replies */ MessageQueueId_t defaultRawReceiver = 0; - store_address_t storedRawData; /** - * the message queue which wants to read all raw traffic - * - * if #isWiretappingActive all raw communication from and to the device will be sent to this queue + * @brief The message queue which wants to read all raw traffic + * If #isWiretappingActive all raw communication from and to the device + * will be sent to this queue */ MessageQueueId_t requestedRawTraffic = 0; - /** - * the object used to set power switches - */ - PowerSwitchIF *powerSwitcher = nullptr; - /** * Pointer to the IPCStore. - * * This caches the pointer received from the objectManager in the constructor. */ StorageManagerIF *IPCStore = nullptr; - - /** - * cached for init - */ + /** The comIF object ID is cached for the intialize() function */ object_id_t deviceCommunicationId; - - /** - * Communication object used for device communication - */ + /** Communication object used for device communication */ DeviceCommunicationIF * communicationInterface = nullptr; - - /** - * Cookie used for communication - */ + /** Cookie used for communication */ CookieIF * comCookie; + /** Health helper for HasHealthIF */ + HealthHelper healthHelper; + /** Mode helper for HasModesIF */ + ModeHelper modeHelper; + /** Parameter helper for ReceivesParameterMessagesIF */ + ParameterHelper parameterHelper; + /** Action helper for HasActionsIF */ + ActionHelper actionHelper; + /** Housekeeping Manager */ + HousekeepingManager hkManager; + + /** + * @brief Information about commands + */ struct DeviceCommandInfo { - bool isExecuting; //!< Indicates if the command is already executing. - uint8_t expectedReplies; //!< Dynamic value to indicate how many replies are expected. Inititated with 0. - MessageQueueId_t sendReplyTo; //!< if this is != NO_COMMANDER, DHB was commanded externally and shall report everything to commander. + //! Indicates if the command is already executing. + bool isExecuting; + //! Dynamic value to indicate how many replies are expected. + //! Inititated with 0. + uint8_t expectedReplies; + //! if this is != NO_COMMANDER, DHB was commanded externally and shall + //! report everything to commander. + MessageQueueId_t sendReplyTo; }; using DeviceCommandMap = std::map ; + /** + * Information about commands + */ + DeviceCommandMap deviceCommandMap; /** * @brief Information about expected replies - * - * This is used to keep track of pending replies + * This is used to keep track of pending replies. */ struct DeviceReplyInfo { - uint16_t maxDelayCycles; //!< The maximum number of cycles the handler should wait for a reply to this command. - uint16_t delayCycles; //!< The currently remaining cycles the handler should wait for a reply, 0 means there is no reply expected + //! The maximum number of cycles the handler should wait for a reply + //! to this command. + uint16_t maxDelayCycles; + //! The currently remaining cycles the handler should wait for a reply, + //! 0 means there is no reply expected + uint16_t delayCycles; size_t replyLen = 0; //!< Expected size of the reply. - uint8_t periodic; //!< if this is !=0, the delayCycles will not be reset to 0 but to maxDelayCycles - DeviceCommandMap::iterator command; //!< The command that expects this reply. + //! if this is !=0, the delayCycles will not be reset to 0 but to + //! maxDelayCycles + bool periodic; + //! 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; + //! The command that expects this reply. + DeviceCommandMap::iterator command; }; using DeviceReplyMap = std::map ; using DeviceReplyIter = DeviceReplyMap::iterator; - /** - * The MessageQueue used to receive device handler commands and to send replies. + * This map is used to check and track correct reception of all replies. + * + * It has multiple use: + * - It stores the information on pending replies. If a command is sent, + * the DeviceCommandInfo.count is incremented. + * - It is used to time-out missing replies. If a command is sent, the + * DeviceCommandInfo.DelayCycles is set to MaxDelayCycles. + * - It is queried to check if a reply from the device can be interpreted. + * scanForReply() returns the id of the command a reply was found for. + * The reply is ignored in the following cases: + * - No entry for the returned id was found + * - The deviceReplyInfo.delayCycles is == 0 */ + DeviceReplyMap deviceReplyMap; + + //! The MessageQueue used to receive device handler commands + //! and to send replies. MessageQueueIF* commandQueue = nullptr; /** @@ -652,15 +688,6 @@ protected: */ uint32_t deviceThermalRequestPoolId; - /** - * Taking care of the health - */ - HealthHelper healthHelper; - - ModeHelper modeHelper; - - ParameterHelper parameterHelper; - /** * Optional Error code * Can be set in doStartUp(), doShutDown() and doTransition() to signal cause for Transition failure. @@ -966,24 +993,11 @@ protected: bool commandIsExecuting(DeviceCommandId_t commandId); /** - * This map is used to check and track correct reception of all replies. + * set all switches returned by getSwitches() * - * It has multiple use: - * - it stores the information on pending replies. If a command is sent, the DeviceCommandInfo.count is incremented. - * - it is used to time-out missing replies. If a command is sent, the DeviceCommandInfo.DelayCycles is set to MaxDelayCycles. - * - it is queried to check if a reply from the device can be interpreted. scanForReply() returns the id of the command a reply was found for. - * The reply is ignored in the following cases: - * - No entry for the returned id was found - * - The deviceReplyInfo.delayCycles is == 0 + * @param onOff on == @c SWITCH_ON; off != @c SWITCH_ON */ - DeviceReplyMap deviceReplyMap; - - /** - * Information about commands - */ - DeviceCommandMap deviceCommandMap; - - ActionHelper actionHelper; + void commandSwitch(ReturnValue_t onOff); private: /** @@ -1016,6 +1030,9 @@ private: */ CookieInfo cookieInfo; + /** the object used to set power switches*/ + PowerSwitchIF *powerSwitcher = nullptr; + /** * Used for timing out mode transitions. * @@ -1148,12 +1165,6 @@ private: ReturnValue_t getStorageData(store_address_t storageAddress, uint8_t **data, uint32_t *len); - /** - * set all switches returned by getSwitches() - * - * @param onOff on == @c SWITCH_ON; off != @c SWITCH_ON - */ - void commandSwitch(ReturnValue_t onOff); /** * @param modeTo either @c MODE_ON, MODE_NORMAL or MODE_RAW NOTHING ELSE!!! @@ -1178,6 +1189,10 @@ private: ReturnValue_t switchCookieChannel(object_id_t newChannelId); ReturnValue_t handleDeviceHandlerMessage(CommandMessage *message); + + void parseReply(const uint8_t* receivedData, + size_t receivedDataLen); + DataSetIF* getDataSetHandle(sid_t sid) override; }; #endif /* DEVICEHANDLERBASE_H_ */ diff --git a/devicehandlers/DeviceHandlerFailureIsolation.cpp b/devicehandlers/DeviceHandlerFailureIsolation.cpp index 65c40219..9bc2cbe8 100644 --- a/devicehandlers/DeviceHandlerFailureIsolation.cpp +++ b/devicehandlers/DeviceHandlerFailureIsolation.cpp @@ -7,13 +7,15 @@ object_id_t DeviceHandlerFailureIsolation::powerConfirmationId = 0; -DeviceHandlerFailureIsolation::DeviceHandlerFailureIsolation(object_id_t owner, object_id_t parent) : - FailureIsolationBase(owner, parent), strangeReplyCount(MAX_STRANGE_REPLIES, - STRANGE_REPLIES_TIME_MS, parameterDomainBase++), missedReplyCount( - MAX_MISSED_REPLY_COUNT, MISSED_REPLY_TIME_MS, - parameterDomainBase++), recoveryCounter(MAX_REBOOT, - REBOOT_TIME_MS, parameterDomainBase++), fdirState(NONE), powerConfirmation( - 0) { +DeviceHandlerFailureIsolation::DeviceHandlerFailureIsolation(object_id_t owner, + object_id_t parent) : + FailureIsolationBase(owner, parent), + strangeReplyCount(MAX_STRANGE_REPLIES, STRANGE_REPLIES_TIME_MS, + parameterDomainBase++), + missedReplyCount( MAX_MISSED_REPLY_COUNT, MISSED_REPLY_TIME_MS, + parameterDomainBase++), + recoveryCounter(MAX_REBOOT, REBOOT_TIME_MS, parameterDomainBase++), + fdirState(NONE), powerConfirmation(0) { } DeviceHandlerFailureIsolation::~DeviceHandlerFailureIsolation() { @@ -68,9 +70,11 @@ ReturnValue_t DeviceHandlerFailureIsolation::eventReceived(EventMessage* event) break; //****Power***** case PowerSwitchIF::SWITCH_WENT_OFF: - result = sendConfirmationRequest(event, powerConfirmation); - if (result == RETURN_OK) { - setFdirState(DEVICE_MIGHT_BE_OFF); + if(hasPowerConfirmation) { + result = sendConfirmationRequest(event, powerConfirmation); + if (result == RETURN_OK) { + setFdirState(DEVICE_MIGHT_BE_OFF); + } } break; case Fuse::FUSE_WENT_OFF: @@ -142,7 +146,8 @@ void DeviceHandlerFailureIsolation::handleRecovery(Event reason) { void DeviceHandlerFailureIsolation::wasParentsFault(EventMessage* event) { //We'll better ignore the SWITCH_WENT_OFF event and await a system-wide reset. - //This means, no fault message will come through until a MODE_ or HEALTH_INFO message comes through -> Is that ok? + //This means, no fault message will come through until a MODE_ or + //HEALTH_INFO message comes through -> Is that ok? //Same issue in TxFailureIsolation! // if ((event->getEvent() == PowerSwitchIF::SWITCH_WENT_OFF) // && (fdirState != RECOVERY_ONGOING)) { @@ -162,10 +167,11 @@ ReturnValue_t DeviceHandlerFailureIsolation::initialize() { } ConfirmsFailuresIF* power = objectManager->get( powerConfirmationId); - if (power == NULL) { - return RETURN_FAILED; + if (power != nullptr) { + powerConfirmation = power->getEventReceptionQueue(); + hasPowerConfirmation = true; } - powerConfirmation = power->getEventReceptionQueue(); + return RETURN_OK; } diff --git a/devicehandlers/DeviceHandlerFailureIsolation.h b/devicehandlers/DeviceHandlerFailureIsolation.h index 91f6ef64..379edae3 100644 --- a/devicehandlers/DeviceHandlerFailureIsolation.h +++ b/devicehandlers/DeviceHandlerFailureIsolation.h @@ -28,6 +28,7 @@ protected: NONE, RECOVERY_ONGOING, DEVICE_MIGHT_BE_OFF, AWAIT_SHUTDOWN }; FDIRState fdirState; + bool hasPowerConfirmation = false; MessageQueueId_t powerConfirmation; static object_id_t powerConfirmationId; static const uint32_t MAX_REBOOT = 1; From b4561465ba273718f03b8f32e73eb4d5ffcb7610 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 6 Jun 2020 01:36:07 +0200 Subject: [PATCH 072/307] some little form improvements --- devicehandlers/DeviceHandlerBase.h | 4 ++-- framework.mk | 4 ++-- housekeeping/HasHkPoolParametersIF.h | 1 - housekeeping/HousekeepingMessage.h | 1 + 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/devicehandlers/DeviceHandlerBase.h b/devicehandlers/DeviceHandlerBase.h index 47cf0284..9b2bcdf4 100644 --- a/devicehandlers/DeviceHandlerBase.h +++ b/devicehandlers/DeviceHandlerBase.h @@ -1,5 +1,5 @@ -#ifndef DEVICEHANDLERS_DEVICEHANDLERBASE_H_ -#define DEVICEHANDLERS_DEVICEHANDLERBASE_H_ +#ifndef FRAMEWORK_DEVICEHANDLERS_DEVICEHANDLERBASE_H_ +#define FRAMEWORK_DEVICEHANDLERS_DEVICEHANDLERBASE_H_ #include #include diff --git a/framework.mk b/framework.mk index 404055ee..c8822981 100644 --- a/framework.mk +++ b/framework.mk @@ -1,5 +1,5 @@ -# This file needs FRAMEWORK_PATH and API set correctly -# Valid API settings: rtems, linux, freeRTOS +# This file needs FRAMEWORK_PATH and OS_FSFW set correctly by another Makefile. +# Valid API settings: rtems, linux, freeRTOS, host CXXSRC += $(wildcard $(FRAMEWORK_PATH)/action/*.cpp) CXXSRC += $(wildcard $(FRAMEWORK_PATH)/container/*.cpp) diff --git a/housekeeping/HasHkPoolParametersIF.h b/housekeeping/HasHkPoolParametersIF.h index 62715a3d..9efc6d16 100644 --- a/housekeeping/HasHkPoolParametersIF.h +++ b/housekeeping/HasHkPoolParametersIF.h @@ -40,7 +40,6 @@ public: virtual MessageQueueId_t getCommandQueue() const = 0; virtual ReturnValue_t initializeHousekeepingPoolEntries( LocalDataPoolMap& localDataPoolMap) = 0; - //virtual float setMinimalHkSamplingFrequency() = 0; virtual HousekeepingManager* getHkManagerHandle() = 0; virtual DataSetIF* getDataSetHandle(sid_t sid) = 0; }; diff --git a/housekeeping/HousekeepingMessage.h b/housekeeping/HousekeepingMessage.h index e7ba68ba..61e6e199 100644 --- a/housekeeping/HousekeepingMessage.h +++ b/housekeeping/HousekeepingMessage.h @@ -19,6 +19,7 @@ union sid_t { */ uint64_t raw; }; + class HousekeepingMessage { public: /** From 8e7593d68a8bf7f909cf87f2daea6625c6ef4010 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 6 Jun 2020 02:10:21 +0200 Subject: [PATCH 073/307] removed error handling in separate fnctn --- osal/linux/MessageQueue.cpp | 74 ++++++++++++++++++++----------------- osal/linux/MessageQueue.h | 4 ++ 2 files changed, 45 insertions(+), 33 deletions(-) diff --git a/osal/linux/MessageQueue.cpp b/osal/linux/MessageQueue.cpp index 48ba29e8..d12fa720 100644 --- a/osal/linux/MessageQueue.cpp +++ b/osal/linux/MessageQueue.cpp @@ -1,14 +1,14 @@ #include +#include #include /* For O_* constants */ #include /* For mode constants */ -#include #include #include -#include -MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize): - id(0), lastPartner(0), defaultDestination(NO_QUEUE) { + +MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize): id(0), + lastPartner(0), defaultDestination(NO_QUEUE) { //debug << "MessageQueue::MessageQueue: Creating a queue" << std::endl; mq_attr attributes; this->id = 0; @@ -17,40 +17,17 @@ MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize): attributes.mq_maxmsg = messageDepth; attributes.mq_msgsize = maxMessageSize; attributes.mq_flags = 0; //Flags are ignored on Linux during mq_open - //Set the name of the queue + //Set the name of the queue. The slash is mandatory! sprintf(name, "/Q%u\n", queueCounter++); - //Create a nonblocking queue if the name is available (the queue is Read and - // writable for the owner as well as the group) + // Create a nonblocking queue if the name is available (the queue is read + // and writable for the owner as well as the group) mqd_t tempId = mq_open(name, O_NONBLOCK | O_RDWR | O_CREAT | O_EXCL, S_IWUSR | S_IREAD | S_IWGRP | S_IRGRP | S_IROTH | S_IWOTH, &attributes); if (tempId == -1) { - //An error occured during open - //We need to distinguish if it is caused by an already created queue - if (errno == EEXIST) { - //There's another queue with the same name - //We unlink the other queue - int status = mq_unlink(name); - if (status != 0) { - sif::error << "mq_unlink Failed with status: " << strerror(errno) - << std::endl; - } else { - //Successful unlinking, try to open again - mqd_t tempId = mq_open(name, - O_NONBLOCK | O_RDWR | O_CREAT | O_EXCL, - S_IWUSR | S_IREAD | S_IWGRP | S_IRGRP, &attributes); - if (tempId != -1) { - //Successful mq_open - this->id = tempId; - return; - } - } - } - //Failed either the first time or the second time - sif::error << "MessageQueue::MessageQueue: Creating Queue " << std::hex - << name << std::dec << " failed with status: " - << strerror(errno) << std::endl; - } else { + ReturnValue_t result = handleError(&attributes); + } + else { //Successful mq_open call this->id = tempId; } @@ -69,6 +46,37 @@ MessageQueue::~MessageQueue() { } } +ReturnValue_t MessageQueue::handleError(mq_attr* attributes) { + // An error occured during open + // We need to distinguish if it is caused by an already created queue + if (errno == EEXIST) { + //There's another queue with the same name + //We unlink the other queue + int status = mq_unlink(name); + if (status != 0) { + sif::error << "mq_unlink Failed with status: " << strerror(errno) + << std::endl; + } + else { + // Successful unlinking, try to open again + mqd_t tempId = mq_open(name, + O_NONBLOCK | O_RDWR | O_CREAT | O_EXCL, + S_IWUSR | S_IREAD | S_IWGRP | S_IRGRP, attributes); + if (tempId != -1) { + //Successful mq_open + this->id = tempId; + return HasReturnvaluesIF::RETURN_OK; + } + } + // Failed either the first time or the second time + sif::error << "MessageQueue::MessageQueue: Creating Queue " << std::hex + << name << std::dec << " failed with status: " + << strerror(errno) << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + +} + ReturnValue_t MessageQueue::sendMessage(MessageQueueId_t sendTo, MessageQueueMessage* message, bool ignoreFault) { return sendMessageFrom(sendTo, message, this->getId(), false); diff --git a/osal/linux/MessageQueue.h b/osal/linux/MessageQueue.h index fdc8dab1..b44ed5c7 100644 --- a/osal/linux/MessageQueue.h +++ b/osal/linux/MessageQueue.h @@ -4,6 +4,8 @@ #include #include #include + +#include /** * @brief This class manages sending and receiving of message queue messages. * @@ -172,6 +174,8 @@ private: char name[5]; static uint16_t queueCounter; + + ReturnValue_t handleError(mq_attr* attributes); }; #endif /* MESSAGEQUEUE_H_ */ From d35524ecbcbcd49d8f95e37180c787f606fad493 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 6 Jun 2020 12:41:17 +0200 Subject: [PATCH 074/307] decoupling from raw reciever, linux mq improvements --- devicehandlers/DeviceHandlerBase.cpp | 67 +++++++++++++++++----------- devicehandlers/DeviceHandlerBase.h | 2 +- health/HealthHelper.cpp | 1 + osal/linux/MessageQueue.cpp | 62 +++++++++++++++---------- osal/linux/MessageQueue.h | 2 +- 5 files changed, 82 insertions(+), 52 deletions(-) diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index 1e3bb16e..d738b3f9 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -15,7 +15,7 @@ #include object_id_t DeviceHandlerBase::powerSwitcherId = objects::NO_OBJECT; -object_id_t DeviceHandlerBase::rawDataReceiverId = 0; +object_id_t DeviceHandlerBase::rawDataReceiverId = objects::NO_OBJECT; object_id_t DeviceHandlerBase::defaultFDIRParentId = 0; DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, @@ -36,7 +36,7 @@ DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, childTransitionDelay(5000), transitionSourceMode(_MODE_POWER_DOWN), transitionSourceSubMode( SUBMODE_NONE), deviceSwitch(setDeviceSwitch) { - commandQueue = QueueFactory::instance()->createMessageQueue(cmdQueueSize, + commandQueue = QueueFactory::instance()->createMessageQueue(1, CommandMessage::MAX_MESSAGE_SIZE); cookieInfo.state = COOKIE_UNUSED; insertInCommandMap(RAW_COMMAND_ID); @@ -121,15 +121,16 @@ ReturnValue_t DeviceHandlerBase::initialize() { return RETURN_FAILED; } - AcceptsDeviceResponsesIF *rawReceiver = objectManager->get< - AcceptsDeviceResponsesIF>(rawDataReceiverId); + if(rawDataReceiverId != objects::NO_OBJECT) { + AcceptsDeviceResponsesIF *rawReceiver = objectManager->get< + AcceptsDeviceResponsesIF>(rawDataReceiverId); - if (rawReceiver == NULL) { - return RETURN_FAILED; + if (rawReceiver == NULL) { + return RETURN_FAILED; + } + defaultRawReceiver = rawReceiver->getDeviceQueue(); } - defaultRawReceiver = rawReceiver->getDeviceQueue(); - if(powerSwitcherId != objects::NO_OBJECT) { powerSwitcher = objectManager->get(powerSwitcherId); if (powerSwitcher == NULL) { @@ -139,6 +140,8 @@ ReturnValue_t DeviceHandlerBase::initialize() { result = healthHelper.initialize(); if (result != RETURN_OK) { + sif::error << "DeviceHandlerBase::initialize: Health Helper " + "initialization failure" << std::endl; return result; } @@ -614,7 +617,7 @@ void DeviceHandlerBase::doGetRead() { replyRawData(receivedData, receivedDataLen, requestedRawTraffic); } - if (mode == MODE_RAW) { + if (mode == MODE_RAW and defaultRawReceiver != MessageQueueIF::NO_QUEUE) { replyRawReplyIfnotWiretapped(receivedData, receivedDataLen); } else { @@ -727,7 +730,7 @@ ReturnValue_t DeviceHandlerBase::getStorageData(store_address_t storageAddress, void DeviceHandlerBase::replyRawData(const uint8_t *data, size_t len, MessageQueueId_t sendTo, bool isCommand) { - if (IPCStore == NULL || len == 0) { + if (IPCStore == NULL || len == 0 || sendTo == MessageQueueIF::NO_QUEUE) { return; } store_address_t address; @@ -1131,35 +1134,47 @@ void DeviceHandlerBase::handleDeviceTM(SerializeIF* data, return; } DeviceTmReportingWrapper wrapper(getObjectId(), replyId, data); - if (iter->second.command != deviceCommandMap.end()) {//replies to a command + //replies to a command + if (iter->second.command != deviceCommandMap.end()) + { MessageQueueId_t queueId = iter->second.command->second.sendReplyTo; if (queueId != NO_COMMANDER) { //This may fail, but we'll ignore the fault. actionHelper.reportData(queueId, replyId, data); } + //This check should make sure we get any TM but don't get anything doubled. if (wiretappingMode == TM && (requestedRawTraffic != queueId)) { actionHelper.reportData(requestedRawTraffic, replyId, &wrapper); - } else if (forceDirectTm && (defaultRawReceiver != queueId)) { - - // hiding of sender needed so the service will handle it as unexpected Data, no matter what state - //(progress or completed) it is in - actionHelper.reportData(defaultRawReceiver, replyId, &wrapper, - true); - } - } else { //unrequested/aperiodic replies - if (wiretappingMode == TM) { - actionHelper.reportData(requestedRawTraffic, replyId, &wrapper); - } else if (forceDirectTm) { - // hiding of sender needed so the service will handle it as unexpected Data, no matter what state - //(progress or completed) it is in + else if (forceDirectTm and (defaultRawReceiver != queueId) and + (defaultRawReceiver != MessageQueueIF::NO_QUEUE)) + { + // hiding of sender needed so the service will handle it as + // unexpected Data, no matter what state (progress or completed) + // it is in actionHelper.reportData(defaultRawReceiver, replyId, &wrapper, - true); + true); } } -//Try to cast to GlobDataSet and commit data. + //unrequested/aperiodic replies + else + { + if (wiretappingMode == TM) { + actionHelper.reportData(requestedRawTraffic, replyId, &wrapper); + } + else if (forceDirectTm and defaultRawReceiver != + MessageQueueIF::NO_QUEUE) + { + // hiding of sender needed so the service will handle it as + // unexpected Data, no matter what state (progress or completed) + // it is in + actionHelper.reportData(defaultRawReceiver, replyId, &wrapper, + true); + } + } + //Try to cast to GlobDataSet and commit data. if (!neverInDataPool) { GlobDataSet* dataSet = dynamic_cast(data); if (dataSet != NULL) { diff --git a/devicehandlers/DeviceHandlerBase.h b/devicehandlers/DeviceHandlerBase.h index 9b2bcdf4..3a43fa74 100644 --- a/devicehandlers/DeviceHandlerBase.h +++ b/devicehandlers/DeviceHandlerBase.h @@ -577,7 +577,7 @@ protected: * Used when there is no method of finding a recipient, ie raw mode and * reporting erroneous replies */ - MessageQueueId_t defaultRawReceiver = 0; + MessageQueueId_t defaultRawReceiver = MessageQueueIF::NO_QUEUE; store_address_t storedRawData; /** diff --git a/health/HealthHelper.cpp b/health/HealthHelper.cpp index b7d54dc1..3a345287 100644 --- a/health/HealthHelper.cpp +++ b/health/HealthHelper.cpp @@ -40,6 +40,7 @@ void HealthHelper::setParentQeueue(MessageQueueId_t parentQueue) { ReturnValue_t HealthHelper::initialize() { healthTable = objectManager->get(objects::HEALTH_TABLE); eventSender = objectManager->get(objectId); + // TODO: Better returnvalues if ((healthTable == NULL) || eventSender == NULL) { return HasReturnvaluesIF::RETURN_FAILED; } diff --git a/osal/linux/MessageQueue.cpp b/osal/linux/MessageQueue.cpp index d12fa720..08a9ab20 100644 --- a/osal/linux/MessageQueue.cpp +++ b/osal/linux/MessageQueue.cpp @@ -7,7 +7,7 @@ -MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize): id(0), +MessageQueue::MessageQueue(uint32_t messageDepth, size_t maxMessageSize): id(0), lastPartner(0), defaultDestination(NO_QUEUE) { //debug << "MessageQueue::MessageQueue: Creating a queue" << std::endl; mq_attr attributes; @@ -25,7 +25,7 @@ MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize): id(0), mqd_t tempId = mq_open(name, O_NONBLOCK | O_RDWR | O_CREAT | O_EXCL, S_IWUSR | S_IREAD | S_IWGRP | S_IRGRP | S_IROTH | S_IWOTH, &attributes); if (tempId == -1) { - ReturnValue_t result = handleError(&attributes); + handleError(&attributes); } else { //Successful mq_open call @@ -47,33 +47,47 @@ MessageQueue::~MessageQueue() { } ReturnValue_t MessageQueue::handleError(mq_attr* attributes) { - // An error occured during open - // We need to distinguish if it is caused by an already created queue - if (errno == EEXIST) { - //There's another queue with the same name - //We unlink the other queue - int status = mq_unlink(name); - if (status != 0) { - sif::error << "mq_unlink Failed with status: " << strerror(errno) - << std::endl; - } - else { - // Successful unlinking, try to open again - mqd_t tempId = mq_open(name, - O_NONBLOCK | O_RDWR | O_CREAT | O_EXCL, - S_IWUSR | S_IREAD | S_IWGRP | S_IRGRP, attributes); - if (tempId != -1) { - //Successful mq_open - this->id = tempId; - return HasReturnvaluesIF::RETURN_OK; + switch(errno) { + case(EINVAL): { + sif::error << "MessageQueue::MessageQueue: Invalid Name " << std::endl; + break; + } + case(EEXIST): { + // An error occured during open + // We need to distinguish if it is caused by an already created queue + if (errno == EEXIST) { + //There's another queue with the same name + //We unlink the other queue + int status = mq_unlink(name); + if (status != 0) { + sif::error << "mq_unlink Failed with status: " << strerror(errno) + << std::endl; + } + else { + // Successful unlinking, try to open again + mqd_t tempId = mq_open(name, + O_NONBLOCK | O_RDWR | O_CREAT | O_EXCL, + S_IWUSR | S_IREAD | S_IWGRP | S_IRGRP, attributes); + if (tempId != -1) { + //Successful mq_open + this->id = tempId; + return HasReturnvaluesIF::RETURN_OK; + } } } + break; + } + + default: // Failed either the first time or the second time sif::error << "MessageQueue::MessageQueue: Creating Queue " << std::hex - << name << std::dec << " failed with status: " - << strerror(errno) << std::endl; - return HasReturnvaluesIF::RETURN_FAILED; + << name << std::dec << " failed with status: " + << strerror(errno) << std::endl; + } + return HasReturnvaluesIF::RETURN_FAILED; + + } diff --git a/osal/linux/MessageQueue.h b/osal/linux/MessageQueue.h index b44ed5c7..debf9cd1 100644 --- a/osal/linux/MessageQueue.h +++ b/osal/linux/MessageQueue.h @@ -40,7 +40,7 @@ public: * @param max_message_size With this parameter, the maximum message size can be adjusted. * This should be left default. */ - MessageQueue(size_t messageDepth = 3, + MessageQueue(uint32_t messageDepth = 3, size_t maxMessageSize = MessageQueueMessage::MAX_MESSAGE_SIZE ); /** * @brief The destructor deletes the formerly created message queue. From 5289497ab5769fc61ba1816322c4f86377cfd36f Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 6 Jun 2020 12:59:43 +0200 Subject: [PATCH 075/307] health helper optional, diagnostic output improved --- devicehandlers/DeviceHandlerBase.cpp | 39 ++++++++++++++----- devicehandlers/DeviceHandlerBase.h | 1 + .../DeviceHandlerFailureIsolation.cpp | 2 + fdir/FailureIsolationBase.cpp | 4 +- objectmanager/ObjectManager.cpp | 7 ++-- 5 files changed, 39 insertions(+), 14 deletions(-) diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index d738b3f9..c73cf618 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -139,10 +139,12 @@ ReturnValue_t DeviceHandlerBase::initialize() { } result = healthHelper.initialize(); - if (result != RETURN_OK) { - sif::error << "DeviceHandlerBase::initialize: Health Helper " - "initialization failure" << std::endl; - return result; + if (result == RETURN_OK) { + healthHelperActive = true; + } + else { + sif::warning << "DeviceHandlerBase::initialize: Health Helper " + "initialization failure." << std::endl; } result = modeHelper.initialize(); @@ -215,9 +217,11 @@ void DeviceHandlerBase::readCommandQueue() { return; } - result = healthHelper.handleHealthCommand(&message); - if (result == RETURN_OK) { - return; + if(healthHelperActive) { + result = healthHelper.handleHealthCommand(&message); + if (result == RETURN_OK) { + return; + } } result = modeHelper.handleModeCommand(&message); @@ -996,7 +1000,9 @@ void DeviceHandlerBase::getMode(Mode_t* mode, Submode_t* submode) { } void DeviceHandlerBase::setToExternalControl() { - healthHelper.setHealth(EXTERNAL_CONTROL); + if(healthHelperActive) { + healthHelper.setHealth(EXTERNAL_CONTROL); + } } void DeviceHandlerBase::announceMode(bool recursive) { @@ -1016,11 +1022,24 @@ void DeviceHandlerBase::missedReply(DeviceCommandId_t id) { } HasHealthIF::HealthState DeviceHandlerBase::getHealth() { - return healthHelper.getHealth(); + if(healthHelperActive) { + return healthHelper.getHealth(); + } + else { + sif::warning << "DeviceHandlerBase::getHealth: Health helper not active" + << std::endl; + return HasHealthIF::HEALTHY; + } } ReturnValue_t DeviceHandlerBase::setHealth(HealthState health) { - healthHelper.setHealth(health); + if(healthHelperActive) { + healthHelper.setHealth(health); + } + else { + sif::warning << "DeviceHandlerBase::getHealth: Health helper not active" + << std::endl; + } return HasReturnvaluesIF::RETURN_OK; } diff --git a/devicehandlers/DeviceHandlerBase.h b/devicehandlers/DeviceHandlerBase.h index 3a43fa74..b079e469 100644 --- a/devicehandlers/DeviceHandlerBase.h +++ b/devicehandlers/DeviceHandlerBase.h @@ -601,6 +601,7 @@ protected: /** Health helper for HasHealthIF */ HealthHelper healthHelper; + bool healthHelperActive = false; /** Mode helper for HasModesIF */ ModeHelper modeHelper; /** Parameter helper for ReceivesParameterMessagesIF */ diff --git a/devicehandlers/DeviceHandlerFailureIsolation.cpp b/devicehandlers/DeviceHandlerFailureIsolation.cpp index 9bc2cbe8..1df2afa0 100644 --- a/devicehandlers/DeviceHandlerFailureIsolation.cpp +++ b/devicehandlers/DeviceHandlerFailureIsolation.cpp @@ -163,6 +163,8 @@ void DeviceHandlerFailureIsolation::clearFaultCounters() { ReturnValue_t DeviceHandlerFailureIsolation::initialize() { ReturnValue_t result = FailureIsolationBase::initialize(); if (result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "DeviceHandlerFailureIsolation::initialize: Could not" + " initialize FailureIsolationBase." << std::endl; return result; } ConfirmsFailuresIF* power = objectManager->get( diff --git a/fdir/FailureIsolationBase.cpp b/fdir/FailureIsolationBase.cpp index c65640c2..46114467 100644 --- a/fdir/FailureIsolationBase.cpp +++ b/fdir/FailureIsolationBase.cpp @@ -19,7 +19,9 @@ FailureIsolationBase::~FailureIsolationBase() { ReturnValue_t FailureIsolationBase::initialize() { EventManagerIF* manager = objectManager->get( objects::EVENT_MANAGER); - if (manager == NULL) { + if (manager == nullptr) { + sif::error << "FailureIsolationBase::initialize: Event Manager has not" + " been initialized!" << std::endl; return RETURN_FAILED; } ReturnValue_t result = manager->registerListener(eventQueue->getId()); diff --git a/objectmanager/ObjectManager.cpp b/objectmanager/ObjectManager.cpp index 2f47950f..fe7adb25 100644 --- a/objectmanager/ObjectManager.cpp +++ b/objectmanager/ObjectManager.cpp @@ -69,9 +69,10 @@ void ObjectManager::initialize() { return_value = it.second->initialize(); if ( return_value != RETURN_OK ) { object_id_t var = it.first; - sif::error << "Object 0x" << std::hex << std::setw(8) << - std::setfill('0')<< var << " failed to initialize " << - "with code 0x" << return_value << std::dec << std::endl; + sif::error << "ObjectManager::initialize: Object 0x" << std::hex << + std::setw(8) << std::setfill('0')<< var << " failed to " + "initialize with code 0x" << return_value << std::dec << + std::endl; error_count++; } } From 04236859daecfcde5ed24829623d0a5dbf5da070 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 6 Jun 2020 13:03:37 +0200 Subject: [PATCH 076/307] slight improvements to diagnostic ouput --- objectmanager/ObjectManager.cpp | 41 ++++++++++++++++----------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/objectmanager/ObjectManager.cpp b/objectmanager/ObjectManager.cpp index fe7adb25..606cd369 100644 --- a/objectmanager/ObjectManager.cpp +++ b/objectmanager/ObjectManager.cpp @@ -58,44 +58,43 @@ ObjectManager::ObjectManager() : produceObjects(nullptr) { void ObjectManager::initialize() { if(produceObjects == nullptr) { - sif::error << "ObjectManager: Passed produceObjects functions is" - "nullptr!" << std::endl; + sif::error << "ObjectManager::initialize: Passed produceObjects " + "functions is nullptr!" << std::endl; return; } this->produceObjects(); - ReturnValue_t return_value = RETURN_FAILED; - uint32_t error_count = 0; + ReturnValue_t result = RETURN_FAILED; + uint32_t errorCount = 0; for (auto const& it : objectList) { - return_value = it.second->initialize(); - if ( return_value != RETURN_OK ) { + result = it.second->initialize(); + if ( result != RETURN_OK ) { object_id_t var = it.first; sif::error << "ObjectManager::initialize: Object 0x" << std::hex << std::setw(8) << std::setfill('0')<< var << " failed to " - "initialize with code 0x" << return_value << std::dec << - std::endl; - error_count++; + "initialize with code 0x" << result << std::dec << + std::setfill(' ') << std::endl; + errorCount++; } } - if (error_count > 0) { - sif::error << "ObjectManager::ObjectManager: Counted " << error_count + if (errorCount > 0) { + sif::error << "ObjectManager::ObjectManager: Counted " << errorCount << " failed initializations." << std::endl; } //Init was successful. Now check successful interconnections. - error_count = 0; + errorCount = 0; for (auto const& it : objectList) { - return_value = it.second->checkObjectConnections(); - if ( return_value != RETURN_OK ) { - sif::error << "Object " << std::hex << (int) it.first - << " connection check failed with code 0x" << return_value - << std::dec << std::endl; - error_count++; + result = it.second->checkObjectConnections(); + if ( result != RETURN_OK ) { + sif::error << "ObjectManager::ObjectManager: Object " << std::hex << + (int) it.first << " connection check failed with code 0x" + << result << std::dec << std::endl; + errorCount++; } } - if (error_count > 0) { - sif::error << "ObjectManager::ObjectManager: Counted " << error_count + if (errorCount > 0) { + sif::error << "ObjectManager::ObjectManager: Counted " << errorCount << " failed connection checks." << std::endl; } - } void ObjectManager::printList() { From d387daa9d669a4a17f02b6e203241070c827c00b Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 6 Jun 2020 13:04:29 +0200 Subject: [PATCH 077/307] slight improvements for diagnositc output --- objectmanager/ObjectManager.cpp | 45 ++++++++++++++++----------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/objectmanager/ObjectManager.cpp b/objectmanager/ObjectManager.cpp index 55f7d964..606cd369 100644 --- a/objectmanager/ObjectManager.cpp +++ b/objectmanager/ObjectManager.cpp @@ -58,44 +58,43 @@ ObjectManager::ObjectManager() : produceObjects(nullptr) { void ObjectManager::initialize() { if(produceObjects == nullptr) { - sif::error << "ObjectManager: Passed produceObjects functions is" - "nullptr!" << std::endl; + sif::error << "ObjectManager::initialize: Passed produceObjects " + "functions is nullptr!" << std::endl; return; } this->produceObjects(); - ReturnValue_t return_value = RETURN_FAILED; - uint32_t error_count = 0; + ReturnValue_t result = RETURN_FAILED; + uint32_t errorCount = 0; for (auto const& it : objectList) { - return_value = it.second->initialize(); - if ( return_value != RETURN_OK ) { + result = it.second->initialize(); + if ( result != RETURN_OK ) { object_id_t var = it.first; - sif::error << "Object 0x" << std::hex << std::setw(8) << - std::setfill('0') << var << " failed to initialize " << - "with code 0x" << return_value << std::dec << - std::setfill('') << std::endl; - error_count++; + sif::error << "ObjectManager::initialize: Object 0x" << std::hex << + std::setw(8) << std::setfill('0')<< var << " failed to " + "initialize with code 0x" << result << std::dec << + std::setfill(' ') << std::endl; + errorCount++; } } - if (error_count > 0) { - sif::error << "ObjectManager::ObjectManager: Counted " << error_count + if (errorCount > 0) { + sif::error << "ObjectManager::ObjectManager: Counted " << errorCount << " failed initializations." << std::endl; } //Init was successful. Now check successful interconnections. - error_count = 0; + errorCount = 0; for (auto const& it : objectList) { - return_value = it.second->checkObjectConnections(); - if ( return_value != RETURN_OK ) { - sif::error << "Object " << std::hex << (int) it.first - << " connection check failed with code 0x" << return_value - << std::dec << std::endl; - error_count++; + result = it.second->checkObjectConnections(); + if ( result != RETURN_OK ) { + sif::error << "ObjectManager::ObjectManager: Object " << std::hex << + (int) it.first << " connection check failed with code 0x" + << result << std::dec << std::endl; + errorCount++; } } - if (error_count > 0) { - sif::error << "ObjectManager::ObjectManager: Counted " << error_count + if (errorCount > 0) { + sif::error << "ObjectManager::ObjectManager: Counted " << errorCount << " failed connection checks." << std::endl; } - } void ObjectManager::printList() { From 95bc5a871b6a3e823cc6ed1c7564e3540456fda0 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 6 Jun 2020 13:56:35 +0200 Subject: [PATCH 078/307] improved diagnostic messages for linux --- devicehandlers/DeviceHandlerBase.cpp | 2 +- osal/linux/MessageQueue.cpp | 32 ++++++++++++++++++++++------ osal/linux/MessageQueue.h | 2 +- osal/linux/PosixThread.cpp | 2 +- 4 files changed, 29 insertions(+), 9 deletions(-) diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index c73cf618..965959af 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -36,7 +36,7 @@ DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, childTransitionDelay(5000), transitionSourceMode(_MODE_POWER_DOWN), transitionSourceSubMode( SUBMODE_NONE), deviceSwitch(setDeviceSwitch) { - commandQueue = QueueFactory::instance()->createMessageQueue(1, + commandQueue = QueueFactory::instance()->createMessageQueue(cmdQueueSize, CommandMessage::MAX_MESSAGE_SIZE); cookieInfo.state = COOKIE_UNUSED; insertInCommandMap(RAW_COMMAND_ID); diff --git a/osal/linux/MessageQueue.cpp b/osal/linux/MessageQueue.cpp index 08a9ab20..493c2aca 100644 --- a/osal/linux/MessageQueue.cpp +++ b/osal/linux/MessageQueue.cpp @@ -1,12 +1,14 @@ #include #include + +#include + #include /* For O_* constants */ #include /* For mode constants */ #include #include - MessageQueue::MessageQueue(uint32_t messageDepth, size_t maxMessageSize): id(0), lastPartner(0), defaultDestination(NO_QUEUE) { //debug << "MessageQueue::MessageQueue: Creating a queue" << std::endl; @@ -22,10 +24,11 @@ MessageQueue::MessageQueue(uint32_t messageDepth, size_t maxMessageSize): id(0), // Create a nonblocking queue if the name is available (the queue is read // and writable for the owner as well as the group) - mqd_t tempId = mq_open(name, O_NONBLOCK | O_RDWR | O_CREAT | O_EXCL, - S_IWUSR | S_IREAD | S_IWGRP | S_IRGRP | S_IROTH | S_IWOTH, &attributes); + int oflag = O_NONBLOCK | O_RDWR | O_CREAT | O_EXCL; + mode_t mode = S_IWUSR | S_IREAD | S_IWGRP | S_IRGRP | S_IROTH | S_IWOTH; + mqd_t tempId = mq_open(name, oflag, mode, &attributes); if (tempId == -1) { - handleError(&attributes); + handleError(&attributes, messageDepth); } else { //Successful mq_open call @@ -46,10 +49,27 @@ MessageQueue::~MessageQueue() { } } -ReturnValue_t MessageQueue::handleError(mq_attr* attributes) { +ReturnValue_t MessageQueue::handleError(mq_attr* attributes, + uint32_t messageDepth) { switch(errno) { case(EINVAL): { - sif::error << "MessageQueue::MessageQueue: Invalid Name " << std::endl; + sif::error << "MessageQueue::MessageQueue: Invalid Name or attributes" + " for message size" << std::endl; + size_t defaultMqMaxMsg; + if(std::ifstream("/proc/sys/fs/mqueue/msg_max",std::ios::in) >> + defaultMqMaxMsg and defaultMqMaxMsg < messageDepth) { + // See: https://www.man7.org/linux/man-pages/man3/mq_open.3.html + // This happens if the msg_max value is not large enough + // It is ignored if the executable is run in privileged mode. + // Run the unlockRealtime script or grant the mode manully by using: + // sudo setcap 'CAP_SYS_RESOURCE=+ep' + + // Permanent solution: + // echo msg_max | sudo tee /proc/sys/fs/mqueue/msg_max + sif::error << "MessageQueue::MessageQueue: Default MQ size " + << defaultMqMaxMsg << " is too small for requested size " + << messageDepth << std::endl; + } break; } case(EEXIST): { diff --git a/osal/linux/MessageQueue.h b/osal/linux/MessageQueue.h index debf9cd1..2808d36e 100644 --- a/osal/linux/MessageQueue.h +++ b/osal/linux/MessageQueue.h @@ -175,7 +175,7 @@ private: static uint16_t queueCounter; - ReturnValue_t handleError(mq_attr* attributes); + ReturnValue_t handleError(mq_attr* attributes, uint32_t messageDepth); }; #endif /* MESSAGEQUEUE_H_ */ diff --git a/osal/linux/PosixThread.cpp b/osal/linux/PosixThread.cpp index 899700f0..e8d624ca 100644 --- a/osal/linux/PosixThread.cpp +++ b/osal/linux/PosixThread.cpp @@ -138,7 +138,7 @@ void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) { void* sp; status = posix_memalign(&sp, sysconf(_SC_PAGESIZE), stackSize); if(status != 0){ - sif::error << "Posix Thread stack init failed with: " << + sif::error << "PosixThread::createTask: Stack init failed with: " << strerror(status) << std::endl; } From 788f7a37459dbd445253c4876da62d0a2298c2d6 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 6 Jun 2020 13:59:00 +0200 Subject: [PATCH 079/307] better name for mq --- osal/linux/MessageQueue.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osal/linux/MessageQueue.cpp b/osal/linux/MessageQueue.cpp index 493c2aca..2456a329 100644 --- a/osal/linux/MessageQueue.cpp +++ b/osal/linux/MessageQueue.cpp @@ -20,7 +20,7 @@ MessageQueue::MessageQueue(uint32_t messageDepth, size_t maxMessageSize): id(0), attributes.mq_msgsize = maxMessageSize; attributes.mq_flags = 0; //Flags are ignored on Linux during mq_open //Set the name of the queue. The slash is mandatory! - sprintf(name, "/Q%u\n", queueCounter++); + sprintf(name, "/FSFW_MQ%u\n", queueCounter++); // Create a nonblocking queue if the name is available (the queue is read // and writable for the owner as well as the group) @@ -53,9 +53,9 @@ ReturnValue_t MessageQueue::handleError(mq_attr* attributes, uint32_t messageDepth) { switch(errno) { case(EINVAL): { - sif::error << "MessageQueue::MessageQueue: Invalid Name or attributes" + sif::error << "MessageQueue::MessageQueue: Invalid name or attributes" " for message size" << std::endl; - size_t defaultMqMaxMsg; + size_t defaultMqMaxMsg = 0; if(std::ifstream("/proc/sys/fs/mqueue/msg_max",std::ios::in) >> defaultMqMaxMsg and defaultMqMaxMsg < messageDepth) { // See: https://www.man7.org/linux/man-pages/man3/mq_open.3.html From 1965a0e33b76e2bf317db48dee3b3592552403ff Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 6 Jun 2020 15:47:33 +0200 Subject: [PATCH 080/307] linux important bugfix and general improvements --- ipc/QueueFactory.h | 4 +- osal/FreeRTOS/QueueFactory.cpp | 4 +- osal/linux/FixedTimeslotTask.cpp | 7 +- osal/linux/FixedTimeslotTask.h | 37 ++++++--- osal/linux/MessageQueue.cpp | 130 +++++++++++++++++++++---------- osal/linux/MessageQueue.h | 36 +++++---- osal/linux/PeriodicPosixTask.cpp | 16 ++-- osal/linux/PeriodicPosixTask.h | 13 ++++ osal/linux/PosixThread.cpp | 43 +++++++--- osal/linux/PosixThread.h | 32 ++++---- osal/linux/QueueFactory.cpp | 16 ++-- osal/linux/TaskFactory.cpp | 16 +++- osal/rtems/QueueFactory.cpp | 6 +- 13 files changed, 239 insertions(+), 121 deletions(-) diff --git a/ipc/QueueFactory.h b/ipc/QueueFactory.h index c385b15d..6e7c4a26 100644 --- a/ipc/QueueFactory.h +++ b/ipc/QueueFactory.h @@ -18,8 +18,8 @@ public: */ static QueueFactory* instance(); - MessageQueueIF* createMessageQueue(uint32_t message_depth = 3, - uint32_t max_message_size = MessageQueueMessage::MAX_MESSAGE_SIZE); + MessageQueueIF* createMessageQueue(uint32_t messageDepth = 3, + size_t maxMessageSize = MessageQueueMessage::MAX_MESSAGE_SIZE); void deleteMessageQueue(MessageQueueIF* queue); private: diff --git a/osal/FreeRTOS/QueueFactory.cpp b/osal/FreeRTOS/QueueFactory.cpp index eaf245d3..a0128918 100644 --- a/osal/FreeRTOS/QueueFactory.cpp +++ b/osal/FreeRTOS/QueueFactory.cpp @@ -25,8 +25,8 @@ QueueFactory::~QueueFactory() { } MessageQueueIF* QueueFactory::createMessageQueue(uint32_t message_depth, - uint32_t max_message_size) { - return new MessageQueue(message_depth, max_message_size); + size_t maxMessageSize) { + return new MessageQueue(message_depth, maxMessageSize); } void QueueFactory::deleteMessageQueue(MessageQueueIF* queue) { diff --git a/osal/linux/FixedTimeslotTask.cpp b/osal/linux/FixedTimeslotTask.cpp index 098753a7..e5c68f9d 100644 --- a/osal/linux/FixedTimeslotTask.cpp +++ b/osal/linux/FixedTimeslotTask.cpp @@ -1,10 +1,7 @@ #include -#include -#include -#include -#include #include +#include uint32_t FixedTimeslotTask::deadlineMissedCount = 0; const size_t PeriodicTaskIF::MINIMUM_STACK_SIZE = PTHREAD_STACK_MIN; @@ -23,7 +20,7 @@ void* FixedTimeslotTask::taskEntryPoint(void* arg) { FixedTimeslotTask *originalTask(reinterpret_cast(arg)); //The task's functionality is called. originalTask->taskFunctionality(); - return NULL; + return nullptr; } ReturnValue_t FixedTimeslotTask::startTask() { diff --git a/osal/linux/FixedTimeslotTask.h b/osal/linux/FixedTimeslotTask.h index 6350f347..916e6d6c 100644 --- a/osal/linux/FixedTimeslotTask.h +++ b/osal/linux/FixedTimeslotTask.h @@ -8,7 +8,20 @@ class FixedTimeslotTask: public FixedTimeslotTaskIF, public PosixThread { public: - FixedTimeslotTask(const char* name_, int priority_, size_t stackSize_, uint32_t periodMs_); + /** + * Create a generic periodic task. + * @param name_ + * Name, maximum allowed size of linux is 16 chars, everything else will + * be truncated. + * @param priority_ + * Real-time priority, ranges from 1 to 99 for Linux. + * See: https://man7.org/linux/man-pages/man7/sched.7.html + * @param stackSize_ + * @param period_ + * @param deadlineMissedFunc_ + */ + FixedTimeslotTask(const char* name_, int priority_, size_t stackSize_, + uint32_t periodMs_); virtual ~FixedTimeslotTask(); virtual ReturnValue_t startTask(); @@ -17,7 +30,9 @@ public: virtual uint32_t getPeriodMs() const; - virtual ReturnValue_t addSlot(object_id_t componentId, uint32_t slotTimeMs, int8_t executionStep); + virtual ReturnValue_t addSlot(object_id_t componentId, uint32_t slotTimeMs, + int8_t executionStep); + virtual ReturnValue_t checkSequence() const; /** @@ -34,11 +49,10 @@ public: protected: /** * @brief This function holds the main functionality of the thread. - * - * - * @details Holding the main functionality of the task, this method is most important. - * It links the functionalities provided by FixedSlotSequence with the OS's System Calls - * to keep the timing of the periods. + * @details + * Holding the main functionality of the task, this method is most important. + * It links the functionalities provided by FixedSlotSequence with the + * OS's System Calls to keep the timing of the periods. */ virtual void taskFunctionality(); @@ -46,8 +60,13 @@ private: /** * @brief This is the entry point in a new thread. * - * @details This method, that is the entry point in the new thread and calls taskFunctionality of the child class. - * Needs a valid pointer to the derived class. + * @details + * This method, that is the entry point in the new thread and calls + * taskFunctionality of the child class. Needs a valid pointer to the + * derived class. + * + * The void* returnvalue is not used yet but could be used to return + * arbitrary data. */ static void* taskEntryPoint(void* arg); FixedSlotSequence pst; diff --git a/osal/linux/MessageQueue.cpp b/osal/linux/MessageQueue.cpp index edabe946..86d1e0d9 100644 --- a/osal/linux/MessageQueue.cpp +++ b/osal/linux/MessageQueue.cpp @@ -1,56 +1,36 @@ #include -#include /* For O_* constants */ -#include /* For mode constants */ -#include -#include -#include #include +#include -MessageQueue::MessageQueue(size_t message_depth, size_t max_message_size) : - id(0), lastPartner(0), defaultDestination(NO_QUEUE) { +#include /* For O_* constants */ +#include /* For mode constants */ +#include +#include + + +MessageQueue::MessageQueue(uint32_t messageDepth, size_t maxMessageSize): id(0), + lastPartner(0), defaultDestination(NO_QUEUE) { //debug << "MessageQueue::MessageQueue: Creating a queue" << std::endl; mq_attr attributes; this->id = 0; //Set attributes attributes.mq_curmsgs = 0; - attributes.mq_maxmsg = message_depth; - attributes.mq_msgsize = max_message_size; + attributes.mq_maxmsg = messageDepth; + attributes.mq_msgsize = maxMessageSize; attributes.mq_flags = 0; //Flags are ignored on Linux during mq_open - //Set the name of the queue - sprintf(name, "/Q%u\n", queueCounter++); + //Set the name of the queue. The slash is mandatory! + sprintf(name, "/FSFW_MQ%u\n", queueCounter++); - //Create a nonblocking queue if the name is available (the queue is Read and - // writable for the owner as well as the group) - mqd_t tempId = mq_open(name, O_NONBLOCK | O_RDWR | O_CREAT | O_EXCL, - S_IWUSR | S_IREAD | S_IWGRP | S_IRGRP | S_IROTH | S_IWOTH, &attributes); + // Create a nonblocking queue if the name is available (the queue is read + // and writable for the owner as well as the group) + int oflag = O_NONBLOCK | O_RDWR | O_CREAT | O_EXCL; + mode_t mode = S_IWUSR | S_IREAD | S_IWGRP | S_IRGRP | S_IROTH | S_IWOTH; + mqd_t tempId = mq_open(name, oflag, mode, &attributes); if (tempId == -1) { - //An error occured during open - //We need to distinguish if it is caused by an already created queue - if (errno == EEXIST) { - //There's another queue with the same name - //We unlink the other queue - int status = mq_unlink(name); - if (status != 0) { - sif::error << "mq_unlink Failed with status: " << strerror(errno) - << std::endl; - } else { - //Successful unlinking, try to open again - mqd_t tempId = mq_open(name, - O_NONBLOCK | O_RDWR | O_CREAT | O_EXCL, - S_IWUSR | S_IREAD | S_IWGRP | S_IRGRP, &attributes); - if (tempId != -1) { - //Successful mq_open - this->id = tempId; - return; - } - } - } - //Failed either the first time or the second time - sif::error << "MessageQueue::MessageQueue: Creating Queue " << std::hex - << name << std::dec << " failed with status: " - << strerror(errno) << std::endl; - } else { + handleError(&attributes, messageDepth); + } + else { //Successful mq_open call this->id = tempId; } @@ -69,6 +49,68 @@ MessageQueue::~MessageQueue() { } } +ReturnValue_t MessageQueue::handleError(mq_attr* attributes, + uint32_t messageDepth) { + switch(errno) { + case(EINVAL): { + sif::error << "MessageQueue::MessageQueue: Invalid name or attributes" + " for message size" << std::endl; + size_t defaultMqMaxMsg = 0; + if(std::ifstream("/proc/sys/fs/mqueue/msg_max",std::ios::in) >> + defaultMqMaxMsg and defaultMqMaxMsg < messageDepth) { + // See: https://www.man7.org/linux/man-pages/man3/mq_open.3.html + // This happens if the msg_max value is not large enough + // It is ignored if the executable is run in privileged mode. + // Run the unlockRealtime script or grant the mode manully by using: + // sudo setcap 'CAP_SYS_RESOURCE=+ep' + + // Permanent solution (EventManager has mq depth of 80): + // echo msg_max | sudo tee /proc/sys/fs/mqueue/msg_max + sif::error << "MessageQueue::MessageQueue: Default MQ size " + << defaultMqMaxMsg << " is too small for requested size " + << messageDepth << std::endl; + } + break; + } + case(EEXIST): { + // An error occured during open + // We need to distinguish if it is caused by an already created queue + if (errno == EEXIST) { + //There's another queue with the same name + //We unlink the other queue + int status = mq_unlink(name); + if (status != 0) { + sif::error << "mq_unlink Failed with status: " << strerror(errno) + << std::endl; + } + else { + // Successful unlinking, try to open again + mqd_t tempId = mq_open(name, + O_NONBLOCK | O_RDWR | O_CREAT | O_EXCL, + S_IWUSR | S_IREAD | S_IWGRP | S_IRGRP, attributes); + if (tempId != -1) { + //Successful mq_open + this->id = tempId; + return HasReturnvaluesIF::RETURN_OK; + } + } + } + break; + } + + default: + // Failed either the first time or the second time + sif::error << "MessageQueue::MessageQueue: Creating Queue " << std::hex + << name << std::dec << " failed with status: " + << strerror(errno) << std::endl; + + } + return HasReturnvaluesIF::RETURN_FAILED; + + + +} + ReturnValue_t MessageQueue::sendMessage(MessageQueueId_t sendTo, MessageQueueMessage* message, bool ignoreFault) { return sendMessageFrom(sendTo, message, this->getId(), false); @@ -265,7 +307,11 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, << strerror(errno) << " in mq_send" << std::endl; /*NO BREAK*/ case EMSGSIZE: - //The msg_len is greater than the msgsize associated with the specified queue. + // The msg_len is greater than the msgsize associated with + //the specified queue. + sif::error << "MessageQueue::sendMessage: Size error [" << + strerror(errno) << "] in mq_send" << std::endl; + /*NO BREAK*/ default: return HasReturnvaluesIF::RETURN_FAILED; } diff --git a/osal/linux/MessageQueue.h b/osal/linux/MessageQueue.h index b8285dc5..2808d36e 100644 --- a/osal/linux/MessageQueue.h +++ b/osal/linux/MessageQueue.h @@ -4,21 +4,26 @@ #include #include #include + +#include /** - * @brief This class manages sending and receiving of message queue messages. + * @brief This class manages sending and receiving of message queue messages. * - * @details Message queues are used to pass asynchronous messages between processes. - * They work like post boxes, where all incoming messages are stored in FIFO - * order. This class creates a new receiving queue and provides methods to fetch - * received messages. Being a child of MessageQueueSender, this class also provides - * methods to send a message to a user-defined or a default destination. In addition - * it also provides a reply method to answer to the queue it received its last message - * from. - * The MessageQueue should be used as "post box" for a single owning object. So all - * message queue communication is "n-to-one". - * For creating the queue, as well as sending and receiving messages, the class makes - * use of the operating system calls provided. - * \ingroup message_queue + * @details + * Message queues are used to pass asynchronous messages between processes. + * They work like post boxes, where all incoming messages are stored in FIFO + * order. This class creates a new receiving queue and provides methods to fetch + * received messages. Being a child of MessageQueueSender, this class also + * provides methods to send a message to a user-defined or a default destination. + * In addition it also provides a reply method to answer to the queue it + * received its last message from. + * + * The MessageQueue should be used as "post box" for a single owning object. + * So all message queue communication is "n-to-one". + * + * The creation of message queues, as well as sending and receiving messages, + * makes use of the operating system calls provided. + * @ingroup message_queue */ class MessageQueue : public MessageQueueIF { friend class MessageQueueSenderIF; @@ -35,7 +40,8 @@ public: * @param max_message_size With this parameter, the maximum message size can be adjusted. * This should be left default. */ - MessageQueue( size_t message_depth = 3, size_t max_message_size = MessageQueueMessage::MAX_MESSAGE_SIZE ); + MessageQueue(uint32_t messageDepth = 3, + size_t maxMessageSize = MessageQueueMessage::MAX_MESSAGE_SIZE ); /** * @brief The destructor deletes the formerly created message queue. * @details This is accomplished by using the delete call provided by the operating system. @@ -168,6 +174,8 @@ private: char name[5]; static uint16_t queueCounter; + + ReturnValue_t handleError(mq_attr* attributes, uint32_t messageDepth); }; #endif /* MESSAGEQUEUE_H_ */ diff --git a/osal/linux/PeriodicPosixTask.cpp b/osal/linux/PeriodicPosixTask.cpp index b754c3f4..df5bbf93 100644 --- a/osal/linux/PeriodicPosixTask.cpp +++ b/osal/linux/PeriodicPosixTask.cpp @@ -3,9 +3,10 @@ #include #include -PeriodicPosixTask::PeriodicPosixTask(const char* name_, int priority_, size_t stackSize_, uint32_t period_, void(deadlineMissedFunc_)()):PosixThread(name_,priority_,stackSize_),objectList(),started(false),periodMs(period_),deadlineMissedFunc( - deadlineMissedFunc_) { - +PeriodicPosixTask::PeriodicPosixTask(const char* name_, int priority_, + size_t stackSize_, uint32_t period_, void(deadlineMissedFunc_)()): + PosixThread(name_,priority_,stackSize_),objectList(),started(false), + periodMs(period_),deadlineMissedFunc(deadlineMissedFunc_) { } PeriodicPosixTask::~PeriodicPosixTask() { @@ -37,7 +38,8 @@ ReturnValue_t PeriodicPosixTask::sleepFor(uint32_t ms) { ReturnValue_t PeriodicPosixTask::startTask(void){ started = true; - createTask(&taskEntryPoint,this); + //sif::info << stackSize << std::endl; + PosixThread::createTask(&taskEntryPoint,this); return HasReturnvaluesIF::RETURN_OK; } @@ -56,9 +58,11 @@ void PeriodicPosixTask::taskFunctionality(void){ char name[20] = {0}; int status = pthread_getname_np(pthread_self(),name,sizeof(name)); if(status==0){ - sif::error << "ObjectTask: " << name << " Deadline missed." << std::endl; + sif::error << "PeriodicPosixTask " << name << ": Deadline " + "missed." << std::endl; }else{ - sif::error << "ObjectTask: X Deadline missed. " << status << std::endl; + sif::error << "PeriodicPosixTask X: Deadline missed. " << + status << std::endl; } if (this->deadlineMissedFunc != NULL) { this->deadlineMissedFunc(); diff --git a/osal/linux/PeriodicPosixTask.h b/osal/linux/PeriodicPosixTask.h index 43647eda..85de0d59 100644 --- a/osal/linux/PeriodicPosixTask.h +++ b/osal/linux/PeriodicPosixTask.h @@ -9,9 +9,22 @@ class PeriodicPosixTask: public PosixThread, public PeriodicTaskIF { public: + /** + * Create a generic periodic task. + * @param name_ + * Name, maximum allowed size of linux is 16 chars, everything else will + * be truncated. + * @param priority_ + * Real-time priority, ranges from 1 to 99 for Linux. + * See: https://man7.org/linux/man-pages/man7/sched.7.html + * @param stackSize_ + * @param period_ + * @param deadlineMissedFunc_ + */ PeriodicPosixTask(const char* name_, int priority_, size_t stackSize_, uint32_t period_, void(*deadlineMissedFunc_)()); virtual ~PeriodicPosixTask(); + /** * @brief The method to start the task. * @details The method starts the task with the respective system call. diff --git a/osal/linux/PosixThread.cpp b/osal/linux/PosixThread.cpp index 899700f0..24545f6f 100644 --- a/osal/linux/PosixThread.cpp +++ b/osal/linux/PosixThread.cpp @@ -1,8 +1,12 @@ #include +#include #include #include -#include +PosixThread::PosixThread(const char* name_, int priority_, size_t stackSize_): + thread(0),priority(priority_),stackSize(stackSize_) { + strncpy(name,name_,16); +} PosixThread::~PosixThread() { //No deletion and no free of Stack Pointer @@ -113,12 +117,6 @@ uint64_t PosixThread::getCurrentMonotonicTimeMs(){ return currentTime_ms; } -PosixThread::PosixThread(const char* name_, int priority_, size_t stackSize_): - thread(0),priority(priority_),stackSize(stackSize_) { - strcpy(name,name_); -} - - void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) { //sif::debug << "PosixThread::createTask" << std::endl; @@ -135,14 +133,24 @@ void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) { sif::error << "Posix Thread attribute init failed with: " << strerror(status) << std::endl; } - void* sp; - status = posix_memalign(&sp, sysconf(_SC_PAGESIZE), stackSize); + void* stackPointer; + status = posix_memalign(&stackPointer, sysconf(_SC_PAGESIZE), stackSize); if(status != 0){ - sif::error << "Posix Thread stack init failed with: " << + sif::error << "PosixThread::createTask: Stack init failed with: " << strerror(status) << std::endl; + if(errno == ENOMEM) { + uint64_t stackMb = stackSize/10e6; + sif::error << "PosixThread::createTask: Insufficient memory for" + " the requested " << stackMb << " MB" << std::endl; + } + else if(errno == EINVAL) { + sif::error << "PosixThread::createTask: Wrong alignment argument!" + << std::endl; + } + return; } - status = pthread_attr_setstack(&attributes, sp, stackSize); + status = pthread_attr_setstack(&attributes, stackPointer, stackSize); if(status != 0){ sif::error << "Posix Thread attribute setStack failed with: " << strerror(status) << std::endl; @@ -188,8 +196,19 @@ void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) { status = pthread_setname_np(thread,name); if(status != 0){ - sif::error << "Posix Thread setname failed with: " << + sif::error << "PosixThread::createTask: setname failed with: " << strerror(status) << std::endl; + if(status == ERANGE) { + sif::error << "PosixThread::createTask: Task name length longer" + " than 16 chars. Truncating.." << std::endl; + name[15] = '\0'; + status = pthread_setname_np(thread,name); + if(status != 0){ + sif::error << "PosixThread::createTask: Setting name" + " did not work.." << std::endl; + } + } + } status = pthread_attr_destroy(&attributes); diff --git a/osal/linux/PosixThread.h b/osal/linux/PosixThread.h index d96c4156..07233fe5 100644 --- a/osal/linux/PosixThread.h +++ b/osal/linux/PosixThread.h @@ -1,12 +1,11 @@ #ifndef FRAMEWORK_OSAL_LINUX_POSIXTHREAD_H_ #define FRAMEWORK_OSAL_LINUX_POSIXTHREAD_H_ -#include -#include -#include -#include -#include #include +#include +#include +#include +#include class PosixThread { public: @@ -54,21 +53,24 @@ protected: pthread_t thread; /** - * @brief Function that has to be called by derived class because the derived class pointer has to be valid as argument - * @details This function creates a pthread with the given parameters. As the function requires a pointer to the derived object - * it has to be called after the this pointer of the derived object is valid. Sets the taskEntryPoint as - * function to be called by new a thread. - * @param name_ Name of the task - * @param priority_ Priority of the task according to POSIX - * @param stackSize_ Size of the stack attached to that task - * @param arg_ argument of the taskEntryPoint function, needs to be this pointer of derived class + * @brief Function that has to be called by derived class because the + * derived class pointer has to be valid as argument + * @details + * This function creates a pthread with the given parameters. As the + * function requires a pointer to the derived object it has to be called + * after the this pointer of the derived object is valid. + * Sets the taskEntryPoint as function to be called by new a thread. + * @param fnc_ Function which will be executed by the thread. + * @param arg_ + * argument of the taskEntryPoint function, needs to be this pointer + * of derived class */ void createTask(void* (*fnc_)(void*),void* arg_); private: - char name[10]; + char name[16]; int priority; - size_t stackSize; + size_t stackSize = 0; }; #endif /* FRAMEWORK_OSAL_LINUX_POSIXTHREAD_H_ */ diff --git a/osal/linux/QueueFactory.cpp b/osal/linux/QueueFactory.cpp index fc4c9026..268d0b99 100644 --- a/osal/linux/QueueFactory.cpp +++ b/osal/linux/QueueFactory.cpp @@ -5,16 +5,18 @@ #include #include -QueueFactory* QueueFactory::factoryInstance = NULL; +QueueFactory* QueueFactory::factoryInstance = nullptr; ReturnValue_t MessageQueueSenderIF::sendMessage(MessageQueueId_t sendTo, - MessageQueueMessage* message, MessageQueueId_t sentFrom,bool ignoreFault) { - return MessageQueue::sendMessageFromMessageQueue(sendTo,message,sentFrom,ignoreFault); + MessageQueueMessage* message, MessageQueueId_t sentFrom, + bool ignoreFault) { + return MessageQueue::sendMessageFromMessageQueue(sendTo,message, + sentFrom,ignoreFault); } QueueFactory* QueueFactory::instance() { - if (factoryInstance == NULL) { + if (factoryInstance == nullptr) { factoryInstance = new QueueFactory; } return factoryInstance; @@ -26,9 +28,9 @@ QueueFactory::QueueFactory() { QueueFactory::~QueueFactory() { } -MessageQueueIF* QueueFactory::createMessageQueue(uint32_t message_depth, - uint32_t max_message_size) { - return new MessageQueue(message_depth, max_message_size); +MessageQueueIF* QueueFactory::createMessageQueue(uint32_t messageDepth, + size_t maxMessageSize) { + return new MessageQueue(messageDepth, maxMessageSize); } void QueueFactory::deleteMessageQueue(MessageQueueIF* queue) { diff --git a/osal/linux/TaskFactory.cpp b/osal/linux/TaskFactory.cpp index 44f46d90..219630a7 100644 --- a/osal/linux/TaskFactory.cpp +++ b/osal/linux/TaskFactory.cpp @@ -13,12 +13,20 @@ TaskFactory* TaskFactory::instance() { return TaskFactory::factoryInstance; } -PeriodicTaskIF* TaskFactory::createPeriodicTask(TaskName name_,TaskPriority taskPriority_,TaskStackSize stackSize_,TaskPeriod periodInSeconds_,TaskDeadlineMissedFunction deadLineMissedFunction_) { - return static_cast(new PeriodicPosixTask(name_, taskPriority_,stackSize_,periodInSeconds_ * 1000,deadLineMissedFunction_)); +PeriodicTaskIF* TaskFactory::createPeriodicTask(TaskName name_, + TaskPriority taskPriority_,TaskStackSize stackSize_, + TaskPeriod periodInSeconds_, + TaskDeadlineMissedFunction deadLineMissedFunction_) { + return new PeriodicPosixTask(name_, taskPriority_,stackSize_, + periodInSeconds_ * 1000, deadLineMissedFunction_); } -FixedTimeslotTaskIF* TaskFactory::createFixedTimeslotTask(TaskName name_,TaskPriority taskPriority_,TaskStackSize stackSize_,TaskPeriod periodInSeconds_,TaskDeadlineMissedFunction deadLineMissedFunction_) { - return static_cast(new FixedTimeslotTask(name_, taskPriority_,stackSize_,periodInSeconds_*1000)); +FixedTimeslotTaskIF* TaskFactory::createFixedTimeslotTask(TaskName name_, + TaskPriority taskPriority_,TaskStackSize stackSize_, + TaskPeriod periodInSeconds_, + TaskDeadlineMissedFunction deadLineMissedFunction_) { + return new FixedTimeslotTask(name_, taskPriority_,stackSize_, + periodInSeconds_*1000); } ReturnValue_t TaskFactory::deleteTask(PeriodicTaskIF* task) { diff --git a/osal/rtems/QueueFactory.cpp b/osal/rtems/QueueFactory.cpp index 0f2e0ea9..8cc9905c 100644 --- a/osal/rtems/QueueFactory.cpp +++ b/osal/rtems/QueueFactory.cpp @@ -49,9 +49,9 @@ QueueFactory::QueueFactory() { QueueFactory::~QueueFactory() { } -MessageQueueIF* QueueFactory::createMessageQueue(uint32_t message_depth, - uint32_t max_message_size) { - return new MessageQueue(message_depth, max_message_size); +MessageQueueIF* QueueFactory::createMessageQueue(uint32_t messageDepth, + size_t maxMessageSize) { + return new MessageQueue(messageDepth, maxMessageSize); } void QueueFactory::deleteMessageQueue(MessageQueueIF* queue) { From 6ad36ceb24fef5bcc52ae8b5405f74042caba4bf Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 6 Jun 2020 16:24:33 +0200 Subject: [PATCH 081/307] variable for max name len --- osal/linux/PosixThread.cpp | 2 +- osal/linux/PosixThread.h | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/osal/linux/PosixThread.cpp b/osal/linux/PosixThread.cpp index 24545f6f..3845123c 100644 --- a/osal/linux/PosixThread.cpp +++ b/osal/linux/PosixThread.cpp @@ -5,7 +5,7 @@ PosixThread::PosixThread(const char* name_, int priority_, size_t stackSize_): thread(0),priority(priority_),stackSize(stackSize_) { - strncpy(name,name_,16); + strncpy(name, name_, PTHREAD_MAX_NAMELEN); } PosixThread::~PosixThread() { diff --git a/osal/linux/PosixThread.h b/osal/linux/PosixThread.h index 07233fe5..e9d31728 100644 --- a/osal/linux/PosixThread.h +++ b/osal/linux/PosixThread.h @@ -9,6 +9,7 @@ class PosixThread { public: + static constexpr uint8_t PTHREAD_MAX_NAMELEN = 16; PosixThread(const char* name_, int priority_, size_t stackSize_); virtual ~PosixThread(); /** @@ -54,7 +55,7 @@ protected: /** * @brief Function that has to be called by derived class because the - * derived class pointer has to be valid as argument + * derived class pointer has to be valid as argument. * @details * This function creates a pthread with the given parameters. As the * function requires a pointer to the derived object it has to be called @@ -68,7 +69,7 @@ protected: void createTask(void* (*fnc_)(void*),void* arg_); private: - char name[16]; + char name[PTHREAD_MAX_NAMELEN]; int priority; size_t stackSize = 0; }; From be066755c0c2e7465149cecac58bab1e1ab49ea7 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 6 Jun 2020 14:39:08 +0200 Subject: [PATCH 082/307] even safer and more efficient alternative --- osal/linux/PosixThread.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osal/linux/PosixThread.cpp b/osal/linux/PosixThread.cpp index 3845123c..c63dde9f 100644 --- a/osal/linux/PosixThread.cpp +++ b/osal/linux/PosixThread.cpp @@ -5,7 +5,8 @@ PosixThread::PosixThread(const char* name_, int priority_, size_t stackSize_): thread(0),priority(priority_),stackSize(stackSize_) { - strncpy(name, name_, PTHREAD_MAX_NAMELEN); + name[0] = '\0'; + strncat(name, name_, PTHREAD_MAX_NAMELE - 1); } PosixThread::~PosixThread() { From 212cd58f9a7a8c7b1ed86b5a4b4f46c09f645022 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 6 Jun 2020 14:45:45 +0200 Subject: [PATCH 083/307] issues with fixed timeslo ttask on linux --- osal/linux/MessageQueue.cpp | 2 +- osal/linux/PosixThread.cpp | 26 +++++++++++++++++--------- osal/linux/PosixThread.h | 2 +- osal/linux/TaskFactory.cpp | 16 ++++++++++++---- 4 files changed, 31 insertions(+), 15 deletions(-) diff --git a/osal/linux/MessageQueue.cpp b/osal/linux/MessageQueue.cpp index 2456a329..86d1e0d9 100644 --- a/osal/linux/MessageQueue.cpp +++ b/osal/linux/MessageQueue.cpp @@ -64,7 +64,7 @@ ReturnValue_t MessageQueue::handleError(mq_attr* attributes, // Run the unlockRealtime script or grant the mode manully by using: // sudo setcap 'CAP_SYS_RESOURCE=+ep' - // Permanent solution: + // Permanent solution (EventManager has mq depth of 80): // echo msg_max | sudo tee /proc/sys/fs/mqueue/msg_max sif::error << "MessageQueue::MessageQueue: Default MQ size " << defaultMqMaxMsg << " is too small for requested size " diff --git a/osal/linux/PosixThread.cpp b/osal/linux/PosixThread.cpp index e8d624ca..cfc3ed4d 100644 --- a/osal/linux/PosixThread.cpp +++ b/osal/linux/PosixThread.cpp @@ -3,6 +3,10 @@ #include #include +PosixThread::PosixThread(const char* name_, int priority_, size_t stackSize_): + thread(0),priority(priority_),stackSize(stackSize_) { + strcpy(name,name_); +} PosixThread::~PosixThread() { //No deletion and no free of Stack Pointer @@ -113,12 +117,6 @@ uint64_t PosixThread::getCurrentMonotonicTimeMs(){ return currentTime_ms; } -PosixThread::PosixThread(const char* name_, int priority_, size_t stackSize_): - thread(0),priority(priority_),stackSize(stackSize_) { - strcpy(name,name_); -} - - void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) { //sif::debug << "PosixThread::createTask" << std::endl; @@ -135,14 +133,24 @@ void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) { sif::error << "Posix Thread attribute init failed with: " << strerror(status) << std::endl; } - void* sp; - status = posix_memalign(&sp, sysconf(_SC_PAGESIZE), stackSize); + void* stackPointer; + status = posix_memalign(&stackPointer, sysconf(_SC_PAGESIZE), stackSize); if(status != 0){ sif::error << "PosixThread::createTask: Stack init failed with: " << strerror(status) << std::endl; + if(errno == ENOMEM) { + double stackMb = (double)((double)stackSize/(double)10e6); + sif::error << "PosixThread::createTask: Insufficient memory for" + " the requested " << stackMb << " MB" << std::endl; + } + else if(errno == EINVAL) { + sif::error << "PosixThread::createTask: Wrong alignment argument!" + << std::endl; + } + return; } - status = pthread_attr_setstack(&attributes, sp, stackSize); + status = pthread_attr_setstack(&attributes, stackPointer, stackSize); if(status != 0){ sif::error << "Posix Thread attribute setStack failed with: " << strerror(status) << std::endl; diff --git a/osal/linux/PosixThread.h b/osal/linux/PosixThread.h index d96c4156..f10352b4 100644 --- a/osal/linux/PosixThread.h +++ b/osal/linux/PosixThread.h @@ -68,7 +68,7 @@ protected: private: char name[10]; int priority; - size_t stackSize; + size_t stackSize = 0; }; #endif /* FRAMEWORK_OSAL_LINUX_POSIXTHREAD_H_ */ diff --git a/osal/linux/TaskFactory.cpp b/osal/linux/TaskFactory.cpp index 44f46d90..219630a7 100644 --- a/osal/linux/TaskFactory.cpp +++ b/osal/linux/TaskFactory.cpp @@ -13,12 +13,20 @@ TaskFactory* TaskFactory::instance() { return TaskFactory::factoryInstance; } -PeriodicTaskIF* TaskFactory::createPeriodicTask(TaskName name_,TaskPriority taskPriority_,TaskStackSize stackSize_,TaskPeriod periodInSeconds_,TaskDeadlineMissedFunction deadLineMissedFunction_) { - return static_cast(new PeriodicPosixTask(name_, taskPriority_,stackSize_,periodInSeconds_ * 1000,deadLineMissedFunction_)); +PeriodicTaskIF* TaskFactory::createPeriodicTask(TaskName name_, + TaskPriority taskPriority_,TaskStackSize stackSize_, + TaskPeriod periodInSeconds_, + TaskDeadlineMissedFunction deadLineMissedFunction_) { + return new PeriodicPosixTask(name_, taskPriority_,stackSize_, + periodInSeconds_ * 1000, deadLineMissedFunction_); } -FixedTimeslotTaskIF* TaskFactory::createFixedTimeslotTask(TaskName name_,TaskPriority taskPriority_,TaskStackSize stackSize_,TaskPeriod periodInSeconds_,TaskDeadlineMissedFunction deadLineMissedFunction_) { - return static_cast(new FixedTimeslotTask(name_, taskPriority_,stackSize_,periodInSeconds_*1000)); +FixedTimeslotTaskIF* TaskFactory::createFixedTimeslotTask(TaskName name_, + TaskPriority taskPriority_,TaskStackSize stackSize_, + TaskPeriod periodInSeconds_, + TaskDeadlineMissedFunction deadLineMissedFunction_) { + return new FixedTimeslotTask(name_, taskPriority_,stackSize_, + periodInSeconds_*1000); } ReturnValue_t TaskFactory::deleteTask(PeriodicTaskIF* task) { From ef01b7814064e6847ce8e90ea00e8ea09bb36111 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 6 Jun 2020 15:01:57 +0200 Subject: [PATCH 084/307] some issue with stack size .. --- osal/linux/PeriodicPosixTask.cpp | 3 ++- osal/linux/PosixThread.cpp | 3 +++ osal/linux/PosixThread.h | 19 +++++++++++-------- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/osal/linux/PeriodicPosixTask.cpp b/osal/linux/PeriodicPosixTask.cpp index f6a74901..df5bbf93 100644 --- a/osal/linux/PeriodicPosixTask.cpp +++ b/osal/linux/PeriodicPosixTask.cpp @@ -38,7 +38,8 @@ ReturnValue_t PeriodicPosixTask::sleepFor(uint32_t ms) { ReturnValue_t PeriodicPosixTask::startTask(void){ started = true; - createTask(&taskEntryPoint,this); + //sif::info << stackSize << std::endl; + PosixThread::createTask(&taskEntryPoint,this); return HasReturnvaluesIF::RETURN_OK; } diff --git a/osal/linux/PosixThread.cpp b/osal/linux/PosixThread.cpp index cfc3ed4d..5f91858f 100644 --- a/osal/linux/PosixThread.cpp +++ b/osal/linux/PosixThread.cpp @@ -128,6 +128,9 @@ void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) { default attributes. */ pthread_attr_t attributes; + //PeriodicPosixTask* task = reinterpret_cast(arg_); + //sif::info << task->stackSize << std::endl; + sif::info << stackSize << std::endl; int status = pthread_attr_init(&attributes); if(status != 0){ sif::error << "Posix Thread attribute init failed with: " << diff --git a/osal/linux/PosixThread.h b/osal/linux/PosixThread.h index f10352b4..ad403ac4 100644 --- a/osal/linux/PosixThread.h +++ b/osal/linux/PosixThread.h @@ -54,14 +54,17 @@ protected: pthread_t thread; /** - * @brief Function that has to be called by derived class because the derived class pointer has to be valid as argument - * @details This function creates a pthread with the given parameters. As the function requires a pointer to the derived object - * it has to be called after the this pointer of the derived object is valid. Sets the taskEntryPoint as - * function to be called by new a thread. - * @param name_ Name of the task - * @param priority_ Priority of the task according to POSIX - * @param stackSize_ Size of the stack attached to that task - * @param arg_ argument of the taskEntryPoint function, needs to be this pointer of derived class + * @brief Function that has to be called by derived class because the + * derived class pointer has to be valid as argument + * @details + * This function creates a pthread with the given parameters. As the + * function requires a pointer to the derived object it has to be called + * after the this pointer of the derived object is valid. + * Sets the taskEntryPoint as function to be called by new a thread. + * @param fnc_ Function which will be executed by the thread. + * @param arg_ + * argument of the taskEntryPoint function, needs to be this pointer + * of derived class */ void createTask(void* (*fnc_)(void*),void* arg_); From b0634ab0a2f53fc7e1e194391f7ef4da80077931 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 6 Jun 2020 15:26:22 +0200 Subject: [PATCH 085/307] fixed bug (critical!) --- osal/linux/FixedTimeslotTask.h | 22 +++++++++++++--------- osal/linux/PosixThread.cpp | 22 +++++++++++++++------- osal/linux/PosixThread.h | 2 +- 3 files changed, 29 insertions(+), 17 deletions(-) diff --git a/osal/linux/FixedTimeslotTask.h b/osal/linux/FixedTimeslotTask.h index 6350f347..6d523ba9 100644 --- a/osal/linux/FixedTimeslotTask.h +++ b/osal/linux/FixedTimeslotTask.h @@ -8,7 +8,8 @@ class FixedTimeslotTask: public FixedTimeslotTaskIF, public PosixThread { public: - FixedTimeslotTask(const char* name_, int priority_, size_t stackSize_, uint32_t periodMs_); + FixedTimeslotTask(const char* name_, int priority_, size_t stackSize_, + uint32_t periodMs_); virtual ~FixedTimeslotTask(); virtual ReturnValue_t startTask(); @@ -17,7 +18,9 @@ public: virtual uint32_t getPeriodMs() const; - virtual ReturnValue_t addSlot(object_id_t componentId, uint32_t slotTimeMs, int8_t executionStep); + virtual ReturnValue_t addSlot(object_id_t componentId, uint32_t slotTimeMs, + int8_t executionStep); + virtual ReturnValue_t checkSequence() const; /** @@ -34,11 +37,10 @@ public: protected: /** * @brief This function holds the main functionality of the thread. - * - * - * @details Holding the main functionality of the task, this method is most important. - * It links the functionalities provided by FixedSlotSequence with the OS's System Calls - * to keep the timing of the periods. + * @details + * Holding the main functionality of the task, this method is most important. + * It links the functionalities provided by FixedSlotSequence with the + * OS's System Calls to keep the timing of the periods. */ virtual void taskFunctionality(); @@ -46,8 +48,10 @@ private: /** * @brief This is the entry point in a new thread. * - * @details This method, that is the entry point in the new thread and calls taskFunctionality of the child class. - * Needs a valid pointer to the derived class. + * @details + * This method, that is the entry point in the new thread and calls + * taskFunctionality of the child class. Needs a valid pointer to the + * derived class. */ static void* taskEntryPoint(void* arg); FixedSlotSequence pst; diff --git a/osal/linux/PosixThread.cpp b/osal/linux/PosixThread.cpp index 5f91858f..24545f6f 100644 --- a/osal/linux/PosixThread.cpp +++ b/osal/linux/PosixThread.cpp @@ -1,11 +1,11 @@ #include +#include #include #include -#include PosixThread::PosixThread(const char* name_, int priority_, size_t stackSize_): thread(0),priority(priority_),stackSize(stackSize_) { - strcpy(name,name_); + strncpy(name,name_,16); } PosixThread::~PosixThread() { @@ -128,9 +128,6 @@ void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) { default attributes. */ pthread_attr_t attributes; - //PeriodicPosixTask* task = reinterpret_cast(arg_); - //sif::info << task->stackSize << std::endl; - sif::info << stackSize << std::endl; int status = pthread_attr_init(&attributes); if(status != 0){ sif::error << "Posix Thread attribute init failed with: " << @@ -142,7 +139,7 @@ void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) { sif::error << "PosixThread::createTask: Stack init failed with: " << strerror(status) << std::endl; if(errno == ENOMEM) { - double stackMb = (double)((double)stackSize/(double)10e6); + uint64_t stackMb = stackSize/10e6; sif::error << "PosixThread::createTask: Insufficient memory for" " the requested " << stackMb << " MB" << std::endl; } @@ -199,8 +196,19 @@ void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) { status = pthread_setname_np(thread,name); if(status != 0){ - sif::error << "Posix Thread setname failed with: " << + sif::error << "PosixThread::createTask: setname failed with: " << strerror(status) << std::endl; + if(status == ERANGE) { + sif::error << "PosixThread::createTask: Task name length longer" + " than 16 chars. Truncating.." << std::endl; + name[15] = '\0'; + status = pthread_setname_np(thread,name); + if(status != 0){ + sif::error << "PosixThread::createTask: Setting name" + " did not work.." << std::endl; + } + } + } status = pthread_attr_destroy(&attributes); diff --git a/osal/linux/PosixThread.h b/osal/linux/PosixThread.h index ad403ac4..488e1986 100644 --- a/osal/linux/PosixThread.h +++ b/osal/linux/PosixThread.h @@ -69,7 +69,7 @@ protected: void createTask(void* (*fnc_)(void*),void* arg_); private: - char name[10]; + char name[16]; int priority; size_t stackSize = 0; }; From dc9ef41bec99951a0012cfa1a6ae17edfbff5bd5 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 6 Jun 2020 15:31:45 +0200 Subject: [PATCH 086/307] added doc for linux --- osal/linux/FixedTimeslotTask.h | 12 ++++++++++++ osal/linux/PeriodicPosixTask.h | 13 +++++++++++++ 2 files changed, 25 insertions(+) diff --git a/osal/linux/FixedTimeslotTask.h b/osal/linux/FixedTimeslotTask.h index 6d523ba9..d35b9ecb 100644 --- a/osal/linux/FixedTimeslotTask.h +++ b/osal/linux/FixedTimeslotTask.h @@ -8,6 +8,18 @@ class FixedTimeslotTask: public FixedTimeslotTaskIF, public PosixThread { public: + /** + * Create a generic periodic task. + * @param name_ + * Name, maximum allowed size of linux is 16 chars, everything else will + * be truncated. + * @param priority_ + * Real-time priority, ranges from 1 to 99 for Linux. + * See: https://man7.org/linux/man-pages/man7/sched.7.html + * @param stackSize_ + * @param period_ + * @param deadlineMissedFunc_ + */ FixedTimeslotTask(const char* name_, int priority_, size_t stackSize_, uint32_t periodMs_); virtual ~FixedTimeslotTask(); diff --git a/osal/linux/PeriodicPosixTask.h b/osal/linux/PeriodicPosixTask.h index 43647eda..85de0d59 100644 --- a/osal/linux/PeriodicPosixTask.h +++ b/osal/linux/PeriodicPosixTask.h @@ -9,9 +9,22 @@ class PeriodicPosixTask: public PosixThread, public PeriodicTaskIF { public: + /** + * Create a generic periodic task. + * @param name_ + * Name, maximum allowed size of linux is 16 chars, everything else will + * be truncated. + * @param priority_ + * Real-time priority, ranges from 1 to 99 for Linux. + * See: https://man7.org/linux/man-pages/man7/sched.7.html + * @param stackSize_ + * @param period_ + * @param deadlineMissedFunc_ + */ PeriodicPosixTask(const char* name_, int priority_, size_t stackSize_, uint32_t period_, void(*deadlineMissedFunc_)()); virtual ~PeriodicPosixTask(); + /** * @brief The method to start the task. * @details The method starts the task with the respective system call. From 096fbec156dc27d269154bebd70b61e9d7ed1c70 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 6 Jun 2020 15:40:10 +0200 Subject: [PATCH 087/307] cleaned includesu p a bit --- osal/linux/FixedTimeslotTask.cpp | 7 ++----- osal/linux/FixedTimeslotTask.h | 3 +++ osal/linux/PosixThread.h | 9 ++++----- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/osal/linux/FixedTimeslotTask.cpp b/osal/linux/FixedTimeslotTask.cpp index 098753a7..e5c68f9d 100644 --- a/osal/linux/FixedTimeslotTask.cpp +++ b/osal/linux/FixedTimeslotTask.cpp @@ -1,10 +1,7 @@ #include -#include -#include -#include -#include #include +#include uint32_t FixedTimeslotTask::deadlineMissedCount = 0; const size_t PeriodicTaskIF::MINIMUM_STACK_SIZE = PTHREAD_STACK_MIN; @@ -23,7 +20,7 @@ void* FixedTimeslotTask::taskEntryPoint(void* arg) { FixedTimeslotTask *originalTask(reinterpret_cast(arg)); //The task's functionality is called. originalTask->taskFunctionality(); - return NULL; + return nullptr; } ReturnValue_t FixedTimeslotTask::startTask() { diff --git a/osal/linux/FixedTimeslotTask.h b/osal/linux/FixedTimeslotTask.h index d35b9ecb..916e6d6c 100644 --- a/osal/linux/FixedTimeslotTask.h +++ b/osal/linux/FixedTimeslotTask.h @@ -64,6 +64,9 @@ private: * This method, that is the entry point in the new thread and calls * taskFunctionality of the child class. Needs a valid pointer to the * derived class. + * + * The void* returnvalue is not used yet but could be used to return + * arbitrary data. */ static void* taskEntryPoint(void* arg); FixedSlotSequence pst; diff --git a/osal/linux/PosixThread.h b/osal/linux/PosixThread.h index 488e1986..07233fe5 100644 --- a/osal/linux/PosixThread.h +++ b/osal/linux/PosixThread.h @@ -1,12 +1,11 @@ #ifndef FRAMEWORK_OSAL_LINUX_POSIXTHREAD_H_ #define FRAMEWORK_OSAL_LINUX_POSIXTHREAD_H_ -#include -#include -#include -#include -#include #include +#include +#include +#include +#include class PosixThread { public: From b79efa6d6c87cbb9d122b654b706a0279df093a9 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 6 Jun 2020 16:25:06 +0200 Subject: [PATCH 088/307] variable for name len --- osal/linux/PosixThread.cpp | 2 +- osal/linux/PosixThread.h | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/osal/linux/PosixThread.cpp b/osal/linux/PosixThread.cpp index 24545f6f..3845123c 100644 --- a/osal/linux/PosixThread.cpp +++ b/osal/linux/PosixThread.cpp @@ -5,7 +5,7 @@ PosixThread::PosixThread(const char* name_, int priority_, size_t stackSize_): thread(0),priority(priority_),stackSize(stackSize_) { - strncpy(name,name_,16); + strncpy(name, name_, PTHREAD_MAX_NAMELEN); } PosixThread::~PosixThread() { diff --git a/osal/linux/PosixThread.h b/osal/linux/PosixThread.h index 07233fe5..e9d31728 100644 --- a/osal/linux/PosixThread.h +++ b/osal/linux/PosixThread.h @@ -9,6 +9,7 @@ class PosixThread { public: + static constexpr uint8_t PTHREAD_MAX_NAMELEN = 16; PosixThread(const char* name_, int priority_, size_t stackSize_); virtual ~PosixThread(); /** @@ -54,7 +55,7 @@ protected: /** * @brief Function that has to be called by derived class because the - * derived class pointer has to be valid as argument + * derived class pointer has to be valid as argument. * @details * This function creates a pthread with the given parameters. As the * function requires a pointer to the derived object it has to be called @@ -68,7 +69,7 @@ protected: void createTask(void* (*fnc_)(void*),void* arg_); private: - char name[16]; + char name[PTHREAD_MAX_NAMELEN]; int priority; size_t stackSize = 0; }; From 92f493f13a9c1b5685c0e4e500854aeb3aeef677 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 6 Jun 2020 16:48:21 +0200 Subject: [PATCH 089/307] name correction --- osal/linux/PosixThread.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osal/linux/PosixThread.cpp b/osal/linux/PosixThread.cpp index c63dde9f..5750471d 100644 --- a/osal/linux/PosixThread.cpp +++ b/osal/linux/PosixThread.cpp @@ -6,7 +6,7 @@ PosixThread::PosixThread(const char* name_, int priority_, size_t stackSize_): thread(0),priority(priority_),stackSize(stackSize_) { name[0] = '\0'; - strncat(name, name_, PTHREAD_MAX_NAMELE - 1); + strncat(name, name_, PTHREAD_MAX_NAMELEN - 1); } PosixThread::~PosixThread() { From c602e30a63278d92ac2951b6452756dea31da539 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 6 Jun 2020 18:45:55 +0200 Subject: [PATCH 090/307] std:: added --- osal/linux/PosixThread.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osal/linux/PosixThread.cpp b/osal/linux/PosixThread.cpp index 5750471d..7cf1d9bc 100644 --- a/osal/linux/PosixThread.cpp +++ b/osal/linux/PosixThread.cpp @@ -6,7 +6,7 @@ PosixThread::PosixThread(const char* name_, int priority_, size_t stackSize_): thread(0),priority(priority_),stackSize(stackSize_) { name[0] = '\0'; - strncat(name, name_, PTHREAD_MAX_NAMELEN - 1); + std::strncat(name, name_, PTHREAD_MAX_NAMELEN - 1); } PosixThread::~PosixThread() { From bf1b86e809a5375fc80031606675e233446c560b Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 6 Jun 2020 18:48:28 +0200 Subject: [PATCH 091/307] small form stuff --- osal/linux/PosixThread.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/osal/linux/PosixThread.cpp b/osal/linux/PosixThread.cpp index 7cf1d9bc..bc3e62ed 100644 --- a/osal/linux/PosixThread.cpp +++ b/osal/linux/PosixThread.cpp @@ -60,10 +60,6 @@ void PosixThread::resume(){ pthread_kill(thread,SIGUSR1); } - - - - bool PosixThread::delayUntil(uint64_t* const prevoiusWakeTime_ms, const uint64_t delayTime_ms) { uint64_t nextTimeToWake_ms; @@ -163,7 +159,7 @@ void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) { strerror(status) << std::endl; } -//TODO FIFO -> This needs root privileges for the process + // TODO FIFO -> This needs root privileges for the process status = pthread_attr_setschedpolicy(&attributes,SCHED_FIFO); if(status != 0){ sif::error << "Posix Thread attribute schedule policy failed with: " << @@ -209,7 +205,6 @@ void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) { " did not work.." << std::endl; } } - } status = pthread_attr_destroy(&attributes); From 262d34174ea9a7bd46b7ffd12b70e9e1258fe063 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 6 Jun 2020 18:56:54 +0200 Subject: [PATCH 092/307] using strncat now --- osal/linux/PosixThread.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/osal/linux/PosixThread.cpp b/osal/linux/PosixThread.cpp index 3845123c..bc3e62ed 100644 --- a/osal/linux/PosixThread.cpp +++ b/osal/linux/PosixThread.cpp @@ -5,7 +5,8 @@ PosixThread::PosixThread(const char* name_, int priority_, size_t stackSize_): thread(0),priority(priority_),stackSize(stackSize_) { - strncpy(name, name_, PTHREAD_MAX_NAMELEN); + name[0] = '\0'; + std::strncat(name, name_, PTHREAD_MAX_NAMELEN - 1); } PosixThread::~PosixThread() { @@ -59,10 +60,6 @@ void PosixThread::resume(){ pthread_kill(thread,SIGUSR1); } - - - - bool PosixThread::delayUntil(uint64_t* const prevoiusWakeTime_ms, const uint64_t delayTime_ms) { uint64_t nextTimeToWake_ms; @@ -162,7 +159,7 @@ void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) { strerror(status) << std::endl; } -//TODO FIFO -> This needs root privileges for the process + // TODO FIFO -> This needs root privileges for the process status = pthread_attr_setschedpolicy(&attributes,SCHED_FIFO); if(status != 0){ sif::error << "Posix Thread attribute schedule policy failed with: " << @@ -208,7 +205,6 @@ void PosixThread::createTask(void* (*fnc_)(void*), void* arg_) { " did not work.." << std::endl; } } - } status = pthread_attr_destroy(&attributes); From d99be255292e7682bac12dea38258c9cc4eed707 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 6 Jun 2020 20:52:28 +0200 Subject: [PATCH 093/307] cookie info iter was uninitialized leads to crash --- devicehandlers/DeviceHandlerBase.cpp | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index 965959af..30ee0394 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -32,19 +32,20 @@ DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, deviceThermalRequestPoolId(thermalRequestPoolId), childTransitionFailure(RETURN_OK), fdirInstance(fdirInstance), hkSwitcher(this), defaultFDIRUsed(fdirInstance == nullptr), - switchOffWasReported(false), cookieInfo(), - childTransitionDelay(5000), + switchOffWasReported(false), childTransitionDelay(5000), transitionSourceMode(_MODE_POWER_DOWN), transitionSourceSubMode( SUBMODE_NONE), deviceSwitch(setDeviceSwitch) { commandQueue = QueueFactory::instance()->createMessageQueue(cmdQueueSize, CommandMessage::MAX_MESSAGE_SIZE); - cookieInfo.state = COOKIE_UNUSED; insertInCommandMap(RAW_COMMAND_ID); + cookieInfo.state = COOKIE_UNUSED; + cookieInfo.pendingCommand = deviceCommandMap.end(); if (comCookie == nullptr) { sif::error << "DeviceHandlerBase: ObjectID 0x" << std::hex << std::setw(8) << std::setfill('0') << this->getObjectId() << std::dec << ": Do not pass nullptr as a cookie, consider " - "passing a dummy cookie instead!" << std::endl; + << std::setfill(' ') << "passing a dummy cookie instead!" << + std::endl; } if (this->fdirInstance == nullptr) { this->fdirInstance = new DeviceHandlerFailureIsolation(setObjectId, @@ -571,12 +572,12 @@ void DeviceHandlerBase::doSendRead() { ReturnValue_t result; size_t requestLen = 0; - DeviceReplyIter iter = deviceReplyMap.find(cookieInfo.pendingCommand->first); - if(iter != deviceReplyMap.end()) { - requestLen = iter->second.replyLen; - } - else { - requestLen = 0; + if(cookieInfo.pendingCommand != deviceCommandMap.end()) { + DeviceReplyIter iter = deviceReplyMap.find( + cookieInfo.pendingCommand->first); + if(iter != deviceReplyMap.end()) { + requestLen = iter->second.replyLen; + } } result = communicationInterface->requestReceiveMessage(comCookie, requestLen); From ea548dea5bbd969ca17cf9cb48a6b5cfad5e8fda Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 6 Jun 2020 21:16:47 +0200 Subject: [PATCH 094/307] map lock init --- osal/host/QueueMapManager.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osal/host/QueueMapManager.cpp b/osal/host/QueueMapManager.cpp index a57d2c0c..e7c86f30 100644 --- a/osal/host/QueueMapManager.cpp +++ b/osal/host/QueueMapManager.cpp @@ -4,7 +4,9 @@ QueueMapManager* QueueMapManager::mqManagerInstance = nullptr; -QueueMapManager::QueueMapManager() {} +QueueMapManager::QueueMapManager() { + mapLock = MutexFactory::instance()->createMutex(); +} QueueMapManager* QueueMapManager::instance() { if (mqManagerInstance == nullptr){ From 8216b26fdee2f5e7dc552b0d037219149abc7edb Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 6 Jun 2020 23:15:05 +0200 Subject: [PATCH 095/307] datapoollocal updates --- datapoollocal/LocalPoolVariable.h | 8 +++----- datapoollocal/LocalPoolVariable.tpp | 12 ++++++------ datapoollocal/LocalPoolVector.h | 6 ++++++ datapoollocal/LocalPoolVector.tpp | 15 +++++++++++++++ 4 files changed, 30 insertions(+), 11 deletions(-) diff --git a/datapoollocal/LocalPoolVariable.h b/datapoollocal/LocalPoolVariable.h index cb373a71..b6bfa5b8 100644 --- a/datapoollocal/LocalPoolVariable.h +++ b/datapoollocal/LocalPoolVariable.h @@ -131,11 +131,9 @@ protected: ReturnValue_t commitWithoutLock() override; // std::ostream is the type for object std::cout -// friend std::ostream& operator<< (std::ostream &out, -// const LocalPoolVar &var) { -// out << static_cast(value); -// return out; -// } + template + friend std::ostream& operator<< (std::ostream &out, + const LocalPoolVar &var); private: //! @brief Pool ID of pool entry inside the used local pool. diff --git a/datapoollocal/LocalPoolVariable.tpp b/datapoollocal/LocalPoolVariable.tpp index b7a0e837..663b73f5 100644 --- a/datapoollocal/LocalPoolVariable.tpp +++ b/datapoollocal/LocalPoolVariable.tpp @@ -151,11 +151,11 @@ inline ReturnValue_t LocalPoolVar::deSerialize(const uint8_t** buffer, return AutoSerializeAdapter::deSerialize(&value, buffer, size, bigEndian); } -//template -//inline friend std::ostream& LocalPoolVar::operator<< (std::ostream &out, -// const LocalPoolVar &var) { -// out << static_cast(out); -//} - +template +inline std::ostream& operator<< (std::ostream &out, + const LocalPoolVar &var) { + out << var.value; + return out; +} #endif diff --git a/datapoollocal/LocalPoolVector.h b/datapoollocal/LocalPoolVector.h index 02c47113..74615151 100644 --- a/datapoollocal/LocalPoolVector.h +++ b/datapoollocal/LocalPoolVector.h @@ -5,6 +5,7 @@ #include #include #include +#include #include @@ -179,6 +180,11 @@ private: ReadWriteMode_t readWriteMode; //! @brief Pointer to the class which manages the HK pool. HousekeepingManager* hkManager; + + // std::ostream is the type for object std::cout + template + friend std::ostream& operator<< (std::ostream &out, + const LocalPoolVector &var); }; #include diff --git a/datapoollocal/LocalPoolVector.tpp b/datapoollocal/LocalPoolVector.tpp index 78637eff..9a00e5df 100644 --- a/datapoollocal/LocalPoolVector.tpp +++ b/datapoollocal/LocalPoolVector.tpp @@ -15,6 +15,7 @@ inline LocalPoolVector::LocalPoolVector(lp_id_t poolId, "NO_PARAMETER value!" << std::endl; } memset(this->value, 0, vectorSize * sizeof(T)); + hkManager = hkOwner->getHkManagerHandle(); if (dataSet != nullptr) { dataSet->registerVariable(this); } @@ -182,4 +183,18 @@ inline bool LocalPoolVector::isValid() const { return valid; } +template +inline std::ostream& operator<< (std::ostream &out, + const LocalPoolVector &var) { + out << "Vector: ["; + for(int i = 0;i < vectorSize; i++) { + out << var.value[i]; + if(i < vectorSize - 1) { + out << ", "; + } + } + out << "]"; + return out; +} + #endif From 70212d9f4e979b1092e151cc7cb666b085acddad Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 6 Jun 2020 23:15:42 +0200 Subject: [PATCH 096/307] slight formatting --- housekeeping/HasHkPoolParametersIF.h | 1 + housekeeping/HousekeepingMessage.h | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/housekeeping/HasHkPoolParametersIF.h b/housekeeping/HasHkPoolParametersIF.h index 9efc6d16..62715a3d 100644 --- a/housekeeping/HasHkPoolParametersIF.h +++ b/housekeeping/HasHkPoolParametersIF.h @@ -40,6 +40,7 @@ public: virtual MessageQueueId_t getCommandQueue() const = 0; virtual ReturnValue_t initializeHousekeepingPoolEntries( LocalDataPoolMap& localDataPoolMap) = 0; + //virtual float setMinimalHkSamplingFrequency() = 0; virtual HousekeepingManager* getHkManagerHandle() = 0; virtual DataSetIF* getDataSetHandle(sid_t sid) = 0; }; diff --git a/housekeeping/HousekeepingMessage.h b/housekeeping/HousekeepingMessage.h index 61e6e199..e7ba68ba 100644 --- a/housekeeping/HousekeepingMessage.h +++ b/housekeeping/HousekeepingMessage.h @@ -19,7 +19,6 @@ union sid_t { */ uint64_t raw; }; - class HousekeepingMessage { public: /** From 9ed92e5e6f24721446613138f81939c763ae4783 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 6 Jun 2020 23:21:51 +0200 Subject: [PATCH 097/307] clock typedefs renamed --- timemanager/Clock.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/timemanager/Clock.h b/timemanager/Clock.h index 19991b81..121c63df 100644 --- a/timemanager/Clock.h +++ b/timemanager/Clock.h @@ -8,8 +8,9 @@ #include #include -typedef uint32_t millis_t; -typedef double seconds_t; +//! Don't use these for time points, type is not large enough for UNIX epoch. +typedef uint32_t dur_millis_t; +typedef double dur_seconds_t; class Clock { public: From 3d8993b0c599636fb7549ade76ca08cb47f0b4f2 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 6 Jun 2020 23:23:20 +0200 Subject: [PATCH 098/307] new typedef names --- timemanager/Stopwatch.cpp | 4 ++-- timemanager/Stopwatch.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/timemanager/Stopwatch.cpp b/timemanager/Stopwatch.cpp index bc8b4149..52118d58 100644 --- a/timemanager/Stopwatch.cpp +++ b/timemanager/Stopwatch.cpp @@ -13,12 +13,12 @@ void Stopwatch::start() { Clock::getClock_timeval(&startTime); } -millis_t Stopwatch::stop() { +dur_millis_t Stopwatch::stop() { stopInternal(); return elapsedTime.tv_sec * 1000 + elapsedTime.tv_usec / 1000; } -seconds_t Stopwatch::stopSeconds() { +dur_seconds_t Stopwatch::stopSeconds() { stopInternal(); return timevalOperations::toDouble(elapsedTime); } diff --git a/timemanager/Stopwatch.h b/timemanager/Stopwatch.h index 71580778..630202cc 100644 --- a/timemanager/Stopwatch.h +++ b/timemanager/Stopwatch.h @@ -40,12 +40,12 @@ public: * Calculates the elapsed time since start and returns it * @return elapsed time in milliseconds (rounded) */ - millis_t stop(); + dur_millis_t stop(); /** * Calculates the elapsed time since start and returns it * @return elapsed time in seconds (double precision) */ - seconds_t stopSeconds(); + dur_seconds_t stopSeconds(); /** * Displays the elapsed times on the osstream, depending on internal display From 65999ac6d6c2d8d1cc1b7b30f38366bf67f96054 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 6 Jun 2020 23:30:16 +0200 Subject: [PATCH 099/307] pool var no param is one now --- datapool/PoolVariableIF.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/datapool/PoolVariableIF.h b/datapool/PoolVariableIF.h index 3086bbe8..6a2900bf 100644 --- a/datapool/PoolVariableIF.h +++ b/datapool/PoolVariableIF.h @@ -27,7 +27,7 @@ public: static constexpr bool VALID = 1; static constexpr bool INVALID = 0; - static constexpr uint32_t NO_PARAMETER = 0; + static constexpr uint32_t NO_PARAMETER = 0xffffffff; enum ReadWriteMode_t { VAR_READ, VAR_WRITE, VAR_READ_WRITE From c81613690be10ae70c6e18f373a303d77b80052c Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 6 Jun 2020 23:41:54 +0200 Subject: [PATCH 100/307] no_queue value is 0xffffffff now --- ipc/MessageQueueIF.h | 2 ++ ipc/MessageQueueSenderIF.h | 2 +- memory/MemoryHelper.cpp | 26 ++++++++++++-------------- tcdistribution/PUSDistributor.cpp | 27 ++++++++++++--------------- 4 files changed, 27 insertions(+), 30 deletions(-) diff --git a/ipc/MessageQueueIF.h b/ipc/MessageQueueIF.h index c67f3870..480019eb 100644 --- a/ipc/MessageQueueIF.h +++ b/ipc/MessageQueueIF.h @@ -2,6 +2,8 @@ #define FRAMEWORK_IPC_MESSAGEQUEUEIF_H_ // COULDDO: We could support blocking calls +// semaphores are being implemented, which makes this idea even more iteresting. + /** * @defgroup message_queue Message Queue diff --git a/ipc/MessageQueueSenderIF.h b/ipc/MessageQueueSenderIF.h index 6eb7733d..ae66cd12 100644 --- a/ipc/MessageQueueSenderIF.h +++ b/ipc/MessageQueueSenderIF.h @@ -16,7 +16,7 @@ typedef uint32_t MessageQueueId_t; class MessageQueueSenderIF { public: - static const MessageQueueId_t NO_QUEUE = 0; + static const MessageQueueId_t NO_QUEUE = 0xffffffff; virtual ~MessageQueueSenderIF() {} diff --git a/memory/MemoryHelper.cpp b/memory/MemoryHelper.cpp index 2a830c5a..b078d6ec 100644 --- a/memory/MemoryHelper.cpp +++ b/memory/MemoryHelper.cpp @@ -33,15 +33,6 @@ ReturnValue_t MemoryHelper::handleMemoryCommand(CommandMessage* message) { } } -ReturnValue_t MemoryHelper::initialize() { - ipcStore = objectManager->get(objects::IPC_STORE); - if (ipcStore != NULL) { - return RETURN_OK; - } else { - return RETURN_FAILED; - } -} - void MemoryHelper::completeLoad(ReturnValue_t errorCode, const uint8_t* dataToCopy, const uint32_t size, uint8_t* copyHere) { busy = false; @@ -185,11 +176,18 @@ void MemoryHelper::handleMemoryCheckOrDump(CommandMessage* message) { } ReturnValue_t MemoryHelper::initialize(MessageQueueIF* queueToUse_) { - if(queueToUse_!=NULL){ - this->queueToUse = queueToUse_; - }else{ - return MessageQueueIF::NO_QUEUE; + if(queueToUse_ == nullptr) { + return HasReturnvaluesIF::RETURN_FAILED; } - + this->queueToUse = queueToUse_; return initialize(); } + +ReturnValue_t MemoryHelper::initialize() { + ipcStore = objectManager->get(objects::IPC_STORE); + if (ipcStore != nullptr) { + return RETURN_OK; + } else { + return RETURN_FAILED; + } +} diff --git a/tcdistribution/PUSDistributor.cpp b/tcdistribution/PUSDistributor.cpp index f4764c4e..bcf6d571 100644 --- a/tcdistribution/PUSDistributor.cpp +++ b/tcdistribution/PUSDistributor.cpp @@ -4,15 +4,13 @@ #include #include -PUSDistributor::PUSDistributor(uint16_t setApid, object_id_t setObjectId, object_id_t setPacketSource) : - TcDistributor(setObjectId), checker(setApid), verifyChannel(), currentPacket(), tcStatus( - RETURN_FAILED), packetSource(setPacketSource) { +PUSDistributor::PUSDistributor(uint16_t setApid, object_id_t setObjectId, + object_id_t setPacketSource) : + TcDistributor(setObjectId), checker(setApid), verifyChannel(), + currentPacket(), tcStatus(RETURN_FAILED), + packetSource(setPacketSource) {} -} - -PUSDistributor::~PUSDistributor() { - -} +PUSDistributor::~PUSDistributor() {} iterator_t PUSDistributor::selectDestination() { // debug << "PUSDistributor::handlePacket received: " << this->current_packet_id.store_index << ", " << this->current_packet_id.packet_index << std::endl; @@ -45,18 +43,17 @@ iterator_t PUSDistributor::selectDestination() { //} ReturnValue_t PUSDistributor::registerService(AcceptsTelecommandsIF* service) { - ReturnValue_t returnValue = RETURN_OK; - bool errorCode = true; uint16_t serviceId = service->getIdentifier(); //info << "Service ID: " << (int)serviceId << std::endl; MessageQueueId_t queue = service->getRequestQueue(); - errorCode = this->queueMap.insert( - std::pair(serviceId, queue)).second; - if (errorCode == false) { + auto returnPair = queueMap.emplace(serviceId, queue); + if (not returnPair.second) { //TODO Return Code - returnValue = MessageQueueIF::NO_QUEUE; + sif::error << "PUSDistributor::registerService: Service ID already" + "exists in map." << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; } - return returnValue; + return HasReturnvaluesIF::RETURN_OK; } MessageQueueId_t PUSDistributor::getRequestQueue() { From 33cc8591dc2f2ca920dbe86d05e35f8aa40c736c Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 7 Jun 2020 01:17:24 +0200 Subject: [PATCH 101/307] yaaay, hardcoded values --- health/HealthHelper.cpp | 5 ++-- health/HealthHelper.h | 11 ++++---- memory/MemoryHelper.cpp | 8 +++--- memory/MemoryHelper.h | 10 +++---- modes/ModeHelper.cpp | 48 ++++++++++++++++++++++------------ modes/ModeHelper.h | 8 ++++-- parameters/ParameterHelper.cpp | 4 +-- parameters/ParameterHelper.h | 9 ++++--- 8 files changed, 61 insertions(+), 42 deletions(-) diff --git a/health/HealthHelper.cpp b/health/HealthHelper.cpp index 3a345287..fdfc0967 100644 --- a/health/HealthHelper.cpp +++ b/health/HealthHelper.cpp @@ -1,9 +1,8 @@ #include -#include #include + HealthHelper::HealthHelper(HasHealthIF* owner, object_id_t objectId) : - healthTable(NULL), eventSender(NULL), objectId(objectId), parentQueue( - 0), owner(owner) { + objectId(objectId), owner(owner) { } HealthHelper::~HealthHelper() { diff --git a/health/HealthHelper.h b/health/HealthHelper.h index 24fd0d14..a17a69f3 100644 --- a/health/HealthHelper.h +++ b/health/HealthHelper.h @@ -1,11 +1,12 @@ -#ifndef HEALTHHELPER_H_ -#define HEALTHHELPER_H_ +#ifndef FRAMEWORK_HEALTH_HEALTHHELPER_H_ +#define FRAMEWORK_HEALTH_HEALTHHELPER_H_ #include #include #include #include #include +#include #include #include @@ -39,12 +40,12 @@ public: * * only valid after initialize() has been called */ - HealthTableIF *healthTable; + HealthTableIF *healthTable = nullptr; /** * Proxy to forward events. */ - EventReportingProxyIF* eventSender; + EventReportingProxyIF* eventSender = nullptr; /** * Try to handle the message. @@ -100,7 +101,7 @@ private: /** * The Queue of the parent */ - MessageQueueId_t parentQueue; + MessageQueueId_t parentQueue = MessageQueueIF::NO_QUEUE; /** * The one using the healthHelper. diff --git a/memory/MemoryHelper.cpp b/memory/MemoryHelper.cpp index b078d6ec..de609252 100644 --- a/memory/MemoryHelper.cpp +++ b/memory/MemoryHelper.cpp @@ -5,10 +5,10 @@ #include #include -MemoryHelper::MemoryHelper(HasMemoryIF* workOnThis, MessageQueueIF* useThisQueue) : - workOnThis(workOnThis), queueToUse(useThisQueue), ipcStore(NULL), ipcAddress(), lastCommand( - CommandMessage::CMD_NONE), lastSender(0), reservedSpaceInIPC( - NULL), busy(false) { +MemoryHelper::MemoryHelper(HasMemoryIF* workOnThis, + MessageQueueIF* useThisQueue): + workOnThis(workOnThis), queueToUse(useThisQueue), ipcStore(nullptr), + ipcAddress(), lastCommand(CommandMessage::CMD_NONE), busy(false) { } ReturnValue_t MemoryHelper::handleMemoryCommand(CommandMessage* message) { diff --git a/memory/MemoryHelper.h b/memory/MemoryHelper.h index 2ff82eb3..da6b9bdb 100644 --- a/memory/MemoryHelper.h +++ b/memory/MemoryHelper.h @@ -1,5 +1,5 @@ -#ifndef MEMORYHELPER_H_ -#define MEMORYHELPER_H_ +#ifndef FRAMEWORK_MEMORY_MEMORYHELPER_H_ +#define FRAMEWORK_MEMORY_MEMORYHELPER_H_ #include #include #include @@ -16,11 +16,11 @@ public: private: HasMemoryIF* workOnThis; MessageQueueIF* queueToUse; - StorageManagerIF* ipcStore; + StorageManagerIF* ipcStore = nullptr; store_address_t ipcAddress; Command_t lastCommand; - MessageQueueId_t lastSender; - uint8_t* reservedSpaceInIPC; + MessageQueueId_t lastSender = MessageQueueIF::NO_QUEUE; + uint8_t* reservedSpaceInIPC = nullptr; bool busy; void handleMemoryLoad(CommandMessage* message); void handleMemoryCheckOrDump(CommandMessage* message); diff --git a/modes/ModeHelper.cpp b/modes/ModeHelper.cpp index d9266c35..66726772 100644 --- a/modes/ModeHelper.cpp +++ b/modes/ModeHelper.cpp @@ -1,13 +1,11 @@ #include #include -#include #include ModeHelper::ModeHelper(HasModesIF *owner) : - theOneWhoCommandedAMode(0), commandedMode(HasModesIF::MODE_OFF), commandedSubmode( - HasModesIF::SUBMODE_NONE), owner(owner), parentQueueId(0), forced( - false) { -} + commandedMode(HasModesIF::MODE_OFF), + commandedSubmode(HasModesIF::SUBMODE_NONE), + owner(owner), forced(false) {} ModeHelper::~ModeHelper() { @@ -71,27 +69,45 @@ ReturnValue_t ModeHelper::initialize(MessageQueueId_t parentQueueId) { return initialize(); } -void ModeHelper::modeChanged(Mode_t mode, Submode_t submode) { +void ModeHelper::modeChanged(Mode_t ownerMode, Submode_t ownerSubmode) { forced = false; + sendModeReplyMessage(ownerMode, ownerSubmode); + sendModeInfoMessage(ownerMode, ownerSubmode); + theOneWhoCommandedAMode = MessageQueueSenderIF::NO_QUEUE; +} + +void ModeHelper::sendModeReplyMessage(Mode_t ownerMode, + Submode_t ownerSubmode) { CommandMessage reply; - if (theOneWhoCommandedAMode != MessageQueueSenderIF::NO_QUEUE) { - if ((mode != commandedMode) || (submode != commandedSubmode)) { + if (theOneWhoCommandedAMode != MessageQueueSenderIF::NO_QUEUE) + { + if (ownerMode != commandedMode or ownerSubmode != commandedSubmode) + { ModeMessage::setModeMessage(&reply, - ModeMessage::REPLY_WRONG_MODE_REPLY, mode, submode); - } else { + ModeMessage::REPLY_WRONG_MODE_REPLY, ownerMode, + ownerSubmode); + } + else + { ModeMessage::setModeMessage(&reply, ModeMessage::REPLY_MODE_REPLY, - mode, submode); + ownerMode, ownerSubmode); } MessageQueueSenderIF::sendMessage(theOneWhoCommandedAMode, &reply, owner->getCommandQueue()); } +} + +void ModeHelper::sendModeInfoMessage(Mode_t ownerMode, + Submode_t ownerSubmode) { + CommandMessage reply; if (theOneWhoCommandedAMode != parentQueueId - && parentQueueId != MessageQueueSenderIF::NO_QUEUE) { - ModeMessage::setModeMessage(&reply, ModeMessage::REPLY_MODE_INFO, mode, - submode); - MessageQueueSenderIF::sendMessage(parentQueueId, &reply, owner->getCommandQueue()); + and parentQueueId != MessageQueueSenderIF::NO_QUEUE) + { + ModeMessage::setModeMessage(&reply, ModeMessage::REPLY_MODE_INFO, + ownerMode, ownerSubmode); + MessageQueueSenderIF::sendMessage(parentQueueId, &reply, + owner->getCommandQueue()); } - theOneWhoCommandedAMode = MessageQueueSenderIF::NO_QUEUE; } void ModeHelper::startTimer(uint32_t timeoutMs) { diff --git a/modes/ModeHelper.h b/modes/ModeHelper.h index 87f6d411..b7f5868d 100644 --- a/modes/ModeHelper.h +++ b/modes/ModeHelper.h @@ -1,6 +1,7 @@ #ifndef MODEHELPER_H_ #define MODEHELPER_H_ +#include #include #include #include @@ -9,7 +10,7 @@ class HasModesIF; class ModeHelper { public: - MessageQueueId_t theOneWhoCommandedAMode; + MessageQueueId_t theOneWhoCommandedAMode = MessageQueueIF::NO_QUEUE; Mode_t commandedMode; Submode_t commandedSubmode; @@ -39,11 +40,14 @@ public: void setForced(bool forced); protected: HasModesIF *owner; - MessageQueueId_t parentQueueId; + MessageQueueId_t parentQueueId = MessageQueueIF::NO_QUEUE; Countdown countdown; bool forced; +private: + void sendModeReplyMessage(Mode_t ownerMode, Submode_t ownerSubmode); + void sendModeInfoMessage(Mode_t ownerMode, Submode_t ownerSubmode); }; #endif /* MODEHELPER_H_ */ diff --git a/parameters/ParameterHelper.cpp b/parameters/ParameterHelper.cpp index 4ba2a1d9..e0756882 100644 --- a/parameters/ParameterHelper.cpp +++ b/parameters/ParameterHelper.cpp @@ -3,9 +3,7 @@ #include ParameterHelper::ParameterHelper(ReceivesParameterMessagesIF* owner) : - owner(owner), ownerQueueId(0), storage(NULL){ - -} + owner(owner) {} ParameterHelper::~ParameterHelper() { } diff --git a/parameters/ParameterHelper.h b/parameters/ParameterHelper.h index e2fefdba..defe2925 100644 --- a/parameters/ParameterHelper.h +++ b/parameters/ParameterHelper.h @@ -1,6 +1,7 @@ -#ifndef PARAMETERHELPER_H_ -#define PARAMETERHELPER_H_ +#ifndef FRAMEWORK_PARAMETERS_PARAMETERHELPER_H_ +#define FRAMEWORK_PARAMETERS_PARAMETERHELPER_H_ +#include #include #include @@ -15,9 +16,9 @@ public: private: ReceivesParameterMessagesIF *owner; - MessageQueueId_t ownerQueueId; + MessageQueueId_t ownerQueueId = MessageQueueIF::NO_QUEUE; - StorageManagerIF *storage; + StorageManagerIF *storage = nullptr; ReturnValue_t sendParameter(MessageQueueId_t to, uint32_t id, const ParameterWrapper *description); From 3c80bdfefa8149823ed9fb6273cabaac3d02ccc0 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 7 Jun 2020 01:18:19 +0200 Subject: [PATCH 102/307] some linebreaks --- parameters/ParameterHelper.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/parameters/ParameterHelper.h b/parameters/ParameterHelper.h index defe2925..352cf0a9 100644 --- a/parameters/ParameterHelper.h +++ b/parameters/ParameterHelper.h @@ -20,9 +20,11 @@ private: StorageManagerIF *storage = nullptr; - ReturnValue_t sendParameter(MessageQueueId_t to, uint32_t id, const ParameterWrapper *description); + ReturnValue_t sendParameter(MessageQueueId_t to, uint32_t id, + const ParameterWrapper *description); - void rejectCommand(MessageQueueId_t to, ReturnValue_t reason, Command_t initialCommand); + void rejectCommand(MessageQueueId_t to, ReturnValue_t reason, + Command_t initialCommand); }; #endif /* PARAMETERHELPER_H_ */ From d0b218c18e2cdd65405903626566f5c996064876 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 7 Jun 2020 01:40:48 +0200 Subject: [PATCH 103/307] renaming for host os --- osal/host/MessageQueue.cpp | 2 +- osal/host/MessageQueue.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osal/host/MessageQueue.cpp b/osal/host/MessageQueue.cpp index 7d5e4d97..7e68fd5b 100644 --- a/osal/host/MessageQueue.cpp +++ b/osal/host/MessageQueue.cpp @@ -135,7 +135,7 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, return HasReturnvaluesIF::RETURN_OK; } -ReturnValue_t MessageQueue::lockQueue(millis_t lockTimeout) { +ReturnValue_t MessageQueue::lockQueue(dur_millis_t lockTimeout) { return queueLock->lockMutex(lockTimeout); } diff --git a/osal/host/MessageQueue.h b/osal/host/MessageQueue.h index a0cce001..619b5e91 100644 --- a/osal/host/MessageQueue.h +++ b/osal/host/MessageQueue.h @@ -182,7 +182,7 @@ public: bool isDefaultDestinationSet() const override; - ReturnValue_t lockQueue(millis_t lockTimeout); + ReturnValue_t lockQueue(dur_millis_t lockTimeout); ReturnValue_t unlockQueue(); protected: /** From fe5b50d8857bb07d7c84d2a89e8cf79d65f6d7a6 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 7 Jun 2020 02:22:18 +0200 Subject: [PATCH 104/307] improved documentation signigicantly --- datapool/PoolVariableIF.h | 14 +++--- .../LocalDataPoolManager.cpp | 25 ++++++----- .../LocalDataPoolManager.h | 45 +++++++++++++------ datapoollocal/LocalDataSet.cpp | 6 +-- datapoollocal/LocalDataSet.h | 8 ++-- datapoollocal/LocalPoolVariable.h | 34 ++++++++------ datapoollocal/LocalPoolVariable.tpp | 10 ++--- datapoollocal/LocalPoolVector.h | 6 +-- datapoollocal/LocalPoolVector.tpp | 6 +-- .../OwnsLocalDataPoolIF.h | 33 ++++++++------ devicehandlers/DeviceHandlerBase.cpp | 4 +- devicehandlers/DeviceHandlerBase.h | 14 +++--- 12 files changed, 118 insertions(+), 87 deletions(-) rename housekeeping/HousekeepingManager.cpp => datapoollocal/LocalDataPoolManager.cpp (69%) rename housekeeping/HousekeepingManager.h => datapoollocal/LocalDataPoolManager.h (71%) rename housekeeping/HasHkPoolParametersIF.h => datapoollocal/OwnsLocalDataPoolIF.h (58%) diff --git a/datapool/PoolVariableIF.h b/datapool/PoolVariableIF.h index 6a2900bf..30b87839 100644 --- a/datapool/PoolVariableIF.h +++ b/datapool/PoolVariableIF.h @@ -1,12 +1,12 @@ -#ifndef POOLVARIABLEIF_H_ -#define POOLVARIABLEIF_H_ +#ifndef FRAMEWORK_DATAPOOL_POOLVARIABLEIF_H_ +#define FRAMEWORK_DATAPOOL_POOLVARIABLEIF_H_ #include #include - /** - * @brief This interface is used to control data pool variable representations. + * @brief This interface is used to control data pool + * variable representations. * @details * To securely handle data pool variables, all pool entries are locally * managed by data pool variable access classes, which are called pool @@ -39,7 +39,8 @@ public: */ virtual ~PoolVariableIF() {} /** - * @brief This method returns if the variable is write-only, read-write or read-only. + * @brief This method returns if the variable is write-only, + * read-write or read-only. */ virtual ReadWriteMode_t getReadWriteMode() const = 0; /** @@ -47,7 +48,8 @@ public: */ virtual uint32_t getDataPoolId() const = 0; /** - * @brief With this call, the valid information of the variable is returned. + * @brief With this call, the valid information of the + * variable is returned. */ virtual bool isValid() const = 0; /** diff --git a/housekeeping/HousekeepingManager.cpp b/datapoollocal/LocalDataPoolManager.cpp similarity index 69% rename from housekeeping/HousekeepingManager.cpp rename to datapoollocal/LocalDataPoolManager.cpp index e8edcc39..78e57c8c 100644 --- a/housekeeping/HousekeepingManager.cpp +++ b/datapoollocal/LocalDataPoolManager.cpp @@ -1,12 +1,12 @@ +#include #include -#include #include #include #include #include -HousekeepingManager::HousekeepingManager(HasHkPoolParametersIF* owner) { +LocalDataPoolManager::LocalDataPoolManager(OwnsLocalDataPoolIF* owner) { if(owner == nullptr) { sif::error << "HkManager: Invalid supplied owner!" << std::endl; std::exit(0); @@ -16,11 +16,12 @@ HousekeepingManager::HousekeepingManager(HasHkPoolParametersIF* owner) { //owner->setMinimalHkSamplingFrequency(); } -HousekeepingManager::~HousekeepingManager() {} +LocalDataPoolManager::~LocalDataPoolManager() {} -ReturnValue_t HousekeepingManager::initializeHousekeepingPoolEntriesOnce() { +ReturnValue_t LocalDataPoolManager::initializeHousekeepingPoolEntriesOnce() { if(not mapInitialized) { - ReturnValue_t result = owner->initializeHousekeepingPoolEntries(localDpMap); + ReturnValue_t result = + owner->initializeHousekeepingPoolEntries(localDpMap); if(result == HasReturnvaluesIF::RETURN_OK) { mapInitialized = true; } @@ -30,24 +31,24 @@ ReturnValue_t HousekeepingManager::initializeHousekeepingPoolEntriesOnce() { return HasReturnvaluesIF::RETURN_OK; } -ReturnValue_t HousekeepingManager::handleHousekeepingMessage( +ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage( CommandMessage *message) { return HasReturnvaluesIF::RETURN_OK; } -ReturnValue_t HousekeepingManager::printPoolEntry( +ReturnValue_t LocalDataPoolManager::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; + return OwnsLocalDataPoolIF::POOL_ENTRY_NOT_FOUND; } poolIter->second->print(); return HasReturnvaluesIF::RETURN_OK; } -MutexIF* HousekeepingManager::getMutexHandle() { +MutexIF* LocalDataPoolManager::getMutexHandle() { return mutex; } @@ -56,7 +57,7 @@ MutexIF* HousekeepingManager::getMutexHandle() { // //} -void HousekeepingManager::generateHousekeepingPacket(sid_t sid) { +void LocalDataPoolManager::generateHousekeepingPacket(sid_t sid) { LocalDataSet* dataSetToSerialize = dynamic_cast( owner->getDataSetHandle(sid)); if(dataSetToSerialize == nullptr) { @@ -73,10 +74,10 @@ void HousekeepingManager::generateHousekeepingPacket(sid_t sid) { } -void HousekeepingManager::setHkPacketQueue(MessageQueueIF *msgQueue) { +void LocalDataPoolManager::setHkPacketQueue(MessageQueueIF *msgQueue) { this->hkPacketQueue = msgQueue; } -const HasHkPoolParametersIF* HousekeepingManager::getOwner() const { +const OwnsLocalDataPoolIF* LocalDataPoolManager::getOwner() const { return owner; } diff --git a/housekeeping/HousekeepingManager.h b/datapoollocal/LocalDataPoolManager.h similarity index 71% rename from housekeeping/HousekeepingManager.h rename to datapoollocal/LocalDataPoolManager.h index 43922ae6..c8a6bf15 100644 --- a/housekeeping/HousekeepingManager.h +++ b/datapoollocal/LocalDataPoolManager.h @@ -2,19 +2,35 @@ #define FRAMEWORK_HK_HOUSEKEEPINGHELPER_H_ #include #include -#include #include #include #include +#include #include #include #include #include - -class HousekeepingManager { +/** + * @brief This class is the managing instance for local data pool. + * @details + * The actual data pool structure is a member of this class. Any class which + * has a local data pool shall have this class as a member and implement + * the OwnsLocalDataPoolIF. + * + * Users of the data pool use the helper classes LocalDataSet, + * LocalPoolVariable and LocalPoolVector to access pool entries in + * a thread-safe and efficient way. + * + * The local data pools employ a blackboard logic: Only the most recent + * value is stored. The helper classes offer a read() and commit() interface + * through the PoolVariableIF which is used to read and update values. + * Each pool entry has a valid state too. + * + */ +class LocalDataPoolManager { template friend class LocalPoolVar; template @@ -23,8 +39,8 @@ class HousekeepingManager { public: static constexpr float MINIMAL_SAMPLING_FREQUENCY = 0.2; - HousekeepingManager(HasHkPoolParametersIF* owner); - virtual~ HousekeepingManager(); + LocalDataPoolManager(OwnsLocalDataPoolIF* owner); + virtual~ LocalDataPoolManager(); // propably will just call respective local data set functions. @@ -40,7 +56,7 @@ public: ReturnValue_t initializeHousekeepingPoolEntriesOnce(); void setHkPacketQueue(MessageQueueIF* msgQueue); - const HasHkPoolParametersIF* getOwner() const; + const OwnsLocalDataPoolIF* getOwner() const; ReturnValue_t printPoolEntry(lp_id_t localPoolId); @@ -48,14 +64,14 @@ private: //! This is the map holding the actual data. Should only be initialized //! once ! bool mapInitialized = false; - LocalDataPoolMap localDpMap; + LocalDataPool localDpMap; //! 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). - HasHkPoolParametersIF* owner = nullptr; + OwnsLocalDataPoolIF* owner = nullptr; //! Used for replies. //! (maybe we dont need this, the sender can be retrieved from command @@ -85,27 +101,28 @@ private: * supplied pointer. * @return */ - template - ReturnValue_t fetchPoolEntry(lp_id_t localPoolId, PoolEntry **poolEntry); - void setMinimalSamplingFrequency(float frequencySeconds); + template ReturnValue_t fetchPoolEntry(lp_id_t localPoolId, + PoolEntry **poolEntry); + void setMinimalSamplingFrequency(float frequencySeconds); }; + template inline -ReturnValue_t HousekeepingManager::fetchPoolEntry(lp_id_t localPoolId, +ReturnValue_t LocalDataPoolManager::fetchPoolEntry(lp_id_t localPoolId, PoolEntry **poolEntry) { 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; + return OwnsLocalDataPoolIF::POOL_ENTRY_NOT_FOUND; } *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 OwnsLocalDataPoolIF::POOL_ENTRY_TYPE_CONFLICT; } return HasReturnvaluesIF::RETURN_OK; } diff --git a/datapoollocal/LocalDataSet.cpp b/datapoollocal/LocalDataSet.cpp index 988f254a..243c9cc1 100644 --- a/datapoollocal/LocalDataSet.cpp +++ b/datapoollocal/LocalDataSet.cpp @@ -1,7 +1,7 @@ +#include #include -#include -LocalDataSet::LocalDataSet(HasHkPoolParametersIF *hkOwner): DataSetBase() { +LocalDataSet::LocalDataSet(OwnsLocalDataPoolIF *hkOwner): DataSetBase() { if(hkOwner != nullptr) { hkManager = hkOwner->getHkManagerHandle(); } @@ -11,7 +11,7 @@ LocalDataSet::LocalDataSet(HasHkPoolParametersIF *hkOwner): DataSetBase() { } LocalDataSet::LocalDataSet(object_id_t ownerId): DataSetBase() { - HasHkPoolParametersIF* hkOwner = objectManager->get( + OwnsLocalDataPoolIF* hkOwner = objectManager->get( ownerId); if(hkOwner == nullptr) { // config error, error output here. diff --git a/datapoollocal/LocalDataSet.h b/datapoollocal/LocalDataSet.h index 607d10b3..54da5562 100644 --- a/datapoollocal/LocalDataSet.h +++ b/datapoollocal/LocalDataSet.h @@ -2,10 +2,10 @@ #define FRAMEWORK_DATAPOOLLOCAL_LOCALDATASET_H_ #include #include -#include +#include #include -class HousekeepingManager; +class LocalDataPoolManager; /** * @brief The LocalDataSet class manages a set of locally checked out variables @@ -35,7 +35,7 @@ public: * The constructor simply sets the fill_count to zero and sets * the state to "uninitialized". */ - LocalDataSet(HasHkPoolParametersIF* hkOwner); + LocalDataSet(OwnsLocalDataPoolIF* hkOwner); /** * @brief Constructor for users of local pool data. The passed pool @@ -78,7 +78,7 @@ private: */ ReturnValue_t unlockDataPool() override; - HousekeepingManager* hkManager; + LocalDataPoolManager* hkManager; }; #endif /* FRAMEWORK_DATAPOOLLOCAL_LOCALDATASET_H_ */ diff --git a/datapoollocal/LocalPoolVariable.h b/datapoollocal/LocalPoolVariable.h index b6bfa5b8..4b6e24aa 100644 --- a/datapoollocal/LocalPoolVariable.h +++ b/datapoollocal/LocalPoolVariable.h @@ -3,11 +3,11 @@ #include #include -#include +#include +#include #include #include -#include /** * @brief Local Pool Variable class which is used to access the local pools. @@ -29,9 +29,12 @@ public: /** * This constructor is used by the data creators to have pool variable * instances which can also be stored in datasets. - * It does not fetch the current value from the data pool. This is performed - * by the read() operation (which is not thread-safe). - * Datasets can be used to access local pool entires in a thread-safe way. + * + * It does not fetch the current value from the data pool, which + * has to be done by calling the read() operation. + * Datasets can be used to access multiple local pool entries in an + * efficient way. A pointer to a dataset can be passed to register + * the pool variable in that dataset directly. * @param poolId ID of the local pool entry. * @param hkOwner Pointer of the owner. This will generally be the calling * class itself which passes "this". @@ -39,7 +42,7 @@ public: * @param dataSet The data set in which the variable shall register itself. * If nullptr, the variable is not registered. */ - LocalPoolVar(lp_id_t poolId, HasHkPoolParametersIF* hkOwner, + LocalPoolVar(lp_id_t poolId, OwnsLocalDataPoolIF* hkOwner, pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE, DataSetIF* dataSet = nullptr); @@ -47,12 +50,14 @@ public: * This constructor is used by data users like controllers to have * access to the local pool variables of data creators by supplying * the respective creator object ID. - * It does not fetch the current value from the data pool. This is performed - * by the read() operation (which is not thread-safe). - * Datasets can be used to access local pool entires in a thread-safe way. + * + * It does not fetch the current value from the data pool, which + * has to be done by calling the read() operation. + * Datasets can be used to access multiple local pool entries in an + * efficient way. A pointer to a dataset can be passed to register + * the pool variable in that dataset directly. * @param poolId ID of the local pool entry. - * @param hkOwner Pointer of the owner. This will generally be the calling - * class itself which passes "this". + * @param hkOwner object ID of the pool owner. * @param setReadWriteMode Specify the read-write mode of the pool variable. * @param dataSet The data set in which the variable shall register itself. * If nullptr, the variable is not registered. @@ -99,7 +104,7 @@ public: * at once to avoid the overhead of unnecessary lock und unlock operations. * */ - ReturnValue_t read(uint32_t lockTimeout = MutexIF::BLOCKING) override; + ReturnValue_t read(dur_millis_t lockTimeout = MutexIF::BLOCKING) override; /** * @brief The commit call copies the array values back to the data pool. * @details @@ -109,7 +114,8 @@ public: * It is recommended to use DataSets to read and commit multiple variables * at once to avoid the overhead of unnecessary lock und unlock operations. */ - ReturnValue_t commit(uint32_t lockTimeout = MutexIF::BLOCKING) override; + ReturnValue_t commit(dur_millis_t lockTimeout = MutexIF::BLOCKING) override; + protected: /** * @brief Like #read, but without a lock protection of the global pool. @@ -144,7 +150,7 @@ private: bool valid = false; //! Pointer to the class which manages the HK pool. - HousekeepingManager* hkManager; + LocalDataPoolManager* hkManager; }; #include diff --git a/datapoollocal/LocalPoolVariable.tpp b/datapoollocal/LocalPoolVariable.tpp index 663b73f5..0140b29d 100644 --- a/datapoollocal/LocalPoolVariable.tpp +++ b/datapoollocal/LocalPoolVariable.tpp @@ -7,7 +7,7 @@ template inline LocalPoolVar::LocalPoolVar(lp_id_t poolId, - HasHkPoolParametersIF* hkOwner, pool_rwm_t setReadWriteMode, + OwnsLocalDataPoolIF* hkOwner, pool_rwm_t setReadWriteMode, DataSetIF* dataSet): localPoolId(poolId),readWriteMode(setReadWriteMode) { if(poolId == PoolVariableIF::NO_PARAMETER) { @@ -33,8 +33,8 @@ inline LocalPoolVar::LocalPoolVar(lp_id_t poolId, object_id_t poolOwner, sif::warning << "LocalPoolVector: 0 passed as pool ID, which is the " "NO_PARAMETER value!" << std::endl; } - HasHkPoolParametersIF* hkOwner = - objectManager->get(poolOwner); + OwnsLocalDataPoolIF* hkOwner = + objectManager->get(poolOwner); if(hkOwner == nullptr) { sif::error << "LocalPoolVariable: The supplied pool owner did not implement" "the correct interface HasHkPoolParametersIF!" << std::endl; @@ -47,7 +47,7 @@ inline LocalPoolVar::LocalPoolVar(lp_id_t poolId, object_id_t poolOwner, } template -inline ReturnValue_t LocalPoolVar::read(millis_t lockTimeout) { +inline ReturnValue_t LocalPoolVar::read(dur_millis_t lockTimeout) { MutexHelper(hkManager->getMutexHandle(), lockTimeout); return readWithoutLock(); } @@ -75,7 +75,7 @@ inline ReturnValue_t LocalPoolVar::readWithoutLock() { } template -inline ReturnValue_t LocalPoolVar::commit(millis_t lockTimeout) { +inline ReturnValue_t LocalPoolVar::commit(dur_millis_t lockTimeout) { MutexHelper(hkManager->getMutexHandle(), lockTimeout); return commitWithoutLock(); } diff --git a/datapoollocal/LocalPoolVector.h b/datapoollocal/LocalPoolVector.h index 74615151..1c5f1d65 100644 --- a/datapoollocal/LocalPoolVector.h +++ b/datapoollocal/LocalPoolVector.h @@ -4,8 +4,8 @@ #include #include #include +#include #include -#include #include @@ -46,7 +46,7 @@ public: * @param dataSet The data set in which the variable shall register itself. * If nullptr, the variable is not registered. */ - LocalPoolVector(lp_id_t poolId, HasHkPoolParametersIF* hkOwner, + LocalPoolVector(lp_id_t poolId, OwnsLocalDataPoolIF* hkOwner, pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE, DataSetIF* dataSet = nullptr); @@ -179,7 +179,7 @@ private: */ ReadWriteMode_t readWriteMode; //! @brief Pointer to the class which manages the HK pool. - HousekeepingManager* hkManager; + LocalDataPoolManager* hkManager; // std::ostream is the type for object std::cout template diff --git a/datapoollocal/LocalPoolVector.tpp b/datapoollocal/LocalPoolVector.tpp index 9a00e5df..bd35eed3 100644 --- a/datapoollocal/LocalPoolVector.tpp +++ b/datapoollocal/LocalPoolVector.tpp @@ -7,7 +7,7 @@ template inline LocalPoolVector::LocalPoolVector(lp_id_t poolId, - HasHkPoolParametersIF* hkOwner, pool_rwm_t setReadWriteMode, + OwnsLocalDataPoolIF* hkOwner, pool_rwm_t setReadWriteMode, DataSetIF* dataSet) : localPoolId(poolId), valid(false), readWriteMode(setReadWriteMode) { if(poolId == PoolVariableIF::NO_PARAMETER) { @@ -29,8 +29,8 @@ inline LocalPoolVector::LocalPoolVector(lp_id_t poolId, sif::warning << "LocalPoolVector: 0 passed as pool ID, which is the " "NO_PARAMETER value!" << std::endl; } - HasHkPoolParametersIF* hkOwner = - objectManager->get(poolOwner); + OwnsLocalDataPoolIF* hkOwner = + objectManager->get(poolOwner); if(hkOwner == nullptr) { sif::error << "LocalPoolVariable: The supplied pool owner did not implement" "the correct interface HasHkPoolParametersIF!" << std::endl; diff --git a/housekeeping/HasHkPoolParametersIF.h b/datapoollocal/OwnsLocalDataPoolIF.h similarity index 58% rename from housekeeping/HasHkPoolParametersIF.h rename to datapoollocal/OwnsLocalDataPoolIF.h index 62715a3d..cf94f946 100644 --- a/housekeeping/HasHkPoolParametersIF.h +++ b/datapoollocal/OwnsLocalDataPoolIF.h @@ -5,33 +5,40 @@ #include #include -class HousekeepingManager; +class LocalDataPoolManager; class DataSetIF; /** * @brief Type definition for local pool entries. */ using lp_id_t = uint32_t; -using LocalDataPoolMap = std::map; -using LocalDataPoolMapIter = LocalDataPoolMap::iterator; +using LocalDataPool = std::map; +using LocalDataPoolMapIter = LocalDataPool::iterator; /** * @brief This interface is implemented by classes which posses a local - * data pool (not the managing class) + * data pool (not the managing class). It defines the relationship + * between the local data pool owner and the LocalDataPoolManager. * @details - * Any class implementing this interface shall also have a HousekeepingManager - * member class which handles the retrieval of the local pool data. + * Any class implementing this interface shall also have a LocalDataPoolManager + * member class which contains the actual pool data structure + * and exposes the public interface for it. * This is required because the pool entries are templates, which makes - * specifying an interface rather difficult. + * specifying an interface rather difficult. The local data pool can be + * accessed by using the LocalPoolVariable, LocalPoolVector or LocalDataSet + * classes. * - * This could be circumvented by using a wrapper/accessor function, but + * Architectural Note: + * This could be circumvented by using a wrapper/accessor function or + * implementing the templated function in this interface.. + * The first solution sounds better than the second 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. + * of the LocalDataPoolManager. */ -class HasHkPoolParametersIF { +class OwnsLocalDataPoolIF { public: - virtual~ HasHkPoolParametersIF() {}; + virtual~ OwnsLocalDataPoolIF() {}; static constexpr uint8_t INTERFACE_ID = CLASS_ID::HOUSEKEEPING; static constexpr ReturnValue_t POOL_ENTRY_NOT_FOUND = MAKE_RETURN_CODE(0XA0); @@ -39,9 +46,9 @@ public: virtual MessageQueueId_t getCommandQueue() const = 0; virtual ReturnValue_t initializeHousekeepingPoolEntries( - LocalDataPoolMap& localDataPoolMap) = 0; + LocalDataPool& localDataPoolMap) = 0; //virtual float setMinimalHkSamplingFrequency() = 0; - virtual HousekeepingManager* getHkManagerHandle() = 0; + virtual LocalDataPoolManager* getHkManagerHandle() = 0; virtual DataSetIF* getDataSetHandle(sid_t sid) = 0; }; diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index 30ee0394..59bfb6af 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -1347,11 +1347,11 @@ void DeviceHandlerBase::performOperationHook() { } ReturnValue_t DeviceHandlerBase::initializeHousekeepingPoolEntries( - LocalDataPoolMap &localDataPoolMap) { + LocalDataPool &localDataPoolMap) { return RETURN_OK; } -HousekeepingManager* DeviceHandlerBase::getHkManagerHandle() { +LocalDataPoolManager* DeviceHandlerBase::getHkManagerHandle() { return &hkManager; } diff --git a/devicehandlers/DeviceHandlerBase.h b/devicehandlers/DeviceHandlerBase.h index b079e469..4ee3d652 100644 --- a/devicehandlers/DeviceHandlerBase.h +++ b/devicehandlers/DeviceHandlerBase.h @@ -11,15 +11,13 @@ #include #include #include -#include - #include #include #include #include +#include #include -#include - +#include #include namespace Factory{ @@ -87,7 +85,7 @@ class DeviceHandlerBase: public DeviceHandlerIF, public HasHealthIF, public HasActionsIF, public ReceivesParameterMessagesIF, - public HasHkPoolParametersIF { + public OwnsLocalDataPoolIF { friend void (Factory::setStaticFrameworkObjectIds)(); public: /** @@ -480,10 +478,10 @@ protected: * @return */ virtual ReturnValue_t initializeHousekeepingPoolEntries( - LocalDataPoolMap& localDataPoolMap) override; + LocalDataPool& localDataPoolMap) override; /** Get the HK manager object handle */ - virtual HousekeepingManager* getHkManagerHandle() override; + virtual LocalDataPoolManager* getHkManagerHandle() override; /** * @brief Hook function for child handlers which is called once per @@ -609,7 +607,7 @@ protected: /** Action helper for HasActionsIF */ ActionHelper actionHelper; /** Housekeeping Manager */ - HousekeepingManager hkManager; + LocalDataPoolManager hkManager; /** * @brief Information about commands From 73932f0349a958aa15b932f23e56dfa4277a02a8 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 7 Jun 2020 13:58:51 +0200 Subject: [PATCH 105/307] object maanager tweaks --- objectmanager/ObjectManager.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/objectmanager/ObjectManager.cpp b/objectmanager/ObjectManager.cpp index 606cd369..cfdf6562 100644 --- a/objectmanager/ObjectManager.cpp +++ b/objectmanager/ObjectManager.cpp @@ -23,6 +23,7 @@ ReturnValue_t ObjectManager::insert( object_id_t id, SystemObjectIF* object) { } else { sif::error << "ObjectManager::insert: Object id " << std::hex << (int)id << std::dec << " is already in use!" << std::endl; + sif::error << "Terminating program." << std::endl; //This is very severe and difficult to handle in other places. std::exit(INSERTION_FAILED); } @@ -31,8 +32,8 @@ ReturnValue_t ObjectManager::insert( object_id_t id, SystemObjectIF* object) { ReturnValue_t ObjectManager::remove( object_id_t id ) { if ( this->getSystemObject(id) != NULL ) { this->objectList.erase( id ); - sif::debug << "ObjectManager::removeObject: Object " << std::hex - << (int)id << std::dec << " removed." << std::endl; + //sif::debug << "ObjectManager::removeObject: Object " << std::hex + // << (int)id << std::dec << " removed." << std::endl; return RETURN_OK; } else { sif::error << "ObjectManager::removeObject: Requested object " From 1748941f3b6b38015590b9437d5b84bae79b2978 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 7 Jun 2020 13:59:22 +0200 Subject: [PATCH 106/307] commented out debug output and additional diagnostic output toi make it clear the program was terminated --- objectmanager/ObjectManager.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/objectmanager/ObjectManager.cpp b/objectmanager/ObjectManager.cpp index 606cd369..cfdf6562 100644 --- a/objectmanager/ObjectManager.cpp +++ b/objectmanager/ObjectManager.cpp @@ -23,6 +23,7 @@ ReturnValue_t ObjectManager::insert( object_id_t id, SystemObjectIF* object) { } else { sif::error << "ObjectManager::insert: Object id " << std::hex << (int)id << std::dec << " is already in use!" << std::endl; + sif::error << "Terminating program." << std::endl; //This is very severe and difficult to handle in other places. std::exit(INSERTION_FAILED); } @@ -31,8 +32,8 @@ ReturnValue_t ObjectManager::insert( object_id_t id, SystemObjectIF* object) { ReturnValue_t ObjectManager::remove( object_id_t id ) { if ( this->getSystemObject(id) != NULL ) { this->objectList.erase( id ); - sif::debug << "ObjectManager::removeObject: Object " << std::hex - << (int)id << std::dec << " removed." << std::endl; + //sif::debug << "ObjectManager::removeObject: Object " << std::hex + // << (int)id << std::dec << " removed." << std::endl; return RETURN_OK; } else { sif::error << "ObjectManager::removeObject: Requested object " From 98e6ca5f78b19e679f5f527db1c3612f8e1f214a Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 7 Jun 2020 15:22:32 +0200 Subject: [PATCH 107/307] removed locks in lockless functions --- datapoollocal/LocalPoolVariable.tpp | 2 -- datapoollocal/LocalPoolVector.h | 10 +++++++--- datapoollocal/LocalPoolVector.tpp | 16 ++++++++++------ 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/datapoollocal/LocalPoolVariable.tpp b/datapoollocal/LocalPoolVariable.tpp index 0140b29d..9dcd0699 100644 --- a/datapoollocal/LocalPoolVariable.tpp +++ b/datapoollocal/LocalPoolVariable.tpp @@ -87,8 +87,6 @@ inline ReturnValue_t LocalPoolVar::commitWithoutLock() { "mode for commit() call." << std::endl; return PoolVariableIF::INVALID_READ_WRITE_MODE; } - // Wait maximum of 50 milliseconds. - MutexHelper(hkManager->getMutexHandle(), 50); PoolEntry* poolEntry = nullptr; ReturnValue_t result = hkManager->fetchPoolEntry(localPoolId, &poolEntry); if(result != RETURN_OK) { diff --git a/datapoollocal/LocalPoolVector.h b/datapoollocal/LocalPoolVector.h index 1c5f1d65..a8d0a7bb 100644 --- a/datapoollocal/LocalPoolVector.h +++ b/datapoollocal/LocalPoolVector.h @@ -70,8 +70,9 @@ public: /** * @brief This is the local copy of the data pool entry. - * @details The user can work on this attribute - * just like he would on a local array of this type. + * @details + * The user can work on this attribute just like he would on a local + * array of this type. */ T value[vectorSize]; /** @@ -109,7 +110,7 @@ public: void setValid(bool valid) override; uint8_t getValid() const; - T &operator [](int i); + T& operator [](int i); const T &operator [](int i) const; virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, @@ -142,6 +143,7 @@ public: * at once to avoid the overhead of unnecessary lock und unlock operations. */ ReturnValue_t commit(uint32_t lockTimeout = MutexIF::BLOCKING) override; + protected: /** * @brief Like #read, but without a lock protection of the global pool. @@ -185,6 +187,8 @@ private: template friend std::ostream& operator<< (std::ostream &out, const LocalPoolVector &var); + + }; #include diff --git a/datapoollocal/LocalPoolVector.tpp b/datapoollocal/LocalPoolVector.tpp index bd35eed3..a18f8327 100644 --- a/datapoollocal/LocalPoolVector.tpp +++ b/datapoollocal/LocalPoolVector.tpp @@ -85,8 +85,6 @@ inline ReturnValue_t LocalPoolVector::commitWithoutLock() { "mode for commit() call." << std::endl; return PoolVariableIF::INVALID_READ_WRITE_MODE; } - // Wait maximum of 50 milliseconds. - MutexHelper(hkManager->getMutexHandle(), 50); PoolEntry* poolEntry = nullptr; ReturnValue_t result = hkManager->fetchPoolEntry(localPoolId, &poolEntry); if(result != RETURN_OK) { @@ -106,8 +104,11 @@ inline T& LocalPoolVector::operator [](int i) { if(i <= vectorSize) { return value[i]; } - sif::warning << "LocalPoolVector: Invalid index" << std::endl; - return 0; + // If this happens, I have to set some value. I consider this + // a configuration error, but I wont exit here. + sif::error << "LocalPoolVector: Invalid index. Setting or returning" + " last value!" << std::endl; + return value[i]; } template @@ -115,8 +116,11 @@ inline const T& LocalPoolVector::operator [](int i) const { if(i <= vectorSize) { return value[i]; } - sif::warning << "LocalPoolVector: Invalid index" << std::endl; - return 0; + // If this happens, I have to set some value. I consider this + // a configuration error, but I wont exit here. + sif::error << "LocalPoolVector: Invalid index. Setting or returning" + " last value!" << std::endl; + return value[i]; } template From 3b4413a6ee268d2759a5ef94c1ce8348c7f4d425 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 7 Jun 2020 16:12:23 +0200 Subject: [PATCH 108/307] added queue lock for receiveMessage --- osal/host/MessageQueue.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/osal/host/MessageQueue.cpp b/osal/host/MessageQueue.cpp index 7e68fd5b..3e30c8ed 100644 --- a/osal/host/MessageQueue.cpp +++ b/osal/host/MessageQueue.cpp @@ -61,6 +61,7 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message) { } // not sure this will work.. //*message = std::move(messageQueue.front()); + MutexHelper mutexLock(queueLock, 20); MessageQueueMessage* currentMessage = &messageQueue.front(); std::copy(currentMessage->getBuffer(), currentMessage->getBuffer() + messageSize, message->getBuffer()); From 4a90f41122339e106b7ec52f45fcd982dccc5c39 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 7 Jun 2020 18:53:55 +0200 Subject: [PATCH 109/307] generate HK packet function continued --- datapoollocal/LocalDataPoolManager.cpp | 42 ++++++++++++++------- datapoollocal/LocalDataPoolManager.h | 14 +++++-- tmtcservices/CommandingServiceBase.cpp | 52 +++++++++++++------------- tmtcservices/CommandingServiceBase.h | 20 +++++----- 4 files changed, 77 insertions(+), 51 deletions(-) diff --git a/datapoollocal/LocalDataPoolManager.cpp b/datapoollocal/LocalDataPoolManager.cpp index 78e57c8c..0a5747dc 100644 --- a/datapoollocal/LocalDataPoolManager.cpp +++ b/datapoollocal/LocalDataPoolManager.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include @@ -13,7 +14,15 @@ LocalDataPoolManager::LocalDataPoolManager(OwnsLocalDataPoolIF* owner) { } this->owner = owner; mutex = MutexFactory::instance()->createMutex(); - //owner->setMinimalHkSamplingFrequency(); + if(mutex == nullptr) { + sif::error << "LocalDataPoolManager::LocalDataPoolManager: " + "Could not create mutex." << std::endl; + } + ipcStore = objectManager->get(objects::IPC_STORE); + if(ipcStore == nullptr) { + sif::error << "LocalDataPoolManager::LocalDataPoolManager: " + "Could not set IPC store." << std::endl; + } } LocalDataPoolManager::~LocalDataPoolManager() {} @@ -52,32 +61,37 @@ MutexIF* LocalDataPoolManager::getMutexHandle() { return mutex; } -//void HousekeepingManager::setMinimalSamplingFrequency(float frequencySeconds) { -// this->samplingFrequency = frequencySeconds; -// -//} - -void LocalDataPoolManager::generateHousekeepingPacket(sid_t sid) { +ReturnValue_t LocalDataPoolManager::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; + return HasReturnvaluesIF::RETURN_FAILED; + } + store_address_t storeId; + size_t hkSize = dataSetToSerialize->getSerializedSize(); + uint8_t* storePtr = nullptr; + ReturnValue_t result = ipcStore->getFreeElement(&storeId, hkSize,&storePtr); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "HousekeepingManager::generateHousekeepingPacket: " + "Could not get free element from IPC store." << std::endl; + return result; } - 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 - + dataSetToSerialize->serialize(&storePtr, &size, hkSize, false); + // and now we have to set a HK message and send it the queue. + return HasReturnvaluesIF::RETURN_OK; } void LocalDataPoolManager::setHkPacketQueue(MessageQueueIF *msgQueue) { this->hkPacketQueue = msgQueue; } +void LocalDataPoolManager::setHkReplyQueue(MessageQueueIF *replyQueue) { + this->hkReplyQueue = replyQueue; +} + const OwnsLocalDataPoolIF* LocalDataPoolManager::getOwner() const { return owner; } diff --git a/datapoollocal/LocalDataPoolManager.h b/datapoollocal/LocalDataPoolManager.h index c8a6bf15..14e7693c 100644 --- a/datapoollocal/LocalDataPoolManager.h +++ b/datapoollocal/LocalDataPoolManager.h @@ -37,14 +37,15 @@ class LocalDataPoolManager { friend class LocalPoolVector; friend class LocalDataSet; public: - static constexpr float MINIMAL_SAMPLING_FREQUENCY = 0.2; LocalDataPoolManager(OwnsLocalDataPoolIF* owner); virtual~ LocalDataPoolManager(); + /* Copying forbidden */ + LocalDataPoolManager(const LocalDataPoolManager &) = delete; + LocalDataPoolManager operator=(const LocalDataPoolManager&) = delete; - // propably will just call respective local data set functions. - void generateHousekeepingPacket(sid_t sid); + ReturnValue_t generateHousekeepingPacket(sid_t sid); ReturnValue_t handleHousekeepingMessage(CommandMessage* message); /** @@ -55,7 +56,12 @@ public: */ ReturnValue_t initializeHousekeepingPoolEntriesOnce(); + //! Set the queue for HK packets, which are sent unrequested. void setHkPacketQueue(MessageQueueIF* msgQueue); + //! Set the queue for replies. This can be set manually or by the owner + //! class if the manager if message are relayed by it. + void setHkReplyQueue(MessageQueueIF* replyQueue); + const OwnsLocalDataPoolIF* getOwner() const; ReturnValue_t printPoolEntry(lp_id_t localPoolId); @@ -81,6 +87,8 @@ private: //! Maybe this will just be the TM funnel. MessageQueueIF* hkPacketQueue = nullptr; + //! 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 * eternally. Use with care and don't forget to unlock locked mutexes! diff --git a/tmtcservices/CommandingServiceBase.cpp b/tmtcservices/CommandingServiceBase.cpp index 5b397756..adc9400f 100644 --- a/tmtcservices/CommandingServiceBase.cpp +++ b/tmtcservices/CommandingServiceBase.cpp @@ -218,7 +218,7 @@ void CommandingServiceBase::handleRequestQueue() { } -void CommandingServiceBase::sendTmPacket(uint8_t subservice, +ReturnValue_t CommandingServiceBase::sendTmPacket(uint8_t subservice, const uint8_t* data, size_t dataLen, const uint8_t* headerData, size_t headerSize) { TmPacketStored tmPacketStored(this->apid, this->service, subservice, @@ -228,36 +228,38 @@ void CommandingServiceBase::sendTmPacket(uint8_t subservice, if (result == HasReturnvaluesIF::RETURN_OK) { this->tmPacketCounter++; } + return result; } -void CommandingServiceBase::sendTmPacket(uint8_t subservice, - object_id_t objectId, const uint8_t *data, size_t dataLen) { - uint8_t buffer[sizeof(object_id_t)]; - uint8_t* pBuffer = buffer; - size_t size = 0; - SerializeAdapter::serialize(&objectId, &pBuffer, &size, - sizeof(object_id_t), true); - TmPacketStored tmPacketStored(this->apid, this->service, subservice, - this->tmPacketCounter, data, dataLen, buffer, size); - ReturnValue_t result = tmPacketStored.sendPacket( - requestQueue->getDefaultDestination(), requestQueue->getId()); - if (result == HasReturnvaluesIF::RETURN_OK) { - this->tmPacketCounter++; - } - +ReturnValue_t CommandingServiceBase::sendTmPacket(uint8_t subservice, + object_id_t objectId, const uint8_t *data, size_t dataLen) { + uint8_t buffer[sizeof(object_id_t)]; + uint8_t* pBuffer = buffer; + size_t size = 0; + SerializeAdapter::serialize(&objectId, &pBuffer, &size, + sizeof(object_id_t), true); + TmPacketStored tmPacketStored(this->apid, this->service, subservice, + this->tmPacketCounter, data, dataLen, buffer, size); + ReturnValue_t result = tmPacketStored.sendPacket( + requestQueue->getDefaultDestination(), requestQueue->getId()); + if (result == HasReturnvaluesIF::RETURN_OK) { + this->tmPacketCounter++; + } + return result; } -void CommandingServiceBase::sendTmPacket(uint8_t subservice, - SerializeIF* content, SerializeIF* header) { - TmPacketStored tmPacketStored(this->apid, this->service, subservice, - this->tmPacketCounter, content, header); - ReturnValue_t result = tmPacketStored.sendPacket( - requestQueue->getDefaultDestination(), requestQueue->getId()); - if (result == HasReturnvaluesIF::RETURN_OK) { - this->tmPacketCounter++; - } +ReturnValue_t CommandingServiceBase::sendTmPacket(uint8_t subservice, + SerializeIF* content, SerializeIF* header) { + TmPacketStored tmPacketStored(this->apid, this->service, subservice, + this->tmPacketCounter, content, header); + ReturnValue_t result = tmPacketStored.sendPacket( + requestQueue->getDefaultDestination(), requestQueue->getId()); + if (result == HasReturnvaluesIF::RETURN_OK) { + this->tmPacketCounter++; + } + return result; } diff --git a/tmtcservices/CommandingServiceBase.h b/tmtcservices/CommandingServiceBase.h index 259ed1a3..e79e806d 100644 --- a/tmtcservices/CommandingServiceBase.h +++ b/tmtcservices/CommandingServiceBase.h @@ -212,36 +212,38 @@ protected: */ PeriodicTaskIF* executingTask; - // todo: why do these functions not have returnvalues? the caller should be - // able to check whether the send operations actually work. /** - * Send TM data from pointer to data. If a header is supplied it is added before data + * @brief Send TM data from pointer to data. + * If a header is supplied it is added before data * @param subservice Number of subservice * @param data Pointer to the data in the Packet * @param dataLen Lenght of data in the Packet * @param headerData HeaderData will be placed before data * @param headerSize Size of HeaderData */ - void sendTmPacket(uint8_t subservice, const uint8_t *data, size_t dataLen, - const uint8_t* headerData = nullptr,size_t headerSize = 0); + ReturnValue_t sendTmPacket(uint8_t subservice, const uint8_t *data, + size_t dataLen, const uint8_t* headerData = nullptr, + size_t headerSize = 0); /** - * To send TM packets of objects that still need to be serialized and consist of an object ID with appended data + * @brief To send TM packets of objects that still need to be serialized + * and consist of an object ID with appended data. * @param subservice Number of subservice * @param objectId ObjectId is placed before data * @param data Data to append to the packet * @param dataLen Length of Data */ - void sendTmPacket(uint8_t subservice, object_id_t objectId, + ReturnValue_t sendTmPacket(uint8_t subservice, object_id_t objectId, const uint8_t *data, size_t dataLen); /** - * To send packets has data which is in form of a SerializeIF or Adapters implementing it + * @brief To send packets which are contained inside a class implementing + * SerializeIF. * @param subservice Number of subservice * @param content This is a pointer to the serialized packet * @param header Serialize IF header which will be placed before content */ - void sendTmPacket(uint8_t subservice, SerializeIF* content, + ReturnValue_t sendTmPacket(uint8_t subservice, SerializeIF* content, SerializeIF* header = nullptr); virtual void handleUnrequestedReply(CommandMessage *reply); From e8bc2cec9f267079f29e78c94d90d4e107e7eba0 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 7 Jun 2020 23:26:52 +0200 Subject: [PATCH 110/307] small comment in semaph factory --- osal/host/SemaphoreFactory.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osal/host/SemaphoreFactory.cpp b/osal/host/SemaphoreFactory.cpp index 8712d866..0c077f68 100644 --- a/osal/host/SemaphoreFactory.cpp +++ b/osal/host/SemaphoreFactory.cpp @@ -23,6 +23,7 @@ SemaphoreFactory* SemaphoreFactory::instance() { } SemaphoreIF* SemaphoreFactory::createBinarySemaphore(uint32_t arguments) { + // Just gonna wait for full C++20 for now. sif::error << "SemaphoreFactory: Binary Semaphore not implemented yet." " Returning nullptr!\n" << std::flush; return nullptr; @@ -30,6 +31,7 @@ SemaphoreIF* SemaphoreFactory::createBinarySemaphore(uint32_t arguments) { SemaphoreIF* SemaphoreFactory::createCountingSemaphore(const uint8_t maxCount, uint8_t initCount, uint32_t arguments) { + // Just gonna wait for full C++20 for now. sif::error << "SemaphoreFactory: Counting Semaphore not implemented yet." " Returning nullptr!\n" << std::flush; return nullptr; From 2649fa150706bc93d88137dc1de595d2d17272b2 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 7 Jun 2020 23:38:15 +0200 Subject: [PATCH 111/307] small small command message tweaks --- ipc/CommandMessage.h | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/ipc/CommandMessage.h b/ipc/CommandMessage.h index 21c393e5..6190e903 100644 --- a/ipc/CommandMessage.h +++ b/ipc/CommandMessage.h @@ -1,13 +1,5 @@ -/** - * @file CommandMessage.h - * @brief This file defines the CommandMessage class. - * @date 20.06.2013 - * @author baetz - */ - -#ifndef COMMANDMESSAGE_H_ -#define COMMANDMESSAGE_H_ - +#ifndef FRAMEWORK_IPC_COMMANDMESSAGE_H_ +#define FRAMEWORK_IPC_COMMANDMESSAGE_H_ #include #include @@ -15,10 +7,11 @@ #include #define MAKE_COMMAND_ID( number ) ((MESSAGE_ID << 8) + (number)) -typedef ReturnValue_t Command_t; +typedef uint16_t Command_t; /** - * @brief Used to pass command messages between tasks + * @brief Used to pass command messages between tasks + * @author Bastian Baetz */ class CommandMessage : public MessageQueueMessage { public: @@ -27,9 +20,12 @@ public: static const uint8_t MESSAGE_ID = MESSAGE_TYPE::COMMAND; - static const Command_t CMD_NONE = MAKE_COMMAND_ID( 0 );//!< Used internally, will be ignored + //! Used internally, will be ignored + static const Command_t CMD_NONE = MAKE_COMMAND_ID( 0 ); static const Command_t REPLY_COMMAND_OK = MAKE_COMMAND_ID( 3 ); - static const Command_t REPLY_REJECTED = MAKE_COMMAND_ID( 0xD1 );//!< Reply indicating that the current command was rejected, par1 should contain the error code + //! Reply indicating that the current command was rejected, + //! par1 should contain the error code + static const Command_t REPLY_REJECTED = MAKE_COMMAND_ID( 0xD1 ); /** * This is the size of a message as it is seen by the MessageQueue @@ -40,11 +36,13 @@ public: /** * Default Constructor, does not initialize anything. * - * This constructor should be used when receiving a Message, as the content is filled by the MessageQueue. + * This constructor should be used when receiving a Message, as the + * content is filled by the MessageQueue. */ CommandMessage(); /** - * This constructor creates a new message with all message content initialized + * This constructor creates a new message with all message content + * initialized * * @param command The DeviceHandlerCommand_t that will be sent * @param parameter1 The first parameter @@ -60,7 +58,8 @@ public: } /** - * Read the DeviceHandlerCommand_t that is stored in the message, usually used after receiving + * Read the DeviceHandlerCommand_t that is stored in the message, + * usually used after receiving. * * @return the Command stored in the Message */ @@ -126,7 +125,8 @@ public: * Is needed quite often, so we better code it once only. */ void setToUnknownCommand(); - void setReplyRejected(ReturnValue_t reason, Command_t initialCommand = CMD_NONE); + void setReplyRejected(ReturnValue_t reason, + Command_t initialCommand = CMD_NONE); size_t getMinimumMessageSize() const; }; From 4c41456ddffb6800119c0e6a0d90f4ff03bd4618 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 8 Jun 2020 01:22:21 +0200 Subject: [PATCH 112/307] thoughts on message queuee message new interface. What if there are MQ messages with different sizes? -> generic interface furthermore, maybe command message should be refactored to operate on a mq message instead of implementing it --- datapoollocal/LocalDataPoolManager.cpp | 2 +- datapoollocal/LocalDataPoolManager.h | 2 +- devicehandlers/DeviceHandlerBase.cpp | 39 +++++++++++++++++------ housekeeping/HousekeepingMessage.cpp | 8 +++++ housekeeping/HousekeepingMessage.h | 17 ++++++---- ipc/CommandMessage.h | 3 +- ipc/MessageQueueMessage.h | 4 ++- ipc/MessageQueueMessageIF.h | 44 ++++++++++++++++++++++++++ 8 files changed, 100 insertions(+), 19 deletions(-) create mode 100644 ipc/MessageQueueMessageIF.h diff --git a/datapoollocal/LocalDataPoolManager.cpp b/datapoollocal/LocalDataPoolManager.cpp index 0a5747dc..37dbed36 100644 --- a/datapoollocal/LocalDataPoolManager.cpp +++ b/datapoollocal/LocalDataPoolManager.cpp @@ -41,7 +41,7 @@ ReturnValue_t LocalDataPoolManager::initializeHousekeepingPoolEntriesOnce() { } ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage( - CommandMessage *message) { + MessageQueueMessage *message) { return HasReturnvaluesIF::RETURN_OK; } diff --git a/datapoollocal/LocalDataPoolManager.h b/datapoollocal/LocalDataPoolManager.h index 14e7693c..1d25fa48 100644 --- a/datapoollocal/LocalDataPoolManager.h +++ b/datapoollocal/LocalDataPoolManager.h @@ -46,7 +46,7 @@ public: LocalDataPoolManager operator=(const LocalDataPoolManager&) = delete; ReturnValue_t generateHousekeepingPacket(sid_t sid); - ReturnValue_t handleHousekeepingMessage(CommandMessage* message); + ReturnValue_t handleHousekeepingMessage(MessageQueueMessage* message); /** * This function is used to fill the local data pool map with pool diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index 59bfb6af..94c9dc63 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include #include #include @@ -36,7 +38,7 @@ DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, transitionSourceMode(_MODE_POWER_DOWN), transitionSourceSubMode( SUBMODE_NONE), deviceSwitch(setDeviceSwitch) { commandQueue = QueueFactory::instance()->createMessageQueue(cmdQueueSize, - CommandMessage::MAX_MESSAGE_SIZE); + MessageQueueMessage::MAX_MESSAGE_SIZE); insertInCommandMap(RAW_COMMAND_ID); cookieInfo.state = COOKIE_UNUSED; cookieInfo.pendingCommand = deviceCommandMap.end(); @@ -212,40 +214,59 @@ void DeviceHandlerBase::readCommandQueue() { return; } - CommandMessage message; - ReturnValue_t result = commandQueue->receiveMessage(&message); + // This is not ideal. What if it is not a command message? (e.g. another + // message with 3 parameters). The full buffer is filled anyway + // and I could just copy the content into the other message but + // all I need are few additional functions the other message type offers. + CommandMessage cmdMessage; + ReturnValue_t result = commandQueue->receiveMessage(&cmdMessage); if (result != RETURN_OK) { return; } + // This is really annoying. I can't cast a parent object to a child. + // But I want to use another message format.. +// CommandMessage* cmdMessage = dynamic_cast(msgPtr); +// if(cmdMessage == nullptr) { +// sif::error << "DeviceHandlerBase::readCommandQueue: Could not cast" +// " message to CommandMessage!" << std::endl; +// return; +// } + if(healthHelperActive) { - result = healthHelper.handleHealthCommand(&message); + result = healthHelper.handleHealthCommand(&cmdMessage); if (result == RETURN_OK) { return; } } - result = modeHelper.handleModeCommand(&message); + result = modeHelper.handleModeCommand(&cmdMessage); if (result == RETURN_OK) { return; } - result = actionHelper.handleActionMessage(&message); + result = actionHelper.handleActionMessage(&cmdMessage); if (result == RETURN_OK) { return; } - result = parameterHelper.handleParameterMessage(&message); + result = parameterHelper.handleParameterMessage(&cmdMessage); if (result == RETURN_OK) { return; } - result = handleDeviceHandlerMessage(&message); +// HousekeepingMessage* hkMessage = dynamic_cast(msgPtr); +// result = hkManager.handleHousekeepingMessage(hkMessage); +// if (result == RETURN_OK) { +// return; +// } + + result = handleDeviceHandlerMessage(&cmdMessage); if (result == RETURN_OK) { return; } - result = letChildHandleMessage(&message); + result = letChildHandleMessage(&cmdMessage); if (result == RETURN_OK) { return; } diff --git a/housekeeping/HousekeepingMessage.cpp b/housekeeping/HousekeepingMessage.cpp index b0109e5d..c94a69d7 100644 --- a/housekeeping/HousekeepingMessage.cpp +++ b/housekeeping/HousekeepingMessage.cpp @@ -1,5 +1,13 @@ #include +HousekeepingMessage::HousekeepingMessage() { + +} + +void HousekeepingMessage::setHkReportMessage() { +} + + //void HousekeepingMessage::setAddHkReportStructMessage(CommandMessage *message, // set_t setId, store_address_t packet) { // message->setCommand(ADD_HK_REPORT_STRUCT); diff --git a/housekeeping/HousekeepingMessage.h b/housekeeping/HousekeepingMessage.h index e7ba68ba..67edc4ed 100644 --- a/housekeeping/HousekeepingMessage.h +++ b/housekeeping/HousekeepingMessage.h @@ -5,12 +5,14 @@ #include union sid_t { - static constexpr uint64_t INVALID_ADDRESS = std::numeric_limits::max(); + static constexpr uint64_t INVALID_ADDRESS = + std::numeric_limits::max(); sid_t(): raw(INVALID_ADDRESS) {} struct { object_id_t objectId ; - // A generic 32 bit ID to identify unique HK packets for a single object. + // 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; }; @@ -19,15 +21,17 @@ union sid_t { */ uint64_t raw; }; -class HousekeepingMessage { + + +class HousekeepingMessage: public MessageQueueMessage { public: /** * No instances of a message shall be created, instead * a CommandMessage instance is manipulated. */ - HousekeepingMessage() = delete; - HousekeepingMessage(const HousekeepingMessage&) = delete; - HousekeepingMessage operator=(const HousekeepingMessage &) = delete; + HousekeepingMessage(); +// HousekeepingMessage(const HousekeepingMessage&) = delete; +// HousekeepingMessage operator=(const HousekeepingMessage &) = delete; static constexpr uint8_t MESSAGE_ID = MESSAGE_TYPE::HOUSEKEEPING; static constexpr Command_t ADD_HK_REPORT_STRUCT = @@ -76,6 +80,7 @@ public: // static void setAddHkReportStructMessage(CommandMessage* message, // DevisetId, store_address_t packet); + static void setHkReportMessage(); }; diff --git a/ipc/CommandMessage.h b/ipc/CommandMessage.h index 6190e903..d7b6820d 100644 --- a/ipc/CommandMessage.h +++ b/ipc/CommandMessage.h @@ -28,7 +28,8 @@ public: static const Command_t REPLY_REJECTED = MAKE_COMMAND_ID( 0xD1 ); /** - * This is the size of a message as it is seen by the MessageQueue + * This is the size of a message as it is seen by the MessageQueue. + * 14 of the 24 available MessageQueueMessage bytes are used. */ static const size_t COMMAND_MESSAGE_SIZE = HEADER_SIZE + sizeof(Command_t) + 2 * sizeof(uint32_t); diff --git a/ipc/MessageQueueMessage.h b/ipc/MessageQueueMessage.h index 4d82bd88..93671321 100644 --- a/ipc/MessageQueueMessage.h +++ b/ipc/MessageQueueMessage.h @@ -1,6 +1,7 @@ #ifndef MESSAGEQUEUEMESSAGE_H_ #define MESSAGEQUEUEMESSAGE_H_ +#include #include #include @@ -23,7 +24,7 @@ * receive messages from other tasks. * @ingroup message_queue */ -class MessageQueueMessage { +class MessageQueueMessage: public MessageQueueMessageIF { public: /** * @brief The class is initialized empty with this constructor. @@ -43,6 +44,7 @@ public: * MAX_MESSAGE_SIZE and larger than MIN_MESSAGE_SIZE. */ MessageQueueMessage(uint8_t* data, size_t size); + /** * @brief The size information of each message is stored in this attribute. * @details diff --git a/ipc/MessageQueueMessageIF.h b/ipc/MessageQueueMessageIF.h new file mode 100644 index 00000000..3bd4a9d6 --- /dev/null +++ b/ipc/MessageQueueMessageIF.h @@ -0,0 +1,44 @@ +#ifndef FRAMEWORK_IPC_MESSAGEQUEUEMESSAGEIF_H_ +#define FRAMEWORK_IPC_MESSAGEQUEUEMESSAGEIF_H_ +#include +#include + +class MessageQueueMessageIF { +public: + virtual ~MessageQueueMessageIF() {}; + + /** + * @brief With this method, the whole content and the message + * size is set to zero. + */ + virtual void clear() = 0; + /** + * @brief This is a debug method that prints the content + * (till messageSize) to the debug output. + */ + virtual void print() = 0; + virtual const uint8_t* getBuffer() const = 0; + /** + * @brief This method is used to get the complete data of the message. + */ + virtual uint8_t* getBuffer() = 0; + /** + * @brief This method is used to set the sender's message queue id + * information prior to sending the message. + * @param setId The message queue id that identifies the sending message queue. + */ + virtual void setSender(MessageQueueId_t setId) = 0; + /** + * @brief This helper function is used by the MessageQueue class to + * check the size of an incoming message. + * @details + * The method must be overwritten by child classes if size checks shall + * be more strict. + * @return The default implementation returns HEADER_SIZE. + */ + virtual size_t getMinimumMessageSize() = 0; +}; + + + +#endif /* FRAMEWORK_IPC_MESSAGEQUEUEMESSAGEIF_H_ */ From 0ea249aac46c7416aa5b908b9c5f844ac8e09388 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 8 Jun 2020 12:25:20 +0200 Subject: [PATCH 113/307] messagetype namespace im small letters now --- action/ActionMessage.h | 2 +- devicehandlers/DeviceHandlerMessage.h | 2 +- health/HealthMessage.h | 2 +- housekeeping/HousekeepingMessage.h | 2 +- ipc/CommandMessage.cpp | 36 +++++++++++++-------------- ipc/CommandMessage.h | 3 ++- ipc/FwMessageTypes.h | 4 +-- ipc/MessageQueueMessageIF.h | 15 +++++++---- memory/FileSystemMessage.h | 2 +- memory/MemoryMessage.h | 2 +- modes/ModeMessage.h | 2 +- monitoring/MonitoringMessage.h | 2 +- parameters/ParameterMessage.h | 2 +- subsystem/modes/ModeSequenceMessage.h | 2 +- tmstorage/TmStoreMessage.h | 2 +- 15 files changed, 43 insertions(+), 37 deletions(-) diff --git a/action/ActionMessage.h b/action/ActionMessage.h index 5d8332cb..59ad619e 100644 --- a/action/ActionMessage.h +++ b/action/ActionMessage.h @@ -10,7 +10,7 @@ class ActionMessage { private: ActionMessage(); public: - static const uint8_t MESSAGE_ID = MESSAGE_TYPE::ACTION; + static const uint8_t MESSAGE_ID = messagetypes::ACTION; static const Command_t EXECUTE_ACTION = MAKE_COMMAND_ID(1); static const Command_t STEP_SUCCESS = MAKE_COMMAND_ID(2); static const Command_t STEP_FAILED = MAKE_COMMAND_ID(3); diff --git a/devicehandlers/DeviceHandlerMessage.h b/devicehandlers/DeviceHandlerMessage.h index c91bb0a4..2bdf03b2 100644 --- a/devicehandlers/DeviceHandlerMessage.h +++ b/devicehandlers/DeviceHandlerMessage.h @@ -25,7 +25,7 @@ public: /** * These are the commands that can be sent to a DeviceHandlerBase */ - static const uint8_t MESSAGE_ID = MESSAGE_TYPE::DEVICE_HANDLER_COMMAND; + static const uint8_t MESSAGE_ID = messagetypes::DEVICE_HANDLER_COMMAND; static const Command_t CMD_RAW = MAKE_COMMAND_ID( 1 ); //!< Sends a raw command, setParameter is a ::store_id_t containing the raw packet to send // static const Command_t CMD_DIRECT = MAKE_COMMAND_ID( 2 ); //!< Sends a direct command, setParameter is a ::DeviceCommandId_t, setParameter2 is a ::store_id_t containing the data needed for the command static const Command_t CMD_SWITCH_ADDRESS = MAKE_COMMAND_ID( 3 ); //!< Requests a IO-Board switch, setParameter() is the IO-Board identifier diff --git a/health/HealthMessage.h b/health/HealthMessage.h index 7fd00904..13e79b88 100644 --- a/health/HealthMessage.h +++ b/health/HealthMessage.h @@ -6,7 +6,7 @@ class HealthMessage { public: - static const uint8_t MESSAGE_ID = MESSAGE_TYPE::HEALTH_COMMAND; + 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_INFO = MAKE_COMMAND_ID(5); diff --git a/housekeeping/HousekeepingMessage.h b/housekeeping/HousekeepingMessage.h index 67edc4ed..3ba6f94d 100644 --- a/housekeeping/HousekeepingMessage.h +++ b/housekeeping/HousekeepingMessage.h @@ -33,7 +33,7 @@ public: // HousekeepingMessage(const HousekeepingMessage&) = delete; // HousekeepingMessage operator=(const HousekeepingMessage &) = delete; - static constexpr uint8_t MESSAGE_ID = MESSAGE_TYPE::HOUSEKEEPING; + static constexpr uint8_t MESSAGE_ID = messagetypes::HOUSEKEEPING; static constexpr Command_t ADD_HK_REPORT_STRUCT = MAKE_COMMAND_ID(1); static constexpr Command_t ADD_DIAGNOSTICS_REPORT_STRUCT = diff --git a/ipc/CommandMessage.cpp b/ipc/CommandMessage.cpp index fa41c653..544ee43c 100644 --- a/ipc/CommandMessage.cpp +++ b/ipc/CommandMessage.cpp @@ -1,9 +1,4 @@ -/** - * @file CommandMessage.cpp - * @brief This file defines the CommandMessage class. - * @date 20.06.2013 - * @author baetz - */ +#include "MissionMessageTypes.h" #include #include @@ -15,7 +10,8 @@ #include #include -namespace MESSAGE_TYPE { +namespace messagetypes { +// Implemented in config. void clearMissionMessage(CommandMessage* message); } @@ -39,6 +35,10 @@ Command_t CommandMessage::getCommand() const { return command; } +uint8_t CommandMessage::getMessageType() const { + return getCommand() >> 8 & 0xff; +} + void CommandMessage::setCommand(Command_t command) { memcpy(getData(), &command, sizeof(command)); } @@ -66,36 +66,36 @@ void CommandMessage::setParameter2(uint32_t parameter2) { } void CommandMessage::clearCommandMessage() { - switch((getCommand()>>8) & 0xff){ - case MESSAGE_TYPE::MODE_COMMAND: + switch(getMessageType()){ + case messagetypes::MODE_COMMAND: ModeMessage::clear(this); break; - case MESSAGE_TYPE::HEALTH_COMMAND: + case messagetypes::HEALTH_COMMAND: HealthMessage::clear(this); break; - case MESSAGE_TYPE::MODE_SEQUENCE: + case messagetypes::MODE_SEQUENCE: ModeSequenceMessage::clear(this); break; - case MESSAGE_TYPE::ACTION: + case messagetypes::ACTION: ActionMessage::clear(this); break; - case MESSAGE_TYPE::DEVICE_HANDLER_COMMAND: + case messagetypes::DEVICE_HANDLER_COMMAND: DeviceHandlerMessage::clear(this); break; - case MESSAGE_TYPE::MEMORY: + case messagetypes::MEMORY: MemoryMessage::clear(this); break; - case MESSAGE_TYPE::MONITORING: + case messagetypes::MONITORING: MonitoringMessage::clear(this); break; - case MESSAGE_TYPE::TM_STORE: + case messagetypes::TM_STORE: TmStoreMessage::clear(this); break; - case MESSAGE_TYPE::PARAMETER: + case messagetypes::PARAMETER: ParameterMessage::clear(this); break; default: - MESSAGE_TYPE::clearMissionMessage(this); + messagetypes::clearMissionMessage(this); break; } } diff --git a/ipc/CommandMessage.h b/ipc/CommandMessage.h index d7b6820d..a5c187f5 100644 --- a/ipc/CommandMessage.h +++ b/ipc/CommandMessage.h @@ -19,7 +19,7 @@ public: static const ReturnValue_t UNKNOW_COMMAND = MAKE_RETURN_CODE(0x01); - static const uint8_t MESSAGE_ID = MESSAGE_TYPE::COMMAND; + static const uint8_t MESSAGE_ID = messagetypes::COMMAND; //! Used internally, will be ignored static const Command_t CMD_NONE = MAKE_COMMAND_ID( 0 ); static const Command_t REPLY_COMMAND_OK = MAKE_COMMAND_ID( 3 ); @@ -66,6 +66,7 @@ public: */ Command_t getCommand() const; + uint8_t getMessageType() const; /** * Set the DeviceHandlerCOmmand_t of the message * diff --git a/ipc/FwMessageTypes.h b/ipc/FwMessageTypes.h index 1665747e..8b49c122 100644 --- a/ipc/FwMessageTypes.h +++ b/ipc/FwMessageTypes.h @@ -1,9 +1,9 @@ #ifndef FRAMEWORK_IPC_FWMESSAGETYPES_H_ #define FRAMEWORK_IPC_FWMESSAGETYPES_H_ -namespace MESSAGE_TYPE { +namespace messagetypes { //Remember to add new Message Types to the clearCommandMessage function! -enum FW_MESSAGE_TYPE { +enum FsfwMessageTypes { COMMAND = 0, MODE_COMMAND, HEALTH_COMMAND, diff --git a/ipc/MessageQueueMessageIF.h b/ipc/MessageQueueMessageIF.h index 3bd4a9d6..70c87d3c 100644 --- a/ipc/MessageQueueMessageIF.h +++ b/ipc/MessageQueueMessageIF.h @@ -17,24 +17,29 @@ public: * (till messageSize) to the debug output. */ virtual void print() = 0; + + /** + * @brief Get read-only pointer to the raw buffer. + * @return + */ virtual const uint8_t* getBuffer() const = 0; + /** * @brief This method is used to get the complete data of the message. */ virtual uint8_t* getBuffer() = 0; + /** * @brief This method is used to set the sender's message queue id * information prior to sending the message. - * @param setId The message queue id that identifies the sending message queue. + * @param setId + * The message queue id that identifies the sending message queue. */ virtual void setSender(MessageQueueId_t setId) = 0; + /** * @brief This helper function is used by the MessageQueue class to * check the size of an incoming message. - * @details - * The method must be overwritten by child classes if size checks shall - * be more strict. - * @return The default implementation returns HEADER_SIZE. */ virtual size_t getMinimumMessageSize() = 0; }; diff --git a/memory/FileSystemMessage.h b/memory/FileSystemMessage.h index b6fd7309..9f9c1496 100644 --- a/memory/FileSystemMessage.h +++ b/memory/FileSystemMessage.h @@ -16,7 +16,7 @@ class FileSystemMessage { private: FileSystemMessage(); //A private ctor inhibits instantiation public: - static const uint8_t MESSAGE_ID = MESSAGE_TYPE::FILE_SYSTEM_MESSAGE; + static const uint8_t MESSAGE_ID = messagetypes::FILE_SYSTEM_MESSAGE; static const Command_t CREATE_FILE = MAKE_COMMAND_ID( 0x01 ); static const Command_t DELETE_FILE = MAKE_COMMAND_ID( 0x02 ); static const Command_t WRITE_TO_FILE = MAKE_COMMAND_ID( 0x80 ); diff --git a/memory/MemoryMessage.h b/memory/MemoryMessage.h index bcc262e9..e2c87ca3 100644 --- a/memory/MemoryMessage.h +++ b/memory/MemoryMessage.h @@ -9,7 +9,7 @@ class MemoryMessage { private: MemoryMessage(); //A private ctor inhibits instantiation public: - static const uint8_t MESSAGE_ID = MESSAGE_TYPE::MEMORY; + static const uint8_t MESSAGE_ID = messagetypes::MEMORY; static const Command_t CMD_MEMORY_LOAD = MAKE_COMMAND_ID( 0x01 ); static const Command_t CMD_MEMORY_DUMP = MAKE_COMMAND_ID( 0x02 ); static const Command_t CMD_MEMORY_CHECK = MAKE_COMMAND_ID( 0x03 ); diff --git a/modes/ModeMessage.h b/modes/ModeMessage.h index f72fdeec..675c614b 100644 --- a/modes/ModeMessage.h +++ b/modes/ModeMessage.h @@ -17,7 +17,7 @@ class ModeMessage { private: ModeMessage(); public: - static const uint8_t MESSAGE_ID = MESSAGE_TYPE::MODE_COMMAND; + static const uint8_t MESSAGE_ID = messagetypes::MODE_COMMAND; static const Command_t CMD_MODE_COMMAND = MAKE_COMMAND_ID(0x01);//!> Command to set the specified Mode, replies are: REPLY_MODE_REPLY, REPLY_WRONG_MODE_REPLY, and REPLY_REJECTED; don't add any replies, as this will break the subsystem mode machine!! static const Command_t CMD_MODE_COMMAND_FORCED = MAKE_COMMAND_ID(0xF1);//!> Command to set the specified Mode, regardless of external control flag, replies are: REPLY_MODE_REPLY, REPLY_WRONG_MODE_REPLY, and REPLY_REJECTED; don't add any replies, as this will break the subsystem mode machine!! static const Command_t REPLY_MODE_REPLY = MAKE_COMMAND_ID(0x02);//!> Reply to a CMD_MODE_COMMAND or CMD_MODE_READ diff --git a/monitoring/MonitoringMessage.h b/monitoring/MonitoringMessage.h index d2ff9b4d..793e1fbf 100644 --- a/monitoring/MonitoringMessage.h +++ b/monitoring/MonitoringMessage.h @@ -6,7 +6,7 @@ class MonitoringMessage: public CommandMessage { public: - static const uint8_t MESSAGE_ID = MESSAGE_TYPE::MONITORING; + static const uint8_t MESSAGE_ID = messagetypes::MONITORING; //Object id could be useful, but we better manage that on service level (register potential reporters). static const Command_t LIMIT_VIOLATION_REPORT = MAKE_COMMAND_ID(10); virtual ~MonitoringMessage(); diff --git a/parameters/ParameterMessage.h b/parameters/ParameterMessage.h index 0f286675..43283294 100644 --- a/parameters/ParameterMessage.h +++ b/parameters/ParameterMessage.h @@ -9,7 +9,7 @@ class ParameterMessage { private: ParameterMessage(); public: - static const uint8_t MESSAGE_ID = MESSAGE_TYPE::PARAMETER; + static const uint8_t MESSAGE_ID = messagetypes::PARAMETER; static const Command_t CMD_PARAMETER_LOAD = MAKE_COMMAND_ID( 0x01 ); static const Command_t CMD_PARAMETER_DUMP = MAKE_COMMAND_ID( 0x02 ); static const Command_t REPLY_PARAMETER_DUMP = MAKE_COMMAND_ID( 0x03 ); diff --git a/subsystem/modes/ModeSequenceMessage.h b/subsystem/modes/ModeSequenceMessage.h index 830cf532..61d1b628 100644 --- a/subsystem/modes/ModeSequenceMessage.h +++ b/subsystem/modes/ModeSequenceMessage.h @@ -7,7 +7,7 @@ class ModeSequenceMessage { public: - static const uint8_t MESSAGE_ID = MESSAGE_TYPE::MODE_SEQUENCE; + static const uint8_t MESSAGE_ID = messagetypes::MODE_SEQUENCE; static const Command_t ADD_SEQUENCE = MAKE_COMMAND_ID(0x01); static const Command_t ADD_TABLE = MAKE_COMMAND_ID(0x02); diff --git a/tmstorage/TmStoreMessage.h b/tmstorage/TmStoreMessage.h index 0883063c..bd6b2def 100644 --- a/tmstorage/TmStoreMessage.h +++ b/tmstorage/TmStoreMessage.h @@ -41,7 +41,7 @@ public: static store_address_t getStoreId(const CommandMessage* cmd); virtual ~TmStoreMessage(); - static const uint8_t MESSAGE_ID = MESSAGE_TYPE::TM_STORE; + static const uint8_t MESSAGE_ID = messagetypes::TM_STORE; static const Command_t ENABLE_STORING = MAKE_COMMAND_ID(1); static const Command_t DELETE_STORE_CONTENT = MAKE_COMMAND_ID(2); static const Command_t DOWNLINK_STORE_CONTENT = MAKE_COMMAND_ID(3); From 07302e0d2aa55dc7a0ed77c595e94f3c4ae9899f Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 8 Jun 2020 17:44:54 +0200 Subject: [PATCH 114/307] removed include --- ipc/CommandMessage.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/ipc/CommandMessage.cpp b/ipc/CommandMessage.cpp index 544ee43c..f9e2e010 100644 --- a/ipc/CommandMessage.cpp +++ b/ipc/CommandMessage.cpp @@ -1,5 +1,3 @@ -#include "MissionMessageTypes.h" - #include #include #include From b1f91439c6325593c59099cbf93d214c27820fc8 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 8 Jun 2020 17:50:09 +0200 Subject: [PATCH 115/307] deleted copy ctor taskes const ref now --- storagemanager/StorageAccessor.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/storagemanager/StorageAccessor.h b/storagemanager/StorageAccessor.h index 57c9369c..06947974 100644 --- a/storagemanager/StorageAccessor.h +++ b/storagemanager/StorageAccessor.h @@ -84,8 +84,8 @@ public: //! The copy ctor and copy assignemnt should be deleted implicitely //! according to https://foonathan.net/2019/02/special-member-functions/ //! but I still deleted them to make it more explicit. (remember rule of 5). - ConstStorageAccessor& operator= (ConstStorageAccessor&) = delete; - ConstStorageAccessor (ConstStorageAccessor&) = delete; + ConstStorageAccessor& operator= (const ConstStorageAccessor&) = delete; + ConstStorageAccessor (const ConstStorageAccessor&) = delete; protected: const uint8_t* constDataPointer = nullptr; store_address_t storeId; From 8ff6506ad90965f6a42d2b03a1fa2b2638f436c9 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 9 Jun 2020 02:18:39 +0200 Subject: [PATCH 116/307] MessageQueue refactoring complete --- action/ActionHelper.cpp | 17 ++++--- action/CommandActionHelper.cpp | 3 +- action/SimpleActionHelper.cpp | 3 +- controller/ControllerBase.cpp | 17 +++---- datalinklayer/MapPacketExtraction.cpp | 6 +-- datapool/HkSwitchHelper.cpp | 11 ++--- datapoolglob/DataPoolAdmin.cpp | 9 ++-- devicehandlers/AssemblyBase.cpp | 3 +- devicehandlers/DeviceHandlerBase.cpp | 29 ++++++------ devicehandlers/HealthDevice.cpp | 7 +-- health/HealthHelper.cpp | 20 +++++---- ipc/CommandMessage.cpp | 62 ++++++++++++++++++++------ ipc/CommandMessage.h | 28 +++++++++--- ipc/MessageQueueIF.h | 16 +++---- ipc/MessageQueueMessage.cpp | 2 +- ipc/MessageQueueMessage.h | 2 +- ipc/MessageQueueMessageIF.h | 29 +++++++++--- ipc/MessageQueueSenderIF.h | 16 ++----- memory/MemoryHelper.cpp | 15 ++++--- modes/ModeHelper.cpp | 31 +++++++------ monitoring/LimitViolationReporter.cpp | 3 +- osal/FreeRTOS/MessageQueue.cpp | 18 ++++---- osal/FreeRTOS/MessageQueue.h | 19 ++++---- osal/FreeRTOS/QueueFactory.cpp | 2 +- parameters/ParameterHelper.cpp | 9 ++-- power/Fuse.cpp | 3 +- power/PowerSensor.cpp | 3 +- subsystem/Subsystem.cpp | 14 +++--- subsystem/SubsystemBase.cpp | 43 +++++++++--------- thermal/AbstractTemperatureSensor.cpp | 11 ++--- thermal/Heater.cpp | 9 ++-- tmstorage/TmStoreMessage.cpp | 2 +- tmstorage/TmStoreMessage.h | 2 +- tmtcservices/CommandingServiceBase.cpp | 20 +++++---- 34 files changed, 293 insertions(+), 191 deletions(-) diff --git a/action/ActionHelper.cpp b/action/ActionHelper.cpp index 19a84d82..0df5f2d4 100644 --- a/action/ActionHelper.cpp +++ b/action/ActionHelper.cpp @@ -16,7 +16,7 @@ ReturnValue_t ActionHelper::handleActionMessage(CommandMessage* command) { ActionMessage::getStoreId(command)); return HasReturnvaluesIF::RETURN_OK; } else { - return CommandMessage::UNKNOW_COMMAND; + return CommandMessage::UNKNOWN_COMMAND; } } @@ -33,13 +33,15 @@ ReturnValue_t ActionHelper::initialize(MessageQueueIF* queueToUse_) { } void ActionHelper::step(uint8_t step, MessageQueueId_t reportTo, ActionId_t commandId, ReturnValue_t result) { - CommandMessage reply; + MessageQueueMessage message; + CommandMessage reply(&message); ActionMessage::setStepReply(&reply, commandId, step + STEP_OFFSET, result); queueToUse->sendMessage(reportTo, &reply); } void ActionHelper::finish(MessageQueueId_t reportTo, ActionId_t commandId, ReturnValue_t result) { - CommandMessage reply; + MessageQueueMessage message; + CommandMessage reply(&message); ActionMessage::setCompletionReply(&reply, commandId, result); queueToUse->sendMessage(reportTo, &reply); } @@ -54,7 +56,8 @@ void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t act size_t size = 0; ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size); if (result != HasReturnvaluesIF::RETURN_OK) { - CommandMessage reply; + MessageQueueMessage message; + CommandMessage reply(&message); ActionMessage::setStepReply(&reply, actionId, 0, result); queueToUse->sendMessage(commandedBy, &reply); return; @@ -62,7 +65,8 @@ void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t act result = owner->executeAction(actionId, commandedBy, dataPtr, size); ipcStore->deleteData(dataAddress); if (result != HasReturnvaluesIF::RETURN_OK) { - CommandMessage reply; + MessageQueueMessage message; + CommandMessage reply(&message); ActionMessage::setStepReply(&reply, actionId, 0, result); queueToUse->sendMessage(commandedBy, &reply); return; @@ -71,7 +75,8 @@ void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t act ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo, ActionId_t replyId, SerializeIF* data, bool hideSender) { - CommandMessage reply; + MessageQueueMessage message; + CommandMessage reply(&message); store_address_t storeAddress; uint8_t *dataPtr; size_t maxSize = data->getSerializedSize(); diff --git a/action/CommandActionHelper.cpp b/action/CommandActionHelper.cpp index 77295401..c871a2d0 100644 --- a/action/CommandActionHelper.cpp +++ b/action/CommandActionHelper.cpp @@ -53,7 +53,8 @@ ReturnValue_t CommandActionHelper::commandAction(object_id_t commandTo, ReturnValue_t CommandActionHelper::sendCommand(MessageQueueId_t queueId, ActionId_t actionId, store_address_t storeId) { - CommandMessage command; + MessageQueueMessage message; + CommandMessage command(&message); ActionMessage::setCommand(&command, actionId, storeId); ReturnValue_t result = queueToUse->sendMessage(queueId, &command); if (result != HasReturnvaluesIF::RETURN_OK) { diff --git a/action/SimpleActionHelper.cpp b/action/SimpleActionHelper.cpp index 6861fc28..f97474b1 100644 --- a/action/SimpleActionHelper.cpp +++ b/action/SimpleActionHelper.cpp @@ -36,7 +36,8 @@ void SimpleActionHelper::resetHelper() { void SimpleActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId, store_address_t dataAddress) { - CommandMessage reply; + MessageQueueMessage message; + CommandMessage reply(&message); if (isExecuting) { ipcStore->deleteData(dataAddress); ActionMessage::setStepReply(&reply, actionId, 0, diff --git a/controller/ControllerBase.cpp b/controller/ControllerBase.cpp index 7b11bdfa..ad0a0b97 100644 --- a/controller/ControllerBase.cpp +++ b/controller/ControllerBase.cpp @@ -56,26 +56,27 @@ MessageQueueId_t ControllerBase::getCommandQueue() const { } void ControllerBase::handleQueue() { - CommandMessage message; + MessageQueueMessage message; + CommandMessage command(&message); ReturnValue_t result; - for (result = commandQueue->receiveMessage(&message); result == RETURN_OK; - result = commandQueue->receiveMessage(&message)) { + for (result = commandQueue->receiveMessage(&command); result == RETURN_OK; + result = commandQueue->receiveMessage(&command)) { - result = modeHelper.handleModeCommand(&message); + result = modeHelper.handleModeCommand(&command); if (result == RETURN_OK) { continue; } - result = healthHelper.handleHealthCommand(&message); + result = healthHelper.handleHealthCommand(&command); if (result == RETURN_OK) { continue; } - result = handleCommandMessage(&message); + result = handleCommandMessage(&command); if (result == RETURN_OK) { continue; } - message.setToUnknownCommand(); - commandQueue->reply(&message); + command.setToUnknownCommand(); + commandQueue->reply(&command); } } diff --git a/datalinklayer/MapPacketExtraction.cpp b/datalinklayer/MapPacketExtraction.cpp index 11b0792a..4ea45e89 100644 --- a/datalinklayer/MapPacketExtraction.cpp +++ b/datalinklayer/MapPacketExtraction.cpp @@ -16,9 +16,9 @@ MapPacketExtraction::MapPacketExtraction(uint8_t setMapId, object_id_t setPacketDestination) : - lastSegmentationFlag(NO_SEGMENTATION), mapId(setMapId), packetLength(0), bufferPosition( - packetBuffer), packetDestination(setPacketDestination), packetStore( - NULL), tcQueueId(MessageQueueSenderIF::NO_QUEUE) { + lastSegmentationFlag(NO_SEGMENTATION), mapId(setMapId), packetLength(0), + bufferPosition(packetBuffer), packetDestination(setPacketDestination), + packetStore(nullptr), tcQueueId(MessageQueueMessageIF::NO_QUEUE) { memset(packetBuffer, 0, sizeof(packetBuffer)); } diff --git a/datapool/HkSwitchHelper.cpp b/datapool/HkSwitchHelper.cpp index 844fcd90..6a923776 100644 --- a/datapool/HkSwitchHelper.cpp +++ b/datapool/HkSwitchHelper.cpp @@ -21,14 +21,15 @@ ReturnValue_t HkSwitchHelper::initialize() { } ReturnValue_t HkSwitchHelper::performOperation(uint8_t operationCode) { - CommandMessage message; - while (actionQueue->receiveMessage(&message) == HasReturnvaluesIF::RETURN_OK) { - ReturnValue_t result = commandActionHelper.handleReply(&message); + MessageQueueMessage message; + CommandMessage command(&message); + while (actionQueue->receiveMessage(&command) == HasReturnvaluesIF::RETURN_OK) { + ReturnValue_t result = commandActionHelper.handleReply(&command); if (result == HasReturnvaluesIF::RETURN_OK) { continue; } - message.setToUnknownCommand(); - actionQueue->reply(&message); + command.setToUnknownCommand(); + actionQueue->reply(&command); } return HasReturnvaluesIF::RETURN_OK; diff --git a/datapoolglob/DataPoolAdmin.cpp b/datapoolglob/DataPoolAdmin.cpp index 05de1eb2..6387263f 100644 --- a/datapoolglob/DataPoolAdmin.cpp +++ b/datapoolglob/DataPoolAdmin.cpp @@ -66,7 +66,8 @@ ReturnValue_t DataPoolAdmin::getParameter(uint8_t domainId, } void DataPoolAdmin::handleCommand() { - CommandMessage command; + MessageQueueMessage message; + CommandMessage command(&message); ReturnValue_t result = commandQueue->receiveMessage(&command); if (result != RETURN_OK) { return; @@ -282,7 +283,8 @@ ReturnValue_t DataPoolAdmin::sendParameter(MessageQueueId_t to, uint32_t id, return result; } - CommandMessage reply; + MessageQueueMessage message; + CommandMessage reply(&message); ParameterMessage::setParameterDumpReply(&reply, id, address); @@ -294,7 +296,8 @@ ReturnValue_t DataPoolAdmin::sendParameter(MessageQueueId_t to, uint32_t id, //identical to ParameterHelper::rejectCommand() void DataPoolAdmin::rejectCommand(MessageQueueId_t to, ReturnValue_t reason, Command_t initialCommand) { - CommandMessage reply; + MessageQueueMessage message; + CommandMessage reply(&message); reply.setReplyRejected(reason, initialCommand); commandQueue->sendMessage(to, &reply); } diff --git a/devicehandlers/AssemblyBase.cpp b/devicehandlers/AssemblyBase.cpp index bd85d1de..a5dcad21 100644 --- a/devicehandlers/AssemblyBase.cpp +++ b/devicehandlers/AssemblyBase.cpp @@ -148,7 +148,8 @@ void AssemblyBase::handleModeTransitionFailed(ReturnValue_t result) { void AssemblyBase::sendHealthCommand(MessageQueueId_t sendTo, HealthState health) { - CommandMessage command; + MessageQueueMessage message; + CommandMessage command(&message); HealthMessage::setHealthMessage(&command, HealthMessage::HEALTH_SET, health); if (commandQueue->sendMessage(sendTo, &command) == RETURN_OK) { diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index 94c9dc63..11cffc74 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -218,8 +218,9 @@ void DeviceHandlerBase::readCommandQueue() { // message with 3 parameters). The full buffer is filled anyway // and I could just copy the content into the other message but // all I need are few additional functions the other message type offers. - CommandMessage cmdMessage; - ReturnValue_t result = commandQueue->receiveMessage(&cmdMessage); + MessageQueueMessage message; + CommandMessage command(&message); + ReturnValue_t result = commandQueue->receiveMessage(&command); if (result != RETURN_OK) { return; } @@ -234,23 +235,23 @@ void DeviceHandlerBase::readCommandQueue() { // } if(healthHelperActive) { - result = healthHelper.handleHealthCommand(&cmdMessage); + result = healthHelper.handleHealthCommand(&command); if (result == RETURN_OK) { return; } } - result = modeHelper.handleModeCommand(&cmdMessage); + result = modeHelper.handleModeCommand(&command); if (result == RETURN_OK) { return; } - result = actionHelper.handleActionMessage(&cmdMessage); + result = actionHelper.handleActionMessage(&command); if (result == RETURN_OK) { return; } - result = parameterHelper.handleParameterMessage(&cmdMessage); + result = parameterHelper.handleParameterMessage(&command); if (result == RETURN_OK) { return; } @@ -261,17 +262,17 @@ void DeviceHandlerBase::readCommandQueue() { // return; // } - result = handleDeviceHandlerMessage(&cmdMessage); + result = handleDeviceHandlerMessage(&command); if (result == RETURN_OK) { return; } - result = letChildHandleMessage(&cmdMessage); + result = letChildHandleMessage(&command); if (result == RETURN_OK) { return; } - replyReturnvalueToCommand(CommandMessage::UNKNOW_COMMAND); + replyReturnvalueToCommand(CommandMessage::UNKNOWN_COMMAND); } @@ -492,12 +493,13 @@ void DeviceHandlerBase::setMode(Mode_t newMode) { void DeviceHandlerBase::replyReturnvalueToCommand(ReturnValue_t status, uint32_t parameter) { + MessageQueueMessage message; //This is actually the reply protocol for raw and misc DH commands. if (status == RETURN_OK) { - CommandMessage reply(CommandMessage::REPLY_COMMAND_OK, 0, parameter); + CommandMessage reply(&message, CommandMessage::REPLY_COMMAND_OK, 0, parameter); commandQueue->reply(&reply); } else { - CommandMessage reply(CommandMessage::REPLY_REJECTED, status, parameter); + CommandMessage reply(&message, CommandMessage::REPLY_REJECTED, status, parameter); commandQueue->reply(&reply); } } @@ -767,9 +769,10 @@ void DeviceHandlerBase::replyRawData(const uint8_t *data, size_t len, return; } - CommandMessage message; + MessageQueueMessage message; + CommandMessage command(&message); - DeviceHandlerMessage::setDeviceHandlerRawReplyMessage(&message, + DeviceHandlerMessage::setDeviceHandlerRawReplyMessage(&command, getObjectId(), address, isCommand); // this->DeviceHandlerCommand = CommandMessage::CMD_NONE; diff --git a/devicehandlers/HealthDevice.cpp b/devicehandlers/HealthDevice.cpp index ea0b99ff..1c9d18f6 100644 --- a/devicehandlers/HealthDevice.cpp +++ b/devicehandlers/HealthDevice.cpp @@ -13,10 +13,11 @@ HealthDevice::~HealthDevice() { } ReturnValue_t HealthDevice::performOperation(uint8_t opCode) { - CommandMessage message; - ReturnValue_t result = commandQueue->receiveMessage(&message); + MessageQueueMessage message; + CommandMessage command(&message); + ReturnValue_t result = commandQueue->receiveMessage(&command); if (result == HasReturnvaluesIF::RETURN_OK) { - healthHelper.handleHealthCommand(&message); + healthHelper.handleHealthCommand(&command); } return HasReturnvaluesIF::RETURN_OK; } diff --git a/health/HealthHelper.cpp b/health/HealthHelper.cpp index fdfc0967..b23a8bd2 100644 --- a/health/HealthHelper.cpp +++ b/health/HealthHelper.cpp @@ -65,29 +65,31 @@ void HealthHelper::informParent(HasHealthIF::HealthState health, if (parentQueue == 0) { return; } - CommandMessage message; - HealthMessage::setHealthMessage(&message, HealthMessage::HEALTH_INFO, + MessageQueueMessage message; + CommandMessage information(&message); + HealthMessage::setHealthMessage(&information, HealthMessage::HEALTH_INFO, health, oldHealth); - if (MessageQueueSenderIF::sendMessage(parentQueue, &message, + if (MessageQueueSenderIF::sendMessage(parentQueue, &information, owner->getCommandQueue()) != HasReturnvaluesIF::RETURN_OK) { sif::debug << "HealthHelper::informParent: sending health reply failed." << std::endl; } } -void HealthHelper::handleSetHealthCommand(CommandMessage* message) { - ReturnValue_t result = owner->setHealth(HealthMessage::getHealth(message)); - if (message->getSender() == 0) { +void HealthHelper::handleSetHealthCommand(CommandMessage* command) { + ReturnValue_t result = owner->setHealth(HealthMessage::getHealth(command)); + if (command->getSender() == MessageQueueMessageIF::NO_QUEUE) { return; } - CommandMessage reply; + MessageQueueMessage message; + CommandMessage reply(&message); if (result == HasReturnvaluesIF::RETURN_OK) { HealthMessage::setHealthMessage(&reply, HealthMessage::REPLY_HEALTH_SET); } else { - reply.setReplyRejected(result, message->getCommand()); + reply.setReplyRejected(result, command->getCommand()); } - if (MessageQueueSenderIF::sendMessage(message->getSender(), &reply, + if (MessageQueueSenderIF::sendMessage(command->getSender(), &reply, owner->getCommandQueue()) != HasReturnvaluesIF::RETURN_OK) { sif::debug << "HealthHelper::handleHealthCommand: sending health " "reply failed." << std::endl; diff --git a/ipc/CommandMessage.cpp b/ipc/CommandMessage.cpp index f9e2e010..cd75aee4 100644 --- a/ipc/CommandMessage.cpp +++ b/ipc/CommandMessage.cpp @@ -14,14 +14,26 @@ void clearMissionMessage(CommandMessage* message); } -CommandMessage::CommandMessage() { - this->messageSize = COMMAND_MESSAGE_SIZE; +CommandMessage::CommandMessage(MessageQueueMessage* receiverMessage): + internalMessage(receiverMessage) { + if(receiverMessage == nullptr) { + sif::error << "CommandMessage::CommandMessage: Don't pass a nullptr" + " as the message queue message, pass the address of an actual" + " message!" << std::endl; + } + internalMessage->messageSize = COMMAND_MESSAGE_SIZE; setCommand(CMD_NONE); } -CommandMessage::CommandMessage(Command_t command, uint32_t parameter1, - uint32_t parameter2) { - this->messageSize = COMMAND_MESSAGE_SIZE; +CommandMessage::CommandMessage(MessageQueueMessage* messageToSet, + Command_t command, uint32_t parameter1, uint32_t parameter2): + internalMessage(messageToSet) { + if(messageToSet == nullptr) { + sif::error << "CommandMessage::CommandMessage: Don't pass a nullptr" + " as the message queue message, pass the address of an actual" + " message!" << std::endl; + } + internalMessage->messageSize = COMMAND_MESSAGE_SIZE; setCommand(command); setParameter(parameter1); setParameter2(parameter2); @@ -29,7 +41,7 @@ CommandMessage::CommandMessage(Command_t command, uint32_t parameter1, Command_t CommandMessage::getCommand() const { Command_t command; - memcpy(&command, getData(), sizeof(Command_t)); + memcpy(&command, internalMessage->getData(), sizeof(Command_t)); return command; } @@ -38,29 +50,35 @@ uint8_t CommandMessage::getMessageType() const { } void CommandMessage::setCommand(Command_t command) { - memcpy(getData(), &command, sizeof(command)); + memcpy(internalMessage->getData(), &command, sizeof(command)); } uint32_t CommandMessage::getParameter() const { uint32_t parameter1; - memcpy(¶meter1, getData() + sizeof(Command_t), sizeof(parameter1)); + memcpy(¶meter1, internalMessage->getData() + sizeof(Command_t), + sizeof(parameter1)); return parameter1; } void CommandMessage::setParameter(uint32_t parameter1) { - memcpy(getData() + sizeof(Command_t), ¶meter1, sizeof(parameter1)); + memcpy(internalMessage->getData() + sizeof(Command_t), + ¶meter1, sizeof(parameter1)); } uint32_t CommandMessage::getParameter2() const { uint32_t parameter2; - memcpy(¶meter2, getData() + sizeof(Command_t) + sizeof(uint32_t), - sizeof(parameter2)); + memcpy(¶meter2, internalMessage->getData() + sizeof(Command_t) + + sizeof(uint32_t), sizeof(parameter2)); return parameter2; } void CommandMessage::setParameter2(uint32_t parameter2) { - memcpy(getData() + sizeof(Command_t) + sizeof(uint32_t), ¶meter2, - sizeof(parameter2)); + memcpy(internalMessage-> getData() + sizeof(Command_t) + sizeof(uint32_t), + ¶meter2, sizeof(parameter2)); +} + +void CommandMessage::clear() { + clearCommandMessage(); } void CommandMessage::clearCommandMessage() { @@ -109,7 +127,7 @@ size_t CommandMessage::getMinimumMessageSize() const { void CommandMessage::setToUnknownCommand() { Command_t initialCommand = getCommand(); clearCommandMessage(); - setReplyRejected(UNKNOW_COMMAND, initialCommand); + setReplyRejected(UNKNOWN_COMMAND, initialCommand); } void CommandMessage::setReplyRejected(ReturnValue_t reason, @@ -118,3 +136,19 @@ void CommandMessage::setReplyRejected(ReturnValue_t reason, setParameter(reason); setParameter2(initialCommand); } + +MessageQueueId_t CommandMessage::getSender() const { + return internalMessage->getSender(); +} + +uint8_t* CommandMessage::getBuffer() { + return internalMessage->getBuffer(); +} + +void CommandMessage::setSender(MessageQueueId_t setId) { + internalMessage->setSender(setId); +} + +const uint8_t* CommandMessage::getBuffer() const { + return internalMessage->getBuffer(); +} diff --git a/ipc/CommandMessage.h b/ipc/CommandMessage.h index a5c187f5..f6fd86cb 100644 --- a/ipc/CommandMessage.h +++ b/ipc/CommandMessage.h @@ -13,10 +13,10 @@ typedef uint16_t Command_t; * @brief Used to pass command messages between tasks * @author Bastian Baetz */ -class CommandMessage : public MessageQueueMessage { +class CommandMessage: public MessageQueueMessageIF { public: static const uint8_t INTERFACE_ID = CLASS_ID::COMMAND_MESSAGE; - static const ReturnValue_t UNKNOW_COMMAND = MAKE_RETURN_CODE(0x01); + static const ReturnValue_t UNKNOWN_COMMAND = MAKE_RETURN_CODE(0x01); static const uint8_t MESSAGE_ID = messagetypes::COMMAND; @@ -31,7 +31,7 @@ public: * This is the size of a message as it is seen by the MessageQueue. * 14 of the 24 available MessageQueueMessage bytes are used. */ - static const size_t COMMAND_MESSAGE_SIZE = HEADER_SIZE + static const size_t COMMAND_MESSAGE_SIZE = MessageQueueMessage::HEADER_SIZE + sizeof(Command_t) + 2 * sizeof(uint32_t); /** @@ -40,7 +40,7 @@ public: * This constructor should be used when receiving a Message, as the * content is filled by the MessageQueue. */ - CommandMessage(); + CommandMessage(MessageQueueMessage* receiverMessage); /** * This constructor creates a new message with all message content * initialized @@ -49,7 +49,7 @@ public: * @param parameter1 The first parameter * @param parameter2 The second parameter */ - CommandMessage(Command_t command, + CommandMessage(MessageQueueMessage* messageToSet, Command_t command, uint32_t parameter1, uint32_t parameter2); /** @@ -58,6 +58,8 @@ public: virtual ~CommandMessage() { } + uint8_t * getBuffer() override; + const uint8_t * getBuffer() const override; /** * Read the DeviceHandlerCommand_t that is stored in the message, * usually used after receiving. @@ -66,6 +68,16 @@ public: */ Command_t getCommand() const; + /** + * @brief This method is used to set the sender's message queue id + * information prior to sending the message. + * @param setId + * The message queue id that identifies the sending message queue. + */ + void setSender(MessageQueueId_t setId) override; + + MessageQueueId_t getSender() const override; + uint8_t getMessageType() const; /** * Set the DeviceHandlerCOmmand_t of the message @@ -102,6 +114,7 @@ public: */ void setParameter2(uint32_t parameter2); + void clear() override; /** * Set the command to CMD_NONE and try to find * the correct class to handle a more detailed @@ -129,7 +142,10 @@ public: void setToUnknownCommand(); void setReplyRejected(ReturnValue_t reason, Command_t initialCommand = CMD_NONE); - size_t getMinimumMessageSize() const; + size_t getMinimumMessageSize() const override; + +private: + MessageQueueMessage* internalMessage; }; diff --git a/ipc/MessageQueueIF.h b/ipc/MessageQueueIF.h index 480019eb..500f71e2 100644 --- a/ipc/MessageQueueIF.h +++ b/ipc/MessageQueueIF.h @@ -15,7 +15,7 @@ #include class MessageQueueIF { public: - static const MessageQueueId_t NO_QUEUE = MessageQueueSenderIF::NO_QUEUE; //!< Ugly hack. + static const MessageQueueId_t NO_QUEUE = MessageQueueMessageIF::NO_QUEUE; //!< Ugly hack. static const uint8_t INTERFACE_ID = CLASS_ID::MESSAGE_QUEUE_IF; /** @@ -41,7 +41,7 @@ public: * @return RETURN_OK if ok * @return NO_REPLY_PARTNER Should return NO_REPLY_PARTNER if partner was found */ - virtual ReturnValue_t reply( MessageQueueMessage* message ) = 0; + virtual ReturnValue_t reply( MessageQueueMessageIF* message ) = 0; /** * @brief This function reads available messages from the message queue and returns the sender. @@ -50,7 +50,7 @@ public: * @param message A pointer to a message in which the received data is stored. * @param receivedFrom A pointer to a queue id in which the sender's id is stored. */ - virtual ReturnValue_t receiveMessage(MessageQueueMessage* message, + virtual ReturnValue_t receiveMessage(MessageQueueMessageIF* message, MessageQueueId_t *receivedFrom) = 0; /** @@ -65,7 +65,7 @@ public: * @return -@c RETURN_OK on success * -@c MessageQueueIF::EMPTY if queue is empty */ - virtual ReturnValue_t receiveMessage(MessageQueueMessage* message) = 0; + virtual ReturnValue_t receiveMessage(MessageQueueMessageIF* message) = 0; /** * Deletes all pending messages in the queue. * @param count The number of flushed messages. @@ -95,7 +95,7 @@ public: * -@c MessageQueueIF::FULL if queue is full */ virtual ReturnValue_t sendMessageFrom( MessageQueueId_t sendTo, - MessageQueueMessage* message, MessageQueueId_t sentFrom, + MessageQueueMessageIF* message, MessageQueueId_t sentFrom, bool ignoreFault = false ) = 0; /** @@ -107,7 +107,7 @@ public: * @param ignoreFault If set to true, the internal software fault counter is not incremented if queue is full. */ virtual ReturnValue_t sendMessage( MessageQueueId_t sendTo, - MessageQueueMessage* message, bool ignoreFault = false ) = 0; + MessageQueueMessageIF* message, bool ignoreFault = false ) = 0; /** * @brief The sendToDefaultFrom method sends a queue message to the default destination. @@ -118,7 +118,7 @@ public: * @return -@c RETURN_OK on success * -@c MessageQueueIF::FULL if queue is full */ - virtual ReturnValue_t sendToDefaultFrom( MessageQueueMessage* message, + virtual ReturnValue_t sendToDefaultFrom( MessageQueueMessageIF* message, MessageQueueId_t sentFrom, bool ignoreFault = false ) = 0; /** * @brief This operation sends a message to the default destination. @@ -128,7 +128,7 @@ public: * @return -@c RETURN_OK on success * -@c MessageQueueIF::FULL if queue is full */ - virtual ReturnValue_t sendToDefault( MessageQueueMessage* message ) = 0; + virtual ReturnValue_t sendToDefault( MessageQueueMessageIF* message ) = 0; /** * \brief This method is a simple setter for the default destination. */ diff --git a/ipc/MessageQueueMessage.cpp b/ipc/MessageQueueMessage.cpp index 544d18e8..c3e1cb7a 100644 --- a/ipc/MessageQueueMessage.cpp +++ b/ipc/MessageQueueMessage.cpp @@ -51,7 +51,7 @@ void MessageQueueMessage::setSender(MessageQueueId_t setId) { memcpy(this->internalBuffer, &setId, sizeof(MessageQueueId_t)); } -size_t MessageQueueMessage::getMinimumMessageSize() { +size_t MessageQueueMessage::getMinimumMessageSize() const { return this->HEADER_SIZE; } diff --git a/ipc/MessageQueueMessage.h b/ipc/MessageQueueMessage.h index 93671321..29d1a869 100644 --- a/ipc/MessageQueueMessage.h +++ b/ipc/MessageQueueMessage.h @@ -132,7 +132,7 @@ public: * @details The method must be overwritten by child classes if size checks shall be more strict. * @return The default implementation returns HEADER_SIZE. */ - virtual size_t getMinimumMessageSize(); + virtual size_t getMinimumMessageSize() const; }; #endif /* MESSAGEQUEUEMESSAGE_H_ */ diff --git a/ipc/MessageQueueMessageIF.h b/ipc/MessageQueueMessageIF.h index 70c87d3c..0a6288b0 100644 --- a/ipc/MessageQueueMessageIF.h +++ b/ipc/MessageQueueMessageIF.h @@ -1,10 +1,23 @@ #ifndef FRAMEWORK_IPC_MESSAGEQUEUEMESSAGEIF_H_ #define FRAMEWORK_IPC_MESSAGEQUEUEMESSAGEIF_H_ -#include #include +#include + +/* + * TODO: Actually, the definition of this ID to be a uint32_t is not ideal and + * breaks layering. However, it is difficult to keep layering, as the ID is + * stored in many places and sent around in MessageQueueMessage. + * Ideally, one would use the (current) object_id_t only, however, doing a + * lookup of queueIDs for every call does not sound ideal. + * In a first step, I'll circumvent the issue by not touching it, + * maybe in a second step. This also influences Interface design + * (getCommandQueue) and some other issues.. */ +typedef uint32_t MessageQueueId_t; class MessageQueueMessageIF { public: + static const MessageQueueId_t NO_QUEUE = 0xffffffff; + virtual ~MessageQueueMessageIF() {}; /** @@ -12,11 +25,11 @@ public: * size is set to zero. */ virtual void clear() = 0; - /** - * @brief This is a debug method that prints the content - * (till messageSize) to the debug output. - */ - virtual void print() = 0; +// /** +// * @brief This is a debug method that prints the content +// * (till messageSize) to the debug output. +// */ +// virtual void print() = 0; /** * @brief Get read-only pointer to the raw buffer. @@ -37,11 +50,13 @@ public: */ virtual void setSender(MessageQueueId_t setId) = 0; + virtual MessageQueueId_t getSender() const = 0; + /** * @brief This helper function is used by the MessageQueue class to * check the size of an incoming message. */ - virtual size_t getMinimumMessageSize() = 0; + virtual size_t getMinimumMessageSize() const = 0; }; diff --git a/ipc/MessageQueueSenderIF.h b/ipc/MessageQueueSenderIF.h index ae66cd12..3172454f 100644 --- a/ipc/MessageQueueSenderIF.h +++ b/ipc/MessageQueueSenderIF.h @@ -1,22 +1,11 @@ #ifndef FRAMEWORK_IPC_MESSAGEQUEUESENDERIF_H_ #define FRAMEWORK_IPC_MESSAGEQUEUESENDERIF_H_ +#include #include -class MessageQueueMessage; - - -//TODO: Actually, the definition of this ID to be a uint32_t is not ideal and breaks layering. -//However, it is difficult to keep layering, as the ID is stored in many places and sent around in -//MessageQueueMessage. -//Ideally, one would use the (current) object_id_t only, however, doing a lookup of queueIDs for every -//call does not sound ideal. -//In a first step, I'll circumvent the issue by not touching it, maybe in a second step. -//This also influences Interface design (getCommandQueue) and some other issues.. -typedef uint32_t MessageQueueId_t; class MessageQueueSenderIF { public: - static const MessageQueueId_t NO_QUEUE = 0xffffffff; virtual ~MessageQueueSenderIF() {} @@ -26,7 +15,8 @@ public: * Must be implemented by a subclass. */ static ReturnValue_t sendMessage(MessageQueueId_t sendTo, - MessageQueueMessage* message, MessageQueueId_t sentFrom = MessageQueueSenderIF::NO_QUEUE, + MessageQueueMessageIF* message, + MessageQueueId_t sentFrom = MessageQueueMessageIF::NO_QUEUE, bool ignoreFault=false); private: MessageQueueSenderIF() {} diff --git a/memory/MemoryHelper.cpp b/memory/MemoryHelper.cpp index de609252..2c384651 100644 --- a/memory/MemoryHelper.cpp +++ b/memory/MemoryHelper.cpp @@ -51,14 +51,16 @@ void MemoryHelper::completeLoad(ReturnValue_t errorCode, break; default: ipcStore->deleteData(ipcAddress); - CommandMessage reply; + MessageQueueMessage message; + CommandMessage reply(&message); MemoryMessage::setMemoryReplyFailed(&reply, errorCode, MemoryMessage::CMD_MEMORY_LOAD); queueToUse->sendMessage(lastSender, &reply); return; } //Only reached on success - CommandMessage reply(CommandMessage::REPLY_COMMAND_OK, 0, 0); + MessageQueueMessage message; + CommandMessage reply(&message, CommandMessage::REPLY_COMMAND_OK, 0, 0); queueToUse->sendMessage(lastSender, &reply); ipcStore->deleteData(ipcAddress); } @@ -66,7 +68,8 @@ void MemoryHelper::completeLoad(ReturnValue_t errorCode, void MemoryHelper::completeDump(ReturnValue_t errorCode, const uint8_t* dataToCopy, const uint32_t size) { busy = false; - CommandMessage reply; + MessageQueueMessage message; + CommandMessage reply(&message); MemoryMessage::setMemoryReplyFailed(&reply, errorCode, lastCommand); switch (errorCode) { case HasMemoryIF::DO_IT_MYSELF: @@ -151,7 +154,8 @@ void MemoryHelper::handleMemoryLoad(CommandMessage* message) { completeLoad(returnCode, p_data, size, dataPointer); } else { //At least inform sender. - CommandMessage reply; + MessageQueueMessage message; + CommandMessage reply(&message); MemoryMessage::setMemoryReplyFailed(&reply, returnCode, MemoryMessage::CMD_MEMORY_LOAD); queueToUse->sendMessage(lastSender, &reply); @@ -169,7 +173,8 @@ void MemoryHelper::handleMemoryCheckOrDump(CommandMessage* message) { reservedSpaceInIPC); completeDump(returnCode, dataPointer, size); } else { - CommandMessage reply; + MessageQueueMessage message; + CommandMessage reply(&message); MemoryMessage::setMemoryReplyFailed(&reply, returnCode, lastCommand); queueToUse->sendMessage(lastSender, &reply); } diff --git a/modes/ModeHelper.cpp b/modes/ModeHelper.cpp index 66726772..b79082af 100644 --- a/modes/ModeHelper.cpp +++ b/modes/ModeHelper.cpp @@ -11,31 +11,32 @@ ModeHelper::~ModeHelper() { } -ReturnValue_t ModeHelper::handleModeCommand(CommandMessage* message) { - CommandMessage reply; +ReturnValue_t ModeHelper::handleModeCommand(CommandMessage* command) { + MessageQueueMessage message; + CommandMessage reply(&message); Mode_t mode; Submode_t submode; - switch (message->getCommand()) { + switch (command->getCommand()) { case ModeMessage::CMD_MODE_COMMAND_FORCED: forced = true; /* NO BREAK falls through*/ case ModeMessage::CMD_MODE_COMMAND: { - mode = ModeMessage::getMode(message); - submode = ModeMessage::getSubmode(message); + mode = ModeMessage::getMode(command); + submode = ModeMessage::getSubmode(command); uint32_t timeout; ReturnValue_t result = owner->checkModeCommand(mode, submode, &timeout); if (result != HasReturnvaluesIF::RETURN_OK) { ModeMessage::cantReachMode(&reply, result); - MessageQueueSenderIF::sendMessage(message->getSender(), &reply, + MessageQueueSenderIF::sendMessage(command->getSender(), &reply, owner->getCommandQueue()); break; } //Free to start transition - theOneWhoCommandedAMode = message->getSender(); + theOneWhoCommandedAMode = command->getSender(); commandedMode = mode; commandedSubmode = submode; - if ((parentQueueId != MessageQueueSenderIF::NO_QUEUE) + if ((parentQueueId != MessageQueueMessageIF::NO_QUEUE) && (theOneWhoCommandedAMode != parentQueueId)) { owner->setToExternalControl(); } @@ -48,7 +49,7 @@ ReturnValue_t ModeHelper::handleModeCommand(CommandMessage* message) { owner->getMode(&mode, &submode); ModeMessage::setModeMessage(&reply, ModeMessage::REPLY_MODE_REPLY, mode, submode); - MessageQueueSenderIF::sendMessage(message->getSender(), &reply, + MessageQueueSenderIF::sendMessage(command->getSender(), &reply, owner->getCommandQueue()); } break; @@ -73,13 +74,14 @@ void ModeHelper::modeChanged(Mode_t ownerMode, Submode_t ownerSubmode) { forced = false; sendModeReplyMessage(ownerMode, ownerSubmode); sendModeInfoMessage(ownerMode, ownerSubmode); - theOneWhoCommandedAMode = MessageQueueSenderIF::NO_QUEUE; + theOneWhoCommandedAMode = MessageQueueMessageIF::NO_QUEUE; } void ModeHelper::sendModeReplyMessage(Mode_t ownerMode, Submode_t ownerSubmode) { - CommandMessage reply; - if (theOneWhoCommandedAMode != MessageQueueSenderIF::NO_QUEUE) + MessageQueueMessage message; + CommandMessage reply(&message); + if (theOneWhoCommandedAMode != MessageQueueMessageIF::NO_QUEUE) { if (ownerMode != commandedMode or ownerSubmode != commandedSubmode) { @@ -99,9 +101,10 @@ void ModeHelper::sendModeReplyMessage(Mode_t ownerMode, void ModeHelper::sendModeInfoMessage(Mode_t ownerMode, Submode_t ownerSubmode) { - CommandMessage reply; + MessageQueueMessage message; + CommandMessage reply(&message); if (theOneWhoCommandedAMode != parentQueueId - and parentQueueId != MessageQueueSenderIF::NO_QUEUE) + and parentQueueId != MessageQueueMessageIF::NO_QUEUE) { ModeMessage::setModeMessage(&reply, ModeMessage::REPLY_MODE_INFO, ownerMode, ownerSubmode); diff --git a/monitoring/LimitViolationReporter.cpp b/monitoring/LimitViolationReporter.cpp index 234a0bff..1378d754 100644 --- a/monitoring/LimitViolationReporter.cpp +++ b/monitoring/LimitViolationReporter.cpp @@ -31,7 +31,8 @@ ReturnValue_t LimitViolationReporter::sendLimitViolationReport(const SerializeIF if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - CommandMessage report; + MessageQueueMessage message; + CommandMessage report(&message); MonitoringMessage::setLimitViolationReport(&report, storeId); return MessageQueueSenderIF::sendMessage(reportQueue, &report); } diff --git a/osal/FreeRTOS/MessageQueue.cpp b/osal/FreeRTOS/MessageQueue.cpp index 0a579296..8c6ec80b 100644 --- a/osal/FreeRTOS/MessageQueue.cpp +++ b/osal/FreeRTOS/MessageQueue.cpp @@ -25,21 +25,21 @@ void MessageQueue::switchSystemContext(CallContext callContext) { } ReturnValue_t MessageQueue::sendMessage(MessageQueueId_t sendTo, - MessageQueueMessage* message, bool ignoreFault) { + MessageQueueMessageIF* message, bool ignoreFault) { return sendMessageFrom(sendTo, message, this->getId(), ignoreFault); } -ReturnValue_t MessageQueue::sendToDefault(MessageQueueMessage* message) { +ReturnValue_t MessageQueue::sendToDefault(MessageQueueMessageIF* message) { return sendToDefaultFrom(message, this->getId()); } -ReturnValue_t MessageQueue::sendToDefaultFrom(MessageQueueMessage* message, +ReturnValue_t MessageQueue::sendToDefaultFrom(MessageQueueMessageIF* message, MessageQueueId_t sentFrom, bool ignoreFault) { return sendMessageFrom(defaultDestination,message,sentFrom,ignoreFault); } -ReturnValue_t MessageQueue::reply(MessageQueueMessage* message) { - if (this->lastPartner != 0) { +ReturnValue_t MessageQueue::reply(MessageQueueMessageIF* message) { + if (this->lastPartner != MessageQueueMessageIF::NO_QUEUE) { return sendMessageFrom(this->lastPartner, message, this->getId()); } else { return NO_REPLY_PARTNER; @@ -47,7 +47,7 @@ ReturnValue_t MessageQueue::reply(MessageQueueMessage* message) { } ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo, - MessageQueueMessage* message, MessageQueueId_t sentFrom, + MessageQueueMessageIF* message, MessageQueueId_t sentFrom, bool ignoreFault) { return sendMessageFromMessageQueue(sendTo, message, sentFrom, ignoreFault, callContext); @@ -69,7 +69,7 @@ ReturnValue_t MessageQueue::handleSendResult(BaseType_t result, bool ignoreFault return HasReturnvaluesIF::RETURN_OK; } -ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message, +ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message, MessageQueueId_t* receivedFrom) { ReturnValue_t status = this->receiveMessage(message); if(status == HasReturnvaluesIF::RETURN_OK) { @@ -78,7 +78,7 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message, return status; } -ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message) { +ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) { BaseType_t result = xQueueReceive(handle,reinterpret_cast( message->getBuffer()), 0); if (result == pdPASS){ @@ -120,7 +120,7 @@ bool MessageQueue::isDefaultDestinationSet() const { // static core function to send messages. ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, - MessageQueueMessage *message, MessageQueueId_t sentFrom, + MessageQueueMessageIF *message, MessageQueueId_t sentFrom, bool ignoreFault, CallContext callContext) { message->setSender(sentFrom); BaseType_t result; diff --git a/osal/FreeRTOS/MessageQueue.h b/osal/FreeRTOS/MessageQueue.h index 81b4c186..6165c1cf 100644 --- a/osal/FreeRTOS/MessageQueue.h +++ b/osal/FreeRTOS/MessageQueue.h @@ -85,14 +85,14 @@ public: * @param ignoreFault If set to true, the internal software fault counter is not incremented if queue is full. */ ReturnValue_t sendMessage(MessageQueueId_t sendTo, - MessageQueueMessage* message, bool ignoreFault = false ); + MessageQueueMessageIF* message, bool ignoreFault = false ); /** * @brief This operation sends a message to the default destination. * @details As in the sendMessage method, this function uses the sendToDefault call of the * MessageQueueSender parent class and adds its queue id as "sentFrom" information. * @param message A pointer to a previously created message, which is sent. */ - ReturnValue_t sendToDefault( MessageQueueMessage* message ); + ReturnValue_t sendToDefault( MessageQueueMessageIF* message ); /** * @brief This operation sends a message to the last communication partner. * @details This operation simplifies answering an incoming message by using the stored @@ -100,7 +100,7 @@ public: * (i.e. lastPartner is zero), an error code is returned. * @param message A pointer to a previously created message, which is sent. */ - ReturnValue_t reply( MessageQueueMessage* message ); + ReturnValue_t reply( MessageQueueMessageIF* message ); /** * @brief With the sendMessage call, a queue message is sent to a receiving queue. @@ -113,8 +113,9 @@ public: * This variable is set to zero by default. * @param ignoreFault If set to true, the internal software fault counter is not incremented if queue is full. */ - virtual ReturnValue_t sendMessageFrom( MessageQueueId_t sendTo, MessageQueueMessage* message, - MessageQueueId_t sentFrom = NO_QUEUE, bool ignoreFault = false ); + virtual ReturnValue_t sendMessageFrom( MessageQueueId_t sendTo, + MessageQueueMessageIF* message, MessageQueueId_t sentFrom = NO_QUEUE, + bool ignoreFault = false ); /** * @brief The sendToDefault method sends a queue message to the default destination. @@ -123,7 +124,7 @@ public: * @param sentFrom The sentFrom information can be set to inject the sender's queue id into the message. * This variable is set to zero by default. */ - virtual ReturnValue_t sendToDefaultFrom( MessageQueueMessage* message, + virtual ReturnValue_t sendToDefaultFrom( MessageQueueMessageIF* message, MessageQueueId_t sentFrom = NO_QUEUE, bool ignoreFault = false ); /** @@ -133,7 +134,7 @@ public: * @param message A pointer to a message in which the received data is stored. * @param receivedFrom A pointer to a queue id in which the sender's id is stored. */ - ReturnValue_t receiveMessage(MessageQueueMessage* message, + ReturnValue_t receiveMessage(MessageQueueMessageIF* message, MessageQueueId_t *receivedFrom); /** @@ -144,7 +145,7 @@ public: * message's content is cleared and the function returns immediately. * @param message A pointer to a message in which the received data is stored. */ - ReturnValue_t receiveMessage(MessageQueueMessage* message); + ReturnValue_t receiveMessage(MessageQueueMessageIF* message); /** * Deletes all pending messages in the queue. * @param count The number of flushed messages. @@ -191,7 +192,7 @@ protected: * @param context Specify whether call is made from task or from an ISR. */ static ReturnValue_t sendMessageFromMessageQueue(MessageQueueId_t sendTo, - MessageQueueMessage* message, MessageQueueId_t sentFrom = NO_QUEUE, + MessageQueueMessageIF* message, MessageQueueId_t sentFrom = NO_QUEUE, bool ignoreFault=false, CallContext callContext = CallContext::TASK); static ReturnValue_t handleSendResult(BaseType_t result, bool ignoreFault); diff --git a/osal/FreeRTOS/QueueFactory.cpp b/osal/FreeRTOS/QueueFactory.cpp index 372d0d41..beb4969b 100644 --- a/osal/FreeRTOS/QueueFactory.cpp +++ b/osal/FreeRTOS/QueueFactory.cpp @@ -7,7 +7,7 @@ QueueFactory* QueueFactory::factoryInstance = nullptr; ReturnValue_t MessageQueueSenderIF::sendMessage(MessageQueueId_t sendTo, - MessageQueueMessage* message, MessageQueueId_t sentFrom, + MessageQueueMessageIF* message, MessageQueueId_t sentFrom, bool ignoreFault) { return MessageQueue::sendMessageFromMessageQueue(sendTo,message, sentFrom,ignoreFault); diff --git a/parameters/ParameterHelper.cpp b/parameters/ParameterHelper.cpp index e0756882..8b91020f 100644 --- a/parameters/ParameterHelper.cpp +++ b/parameters/ParameterHelper.cpp @@ -102,7 +102,8 @@ ReturnValue_t ParameterHelper::sendParameter(MessageQueueId_t to, uint32_t id, return result; } - CommandMessage reply; + MessageQueueMessage message; + CommandMessage reply(&message); ParameterMessage::setParameterDumpReply(&reply, id, address); @@ -123,8 +124,10 @@ ReturnValue_t ParameterHelper::initialize() { } } -void ParameterHelper::rejectCommand(MessageQueueId_t to, ReturnValue_t reason, Command_t initialCommand) { - CommandMessage reply; +void ParameterHelper::rejectCommand(MessageQueueId_t to, ReturnValue_t reason, + Command_t initialCommand) { + MessageQueueMessage message; + CommandMessage reply(&message); reply.setReplyRejected(reason, initialCommand); MessageQueueSenderIF::sendMessage(to, &reply, ownerQueueId); } diff --git a/power/Fuse.cpp b/power/Fuse.cpp index eee91984..a80a111f 100644 --- a/power/Fuse.cpp +++ b/power/Fuse.cpp @@ -163,7 +163,8 @@ void Fuse::setAllMonitorsToUnchecked() { } void Fuse::checkCommandQueue() { - CommandMessage command; + MessageQueueMessage message; + CommandMessage command(&message); ReturnValue_t result = commandQueue->receiveMessage(&command); if (result != HasReturnvaluesIF::RETURN_OK) { return; diff --git a/power/PowerSensor.cpp b/power/PowerSensor.cpp index 5433acc9..b1aea270 100644 --- a/power/PowerSensor.cpp +++ b/power/PowerSensor.cpp @@ -74,7 +74,8 @@ void PowerSensor::setAllMonitorsToUnchecked() { } void PowerSensor::checkCommandQueue() { - CommandMessage command; + MessageQueueMessage message; + CommandMessage command(&message); ReturnValue_t result = commandQueue->receiveMessage(&command); if (result != HasReturnvaluesIF::RETURN_OK) { return; diff --git a/subsystem/Subsystem.cpp b/subsystem/Subsystem.cpp index 52f2c474..d774b4d5 100644 --- a/subsystem/Subsystem.cpp +++ b/subsystem/Subsystem.cpp @@ -309,7 +309,8 @@ ReturnValue_t Subsystem::handleCommandMessage(CommandMessage* message) { break; case ModeSequenceMessage::READ_FREE_SEQUENCE_SLOTS: { uint32_t freeSlots = modeSequences.maxSize() - modeSequences.size(); - CommandMessage reply; + MessageQueueMessage message; + CommandMessage reply(&message); ModeSequenceMessage::setModeSequenceMessage(&reply, ModeSequenceMessage::FREE_SEQUENCE_SLOTS, freeSlots); commandQueue->reply(&reply); @@ -317,7 +318,8 @@ ReturnValue_t Subsystem::handleCommandMessage(CommandMessage* message) { break; case ModeSequenceMessage::READ_FREE_TABLE_SLOTS: { uint32_t free = modeTables.maxSize() - modeTables.size(); - CommandMessage reply; + MessageQueueMessage message; + CommandMessage reply(&message); ModeSequenceMessage::setModeSequenceMessage(&reply, ModeSequenceMessage::FREE_TABLE_SLOTS, free); commandQueue->reply(&reply); @@ -330,11 +332,12 @@ ReturnValue_t Subsystem::handleCommandMessage(CommandMessage* message) { } void Subsystem::replyToCommand(ReturnValue_t status, uint32_t parameter) { + MessageQueueMessage message; if (status == RETURN_OK) { - CommandMessage reply(CommandMessage::REPLY_COMMAND_OK, 0, 0); + CommandMessage reply(&message, CommandMessage::REPLY_COMMAND_OK, 0, 0); commandQueue->reply(&reply); } else { - CommandMessage reply(CommandMessage::REPLY_REJECTED, status, 0); + CommandMessage reply(&message, CommandMessage::REPLY_REJECTED, status, 0); commandQueue->reply(&reply); } } @@ -617,7 +620,8 @@ void Subsystem::sendSerializablesAsCommandMessage(Command_t command, for (uint8_t i = 0; i < count; i++) { elements[i]->serialize(&storeBuffer, &size, maxSize, true); } - CommandMessage reply; + MessageQueueMessage message; + CommandMessage reply(&message); ModeSequenceMessage::setModeSequenceMessage(&reply, command, address); if (commandQueue->reply(&reply) != RETURN_OK) { IPCStore->deleteData(address); diff --git a/subsystem/SubsystemBase.cpp b/subsystem/SubsystemBase.cpp index 6df0b64f..5527f215 100644 --- a/subsystem/SubsystemBase.cpp +++ b/subsystem/SubsystemBase.cpp @@ -9,7 +9,7 @@ SubsystemBase::SubsystemBase(object_id_t setObjectId, object_id_t parent, false), commandsOutstanding(0), commandQueue(NULL), healthHelper(this, setObjectId), modeHelper(this), parentId(parent) { commandQueue = QueueFactory::instance()->createMessageQueue(commandQueueDepth, - CommandMessage::MAX_MESSAGE_SIZE); + MessageQueueMessage::MAX_MESSAGE_SIZE); } SubsystemBase::~SubsystemBase() { @@ -77,8 +77,8 @@ ReturnValue_t SubsystemBase::checkStateAgainstTable( } void SubsystemBase::executeTable(HybridIterator tableIter, Submode_t targetSubmode) { - - CommandMessage message; + MessageQueueMessage message; + CommandMessage command(&message); std::map::iterator iter; @@ -100,17 +100,17 @@ void SubsystemBase::executeTable(HybridIterator tableIter, Submod if (healthHelper.healthTable->hasHealth(object)) { if (healthHelper.healthTable->isFaulty(object)) { - ModeMessage::setModeMessage(&message, + ModeMessage::setModeMessage(&command, ModeMessage::CMD_MODE_COMMAND, HasModesIF::MODE_OFF, SUBMODE_NONE); } else { if (modeHelper.isForced()) { - ModeMessage::setModeMessage(&message, + ModeMessage::setModeMessage(&command, ModeMessage::CMD_MODE_COMMAND_FORCED, tableIter.value->getMode(), submodeToCommand); } else { if (healthHelper.healthTable->isCommandable(object)) { - ModeMessage::setModeMessage(&message, + ModeMessage::setModeMessage(&command, ModeMessage::CMD_MODE_COMMAND, tableIter.value->getMode(), submodeToCommand); } else { @@ -119,12 +119,12 @@ void SubsystemBase::executeTable(HybridIterator tableIter, Submod } } } else { - ModeMessage::setModeMessage(&message, ModeMessage::CMD_MODE_COMMAND, + ModeMessage::setModeMessage(&command, ModeMessage::CMD_MODE_COMMAND, tableIter.value->getMode(), submodeToCommand); } - if ((iter->second.mode == ModeMessage::getMode(&message)) - && (iter->second.submode == ModeMessage::getSubmode(&message)) + if ((iter->second.mode == ModeMessage::getMode(&command)) + && (iter->second.submode == ModeMessage::getSubmode(&command)) && !modeHelper.isForced()) { continue; //don't send redundant mode commands (produces event spam), but still command if mode is forced to reach lower levels } @@ -297,7 +297,8 @@ void SubsystemBase::setToExternalControl() { void SubsystemBase::announceMode(bool recursive) { triggerEvent(MODE_INFO, mode, submode); if (recursive) { - CommandMessage command; + MessageQueueMessage message; + CommandMessage command(&message); ModeMessage::setModeMessage(&command, ModeMessage::CMD_MODE_ANNOUNCE_RECURSIVELY, 0, 0); commandAllChildren(&command); @@ -306,31 +307,33 @@ void SubsystemBase::announceMode(bool recursive) { void SubsystemBase::checkCommandQueue() { ReturnValue_t result; - CommandMessage message; + MessageQueueMessage message; + CommandMessage command(&message); - for (result = commandQueue->receiveMessage(&message); result == RETURN_OK; - result = commandQueue->receiveMessage(&message)) { + for (result = commandQueue->receiveMessage(&command); result == RETURN_OK; + result = commandQueue->receiveMessage(&command)) { - result = healthHelper.handleHealthCommand(&message); + result = healthHelper.handleHealthCommand(&command); if (result == RETURN_OK) { continue; } - result = modeHelper.handleModeCommand(&message); + result = modeHelper.handleModeCommand(&command); if (result == RETURN_OK) { continue; } - result = handleModeReply(&message); + result = handleModeReply(&command); if (result == RETURN_OK) { continue; } - result = handleCommandMessage(&message); + result = handleCommandMessage(&command); if (result != RETURN_OK) { - CommandMessage reply; - reply.setReplyRejected(CommandMessage::UNKNOW_COMMAND, - message.getCommand()); + MessageQueueMessage message; + CommandMessage reply(&message); + reply.setReplyRejected(CommandMessage::UNKNOWN_COMMAND, + command.getCommand()); replyToCommand(&reply); } } diff --git a/thermal/AbstractTemperatureSensor.cpp b/thermal/AbstractTemperatureSensor.cpp index be143410..759af87e 100644 --- a/thermal/AbstractTemperatureSensor.cpp +++ b/thermal/AbstractTemperatureSensor.cpp @@ -44,18 +44,19 @@ ReturnValue_t AbstractTemperatureSensor::performHealthOp() { } void AbstractTemperatureSensor::handleCommandQueue() { - CommandMessage message; - ReturnValue_t result = commandQueue->receiveMessage(&message); + MessageQueueMessage message; + CommandMessage command(&message); + ReturnValue_t result = commandQueue->receiveMessage(&command); if (result == HasReturnvaluesIF::RETURN_OK) { - result = healthHelper.handleHealthCommand(&message); + result = healthHelper.handleHealthCommand(&command); if (result == HasReturnvaluesIF::RETURN_OK) { return; } - result = parameterHelper.handleParameterMessage(&message); + result = parameterHelper.handleParameterMessage(&command); if (result == HasReturnvaluesIF::RETURN_OK) { return; } - message.setToUnknownCommand(); + command.setToUnknownCommand(); commandQueue->reply(&message); } } diff --git a/thermal/Heater.cpp b/thermal/Heater.cpp index 29daa15d..6e191fc1 100644 --- a/thermal/Heater.cpp +++ b/thermal/Heater.cpp @@ -279,14 +279,15 @@ ReturnValue_t Heater::initialize() { } void Heater::handleQueue() { - CommandMessage message; - ReturnValue_t result = commandQueue->receiveMessage(&message); + MessageQueueMessage message; + CommandMessage command(&message); + ReturnValue_t result = commandQueue->receiveMessage(&command); if (result == HasReturnvaluesIF::RETURN_OK) { - result = healthHelper.handleHealthCommand(&message); + result = healthHelper.handleHealthCommand(&command); if (result == HasReturnvaluesIF::RETURN_OK) { return; } - parameterHelper.handleParameterMessage(&message); + parameterHelper.handleParameterMessage(&command); } } diff --git a/tmstorage/TmStoreMessage.cpp b/tmstorage/TmStoreMessage.cpp index 4509ba91..669ecc0e 100644 --- a/tmstorage/TmStoreMessage.cpp +++ b/tmstorage/TmStoreMessage.cpp @@ -74,7 +74,7 @@ void TmStoreMessage::clear(CommandMessage* cmd) { case DELETE_STORE_CONTENT_BLOCKS: case DOWNLINK_STORE_CONTENT_BLOCKS: case REPORT_INDEX_REQUEST: - cmd->setCommand(UNKNOW_COMMAND); + cmd->setCommand(CommandMessage::UNKNOWN_COMMAND); cmd->setParameter(0); cmd->setParameter2(0); break; diff --git a/tmstorage/TmStoreMessage.h b/tmstorage/TmStoreMessage.h index bd6b2def..93c23e40 100644 --- a/tmstorage/TmStoreMessage.h +++ b/tmstorage/TmStoreMessage.h @@ -5,7 +5,7 @@ #include #include #include -class TmStoreMessage: public CommandMessage { +class TmStoreMessage { public: static ReturnValue_t setEnableStoringMessage(CommandMessage* cmd, bool setEnabled); diff --git a/tmtcservices/CommandingServiceBase.cpp b/tmtcservices/CommandingServiceBase.cpp index adc9400f..a4fc1110 100644 --- a/tmtcservices/CommandingServiceBase.cpp +++ b/tmtcservices/CommandingServiceBase.cpp @@ -77,7 +77,10 @@ ReturnValue_t CommandingServiceBase::initialize() { } void CommandingServiceBase::handleCommandQueue() { - CommandMessage reply, nextCommand; + MessageQueueMessage replyMessage; + CommandMessage reply(&replyMessage); + MessageQueueMessage nextCommandMessage; + CommandMessage nextCommand(&nextCommandMessage); ReturnValue_t result, sendResult = RETURN_OK; bool isStep = false; for (result = commandQueue->receiveMessage(&reply); result == RETURN_OK; @@ -268,16 +271,17 @@ void CommandingServiceBase::startExecution( typename FixedMap::Iterator *iter) { ReturnValue_t result, sendResult = RETURN_OK; - CommandMessage message; + MessageQueueMessage message; + CommandMessage command(&message); (*iter)->subservice = storedPacket->getSubService(); - result = prepareCommand(&message, (*iter)->subservice, + result = prepareCommand(&command, (*iter)->subservice, storedPacket->getApplicationData(), storedPacket->getApplicationDataSize(), &(*iter)->state, (*iter)->objectId); switch (result) { case RETURN_OK: - if (message.getCommand() != CommandMessage::CMD_NONE) { + if (command.getCommand() != CommandMessage::CMD_NONE) { sendResult = commandQueue->sendMessage((*iter).value->first, &message); } @@ -286,20 +290,20 @@ void CommandingServiceBase::startExecution( (*iter)->step = 0; // (*iter)->state = 0; (*iter)->subservice = storedPacket->getSubService(); - (*iter)->command = message.getCommand(); + (*iter)->command = command.getCommand(); (*iter)->tcInfo.ackFlags = storedPacket->getAcknowledgeFlags(); (*iter)->tcInfo.tcPacketId = storedPacket->getPacketId(); (*iter)->tcInfo.tcSequenceControl = storedPacket->getPacketSequenceControl(); acceptPacket(TC_VERIFY::START_SUCCESS, storedPacket); } else { - message.clearCommandMessage(); + command.clearCommandMessage(); rejectPacket(TC_VERIFY::START_FAILURE, storedPacket, sendResult); checkAndExecuteFifo(iter); } break; case EXECUTION_COMPLETE: - if (message.getCommand() != CommandMessage::CMD_NONE) { + if (command.getCommand() != CommandMessage::CMD_NONE) { //Fire-and-forget command. sendResult = commandQueue->sendMessage((*iter).value->first, &message); @@ -310,7 +314,7 @@ void CommandingServiceBase::startExecution( acceptPacket(TC_VERIFY::COMPLETION_SUCCESS, storedPacket); checkAndExecuteFifo(iter); } else { - message.clearCommandMessage(); + command.clearCommandMessage(); rejectPacket(TC_VERIFY::START_FAILURE, storedPacket, sendResult); checkAndExecuteFifo(iter); } From 47aa9ddcc382393279c0a769e51e7d732cf25a35 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 9 Jun 2020 02:46:19 +0200 Subject: [PATCH 117/307] doc for mqm improved --- ipc/CommandMessage.cpp | 8 +++ ipc/CommandMessage.h | 56 +++++++++++-------- ipc/MessageQueueMessage.h | 107 +++++++++++++++++++++--------------- ipc/MessageQueueMessageIF.h | 28 +++++++--- 4 files changed, 127 insertions(+), 72 deletions(-) diff --git a/ipc/CommandMessage.cpp b/ipc/CommandMessage.cpp index cd75aee4..44424e02 100644 --- a/ipc/CommandMessage.cpp +++ b/ipc/CommandMessage.cpp @@ -152,3 +152,11 @@ void CommandMessage::setSender(MessageQueueId_t setId) { const uint8_t* CommandMessage::getBuffer() const { return internalMessage->getBuffer(); } + +uint8_t* CommandMessage::getData() { + return internalMessage->getData(); +} + +const uint8_t* CommandMessage::getData() const { + return internalMessage->getData(); +} diff --git a/ipc/CommandMessage.h b/ipc/CommandMessage.h index f6fd86cb..772bd774 100644 --- a/ipc/CommandMessage.h +++ b/ipc/CommandMessage.h @@ -1,16 +1,25 @@ #ifndef FRAMEWORK_IPC_COMMANDMESSAGE_H_ #define FRAMEWORK_IPC_COMMANDMESSAGE_H_ +#include #include #include -#include + #define MAKE_COMMAND_ID( number ) ((MESSAGE_ID << 8) + (number)) typedef uint16_t Command_t; /** - * @brief Used to pass command messages between tasks + * @brief Used to pass command messages between tasks. Primary message type + * for IPC. Contains sender, 2-byte command field, and 2 4-byte + * parameters. + * @details + * It operates on an external memory which is contained inside a + * MessageQueueMessage by taking its address. + * This allows for a more flexible designs of message implementations. + * The pointer can be passed to different message implementations without + * the need of unnecessary copying. * @author Bastian Baetz */ class CommandMessage: public MessageQueueMessageIF { @@ -53,13 +62,10 @@ public: uint32_t parameter1, uint32_t parameter2); /** - * Default Destructor + * @brief Default Destructor */ - virtual ~CommandMessage() { - } + virtual ~CommandMessage() {} - uint8_t * getBuffer() override; - const uint8_t * getBuffer() const override; /** * Read the DeviceHandlerCommand_t that is stored in the message, * usually used after receiving. @@ -68,53 +74,54 @@ public: */ Command_t getCommand() const; - /** - * @brief This method is used to set the sender's message queue id - * information prior to sending the message. - * @param setId - * The message queue id that identifies the sending message queue. + /* + * MessageQueueMessageIF functions, which generally just call the + * respective functions of the internal message */ + uint8_t * getBuffer() override; + const uint8_t * getBuffer() const override; void setSender(MessageQueueId_t setId) override; - MessageQueueId_t getSender() const override; + uint8_t * getData() override; + const uint8_t* getData() const override; + size_t getMinimumMessageSize() const override; + /** + * Extract message ID, which is the first byte of the command ID. + * @return + */ uint8_t getMessageType() const; /** - * Set the DeviceHandlerCOmmand_t of the message - * + * Set the command type of the message * @param the Command to be sent */ void setCommand(Command_t command); /** * Get the first parameter of the message - * * @return the first Parameter of the message */ uint32_t getParameter() const; /** * Set the first parameter of the message - * * @param the first parameter of the message */ void setParameter(uint32_t parameter1); /** * Get the second parameter of the message - * * @return the second Parameter of the message */ uint32_t getParameter2() const; /** * Set the second parameter of the message - * * @param the second parameter of the message */ void setParameter2(uint32_t parameter2); - void clear() override; + /** * Set the command to CMD_NONE and try to find * the correct class to handle a more detailed @@ -126,6 +133,7 @@ public: * */ void clearCommandMessage(); + void clear() override; /** * check if a message was cleared @@ -134,7 +142,6 @@ public: */ bool isClearedCommandMessage(); - /** * Sets the command to REPLY_REJECTED with parameter UNKNOWN_COMMAND. * Is needed quite often, so we better code it once only. @@ -142,9 +149,14 @@ public: void setToUnknownCommand(); void setReplyRejected(ReturnValue_t reason, Command_t initialCommand = CMD_NONE); - size_t getMinimumMessageSize() const override; private: + /** + * @brief Pointer to the message containing the data. + * @details + * The command message does not actually own the memory containing a + * message, it just oprates on it via a pointer to a message queue message. + */ MessageQueueMessage* internalMessage; }; diff --git a/ipc/MessageQueueMessage.h b/ipc/MessageQueueMessage.h index 29d1a869..bee39ae6 100644 --- a/ipc/MessageQueueMessage.h +++ b/ipc/MessageQueueMessage.h @@ -1,5 +1,5 @@ -#ifndef MESSAGEQUEUEMESSAGE_H_ -#define MESSAGEQUEUEMESSAGE_H_ +#ifndef FRAMEWORK_IPC_MESSAGEQUEUEMESSAGE_H_ +#define FRAMEWORK_IPC_MESSAGEQUEUEMESSAGE_H_ #include #include @@ -8,7 +8,6 @@ /** * @brief This class is the representation and data organizer * for interprocess messages. - * * @details * To facilitate and standardize interprocess communication, this class was * created to handle a lightweight "interprocess message protocol". @@ -28,12 +27,14 @@ class MessageQueueMessage: public MessageQueueMessageIF { public: /** * @brief The class is initialized empty with this constructor. - * @details The messageSize attribute is set to the header's size and the - * whole content is set to zero. + * @details + * The messageSize attribute is set to the header's size and the whole + * content is set to zero. */ MessageQueueMessage(); /** - * @brief With this constructor the class is initialized with the given content. + * @brief With this constructor the class is initialized with + * the given content. * @details * If the passed message size fits into the buffer, the passed data is * copied to the internal buffer and the messageSize information is set. @@ -46,7 +47,14 @@ public: MessageQueueMessage(uint8_t* data, size_t size); /** - * @brief The size information of each message is stored in this attribute. + * @brief As no memory is allocated in this class, + * the destructor is empty. + */ + virtual ~MessageQueueMessage(); + + /** + * @brief The size information of each message is stored in + * this attribute. * @details * It is public to simplify usage and to allow for passing the size * address as a pointer. Care must be taken when inheriting from this class, @@ -59,19 +67,26 @@ public: */ size_t messageSize; /** - * @brief This constant defines the maximum size of the data content, excluding the header. - * @details It may be changed if necessary, but in general should be kept as small as possible. + * @brief This constant defines the maximum size of the data content, + * excluding the header. + * @details + * It may be changed if necessary, but in general should be kept + * as small as possible. */ static const size_t MAX_DATA_SIZE = 24; /** - * @brief This constants defines the size of the header, which is added to every message. + * @brief This constants defines the size of the header, + * which is added to every message. */ static const size_t HEADER_SIZE = sizeof(MessageQueueId_t); /** - * @brief This constant defines the maximum total size in bytes of a sent message. - * @details It is the sum of the maximum data and the header size. Be aware that this constant - * is used to define the buffer sizes for every message queue in the system. So, a change - * here may have significant impact on the required resources. + * @brief This constant defines the maximum total size in bytes + * of a sent message. + * @details + * It is the sum of the maximum data and the header size. Be aware that + * this constant is used to define the buffer sizes for every message + * queue in the system. So, a change here may have significant impact on + * the required resources. */ static const size_t MAX_MESSAGE_SIZE = MAX_DATA_SIZE + HEADER_SIZE; /** @@ -81,58 +96,64 @@ public: static const size_t MIN_MESSAGE_SIZE = HEADER_SIZE; private: /** - * @brief This is the internal buffer that contains the actual message data. + * @brief This is the internal buffer that contains the + * actual message data. */ uint8_t internalBuffer[MAX_MESSAGE_SIZE]; public: /** - * @brief As no memory is allocated in this class, the destructor is empty. + * @brief This method is used to get the complete data of the message. */ - virtual ~MessageQueueMessage(); + const uint8_t* getBuffer() const override; /** * @brief This method is used to get the complete data of the message. */ - const uint8_t* getBuffer() const; - /** - * @brief This method is used to get the complete data of the message. - */ - uint8_t* getBuffer(); + uint8_t* getBuffer() override; /** * @brief This method is used to fetch the data content of the message. - * @details It shall be used by child classes to add data at the right position. + * @details + * It shall be used by child classes to add data at the right position. */ - const uint8_t* getData() const; + const uint8_t* getData() const override; /** * @brief This method is used to fetch the data content of the message. - * @details It shall be used by child classes to add data at the right position. + * @details + * It shall be used by child classes to add data at the right position. */ - uint8_t* getData(); + uint8_t* getData() override; /** - * @brief This method is used to extract the sender's message queue id information from a - * received message. + * @brief This method is used to extract the sender's message + * queue id information from a received message. */ - MessageQueueId_t getSender() const; + MessageQueueId_t getSender() const override; /** - * @brief With this method, the whole content and the message size is set to zero. + * @brief With this method, the whole content + * and the message size is set to zero. */ - void clear(); + void clear() override; + /** - * @brief This is a debug method that prints the content (till messageSize) to the debug output. + * @brief This method is used to set the sender's message queue id + * information prior to ing the message. + * @param setId + * The message queue id that identifies the sending message queue. */ - void print(); + void setSender(MessageQueueId_t setId) override; /** - * @brief This method is used to set the sender's message queue id information prior to - * sending the message. - * @param setId The message queue id that identifies the sending message queue. - */ - void setSender(MessageQueueId_t setId); - /** - * @brief This helper function is used by the MessageQueue class to check the size of an - * incoming message. - * @details The method must be overwritten by child classes if size checks shall be more strict. + * @brief This helper function is used by the MessageQueue class to check + * the size of an incoming message. + * @details + * The method must be overwritten by child classes if size + * checks shall be more strict. * @return The default implementation returns HEADER_SIZE. */ - virtual size_t getMinimumMessageSize() const; + virtual size_t getMinimumMessageSize() const override; + + /** + * @brief This is a debug method that prints the content + * (till messageSize) to the debug output. + */ + void print(); }; #endif /* MESSAGEQUEUEMESSAGE_H_ */ diff --git a/ipc/MessageQueueMessageIF.h b/ipc/MessageQueueMessageIF.h index 0a6288b0..197a26fd 100644 --- a/ipc/MessageQueueMessageIF.h +++ b/ipc/MessageQueueMessageIF.h @@ -11,7 +11,9 @@ * lookup of queueIDs for every call does not sound ideal. * In a first step, I'll circumvent the issue by not touching it, * maybe in a second step. This also influences Interface design - * (getCommandQueue) and some other issues.. */ + * (getCommandQueue) and some other issues.. + */ + typedef uint32_t MessageQueueId_t; class MessageQueueMessageIF { @@ -25,14 +27,9 @@ public: * size is set to zero. */ virtual void clear() = 0; -// /** -// * @brief This is a debug method that prints the content -// * (till messageSize) to the debug output. -// */ -// virtual void print() = 0; /** - * @brief Get read-only pointer to the raw buffer. + * @brief Get read-only pointer to the complete data of the message. * @return */ virtual const uint8_t* getBuffer() const = 0; @@ -50,8 +47,25 @@ public: */ virtual void setSender(MessageQueueId_t setId) = 0; + /** + * @brief This method is used to extract the sender's message queue id + * information from a received message. + */ virtual MessageQueueId_t getSender() const = 0; + /** + * @brief This method is used to fetch the data content of the message. + * @details + * It shall be used by child classes to add data at the right position. + */ + virtual const uint8_t* getData() const = 0; + /** + * @brief This method is used to fetch the data content of the message. + * @details + * It shall be used by child classes to add data at the right position. + */ + virtual uint8_t* getData() = 0; + /** * @brief This helper function is used by the MessageQueue class to * check the size of an incoming message. From ea2cd7c1a0b4f50e534e0640236dc3a349b4bcdd Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 10 Jun 2020 01:07:08 +0200 Subject: [PATCH 118/307] some fixes, doc improvements --- osal/linux/MessageQueue.cpp | 102 +++++++++++++++++++++--------------- 1 file changed, 60 insertions(+), 42 deletions(-) diff --git a/osal/linux/MessageQueue.cpp b/osal/linux/MessageQueue.cpp index 86d1e0d9..a9c140c6 100644 --- a/osal/linux/MessageQueue.cpp +++ b/osal/linux/MessageQueue.cpp @@ -56,16 +56,23 @@ ReturnValue_t MessageQueue::handleError(mq_attr* attributes, sif::error << "MessageQueue::MessageQueue: Invalid name or attributes" " for message size" << std::endl; size_t defaultMqMaxMsg = 0; + // Not POSIX conformant, but should work for all UNIX systems. + // Just an additional helpful printout :-) if(std::ifstream("/proc/sys/fs/mqueue/msg_max",std::ios::in) >> defaultMqMaxMsg and defaultMqMaxMsg < messageDepth) { // See: https://www.man7.org/linux/man-pages/man3/mq_open.3.html // This happens if the msg_max value is not large enough // It is ignored if the executable is run in privileged mode. - // Run the unlockRealtime script or grant the mode manully by using: + // Run the unlockRealtime script or grant the mode manually by using: // sudo setcap 'CAP_SYS_RESOURCE=+ep' - // Permanent solution (EventManager has mq depth of 80): - // echo msg_max | sudo tee /proc/sys/fs/mqueue/msg_max + // Persistent solution for session: + // echo | sudo tee /proc/sys/fs/mqueue/msg_max + + // Permanent solution: + // sudo nano /etc/sysctl.conf + // Append at end: fs/mqueue/msg_max = + // Apply changes with: sudo sysctl -p sif::error << "MessageQueue::MessageQueue: Default MQ size " << defaultMqMaxMsg << " is too small for requested size " << messageDepth << std::endl; @@ -75,24 +82,22 @@ ReturnValue_t MessageQueue::handleError(mq_attr* attributes, case(EEXIST): { // An error occured during open // We need to distinguish if it is caused by an already created queue - if (errno == EEXIST) { - //There's another queue with the same name - //We unlink the other queue - int status = mq_unlink(name); - if (status != 0) { - sif::error << "mq_unlink Failed with status: " << strerror(errno) - << std::endl; - } - else { - // Successful unlinking, try to open again - mqd_t tempId = mq_open(name, - O_NONBLOCK | O_RDWR | O_CREAT | O_EXCL, - S_IWUSR | S_IREAD | S_IWGRP | S_IRGRP, attributes); - if (tempId != -1) { - //Successful mq_open - this->id = tempId; - return HasReturnvaluesIF::RETURN_OK; - } + //There's another queue with the same name + //We unlink the other queue + int status = mq_unlink(name); + if (status != 0) { + sif::error << "mq_unlink Failed with status: " << strerror(errno) + << std::endl; + } + else { + // Successful unlinking, try to open again + mqd_t tempId = mq_open(name, + O_NONBLOCK | O_RDWR | O_CREAT | O_EXCL, + S_IWUSR | S_IREAD | S_IWGRP | S_IRGRP, attributes); + if (tempId != -1) { + //Successful mq_open + this->id = tempId; + return HasReturnvaluesIF::RETURN_OK; } } break; @@ -150,12 +155,13 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message) { //Success but no message received return MessageQueueIF::EMPTY; } else { - //No message was received. Keep lastPartner anyway, I might send something later. - //But still, delete packet content. + //No message was received. Keep lastPartner anyway, I might send + //something later. But still, delete packet content. memset(message->getData(), 0, message->MAX_DATA_SIZE); switch(errno){ case EAGAIN: - //O_NONBLOCK or MQ_NONBLOCK was set and there are no messages currently on the specified queue. + //O_NONBLOCK or MQ_NONBLOCK was set and there are no messages + //currently on the specified queue. return MessageQueueIF::EMPTY; case EBADF: //mqdes doesn't represent a valid queue open for reading. @@ -165,9 +171,12 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message) { case EINVAL: /* * This value indicates one of the following: - * * The pointer to the buffer for storing the received message, msg_ptr, is NULL. - * * The number of bytes requested, msg_len is less than zero. - * * msg_len is anything other than the mq_msgsize of the specified queue, and the QNX extended option MQ_READBUF_DYNAMIC hasn't been set in the queue's mq_flags. + * - The pointer to the buffer for storing the received message, + * msg_ptr, is NULL. + * - The number of bytes requested, msg_len is less than zero. + * - msg_len is anything other than the mq_msgsize of the specified + * queue, and the QNX extended option MQ_READBUF_DYNAMIC hasn't + * been set in the queue's mq_flags. */ sif::error << "MessageQueue::receive: configuration error " << strerror(errno) << std::endl; @@ -175,8 +184,12 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message) { case EMSGSIZE: /* * This value indicates one of the following: - * * the QNX extended option MQ_READBUF_DYNAMIC hasn't been set, and the given msg_len is shorter than the mq_msgsize for the given queue. - * * the extended option MQ_READBUF_DYNAMIC has been set, but the given msg_len is too short for the message that would have been received. + * - the QNX extended option MQ_READBUF_DYNAMIC hasn't been set, + * and the given msg_len is shorter than the mq_msgsize for + * the given queue. + * - the extended option MQ_READBUF_DYNAMIC has been set, but the + * given msg_len is too short for the message that would have + * been received. */ sif::error << "MessageQueue::receive: configuration error " << strerror(errno) << std::endl; @@ -224,9 +237,10 @@ ReturnValue_t MessageQueue::flush(uint32_t* count) { case EINVAL: /* * This value indicates one of the following: - * * mq_attr is NULL. - * * MQ_MULT_NOTIFY had been set for this queue, and the given mq_flags includes a 0 in the MQ_MULT_NOTIFY bit. Once MQ_MULT_NOTIFY has been turned on, it may never be turned off. - * + * - mq_attr is NULL. + * - MQ_MULT_NOTIFY had been set for this queue, and the given + * mq_flags includes a 0 in the MQ_MULT_NOTIFY bit. Once + * MQ_MULT_NOTIFY has been turned on, it may never be turned off. */ default: return HasReturnvaluesIF::RETURN_FAILED; @@ -275,7 +289,8 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, //TODO: Check if we're in ISR. if (result != 0) { if(!ignoreFault){ - InternalErrorReporterIF* internalErrorReporter = objectManager->get( + InternalErrorReporterIF* internalErrorReporter = + objectManager->get( objects::INTERNAL_ERROR_REPORTER); if (internalErrorReporter != NULL) { internalErrorReporter->queueMessageNotSent(); @@ -283,10 +298,13 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, } switch(errno){ case EAGAIN: - //The O_NONBLOCK flag was set when opening the queue, or the MQ_NONBLOCK flag was set in its attributes, and the specified queue is full. + //The O_NONBLOCK flag was set when opening the queue, or the + //MQ_NONBLOCK flag was set in its attributes, and the + //specified queue is full. return MessageQueueIF::FULL; case EBADF: - //mq_des doesn't represent a valid message queue descriptor, or mq_des wasn't opened for writing. + //mq_des doesn't represent a valid message queue descriptor, + //or mq_des wasn't opened for writing. sif::error << "MessageQueue::sendMessage: Configuration error " << strerror(errno) << " in mq_send mqSendTo: " << sendTo << " sent from " << sentFrom << std::endl; @@ -296,13 +314,13 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, case EINVAL: /* * This value indicates one of the following: - * * msg_ptr is NULL. - * * msg_len is negative. - * * msg_prio is greater than MQ_PRIO_MAX. - * * msg_prio is less than 0. - * * MQ_PRIO_RESTRICT is set in the mq_attr of mq_des, - * and msg_prio is greater than the priority of the calling process. - * */ + * - msg_ptr is NULL. + * - msg_len is negative. + * - msg_prio is greater than MQ_PRIO_MAX. + * - msg_prio is less than 0. + * - MQ_PRIO_RESTRICT is set in the mq_attr of mq_des, and + * msg_prio is greater than the priority of the calling process. + */ sif::error << "MessageQueue::sendMessage: Configuration error " << strerror(errno) << " in mq_send" << std::endl; /*NO BREAK*/ From 3277d199ac166db242ff1fb7b5edfab6fa2964ec Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 10 Jun 2020 01:07:50 +0200 Subject: [PATCH 119/307] linux mq update --- osal/linux/MessageQueue.cpp | 102 +++++++++++++++++++++--------------- 1 file changed, 60 insertions(+), 42 deletions(-) diff --git a/osal/linux/MessageQueue.cpp b/osal/linux/MessageQueue.cpp index 86d1e0d9..a9c140c6 100644 --- a/osal/linux/MessageQueue.cpp +++ b/osal/linux/MessageQueue.cpp @@ -56,16 +56,23 @@ ReturnValue_t MessageQueue::handleError(mq_attr* attributes, sif::error << "MessageQueue::MessageQueue: Invalid name or attributes" " for message size" << std::endl; size_t defaultMqMaxMsg = 0; + // Not POSIX conformant, but should work for all UNIX systems. + // Just an additional helpful printout :-) if(std::ifstream("/proc/sys/fs/mqueue/msg_max",std::ios::in) >> defaultMqMaxMsg and defaultMqMaxMsg < messageDepth) { // See: https://www.man7.org/linux/man-pages/man3/mq_open.3.html // This happens if the msg_max value is not large enough // It is ignored if the executable is run in privileged mode. - // Run the unlockRealtime script or grant the mode manully by using: + // Run the unlockRealtime script or grant the mode manually by using: // sudo setcap 'CAP_SYS_RESOURCE=+ep' - // Permanent solution (EventManager has mq depth of 80): - // echo msg_max | sudo tee /proc/sys/fs/mqueue/msg_max + // Persistent solution for session: + // echo | sudo tee /proc/sys/fs/mqueue/msg_max + + // Permanent solution: + // sudo nano /etc/sysctl.conf + // Append at end: fs/mqueue/msg_max = + // Apply changes with: sudo sysctl -p sif::error << "MessageQueue::MessageQueue: Default MQ size " << defaultMqMaxMsg << " is too small for requested size " << messageDepth << std::endl; @@ -75,24 +82,22 @@ ReturnValue_t MessageQueue::handleError(mq_attr* attributes, case(EEXIST): { // An error occured during open // We need to distinguish if it is caused by an already created queue - if (errno == EEXIST) { - //There's another queue with the same name - //We unlink the other queue - int status = mq_unlink(name); - if (status != 0) { - sif::error << "mq_unlink Failed with status: " << strerror(errno) - << std::endl; - } - else { - // Successful unlinking, try to open again - mqd_t tempId = mq_open(name, - O_NONBLOCK | O_RDWR | O_CREAT | O_EXCL, - S_IWUSR | S_IREAD | S_IWGRP | S_IRGRP, attributes); - if (tempId != -1) { - //Successful mq_open - this->id = tempId; - return HasReturnvaluesIF::RETURN_OK; - } + //There's another queue with the same name + //We unlink the other queue + int status = mq_unlink(name); + if (status != 0) { + sif::error << "mq_unlink Failed with status: " << strerror(errno) + << std::endl; + } + else { + // Successful unlinking, try to open again + mqd_t tempId = mq_open(name, + O_NONBLOCK | O_RDWR | O_CREAT | O_EXCL, + S_IWUSR | S_IREAD | S_IWGRP | S_IRGRP, attributes); + if (tempId != -1) { + //Successful mq_open + this->id = tempId; + return HasReturnvaluesIF::RETURN_OK; } } break; @@ -150,12 +155,13 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message) { //Success but no message received return MessageQueueIF::EMPTY; } else { - //No message was received. Keep lastPartner anyway, I might send something later. - //But still, delete packet content. + //No message was received. Keep lastPartner anyway, I might send + //something later. But still, delete packet content. memset(message->getData(), 0, message->MAX_DATA_SIZE); switch(errno){ case EAGAIN: - //O_NONBLOCK or MQ_NONBLOCK was set and there are no messages currently on the specified queue. + //O_NONBLOCK or MQ_NONBLOCK was set and there are no messages + //currently on the specified queue. return MessageQueueIF::EMPTY; case EBADF: //mqdes doesn't represent a valid queue open for reading. @@ -165,9 +171,12 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message) { case EINVAL: /* * This value indicates one of the following: - * * The pointer to the buffer for storing the received message, msg_ptr, is NULL. - * * The number of bytes requested, msg_len is less than zero. - * * msg_len is anything other than the mq_msgsize of the specified queue, and the QNX extended option MQ_READBUF_DYNAMIC hasn't been set in the queue's mq_flags. + * - The pointer to the buffer for storing the received message, + * msg_ptr, is NULL. + * - The number of bytes requested, msg_len is less than zero. + * - msg_len is anything other than the mq_msgsize of the specified + * queue, and the QNX extended option MQ_READBUF_DYNAMIC hasn't + * been set in the queue's mq_flags. */ sif::error << "MessageQueue::receive: configuration error " << strerror(errno) << std::endl; @@ -175,8 +184,12 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message) { case EMSGSIZE: /* * This value indicates one of the following: - * * the QNX extended option MQ_READBUF_DYNAMIC hasn't been set, and the given msg_len is shorter than the mq_msgsize for the given queue. - * * the extended option MQ_READBUF_DYNAMIC has been set, but the given msg_len is too short for the message that would have been received. + * - the QNX extended option MQ_READBUF_DYNAMIC hasn't been set, + * and the given msg_len is shorter than the mq_msgsize for + * the given queue. + * - the extended option MQ_READBUF_DYNAMIC has been set, but the + * given msg_len is too short for the message that would have + * been received. */ sif::error << "MessageQueue::receive: configuration error " << strerror(errno) << std::endl; @@ -224,9 +237,10 @@ ReturnValue_t MessageQueue::flush(uint32_t* count) { case EINVAL: /* * This value indicates one of the following: - * * mq_attr is NULL. - * * MQ_MULT_NOTIFY had been set for this queue, and the given mq_flags includes a 0 in the MQ_MULT_NOTIFY bit. Once MQ_MULT_NOTIFY has been turned on, it may never be turned off. - * + * - mq_attr is NULL. + * - MQ_MULT_NOTIFY had been set for this queue, and the given + * mq_flags includes a 0 in the MQ_MULT_NOTIFY bit. Once + * MQ_MULT_NOTIFY has been turned on, it may never be turned off. */ default: return HasReturnvaluesIF::RETURN_FAILED; @@ -275,7 +289,8 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, //TODO: Check if we're in ISR. if (result != 0) { if(!ignoreFault){ - InternalErrorReporterIF* internalErrorReporter = objectManager->get( + InternalErrorReporterIF* internalErrorReporter = + objectManager->get( objects::INTERNAL_ERROR_REPORTER); if (internalErrorReporter != NULL) { internalErrorReporter->queueMessageNotSent(); @@ -283,10 +298,13 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, } switch(errno){ case EAGAIN: - //The O_NONBLOCK flag was set when opening the queue, or the MQ_NONBLOCK flag was set in its attributes, and the specified queue is full. + //The O_NONBLOCK flag was set when opening the queue, or the + //MQ_NONBLOCK flag was set in its attributes, and the + //specified queue is full. return MessageQueueIF::FULL; case EBADF: - //mq_des doesn't represent a valid message queue descriptor, or mq_des wasn't opened for writing. + //mq_des doesn't represent a valid message queue descriptor, + //or mq_des wasn't opened for writing. sif::error << "MessageQueue::sendMessage: Configuration error " << strerror(errno) << " in mq_send mqSendTo: " << sendTo << " sent from " << sentFrom << std::endl; @@ -296,13 +314,13 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, case EINVAL: /* * This value indicates one of the following: - * * msg_ptr is NULL. - * * msg_len is negative. - * * msg_prio is greater than MQ_PRIO_MAX. - * * msg_prio is less than 0. - * * MQ_PRIO_RESTRICT is set in the mq_attr of mq_des, - * and msg_prio is greater than the priority of the calling process. - * */ + * - msg_ptr is NULL. + * - msg_len is negative. + * - msg_prio is greater than MQ_PRIO_MAX. + * - msg_prio is less than 0. + * - MQ_PRIO_RESTRICT is set in the mq_attr of mq_des, and + * msg_prio is greater than the priority of the calling process. + */ sif::error << "MessageQueue::sendMessage: Configuration error " << strerror(errno) << " in mq_send" << std::endl; /*NO BREAK*/ From 20e3b3c0e2eeec791f2f7c25e1893808af28c0eb Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 10 Jun 2020 01:10:16 +0200 Subject: [PATCH 120/307] 0 replaced by MQIF::NO_QUEUE --- osal/linux/MessageQueue.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osal/linux/MessageQueue.cpp b/osal/linux/MessageQueue.cpp index a9c140c6..a0749ded 100644 --- a/osal/linux/MessageQueue.cpp +++ b/osal/linux/MessageQueue.cpp @@ -9,8 +9,9 @@ #include -MessageQueue::MessageQueue(uint32_t messageDepth, size_t maxMessageSize): id(0), - lastPartner(0), defaultDestination(NO_QUEUE) { +MessageQueue::MessageQueue(uint32_t messageDepth, size_t maxMessageSize): + id(MessageQueueIF::NO_QUEUE),lastPartner(MessageQueueIF::NO_QUEUE), + defaultDestination(MessageQueueIF::NO_QUEUE) { //debug << "MessageQueue::MessageQueue: Creating a queue" << std::endl; mq_attr attributes; this->id = 0; From 4dd037550774263fe9941e96a9212ea5b084531a Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 10 Jun 2020 01:10:40 +0200 Subject: [PATCH 121/307] 0 replaced by MQIF:NO_QUEUE --- osal/linux/MessageQueue.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osal/linux/MessageQueue.cpp b/osal/linux/MessageQueue.cpp index a9c140c6..a0749ded 100644 --- a/osal/linux/MessageQueue.cpp +++ b/osal/linux/MessageQueue.cpp @@ -9,8 +9,9 @@ #include -MessageQueue::MessageQueue(uint32_t messageDepth, size_t maxMessageSize): id(0), - lastPartner(0), defaultDestination(NO_QUEUE) { +MessageQueue::MessageQueue(uint32_t messageDepth, size_t maxMessageSize): + id(MessageQueueIF::NO_QUEUE),lastPartner(MessageQueueIF::NO_QUEUE), + defaultDestination(MessageQueueIF::NO_QUEUE) { //debug << "MessageQueue::MessageQueue: Creating a queue" << std::endl; mq_attr attributes; this->id = 0; From b6f6a61656ac423b2411e4c4ab187d54d0b18b1b Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 10 Jun 2020 20:51:59 +0200 Subject: [PATCH 122/307] iomanip include missing --- objectmanager/ObjectManager.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/objectmanager/ObjectManager.cpp b/objectmanager/ObjectManager.cpp index cfdf6562..1c54355a 100644 --- a/objectmanager/ObjectManager.cpp +++ b/objectmanager/ObjectManager.cpp @@ -1,5 +1,6 @@ #include #include +#include #include ObjectManager::ObjectManager( void (*setProducer)() ): From 52c887925fe68f0729db72925c24e3b703ca600b Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 10 Jun 2020 20:53:28 +0200 Subject: [PATCH 123/307] iomanip include --- objectmanager/ObjectManager.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/objectmanager/ObjectManager.cpp b/objectmanager/ObjectManager.cpp index cfdf6562..1c54355a 100644 --- a/objectmanager/ObjectManager.cpp +++ b/objectmanager/ObjectManager.cpp @@ -1,5 +1,6 @@ #include #include +#include #include ObjectManager::ObjectManager( void (*setProducer)() ): From 606957dc243f31d18d80f51885f4684fc134186b Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 10 Jun 2020 21:26:45 +0200 Subject: [PATCH 124/307] PSB update --- tmtcservices/PusServiceBase.cpp | 74 +++++++++++++++++++-------------- tmtcservices/PusServiceBase.h | 8 ++-- 2 files changed, 48 insertions(+), 34 deletions(-) diff --git a/tmtcservices/PusServiceBase.cpp b/tmtcservices/PusServiceBase.cpp index c27defe6..f5d1e30b 100644 --- a/tmtcservices/PusServiceBase.cpp +++ b/tmtcservices/PusServiceBase.cpp @@ -9,10 +9,11 @@ object_id_t PusServiceBase::packetSource = 0; object_id_t PusServiceBase::packetDestination = 0; -PusServiceBase::PusServiceBase(object_id_t setObjectId, uint16_t setApid, uint8_t setServiceId) : - SystemObject(setObjectId), apid(setApid), serviceId(setServiceId), errorParameter1( - 0), errorParameter2(0), requestQueue(NULL) { - requestQueue = QueueFactory::instance()->createMessageQueue(PUS_SERVICE_MAX_RECEPTION); +PusServiceBase::PusServiceBase(object_id_t setObjectId, uint16_t setApid, + uint8_t setServiceId) : + SystemObject(setObjectId), apid(setApid), serviceId(setServiceId) { + requestQueue = QueueFactory::instance()-> + createMessageQueue(PUS_SERVICE_MAX_RECEPTION); } PusServiceBase::~PusServiceBase() { @@ -20,51 +21,60 @@ PusServiceBase::~PusServiceBase() { } ReturnValue_t PusServiceBase::performOperation(uint8_t opCode) { + handleRequestQueue(); + ReturnValue_t result = this->performService(); + if (result != RETURN_OK) { + sif::error << "PusService " << (uint16_t) this->serviceId + << ": performService returned with " << (int16_t) result + << std::endl; + return RETURN_FAILED; + } + return RETURN_OK; +} + +void PusServiceBase::handleRequestQueue() { TmTcMessage message; + ReturnValue_t result = RETURN_FAILED; for (uint8_t count = 0; count < PUS_SERVICE_MAX_RECEPTION; count++) { ReturnValue_t status = this->requestQueue->receiveMessage(&message); - // debug << "PusServiceBase::performOperation: Receiving from MQ ID: " << std::hex << this->requestQueue.getId() - // << std::dec << " returned: " << status << std::endl; + // debug << "PusServiceBase::performOperation: Receiving from MQ ID: " + // << std::hex << this->requestQueue.getId() + // << std::dec << " returned: " << status << std::endl; if (status == RETURN_OK) { this->currentPacket.setStoreAddress(message.getStorageId()); - // info << "Service " << (uint16_t) this->serviceId << ": new packet!" << std::endl; + //info << "Service " << (uint16_t) this->serviceId << + // ": new packet!" << std::endl; - ReturnValue_t return_code = this->handleRequest(currentPacket.getSubService()); + result = this->handleRequest(currentPacket.getSubService()); - // debug << "Service " << (uint16_t)this->serviceId << ": handleRequest returned: " << (int)return_code << std::endl; - if (return_code == RETURN_OK) { + // debug << "Service " << (uint16_t)this->serviceId << + // ": handleRequest returned: " << (int)return_code << std::endl; + if (result == RETURN_OK) { this->verifyReporter.sendSuccessReport( TC_VERIFY::COMPLETION_SUCCESS, &this->currentPacket); - } else { + } + else { this->verifyReporter.sendFailureReport( TC_VERIFY::COMPLETION_FAILURE, &this->currentPacket, - return_code, 0, errorParameter1, errorParameter2); + result, 0, errorParameter1, errorParameter2); } this->currentPacket.deletePacket(); errorParameter1 = 0; errorParameter2 = 0; - } else if (status == MessageQueueIF::EMPTY) { + } + else if (status == MessageQueueIF::EMPTY) { status = RETURN_OK; - // debug << "PusService " << (uint16_t)this->serviceId << ": no new packet." << std::endl; + // debug << "PusService " << (uint16_t)this->serviceId << + // ": no new packet." << std::endl; break; - } else { - + } + else { sif::error << "PusServiceBase::performOperation: Service " << (uint16_t) this->serviceId << ": Error receiving packet. Code: " << std::hex << status << std::dec << std::endl; } } - ReturnValue_t return_code = this->performService(); - if (return_code == RETURN_OK) { - return RETURN_OK; - } else { - - sif::error << "PusService " << (uint16_t) this->serviceId - << ": performService returned with " << (int16_t) return_code - << std::endl; - return RETURN_FAILED; - } } uint16_t PusServiceBase::getIdentifier() { @@ -80,19 +90,21 @@ ReturnValue_t PusServiceBase::initialize() { if (result != RETURN_OK) { return result; } - AcceptsTelemetryIF* dest_service = objectManager->get( + AcceptsTelemetryIF* destService = objectManager->get( packetDestination); PUSDistributorIF* distributor = objectManager->get( packetSource); - if ((dest_service != NULL) && (distributor != NULL)) { + if ((destService != nullptr) && (distributor != nullptr)) { this->requestQueue->setDefaultDestination( - dest_service->getReportReceptionQueue()); + destService->getReportReceptionQueue()); distributor->registerService(this); return RETURN_OK; - } else { + } + else { sif::error << "PusServiceBase::PusServiceBase: Service " << (uint32_t) this->serviceId << ": Configuration error." - << " Make sure packetSource and packetDestination are defined correctly" << std::endl; + << " Make sure packetSource and packetDestination are defined " + "correctly" << std::endl; return RETURN_FAILED; } } diff --git a/tmtcservices/PusServiceBase.h b/tmtcservices/PusServiceBase.h index dbb1754c..5f741410 100644 --- a/tmtcservices/PusServiceBase.h +++ b/tmtcservices/PusServiceBase.h @@ -97,16 +97,16 @@ protected: /** * One of two error parameters for additional error information. */ - uint32_t errorParameter1; + uint32_t errorParameter1 = 0; /** * One of two error parameters for additional error information. */ - uint32_t errorParameter2; + uint32_t errorParameter2 = 0; /** * This is a complete instance of the Telecommand reception queue of the class. * It is initialized on construction of the class. */ - MessageQueueIF* requestQueue; + MessageQueueIF* requestQueue = nullptr; /** * An instance of the VerificationReporter class, that simplifies sending any kind of * Verification Message to the TC Verification Service. @@ -127,6 +127,8 @@ private: * Remember that one packet must be completely handled in one #handleRequest call. */ static const uint8_t PUS_SERVICE_MAX_RECEPTION = 10; + + void handleRequestQueue(); }; #endif /* PUSSERVICEBASE_H_ */ From 659594bac71505492c01feff182a2577f79fb1fe Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 10 Jun 2020 21:35:47 +0200 Subject: [PATCH 125/307] better include guard and doc form improvement --- tmtcservices/PusServiceBase.h | 80 +++++++++++++++++++++-------------- 1 file changed, 48 insertions(+), 32 deletions(-) diff --git a/tmtcservices/PusServiceBase.h b/tmtcservices/PusServiceBase.h index 5f741410..39600c41 100644 --- a/tmtcservices/PusServiceBase.h +++ b/tmtcservices/PusServiceBase.h @@ -1,5 +1,5 @@ -#ifndef PUSSERVICEBASE_H_ -#define PUSSERVICEBASE_H_ +#ifndef FRAMEWORK_TMTCSERVICES_PUSSERVICEBASE_H_ +#define FRAMEWORK_TMTCSERVICES_PUSSERVICEBASE_H_ #include #include @@ -9,7 +9,6 @@ #include #include #include -#include #include namespace Factory{ @@ -17,18 +16,22 @@ void setStaticFrameworkObjectIds(); } /** - * \defgroup pus_services PUS Service Framework + * @defgroup pus_services PUS Service Framework * These group contains all implementations of PUS Services in the OBSW. * Most of the Services are directly taken from the ECSS PUS Standard. */ /** - * \brief This class is the basis for all PUS Services, which can immediately process Telecommand Packets. - * It manages Telecommand reception and the generation of Verification Reports. Every class that inherits - * from this abstract class has to implement handleRequest and performService. Services that are created with this + * @brief This class is the basis for all PUS Services, + * which can immediately process Telecommand Packets. + * @details + * It manages Telecommand reception and the generation of Verification Reports. + * Every class that inherits from this abstract class has to implement + * handleRequest and performService. Services that are created with this * Base class have to handle any kind of request immediately on reception. - * All PUS Services are System Objects, so an Object ID needs to be specified on construction. - * \ingroup pus_services + * All PUS Services are System Objects, so an Object ID needs to be specified + * on construction. + * @ingroup pus_services */ class PusServiceBase : public ExecutableObjectIF, public AcceptsTelecommandsIF, @@ -37,49 +40,61 @@ class PusServiceBase : public ExecutableObjectIF, friend void (Factory::setStaticFrameworkObjectIds)(); public: /** - * The constructor for the class. - * The passed values are set, but inter-object initialization is done in the initialize method. - * @param setObjectId The system object identifier of this Service instance. - * @param set_apid The APID the Service is instantiated for. - * @param set_service_id The Service Identifier as specified in ECSS PUS. + * @brief The passed values are set, but inter-object initialization is + * done in the initialize method. + * @param setObjectId + * The system object identifier of this Service instance. + * @param setApid + * The APID the Service is instantiated for. + * @param setServiceId + * The Service Identifier as specified in ECSS PUS. */ - PusServiceBase( object_id_t setObjectId, uint16_t setApid, uint8_t setServiceId); + PusServiceBase( object_id_t setObjectId, uint16_t setApid, + uint8_t setServiceId); /** * The destructor is empty. */ virtual ~PusServiceBase(); /** - * @brief The handleRequest method shall handle any kind of Telecommand Request immediately. + * @brief The handleRequest method shall handle any kind of Telecommand + * Request immediately. * @details - * Implemetations can take the Telecommand in currentPacket and perform any kind of operation. - * They may send additional "Start Success (1,3)" messages with the verifyReporter, but Completion - * Success or Failure Reports are generated automatically after execution of this method. + * Implemetations can take the Telecommand in currentPacket and perform + * any kind of operation. + * They may send additional "Start Success (1,3)" messages with the + * verifyReporter, but Completion Success or Failure Reports are generated + * automatically after execution of this method. * * If a Telecommand can not be executed within one call cycle, * this Base class is not the right parent. * - * The child class may add additional error information by setting #errorParameters which are - * attached to the generated verification message. + * The child class may add additional error information by setting + * #errorParameters which aren attached to the generated verification + * message. * * Subservice checking should be implemented in this method. * - * @return The returned status_code is directly taken as main error code in the Verification Report. + * @return The returned status_code is directly taken as main error code + * in the Verification Report. * On success, RETURN_OK shall be returned. */ virtual ReturnValue_t handleRequest(uint8_t subservice) = 0; /** - * In performService, implementations can handle periodic, non-TC-triggered activities. + * In performService, implementations can handle periodic, + * non-TC-triggered activities. * The performService method is always called. - * @return A success or failure code that does not trigger any kind of verification message. + * @return Currently, everything other that RETURN_OK only triggers + * diagnostic output. */ virtual ReturnValue_t performService() = 0; /** * This method implements the typical activity of a simple PUS Service. - * It checks for new requests, and, if found, calls handleRequest, sends completion verification messages and deletes + * It checks for new requests, and, if found, calls handleRequest, sends + * completion verification messages and deletes * the TC requests afterwards. * performService is always executed afterwards. - * @return \c RETURN_OK if the periodic performService was successful. - * \c RETURN_FAILED else. + * @return @c RETURN_OK if the periodic performService was successful. + * @c RETURN_FAILED else. */ ReturnValue_t performOperation(uint8_t opCode); virtual uint16_t getIdentifier(); @@ -103,13 +118,13 @@ protected: */ uint32_t errorParameter2 = 0; /** - * This is a complete instance of the Telecommand reception queue of the class. - * It is initialized on construction of the class. + * This is a complete instance of the telecommand reception queue + * of the class. It is initialized on construction of the class. */ MessageQueueIF* requestQueue = nullptr; /** - * An instance of the VerificationReporter class, that simplifies sending any kind of - * Verification Message to the TC Verification Service. + * An instance of the VerificationReporter class, that simplifies + * sending any kind of verification message to the TC Verification Service. */ VerificationReporter verifyReporter; /** @@ -124,7 +139,8 @@ protected: private: /** * This constant sets the maximum number of packets accepted per call. - * Remember that one packet must be completely handled in one #handleRequest call. + * Remember that one packet must be completely handled in one + * #handleRequest call. */ static const uint8_t PUS_SERVICE_MAX_RECEPTION = 10; From 5007041bc87e39a44284de14f465fa0478cbc2a0 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 10 Jun 2020 22:12:29 +0200 Subject: [PATCH 126/307] cleaned up includes and improved doc a bit --- tmtcservices/CommandingServiceBase.cpp | 27 +++--- tmtcservices/CommandingServiceBase.h | 114 ++++++++++++++----------- 2 files changed, 76 insertions(+), 65 deletions(-) diff --git a/tmtcservices/CommandingServiceBase.cpp b/tmtcservices/CommandingServiceBase.cpp index adc9400f..361baf3b 100644 --- a/tmtcservices/CommandingServiceBase.cpp +++ b/tmtcservices/CommandingServiceBase.cpp @@ -1,22 +1,21 @@ -/* - * CommandingServiceBase.cpp - * - * Created on: 28.08.2019 - * Author: gaisser - */ +#include +#include +#include #include +#include +#include +#include +#include CommandingServiceBase::CommandingServiceBase(object_id_t setObjectId, uint16_t apid, uint8_t service, uint8_t numberOfParallelCommands, - uint16_t commandTimeout_seconds, object_id_t setPacketSource, + uint16_t commandTimeoutSeconds, object_id_t setPacketSource, object_id_t setPacketDestination, size_t queueDepth) : - SystemObject(setObjectId), apid(apid), service(service), timeout_seconds( - commandTimeout_seconds), tmPacketCounter(0), IPCStore(NULL), TCStore( - NULL), commandQueue(NULL), requestQueue(NULL), commandMap( - numberOfParallelCommands), failureParameter1(0), failureParameter2( - 0), packetSource(setPacketSource), packetDestination( - setPacketDestination),executingTask(NULL) { + SystemObject(setObjectId), apid(apid), service(service), + timeoutSeconds(commandTimeoutSeconds), + commandMap(numberOfParallelCommands), packetSource(setPacketSource), + packetDestination(setPacketDestination) { commandQueue = QueueFactory::instance()->createMessageQueue(queueDepth); requestQueue = QueueFactory::instance()->createMessageQueue(queueDepth); } @@ -369,7 +368,7 @@ void CommandingServiceBase::checkTimeout() { typename FixedMap::Iterator iter; for (iter = commandMap.begin(); iter != commandMap.end(); ++iter) { - if ((iter->uptimeOfStart + (timeout_seconds * 1000)) < uptime) { + if ((iter->uptimeOfStart + (timeoutSeconds * 1000)) < uptime) { verificationReporter.sendFailureReport( TC_VERIFY::COMPLETION_FAILURE, iter->tcInfo.ackFlags, iter->tcInfo.tcPacketId, iter->tcInfo.tcSequenceControl, diff --git a/tmtcservices/CommandingServiceBase.h b/tmtcservices/CommandingServiceBase.h index e79e806d..37f6891c 100644 --- a/tmtcservices/CommandingServiceBase.h +++ b/tmtcservices/CommandingServiceBase.h @@ -1,35 +1,33 @@ -#ifndef COMMANDINGSERVICEBASE_H_ -#define COMMANDINGSERVICEBASE_H_ +#ifndef FRAMEWORK_TMTCSERVICES_COMMANDINGSERVICEBASE_H_ +#define FRAMEWORK_TMTCSERVICES_COMMANDINGSERVICEBASE_H_ -#include -#include -#include -#include #include -#include #include #include -#include -#include -#include +#include #include -#include -#include + #include -#include -#include -#include +#include +#include +#include +#include + +class TcPacketStored; /** - * \brief This class is the basis for all PUS Services, which have to relay Telecommands to software bus. + * @brief This class is the basis for all PUS Services, which have to + * relay Telecommands to software bus. * - * It manages Telecommand reception and the generation of Verification Reports like PUSServiceBase. - * Every class that inherits from this abstract class has to implement four adaption points: + * It manages Telecommand reception and the generation of Verification Reports + * similar to PusServiceBase. This class is used if a telecommand can't be + * handled immediately and must be relayed to the internal software bus. * - isValidSubservice * - getMessageQueueAndObject * - prepareCommand * - handleReply - * \ingroup pus_services + * @author gaisser + * @ingroup pus_services */ class CommandingServiceBase: public SystemObject, public AcceptsTelecommandsIF, @@ -59,7 +57,7 @@ public: */ CommandingServiceBase(object_id_t setObjectId, uint16_t apid, uint8_t service, uint8_t numberOfParallelCommands, - uint16_t commandTimeout_seconds, object_id_t setPacketSource, + uint16_t commandTimeoutSeconds, object_id_t setPacketSource, object_id_t setPacketDestination, size_t queueDepth = 20); virtual ~CommandingServiceBase(); @@ -113,8 +111,9 @@ protected: virtual ReturnValue_t isValidSubservice(uint8_t subservice) = 0; /** - * Once a TC Request is valid, the existence of the destination and its target interface is checked and retrieved. - * The target message queue ID can then be acquired by using the target interface. + * Once a TC Request is valid, the existence of the destination and its + * target interface is checked and retrieved. The target message queue ID + * can then be acquired by using the target interface. * @param subservice * @param tcData Application Data of TC Packet * @param tcDataLen @@ -129,10 +128,10 @@ protected: object_id_t *objectId) = 0; /** - * After the Message Queue and Object ID are determined, - * the command is prepared by using an implementation specific CommandMessage type - * which is sent to the target object. - * It contains all necessary information for the device to execute telecommands. + * After the Message Queue and Object ID are determined, the command is + * prepared by using an implementation specific CommandMessage type + * which is sent to the target object. It contains all necessary information + * for the device to execute telecommands. * @param message * @param subservice * @param tcData @@ -146,25 +145,40 @@ protected: uint32_t *state, object_id_t objectId) = 0; /** - * This function is responsible for the communication between the Command Service Base - * and the respective PUS Commanding Service once the execution has started. - * The PUS Commanding Service receives replies from the target device and forwards them by calling this function. - * There are different translations of these replies to specify how the Command Service proceeds. - * @param reply[out] Command Message which contains information about the command - * @param previousCommand [out] - * @param state - * @param optionalNextCommand + * This function is implemented by child services to specify how replies + * to a command from another software component are handled + * @param reply + * This is the reply in form of a command message. + * @param previousCommand + * Command_t of related command + * @param state [out/in] + * Additional parameter which can be used to pass state information. + * State of the communication + * @param optionalNextCommand [out] + * An optional next command which can be set in this function * @param objectId Source object ID * @param isStep Flag value to mark steps of command execution - * @return - @c RETURN_OK, @c EXECUTION_COMPLETE or @c NO_STEP_MESSAGE to generate TC verification success - * - @c INVALID_REPLY can handle unrequested replies - * - Anything else triggers a TC verification failure + * @return + * - @c RETURN_OK, @c EXECUTION_COMPLETE or @c NO_STEP_MESSAGE to + * generate TC verification success + * - @c INVALID_REPLY calls handleUnrequestedReply + * - Anything else triggers a TC verification failure */ virtual ReturnValue_t handleReply(const CommandMessage *reply, Command_t previousCommand, uint32_t *state, CommandMessage *optionalNextCommand, object_id_t objectId, bool *isStep) = 0; + /** + * This function can be overidden to handle unrequested reply, + * when the reply sender ID is unknown or is not found is the command map. + * @param reply + */ + virtual void handleUnrequestedReply(CommandMessage *reply); + + virtual void doPeriodicOperation(); + + struct CommandInfo { struct tcInfo { uint8_t ackFlags; @@ -184,33 +198,35 @@ protected: const uint8_t service; - const uint16_t timeout_seconds; + const uint16_t timeoutSeconds; - uint8_t tmPacketCounter; + uint8_t tmPacketCounter = 0; - StorageManagerIF *IPCStore; + StorageManagerIF *IPCStore = nullptr; - StorageManagerIF *TCStore; + StorageManagerIF *TCStore = nullptr; - MessageQueueIF* commandQueue; + MessageQueueIF* commandQueue = nullptr; - MessageQueueIF* requestQueue; + MessageQueueIF* requestQueue = nullptr; VerificationReporter verificationReporter; FixedMap commandMap; - uint32_t failureParameter1; //!< May be set be children to return a more precise failure condition. - uint32_t failureParameter2; //!< May be set be children to return a more precise failure condition. + /* May be set be children to return a more precise failure condition. */ + uint32_t failureParameter1 = 0; + uint32_t failureParameter2 = 0; object_id_t packetSource; object_id_t packetDestination; /** - * Pointer to the task which executes this component, is invalid before setTaskIF was called. + * Pointer to the task which executes this component, + * is invalid before setTaskIF was called. */ - PeriodicTaskIF* executingTask; + PeriodicTaskIF* executingTask = nullptr; /** * @brief Send TM data from pointer to data. @@ -246,10 +262,6 @@ protected: ReturnValue_t sendTmPacket(uint8_t subservice, SerializeIF* content, SerializeIF* header = nullptr); - virtual void handleUnrequestedReply(CommandMessage *reply); - - virtual void doPeriodicOperation(); - void checkAndExecuteFifo( typename FixedMap::Iterator *iter); From bb9a299e33ce7429314acb58606f964613a31589 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 10 Jun 2020 22:19:40 +0200 Subject: [PATCH 127/307] added back removed comments --- tmtcservices/CommandingServiceBase.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tmtcservices/CommandingServiceBase.h b/tmtcservices/CommandingServiceBase.h index 37f6891c..f97eabb0 100644 --- a/tmtcservices/CommandingServiceBase.h +++ b/tmtcservices/CommandingServiceBase.h @@ -132,11 +132,12 @@ protected: * prepared by using an implementation specific CommandMessage type * which is sent to the target object. It contains all necessary information * for the device to execute telecommands. - * @param message - * @param subservice - * @param tcData - * @param tcDataLen - * @param state + * @param message [out] message which can be set and is sent to the object + * @param subservice Subservice of the current communication + * @param tcData Application data of command + * @param tcDataLen Application data length + * @param state [out/in] Setable state of the communication. + * communication * @param objectId Target object ID * @return */ From 3268806f75a3ea8ceaf7ce933276133d26b05719 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 10 Jun 2020 22:51:54 +0200 Subject: [PATCH 128/307] split up huge function to be more readable --- tmtcservices/CommandingServiceBase.cpp | 193 ++++++++++++++----------- tmtcservices/CommandingServiceBase.h | 7 + 2 files changed, 113 insertions(+), 87 deletions(-) diff --git a/tmtcservices/CommandingServiceBase.cpp b/tmtcservices/CommandingServiceBase.cpp index 361baf3b..4c557f82 100644 --- a/tmtcservices/CommandingServiceBase.cpp +++ b/tmtcservices/CommandingServiceBase.cpp @@ -56,7 +56,7 @@ ReturnValue_t CommandingServiceBase::initialize() { objectManager->get(packetDestination); PUSDistributorIF* distributor = objectManager->get( packetSource); - if ((packetForwarding == NULL) && (distributor == NULL)) { + if (packetForwarding == nullptr or distributor == nullptr) { return RETURN_FAILED; } @@ -67,7 +67,7 @@ ReturnValue_t CommandingServiceBase::initialize() { IPCStore = objectManager->get(objects::IPC_STORE); TCStore = objectManager->get(objects::TC_STORE); - if ((IPCStore == NULL) || (TCStore == NULL)) { + if (IPCStore == nullptr or TCStore == nullptr) { return RETURN_FAILED; } @@ -76,97 +76,116 @@ ReturnValue_t CommandingServiceBase::initialize() { } void CommandingServiceBase::handleCommandQueue() { - CommandMessage reply, nextCommand; - ReturnValue_t result, sendResult = RETURN_OK; - bool isStep = false; + CommandMessage reply; + ReturnValue_t result = RETURN_FAILED; for (result = commandQueue->receiveMessage(&reply); result == RETURN_OK; result = commandQueue->receiveMessage(&reply)) { - isStep = false; - typename FixedMap::Iterator iter; - if (reply.getSender() == MessageQueueIF::NO_QUEUE) { - handleUnrequestedReply(&reply); - continue; - } - if ((iter = commandMap.find(reply.getSender())) == commandMap.end()) { - handleUnrequestedReply(&reply); - continue; - } - nextCommand.setCommand(CommandMessage::CMD_NONE); - result = handleReply(&reply, iter->command, &iter->state, &nextCommand, - iter->objectId, &isStep); - switch (result) { - case EXECUTION_COMPLETE: - case RETURN_OK: - case NO_STEP_MESSAGE: - iter->command = nextCommand.getCommand(); - if (nextCommand.getCommand() != CommandMessage::CMD_NONE) { - sendResult = commandQueue->sendMessage(reply.getSender(), - &nextCommand); - } - if (sendResult == RETURN_OK) { - if (isStep) { - if (result != NO_STEP_MESSAGE) { - verificationReporter.sendSuccessReport( - TC_VERIFY::PROGRESS_SUCCESS, - iter->tcInfo.ackFlags, iter->tcInfo.tcPacketId, - iter->tcInfo.tcSequenceControl, ++iter->step); - } - } else { - verificationReporter.sendSuccessReport( - TC_VERIFY::COMPLETION_SUCCESS, - iter->tcInfo.ackFlags, iter->tcInfo.tcPacketId, - iter->tcInfo.tcSequenceControl, 0); - checkAndExecuteFifo(&iter); - } - } else { - if (isStep) { - nextCommand.clearCommandMessage(); - verificationReporter.sendFailureReport( - TC_VERIFY::PROGRESS_FAILURE, iter->tcInfo.ackFlags, - iter->tcInfo.tcPacketId, - iter->tcInfo.tcSequenceControl, sendResult, - ++iter->step, failureParameter1, failureParameter2); - } else { - nextCommand.clearCommandMessage(); - verificationReporter.sendFailureReport( - TC_VERIFY::COMPLETION_FAILURE, - iter->tcInfo.ackFlags, iter->tcInfo.tcPacketId, - iter->tcInfo.tcSequenceControl, sendResult, 0, - failureParameter1, failureParameter2); - } - failureParameter1 = 0; - failureParameter2 = 0; - checkAndExecuteFifo(&iter); - } - break; - case INVALID_REPLY: - //might be just an unrequested reply at a bad moment - handleUnrequestedReply(&reply); - break; - default: - if (isStep) { - verificationReporter.sendFailureReport( - TC_VERIFY::PROGRESS_FAILURE, iter->tcInfo.ackFlags, - iter->tcInfo.tcPacketId, iter->tcInfo.tcSequenceControl, - result, ++iter->step, failureParameter1, - failureParameter2); - } else { - verificationReporter.sendFailureReport( - TC_VERIFY::COMPLETION_FAILURE, iter->tcInfo.ackFlags, - iter->tcInfo.tcPacketId, iter->tcInfo.tcSequenceControl, - result, 0, failureParameter1, failureParameter2); - } - failureParameter1 = 0; - failureParameter2 = 0; - checkAndExecuteFifo(&iter); - break; - } - + handleCommandMessage(reply); } } +void CommandingServiceBase::handleCommandMessage(CommandMessage& reply) { + bool isStep = false; + CommandMessage nextCommand; + CommandMapIter iter; + if (reply.getSender() == MessageQueueIF::NO_QUEUE) { + handleUnrequestedReply(&reply); + return; + } + if ((iter = commandMap.find(reply.getSender())) == commandMap.end()) { + handleUnrequestedReply(&reply); + return; + } + nextCommand.setCommand(CommandMessage::CMD_NONE); + + // Implemented by child class, specifies what to do with reply. + ReturnValue_t result = handleReply(&reply, iter->command, &iter->state, + &nextCommand, iter->objectId, &isStep); + + switch (result) { + case EXECUTION_COMPLETE: + case RETURN_OK: + case NO_STEP_MESSAGE: + // handle result of reply handler implemented by developer. + handleReplyHandlerResult(result, iter, nextCommand, reply, isStep); + break; + case INVALID_REPLY: + //might be just an unrequested reply at a bad moment + handleUnrequestedReply(&reply); + break; + default: + if (isStep) { + verificationReporter.sendFailureReport( + TC_VERIFY::PROGRESS_FAILURE, iter->tcInfo.ackFlags, + iter->tcInfo.tcPacketId, iter->tcInfo.tcSequenceControl, + result, ++iter->step, failureParameter1, + failureParameter2); + } else { + verificationReporter.sendFailureReport( + TC_VERIFY::COMPLETION_FAILURE, iter->tcInfo.ackFlags, + iter->tcInfo.tcPacketId, iter->tcInfo.tcSequenceControl, + result, 0, failureParameter1, failureParameter2); + } + failureParameter1 = 0; + failureParameter2 = 0; + checkAndExecuteFifo(&iter); + break; + } + +} + +void CommandingServiceBase::handleReplyHandlerResult(ReturnValue_t result, + CommandMapIter iter, CommandMessage& nextCommand, CommandMessage& reply, + bool& isStep) { + iter->command = nextCommand.getCommand(); + + // In case a new command is to be sent immediately, this is performed here. + // If no new command is sent, only analyse reply result by initializing + // sendResult as RETURN_OK + ReturnValue_t sendResult = RETURN_OK; + if (nextCommand.getCommand() != CommandMessage::CMD_NONE) { + sendResult = commandQueue->sendMessage(reply.getSender(), + &nextCommand); + } + + if (sendResult == RETURN_OK) { + if (isStep and result != NO_STEP_MESSAGE) { + verificationReporter.sendSuccessReport( + TC_VERIFY::PROGRESS_SUCCESS, + iter->tcInfo.ackFlags, iter->tcInfo.tcPacketId, + iter->tcInfo.tcSequenceControl, ++iter->step); + } + else { + verificationReporter.sendSuccessReport( + TC_VERIFY::COMPLETION_SUCCESS, + iter->tcInfo.ackFlags, iter->tcInfo.tcPacketId, + iter->tcInfo.tcSequenceControl, 0); + checkAndExecuteFifo(&iter); + } + } + else { + if (isStep) { + nextCommand.clearCommandMessage(); + verificationReporter.sendFailureReport( + TC_VERIFY::PROGRESS_FAILURE, iter->tcInfo.ackFlags, + iter->tcInfo.tcPacketId, + iter->tcInfo.tcSequenceControl, sendResult, + ++iter->step, failureParameter1, failureParameter2); + } else { + nextCommand.clearCommandMessage(); + verificationReporter.sendFailureReport( + TC_VERIFY::COMPLETION_FAILURE, + iter->tcInfo.ackFlags, iter->tcInfo.tcPacketId, + iter->tcInfo.tcSequenceControl, sendResult, 0, + failureParameter1, failureParameter2); + } + failureParameter1 = 0; + failureParameter2 = 0; + checkAndExecuteFifo(&iter); + } +} + void CommandingServiceBase::handleRequestQueue() { TmTcMessage message; ReturnValue_t result; diff --git a/tmtcservices/CommandingServiceBase.h b/tmtcservices/CommandingServiceBase.h index f97eabb0..9a68a2d3 100644 --- a/tmtcservices/CommandingServiceBase.h +++ b/tmtcservices/CommandingServiceBase.h @@ -267,6 +267,9 @@ protected: typename FixedMap::Iterator *iter); private: + using CommandMapIter = FixedMap::Iterator; + /** * This method handles internal execution of a command, * once it has been started by @sa{startExecution()} in the Request Queue handler. @@ -298,6 +301,10 @@ private: void startExecution(TcPacketStored *storedPacket, typename FixedMap::Iterator *iter); + void handleCommandMessage(CommandMessage& reply); + void handleReplyHandlerResult(ReturnValue_t result, CommandMapIter iter, + CommandMessage& nextCommand,CommandMessage& reply, bool& isStep); + void checkTimeout(); }; From a9c7ad84c8b93c39021194e99306e023432b4ee0 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 11 Jun 2020 02:03:18 +0200 Subject: [PATCH 129/307] added new interface to host and linux osal --- ipc/CommandMessage.cpp | 8 ++++++++ ipc/CommandMessage.h | 2 ++ ipc/MessageQueueMessage.cpp | 8 ++++++++ ipc/MessageQueueMessage.h | 4 ++++ ipc/MessageQueueMessageIF.h | 12 ++++++++++++ osal/host/MessageQueue.cpp | 30 ++++++++++++++++++++---------- osal/host/MessageQueue.h | 16 ++++++++-------- osal/host/QueueFactory.cpp | 2 +- osal/linux/MessageQueue.cpp | 25 +++++++++++++------------ osal/linux/MessageQueue.h | 21 +++++++++++++-------- osal/linux/QueueFactory.cpp | 2 +- 11 files changed, 90 insertions(+), 40 deletions(-) diff --git a/ipc/CommandMessage.cpp b/ipc/CommandMessage.cpp index 44424e02..7d2ecc9b 100644 --- a/ipc/CommandMessage.cpp +++ b/ipc/CommandMessage.cpp @@ -160,3 +160,11 @@ uint8_t* CommandMessage::getData() { const uint8_t* CommandMessage::getData() const { return internalMessage->getData(); } + +size_t CommandMessage::getMessageSize() const { + return COMMAND_MESSAGE_SIZE; +} + +size_t CommandMessage::getMaximumMessageSize() const { + return MessageQueueMessage::MAX_MESSAGE_SIZE; +} diff --git a/ipc/CommandMessage.h b/ipc/CommandMessage.h index 772bd774..25d608f0 100644 --- a/ipc/CommandMessage.h +++ b/ipc/CommandMessage.h @@ -85,6 +85,8 @@ public: uint8_t * getData() override; const uint8_t* getData() const override; size_t getMinimumMessageSize() const override; + size_t getMessageSize() const override; + size_t getMaximumMessageSize() const override; /** * Extract message ID, which is the first byte of the command ID. diff --git a/ipc/MessageQueueMessage.cpp b/ipc/MessageQueueMessage.cpp index c3e1cb7a..8430a8ea 100644 --- a/ipc/MessageQueueMessage.cpp +++ b/ipc/MessageQueueMessage.cpp @@ -67,3 +67,11 @@ void MessageQueueMessage::print() { void MessageQueueMessage::clear() { memset(this->getBuffer(), 0, this->MAX_MESSAGE_SIZE); } + +size_t MessageQueueMessage::getMessageSize() const { + return this->messageSize; +} + +size_t MessageQueueMessage::getMaximumMessageSize() const { + return this->MAX_MESSAGE_SIZE; +} diff --git a/ipc/MessageQueueMessage.h b/ipc/MessageQueueMessage.h index bee39ae6..31a43f66 100644 --- a/ipc/MessageQueueMessage.h +++ b/ipc/MessageQueueMessage.h @@ -149,6 +149,10 @@ public: */ virtual size_t getMinimumMessageSize() const override; + virtual size_t getMessageSize() const override; + + virtual size_t getMaximumMessageSize() const override; + /** * @brief This is a debug method that prints the content * (till messageSize) to the debug output. diff --git a/ipc/MessageQueueMessageIF.h b/ipc/MessageQueueMessageIF.h index 197a26fd..05330ce9 100644 --- a/ipc/MessageQueueMessageIF.h +++ b/ipc/MessageQueueMessageIF.h @@ -71,6 +71,18 @@ public: * check the size of an incoming message. */ virtual size_t getMinimumMessageSize() const = 0; + + /** + * Get message size of current message implementation. + * @return + */ + virtual size_t getMessageSize() const = 0; + + /** + * Get maximum allowed size of current message implementation. + * @return + */ + virtual size_t getMaximumMessageSize() const = 0; }; diff --git a/osal/host/MessageQueue.cpp b/osal/host/MessageQueue.cpp index 3e30c8ed..7af5fbd9 100644 --- a/osal/host/MessageQueue.cpp +++ b/osal/host/MessageQueue.cpp @@ -18,20 +18,20 @@ MessageQueue::~MessageQueue() { } ReturnValue_t MessageQueue::sendMessage(MessageQueueId_t sendTo, - MessageQueueMessage* message, bool ignoreFault) { + MessageQueueMessageIF* message, bool ignoreFault) { return sendMessageFrom(sendTo, message, this->getId(), ignoreFault); } -ReturnValue_t MessageQueue::sendToDefault(MessageQueueMessage* message) { +ReturnValue_t MessageQueue::sendToDefault(MessageQueueMessageIF* message) { return sendToDefaultFrom(message, this->getId()); } -ReturnValue_t MessageQueue::sendToDefaultFrom(MessageQueueMessage* message, +ReturnValue_t MessageQueue::sendToDefaultFrom(MessageQueueMessageIF* message, MessageQueueId_t sentFrom, bool ignoreFault) { return sendMessageFrom(defaultDestination,message,sentFrom,ignoreFault); } -ReturnValue_t MessageQueue::reply(MessageQueueMessage* message) { +ReturnValue_t MessageQueue::reply(MessageQueueMessageIF* message) { if (this->lastPartner != 0) { return sendMessageFrom(this->lastPartner, message, this->getId()); } else { @@ -40,13 +40,13 @@ ReturnValue_t MessageQueue::reply(MessageQueueMessage* message) { } ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo, - MessageQueueMessage* message, MessageQueueId_t sentFrom, + MessageQueueMessageIF* message, MessageQueueId_t sentFrom, bool ignoreFault) { return sendMessageFromMessageQueue(sendTo, message, sentFrom, ignoreFault); } -ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message, +ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message, MessageQueueId_t* receivedFrom) { ReturnValue_t status = this->receiveMessage(message); if(status == HasReturnvaluesIF::RETURN_OK) { @@ -55,7 +55,7 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message, return status; } -ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message) { +ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) { if(messageQueue.empty()) { return MessageQueueIF::EMPTY; } @@ -102,9 +102,9 @@ bool MessageQueue::isDefaultDestinationSet() const { // static core function to send messages. ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, - MessageQueueMessage *message, MessageQueueId_t sentFrom, + MessageQueueMessageIF* message, MessageQueueId_t sentFrom, bool ignoreFault) { - if(message->messageSize > MessageQueueMessage::MAX_DATA_SIZE) { + if(message->getMessageSize() > message->getMaximumMessageSize()) { // Actually, this should never happen or an error will be emitted // in MessageQueueMessage. // But I will still return a failure here. @@ -127,7 +127,17 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, if(targetQueue->messageQueue.size() < targetQueue->messageDepth) { MutexHelper mutexLock(targetQueue->queueLock, 20); - targetQueue->messageQueue.push(*message); + // not ideal, works for now though. + MessageQueueMessage* mqmMessage = + dynamic_cast(message); + if(message != nullptr) { + targetQueue->messageQueue.push(*mqmMessage); + } + else { + sif::error << "MessageQueue::sendMessageFromMessageQueue: Message" + "is not MessageQueueMessage!" << std::endl; + } + } else { return MessageQueueIF::FULL; diff --git a/osal/host/MessageQueue.h b/osal/host/MessageQueue.h index 619b5e91..7fc77f7a 100644 --- a/osal/host/MessageQueue.h +++ b/osal/host/MessageQueue.h @@ -77,7 +77,7 @@ public: * is not incremented if queue is full. */ ReturnValue_t sendMessage(MessageQueueId_t sendTo, - MessageQueueMessage* message, bool ignoreFault = false) override; + MessageQueueMessageIF* message, bool ignoreFault = false) override; /** * @brief This operation sends a message to the default destination. * @details As in the sendMessage method, this function uses the @@ -85,7 +85,7 @@ public: * queue id as "sentFrom" information. * @param message A pointer to a previously created message, which is sent. */ - ReturnValue_t sendToDefault(MessageQueueMessage* message) override; + ReturnValue_t sendToDefault(MessageQueueMessageIF* message) override; /** * @brief This operation sends a message to the last communication partner. * @details This operation simplifies answering an incoming message by using @@ -93,7 +93,7 @@ public: * message received yet (i.e. lastPartner is zero), an error code is returned. * @param message A pointer to a previously created message, which is sent. */ - ReturnValue_t reply(MessageQueueMessage* message) override; + ReturnValue_t reply(MessageQueueMessageIF* message) override; /** * @brief With the sendMessage call, a queue message is sent to a @@ -113,7 +113,7 @@ public: * is not incremented if queue is full. */ virtual ReturnValue_t sendMessageFrom( MessageQueueId_t sendTo, - MessageQueueMessage* message, MessageQueueId_t sentFrom = NO_QUEUE, + MessageQueueMessageIF* message, MessageQueueId_t sentFrom = NO_QUEUE, bool ignoreFault = false) override; /** @@ -127,7 +127,7 @@ public: * sender's queue id into the message. This variable is set to zero by * default. */ - virtual ReturnValue_t sendToDefaultFrom( MessageQueueMessage* message, + virtual ReturnValue_t sendToDefaultFrom( MessageQueueMessageIF* message, MessageQueueId_t sentFrom = NO_QUEUE, bool ignoreFault = false) override; @@ -140,7 +140,7 @@ public: * @param message A pointer to a message in which the received data is stored. * @param receivedFrom A pointer to a queue id in which the sender's id is stored. */ - ReturnValue_t receiveMessage(MessageQueueMessage* message, + ReturnValue_t receiveMessage(MessageQueueMessageIF* message, MessageQueueId_t *receivedFrom) override; /** @@ -153,7 +153,7 @@ public: * function returns immediately. * @param message A pointer to a message in which the received data is stored. */ - ReturnValue_t receiveMessage(MessageQueueMessage* message) override; + ReturnValue_t receiveMessage(MessageQueueMessageIF* message) override; /** * Deletes all pending messages in the queue. * @param count The number of flushed messages. @@ -205,7 +205,7 @@ protected: * @param context Specify whether call is made from task or from an ISR. */ static ReturnValue_t sendMessageFromMessageQueue(MessageQueueId_t sendTo, - MessageQueueMessage* message, MessageQueueId_t sentFrom = NO_QUEUE, + MessageQueueMessageIF* message, MessageQueueId_t sentFrom = NO_QUEUE, bool ignoreFault=false); //static ReturnValue_t handleSendResult(BaseType_t result, bool ignoreFault); diff --git a/osal/host/QueueFactory.cpp b/osal/host/QueueFactory.cpp index 60274c84..225bb8c7 100644 --- a/osal/host/QueueFactory.cpp +++ b/osal/host/QueueFactory.cpp @@ -7,7 +7,7 @@ QueueFactory* QueueFactory::factoryInstance = nullptr; ReturnValue_t MessageQueueSenderIF::sendMessage(MessageQueueId_t sendTo, - MessageQueueMessage* message, MessageQueueId_t sentFrom, + MessageQueueMessageIF* message, MessageQueueId_t sentFrom, bool ignoreFault) { return MessageQueue::sendMessageFromMessageQueue(sendTo,message, sentFrom,ignoreFault); diff --git a/osal/linux/MessageQueue.cpp b/osal/linux/MessageQueue.cpp index a0749ded..605dea2a 100644 --- a/osal/linux/MessageQueue.cpp +++ b/osal/linux/MessageQueue.cpp @@ -118,15 +118,15 @@ ReturnValue_t MessageQueue::handleError(mq_attr* attributes, } ReturnValue_t MessageQueue::sendMessage(MessageQueueId_t sendTo, - MessageQueueMessage* message, bool ignoreFault) { + MessageQueueMessageIF* message, bool ignoreFault) { return sendMessageFrom(sendTo, message, this->getId(), false); } -ReturnValue_t MessageQueue::sendToDefault(MessageQueueMessage* message) { +ReturnValue_t MessageQueue::sendToDefault(MessageQueueMessageIF* message) { return sendToDefaultFrom(message, this->getId()); } -ReturnValue_t MessageQueue::reply(MessageQueueMessage* message) { +ReturnValue_t MessageQueue::reply(MessageQueueMessageIF* message) { if (this->lastPartner != 0) { return sendMessageFrom(this->lastPartner, message, this->getId()); } else { @@ -134,21 +134,21 @@ ReturnValue_t MessageQueue::reply(MessageQueueMessage* message) { } } -ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message, +ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message, MessageQueueId_t* receivedFrom) { ReturnValue_t status = this->receiveMessage(message); *receivedFrom = this->lastPartner; return status; } -ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message) { +ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) { unsigned int messagePriority = 0; int status = mq_receive(id,reinterpret_cast(message->getBuffer()), - message->MAX_MESSAGE_SIZE,&messagePriority); + message->getMaximumMessageSize(),&messagePriority); if (status > 0) { this->lastPartner = message->getSender(); //Check size of incoming message. - if (message->messageSize < message->getMinimumMessageSize()) { + if (message->getMessageSize() < message->getMinimumMessageSize()) { return HasReturnvaluesIF::RETURN_FAILED; } return HasReturnvaluesIF::RETURN_OK; @@ -158,7 +158,7 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessage* message) { } else { //No message was received. Keep lastPartner anyway, I might send //something later. But still, delete packet content. - memset(message->getData(), 0, message->MAX_DATA_SIZE); + memset(message->getData(), 0, message->getMaximumMessageSize()); switch(errno){ case EAGAIN: //O_NONBLOCK or MQ_NONBLOCK was set and there are no messages @@ -259,13 +259,13 @@ void MessageQueue::setDefaultDestination(MessageQueueId_t defaultDestination) { } ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo, - MessageQueueMessage* message, MessageQueueId_t sentFrom, + MessageQueueMessageIF* message, MessageQueueId_t sentFrom, bool ignoreFault) { return sendMessageFromMessageQueue(sendTo,message,sentFrom,ignoreFault); } -ReturnValue_t MessageQueue::sendToDefaultFrom(MessageQueueMessage* message, +ReturnValue_t MessageQueue::sendToDefaultFrom(MessageQueueMessageIF* message, MessageQueueId_t sentFrom, bool ignoreFault) { return sendMessageFrom(defaultDestination, message, sentFrom, ignoreFault); } @@ -281,11 +281,12 @@ bool MessageQueue::isDefaultDestinationSet() const { uint16_t MessageQueue::queueCounter = 0; ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, - MessageQueueMessage *message, MessageQueueId_t sentFrom, + MessageQueueMessageIF *message, MessageQueueId_t sentFrom, bool ignoreFault) { message->setSender(sentFrom); int result = mq_send(sendTo, - reinterpret_cast(message->getBuffer()), message->messageSize,0); + reinterpret_cast(message->getBuffer()), + message->getMessageSize(),0); //TODO: Check if we're in ISR. if (result != 0) { diff --git a/osal/linux/MessageQueue.h b/osal/linux/MessageQueue.h index 2808d36e..91066bf7 100644 --- a/osal/linux/MessageQueue.h +++ b/osal/linux/MessageQueue.h @@ -56,14 +56,14 @@ public: * @param ignoreFault If set to true, the internal software fault counter is not incremented if queue is full. */ virtual ReturnValue_t sendMessage(MessageQueueId_t sendTo, - MessageQueueMessage* message, bool ignoreFault = false ); + MessageQueueMessageIF* message, bool ignoreFault = false ); /** * @brief This operation sends a message to the default destination. * @details As in the sendMessage method, this function uses the sendToDefault call of the * MessageQueueSender parent class and adds its queue id as "sentFrom" information. * @param message A pointer to a previously created message, which is sent. */ - virtual ReturnValue_t sendToDefault( MessageQueueMessage* message ); + virtual ReturnValue_t sendToDefault( MessageQueueMessageIF* message ); /** * @brief This operation sends a message to the last communication partner. * @details This operation simplifies answering an incoming message by using the stored @@ -71,7 +71,7 @@ public: * (i.e. lastPartner is zero), an error code is returned. * @param message A pointer to a previously created message, which is sent. */ - ReturnValue_t reply( MessageQueueMessage* message ); + ReturnValue_t reply( MessageQueueMessageIF* message ); /** * @brief This function reads available messages from the message queue and returns the sender. @@ -80,7 +80,7 @@ public: * @param message A pointer to a message in which the received data is stored. * @param receivedFrom A pointer to a queue id in which the sender's id is stored. */ - ReturnValue_t receiveMessage(MessageQueueMessage* message, + ReturnValue_t receiveMessage(MessageQueueMessageIF* message, MessageQueueId_t *receivedFrom); /** @@ -91,7 +91,7 @@ public: * message's content is cleared and the function returns immediately. * @param message A pointer to a message in which the received data is stored. */ - ReturnValue_t receiveMessage(MessageQueueMessage* message); + ReturnValue_t receiveMessage(MessageQueueMessageIF* message); /** * Deletes all pending messages in the queue. * @param count The number of flushed messages. @@ -114,7 +114,9 @@ public: * This variable is set to zero by default. * \param ignoreFault If set to true, the internal software fault counter is not incremented if queue is full. */ - virtual ReturnValue_t sendMessageFrom( MessageQueueId_t sendTo, MessageQueueMessage* message, MessageQueueId_t sentFrom, bool ignoreFault = false ); + virtual ReturnValue_t sendMessageFrom( MessageQueueId_t sendTo, + MessageQueueMessageIF* message, MessageQueueId_t sentFrom, + bool ignoreFault = false ); /** * \brief The sendToDefault method sends a queue message to the default destination. * \details In all other aspects, it works identical to the sendMessage method. @@ -122,7 +124,8 @@ public: * \param sentFrom The sentFrom information can be set to inject the sender's queue id into the message. * This variable is set to zero by default. */ - virtual ReturnValue_t sendToDefaultFrom( MessageQueueMessage* message, MessageQueueId_t sentFrom = NO_QUEUE, bool ignoreFault = false ); + virtual ReturnValue_t sendToDefaultFrom( MessageQueueMessageIF* message, + MessageQueueId_t sentFrom = NO_QUEUE, bool ignoreFault = false ); /** * \brief This method is a simple setter for the default destination. */ @@ -145,7 +148,9 @@ protected: * This variable is set to zero by default. * \param ignoreFault If set to true, the internal software fault counter is not incremented if queue is full. */ - static ReturnValue_t sendMessageFromMessageQueue(MessageQueueId_t sendTo,MessageQueueMessage* message, MessageQueueId_t sentFrom = NO_QUEUE,bool ignoreFault=false); + static ReturnValue_t sendMessageFromMessageQueue(MessageQueueId_t sendTo, + MessageQueueMessageIF* message, MessageQueueId_t sentFrom = NO_QUEUE, + bool ignoreFault=false); private: /** * @brief The class stores the queue id it got assigned from the operating system in this attribute. diff --git a/osal/linux/QueueFactory.cpp b/osal/linux/QueueFactory.cpp index 268d0b99..8bd9d52c 100644 --- a/osal/linux/QueueFactory.cpp +++ b/osal/linux/QueueFactory.cpp @@ -9,7 +9,7 @@ QueueFactory* QueueFactory::factoryInstance = nullptr; ReturnValue_t MessageQueueSenderIF::sendMessage(MessageQueueId_t sendTo, - MessageQueueMessage* message, MessageQueueId_t sentFrom, + MessageQueueMessageIF* message, MessageQueueId_t sentFrom, bool ignoreFault) { return MessageQueue::sendMessageFromMessageQueue(sendTo,message, sentFrom,ignoreFault); From 206235ed47e0b086acc06015aeb36484bfeeab76 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 11 Jun 2020 16:03:09 +0200 Subject: [PATCH 130/307] dataset base bugfixes --- datapool/DataSetBase.cpp | 10 +++++++--- health/HealthHelper.cpp | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/datapool/DataSetBase.cpp b/datapool/DataSetBase.cpp index 9104c8e7..60b20f29 100644 --- a/datapool/DataSetBase.cpp +++ b/datapool/DataSetBase.cpp @@ -36,7 +36,7 @@ ReturnValue_t DataSetBase::read(uint32_t lockTimeout) { if (state == States::DATA_SET_UNINITIALISED) { lockDataPool(lockTimeout); for (uint16_t count = 0; count < fillCount; count++) { - ReturnValue_t result = readVariable(count); + result = readVariable(count); if(result != RETURN_OK) { break; } @@ -46,14 +46,15 @@ ReturnValue_t DataSetBase::read(uint32_t lockTimeout) { } else { sif::error << "DataSet::read(): " - "Call made in wrong position." << std::endl; + "Call made in wrong position. Don't forget to commit" + " member datasets!" << std::endl; result = SET_WAS_ALREADY_READ; } return result; } ReturnValue_t DataSetBase::readVariable(uint16_t count) { - ReturnValue_t result = DataSetIF::INVALID_PARAMETER_DEFINITION; + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; // These checks are often performed by the respective // variable implementation too, but I guess a double check does not hurt. if (registeredVariables[count]->getReadWriteMode() != @@ -62,6 +63,9 @@ ReturnValue_t DataSetBase::readVariable(uint16_t count) { != PoolVariableIF::NO_PARAMETER) { result = registeredVariables[count]->readWithoutLock(); + if(result != HasReturnvaluesIF::RETURN_OK) { + result = INVALID_PARAMETER_DEFINITION; + } } return result; } diff --git a/health/HealthHelper.cpp b/health/HealthHelper.cpp index b23a8bd2..df259b52 100644 --- a/health/HealthHelper.cpp +++ b/health/HealthHelper.cpp @@ -62,7 +62,7 @@ void HealthHelper::setHealth(HasHealthIF::HealthState health) { void HealthHelper::informParent(HasHealthIF::HealthState health, HasHealthIF::HealthState oldHealth) { - if (parentQueue == 0) { + if (parentQueue == MessageQueueMessageIF::NO_QUEUE) { return; } MessageQueueMessage message; From 6838a9e7687a7232f903b5b39c11fe026bf476ff Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 11 Jun 2020 16:19:22 +0200 Subject: [PATCH 131/307] serial buffer adapter bugfix --- serialize/SerialBufferAdapter.cpp | 16 ++++++++-------- serialize/SerialBufferAdapter.h | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/serialize/SerialBufferAdapter.cpp b/serialize/SerialBufferAdapter.cpp index e409686f..d417ba45 100644 --- a/serialize/SerialBufferAdapter.cpp +++ b/serialize/SerialBufferAdapter.cpp @@ -21,29 +21,29 @@ SerialBufferAdapter::~SerialBufferAdapter() { } template -ReturnValue_t SerialBufferAdapter::serialize(uint8_t** buffer, - size_t* size, const size_t max_size, bool bigEndian) const { +ReturnValue_t SerialBufferAdapter::serialize(uint8_t** buffer_, + size_t* size_, const size_t max_size, bool bigEndian) const { uint32_t serializedLength = bufferLength; if (serializeLength) { serializedLength += AutoSerializeAdapter::getSerializedSize( &bufferLength); } - if (*size + serializedLength > max_size) { + if (*size_ + serializedLength > max_size) { return BUFFER_TOO_SHORT; } else { if (serializeLength) { - AutoSerializeAdapter::serialize(&bufferLength, buffer, size, + AutoSerializeAdapter::serialize(&bufferLength, buffer_, size_, max_size, bigEndian); } if (constBuffer != nullptr) { - memcpy(*buffer, constBuffer, bufferLength); + memcpy(*buffer_, this->constBuffer, bufferLength); } else if (buffer != nullptr) { - memcpy(*buffer, buffer, bufferLength); + memcpy(*buffer_, this->buffer, bufferLength); } else { return HasReturnvaluesIF::RETURN_FAILED; } - *size += bufferLength; - (*buffer) += bufferLength; + *size_ += bufferLength; + (*buffer_) += bufferLength; return HasReturnvaluesIF::RETURN_OK; } } diff --git a/serialize/SerialBufferAdapter.h b/serialize/SerialBufferAdapter.h index cb799be5..02690021 100644 --- a/serialize/SerialBufferAdapter.h +++ b/serialize/SerialBufferAdapter.h @@ -45,7 +45,7 @@ public: virtual ~SerialBufferAdapter(); - virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, + virtual ReturnValue_t serialize(uint8_t** buffer_, size_t* size, const size_t max_size, bool bigEndian) const override; virtual size_t getSerializedSize() const; From f578c3ea29731f29153741b1ee99ae95c02782c6 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 11 Jun 2020 16:46:18 +0200 Subject: [PATCH 132/307] set buffer: const buffer is set too --- serialize/SerialBufferAdapter.cpp | 15 ++++++++++----- serialize/SerialBufferAdapter.h | 2 +- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/serialize/SerialBufferAdapter.cpp b/serialize/SerialBufferAdapter.cpp index d417ba45..5e834fe2 100644 --- a/serialize/SerialBufferAdapter.cpp +++ b/serialize/SerialBufferAdapter.cpp @@ -37,9 +37,13 @@ ReturnValue_t SerialBufferAdapter::serialize(uint8_t** buffer_, } if (constBuffer != nullptr) { memcpy(*buffer_, this->constBuffer, bufferLength); - } else if (buffer != nullptr) { + } + else if (buffer != nullptr) { + // This will propably be never reached, constBuffer should always be + // set if non-const buffer is set. memcpy(*buffer_, this->buffer, bufferLength); - } else { + } + else { return HasReturnvaluesIF::RETURN_FAILED; } *size_ += bufferLength; @@ -93,7 +97,7 @@ template uint8_t * SerialBufferAdapter::getBuffer() { if(buffer == nullptr) { sif::error << "Wrong access function for stored type !" - " Use getConstBuffer()" << std::endl; + " Use getConstBuffer()." << std::endl; return nullptr; } return buffer; @@ -110,9 +114,10 @@ const uint8_t * SerialBufferAdapter::getConstBuffer() { template void SerialBufferAdapter::setBuffer(uint8_t* buffer, - count_t buffer_length) { + count_t bufferLength) { this->buffer = buffer; - bufferLength = buffer_length; + this->constBuffer = buffer; + this->bufferLength = bufferLength; } diff --git a/serialize/SerialBufferAdapter.h b/serialize/SerialBufferAdapter.h index 02690021..a30451a1 100644 --- a/serialize/SerialBufferAdapter.h +++ b/serialize/SerialBufferAdapter.h @@ -67,7 +67,7 @@ public: uint8_t * getBuffer(); const uint8_t * getConstBuffer(); - void setBuffer(uint8_t* buffer_, count_t bufferLength_); + void setBuffer(uint8_t* buffer, count_t bufferLength); private: bool serializeLength = false; const uint8_t *constBuffer = nullptr; From 7b538e9750001a7b91a89fbde5a47f9b619674eb Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 12 Jun 2020 20:23:39 +0200 Subject: [PATCH 133/307] introduced command message base and command message IF --- housekeeping/HousekeepingMessage.cpp | 17 +--- housekeeping/HousekeepingMessage.h | 13 ++- ipc/CommandMessage.cpp | 128 +++++++++------------------ ipc/CommandMessage.h | 79 +++++------------ ipc/CommandMessageBase.cpp | 55 ++++++++++++ ipc/CommandMessageBase.h | 73 +++++++++++++++ ipc/CommandMessageIF.h | 25 ++++++ ipc/MessageQueueMessage.cpp | 4 + ipc/MessageQueueMessage.h | 3 +- ipc/MessageQueueMessageIF.h | 4 +- 10 files changed, 232 insertions(+), 169 deletions(-) create mode 100644 ipc/CommandMessageBase.cpp create mode 100644 ipc/CommandMessageBase.h create mode 100644 ipc/CommandMessageIF.h diff --git a/housekeeping/HousekeepingMessage.cpp b/housekeeping/HousekeepingMessage.cpp index c94a69d7..d9daf974 100644 --- a/housekeeping/HousekeepingMessage.cpp +++ b/housekeeping/HousekeepingMessage.cpp @@ -1,18 +1,7 @@ #include -HousekeepingMessage::HousekeepingMessage() { +HousekeepingMessage::HousekeepingMessage(MessageQueueMessage *message): + CommandMessageBase (message) {} -} +HousekeepingMessage::~HousekeepingMessage() {} -void HousekeepingMessage::setHkReportMessage() { -} - - -//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 3ba6f94d..d0cbd0eb 100644 --- a/housekeeping/HousekeepingMessage.h +++ b/housekeeping/HousekeepingMessage.h @@ -1,6 +1,8 @@ #ifndef FRAMEWORK_HK_HOUSEKEEPINGMESSAGE_H_ #define FRAMEWORK_HK_HOUSEKEEPINGMESSAGE_H_ -#include +#include +#include +#include #include #include @@ -23,15 +25,14 @@ union sid_t { }; -class HousekeepingMessage: public MessageQueueMessage { +class HousekeepingMessage : public CommandMessageBase { public: /** * No instances of a message shall be created, instead * a CommandMessage instance is manipulated. */ - HousekeepingMessage(); -// HousekeepingMessage(const HousekeepingMessage&) = delete; -// HousekeepingMessage operator=(const HousekeepingMessage &) = delete; + HousekeepingMessage(MessageQueueMessage* message); + virtual ~HousekeepingMessage(); static constexpr uint8_t MESSAGE_ID = messagetypes::HOUSEKEEPING; static constexpr Command_t ADD_HK_REPORT_STRUCT = @@ -78,8 +79,6 @@ public: static constexpr Command_t MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL = MAKE_COMMAND_ID(32); -// static void setAddHkReportStructMessage(CommandMessage* message, -// DevisetId, store_address_t packet); static void setHkReportMessage(); }; diff --git a/ipc/CommandMessage.cpp b/ipc/CommandMessage.cpp index 7d2ecc9b..8f53b77c 100644 --- a/ipc/CommandMessage.cpp +++ b/ipc/CommandMessage.cpp @@ -1,6 +1,7 @@ +#include + #include #include -#include #include #include #include @@ -8,82 +9,86 @@ #include #include -namespace messagetypes { -// Implemented in config. -void clearMissionMessage(CommandMessage* message); -} - - CommandMessage::CommandMessage(MessageQueueMessage* receiverMessage): - internalMessage(receiverMessage) { + CommandMessageBase(receiverMessage) { if(receiverMessage == nullptr) { sif::error << "CommandMessage::CommandMessage: Don't pass a nullptr" " as the message queue message, pass the address of an actual" " message!" << std::endl; } - internalMessage->messageSize = COMMAND_MESSAGE_SIZE; + internalMessage->setMessageSize(COMMAND_MESSAGE_SIZE); setCommand(CMD_NONE); } CommandMessage::CommandMessage(MessageQueueMessage* messageToSet, Command_t command, uint32_t parameter1, uint32_t parameter2): - internalMessage(messageToSet) { + CommandMessageBase(messageToSet) { if(messageToSet == nullptr) { sif::error << "CommandMessage::CommandMessage: Don't pass a nullptr" " as the message queue message, pass the address of an actual" " message!" << std::endl; } - internalMessage->messageSize = COMMAND_MESSAGE_SIZE; + internalMessage->setMessageSize(COMMAND_MESSAGE_SIZE); setCommand(command); setParameter(parameter1); setParameter2(parameter2); } -Command_t CommandMessage::getCommand() const { - Command_t command; - memcpy(&command, internalMessage->getData(), sizeof(Command_t)); - return command; -} - -uint8_t CommandMessage::getMessageType() const { - return getCommand() >> 8 & 0xff; -} - -void CommandMessage::setCommand(Command_t command) { - memcpy(internalMessage->getData(), &command, sizeof(command)); -} - uint32_t CommandMessage::getParameter() const { uint32_t parameter1; - memcpy(¶meter1, internalMessage->getData() + sizeof(Command_t), - sizeof(parameter1)); + memcpy(¶meter1, CommandMessageBase::getData(), sizeof(parameter1)); return parameter1; } void CommandMessage::setParameter(uint32_t parameter1) { - memcpy(internalMessage->getData() + sizeof(Command_t), - ¶meter1, sizeof(parameter1)); + memcpy(CommandMessageBase::getData(), ¶meter1, sizeof(parameter1)); } uint32_t CommandMessage::getParameter2() const { uint32_t parameter2; - memcpy(¶meter2, internalMessage->getData() + sizeof(Command_t) - + sizeof(uint32_t), sizeof(parameter2)); + memcpy(¶meter2, CommandMessageBase::getData() + sizeof(uint32_t), + sizeof(parameter2)); return parameter2; } void CommandMessage::setParameter2(uint32_t parameter2) { - memcpy(internalMessage-> getData() + sizeof(Command_t) + sizeof(uint32_t), - ¶meter2, sizeof(parameter2)); + memcpy(CommandMessageBase::getData() + sizeof(uint32_t), ¶meter2, + sizeof(parameter2)); } +size_t CommandMessage::getMinimumMessageSize() const { + return COMMAND_MESSAGE_SIZE; +} + +size_t CommandMessage::getMaximumMessageSize() const { + return MessageQueueMessage::MAX_MESSAGE_SIZE; +} + +bool CommandMessage::isClearedCommandMessage() { + return getCommand() == CMD_NONE; +} + +void CommandMessage::setToUnknownCommand() { + Command_t initialCommand = getCommand(); + clearCommandMessage(); + setReplyRejected(UNKNOWN_COMMAND, initialCommand); +} + +void CommandMessage::setReplyRejected(ReturnValue_t reason, + Command_t initialCommand) { + setCommand(REPLY_REJECTED); + setParameter(reason); + setParameter2(initialCommand); +} + + void CommandMessage::clear() { clearCommandMessage(); } void CommandMessage::clearCommandMessage() { - switch(getMessageType()){ - case messagetypes::MODE_COMMAND: + switch(this->getMessageType()){ + case messagetypes::MODE_COMMAND: ModeMessage::clear(this); break; case messagetypes::HEALTH_COMMAND: @@ -115,56 +120,3 @@ void CommandMessage::clearCommandMessage() { break; } } - -bool CommandMessage::isClearedCommandMessage() { - return getCommand() == CMD_NONE; -} - -size_t CommandMessage::getMinimumMessageSize() const { - return COMMAND_MESSAGE_SIZE; -} - -void CommandMessage::setToUnknownCommand() { - Command_t initialCommand = getCommand(); - clearCommandMessage(); - setReplyRejected(UNKNOWN_COMMAND, initialCommand); -} - -void CommandMessage::setReplyRejected(ReturnValue_t reason, - Command_t initialCommand) { - setCommand(REPLY_REJECTED); - setParameter(reason); - setParameter2(initialCommand); -} - -MessageQueueId_t CommandMessage::getSender() const { - return internalMessage->getSender(); -} - -uint8_t* CommandMessage::getBuffer() { - return internalMessage->getBuffer(); -} - -void CommandMessage::setSender(MessageQueueId_t setId) { - internalMessage->setSender(setId); -} - -const uint8_t* CommandMessage::getBuffer() const { - return internalMessage->getBuffer(); -} - -uint8_t* CommandMessage::getData() { - return internalMessage->getData(); -} - -const uint8_t* CommandMessage::getData() const { - return internalMessage->getData(); -} - -size_t CommandMessage::getMessageSize() const { - return COMMAND_MESSAGE_SIZE; -} - -size_t CommandMessage::getMaximumMessageSize() const { - return MessageQueueMessage::MAX_MESSAGE_SIZE; -} diff --git a/ipc/CommandMessage.h b/ipc/CommandMessage.h index 25d608f0..434f8c8c 100644 --- a/ipc/CommandMessage.h +++ b/ipc/CommandMessage.h @@ -1,33 +1,35 @@ #ifndef FRAMEWORK_IPC_COMMANDMESSAGE_H_ #define FRAMEWORK_IPC_COMMANDMESSAGE_H_ +#include #include #include -#include - - -#define MAKE_COMMAND_ID( number ) ((MESSAGE_ID << 8) + (number)) -typedef uint16_t Command_t; +namespace messagetypes { +// Implemented in config. +void clearMissionMessage(CommandMessageIF* message); +} /** - * @brief Used to pass command messages between tasks. Primary message type - * for IPC. Contains sender, 2-byte command field, and 2 4-byte - * parameters. + * @brief Default command message used to pass command messages between tasks. + * Primary message type for IPC. Contains sender, 2-byte command ID + * field, and 2 4-byte parameters. * @details * It operates on an external memory which is contained inside a - * MessageQueueMessage by taking its address. + * class implementing MessageQueueMessageIF by taking its address. * This allows for a more flexible designs of message implementations. * The pointer can be passed to different message implementations without * the need of unnecessary copying. + * + * The command message is based of the generic MessageQueueMessage which + * currently has an internal message size of 28 bytes. * @author Bastian Baetz */ -class CommandMessage: public MessageQueueMessageIF { +class CommandMessage: public CommandMessageBase { public: static const uint8_t INTERFACE_ID = CLASS_ID::COMMAND_MESSAGE; static const ReturnValue_t UNKNOWN_COMMAND = MAKE_RETURN_CODE(0x01); - static const uint8_t MESSAGE_ID = messagetypes::COMMAND; //! Used internally, will be ignored static const Command_t CMD_NONE = MAKE_COMMAND_ID( 0 ); @@ -66,39 +68,11 @@ public: */ virtual ~CommandMessage() {} - /** - * Read the DeviceHandlerCommand_t that is stored in the message, - * usually used after receiving. - * - * @return the Command stored in the Message - */ - Command_t getCommand() const; - - /* - * MessageQueueMessageIF functions, which generally just call the - * respective functions of the internal message - */ - uint8_t * getBuffer() override; - const uint8_t * getBuffer() const override; - void setSender(MessageQueueId_t setId) override; - MessageQueueId_t getSender() const override; - uint8_t * getData() override; - const uint8_t* getData() const override; + /** MessageQueueMessageIF functions used for minimum size check. */ size_t getMinimumMessageSize() const override; - size_t getMessageSize() const override; + /** MessageQueueMessageIF functions used for maximum size check. */ size_t getMaximumMessageSize() const override; - /** - * Extract message ID, which is the first byte of the command ID. - * @return - */ - uint8_t getMessageType() const; - /** - * Set the command type of the message - * @param the Command to be sent - */ - void setCommand(Command_t command); - /** * Get the first parameter of the message * @return the first Parameter of the message @@ -123,19 +97,17 @@ public: */ void setParameter2(uint32_t parameter2); + void clear() override; /** - * Set the command to CMD_NONE and try to find - * the correct class to handle a more detailed - * clear. - * Also, calls a mission-specific clearMissionMessage - * function to separate between framework and mission - * messages. Not optimal, may be replaced by totally - * different auto-delete solution (e.g. smart pointers). + * Set the command to CMD_NONE and try to find the correct class to handle + * a more detailed clear. + * Also, calls a mission-specific clearMissionMessage function to separate + * between framework and mission messages. Not optimal, may be replaced by + * totally different auto-delete solution (e.g. smart pointers). * */ void clearCommandMessage(); - void clear() override; /** * check if a message was cleared @@ -151,15 +123,6 @@ public: void setToUnknownCommand(); void setReplyRejected(ReturnValue_t reason, Command_t initialCommand = CMD_NONE); - -private: - /** - * @brief Pointer to the message containing the data. - * @details - * The command message does not actually own the memory containing a - * message, it just oprates on it via a pointer to a message queue message. - */ - MessageQueueMessage* internalMessage; }; diff --git a/ipc/CommandMessageBase.cpp b/ipc/CommandMessageBase.cpp new file mode 100644 index 00000000..aa84bd1e --- /dev/null +++ b/ipc/CommandMessageBase.cpp @@ -0,0 +1,55 @@ +#include +#include + +CommandMessageBase::CommandMessageBase(MessageQueueMessageIF *message): + internalMessage(message) { +} + +Command_t CommandMessageBase::getCommand() const { + Command_t command; + std::memcpy(&command, internalMessage->getData(), sizeof(Command_t)); + return command; +} + +void CommandMessageBase::setCommand(Command_t command) { + std::memcpy(internalMessage->getData(), &command, sizeof(command)); +} + +uint8_t CommandMessageBase::getMessageType() const { + // first byte of command ID. + return getCommand() >> 8 & 0xff; +} + +MessageQueueId_t CommandMessageBase::getSender() const { + return internalMessage->getSender(); +} + +uint8_t* CommandMessageBase::getBuffer() { + return internalMessage->getBuffer(); +} + +void CommandMessageBase::setSender(MessageQueueId_t setId) { + internalMessage->setSender(setId); +} + +const uint8_t* CommandMessageBase::getBuffer() const { + return internalMessage->getBuffer(); +} + +// Header includes command ID. +uint8_t* CommandMessageBase::getData() { + return internalMessage->getData() + sizeof(Command_t); +} + +// Header includes command ID. +const uint8_t* CommandMessageBase::getData() const { + return internalMessage->getData() + sizeof(Command_t); +} + +void CommandMessageBase::setMessageSize(size_t messageSize) { + internalMessage->setMessageSize(messageSize); +} + +size_t CommandMessageBase::getMessageSize() const { + return internalMessage->getMessageSize(); +} diff --git a/ipc/CommandMessageBase.h b/ipc/CommandMessageBase.h new file mode 100644 index 00000000..fa3fd477 --- /dev/null +++ b/ipc/CommandMessageBase.h @@ -0,0 +1,73 @@ +#ifndef FRAMEWORK_IPC_COMMANDMESSAGEBASE_H_ +#define FRAMEWORK_IPC_COMMANDMESSAGEBASE_H_ +#include +#include + +/** + * @brief Base implementation of a generic command message, which has + * a Command_t ID and message type ID in the header in addition + * to the sender message queue ID. + * @details + * This is the base implementation serves as a base for other command messages + * and which implements most functions required for MessageQueueMessageIF. + * The only functions which have to be supplied by a specific command message + * impelementations are the size related functions which are used for + * size checks: + * + * 1. getMinimumMessageSize() + * 2. getMaximumMessageSize() + * + * Don't forget to set the message size of the passed message in the concrete + * commandmessage implementation! + */ +class CommandMessageBase: public CommandMessageIF { +public: + CommandMessageBase(MessageQueueMessageIF* message); + + /** + * Read the DeviceHandlerCommand_t that is stored in the message, + * usually used after receiving. + * + * @return the Command stored in the Message + */ + virtual Command_t getCommand() const override; + /** + * Set the command type of the message. Default implementation also + * sets the message type, which will be the first byte of the command ID. + * @param the Command to be sent + */ + virtual void setCommand(Command_t command); + + /** + * Extract message ID, which is the first byte of the command ID for the + * default implementation. + * @return + */ + virtual uint8_t getMessageType() const override; + + /* + * MessageQueueMessageIF functions, which generally just call the + * respective functions of the internal message queue message. + */ + virtual uint8_t * getBuffer() override; + virtual const uint8_t * getBuffer() const override; + virtual void setSender(MessageQueueId_t setId) override; + virtual MessageQueueId_t getSender() const override; + virtual uint8_t * getData() override; + virtual const uint8_t* getData() const override; + virtual void setMessageSize(size_t messageSize) override; + virtual size_t getMessageSize() const override; + +protected: + /** + * @brief Pointer to the message containing the data. + * @details + * The command message does not actually own the memory containing a + * message, it just oprates on it via a pointer to a message queue message. + */ + MessageQueueMessageIF* internalMessage; +}; + + + +#endif /* FRAMEWORK_IPC_COMMANDMESSAGEBASE_H_ */ diff --git a/ipc/CommandMessageIF.h b/ipc/CommandMessageIF.h new file mode 100644 index 00000000..fbc40f88 --- /dev/null +++ b/ipc/CommandMessageIF.h @@ -0,0 +1,25 @@ +#ifndef FRAMEWORK_IPC_COMMANDMESSAGEIF_H_ +#define FRAMEWORK_IPC_COMMANDMESSAGEIF_H_ + +#include + +#define MAKE_COMMAND_ID( number ) ((MESSAGE_ID << 8) + (number)) +typedef uint16_t Command_t; + +class CommandMessageIF: public MessageQueueMessageIF { +public: + virtual ~CommandMessageIF() {}; + + /** + * A command message shall have a uint16_t command ID field. + * @return + */ + virtual Command_t getCommand() const = 0; + /** + * A command message shall have a uint8_t message type ID field. + * @return + */ + virtual uint8_t getMessageType() const = 0; +}; + +#endif /* FRAMEWORK_IPC_COMMANDMESSAGEIF_H_ */ diff --git a/ipc/MessageQueueMessage.cpp b/ipc/MessageQueueMessage.cpp index 8430a8ea..b173f2c4 100644 --- a/ipc/MessageQueueMessage.cpp +++ b/ipc/MessageQueueMessage.cpp @@ -75,3 +75,7 @@ size_t MessageQueueMessage::getMessageSize() const { size_t MessageQueueMessage::getMaximumMessageSize() const { return this->MAX_MESSAGE_SIZE; } + +void MessageQueueMessage::setMessageSize(size_t messageSize) { + this->messageSize = messageSize; +} diff --git a/ipc/MessageQueueMessage.h b/ipc/MessageQueueMessage.h index 31a43f66..2eb1f4f5 100644 --- a/ipc/MessageQueueMessage.h +++ b/ipc/MessageQueueMessage.h @@ -3,7 +3,7 @@ #include #include -#include +#include /** * @brief This class is the representation and data organizer @@ -150,6 +150,7 @@ public: virtual size_t getMinimumMessageSize() const override; virtual size_t getMessageSize() const override; + virtual void setMessageSize(size_t messageSize) override; virtual size_t getMaximumMessageSize() const override; diff --git a/ipc/MessageQueueMessageIF.h b/ipc/MessageQueueMessageIF.h index 05330ce9..f34cab98 100644 --- a/ipc/MessageQueueMessageIF.h +++ b/ipc/MessageQueueMessageIF.h @@ -24,7 +24,8 @@ public: /** * @brief With this method, the whole content and the message - * size is set to zero. + * size is set to zero. Implementations should also take care + * to clear data which is stored indirectly (e.g. storage data). */ virtual void clear() = 0; @@ -77,6 +78,7 @@ public: * @return */ virtual size_t getMessageSize() const = 0; + virtual void setMessageSize(size_t messageSize) = 0; /** * Get maximum allowed size of current message implementation. From 6b67f46c802aa1b421689097d3faf96668073c71 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 13 Jun 2020 17:37:48 +0200 Subject: [PATCH 134/307] evil hidden bug found. CSB uses CommandMessageIF now --- datapoollocal/LocalDataPoolManager.cpp | 4 +- datapoollocal/LocalDataPoolManager.h | 2 +- devicehandlers/DeviceHandlerBase.cpp | 28 ++++-------- devicehandlers/HealthDevice.cpp | 2 +- housekeeping/HousekeepingMessage.cpp | 45 +++++++++++++++++-- housekeeping/HousekeepingMessage.h | 29 +++++++++--- ipc/CommandMessage.cpp | 33 +++++++++++--- ipc/CommandMessage.h | 12 +++-- ipc/CommandMessageBase.cpp | 6 ++- ipc/CommandMessageBase.h | 6 ++- ipc/CommandMessageIF.h | 16 +++++++ ipc/MessageQueueMessage.h | 4 +- osal/FreeRTOS/MessageQueue.cpp | 2 +- osal/FreeRTOS/MessageQueue.h | 22 ++++----- tmtcservices/CommandingServiceBase.cpp | 62 +++++++++++++++++--------- tmtcservices/CommandingServiceBase.h | 23 +++++++--- tmtcservices/VerificationReporter.cpp | 10 ++--- 17 files changed, 214 insertions(+), 92 deletions(-) diff --git a/datapoollocal/LocalDataPoolManager.cpp b/datapoollocal/LocalDataPoolManager.cpp index 37dbed36..58694508 100644 --- a/datapoollocal/LocalDataPoolManager.cpp +++ b/datapoollocal/LocalDataPoolManager.cpp @@ -41,8 +41,8 @@ ReturnValue_t LocalDataPoolManager::initializeHousekeepingPoolEntriesOnce() { } ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage( - MessageQueueMessage *message) { - return HasReturnvaluesIF::RETURN_OK; + HousekeepingMessage& message) { + return HasReturnvaluesIF::RETURN_FAILED; } ReturnValue_t LocalDataPoolManager::printPoolEntry( diff --git a/datapoollocal/LocalDataPoolManager.h b/datapoollocal/LocalDataPoolManager.h index 1d25fa48..d1a2d410 100644 --- a/datapoollocal/LocalDataPoolManager.h +++ b/datapoollocal/LocalDataPoolManager.h @@ -46,7 +46,7 @@ public: LocalDataPoolManager operator=(const LocalDataPoolManager&) = delete; ReturnValue_t generateHousekeepingPacket(sid_t sid); - ReturnValue_t handleHousekeepingMessage(MessageQueueMessage* message); + ReturnValue_t handleHousekeepingMessage(HousekeepingMessage& message); /** * This function is used to fill the local data pool map with pool diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index 11cffc74..bf699848 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -225,15 +225,6 @@ void DeviceHandlerBase::readCommandQueue() { return; } - // This is really annoying. I can't cast a parent object to a child. - // But I want to use another message format.. -// CommandMessage* cmdMessage = dynamic_cast(msgPtr); -// if(cmdMessage == nullptr) { -// sif::error << "DeviceHandlerBase::readCommandQueue: Could not cast" -// " message to CommandMessage!" << std::endl; -// return; -// } - if(healthHelperActive) { result = healthHelper.handleHealthCommand(&command); if (result == RETURN_OK) { @@ -256,11 +247,11 @@ void DeviceHandlerBase::readCommandQueue() { return; } -// HousekeepingMessage* hkMessage = dynamic_cast(msgPtr); -// result = hkManager.handleHousekeepingMessage(hkMessage); -// if (result == RETURN_OK) { -// return; -// } + HousekeepingMessage hkMessage(&message); + result = hkManager.handleHousekeepingMessage(hkMessage); + if (result == RETURN_OK) { + return; + } result = handleDeviceHandlerMessage(&command); if (result == RETURN_OK) { @@ -758,7 +749,7 @@ ReturnValue_t DeviceHandlerBase::getStorageData(store_address_t storageAddress, void DeviceHandlerBase::replyRawData(const uint8_t *data, size_t len, MessageQueueId_t sendTo, bool isCommand) { - if (IPCStore == NULL || len == 0 || sendTo == MessageQueueIF::NO_QUEUE) { + if (IPCStore == nullptr or len == 0 or sendTo == MessageQueueIF::NO_QUEUE) { return; } store_address_t address; @@ -775,13 +766,12 @@ void DeviceHandlerBase::replyRawData(const uint8_t *data, size_t len, DeviceHandlerMessage::setDeviceHandlerRawReplyMessage(&command, getObjectId(), address, isCommand); -// this->DeviceHandlerCommand = CommandMessage::CMD_NONE; - - result = commandQueue->sendMessage(sendTo, &message); + result = commandQueue->sendMessage(sendTo, &command); if (result != RETURN_OK) { IPCStore->deleteData(address); - //Silently discard data, this indicates heavy TM traffic which should not be increased by additional events. + // Silently discard data, this indicates heavy TM traffic which + // should not be increased by additional events. } } diff --git a/devicehandlers/HealthDevice.cpp b/devicehandlers/HealthDevice.cpp index 1c9d18f6..7e3a59bd 100644 --- a/devicehandlers/HealthDevice.cpp +++ b/devicehandlers/HealthDevice.cpp @@ -5,7 +5,7 @@ HealthDevice::HealthDevice(object_id_t setObjectId, MessageQueueId_t parentQueue) : SystemObject(setObjectId), lastHealth(HEALTHY), parentQueue( parentQueue), commandQueue(), healthHelper(this, setObjectId) { - commandQueue = QueueFactory::instance()->createMessageQueue(3, CommandMessage::COMMAND_MESSAGE_SIZE); + commandQueue = QueueFactory::instance()->createMessageQueue(3, CommandMessage::MINIMUM_COMMAND_MESSAGE_SIZE); } HealthDevice::~HealthDevice() { diff --git a/housekeeping/HousekeepingMessage.cpp b/housekeeping/HousekeepingMessage.cpp index d9daf974..6dd1a711 100644 --- a/housekeeping/HousekeepingMessage.cpp +++ b/housekeeping/HousekeepingMessage.cpp @@ -1,7 +1,46 @@ #include +#include -HousekeepingMessage::HousekeepingMessage(MessageQueueMessage *message): - CommandMessageBase (message) {} +HousekeepingMessage::HousekeepingMessage(MessageQueueMessageIF* message): + CommandMessageBase(message) { +} -HousekeepingMessage::~HousekeepingMessage() {} +HousekeepingMessage::~HousekeepingMessage() { +} +void HousekeepingMessage::setHkReportMessage(sid_t sid, + store_address_t storeId) { + CommandMessageBase::setCommand(HK_REPORT); + setSid(sid); + setParameter(storeId.raw); +} + +size_t HousekeepingMessage::getMinimumMessageSize() const { + return HK_MESSAGE_SIZE; +} + +size_t HousekeepingMessage::getMaximumMessageSize() const { + return MessageQueueMessage::MAX_MESSAGE_SIZE; +} + +void HousekeepingMessage::clear() { + // clear IPC store where it is needed. +} + +sid_t HousekeepingMessage::getSid() const { + sid_t sid; + std::memcpy(&sid.raw, CommandMessageBase::getData(), sizeof(sid.raw)); + return sid; +} + +uint8_t* HousekeepingMessage::getData() { + return internalMessage->getBuffer() + sizeof(sid_t); +} + +void HousekeepingMessage::setParameter(uint32_t parameter) { + memcpy(getData(), ¶meter, sizeof(parameter)); +} + +void HousekeepingMessage::setSid(sid_t sid) { + std::memcpy(CommandMessageBase::getData(), &sid.raw, sizeof(sid.raw)); +} diff --git a/housekeeping/HousekeepingMessage.h b/housekeeping/HousekeepingMessage.h index d0cbd0eb..4e9d4553 100644 --- a/housekeeping/HousekeepingMessage.h +++ b/housekeeping/HousekeepingMessage.h @@ -13,13 +13,15 @@ union sid_t { struct { object_id_t objectId ; - // A generic 32 bit ID to identify unique HK packets for a single - // object. - // For example, the DeviceCommandId_t is used for DeviceHandlers + /** + * 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. + * Alternative access to the raw value. This is also the size of the type. */ uint64_t raw; }; @@ -27,14 +29,18 @@ union sid_t { class HousekeepingMessage : public CommandMessageBase { public: + + static constexpr size_t HK_MESSAGE_SIZE = sizeof(MessageQueueId_t) + + sizeof(Command_t) + sizeof(sid_t) * sizeof(uint32_t); /** * No instances of a message shall be created, instead * a CommandMessage instance is manipulated. */ - HousekeepingMessage(MessageQueueMessage* message); + HousekeepingMessage(MessageQueueMessageIF* message); virtual ~HousekeepingMessage(); static constexpr uint8_t MESSAGE_ID = messagetypes::HOUSEKEEPING; + static constexpr Command_t ADD_HK_REPORT_STRUCT = MAKE_COMMAND_ID(1); static constexpr Command_t ADD_DIAGNOSTICS_REPORT_STRUCT = @@ -79,7 +85,18 @@ public: static constexpr Command_t MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL = MAKE_COMMAND_ID(32); - static void setHkReportMessage(); + void setHkReportMessage(sid_t sid, store_address_t storeId); + + void setParameter(uint32_t parameter); + + virtual void clear() override; + virtual size_t getMinimumMessageSize() const override; + virtual size_t getMaximumMessageSize() const override; + + virtual uint8_t* getData() override; +private: + sid_t getSid() const; + void setSid(sid_t sid); }; diff --git a/ipc/CommandMessage.cpp b/ipc/CommandMessage.cpp index 8f53b77c..9d448aed 100644 --- a/ipc/CommandMessage.cpp +++ b/ipc/CommandMessage.cpp @@ -9,18 +9,25 @@ #include #include -CommandMessage::CommandMessage(MessageQueueMessage* receiverMessage): +CommandMessage::CommandMessage(MessageQueueMessageIF* receiverMessage): CommandMessageBase(receiverMessage) { if(receiverMessage == nullptr) { sif::error << "CommandMessage::CommandMessage: Don't pass a nullptr" " as the message queue message, pass the address of an actual" " message!" << std::endl; + return; } - internalMessage->setMessageSize(COMMAND_MESSAGE_SIZE); - setCommand(CMD_NONE); + if(receiverMessage->getMaximumMessageSize() < + MINIMUM_COMMAND_MESSAGE_SIZE) { + sif::error << "CommandMessage::ComandMessage: Passed message buffer" + " can not hold minimum "<< MINIMUM_COMMAND_MESSAGE_SIZE + << " bytes!" << std::endl; + return; + } + internalMessage->setMessageSize(MINIMUM_COMMAND_MESSAGE_SIZE); } -CommandMessage::CommandMessage(MessageQueueMessage* messageToSet, +CommandMessage::CommandMessage(MessageQueueMessageIF* messageToSet, Command_t command, uint32_t parameter1, uint32_t parameter2): CommandMessageBase(messageToSet) { if(messageToSet == nullptr) { @@ -28,7 +35,14 @@ CommandMessage::CommandMessage(MessageQueueMessage* messageToSet, " as the message queue message, pass the address of an actual" " message!" << std::endl; } - internalMessage->setMessageSize(COMMAND_MESSAGE_SIZE); + if(messageToSet->getMaximumMessageSize() < + MINIMUM_COMMAND_MESSAGE_SIZE) { + sif::error << "CommandMessage::ComandMessage: Passed message buffer" + " can not hold minimum "<< MINIMUM_COMMAND_MESSAGE_SIZE + << " bytes!" << std::endl; + return; + } + internalMessage->setMessageSize(MINIMUM_COMMAND_MESSAGE_SIZE); setCommand(command); setParameter(parameter1); setParameter2(parameter2); @@ -57,7 +71,7 @@ void CommandMessage::setParameter2(uint32_t parameter2) { } size_t CommandMessage::getMinimumMessageSize() const { - return COMMAND_MESSAGE_SIZE; + return MINIMUM_COMMAND_MESSAGE_SIZE; } size_t CommandMessage::getMaximumMessageSize() const { @@ -81,6 +95,13 @@ void CommandMessage::setReplyRejected(ReturnValue_t reason, setParameter2(initialCommand); } +ReturnValue_t CommandMessage::getRejectedReplyReason( + Command_t* initialCommand) const { + if(initialCommand != nullptr) { + *initialCommand = getParameter2(); + } + return getParameter(); +} void CommandMessage::clear() { clearCommandMessage(); diff --git a/ipc/CommandMessage.h b/ipc/CommandMessage.h index 434f8c8c..8e1e9c8c 100644 --- a/ipc/CommandMessage.h +++ b/ipc/CommandMessage.h @@ -42,8 +42,9 @@ public: * This is the size of a message as it is seen by the MessageQueue. * 14 of the 24 available MessageQueueMessage bytes are used. */ - static const size_t COMMAND_MESSAGE_SIZE = MessageQueueMessage::HEADER_SIZE - + sizeof(Command_t) + 2 * sizeof(uint32_t); + static const size_t MINIMUM_COMMAND_MESSAGE_SIZE = + MessageQueueMessage::HEADER_SIZE + sizeof(Command_t) + + 2 * sizeof(uint32_t); /** * Default Constructor, does not initialize anything. @@ -51,7 +52,7 @@ public: * This constructor should be used when receiving a Message, as the * content is filled by the MessageQueue. */ - CommandMessage(MessageQueueMessage* receiverMessage); + CommandMessage(MessageQueueMessageIF* receiverMessage); /** * This constructor creates a new message with all message content * initialized @@ -60,7 +61,7 @@ public: * @param parameter1 The first parameter * @param parameter2 The second parameter */ - CommandMessage(MessageQueueMessage* messageToSet, Command_t command, + CommandMessage(MessageQueueMessageIF* messageToSet, Command_t command, uint32_t parameter1, uint32_t parameter2); /** @@ -121,8 +122,11 @@ public: * Is needed quite often, so we better code it once only. */ void setToUnknownCommand(); + void setReplyRejected(ReturnValue_t reason, Command_t initialCommand = CMD_NONE); + ReturnValue_t getRejectedReplyReason( + Command_t* initialCommand = nullptr) const; }; diff --git a/ipc/CommandMessageBase.cpp b/ipc/CommandMessageBase.cpp index aa84bd1e..3ffe4daa 100644 --- a/ipc/CommandMessageBase.cpp +++ b/ipc/CommandMessageBase.cpp @@ -12,7 +12,7 @@ Command_t CommandMessageBase::getCommand() const { } void CommandMessageBase::setCommand(Command_t command) { - std::memcpy(internalMessage->getData(), &command, sizeof(command)); + std::memcpy(internalMessage->getData(), &command, sizeof(Command_t)); } uint8_t CommandMessageBase::getMessageType() const { @@ -53,3 +53,7 @@ void CommandMessageBase::setMessageSize(size_t messageSize) { size_t CommandMessageBase::getMessageSize() const { return internalMessage->getMessageSize(); } + +MessageQueueMessageIF* CommandMessageBase::getInternalMessage() const { + return internalMessage; +} diff --git a/ipc/CommandMessageBase.h b/ipc/CommandMessageBase.h index fa3fd477..b2b7d5f2 100644 --- a/ipc/CommandMessageBase.h +++ b/ipc/CommandMessageBase.h @@ -22,6 +22,9 @@ */ class CommandMessageBase: public CommandMessageIF { public: + static constexpr size_t HEADER_SIZE = sizeof(MessageQueueId_t) + + sizeof(Command_t); + CommandMessageBase(MessageQueueMessageIF* message); /** @@ -58,6 +61,7 @@ public: virtual void setMessageSize(size_t messageSize) override; virtual size_t getMessageSize() const override; + virtual MessageQueueMessageIF* getInternalMessage() const override; protected: /** * @brief Pointer to the message containing the data. @@ -65,7 +69,7 @@ protected: * The command message does not actually own the memory containing a * message, it just oprates on it via a pointer to a message queue message. */ - MessageQueueMessageIF* internalMessage; + MessageQueueMessageIF* internalMessage = nullptr; }; diff --git a/ipc/CommandMessageIF.h b/ipc/CommandMessageIF.h index fbc40f88..44853c38 100644 --- a/ipc/CommandMessageIF.h +++ b/ipc/CommandMessageIF.h @@ -6,6 +6,12 @@ #define MAKE_COMMAND_ID( number ) ((MESSAGE_ID << 8) + (number)) typedef uint16_t Command_t; +// TODO: actually, this interface propably does not have to implement +// MQM IF, because there is a getter function for the internal message.. +// But it is also convenient to have the full access to all MQM IF functions. +// That way, I can just pass CommandMessages to functions expecting a MQM IF. +// The command message implementations just forwards the calls. Maybe +// we should just leave it like that. class CommandMessageIF: public MessageQueueMessageIF { public: virtual ~CommandMessageIF() {}; @@ -20,6 +26,16 @@ public: * @return */ virtual uint8_t getMessageType() const = 0; + + /** + * This function is used to get a pointer to the internal message, as + * the command message implementations always operate on the memory + * contained in the message queue message implementation. + * This pointer can be used to set the internal message of different + * command message implementations. + * @return + */ + virtual MessageQueueMessageIF* getInternalMessage() const = 0; }; #endif /* FRAMEWORK_IPC_COMMANDMESSAGEIF_H_ */ diff --git a/ipc/MessageQueueMessage.h b/ipc/MessageQueueMessage.h index 2eb1f4f5..8716df54 100644 --- a/ipc/MessageQueueMessage.h +++ b/ipc/MessageQueueMessage.h @@ -88,12 +88,12 @@ public: * queue in the system. So, a change here may have significant impact on * the required resources. */ - static const size_t MAX_MESSAGE_SIZE = MAX_DATA_SIZE + HEADER_SIZE; + static constexpr size_t MAX_MESSAGE_SIZE = MAX_DATA_SIZE + HEADER_SIZE; /** * @brief Defines the minimum size of a message where only the * header is included */ - static const size_t MIN_MESSAGE_SIZE = HEADER_SIZE; + static constexpr size_t MIN_MESSAGE_SIZE = HEADER_SIZE; private: /** * @brief This is the internal buffer that contains the diff --git a/osal/FreeRTOS/MessageQueue.cpp b/osal/FreeRTOS/MessageQueue.cpp index 8c6ec80b..d44b0bc0 100644 --- a/osal/FreeRTOS/MessageQueue.cpp +++ b/osal/FreeRTOS/MessageQueue.cpp @@ -101,7 +101,7 @@ ReturnValue_t MessageQueue::flush(uint32_t* count) { } MessageQueueId_t MessageQueue::getId() const { - return (MessageQueueId_t) handle; + return reinterpret_cast(handle); } void MessageQueue::setDefaultDestination(MessageQueueId_t defaultDestination) { diff --git a/osal/FreeRTOS/MessageQueue.h b/osal/FreeRTOS/MessageQueue.h index 6165c1cf..c13a8a20 100644 --- a/osal/FreeRTOS/MessageQueue.h +++ b/osal/FreeRTOS/MessageQueue.h @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include @@ -85,14 +85,14 @@ public: * @param ignoreFault If set to true, the internal software fault counter is not incremented if queue is full. */ ReturnValue_t sendMessage(MessageQueueId_t sendTo, - MessageQueueMessageIF* message, bool ignoreFault = false ); + MessageQueueMessageIF* message, bool ignoreFault = false) override; /** * @brief This operation sends a message to the default destination. * @details As in the sendMessage method, this function uses the sendToDefault call of the * MessageQueueSender parent class and adds its queue id as "sentFrom" information. * @param message A pointer to a previously created message, which is sent. */ - ReturnValue_t sendToDefault( MessageQueueMessageIF* message ); + ReturnValue_t sendToDefault(MessageQueueMessageIF* message) override; /** * @brief This operation sends a message to the last communication partner. * @details This operation simplifies answering an incoming message by using the stored @@ -100,7 +100,7 @@ public: * (i.e. lastPartner is zero), an error code is returned. * @param message A pointer to a previously created message, which is sent. */ - ReturnValue_t reply( MessageQueueMessageIF* message ); + ReturnValue_t reply(MessageQueueMessageIF* message) override; /** * @brief With the sendMessage call, a queue message is sent to a receiving queue. @@ -113,9 +113,10 @@ public: * This variable is set to zero by default. * @param ignoreFault If set to true, the internal software fault counter is not incremented if queue is full. */ - virtual ReturnValue_t sendMessageFrom( MessageQueueId_t sendTo, - MessageQueueMessageIF* message, MessageQueueId_t sentFrom = NO_QUEUE, - bool ignoreFault = false ); + virtual ReturnValue_t sendMessageFrom(MessageQueueId_t sendTo, + MessageQueueMessageIF* message, + MessageQueueId_t sentFrom = NO_QUEUE, + bool ignoreFault = false) override; /** * @brief The sendToDefault method sends a queue message to the default destination. @@ -125,7 +126,8 @@ public: * This variable is set to zero by default. */ virtual ReturnValue_t sendToDefaultFrom( MessageQueueMessageIF* message, - MessageQueueId_t sentFrom = NO_QUEUE, bool ignoreFault = false ); + MessageQueueId_t sentFrom = NO_QUEUE, + bool ignoreFault = false) override; /** * @brief This function reads available messages from the message queue and returns the sender. @@ -135,7 +137,7 @@ public: * @param receivedFrom A pointer to a queue id in which the sender's id is stored. */ ReturnValue_t receiveMessage(MessageQueueMessageIF* message, - MessageQueueId_t *receivedFrom); + MessageQueueId_t *receivedFrom) override; /** * @brief This function reads available messages from the message queue. @@ -145,7 +147,7 @@ public: * message's content is cleared and the function returns immediately. * @param message A pointer to a message in which the received data is stored. */ - ReturnValue_t receiveMessage(MessageQueueMessageIF* message); + ReturnValue_t receiveMessage(MessageQueueMessageIF* message) override; /** * Deletes all pending messages in the queue. * @param count The number of flushed messages. diff --git a/tmtcservices/CommandingServiceBase.cpp b/tmtcservices/CommandingServiceBase.cpp index 72351995..65053cc8 100644 --- a/tmtcservices/CommandingServiceBase.cpp +++ b/tmtcservices/CommandingServiceBase.cpp @@ -81,40 +81,58 @@ void CommandingServiceBase::handleCommandQueue() { ReturnValue_t result = RETURN_FAILED; for (result = commandQueue->receiveMessage(&reply); result == RETURN_OK; result = commandQueue->receiveMessage(&reply)) { - handleCommandMessage(reply); + if(reply.getInternalMessage() == nullptr) { + // This should never happen unless the passed message maximum size + // is too small! + sif::error << "CommandingServiceBase::handleCommandMessage: Reply" + "does not satisfy minimum requirements for a command " + "message!" << std::endl; + continue; + } + handleCommandMessage(&reply); } } -void CommandingServiceBase::handleCommandMessage(CommandMessage& reply) { +void CommandingServiceBase::handleCommandMessage(CommandMessage* reply) { bool isStep = false; MessageQueueMessage message; CommandMessage nextCommand(&message); - CommandMapIter iter; - if (reply.getSender() == MessageQueueIF::NO_QUEUE) { - handleUnrequestedReply(&reply); - return; - } - if ((iter = commandMap.find(reply.getSender())) == commandMap.end()) { - handleUnrequestedReply(&reply); + CommandMapIter iter = commandMap.find(reply->getSender()); + + // handle unrequested reply first + if (reply->getSender() == MessageQueueIF::NO_QUEUE or + iter == commandMap.end()) { + handleUnrequestedReply(reply); return; } nextCommand.setCommand(CommandMessage::CMD_NONE); + // Implemented by child class, specifies what to do with reply. - ReturnValue_t result = handleReply(&reply, iter->command, &iter->state, + ReturnValue_t result = handleReply(reply, iter->command, &iter->state, &nextCommand, iter->objectId, &isStep); + /* If the child implementation does not implement special handling for + * rejected replies (RETURN_FAILED is returned), a failure verification + * will be generated with the reason as the return code and the initial + * command as failure parameter 1 */ + if(reply->getCommand() == CommandMessage::REPLY_REJECTED and + result == RETURN_FAILED) { + result = reply->getRejectedReplyReason( + reinterpret_cast(&failureParameter1)); + } + switch (result) { case EXECUTION_COMPLETE: case RETURN_OK: case NO_STEP_MESSAGE: // handle result of reply handler implemented by developer. - handleReplyHandlerResult(result, iter, nextCommand, reply, isStep); + handleReplyHandlerResult(result, iter, &nextCommand, reply, isStep); break; case INVALID_REPLY: //might be just an unrequested reply at a bad moment - handleUnrequestedReply(&reply); + handleUnrequestedReply(reply); break; default: if (isStep) { @@ -138,17 +156,17 @@ void CommandingServiceBase::handleCommandMessage(CommandMessage& reply) { } void CommandingServiceBase::handleReplyHandlerResult(ReturnValue_t result, - CommandMapIter iter, CommandMessage& nextCommand, CommandMessage& reply, + CommandMapIter iter, CommandMessage* nextCommand, CommandMessage* reply, bool& isStep) { - iter->command = nextCommand.getCommand(); + iter->command = nextCommand->getCommand(); // In case a new command is to be sent immediately, this is performed here. // If no new command is sent, only analyse reply result by initializing // sendResult as RETURN_OK ReturnValue_t sendResult = RETURN_OK; - if (nextCommand.getCommand() != CommandMessage::CMD_NONE) { - sendResult = commandQueue->sendMessage(reply.getSender(), - &nextCommand); + if (nextCommand->getCommand() != CommandMessage::CMD_NONE) { + sendResult = commandQueue->sendMessage(reply->getSender(), + nextCommand); } if (sendResult == RETURN_OK) { @@ -168,14 +186,14 @@ void CommandingServiceBase::handleReplyHandlerResult(ReturnValue_t result, } else { if (isStep) { - nextCommand.clearCommandMessage(); + nextCommand->clearCommandMessage(); verificationReporter.sendFailureReport( TC_VERIFY::PROGRESS_FAILURE, iter->tcInfo.ackFlags, iter->tcInfo.tcPacketId, iter->tcInfo.tcSequenceControl, sendResult, ++iter->step, failureParameter1, failureParameter2); } else { - nextCommand.clearCommandMessage(); + nextCommand->clearCommandMessage(); verificationReporter.sendFailureReport( TC_VERIFY::COMPLETION_FAILURE, iter->tcInfo.ackFlags, iter->tcInfo.tcPacketId, @@ -366,9 +384,9 @@ void CommandingServiceBase::checkAndExecuteFifo(CommandMapIter iter) { } -void CommandingServiceBase::handleUnrequestedReply( - CommandMessage* reply) { - reply->clearCommandMessage(); +void CommandingServiceBase::handleUnrequestedReply(CommandMessageIF* reply) { + CommandMessage commandReply(reply->getInternalMessage()); + commandReply.clear(); } diff --git a/tmtcservices/CommandingServiceBase.h b/tmtcservices/CommandingServiceBase.h index 1dcafff8..5adfe4a6 100644 --- a/tmtcservices/CommandingServiceBase.h +++ b/tmtcservices/CommandingServiceBase.h @@ -147,9 +147,11 @@ protected: /** * This function is implemented by child services to specify how replies - * to a command from another software component are handled + * to a command from another software component are handled. * @param reply - * This is the reply in form of a command message. + * This is the reply which can be accessed via the command message + * interface. The internal message pointer can be passed to different + * command message implementations (see CommandMessageIF) * @param previousCommand * Command_t of related command * @param state [out/in] @@ -163,9 +165,12 @@ protected: * - @c RETURN_OK, @c EXECUTION_COMPLETE or @c NO_STEP_MESSAGE to * generate TC verification success * - @c INVALID_REPLY calls handleUnrequestedReply - * - Anything else triggers a TC verification failure + * - Anything else triggers a TC verification failure. If RETURN_FAILED + * is returned and the command ID is CommandMessage::REPLY_REJECTED, + * a failure verification message with the reason as the error parameter + * and the initial command as failure parameter 1. */ - virtual ReturnValue_t handleReply(const CommandMessage *reply, + virtual ReturnValue_t handleReply(const CommandMessageIF *reply, Command_t previousCommand, uint32_t *state, CommandMessage *optionalNextCommand, object_id_t objectId, bool *isStep) = 0; @@ -173,9 +178,13 @@ protected: /** * This function can be overidden to handle unrequested reply, * when the reply sender ID is unknown or is not found is the command map. + * The default implementation will clear the command message and all + * its contents. * @param reply + * Reply which is non-const so the default implementation can clear the + * message. */ - virtual void handleUnrequestedReply(CommandMessage *reply); + virtual void handleUnrequestedReply(CommandMessageIF *reply); virtual void doPeriodicOperation(); @@ -303,9 +312,9 @@ private: void startExecution(TcPacketStored *storedPacket, CommandMapIter iter); - void handleCommandMessage(CommandMessage& reply); + void handleCommandMessage(CommandMessage* reply); void handleReplyHandlerResult(ReturnValue_t result, CommandMapIter iter, - CommandMessage& nextCommand,CommandMessage& reply, bool& isStep); + CommandMessage* nextCommand,CommandMessage* reply, bool& isStep); void checkTimeout(); }; diff --git a/tmtcservices/VerificationReporter.cpp b/tmtcservices/VerificationReporter.cpp index 4484fb9b..b0247944 100644 --- a/tmtcservices/VerificationReporter.cpp +++ b/tmtcservices/VerificationReporter.cpp @@ -24,9 +24,8 @@ void VerificationReporter::sendSuccessReport(uint8_t set_report_id, current_packet->getPacketSequenceControl(), 0, set_step); ReturnValue_t status = MessageQueueSenderIF::sendMessage(acknowledgeQueue, &message); if (status != HasReturnvaluesIF::RETURN_OK) { - sif::error - << "VerificationReporter::sendSuccessReport: Error writing to queue. Code: " - << (uint16_t) status << std::endl; + sif::error << "VerificationReporter::sendSuccessReport: Error writing " + "to queue. Code: " << std::hex << (uint16_t) status << std::endl; } } @@ -40,9 +39,8 @@ void VerificationReporter::sendSuccessReport(uint8_t set_report_id, tcSequenceControl, 0, set_step); ReturnValue_t status = MessageQueueSenderIF::sendMessage(acknowledgeQueue, &message); if (status != HasReturnvaluesIF::RETURN_OK) { - sif::error - << "VerificationReporter::sendSuccessReport: Error writing to queue. Code: " - << (uint16_t) status << std::endl; + sif::error << "VerificationReporter::sendSuccessReport: Error writing " + "to queue. Code: " << std::hex << (uint16_t) status << std::endl; } } From 8c03f6a823afca715f51d01cbecdbaa5e6ca185e Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 13 Jun 2020 21:01:01 +0200 Subject: [PATCH 135/307] command message only passed IF now --- ipc/CommandMessage.cpp | 74 +++----------------------- ipc/CommandMessage.h | 33 ------------ ipc/CommandMessageBase.cpp | 23 ++++++++ ipc/CommandMessageBase.h | 21 ++++++-- ipc/CommandMessageCleaner.cpp | 45 ++++++++++++++++ ipc/CommandMessageCleaner.h | 16 ++++++ ipc/CommandMessageIF.h | 34 ++++++++++++ memory/MemoryHelper.cpp | 2 +- tmtcservices/CommandingServiceBase.cpp | 16 +++--- tmtcservices/CommandingServiceBase.h | 8 +-- 10 files changed, 155 insertions(+), 117 deletions(-) create mode 100644 ipc/CommandMessageCleaner.cpp create mode 100644 ipc/CommandMessageCleaner.h diff --git a/ipc/CommandMessage.cpp b/ipc/CommandMessage.cpp index 9d448aed..39290688 100644 --- a/ipc/CommandMessage.cpp +++ b/ipc/CommandMessage.cpp @@ -1,13 +1,5 @@ #include - -#include -#include -#include -#include -#include -#include -#include -#include +#include CommandMessage::CommandMessage(MessageQueueMessageIF* receiverMessage): CommandMessageBase(receiverMessage) { @@ -50,23 +42,23 @@ CommandMessage::CommandMessage(MessageQueueMessageIF* messageToSet, uint32_t CommandMessage::getParameter() const { uint32_t parameter1; - memcpy(¶meter1, CommandMessageBase::getData(), sizeof(parameter1)); + std::memcpy(¶meter1, CommandMessageBase::getData(), sizeof(parameter1)); return parameter1; } void CommandMessage::setParameter(uint32_t parameter1) { - memcpy(CommandMessageBase::getData(), ¶meter1, sizeof(parameter1)); + std::memcpy(CommandMessageBase::getData(), ¶meter1, sizeof(parameter1)); } uint32_t CommandMessage::getParameter2() const { uint32_t parameter2; - memcpy(¶meter2, CommandMessageBase::getData() + sizeof(uint32_t), + std::memcpy(¶meter2, CommandMessageBase::getData() + sizeof(uint32_t), sizeof(parameter2)); return parameter2; } void CommandMessage::setParameter2(uint32_t parameter2) { - memcpy(CommandMessageBase::getData() + sizeof(uint32_t), ¶meter2, + std::memcpy(CommandMessageBase::getData() + sizeof(uint32_t), ¶meter2, sizeof(parameter2)); } @@ -84,60 +76,6 @@ bool CommandMessage::isClearedCommandMessage() { void CommandMessage::setToUnknownCommand() { Command_t initialCommand = getCommand(); - clearCommandMessage(); + this->clear(); setReplyRejected(UNKNOWN_COMMAND, initialCommand); } - -void CommandMessage::setReplyRejected(ReturnValue_t reason, - Command_t initialCommand) { - setCommand(REPLY_REJECTED); - setParameter(reason); - setParameter2(initialCommand); -} - -ReturnValue_t CommandMessage::getRejectedReplyReason( - Command_t* initialCommand) const { - if(initialCommand != nullptr) { - *initialCommand = getParameter2(); - } - return getParameter(); -} - -void CommandMessage::clear() { - clearCommandMessage(); -} - -void CommandMessage::clearCommandMessage() { - switch(this->getMessageType()){ - case messagetypes::MODE_COMMAND: - ModeMessage::clear(this); - break; - case messagetypes::HEALTH_COMMAND: - HealthMessage::clear(this); - break; - case messagetypes::MODE_SEQUENCE: - ModeSequenceMessage::clear(this); - break; - case messagetypes::ACTION: - ActionMessage::clear(this); - break; - case messagetypes::DEVICE_HANDLER_COMMAND: - DeviceHandlerMessage::clear(this); - break; - case messagetypes::MEMORY: - MemoryMessage::clear(this); - break; - case messagetypes::MONITORING: - MonitoringMessage::clear(this); - break; - case messagetypes::TM_STORE: - TmStoreMessage::clear(this); - break; - case messagetypes::PARAMETER: - ParameterMessage::clear(this); - break; - default: - messagetypes::clearMissionMessage(this); - break; - } -} diff --git a/ipc/CommandMessage.h b/ipc/CommandMessage.h index 8e1e9c8c..72f39357 100644 --- a/ipc/CommandMessage.h +++ b/ipc/CommandMessage.h @@ -5,11 +5,6 @@ #include #include -namespace messagetypes { -// Implemented in config. -void clearMissionMessage(CommandMessageIF* message); -} - /** * @brief Default command message used to pass command messages between tasks. * Primary message type for IPC. Contains sender, 2-byte command ID @@ -27,17 +22,6 @@ void clearMissionMessage(CommandMessageIF* message); */ class CommandMessage: public CommandMessageBase { public: - static const uint8_t INTERFACE_ID = CLASS_ID::COMMAND_MESSAGE; - static const ReturnValue_t UNKNOWN_COMMAND = MAKE_RETURN_CODE(0x01); - - static const uint8_t MESSAGE_ID = messagetypes::COMMAND; - //! Used internally, will be ignored - static const Command_t CMD_NONE = MAKE_COMMAND_ID( 0 ); - static const Command_t REPLY_COMMAND_OK = MAKE_COMMAND_ID( 3 ); - //! Reply indicating that the current command was rejected, - //! par1 should contain the error code - static const Command_t REPLY_REJECTED = MAKE_COMMAND_ID( 0xD1 ); - /** * This is the size of a message as it is seen by the MessageQueue. * 14 of the 24 available MessageQueueMessage bytes are used. @@ -98,18 +82,6 @@ public: */ void setParameter2(uint32_t parameter2); - void clear() override; - - /** - * Set the command to CMD_NONE and try to find the correct class to handle - * a more detailed clear. - * Also, calls a mission-specific clearMissionMessage function to separate - * between framework and mission messages. Not optimal, may be replaced by - * totally different auto-delete solution (e.g. smart pointers). - * - */ - void clearCommandMessage(); - /** * check if a message was cleared * @@ -122,11 +94,6 @@ public: * Is needed quite often, so we better code it once only. */ void setToUnknownCommand(); - - void setReplyRejected(ReturnValue_t reason, - Command_t initialCommand = CMD_NONE); - ReturnValue_t getRejectedReplyReason( - Command_t* initialCommand = nullptr) const; }; diff --git a/ipc/CommandMessageBase.cpp b/ipc/CommandMessageBase.cpp index 3ffe4daa..7085ab88 100644 --- a/ipc/CommandMessageBase.cpp +++ b/ipc/CommandMessageBase.cpp @@ -1,4 +1,5 @@ #include +#include #include CommandMessageBase::CommandMessageBase(MessageQueueMessageIF *message): @@ -57,3 +58,25 @@ size_t CommandMessageBase::getMessageSize() const { MessageQueueMessageIF* CommandMessageBase::getInternalMessage() const { return internalMessage; } + +void CommandMessageBase::setReplyRejected(ReturnValue_t reason, + Command_t initialCommand) { + std::memcpy(getData(), &reason, sizeof(reason)); + std::memcpy(getData() + sizeof(reason), &initialCommand, + sizeof(initialCommand)); +} + +ReturnValue_t CommandMessageBase::getReplyRejectedReason( + Command_t *initialCommand) const { + ReturnValue_t reason = HasReturnvaluesIF::RETURN_FAILED; + std::memcpy(&reason, getData(), sizeof(reason)); + if(initialCommand != nullptr) { + std::memcpy(initialCommand, getData() + sizeof(reason), + sizeof(Command_t)); + } + return reason; +} + +void CommandMessageBase::clear() { + CommandMessageCleaner::clearCommandMessage(this); +} diff --git a/ipc/CommandMessageBase.h b/ipc/CommandMessageBase.h index b2b7d5f2..d2f24c7e 100644 --- a/ipc/CommandMessageBase.h +++ b/ipc/CommandMessageBase.h @@ -22,9 +22,6 @@ */ class CommandMessageBase: public CommandMessageIF { public: - static constexpr size_t HEADER_SIZE = sizeof(MessageQueueId_t) + - sizeof(Command_t); - CommandMessageBase(MessageQueueMessageIF* message); /** @@ -61,7 +58,25 @@ public: virtual void setMessageSize(size_t messageSize) override; virtual size_t getMessageSize() const override; + /** + * A command message can be rejected and needs to offer a function + * to set a rejected reply + * @param reason + * @param initialCommand + */ + void setReplyRejected(ReturnValue_t reason, + Command_t initialCommand) override; + /** + * Corrensonding getter function. + * @param initialCommand + * @return + */ + ReturnValue_t getReplyRejectedReason( + Command_t* initialCommand = nullptr) const override; + virtual MessageQueueMessageIF* getInternalMessage() const override; + + virtual void clear() override; protected: /** * @brief Pointer to the message containing the data. diff --git a/ipc/CommandMessageCleaner.cpp b/ipc/CommandMessageCleaner.cpp new file mode 100644 index 00000000..7153a8e7 --- /dev/null +++ b/ipc/CommandMessageCleaner.cpp @@ -0,0 +1,45 @@ +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +void CommandMessageCleaner::clearCommandMessage(CommandMessageIF* message) { + switch(message->getMessageType()){ + case messagetypes::MODE_COMMAND: + ModeMessage::clear(dynamic_cast(message)); + break; + case messagetypes::HEALTH_COMMAND: + HealthMessage::clear(dynamic_cast(message)); + break; + case messagetypes::MODE_SEQUENCE: + ModeSequenceMessage::clear(dynamic_cast(message)); + break; + case messagetypes::ACTION: + ActionMessage::clear(dynamic_cast(message)); + break; + case messagetypes::DEVICE_HANDLER_COMMAND: + DeviceHandlerMessage::clear(dynamic_cast(message)); + break; + case messagetypes::MEMORY: + MemoryMessage::clear(dynamic_cast(message)); + break; + case messagetypes::MONITORING: + MonitoringMessage::clear(dynamic_cast(message)); + break; + case messagetypes::TM_STORE: + TmStoreMessage::clear(dynamic_cast(message)); + break; + case messagetypes::PARAMETER: + ParameterMessage::clear(dynamic_cast(message)); + break; + default: + messagetypes::clearMissionMessage(message); + break; + } +} diff --git a/ipc/CommandMessageCleaner.h b/ipc/CommandMessageCleaner.h new file mode 100644 index 00000000..0bd369a2 --- /dev/null +++ b/ipc/CommandMessageCleaner.h @@ -0,0 +1,16 @@ +#ifndef FRAMEWORK_IPC_COMMANDMESSAGECLEANER_H_ +#define FRAMEWORK_IPC_COMMANDMESSAGECLEANER_H_ +#include + +namespace messagetypes { +// Implemented in config. +void clearMissionMessage(CommandMessageIF* message); +} + +class CommandMessageCleaner { +public: + static void clearCommandMessage(CommandMessageIF* message); +}; + + +#endif /* FRAMEWORK_IPC_COMMANDMESSAGECLEANER_H_ */ diff --git a/ipc/CommandMessageIF.h b/ipc/CommandMessageIF.h index 44853c38..fbfbddbb 100644 --- a/ipc/CommandMessageIF.h +++ b/ipc/CommandMessageIF.h @@ -2,6 +2,9 @@ #define FRAMEWORK_IPC_COMMANDMESSAGEIF_H_ #include +#include +#include + #define MAKE_COMMAND_ID( number ) ((MESSAGE_ID << 8) + (number)) typedef uint16_t Command_t; @@ -14,6 +17,20 @@ typedef uint16_t Command_t; // we should just leave it like that. class CommandMessageIF: public MessageQueueMessageIF { public: + static constexpr size_t HEADER_SIZE = sizeof(MessageQueueId_t) + + sizeof(Command_t); + + static const uint8_t INTERFACE_ID = CLASS_ID::COMMAND_MESSAGE; + static const ReturnValue_t UNKNOWN_COMMAND = MAKE_RETURN_CODE(0x01); + + static const uint8_t MESSAGE_ID = messagetypes::COMMAND; + //! Used internally, shall be ignored + static const Command_t CMD_NONE = MAKE_COMMAND_ID( 0 ); + static const Command_t REPLY_COMMAND_OK = MAKE_COMMAND_ID( 1 ); + //! Reply indicating that the current command was rejected, + //! par1 should contain the error code + static const Command_t REPLY_REJECTED = MAKE_COMMAND_ID( 2 ); + virtual ~CommandMessageIF() {}; /** @@ -27,6 +44,22 @@ public: */ virtual uint8_t getMessageType() const = 0; + /** + * A command message can be rejected and needs to offer a function + * to set a rejected reply + * @param reason + * @param initialCommand + */ + virtual void setReplyRejected(ReturnValue_t reason, + Command_t initialCommand) = 0; + /** + * Corrensonding getter function. + * @param initialCommand + * @return + */ + virtual ReturnValue_t getReplyRejectedReason( + Command_t* initialCommand = nullptr) const = 0; + /** * This function is used to get a pointer to the internal message, as * the command message implementations always operate on the memory @@ -36,6 +69,7 @@ public: * @return */ virtual MessageQueueMessageIF* getInternalMessage() const = 0; + }; #endif /* FRAMEWORK_IPC_COMMANDMESSAGEIF_H_ */ diff --git a/memory/MemoryHelper.cpp b/memory/MemoryHelper.cpp index 2c384651..fb4d9eb6 100644 --- a/memory/MemoryHelper.cpp +++ b/memory/MemoryHelper.cpp @@ -119,7 +119,7 @@ void MemoryHelper::completeDump(ReturnValue_t errorCode, break; } if (queueToUse->sendMessage(lastSender, &reply) != RETURN_OK) { - reply.clearCommandMessage(); + reply.clear(); } } diff --git a/tmtcservices/CommandingServiceBase.cpp b/tmtcservices/CommandingServiceBase.cpp index 65053cc8..97856b40 100644 --- a/tmtcservices/CommandingServiceBase.cpp +++ b/tmtcservices/CommandingServiceBase.cpp @@ -94,7 +94,7 @@ void CommandingServiceBase::handleCommandQueue() { } -void CommandingServiceBase::handleCommandMessage(CommandMessage* reply) { +void CommandingServiceBase::handleCommandMessage(CommandMessageIF* reply) { bool isStep = false; MessageQueueMessage message; CommandMessage nextCommand(&message); @@ -119,7 +119,7 @@ void CommandingServiceBase::handleCommandMessage(CommandMessage* reply) { * command as failure parameter 1 */ if(reply->getCommand() == CommandMessage::REPLY_REJECTED and result == RETURN_FAILED) { - result = reply->getRejectedReplyReason( + result = reply->getReplyRejectedReason( reinterpret_cast(&failureParameter1)); } @@ -156,8 +156,8 @@ void CommandingServiceBase::handleCommandMessage(CommandMessage* reply) { } void CommandingServiceBase::handleReplyHandlerResult(ReturnValue_t result, - CommandMapIter iter, CommandMessage* nextCommand, CommandMessage* reply, - bool& isStep) { + CommandMapIter iter, CommandMessageIF* nextCommand, + CommandMessageIF* reply, bool& isStep) { iter->command = nextCommand->getCommand(); // In case a new command is to be sent immediately, this is performed here. @@ -186,14 +186,14 @@ void CommandingServiceBase::handleReplyHandlerResult(ReturnValue_t result, } else { if (isStep) { - nextCommand->clearCommandMessage(); + nextCommand->clear(); verificationReporter.sendFailureReport( TC_VERIFY::PROGRESS_FAILURE, iter->tcInfo.ackFlags, iter->tcInfo.tcPacketId, iter->tcInfo.tcSequenceControl, sendResult, ++iter->step, failureParameter1, failureParameter2); } else { - nextCommand->clearCommandMessage(); + nextCommand->clear(); verificationReporter.sendFailureReport( TC_VERIFY::COMPLETION_FAILURE, iter->tcInfo.ackFlags, iter->tcInfo.tcPacketId, @@ -329,7 +329,7 @@ void CommandingServiceBase::startExecution(TcPacketStored *storedPacket, storedPacket->getPacketSequenceControl(); acceptPacket(TC_VERIFY::START_SUCCESS, storedPacket); } else { - command.clearCommandMessage(); + command.clear(); rejectPacket(TC_VERIFY::START_FAILURE, storedPacket, sendResult); checkAndExecuteFifo(iter); } @@ -346,7 +346,7 @@ void CommandingServiceBase::startExecution(TcPacketStored *storedPacket, acceptPacket(TC_VERIFY::COMPLETION_SUCCESS, storedPacket); checkAndExecuteFifo(iter); } else { - command.clearCommandMessage(); + command.clear(); rejectPacket(TC_VERIFY::START_FAILURE, storedPacket, sendResult); checkAndExecuteFifo(iter); } diff --git a/tmtcservices/CommandingServiceBase.h b/tmtcservices/CommandingServiceBase.h index 5adfe4a6..5e2c3171 100644 --- a/tmtcservices/CommandingServiceBase.h +++ b/tmtcservices/CommandingServiceBase.h @@ -141,7 +141,7 @@ protected: * @param objectId Target object ID * @return */ - virtual ReturnValue_t prepareCommand(CommandMessage *message, + virtual ReturnValue_t prepareCommand(CommandMessageIF *message, uint8_t subservice, const uint8_t *tcData, size_t tcDataLen, uint32_t *state, object_id_t objectId) = 0; @@ -172,7 +172,7 @@ protected: */ virtual ReturnValue_t handleReply(const CommandMessageIF *reply, Command_t previousCommand, uint32_t *state, - CommandMessage *optionalNextCommand, object_id_t objectId, + CommandMessageIF *optionalNextCommand, object_id_t objectId, bool *isStep) = 0; /** @@ -312,9 +312,9 @@ private: void startExecution(TcPacketStored *storedPacket, CommandMapIter iter); - void handleCommandMessage(CommandMessage* reply); + void handleCommandMessage(CommandMessageIF* reply); void handleReplyHandlerResult(ReturnValue_t result, CommandMapIter iter, - CommandMessage* nextCommand,CommandMessage* reply, bool& isStep); + CommandMessageIF* nextCommand,CommandMessageIF* reply, bool& isStep); void checkTimeout(); }; From 9f69191f234d84e8d73b6ceeeabac3699466aaea Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 14 Jun 2020 17:59:14 +0200 Subject: [PATCH 136/307] optimized command messages a bit --- ipc/CommandMessage.cpp | 4 ---- ipc/CommandMessage.h | 6 ++---- ipc/CommandMessageBase.cpp | 8 ++++++++ ipc/CommandMessageBase.h | 16 +++++++++++++++- 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/ipc/CommandMessage.cpp b/ipc/CommandMessage.cpp index 39290688..64d4d41c 100644 --- a/ipc/CommandMessage.cpp +++ b/ipc/CommandMessage.cpp @@ -66,10 +66,6 @@ size_t CommandMessage::getMinimumMessageSize() const { return MINIMUM_COMMAND_MESSAGE_SIZE; } -size_t CommandMessage::getMaximumMessageSize() const { - return MessageQueueMessage::MAX_MESSAGE_SIZE; -} - bool CommandMessage::isClearedCommandMessage() { return getCommand() == CMD_NONE; } diff --git a/ipc/CommandMessage.h b/ipc/CommandMessage.h index 72f39357..a09494c6 100644 --- a/ipc/CommandMessage.h +++ b/ipc/CommandMessage.h @@ -24,11 +24,11 @@ class CommandMessage: public CommandMessageBase { public: /** * This is the size of a message as it is seen by the MessageQueue. + * It can hold the CommandMessage header plus 2 4-byte parameters. * 14 of the 24 available MessageQueueMessage bytes are used. */ static const size_t MINIMUM_COMMAND_MESSAGE_SIZE = - MessageQueueMessage::HEADER_SIZE + sizeof(Command_t) + - 2 * sizeof(uint32_t); + CommandMessageIF::HEADER_SIZE + 2 * sizeof(uint32_t); /** * Default Constructor, does not initialize anything. @@ -55,8 +55,6 @@ public: /** MessageQueueMessageIF functions used for minimum size check. */ size_t getMinimumMessageSize() const override; - /** MessageQueueMessageIF functions used for maximum size check. */ - size_t getMaximumMessageSize() const override; /** * Get the first parameter of the message diff --git a/ipc/CommandMessageBase.cpp b/ipc/CommandMessageBase.cpp index 7085ab88..80f9d378 100644 --- a/ipc/CommandMessageBase.cpp +++ b/ipc/CommandMessageBase.cpp @@ -55,10 +55,18 @@ size_t CommandMessageBase::getMessageSize() const { return internalMessage->getMessageSize(); } +size_t CommandMessageBase::getMaximumMessageSize() const { + return internalMessage->getMaximumMessageSize(); +} + MessageQueueMessageIF* CommandMessageBase::getInternalMessage() const { return internalMessage; } +size_t CommandMessageBase::getMinimumMessageSize() const { + return MINIMUM_COMMAND_MESSAGE_BASE_SIZE; +} + void CommandMessageBase::setReplyRejected(ReturnValue_t reason, Command_t initialCommand) { std::memcpy(getData(), &reason, sizeof(reason)); diff --git a/ipc/CommandMessageBase.h b/ipc/CommandMessageBase.h index d2f24c7e..b237b68f 100644 --- a/ipc/CommandMessageBase.h +++ b/ipc/CommandMessageBase.h @@ -15,13 +15,21 @@ * size checks: * * 1. getMinimumMessageSize() - * 2. getMaximumMessageSize() * + * The maximum message size generally depends on the buffer size of the passed + * internal message. * Don't forget to set the message size of the passed message in the concrete * commandmessage implementation! */ class CommandMessageBase: public CommandMessageIF { public: + //! This minimum size is derived from the interface requirement to be able + //! to set a rejected reply, which contains a returnvalue and the initial + //! command. + static constexpr size_t MINIMUM_COMMAND_MESSAGE_BASE_SIZE = + CommandMessageIF::HEADER_SIZE + sizeof(ReturnValue_t) + + sizeof(Command_t); + CommandMessageBase(MessageQueueMessageIF* message); /** @@ -58,6 +66,12 @@ public: virtual void setMessageSize(size_t messageSize) override; virtual size_t getMessageSize() const override; + //! This depends on the maximum message size of the passed internal message. + virtual size_t getMaximumMessageSize() const override; + + //! Return the constant minimum message size. + virtual size_t getMinimumMessageSize() const override; + /** * A command message can be rejected and needs to offer a function * to set a rejected reply From 6ecf1cf534b1eaf45be731263a241b629fa3d937 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 14 Jun 2020 19:03:28 +0200 Subject: [PATCH 137/307] hk message continued --- housekeeping/HousekeepingMessage.cpp | 57 +++++++++++++++++++++------- housekeeping/HousekeepingMessage.h | 28 ++++++++++---- 2 files changed, 64 insertions(+), 21 deletions(-) diff --git a/housekeeping/HousekeepingMessage.cpp b/housekeeping/HousekeepingMessage.cpp index 6dd1a711..d47fb92a 100644 --- a/housekeeping/HousekeepingMessage.cpp +++ b/housekeeping/HousekeepingMessage.cpp @@ -3,9 +3,25 @@ HousekeepingMessage::HousekeepingMessage(MessageQueueMessageIF* message): CommandMessageBase(message) { + if(message->getMaximumMessageSize() < HK_MESSAGE_SIZE) { + sif::error << "CommandMessage::ComandMessage: Passed message buffer" + " can not hold minimum "<< HK_MESSAGE_SIZE + << " bytes!" << std::endl; + return; + } + message->setMessageSize(HK_MESSAGE_SIZE); } -HousekeepingMessage::~HousekeepingMessage() { +HousekeepingMessage::~HousekeepingMessage() {} + +void HousekeepingMessage::setParameter(uint32_t parameter) { + std::memcpy(getData(), ¶meter, sizeof(parameter)); +} + +uint32_t HousekeepingMessage::getParameter() const { + uint32_t parameter; + std::memcpy(¶meter, getData(), sizeof(parameter)); + return parameter; } void HousekeepingMessage::setHkReportMessage(sid_t sid, @@ -15,32 +31,45 @@ void HousekeepingMessage::setHkReportMessage(sid_t sid, setParameter(storeId.raw); } +void HousekeepingMessage::setHkDiagnosticsMessage(sid_t sid, + store_address_t storeId) { + CommandMessageBase::setCommand(DIAGNOSTICS_REPORT); + setSid(sid); + setParameter(storeId.raw); +} + size_t HousekeepingMessage::getMinimumMessageSize() const { return HK_MESSAGE_SIZE; } -size_t HousekeepingMessage::getMaximumMessageSize() const { - return MessageQueueMessage::MAX_MESSAGE_SIZE; -} - -void HousekeepingMessage::clear() { - // clear IPC store where it is needed. -} - sid_t HousekeepingMessage::getSid() const { sid_t sid; std::memcpy(&sid.raw, CommandMessageBase::getData(), sizeof(sid.raw)); return sid; } -uint8_t* HousekeepingMessage::getData() { - return internalMessage->getBuffer() + sizeof(sid_t); -} -void HousekeepingMessage::setParameter(uint32_t parameter) { - memcpy(getData(), ¶meter, sizeof(parameter)); +sid_t HousekeepingMessage::getHkReportMessage( + store_address_t *storeIdToSet) const { + if(storeIdToSet != nullptr) { + *storeIdToSet = getParameter(); + } + return getSid(); } void HousekeepingMessage::setSid(sid_t sid) { std::memcpy(CommandMessageBase::getData(), &sid.raw, sizeof(sid.raw)); } + + +uint8_t* HousekeepingMessage::getData() { + return CommandMessageBase::getData() + sizeof(sid_t); +} + +const uint8_t* HousekeepingMessage::getData() const { + return CommandMessageBase::getData() + sizeof(sid_t); +} + +void HousekeepingMessage::clear() { + // clear IPC store where it is needed. +} diff --git a/housekeeping/HousekeepingMessage.h b/housekeeping/HousekeepingMessage.h index 4e9d4553..c5e31fda 100644 --- a/housekeeping/HousekeepingMessage.h +++ b/housekeeping/HousekeepingMessage.h @@ -27,14 +27,22 @@ union sid_t { }; +/** + * @brief Special command message type for housekeeping messages + * @details + * This message is slightly larger than regular command messages to accomodate + * the uint64_t structure ID (SID). + */ class HousekeepingMessage : public CommandMessageBase { public: static constexpr size_t HK_MESSAGE_SIZE = sizeof(MessageQueueId_t) + sizeof(Command_t) + sizeof(sid_t) * sizeof(uint32_t); + /** - * No instances of a message shall be created, instead - * a CommandMessage instance is manipulated. + * The HK message is initialized with a pointer to a message which holds + * the message data, see CommandMessageIF and getInternalMessage(). + * @param message */ HousekeepingMessage(MessageQueueMessageIF* message); virtual ~HousekeepingMessage(); @@ -85,18 +93,24 @@ public: static constexpr Command_t MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL = MAKE_COMMAND_ID(32); - void setHkReportMessage(sid_t sid, store_address_t storeId); void setParameter(uint32_t parameter); + uint32_t getParameter() const; + + void setHkReportMessage(sid_t sid, store_address_t storeId); + void setHkDiagnosticsMessage(sid_t sid, store_address_t storeId); + //! Get the respective SID and store ID. Command ID can be used beforehand + //! to distinguish between diagnostics and regular HK packets + sid_t getHkReportMessage(store_address_t * storeIdToSet) const; - virtual void clear() override; virtual size_t getMinimumMessageSize() const override; - virtual size_t getMaximumMessageSize() const override; - - virtual uint8_t* getData() override; + virtual void clear() override; private: sid_t getSid() const; void setSid(sid_t sid); + + virtual uint8_t* getData() override; + virtual const uint8_t* getData() const override; }; From c9d8bd59f0120dca352352dab737d39c43896131 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 15 Jun 2020 11:11:42 +0200 Subject: [PATCH 138/307] ctor improved --- ipc/CommandMessage.cpp | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/ipc/CommandMessage.cpp b/ipc/CommandMessage.cpp index 64d4d41c..163a6a2d 100644 --- a/ipc/CommandMessage.cpp +++ b/ipc/CommandMessage.cpp @@ -10,31 +10,18 @@ CommandMessage::CommandMessage(MessageQueueMessageIF* receiverMessage): return; } if(receiverMessage->getMaximumMessageSize() < - MINIMUM_COMMAND_MESSAGE_SIZE) { + getMinimumMessageSize()) { sif::error << "CommandMessage::ComandMessage: Passed message buffer" " can not hold minimum "<< MINIMUM_COMMAND_MESSAGE_SIZE << " bytes!" << std::endl; return; } - internalMessage->setMessageSize(MINIMUM_COMMAND_MESSAGE_SIZE); + internalMessage->setMessageSize(getMinimumMessageSize()); } CommandMessage::CommandMessage(MessageQueueMessageIF* messageToSet, Command_t command, uint32_t parameter1, uint32_t parameter2): - CommandMessageBase(messageToSet) { - if(messageToSet == nullptr) { - sif::error << "CommandMessage::CommandMessage: Don't pass a nullptr" - " as the message queue message, pass the address of an actual" - " message!" << std::endl; - } - if(messageToSet->getMaximumMessageSize() < - MINIMUM_COMMAND_MESSAGE_SIZE) { - sif::error << "CommandMessage::ComandMessage: Passed message buffer" - " can not hold minimum "<< MINIMUM_COMMAND_MESSAGE_SIZE - << " bytes!" << std::endl; - return; - } - internalMessage->setMessageSize(MINIMUM_COMMAND_MESSAGE_SIZE); + CommandMessage(messageToSet) { setCommand(command); setParameter(parameter1); setParameter2(parameter2); From e39d5689e537be8ae3595383005d62e656ad554d Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 15 Jun 2020 16:56:22 +0200 Subject: [PATCH 139/307] device com IF formattign --- devicehandlers/DeviceCommunicationIF.h | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/devicehandlers/DeviceCommunicationIF.h b/devicehandlers/DeviceCommunicationIF.h index bb095116..20565025 100644 --- a/devicehandlers/DeviceCommunicationIF.h +++ b/devicehandlers/DeviceCommunicationIF.h @@ -1,5 +1,5 @@ -#ifndef DEVICECOMMUNICATIONIF_H_ -#define DEVICECOMMUNICATIONIF_H_ +#ifndef FRAMEWORK_DEVICES_DEVICECOMMUNICATIONIF_H_ +#define FRAMEWORK_DEVICES_DEVICECOMMUNICATIONIF_H_ #include #include @@ -19,8 +19,8 @@ * the device handler to allow reuse of these components. * @details * Documentation: Dissertation Baetz p.138. - * It works with the assumption that received data - * is polled by a component. There are four generic steps of device communication: + * It works with the assumption that received data is polled by a component. + * There are four generic steps of device communication: * * 1. Send data to a device * 2. Get acknowledgement for sending @@ -77,8 +77,8 @@ public: * - @c RETURN_OK for successfull send * - Everything else triggers failure event with returnvalue as parameter 1 */ - virtual ReturnValue_t sendMessage(CookieIF *cookie, const uint8_t * sendData, - size_t sendLen) = 0; + virtual ReturnValue_t sendMessage(CookieIF *cookie, + const uint8_t * sendData, size_t sendLen) = 0; /** * Called by DHB in the GET_WRITE doGetWrite(). @@ -103,7 +103,8 @@ public: * - Everything else triggers failure event with * returnvalue as parameter 1 */ - virtual ReturnValue_t requestReceiveMessage(CookieIF *cookie, size_t requestLen) = 0; + virtual ReturnValue_t requestReceiveMessage(CookieIF *cookie, + size_t requestLen) = 0; /** * Called by DHB in the GET_WRITE doGetRead(). @@ -119,8 +120,8 @@ public: * - Everything else triggers failure event with * returnvalue as parameter 1 */ - virtual ReturnValue_t readReceivedMessage(CookieIF *cookie, uint8_t **buffer, - size_t *size) = 0; + virtual ReturnValue_t readReceivedMessage(CookieIF *cookie, + uint8_t **buffer, size_t *size) = 0; }; #endif /* DEVICECOMMUNICATIONIF_H_ */ From 7871ee7ca810bc49380b3362b3d0c9e1c0e49e0d Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 15 Jun 2020 17:39:52 +0200 Subject: [PATCH 140/307] mutex helper little formatting correction --- ipc/MutexHelper.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ipc/MutexHelper.h b/ipc/MutexHelper.h index 20760b32..c9579e9b 100644 --- a/ipc/MutexHelper.h +++ b/ipc/MutexHelper.h @@ -10,7 +10,7 @@ public: internalMutex(mutex) { ReturnValue_t status = mutex->lockMutex(timeoutMs); if(status == MutexIF::MUTEX_TIMEOUT) { - sif::error << "MutexHelper: Lock of mutex failed with timeout of" + sif::error << "MutexHelper: Lock of mutex failed with timeout of " << timeoutMs << " milliseconds!" << std::endl; } else if(status != HasReturnvaluesIF::RETURN_OK){ From 813e82415affa80420751065d83454ae88d47262 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 16 Jun 2020 11:03:24 +0200 Subject: [PATCH 141/307] additional doc info --- devicehandlers/DeviceCommunicationIF.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devicehandlers/DeviceCommunicationIF.h b/devicehandlers/DeviceCommunicationIF.h index 20565025..a2662d46 100644 --- a/devicehandlers/DeviceCommunicationIF.h +++ b/devicehandlers/DeviceCommunicationIF.h @@ -72,7 +72,7 @@ public: * by implementing and calling related drivers or wrapper functions. * @param cookie * @param data - * @param len + * @param len If this is 0, nothing shall be sent. * @return * - @c RETURN_OK for successfull send * - Everything else triggers failure event with returnvalue as parameter 1 From 38676308e332ead072d35238c95953b7e64abaec Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 17 Jun 2020 19:37:55 +0200 Subject: [PATCH 142/307] improved array list a bit --- container/ArrayList.h | 176 ++++++++++++++++++++---------------------- 1 file changed, 84 insertions(+), 92 deletions(-) diff --git a/container/ArrayList.h b/container/ArrayList.h index a37a1c42..8138864b 100644 --- a/container/ArrayList.h +++ b/container/ArrayList.h @@ -1,5 +1,5 @@ -#ifndef ARRAYLIST_H_ -#define ARRAYLIST_H_ +#ifndef FRAMEWORK_CONTAINER_ARRAYLIST_H_ +#define FRAMEWORK_CONTAINER_ARRAYLIST_H_ #include #include @@ -7,8 +7,9 @@ /** * @brief A List that stores its values in an array. - * @details The backend is an array that can be allocated - * by the class itself or supplied via ctor. + * @details + * The underlying storage is an array that can be allocated by the class + * itself or supplied via ctor. * * @ingroup container */ @@ -19,81 +20,13 @@ public: static const uint8_t INTERFACE_ID = CLASS_ID::ARRAY_LIST; static const ReturnValue_t FULL = MAKE_RETURN_CODE(0x01); - /** - * An Iterator to go trough an ArrayList - * - * It stores a pointer to an element and increments the - * pointer when incremented itself. - */ - class Iterator { - public: - /** - * Empty ctor, points to NULL - */ - Iterator() : - value(0) { - - } - - /** - * Initializes the Iterator to point to an element - * - * @param initialize - */ - Iterator(T *initialize) { - value = initialize; - } - - /** - * The current element the iterator points to - */ - T *value; - - Iterator& operator++() { - value++; - return *this; - } - - Iterator operator++(int) { - Iterator tmp(*this); - operator++(); - return tmp; - } - - Iterator& operator--() { - value--; - return *this; - } - - Iterator operator--(int) { - Iterator tmp(*this); - operator--(); - return tmp; - } - - T operator*() { - return *value; - } - - T *operator->() { - return value; - } - - const T *operator->() const{ - return value; - } - - //SHOULDDO this should be implemented as non-member - bool operator==(const typename ArrayList::Iterator& other) const{ - return (value == other.value); - } - - //SHOULDDO this should be implemented as non-member - bool operator!=(const typename ArrayList::Iterator& other) const { - return !(*this == other); - } - } - ; + /** + * Copying is forbiden by declaring copy ctor and copy assignment deleted + * It is too ambigous in this case. + * (Allocate a new backend? Use the same? What to do in an modifying call?) + */ + ArrayList(const ArrayList& other) = delete; + const ArrayList& operator=(const ArrayList& other) = delete; /** * Number of Elements stored in this List @@ -134,6 +67,78 @@ public: } } + /** + * An Iterator to go trough an ArrayList + * + * It stores a pointer to an element and increments the + * pointer when incremented itself. + */ + class Iterator { + public: + /** + * Empty ctor, points to NULL + */ + Iterator(): value(0) {} + + /** + * Initializes the Iterator to point to an element + * + * @param initialize + */ + Iterator(T *initialize) { + value = initialize; + } + + /** + * The current element the iterator points to + */ + T *value; + + Iterator& operator++() { + value++; + return *this; + } + + Iterator operator++(int) { + Iterator tmp(*this); + operator++(); + return tmp; + } + + Iterator& operator--() { + value--; + return *this; + } + + Iterator operator--(int) { + Iterator tmp(*this); + operator--(); + return tmp; + } + + T operator*() { + return *value; + } + + T *operator->() { + return value; + } + + const T *operator->() const{ + return value; + } + + //SHOULDDO this should be implemented as non-member + bool operator==(const typename ArrayList::Iterator& other) const{ + return (value == other.value); + } + + //SHOULDDO this should be implemented as non-member + bool operator!=(const typename ArrayList::Iterator& other) const { + return !(*this == other); + } + }; + /** * Iterator pointing to the first stored elmement * @@ -223,19 +228,6 @@ public: return (maxSize_ - size); } -private: - /** - * This is the copy constructor - * - * It is private, as copying is too ambigous in this case. (Allocate a new backend? Use the same? - * What to do in an modifying call?) - * - * @param other - */ - ArrayList(const ArrayList& other) : - size(other.size), entries(other.entries), maxSize_(other.maxSize_), - allocated(false) {} - protected: /** * pointer to the array in which the entries are stored From f8f10a173033b71d0bb4916cf89243327c0c2921 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 17 Jun 2020 19:41:10 +0200 Subject: [PATCH 143/307] slight hybrid iter improvements --- container/HybridIterator.h | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/container/HybridIterator.h b/container/HybridIterator.h index 1c56aa13..db1ce4bc 100644 --- a/container/HybridIterator.h +++ b/container/HybridIterator.h @@ -8,13 +8,11 @@ template class HybridIterator: public LinkedElement::Iterator, public ArrayList::Iterator { public: - HybridIterator() : - value(NULL), linked(NULL), end(NULL) { - } + HybridIterator() {} HybridIterator(typename LinkedElement::Iterator *iter) : - LinkedElement::Iterator(*iter), value( - iter->value), linked(true), end(NULL) { + LinkedElement::Iterator(*iter), value(iter->value), + linked(true) { } @@ -66,11 +64,11 @@ public: return tmp; } - bool operator==(HybridIterator other) { + bool operator==(const HybridIterator& other) { return value == other.value; } - bool operator!=(HybridIterator other) { + bool operator!=(const HybridIterator& other) { return !(*this == other); } @@ -82,11 +80,11 @@ public: return value; } - T* value; + T* value = nullptr; private: - bool linked; - T *end; + bool linked = false; + T *end = nullptr; }; #endif /* HYBRIDITERATOR_H_ */ From b68ad9e4f9182f8e216e69b34d58138e4044494f Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 17 Jun 2020 19:50:26 +0200 Subject: [PATCH 144/307] new ctor for simple ring buffer which does not allocate --- container/RingBufferBase.h | 8 +++++--- container/SimpleRingBuffer.cpp | 12 +++++++++--- container/SimpleRingBuffer.h | 30 ++++++++++++++++++++++++------ 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/container/RingBufferBase.h b/container/RingBufferBase.h index 3ef782d8..1beb51c2 100644 --- a/container/RingBufferBase.h +++ b/container/RingBufferBase.h @@ -2,12 +2,14 @@ #define FRAMEWORK_CONTAINER_RINGBUFFERBASE_H_ #include +#include template class RingBufferBase { public: - RingBufferBase(uint32_t startAddress, uint32_t size, bool overwriteOld) : - start(startAddress), write(startAddress), size(size), overwriteOld(overwriteOld) { + RingBufferBase(uint32_t startAddress, const size_t size, bool overwriteOld) : + start(startAddress), write(startAddress), size(size), + overwriteOld(overwriteOld) { for (uint8_t count = 0; count < N_READ_PTRS; count++) { read[count] = startAddress; } @@ -83,7 +85,7 @@ protected: const uint32_t start; uint32_t write; uint32_t read[N_READ_PTRS]; - const uint32_t size; + const size_t size; const bool overwriteOld; void incrementWrite(uint32_t amount) { write = ((write + amount - start) % size) + start; diff --git a/container/SimpleRingBuffer.cpp b/container/SimpleRingBuffer.cpp index 63dc3514..4e50109b 100644 --- a/container/SimpleRingBuffer.cpp +++ b/container/SimpleRingBuffer.cpp @@ -1,11 +1,16 @@ #include -#include +#include -SimpleRingBuffer::SimpleRingBuffer(uint32_t size, bool overwriteOld) : - RingBufferBase<>(0, size, overwriteOld), buffer(NULL) { +SimpleRingBuffer::SimpleRingBuffer(const size_t size, bool overwriteOld) : + RingBufferBase<>(0, size, overwriteOld) { buffer = new uint8_t[size]; } +SimpleRingBuffer::SimpleRingBuffer(uint8_t *buffer, const size_t size, + bool overwriteOld): + RingBufferBase<>(0, size, overwriteOld), buffer(buffer) {} + + SimpleRingBuffer::~SimpleRingBuffer() { delete[] buffer; } @@ -66,3 +71,4 @@ ReturnValue_t SimpleRingBuffer::deleteData(uint32_t amount, incrementRead(amount, READ_PTR); return HasReturnvaluesIF::RETURN_OK; } + diff --git a/container/SimpleRingBuffer.h b/container/SimpleRingBuffer.h index 4552a1c0..b5bc2c1c 100644 --- a/container/SimpleRingBuffer.h +++ b/container/SimpleRingBuffer.h @@ -5,13 +5,29 @@ #include /** - * @brief Circular buffer implementation, useful for buffering into data streams. - * @details Note that the deleteData() has to be called to increment the read pointer + * @brief Circular buffer implementation, useful for buffering + * into data streams. + * @details + * Note that the deleteData() has to be called to increment the read pointer. + * This class allocated dynamically, so * @ingroup containers */ class SimpleRingBuffer: public RingBufferBase<> { public: - SimpleRingBuffer(uint32_t size, bool overwriteOld); + /** + * This constructor allocates a new internal buffer with the supplied size. + * @param size + * @param overwriteOld + */ + SimpleRingBuffer(const size_t size, bool overwriteOld); + /** + * This constructor takes an external buffer with the specified size. + * @param buffer + * @param size + * @param overwriteOld + */ + SimpleRingBuffer(uint8_t* buffer, const size_t size, bool overwriteOld); + virtual ~SimpleRingBuffer(); /** @@ -30,7 +46,8 @@ public: * @param trueAmount * @return */ - ReturnValue_t readData(uint8_t* data, uint32_t amount, bool readRemaining = false, uint32_t* trueAmount = NULL); + ReturnValue_t readData(uint8_t* data, uint32_t amount, + bool readRemaining = false, uint32_t* trueAmount = nullptr); /** * Delete data starting by incrementing read pointer @@ -39,11 +56,12 @@ public: * @param trueAmount * @return */ - ReturnValue_t deleteData(uint32_t amount, bool deleteRemaining = false, uint32_t* trueAmount = NULL); + ReturnValue_t deleteData(uint32_t amount, bool deleteRemaining = false, + uint32_t* trueAmount = nullptr); private: // static const uint8_t TEMP_READ_PTR = 1; static const uint8_t READ_PTR = 0; - uint8_t* buffer; + uint8_t* buffer = nullptr; }; #endif /* FRAMEWORK_CONTAINER_SIMPLERINGBUFFER_H_ */ From d5ae74f86073c2f9847f4abbd9ed921cdb5ae094 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 17 Jun 2020 20:21:49 +0200 Subject: [PATCH 145/307] bugfix hk message size --- housekeeping/HousekeepingMessage.cpp | 4 ++-- housekeeping/HousekeepingMessage.h | 4 ++-- ipc/CommandMessage.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/housekeeping/HousekeepingMessage.cpp b/housekeeping/HousekeepingMessage.cpp index d47fb92a..d7efd703 100644 --- a/housekeeping/HousekeepingMessage.cpp +++ b/housekeeping/HousekeepingMessage.cpp @@ -4,8 +4,8 @@ HousekeepingMessage::HousekeepingMessage(MessageQueueMessageIF* message): CommandMessageBase(message) { if(message->getMaximumMessageSize() < HK_MESSAGE_SIZE) { - sif::error << "CommandMessage::ComandMessage: Passed message buffer" - " can not hold minimum "<< HK_MESSAGE_SIZE + sif::error << "HousekeepingMessage::HousekeepingMessage: Passed " + "message buffer can not hold minimum " << HK_MESSAGE_SIZE << " bytes!" << std::endl; return; } diff --git a/housekeeping/HousekeepingMessage.h b/housekeeping/HousekeepingMessage.h index c5e31fda..75afc8ea 100644 --- a/housekeeping/HousekeepingMessage.h +++ b/housekeeping/HousekeepingMessage.h @@ -36,8 +36,8 @@ union sid_t { class HousekeepingMessage : public CommandMessageBase { public: - static constexpr size_t HK_MESSAGE_SIZE = sizeof(MessageQueueId_t) - + sizeof(Command_t) + sizeof(sid_t) * sizeof(uint32_t); + static constexpr size_t HK_MESSAGE_SIZE = CommandMessageIF::HEADER_SIZE + + sizeof(sid_t) + sizeof(uint32_t); /** * The HK message is initialized with a pointer to a message which holds diff --git a/ipc/CommandMessage.cpp b/ipc/CommandMessage.cpp index 163a6a2d..9a8a82f2 100644 --- a/ipc/CommandMessage.cpp +++ b/ipc/CommandMessage.cpp @@ -12,7 +12,7 @@ CommandMessage::CommandMessage(MessageQueueMessageIF* receiverMessage): if(receiverMessage->getMaximumMessageSize() < getMinimumMessageSize()) { sif::error << "CommandMessage::ComandMessage: Passed message buffer" - " can not hold minimum "<< MINIMUM_COMMAND_MESSAGE_SIZE + " can not hold minimum "<< getMinimumMessageSize() << " bytes!" << std::endl; return; } From 259517ac9ba0cc51e61980883467374b3ed849f5 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 17 Jun 2020 20:22:09 +0200 Subject: [PATCH 146/307] single linked list improvement --- container/SinglyLinkedList.h | 46 ++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/container/SinglyLinkedList.h b/container/SinglyLinkedList.h index 54e7687c..ed466086 100644 --- a/container/SinglyLinkedList.h +++ b/container/SinglyLinkedList.h @@ -1,8 +1,9 @@ -#ifndef SINGLYLINKEDLIST_H_ -#define SINGLYLINKEDLIST_H_ +#ifndef FRAMEWORK_CONTAINER_SINGLYLINKEDLIST_H_ +#define FRAMEWORK_CONTAINER_SINGLYLINKEDLIST_H_ + +#include +#include -#include -#include /** * @brief Linked list data structure, * each entry has a pointer to the next entry (singly) @@ -47,12 +48,11 @@ public: } }; - LinkedElement(T* setElement, LinkedElement* setNext = NULL) : value(setElement), - next(setNext) { - } - virtual ~LinkedElement(){ + LinkedElement(T* setElement, LinkedElement* setNext = nullptr): + value(setElement), next(setNext) {} + + virtual ~LinkedElement(){} - } virtual LinkedElement* getNext() const { return next; } @@ -69,7 +69,7 @@ public: return this; } LinkedElement* end() { - return NULL; + return nullptr; } private: LinkedElement *next; @@ -78,21 +78,21 @@ private: template class SinglyLinkedList { public: - SinglyLinkedList() : - start(NULL) { - } + using ElementIterator = typename LinkedElement::Iterator; + + SinglyLinkedList() {} + + SinglyLinkedList(ElementIterator start) : + start(start.value) {} - SinglyLinkedList(typename LinkedElement::Iterator start) : - start(start.value) { - } SinglyLinkedList(LinkedElement* startElement) : - start(startElement) { - } - typename LinkedElement::Iterator begin() const { - return LinkedElement::Iterator::Iterator(start); + start(startElement) {} + + ElementIterator begin() const { + return ElementIterator::Iterator(start); } - typename LinkedElement::Iterator::Iterator end() const { - return LinkedElement::Iterator::Iterator(); + typename ElementIterator::Iterator end() const { + return ElementIterator::Iterator(); } uint32_t getSize() const { @@ -108,7 +108,7 @@ public: start = setStart; } protected: - LinkedElement *start; + LinkedElement *start = nullptr; }; #endif /* SINGLYLINKEDLIST_H_ */ From bb16fd80b8d60813f0605737e2cdd47d729effbf Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 17 Jun 2020 20:37:45 +0200 Subject: [PATCH 147/307] singly linked list improvements --- container/SinglyLinkedList.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/container/SinglyLinkedList.h b/container/SinglyLinkedList.h index ed466086..7fffdaac 100644 --- a/container/SinglyLinkedList.h +++ b/container/SinglyLinkedList.h @@ -61,8 +61,8 @@ public: this->next = next; } - void setEnd() { - this->next = nullptr; + virtual void setEnd() { + this->next = nullptr; } LinkedElement* begin() { @@ -107,6 +107,11 @@ public: void setStart(LinkedElement* setStart) { start = setStart; } + + void setEnd(LinkedElement* setEnd) { + setEnd->setEnd(); + } + protected: LinkedElement *start = nullptr; }; From ed26992d7f1decf404e04d39477836381ec5635b Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 17 Jun 2020 20:40:40 +0200 Subject: [PATCH 148/307] shoulddo added --- container/SinglyLinkedList.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/container/SinglyLinkedList.h b/container/SinglyLinkedList.h index 7fffdaac..79562cd4 100644 --- a/container/SinglyLinkedList.h +++ b/container/SinglyLinkedList.h @@ -112,6 +112,8 @@ public: setEnd->setEnd(); } + // SHOULDDO: Insertion operation ? + protected: LinkedElement *start = nullptr; }; From 583efec3f8d93efab38c792a9f264f29b0bc01c2 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 17 Jun 2020 20:45:44 +0200 Subject: [PATCH 149/307] nullptr --- container/SinglyLinkedList.h | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/container/SinglyLinkedList.h b/container/SinglyLinkedList.h index 79562cd4..3c0078fc 100644 --- a/container/SinglyLinkedList.h +++ b/container/SinglyLinkedList.h @@ -15,11 +15,8 @@ public: T *value; class Iterator { public: - LinkedElement *value; - Iterator() : - value(NULL) { - - } + LinkedElement *value = nullptr; + Iterator() {} Iterator(LinkedElement *element) : value(element) { From 84b8d733c0065280fbb1e39d81bcb8f20fc1ddb7 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 19 Jun 2020 03:03:17 +0200 Subject: [PATCH 150/307] hk continued --- datapool/DataSetBase.h | 2 +- datapoollocal/LocalDataPoolManager.cpp | 96 +++++++++++++++++++------- datapoollocal/LocalDataPoolManager.h | 42 +++++++---- datapoollocal/LocalDataSet.cpp | 68 ++++++++++++++---- datapoollocal/LocalDataSet.h | 24 +++++++ datapoollocal/OwnsLocalDataPoolIF.h | 4 +- housekeeping/HousekeepingMessage.h | 3 +- returnvalues/FwClassIds.h | 3 +- 8 files changed, 186 insertions(+), 56 deletions(-) diff --git a/datapool/DataSetBase.h b/datapool/DataSetBase.h index 8bf9a99a..a914ec6b 100644 --- a/datapool/DataSetBase.h +++ b/datapool/DataSetBase.h @@ -102,7 +102,7 @@ public: virtual ReturnValue_t unlockDataPool() override; /* SerializeIF implementations */ - ReturnValue_t serialize(uint8_t** buffer, size_t* size, + virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, const size_t maxSize, bool bigEndian) const override; virtual size_t getSerializedSize() const override; virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, diff --git a/datapoollocal/LocalDataPoolManager.cpp b/datapoollocal/LocalDataPoolManager.cpp index 58694508..a9d131eb 100644 --- a/datapoollocal/LocalDataPoolManager.cpp +++ b/datapoollocal/LocalDataPoolManager.cpp @@ -1,16 +1,17 @@ #include #include -#include -#include #include #include +#include #include -LocalDataPoolManager::LocalDataPoolManager(OwnsLocalDataPoolIF* owner) { +LocalDataPoolManager::LocalDataPoolManager(OwnsLocalDataPoolIF* owner, + uint32_t replyQueueDepth, bool appendValidityBuffer): + appendValidityBuffer(appendValidityBuffer) { if(owner == nullptr) { sif::error << "HkManager: Invalid supplied owner!" << std::endl; - std::exit(0); + return; } this->owner = owner; mutex = MutexFactory::instance()->createMutex(); @@ -23,6 +24,8 @@ LocalDataPoolManager::LocalDataPoolManager(OwnsLocalDataPoolIF* owner) { sif::error << "LocalDataPoolManager::LocalDataPoolManager: " "Could not set IPC store." << std::endl; } + hkQueue = QueueFactory::instance()->createMessageQueue(replyQueueDepth, + HousekeepingMessage::HK_MESSAGE_SIZE); } LocalDataPoolManager::~LocalDataPoolManager() {} @@ -36,13 +39,21 @@ ReturnValue_t LocalDataPoolManager::initializeHousekeepingPoolEntriesOnce() { } return result; } - sif::warning << "HousekeepingManager: The map" << std::endl; + sif::warning << "HousekeepingManager: The map should only be initialized " + "once!" << std::endl; return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage( HousekeepingMessage& message) { - return HasReturnvaluesIF::RETURN_FAILED; + Command_t command = message.getCommand(); + switch(command) { + case(HousekeepingMessage::GENERATE_ONE_PARAMETER_REPORT): + case(HousekeepingMessage::GENERATE_ONE_DIAGNOSTICS_REPORT): + return generateHousekeepingPacket(message.getSid()); + default: + return CommandMessageIF::UNKNOWN_COMMAND; + } } ReturnValue_t LocalDataPoolManager::printPoolEntry( @@ -51,7 +62,7 @@ ReturnValue_t LocalDataPoolManager::printPoolEntry( if (poolIter == localDpMap.end()) { sif::debug << "HousekeepingManager::fechPoolEntry:" " Pool entry not found." << std::endl; - return OwnsLocalDataPoolIF::POOL_ENTRY_NOT_FOUND; + return POOL_ENTRY_NOT_FOUND; } poolIter->second->print(); return HasReturnvaluesIF::RETURN_OK; @@ -61,6 +72,15 @@ 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) { LocalDataSet* dataSetToSerialize = dynamic_cast( owner->getDataSetHandle(sid)); @@ -70,28 +90,56 @@ ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid) { return HasReturnvaluesIF::RETURN_FAILED; } store_address_t storeId; - size_t hkSize = dataSetToSerialize->getSerializedSize(); - uint8_t* storePtr = nullptr; - ReturnValue_t result = ipcStore->getFreeElement(&storeId, hkSize,&storePtr); + ReturnValue_t result = serializeHkPacketIntoStore(&storeId, + dataSetToSerialize); if(result != HasReturnvaluesIF::RETURN_OK) { - sif::warning << "HousekeepingManager::generateHousekeepingPacket: " - "Could not get free element from IPC store." << std::endl; return result; } - size_t size = 0; - dataSetToSerialize->serialize(&storePtr, &size, hkSize, false); - // and now we have to set a HK message and send it the queue. - return HasReturnvaluesIF::RETURN_OK; + + // and now we set a HK message and send it the HK packet destination. + MessageQueueMessage message; + HousekeepingMessage hkMessage(&message); + hkMessage.setHkReportMessage(sid, storeId); + if(hkQueue == nullptr) { + return QUEUE_NOT_SET; + } + + if(currentHkPacketDestination != MessageQueueIF::NO_QUEUE) { + result = hkQueue->sendMessage(currentHkPacketDestination, &hkMessage); + } + else { + result = hkQueue->sendToDefault(&hkMessage); + } + + return result; } -void LocalDataPoolManager::setHkPacketQueue(MessageQueueIF *msgQueue) { - this->hkPacketQueue = msgQueue; +ReturnValue_t LocalDataPoolManager::serializeHkPacketIntoStore( + store_address_t *storeId, LocalDataSet* dataSet) { + size_t hkSize = dataSet->getSerializedSize(); + uint8_t* storePtr = nullptr; + ReturnValue_t result = ipcStore->getFreeElement(storeId, hkSize,&storePtr); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "HousekeepingManager::generateHousekeepingPacket: " + "Could not get free element from IPC store." << std::endl; + return result; + } + size_t size = 0; + + if(appendValidityBuffer) { + result = dataSet->serializeWithValidityBuffer(&storePtr, + &size, hkSize, false); + } + else { + result = dataSet->serialize(&storePtr, &size, hkSize, false); + } + + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "HousekeepingManager::serializeHkPacketIntoStore: " + "Serialization proccess failed!" << std::endl; + } + return result; } -void LocalDataPoolManager::setHkReplyQueue(MessageQueueIF *replyQueue) { - this->hkReplyQueue = replyQueue; -} -const OwnsLocalDataPoolIF* LocalDataPoolManager::getOwner() const { - return owner; -} + diff --git a/datapoollocal/LocalDataPoolManager.h b/datapoollocal/LocalDataPoolManager.h index d1a2d410..c649cd68 100644 --- a/datapoollocal/LocalDataPoolManager.h +++ b/datapoollocal/LocalDataPoolManager.h @@ -13,6 +13,8 @@ #include +class LocalDataSet; + /** * @brief This class is the managing instance for local data pool. * @details @@ -37,8 +39,16 @@ class LocalDataPoolManager { friend class LocalPoolVector; friend class LocalDataSet; public: + static constexpr uint8_t INTERFACE_ID = CLASS_ID::HOUSEKEEPING_MANAGER; - LocalDataPoolManager(OwnsLocalDataPoolIF* owner); + 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 SET_NOT_FOUND = MAKE_RETURN_CODE(0x3); + + LocalDataPoolManager(OwnsLocalDataPoolIF* owner, + uint32_t replyQueueDepth = 20, bool appendValidityBuffer = true); virtual~ LocalDataPoolManager(); /* Copying forbidden */ @@ -57,10 +67,7 @@ public: ReturnValue_t initializeHousekeepingPoolEntriesOnce(); //! Set the queue for HK packets, which are sent unrequested. - void setHkPacketQueue(MessageQueueIF* msgQueue); - //! Set the queue for replies. This can be set manually or by the owner - //! class if the manager if message are relayed by it. - void setHkReplyQueue(MessageQueueIF* replyQueue); + void setHkPacketDestination(MessageQueueId_t destinationQueueId); const OwnsLocalDataPoolIF* getOwner() const; @@ -70,6 +77,10 @@ private: //! 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. + bool appendValidityBuffer = true; + LocalDataPool localDpMap; //! Every housekeeping data manager has a mutex to protect access @@ -79,13 +90,14 @@ private: //! The class which actually owns the manager (and its datapool). OwnsLocalDataPoolIF* owner = nullptr; - //! Used for replies. - //! (maybe we dont need this, the sender can be retrieved from command - //! message..) - MessageQueueIF* hkReplyQueue = nullptr; - //! Used for HK packets, which are generated without requests. - //! Maybe this will just be the TM funnel. - MessageQueueIF* hkPacketQueue = nullptr; + //! Queue used for communication, for example commands. + //! Is also used to send messages. + 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; //! Global IPC store is used to store all packets. StorageManagerIF* ipcStore = nullptr; @@ -113,6 +125,8 @@ private: PoolEntry **poolEntry); void setMinimalSamplingFrequency(float frequencySeconds); + ReturnValue_t serializeHkPacketIntoStore(store_address_t* storeId, + LocalDataSet* dataSet); }; @@ -123,14 +137,14 @@ ReturnValue_t LocalDataPoolManager::fetchPoolEntry(lp_id_t localPoolId, if (poolIter == localDpMap.end()) { sif::debug << "HousekeepingManager::fechPoolEntry:" " Pool entry not found." << std::endl; - return OwnsLocalDataPoolIF::POOL_ENTRY_NOT_FOUND; + return POOL_ENTRY_NOT_FOUND; } *poolEntry = dynamic_cast< PoolEntry* >(poolIter->second); if(*poolEntry == nullptr) { sif::debug << "HousekeepingManager::fetchPoolEntry:" " Pool entry not found." << std::endl; - return OwnsLocalDataPoolIF::POOL_ENTRY_TYPE_CONFLICT; + return POOL_ENTRY_TYPE_CONFLICT; } return HasReturnvaluesIF::RETURN_OK; } diff --git a/datapoollocal/LocalDataSet.cpp b/datapoollocal/LocalDataSet.cpp index 243c9cc1..bb4aafef 100644 --- a/datapoollocal/LocalDataSet.cpp +++ b/datapoollocal/LocalDataSet.cpp @@ -1,22 +1,25 @@ #include #include +#include +#include + LocalDataSet::LocalDataSet(OwnsLocalDataPoolIF *hkOwner): DataSetBase() { - if(hkOwner != nullptr) { - hkManager = hkOwner->getHkManagerHandle(); - } - else { - // config error, error output here. - } + if(hkOwner == nullptr) { + sif::error << "LocalDataSet::LocalDataSet: Owner can't be nullptr!" + << std::endl; + } + hkManager = hkOwner->getHkManagerHandle(); } LocalDataSet::LocalDataSet(object_id_t ownerId): DataSetBase() { - OwnsLocalDataPoolIF* hkOwner = objectManager->get( - ownerId); - if(hkOwner == nullptr) { - // config error, error output here. - } - hkManager = hkOwner->getHkManagerHandle(); + OwnsLocalDataPoolIF* hkOwner = objectManager->get( + ownerId); + if(hkOwner == nullptr) { + sif::error << "LocalDataSet::LocalDataSet: Owner can't be nullptr!" + << std::endl; + } + hkManager = hkOwner->getHkManagerHandle(); } LocalDataSet::~LocalDataSet() { @@ -27,9 +30,50 @@ ReturnValue_t LocalDataSet::lockDataPool(uint32_t timeoutMs) { return mutex->lockMutex(timeoutMs); } +ReturnValue_t LocalDataSet::serializeWithValidityBuffer(uint8_t **buffer, + size_t *size, const size_t maxSize, bool bigEndian) const { + ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED; + uint8_t validityMaskSize = std::ceil(static_cast(fillCount)/8.0); + uint8_t validityMask[validityMaskSize]; + uint8_t validBufferIndex = 0; + uint8_t validBufferIndexBit = 0; + for (uint16_t count = 0; count < fillCount; count++) { + if(registeredVariables[count]->isValid()) { + // set validity buffer here. + this->bitSetter(validityMask + validBufferIndex, + validBufferIndexBit, true); + if(validBufferIndexBit == 7) { + validBufferIndex ++; + validBufferIndexBit = 0; + } + else { + validBufferIndexBit ++; + } + } + result = registeredVariables[count]->serialize(buffer, size, maxSize, + bigEndian); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + } + // copy validity buffer to end + std::memcpy(*buffer, validityMask, validityMaskSize); + *size += validityMaskSize; + return result; +} + ReturnValue_t LocalDataSet::unlockDataPool() { MutexIF* mutex = hkManager->getMutexHandle(); return mutex->unlockMutex(); } +void LocalDataSet::bitSetter(uint8_t* byte, uint8_t position, + bool value) const { + if(position > 7) { + sif::debug << "Pool Raw Access: Bit setting invalid position" << std::endl; + return; + } + uint8_t shiftNumber = position + (7 - 2 * position); + *byte |= 1UL << shiftNumber; +} diff --git a/datapoollocal/LocalDataSet.h b/datapoollocal/LocalDataSet.h index 54da5562..0c3b3bd8 100644 --- a/datapoollocal/LocalDataSet.h +++ b/datapoollocal/LocalDataSet.h @@ -55,6 +55,20 @@ public: */ ~LocalDataSet(); + /** + * Special version of the serilization function which appends a + * validity buffer at the end. Each bit of this validity buffer + * denotes whether the container data set entries are valid from left + * to right, MSB first. + * @param buffer + * @param size + * @param maxSize + * @param bigEndian + * @param withValidityBuffer + * @return + */ + ReturnValue_t serializeWithValidityBuffer(uint8_t** buffer, + size_t* size, const size_t maxSize, bool bigEndian) const ; protected: private: /** @@ -79,6 +93,16 @@ private: ReturnValue_t unlockDataPool() override; LocalDataPoolManager* hkManager; + + /** + * Sets the bit at the bit-position of a byte provided by its address + * to the specified value (zero or one). + * @param byte Pointer to byte to bitset. + * @param position MSB first, 0 to 7 possible. + * @param value Value to set. + * @return + */ + void bitSetter(uint8_t* byte, uint8_t position, bool value) const; }; #endif /* FRAMEWORK_DATAPOOLLOCAL_LOCALDATASET_H_ */ diff --git a/datapoollocal/OwnsLocalDataPoolIF.h b/datapoollocal/OwnsLocalDataPoolIF.h index cf94f946..8d657879 100644 --- a/datapoollocal/OwnsLocalDataPoolIF.h +++ b/datapoollocal/OwnsLocalDataPoolIF.h @@ -40,9 +40,7 @@ class OwnsLocalDataPoolIF { public: virtual~ OwnsLocalDataPoolIF() {}; - 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); + static constexpr uint8_t INTERFACE_ID = CLASS_ID::LOCAL_POOL_OWNER_IF; virtual MessageQueueId_t getCommandQueue() const = 0; virtual ReturnValue_t initializeHousekeepingPoolEntries( diff --git a/housekeeping/HousekeepingMessage.h b/housekeeping/HousekeepingMessage.h index 75afc8ea..c6a33c83 100644 --- a/housekeeping/HousekeepingMessage.h +++ b/housekeeping/HousekeepingMessage.h @@ -96,6 +96,7 @@ public: void setParameter(uint32_t parameter); uint32_t getParameter() const; + sid_t getSid() const; void setHkReportMessage(sid_t sid, store_address_t storeId); void setHkDiagnosticsMessage(sid_t sid, store_address_t storeId); @@ -106,7 +107,7 @@ public: virtual size_t getMinimumMessageSize() const override; virtual void clear() override; private: - sid_t getSid() const; + void setSid(sid_t sid); virtual uint8_t* getData() override; diff --git a/returnvalues/FwClassIds.h b/returnvalues/FwClassIds.h index 870efb46..ddee539e 100644 --- a/returnvalues/FwClassIds.h +++ b/returnvalues/FwClassIds.h @@ -61,8 +61,9 @@ enum { MUTEX_IF, //MUX 55 MESSAGE_QUEUE_IF,//MQI 56 SEMAPHORE_IF, //SPH 57 - HOUSEKEEPING, //HK 58 + LOCAL_POOL_OWNER_IF, //LPIF 58 POOL_VARIABLE_IF, //PVA 59 + HOUSEKEEPING_MANAGER, //HKM 60 FW_CLASS_ID_COUNT //is actually count + 1 ! }; From 60ae2d45655330a3d81dd897b8dfb0ff6456dcd4 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 19 Jun 2020 14:25:03 +0200 Subject: [PATCH 151/307] continued with hk data pool added deadline missed check for fixed timeslot task, improved doc for both periodic task and fixed timeslot task --- datapool/DataSetBase.cpp | 4 ++ datapool/DataSetBase.h | 2 + datapool/DataSetIF.h | 1 + datapoollocal/LocalDataPoolManager.cpp | 40 ++++++++++++++++- datapoollocal/LocalDataPoolManager.h | 2 + datapoollocal/LocalDataSet.cpp | 16 +++++++ datapoollocal/LocalDataSet.h | 5 ++- datapoollocal/OwnsLocalDataPoolIF.h | 30 +++++++++++-- devicehandlers/DeviceHandlerBase.cpp | 17 +++++++- devicehandlers/DeviceHandlerBase.h | 11 ++++- events/EventManager.cpp | 11 +++-- events/EventManager.h | 4 +- osal/FreeRTOS/FixedTimeslotTask.cpp | 60 +++++++++++++++++--------- osal/FreeRTOS/FixedTimeslotTask.h | 49 ++++++++++----------- osal/FreeRTOS/PeriodicTask.cpp | 30 +++++++------ osal/FreeRTOS/PeriodicTask.h | 49 ++++++++++++--------- serialize/SerializeAdapter.h | 15 +++++++ tasks/ExecutableObjectIF.h | 6 ++- tmtcservices/CommandingServiceBase.cpp | 5 ++- tmtcservices/CommandingServiceBase.h | 4 +- 20 files changed, 261 insertions(+), 100 deletions(-) diff --git a/datapool/DataSetBase.cpp b/datapool/DataSetBase.cpp index 60b20f29..b788d05d 100644 --- a/datapool/DataSetBase.cpp +++ b/datapool/DataSetBase.cpp @@ -53,6 +53,10 @@ ReturnValue_t DataSetBase::read(uint32_t lockTimeout) { return result; } +uint16_t DataSetBase::getFillCount() const { + return fillCount; +} + ReturnValue_t DataSetBase::readVariable(uint16_t count) { ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; // These checks are often performed by the respective diff --git a/datapool/DataSetBase.h b/datapool/DataSetBase.h index a914ec6b..8f7d892a 100644 --- a/datapool/DataSetBase.h +++ b/datapool/DataSetBase.h @@ -101,6 +101,8 @@ public: */ virtual ReturnValue_t unlockDataPool() override; + virtual uint16_t getFillCount() const; + /* SerializeIF implementations */ virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, const size_t maxSize, bool bigEndian) const override; diff --git a/datapool/DataSetIF.h b/datapool/DataSetIF.h index 9c5b13c8..437f324f 100644 --- a/datapool/DataSetIF.h +++ b/datapool/DataSetIF.h @@ -43,6 +43,7 @@ public: */ virtual ReturnValue_t registerVariable(PoolVariableIF* variable) = 0; + virtual uint16_t getFillCount() const = 0; private: /** * @brief Most underlying data structures will have a pool like structure diff --git a/datapoollocal/LocalDataPoolManager.cpp b/datapoollocal/LocalDataPoolManager.cpp index a9d131eb..e0731a96 100644 --- a/datapoollocal/LocalDataPoolManager.cpp +++ b/datapoollocal/LocalDataPoolManager.cpp @@ -33,7 +33,7 @@ LocalDataPoolManager::~LocalDataPoolManager() {} ReturnValue_t LocalDataPoolManager::initializeHousekeepingPoolEntriesOnce() { if(not mapInitialized) { ReturnValue_t result = - owner->initializeHousekeepingPoolEntries(localDpMap); + owner->initializePoolEntries(localDpMap); if(result == HasReturnvaluesIF::RETURN_OK) { mapInitialized = true; } @@ -48,6 +48,14 @@ ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage( HousekeepingMessage& message) { Command_t command = message.getCommand(); switch(command) { + // I think those are the only commands which can be handled here.. + case(HousekeepingMessage::ADD_HK_REPORT_STRUCT): + case(HousekeepingMessage::ADD_DIAGNOSTICS_REPORT_STRUCT): + // We should use OwnsLocalPoolDataIF to specify those functions.. + return HasReturnvaluesIF::RETURN_OK; + case(HousekeepingMessage::REPORT_DIAGNOSTICS_REPORT_STRUCTURES): + case(HousekeepingMessage::REPORT_HK_REPORT_STRUCTURES): + return generateSetStructurePacket(message.getSid()); case(HousekeepingMessage::GENERATE_ONE_PARAMETER_REPORT): case(HousekeepingMessage::GENERATE_ONE_DIAGNOSTICS_REPORT): return generateHousekeepingPacket(message.getSid()); @@ -114,13 +122,41 @@ ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid) { return result; } +ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid) { + LocalDataSet* dataSet = dynamic_cast( + owner->getDataSetHandle(sid)); + if(dataSet == nullptr) { + sif::warning << "HousekeepingManager::generateHousekeepingPacket:" + " Set ID not found" << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + size_t expectedSize = dataSet->getFillCount() * sizeof(lp_id_t); + 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 = dataSet->serializeLocalPoolIds(&storePtr, &size, + expectedSize, false); + if(expectedSize != size) { + sif::error << "HousekeepingManager::generateSetStructurePacket: " + "Expected size is not equal to serialized size" << std::endl; + } + return result; +} + ReturnValue_t LocalDataPoolManager::serializeHkPacketIntoStore( store_address_t *storeId, LocalDataSet* dataSet) { size_t hkSize = dataSet->getSerializedSize(); uint8_t* storePtr = nullptr; ReturnValue_t result = ipcStore->getFreeElement(storeId, hkSize,&storePtr); if(result != HasReturnvaluesIF::RETURN_OK) { - sif::warning << "HousekeepingManager::generateHousekeepingPacket: " + sif::error << "HousekeepingManager::generateHousekeepingPacket: " "Could not get free element from IPC store." << std::endl; return result; } diff --git a/datapoollocal/LocalDataPoolManager.h b/datapoollocal/LocalDataPoolManager.h index c649cd68..b6491724 100644 --- a/datapoollocal/LocalDataPoolManager.h +++ b/datapoollocal/LocalDataPoolManager.h @@ -56,6 +56,8 @@ public: LocalDataPoolManager operator=(const LocalDataPoolManager&) = delete; ReturnValue_t generateHousekeepingPacket(sid_t sid); + ReturnValue_t generateSetStructurePacket(sid_t sid); + ReturnValue_t handleHousekeepingMessage(HousekeepingMessage& message); /** diff --git a/datapoollocal/LocalDataSet.cpp b/datapoollocal/LocalDataSet.cpp index bb4aafef..27ad4bc2 100644 --- a/datapoollocal/LocalDataSet.cpp +++ b/datapoollocal/LocalDataSet.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -67,6 +68,21 @@ ReturnValue_t LocalDataSet::unlockDataPool() { return mutex->unlockMutex(); } +ReturnValue_t LocalDataSet::serializeLocalPoolIds(uint8_t** buffer, + size_t* size, const size_t maxSize, bool bigEndian) const { + for (uint16_t count = 0; count < fillCount; count++) { + lp_id_t currentPoolId = registeredVariables[count]->getDataPoolId(); + auto result = AutoSerializeAdapter::serialize(¤tPoolId, buffer, + size, maxSize, bigEndian); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "LocalDataSet::serializeLocalPoolIds: Serialization" + " error!" << std::endl; + return result; + } + } + return HasReturnvaluesIF::RETURN_OK; +} + void LocalDataSet::bitSetter(uint8_t* byte, uint8_t position, bool value) const { if(position > 7) { diff --git a/datapoollocal/LocalDataSet.h b/datapoollocal/LocalDataSet.h index 0c3b3bd8..48138e63 100644 --- a/datapoollocal/LocalDataSet.h +++ b/datapoollocal/LocalDataSet.h @@ -68,7 +68,10 @@ public: * @return */ ReturnValue_t serializeWithValidityBuffer(uint8_t** buffer, - size_t* size, const size_t maxSize, bool bigEndian) const ; + size_t* size, const size_t maxSize, bool bigEndian) const; + + ReturnValue_t serializeLocalPoolIds(uint8_t** buffer, + size_t* size, const size_t maxSize, bool bigEndian) const; protected: private: /** diff --git a/datapoollocal/OwnsLocalDataPoolIF.h b/datapoollocal/OwnsLocalDataPoolIF.h index 8d657879..6fc10889 100644 --- a/datapoollocal/OwnsLocalDataPoolIF.h +++ b/datapoollocal/OwnsLocalDataPoolIF.h @@ -42,12 +42,36 @@ public: static constexpr uint8_t INTERFACE_ID = CLASS_ID::LOCAL_POOL_OWNER_IF; + /** Command queue for housekeeping messages. */ virtual MessageQueueId_t getCommandQueue() const = 0; - virtual ReturnValue_t initializeHousekeepingPoolEntries( - LocalDataPool& localDataPoolMap) = 0; - //virtual float setMinimalHkSamplingFrequency() = 0; + + /** Is used by pool owner to initialize the pool map once */ + virtual ReturnValue_t initializePoolEntries( + LocalDataPool& localDataPoolMap) = 0; + + /** Can be used to get a handle to the local data pool manager. */ virtual LocalDataPoolManager* getHkManagerHandle() = 0; + + /** + * This function is used by the pool manager to get a valid dataset + * from a SID + * @param sid Corresponding structure ID + * @return + */ virtual DataSetIF* getDataSetHandle(sid_t sid) = 0; + + /* These function can be implemented by pool owner, as they are required + * by the housekeeping message interface */ + virtual ReturnValue_t addDataSet(sid_t sid) { + return HasReturnvaluesIF::RETURN_FAILED; + }; + virtual ReturnValue_t removeDataSet(sid_t sid) { + return HasReturnvaluesIF::RETURN_FAILED; + }; + virtual ReturnValue_t changeCollectionInterval(sid_t sid, + dur_seconds_t newInterval) { + return HasReturnvaluesIF::RETURN_FAILED; + }; }; #endif /* FRAMEWORK_DATAPOOL_HASHKPOOLPARAMETERSIF_H_ */ diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index bf699848..1ae056a6 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -1350,7 +1350,7 @@ void DeviceHandlerBase::changeHK(Mode_t mode, Submode_t submode, bool enable) { } void DeviceHandlerBase::setTaskIF(PeriodicTaskIF* task_){ - executingTask = task_; + executingTask = task_; } // Default implementations empty. @@ -1360,7 +1360,7 @@ void DeviceHandlerBase::debugInterface(uint8_t positionTracker, void DeviceHandlerBase::performOperationHook() { } -ReturnValue_t DeviceHandlerBase::initializeHousekeepingPoolEntries( +ReturnValue_t DeviceHandlerBase::initializePoolEntries( LocalDataPool &localDataPoolMap) { return RETURN_OK; } @@ -1369,6 +1369,19 @@ LocalDataPoolManager* DeviceHandlerBase::getHkManagerHandle() { return &hkManager; } +ReturnValue_t DeviceHandlerBase::addDataSet(sid_t sid) { + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t DeviceHandlerBase::removeDataSet(sid_t sid) { + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t DeviceHandlerBase::changeCollectionInterval(sid_t sid, + dur_seconds_t newInterval) { + return HasReturnvaluesIF::RETURN_OK; +} + DataSetIF* DeviceHandlerBase::getDataSetHandle(sid_t sid) { auto iter = deviceReplyMap.find(sid.ownerSetId); if(iter != deviceReplyMap.end()) { diff --git a/devicehandlers/DeviceHandlerBase.h b/devicehandlers/DeviceHandlerBase.h index 4ee3d652..1290742c 100644 --- a/devicehandlers/DeviceHandlerBase.h +++ b/devicehandlers/DeviceHandlerBase.h @@ -477,12 +477,17 @@ protected: * @param localDataPoolMap * @return */ - virtual ReturnValue_t initializeHousekeepingPoolEntries( + virtual ReturnValue_t initializePoolEntries( LocalDataPool& localDataPoolMap) override; /** Get the HK manager object handle */ virtual LocalDataPoolManager* getHkManagerHandle() override; + virtual ReturnValue_t addDataSet(sid_t sid) override; + virtual ReturnValue_t removeDataSet(sid_t sid) override; + virtual ReturnValue_t changeCollectionInterval(sid_t sid, + dur_seconds_t newInterval) override; + /** * @brief Hook function for child handlers which is called once per * performOperation(). Default implementation is empty. @@ -703,7 +708,9 @@ protected: bool switchOffWasReported; //!< Indicates if SWITCH_WENT_OFF was already thrown. - PeriodicTaskIF* executingTask = nullptr;//!< Pointer to the task which executes this component, is invalid before setTaskIF was called. + //! Pointer to the task which executes this component, is invalid + //! before setTaskIF was called. + PeriodicTaskIF* executingTask = nullptr; static object_id_t powerSwitcherId; //!< Object which switches power on and off. diff --git a/events/EventManager.cpp b/events/EventManager.cpp index 73e77e94..539f9e27 100644 --- a/events/EventManager.cpp +++ b/events/EventManager.cpp @@ -8,13 +8,16 @@ const uint16_t EventManager::POOL_SIZES[N_POOLS] = { sizeof(EventMatchTree::Node), sizeof(EventIdRangeMatcher), sizeof(ReporterRangeMatcher) }; -//If one checks registerListener calls, there are around 40 (to max 50) objects registering for certain events. -//Each listener requires 1 or 2 EventIdMatcher and 1 or 2 ReportRangeMatcher. So a good guess is 75 to a max of 100 pools required for each, which fits well. +// If one checks registerListener calls, there are around 40 (to max 50) +// objects registering for certain events. +// Each listener requires 1 or 2 EventIdMatcher and 1 or 2 ReportRangeMatcher. +// So a good guess is 75 to a max of 100 pools required for each, which fits well. +// SHOULDDO: Shouldn't this be in the config folder and passed via ctor? const uint16_t EventManager::N_ELEMENTS[N_POOLS] = { 240, 120, 120 }; EventManager::EventManager(object_id_t setObjectId) : - SystemObject(setObjectId), eventReportQueue(NULL), mutex(NULL), factoryBackend( - 0, POOL_SIZES, N_ELEMENTS, false, true) { + SystemObject(setObjectId), + factoryBackend(0, POOL_SIZES, N_ELEMENTS, false, true) { mutex = MutexFactory::instance()->createMutex(); eventReportQueue = QueueFactory::instance()->createMessageQueue( MAX_EVENTS_PER_CYCLE, EventMessage::EVENT_MESSAGE_SIZE); diff --git a/events/EventManager.h b/events/EventManager.h index 76dde9f8..6fac8352 100644 --- a/events/EventManager.h +++ b/events/EventManager.h @@ -36,11 +36,11 @@ public: ReturnValue_t performOperation(uint8_t opCode); protected: - MessageQueueIF* eventReportQueue; + MessageQueueIF* eventReportQueue = nullptr; std::map listenerList; - MutexIF* mutex; + MutexIF* mutex = nullptr; static const uint8_t N_POOLS = 3; LocalPool factoryBackend; diff --git a/osal/FreeRTOS/FixedTimeslotTask.cpp b/osal/FreeRTOS/FixedTimeslotTask.cpp index 18ec1092..de99413e 100644 --- a/osal/FreeRTOS/FixedTimeslotTask.cpp +++ b/osal/FreeRTOS/FixedTimeslotTask.cpp @@ -1,6 +1,7 @@ -#include #include "FixedTimeslotTask.h" +#include + uint32_t FixedTimeslotTask::deadlineMissedCount = 0; const size_t PeriodicTaskIF::MINIMUM_STACK_SIZE = configMINIMAL_STACK_SIZE; @@ -18,16 +19,19 @@ FixedTimeslotTask::~FixedTimeslotTask() { void FixedTimeslotTask::taskEntryPoint(void* argument) { - //The argument is re-interpreted as FixedTimeslotTask. The Task object is global, so it is found from any place. + // The argument is re-interpreted as FixedTimeslotTask. The Task object is + // global, so it is found from any place. FixedTimeslotTask *originalTask(reinterpret_cast(argument)); - // Task should not start until explicitly requested - // in FreeRTOS, tasks start as soon as they are created if the scheduler is running - // but not if the scheduler is not running. - // to be able to accommodate both cases we check a member which is set in #startTask() - // if it is not set and we get here, the scheduler was started before #startTask() was called and we need to suspend - // if it is set, the scheduler was not running before #startTask() was called and we can continue + /* Task should not start until explicitly requested, + * but in FreeRTOS, tasks start as soon as they are created if the scheduler + * is running but not if the scheduler is not running. + * To be able to accommodate both cases we check a member which is set in + * #startTask(). If it is not set and we get here, the scheduler was started + * before #startTask() was called and we need to suspend if it is set, + * the scheduler was not running before #startTask() was called and we + * can continue */ - if (!originalTask->started) { + if (not originalTask->started) { vTaskSuspend(NULL); } @@ -81,7 +85,8 @@ ReturnValue_t FixedTimeslotTask::checkSequence() const { } void FixedTimeslotTask::taskFunctionality() { - // A local iterator for the Polling Sequence Table is created to find the start time for the first entry. + // A local iterator for the Polling Sequence Table is created to find the + // start time for the first entry. SlotListIter slotListIter = pst.current; //The start time for the first entry is read. @@ -101,17 +106,30 @@ void FixedTimeslotTask::taskFunctionality() { /* Enter the loop that defines the task behavior. */ for (;;) { //The component for this slot is executed and the next one is chosen. - this->pst.executeAndAdvance(); - if (pst.slotFollowsImmediately()) { - //Do nothing - } else { - // we need to wait before executing the current slot - //this gives us the time to wait: - intervalMs = this->pst.getIntervalToPreviousSlotMs(); - interval = pdMS_TO_TICKS(intervalMs); - vTaskDelayUntil(&xLastWakeTime, interval); - //TODO deadline missed check - } + this->pst.executeAndAdvance(); + if (not pst.slotFollowsImmediately()) { + /* If all operations are finished and the difference of the + * current time minus the last wake time is larger than the + * expected wait period, a deadline was missed. */ + if(xTaskGetTickCount() - xLastWakeTime >= + pdMS_TO_TICKS(this->pst.getIntervalToPreviousSlotMs())) { +#ifdef DEBUG + sif::warning << "PeriodicTask: " << pcTaskGetName(NULL) << + " missed deadline!\n" << std::flush; +#endif + if(deadlineMissedFunc != nullptr) { + this->deadlineMissedFunc(); + } + // Continue immediately, no need to wait. + break; + } + + // we need to wait before executing the current slot + //this gives us the time to wait: + intervalMs = this->pst.getIntervalToPreviousSlotMs(); + interval = pdMS_TO_TICKS(intervalMs); + vTaskDelayUntil(&xLastWakeTime, interval); + } } } diff --git a/osal/FreeRTOS/FixedTimeslotTask.h b/osal/FreeRTOS/FixedTimeslotTask.h index fe93daff..39db667c 100644 --- a/osal/FreeRTOS/FixedTimeslotTask.h +++ b/osal/FreeRTOS/FixedTimeslotTask.h @@ -1,12 +1,12 @@ -#ifndef POLLINGTASK_H_ -#define POLLINGTASK_H_ +#ifndef FRAMEWORK_OSAL_FREERTOS_FIXEDTIMESLOTTASK_H_ +#define FRAMEWORK_OSAL_FREERTOS_FIXEDTIMESLOTTASK_H_ #include #include #include -#include -#include "task.h" +#include +#include class FixedTimeslotTask: public FixedTimeslotTaskIF { public: @@ -29,16 +29,18 @@ public: /** * @brief The destructor of the class. - * - * @details The destructor frees all heap memory that was allocated on thread initialization for the PST and - * the device handlers. This is done by calling the PST's destructor. + * @details + * The destructor frees all heap memory that was allocated on thread + * initialization for the PST and the device handlers. This is done by + * calling the PST's destructor. */ virtual ~FixedTimeslotTask(void); ReturnValue_t startTask(void); /** * This static function can be used as #deadlineMissedFunc. - * It counts missedDeadlines and prints the number of missed deadlines every 10th time. + * It counts missedDeadlines and prints the number of missed deadlines + * every 10th time. */ static void missedDeadlineCounter(); /** @@ -62,30 +64,29 @@ protected: FixedSlotSequence pst; /** - * @brief This attribute holds a function pointer that is executed when a deadline was missed. - * - * @details Another function may be announced to determine the actions to perform when a deadline was missed. - * Currently, only one function for missing any deadline is allowed. - * If not used, it shall be declared NULL. + * @brief This attribute holds a function pointer that is executed when + * a deadline was missed. + * @details + * Another function may be announced to determine the actions to perform + * when a deadline was missed. Currently, only one function for missing + * any deadline is allowed. If not used, it shall be declared NULL. */ void (*deadlineMissedFunc)(void); /** - * @brief This is the entry point in a new polling thread. - * - * @details This method, that is the generalOSAL::checkAndRestartPeriod( this->periodId, interval ); entry point in the new thread, is here set to generate - * and link the Polling Sequence Table to the thread object and start taskFunctionality() - * on success. If operation of the task is ended for some reason, - * the destructor is called to free allocated memory. + * @brief This is the entry point for a new task. + * @details + * This method starts the task by calling taskFunctionality(), as soon as + * all requirements (task scheduler has started and startTask() + * has been called) are met. */ static void taskEntryPoint(void* argument); /** * @brief This function holds the main functionality of the thread. - * - * - * @details Holding the main functionality of the task, this method is most important. - * It links the functionalities provided by FixedSlotSequence with the OS's System Calls - * to keep the timing of the periods. + * @details + * Core function holding the main functionality of the task + * It links the functionalities provided by FixedSlotSequence with the + * OS's System Calls to keep the timing of the periods. */ void taskFunctionality(void); }; diff --git a/osal/FreeRTOS/PeriodicTask.cpp b/osal/FreeRTOS/PeriodicTask.cpp index a8e40561..31867639 100644 --- a/osal/FreeRTOS/PeriodicTask.cpp +++ b/osal/FreeRTOS/PeriodicTask.cpp @@ -12,8 +12,8 @@ PeriodicTask::PeriodicTask(const char *name, TaskPriority setPriority, BaseType_t status = xTaskCreate(taskEntryPoint, name, setStack, this, setPriority, &handle); if(status != pdPASS){ - sif::debug << "PeriodicTask Insufficient heap memory remaining. Status: " - << status << std::endl; + sif::debug << "PeriodicTask Insufficient heap memory remaining. " + "Status: " << status << std::endl; } } @@ -23,14 +23,17 @@ PeriodicTask::~PeriodicTask(void) { } void PeriodicTask::taskEntryPoint(void* argument) { - //The argument is re-interpreted as PeriodicTask. The Task object is global, so it is found from any place. + // The argument is re-interpreted as PeriodicTask. The Task object is + // global, so it is found from any place. PeriodicTask *originalTask(reinterpret_cast(argument)); - // Task should not start until explicitly requested - // in FreeRTOS, tasks start as soon as they are created if the scheduler is running - // but not if the scheduler is not running. - // to be able to accommodate both cases we check a member which is set in #startTask() - // if it is not set and we get here, the scheduler was started before #startTask() was called and we need to suspend - // if it is set, the scheduler was not running before #startTask() was called and we can continue + /* Task should not start until explicitly requested, + * but in FreeRTOS, tasks start as soon as they are created if the scheduler + * is running but not if the scheduler is not running. + * To be able to accommodate both cases we check a member which is set in + * #startTask(). If it is not set and we get here, the scheduler was started + * before #startTask() was called and we need to suspend if it is set, + * the scheduler was not running before #startTask() was called and we + * can continue */ if (not originalTask->started) { vTaskSuspend(NULL); @@ -61,9 +64,9 @@ void PeriodicTask::taskFunctionality() { TickType_t xLastWakeTime; const TickType_t xPeriod = pdMS_TO_TICKS(this->period * 1000.); /* The xLastWakeTime variable needs to be initialized with the current tick - count. Note that this is the only time the variable is written to explicitly. - After this assignment, xLastWakeTime is updated automatically internally within - vTaskDelayUntil(). */ + count. Note that this is the only time the variable is written to + explicitly. After this assignment, xLastWakeTime is updated automatically + internally within vTaskDelayUntil(). */ xLastWakeTime = xTaskGetTickCount(); /* Enter the loop that defines the task behavior. */ for (;;) { @@ -76,12 +79,15 @@ void PeriodicTask::taskFunctionality() { * current time minus the last wake time is larger than the * wait period, a deadline was missed. */ if(xTaskGetTickCount() - xLastWakeTime >= xPeriod) { +#ifdef DEBUG sif::warning << "PeriodicTask: " << pcTaskGetName(NULL) << " missed deadline!\n" << std::flush; +#endif if(deadlineMissedFunc != nullptr) { this->deadlineMissedFunc(); } } + vTaskDelayUntil(&xLastWakeTime, xPeriod); } diff --git a/osal/FreeRTOS/PeriodicTask.h b/osal/FreeRTOS/PeriodicTask.h index a449328e..fd1dd0df 100644 --- a/osal/FreeRTOS/PeriodicTask.h +++ b/osal/FreeRTOS/PeriodicTask.h @@ -5,10 +5,8 @@ #include #include -extern "C" { #include #include -} #include @@ -22,7 +20,8 @@ class ExecutableObjectIF; class PeriodicTask: public PeriodicTaskIF { public: /** - * @brief Standard constructor of the class. + * Keep in Mind that you need to call before this vTaskStartScheduler()! + * A lot of task parameters are set in "FreeRTOSConfig.h". * @details * The class is initialized without allocated objects. * These need to be added with #addComponent. @@ -38,8 +37,9 @@ public: * The function pointer to the deadline missed function that shall * be assigned. */ - PeriodicTask(const char *name, TaskPriority setPriority, TaskStackSize setStack, - TaskPeriod setPeriod,void (*setDeadlineMissedFunc)()); + PeriodicTask(const char *name, TaskPriority setPriority, + TaskStackSize setStack, TaskPeriod setPeriod, + void (*setDeadlineMissedFunc)()); /** * @brief Currently, the executed object's lifetime is not coupled with * the task object's lifetime, so the destructor is empty. @@ -58,7 +58,9 @@ public: * Adds an object to the list of objects to be executed. * The objects are executed in the order added. * @param object Id of the object to add. - * @return RETURN_OK on success, RETURN_FAILED if the object could not be added. + * @return + * -@c RETURN_OK on success + * -@c RETURN_FAILED if the object could not be added. */ ReturnValue_t addComponent(object_id_t object); @@ -69,40 +71,47 @@ protected: bool started; TaskHandle_t handle; - typedef std::vector ObjectList; //!< Typedef for the List of objects. + //! Typedef for the List of objects. + typedef std::vector ObjectList; /** * @brief This attribute holds a list of objects to be executed. */ ObjectList objectList; /** * @brief The period of the task. - * @details The period determines the frequency of the task's execution. It is expressed in clock ticks. + * @details + * The period determines the frequency of the task's execution. + * It is expressed in clock ticks. */ TaskPeriod period; /** * @brief The pointer to the deadline-missed function. - * @details This pointer stores the function that is executed if the task's deadline is missed. - * So, each may react individually on a timing failure. The pointer may be NULL, - * then nothing happens on missing the deadline. The deadline is equal to the next execution - * of the periodic task. + * @details + * This pointer stores the function that is executed if the task's deadline + * is missed so each may react individually on a timing failure. + * The pointer may be NULL, then nothing happens on missing the deadline. + * The deadline is equal to the next execution of the periodic task. */ void (*deadlineMissedFunc)(void); /** * @brief This is the function executed in the new task's context. - * @details It converts the argument back to the thread object type and copies the class instance - * to the task context. The taskFunctionality method is called afterwards. + * @details + * It converts the argument back to the thread object type and copies the + * class instance to the task context. The taskFunctionality method is + * called afterwards. * @param A pointer to the task object itself is passed as argument. */ static void taskEntryPoint(void* argument); /** * @brief The function containing the actual functionality of the task. - * @details The method sets and starts - * the task's period, then enters a loop that is repeated as long as the isRunning - * attribute is true. Within the loop, all performOperation methods of the added - * objects are called. Afterwards the checkAndRestartPeriod system call blocks the task - * until the next period. - * On missing the deadline, the deadlineMissedFunction is executed. + * @details + * The method sets and starts the task's period, then enters a loop that is + * repeated as long as the isRunning attribute is true. Within the loop, + * all performOperation methods of the added objects are called. + * Afterwards the checkAndRestartPeriod system call blocks the task until + * the next period. + * On missing the deadline, the deadlineMissedFunction is executed. */ void taskFunctionality(void); }; diff --git a/serialize/SerializeAdapter.h b/serialize/SerializeAdapter.h index 87e4457a..62c20204 100644 --- a/serialize/SerializeAdapter.h +++ b/serialize/SerializeAdapter.h @@ -65,6 +65,21 @@ // No type specification necessary here. class AutoSerializeAdapter { public: + /** + * Serialize object into buffer. + * @tparam T Type of object. + * @param object Object to serialize + * @param buffer + * Serialize into this buffer, pointer to pointer has to be passed, + * *buffer will be incremented automatically. + * @param size [out] + * Update passed size value, will be incremented by serialized size + * @param max_size + * Maximum size for range checking + * @param bigEndian + * Set to true if host-to-network conversion or vice-versa is needed + * @return + */ template static ReturnValue_t serialize(const T* object, uint8_t** buffer, size_t* size, const size_t max_size, bool bigEndian) { diff --git a/tasks/ExecutableObjectIF.h b/tasks/ExecutableObjectIF.h index 5c5955c1..516b4084 100644 --- a/tasks/ExecutableObjectIF.h +++ b/tasks/ExecutableObjectIF.h @@ -37,8 +37,10 @@ public: /** * @brief Function called during setup assignment of object to task - * @details Has to be called from the function that assigns the object to a task and - * enables the object implementation to overwrite this function and get a reference to the executing task + * @details + * Has to be called from the function that assigns the object to a task and + * enables the object implementation to overwrite this function and get + * a reference to the executing task * @param task_ Pointer to the taskIF of this task */ virtual void setTaskIF(PeriodicTaskIF* task_) { diff --git a/tmtcservices/CommandingServiceBase.cpp b/tmtcservices/CommandingServiceBase.cpp index 97856b40..4d29c10e 100644 --- a/tmtcservices/CommandingServiceBase.cpp +++ b/tmtcservices/CommandingServiceBase.cpp @@ -412,5 +412,6 @@ void CommandingServiceBase::checkTimeout() { } } - - +void CommandingServiceBase::setTaskIF(PeriodicTaskIF* task_) { + executingTask = task_; +} diff --git a/tmtcservices/CommandingServiceBase.h b/tmtcservices/CommandingServiceBase.h index 5e2c3171..05f50709 100644 --- a/tmtcservices/CommandingServiceBase.h +++ b/tmtcservices/CommandingServiceBase.h @@ -97,9 +97,7 @@ public: * Used to setup the reference of the task, that executes this component * @param task_ Pointer to the taskIF of this task */ - virtual void setTaskIF(PeriodicTaskIF* task_){ - executingTask = task_; - }; + virtual void setTaskIF(PeriodicTaskIF* task_); protected: /** From eb4ce980fe93feaba64f01cf13d43d96aaa7d20a Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 19 Jun 2020 14:32:04 +0200 Subject: [PATCH 152/307] small fixed --- osal/FreeRTOS/FixedTimeslotTask.cpp | 2 +- osal/FreeRTOS/PeriodicTask.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/osal/FreeRTOS/FixedTimeslotTask.cpp b/osal/FreeRTOS/FixedTimeslotTask.cpp index de99413e..ea324d35 100644 --- a/osal/FreeRTOS/FixedTimeslotTask.cpp +++ b/osal/FreeRTOS/FixedTimeslotTask.cpp @@ -114,7 +114,7 @@ void FixedTimeslotTask::taskFunctionality() { if(xTaskGetTickCount() - xLastWakeTime >= pdMS_TO_TICKS(this->pst.getIntervalToPreviousSlotMs())) { #ifdef DEBUG - sif::warning << "PeriodicTask: " << pcTaskGetName(NULL) << + sif::warning << "FixedTimeslotTask: " << pcTaskGetName(NULL) << " missed deadline!\n" << std::flush; #endif if(deadlineMissedFunc != nullptr) { diff --git a/osal/FreeRTOS/PeriodicTask.h b/osal/FreeRTOS/PeriodicTask.h index fd1dd0df..b9930a73 100644 --- a/osal/FreeRTOS/PeriodicTask.h +++ b/osal/FreeRTOS/PeriodicTask.h @@ -22,6 +22,7 @@ public: /** * Keep in Mind that you need to call before this vTaskStartScheduler()! * A lot of task parameters are set in "FreeRTOSConfig.h". + * TODO: why does this need to be called before vTaskStartScheduler? * @details * The class is initialized without allocated objects. * These need to be added with #addComponent. From 2de811e0afd0ae6a1dc9e4d700bedc693a888691 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 19 Jun 2020 20:14:56 +0200 Subject: [PATCH 153/307] moved timeslot files to task folder implmented setting task IF for regular periodic tasks --- osal/FreeRTOS/FixedTimeslotTask.cpp | 10 +++---- osal/FreeRTOS/FixedTimeslotTask.h | 10 +++---- osal/FreeRTOS/PeriodicTask.cpp | 14 ++++++---- osal/FreeRTOS/PeriodicTask.h | 9 ++++--- osal/host/FixedTimeslotTask.h | 2 +- osal/linux/PeriodicPosixTask.cpp | 7 ++++- osal/linux/PeriodicPosixTask.h | 3 ++- .../FixedSequenceSlot.cpp | 15 ++++------- {devicehandlers => tasks}/FixedSequenceSlot.h | 25 +++++++----------- .../FixedSlotSequence.cpp | 2 +- {devicehandlers => tasks}/FixedSlotSequence.h | 6 ++--- tasks/FixedTimeslotTaskIF.h | 11 ++++++-- tasks/PeriodicTaskIF.h | 26 ++++++++++++++++--- 13 files changed, 82 insertions(+), 58 deletions(-) rename {devicehandlers => tasks}/FixedSequenceSlot.cpp (53%) rename {devicehandlers => tasks}/FixedSequenceSlot.h (78%) rename {devicehandlers => tasks}/FixedSlotSequence.cpp (98%) rename {devicehandlers => tasks}/FixedSlotSequence.h (97%) diff --git a/osal/FreeRTOS/FixedTimeslotTask.cpp b/osal/FreeRTOS/FixedTimeslotTask.cpp index ea324d35..f3a65fcd 100644 --- a/osal/FreeRTOS/FixedTimeslotTask.cpp +++ b/osal/FreeRTOS/FixedTimeslotTask.cpp @@ -62,11 +62,6 @@ ReturnValue_t FixedTimeslotTask::startTask() { ReturnValue_t FixedTimeslotTask::addSlot(object_id_t componentId, uint32_t slotTimeMs, int8_t executionStep) { if (objectManager->get(componentId) != nullptr) { - if(slotTimeMs == 0) { - // FreeRTOS throws a sanity error for zero values, so we set - // the time to one millisecond. - slotTimeMs = 1; - } pst.addSlot(componentId, slotTimeMs, executionStep, this); return HasReturnvaluesIF::RETURN_OK; } @@ -101,7 +96,9 @@ void FixedTimeslotTask::taskFunctionality() { xLastWakeTime = xTaskGetTickCount(); // wait for first entry's start time - vTaskDelayUntil(&xLastWakeTime, interval); + if(interval > 0) { + vTaskDelayUntil(&xLastWakeTime, interval); + } /* Enter the loop that defines the task behavior. */ for (;;) { @@ -137,3 +134,4 @@ ReturnValue_t FixedTimeslotTask::sleepFor(uint32_t ms) { vTaskDelay(pdMS_TO_TICKS(ms)); return HasReturnvaluesIF::RETURN_OK; } + diff --git a/osal/FreeRTOS/FixedTimeslotTask.h b/osal/FreeRTOS/FixedTimeslotTask.h index 39db667c..183fad20 100644 --- a/osal/FreeRTOS/FixedTimeslotTask.h +++ b/osal/FreeRTOS/FixedTimeslotTask.h @@ -1,7 +1,7 @@ #ifndef FRAMEWORK_OSAL_FREERTOS_FIXEDTIMESLOTTASK_H_ #define FRAMEWORK_OSAL_FREERTOS_FIXEDTIMESLOTTASK_H_ -#include +#include #include #include @@ -49,13 +49,13 @@ public: static uint32_t deadlineMissedCount; ReturnValue_t addSlot(object_id_t componentId, uint32_t slotTimeMs, - int8_t executionStep); + int8_t executionStep) override; - uint32_t getPeriodMs() const; + uint32_t getPeriodMs() const override; - ReturnValue_t checkSequence() const; + ReturnValue_t checkSequence() const override; - ReturnValue_t sleepFor(uint32_t ms); + ReturnValue_t sleepFor(uint32_t ms) override; protected: bool started; diff --git a/osal/FreeRTOS/PeriodicTask.cpp b/osal/FreeRTOS/PeriodicTask.cpp index 31867639..43928f7c 100644 --- a/osal/FreeRTOS/PeriodicTask.cpp +++ b/osal/FreeRTOS/PeriodicTask.cpp @@ -70,9 +70,8 @@ void PeriodicTask::taskFunctionality() { xLastWakeTime = xTaskGetTickCount(); /* Enter the loop that defines the task behavior. */ for (;;) { - for (ObjectList::iterator it = objectList.begin(); - it != objectList.end(); ++it) { - (*it)->performOperation(); + for (auto const& object: objectList) { + object->performOperation(); } /* If all operations are finished and the difference of the @@ -93,12 +92,17 @@ void PeriodicTask::taskFunctionality() { } } -ReturnValue_t PeriodicTask::addComponent(object_id_t object) { +ReturnValue_t PeriodicTask::addComponent(object_id_t object, bool setTaskIF) { ExecutableObjectIF* newObject = objectManager->get( object); - if (newObject == NULL) { + if (newObject == nullptr) { + sif::error << "PeriodicTask::addComponent: Invalid object. Make sure" + "it implement ExecutableObjectIF" << std::endl; return HasReturnvaluesIF::RETURN_FAILED; } + if(setTaskIF) { + newObject->setTaskIF(this); + } objectList.push_back(newObject); return HasReturnvaluesIF::RETURN_OK; } diff --git a/osal/FreeRTOS/PeriodicTask.h b/osal/FreeRTOS/PeriodicTask.h index b9930a73..a580f519 100644 --- a/osal/FreeRTOS/PeriodicTask.h +++ b/osal/FreeRTOS/PeriodicTask.h @@ -54,7 +54,7 @@ public: * The address of the task object is passed as an argument * to the system call. */ - ReturnValue_t startTask(void); + ReturnValue_t startTask() override; /** * Adds an object to the list of objects to be executed. * The objects are executed in the order added. @@ -63,11 +63,12 @@ public: * -@c RETURN_OK on success * -@c RETURN_FAILED if the object could not be added. */ - ReturnValue_t addComponent(object_id_t object); + ReturnValue_t addComponent(object_id_t object, + bool setTaskIF = true) override; - uint32_t getPeriodMs() const; + uint32_t getPeriodMs() const override; - ReturnValue_t sleepFor(uint32_t ms); + ReturnValue_t sleepFor(uint32_t ms) override; protected: bool started; TaskHandle_t handle; diff --git a/osal/host/FixedTimeslotTask.h b/osal/host/FixedTimeslotTask.h index bb2f757a..b12cc6d3 100644 --- a/osal/host/FixedTimeslotTask.h +++ b/osal/host/FixedTimeslotTask.h @@ -2,7 +2,7 @@ #define FRAMEWORK_OSAL_HOST_FIXEDTIMESLOTTASK_H_ #include -#include +#include #include #include diff --git a/osal/linux/PeriodicPosixTask.cpp b/osal/linux/PeriodicPosixTask.cpp index df5bbf93..ca7011b0 100644 --- a/osal/linux/PeriodicPosixTask.cpp +++ b/osal/linux/PeriodicPosixTask.cpp @@ -24,9 +24,14 @@ void* PeriodicPosixTask::taskEntryPoint(void* arg) { ReturnValue_t PeriodicPosixTask::addComponent(object_id_t object) { ExecutableObjectIF* newObject = objectManager->get( object); - if (newObject == NULL) { + if (newObject == nullptr) { + sif::error << "PeriodicTask::addComponent: Invalid object. Make sure" + "it implements ExecutableObjectIF" << std::endl; return HasReturnvaluesIF::RETURN_FAILED; } + if(setTaskIF) { + newObject->setTaskIF(this); + } objectList.push_back(newObject); return HasReturnvaluesIF::RETURN_OK; } diff --git a/osal/linux/PeriodicPosixTask.h b/osal/linux/PeriodicPosixTask.h index 85de0d59..1d62a565 100644 --- a/osal/linux/PeriodicPosixTask.h +++ b/osal/linux/PeriodicPosixTask.h @@ -39,7 +39,8 @@ public: * @param object Id of the object to add. * @return RETURN_OK on success, RETURN_FAILED if the object could not be added. */ - ReturnValue_t addComponent(object_id_t object); + ReturnValue_t addComponent(object_id_t object, + bool setTaskIF = true) override; uint32_t getPeriodMs() const; diff --git a/devicehandlers/FixedSequenceSlot.cpp b/tasks/FixedSequenceSlot.cpp similarity index 53% rename from devicehandlers/FixedSequenceSlot.cpp rename to tasks/FixedSequenceSlot.cpp index bb97a8e5..c46b4fc0 100644 --- a/devicehandlers/FixedSequenceSlot.cpp +++ b/tasks/FixedSequenceSlot.cpp @@ -1,19 +1,14 @@ -/** - * @file PollingSlot.cpp - * @brief This file defines the PollingSlot class. - * @date 19.12.2012 - * @author baetz - */ - -#include #include +#include #include FixedSequenceSlot::FixedSequenceSlot(object_id_t handlerId, uint32_t setTime, int8_t setSequenceId, PeriodicTaskIF* executingTask) : - handler(NULL), pollingTimeMs(setTime), opcode(setSequenceId) { + pollingTimeMs(setTime), opcode(setSequenceId) { handler = objectManager->get(handlerId); - handler->setTaskIF(executingTask); + if(executingTask != nullptr) { + handler->setTaskIF(executingTask); + } } FixedSequenceSlot::~FixedSequenceSlot() {} diff --git a/devicehandlers/FixedSequenceSlot.h b/tasks/FixedSequenceSlot.h similarity index 78% rename from devicehandlers/FixedSequenceSlot.h rename to tasks/FixedSequenceSlot.h index 7868cce3..72a35c74 100644 --- a/devicehandlers/FixedSequenceSlot.h +++ b/tasks/FixedSequenceSlot.h @@ -1,22 +1,17 @@ -/** - * @file FixedSequenceSlot.h - * @brief This file defines the PollingSlot class. - * @date 19.12.2012 - * @author baetz - */ - -#ifndef FIXEDSEQUENCESLOT_H_ -#define FIXEDSEQUENCESLOT_H_ +#ifndef FRAMEWORK_TASKS_FIXEDSEQUENCESLOT_H_ +#define FRAMEWORK_TASKS_FIXEDSEQUENCESLOT_H_ #include #include class PeriodicTaskIF; /** - * @brief This class is the representation of a single polling sequence table entry. - * - * @details The PollingSlot class is the representation of a single polling - * sequence table entry. + * @brief This class is the representation of a single polling sequence + * table entry. + * @details + * The PollingSlot class is the representation of a single polling + * sequence table entry. + * @author baetz */ class FixedSequenceSlot { public: @@ -27,7 +22,7 @@ public: /** * @brief Handler identifies which device handler object is executed in this slot. */ - ExecutableObjectIF* handler; + ExecutableObjectIF* handler = nullptr; /** * @brief This attribute defines when a device handler object is executed. @@ -43,7 +38,7 @@ public: * @details The state of this value decides what communication routine is * called in the PST executable or the device handler object. */ - uint8_t opcode; + uint8_t opcode; /** * @brief Operator overload for the comparison operator to diff --git a/devicehandlers/FixedSlotSequence.cpp b/tasks/FixedSlotSequence.cpp similarity index 98% rename from devicehandlers/FixedSlotSequence.cpp rename to tasks/FixedSlotSequence.cpp index aeb97f3a..3e542bfc 100644 --- a/devicehandlers/FixedSlotSequence.cpp +++ b/tasks/FixedSlotSequence.cpp @@ -1,5 +1,5 @@ -#include #include +#include #include FixedSlotSequence::FixedSlotSequence(uint32_t setLengthMs) : diff --git a/devicehandlers/FixedSlotSequence.h b/tasks/FixedSlotSequence.h similarity index 97% rename from devicehandlers/FixedSlotSequence.h rename to tasks/FixedSlotSequence.h index 145cdbc3..7de1884c 100644 --- a/devicehandlers/FixedSlotSequence.h +++ b/tasks/FixedSlotSequence.h @@ -1,8 +1,8 @@ -#ifndef FIXEDSLOTSEQUENCE_H_ -#define FIXEDSLOTSEQUENCE_H_ +#ifndef FRAMEWORK_TASKS_FIXEDSLOTSEQUENCE_H_ +#define FRAMEWORK_TASKS_FIXEDSLOTSEQUENCE_H_ -#include #include +#include #include diff --git a/tasks/FixedTimeslotTaskIF.h b/tasks/FixedTimeslotTaskIF.h index 7edd6751..023b5ee0 100644 --- a/tasks/FixedTimeslotTaskIF.h +++ b/tasks/FixedTimeslotTaskIF.h @@ -12,11 +12,18 @@ class FixedTimeslotTaskIF : public PeriodicTaskIF { public: virtual ~FixedTimeslotTaskIF() {} + /** + * Add an object with a slot time and the execution step to the task. + * The execution step shall be passed to the object. + * @param componentId + * @param slotTimeMs + * @param executionStep + * @return + */ virtual ReturnValue_t addSlot(object_id_t componentId, uint32_t slotTimeMs, int8_t executionStep) = 0; + /** Check whether the sequence is valid */ virtual ReturnValue_t checkSequence() const = 0; }; - - #endif /* FRAMEWORK_TASKS_FIXEDTIMESLOTTASKIF_H_ */ diff --git a/tasks/PeriodicTaskIF.h b/tasks/PeriodicTaskIF.h index 304a7de6..6f490977 100644 --- a/tasks/PeriodicTaskIF.h +++ b/tasks/PeriodicTaskIF.h @@ -1,9 +1,11 @@ -#ifndef PERIODICTASKIF_H_ -#define PERIODICTASKIF_H_ +#ifndef FRAMEWORK_TASK_PERIODICTASKIF_H_ +#define FRAMEWORK_TASK_PERIODICTASKIF_H_ #include +#include #include class ExecutableObjectIF; + /** * New version of TaskIF * Follows RAII principles, i.e. there's no create or delete method. @@ -17,11 +19,27 @@ public: */ virtual ~PeriodicTaskIF() { } /** - * @brief With the startTask method, a created task can be started for the first time. + * @brief With the startTask method, a created task can be started + * for the first time. */ virtual ReturnValue_t startTask() = 0; - virtual ReturnValue_t addComponent(object_id_t object) {return HasReturnvaluesIF::RETURN_FAILED;}; + /** + * Add a component (object) to a periodic task. The pointer to the + * task can be set optionally + * @param object + * Add an object to the task. The most important case is to add an + * executable object with a function which will be called regularly + * (see ExecutableObjectIF) + * @param setTaskIF + * Can be used to specify whether the task object pointer is passed + * to the component. + * @return + */ + virtual ReturnValue_t addComponent(object_id_t object, + bool setTaskIF = true) { + return HasReturnvaluesIF::RETURN_FAILED; + }; virtual ReturnValue_t sleepFor(uint32_t ms) = 0; From 1b0e7c84c7ac2fff9e8b7129110271681c147620 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 19 Jun 2020 20:15:58 +0200 Subject: [PATCH 154/307] linux periodic task improvements --- osal/linux/PeriodicPosixTask.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/osal/linux/PeriodicPosixTask.cpp b/osal/linux/PeriodicPosixTask.cpp index ca7011b0..afdd3a52 100644 --- a/osal/linux/PeriodicPosixTask.cpp +++ b/osal/linux/PeriodicPosixTask.cpp @@ -1,12 +1,13 @@ #include #include -#include #include +#include + PeriodicPosixTask::PeriodicPosixTask(const char* name_, int priority_, size_t stackSize_, uint32_t period_, void(deadlineMissedFunc_)()): - PosixThread(name_,priority_,stackSize_),objectList(),started(false), - periodMs(period_),deadlineMissedFunc(deadlineMissedFunc_) { + PosixThread(name_, priority_, stackSize_), objectList(), started(false), + periodMs(period_), deadlineMissedFunc(deadlineMissedFunc_) { } PeriodicPosixTask::~PeriodicPosixTask() { From 2c04b87418f2552f836775e4c3eaa1b14bcd033c Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 19 Jun 2020 20:18:00 +0200 Subject: [PATCH 155/307] corrected includes --- osal/linux/FixedTimeslotTask.h | 2 +- osal/rtems/PollingTask.cpp | 2 +- osal/rtems/PollingTask.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osal/linux/FixedTimeslotTask.h b/osal/linux/FixedTimeslotTask.h index 916e6d6c..409cd982 100644 --- a/osal/linux/FixedTimeslotTask.h +++ b/osal/linux/FixedTimeslotTask.h @@ -2,7 +2,7 @@ #define FRAMEWORK_OSAL_LINUX_FIXEDTIMESLOTTASK_H_ #include -#include +#include #include #include diff --git a/osal/rtems/PollingTask.cpp b/osal/rtems/PollingTask.cpp index 6b0c0fbd..a6be7ddf 100644 --- a/osal/rtems/PollingTask.cpp +++ b/osal/rtems/PollingTask.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include #include diff --git a/osal/rtems/PollingTask.h b/osal/rtems/PollingTask.h index 82ec65a2..5bf8cf57 100644 --- a/osal/rtems/PollingTask.h +++ b/osal/rtems/PollingTask.h @@ -1,7 +1,7 @@ #ifndef POLLINGTASK_H_ #define POLLINGTASK_H_ -#include +#include #include #include "TaskBase.h" From 3936fe93609875c7f49332a8a5f24b09d67b7c1c Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 19 Jun 2020 20:34:19 +0200 Subject: [PATCH 156/307] linux fix --- osal/linux/PeriodicPosixTask.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osal/linux/PeriodicPosixTask.cpp b/osal/linux/PeriodicPosixTask.cpp index afdd3a52..fe8ac19c 100644 --- a/osal/linux/PeriodicPosixTask.cpp +++ b/osal/linux/PeriodicPosixTask.cpp @@ -22,7 +22,8 @@ void* PeriodicPosixTask::taskEntryPoint(void* arg) { return NULL; } -ReturnValue_t PeriodicPosixTask::addComponent(object_id_t object) { +ReturnValue_t PeriodicPosixTask::addComponent(object_id_t object, + bool setTaskIF) { ExecutableObjectIF* newObject = objectManager->get( object); if (newObject == nullptr) { From 95b646046b162d2c47e0a231ae8fad35cc733f21 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 19 Jun 2020 20:43:29 +0200 Subject: [PATCH 157/307] debug output working again --- events/EventManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/events/EventManager.cpp b/events/EventManager.cpp index 539f9e27..1eb88c32 100644 --- a/events/EventManager.cpp +++ b/events/EventManager.cpp @@ -133,7 +133,7 @@ void EventManager::printEvent(EventMessage* message) { break; default: string = translateObject(message->getReporter()); - sif::error << "EVENT: "; + sif::error << "EventManager: "; if (string != 0) { sif::error << string; } else { From 45a55044ddd3ded4cac2522313f1db53ac62c1d4 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 19 Jun 2020 20:47:36 +0200 Subject: [PATCH 158/307] using debug stream now --- events/EventManager.cpp | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/events/EventManager.cpp b/events/EventManager.cpp index 1eb88c32..30f5ed71 100644 --- a/events/EventManager.cpp +++ b/events/EventManager.cpp @@ -133,20 +133,23 @@ void EventManager::printEvent(EventMessage* message) { break; default: string = translateObject(message->getReporter()); - sif::error << "EventManager: "; + sif::debug << "EventManager: "; if (string != 0) { - sif::error << string; - } else { - sif::error << "0x" << std::hex << message->getReporter() << std::dec; + sif::debug << string; } - sif::error << " reported " << translateEvents(message->getEvent()) << " (" - << std::dec << message->getEventId() << ") " << std::endl; - - sif::error << std::hex << "P1 Hex: 0x" << message->getParameter1() << ", P1 Dec: " - << std::dec << message->getParameter1() << std::endl; - sif::error << std::hex << "P2 Hex: 0x" << message->getParameter2() << ", P2 Dec: " - << std::dec << message->getParameter2() << std::endl; + else { + sif::debug << "0x" << std::hex << message->getReporter() << std::dec; + } + sif::debug << " reported " << translateEvents(message->getEvent()) + << " (" << std::dec << message->getEventId() << ") " + << std::endl; + sif::debug << std::hex << "P1 Hex: 0x" << message->getParameter1() + << ", P1 Dec: " << std::dec << message->getParameter1() + << std::endl; + sif::debug << std::hex << "P2 Hex: 0x" << message->getParameter2() + << ", P2 Dec: " << std::dec << message->getParameter2() + << std::endl; break; } From 109fdad8b36ca1fe99f0ebad89fb28b04fa7d197 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 22 Jun 2020 15:34:35 +0200 Subject: [PATCH 159/307] size check for message queue --- osal/FreeRTOS/MessageQueue.cpp | 11 +++++++++-- osal/FreeRTOS/MessageQueue.h | 1 + 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/osal/FreeRTOS/MessageQueue.cpp b/osal/FreeRTOS/MessageQueue.cpp index d44b0bc0..cf6130f8 100644 --- a/osal/FreeRTOS/MessageQueue.cpp +++ b/osal/FreeRTOS/MessageQueue.cpp @@ -7,7 +7,8 @@ // As a first step towards this, introduces system context variable which needs // to be switched manually // Haven't found function to find system context. -MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize) { +MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize): + maxMessageSize(maxMessageSize) { handle = xQueueCreate(messageDepth, maxMessageSize); if (handle == NULL) { sif::error << "MessageQueue: Creation failed" << std::endl; @@ -120,10 +121,16 @@ bool MessageQueue::isDefaultDestinationSet() const { // static core function to send messages. ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, - MessageQueueMessageIF *message, MessageQueueId_t sentFrom, + MessageQueueMessageIF* message, MessageQueueId_t sentFrom, bool ignoreFault, CallContext callContext) { message->setSender(sentFrom); BaseType_t result; + if(message->getMaximumMessageSize() > maxMessageSize) { + sif::error << "MessageQueue::sendMessageFromMessageQueue: Message size" + "too large for queue!" << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + if(callContext == CallContext::TASK) { result = xQueueSendToBack(reinterpret_cast(sendTo), static_cast(message->getBuffer()), 0); diff --git a/osal/FreeRTOS/MessageQueue.h b/osal/FreeRTOS/MessageQueue.h index c13a8a20..b7e52bb3 100644 --- a/osal/FreeRTOS/MessageQueue.h +++ b/osal/FreeRTOS/MessageQueue.h @@ -204,6 +204,7 @@ private: QueueHandle_t handle; MessageQueueId_t defaultDestination = 0; MessageQueueId_t lastPartner = 0; + const size_t maxMessageSize; //!< Stores the current system context CallContext callContext = CallContext::TASK; }; From 3b2fa978e1b86ccf1b9c113ab958dcaf81e63b4a Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 22 Jun 2020 19:06:10 +0200 Subject: [PATCH 160/307] replaced break with continue --- osal/FreeRTOS/FixedTimeslotTask.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osal/FreeRTOS/FixedTimeslotTask.cpp b/osal/FreeRTOS/FixedTimeslotTask.cpp index f3a65fcd..5d16a408 100644 --- a/osal/FreeRTOS/FixedTimeslotTask.cpp +++ b/osal/FreeRTOS/FixedTimeslotTask.cpp @@ -118,7 +118,7 @@ void FixedTimeslotTask::taskFunctionality() { this->deadlineMissedFunc(); } // Continue immediately, no need to wait. - break; + continue; } // we need to wait before executing the current slot From 5734a0a0e948df50c57f9d589a2eddac479bb70b Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 22 Jun 2020 19:22:52 +0200 Subject: [PATCH 161/307] some fixes necessary to perform size check --- action/ActionHelper.cpp | 3 ++- datalinklayer/MapPacketExtraction.cpp | 3 ++- ipc/MessageQueueSenderIF.h | 2 +- monitoring/LimitViolationReporter.cpp | 3 ++- osal/FreeRTOS/MessageQueue.cpp | 8 ++++---- osal/FreeRTOS/MessageQueue.h | 5 +++-- osal/FreeRTOS/QueueFactory.cpp | 6 +++--- tmtcservices/VerificationReporter.cpp | 12 ++++++++---- 8 files changed, 25 insertions(+), 17 deletions(-) diff --git a/action/ActionHelper.cpp b/action/ActionHelper.cpp index 0df5f2d4..026df4e1 100644 --- a/action/ActionHelper.cpp +++ b/action/ActionHelper.cpp @@ -101,7 +101,8 @@ ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo, //TODO Service Implementation sucks at the moment if (hideSender){ - result = MessageQueueSenderIF::sendMessage(reportTo, &reply); + result = MessageQueueSenderIF::sendMessage(reportTo, &reply, + MessageQueueMessage::MAX_MESSAGE_SIZE); } else { result = queueToUse->sendMessage(reportTo, &reply); } diff --git a/datalinklayer/MapPacketExtraction.cpp b/datalinklayer/MapPacketExtraction.cpp index 4ea45e89..87b46556 100644 --- a/datalinklayer/MapPacketExtraction.cpp +++ b/datalinklayer/MapPacketExtraction.cpp @@ -117,7 +117,8 @@ ReturnValue_t MapPacketExtraction::sendCompletePacket(uint8_t* data, ReturnValue_t status = this->packetStore->addData(&store_id, data, size); if (status == RETURN_OK) { TmTcMessage message(store_id); - status = MessageQueueSenderIF::sendMessage(tcQueueId,&message); + status = MessageQueueSenderIF::sendMessage(tcQueueId,&message, + MessageQueueMessage::MAX_MESSAGE_SIZE); } return status; } diff --git a/ipc/MessageQueueSenderIF.h b/ipc/MessageQueueSenderIF.h index 3172454f..912f4d7e 100644 --- a/ipc/MessageQueueSenderIF.h +++ b/ipc/MessageQueueSenderIF.h @@ -15,7 +15,7 @@ public: * Must be implemented by a subclass. */ static ReturnValue_t sendMessage(MessageQueueId_t sendTo, - MessageQueueMessageIF* message, + MessageQueueMessageIF* message, size_t maxMessageSize, MessageQueueId_t sentFrom = MessageQueueMessageIF::NO_QUEUE, bool ignoreFault=false); private: diff --git a/monitoring/LimitViolationReporter.cpp b/monitoring/LimitViolationReporter.cpp index 1378d754..c6e2b5db 100644 --- a/monitoring/LimitViolationReporter.cpp +++ b/monitoring/LimitViolationReporter.cpp @@ -34,7 +34,8 @@ ReturnValue_t LimitViolationReporter::sendLimitViolationReport(const SerializeIF MessageQueueMessage message; CommandMessage report(&message); MonitoringMessage::setLimitViolationReport(&report, storeId); - return MessageQueueSenderIF::sendMessage(reportQueue, &report); + return MessageQueueSenderIF::sendMessage(reportQueue, &report, + MessageQueueMessage::MAX_MESSAGE_SIZE); } ReturnValue_t LimitViolationReporter::checkClassLoaded() { diff --git a/osal/FreeRTOS/MessageQueue.cpp b/osal/FreeRTOS/MessageQueue.cpp index cf6130f8..0280869d 100644 --- a/osal/FreeRTOS/MessageQueue.cpp +++ b/osal/FreeRTOS/MessageQueue.cpp @@ -50,7 +50,7 @@ ReturnValue_t MessageQueue::reply(MessageQueueMessageIF* message) { ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message, MessageQueueId_t sentFrom, bool ignoreFault) { - return sendMessageFromMessageQueue(sendTo, message, sentFrom, + return sendMessageFromMessageQueue(sendTo, message, maxMessageSize, sentFrom, ignoreFault, callContext); } @@ -121,11 +121,11 @@ bool MessageQueue::isDefaultDestinationSet() const { // static core function to send messages. ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, - MessageQueueMessageIF* message, MessageQueueId_t sentFrom, - bool ignoreFault, CallContext callContext) { + MessageQueueMessageIF* message, size_t maxSize, + MessageQueueId_t sentFrom, bool ignoreFault, CallContext callContext) { message->setSender(sentFrom); BaseType_t result; - if(message->getMaximumMessageSize() > maxMessageSize) { + if(message->getMaximumMessageSize() > maxSize) { sif::error << "MessageQueue::sendMessageFromMessageQueue: Message size" "too large for queue!" << std::endl; return HasReturnvaluesIF::RETURN_FAILED; diff --git a/osal/FreeRTOS/MessageQueue.h b/osal/FreeRTOS/MessageQueue.h index b7e52bb3..e87e884f 100644 --- a/osal/FreeRTOS/MessageQueue.h +++ b/osal/FreeRTOS/MessageQueue.h @@ -194,8 +194,9 @@ protected: * @param context Specify whether call is made from task or from an ISR. */ static ReturnValue_t sendMessageFromMessageQueue(MessageQueueId_t sendTo, - MessageQueueMessageIF* message, MessageQueueId_t sentFrom = NO_QUEUE, - bool ignoreFault=false, CallContext callContext = CallContext::TASK); + MessageQueueMessageIF* message, size_t maxSize, + MessageQueueId_t sentFrom = NO_QUEUE, bool ignoreFault=false, + CallContext callContext = CallContext::TASK); static ReturnValue_t handleSendResult(BaseType_t result, bool ignoreFault); diff --git a/osal/FreeRTOS/QueueFactory.cpp b/osal/FreeRTOS/QueueFactory.cpp index beb4969b..ec678890 100644 --- a/osal/FreeRTOS/QueueFactory.cpp +++ b/osal/FreeRTOS/QueueFactory.cpp @@ -7,9 +7,9 @@ QueueFactory* QueueFactory::factoryInstance = nullptr; ReturnValue_t MessageQueueSenderIF::sendMessage(MessageQueueId_t sendTo, - MessageQueueMessageIF* message, MessageQueueId_t sentFrom, - bool ignoreFault) { - return MessageQueue::sendMessageFromMessageQueue(sendTo,message, + MessageQueueMessageIF* message, size_t maxSize, + MessageQueueId_t sentFrom, bool ignoreFault) { + return MessageQueue::sendMessageFromMessageQueue(sendTo,message, maxSize, sentFrom,ignoreFault); } diff --git a/tmtcservices/VerificationReporter.cpp b/tmtcservices/VerificationReporter.cpp index b0247944..a54c1f8d 100644 --- a/tmtcservices/VerificationReporter.cpp +++ b/tmtcservices/VerificationReporter.cpp @@ -22,7 +22,8 @@ void VerificationReporter::sendSuccessReport(uint8_t set_report_id, current_packet->getAcknowledgeFlags(), current_packet->getPacketId(), current_packet->getPacketSequenceControl(), 0, set_step); - ReturnValue_t status = MessageQueueSenderIF::sendMessage(acknowledgeQueue, &message); + ReturnValue_t status = MessageQueueSenderIF::sendMessage(acknowledgeQueue, + &message, MessageQueueMessage::MAX_MESSAGE_SIZE); if (status != HasReturnvaluesIF::RETURN_OK) { sif::error << "VerificationReporter::sendSuccessReport: Error writing " "to queue. Code: " << std::hex << (uint16_t) status << std::endl; @@ -37,7 +38,8 @@ void VerificationReporter::sendSuccessReport(uint8_t set_report_id, } PusVerificationMessage message(set_report_id, ackFlags, tcPacketId, tcSequenceControl, 0, set_step); - ReturnValue_t status = MessageQueueSenderIF::sendMessage(acknowledgeQueue, &message); + ReturnValue_t status = MessageQueueSenderIF::sendMessage(acknowledgeQueue, + &message, MessageQueueMessage::MAX_MESSAGE_SIZE); if (status != HasReturnvaluesIF::RETURN_OK) { sif::error << "VerificationReporter::sendSuccessReport: Error writing " "to queue. Code: " << std::hex << (uint16_t) status << std::endl; @@ -55,7 +57,8 @@ void VerificationReporter::sendFailureReport(uint8_t report_id, current_packet->getPacketId(), current_packet->getPacketSequenceControl(), error_code, step, parameter1, parameter2); - ReturnValue_t status = MessageQueueSenderIF::sendMessage(acknowledgeQueue, &message); + ReturnValue_t status = MessageQueueSenderIF::sendMessage(acknowledgeQueue, + &message, MessageQueueMessage::MAX_MESSAGE_SIZE); if (status != HasReturnvaluesIF::RETURN_OK) { sif::error << "VerificationReporter::sendFailureReport Error writing to queue. Code: " @@ -72,7 +75,8 @@ void VerificationReporter::sendFailureReport(uint8_t report_id, } PusVerificationMessage message(report_id, ackFlags, tcPacketId, tcSequenceControl, error_code, step, parameter1, parameter2); - ReturnValue_t status = MessageQueueSenderIF::sendMessage(acknowledgeQueue, &message); + ReturnValue_t status = MessageQueueSenderIF::sendMessage(acknowledgeQueue, + &message, MessageQueueMessage::MAX_MESSAGE_SIZE); if (status != HasReturnvaluesIF::RETURN_OK) { sif::error << "VerificationReporter::sendFailureReport Error writing to queue. Code: " From dadc867d9ed44d82782d2f3f66cc0f54b50bfe00 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 22 Jun 2020 20:18:13 +0200 Subject: [PATCH 162/307] adapted MessageQueueSenderIF function calls --- events/EventManager.cpp | 3 ++- events/EventManagerIF.h | 3 ++- health/HealthHelper.cpp | 6 ++++-- modes/ModeHelper.cpp | 11 +++++++---- osal/FreeRTOS/FixedTimeslotTask.cpp | 16 +++++++--------- osal/FreeRTOS/MessageQueue.cpp | 12 ++++++++++-- osal/FreeRTOS/QueueFactory.cpp | 5 +++++ parameters/ParameterHelper.cpp | 6 ++++-- tmtcpacket/pus/TmPacketStored.cpp | 3 ++- 9 files changed, 43 insertions(+), 22 deletions(-) diff --git a/events/EventManager.cpp b/events/EventManager.cpp index 30f5ed71..a5d14569 100644 --- a/events/EventManager.cpp +++ b/events/EventManager.cpp @@ -52,7 +52,8 @@ void EventManager::notifyListeners(EventMessage* message) { for (auto iter = listenerList.begin(); iter != listenerList.end(); ++iter) { if (iter->second.match(message)) { MessageQueueSenderIF::sendMessage(iter->first, message, - message->getSender()); + MessageQueueMessage::MAX_MESSAGE_SIZE, + message->getSender()); } } unlockMutex(); diff --git a/events/EventManagerIF.h b/events/EventManagerIF.h index bc0de432..053e320b 100644 --- a/events/EventManagerIF.h +++ b/events/EventManagerIF.h @@ -44,7 +44,8 @@ public: eventmanagerQueue = eventmanager->getEventReportQueue(); } } - MessageQueueSenderIF::sendMessage(eventmanagerQueue, message, sentFrom); + MessageQueueSenderIF::sendMessage(eventmanagerQueue, message, + MessageQueueMessage::MAX_MESSAGE_SIZE, sentFrom); } }; diff --git a/health/HealthHelper.cpp b/health/HealthHelper.cpp index df259b52..935bf5e3 100644 --- a/health/HealthHelper.cpp +++ b/health/HealthHelper.cpp @@ -70,7 +70,8 @@ void HealthHelper::informParent(HasHealthIF::HealthState health, HealthMessage::setHealthMessage(&information, HealthMessage::HEALTH_INFO, health, oldHealth); if (MessageQueueSenderIF::sendMessage(parentQueue, &information, - owner->getCommandQueue()) != HasReturnvaluesIF::RETURN_OK) { + MessageQueueMessage::MAX_MESSAGE_SIZE, + owner->getCommandQueue()) != HasReturnvaluesIF::RETURN_OK) { sif::debug << "HealthHelper::informParent: sending health reply failed." << std::endl; } @@ -90,7 +91,8 @@ void HealthHelper::handleSetHealthCommand(CommandMessage* command) { reply.setReplyRejected(result, command->getCommand()); } if (MessageQueueSenderIF::sendMessage(command->getSender(), &reply, - owner->getCommandQueue()) != HasReturnvaluesIF::RETURN_OK) { + MessageQueueMessage::MAX_MESSAGE_SIZE, + owner->getCommandQueue()) != HasReturnvaluesIF::RETURN_OK) { sif::debug << "HealthHelper::handleHealthCommand: sending health " "reply failed." << std::endl; diff --git a/modes/ModeHelper.cpp b/modes/ModeHelper.cpp index b79082af..f636c0bf 100644 --- a/modes/ModeHelper.cpp +++ b/modes/ModeHelper.cpp @@ -28,7 +28,8 @@ ReturnValue_t ModeHelper::handleModeCommand(CommandMessage* command) { if (result != HasReturnvaluesIF::RETURN_OK) { ModeMessage::cantReachMode(&reply, result); MessageQueueSenderIF::sendMessage(command->getSender(), &reply, - owner->getCommandQueue()); + MessageQueueMessage::MAX_MESSAGE_SIZE, + owner->getCommandQueue()); break; } //Free to start transition @@ -50,7 +51,8 @@ ReturnValue_t ModeHelper::handleModeCommand(CommandMessage* command) { ModeMessage::setModeMessage(&reply, ModeMessage::REPLY_MODE_REPLY, mode, submode); MessageQueueSenderIF::sendMessage(command->getSender(), &reply, - owner->getCommandQueue()); + MessageQueueMessage::MAX_MESSAGE_SIZE, + owner->getCommandQueue()); } break; case ModeMessage::CMD_MODE_ANNOUNCE: @@ -95,7 +97,7 @@ void ModeHelper::sendModeReplyMessage(Mode_t ownerMode, ownerMode, ownerSubmode); } MessageQueueSenderIF::sendMessage(theOneWhoCommandedAMode, &reply, - owner->getCommandQueue()); + MessageQueueMessage::MAX_MESSAGE_SIZE, owner->getCommandQueue()); } } @@ -109,7 +111,8 @@ void ModeHelper::sendModeInfoMessage(Mode_t ownerMode, ModeMessage::setModeMessage(&reply, ModeMessage::REPLY_MODE_INFO, ownerMode, ownerSubmode); MessageQueueSenderIF::sendMessage(parentQueueId, &reply, - owner->getCommandQueue()); + MessageQueueMessage::MAX_MESSAGE_SIZE, + owner->getCommandQueue()); } } diff --git a/osal/FreeRTOS/FixedTimeslotTask.cpp b/osal/FreeRTOS/FixedTimeslotTask.cpp index 5d16a408..4d4ec996 100644 --- a/osal/FreeRTOS/FixedTimeslotTask.cpp +++ b/osal/FreeRTOS/FixedTimeslotTask.cpp @@ -105,11 +105,14 @@ void FixedTimeslotTask::taskFunctionality() { //The component for this slot is executed and the next one is chosen. this->pst.executeAndAdvance(); if (not pst.slotFollowsImmediately()) { + // Get the interval till execution of the next slot. + intervalMs = this->pst.getIntervalToPreviousSlotMs(); + interval = pdMS_TO_TICKS(intervalMs); + /* If all operations are finished and the difference of the * current time minus the last wake time is larger than the * expected wait period, a deadline was missed. */ - if(xTaskGetTickCount() - xLastWakeTime >= - pdMS_TO_TICKS(this->pst.getIntervalToPreviousSlotMs())) { + if(xTaskGetTickCount() - xLastWakeTime >= interval) { #ifdef DEBUG sif::warning << "FixedTimeslotTask: " << pcTaskGetName(NULL) << " missed deadline!\n" << std::flush; @@ -117,14 +120,9 @@ void FixedTimeslotTask::taskFunctionality() { if(deadlineMissedFunc != nullptr) { this->deadlineMissedFunc(); } - // Continue immediately, no need to wait. - continue; } - - // we need to wait before executing the current slot - //this gives us the time to wait: - intervalMs = this->pst.getIntervalToPreviousSlotMs(); - interval = pdMS_TO_TICKS(intervalMs); + // Wait for the interval. This exits immediately if a deadline was + // missed while also updating the last wake time. vTaskDelayUntil(&xLastWakeTime, interval); } } diff --git a/osal/FreeRTOS/MessageQueue.cpp b/osal/FreeRTOS/MessageQueue.cpp index 0280869d..c9adf229 100644 --- a/osal/FreeRTOS/MessageQueue.cpp +++ b/osal/FreeRTOS/MessageQueue.cpp @@ -80,6 +80,12 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message, } ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) { + if(message->getMaximumMessageSize() < maxMessageSize) { + sif::error << "MessageQueue::receiveMessage: Message size " + << message->getMaximumMessageSize() << + " too small to receive data!" << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } BaseType_t result = xQueueReceive(handle,reinterpret_cast( message->getBuffer()), 0); if (result == pdPASS){ @@ -126,8 +132,10 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, message->setSender(sentFrom); BaseType_t result; if(message->getMaximumMessageSize() > maxSize) { - sif::error << "MessageQueue::sendMessageFromMessageQueue: Message size" - "too large for queue!" << std::endl; + sif::error << "MessageQueue::sendMessageFromMessageQueue: Message size " + << message->getMaximumMessageSize() << " too large for queue" + " with max. message size " << maxSize << "!" + << std::endl; return HasReturnvaluesIF::RETURN_FAILED; } diff --git a/osal/FreeRTOS/QueueFactory.cpp b/osal/FreeRTOS/QueueFactory.cpp index ec678890..d754b2b9 100644 --- a/osal/FreeRTOS/QueueFactory.cpp +++ b/osal/FreeRTOS/QueueFactory.cpp @@ -9,6 +9,11 @@ QueueFactory* QueueFactory::factoryInstance = nullptr; ReturnValue_t MessageQueueSenderIF::sendMessage(MessageQueueId_t sendTo, MessageQueueMessageIF* message, size_t maxSize, MessageQueueId_t sentFrom, bool ignoreFault) { + if(maxSize == 0) { + sif::error << "MessageQueueSenderIF::sendMessage: Max Size is 0!" + << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } return MessageQueue::sendMessageFromMessageQueue(sendTo,message, maxSize, sentFrom,ignoreFault); } diff --git a/parameters/ParameterHelper.cpp b/parameters/ParameterHelper.cpp index 8b91020f..68ff5ab0 100644 --- a/parameters/ParameterHelper.cpp +++ b/parameters/ParameterHelper.cpp @@ -107,7 +107,8 @@ ReturnValue_t ParameterHelper::sendParameter(MessageQueueId_t to, uint32_t id, ParameterMessage::setParameterDumpReply(&reply, id, address); - MessageQueueSenderIF::sendMessage(to, &reply, ownerQueueId); + MessageQueueSenderIF::sendMessage(to, &reply, + MessageQueueMessage::MAX_MESSAGE_SIZE, ownerQueueId); return HasReturnvaluesIF::RETURN_OK; } @@ -129,5 +130,6 @@ void ParameterHelper::rejectCommand(MessageQueueId_t to, ReturnValue_t reason, MessageQueueMessage message; CommandMessage reply(&message); reply.setReplyRejected(reason, initialCommand); - MessageQueueSenderIF::sendMessage(to, &reply, ownerQueueId); + MessageQueueSenderIF::sendMessage(to, &reply, + MessageQueueMessage::MAX_MESSAGE_SIZE, ownerQueueId); } diff --git a/tmtcpacket/pus/TmPacketStored.cpp b/tmtcpacket/pus/TmPacketStored.cpp index 42d0d038..d589db8d 100644 --- a/tmtcpacket/pus/TmPacketStored.cpp +++ b/tmtcpacket/pus/TmPacketStored.cpp @@ -117,7 +117,8 @@ ReturnValue_t TmPacketStored::sendPacket(MessageQueueId_t destination, return HasReturnvaluesIF::RETURN_FAILED; } TmTcMessage tmMessage(getStoreAddress()); - ReturnValue_t result = MessageQueueSenderIF::sendMessage(destination, &tmMessage, sentFrom); + ReturnValue_t result = MessageQueueSenderIF::sendMessage(destination, + &tmMessage, MessageQueueMessage::MAX_MESSAGE_SIZE, sentFrom); if (result != HasReturnvaluesIF::RETURN_OK) { deletePacket(); if (doErrorReporting) { From 6a7f47e06d95c91f8f9885c38f0716894735a10a Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 22 Jun 2020 23:46:44 +0200 Subject: [PATCH 163/307] doc fix --- osal/FreeRTOS/FixedTimeslotTask.cpp | 56 ++++++++++++++++++++--------- osal/FreeRTOS/FixedTimeslotTask.h | 6 +++- 2 files changed, 45 insertions(+), 17 deletions(-) diff --git a/osal/FreeRTOS/FixedTimeslotTask.cpp b/osal/FreeRTOS/FixedTimeslotTask.cpp index 4d4ec996..57c927f9 100644 --- a/osal/FreeRTOS/FixedTimeslotTask.cpp +++ b/osal/FreeRTOS/FixedTimeslotTask.cpp @@ -82,7 +82,7 @@ ReturnValue_t FixedTimeslotTask::checkSequence() const { void FixedTimeslotTask::taskFunctionality() { // A local iterator for the Polling Sequence Table is created to find the // start time for the first entry. - SlotListIter slotListIter = pst.current; + auto slotListIter = pst.current; //The start time for the first entry is read. uint32_t intervalMs = slotListIter->pollingTimeMs; @@ -90,9 +90,9 @@ void FixedTimeslotTask::taskFunctionality() { TickType_t xLastWakeTime; /* The xLastWakeTime variable needs to be initialized with the current tick - count. Note that this is the only time the variable is written to explicitly. - After this assignment, xLastWakeTime is updated automatically internally within - vTaskDelayUntil(). */ + count. Note that this is the only time the variable is written to + explicitly. After this assignment, xLastWakeTime is updated automatically + internally within vTaskDelayUntil(). */ xLastWakeTime = xTaskGetTickCount(); // wait for first entry's start time @@ -109,18 +109,8 @@ void FixedTimeslotTask::taskFunctionality() { intervalMs = this->pst.getIntervalToPreviousSlotMs(); interval = pdMS_TO_TICKS(intervalMs); - /* If all operations are finished and the difference of the - * current time minus the last wake time is larger than the - * expected wait period, a deadline was missed. */ - if(xTaskGetTickCount() - xLastWakeTime >= interval) { -#ifdef DEBUG - sif::warning << "FixedTimeslotTask: " << pcTaskGetName(NULL) << - " missed deadline!\n" << std::flush; -#endif - if(deadlineMissedFunc != nullptr) { - this->deadlineMissedFunc(); - } - } + checkMissedDeadline(xLastWakeTime, interval); + // Wait for the interval. This exits immediately if a deadline was // missed while also updating the last wake time. vTaskDelayUntil(&xLastWakeTime, interval); @@ -128,6 +118,40 @@ void FixedTimeslotTask::taskFunctionality() { } } +void FixedTimeslotTask::checkMissedDeadline(const TickType_t xLastWakeTime, + const TickType_t interval) { + /* Check whether deadline was missed while also taking overflows + * into account. Drawing this on paper with a timeline helps to understand + * it. */ + TickType_t currentTickCount = xTaskGetTickCount(); + TickType_t timeToWake = xLastWakeTime + interval; + // Tick count has overflown + if(currentTickCount < xLastWakeTime) { + // Time to wake has overflown as well. If the tick count + // is larger than the time to wake, a deadline was missed. + if(timeToWake < xLastWakeTime and + currentTickCount > timeToWake) { + handleMissedDeadline(); + } + } + // No tick count overflow. If the timeToWake has not overflown + // and the current tick count is larger than the time to wake, + // a deadline was missed. + else if(timeToWake > xLastWakeTime and currentTickCount > timeToWake) { + handleMissedDeadline(); + } +} + +void FixedTimeslotTask::handleMissedDeadline() { +#ifdef DEBUG + sif::warning << "FixedTimeslotTask: " << pcTaskGetName(NULL) << + " missed deadline!\n" << std::flush; +#endif + if(deadlineMissedFunc != nullptr) { + this->deadlineMissedFunc(); + } +} + ReturnValue_t FixedTimeslotTask::sleepFor(uint32_t ms) { vTaskDelay(pdMS_TO_TICKS(ms)); return HasReturnvaluesIF::RETURN_OK; diff --git a/osal/FreeRTOS/FixedTimeslotTask.h b/osal/FreeRTOS/FixedTimeslotTask.h index 183fad20..32289f4b 100644 --- a/osal/FreeRTOS/FixedTimeslotTask.h +++ b/osal/FreeRTOS/FixedTimeslotTask.h @@ -12,7 +12,7 @@ class FixedTimeslotTask: public FixedTimeslotTaskIF { public: /** - * Keep in Mind that you need to call before this vTaskStartScheduler()! + * Keep in Mind that you need to call before vTaskStartScheduler()! * A lot of task parameters are set in "FreeRTOSConfig.h". * @param name Name of the task, lenght limited by configMAX_TASK_NAME_LEN * @param setPriority Number of priorities specified by @@ -89,6 +89,10 @@ protected: * OS's System Calls to keep the timing of the periods. */ void taskFunctionality(void); + + void checkMissedDeadline(const TickType_t xLastWakeTime, + const TickType_t interval); + void handleMissedDeadline(); }; #endif /* POLLINGTASK_H_ */ From a82dbcbd501a6c035430f8394d5eaebe06480918 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 22 Jun 2020 23:47:18 +0200 Subject: [PATCH 164/307] minor doc correction --- osal/FreeRTOS/FixedTimeslotTask.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osal/FreeRTOS/FixedTimeslotTask.h b/osal/FreeRTOS/FixedTimeslotTask.h index 32289f4b..27d08190 100644 --- a/osal/FreeRTOS/FixedTimeslotTask.h +++ b/osal/FreeRTOS/FixedTimeslotTask.h @@ -12,7 +12,7 @@ class FixedTimeslotTask: public FixedTimeslotTaskIF { public: /** - * Keep in Mind that you need to call before vTaskStartScheduler()! + * Keep in mind that you need to call before vTaskStartScheduler()! * A lot of task parameters are set in "FreeRTOSConfig.h". * @param name Name of the task, lenght limited by configMAX_TASK_NAME_LEN * @param setPriority Number of priorities specified by From 847292ea30e3c71678b0cf994e6436caad71a463 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 23 Jun 2020 01:10:19 +0200 Subject: [PATCH 165/307] added overflow checking for periodic task --- osal/FreeRTOS/PeriodicTask.cpp | 47 +++++++++++++++++++++++++--------- osal/FreeRTOS/PeriodicTask.h | 4 +++ 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/osal/FreeRTOS/PeriodicTask.cpp b/osal/FreeRTOS/PeriodicTask.cpp index 43928f7c..fa49150e 100644 --- a/osal/FreeRTOS/PeriodicTask.cpp +++ b/osal/FreeRTOS/PeriodicTask.cpp @@ -74,18 +74,7 @@ void PeriodicTask::taskFunctionality() { object->performOperation(); } - /* If all operations are finished and the difference of the - * current time minus the last wake time is larger than the - * wait period, a deadline was missed. */ - if(xTaskGetTickCount() - xLastWakeTime >= xPeriod) { -#ifdef DEBUG - sif::warning << "PeriodicTask: " << pcTaskGetName(NULL) << - " missed deadline!\n" << std::flush; -#endif - if(deadlineMissedFunc != nullptr) { - this->deadlineMissedFunc(); - } - } + checkMissedDeadline(xLastWakeTime, xPeriod); vTaskDelayUntil(&xLastWakeTime, xPeriod); @@ -110,3 +99,37 @@ ReturnValue_t PeriodicTask::addComponent(object_id_t object, bool setTaskIF) { uint32_t PeriodicTask::getPeriodMs() const { return period * 1000; } + +void PeriodicTask::checkMissedDeadline(const TickType_t xLastWakeTime, + const TickType_t interval) { + /* Check whether deadline was missed while also taking overflows + * into account. Drawing this on paper with a timeline helps to understand + * it. */ + TickType_t currentTickCount = xTaskGetTickCount(); + TickType_t timeToWake = xLastWakeTime + interval; + // Tick count has overflown + if(currentTickCount < xLastWakeTime) { + // Time to wake has overflown as well. If the tick count + // is larger than the time to wake, a deadline was missed. + if(timeToWake < xLastWakeTime and + currentTickCount > timeToWake) { + handleMissedDeadline(); + } + } + // No tick count overflow. If the timeToWake has not overflown + // and the current tick count is larger than the time to wake, + // a deadline was missed. + else if(timeToWake > xLastWakeTime and currentTickCount > timeToWake) { + handleMissedDeadline(); + } +} + +void PeriodicTask::handleMissedDeadline() { +#ifdef DEBUG + sif::warning << "PeriodicTask: " << pcTaskGetName(NULL) << + " missed deadline!\n" << std::flush; +#endif + if(deadlineMissedFunc != nullptr) { + this->deadlineMissedFunc(); + } +} diff --git a/osal/FreeRTOS/PeriodicTask.h b/osal/FreeRTOS/PeriodicTask.h index a580f519..09aa6bc7 100644 --- a/osal/FreeRTOS/PeriodicTask.h +++ b/osal/FreeRTOS/PeriodicTask.h @@ -116,6 +116,10 @@ protected: * On missing the deadline, the deadlineMissedFunction is executed. */ void taskFunctionality(void); + + void checkMissedDeadline(const TickType_t xLastWakeTime, + const TickType_t interval); + void handleMissedDeadline(); }; #endif /* PERIODICTASK_H_ */ From f7d55a8a37559bf9717b49e414c19db99c5113e9 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 23 Jun 2020 01:15:35 +0200 Subject: [PATCH 166/307] equal to pull request now --- osal/FreeRTOS/PeriodicTask.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/osal/FreeRTOS/PeriodicTask.cpp b/osal/FreeRTOS/PeriodicTask.cpp index fa49150e..170eb0a4 100644 --- a/osal/FreeRTOS/PeriodicTask.cpp +++ b/osal/FreeRTOS/PeriodicTask.cpp @@ -89,10 +89,11 @@ ReturnValue_t PeriodicTask::addComponent(object_id_t object, bool setTaskIF) { "it implement ExecutableObjectIF" << std::endl; return HasReturnvaluesIF::RETURN_FAILED; } - if(setTaskIF) { - newObject->setTaskIF(this); - } objectList.push_back(newObject); + + if(setTaskIF) { + newObject->setTaskIF(this); + } return HasReturnvaluesIF::RETURN_OK; } From 64a02c55ba9c0f067e64b460b66750b613a31526 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 23 Jun 2020 01:37:25 +0200 Subject: [PATCH 167/307] linux fixed, size checks added --- osal/linux/MessageQueue.cpp | 50 +++++++++++++++++++++++++------- osal/linux/MessageQueue.h | 6 ++-- osal/linux/PeriodicPosixTask.cpp | 14 +++++---- osal/linux/PeriodicPosixTask.h | 6 ++-- osal/linux/QueueFactory.cpp | 6 ++-- 5 files changed, 58 insertions(+), 24 deletions(-) diff --git a/osal/linux/MessageQueue.cpp b/osal/linux/MessageQueue.cpp index 605dea2a..c4b24a13 100644 --- a/osal/linux/MessageQueue.cpp +++ b/osal/linux/MessageQueue.cpp @@ -11,7 +11,8 @@ MessageQueue::MessageQueue(uint32_t messageDepth, size_t maxMessageSize): id(MessageQueueIF::NO_QUEUE),lastPartner(MessageQueueIF::NO_QUEUE), - defaultDestination(MessageQueueIF::NO_QUEUE) { + defaultDestination(MessageQueueIF::NO_QUEUE), + maxMessageSize(maxMessageSize) { //debug << "MessageQueue::MessageQueue: Creating a queue" << std::endl; mq_attr attributes; this->id = 0; @@ -142,6 +143,19 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message, } ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) { + if(message == nullptr) { + sif::error << "MessageQueue::receiveMessage: Message is " + "nullptr!" << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + + if(message->getMaximumMessageSize() < maxMessageSize) { + sif::error << "MessageQueue::receiveMessage: Message size " + << message->getMaximumMessageSize() << + " too small to receive data!" << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + unsigned int messagePriority = 0; int status = mq_receive(id,reinterpret_cast(message->getBuffer()), message->getMaximumMessageSize(),&messagePriority); @@ -258,18 +272,20 @@ void MessageQueue::setDefaultDestination(MessageQueueId_t defaultDestination) { this->defaultDestination = defaultDestination; } -ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo, - MessageQueueMessageIF* message, MessageQueueId_t sentFrom, - bool ignoreFault) { - return sendMessageFromMessageQueue(sendTo,message,sentFrom,ignoreFault); - -} - ReturnValue_t MessageQueue::sendToDefaultFrom(MessageQueueMessageIF* message, MessageQueueId_t sentFrom, bool ignoreFault) { return sendMessageFrom(defaultDestination, message, sentFrom, ignoreFault); } + +ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo, + MessageQueueMessageIF* message, MessageQueueId_t sentFrom, + bool ignoreFault) { + return sendMessageFromMessageQueue(sendTo,message, maxMessageSize, + sentFrom,ignoreFault); + +} + MessageQueueId_t MessageQueue::getDefaultDestination() const { return this->defaultDestination; } @@ -281,8 +297,22 @@ bool MessageQueue::isDefaultDestinationSet() const { uint16_t MessageQueue::queueCounter = 0; ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, - MessageQueueMessageIF *message, MessageQueueId_t sentFrom, - bool ignoreFault) { + MessageQueueMessageIF *message, size_t maxSize, + MessageQueueId_t sentFrom, bool ignoreFault) { + if(message == nullptr) { + sif::error << "MessageQueue::sendMessageFromMessageQueue: Message is " + "nullptr!" << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + + if(message->getMaximumMessageSize() > maxSize) { + sif::error << "MessageQueue::sendMessageFromMessageQueue: Message size " + << message->getMaximumMessageSize() << " too large for queue" + " with max. message size " << maxSize << "!" + << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + message->setSender(sentFrom); int result = mq_send(sendTo, reinterpret_cast(message->getBuffer()), diff --git a/osal/linux/MessageQueue.h b/osal/linux/MessageQueue.h index 91066bf7..22725d18 100644 --- a/osal/linux/MessageQueue.h +++ b/osal/linux/MessageQueue.h @@ -149,7 +149,8 @@ protected: * \param ignoreFault If set to true, the internal software fault counter is not incremented if queue is full. */ static ReturnValue_t sendMessageFromMessageQueue(MessageQueueId_t sendTo, - MessageQueueMessageIF* message, MessageQueueId_t sentFrom = NO_QUEUE, + MessageQueueMessageIF* message, size_t maxSize, + MessageQueueId_t sentFrom = NO_QUEUE, bool ignoreFault=false); private: /** @@ -176,9 +177,10 @@ private: /** * The name of the message queue, stored for unlinking */ - char name[5]; + char name[16]; static uint16_t queueCounter; + const size_t maxMessageSize; ReturnValue_t handleError(mq_attr* attributes, uint32_t messageDepth); }; diff --git a/osal/linux/PeriodicPosixTask.cpp b/osal/linux/PeriodicPosixTask.cpp index fe8ac19c..db4005b0 100644 --- a/osal/linux/PeriodicPosixTask.cpp +++ b/osal/linux/PeriodicPosixTask.cpp @@ -31,10 +31,11 @@ ReturnValue_t PeriodicPosixTask::addComponent(object_id_t object, "it implements ExecutableObjectIF" << std::endl; return HasReturnvaluesIF::RETURN_FAILED; } + objectList.push_back(newObject); + if(setTaskIF) { newObject->setTaskIF(this); } - objectList.push_back(newObject); return HasReturnvaluesIF::RETURN_OK; } @@ -43,14 +44,14 @@ ReturnValue_t PeriodicPosixTask::sleepFor(uint32_t ms) { } -ReturnValue_t PeriodicPosixTask::startTask(void){ +ReturnValue_t PeriodicPosixTask::startTask(void) { started = true; //sif::info << stackSize << std::endl; PosixThread::createTask(&taskEntryPoint,this); return HasReturnvaluesIF::RETURN_OK; } -void PeriodicPosixTask::taskFunctionality(void){ +void PeriodicPosixTask::taskFunctionality(void) { if(!started){ suspend(); } @@ -64,14 +65,15 @@ void PeriodicPosixTask::taskFunctionality(void){ if(!PosixThread::delayUntil(&lastWakeTime,periodMs)){ char name[20] = {0}; int status = pthread_getname_np(pthread_self(),name,sizeof(name)); - if(status==0){ + if(status == 0){ sif::error << "PeriodicPosixTask " << name << ": Deadline " "missed." << std::endl; - }else{ + } + else { sif::error << "PeriodicPosixTask X: Deadline missed. " << status << std::endl; } - if (this->deadlineMissedFunc != NULL) { + if (this->deadlineMissedFunc != nullptr) { this->deadlineMissedFunc(); } } diff --git a/osal/linux/PeriodicPosixTask.h b/osal/linux/PeriodicPosixTask.h index 1d62a565..9b477e36 100644 --- a/osal/linux/PeriodicPosixTask.h +++ b/osal/linux/PeriodicPosixTask.h @@ -32,7 +32,7 @@ public: * The address of the task object is passed as an argument * to the system call. */ - ReturnValue_t startTask(void); + ReturnValue_t startTask(void) override; /** * Adds an object to the list of objects to be executed. * The objects are executed in the order added. @@ -42,9 +42,9 @@ public: ReturnValue_t addComponent(object_id_t object, bool setTaskIF = true) override; - uint32_t getPeriodMs() const; + uint32_t getPeriodMs() const override; - ReturnValue_t sleepFor(uint32_t ms); + ReturnValue_t sleepFor(uint32_t ms) override; private: typedef std::vector ObjectList; //!< Typedef for the List of objects. diff --git a/osal/linux/QueueFactory.cpp b/osal/linux/QueueFactory.cpp index 8bd9d52c..95264a42 100644 --- a/osal/linux/QueueFactory.cpp +++ b/osal/linux/QueueFactory.cpp @@ -9,10 +9,10 @@ QueueFactory* QueueFactory::factoryInstance = nullptr; ReturnValue_t MessageQueueSenderIF::sendMessage(MessageQueueId_t sendTo, - MessageQueueMessageIF* message, MessageQueueId_t sentFrom, - bool ignoreFault) { + MessageQueueMessageIF* message, size_t maxSize, + MessageQueueId_t sentFrom, bool ignoreFault) { return MessageQueue::sendMessageFromMessageQueue(sendTo,message, - sentFrom,ignoreFault); + maxSize, sentFrom,ignoreFault); } QueueFactory* QueueFactory::instance() { From c0beef44630f991e7307727bbcca6adc81bb48a0 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 23 Jun 2020 10:27:44 +0200 Subject: [PATCH 168/307] some include guards, todo comments --- devicehandlers/DeviceHandlerFailureIsolation.cpp | 2 +- devicehandlers/DeviceHandlerFailureIsolation.h | 1 + fdir/ConfirmsFailuresIF.h | 1 + fdir/FailureIsolationBase.cpp | 3 ++- health/HealthTable.h | 4 ++-- health/HealthTableIF.h | 8 +++++--- ipc/MessageQueueSenderIF.h | 1 - returnvalues/HasReturnvaluesIF.h | 4 ++-- 8 files changed, 14 insertions(+), 10 deletions(-) diff --git a/devicehandlers/DeviceHandlerFailureIsolation.cpp b/devicehandlers/DeviceHandlerFailureIsolation.cpp index 1df2afa0..46e73cd8 100644 --- a/devicehandlers/DeviceHandlerFailureIsolation.cpp +++ b/devicehandlers/DeviceHandlerFailureIsolation.cpp @@ -137,7 +137,7 @@ void DeviceHandlerFailureIsolation::decrementFaultCounters() { void DeviceHandlerFailureIsolation::handleRecovery(Event reason) { clearFaultCounters(); - if (!recoveryCounter.incrementAndCheck()) { + if (not recoveryCounter.incrementAndCheck()) { startRecovery(reason); } else { setFaulty(reason); diff --git a/devicehandlers/DeviceHandlerFailureIsolation.h b/devicehandlers/DeviceHandlerFailureIsolation.h index 379edae3..4343d88b 100644 --- a/devicehandlers/DeviceHandlerFailureIsolation.h +++ b/devicehandlers/DeviceHandlerFailureIsolation.h @@ -31,6 +31,7 @@ protected: bool hasPowerConfirmation = false; MessageQueueId_t powerConfirmation; static object_id_t powerConfirmationId; + // TODO: Are those hardcoded value? How can they be changed. static const uint32_t MAX_REBOOT = 1; static const uint32_t REBOOT_TIME_MS = 180000; static const uint32_t MAX_STRANGE_REPLIES = 10; diff --git a/fdir/ConfirmsFailuresIF.h b/fdir/ConfirmsFailuresIF.h index 99cd212a..460749ee 100644 --- a/fdir/ConfirmsFailuresIF.h +++ b/fdir/ConfirmsFailuresIF.h @@ -4,6 +4,7 @@ #include #include +// TODO: Documentation. class ConfirmsFailuresIF { public: static const uint8_t INTERFACE_ID = CLASS_ID::HANDLES_FAILURES_IF; diff --git a/fdir/FailureIsolationBase.cpp b/fdir/FailureIsolationBase.cpp index 46114467..018fbe6a 100644 --- a/fdir/FailureIsolationBase.cpp +++ b/fdir/FailureIsolationBase.cpp @@ -9,7 +9,8 @@ FailureIsolationBase::FailureIsolationBase(object_id_t owner, object_id_t parent, uint8_t messageDepth, uint8_t parameterDomainBase) : eventQueue(NULL), ownerId(owner), owner(NULL), faultTreeParent(parent), parameterDomainBase(parameterDomainBase) { - eventQueue = QueueFactory::instance()->createMessageQueue(messageDepth, EventMessage::EVENT_MESSAGE_SIZE); + eventQueue = QueueFactory::instance()->createMessageQueue(messageDepth, + EventMessage::EVENT_MESSAGE_SIZE); } FailureIsolationBase::~FailureIsolationBase() { diff --git a/health/HealthTable.h b/health/HealthTable.h index 32a7eee2..194ad259 100644 --- a/health/HealthTable.h +++ b/health/HealthTable.h @@ -1,5 +1,5 @@ -#ifndef HEALTHTABLE_H_ -#define HEALTHTABLE_H_ +#ifndef FRAMEWORK_HEALTH_HEALTHTABLE_H_ +#define FRAMEWORK_HEALTH_HEALTHTABLE_H_ #include #include diff --git a/health/HealthTableIF.h b/health/HealthTableIF.h index 6fdfc2c0..c8d2c74a 100644 --- a/health/HealthTableIF.h +++ b/health/HealthTableIF.h @@ -1,5 +1,5 @@ -#ifndef HEALTHTABLEIF_H_ -#define HEALTHTABLEIF_H_ +#ifndef FRAMEWORK_HEALTH_HEALTHTABLEIF_H_ +#define FRAMEWORK_HEALTH_HEALTHTABLEIF_H_ #include #include @@ -8,6 +8,8 @@ class HealthTableIF: public ManagesHealthIF { + // TODO: This is in the mission folder and not in the framework folder. + // delete it? friend class HealthCommandingService; public: virtual ~HealthTableIF() { @@ -23,4 +25,4 @@ protected: virtual ReturnValue_t iterate(std::pair *value, bool reset = false) = 0; }; -#endif /* HEALTHTABLEIF_H_ */ +#endif /* FRAMEWORK_HEALTH_HEALTHTABLEIF_H_ */ diff --git a/ipc/MessageQueueSenderIF.h b/ipc/MessageQueueSenderIF.h index 912f4d7e..8bc14948 100644 --- a/ipc/MessageQueueSenderIF.h +++ b/ipc/MessageQueueSenderIF.h @@ -12,7 +12,6 @@ public: /** * Allows sending messages without actually "owing" a message queue. * Not sure whether this is actually a good idea. - * Must be implemented by a subclass. */ static ReturnValue_t sendMessage(MessageQueueId_t sendTo, MessageQueueMessageIF* message, size_t maxMessageSize, diff --git a/returnvalues/HasReturnvaluesIF.h b/returnvalues/HasReturnvaluesIF.h index 9bbaf601..b51dfc82 100644 --- a/returnvalues/HasReturnvaluesIF.h +++ b/returnvalues/HasReturnvaluesIF.h @@ -1,5 +1,5 @@ -#ifndef HASRETURNVALUESIF_H_ -#define HASRETURNVALUESIF_H_ +#ifndef FRAMEWORK_RETURNVALUES_HASRETURNVALUESIF_H_ +#define FRAMEWORK_RETURNVALUES_HASRETURNVALUESIF_H_ #include #include From 918329163f2148ed80b62f74d584ebcc28b511d5 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 23 Jun 2020 10:31:53 +0200 Subject: [PATCH 169/307] removed empty line --- osal/FreeRTOS/FixedTimeslotTask.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/osal/FreeRTOS/FixedTimeslotTask.cpp b/osal/FreeRTOS/FixedTimeslotTask.cpp index 323eab03..0fb1e1d7 100644 --- a/osal/FreeRTOS/FixedTimeslotTask.cpp +++ b/osal/FreeRTOS/FixedTimeslotTask.cpp @@ -57,7 +57,6 @@ ReturnValue_t FixedTimeslotTask::startTask() { ReturnValue_t FixedTimeslotTask::addSlot(object_id_t componentId, uint32_t slotTimeMs, int8_t executionStep) { - if (objectManager->get(componentId) != nullptr) { if(slotTimeMs == 0) { // FreeRTOS throws a sanity error for zero values, so we set From e27310da40a420e78cc894746301d318da632bc9 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 23 Jun 2020 10:47:31 +0200 Subject: [PATCH 170/307] updates for tmtcbridge --- tmtcservices/TmTcBridge.cpp | 17 +++++------------ tmtcservices/TmTcBridge.h | 11 ++++++----- 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/tmtcservices/TmTcBridge.cpp b/tmtcservices/TmTcBridge.cpp index c5eaf78b..f9a7d3bc 100644 --- a/tmtcservices/TmTcBridge.cpp +++ b/tmtcservices/TmTcBridge.cpp @@ -3,6 +3,7 @@ #include #include #include +#include TmTcBridge::TmTcBridge(object_id_t objectId_, object_id_t ccsdsPacketDistributor_): SystemObject(objectId_), @@ -85,7 +86,7 @@ ReturnValue_t TmTcBridge::handleTm() { return RETURN_FAILED; } - if(tmStored && communicationLinkUp) { + if(tmStored and communicationLinkUp) { result = handleStoredTm(); } return result; @@ -141,11 +142,11 @@ ReturnValue_t TmTcBridge::storeDownlinkData(TmTcMessage *message) { ReturnValue_t TmTcBridge::handleStoredTm() { uint8_t counter = 0; ReturnValue_t result = RETURN_OK; - while(not tmFifo.empty() && counter < sentPacketsPerCycle) { + while(not tmFifo.empty() and counter < sentPacketsPerCycle) { //info << "TMTC Bridge: Sending stored TM data. There are " // << (int) fifo.size() << " left to send\r\n" << std::flush; store_address_t storeId; - const uint8_t* data = NULL; + const uint8_t* data = nullptr; size_t size = 0; tmFifo.retrieve(&storeId); result = tmStore->getData(storeId, &data, &size); @@ -186,14 +187,6 @@ MessageQueueId_t TmTcBridge::getReportReceptionQueue(uint8_t virtualChannel) { } - void TmTcBridge::printData(uint8_t * data, size_t dataLen) { - sif::info << "TMTC Bridge: Printing data: ["; - for(uint32_t i = 0; i < dataLen; i++) { - sif::info << std::hex << (int)data[i]; - if(i < dataLen-1){ - sif::info << " , "; - } - } - sif::info << " ] " << std::endl; + arrayprinter::print(data, dataLen); } diff --git a/tmtcservices/TmTcBridge.h b/tmtcservices/TmTcBridge.h index 0a1fcfab..3e0432d8 100644 --- a/tmtcservices/TmTcBridge.h +++ b/tmtcservices/TmTcBridge.h @@ -43,26 +43,27 @@ public: */ ReturnValue_t setMaxNumberOfPacketsStored(uint8_t maxNumberOfPacketsStored); - void registerCommConnect(); - void registerCommDisconnect(); + virtual void registerCommConnect(); + virtual void registerCommDisconnect(); /** * Initializes necessary FSFW components for the TMTC Bridge * @return */ - ReturnValue_t initialize() override; + virtual ReturnValue_t initialize() override; /** * @brief Handles TMTC reception */ - ReturnValue_t performOperation(uint8_t operationCode = 0) override; + virtual ReturnValue_t performOperation(uint8_t operationCode = 0) override; /** * Return TMTC Reception Queue * @param virtualChannel * @return */ - MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel = 0) override; + MessageQueueId_t getReportReceptionQueue( + uint8_t virtualChannel = 0) override; protected: //! Used to send and receive TMTC messages. //! TmTcMessage is used to transport messages between tasks. From 45ffb7549aa0654f1423ef5cd8dd0f012ab0537a Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 23 Jun 2020 10:58:48 +0200 Subject: [PATCH 171/307] storage accessor const in own file now --- storagemanager/ConstStorageAccessor.cpp | 93 +++++++++++++++++++ storagemanager/ConstStorageAccessor.h | 116 ++++++++++++++++++++++++ storagemanager/StorageAccessor.cpp | 98 +------------------- storagemanager/StorageAccessor.h | 109 +--------------------- 4 files changed, 215 insertions(+), 201 deletions(-) create mode 100644 storagemanager/ConstStorageAccessor.cpp create mode 100644 storagemanager/ConstStorageAccessor.h diff --git a/storagemanager/ConstStorageAccessor.cpp b/storagemanager/ConstStorageAccessor.cpp new file mode 100644 index 00000000..be3188c1 --- /dev/null +++ b/storagemanager/ConstStorageAccessor.cpp @@ -0,0 +1,93 @@ +#include +#include +#include + +ConstStorageAccessor::ConstStorageAccessor(store_address_t storeId): + storeId(storeId) {} + +ConstStorageAccessor::ConstStorageAccessor(store_address_t storeId, + StorageManagerIF* store): + storeId(storeId), store(store) { + internalState = AccessState::ASSIGNED; +} + +ConstStorageAccessor::~ConstStorageAccessor() { + if(deleteData and store != nullptr) { + sif::debug << "deleting store data" << std::endl; + store->deleteData(storeId); + } +} + +ConstStorageAccessor::ConstStorageAccessor(ConstStorageAccessor&& other): + constDataPointer(other.constDataPointer), storeId(other.storeId), + size_(other.size_), store(other.store), deleteData(other.deleteData), + internalState(other.internalState) { + // This prevent premature deletion + other.store = nullptr; +} + +ConstStorageAccessor& ConstStorageAccessor::operator=( + ConstStorageAccessor&& other) { + constDataPointer = other.constDataPointer; + storeId = other.storeId; + store = other.store; + size_ = other.size_; + deleteData = other.deleteData; + this->store = other.store; + // This prevents premature deletion + other.store = nullptr; + return *this; +} + +const uint8_t* ConstStorageAccessor::data() const { + return constDataPointer; +} + +size_t ConstStorageAccessor::size() const { + if(internalState == AccessState::UNINIT) { + sif::warning << "StorageAccessor: Not initialized!" << std::endl; + } + return size_; +} + +ReturnValue_t ConstStorageAccessor::getDataCopy(uint8_t *pointer, + size_t maxSize) { + if(internalState == AccessState::UNINIT) { + sif::warning << "StorageAccessor: Not initialized!" << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + if(size_ > maxSize) { + sif::error << "StorageAccessor: Supplied buffer not large enough" << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + std::copy(constDataPointer, constDataPointer + size_, pointer); + return HasReturnvaluesIF::RETURN_OK; +} + +void ConstStorageAccessor::release() { + deleteData = false; +} + +store_address_t ConstStorageAccessor::getId() const { + return storeId; +} + +void ConstStorageAccessor::print() const { + if(internalState == AccessState::UNINIT) { + sif::warning << "StorageAccessor: Not initialized!" << std::endl; + return; + } + sif::info << "StorageAccessor: Printing data: ["; + for(uint16_t iPool = 0; iPool < size_; iPool++) { + sif::info << std::hex << (int)constDataPointer[iPool]; + if(iPool < size_ - 1){ + sif::info << " , "; + } + } + sif::info << " ] " << std::endl; +} + +void ConstStorageAccessor::assignStore(StorageManagerIF* store) { + internalState = AccessState::ASSIGNED; + this->store = store; +} diff --git a/storagemanager/ConstStorageAccessor.h b/storagemanager/ConstStorageAccessor.h new file mode 100644 index 00000000..cf8ca08f --- /dev/null +++ b/storagemanager/ConstStorageAccessor.h @@ -0,0 +1,116 @@ +#ifndef FRAMEWORK_STORAGEMANAGER_CONSTSTORAGEACCESSOR_H_ +#define FRAMEWORK_STORAGEMANAGER_CONSTSTORAGEACCESSOR_H_ + +#include +#include +#include + +class StorageManagerIF; + +/** + * @brief Helper classes to facilitate safe access to storages which is also + * conforming to RAII principles + * @details + * Accessor class which can be returned by pool manager or passed and set by + * pool managers to have safe access to the pool resources. + * + * These helper can be used together with the StorageManager classes to manage + * access to a storage. It can take care of thread-safety while also providing + * mechanisms to automatically clear storage data. + */ +class ConstStorageAccessor { + //! StorageManager classes have exclusive access to private variables. + template + friend class PoolManager; + template + friend class LocalPool; +public: + /** + * @brief Simple constructor which takes the store ID of the storage + * entry to access. + * @param storeId + */ + ConstStorageAccessor(store_address_t storeId); + ConstStorageAccessor(store_address_t storeId, StorageManagerIF* store); + + /** + * @brief The destructor in default configuration takes care of + * deleting the accessed pool entry and unlocking the mutex + */ + virtual ~ConstStorageAccessor(); + + /** + * @brief Returns a pointer to the read-only data + * @return + */ + const uint8_t* data() const; + + /** + * @brief Copies the read-only data to the supplied pointer + * @param pointer + */ + virtual ReturnValue_t getDataCopy(uint8_t *pointer, size_t maxSize); + + /** + * @brief Calling this will prevent the Accessor from deleting the data + * when the destructor is called. + */ + void release(); + + /** + * Get the size of the data + * @return + */ + size_t size() const; + + /** + * Get the storage ID. + * @return + */ + store_address_t getId() const; + + void print() const; + + /** + * @brief Move ctor and move assignment allow returning accessors as + * a returnvalue. They prevent resource being free prematurely. + * Refer to: https://github.com/MicrosoftDocs/cpp-docs/blob/master/docs/cpp/ + * move-constructors-and-move-assignment-operators-cpp.md + * @param + * @return + */ + ConstStorageAccessor& operator= (ConstStorageAccessor&&); + ConstStorageAccessor (ConstStorageAccessor&&); + + //! The copy ctor and copy assignemnt should be deleted implicitely + //! according to https://foonathan.net/2019/02/special-member-functions/ + //! but I still deleted them to make it more explicit. (remember rule of 5). + ConstStorageAccessor& operator= (ConstStorageAccessor&) = delete; + ConstStorageAccessor (ConstStorageAccessor&) = delete; +protected: + const uint8_t* constDataPointer = nullptr; + store_address_t storeId; + size_t size_ = 0; + //! Managing pool, has to assign itself. + StorageManagerIF* store = nullptr; + bool deleteData = true; + + enum class AccessState { + UNINIT, + ASSIGNED + }; + //! Internal state for safety reasons. + AccessState internalState = AccessState::UNINIT; + /** + * Used by the pool manager instances to assign themselves to the + * accessor. This is necessary to delete the data when the acessor + * exits the scope ! The internal state will be considered read + * when this function is called, so take care all data is set properly as + * well. + * @param + */ + void assignStore(StorageManagerIF*); +}; + + +#endif /* FRAMEWORK_STORAGEMANAGER_CONSTSTORAGEACCESSOR_H_ */ diff --git a/storagemanager/StorageAccessor.cpp b/storagemanager/StorageAccessor.cpp index c0c8126b..b827b9c0 100644 --- a/storagemanager/StorageAccessor.cpp +++ b/storagemanager/StorageAccessor.cpp @@ -1,96 +1,6 @@ #include #include - -ConstStorageAccessor::ConstStorageAccessor(store_address_t storeId): - storeId(storeId) {} - -ConstStorageAccessor::ConstStorageAccessor(store_address_t storeId, - StorageManagerIF* store): - storeId(storeId), store(store) { - internalState = AccessState::ASSIGNED; -} - -ConstStorageAccessor::~ConstStorageAccessor() { - if(deleteData and store != nullptr) { - sif::debug << "deleting store data" << std::endl; - store->deleteData(storeId); - } -} - -ConstStorageAccessor::ConstStorageAccessor(ConstStorageAccessor&& other): - constDataPointer(other.constDataPointer), storeId(other.storeId), - size_(other.size_), store(other.store), deleteData(other.deleteData), - internalState(other.internalState) { - // This prevent premature deletion - other.store = nullptr; -} - -ConstStorageAccessor& ConstStorageAccessor::operator=( - ConstStorageAccessor&& other) { - constDataPointer = other.constDataPointer; - storeId = other.storeId; - store = other.store; - size_ = other.size_; - deleteData = other.deleteData; - this->store = other.store; - // This prevents premature deletion - other.store = nullptr; - return *this; -} - -const uint8_t* ConstStorageAccessor::data() const { - return constDataPointer; -} - -size_t ConstStorageAccessor::size() const { - if(internalState == AccessState::UNINIT) { - sif::warning << "StorageAccessor: Not initialized!" << std::endl; - } - return size_; -} - -ReturnValue_t ConstStorageAccessor::getDataCopy(uint8_t *pointer, - size_t maxSize) { - if(internalState == AccessState::UNINIT) { - sif::warning << "StorageAccessor: Not initialized!" << std::endl; - return HasReturnvaluesIF::RETURN_FAILED; - } - if(size_ > maxSize) { - sif::error << "StorageAccessor: Supplied buffer not large enough" << std::endl; - return HasReturnvaluesIF::RETURN_FAILED; - } - std::copy(constDataPointer, constDataPointer + size_, pointer); - return HasReturnvaluesIF::RETURN_OK; -} - -void ConstStorageAccessor::release() { - deleteData = false; -} - -store_address_t ConstStorageAccessor::getId() const { - return storeId; -} - -void ConstStorageAccessor::print() const { - if(internalState == AccessState::UNINIT) { - sif::warning << "StorageAccessor: Not initialized!" << std::endl; - return; - } - sif::info << "StorageAccessor: Printing data: ["; - for(uint16_t iPool = 0; iPool < size_; iPool++) { - sif::info << std::hex << (int)constDataPointer[iPool]; - if(iPool < size_ - 1){ - sif::info << " , "; - } - } - sif::info << " ] " << std::endl; -} - -void ConstStorageAccessor::assignStore(StorageManagerIF* store) { - internalState = AccessState::ASSIGNED; - this->store = store; -} - +#include StorageAccessor::StorageAccessor(store_address_t storeId): ConstStorageAccessor(storeId) { @@ -120,7 +30,8 @@ ReturnValue_t StorageAccessor::getDataCopy(uint8_t *pointer, size_t maxSize) { return HasReturnvaluesIF::RETURN_FAILED; } if(size_ > maxSize) { - sif::error << "StorageAccessor: Supplied buffer not large enough" << std::endl; + sif::error << "StorageAccessor: Supplied buffer not large " + "enough" << std::endl; return HasReturnvaluesIF::RETURN_FAILED; } std::copy(dataPointer, dataPointer + size_, pointer); @@ -141,7 +52,8 @@ ReturnValue_t StorageAccessor::write(uint8_t *data, size_t size, return HasReturnvaluesIF::RETURN_FAILED; } if(offset + size > size_) { - sif::error << "StorageAccessor: Data too large for pool entry!" << std::endl; + sif::error << "StorageAccessor: Data too large for pool " + "entry!" << std::endl; return HasReturnvaluesIF::RETURN_FAILED; } std::copy(data, data + size, dataPointer + offset); diff --git a/storagemanager/StorageAccessor.h b/storagemanager/StorageAccessor.h index 06947974..c5e38306 100644 --- a/storagemanager/StorageAccessor.h +++ b/storagemanager/StorageAccessor.h @@ -1,117 +1,10 @@ #ifndef FRAMEWORK_STORAGEMANAGER_STORAGEACCESSOR_H_ #define FRAMEWORK_STORAGEMANAGER_STORAGEACCESSOR_H_ -#include -#include +#include class StorageManagerIF; -/** - * @brief Helper classes to facilitate safe access to storages which is also - * conforming to RAII principles - * @details - * Accessor class which can be returned by pool manager or passed and set by - * pool managers to have safe access to the pool resources. - * - * These helper can be used together with the StorageManager classes to manage - * access to a storage. It can take care of thread-safety while also providing - * mechanisms to automatically clear storage data. - */ -class ConstStorageAccessor { - //! StorageManager classes have exclusive access to private variables. - template - friend class PoolManager; - template - friend class LocalPool; -public: - /** - * @brief Simple constructor which takes the store ID of the storage - * entry to access. - * @param storeId - */ - ConstStorageAccessor(store_address_t storeId); - ConstStorageAccessor(store_address_t storeId, StorageManagerIF* store); - - /** - * @brief The destructor in default configuration takes care of - * deleting the accessed pool entry and unlocking the mutex - */ - virtual ~ConstStorageAccessor(); - - /** - * @brief Returns a pointer to the read-only data - * @return - */ - const uint8_t* data() const; - - /** - * @brief Copies the read-only data to the supplied pointer - * @param pointer - */ - virtual ReturnValue_t getDataCopy(uint8_t *pointer, size_t maxSize); - - /** - * @brief Calling this will prevent the Accessor from deleting the data - * when the destructor is called. - */ - void release(); - - /** - * Get the size of the data - * @return - */ - size_t size() const; - - /** - * Get the storage ID. - * @return - */ - store_address_t getId() const; - - void print() const; - - /** - * @brief Move ctor and move assignment allow returning accessors as - * a returnvalue. They prevent resource being free prematurely. - * Refer to: https://github.com/MicrosoftDocs/cpp-docs/blob/master/docs/cpp/ - * move-constructors-and-move-assignment-operators-cpp.md - * @param - * @return - */ - ConstStorageAccessor& operator= (ConstStorageAccessor&&); - ConstStorageAccessor (ConstStorageAccessor&&); - - //! The copy ctor and copy assignemnt should be deleted implicitely - //! according to https://foonathan.net/2019/02/special-member-functions/ - //! but I still deleted them to make it more explicit. (remember rule of 5). - ConstStorageAccessor& operator= (const ConstStorageAccessor&) = delete; - ConstStorageAccessor (const ConstStorageAccessor&) = delete; -protected: - const uint8_t* constDataPointer = nullptr; - store_address_t storeId; - size_t size_ = 0; - //! Managing pool, has to assign itself. - StorageManagerIF* store = nullptr; - bool deleteData = true; - - enum class AccessState { - UNINIT, - ASSIGNED - }; - //! Internal state for safety reasons. - AccessState internalState = AccessState::UNINIT; - /** - * Used by the pool manager instances to assign themselves to the - * accessor. This is necessary to delete the data when the acessor - * exits the scope ! The internal state will be considered read - * when this function is called, so take care all data is set properly as - * well. - * @param - */ - void assignStore(StorageManagerIF*); -}; - - /** * @brief Child class for modifyable data. Also has a normal pointer member. */ From 446e7d2f82d46ce9690d3f2c4c84b166407a8c2d Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 23 Jun 2020 11:00:40 +0200 Subject: [PATCH 172/307] const storage accessor improvement --- storagemanager/ConstStorageAccessor.cpp | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/storagemanager/ConstStorageAccessor.cpp b/storagemanager/ConstStorageAccessor.cpp index be3188c1..0bfde58c 100644 --- a/storagemanager/ConstStorageAccessor.cpp +++ b/storagemanager/ConstStorageAccessor.cpp @@ -1,6 +1,7 @@ #include #include #include +#include ConstStorageAccessor::ConstStorageAccessor(store_address_t storeId): storeId(storeId) {} @@ -73,18 +74,11 @@ store_address_t ConstStorageAccessor::getId() const { } void ConstStorageAccessor::print() const { - if(internalState == AccessState::UNINIT) { + if(internalState == AccessState::UNINIT or constDataPointer == nullptr) { sif::warning << "StorageAccessor: Not initialized!" << std::endl; return; } - sif::info << "StorageAccessor: Printing data: ["; - for(uint16_t iPool = 0; iPool < size_; iPool++) { - sif::info << std::hex << (int)constDataPointer[iPool]; - if(iPool < size_ - 1){ - sif::info << " , "; - } - } - sif::info << " ] " << std::endl; + arrayprinter::print(constDataPointer, size_); } void ConstStorageAccessor::assignStore(StorageManagerIF* store) { From 2ecd7c44937180ab0aad13a1185ed9cc54c9eaa4 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 23 Jun 2020 11:05:40 +0200 Subject: [PATCH 173/307] some minor improvements --- storagemanager/LocalPool.h | 11 +++++++---- storagemanager/PoolManager.h | 3 +++ storagemanager/PoolManager.tpp | 6 +++--- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/storagemanager/LocalPool.h b/storagemanager/LocalPool.h index bb94a3be..7e349dcd 100644 --- a/storagemanager/LocalPool.h +++ b/storagemanager/LocalPool.h @@ -35,7 +35,7 @@ public: /** * @brief This is the default constructor for a pool manager instance. * @details By passing two arrays of size NUMBER_OF_POOLS, the constructor - * allocates memory (with \c new) for store and size_list. These + * allocates memory (with @c new) for store and size_list. These * regions are all set to zero on start up. * @param setObjectId The object identifier to be set. This allows for * multiple instances of LocalPool in the system. @@ -87,7 +87,7 @@ public: ReturnValue_t initialize() override; protected: /** - * With this helper method, a free element of \c size is reserved. + * With this helper method, a free element of @c size is reserved. * @param size The minimum packet size that shall be reserved. * @param[out] address Storage ID of the reserved data. * @return - #RETURN_OK on success, @@ -100,7 +100,8 @@ protected: private: /** * Indicates that this element is free. - * This value limits the maximum size of a pool. Change to larger data type if increase is required. + * This value limits the maximum size of a pool. Change to larger data type + * if increase is required. */ static const uint32_t STORAGE_FREE = 0xFFFFFFFF; /** @@ -126,7 +127,9 @@ private: * is also dynamically allocated there. */ uint32_t* size_list[NUMBER_OF_POOLS]; - bool spillsToHigherPools; //!< A variable to determine whether higher n pools are used if the store is full. + //! A variable to determine whether higher n pools are used if + //! the store is full. + bool spillsToHigherPools; /** * @brief This method safely stores the given data in the given packet_id. * @details It also sets the size in size_list. The method does not perform diff --git a/storagemanager/PoolManager.h b/storagemanager/PoolManager.h index 7c2e8a71..3c1c1217 100644 --- a/storagemanager/PoolManager.h +++ b/storagemanager/PoolManager.h @@ -29,6 +29,9 @@ public: store_address_t* storeId = nullptr) override; protected: + //! Default mutex timeout value to prevent permanent blocking. + static constexpr uint32_t mutexTimeout = 50; + ReturnValue_t reserveSpace(const uint32_t size, store_address_t* address, bool ignoreFault) override; diff --git a/storagemanager/PoolManager.tpp b/storagemanager/PoolManager.tpp index a35b810c..4ca22b85 100644 --- a/storagemanager/PoolManager.tpp +++ b/storagemanager/PoolManager.tpp @@ -21,7 +21,7 @@ inline PoolManager::~PoolManager(void) { template inline ReturnValue_t PoolManager::reserveSpace( const uint32_t size, store_address_t* address, bool ignoreFault) { - MutexHelper mutexHelper(mutex,MutexIF::BLOCKING); + MutexHelper mutexHelper(mutex, mutexTimeout); ReturnValue_t status = LocalPool::reserveSpace(size, address,ignoreFault); return status; @@ -33,7 +33,7 @@ inline ReturnValue_t PoolManager::deleteData( // debug << "PoolManager( " << translateObject(getObjectId()) << // " )::deleteData from store " << packet_id.pool_index << // ". id is "<< packet_id.packet_index << std::endl; - MutexHelper mutexHelper(mutex,MutexIF::BLOCKING); + MutexHelper mutexHelper(mutex, mutexTimeout); ReturnValue_t status = LocalPool::deleteData(packet_id); return status; } @@ -41,7 +41,7 @@ inline ReturnValue_t PoolManager::deleteData( template inline ReturnValue_t PoolManager::deleteData(uint8_t* buffer, size_t size, store_address_t* storeId) { - MutexHelper mutexHelper(mutex,MutexIF::BLOCKING); + MutexHelper mutexHelper(mutex, mutexTimeout); ReturnValue_t status = LocalPool::deleteData(buffer, size, storeId); return status; From 6f4682e1c8848e8fb578af9329c6f274e84a6f60 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 23 Jun 2020 12:53:30 +0200 Subject: [PATCH 174/307] hasactionsIF include guard and doc --- action/HasActionsIF.h | 47 ++++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/action/HasActionsIF.h b/action/HasActionsIF.h index 12ecb89a..9c2a9c01 100644 --- a/action/HasActionsIF.h +++ b/action/HasActionsIF.h @@ -1,5 +1,5 @@ -#ifndef HASACTIONSIF_H_ -#define HASACTIONSIF_H_ +#ifndef FRAMEWORK_ACTION_HASACTIONSIF_H_ +#define FRAMEWORK_ACTION_HASACTIONSIF_H_ #include #include @@ -11,22 +11,26 @@ * Interface for component which uses actions * * @details - * This interface is used to execute actions in the component. Actions, in the sense of this interface, are activities with a well-defined beginning and - * end in time. They may adjust sub-states of components, but are not supposed to change - * the main mode of operation, which is handled with the HasModesIF described below. + * This interface is used to execute actions in the component. Actions, in the + * sense of this interface, are activities with a well-defined beginning and + * end in time. They may adjust sub-states of components, but are not supposed + * to change the main mode of operation, which is handled with the HasModesIF + * described below. * - * The HasActionsIF allows components to define such actions and make them available - * for other components to use. Implementing the interface is straightforward: There’s a - * single executeAction call, which provides an identifier for the action to execute, as well - * as arbitrary parameters for input. Aside from direct, software-based - * actions, it is used in device handler components as an interface to forward commands to - * devices. - * Implementing components of the interface are supposed to check identifier (ID) and - * parameters and immediately start execution of the action. It is, however, not required to - * immediately finish execution. Instead, this may be deferred to a later point in time, at - * which the component needs to inform the caller about finished or failed execution. + * The HasActionsIF allows components to define such actions and make them + * available for other components to use. Implementing the interface is + * straightforward: There’s a single executeAction call, which provides an + * identifier for the action to execute, as well as arbitrary parameters for + * input. + * Aside from direct, software-based actions, it is used in device handler + * components as an interface to forward commands to devices. + * Implementing components of the interface are supposed to check identifier + * (ID) and parameters and immediately start execution of the action. + * It is, however, not required to immediately finish execution. + * Instead, this may be deferred to a later point in time, at which the + * component needs to inform the caller about finished or failed execution. * - * \ingroup interfaces + * @ingroup interfaces */ class HasActionsIF { public: @@ -43,13 +47,14 @@ public: virtual MessageQueueId_t getCommandQueue() const = 0; /** * Execute or initialize the execution of a certain function. - * Returning #EXECUTION_FINISHED or a failure code, nothing else needs to be done. - * When needing more steps, return RETURN_OK and issue steps and completion manually. + * Returning #EXECUTION_FINISHED or a failure code, nothing else needs to + * be done. When needing more steps, return RETURN_OK and issue steps and + * completion manually. * One "step failed" or completion report must be issued! */ - virtual ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, - const uint8_t* data, size_t size) = 0; + virtual ReturnValue_t executeAction(ActionId_t actionId, + MessageQueueId_t commandedBy, const uint8_t* data, size_t size) = 0; }; -#endif /* HASACTIONSIF_H_ */ +#endif /* FRAMEWORK_ACTION_HASACTIONSIF_H_ */ From fd8a3e9fcc4efa40f84c6ecaa9163aac9843730f Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 23 Jun 2020 13:00:38 +0200 Subject: [PATCH 175/307] new returnvalues, return failed is 0xFFFF now --- returnvalues/FwClassIds.h | 13 +++++++++---- returnvalues/HasReturnvaluesIF.h | 18 +++++------------- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/returnvalues/FwClassIds.h b/returnvalues/FwClassIds.h index d21861c0..ddee539e 100644 --- a/returnvalues/FwClassIds.h +++ b/returnvalues/FwClassIds.h @@ -24,6 +24,7 @@ enum { MEMORY_HELPER, //MH SERIALIZE_IF, //SE FIXED_MAP, //FM + FIXED_MULTIMAP, //FMM HAS_HEALTH_IF, //HHI FIFO_CLASS, //FF MESSAGE_PROXY, //MQP @@ -54,11 +55,15 @@ enum { HAS_ACTIONS_IF, //HF DEVICE_COMMUNICATION_IF, //DC BSP, //BSP - TIME_STAMPER_IF, //TSI 52 + TIME_STAMPER_IF, //TSI 53 //TODO This will shift all IDs for FLP - SGP4PROPAGATOR_CLASS, //SGP4 53 - MUTEX_IF, //MUX 54 - MESSAGE_QUEUE_IF,//MQI 55 + SGP4PROPAGATOR_CLASS, //SGP4 54 + MUTEX_IF, //MUX 55 + MESSAGE_QUEUE_IF,//MQI 56 + SEMAPHORE_IF, //SPH 57 + LOCAL_POOL_OWNER_IF, //LPIF 58 + POOL_VARIABLE_IF, //PVA 59 + HOUSEKEEPING_MANAGER, //HKM 60 FW_CLASS_ID_COUNT //is actually count + 1 ! }; diff --git a/returnvalues/HasReturnvaluesIF.h b/returnvalues/HasReturnvaluesIF.h index 5adbca3f..b51dfc82 100644 --- a/returnvalues/HasReturnvaluesIF.h +++ b/returnvalues/HasReturnvaluesIF.h @@ -1,27 +1,19 @@ -#ifndef HASRETURNVALUESIF_H_ -#define HASRETURNVALUESIF_H_ +#ifndef FRAMEWORK_RETURNVALUES_HASRETURNVALUESIF_H_ +#define FRAMEWORK_RETURNVALUES_HASRETURNVALUESIF_H_ -#include #include #include +#include #define MAKE_RETURN_CODE( number ) ((INTERFACE_ID << 8) + (number)) typedef uint16_t ReturnValue_t; - - - - class HasReturnvaluesIF { public: static const ReturnValue_t RETURN_OK = 0; - static const ReturnValue_t RETURN_FAILED = 1; - virtual ~HasReturnvaluesIF() { - } - + static const ReturnValue_t RETURN_FAILED = 0xFFFF; + virtual ~HasReturnvaluesIF() {} }; - - #endif /* HASRETURNVALUESIF_H_ */ From 1d6ce656829b0ac7c4202fb7b015b01a89e43827 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 23 Jun 2020 13:46:43 +0200 Subject: [PATCH 176/307] returnvalue all ones now --- returnvalues/HasReturnvaluesIF.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/returnvalues/HasReturnvaluesIF.h b/returnvalues/HasReturnvaluesIF.h index b51dfc82..6ead6fbb 100644 --- a/returnvalues/HasReturnvaluesIF.h +++ b/returnvalues/HasReturnvaluesIF.h @@ -12,7 +12,8 @@ typedef uint16_t ReturnValue_t; class HasReturnvaluesIF { public: static const ReturnValue_t RETURN_OK = 0; - static const ReturnValue_t RETURN_FAILED = 0xFFFF; + //! This will be the alll-ones value irrespective of used unsigned datatype. + static const ReturnValue_t RETURN_FAILED = -1; virtual ~HasReturnvaluesIF() {} }; From 5f16d30d822a26fd42ddd2cdc4bc5211db695f41 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 23 Jun 2020 13:47:38 +0200 Subject: [PATCH 177/307] all ones value for return failed now --- returnvalues/HasReturnvaluesIF.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/returnvalues/HasReturnvaluesIF.h b/returnvalues/HasReturnvaluesIF.h index b51dfc82..6ead6fbb 100644 --- a/returnvalues/HasReturnvaluesIF.h +++ b/returnvalues/HasReturnvaluesIF.h @@ -12,7 +12,8 @@ typedef uint16_t ReturnValue_t; class HasReturnvaluesIF { public: static const ReturnValue_t RETURN_OK = 0; - static const ReturnValue_t RETURN_FAILED = 0xFFFF; + //! This will be the alll-ones value irrespective of used unsigned datatype. + static const ReturnValue_t RETURN_FAILED = -1; virtual ~HasReturnvaluesIF() {} }; From 9dc2ea426bd70b6e9229a7c61f74423fcf0e358a Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 23 Jun 2020 13:49:04 +0200 Subject: [PATCH 178/307] typo fix --- returnvalues/HasReturnvaluesIF.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/returnvalues/HasReturnvaluesIF.h b/returnvalues/HasReturnvaluesIF.h index 6ead6fbb..7a861b50 100644 --- a/returnvalues/HasReturnvaluesIF.h +++ b/returnvalues/HasReturnvaluesIF.h @@ -12,7 +12,7 @@ typedef uint16_t ReturnValue_t; class HasReturnvaluesIF { public: static const ReturnValue_t RETURN_OK = 0; - //! This will be the alll-ones value irrespective of used unsigned datatype. + //! This will be the all-ones value irrespective of used unsigned datatype. static const ReturnValue_t RETURN_FAILED = -1; virtual ~HasReturnvaluesIF() {} }; From 67366c25a0bd0b4e532cb8ee48d3d795215c773b Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 23 Jun 2020 13:49:25 +0200 Subject: [PATCH 179/307] typo fix --- returnvalues/HasReturnvaluesIF.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/returnvalues/HasReturnvaluesIF.h b/returnvalues/HasReturnvaluesIF.h index 6ead6fbb..7a861b50 100644 --- a/returnvalues/HasReturnvaluesIF.h +++ b/returnvalues/HasReturnvaluesIF.h @@ -12,7 +12,7 @@ typedef uint16_t ReturnValue_t; class HasReturnvaluesIF { public: static const ReturnValue_t RETURN_OK = 0; - //! This will be the alll-ones value irrespective of used unsigned datatype. + //! This will be the all-ones value irrespective of used unsigned datatype. static const ReturnValue_t RETURN_FAILED = -1; virtual ~HasReturnvaluesIF() {} }; From 56455a5fa290d69f62ad6a17a2ad66b311401c5e Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 23 Jun 2020 14:11:53 +0200 Subject: [PATCH 180/307] added static function as alternative to macro --- returnvalues/HasReturnvaluesIF.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/returnvalues/HasReturnvaluesIF.h b/returnvalues/HasReturnvaluesIF.h index 7a861b50..04acd66e 100644 --- a/returnvalues/HasReturnvaluesIF.h +++ b/returnvalues/HasReturnvaluesIF.h @@ -15,6 +15,10 @@ public: //! This will be the all-ones value irrespective of used unsigned datatype. static const ReturnValue_t RETURN_FAILED = -1; virtual ~HasReturnvaluesIF() {} + + static ReturnValue_t makeReturnCode(uint8_t interfaceId, uint8_t number) { + return (interfaceId << 8) + number; + } }; #endif /* HASRETURNVALUESIF_H_ */ From 7aa713a45238f62580fa04d55f16f643cd697b28 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 23 Jun 2020 14:12:55 +0200 Subject: [PATCH 181/307] added function as alternative to macro --- returnvalues/HasReturnvaluesIF.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/returnvalues/HasReturnvaluesIF.h b/returnvalues/HasReturnvaluesIF.h index 7a861b50..04acd66e 100644 --- a/returnvalues/HasReturnvaluesIF.h +++ b/returnvalues/HasReturnvaluesIF.h @@ -15,6 +15,10 @@ public: //! This will be the all-ones value irrespective of used unsigned datatype. static const ReturnValue_t RETURN_FAILED = -1; virtual ~HasReturnvaluesIF() {} + + static ReturnValue_t makeReturnCode(uint8_t interfaceId, uint8_t number) { + return (interfaceId << 8) + number; + } }; #endif /* HASRETURNVALUESIF_H_ */ From 905c1a92e38865558e25bebb10a8c7ca380d2ab6 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 23 Jun 2020 21:03:22 +0200 Subject: [PATCH 182/307] reverted some changes --- action/ActionHelper.cpp | 3 +-- datalinklayer/MapPacketExtraction.cpp | 3 +-- events/EventManager.cpp | 1 - events/EventManagerIF.h | 3 +-- health/HealthHelper.cpp | 2 -- housekeeping/HousekeepingMessage.cpp | 10 +++++----- housekeeping/HousekeepingMessage.h | 2 +- ipc/CommandMessage.cpp | 22 +++++++++++----------- ipc/CommandMessage.h | 2 +- ipc/CommandMessageBase.cpp | 16 ++++++---------- ipc/CommandMessageBase.h | 7 ------- ipc/MessageQueueMessage.cpp | 16 ++++++---------- ipc/MessageQueueMessage.h | 12 ------------ ipc/MessageQueueMessageIF.h | 14 +------------- ipc/MessageQueueSenderIF.h | 7 +++---- modes/ModeHelper.cpp | 5 +---- monitoring/LimitViolationReporter.cpp | 3 +-- osal/FreeRTOS/MessageQueue.cpp | 19 ++++++------------- osal/FreeRTOS/MessageQueue.h | 5 ++--- osal/FreeRTOS/QueueFactory.cpp | 11 +++-------- parameters/ParameterHelper.cpp | 6 ++---- tmtcpacket/pus/TmPacketStored.cpp | 2 +- tmtcservices/VerificationReporter.cpp | 8 ++++---- 23 files changed, 57 insertions(+), 122 deletions(-) diff --git a/action/ActionHelper.cpp b/action/ActionHelper.cpp index 026df4e1..0df5f2d4 100644 --- a/action/ActionHelper.cpp +++ b/action/ActionHelper.cpp @@ -101,8 +101,7 @@ ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo, //TODO Service Implementation sucks at the moment if (hideSender){ - result = MessageQueueSenderIF::sendMessage(reportTo, &reply, - MessageQueueMessage::MAX_MESSAGE_SIZE); + result = MessageQueueSenderIF::sendMessage(reportTo, &reply); } else { result = queueToUse->sendMessage(reportTo, &reply); } diff --git a/datalinklayer/MapPacketExtraction.cpp b/datalinklayer/MapPacketExtraction.cpp index 87b46556..4ea45e89 100644 --- a/datalinklayer/MapPacketExtraction.cpp +++ b/datalinklayer/MapPacketExtraction.cpp @@ -117,8 +117,7 @@ ReturnValue_t MapPacketExtraction::sendCompletePacket(uint8_t* data, ReturnValue_t status = this->packetStore->addData(&store_id, data, size); if (status == RETURN_OK) { TmTcMessage message(store_id); - status = MessageQueueSenderIF::sendMessage(tcQueueId,&message, - MessageQueueMessage::MAX_MESSAGE_SIZE); + status = MessageQueueSenderIF::sendMessage(tcQueueId,&message); } return status; } diff --git a/events/EventManager.cpp b/events/EventManager.cpp index a5d14569..04be6f68 100644 --- a/events/EventManager.cpp +++ b/events/EventManager.cpp @@ -52,7 +52,6 @@ void EventManager::notifyListeners(EventMessage* message) { for (auto iter = listenerList.begin(); iter != listenerList.end(); ++iter) { if (iter->second.match(message)) { MessageQueueSenderIF::sendMessage(iter->first, message, - MessageQueueMessage::MAX_MESSAGE_SIZE, message->getSender()); } } diff --git a/events/EventManagerIF.h b/events/EventManagerIF.h index 053e320b..bc0de432 100644 --- a/events/EventManagerIF.h +++ b/events/EventManagerIF.h @@ -44,8 +44,7 @@ public: eventmanagerQueue = eventmanager->getEventReportQueue(); } } - MessageQueueSenderIF::sendMessage(eventmanagerQueue, message, - MessageQueueMessage::MAX_MESSAGE_SIZE, sentFrom); + MessageQueueSenderIF::sendMessage(eventmanagerQueue, message, sentFrom); } }; diff --git a/health/HealthHelper.cpp b/health/HealthHelper.cpp index 935bf5e3..0b3bffcb 100644 --- a/health/HealthHelper.cpp +++ b/health/HealthHelper.cpp @@ -70,7 +70,6 @@ void HealthHelper::informParent(HasHealthIF::HealthState health, HealthMessage::setHealthMessage(&information, HealthMessage::HEALTH_INFO, health, oldHealth); if (MessageQueueSenderIF::sendMessage(parentQueue, &information, - MessageQueueMessage::MAX_MESSAGE_SIZE, owner->getCommandQueue()) != HasReturnvaluesIF::RETURN_OK) { sif::debug << "HealthHelper::informParent: sending health reply failed." << std::endl; @@ -91,7 +90,6 @@ void HealthHelper::handleSetHealthCommand(CommandMessage* command) { reply.setReplyRejected(result, command->getCommand()); } if (MessageQueueSenderIF::sendMessage(command->getSender(), &reply, - MessageQueueMessage::MAX_MESSAGE_SIZE, owner->getCommandQueue()) != HasReturnvaluesIF::RETURN_OK) { sif::debug << "HealthHelper::handleHealthCommand: sending health " "reply failed." << std::endl; diff --git a/housekeeping/HousekeepingMessage.cpp b/housekeeping/HousekeepingMessage.cpp index d7efd703..f425d16e 100644 --- a/housekeeping/HousekeepingMessage.cpp +++ b/housekeeping/HousekeepingMessage.cpp @@ -3,13 +3,13 @@ HousekeepingMessage::HousekeepingMessage(MessageQueueMessageIF* message): CommandMessageBase(message) { - if(message->getMaximumMessageSize() < HK_MESSAGE_SIZE) { + if(message->getMessageSize() < HK_MESSAGE_SIZE) { sif::error << "HousekeepingMessage::HousekeepingMessage: Passed " "message buffer can not hold minimum " << HK_MESSAGE_SIZE << " bytes!" << std::endl; return; } - message->setMessageSize(HK_MESSAGE_SIZE); + //message->setMessageSize(HK_MESSAGE_SIZE); } HousekeepingMessage::~HousekeepingMessage() {} @@ -38,9 +38,9 @@ void HousekeepingMessage::setHkDiagnosticsMessage(sid_t sid, setParameter(storeId.raw); } -size_t HousekeepingMessage::getMinimumMessageSize() const { - return HK_MESSAGE_SIZE; -} +//size_t HousekeepingMessage::getMinimumMessageSize() const { +// return HK_MESSAGE_SIZE; +//} sid_t HousekeepingMessage::getSid() const { sid_t sid; diff --git a/housekeeping/HousekeepingMessage.h b/housekeeping/HousekeepingMessage.h index c6a33c83..f568a418 100644 --- a/housekeeping/HousekeepingMessage.h +++ b/housekeeping/HousekeepingMessage.h @@ -104,7 +104,7 @@ public: //! to distinguish between diagnostics and regular HK packets sid_t getHkReportMessage(store_address_t * storeIdToSet) const; - virtual size_t getMinimumMessageSize() const override; + //virtual size_t getMinimumMessageSize() const override; virtual void clear() override; private: diff --git a/ipc/CommandMessage.cpp b/ipc/CommandMessage.cpp index 9a8a82f2..11355e38 100644 --- a/ipc/CommandMessage.cpp +++ b/ipc/CommandMessage.cpp @@ -9,14 +9,14 @@ CommandMessage::CommandMessage(MessageQueueMessageIF* receiverMessage): " message!" << std::endl; return; } - if(receiverMessage->getMaximumMessageSize() < - getMinimumMessageSize()) { - sif::error << "CommandMessage::ComandMessage: Passed message buffer" - " can not hold minimum "<< getMinimumMessageSize() - << " bytes!" << std::endl; - return; - } - internalMessage->setMessageSize(getMinimumMessageSize()); +// if(receiverMessage->getMessageSize() < +// getMinimumMessageSize()) { +// sif::error << "CommandMessage::ComandMessage: Passed message buffer" +// " can not hold minimum "<< getMinimumMessageSize() +// << " bytes!" << std::endl; +// return; +// } +// internalMessage->setMessageSize(getMinimumMessageSize()); } CommandMessage::CommandMessage(MessageQueueMessageIF* messageToSet, @@ -49,9 +49,9 @@ void CommandMessage::setParameter2(uint32_t parameter2) { sizeof(parameter2)); } -size_t CommandMessage::getMinimumMessageSize() const { - return MINIMUM_COMMAND_MESSAGE_SIZE; -} +//size_t CommandMessage::getMinimumMessageSize() const { +// return MINIMUM_COMMAND_MESSAGE_SIZE; +//} bool CommandMessage::isClearedCommandMessage() { return getCommand() == CMD_NONE; diff --git a/ipc/CommandMessage.h b/ipc/CommandMessage.h index a09494c6..ae4016b0 100644 --- a/ipc/CommandMessage.h +++ b/ipc/CommandMessage.h @@ -54,7 +54,7 @@ public: virtual ~CommandMessage() {} /** MessageQueueMessageIF functions used for minimum size check. */ - size_t getMinimumMessageSize() const override; + //size_t getMinimumMessageSize() const override; /** * Get the first parameter of the message diff --git a/ipc/CommandMessageBase.cpp b/ipc/CommandMessageBase.cpp index 80f9d378..ea50f4ea 100644 --- a/ipc/CommandMessageBase.cpp +++ b/ipc/CommandMessageBase.cpp @@ -47,25 +47,21 @@ const uint8_t* CommandMessageBase::getData() const { return internalMessage->getData() + sizeof(Command_t); } -void CommandMessageBase::setMessageSize(size_t messageSize) { - internalMessage->setMessageSize(messageSize); -} +//void CommandMessageBase::setMessageSize(size_t messageSize) { +// //internalMessage->setMessageSize(messageSize); +//} size_t CommandMessageBase::getMessageSize() const { return internalMessage->getMessageSize(); } -size_t CommandMessageBase::getMaximumMessageSize() const { - return internalMessage->getMaximumMessageSize(); -} - MessageQueueMessageIF* CommandMessageBase::getInternalMessage() const { return internalMessage; } -size_t CommandMessageBase::getMinimumMessageSize() const { - return MINIMUM_COMMAND_MESSAGE_BASE_SIZE; -} +//size_t CommandMessageBase::getMinimumMessageSize() const { +// return MINIMUM_COMMAND_MESSAGE_BASE_SIZE; +//} void CommandMessageBase::setReplyRejected(ReturnValue_t reason, Command_t initialCommand) { diff --git a/ipc/CommandMessageBase.h b/ipc/CommandMessageBase.h index b237b68f..1ee1b970 100644 --- a/ipc/CommandMessageBase.h +++ b/ipc/CommandMessageBase.h @@ -63,15 +63,8 @@ public: virtual MessageQueueId_t getSender() const override; virtual uint8_t * getData() override; virtual const uint8_t* getData() const override; - virtual void setMessageSize(size_t messageSize) override; virtual size_t getMessageSize() const override; - //! This depends on the maximum message size of the passed internal message. - virtual size_t getMaximumMessageSize() const override; - - //! Return the constant minimum message size. - virtual size_t getMinimumMessageSize() const override; - /** * A command message can be rejected and needs to offer a function * to set a rejected reply diff --git a/ipc/MessageQueueMessage.cpp b/ipc/MessageQueueMessage.cpp index b173f2c4..f3665074 100644 --- a/ipc/MessageQueueMessage.cpp +++ b/ipc/MessageQueueMessage.cpp @@ -51,9 +51,9 @@ void MessageQueueMessage::setSender(MessageQueueId_t setId) { memcpy(this->internalBuffer, &setId, sizeof(MessageQueueId_t)); } -size_t MessageQueueMessage::getMinimumMessageSize() const { - return this->HEADER_SIZE; -} +//size_t MessageQueueMessage::getMinimumMessageSize() const { +// return this->HEADER_SIZE; +//} void MessageQueueMessage::print() { sif::debug << "MessageQueueMessage has size: " << this->messageSize << @@ -69,13 +69,9 @@ void MessageQueueMessage::clear() { } size_t MessageQueueMessage::getMessageSize() const { - return this->messageSize; -} - -size_t MessageQueueMessage::getMaximumMessageSize() const { return this->MAX_MESSAGE_SIZE; } -void MessageQueueMessage::setMessageSize(size_t messageSize) { - this->messageSize = messageSize; -} +//void MessageQueueMessage::setMessageSize(size_t messageSize) { +// this->messageSize = messageSize; +//} diff --git a/ipc/MessageQueueMessage.h b/ipc/MessageQueueMessage.h index 8716df54..a994c323 100644 --- a/ipc/MessageQueueMessage.h +++ b/ipc/MessageQueueMessage.h @@ -139,20 +139,8 @@ public: * The message queue id that identifies the sending message queue. */ void setSender(MessageQueueId_t setId) override; - /** - * @brief This helper function is used by the MessageQueue class to check - * the size of an incoming message. - * @details - * The method must be overwritten by child classes if size - * checks shall be more strict. - * @return The default implementation returns HEADER_SIZE. - */ - virtual size_t getMinimumMessageSize() const override; virtual size_t getMessageSize() const override; - virtual void setMessageSize(size_t messageSize) override; - - virtual size_t getMaximumMessageSize() const override; /** * @brief This is a debug method that prints the content diff --git a/ipc/MessageQueueMessageIF.h b/ipc/MessageQueueMessageIF.h index f34cab98..19c69bfb 100644 --- a/ipc/MessageQueueMessageIF.h +++ b/ipc/MessageQueueMessageIF.h @@ -68,23 +68,11 @@ public: virtual uint8_t* getData() = 0; /** - * @brief This helper function is used by the MessageQueue class to - * check the size of an incoming message. - */ - virtual size_t getMinimumMessageSize() const = 0; - - /** - * Get message size of current message implementation. + * Get constant message size of current message implementation. * @return */ virtual size_t getMessageSize() const = 0; - virtual void setMessageSize(size_t messageSize) = 0; - /** - * Get maximum allowed size of current message implementation. - * @return - */ - virtual size_t getMaximumMessageSize() const = 0; }; diff --git a/ipc/MessageQueueSenderIF.h b/ipc/MessageQueueSenderIF.h index 8bc14948..e4b9670e 100644 --- a/ipc/MessageQueueSenderIF.h +++ b/ipc/MessageQueueSenderIF.h @@ -10,17 +10,16 @@ public: virtual ~MessageQueueSenderIF() {} /** - * Allows sending messages without actually "owing" a message queue. + * Allows sending messages without actually "owning" a message queue. * Not sure whether this is actually a good idea. */ static ReturnValue_t sendMessage(MessageQueueId_t sendTo, - MessageQueueMessageIF* message, size_t maxMessageSize, + MessageQueueMessageIF* message, MessageQueueId_t sentFrom = MessageQueueMessageIF::NO_QUEUE, - bool ignoreFault=false); + bool ignoreFault = false); private: MessageQueueSenderIF() {} }; - #endif /* FRAMEWORK_IPC_MESSAGEQUEUESENDERIF_H_ */ diff --git a/modes/ModeHelper.cpp b/modes/ModeHelper.cpp index f636c0bf..59a6d974 100644 --- a/modes/ModeHelper.cpp +++ b/modes/ModeHelper.cpp @@ -28,7 +28,6 @@ ReturnValue_t ModeHelper::handleModeCommand(CommandMessage* command) { if (result != HasReturnvaluesIF::RETURN_OK) { ModeMessage::cantReachMode(&reply, result); MessageQueueSenderIF::sendMessage(command->getSender(), &reply, - MessageQueueMessage::MAX_MESSAGE_SIZE, owner->getCommandQueue()); break; } @@ -51,7 +50,6 @@ ReturnValue_t ModeHelper::handleModeCommand(CommandMessage* command) { ModeMessage::setModeMessage(&reply, ModeMessage::REPLY_MODE_REPLY, mode, submode); MessageQueueSenderIF::sendMessage(command->getSender(), &reply, - MessageQueueMessage::MAX_MESSAGE_SIZE, owner->getCommandQueue()); } break; @@ -97,7 +95,7 @@ void ModeHelper::sendModeReplyMessage(Mode_t ownerMode, ownerMode, ownerSubmode); } MessageQueueSenderIF::sendMessage(theOneWhoCommandedAMode, &reply, - MessageQueueMessage::MAX_MESSAGE_SIZE, owner->getCommandQueue()); + owner->getCommandQueue()); } } @@ -111,7 +109,6 @@ void ModeHelper::sendModeInfoMessage(Mode_t ownerMode, ModeMessage::setModeMessage(&reply, ModeMessage::REPLY_MODE_INFO, ownerMode, ownerSubmode); MessageQueueSenderIF::sendMessage(parentQueueId, &reply, - MessageQueueMessage::MAX_MESSAGE_SIZE, owner->getCommandQueue()); } } diff --git a/monitoring/LimitViolationReporter.cpp b/monitoring/LimitViolationReporter.cpp index c6e2b5db..1378d754 100644 --- a/monitoring/LimitViolationReporter.cpp +++ b/monitoring/LimitViolationReporter.cpp @@ -34,8 +34,7 @@ ReturnValue_t LimitViolationReporter::sendLimitViolationReport(const SerializeIF MessageQueueMessage message; CommandMessage report(&message); MonitoringMessage::setLimitViolationReport(&report, storeId); - return MessageQueueSenderIF::sendMessage(reportQueue, &report, - MessageQueueMessage::MAX_MESSAGE_SIZE); + return MessageQueueSenderIF::sendMessage(reportQueue, &report); } ReturnValue_t LimitViolationReporter::checkClassLoaded() { diff --git a/osal/FreeRTOS/MessageQueue.cpp b/osal/FreeRTOS/MessageQueue.cpp index c9adf229..464a4f16 100644 --- a/osal/FreeRTOS/MessageQueue.cpp +++ b/osal/FreeRTOS/MessageQueue.cpp @@ -50,8 +50,8 @@ ReturnValue_t MessageQueue::reply(MessageQueueMessageIF* message) { ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message, MessageQueueId_t sentFrom, bool ignoreFault) { - return sendMessageFromMessageQueue(sendTo, message, maxMessageSize, sentFrom, - ignoreFault, callContext); + return sendMessageFromMessageQueue(sendTo, message, sentFrom, ignoreFault, + callContext); } @@ -80,9 +80,9 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message, } ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) { - if(message->getMaximumMessageSize() < maxMessageSize) { + if(message->getMessageSize() < maxMessageSize) { sif::error << "MessageQueue::receiveMessage: Message size " - << message->getMaximumMessageSize() << + << message->getMessageSize() << " too small to receive data!" << std::endl; return HasReturnvaluesIF::RETURN_FAILED; } @@ -127,17 +127,10 @@ bool MessageQueue::isDefaultDestinationSet() const { // static core function to send messages. ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, - MessageQueueMessageIF* message, size_t maxSize, - MessageQueueId_t sentFrom, bool ignoreFault, CallContext callContext) { + MessageQueueMessageIF* message, MessageQueueId_t sentFrom, + bool ignoreFault, CallContext callContext) { message->setSender(sentFrom); BaseType_t result; - if(message->getMaximumMessageSize() > maxSize) { - sif::error << "MessageQueue::sendMessageFromMessageQueue: Message size " - << message->getMaximumMessageSize() << " too large for queue" - " with max. message size " << maxSize << "!" - << std::endl; - return HasReturnvaluesIF::RETURN_FAILED; - } if(callContext == CallContext::TASK) { result = xQueueSendToBack(reinterpret_cast(sendTo), diff --git a/osal/FreeRTOS/MessageQueue.h b/osal/FreeRTOS/MessageQueue.h index e87e884f..b7e52bb3 100644 --- a/osal/FreeRTOS/MessageQueue.h +++ b/osal/FreeRTOS/MessageQueue.h @@ -194,9 +194,8 @@ protected: * @param context Specify whether call is made from task or from an ISR. */ static ReturnValue_t sendMessageFromMessageQueue(MessageQueueId_t sendTo, - MessageQueueMessageIF* message, size_t maxSize, - MessageQueueId_t sentFrom = NO_QUEUE, bool ignoreFault=false, - CallContext callContext = CallContext::TASK); + MessageQueueMessageIF* message, MessageQueueId_t sentFrom = NO_QUEUE, + bool ignoreFault=false, CallContext callContext = CallContext::TASK); static ReturnValue_t handleSendResult(BaseType_t result, bool ignoreFault); diff --git a/osal/FreeRTOS/QueueFactory.cpp b/osal/FreeRTOS/QueueFactory.cpp index d754b2b9..beb4969b 100644 --- a/osal/FreeRTOS/QueueFactory.cpp +++ b/osal/FreeRTOS/QueueFactory.cpp @@ -7,14 +7,9 @@ QueueFactory* QueueFactory::factoryInstance = nullptr; ReturnValue_t MessageQueueSenderIF::sendMessage(MessageQueueId_t sendTo, - MessageQueueMessageIF* message, size_t maxSize, - MessageQueueId_t sentFrom, bool ignoreFault) { - if(maxSize == 0) { - sif::error << "MessageQueueSenderIF::sendMessage: Max Size is 0!" - << std::endl; - return HasReturnvaluesIF::RETURN_FAILED; - } - return MessageQueue::sendMessageFromMessageQueue(sendTo,message, maxSize, + MessageQueueMessageIF* message, MessageQueueId_t sentFrom, + bool ignoreFault) { + return MessageQueue::sendMessageFromMessageQueue(sendTo,message, sentFrom,ignoreFault); } diff --git a/parameters/ParameterHelper.cpp b/parameters/ParameterHelper.cpp index 68ff5ab0..8b91020f 100644 --- a/parameters/ParameterHelper.cpp +++ b/parameters/ParameterHelper.cpp @@ -107,8 +107,7 @@ ReturnValue_t ParameterHelper::sendParameter(MessageQueueId_t to, uint32_t id, ParameterMessage::setParameterDumpReply(&reply, id, address); - MessageQueueSenderIF::sendMessage(to, &reply, - MessageQueueMessage::MAX_MESSAGE_SIZE, ownerQueueId); + MessageQueueSenderIF::sendMessage(to, &reply, ownerQueueId); return HasReturnvaluesIF::RETURN_OK; } @@ -130,6 +129,5 @@ void ParameterHelper::rejectCommand(MessageQueueId_t to, ReturnValue_t reason, MessageQueueMessage message; CommandMessage reply(&message); reply.setReplyRejected(reason, initialCommand); - MessageQueueSenderIF::sendMessage(to, &reply, - MessageQueueMessage::MAX_MESSAGE_SIZE, ownerQueueId); + MessageQueueSenderIF::sendMessage(to, &reply, ownerQueueId); } diff --git a/tmtcpacket/pus/TmPacketStored.cpp b/tmtcpacket/pus/TmPacketStored.cpp index d589db8d..c0ff874b 100644 --- a/tmtcpacket/pus/TmPacketStored.cpp +++ b/tmtcpacket/pus/TmPacketStored.cpp @@ -118,7 +118,7 @@ ReturnValue_t TmPacketStored::sendPacket(MessageQueueId_t destination, } TmTcMessage tmMessage(getStoreAddress()); ReturnValue_t result = MessageQueueSenderIF::sendMessage(destination, - &tmMessage, MessageQueueMessage::MAX_MESSAGE_SIZE, sentFrom); + &tmMessage, sentFrom); if (result != HasReturnvaluesIF::RETURN_OK) { deletePacket(); if (doErrorReporting) { diff --git a/tmtcservices/VerificationReporter.cpp b/tmtcservices/VerificationReporter.cpp index a54c1f8d..bcb4756c 100644 --- a/tmtcservices/VerificationReporter.cpp +++ b/tmtcservices/VerificationReporter.cpp @@ -23,7 +23,7 @@ void VerificationReporter::sendSuccessReport(uint8_t set_report_id, current_packet->getPacketId(), current_packet->getPacketSequenceControl(), 0, set_step); ReturnValue_t status = MessageQueueSenderIF::sendMessage(acknowledgeQueue, - &message, MessageQueueMessage::MAX_MESSAGE_SIZE); + &message); if (status != HasReturnvaluesIF::RETURN_OK) { sif::error << "VerificationReporter::sendSuccessReport: Error writing " "to queue. Code: " << std::hex << (uint16_t) status << std::endl; @@ -39,7 +39,7 @@ void VerificationReporter::sendSuccessReport(uint8_t set_report_id, PusVerificationMessage message(set_report_id, ackFlags, tcPacketId, tcSequenceControl, 0, set_step); ReturnValue_t status = MessageQueueSenderIF::sendMessage(acknowledgeQueue, - &message, MessageQueueMessage::MAX_MESSAGE_SIZE); + &message); if (status != HasReturnvaluesIF::RETURN_OK) { sif::error << "VerificationReporter::sendSuccessReport: Error writing " "to queue. Code: " << std::hex << (uint16_t) status << std::endl; @@ -58,7 +58,7 @@ void VerificationReporter::sendFailureReport(uint8_t report_id, current_packet->getPacketSequenceControl(), error_code, step, parameter1, parameter2); ReturnValue_t status = MessageQueueSenderIF::sendMessage(acknowledgeQueue, - &message, MessageQueueMessage::MAX_MESSAGE_SIZE); + &message); if (status != HasReturnvaluesIF::RETURN_OK) { sif::error << "VerificationReporter::sendFailureReport Error writing to queue. Code: " @@ -76,7 +76,7 @@ void VerificationReporter::sendFailureReport(uint8_t report_id, PusVerificationMessage message(report_id, ackFlags, tcPacketId, tcSequenceControl, error_code, step, parameter1, parameter2); ReturnValue_t status = MessageQueueSenderIF::sendMessage(acknowledgeQueue, - &message, MessageQueueMessage::MAX_MESSAGE_SIZE); + &message); if (status != HasReturnvaluesIF::RETURN_OK) { sif::error << "VerificationReporter::sendFailureReport Error writing to queue. Code: " From 3bf29a7315d926dc1447e954494f393061ee2c8a Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 24 Jun 2020 00:24:15 +0200 Subject: [PATCH 183/307] removed CommandMessageBase, changed interfaces --- action/ActionHelper.cpp | 15 +-- action/CommandActionHelper.cpp | 3 +- action/SimpleActionHelper.cpp | 3 +- controller/ControllerBase.cpp | 3 +- datapool/HkSwitchHelper.cpp | 3 +- datapoolglob/DataPoolAdmin.cpp | 9 +- datapoollocal/LocalDataPoolManager.cpp | 33 +++-- datapoollocal/LocalDataPoolManager.h | 2 +- devicehandlers/AssemblyBase.cpp | 3 +- devicehandlers/DeviceHandlerBase.cpp | 18 +-- devicehandlers/HealthDevice.cpp | 3 +- health/HealthHelper.cpp | 6 +- housekeeping/HousekeepingMessage.cpp | 22 ++-- housekeeping/HousekeepingMessage.h | 7 +- ipc/CommandMessage.cpp | 77 ++++++++---- ipc/CommandMessage.h | 73 ++++++++--- ipc/CommandMessageBase.cpp | 168 ++++++++++++------------- ipc/CommandMessageBase.h | 67 +++------- ipc/CommandMessageIF.h | 34 +++-- ipc/MessageQueueMessage.cpp | 41 +++--- ipc/MessageQueueMessage.h | 16 ++- ipc/MessageQueueMessageIF.h | 11 +- memory/MemoryHelper.cpp | 15 +-- modes/ModeHelper.cpp | 9 +- monitoring/LimitViolationReporter.cpp | 3 +- parameters/ParameterHelper.cpp | 6 +- power/Fuse.cpp | 3 +- power/PowerSensor.cpp | 3 +- subsystem/Subsystem.cpp | 14 +-- subsystem/SubsystemBase.cpp | 14 +-- thermal/AbstractTemperatureSensor.cpp | 5 +- thermal/Heater.cpp | 3 +- tmtcservices/CommandingServiceBase.cpp | 28 ++--- tmtcservices/CommandingServiceBase.h | 10 +- 34 files changed, 348 insertions(+), 382 deletions(-) diff --git a/action/ActionHelper.cpp b/action/ActionHelper.cpp index 0df5f2d4..57b64686 100644 --- a/action/ActionHelper.cpp +++ b/action/ActionHelper.cpp @@ -33,15 +33,13 @@ ReturnValue_t ActionHelper::initialize(MessageQueueIF* queueToUse_) { } void ActionHelper::step(uint8_t step, MessageQueueId_t reportTo, ActionId_t commandId, ReturnValue_t result) { - MessageQueueMessage message; - CommandMessage reply(&message); + CommandMessage reply; ActionMessage::setStepReply(&reply, commandId, step + STEP_OFFSET, result); queueToUse->sendMessage(reportTo, &reply); } void ActionHelper::finish(MessageQueueId_t reportTo, ActionId_t commandId, ReturnValue_t result) { - MessageQueueMessage message; - CommandMessage reply(&message); + CommandMessage reply; ActionMessage::setCompletionReply(&reply, commandId, result); queueToUse->sendMessage(reportTo, &reply); } @@ -56,8 +54,7 @@ void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t act size_t size = 0; ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size); if (result != HasReturnvaluesIF::RETURN_OK) { - MessageQueueMessage message; - CommandMessage reply(&message); + CommandMessage reply; ActionMessage::setStepReply(&reply, actionId, 0, result); queueToUse->sendMessage(commandedBy, &reply); return; @@ -65,8 +62,7 @@ void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t act result = owner->executeAction(actionId, commandedBy, dataPtr, size); ipcStore->deleteData(dataAddress); if (result != HasReturnvaluesIF::RETURN_OK) { - MessageQueueMessage message; - CommandMessage reply(&message); + CommandMessage reply; ActionMessage::setStepReply(&reply, actionId, 0, result); queueToUse->sendMessage(commandedBy, &reply); return; @@ -75,8 +71,7 @@ void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t act ReturnValue_t ActionHelper::reportData(MessageQueueId_t reportTo, ActionId_t replyId, SerializeIF* data, bool hideSender) { - MessageQueueMessage message; - CommandMessage reply(&message); + CommandMessage reply; store_address_t storeAddress; uint8_t *dataPtr; size_t maxSize = data->getSerializedSize(); diff --git a/action/CommandActionHelper.cpp b/action/CommandActionHelper.cpp index c871a2d0..77295401 100644 --- a/action/CommandActionHelper.cpp +++ b/action/CommandActionHelper.cpp @@ -53,8 +53,7 @@ ReturnValue_t CommandActionHelper::commandAction(object_id_t commandTo, ReturnValue_t CommandActionHelper::sendCommand(MessageQueueId_t queueId, ActionId_t actionId, store_address_t storeId) { - MessageQueueMessage message; - CommandMessage command(&message); + CommandMessage command; ActionMessage::setCommand(&command, actionId, storeId); ReturnValue_t result = queueToUse->sendMessage(queueId, &command); if (result != HasReturnvaluesIF::RETURN_OK) { diff --git a/action/SimpleActionHelper.cpp b/action/SimpleActionHelper.cpp index f97474b1..6861fc28 100644 --- a/action/SimpleActionHelper.cpp +++ b/action/SimpleActionHelper.cpp @@ -36,8 +36,7 @@ void SimpleActionHelper::resetHelper() { void SimpleActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId, store_address_t dataAddress) { - MessageQueueMessage message; - CommandMessage reply(&message); + CommandMessage reply; if (isExecuting) { ipcStore->deleteData(dataAddress); ActionMessage::setStepReply(&reply, actionId, 0, diff --git a/controller/ControllerBase.cpp b/controller/ControllerBase.cpp index ad0a0b97..674d0fc8 100644 --- a/controller/ControllerBase.cpp +++ b/controller/ControllerBase.cpp @@ -56,8 +56,7 @@ MessageQueueId_t ControllerBase::getCommandQueue() const { } void ControllerBase::handleQueue() { - MessageQueueMessage message; - CommandMessage command(&message); + CommandMessage command; ReturnValue_t result; for (result = commandQueue->receiveMessage(&command); result == RETURN_OK; result = commandQueue->receiveMessage(&command)) { diff --git a/datapool/HkSwitchHelper.cpp b/datapool/HkSwitchHelper.cpp index 6a923776..cf5114f7 100644 --- a/datapool/HkSwitchHelper.cpp +++ b/datapool/HkSwitchHelper.cpp @@ -21,8 +21,7 @@ ReturnValue_t HkSwitchHelper::initialize() { } ReturnValue_t HkSwitchHelper::performOperation(uint8_t operationCode) { - MessageQueueMessage message; - CommandMessage command(&message); + CommandMessage command; while (actionQueue->receiveMessage(&command) == HasReturnvaluesIF::RETURN_OK) { ReturnValue_t result = commandActionHelper.handleReply(&command); if (result == HasReturnvaluesIF::RETURN_OK) { diff --git a/datapoolglob/DataPoolAdmin.cpp b/datapoolglob/DataPoolAdmin.cpp index 6387263f..05de1eb2 100644 --- a/datapoolglob/DataPoolAdmin.cpp +++ b/datapoolglob/DataPoolAdmin.cpp @@ -66,8 +66,7 @@ ReturnValue_t DataPoolAdmin::getParameter(uint8_t domainId, } void DataPoolAdmin::handleCommand() { - MessageQueueMessage message; - CommandMessage command(&message); + CommandMessage command; ReturnValue_t result = commandQueue->receiveMessage(&command); if (result != RETURN_OK) { return; @@ -283,8 +282,7 @@ ReturnValue_t DataPoolAdmin::sendParameter(MessageQueueId_t to, uint32_t id, return result; } - MessageQueueMessage message; - CommandMessage reply(&message); + CommandMessage reply; ParameterMessage::setParameterDumpReply(&reply, id, address); @@ -296,8 +294,7 @@ ReturnValue_t DataPoolAdmin::sendParameter(MessageQueueId_t to, uint32_t id, //identical to ParameterHelper::rejectCommand() void DataPoolAdmin::rejectCommand(MessageQueueId_t to, ReturnValue_t reason, Command_t initialCommand) { - MessageQueueMessage message; - CommandMessage reply(&message); + CommandMessage reply; reply.setReplyRejected(reason, initialCommand); commandQueue->sendMessage(to, &reply); } diff --git a/datapoollocal/LocalDataPoolManager.cpp b/datapoollocal/LocalDataPoolManager.cpp index e0731a96..bc57468a 100644 --- a/datapoollocal/LocalDataPoolManager.cpp +++ b/datapoollocal/LocalDataPoolManager.cpp @@ -45,8 +45,8 @@ ReturnValue_t LocalDataPoolManager::initializeHousekeepingPoolEntriesOnce() { } ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage( - HousekeepingMessage& message) { - Command_t command = message.getCommand(); + CommandMessage* message) { + Command_t command = message->getCommand(); switch(command) { // I think those are the only commands which can be handled here.. case(HousekeepingMessage::ADD_HK_REPORT_STRUCT): @@ -55,10 +55,10 @@ ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage( return HasReturnvaluesIF::RETURN_OK; case(HousekeepingMessage::REPORT_DIAGNOSTICS_REPORT_STRUCTURES): case(HousekeepingMessage::REPORT_HK_REPORT_STRUCTURES): - return generateSetStructurePacket(message.getSid()); + //return generateSetStructurePacket(message->getSid()); case(HousekeepingMessage::GENERATE_ONE_PARAMETER_REPORT): case(HousekeepingMessage::GENERATE_ONE_DIAGNOSTICS_REPORT): - return generateHousekeepingPacket(message.getSid()); + //return generateHousekeepingPacket(message->getSid()); default: return CommandMessageIF::UNKNOWN_COMMAND; } @@ -105,19 +105,18 @@ ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid) { } // and now we set a HK message and send it the HK packet destination. - MessageQueueMessage message; - HousekeepingMessage hkMessage(&message); - hkMessage.setHkReportMessage(sid, storeId); - if(hkQueue == nullptr) { - return QUEUE_NOT_SET; - } - - if(currentHkPacketDestination != MessageQueueIF::NO_QUEUE) { - result = hkQueue->sendMessage(currentHkPacketDestination, &hkMessage); - } - else { - result = hkQueue->sendToDefault(&hkMessage); - } + //HousekeepingMessage hkMessage; +// hkMessage.setHkReportMessage(sid, storeId); +// if(hkQueue == nullptr) { +// return QUEUE_NOT_SET; +// } +// +// if(currentHkPacketDestination != MessageQueueIF::NO_QUEUE) { +// result = hkQueue->sendMessage(currentHkPacketDestination, &hkMessage); +// } +// else { +// result = hkQueue->sendToDefault(&hkMessage); +// } return result; } diff --git a/datapoollocal/LocalDataPoolManager.h b/datapoollocal/LocalDataPoolManager.h index b6491724..9d072bf4 100644 --- a/datapoollocal/LocalDataPoolManager.h +++ b/datapoollocal/LocalDataPoolManager.h @@ -58,7 +58,7 @@ public: ReturnValue_t generateHousekeepingPacket(sid_t sid); ReturnValue_t generateSetStructurePacket(sid_t sid); - ReturnValue_t handleHousekeepingMessage(HousekeepingMessage& message); + ReturnValue_t handleHousekeepingMessage(CommandMessage* message); /** * This function is used to fill the local data pool map with pool diff --git a/devicehandlers/AssemblyBase.cpp b/devicehandlers/AssemblyBase.cpp index a5dcad21..bd85d1de 100644 --- a/devicehandlers/AssemblyBase.cpp +++ b/devicehandlers/AssemblyBase.cpp @@ -148,8 +148,7 @@ void AssemblyBase::handleModeTransitionFailed(ReturnValue_t result) { void AssemblyBase::sendHealthCommand(MessageQueueId_t sendTo, HealthState health) { - MessageQueueMessage message; - CommandMessage command(&message); + CommandMessage command; HealthMessage::setHealthMessage(&command, HealthMessage::HEALTH_SET, health); if (commandQueue->sendMessage(sendTo, &command) == RETURN_OK) { diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index 1ae056a6..0442be89 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -214,12 +214,7 @@ void DeviceHandlerBase::readCommandQueue() { return; } - // This is not ideal. What if it is not a command message? (e.g. another - // message with 3 parameters). The full buffer is filled anyway - // and I could just copy the content into the other message but - // all I need are few additional functions the other message type offers. - MessageQueueMessage message; - CommandMessage command(&message); + CommandMessage command; ReturnValue_t result = commandQueue->receiveMessage(&command); if (result != RETURN_OK) { return; @@ -247,8 +242,7 @@ void DeviceHandlerBase::readCommandQueue() { return; } - HousekeepingMessage hkMessage(&message); - result = hkManager.handleHousekeepingMessage(hkMessage); + result = hkManager.handleHousekeepingMessage(&command); if (result == RETURN_OK) { return; } @@ -484,13 +478,12 @@ void DeviceHandlerBase::setMode(Mode_t newMode) { void DeviceHandlerBase::replyReturnvalueToCommand(ReturnValue_t status, uint32_t parameter) { - MessageQueueMessage message; //This is actually the reply protocol for raw and misc DH commands. if (status == RETURN_OK) { - CommandMessage reply(&message, CommandMessage::REPLY_COMMAND_OK, 0, parameter); + CommandMessage reply(CommandMessage::REPLY_COMMAND_OK, 0, parameter); commandQueue->reply(&reply); } else { - CommandMessage reply(&message, CommandMessage::REPLY_REJECTED, status, parameter); + CommandMessage reply(CommandMessage::REPLY_REJECTED, status, parameter); commandQueue->reply(&reply); } } @@ -760,8 +753,7 @@ void DeviceHandlerBase::replyRawData(const uint8_t *data, size_t len, return; } - MessageQueueMessage message; - CommandMessage command(&message); + CommandMessage command; DeviceHandlerMessage::setDeviceHandlerRawReplyMessage(&command, getObjectId(), address, isCommand); diff --git a/devicehandlers/HealthDevice.cpp b/devicehandlers/HealthDevice.cpp index 7e3a59bd..0bce34ec 100644 --- a/devicehandlers/HealthDevice.cpp +++ b/devicehandlers/HealthDevice.cpp @@ -13,8 +13,7 @@ HealthDevice::~HealthDevice() { } ReturnValue_t HealthDevice::performOperation(uint8_t opCode) { - MessageQueueMessage message; - CommandMessage command(&message); + CommandMessage command; ReturnValue_t result = commandQueue->receiveMessage(&command); if (result == HasReturnvaluesIF::RETURN_OK) { healthHelper.handleHealthCommand(&command); diff --git a/health/HealthHelper.cpp b/health/HealthHelper.cpp index 0b3bffcb..e01e6fbb 100644 --- a/health/HealthHelper.cpp +++ b/health/HealthHelper.cpp @@ -65,8 +65,7 @@ void HealthHelper::informParent(HasHealthIF::HealthState health, if (parentQueue == MessageQueueMessageIF::NO_QUEUE) { return; } - MessageQueueMessage message; - CommandMessage information(&message); + CommandMessage information; HealthMessage::setHealthMessage(&information, HealthMessage::HEALTH_INFO, health, oldHealth); if (MessageQueueSenderIF::sendMessage(parentQueue, &information, @@ -81,8 +80,7 @@ void HealthHelper::handleSetHealthCommand(CommandMessage* command) { if (command->getSender() == MessageQueueMessageIF::NO_QUEUE) { return; } - MessageQueueMessage message; - CommandMessage reply(&message); + CommandMessage reply; if (result == HasReturnvaluesIF::RETURN_OK) { HealthMessage::setHealthMessage(&reply, HealthMessage::REPLY_HEALTH_SET); diff --git a/housekeeping/HousekeepingMessage.cpp b/housekeeping/HousekeepingMessage.cpp index f425d16e..0d0f9860 100644 --- a/housekeeping/HousekeepingMessage.cpp +++ b/housekeeping/HousekeepingMessage.cpp @@ -1,15 +1,7 @@ #include #include -HousekeepingMessage::HousekeepingMessage(MessageQueueMessageIF* message): - CommandMessageBase(message) { - if(message->getMessageSize() < HK_MESSAGE_SIZE) { - sif::error << "HousekeepingMessage::HousekeepingMessage: Passed " - "message buffer can not hold minimum " << HK_MESSAGE_SIZE - << " bytes!" << std::endl; - return; - } - //message->setMessageSize(HK_MESSAGE_SIZE); +HousekeepingMessage::HousekeepingMessage(): CommandMessage() { } HousekeepingMessage::~HousekeepingMessage() {} @@ -26,14 +18,14 @@ uint32_t HousekeepingMessage::getParameter() const { void HousekeepingMessage::setHkReportMessage(sid_t sid, store_address_t storeId) { - CommandMessageBase::setCommand(HK_REPORT); + CommandMessage::setCommand(HK_REPORT); setSid(sid); setParameter(storeId.raw); } void HousekeepingMessage::setHkDiagnosticsMessage(sid_t sid, store_address_t storeId) { - CommandMessageBase::setCommand(DIAGNOSTICS_REPORT); + CommandMessage::setCommand(DIAGNOSTICS_REPORT); setSid(sid); setParameter(storeId.raw); } @@ -44,7 +36,7 @@ void HousekeepingMessage::setHkDiagnosticsMessage(sid_t sid, sid_t HousekeepingMessage::getSid() const { sid_t sid; - std::memcpy(&sid.raw, CommandMessageBase::getData(), sizeof(sid.raw)); + std::memcpy(&sid.raw, CommandMessage::getData(), sizeof(sid.raw)); return sid; } @@ -58,16 +50,16 @@ sid_t HousekeepingMessage::getHkReportMessage( } void HousekeepingMessage::setSid(sid_t sid) { - std::memcpy(CommandMessageBase::getData(), &sid.raw, sizeof(sid.raw)); + std::memcpy(CommandMessage::getData(), &sid.raw, sizeof(sid.raw)); } uint8_t* HousekeepingMessage::getData() { - return CommandMessageBase::getData() + sizeof(sid_t); + return CommandMessage::getData() + sizeof(sid_t); } const uint8_t* HousekeepingMessage::getData() const { - return CommandMessageBase::getData() + sizeof(sid_t); + return CommandMessage::getData() + sizeof(sid_t); } void HousekeepingMessage::clear() { diff --git a/housekeeping/HousekeepingMessage.h b/housekeeping/HousekeepingMessage.h index f568a418..8958201e 100644 --- a/housekeeping/HousekeepingMessage.h +++ b/housekeeping/HousekeepingMessage.h @@ -1,6 +1,7 @@ #ifndef FRAMEWORK_HK_HOUSEKEEPINGMESSAGE_H_ #define FRAMEWORK_HK_HOUSEKEEPINGMESSAGE_H_ -#include + +#include #include #include #include @@ -33,7 +34,7 @@ union sid_t { * This message is slightly larger than regular command messages to accomodate * the uint64_t structure ID (SID). */ -class HousekeepingMessage : public CommandMessageBase { +class HousekeepingMessage : public CommandMessage { public: static constexpr size_t HK_MESSAGE_SIZE = CommandMessageIF::HEADER_SIZE + @@ -44,7 +45,7 @@ public: * the message data, see CommandMessageIF and getInternalMessage(). * @param message */ - HousekeepingMessage(MessageQueueMessageIF* message); + HousekeepingMessage(); virtual ~HousekeepingMessage(); static constexpr uint8_t MESSAGE_ID = messagetypes::HOUSEKEEPING; diff --git a/ipc/CommandMessage.cpp b/ipc/CommandMessage.cpp index 11355e38..6aa433df 100644 --- a/ipc/CommandMessage.cpp +++ b/ipc/CommandMessage.cpp @@ -1,57 +1,64 @@ #include +#include #include -CommandMessage::CommandMessage(MessageQueueMessageIF* receiverMessage): - CommandMessageBase(receiverMessage) { - if(receiverMessage == nullptr) { - sif::error << "CommandMessage::CommandMessage: Don't pass a nullptr" - " as the message queue message, pass the address of an actual" - " message!" << std::endl; - return; - } -// if(receiverMessage->getMessageSize() < -// getMinimumMessageSize()) { -// sif::error << "CommandMessage::ComandMessage: Passed message buffer" -// " can not hold minimum "<< getMinimumMessageSize() -// << " bytes!" << std::endl; -// return; -// } -// internalMessage->setMessageSize(getMinimumMessageSize()); +CommandMessage::CommandMessage() { + MessageQueueMessage::setMessageSize(DEFAULT_COMMAND_MESSAGE_SIZE); + setCommand(CMD_NONE); } -CommandMessage::CommandMessage(MessageQueueMessageIF* messageToSet, - Command_t command, uint32_t parameter1, uint32_t parameter2): - CommandMessage(messageToSet) { +CommandMessage::CommandMessage(Command_t command, uint32_t parameter1, + uint32_t parameter2) { + MessageQueueMessage::setMessageSize(DEFAULT_COMMAND_MESSAGE_SIZE); setCommand(command); setParameter(parameter1); setParameter2(parameter2); } +Command_t CommandMessage::getCommand() const { + Command_t command; + std::memcpy(&command, getData(), sizeof(Command_t)); + return command; +} + +void CommandMessage::setCommand(Command_t command) { + std::memcpy(getData(), &command, sizeof(Command_t)); +} + +uint8_t CommandMessage::getMessageType() const { + // first byte of command ID. + return getCommand() >> 8 & 0xff; +} + uint32_t CommandMessage::getParameter() const { uint32_t parameter1; - std::memcpy(¶meter1, CommandMessageBase::getData(), sizeof(parameter1)); + std::memcpy(¶meter1, MessageQueueMessage::getData(), sizeof(parameter1)); return parameter1; } void CommandMessage::setParameter(uint32_t parameter1) { - std::memcpy(CommandMessageBase::getData(), ¶meter1, sizeof(parameter1)); + std::memcpy(MessageQueueMessage::getData(), ¶meter1, sizeof(parameter1)); } uint32_t CommandMessage::getParameter2() const { uint32_t parameter2; - std::memcpy(¶meter2, CommandMessageBase::getData() + sizeof(uint32_t), + std::memcpy(¶meter2, MessageQueueMessage::getData() + sizeof(uint32_t), sizeof(parameter2)); return parameter2; } void CommandMessage::setParameter2(uint32_t parameter2) { - std::memcpy(CommandMessageBase::getData() + sizeof(uint32_t), ¶meter2, + std::memcpy(MessageQueueMessage::getData() + sizeof(uint32_t), ¶meter2, sizeof(parameter2)); } -//size_t CommandMessage::getMinimumMessageSize() const { -// return MINIMUM_COMMAND_MESSAGE_SIZE; -//} +size_t CommandMessage::getMinimumMessageSize() const { + return MINIMUM_COMMAND_MESSAGE_SIZE; +} + +void CommandMessage::clear() { + CommandMessageCleaner::clearCommandMessage(this); +} bool CommandMessage::isClearedCommandMessage() { return getCommand() == CMD_NONE; @@ -62,3 +69,21 @@ void CommandMessage::setToUnknownCommand() { this->clear(); setReplyRejected(UNKNOWN_COMMAND, initialCommand); } + +void CommandMessage::setReplyRejected(ReturnValue_t reason, + Command_t initialCommand) { + std::memcpy(getData(), &reason, sizeof(reason)); + std::memcpy(getData() + sizeof(reason), &initialCommand, + sizeof(initialCommand)); +} + +ReturnValue_t CommandMessage::getReplyRejectedReason( + Command_t *initialCommand) const { + ReturnValue_t reason = HasReturnvaluesIF::RETURN_FAILED; + std::memcpy(&reason, getData(), sizeof(reason)); + if(initialCommand != nullptr) { + std::memcpy(initialCommand, getData() + sizeof(reason), + sizeof(Command_t)); + } + return reason; +} diff --git a/ipc/CommandMessage.h b/ipc/CommandMessage.h index ae4016b0..a319a0cf 100644 --- a/ipc/CommandMessage.h +++ b/ipc/CommandMessage.h @@ -1,7 +1,7 @@ #ifndef FRAMEWORK_IPC_COMMANDMESSAGE_H_ #define FRAMEWORK_IPC_COMMANDMESSAGE_H_ -#include +#include #include #include @@ -20,23 +20,21 @@ * currently has an internal message size of 28 bytes. * @author Bastian Baetz */ -class CommandMessage: public CommandMessageBase { +class CommandMessage: public MessageQueueMessage, public CommandMessageIF { public: - /** - * This is the size of a message as it is seen by the MessageQueue. - * It can hold the CommandMessage header plus 2 4-byte parameters. - * 14 of the 24 available MessageQueueMessage bytes are used. - */ - static const size_t MINIMUM_COMMAND_MESSAGE_SIZE = - CommandMessageIF::HEADER_SIZE + 2 * sizeof(uint32_t); + /** + * Default size can accomodate 2 4-byte parameters. + */ + static constexpr size_t DEFAULT_COMMAND_MESSAGE_SIZE = + CommandMessageIF::MINIMUM_COMMAND_MESSAGE_SIZE + sizeof(uint32_t); /** - * Default Constructor, does not initialize anything. - * + * @brief Default Constructor, does not initialize anything. + * @details * This constructor should be used when receiving a Message, as the * content is filled by the MessageQueue. */ - CommandMessage(MessageQueueMessageIF* receiverMessage); + CommandMessage(); /** * This constructor creates a new message with all message content * initialized @@ -45,17 +43,13 @@ public: * @param parameter1 The first parameter * @param parameter2 The second parameter */ - CommandMessage(MessageQueueMessageIF* messageToSet, Command_t command, - uint32_t parameter1, uint32_t parameter2); + CommandMessage(Command_t command, uint32_t parameter1, uint32_t parameter2); /** * @brief Default Destructor */ virtual ~CommandMessage() {} - /** MessageQueueMessageIF functions used for minimum size check. */ - //size_t getMinimumMessageSize() const override; - /** * Get the first parameter of the message * @return the first Parameter of the message @@ -91,8 +85,49 @@ public: * Sets the command to REPLY_REJECTED with parameter UNKNOWN_COMMAND. * Is needed quite often, so we better code it once only. */ - void setToUnknownCommand(); + void setToUnknownCommand() override; + + /** + * A command message can be rejected and needs to offer a function + * to set a rejected reply + * @param reason + * @param initialCommand + */ + void setReplyRejected(ReturnValue_t reason, + Command_t initialCommand) override; + /** + * Corrensonding getter function. + * @param initialCommand + * @return + */ + ReturnValue_t getReplyRejectedReason( + Command_t* initialCommand = nullptr) const override; + + virtual void clear() override; + + /** + * Read the DeviceHandlerCommand_t that is stored in the message, + * usually used after receiving. + * + * @return the Command stored in the Message + */ + virtual Command_t getCommand() const override; + /** + * Set the command type of the message. Default implementation also + * sets the message type, which will be the first byte of the command ID. + * @param the Command to be sent + */ + virtual void setCommand(Command_t command); + + /** + * Extract message ID, which is the first byte of the command ID for the + * default implementation. + * @return + */ + virtual uint8_t getMessageType() const override; + + /** MessageQueueMessageIF functions used for minimum size check. */ + size_t getMinimumMessageSize() const override; }; - #endif /* COMMANDMESSAGE_H_ */ diff --git a/ipc/CommandMessageBase.cpp b/ipc/CommandMessageBase.cpp index ea50f4ea..745e6c5f 100644 --- a/ipc/CommandMessageBase.cpp +++ b/ipc/CommandMessageBase.cpp @@ -1,86 +1,86 @@ -#include -#include -#include - -CommandMessageBase::CommandMessageBase(MessageQueueMessageIF *message): - internalMessage(message) { -} - -Command_t CommandMessageBase::getCommand() const { - Command_t command; - std::memcpy(&command, internalMessage->getData(), sizeof(Command_t)); - return command; -} - -void CommandMessageBase::setCommand(Command_t command) { - std::memcpy(internalMessage->getData(), &command, sizeof(Command_t)); -} - -uint8_t CommandMessageBase::getMessageType() const { - // first byte of command ID. - return getCommand() >> 8 & 0xff; -} - -MessageQueueId_t CommandMessageBase::getSender() const { - return internalMessage->getSender(); -} - -uint8_t* CommandMessageBase::getBuffer() { - return internalMessage->getBuffer(); -} - -void CommandMessageBase::setSender(MessageQueueId_t setId) { - internalMessage->setSender(setId); -} - -const uint8_t* CommandMessageBase::getBuffer() const { - return internalMessage->getBuffer(); -} - -// Header includes command ID. -uint8_t* CommandMessageBase::getData() { - return internalMessage->getData() + sizeof(Command_t); -} - -// Header includes command ID. -const uint8_t* CommandMessageBase::getData() const { - return internalMessage->getData() + sizeof(Command_t); -} - -//void CommandMessageBase::setMessageSize(size_t messageSize) { -// //internalMessage->setMessageSize(messageSize); +//#include +//#include +//#include +// +//CommandMessageBase::CommandMessageBase(MessageQueueMessageIF *message): +// internalMessage(message) { //} - -size_t CommandMessageBase::getMessageSize() const { - return internalMessage->getMessageSize(); -} - -MessageQueueMessageIF* CommandMessageBase::getInternalMessage() const { - return internalMessage; -} - -//size_t CommandMessageBase::getMinimumMessageSize() const { -// return MINIMUM_COMMAND_MESSAGE_BASE_SIZE; +// +//Command_t CommandMessageBase::getCommand() const { +// Command_t command; +// std::memcpy(&command, internalMessage->getData(), sizeof(Command_t)); +// return command; +//} +// +//void CommandMessageBase::setCommand(Command_t command) { +// std::memcpy(internalMessage->getData(), &command, sizeof(Command_t)); +//} +// +//uint8_t CommandMessageBase::getMessageType() const { +// // first byte of command ID. +// return getCommand() >> 8 & 0xff; +//} +// +//MessageQueueId_t CommandMessageBase::getSender() const { +// return internalMessage->getSender(); +//} +// +//uint8_t* CommandMessageBase::getBuffer() { +// return internalMessage->getBuffer(); +//} +// +//void CommandMessageBase::setSender(MessageQueueId_t setId) { +// internalMessage->setSender(setId); +//} +// +//const uint8_t* CommandMessageBase::getBuffer() const { +// return internalMessage->getBuffer(); +//} +// +//// Header includes command ID. +//uint8_t* CommandMessageBase::getData() { +// return internalMessage->getData() + sizeof(Command_t); +//} +// +//// Header includes command ID. +//const uint8_t* CommandMessageBase::getData() const { +// return internalMessage->getData() + sizeof(Command_t); +//} +// +////void CommandMessageBase::setMessageSize(size_t messageSize) { +//// //internalMessage->setMessageSize(messageSize); +////} +// +//size_t CommandMessageBase::getMessageSize() const { +// return internalMessage->getMessageSize(); +//} +// +//MessageQueueMessageIF* CommandMessageBase::getInternalMessage() const { +// return internalMessage; +//} +// +////size_t CommandMessageBase::getMinimumMessageSize() const { +//// return MINIMUM_COMMAND_MESSAGE_BASE_SIZE; +////} +// +//void CommandMessageBase::setReplyRejected(ReturnValue_t reason, +// Command_t initialCommand) { +// std::memcpy(getData(), &reason, sizeof(reason)); +// std::memcpy(getData() + sizeof(reason), &initialCommand, +// sizeof(initialCommand)); +//} +// +//ReturnValue_t CommandMessageBase::getReplyRejectedReason( +// Command_t *initialCommand) const { +// ReturnValue_t reason = HasReturnvaluesIF::RETURN_FAILED; +// std::memcpy(&reason, getData(), sizeof(reason)); +// if(initialCommand != nullptr) { +// std::memcpy(initialCommand, getData() + sizeof(reason), +// sizeof(Command_t)); +// } +// return reason; +//} +// +//void CommandMessageBase::clear() { +// CommandMessageCleaner::clearCommandMessage(this); //} - -void CommandMessageBase::setReplyRejected(ReturnValue_t reason, - Command_t initialCommand) { - std::memcpy(getData(), &reason, sizeof(reason)); - std::memcpy(getData() + sizeof(reason), &initialCommand, - sizeof(initialCommand)); -} - -ReturnValue_t CommandMessageBase::getReplyRejectedReason( - Command_t *initialCommand) const { - ReturnValue_t reason = HasReturnvaluesIF::RETURN_FAILED; - std::memcpy(&reason, getData(), sizeof(reason)); - if(initialCommand != nullptr) { - std::memcpy(initialCommand, getData() + sizeof(reason), - sizeof(Command_t)); - } - return reason; -} - -void CommandMessageBase::clear() { - CommandMessageCleaner::clearCommandMessage(this); -} diff --git a/ipc/CommandMessageBase.h b/ipc/CommandMessageBase.h index 1ee1b970..59795114 100644 --- a/ipc/CommandMessageBase.h +++ b/ipc/CommandMessageBase.h @@ -23,67 +23,28 @@ */ class CommandMessageBase: public CommandMessageIF { public: - //! This minimum size is derived from the interface requirement to be able - //! to set a rejected reply, which contains a returnvalue and the initial - //! command. - static constexpr size_t MINIMUM_COMMAND_MESSAGE_BASE_SIZE = - CommandMessageIF::HEADER_SIZE + sizeof(ReturnValue_t) + - sizeof(Command_t); + CommandMessageBase(MessageQueueMessageIF* message); - /** - * Read the DeviceHandlerCommand_t that is stored in the message, - * usually used after receiving. - * - * @return the Command stored in the Message - */ - virtual Command_t getCommand() const override; - /** - * Set the command type of the message. Default implementation also - * sets the message type, which will be the first byte of the command ID. - * @param the Command to be sent - */ - virtual void setCommand(Command_t command); - /** - * Extract message ID, which is the first byte of the command ID for the - * default implementation. - * @return - */ - virtual uint8_t getMessageType() const override; - /* - * MessageQueueMessageIF functions, which generally just call the - * respective functions of the internal message queue message. - */ - virtual uint8_t * getBuffer() override; - virtual const uint8_t * getBuffer() const override; - virtual void setSender(MessageQueueId_t setId) override; - virtual MessageQueueId_t getSender() const override; - virtual uint8_t * getData() override; - virtual const uint8_t* getData() const override; - virtual size_t getMessageSize() const override; +// /* +// * MessageQueueMessageIF functions, which generally just call the +// * respective functions of the internal message queue message. +// */ +// virtual uint8_t * getBuffer() override; +// virtual const uint8_t * getBuffer() const override; +// virtual void setSender(MessageQueueId_t setId) override; +// virtual MessageQueueId_t getSender() const override; +// virtual uint8_t * getData() override; +// virtual const uint8_t* getData() const override; +// virtual size_t getMessageSize() const override; - /** - * A command message can be rejected and needs to offer a function - * to set a rejected reply - * @param reason - * @param initialCommand - */ - void setReplyRejected(ReturnValue_t reason, - Command_t initialCommand) override; - /** - * Corrensonding getter function. - * @param initialCommand - * @return - */ - ReturnValue_t getReplyRejectedReason( - Command_t* initialCommand = nullptr) const override; - virtual MessageQueueMessageIF* getInternalMessage() const override; + //virtual MessageQueueMessageIF* getInternalMessage() const override; + - virtual void clear() override; protected: /** * @brief Pointer to the message containing the data. diff --git a/ipc/CommandMessageIF.h b/ipc/CommandMessageIF.h index fbfbddbb..ca050c32 100644 --- a/ipc/CommandMessageIF.h +++ b/ipc/CommandMessageIF.h @@ -5,20 +5,24 @@ #include #include - #define MAKE_COMMAND_ID( number ) ((MESSAGE_ID << 8) + (number)) typedef uint16_t Command_t; -// TODO: actually, this interface propably does not have to implement -// MQM IF, because there is a getter function for the internal message.. -// But it is also convenient to have the full access to all MQM IF functions. -// That way, I can just pass CommandMessages to functions expecting a MQM IF. -// The command message implementations just forwards the calls. Maybe -// we should just leave it like that. -class CommandMessageIF: public MessageQueueMessageIF { +class CommandMessageIF: virtual public MessageQueueMessageIF { public: - static constexpr size_t HEADER_SIZE = sizeof(MessageQueueId_t) + + /** + * Header consists of sender ID and command ID. + */ + static constexpr size_t HEADER_SIZE = MessageQueueMessageIF::HEADER_SIZE + sizeof(Command_t); + /** + * This minimum size is derived from the interface requirement to be able + * to set a rejected reply, which contains a returnvalue and the initial + * command. + */ + static constexpr size_t MINIMUM_COMMAND_MESSAGE_SIZE = + CommandMessageIF::HEADER_SIZE + sizeof(ReturnValue_t) + + sizeof(Command_t); static const uint8_t INTERFACE_ID = CLASS_ID::COMMAND_MESSAGE; static const ReturnValue_t UNKNOWN_COMMAND = MAKE_RETURN_CODE(0x01); @@ -60,15 +64,9 @@ public: virtual ReturnValue_t getReplyRejectedReason( Command_t* initialCommand = nullptr) const = 0; - /** - * This function is used to get a pointer to the internal message, as - * the command message implementations always operate on the memory - * contained in the message queue message implementation. - * This pointer can be used to set the internal message of different - * command message implementations. - * @return - */ - virtual MessageQueueMessageIF* getInternalMessage() const = 0; + virtual void setToUnknownCommand() = 0; + + virtual void clear() = 0; }; diff --git a/ipc/MessageQueueMessage.cpp b/ipc/MessageQueueMessage.cpp index f3665074..0f4d861b 100644 --- a/ipc/MessageQueueMessage.cpp +++ b/ipc/MessageQueueMessage.cpp @@ -1,10 +1,10 @@ #include #include - -#include +#include +#include MessageQueueMessage::MessageQueueMessage() : - messageSize(this->HEADER_SIZE) { + messageSize(getMinimumMessageSize()) { memset(this->internalBuffer, 0, sizeof(this->internalBuffer)); } @@ -51,17 +51,15 @@ void MessageQueueMessage::setSender(MessageQueueId_t setId) { memcpy(this->internalBuffer, &setId, sizeof(MessageQueueId_t)); } -//size_t MessageQueueMessage::getMinimumMessageSize() const { -// return this->HEADER_SIZE; -//} - -void MessageQueueMessage::print() { - sif::debug << "MessageQueueMessage has size: " << this->messageSize << - std::hex << std::endl; - for (uint8_t count = 0; count < this->messageSize; count++) { - sif::debug << (uint32_t) this->internalBuffer[count] << ":"; +void MessageQueueMessage::print(bool printWholeMessage) { + sif::debug << "MessageQueueMessage content: " << std::endl; + if(printWholeMessage) { + arrayprinter::print(getData(), getMaximumMessageSize()); } - sif::debug << std::dec << std::endl; + else { + arrayprinter::print(getData(), getMessageSize()); + } + } void MessageQueueMessage::clear() { @@ -69,9 +67,18 @@ void MessageQueueMessage::clear() { } size_t MessageQueueMessage::getMessageSize() const { - return this->MAX_MESSAGE_SIZE; + return this->messageSize; +} + +void MessageQueueMessage::setMessageSize(size_t messageSize) { + this->messageSize = messageSize; +} + +size_t MessageQueueMessage::getMinimumMessageSize() const { + return this->MIN_MESSAGE_SIZE; +} + +size_t MessageQueueMessage::getMaximumMessageSize() const { + return this->MAX_MESSAGE_SIZE; } -//void MessageQueueMessage::setMessageSize(size_t messageSize) { -// this->messageSize = messageSize; -//} diff --git a/ipc/MessageQueueMessage.h b/ipc/MessageQueueMessage.h index a994c323..c4e82a94 100644 --- a/ipc/MessageQueueMessage.h +++ b/ipc/MessageQueueMessage.h @@ -23,7 +23,7 @@ * receive messages from other tasks. * @ingroup message_queue */ -class MessageQueueMessage: public MessageQueueMessageIF { +class MessageQueueMessage: virtual public MessageQueueMessageIF { public: /** * @brief The class is initialized empty with this constructor. @@ -74,11 +74,7 @@ public: * as small as possible. */ static const size_t MAX_DATA_SIZE = 24; - /** - * @brief This constants defines the size of the header, - * which is added to every message. - */ - static const size_t HEADER_SIZE = sizeof(MessageQueueId_t); + /** * @brief This constant defines the maximum total size in bytes * of a sent message. @@ -141,12 +137,14 @@ public: void setSender(MessageQueueId_t setId) override; virtual size_t getMessageSize() const override; + virtual void setMessageSize(size_t messageSize) override; + virtual size_t getMinimumMessageSize() const override; + virtual size_t getMaximumMessageSize() const override; /** - * @brief This is a debug method that prints the content - * (till messageSize) to the debug output. + * @brief This is a debug method that prints the content. */ - void print(); + void print(bool printWholeMessage); }; #endif /* MESSAGEQUEUEMESSAGE_H_ */ diff --git a/ipc/MessageQueueMessageIF.h b/ipc/MessageQueueMessageIF.h index 19c69bfb..c6c677c1 100644 --- a/ipc/MessageQueueMessageIF.h +++ b/ipc/MessageQueueMessageIF.h @@ -18,7 +18,12 @@ typedef uint32_t MessageQueueId_t; class MessageQueueMessageIF { public: - static const MessageQueueId_t NO_QUEUE = 0xffffffff; + static const MessageQueueId_t NO_QUEUE = -1; + /** + * @brief This constants defines the size of the header, + * which is added to every message. + */ + static const size_t HEADER_SIZE = sizeof(MessageQueueId_t); virtual ~MessageQueueMessageIF() {}; @@ -73,6 +78,10 @@ public: */ virtual size_t getMessageSize() const = 0; + virtual void setMessageSize(size_t messageSize) = 0; + virtual size_t getMinimumMessageSize() const = 0; + virtual size_t getMaximumMessageSize() const = 0; + }; diff --git a/memory/MemoryHelper.cpp b/memory/MemoryHelper.cpp index fb4d9eb6..ea7ef9e1 100644 --- a/memory/MemoryHelper.cpp +++ b/memory/MemoryHelper.cpp @@ -51,16 +51,14 @@ void MemoryHelper::completeLoad(ReturnValue_t errorCode, break; default: ipcStore->deleteData(ipcAddress); - MessageQueueMessage message; - CommandMessage reply(&message); + CommandMessage reply; MemoryMessage::setMemoryReplyFailed(&reply, errorCode, MemoryMessage::CMD_MEMORY_LOAD); queueToUse->sendMessage(lastSender, &reply); return; } //Only reached on success - MessageQueueMessage message; - CommandMessage reply(&message, CommandMessage::REPLY_COMMAND_OK, 0, 0); + CommandMessage reply( CommandMessage::REPLY_COMMAND_OK, 0, 0); queueToUse->sendMessage(lastSender, &reply); ipcStore->deleteData(ipcAddress); } @@ -68,8 +66,7 @@ void MemoryHelper::completeLoad(ReturnValue_t errorCode, void MemoryHelper::completeDump(ReturnValue_t errorCode, const uint8_t* dataToCopy, const uint32_t size) { busy = false; - MessageQueueMessage message; - CommandMessage reply(&message); + CommandMessage reply; MemoryMessage::setMemoryReplyFailed(&reply, errorCode, lastCommand); switch (errorCode) { case HasMemoryIF::DO_IT_MYSELF: @@ -154,8 +151,7 @@ void MemoryHelper::handleMemoryLoad(CommandMessage* message) { completeLoad(returnCode, p_data, size, dataPointer); } else { //At least inform sender. - MessageQueueMessage message; - CommandMessage reply(&message); + CommandMessage reply; MemoryMessage::setMemoryReplyFailed(&reply, returnCode, MemoryMessage::CMD_MEMORY_LOAD); queueToUse->sendMessage(lastSender, &reply); @@ -173,8 +169,7 @@ void MemoryHelper::handleMemoryCheckOrDump(CommandMessage* message) { reservedSpaceInIPC); completeDump(returnCode, dataPointer, size); } else { - MessageQueueMessage message; - CommandMessage reply(&message); + CommandMessage reply; MemoryMessage::setMemoryReplyFailed(&reply, returnCode, lastCommand); queueToUse->sendMessage(lastSender, &reply); } diff --git a/modes/ModeHelper.cpp b/modes/ModeHelper.cpp index 59a6d974..030f1db3 100644 --- a/modes/ModeHelper.cpp +++ b/modes/ModeHelper.cpp @@ -12,8 +12,7 @@ ModeHelper::~ModeHelper() { } ReturnValue_t ModeHelper::handleModeCommand(CommandMessage* command) { - MessageQueueMessage message; - CommandMessage reply(&message); + CommandMessage reply; Mode_t mode; Submode_t submode; switch (command->getCommand()) { @@ -79,8 +78,7 @@ void ModeHelper::modeChanged(Mode_t ownerMode, Submode_t ownerSubmode) { void ModeHelper::sendModeReplyMessage(Mode_t ownerMode, Submode_t ownerSubmode) { - MessageQueueMessage message; - CommandMessage reply(&message); + CommandMessage reply; if (theOneWhoCommandedAMode != MessageQueueMessageIF::NO_QUEUE) { if (ownerMode != commandedMode or ownerSubmode != commandedSubmode) @@ -101,8 +99,7 @@ void ModeHelper::sendModeReplyMessage(Mode_t ownerMode, void ModeHelper::sendModeInfoMessage(Mode_t ownerMode, Submode_t ownerSubmode) { - MessageQueueMessage message; - CommandMessage reply(&message); + CommandMessage reply; if (theOneWhoCommandedAMode != parentQueueId and parentQueueId != MessageQueueMessageIF::NO_QUEUE) { diff --git a/monitoring/LimitViolationReporter.cpp b/monitoring/LimitViolationReporter.cpp index 1378d754..234a0bff 100644 --- a/monitoring/LimitViolationReporter.cpp +++ b/monitoring/LimitViolationReporter.cpp @@ -31,8 +31,7 @@ ReturnValue_t LimitViolationReporter::sendLimitViolationReport(const SerializeIF if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - MessageQueueMessage message; - CommandMessage report(&message); + CommandMessage report; MonitoringMessage::setLimitViolationReport(&report, storeId); return MessageQueueSenderIF::sendMessage(reportQueue, &report); } diff --git a/parameters/ParameterHelper.cpp b/parameters/ParameterHelper.cpp index 8b91020f..20e7e8ec 100644 --- a/parameters/ParameterHelper.cpp +++ b/parameters/ParameterHelper.cpp @@ -102,8 +102,7 @@ ReturnValue_t ParameterHelper::sendParameter(MessageQueueId_t to, uint32_t id, return result; } - MessageQueueMessage message; - CommandMessage reply(&message); + CommandMessage reply; ParameterMessage::setParameterDumpReply(&reply, id, address); @@ -126,8 +125,7 @@ ReturnValue_t ParameterHelper::initialize() { void ParameterHelper::rejectCommand(MessageQueueId_t to, ReturnValue_t reason, Command_t initialCommand) { - MessageQueueMessage message; - CommandMessage reply(&message); + CommandMessage reply; reply.setReplyRejected(reason, initialCommand); MessageQueueSenderIF::sendMessage(to, &reply, ownerQueueId); } diff --git a/power/Fuse.cpp b/power/Fuse.cpp index a80a111f..eee91984 100644 --- a/power/Fuse.cpp +++ b/power/Fuse.cpp @@ -163,8 +163,7 @@ void Fuse::setAllMonitorsToUnchecked() { } void Fuse::checkCommandQueue() { - MessageQueueMessage message; - CommandMessage command(&message); + CommandMessage command; ReturnValue_t result = commandQueue->receiveMessage(&command); if (result != HasReturnvaluesIF::RETURN_OK) { return; diff --git a/power/PowerSensor.cpp b/power/PowerSensor.cpp index b1aea270..5433acc9 100644 --- a/power/PowerSensor.cpp +++ b/power/PowerSensor.cpp @@ -74,8 +74,7 @@ void PowerSensor::setAllMonitorsToUnchecked() { } void PowerSensor::checkCommandQueue() { - MessageQueueMessage message; - CommandMessage command(&message); + CommandMessage command; ReturnValue_t result = commandQueue->receiveMessage(&command); if (result != HasReturnvaluesIF::RETURN_OK) { return; diff --git a/subsystem/Subsystem.cpp b/subsystem/Subsystem.cpp index d774b4d5..52f2c474 100644 --- a/subsystem/Subsystem.cpp +++ b/subsystem/Subsystem.cpp @@ -309,8 +309,7 @@ ReturnValue_t Subsystem::handleCommandMessage(CommandMessage* message) { break; case ModeSequenceMessage::READ_FREE_SEQUENCE_SLOTS: { uint32_t freeSlots = modeSequences.maxSize() - modeSequences.size(); - MessageQueueMessage message; - CommandMessage reply(&message); + CommandMessage reply; ModeSequenceMessage::setModeSequenceMessage(&reply, ModeSequenceMessage::FREE_SEQUENCE_SLOTS, freeSlots); commandQueue->reply(&reply); @@ -318,8 +317,7 @@ ReturnValue_t Subsystem::handleCommandMessage(CommandMessage* message) { break; case ModeSequenceMessage::READ_FREE_TABLE_SLOTS: { uint32_t free = modeTables.maxSize() - modeTables.size(); - MessageQueueMessage message; - CommandMessage reply(&message); + CommandMessage reply; ModeSequenceMessage::setModeSequenceMessage(&reply, ModeSequenceMessage::FREE_TABLE_SLOTS, free); commandQueue->reply(&reply); @@ -332,12 +330,11 @@ ReturnValue_t Subsystem::handleCommandMessage(CommandMessage* message) { } void Subsystem::replyToCommand(ReturnValue_t status, uint32_t parameter) { - MessageQueueMessage message; if (status == RETURN_OK) { - CommandMessage reply(&message, CommandMessage::REPLY_COMMAND_OK, 0, 0); + CommandMessage reply(CommandMessage::REPLY_COMMAND_OK, 0, 0); commandQueue->reply(&reply); } else { - CommandMessage reply(&message, CommandMessage::REPLY_REJECTED, status, 0); + CommandMessage reply(CommandMessage::REPLY_REJECTED, status, 0); commandQueue->reply(&reply); } } @@ -620,8 +617,7 @@ void Subsystem::sendSerializablesAsCommandMessage(Command_t command, for (uint8_t i = 0; i < count; i++) { elements[i]->serialize(&storeBuffer, &size, maxSize, true); } - MessageQueueMessage message; - CommandMessage reply(&message); + CommandMessage reply; ModeSequenceMessage::setModeSequenceMessage(&reply, command, address); if (commandQueue->reply(&reply) != RETURN_OK) { IPCStore->deleteData(address); diff --git a/subsystem/SubsystemBase.cpp b/subsystem/SubsystemBase.cpp index 5527f215..737accef 100644 --- a/subsystem/SubsystemBase.cpp +++ b/subsystem/SubsystemBase.cpp @@ -77,8 +77,7 @@ ReturnValue_t SubsystemBase::checkStateAgainstTable( } void SubsystemBase::executeTable(HybridIterator tableIter, Submode_t targetSubmode) { - MessageQueueMessage message; - CommandMessage command(&message); + CommandMessage command; std::map::iterator iter; @@ -129,7 +128,7 @@ void SubsystemBase::executeTable(HybridIterator tableIter, Submod continue; //don't send redundant mode commands (produces event spam), but still command if mode is forced to reach lower levels } ReturnValue_t result = commandQueue->sendMessage( - iter->second.commandQueue, &message); + iter->second.commandQueue, &command); if (result == RETURN_OK) { ++commandsOutstanding; } @@ -297,8 +296,7 @@ void SubsystemBase::setToExternalControl() { void SubsystemBase::announceMode(bool recursive) { triggerEvent(MODE_INFO, mode, submode); if (recursive) { - MessageQueueMessage message; - CommandMessage command(&message); + CommandMessage command; ModeMessage::setModeMessage(&command, ModeMessage::CMD_MODE_ANNOUNCE_RECURSIVELY, 0, 0); commandAllChildren(&command); @@ -307,8 +305,7 @@ void SubsystemBase::announceMode(bool recursive) { void SubsystemBase::checkCommandQueue() { ReturnValue_t result; - MessageQueueMessage message; - CommandMessage command(&message); + CommandMessage command; for (result = commandQueue->receiveMessage(&command); result == RETURN_OK; result = commandQueue->receiveMessage(&command)) { @@ -330,8 +327,7 @@ void SubsystemBase::checkCommandQueue() { result = handleCommandMessage(&command); if (result != RETURN_OK) { - MessageQueueMessage message; - CommandMessage reply(&message); + CommandMessage reply; reply.setReplyRejected(CommandMessage::UNKNOWN_COMMAND, command.getCommand()); replyToCommand(&reply); diff --git a/thermal/AbstractTemperatureSensor.cpp b/thermal/AbstractTemperatureSensor.cpp index 759af87e..41230f59 100644 --- a/thermal/AbstractTemperatureSensor.cpp +++ b/thermal/AbstractTemperatureSensor.cpp @@ -44,8 +44,7 @@ ReturnValue_t AbstractTemperatureSensor::performHealthOp() { } void AbstractTemperatureSensor::handleCommandQueue() { - MessageQueueMessage message; - CommandMessage command(&message); + CommandMessage command; ReturnValue_t result = commandQueue->receiveMessage(&command); if (result == HasReturnvaluesIF::RETURN_OK) { result = healthHelper.handleHealthCommand(&command); @@ -57,7 +56,7 @@ void AbstractTemperatureSensor::handleCommandQueue() { return; } command.setToUnknownCommand(); - commandQueue->reply(&message); + commandQueue->reply(&command); } } diff --git a/thermal/Heater.cpp b/thermal/Heater.cpp index 6e191fc1..b1cf38f2 100644 --- a/thermal/Heater.cpp +++ b/thermal/Heater.cpp @@ -279,8 +279,7 @@ ReturnValue_t Heater::initialize() { } void Heater::handleQueue() { - MessageQueueMessage message; - CommandMessage command(&message); + CommandMessage command; ReturnValue_t result = commandQueue->receiveMessage(&command); if (result == HasReturnvaluesIF::RETURN_OK) { result = healthHelper.handleHealthCommand(&command); diff --git a/tmtcservices/CommandingServiceBase.cpp b/tmtcservices/CommandingServiceBase.cpp index 4d29c10e..bd6fa5b5 100644 --- a/tmtcservices/CommandingServiceBase.cpp +++ b/tmtcservices/CommandingServiceBase.cpp @@ -76,28 +76,18 @@ ReturnValue_t CommandingServiceBase::initialize() { } void CommandingServiceBase::handleCommandQueue() { - MessageQueueMessage message; - CommandMessage reply(&message); + CommandMessage reply; ReturnValue_t result = RETURN_FAILED; for (result = commandQueue->receiveMessage(&reply); result == RETURN_OK; result = commandQueue->receiveMessage(&reply)) { - if(reply.getInternalMessage() == nullptr) { - // This should never happen unless the passed message maximum size - // is too small! - sif::error << "CommandingServiceBase::handleCommandMessage: Reply" - "does not satisfy minimum requirements for a command " - "message!" << std::endl; - continue; - } handleCommandMessage(&reply); } } -void CommandingServiceBase::handleCommandMessage(CommandMessageIF* reply) { +void CommandingServiceBase::handleCommandMessage(CommandMessage* reply) { bool isStep = false; - MessageQueueMessage message; - CommandMessage nextCommand(&message); + CommandMessage nextCommand; CommandMapIter iter = commandMap.find(reply->getSender()); // handle unrequested reply first @@ -303,8 +293,7 @@ ReturnValue_t CommandingServiceBase::sendTmPacket(uint8_t subservice, void CommandingServiceBase::startExecution(TcPacketStored *storedPacket, CommandMapIter iter) { ReturnValue_t result = RETURN_OK; - MessageQueueMessage message; - CommandMessage command(&message); + CommandMessage command; iter->subservice = storedPacket->getSubService(); result = prepareCommand(&command, iter->subservice, storedPacket->getApplicationData(), @@ -316,7 +305,7 @@ void CommandingServiceBase::startExecution(TcPacketStored *storedPacket, case RETURN_OK: if (command.getCommand() != CommandMessage::CMD_NONE) { sendResult = commandQueue->sendMessage(iter.value->first, - &message); + &command); } if (sendResult == RETURN_OK) { Clock::getUptime(&iter->uptimeOfStart); @@ -338,7 +327,7 @@ void CommandingServiceBase::startExecution(TcPacketStored *storedPacket, if (command.getCommand() != CommandMessage::CMD_NONE) { //Fire-and-forget command. sendResult = commandQueue->sendMessage(iter.value->first, - &message); + &command); } if (sendResult == RETURN_OK) { verificationReporter.sendSuccessReport(TC_VERIFY::START_SUCCESS, @@ -384,9 +373,8 @@ void CommandingServiceBase::checkAndExecuteFifo(CommandMapIter iter) { } -void CommandingServiceBase::handleUnrequestedReply(CommandMessageIF* reply) { - CommandMessage commandReply(reply->getInternalMessage()); - commandReply.clear(); +void CommandingServiceBase::handleUnrequestedReply(CommandMessage* reply) { + reply->clear(); } diff --git a/tmtcservices/CommandingServiceBase.h b/tmtcservices/CommandingServiceBase.h index 05f50709..54a0dc7a 100644 --- a/tmtcservices/CommandingServiceBase.h +++ b/tmtcservices/CommandingServiceBase.h @@ -139,7 +139,7 @@ protected: * @param objectId Target object ID * @return */ - virtual ReturnValue_t prepareCommand(CommandMessageIF *message, + virtual ReturnValue_t prepareCommand(CommandMessage* message, uint8_t subservice, const uint8_t *tcData, size_t tcDataLen, uint32_t *state, object_id_t objectId) = 0; @@ -168,9 +168,9 @@ protected: * a failure verification message with the reason as the error parameter * and the initial command as failure parameter 1. */ - virtual ReturnValue_t handleReply(const CommandMessageIF *reply, + virtual ReturnValue_t handleReply(const CommandMessage* reply, Command_t previousCommand, uint32_t *state, - CommandMessageIF *optionalNextCommand, object_id_t objectId, + CommandMessage* optionalNextCommand, object_id_t objectId, bool *isStep) = 0; /** @@ -182,7 +182,7 @@ protected: * Reply which is non-const so the default implementation can clear the * message. */ - virtual void handleUnrequestedReply(CommandMessageIF *reply); + virtual void handleUnrequestedReply(CommandMessage* reply); virtual void doPeriodicOperation(); @@ -310,7 +310,7 @@ private: void startExecution(TcPacketStored *storedPacket, CommandMapIter iter); - void handleCommandMessage(CommandMessageIF* reply); + void handleCommandMessage(CommandMessage* reply); void handleReplyHandlerResult(ReturnValue_t result, CommandMapIter iter, CommandMessageIF* nextCommand,CommandMessageIF* reply, bool& isStep); From c7c49b4239fe42f4c4da47eba686c41ff687cf17 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 24 Jun 2020 00:30:32 +0200 Subject: [PATCH 184/307] deleted command messge base --- ipc/CommandMessageBase.cpp | 86 -------------------------- ipc/CommandMessageBase.h | 60 ------------------ ipc/CommandMessageIF.h | 2 +- ipc/MessageQueueMessage.h | 2 +- tmtcservices/CommandingServiceBase.cpp | 4 +- tmtcservices/CommandingServiceBase.h | 2 +- 6 files changed, 5 insertions(+), 151 deletions(-) delete mode 100644 ipc/CommandMessageBase.cpp delete mode 100644 ipc/CommandMessageBase.h diff --git a/ipc/CommandMessageBase.cpp b/ipc/CommandMessageBase.cpp deleted file mode 100644 index 745e6c5f..00000000 --- a/ipc/CommandMessageBase.cpp +++ /dev/null @@ -1,86 +0,0 @@ -//#include -//#include -//#include -// -//CommandMessageBase::CommandMessageBase(MessageQueueMessageIF *message): -// internalMessage(message) { -//} -// -//Command_t CommandMessageBase::getCommand() const { -// Command_t command; -// std::memcpy(&command, internalMessage->getData(), sizeof(Command_t)); -// return command; -//} -// -//void CommandMessageBase::setCommand(Command_t command) { -// std::memcpy(internalMessage->getData(), &command, sizeof(Command_t)); -//} -// -//uint8_t CommandMessageBase::getMessageType() const { -// // first byte of command ID. -// return getCommand() >> 8 & 0xff; -//} -// -//MessageQueueId_t CommandMessageBase::getSender() const { -// return internalMessage->getSender(); -//} -// -//uint8_t* CommandMessageBase::getBuffer() { -// return internalMessage->getBuffer(); -//} -// -//void CommandMessageBase::setSender(MessageQueueId_t setId) { -// internalMessage->setSender(setId); -//} -// -//const uint8_t* CommandMessageBase::getBuffer() const { -// return internalMessage->getBuffer(); -//} -// -//// Header includes command ID. -//uint8_t* CommandMessageBase::getData() { -// return internalMessage->getData() + sizeof(Command_t); -//} -// -//// Header includes command ID. -//const uint8_t* CommandMessageBase::getData() const { -// return internalMessage->getData() + sizeof(Command_t); -//} -// -////void CommandMessageBase::setMessageSize(size_t messageSize) { -//// //internalMessage->setMessageSize(messageSize); -////} -// -//size_t CommandMessageBase::getMessageSize() const { -// return internalMessage->getMessageSize(); -//} -// -//MessageQueueMessageIF* CommandMessageBase::getInternalMessage() const { -// return internalMessage; -//} -// -////size_t CommandMessageBase::getMinimumMessageSize() const { -//// return MINIMUM_COMMAND_MESSAGE_BASE_SIZE; -////} -// -//void CommandMessageBase::setReplyRejected(ReturnValue_t reason, -// Command_t initialCommand) { -// std::memcpy(getData(), &reason, sizeof(reason)); -// std::memcpy(getData() + sizeof(reason), &initialCommand, -// sizeof(initialCommand)); -//} -// -//ReturnValue_t CommandMessageBase::getReplyRejectedReason( -// Command_t *initialCommand) const { -// ReturnValue_t reason = HasReturnvaluesIF::RETURN_FAILED; -// std::memcpy(&reason, getData(), sizeof(reason)); -// if(initialCommand != nullptr) { -// std::memcpy(initialCommand, getData() + sizeof(reason), -// sizeof(Command_t)); -// } -// return reason; -//} -// -//void CommandMessageBase::clear() { -// CommandMessageCleaner::clearCommandMessage(this); -//} diff --git a/ipc/CommandMessageBase.h b/ipc/CommandMessageBase.h deleted file mode 100644 index 59795114..00000000 --- a/ipc/CommandMessageBase.h +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef FRAMEWORK_IPC_COMMANDMESSAGEBASE_H_ -#define FRAMEWORK_IPC_COMMANDMESSAGEBASE_H_ -#include -#include - -/** - * @brief Base implementation of a generic command message, which has - * a Command_t ID and message type ID in the header in addition - * to the sender message queue ID. - * @details - * This is the base implementation serves as a base for other command messages - * and which implements most functions required for MessageQueueMessageIF. - * The only functions which have to be supplied by a specific command message - * impelementations are the size related functions which are used for - * size checks: - * - * 1. getMinimumMessageSize() - * - * The maximum message size generally depends on the buffer size of the passed - * internal message. - * Don't forget to set the message size of the passed message in the concrete - * commandmessage implementation! - */ -class CommandMessageBase: public CommandMessageIF { -public: - - - CommandMessageBase(MessageQueueMessageIF* message); - - - -// /* -// * MessageQueueMessageIF functions, which generally just call the -// * respective functions of the internal message queue message. -// */ -// virtual uint8_t * getBuffer() override; -// virtual const uint8_t * getBuffer() const override; -// virtual void setSender(MessageQueueId_t setId) override; -// virtual MessageQueueId_t getSender() const override; -// virtual uint8_t * getData() override; -// virtual const uint8_t* getData() const override; -// virtual size_t getMessageSize() const override; - - - //virtual MessageQueueMessageIF* getInternalMessage() const override; - - -protected: - /** - * @brief Pointer to the message containing the data. - * @details - * The command message does not actually own the memory containing a - * message, it just oprates on it via a pointer to a message queue message. - */ - MessageQueueMessageIF* internalMessage = nullptr; -}; - - - -#endif /* FRAMEWORK_IPC_COMMANDMESSAGEBASE_H_ */ diff --git a/ipc/CommandMessageIF.h b/ipc/CommandMessageIF.h index ca050c32..2cb6324e 100644 --- a/ipc/CommandMessageIF.h +++ b/ipc/CommandMessageIF.h @@ -8,7 +8,7 @@ #define MAKE_COMMAND_ID( number ) ((MESSAGE_ID << 8) + (number)) typedef uint16_t Command_t; -class CommandMessageIF: virtual public MessageQueueMessageIF { +class CommandMessageIF { public: /** * Header consists of sender ID and command ID. diff --git a/ipc/MessageQueueMessage.h b/ipc/MessageQueueMessage.h index c4e82a94..3d5d4283 100644 --- a/ipc/MessageQueueMessage.h +++ b/ipc/MessageQueueMessage.h @@ -23,7 +23,7 @@ * receive messages from other tasks. * @ingroup message_queue */ -class MessageQueueMessage: virtual public MessageQueueMessageIF { +class MessageQueueMessage: public MessageQueueMessageIF { public: /** * @brief The class is initialized empty with this constructor. diff --git a/tmtcservices/CommandingServiceBase.cpp b/tmtcservices/CommandingServiceBase.cpp index bd6fa5b5..acf66389 100644 --- a/tmtcservices/CommandingServiceBase.cpp +++ b/tmtcservices/CommandingServiceBase.cpp @@ -146,8 +146,8 @@ void CommandingServiceBase::handleCommandMessage(CommandMessage* reply) { } void CommandingServiceBase::handleReplyHandlerResult(ReturnValue_t result, - CommandMapIter iter, CommandMessageIF* nextCommand, - CommandMessageIF* reply, bool& isStep) { + CommandMapIter iter, CommandMessage* nextCommand, + CommandMessage* reply, bool& isStep) { iter->command = nextCommand->getCommand(); // In case a new command is to be sent immediately, this is performed here. diff --git a/tmtcservices/CommandingServiceBase.h b/tmtcservices/CommandingServiceBase.h index 54a0dc7a..8806bd52 100644 --- a/tmtcservices/CommandingServiceBase.h +++ b/tmtcservices/CommandingServiceBase.h @@ -312,7 +312,7 @@ private: void handleCommandMessage(CommandMessage* reply); void handleReplyHandlerResult(ReturnValue_t result, CommandMapIter iter, - CommandMessageIF* nextCommand,CommandMessageIF* reply, bool& isStep); + CommandMessage* nextCommand, CommandMessage* reply, bool& isStep); void checkTimeout(); }; From af24cc7d047cccf09ff5a002a86aa222b18b19ed Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 24 Jun 2020 00:49:13 +0200 Subject: [PATCH 185/307] some bugfixes --- ipc/CommandMessage.cpp | 82 +++++++++++++++++++--------------- ipc/CommandMessage.h | 30 +++++++------ ipc/CommandMessageCleaner.cpp | 20 ++++----- ipc/CommandMessageCleaner.h | 6 +-- osal/FreeRTOS/MessageQueue.cpp | 6 --- 5 files changed, 74 insertions(+), 70 deletions(-) diff --git a/ipc/CommandMessage.cpp b/ipc/CommandMessage.cpp index 6aa433df..2b0c34d5 100644 --- a/ipc/CommandMessage.cpp +++ b/ipc/CommandMessage.cpp @@ -3,57 +3,57 @@ #include CommandMessage::CommandMessage() { - MessageQueueMessage::setMessageSize(DEFAULT_COMMAND_MESSAGE_SIZE); + MessageQueueMessage::setMessageSize(DEFAULT_COMMAND_MESSAGE_SIZE); setCommand(CMD_NONE); } CommandMessage::CommandMessage(Command_t command, uint32_t parameter1, uint32_t parameter2) { MessageQueueMessage::setMessageSize(DEFAULT_COMMAND_MESSAGE_SIZE); - setCommand(command); - setParameter(parameter1); - setParameter2(parameter2); + setCommand(command); + setParameter(parameter1); + setParameter2(parameter2); } Command_t CommandMessage::getCommand() const { - Command_t command; - std::memcpy(&command, getData(), sizeof(Command_t)); - return command; + Command_t command; + std::memcpy(&command, MessageQueueMessage::getData(), sizeof(Command_t)); + return command; } void CommandMessage::setCommand(Command_t command) { - std::memcpy(getData(), &command, sizeof(Command_t)); + std::memcpy(MessageQueueMessage::getData(), &command, sizeof(Command_t)); } uint8_t CommandMessage::getMessageType() const { - // first byte of command ID. - return getCommand() >> 8 & 0xff; + // first byte of command ID. + return getCommand() >> 8 & 0xff; } uint32_t CommandMessage::getParameter() const { - uint32_t parameter1; - std::memcpy(¶meter1, MessageQueueMessage::getData(), sizeof(parameter1)); - return parameter1; + uint32_t parameter1; + std::memcpy(¶meter1, this->getData(), sizeof(parameter1)); + return parameter1; } void CommandMessage::setParameter(uint32_t parameter1) { - std::memcpy(MessageQueueMessage::getData(), ¶meter1, sizeof(parameter1)); + std::memcpy(this->getData(), ¶meter1, sizeof(parameter1)); } uint32_t CommandMessage::getParameter2() const { - uint32_t parameter2; - std::memcpy(¶meter2, MessageQueueMessage::getData() + sizeof(uint32_t), - sizeof(parameter2)); - return parameter2; + uint32_t parameter2; + std::memcpy(¶meter2, this->getData() + sizeof(uint32_t), + sizeof(parameter2)); + return parameter2; } void CommandMessage::setParameter2(uint32_t parameter2) { - std::memcpy(MessageQueueMessage::getData() + sizeof(uint32_t), ¶meter2, - sizeof(parameter2)); + std::memcpy(this->getData() + sizeof(uint32_t), ¶meter2, + sizeof(parameter2)); } size_t CommandMessage::getMinimumMessageSize() const { - return MINIMUM_COMMAND_MESSAGE_SIZE; + return MINIMUM_COMMAND_MESSAGE_SIZE; } void CommandMessage::clear() { @@ -61,29 +61,37 @@ void CommandMessage::clear() { } bool CommandMessage::isClearedCommandMessage() { - return getCommand() == CMD_NONE; + return getCommand() == CMD_NONE; } void CommandMessage::setToUnknownCommand() { - Command_t initialCommand = getCommand(); - this->clear(); - setReplyRejected(UNKNOWN_COMMAND, initialCommand); + Command_t initialCommand = getCommand(); + this->clear(); + setReplyRejected(UNKNOWN_COMMAND, initialCommand); } void CommandMessage::setReplyRejected(ReturnValue_t reason, - Command_t initialCommand) { - std::memcpy(getData(), &reason, sizeof(reason)); - std::memcpy(getData() + sizeof(reason), &initialCommand, - sizeof(initialCommand)); + Command_t initialCommand) { + std::memcpy(getData(), &reason, sizeof(reason)); + std::memcpy(getData() + sizeof(reason), &initialCommand, + sizeof(initialCommand)); } ReturnValue_t CommandMessage::getReplyRejectedReason( - Command_t *initialCommand) const { - ReturnValue_t reason = HasReturnvaluesIF::RETURN_FAILED; - std::memcpy(&reason, getData(), sizeof(reason)); - if(initialCommand != nullptr) { - std::memcpy(initialCommand, getData() + sizeof(reason), - sizeof(Command_t)); - } - return reason; + Command_t *initialCommand) const { + ReturnValue_t reason = HasReturnvaluesIF::RETURN_FAILED; + std::memcpy(&reason, getData(), sizeof(reason)); + if(initialCommand != nullptr) { + std::memcpy(initialCommand, getData() + sizeof(reason), + sizeof(Command_t)); + } + return reason; +} + +uint8_t* CommandMessage::getData() { + return MessageQueueMessage::getData() + sizeof(Command_t); +} + +const uint8_t* CommandMessage::getData() const { + return MessageQueueMessage::getData() + sizeof(Command_t); } diff --git a/ipc/CommandMessage.h b/ipc/CommandMessage.h index a319a0cf..53df1c08 100644 --- a/ipc/CommandMessage.h +++ b/ipc/CommandMessage.h @@ -50,6 +50,22 @@ public: */ virtual ~CommandMessage() {} + /** + * Read the DeviceHandlerCommand_t that is stored in the message, + * usually used after receiving. + * + * @return the Command stored in the Message + */ + virtual Command_t getCommand() const override; + /** + * Set the command type of the message. Default implementation also + * sets the message type, which will be the first byte of the command ID. + * @param the Command to be sent + */ + virtual void setCommand(Command_t command); + + virtual uint8_t* getData() override; + virtual const uint8_t* getData() const override; /** * Get the first parameter of the message * @return the first Parameter of the message @@ -105,20 +121,6 @@ public: virtual void clear() override; - /** - * Read the DeviceHandlerCommand_t that is stored in the message, - * usually used after receiving. - * - * @return the Command stored in the Message - */ - virtual Command_t getCommand() const override; - /** - * Set the command type of the message. Default implementation also - * sets the message type, which will be the first byte of the command ID. - * @param the Command to be sent - */ - virtual void setCommand(Command_t command); - /** * Extract message ID, which is the first byte of the command ID for the * default implementation. diff --git a/ipc/CommandMessageCleaner.cpp b/ipc/CommandMessageCleaner.cpp index 7153a8e7..23e6e168 100644 --- a/ipc/CommandMessageCleaner.cpp +++ b/ipc/CommandMessageCleaner.cpp @@ -9,34 +9,34 @@ #include #include -void CommandMessageCleaner::clearCommandMessage(CommandMessageIF* message) { +void CommandMessageCleaner::clearCommandMessage(CommandMessage* message) { switch(message->getMessageType()){ case messagetypes::MODE_COMMAND: - ModeMessage::clear(dynamic_cast(message)); + ModeMessage::clear(message); break; case messagetypes::HEALTH_COMMAND: - HealthMessage::clear(dynamic_cast(message)); + HealthMessage::clear(message); break; case messagetypes::MODE_SEQUENCE: - ModeSequenceMessage::clear(dynamic_cast(message)); + ModeSequenceMessage::clear(message); break; case messagetypes::ACTION: - ActionMessage::clear(dynamic_cast(message)); + ActionMessage::clear(message); break; case messagetypes::DEVICE_HANDLER_COMMAND: - DeviceHandlerMessage::clear(dynamic_cast(message)); + DeviceHandlerMessage::clear(message); break; case messagetypes::MEMORY: - MemoryMessage::clear(dynamic_cast(message)); + MemoryMessage::clear(message); break; case messagetypes::MONITORING: - MonitoringMessage::clear(dynamic_cast(message)); + MonitoringMessage::clear(message); break; case messagetypes::TM_STORE: - TmStoreMessage::clear(dynamic_cast(message)); + TmStoreMessage::clear(message); break; case messagetypes::PARAMETER: - ParameterMessage::clear(dynamic_cast(message)); + ParameterMessage::clear(message); break; default: messagetypes::clearMissionMessage(message); diff --git a/ipc/CommandMessageCleaner.h b/ipc/CommandMessageCleaner.h index 0bd369a2..48aaa478 100644 --- a/ipc/CommandMessageCleaner.h +++ b/ipc/CommandMessageCleaner.h @@ -1,15 +1,15 @@ #ifndef FRAMEWORK_IPC_COMMANDMESSAGECLEANER_H_ #define FRAMEWORK_IPC_COMMANDMESSAGECLEANER_H_ -#include +#include namespace messagetypes { // Implemented in config. -void clearMissionMessage(CommandMessageIF* message); +void clearMissionMessage(CommandMessage* message); } class CommandMessageCleaner { public: - static void clearCommandMessage(CommandMessageIF* message); + static void clearCommandMessage(CommandMessage* message); }; diff --git a/osal/FreeRTOS/MessageQueue.cpp b/osal/FreeRTOS/MessageQueue.cpp index 464a4f16..8eb669ed 100644 --- a/osal/FreeRTOS/MessageQueue.cpp +++ b/osal/FreeRTOS/MessageQueue.cpp @@ -80,12 +80,6 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message, } ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) { - if(message->getMessageSize() < maxMessageSize) { - sif::error << "MessageQueue::receiveMessage: Message size " - << message->getMessageSize() << - " too small to receive data!" << std::endl; - return HasReturnvaluesIF::RETURN_FAILED; - } BaseType_t result = xQueueReceive(handle,reinterpret_cast( message->getBuffer()), 0); if (result == pdPASS){ From 16cbbb2693a18cc588661270c482325d4257e95f Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 24 Jun 2020 01:11:48 +0200 Subject: [PATCH 186/307] linux fixes --- osal/linux/MessageQueue.cpp | 15 +++------------ osal/linux/MessageQueue.h | 3 +-- osal/linux/QueueFactory.cpp | 6 +++--- 3 files changed, 7 insertions(+), 17 deletions(-) diff --git a/osal/linux/MessageQueue.cpp b/osal/linux/MessageQueue.cpp index c4b24a13..b11b9b6f 100644 --- a/osal/linux/MessageQueue.cpp +++ b/osal/linux/MessageQueue.cpp @@ -281,8 +281,7 @@ ReturnValue_t MessageQueue::sendToDefaultFrom(MessageQueueMessageIF* message, ReturnValue_t MessageQueue::sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message, MessageQueueId_t sentFrom, bool ignoreFault) { - return sendMessageFromMessageQueue(sendTo,message, maxMessageSize, - sentFrom,ignoreFault); + return sendMessageFromMessageQueue(sendTo,message, sentFrom,ignoreFault); } @@ -297,22 +296,14 @@ bool MessageQueue::isDefaultDestinationSet() const { uint16_t MessageQueue::queueCounter = 0; ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, - MessageQueueMessageIF *message, size_t maxSize, - MessageQueueId_t sentFrom, bool ignoreFault) { + MessageQueueMessageIF *message, MessageQueueId_t sentFrom, + bool ignoreFault) { if(message == nullptr) { sif::error << "MessageQueue::sendMessageFromMessageQueue: Message is " "nullptr!" << std::endl; return HasReturnvaluesIF::RETURN_FAILED; } - if(message->getMaximumMessageSize() > maxSize) { - sif::error << "MessageQueue::sendMessageFromMessageQueue: Message size " - << message->getMaximumMessageSize() << " too large for queue" - " with max. message size " << maxSize << "!" - << std::endl; - return HasReturnvaluesIF::RETURN_FAILED; - } - message->setSender(sentFrom); int result = mq_send(sendTo, reinterpret_cast(message->getBuffer()), diff --git a/osal/linux/MessageQueue.h b/osal/linux/MessageQueue.h index 22725d18..8e3a5191 100644 --- a/osal/linux/MessageQueue.h +++ b/osal/linux/MessageQueue.h @@ -149,8 +149,7 @@ protected: * \param ignoreFault If set to true, the internal software fault counter is not incremented if queue is full. */ static ReturnValue_t sendMessageFromMessageQueue(MessageQueueId_t sendTo, - MessageQueueMessageIF* message, size_t maxSize, - MessageQueueId_t sentFrom = NO_QUEUE, + MessageQueueMessageIF* message, MessageQueueId_t sentFrom = NO_QUEUE, bool ignoreFault=false); private: /** diff --git a/osal/linux/QueueFactory.cpp b/osal/linux/QueueFactory.cpp index 95264a42..8bd9d52c 100644 --- a/osal/linux/QueueFactory.cpp +++ b/osal/linux/QueueFactory.cpp @@ -9,10 +9,10 @@ QueueFactory* QueueFactory::factoryInstance = nullptr; ReturnValue_t MessageQueueSenderIF::sendMessage(MessageQueueId_t sendTo, - MessageQueueMessageIF* message, size_t maxSize, - MessageQueueId_t sentFrom, bool ignoreFault) { + MessageQueueMessageIF* message, MessageQueueId_t sentFrom, + bool ignoreFault) { return MessageQueue::sendMessageFromMessageQueue(sendTo,message, - maxSize, sentFrom,ignoreFault); + sentFrom,ignoreFault); } QueueFactory* QueueFactory::instance() { From 7f3607c3d998fb4473fd7b35b3ddf9ebff7b1dbb Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 24 Jun 2020 02:00:26 +0200 Subject: [PATCH 187/307] hk service fixed --- housekeeping/HousekeepingMessage.cpp | 66 ++++++++++------------------ housekeeping/HousekeepingMessage.h | 27 +++++------- ipc/CommandMessage.cpp | 12 +++++ ipc/CommandMessage.h | 14 ++---- 4 files changed, 50 insertions(+), 69 deletions(-) diff --git a/housekeeping/HousekeepingMessage.cpp b/housekeeping/HousekeepingMessage.cpp index 0d0f9860..64b07c17 100644 --- a/housekeeping/HousekeepingMessage.cpp +++ b/housekeeping/HousekeepingMessage.cpp @@ -1,67 +1,47 @@ #include #include -HousekeepingMessage::HousekeepingMessage(): CommandMessage() { -} - HousekeepingMessage::~HousekeepingMessage() {} -void HousekeepingMessage::setParameter(uint32_t parameter) { - std::memcpy(getData(), ¶meter, sizeof(parameter)); -} - -uint32_t HousekeepingMessage::getParameter() const { - uint32_t parameter; - std::memcpy(¶meter, getData(), sizeof(parameter)); - return parameter; -} - -void HousekeepingMessage::setHkReportMessage(sid_t sid, +void HousekeepingMessage::setHkReportMessage(CommandMessage* message, sid_t sid, store_address_t storeId) { - CommandMessage::setCommand(HK_REPORT); - setSid(sid); - setParameter(storeId.raw); + message->setCommand(HK_REPORT); + message->setMessageSize(HK_MESSAGE_SIZE); + setSid(message, sid); + message->setParameter(storeId.raw); } -void HousekeepingMessage::setHkDiagnosticsMessage(sid_t sid, - store_address_t storeId) { - CommandMessage::setCommand(DIAGNOSTICS_REPORT); - setSid(sid); - setParameter(storeId.raw); +void HousekeepingMessage::setHkDiagnosticsMessage(CommandMessage* message, + sid_t sid, store_address_t storeId) { + message->setCommand(DIAGNOSTICS_REPORT); + setSid(message, sid); + setParameter(message, storeId.raw); } - -//size_t HousekeepingMessage::getMinimumMessageSize() const { -// return HK_MESSAGE_SIZE; -//} - -sid_t HousekeepingMessage::getSid() const { +sid_t HousekeepingMessage::getSid(const CommandMessage* message) { sid_t sid; - std::memcpy(&sid.raw, CommandMessage::getData(), sizeof(sid.raw)); + std::memcpy(&sid.raw, message->getData(), sizeof(sid.raw)); return sid; } -sid_t HousekeepingMessage::getHkReportMessage( - store_address_t *storeIdToSet) const { +sid_t HousekeepingMessage::getHkReportMessage(const CommandMessage *message, + store_address_t *storeIdToSet) { if(storeIdToSet != nullptr) { - *storeIdToSet = getParameter(); + *storeIdToSet = getParameter(message); } - return getSid(); + return getSid(message); } -void HousekeepingMessage::setSid(sid_t sid) { - std::memcpy(CommandMessage::getData(), &sid.raw, sizeof(sid.raw)); +void HousekeepingMessage::setSid(CommandMessage *message, sid_t sid) { + std::memcpy(message->getData(), &sid.raw, sizeof(sid.raw)); } -uint8_t* HousekeepingMessage::getData() { - return CommandMessage::getData() + sizeof(sid_t); +void HousekeepingMessage::setParameter(CommandMessage *message, + uint32_t parameter) { + message->setParameter3(parameter); } -const uint8_t* HousekeepingMessage::getData() const { - return CommandMessage::getData() + sizeof(sid_t); -} - -void HousekeepingMessage::clear() { - // clear IPC store where it is needed. +uint32_t HousekeepingMessage::getParameter(const CommandMessage *message) { + return message->getParameter3(); } diff --git a/housekeeping/HousekeepingMessage.h b/housekeeping/HousekeepingMessage.h index 8958201e..e2a69805 100644 --- a/housekeeping/HousekeepingMessage.h +++ b/housekeeping/HousekeepingMessage.h @@ -34,7 +34,7 @@ union sid_t { * This message is slightly larger than regular command messages to accomodate * the uint64_t structure ID (SID). */ -class HousekeepingMessage : public CommandMessage { +class HousekeepingMessage { public: static constexpr size_t HK_MESSAGE_SIZE = CommandMessageIF::HEADER_SIZE + @@ -45,7 +45,7 @@ public: * the message data, see CommandMessageIF and getInternalMessage(). * @param message */ - HousekeepingMessage(); + HousekeepingMessage() = delete; virtual ~HousekeepingMessage(); static constexpr uint8_t MESSAGE_ID = messagetypes::HOUSEKEEPING; @@ -94,25 +94,22 @@ public: static constexpr Command_t MODIFY_DIAGNOSTICS_REPORT_COLLECTION_INTERVAL = MAKE_COMMAND_ID(32); + static sid_t getSid(const CommandMessage* message); - void setParameter(uint32_t parameter); - uint32_t getParameter() const; - sid_t getSid() const; + static void setHkReportMessage(CommandMessage* message, sid_t sid, + store_address_t storeId); + static void setHkDiagnosticsMessage(CommandMessage* message, sid_t sid, + store_address_t storeId); - void setHkReportMessage(sid_t sid, store_address_t storeId); - void setHkDiagnosticsMessage(sid_t sid, store_address_t storeId); //! Get the respective SID and store ID. Command ID can be used beforehand //! to distinguish between diagnostics and regular HK packets - sid_t getHkReportMessage(store_address_t * storeIdToSet) const; + static sid_t getHkReportMessage(const CommandMessage* message, + store_address_t * storeIdToSet); - //virtual size_t getMinimumMessageSize() const override; - virtual void clear() override; private: - - void setSid(sid_t sid); - - virtual uint8_t* getData() override; - virtual const uint8_t* getData() const override; + static void setSid(CommandMessage* message, sid_t sid); + static void setParameter(CommandMessage* message, uint32_t parameter); + static uint32_t getParameter(const CommandMessage* message); }; diff --git a/ipc/CommandMessage.cpp b/ipc/CommandMessage.cpp index 2b0c34d5..e1d4dfae 100644 --- a/ipc/CommandMessage.cpp +++ b/ipc/CommandMessage.cpp @@ -52,6 +52,18 @@ void CommandMessage::setParameter2(uint32_t parameter2) { sizeof(parameter2)); } +uint32_t CommandMessage::getParameter3() const { + uint32_t parameter3; + std::memcpy(¶meter3, this->getData() + 2 * sizeof(uint32_t), + sizeof(parameter3)); + return parameter3; +} + +void CommandMessage::setParameter3(uint32_t parameter3) { + std::memcpy(this->getData() + 2 * sizeof(uint32_t), ¶meter3, + sizeof(parameter3)); +} + size_t CommandMessage::getMinimumMessageSize() const { return MINIMUM_COMMAND_MESSAGE_SIZE; } diff --git a/ipc/CommandMessage.h b/ipc/CommandMessage.h index 53df1c08..021fa49a 100644 --- a/ipc/CommandMessage.h +++ b/ipc/CommandMessage.h @@ -66,29 +66,21 @@ public: virtual uint8_t* getData() override; virtual const uint8_t* getData() const override; + /** * Get the first parameter of the message * @return the first Parameter of the message */ uint32_t getParameter() const; - /** * Set the first parameter of the message * @param the first parameter of the message */ void setParameter(uint32_t parameter1); - - /** - * Get the second parameter of the message - * @return the second Parameter of the message - */ uint32_t getParameter2() const; - - /** - * Set the second parameter of the message - * @param the second parameter of the message - */ void setParameter2(uint32_t parameter2); + uint32_t getParameter3() const; + void setParameter3(uint32_t parameter3); /** * check if a message was cleared From 6f2bb4125d7e4cd9baaf812c3dcd118883f65e71 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 24 Jun 2020 02:02:57 +0200 Subject: [PATCH 188/307] bugfix --- housekeeping/HousekeepingMessage.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/housekeeping/HousekeepingMessage.cpp b/housekeeping/HousekeepingMessage.cpp index 64b07c17..2335f03d 100644 --- a/housekeeping/HousekeepingMessage.cpp +++ b/housekeeping/HousekeepingMessage.cpp @@ -8,21 +8,16 @@ void HousekeepingMessage::setHkReportMessage(CommandMessage* message, sid_t sid, message->setCommand(HK_REPORT); message->setMessageSize(HK_MESSAGE_SIZE); setSid(message, sid); - message->setParameter(storeId.raw); + setParameter(message, storeId.raw); } void HousekeepingMessage::setHkDiagnosticsMessage(CommandMessage* message, sid_t sid, store_address_t storeId) { message->setCommand(DIAGNOSTICS_REPORT); + message->setMessageSize(HK_MESSAGE_SIZE); setSid(message, sid); setParameter(message, storeId.raw); } -sid_t HousekeepingMessage::getSid(const CommandMessage* message) { - sid_t sid; - std::memcpy(&sid.raw, message->getData(), sizeof(sid.raw)); - return sid; -} - sid_t HousekeepingMessage::getHkReportMessage(const CommandMessage *message, store_address_t *storeIdToSet) { @@ -32,6 +27,12 @@ sid_t HousekeepingMessage::getHkReportMessage(const CommandMessage *message, return getSid(message); } +sid_t HousekeepingMessage::getSid(const CommandMessage* message) { + sid_t sid; + std::memcpy(&sid.raw, message->getData(), sizeof(sid.raw)); + return sid; +} + void HousekeepingMessage::setSid(CommandMessage *message, sid_t sid) { std::memcpy(message->getData(), &sid.raw, sizeof(sid.raw)); } From 8d633bf1278e473a23ab67ee86458771a5c45bc2 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 24 Jun 2020 11:40:48 +0200 Subject: [PATCH 189/307] took over changed for singly linked list --- container/SinglyLinkedList.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/container/SinglyLinkedList.h b/container/SinglyLinkedList.h index 3c0078fc..a78a1467 100644 --- a/container/SinglyLinkedList.h +++ b/container/SinglyLinkedList.h @@ -88,14 +88,15 @@ public: ElementIterator begin() const { return ElementIterator::Iterator(start); } - typename ElementIterator::Iterator end() const { + + ElementIterator end() const { return ElementIterator::Iterator(); } - uint32_t getSize() const { - uint32_t size = 0; + size_t getSize() const { + size_t size = 0; LinkedElement *element = start; - while (element != NULL) { + while (element != nullptr) { size++; element = element->getNext(); } From 0c32a964529105b611b600938c84df647f8fa0cf Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 24 Jun 2020 11:54:41 +0200 Subject: [PATCH 190/307] some more singly linked list improvements --- container/SinglyLinkedList.h | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/container/SinglyLinkedList.h b/container/SinglyLinkedList.h index a78a1467..85a92e6a 100644 --- a/container/SinglyLinkedList.h +++ b/container/SinglyLinkedList.h @@ -16,8 +16,13 @@ public: class Iterator { public: LinkedElement *value = nullptr; + //! Creates an uninitialized iterator which points to nullptr. Iterator() {} + /** + * Initialize iterator at specified linked element. + * @param element + */ Iterator(LinkedElement *element) : value(element) { } @@ -72,6 +77,11 @@ private: LinkedElement *next; }; +/** + * @brief SinglyLinkedList data structure which keeps a pointer to its + * first element to perform all operations. + * @tparam T + */ template class SinglyLinkedList { public: @@ -90,7 +100,11 @@ public: } ElementIterator end() const { - return ElementIterator::Iterator(); + LinkedElement *element = start; + while (element != nullptr) { + element = element->getNext(); + } + return ElementIterator::Iterator(element); } size_t getSize() const { From df418ae1b4d1cd97d3b676813dcd8f4a67664365 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 24 Jun 2020 12:02:01 +0200 Subject: [PATCH 191/307] typedef in class declaration now --- devicehandlers/FixedSlotSequence.h | 9 ++++----- osal/FreeRTOS/FixedTimeslotTask.cpp | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/devicehandlers/FixedSlotSequence.h b/devicehandlers/FixedSlotSequence.h index fa4c4aeb..32b61f56 100644 --- a/devicehandlers/FixedSlotSequence.h +++ b/devicehandlers/FixedSlotSequence.h @@ -1,13 +1,10 @@ -#ifndef FIXEDSLOTSEQUENCE_H_ -#define FIXEDSLOTSEQUENCE_H_ +#ifndef FRAMEWORK_DEVICEHANDLERS_FIXEDSLOTSEQUENCE_H_ +#define FRAMEWORK_DEVICEHANDLERS_FIXEDSLOTSEQUENCE_H_ #include #include #include -using SlotList = std::multiset; -using SlotListIter = std::multiset::iterator; - /** * @brief This class is the representation of a Polling Sequence Table in software. * @@ -27,6 +24,8 @@ using SlotListIter = std::multiset::iterator; */ class FixedSlotSequence { public: + using SlotList = std::multiset; + using SlotListIter = std::multiset::iterator; /** * @brief The constructor of the FixedSlotSequence object. diff --git a/osal/FreeRTOS/FixedTimeslotTask.cpp b/osal/FreeRTOS/FixedTimeslotTask.cpp index 0fb1e1d7..eea2f7d8 100644 --- a/osal/FreeRTOS/FixedTimeslotTask.cpp +++ b/osal/FreeRTOS/FixedTimeslotTask.cpp @@ -82,7 +82,7 @@ ReturnValue_t FixedTimeslotTask::checkSequence() const { void FixedTimeslotTask::taskFunctionality() { // A local iterator for the Polling Sequence Table is created to find the start time for the first entry. - SlotListIter slotListIter = pst.current; + auto slotListIter = pst.current; //The start time for the first entry is read. uint32_t intervalMs = slotListIter->pollingTimeMs; From 08f25370f3505ebf39f26166b2bf5a4000c28461 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 24 Jun 2020 12:03:52 +0200 Subject: [PATCH 192/307] moved typedefs into namespace --- tasks/FixedSlotSequence.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tasks/FixedSlotSequence.h b/tasks/FixedSlotSequence.h index 7de1884c..61883658 100644 --- a/tasks/FixedSlotSequence.h +++ b/tasks/FixedSlotSequence.h @@ -6,9 +6,6 @@ #include -using SlotList = std::multiset; -using SlotListIter = std::multiset::iterator; - /** * @brief This class is the representation of a Polling Sequence Table in software. * @details @@ -27,6 +24,8 @@ using SlotListIter = std::multiset::iterator; */ class FixedSlotSequence { public: + using SlotList = std::multiset; + using SlotListIter = std::multiset::iterator; /** * @brief The constructor of the FixedSlotSequence object. From ba5b8bd682e1e3e36612a9c8974a4b27c8bf1151 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 26 Jun 2020 13:28:58 +0200 Subject: [PATCH 193/307] hybrid iter update --- container/HybridIterator.h | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/container/HybridIterator.h b/container/HybridIterator.h index db1ce4bc..f2fd6b28 100644 --- a/container/HybridIterator.h +++ b/container/HybridIterator.h @@ -1,5 +1,5 @@ -#ifndef HYBRIDITERATOR_H_ -#define HYBRIDITERATOR_H_ +#ifndef FRAMEWORK_CONTAINER_HYBRIDITERATOR_H_ +#define FRAMEWORK_CONTAINER_HYBRIDITERATOR_H_ #include #include @@ -17,23 +17,23 @@ public: } HybridIterator(LinkedElement *start) : - LinkedElement::Iterator(start), value( - start->value), linked(true), end(NULL) { + LinkedElement::Iterator(start), value(start->value), + linked(true) { } HybridIterator(typename ArrayList::Iterator start, typename ArrayList::Iterator end) : - ArrayList::Iterator(start), value(start.value), linked( - false), end(end.value) { + ArrayList::Iterator(start), value(start.value), + linked(false), end(end.value) { if (value == this->end) { value = NULL; } } HybridIterator(T *firstElement, T *lastElement) : - ArrayList::Iterator(firstElement), value(firstElement), linked( - false), end(++lastElement) { + ArrayList::Iterator(firstElement), value(firstElement), + linked(false), end(++lastElement) { if (value == end) { value = NULL; } @@ -42,17 +42,17 @@ public: HybridIterator& operator++() { if (linked) { LinkedElement::Iterator::operator++(); - if (LinkedElement::Iterator::value != NULL) { + if (LinkedElement::Iterator::value != nullptr) { value = LinkedElement::Iterator::value->value; } else { - value = NULL; + value = nullptr; } } else { ArrayList::Iterator::operator++(); value = ArrayList::Iterator::value; if (value == end) { - value = NULL; + value = nullptr; } } return *this; @@ -64,11 +64,11 @@ public: return tmp; } - bool operator==(const HybridIterator& other) { + bool operator==(const HybridIterator& other) const { return value == other.value; } - bool operator!=(const HybridIterator& other) { + bool operator!=(const HybridIterator& other) const { return !(*this == other); } @@ -87,4 +87,4 @@ private: T *end = nullptr; }; -#endif /* HYBRIDITERATOR_H_ */ +#endif /* FRAMEWORK_CONTAINER_HYBRIDITERATOR_H_ */ From b81b458ba6cc5c6819b9dae6045e25469a1d43cc Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 29 Jun 2020 15:44:18 +0200 Subject: [PATCH 194/307] exec task if new init function, some corrections --- ipc/CommandMessage.cpp | 5 ++--- osal/host/FixedTimeslotTask.cpp | 2 +- osal/host/QueueMapManager.h | 2 +- tasks/ExecutableObjectIF.h | 13 +++++++++++-- tasks/FixedSequenceSlot.cpp | 1 + tmtcservices/CommandingServiceBase.cpp | 4 ++-- 6 files changed, 18 insertions(+), 9 deletions(-) diff --git a/ipc/CommandMessage.cpp b/ipc/CommandMessage.cpp index e1d4dfae..0aeaa79a 100644 --- a/ipc/CommandMessage.cpp +++ b/ipc/CommandMessage.cpp @@ -84,9 +84,8 @@ void CommandMessage::setToUnknownCommand() { void CommandMessage::setReplyRejected(ReturnValue_t reason, Command_t initialCommand) { - std::memcpy(getData(), &reason, sizeof(reason)); - std::memcpy(getData() + sizeof(reason), &initialCommand, - sizeof(initialCommand)); + setParameter(reason); + setParameter2(initialCommand); } ReturnValue_t CommandMessage::getReplyRejectedReason( diff --git a/osal/host/FixedTimeslotTask.cpp b/osal/host/FixedTimeslotTask.cpp index 48d11843..dac399f6 100644 --- a/osal/host/FixedTimeslotTask.cpp +++ b/osal/host/FixedTimeslotTask.cpp @@ -92,7 +92,7 @@ ReturnValue_t FixedTimeslotTask::sleepFor(uint32_t ms) { void FixedTimeslotTask::taskFunctionality() { // A local iterator for the Polling Sequence Table is created to // find the start time for the first entry. - SlotListIter slotListIter = pollingSeqTable.current; + FixedSlotSequence::SlotListIter slotListIter = pollingSeqTable.current; // Get start time for first entry. chron_ms interval(slotListIter->pollingTimeMs); auto currentStartTime { diff --git a/osal/host/QueueMapManager.h b/osal/host/QueueMapManager.h index 34f0fc95..499b1622 100644 --- a/osal/host/QueueMapManager.h +++ b/osal/host/QueueMapManager.h @@ -36,7 +36,7 @@ public: private: //! External instantiation is forbidden. QueueMapManager(); - std::atomic queueCounter = MessageQueueIF::NO_QUEUE + 1; + std::atomic queueCounter = 1; MutexIF* mapLock; QueueMap queueMap; static QueueMapManager* mqManagerInstance; diff --git a/tasks/ExecutableObjectIF.h b/tasks/ExecutableObjectIF.h index 516b4084..f66b53da 100644 --- a/tasks/ExecutableObjectIF.h +++ b/tasks/ExecutableObjectIF.h @@ -43,9 +43,18 @@ public: * a reference to the executing task * @param task_ Pointer to the taskIF of this task */ - virtual void setTaskIF(PeriodicTaskIF* task_) { + virtual void setTaskIF(PeriodicTaskIF* task_) {}; - } + /** + * This function will be called after the object was assigned to a specific + * task. + * + * Example: Can be used to get task execution frequency. + * The task is created after initialize() and the object ctors have been + * called so the execution frequency can't be cached in initialize() + * @return + */ + //virtual ReturnValue_t initializeAfterTaskCreation() = 0; }; #endif /* EXECUTABLEOBJECTIF_H_ */ diff --git a/tasks/FixedSequenceSlot.cpp b/tasks/FixedSequenceSlot.cpp index c46b4fc0..430ce019 100644 --- a/tasks/FixedSequenceSlot.cpp +++ b/tasks/FixedSequenceSlot.cpp @@ -9,6 +9,7 @@ FixedSequenceSlot::FixedSequenceSlot(object_id_t handlerId, uint32_t setTime, if(executingTask != nullptr) { handler->setTaskIF(executingTask); } + //handler->initializeAfterTaskCreation(); } FixedSequenceSlot::~FixedSequenceSlot() {} diff --git a/tmtcservices/CommandingServiceBase.cpp b/tmtcservices/CommandingServiceBase.cpp index acf66389..5a48bd63 100644 --- a/tmtcservices/CommandingServiceBase.cpp +++ b/tmtcservices/CommandingServiceBase.cpp @@ -109,8 +109,8 @@ void CommandingServiceBase::handleCommandMessage(CommandMessage* reply) { * command as failure parameter 1 */ if(reply->getCommand() == CommandMessage::REPLY_REJECTED and result == RETURN_FAILED) { - result = reply->getReplyRejectedReason( - reinterpret_cast(&failureParameter1)); + result = reply->getReplyRejectedReason(); + failureParameter1 = iter->command; } switch (result) { From d5d968a39365b2b0c285d8f283a054050e94be3b Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 29 Jun 2020 15:46:16 +0200 Subject: [PATCH 195/307] some more correctioons --- datapoollocal/LocalDataPoolManager.cpp | 24 ++++++++++++------------ ipc/CommandMessage.cpp | 6 ++---- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/datapoollocal/LocalDataPoolManager.cpp b/datapoollocal/LocalDataPoolManager.cpp index bc57468a..55d36a9a 100644 --- a/datapoollocal/LocalDataPoolManager.cpp +++ b/datapoollocal/LocalDataPoolManager.cpp @@ -105,18 +105,18 @@ ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid) { } // and now we set a HK message and send it the HK packet destination. - //HousekeepingMessage hkMessage; -// hkMessage.setHkReportMessage(sid, storeId); -// if(hkQueue == nullptr) { -// return QUEUE_NOT_SET; -// } -// -// if(currentHkPacketDestination != MessageQueueIF::NO_QUEUE) { -// result = hkQueue->sendMessage(currentHkPacketDestination, &hkMessage); -// } -// else { -// result = hkQueue->sendToDefault(&hkMessage); -// } + CommandMessage hkMessage; + HousekeepingMessage::setHkReportMessage(&hkMessage, sid, storeId); + if(hkQueue == nullptr) { + return QUEUE_NOT_SET; + } + + if(currentHkPacketDestination != MessageQueueIF::NO_QUEUE) { + result = hkQueue->sendMessage(currentHkPacketDestination, &hkMessage); + } + else { + result = hkQueue->sendToDefault(&hkMessage); + } return result; } diff --git a/ipc/CommandMessage.cpp b/ipc/CommandMessage.cpp index 0aeaa79a..1470fe85 100644 --- a/ipc/CommandMessage.cpp +++ b/ipc/CommandMessage.cpp @@ -90,11 +90,9 @@ void CommandMessage::setReplyRejected(ReturnValue_t reason, ReturnValue_t CommandMessage::getReplyRejectedReason( Command_t *initialCommand) const { - ReturnValue_t reason = HasReturnvaluesIF::RETURN_FAILED; - std::memcpy(&reason, getData(), sizeof(reason)); + ReturnValue_t reason = getParameter(); if(initialCommand != nullptr) { - std::memcpy(initialCommand, getData() + sizeof(reason), - sizeof(Command_t)); + *initialCommand = getParameter2(); } return reason; } From 003e70bf4785a8b9e57a8f8ab5f67ae0b0dfade3 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 29 Jun 2020 15:55:20 +0200 Subject: [PATCH 196/307] new initializeAfterTaskCreation() --- osal/FreeRTOS/PeriodicTask.cpp | 3 ++- osal/linux/PeriodicPosixTask.cpp | 4 +++- osal/rtems/MultiObjectTask.cpp | 3 ++- tasks/ExecutableObjectIF.h | 25 +++++++++---------------- tasks/FixedSequenceSlot.cpp | 2 +- 5 files changed, 17 insertions(+), 20 deletions(-) diff --git a/osal/FreeRTOS/PeriodicTask.cpp b/osal/FreeRTOS/PeriodicTask.cpp index 170eb0a4..2ebfebf4 100644 --- a/osal/FreeRTOS/PeriodicTask.cpp +++ b/osal/FreeRTOS/PeriodicTask.cpp @@ -94,7 +94,8 @@ ReturnValue_t PeriodicTask::addComponent(object_id_t object, bool setTaskIF) { if(setTaskIF) { newObject->setTaskIF(this); } - return HasReturnvaluesIF::RETURN_OK; + ReturnValue_t result = newObject->initializeAfterTaskCreation(); + return result; } uint32_t PeriodicTask::getPeriodMs() const { diff --git a/osal/linux/PeriodicPosixTask.cpp b/osal/linux/PeriodicPosixTask.cpp index db4005b0..b811274b 100644 --- a/osal/linux/PeriodicPosixTask.cpp +++ b/osal/linux/PeriodicPosixTask.cpp @@ -36,7 +36,9 @@ ReturnValue_t PeriodicPosixTask::addComponent(object_id_t object, if(setTaskIF) { newObject->setTaskIF(this); } - return HasReturnvaluesIF::RETURN_OK; + + ReturnValue_t result = newObject->initializeAfterTaskCreation(); + return result; } ReturnValue_t PeriodicPosixTask::sleepFor(uint32_t ms) { diff --git a/osal/rtems/MultiObjectTask.cpp b/osal/rtems/MultiObjectTask.cpp index bb8c2c81..6b9c8c8e 100644 --- a/osal/rtems/MultiObjectTask.cpp +++ b/osal/rtems/MultiObjectTask.cpp @@ -78,7 +78,8 @@ ReturnValue_t MultiObjectTask::addComponent(object_id_t object) { return HasReturnvaluesIF::RETURN_FAILED; } objectList.push_back(newObject); - return HasReturnvaluesIF::RETURN_OK; + ReturnValue_t result = newObject->initializeAfterTaskCreation(); + return result; } uint32_t MultiObjectTask::getPeriodMs() const { diff --git a/tasks/ExecutableObjectIF.h b/tasks/ExecutableObjectIF.h index f66b53da..d716cdfb 100644 --- a/tasks/ExecutableObjectIF.h +++ b/tasks/ExecutableObjectIF.h @@ -1,15 +1,5 @@ -/** - * @file ExecutableObjectIF.h - * - * @brief This file contains the definition for the ExecutableObjectIF interface. - * - * @author Bastian Baetz - * - * @date 12.03.2012 - */ - -#ifndef EXECUTABLEOBJECTIF_H_ -#define EXECUTABLEOBJECTIF_H_ +#ifndef FRAMEWORK_TASKS_EXECUTABLEOBJECTIF_H_ +#define FRAMEWORK_TASKS_EXECUTABLEOBJECTIF_H_ class PeriodicTaskIF; @@ -20,6 +10,7 @@ class PeriodicTaskIF; * @brief The interface provides a method to execute objects within a task. * @details The performOperation method, that is required by the interface is * executed cyclically within a task context. + * @author Bastian Baetz */ class ExecutableObjectIF { public: @@ -46,15 +37,17 @@ public: virtual void setTaskIF(PeriodicTaskIF* task_) {}; /** - * This function will be called after the object was assigned to a specific - * task. + * This function should be called after the object was assigned to a + * specific task. * * Example: Can be used to get task execution frequency. * The task is created after initialize() and the object ctors have been * called so the execution frequency can't be cached in initialize() * @return */ - //virtual ReturnValue_t initializeAfterTaskCreation() = 0; + virtual ReturnValue_t initializeAfterTaskCreation() { + return HasReturnvaluesIF::RETURN_OK; + } }; -#endif /* EXECUTABLEOBJECTIF_H_ */ +#endif /* FRAMEWORK_TASKS_EXECUTABLEOBJECTIF_H_ */ diff --git a/tasks/FixedSequenceSlot.cpp b/tasks/FixedSequenceSlot.cpp index 430ce019..4331aada 100644 --- a/tasks/FixedSequenceSlot.cpp +++ b/tasks/FixedSequenceSlot.cpp @@ -9,7 +9,7 @@ FixedSequenceSlot::FixedSequenceSlot(object_id_t handlerId, uint32_t setTime, if(executingTask != nullptr) { handler->setTaskIF(executingTask); } - //handler->initializeAfterTaskCreation(); + handler->initializeAfterTaskCreation(); } FixedSequenceSlot::~FixedSequenceSlot() {} From ae6314d8cd43a0ad8f0c1a7b9bd567be378203d3 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 29 Jun 2020 16:06:53 +0200 Subject: [PATCH 197/307] added task handle member --- tmtcservices/PusServiceBase.cpp | 11 +++++++++++ tmtcservices/PusServiceBase.h | 17 +++++++++++++---- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/tmtcservices/PusServiceBase.cpp b/tmtcservices/PusServiceBase.cpp index f5d1e30b..82e5ff5c 100644 --- a/tmtcservices/PusServiceBase.cpp +++ b/tmtcservices/PusServiceBase.cpp @@ -32,6 +32,10 @@ ReturnValue_t PusServiceBase::performOperation(uint8_t opCode) { return RETURN_OK; } +void PusServiceBase::setTaskIF(PeriodicTaskIF* taskHandle) { + this->taskHandle = taskHandle; +} + void PusServiceBase::handleRequestQueue() { TmTcMessage message; ReturnValue_t result = RETURN_FAILED; @@ -108,3 +112,10 @@ ReturnValue_t PusServiceBase::initialize() { return RETURN_FAILED; } } + +ReturnValue_t PusServiceBase::initializeAfterTaskCreation() { + // If task parameters, for example task frequency are required, this + // function should be overriden and the system object task IF can + // be used to get those parameters. + return HasReturnvaluesIF::RETURN_OK; +} diff --git a/tmtcservices/PusServiceBase.h b/tmtcservices/PusServiceBase.h index 39600c41..6d3d9bac 100644 --- a/tmtcservices/PusServiceBase.h +++ b/tmtcservices/PusServiceBase.h @@ -96,11 +96,20 @@ public: * @return @c RETURN_OK if the periodic performService was successful. * @c RETURN_FAILED else. */ - ReturnValue_t performOperation(uint8_t opCode); - virtual uint16_t getIdentifier(); - MessageQueueId_t getRequestQueue(); - virtual ReturnValue_t initialize(); + ReturnValue_t performOperation(uint8_t opCode) override; + virtual uint16_t getIdentifier() override; + MessageQueueId_t getRequestQueue() override; + virtual ReturnValue_t initialize() override; + + virtual void setTaskIF(PeriodicTaskIF* taskHandle) override; + virtual ReturnValue_t initializeAfterTaskCreation() override; protected: + /** + * @brief Handle to the underlying task + * @details + * Will be set by setTaskIF(), which is called on task creation. + */ + PeriodicTaskIF* taskHandle = nullptr; /** * The APID of this instance of the Service. */ From 044aa259e6298bf8accff8c8ab53cd373ed186bc Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 29 Jun 2020 16:37:55 +0200 Subject: [PATCH 198/307] dhb cached pst interval now --- devicehandlers/DeviceHandlerBase.cpp | 9 +++++++++ devicehandlers/DeviceHandlerBase.h | 11 +++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index 0442be89..3994dc12 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -1374,6 +1374,15 @@ ReturnValue_t DeviceHandlerBase::changeCollectionInterval(sid_t sid, return HasReturnvaluesIF::RETURN_OK; } +ReturnValue_t DeviceHandlerBase::initializeAfterTaskCreation() { + // In this function, the task handle should be valid in any case. + // We still check to be 1000 % sure :-) + if(executingTask != nullptr) { + pstIntervalMs = executingTask->getPeriodMs(); + } + return HasReturnvaluesIF::RETURN_OK; +} + DataSetIF* DeviceHandlerBase::getDataSetHandle(sid_t sid) { auto iter = deviceReplyMap.find(sid.ownerSetId); if(iter != deviceReplyMap.end()) { diff --git a/devicehandlers/DeviceHandlerBase.h b/devicehandlers/DeviceHandlerBase.h index 1290742c..b2b4798d 100644 --- a/devicehandlers/DeviceHandlerBase.h +++ b/devicehandlers/DeviceHandlerBase.h @@ -11,6 +11,8 @@ #include #include #include +#include + #include #include #include @@ -18,6 +20,7 @@ #include #include #include + #include namespace Factory{ @@ -563,6 +566,8 @@ protected: /** This is the counter value from performOperation(). */ uint8_t pstStep = 0; + uint32_t pstIntervalMs = 0; + /** * Wiretapping flag: * @@ -1196,9 +1201,11 @@ private: ReturnValue_t handleDeviceHandlerMessage(CommandMessage *message); - void parseReply(const uint8_t* receivedData, - size_t receivedDataLen); + virtual ReturnValue_t initializeAfterTaskCreation() override; DataSetIF* getDataSetHandle(sid_t sid) override; + + void parseReply(const uint8_t* receivedData, + size_t receivedDataLen); }; #endif /* DEVICEHANDLERBASE_H_ */ From 691be0dcd4f6c8586b4a29b866bc7d9808d345c5 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 29 Jun 2020 16:39:55 +0200 Subject: [PATCH 199/307] dhb doc improvements --- devicehandlers/DeviceHandlerBase.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index 3994dc12..cebe8953 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -1375,8 +1375,8 @@ ReturnValue_t DeviceHandlerBase::changeCollectionInterval(sid_t sid, } ReturnValue_t DeviceHandlerBase::initializeAfterTaskCreation() { - // In this function, the task handle should be valid in any case. - // We still check to be 1000 % sure :-) + // In this function, the task handle should be valid if the task + // was implemented correctly. We still check to be 1000 % sure :-) if(executingTask != nullptr) { pstIntervalMs = executingTask->getPeriodMs(); } From 48df3cbe8382423b671d7b5d651e3b623f4e2d90 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 29 Jun 2020 16:43:02 +0200 Subject: [PATCH 200/307] csb comment improved --- tmtcservices/CommandingServiceBase.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tmtcservices/CommandingServiceBase.h b/tmtcservices/CommandingServiceBase.h index 8806bd52..37fa0a04 100644 --- a/tmtcservices/CommandingServiceBase.h +++ b/tmtcservices/CommandingServiceBase.h @@ -276,7 +276,6 @@ protected: void checkAndExecuteFifo(CommandMapIter iter); private: - /** * This method handles internal execution of a command, * once it has been started by @sa{startExecution()} in the request @@ -296,10 +295,13 @@ private: void handleCommandQueue(); /** + * @brief Handler function for request queue + * @details * Sequence of request queue handling: * isValidSubservice -> getMessageQueueAndObject -> startExecution - * Generates Start Success Reports TM[1,3] in subfunction @sa{startExecution()} - * or Start Failure Report TM[1,4] by using the TC Verification Service + * Generates a Start Success Reports TM[1,3] in subfunction + * @sa{startExecution()} or a Start Failure Report TM[1,4] by using the + * TC Verification Service. */ void handleRequestQueue(); From e2a36efce3d210c85c1ba924cd627a43b1cac922 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 29 Jun 2020 16:47:58 +0200 Subject: [PATCH 201/307] csb changes taken over --- tmtcservices/CommandingServiceBase.cpp | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/tmtcservices/CommandingServiceBase.cpp b/tmtcservices/CommandingServiceBase.cpp index 5a48bd63..f8af15af 100644 --- a/tmtcservices/CommandingServiceBase.cpp +++ b/tmtcservices/CommandingServiceBase.cpp @@ -57,7 +57,9 @@ ReturnValue_t CommandingServiceBase::initialize() { PUSDistributorIF* distributor = objectManager->get( packetSource); if (packetForwarding == nullptr or distributor == nullptr) { - return RETURN_FAILED; + sif::error << "CommandingServiceBase::intialize: Packet source or " + "packet destination invalid!" << std::endl; + return ObjectManagerIF::CHILD_INIT_FAILED; } distributor->registerService(this); @@ -68,7 +70,9 @@ ReturnValue_t CommandingServiceBase::initialize() { TCStore = objectManager->get(objects::TC_STORE); if (IPCStore == nullptr or TCStore == nullptr) { - return RETURN_FAILED; + sif::error << "CommandingServiceBase::intialize: IPC store or TC store " + "not initialized yet!" << std::endl; + return ObjectManagerIF::CHILD_INIT_FAILED; } return RETURN_OK; @@ -109,8 +113,8 @@ void CommandingServiceBase::handleCommandMessage(CommandMessage* reply) { * command as failure parameter 1 */ if(reply->getCommand() == CommandMessage::REPLY_REJECTED and result == RETURN_FAILED) { - result = reply->getReplyRejectedReason(); - failureParameter1 = iter->command; + result = reply->getReplyRejectedReason(); + failureParameter1 = iter->command; } switch (result) { @@ -176,14 +180,14 @@ void CommandingServiceBase::handleReplyHandlerResult(ReturnValue_t result, } else { if (isStep) { - nextCommand->clear(); + nextCommand->clearCommandMessage(); verificationReporter.sendFailureReport( TC_VERIFY::PROGRESS_FAILURE, iter->tcInfo.ackFlags, iter->tcInfo.tcPacketId, iter->tcInfo.tcSequenceControl, sendResult, ++iter->step, failureParameter1, failureParameter2); } else { - nextCommand->clear(); + nextCommand->clearCommandMessage(); verificationReporter.sendFailureReport( TC_VERIFY::COMPLETION_FAILURE, iter->tcInfo.ackFlags, iter->tcInfo.tcPacketId, @@ -318,7 +322,7 @@ void CommandingServiceBase::startExecution(TcPacketStored *storedPacket, storedPacket->getPacketSequenceControl(); acceptPacket(TC_VERIFY::START_SUCCESS, storedPacket); } else { - command.clear(); + command.clearCommandMessage(); rejectPacket(TC_VERIFY::START_FAILURE, storedPacket, sendResult); checkAndExecuteFifo(iter); } @@ -335,7 +339,7 @@ void CommandingServiceBase::startExecution(TcPacketStored *storedPacket, acceptPacket(TC_VERIFY::COMPLETION_SUCCESS, storedPacket); checkAndExecuteFifo(iter); } else { - command.clear(); + command.clearCommandMessage(); rejectPacket(TC_VERIFY::START_FAILURE, storedPacket, sendResult); checkAndExecuteFifo(iter); } @@ -374,7 +378,7 @@ void CommandingServiceBase::checkAndExecuteFifo(CommandMapIter iter) { void CommandingServiceBase::handleUnrequestedReply(CommandMessage* reply) { - reply->clear(); + reply->clearCommandMessage(); } From 85cc936d5da669f8f74ea02c87a8204f4a6235c4 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 29 Jun 2020 16:50:45 +0200 Subject: [PATCH 202/307] added back clear CommandMessage function --- ipc/CommandMessage.cpp | 4 ++++ ipc/CommandMessage.h | 2 ++ 2 files changed, 6 insertions(+) diff --git a/ipc/CommandMessage.cpp b/ipc/CommandMessage.cpp index 1470fe85..8c296abd 100644 --- a/ipc/CommandMessage.cpp +++ b/ipc/CommandMessage.cpp @@ -68,6 +68,10 @@ size_t CommandMessage::getMinimumMessageSize() const { return MINIMUM_COMMAND_MESSAGE_SIZE; } +void CommandMessage::clearCommandMessage() { + clear(); +} + void CommandMessage::clear() { CommandMessageCleaner::clearCommandMessage(this); } diff --git a/ipc/CommandMessage.h b/ipc/CommandMessage.h index 021fa49a..d843e4c5 100644 --- a/ipc/CommandMessage.h +++ b/ipc/CommandMessage.h @@ -111,7 +111,9 @@ public: ReturnValue_t getReplyRejectedReason( Command_t* initialCommand = nullptr) const override; + virtual void clear() override; + void clearCommandMessage(); /** * Extract message ID, which is the first byte of the command ID for the From 3a850018550b319476a4ec8b68bd75b035909df2 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 30 Jun 2020 00:48:48 +0200 Subject: [PATCH 203/307] bit setter correction --- datapoollocal/LocalDataSet.cpp | 7 +++---- datapoollocal/LocalDataSet.h | 10 +++------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/datapoollocal/LocalDataSet.cpp b/datapoollocal/LocalDataSet.cpp index 27ad4bc2..3fc8592e 100644 --- a/datapoollocal/LocalDataSet.cpp +++ b/datapoollocal/LocalDataSet.cpp @@ -42,7 +42,7 @@ ReturnValue_t LocalDataSet::serializeWithValidityBuffer(uint8_t **buffer, if(registeredVariables[count]->isValid()) { // set validity buffer here. this->bitSetter(validityMask + validBufferIndex, - validBufferIndexBit, true); + validBufferIndexBit); if(validBufferIndexBit == 7) { validBufferIndex ++; validBufferIndexBit = 0; @@ -83,13 +83,12 @@ ReturnValue_t LocalDataSet::serializeLocalPoolIds(uint8_t** buffer, return HasReturnvaluesIF::RETURN_OK; } -void LocalDataSet::bitSetter(uint8_t* byte, uint8_t position, - bool value) const { +void LocalDataSet::bitSetter(uint8_t* byte, uint8_t position) const { if(position > 7) { sif::debug << "Pool Raw Access: Bit setting invalid position" << std::endl; return; } uint8_t shiftNumber = position + (7 - 2 * position); - *byte |= 1UL << shiftNumber; + *byte |= 1 << shiftNumber; } diff --git a/datapoollocal/LocalDataSet.h b/datapoollocal/LocalDataSet.h index 48138e63..aea699d8 100644 --- a/datapoollocal/LocalDataSet.h +++ b/datapoollocal/LocalDataSet.h @@ -98,14 +98,10 @@ private: LocalDataPoolManager* hkManager; /** - * Sets the bit at the bit-position of a byte provided by its address - * to the specified value (zero or one). - * @param byte Pointer to byte to bitset. - * @param position MSB first, 0 to 7 possible. - * @param value Value to set. - * @return + * Set n-th bit of a byte, with n being the position from 0 + * (most significant bit) to 7 (least significant bit) */ - void bitSetter(uint8_t* byte, uint8_t position, bool value) const; + void bitSetter(uint8_t* byte, uint8_t position) const; }; #endif /* FRAMEWORK_DATAPOOLLOCAL_LOCALDATASET_H_ */ From 2de972bb8a9a35b81824f5c6bc5d00802c32dadd Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 30 Jun 2020 15:51:19 +0200 Subject: [PATCH 204/307] const store accessor copy ctor fixx --- storagemanager/ConstStorageAccessor.h | 6 +++--- storagemanager/StorageAccessor.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/storagemanager/ConstStorageAccessor.h b/storagemanager/ConstStorageAccessor.h index cf8ca08f..020030a9 100644 --- a/storagemanager/ConstStorageAccessor.h +++ b/storagemanager/ConstStorageAccessor.h @@ -80,13 +80,13 @@ public: * @return */ ConstStorageAccessor& operator= (ConstStorageAccessor&&); - ConstStorageAccessor (ConstStorageAccessor&&); + ConstStorageAccessor(ConstStorageAccessor&&); //! The copy ctor and copy assignemnt should be deleted implicitely //! according to https://foonathan.net/2019/02/special-member-functions/ //! but I still deleted them to make it more explicit. (remember rule of 5). - ConstStorageAccessor& operator= (ConstStorageAccessor&) = delete; - ConstStorageAccessor (ConstStorageAccessor&) = delete; + ConstStorageAccessor& operator=(const ConstStorageAccessor&) = delete; + ConstStorageAccessor(const ConstStorageAccessor&) = delete; protected: const uint8_t* constDataPointer = nullptr; store_address_t storeId; diff --git a/storagemanager/StorageAccessor.h b/storagemanager/StorageAccessor.h index c5e38306..475b2f4f 100644 --- a/storagemanager/StorageAccessor.h +++ b/storagemanager/StorageAccessor.h @@ -26,7 +26,7 @@ public: * @return */ StorageAccessor& operator= (StorageAccessor&&); - StorageAccessor (StorageAccessor&&); + StorageAccessor(StorageAccessor&&); ReturnValue_t write(uint8_t *data, size_t size, uint16_t offset = 0); From 1820b5f95c4e3d03c06cd7c0ee9b2fa6639adac9 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 30 Jun 2020 16:02:07 +0200 Subject: [PATCH 205/307] hotfix for copy ctor --- storagemanager/ConstStorageAccessor.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/storagemanager/ConstStorageAccessor.h b/storagemanager/ConstStorageAccessor.h index cf8ca08f..020030a9 100644 --- a/storagemanager/ConstStorageAccessor.h +++ b/storagemanager/ConstStorageAccessor.h @@ -80,13 +80,13 @@ public: * @return */ ConstStorageAccessor& operator= (ConstStorageAccessor&&); - ConstStorageAccessor (ConstStorageAccessor&&); + ConstStorageAccessor(ConstStorageAccessor&&); //! The copy ctor and copy assignemnt should be deleted implicitely //! according to https://foonathan.net/2019/02/special-member-functions/ //! but I still deleted them to make it more explicit. (remember rule of 5). - ConstStorageAccessor& operator= (ConstStorageAccessor&) = delete; - ConstStorageAccessor (ConstStorageAccessor&) = delete; + ConstStorageAccessor& operator=(const ConstStorageAccessor&) = delete; + ConstStorageAccessor(const ConstStorageAccessor&) = delete; protected: const uint8_t* constDataPointer = nullptr; store_address_t storeId; From 837fecf8599a54102c59ea549ac56a876ff5c32b Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 30 Jun 2020 21:22:26 +0200 Subject: [PATCH 206/307] 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 55d36a9a..bb06206e 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 9d072bf4..3841b99c 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 c811158f..fcf5237d 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 c3484676..3e5bcc60 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 493b22ee..10021631 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 cebe8953..867bf415 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 b2b4798d..3fdab9ed 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 00000000..f44e1d95 --- /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 37fa0a04..700503c6 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 From d7bff31a4cfd5e720847a0c9525a4099b97560ac Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 1 Jul 2020 14:17:55 +0200 Subject: [PATCH 207/307] compiling again --- datapool/DataSetBase.cpp | 8 +- datapool/DataSetBase.h | 5 +- datapool/PoolRawAccessHelper.cpp | 20 ++-- datapool/PoolRawAccessHelper.h | 6 +- datapoolglob/GlobalPoolVariable.h | 14 +-- datapoolglob/GlobalPoolVector.h | 4 +- datapoolglob/GlobalPoolVector.tpp | 16 ++-- datapoolglob/PIDReader.h | 6 +- datapoolglob/PoolRawAccess.cpp | 70 +++++++------- datapoolglob/PoolRawAccess.h | 14 +-- datapoollocal/LocalDataPoolManager.cpp | 7 +- datapoollocal/LocalDataSet.cpp | 12 ++- datapoollocal/LocalDataSet.h | 6 +- datapoollocal/LocalPoolVariable.h | 6 +- datapoollocal/LocalPoolVariable.tpp | 12 +-- datapoollocal/LocalPoolVector.h | 5 +- datapoollocal/LocalPoolVector.tpp | 16 ++-- health/HealthTableIF.h | 2 +- power/PowerComponent.h | 9 -- serialize/SerialBufferAdapter.cpp | 8 +- serialize/SerialFixedArrayListAdapter.h | 35 +++---- serialize/SerializeAdapter.h | 3 +- serialize/SerializeAdapterInternal.h | 118 ------------------------ tmtcpacket/pus/TmPacketStored.cpp | 2 +- 24 files changed, 144 insertions(+), 260 deletions(-) delete mode 100644 serialize/SerializeAdapterInternal.h diff --git a/datapool/DataSetBase.cpp b/datapool/DataSetBase.cpp index b788d05d..55801eb1 100644 --- a/datapool/DataSetBase.cpp +++ b/datapool/DataSetBase.cpp @@ -131,11 +131,11 @@ ReturnValue_t DataSetBase::unlockDataPool() { } ReturnValue_t DataSetBase::serialize(uint8_t** buffer, size_t* size, - const size_t maxSize, bool bigEndian) const { + const size_t maxSize, SerializeIF::Endianness streamEndianness) const { ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED; for (uint16_t count = 0; count < fillCount; count++) { result = registeredVariables[count]->serialize(buffer, size, maxSize, - bigEndian); + streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } @@ -144,11 +144,11 @@ ReturnValue_t DataSetBase::serialize(uint8_t** buffer, size_t* size, } ReturnValue_t DataSetBase::deSerialize(const uint8_t** buffer, size_t* size, - bool bigEndian) { + SerializeIF::Endianness streamEndianness) { ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED; for (uint16_t count = 0; count < fillCount; count++) { result = registeredVariables[count]->deSerialize(buffer, size, - bigEndian); + streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } diff --git a/datapool/DataSetBase.h b/datapool/DataSetBase.h index 8f7d892a..8eae6a09 100644 --- a/datapool/DataSetBase.h +++ b/datapool/DataSetBase.h @@ -105,10 +105,11 @@ public: /* SerializeIF implementations */ virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, - const size_t maxSize, bool bigEndian) const override; + const size_t maxSize, + SerializeIF::Endianness streamEndianness) const override; virtual size_t getSerializedSize() const override; virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, - bool bigEndian) override; + SerializeIF::Endianness streamEndianness) override; // SHOULDDO we could use a linked list of datapool variables //!< This definition sets the maximum number of variables to diff --git a/datapool/PoolRawAccessHelper.cpp b/datapool/PoolRawAccessHelper.cpp index 6e289303..2324a56c 100644 --- a/datapool/PoolRawAccessHelper.cpp +++ b/datapool/PoolRawAccessHelper.cpp @@ -24,8 +24,9 @@ PoolRawAccessHelper::~PoolRawAccessHelper() { } ReturnValue_t PoolRawAccessHelper::serialize(uint8_t **buffer, size_t *size, - const size_t max_size, bool bigEndian) { - SerializationArgs serializationArgs = {buffer, size, max_size, bigEndian}; + const size_t max_size, SerializeIF::Endianness streamEndianness) { + SerializationArgs serializationArgs = {buffer, size, max_size, + streamEndianness}; ReturnValue_t result = RETURN_OK; size_t remainingParametersSize = numberOfParameters * 4; for(uint8_t count=0; count < numberOfParameters; count++) { @@ -44,9 +45,10 @@ ReturnValue_t PoolRawAccessHelper::serialize(uint8_t **buffer, size_t *size, } ReturnValue_t PoolRawAccessHelper::serializeWithValidityMask(uint8_t ** buffer, - size_t * size, const size_t max_size, bool bigEndian) { + size_t * size, const size_t max_size, + SerializeIF::Endianness streamEndianness) { ReturnValue_t result = RETURN_OK; - SerializationArgs argStruct = {buffer, size, max_size, bigEndian}; + SerializationArgs argStruct = {buffer, size, max_size, streamEndianness}; size_t remainingParametersSize = numberOfParameters * 4; uint8_t validityMaskSize = ceil((float)numberOfParameters/8.0); uint8_t validityMask[validityMaskSize]; @@ -76,8 +78,8 @@ ReturnValue_t PoolRawAccessHelper::serializeCurrentPoolEntryIntoBuffer( bool withValidMask, uint8_t * validityMask) { uint32_t currentPoolId; // Deserialize current pool ID from pool ID buffer - ReturnValue_t result = AutoSerializeAdapter::deSerialize(¤tPoolId, - &poolIdBuffer,remainingParameters, false); + ReturnValue_t result = SerializeAdapter::deSerialize(¤tPoolId, + &poolIdBuffer,remainingParameters, SerializeIF::Endianness::MACHINE); if(result != RETURN_OK) { sif::debug << std::hex << "PoolRawAccessHelper: Error deSeralizing " "pool IDs" << std::dec << std::endl; @@ -109,8 +111,8 @@ ReturnValue_t PoolRawAccessHelper::handlePoolEntrySerialization( GlobDataSet currentDataSet; //debug << "Current array position: " << (int)arrayPosition << std::endl; - PoolRawAccess currentPoolRawAccess(currentPoolId,arrayPosition, - ¤tDataSet,PoolVariableIF::VAR_READ); + PoolRawAccess currentPoolRawAccess(currentPoolId, arrayPosition, + ¤tDataSet, PoolVariableIF::VAR_READ); result = currentDataSet.read(); if (result != RETURN_OK) { @@ -137,7 +139,7 @@ ReturnValue_t PoolRawAccessHelper::handlePoolEntrySerialization( } result = currentDataSet.serialize(argStruct.buffer, argStruct.size, - argStruct.max_size, argStruct.bigEndian); + argStruct.max_size, argStruct.streamEndianness); if (result != RETURN_OK) { sif::debug << "Pool Raw Access Helper: Error serializing pool data with " "ID 0x" << std::hex << currentPoolId << " into send buffer " diff --git a/datapool/PoolRawAccessHelper.h b/datapool/PoolRawAccessHelper.h index 52d9ebe5..0d8f8d6d 100644 --- a/datapool/PoolRawAccessHelper.h +++ b/datapool/PoolRawAccessHelper.h @@ -43,7 +43,7 @@ public: * @c RETURN_FAILED on failure */ ReturnValue_t serialize(uint8_t ** buffer, size_t * size, - const size_t max_size, bool bigEndian); + const size_t max_size, SerializeIF::Endianness streamEndianness); /** * Serializes data pool entries into provided buffer with the validity mask buffer @@ -56,7 +56,7 @@ public: * @c RETURN_FAILED on failure */ ReturnValue_t serializeWithValidityMask(uint8_t ** buffer, size_t * size, - const size_t max_size, bool bigEndian); + const size_t max_size, SerializeIF::Endianness streamEndianness); private: @@ -71,7 +71,7 @@ private: uint8_t ** buffer; size_t * size; const size_t max_size; - bool bigEndian; + SerializeIF::Endianness streamEndianness; }; /** * Helper function to serialize single pool entries diff --git a/datapoolglob/GlobalPoolVariable.h b/datapoolglob/GlobalPoolVariable.h index 9e3eea0c..b4aa6c4c 100644 --- a/datapoolglob/GlobalPoolVariable.h +++ b/datapoolglob/GlobalPoolVariable.h @@ -181,18 +181,20 @@ public: } virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, - const size_t max_size, bool bigEndian) const override { - return SerializeAdapter::serialize(&value, buffer, size, max_size, - bigEndian); + const size_t max_size, + SerializeIF::Endianness streamEndianness) const override { + return SerializeAdapter::serialize(&value, buffer, size, max_size, + streamEndianness); } virtual size_t getSerializedSize() const { - return SerializeAdapter::getSerializedSize(&value); + return SerializeAdapter::getSerializedSize(&value); } virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, - bool bigEndian) { - return SerializeAdapter::deSerialize(&value, buffer, size, bigEndian); + SerializeIF::Endianness streamEndianness) { + return SerializeAdapter::deSerialize(&value, buffer, size, + streamEndianness); } }; diff --git a/datapoolglob/GlobalPoolVector.h b/datapoolglob/GlobalPoolVector.h index 93092228..0e03f77d 100644 --- a/datapoolglob/GlobalPoolVector.h +++ b/datapoolglob/GlobalPoolVector.h @@ -109,10 +109,10 @@ public: const T &operator [](int i) const {return value[i];} virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, - const size_t max_size, bool bigEndian) const override; + size_t max_size, Endianness streamEndianness) const override; virtual size_t getSerializedSize() const override; virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, - bool bigEndian) override; + Endianness streamEndianness) override; /** * @brief This is a call to read the array's values diff --git a/datapoolglob/GlobalPoolVector.tpp b/datapoolglob/GlobalPoolVector.tpp index 5710da57..ccf33138 100644 --- a/datapoolglob/GlobalPoolVector.tpp +++ b/datapoolglob/GlobalPoolVector.tpp @@ -79,12 +79,13 @@ inline ReturnValue_t GlobPoolVector::commitWithoutLock() { template inline ReturnValue_t GlobPoolVector::serialize(uint8_t** buffer, - size_t* size, const size_t max_size, bool bigEndian) const { + size_t* size, size_t max_size, + SerializeIF::Endianness streamEndianness) const { uint16_t i; ReturnValue_t result; for (i = 0; i < vectorSize; i++) { - result = SerializeAdapter::serialize(&(value[i]), buffer, size, - max_size, bigEndian); + result = SerializeAdapter::serialize(&(value[i]), buffer, size, + max_size, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } @@ -94,17 +95,18 @@ inline ReturnValue_t GlobPoolVector::serialize(uint8_t** buffer, template inline size_t GlobPoolVector::getSerializedSize() const { - return vectorSize * SerializeAdapter::getSerializedSize(value); + return vectorSize * SerializeAdapter::getSerializedSize(value); } template inline ReturnValue_t GlobPoolVector::deSerialize( - const uint8_t** buffer, size_t* size, bool bigEndian) { + const uint8_t** buffer, size_t* size, + SerializeIF::Endianness streamEndianness) { uint16_t i; ReturnValue_t result; for (i = 0; i < vectorSize; i++) { - result = SerializeAdapter::deSerialize(&(value[i]), buffer, size, - bigEndian); + result = SerializeAdapter::deSerialize(&(value[i]), buffer, size, + streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } diff --git a/datapoolglob/PIDReader.h b/datapoolglob/PIDReader.h index 1b337f28..a1116040 100644 --- a/datapoolglob/PIDReader.h +++ b/datapoolglob/PIDReader.h @@ -16,9 +16,9 @@ protected: uint32_t parameterId; uint8_t valid; ReturnValue_t readWithoutLock() { - uint8_t arrayIndex = DataPool::PIDToArrayIndex(parameterId); - PoolEntry *read_out = ::dataPool.getData( - DataPool::PIDToDataPoolId(parameterId), arrayIndex); + uint8_t arrayIndex = GlobalDataPool::PIDToArrayIndex(parameterId); + PoolEntry *read_out = glob::dataPool.getData( + GlobalDataPool::PIDToDataPoolId(parameterId), arrayIndex); if (read_out != NULL) { valid = read_out->valid; value = read_out->address[arrayIndex]; diff --git a/datapoolglob/PoolRawAccess.cpp b/datapoolglob/PoolRawAccess.cpp index 39cfd58c..bec54ab3 100644 --- a/datapoolglob/PoolRawAccess.cpp +++ b/datapoolglob/PoolRawAccess.cpp @@ -145,27 +145,29 @@ ReturnValue_t PoolRawAccess::getEntryEndianSafe(uint8_t* buffer, ReturnValue_t PoolRawAccess::serialize(uint8_t** buffer, size_t* size, - const size_t max_size, bool bigEndian) const { - if (typeSize + *size <= max_size) { - if (bigEndian) { + size_t maxSize, Endianness streamEndianness) const { + //TODO integer overflow + if (typeSize + *size <= maxSize) { +#warning use endian swapper + if (1) { #ifndef BYTE_ORDER_SYSTEM #error BYTE_ORDER_SYSTEM not defined #elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN - for (uint8_t count = 0; count < typeSize; count++) { - (*buffer)[count] = value[typeSize - count - 1]; - } + for (uint8_t count = 0; count < typeSize; count++) { + (*buffer)[count] = value[typeSize - count - 1]; + } #elif BYTE_ORDER_SYSTEM == BIG_ENDIAN - memcpy(*buffer, value, typeSize); + memcpy(*buffer, value, typeSize); #endif - } else { - memcpy(*buffer, value, typeSize); - } - *size += typeSize; - (*buffer) += typeSize; - return HasReturnvaluesIF::RETURN_OK; - } else { - return SerializeIF::BUFFER_TOO_SHORT; - } + } else { + memcpy(*buffer, value, typeSize); + } + *size += typeSize; + (*buffer) += typeSize; + return HasReturnvaluesIF::RETURN_OK; + } else { + return SerializeIF::BUFFER_TOO_SHORT; + } } @@ -231,28 +233,26 @@ size_t PoolRawAccess::getSerializedSize() const { } ReturnValue_t PoolRawAccess::deSerialize(const uint8_t** buffer, size_t* size, - bool bigEndian) { - // TODO: Needs to be tested!!! - if (*size >= typeSize) { - *size -= typeSize; - if (bigEndian) { + Endianness streamEndianness) { + + if (*size >= typeSize) { + *size -= typeSize; + if (1) { #ifndef BYTE_ORDER_SYSTEM #error BYTE_ORDER_SYSTEM not defined #elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN - for (uint8_t count = 0; count < typeSize; count++) { - value[count] = (*buffer)[typeSize - count - 1]; - } + for (uint8_t count = 0; count < typeSize; count++) { + value[count] = (*buffer)[typeSize - count - 1]; + } #elif BYTE_ORDER_SYSTEM == BIG_ENDIAN - memcpy(value, *buffer, typeSize); + memcpy(value, *buffer, typeSize); #endif - } - else { - memcpy(value, *buffer, typeSize); - } - *buffer += typeSize; - return HasReturnvaluesIF::RETURN_OK; - } - else { - return SerializeIF::STREAM_TOO_SHORT; - } + } else { + memcpy(value, *buffer, typeSize); + } + *buffer += typeSize; + return HasReturnvaluesIF::RETURN_OK; + } else { + return SerializeIF::STREAM_TOO_SHORT; + } } diff --git a/datapoolglob/PoolRawAccess.h b/datapoolglob/PoolRawAccess.h index 60e3c71e..ea07356e 100644 --- a/datapoolglob/PoolRawAccess.h +++ b/datapoolglob/PoolRawAccess.h @@ -69,8 +69,13 @@ public: * @return - @c RETURN_OK if serialization was successfull * - @c SerializeIF::BUFFER_TOO_SHORT if range check failed */ - ReturnValue_t serialize(uint8_t** buffer, size_t* size, - const size_t max_size, bool bigEndian) const; + ReturnValue_t serialize(uint8_t **buffer, size_t *size, + size_t maxSize, Endianness streamEndianness) const override; + + size_t getSerializedSize() const override; + + ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size, + Endianness streamEndianness) override; /** * With this method, the content can be set from a big endian buffer safely. @@ -130,11 +135,6 @@ public: */ uint16_t getSizeTillEnd() const; - size_t getSerializedSize() const; - - ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, - bool bigEndian); - /** * @brief This is a call to read the value from the global data pool. * @details diff --git a/datapoollocal/LocalDataPoolManager.cpp b/datapoollocal/LocalDataPoolManager.cpp index bb06206e..78116138 100644 --- a/datapoollocal/LocalDataPoolManager.cpp +++ b/datapoollocal/LocalDataPoolManager.cpp @@ -173,7 +173,7 @@ ReturnValue_t LocalDataPoolManager::generateSetStructurePacket(sid_t sid) { } size_t size = 0; result = dataSet->serializeLocalPoolIds(&storePtr, &size, - expectedSize, false); + expectedSize, SerializeIF::Endianness::BIG); if(expectedSize != size) { sif::error << "HousekeepingManager::generateSetStructurePacket: " "Expected size is not equal to serialized size" << std::endl; @@ -198,10 +198,11 @@ ReturnValue_t LocalDataPoolManager::serializeHkPacketIntoStore( if(appendValidityBuffer) { result = dataSet->serializeWithValidityBuffer(&storePtr, - &size, hkSize, false); + &size, hkSize, SerializeIF::Endianness::MACHINE); } else { - result = dataSet->serialize(&storePtr, &size, hkSize, false); + result = dataSet->serialize(&storePtr, &size, hkSize, + SerializeIF::Endianness::MACHINE); } if(result != HasReturnvaluesIF::RETURN_OK) { diff --git a/datapoollocal/LocalDataSet.cpp b/datapoollocal/LocalDataSet.cpp index 3fc8592e..72d79103 100644 --- a/datapoollocal/LocalDataSet.cpp +++ b/datapoollocal/LocalDataSet.cpp @@ -32,7 +32,8 @@ ReturnValue_t LocalDataSet::lockDataPool(uint32_t timeoutMs) { } ReturnValue_t LocalDataSet::serializeWithValidityBuffer(uint8_t **buffer, - size_t *size, const size_t maxSize, bool bigEndian) const { + size_t *size, size_t maxSize, + SerializeIF::Endianness streamEndianness) const { ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED; uint8_t validityMaskSize = std::ceil(static_cast(fillCount)/8.0); uint8_t validityMask[validityMaskSize]; @@ -52,7 +53,7 @@ ReturnValue_t LocalDataSet::serializeWithValidityBuffer(uint8_t **buffer, } } result = registeredVariables[count]->serialize(buffer, size, maxSize, - bigEndian); + streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { return result; } @@ -69,11 +70,12 @@ ReturnValue_t LocalDataSet::unlockDataPool() { } ReturnValue_t LocalDataSet::serializeLocalPoolIds(uint8_t** buffer, - size_t* size, const size_t maxSize, bool bigEndian) const { + size_t* size, size_t maxSize, + SerializeIF::Endianness streamEndianness) const { for (uint16_t count = 0; count < fillCount; count++) { lp_id_t currentPoolId = registeredVariables[count]->getDataPoolId(); - auto result = AutoSerializeAdapter::serialize(¤tPoolId, buffer, - size, maxSize, bigEndian); + auto result = SerializeAdapter::serialize(¤tPoolId, buffer, + size, maxSize, streamEndianness); if(result != HasReturnvaluesIF::RETURN_OK) { sif::warning << "LocalDataSet::serializeLocalPoolIds: Serialization" " error!" << std::endl; diff --git a/datapoollocal/LocalDataSet.h b/datapoollocal/LocalDataSet.h index aea699d8..e997b729 100644 --- a/datapoollocal/LocalDataSet.h +++ b/datapoollocal/LocalDataSet.h @@ -68,10 +68,12 @@ public: * @return */ ReturnValue_t serializeWithValidityBuffer(uint8_t** buffer, - size_t* size, const size_t maxSize, bool bigEndian) const; + size_t* size, size_t maxSize, + SerializeIF::Endianness streamEndianness) const; ReturnValue_t serializeLocalPoolIds(uint8_t** buffer, - size_t* size, const size_t maxSize, bool bigEndian) const; + size_t* size, size_t maxSize, + SerializeIF::Endianness streamEndianness) const; protected: private: /** diff --git a/datapoollocal/LocalPoolVariable.h b/datapoollocal/LocalPoolVariable.h index 4b6e24aa..98782b8d 100644 --- a/datapoollocal/LocalPoolVariable.h +++ b/datapoollocal/LocalPoolVariable.h @@ -84,11 +84,11 @@ public: void setValid(bool validity) override; uint8_t getValid() const; - ReturnValue_t serialize(uint8_t** buffer, size_t* size, - const size_t max_size, bool bigEndian) const override; + ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize, + SerializeIF::Endianness streamEndianness) const override; virtual size_t getSerializedSize() const override; virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, - bool bigEndian) override; + SerializeIF::Endianness streamEndianness) override; /** * @brief This is a call to read the array's values diff --git a/datapoollocal/LocalPoolVariable.tpp b/datapoollocal/LocalPoolVariable.tpp index 9dcd0699..7f9fbf13 100644 --- a/datapoollocal/LocalPoolVariable.tpp +++ b/datapoollocal/LocalPoolVariable.tpp @@ -133,20 +133,20 @@ inline uint8_t LocalPoolVar::getValid() const { template inline ReturnValue_t LocalPoolVar::serialize(uint8_t** buffer, size_t* size, - const size_t max_size, bool bigEndian) const { - return AutoSerializeAdapter::serialize(&value, - buffer, size ,max_size, bigEndian); + const size_t max_size, SerializeIF::Endianness streamEndianness) const { + return SerializeAdapter::serialize(&value, + buffer, size ,max_size, streamEndianness); } template inline size_t LocalPoolVar::getSerializedSize() const { - return AutoSerializeAdapter::getSerializedSize(&value); + return SerializeAdapter::getSerializedSize(&value); } template inline ReturnValue_t LocalPoolVar::deSerialize(const uint8_t** buffer, - size_t* size, bool bigEndian) { - return AutoSerializeAdapter::deSerialize(&value, buffer, size, bigEndian); + size_t* size, SerializeIF::Endianness streamEndianness) { + return SerializeAdapter::deSerialize(&value, buffer, size, streamEndianness); } template diff --git a/datapoollocal/LocalPoolVector.h b/datapoollocal/LocalPoolVector.h index a8d0a7bb..f6532894 100644 --- a/datapoollocal/LocalPoolVector.h +++ b/datapoollocal/LocalPoolVector.h @@ -114,10 +114,11 @@ public: const T &operator [](int i) const; virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, - const size_t max_size, bool bigEndian) const override; + const size_t maxSize, + SerializeIF::Endianness streamEndiannes) const override; virtual size_t getSerializedSize() const override; virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, - bool bigEndian) override; + SerializeIF::Endianness streamEndianness) override; /** * @brief This is a call to read the array's values diff --git a/datapoollocal/LocalPoolVector.tpp b/datapoollocal/LocalPoolVector.tpp index a18f8327..872c49ec 100644 --- a/datapoollocal/LocalPoolVector.tpp +++ b/datapoollocal/LocalPoolVector.tpp @@ -125,11 +125,12 @@ inline const T& LocalPoolVector::operator [](int i) const { template inline ReturnValue_t LocalPoolVector::serialize(uint8_t** buffer, - size_t* size, const size_t max_size, bool bigEndian) const { + size_t* size, size_t maxSize, + SerializeIF::Endianness streamEndianness) const { ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED; for (uint16_t i = 0; i < vectorSize; i++) { - result = SerializeAdapter::serialize(&(value[i]), buffer, size, - max_size, bigEndian); + result = SerializeAdapter::serialize(&(value[i]), buffer, size, + maxSize, streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { break; } @@ -139,16 +140,17 @@ inline ReturnValue_t LocalPoolVector::serialize(uint8_t** buffer, template inline size_t LocalPoolVector::getSerializedSize() const { - return vectorSize * SerializeAdapter::getSerializedSize(value); + return vectorSize * SerializeAdapter::getSerializedSize(value); } template inline ReturnValue_t LocalPoolVector::deSerialize( - const uint8_t** buffer, size_t* size, bool bigEndian) { + const uint8_t** buffer, size_t* size, + SerializeIF::Endianness streamEndianness) { ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED; for (uint16_t i = 0; i < vectorSize; i++) { - result = SerializeAdapter::deSerialize(&(value[i]), buffer, size, - bigEndian); + result = SerializeAdapter::deSerialize(&(value[i]), buffer, size, + streamEndianness); if (result != HasReturnvaluesIF::RETURN_OK) { break; } diff --git a/health/HealthTableIF.h b/health/HealthTableIF.h index c8d2c74a..e4606286 100644 --- a/health/HealthTableIF.h +++ b/health/HealthTableIF.h @@ -19,7 +19,7 @@ public: HasHealthIF::HealthState initilialState = HasHealthIF::HEALTHY) = 0; virtual uint32_t getPrintSize() = 0; - virtual void printAll(uint8_t *pointer, uint32_t maxSize) = 0; + virtual void printAll(uint8_t *pointer, size_t maxSize) = 0; protected: virtual ReturnValue_t iterate(std::pair *value, bool reset = false) = 0; diff --git a/power/PowerComponent.h b/power/PowerComponent.h index 1c550776..61ab3674 100644 --- a/power/PowerComponent.h +++ b/power/PowerComponent.h @@ -20,21 +20,12 @@ public: float getMax(); ReturnValue_t serialize(uint8_t** buffer, size_t* size, -<<<<<<< HEAD - const size_t max_size, bool bigEndian) const; - - size_t getSerializedSize() const; - - ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, - bool bigEndian); -======= size_t maxSize, Endianness streamEndianness) const override; size_t getSerializedSize() const override; ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, Endianness streamEndianness) override; ->>>>>>> upstream/mohr_serialize ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId, ParameterWrapper *parameterWrapper, diff --git a/serialize/SerialBufferAdapter.cpp b/serialize/SerialBufferAdapter.cpp index 69f40a34..1224bba1 100644 --- a/serialize/SerialBufferAdapter.cpp +++ b/serialize/SerialBufferAdapter.cpp @@ -36,18 +36,18 @@ ReturnValue_t SerialBufferAdapter::serialize(uint8_t** buffer, size_t* size, maxSize, streamEndianness); } if (constBuffer != nullptr) { - memcpy(*buffer_, this->constBuffer, bufferLength); + memcpy(*buffer, this->constBuffer, bufferLength); } else if (buffer != nullptr) { // This will propably be never reached, constBuffer should always be // set if non-const buffer is set. - memcpy(*buffer_, this->buffer, bufferLength); + memcpy(*buffer, this->buffer, bufferLength); } else { return HasReturnvaluesIF::RETURN_FAILED; } - *size_ += bufferLength; - (*buffer_) += bufferLength; + *size += bufferLength; + (*buffer) += bufferLength; return HasReturnvaluesIF::RETURN_OK; } } diff --git a/serialize/SerialFixedArrayListAdapter.h b/serialize/SerialFixedArrayListAdapter.h index 6ad154a8..196af67c 100644 --- a/serialize/SerialFixedArrayListAdapter.h +++ b/serialize/SerialFixedArrayListAdapter.h @@ -39,30 +39,25 @@ public: */ template SerialFixedArrayListAdapter(Args... args) : - FixedArrayList(std::forward(args)...) - {} + FixedArrayList( + std::forward(args)...){} - virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, - const size_t max_size, bool bigEndian) const override { - return SerialArrayListAdapter::serialize(this, - buffer, size, max_size, bigEndian); - } + ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, Endianness streamEndianness) const { + return SerialArrayListAdapter::serialize(this, + buffer, size, maxSize, streamEndianness); + } - ReturnValue_t serialize(uint8_t** buffer, size_t* size, - size_t maxSize, Endianness streamEndianness) const { - return SerialArrayListAdapter::serialize(this, buffer, size, maxSize, streamEndianness); - } + size_t getSerializedSize() const { + return SerialArrayListAdapter::getSerializedSize(this); + } - size_t getSerializedSize() const { - return SerialArrayListAdapter::getSerializedSize(this); - } + ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) { + return SerialArrayListAdapter::deSerialize(this, + buffer, size, streamEndianness); + } - ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, - Endianness streamEndianness) { - return SerialArrayListAdapter::deSerialize(this, buffer, size, streamEndianness); - } }; - - #endif /* SERIALFIXEDARRAYLISTADAPTER_H_ */ diff --git a/serialize/SerializeAdapter.h b/serialize/SerializeAdapter.h index f8042861..2be39d5c 100644 --- a/serialize/SerializeAdapter.h +++ b/serialize/SerializeAdapter.h @@ -2,8 +2,9 @@ #define SERIALIZEADAPTER_H_ #include +#include +#include #include -#include #include /** diff --git a/serialize/SerializeAdapterInternal.h b/serialize/SerializeAdapterInternal.h deleted file mode 100644 index c57af0c9..00000000 --- a/serialize/SerializeAdapterInternal.h +++ /dev/null @@ -1,118 +0,0 @@ -/** - * @file SerializeAdapterInternal.h - * - * @date 13.04.2020 - * @author R. Mueller - */ - -#ifndef FRAMEWORK_SERIALIZE_SERIALIZEADAPTERINTERNAL_H_ -#define FRAMEWORK_SERIALIZE_SERIALIZEADAPTERINTERNAL_H_ -#include -#include -#include - -/** - * This template specialization will be chosen for fundamental types or - * anything else not implementing SerializeIF, based on partial - * template specialization. - * @tparam T - * @tparam - */ -template -class SerializeAdapter_ { -public: - /** - * - * @param object - * @param buffer - * @param size - * @param max_size - * @param bigEndian - * @return - */ - static ReturnValue_t serialize(const T* object, uint8_t** buffer, - size_t* size, const size_t max_size, bool bigEndian) { - // function eventuelly serializes structs here. - // does this work on every architecture? - // static_assert(std::is_fundamental::value); - size_t ignoredSize = 0; - if (size == nullptr) { - size = &ignoredSize; - } - if (sizeof(T) + *size <= max_size) { - T tmp; - if (bigEndian) { - tmp = EndianSwapper::swap(*object); - } else { - tmp = *object; - } - memcpy(*buffer, &tmp, sizeof(T)); - *size += sizeof(T); - (*buffer) += sizeof(T); - return HasReturnvaluesIF::RETURN_OK; - } else { - return SerializeIF::BUFFER_TOO_SHORT; - } - } - - /** - * Deserialize buffer into object - * @param object [out] Object to be deserialized with buffer data - * @param buffer contains the data. Non-Const pointer to non-const - * pointer to const data. - * @param size Size to deSerialize. wil be decremented by sizeof(T) - * @param bigEndian Specify endianness - * @return - */ - ReturnValue_t deSerialize(T* object, const uint8_t** buffer, size_t* size, - bool bigEndian) { - T tmp; - if (*size >= sizeof(T)) { - *size -= sizeof(T); - memcpy(&tmp, *buffer, sizeof(T)); - if (bigEndian) { - *object = EndianSwapper::swap(tmp); - } else { - *object = tmp; - } - *buffer += sizeof(T); - return HasReturnvaluesIF::RETURN_OK; - } else { - return SerializeIF::STREAM_TOO_SHORT; - } - } - - size_t getSerializedSize(const T * object) { - return sizeof(T); - } -}; - -/** - * This template specialization will be chosen for class derived from - * SerializeIF, based on partial template specialization. - * @tparam T - * @tparam - */ -template -class SerializeAdapter_ { -public: - ReturnValue_t serialize(const T* object, uint8_t** buffer, size_t* size, - const size_t max_size, bool bigEndian) const { - size_t ignoredSize = 0; - if (size == NULL) { - size = &ignoredSize; - } - return object->serialize(buffer, size, max_size, bigEndian); - } - - size_t getSerializedSize(const T* object) const { - return object->getSerializedSize(); - } - - ReturnValue_t deSerialize(T* object, const uint8_t** buffer, size_t* size, - bool bigEndian) { - return object->deSerialize(buffer, size, bigEndian); - } -}; - -#endif /* FRAMEWORK_SERIALIZE_SERIALIZEADAPTERINTERNAL_H_ */ diff --git a/tmtcpacket/pus/TmPacketStored.cpp b/tmtcpacket/pus/TmPacketStored.cpp index 14cf6a03..d6a4a69f 100644 --- a/tmtcpacket/pus/TmPacketStored.cpp +++ b/tmtcpacket/pus/TmPacketStored.cpp @@ -84,7 +84,7 @@ void TmPacketStored::deletePacket() { void TmPacketStored::setStoreAddress(store_address_t setAddress) { storeAddress = setAddress; const uint8_t *temp_data = NULL; - uint32_t temp_size; + size_t temp_size; if (!checkAndSetStore()) { return; } From 47b8ed2321c1a71743cb50fa555cbb3f6b2a3a62 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 1 Jul 2020 14:34:16 +0200 Subject: [PATCH 208/307] split up long debug message --- datapoollocal/LocalDataPoolManager.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/datapoollocal/LocalDataPoolManager.cpp b/datapoollocal/LocalDataPoolManager.cpp index 78116138..9c70c74f 100644 --- a/datapoollocal/LocalDataPoolManager.cpp +++ b/datapoollocal/LocalDataPoolManager.cpp @@ -47,8 +47,9 @@ ReturnValue_t LocalDataPoolManager::initialize(MessageQueueIF* queueToUse, } 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; + " queue ID from HK destination object ID. " << std::flush; + sif::warning << "Make sure it exists and the object impements " + "AcceptsHkPacketsIF!" << std::endl; } return initializeHousekeepingPoolEntriesOnce(); } From f67c836dedd087b18afe03f931d1ab69a0872f95 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 2 Jul 2020 14:42:16 +0200 Subject: [PATCH 209/307] RETURN_FAILED is 1 again --- returnvalues/HasReturnvaluesIF.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/returnvalues/HasReturnvaluesIF.h b/returnvalues/HasReturnvaluesIF.h index 04acd66e..38b343d4 100644 --- a/returnvalues/HasReturnvaluesIF.h +++ b/returnvalues/HasReturnvaluesIF.h @@ -12,8 +12,7 @@ typedef uint16_t ReturnValue_t; class HasReturnvaluesIF { public: static const ReturnValue_t RETURN_OK = 0; - //! This will be the all-ones value irrespective of used unsigned datatype. - static const ReturnValue_t RETURN_FAILED = -1; + static const ReturnValue_t RETURN_FAILED = 1; virtual ~HasReturnvaluesIF() {} static ReturnValue_t makeReturnCode(uint8_t interfaceId, uint8_t number) { From a09aa8df4ae8ba8fba3a7c6dd2e4b13ffc588d79 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 2 Jul 2020 14:43:19 +0200 Subject: [PATCH 210/307] include guard commnet --- returnvalues/HasReturnvaluesIF.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/returnvalues/HasReturnvaluesIF.h b/returnvalues/HasReturnvaluesIF.h index 38b343d4..d231f4ee 100644 --- a/returnvalues/HasReturnvaluesIF.h +++ b/returnvalues/HasReturnvaluesIF.h @@ -20,4 +20,4 @@ public: } }; -#endif /* HASRETURNVALUESIF_H_ */ +#endif /* FRAMEWORK_RETURNVALUES_HASRETURNVALUESIF_H_ */ From 3e069c34aa6a076f0394ab6bdf3c66f14294ba53 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 2 Jul 2020 16:29:29 +0200 Subject: [PATCH 211/307] datasetbase stays same f or now --- datapool/{StaticDataSetBase.cpp => DataSetBase.cpp} | 2 +- datapool/{StaticDataSetBase.h => DataSetBase.h} | 6 +++--- datapoolglob/GlobalDataSet.h | 2 +- datapoollocal/LocalDataSet.h | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) rename datapool/{StaticDataSetBase.cpp => DataSetBase.cpp} (98%) rename datapool/{StaticDataSetBase.h => DataSetBase.h} (97%) diff --git a/datapool/StaticDataSetBase.cpp b/datapool/DataSetBase.cpp similarity index 98% rename from datapool/StaticDataSetBase.cpp rename to datapool/DataSetBase.cpp index 3815534e..b788d05d 100644 --- a/datapool/StaticDataSetBase.cpp +++ b/datapool/DataSetBase.cpp @@ -1,4 +1,4 @@ -#include +#include #include DataSetBase::DataSetBase() { diff --git a/datapool/StaticDataSetBase.h b/datapool/DataSetBase.h similarity index 97% rename from datapool/StaticDataSetBase.h rename to datapool/DataSetBase.h index 708849ce..8f7d892a 100644 --- a/datapool/StaticDataSetBase.h +++ b/datapool/DataSetBase.h @@ -1,5 +1,5 @@ -#ifndef FRAMEWORK_DATAPOOL_STATICDATASETBASE_H_ -#define FRAMEWORK_DATAPOOL_STATICDATASETBASE_H_ +#ifndef FRAMEWORK_DATAPOOL_DATASETBASE_H_ +#define FRAMEWORK_DATAPOOL_DATASETBASE_H_ #include #include #include @@ -146,4 +146,4 @@ private: ReturnValue_t handleUnreadDatasetCommit(uint32_t lockTimeout); }; -#endif /* FRAMEWORK_DATAPOOL_STATICDATASETBASE_H_ */ +#endif /* FRAMEWORK_DATAPOOL_DATASETBASE_H_ */ diff --git a/datapoolglob/GlobalDataSet.h b/datapoolglob/GlobalDataSet.h index dec66dbc..f0bf7daa 100644 --- a/datapoolglob/GlobalDataSet.h +++ b/datapoolglob/GlobalDataSet.h @@ -1,7 +1,7 @@ #ifndef DATASET_H_ #define DATASET_H_ -#include +#include /** * @brief The DataSet class manages a set of locally checked out variables diff --git a/datapoollocal/LocalDataSet.h b/datapoollocal/LocalDataSet.h index 52a227e5..aea699d8 100644 --- a/datapoollocal/LocalDataSet.h +++ b/datapoollocal/LocalDataSet.h @@ -1,7 +1,7 @@ #ifndef FRAMEWORK_DATAPOOLLOCAL_LOCALDATASET_H_ #define FRAMEWORK_DATAPOOLLOCAL_LOCALDATASET_H_ +#include #include -#include #include #include From 099e6281ecdaccf39127da33e7b86b6eaa3f2335 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 2 Jul 2020 16:54:53 +0200 Subject: [PATCH 212/307] DataSetBase not bound to max size anymore --- datapool/DataSetBase.cpp | 9 ++++++--- datapool/DataSetBase.h | 13 ++++++------- datapoolglob/GlobalDataSet.cpp | 4 +++- datapoolglob/GlobalDataSet.h | 6 ++++++ datapoollocal/LocalDataSet.cpp | 14 ++++++++++++-- datapoollocal/LocalDataSet.h | 10 ++++++++-- datapoollocal/StaticLocalDataSet.cpp | 6 ++++++ datapoollocal/StaticLocalDataSet.h | 11 +++++++++++ 8 files changed, 58 insertions(+), 15 deletions(-) create mode 100644 datapoollocal/StaticLocalDataSet.cpp create mode 100644 datapoollocal/StaticLocalDataSet.h diff --git a/datapool/DataSetBase.cpp b/datapool/DataSetBase.cpp index b788d05d..3d38e143 100644 --- a/datapool/DataSetBase.cpp +++ b/datapool/DataSetBase.cpp @@ -1,8 +1,11 @@ #include #include -DataSetBase::DataSetBase() { - for (uint8_t count = 0; count < DATA_SET_MAX_SIZE; count++) { +DataSetBase::DataSetBase(PoolVariableIF** registeredVariablesArray, + const size_t maxFillCount): + registeredVariables(registeredVariablesArray), + maxFillCount(maxFillCount) { + for (uint8_t count = 0; count < maxFillCount; count++) { registeredVariables[count] = nullptr; } } @@ -21,7 +24,7 @@ ReturnValue_t DataSetBase::registerVariable( "Pool variable is nullptr." << std::endl; return DataSetIF::POOL_VAR_NULL; } - if (fillCount >= DATA_SET_MAX_SIZE) { + if (fillCount >= maxFillCount) { sif::error << "DataSet::registerVariable: " "DataSet is full." << std::endl; return DataSetIF::DATA_SET_FULL; diff --git a/datapool/DataSetBase.h b/datapool/DataSetBase.h index 8f7d892a..12ae2b53 100644 --- a/datapool/DataSetBase.h +++ b/datapool/DataSetBase.h @@ -37,7 +37,8 @@ public: * supply a pointer to this dataset to PoolVariable * initializations to register pool variables. */ - DataSetBase(); + DataSetBase(PoolVariableIF** registeredVariablesArray, + const size_t maxFillCount); virtual~ DataSetBase(); /** @@ -110,11 +111,6 @@ public: virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, bool bigEndian) override; - // SHOULDDO we could use a linked list of datapool variables - //!< This definition sets the maximum number of variables to - //! register in one DataSet. - static const uint8_t DATA_SET_MAX_SIZE = 63; - protected: /** * @brief The fill_count attribute ensures that the variables @@ -137,8 +133,11 @@ protected: /** * @brief This array represents all pool variables registered in this set. + * Child classes can use a static or dynamic container to create + * an array of registered variables and assign the first entry here. */ - PoolVariableIF* registeredVariables[DATA_SET_MAX_SIZE] = { }; + PoolVariableIF** registeredVariables = nullptr; + const size_t maxFillCount = 0; private: ReturnValue_t readVariable(uint16_t count); diff --git a/datapoolglob/GlobalDataSet.cpp b/datapoolglob/GlobalDataSet.cpp index 9da8d524..883f6157 100644 --- a/datapoolglob/GlobalDataSet.cpp +++ b/datapoolglob/GlobalDataSet.cpp @@ -2,7 +2,9 @@ #include #include -GlobDataSet::GlobDataSet(): DataSetBase() {} +GlobDataSet::GlobDataSet(): DataSetBase( + reinterpret_cast(®isteredVariables), + DATA_SET_MAX_SIZE) {} // Don't do anything with your variables, they are dead already! // (Destructor is already called) diff --git a/datapoolglob/GlobalDataSet.h b/datapoolglob/GlobalDataSet.h index f0bf7daa..519b08c0 100644 --- a/datapoolglob/GlobalDataSet.h +++ b/datapoolglob/GlobalDataSet.h @@ -61,6 +61,10 @@ public: */ void setEntriesValid(bool valid); + //!< This definition sets the maximum number of variables to + //! register in one DataSet. + static const uint8_t DATA_SET_MAX_SIZE = 63; + private: /** * If the valid state of a dataset is always relevant to the whole @@ -85,6 +89,8 @@ private: void handleAlreadyReadDatasetCommit(); ReturnValue_t handleUnreadDatasetCommit(); + + PoolVariableIF* registeredVariables[DATA_SET_MAX_SIZE]; }; #endif /* DATASET_H_ */ diff --git a/datapoollocal/LocalDataSet.cpp b/datapoollocal/LocalDataSet.cpp index 3fc8592e..c5142bfc 100644 --- a/datapoollocal/LocalDataSet.cpp +++ b/datapoollocal/LocalDataSet.cpp @@ -5,20 +5,30 @@ #include #include -LocalDataSet::LocalDataSet(OwnsLocalDataPoolIF *hkOwner): DataSetBase() { +LocalDataSet::LocalDataSet(OwnsLocalDataPoolIF *hkOwner, + const size_t maxNumberOfVariables): + DataSetBase(poolVarList.data(), maxNumberOfVariables) { + poolVarList.reserve(maxNumberOfVariables); + poolVarList.resize(maxNumberOfVariables); if(hkOwner == nullptr) { sif::error << "LocalDataSet::LocalDataSet: Owner can't be nullptr!" << std::endl; + return; } hkManager = hkOwner->getHkManagerHandle(); } -LocalDataSet::LocalDataSet(object_id_t ownerId): DataSetBase() { +LocalDataSet::LocalDataSet(object_id_t ownerId, + const size_t maxNumberOfVariables): + DataSetBase(poolVarList.data(), maxNumberOfVariables) { + poolVarList.reserve(maxNumberOfVariables); + poolVarList.resize(maxNumberOfVariables); OwnsLocalDataPoolIF* hkOwner = objectManager->get( ownerId); if(hkOwner == nullptr) { sif::error << "LocalDataSet::LocalDataSet: Owner can't be nullptr!" << std::endl; + return; } hkManager = hkOwner->getHkManagerHandle(); } diff --git a/datapoollocal/LocalDataSet.h b/datapoollocal/LocalDataSet.h index aea699d8..1a894130 100644 --- a/datapoollocal/LocalDataSet.h +++ b/datapoollocal/LocalDataSet.h @@ -5,6 +5,8 @@ #include #include +#include + class LocalDataPoolManager; /** @@ -35,7 +37,8 @@ public: * The constructor simply sets the fill_count to zero and sets * the state to "uninitialized". */ - LocalDataSet(OwnsLocalDataPoolIF* hkOwner); + LocalDataSet(OwnsLocalDataPoolIF *hkOwner, + const size_t maxNumberOfVariables); /** * @brief Constructor for users of local pool data. The passed pool @@ -43,7 +46,8 @@ public: * The constructor simply sets the fill_count to zero and sets * the state to "uninitialized". */ - LocalDataSet(object_id_t ownerId); + LocalDataSet(object_id_t ownerId, + const size_t maxNumberOfVariables); /** * @brief The destructor automatically manages writing the valid @@ -102,6 +106,8 @@ private: * (most significant bit) to 7 (least significant bit) */ void bitSetter(uint8_t* byte, uint8_t position) const; + + std::vector poolVarList; }; #endif /* FRAMEWORK_DATAPOOLLOCAL_LOCALDATASET_H_ */ diff --git a/datapoollocal/StaticLocalDataSet.cpp b/datapoollocal/StaticLocalDataSet.cpp new file mode 100644 index 00000000..15d4251a --- /dev/null +++ b/datapoollocal/StaticLocalDataSet.cpp @@ -0,0 +1,6 @@ +#include + + + + + diff --git a/datapoollocal/StaticLocalDataSet.h b/datapoollocal/StaticLocalDataSet.h new file mode 100644 index 00000000..15a79aae --- /dev/null +++ b/datapoollocal/StaticLocalDataSet.h @@ -0,0 +1,11 @@ +#ifndef FRAMEWORK_DATAPOOLLOCAL_STATICLOCALDATASET_H_ +#define FRAMEWORK_DATAPOOLLOCAL_STATICLOCALDATASET_H_ +#include + + +class StaticLocalDataSet: public DataSetBase { + +}; + + +#endif /* FRAMEWORK_DATAPOOLLOCAL_STATICLOCALDATASET_H_ */ From 72768a68152b3fb6778e7c90aead2b6f46d596ab Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 4 Jul 2020 00:51:49 +0200 Subject: [PATCH 213/307] started unix udp bridge --- osal/linux/TmTcUnixUdpBridge.cpp | 37 ++++++++++++++++++++++++++++++++ osal/linux/TmTcUnixUdpBridge.h | 28 ++++++++++++++++++++++++ tmtcservices/TmTcBridge.cpp | 6 +++--- tmtcservices/TmTcBridge.h | 2 +- 4 files changed, 69 insertions(+), 4 deletions(-) create mode 100644 osal/linux/TmTcUnixUdpBridge.cpp create mode 100644 osal/linux/TmTcUnixUdpBridge.h diff --git a/osal/linux/TmTcUnixUdpBridge.cpp b/osal/linux/TmTcUnixUdpBridge.cpp new file mode 100644 index 00000000..02c17312 --- /dev/null +++ b/osal/linux/TmTcUnixUdpBridge.cpp @@ -0,0 +1,37 @@ +#include +#include + +TmTcUnixUdpBridge::TmTcUnixUdpBridge(object_id_t objectId, + object_id_t ccsdsPacketDistributor): + TmTcBridge(objectId, ccsdsPacketDistributor) { + serverSocket = socket(AF_INET, SOCK_DGRAM, 0); + if(socket < 0) { + sif::error << "TmTcUnixUdpBridge::TmTcUnixUdpBridge: Could not open" + " UDP socket!" << std::endl; + // check errno here. + return; + } + + serverAddress.sin_family = AF_INET; + serverAddress.sin_addr.s_addr = htonl(INADDR_ANY); + serverAddress.sin_port = htons(UDP_SERVER_PORT); + setsockopt(serverSocket, SOL_SOCKET, SO_REUSEADDR, &serverSocketOptions, + sizeof(serverSocketOptions)); + + int result = bind(serverSocket, + reinterpret_cast(&serverAddress), + sizeof(serverAddress)); + if(result== -1) { + sif::error << "TmTcUnixUdpBridge::TmTcUnixUdpBridge: Could not bind " + "local port " << UDP_SERVER_PORT << " to server socket!" + << std::endl; + // check errno here. + return; + } + + + +} + +TmTcUnixUdpBridge::~TmTcUnixUdpBridge() { +} diff --git a/osal/linux/TmTcUnixUdpBridge.h b/osal/linux/TmTcUnixUdpBridge.h new file mode 100644 index 00000000..b84d9fe1 --- /dev/null +++ b/osal/linux/TmTcUnixUdpBridge.h @@ -0,0 +1,28 @@ +#ifndef FRAMEWORK_OSAL_LINUX_TMTCUNIXUDPBRIDGE_H_ +#define FRAMEWORK_OSAL_LINUX_TMTCUNIXUDPBRIDGE_H_ + +#include +#include +#include +#include + +class TmTcUnixUdpBridge: public TmTcBridge { +public: + static constexpr int UDP_SERVER_PORT = 7; + static constexpr int UDP_CLIENT_PORT = 2008; + + TmTcUnixUdpBridge(object_id_t objectId, object_id_t ccsdsPacketDistributor); + virtual~ TmTcUnixUdpBridge(); + +protected: + +private: + int serverSocket = 0; + const int serverSocketOptions = 0; + struct sockaddr_in clientAddress; + struct sockaddr_in serverAddress; +}; + + + +#endif /* FRAMEWORK_OSAL_LINUX_TMTCUNIXUDPBRIDGE_H_ */ diff --git a/tmtcservices/TmTcBridge.cpp b/tmtcservices/TmTcBridge.cpp index f9a7d3bc..092884bb 100644 --- a/tmtcservices/TmTcBridge.cpp +++ b/tmtcservices/TmTcBridge.cpp @@ -5,9 +5,9 @@ #include #include -TmTcBridge::TmTcBridge(object_id_t objectId_, - object_id_t ccsdsPacketDistributor_): SystemObject(objectId_), - ccsdsPacketDistributor(ccsdsPacketDistributor_) +TmTcBridge::TmTcBridge(object_id_t objectId, + object_id_t ccsdsPacketDistributor): SystemObject(objectId), + ccsdsPacketDistributor(ccsdsPacketDistributor) { TmTcReceptionQueue = QueueFactory::instance()-> createMessageQueue(TMTC_RECEPTION_QUEUE_DEPTH); diff --git a/tmtcservices/TmTcBridge.h b/tmtcservices/TmTcBridge.h index 3e0432d8..b50e9e1b 100644 --- a/tmtcservices/TmTcBridge.h +++ b/tmtcservices/TmTcBridge.h @@ -22,7 +22,7 @@ public: static constexpr uint8_t DEFAULT_STORED_DATA_SENT_PER_CYCLE = 5; static constexpr uint8_t DEFAULT_DOWNLINK_PACKETS_STORED = 10; - TmTcBridge(object_id_t objectId_, object_id_t ccsdsPacketDistributor_); + TmTcBridge(object_id_t objectId, object_id_t ccsdsPacketDistributor); virtual ~TmTcBridge(); /** From e0a3257f8b945da09aba28e784ebc2756e72f984 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 4 Jul 2020 23:20:29 +0200 Subject: [PATCH 214/307] even better output for unset max msg size --- osal/linux/MessageQueue.cpp | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/osal/linux/MessageQueue.cpp b/osal/linux/MessageQueue.cpp index b11b9b6f..3d5d7a5a 100644 --- a/osal/linux/MessageQueue.cpp +++ b/osal/linux/MessageQueue.cpp @@ -62,22 +62,27 @@ ReturnValue_t MessageQueue::handleError(mq_attr* attributes, // Just an additional helpful printout :-) if(std::ifstream("/proc/sys/fs/mqueue/msg_max",std::ios::in) >> defaultMqMaxMsg and defaultMqMaxMsg < messageDepth) { - // See: https://www.man7.org/linux/man-pages/man3/mq_open.3.html - // This happens if the msg_max value is not large enough - // It is ignored if the executable is run in privileged mode. - // Run the unlockRealtime script or grant the mode manually by using: - // sudo setcap 'CAP_SYS_RESOURCE=+ep' + /* + See: https://www.man7.org/linux/man-pages/man3/mq_open.3.html + This happens if the msg_max value is not large enough + It is ignored if the executable is run in privileged mode. + Run the unlockRealtime script or grant the mode manually by using: + sudo setcap 'CAP_SYS_RESOURCE=+ep' - // Persistent solution for session: - // echo | sudo tee /proc/sys/fs/mqueue/msg_max + Persistent solution for session: + echo | sudo tee /proc/sys/fs/mqueue/msg_max - // Permanent solution: - // sudo nano /etc/sysctl.conf - // Append at end: fs/mqueue/msg_max = - // Apply changes with: sudo sysctl -p + Permanent solution: + sudo nano /etc/sysctl.conf + Append at end: fs/mqueue/msg_max = + Apply changes with: sudo sysctl -p + */ sif::error << "MessageQueue::MessageQueue: Default MQ size " << defaultMqMaxMsg << " is too small for requested size " << messageDepth << std::endl; + sif::error << "This error can be fixed by setting the maximum " + "allowed message size higher!" << std::endl; + } break; } From 571da391087a8c03220989ed61b1333543aef4ee Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 4 Jul 2020 23:52:44 +0200 Subject: [PATCH 215/307] continued new bridge --- osal/linux/TmTcUnixUdpBridge.cpp | 29 ++++++++++++++++++++++++++--- osal/linux/TmTcUnixUdpBridge.h | 12 ++++++++---- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/osal/linux/TmTcUnixUdpBridge.cpp b/osal/linux/TmTcUnixUdpBridge.cpp index 02c17312..c2c0c353 100644 --- a/osal/linux/TmTcUnixUdpBridge.cpp +++ b/osal/linux/TmTcUnixUdpBridge.cpp @@ -2,8 +2,19 @@ #include TmTcUnixUdpBridge::TmTcUnixUdpBridge(object_id_t objectId, - object_id_t ccsdsPacketDistributor): + object_id_t ccsdsPacketDistributor, uint16_t serverPort, + uint16_t clientPort): TmTcBridge(objectId, ccsdsPacketDistributor) { + uint16_t setServerPort = DEFAULT_UDP_SERVER_PORT; + if(serverPort != 0xFFFF) { + setServerPort = serverPort; + } + + uint16_t setClientPort = DEFAULT_UDP_CLIENT_PORT; + if(clientPort != 0xFFFF) { + setClientPort = clientPort; + } + serverSocket = socket(AF_INET, SOCK_DGRAM, 0); if(socket < 0) { sif::error << "TmTcUnixUdpBridge::TmTcUnixUdpBridge: Could not open" @@ -14,7 +25,7 @@ TmTcUnixUdpBridge::TmTcUnixUdpBridge(object_id_t objectId, serverAddress.sin_family = AF_INET; serverAddress.sin_addr.s_addr = htonl(INADDR_ANY); - serverAddress.sin_port = htons(UDP_SERVER_PORT); + serverAddress.sin_port = htons(setServerPort); setsockopt(serverSocket, SOL_SOCKET, SO_REUSEADDR, &serverSocketOptions, sizeof(serverSocketOptions)); @@ -23,7 +34,7 @@ TmTcUnixUdpBridge::TmTcUnixUdpBridge(object_id_t objectId, sizeof(serverAddress)); if(result== -1) { sif::error << "TmTcUnixUdpBridge::TmTcUnixUdpBridge: Could not bind " - "local port " << UDP_SERVER_PORT << " to server socket!" + "local port " << setServerPort << " to server socket!" << std::endl; // check errno here. return; @@ -35,3 +46,15 @@ TmTcUnixUdpBridge::TmTcUnixUdpBridge(object_id_t objectId, TmTcUnixUdpBridge::~TmTcUnixUdpBridge() { } + +ReturnValue_t TmTcUnixUdpBridge::handleTc() { + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t TmTcUnixUdpBridge::receiveTc(uint8_t **recvBuffer, size_t *size) { + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t TmTcUnixUdpBridge::sendTm(const uint8_t *data, size_t dataLen) { + return HasReturnvaluesIF::RETURN_OK; +} diff --git a/osal/linux/TmTcUnixUdpBridge.h b/osal/linux/TmTcUnixUdpBridge.h index b84d9fe1..ab2e2d67 100644 --- a/osal/linux/TmTcUnixUdpBridge.h +++ b/osal/linux/TmTcUnixUdpBridge.h @@ -8,14 +8,18 @@ class TmTcUnixUdpBridge: public TmTcBridge { public: - static constexpr int UDP_SERVER_PORT = 7; - static constexpr int UDP_CLIENT_PORT = 2008; + static constexpr int DEFAULT_UDP_SERVER_PORT = 7; + static constexpr int DEFAULT_UDP_CLIENT_PORT = 2008; - TmTcUnixUdpBridge(object_id_t objectId, object_id_t ccsdsPacketDistributor); + TmTcUnixUdpBridge(object_id_t objectId, object_id_t ccsdsPacketDistributor, + uint16_t serverPort = 0xFFFF,uint16_t clientPort = 0xFFFF); virtual~ TmTcUnixUdpBridge(); protected: - + virtual ReturnValue_t handleTc() override; + virtual ReturnValue_t receiveTc(uint8_t ** recvBuffer, + size_t * size) override; + virtual ReturnValue_t sendTm(const uint8_t * data, size_t dataLen) override; private: int serverSocket = 0; const int serverSocketOptions = 0; From 5cee12684142153d01f31627b0bd9b17bcee31d2 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 5 Jul 2020 00:06:30 +0200 Subject: [PATCH 216/307] formatting --- osal/linux/TmTcUnixUdpBridge.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osal/linux/TmTcUnixUdpBridge.cpp b/osal/linux/TmTcUnixUdpBridge.cpp index c2c0c353..045e475a 100644 --- a/osal/linux/TmTcUnixUdpBridge.cpp +++ b/osal/linux/TmTcUnixUdpBridge.cpp @@ -32,7 +32,7 @@ TmTcUnixUdpBridge::TmTcUnixUdpBridge(object_id_t objectId, int result = bind(serverSocket, reinterpret_cast(&serverAddress), sizeof(serverAddress)); - if(result== -1) { + if(result == -1) { sif::error << "TmTcUnixUdpBridge::TmTcUnixUdpBridge: Could not bind " "local port " << setServerPort << " to server socket!" << std::endl; From c160000027bbe6311fd9c0d318c62a51179129ac Mon Sep 17 00:00:00 2001 From: Ulrich Mohr Date: Fri, 3 Jul 2020 12:44:08 +0200 Subject: [PATCH 217/307] Corrected filename of EndianConverter.h --- memory/MemoryHelper.cpp | 2 +- serialize/{EndianSwapper.h => EndianConverter.h} | 0 serialize/SerializeAdapter.h | 3 +-- 3 files changed, 2 insertions(+), 3 deletions(-) rename serialize/{EndianSwapper.h => EndianConverter.h} (100%) diff --git a/memory/MemoryHelper.cpp b/memory/MemoryHelper.cpp index 7c8f7610..b07f450c 100644 --- a/memory/MemoryHelper.cpp +++ b/memory/MemoryHelper.cpp @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include MemoryHelper::MemoryHelper(HasMemoryIF* workOnThis, diff --git a/serialize/EndianSwapper.h b/serialize/EndianConverter.h similarity index 100% rename from serialize/EndianSwapper.h rename to serialize/EndianConverter.h diff --git a/serialize/SerializeAdapter.h b/serialize/SerializeAdapter.h index 2be39d5c..bb364eae 100644 --- a/serialize/SerializeAdapter.h +++ b/serialize/SerializeAdapter.h @@ -2,8 +2,7 @@ #define SERIALIZEADAPTER_H_ #include -#include -#include +#include #include #include From 24240b6c7d73d124af1caae18ead919ccde203c8 Mon Sep 17 00:00:00 2001 From: Ulrich Mohr Date: Fri, 3 Jul 2020 15:46:00 +0200 Subject: [PATCH 218/307] Documented EndianConverter and changed length to size_t --- serialize/EndianConverter.h | 59 ++++++++++++++++++++++++++++++------- 1 file changed, 48 insertions(+), 11 deletions(-) diff --git a/serialize/EndianConverter.h b/serialize/EndianConverter.h index 4ab28ecf..81117a5e 100644 --- a/serialize/EndianConverter.h +++ b/serialize/EndianConverter.h @@ -5,15 +5,41 @@ #include #include +/** + * Helper class to convert variables or bitstreams between machine + * endian and either big or little endian. + * Machine endian is the endianness used by the machine running the + * program and is one of big or little endian. As this is portable + * code, it is not known at coding time which it is. At compile time + * it is however, which is why this is implemented using compiler + * macros and translates to a copy operation at runtime. + * + * This changes the layout of multi-byte variables in the machine's + * memory. In most cases, you should not need to use this class. + * Probably what you are looking for is the SerializeAdapter. + * If you still decide you need this class, please read and understand + * the code first. + * + * The order of the individual bytes of the multi-byte variable is + * reversed, the byte at the highest address is moved to the lowest + * address and vice versa, same for the bytes in between. + * + * Note that the conversion is also its inversion, that is converting + * from machine to a specified endianness is the same operation as + * converting from specified to machine (I looked it up, mathematicians + * would call it an involution): + * + * X == convertBigEndian(convertBigEndian(X)) + * + * Thus, there is only one function supplied to do the conversion. + */ class EndianConverter { private: EndianConverter() {}; public: /** - * Swap the endianness of a variable with arbitrary type - * @tparam T Type of variable - * @param in variable - * @return Variable with swapped endianness + * Convert a typed variable between big endian and machine endian. + * Intended for plain old datatypes. */ template static T convertBigEndian(T in) { @@ -23,7 +49,7 @@ public: T tmp; uint8_t *pointerOut = (uint8_t*) &tmp; uint8_t *pointerIn = (uint8_t*) ∈ - for (uint8_t count = 0; count < sizeof(T); count++) { + for (size_t count = 0; count < sizeof(T); count++) { pointerOut[sizeof(T) - count - 1] = pointerIn[count]; } return tmp; @@ -34,12 +60,16 @@ public: #endif } + /** + * convert a bytestream representing a single variable between big endian + * and machine endian. + */ static void convertBigEndian(uint8_t *out, const uint8_t *in, - uint32_t size) { + size_t size) { #ifndef BYTE_ORDER_SYSTEM #error BYTE_ORDER_SYSTEM not defined #elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN - for (uint8_t count = 0; count < size; count++) { + for (size_t count = 0; count < size; count++) { out[size - count - 1] = in[count]; } return; @@ -49,7 +79,10 @@ public: #endif } - + /** + * Convert a typed variable between little endian and machine endian. + * Intended for plain old datatypes. + */ template static T convertLittleEndian(T in) { #ifndef BYTE_ORDER_SYSTEM @@ -58,7 +91,7 @@ public: T tmp; uint8_t *pointerOut = (uint8_t *) &tmp; uint8_t *pointerIn = (uint8_t *) ∈ - for (uint8_t count = 0; count < sizeof(T); count++) { + for (size_t count = 0; count < sizeof(T); count++) { pointerOut[sizeof(T) - count - 1] = pointerIn[count]; } return tmp; @@ -68,12 +101,16 @@ public: #error Unknown Byte Order #endif } + /** + * convert a bytestream representing a single variable between little endian + * and machine endian. + */ static void convertLittleEndian(uint8_t *out, const uint8_t *in, - uint32_t size) { + size_t size) { #ifndef BYTE_ORDER_SYSTEM #error BYTE_ORDER_SYSTEM not defined #elif BYTE_ORDER_SYSTEM == BIG_ENDIAN - for (uint8_t count = 0; count < size; count++) { + for (size_t count = 0; count < size; count++) { out[size - count - 1] = in[count]; } return; From 1a177d2efa05f62c86fe33352cf3608d1b96340b Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 5 Jul 2020 00:28:06 +0200 Subject: [PATCH 219/307] integrated pool raw access serialize changes --- datapoolglob/PoolRawAccess.cpp | 84 +++++++++++++--------------------- datapoolglob/PoolRawAccess.h | 6 +-- 2 files changed, 34 insertions(+), 56 deletions(-) diff --git a/datapoolglob/PoolRawAccess.cpp b/datapoolglob/PoolRawAccess.cpp index bec54ab3..cd4138d3 100644 --- a/datapoolglob/PoolRawAccess.cpp +++ b/datapoolglob/PoolRawAccess.cpp @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include @@ -130,15 +130,7 @@ ReturnValue_t PoolRawAccess::getEntryEndianSafe(uint8_t* buffer, return DATA_POOL_ACCESS_FAILED; if (typeSize > max_size) return INCORRECT_SIZE; -#ifndef BYTE_ORDER_SYSTEM -#error BYTE_ORDER_SYSTEM not defined -#elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN - for (uint8_t count = 0; count < typeSize; count++) { - buffer[count] = data_ptr[typeSize - count - 1]; - } -#elif BYTE_ORDER_SYSTEM == BIG_ENDIAN - memcpy(buffer, data_ptr, typeSize); -#endif + EndianConverter::convertBigEndian(buffer, data_ptr, typeSize); *writtenBytes = typeSize; return HasReturnvaluesIF::RETURN_OK; } @@ -146,21 +138,18 @@ ReturnValue_t PoolRawAccess::getEntryEndianSafe(uint8_t* buffer, ReturnValue_t PoolRawAccess::serialize(uint8_t** buffer, size_t* size, size_t maxSize, Endianness streamEndianness) const { - //TODO integer overflow if (typeSize + *size <= maxSize) { -#warning use endian swapper - if (1) { -#ifndef BYTE_ORDER_SYSTEM -#error BYTE_ORDER_SYSTEM not defined -#elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN - for (uint8_t count = 0; count < typeSize; count++) { - (*buffer)[count] = value[typeSize - count - 1]; - } -#elif BYTE_ORDER_SYSTEM == BIG_ENDIAN - memcpy(*buffer, value, typeSize); -#endif - } else { + switch(streamEndianness) { + case(Endianness::BIG): + EndianConverter::convertBigEndian(*buffer, value, typeSize); + break; + case(Endianness::LITTLE): + EndianConverter::convertLittleEndian(*buffer, value, typeSize); + break; + case(Endianness::MACHINE): + default: memcpy(*buffer, value, typeSize); + break; } *size += typeSize; (*buffer) += typeSize; @@ -175,11 +164,11 @@ Type PoolRawAccess::getType() { return type; } -uint8_t PoolRawAccess::getSizeOfType() { +size_t PoolRawAccess::getSizeOfType() { return typeSize; } -uint8_t PoolRawAccess::getArraySize(){ +size_t PoolRawAccess::getArraySize(){ return arraySize; } @@ -191,22 +180,14 @@ PoolVariableIF::ReadWriteMode_t PoolRawAccess::getReadWriteMode() const { return readWriteMode; } -ReturnValue_t PoolRawAccess::setEntryFromBigEndian(const uint8_t* buffer, - uint32_t setSize) { +ReturnValue_t PoolRawAccess::setEntryFromBigEndian(const uint8_t *buffer, + size_t setSize) { if (typeSize == setSize) { -#ifndef BYTE_ORDER_SYSTEM -#error BYTE_ORDER_SYSTEM not defined -#elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN - for (uint8_t count = 0; count < typeSize; count++) { - value[count] = buffer[typeSize - count - 1]; - } -#elif BYTE_ORDER_SYSTEM == BIG_ENDIAN - memcpy(value, buffer, typeSize); -#endif + EndianConverter::convertBigEndian(value, buffer, typeSize); return HasReturnvaluesIF::RETURN_OK; } else { - sif::error << "PoolRawAccess::setEntryFromBigEndian: Illegal sizes: Internal" - << (uint32_t) typeSize << ", Requested: " << setSize + sif::error << "PoolRawAccess::setEntryFromBigEndian: Illegal sizes: " + "Internal" << (uint32_t) typeSize << ", Requested: " << setSize << std::endl; return INCORRECT_SIZE; } @@ -232,27 +213,24 @@ size_t PoolRawAccess::getSerializedSize() const { return typeSize; } -ReturnValue_t PoolRawAccess::deSerialize(const uint8_t** buffer, size_t* size, +ReturnValue_t PoolRawAccess::deSerialize(const uint8_t **buffer, size_t *size, Endianness streamEndianness) { if (*size >= typeSize) { - *size -= typeSize; - if (1) { -#ifndef BYTE_ORDER_SYSTEM -#error BYTE_ORDER_SYSTEM not defined -#elif BYTE_ORDER_SYSTEM == LITTLE_ENDIAN - for (uint8_t count = 0; count < typeSize; count++) { - value[count] = (*buffer)[typeSize - count - 1]; - } -#elif BYTE_ORDER_SYSTEM == BIG_ENDIAN - memcpy(value, *buffer, typeSize); -#endif - } else { + switch(streamEndianness) { + case(Endianness::BIG): + EndianConverter::convertBigEndian(value, *buffer, typeSize); + break; + case(Endianness::LITTLE): + EndianConverter::convertLittleEndian(value, *buffer, typeSize); + break; + case(Endianness::MACHINE): + default: memcpy(value, *buffer, typeSize); + break; } + *size -= typeSize; *buffer += typeSize; return HasReturnvaluesIF::RETURN_OK; - } else { - return SerializeIF::STREAM_TOO_SHORT; } } diff --git a/datapoolglob/PoolRawAccess.h b/datapoolglob/PoolRawAccess.h index ea07356e..2ef1d653 100644 --- a/datapoolglob/PoolRawAccess.h +++ b/datapoolglob/PoolRawAccess.h @@ -85,7 +85,7 @@ public: * - @c RETURN_FAILED on failure */ ReturnValue_t setEntryFromBigEndian(const uint8_t* buffer, - uint32_t setSize); + size_t setSize); /** * @brief This operation returns the type of the entry currently stored. */ @@ -93,12 +93,12 @@ public: /** * @brief This operation returns the size of the entry currently stored. */ - uint8_t getSizeOfType(); + size_t getSizeOfType(); /** * * @return the size of the datapool array */ - uint8_t getArraySize(); + size_t getArraySize(); /** * @brief This operation returns the data pool id of the variable. */ From b86e5664c470bf1b1c9615abb8557d51d3f86eb8 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 5 Jul 2020 00:33:03 +0200 Subject: [PATCH 220/307] include which was missing, pool raw access size_t replacements --- datapoolglob/PoolRawAccess.cpp | 5 ++++- datapoolglob/PoolRawAccess.h | 8 ++++---- serialize/SerializeAdapter.h | 1 + 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/datapoolglob/PoolRawAccess.cpp b/datapoolglob/PoolRawAccess.cpp index cd4138d3..4355cd0f 100644 --- a/datapoolglob/PoolRawAccess.cpp +++ b/datapoolglob/PoolRawAccess.cpp @@ -204,7 +204,7 @@ void PoolRawAccess::setValid(bool valid) { this->valid = valid; } -uint16_t PoolRawAccess::getSizeTillEnd() const { +size_t PoolRawAccess::getSizeTillEnd() const { return sizeTillEnd; } @@ -233,4 +233,7 @@ ReturnValue_t PoolRawAccess::deSerialize(const uint8_t **buffer, size_t *size, *buffer += typeSize; return HasReturnvaluesIF::RETURN_OK; } + else { + return SerializeIF::STREAM_TOO_SHORT; + } } diff --git a/datapoolglob/PoolRawAccess.h b/datapoolglob/PoolRawAccess.h index 2ef1d653..f58efdd0 100644 --- a/datapoolglob/PoolRawAccess.h +++ b/datapoolglob/PoolRawAccess.h @@ -133,7 +133,7 @@ public: /** * Getter for the remaining size. */ - uint16_t getSizeTillEnd() const; + size_t getSizeTillEnd() const; /** * @brief This is a call to read the value from the global data pool. @@ -202,15 +202,15 @@ private: /** * @brief This value contains the size of the data pool entry type in bytes. */ - uint8_t typeSize; + size_t typeSize; /** * The size of the DP array (single values return 1) */ - uint8_t arraySize; + size_t arraySize; /** * The size (in bytes) from the selected entry till the end of this DataPool variable. */ - uint16_t sizeTillEnd; + size_t sizeTillEnd; /** * @brief The information whether the class is read-write or read-only is stored here. */ diff --git a/serialize/SerializeAdapter.h b/serialize/SerializeAdapter.h index bb364eae..4534ffb8 100644 --- a/serialize/SerializeAdapter.h +++ b/serialize/SerializeAdapter.h @@ -1,6 +1,7 @@ #ifndef SERIALIZEADAPTER_H_ #define SERIALIZEADAPTER_H_ +#include #include #include #include From 9dcf0c711854aff22789f0bdcb5375bde51e74bd Mon Sep 17 00:00:00 2001 From: Ulrich Mohr Date: Fri, 3 Jul 2020 15:50:29 +0200 Subject: [PATCH 221/307] size_t for DataPoolAdmin --- datapoolglob/DataPoolAdmin.cpp | 8 ++++---- datapoolglob/DataPoolAdmin.h | 6 +++--- datapoolglob/PoolRawAccess.cpp | 2 +- datapoolglob/PoolRawAccess.h | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/datapoolglob/DataPoolAdmin.cpp b/datapoolglob/DataPoolAdmin.cpp index edbac6eb..4d0e5530 100644 --- a/datapoolglob/DataPoolAdmin.cpp +++ b/datapoolglob/DataPoolAdmin.cpp @@ -26,7 +26,7 @@ MessageQueueId_t DataPoolAdmin::getCommandQueue() const { } ReturnValue_t DataPoolAdmin::executeAction(ActionId_t actionId, - MessageQueueId_t commandedBy, const uint8_t* data, uint32_t size) { + MessageQueueId_t commandedBy, const uint8_t* data, size_t size) { if (actionId != SET_VALIDITY) { return INVALID_ACTION_ID; } @@ -91,7 +91,7 @@ void DataPoolAdmin::handleCommand() { } ReturnValue_t DataPoolAdmin::handleMemoryLoad(uint32_t address, - const uint8_t* data, uint32_t size, uint8_t** dataPointer) { + const uint8_t* data, size_t size, uint8_t** dataPointer) { uint32_t poolId = glob::dataPool.PIDToDataPoolId(address); uint8_t arrayIndex = glob::dataPool.PIDToArrayIndex(address); GlobDataSet testSet; @@ -129,7 +129,7 @@ ReturnValue_t DataPoolAdmin::handleMemoryLoad(uint32_t address, return ACTIVITY_COMPLETED; } -ReturnValue_t DataPoolAdmin::handleMemoryDump(uint32_t address, uint32_t size, +ReturnValue_t DataPoolAdmin::handleMemoryDump(uint32_t address, size_t size, uint8_t** dataPointer, uint8_t* copyHere) { uint32_t poolId = glob::dataPool.PIDToDataPoolId(address); uint8_t arrayIndex = glob::dataPool.PIDToArrayIndex(address); @@ -151,7 +151,7 @@ ReturnValue_t DataPoolAdmin::handleMemoryDump(uint32_t address, uint32_t size, PoolVariableIF::VAR_READ); status = rawSet.read(); if (status == RETURN_OK) { - uint32_t temp = 0; + size_t temp = 0; status = variable.getEntryEndianSafe(ptrToCopy, &temp, size); if (status != RETURN_OK) { return RETURN_FAILED; diff --git a/datapoolglob/DataPoolAdmin.h b/datapoolglob/DataPoolAdmin.h index 5f995893..653fdd8e 100644 --- a/datapoolglob/DataPoolAdmin.h +++ b/datapoolglob/DataPoolAdmin.h @@ -30,12 +30,12 @@ public: MessageQueueId_t getCommandQueue() const; ReturnValue_t handleMemoryLoad(uint32_t address, const uint8_t* data, - uint32_t size, uint8_t** dataPointer); - ReturnValue_t handleMemoryDump(uint32_t address, uint32_t size, + size_t size, uint8_t** dataPointer); + ReturnValue_t handleMemoryDump(uint32_t address, size_t size, uint8_t** dataPointer, uint8_t* copyHere); ReturnValue_t executeAction(ActionId_t actionId, - MessageQueueId_t commandedBy, const uint8_t* data, uint32_t size); + MessageQueueId_t commandedBy, const uint8_t* data, size_t size); //not implemented as ParameterHelper is no used ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId, diff --git a/datapoolglob/PoolRawAccess.cpp b/datapoolglob/PoolRawAccess.cpp index 4355cd0f..783418cc 100644 --- a/datapoolglob/PoolRawAccess.cpp +++ b/datapoolglob/PoolRawAccess.cpp @@ -121,7 +121,7 @@ uint8_t* PoolRawAccess::getEntry() { } ReturnValue_t PoolRawAccess::getEntryEndianSafe(uint8_t* buffer, - uint32_t* writtenBytes, uint32_t max_size) { + size_t* writtenBytes, size_t max_size) { uint8_t* data_ptr = getEntry(); // debug << "PoolRawAccess::getEntry: Array position: " << // index * size_of_type << " Size of T: " << (int)size_of_type << diff --git a/datapoolglob/PoolRawAccess.h b/datapoolglob/PoolRawAccess.h index f58efdd0..22dc312d 100644 --- a/datapoolglob/PoolRawAccess.h +++ b/datapoolglob/PoolRawAccess.h @@ -57,8 +57,8 @@ public: * @return - @c RETURN_OK if entry could be acquired * - @c RETURN_FAILED else. */ - ReturnValue_t getEntryEndianSafe(uint8_t* buffer, uint32_t* size, - uint32_t max_size); + ReturnValue_t getEntryEndianSafe(uint8_t *buffer, size_t *size, + size_t maxSize); /** * @brief Serialize raw pool entry into provided buffer directly From fcf3f04377910154f4a8302481b5f0cbec5273fe Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 5 Jul 2020 01:25:49 +0200 Subject: [PATCH 222/307] diag output for inits improved --- devicehandlers/DeviceHandlerBase.cpp | 8 ++++++-- fdir/FailureIsolationBase.cpp | 6 ++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index 867bf415..fcb61ace 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -128,8 +128,12 @@ ReturnValue_t DeviceHandlerBase::initialize() { AcceptsDeviceResponsesIF *rawReceiver = objectManager->get< AcceptsDeviceResponsesIF>(rawDataReceiverId); - if (rawReceiver == NULL) { - return RETURN_FAILED; + if (rawReceiver == nullptr) { + sif::error << "DeviceHandlerBase::initialize: Raw receiver object " + "ID set but no valid object found." << std::endl; + sif::error << "Make sure the raw receiver object is set up properly" + " and implements AcceptsDeviceResponsesIF" << std::endl; + return ObjectManagerIF::CHILD_INIT_FAILED; } defaultRawReceiver = rawReceiver->getDeviceQueue(); } diff --git a/fdir/FailureIsolationBase.cpp b/fdir/FailureIsolationBase.cpp index 018fbe6a..a2fc9ea1 100644 --- a/fdir/FailureIsolationBase.cpp +++ b/fdir/FailureIsolationBase.cpp @@ -35,8 +35,10 @@ ReturnValue_t FailureIsolationBase::initialize() { return result; } owner = objectManager->get(ownerId); - if (owner == NULL) { - return RETURN_FAILED; + if (owner == nullptr) { + sif::error << "FailureIsolationBase::intialize: Owner object " + "invalid. Make sure it implements HasHealthIF" << std::endl; + return ObjectManagerIF::CHILD_INIT_FAILED; } } if (faultTreeParent != 0) { From 9e2fa165506192b18ca2ea4fa2540c7918c9e480 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 5 Jul 2020 15:31:02 +0200 Subject: [PATCH 223/307] mq stack error improved --- osal/linux/MessageQueue.cpp | 2 +- osal/linux/PosixThread.cpp | 6 ++++-- osal/linux/TmTcUnixUdpBridge.cpp | 21 ++++++++++++++++++--- osal/linux/TmTcUnixUdpBridge.h | 2 ++ 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/osal/linux/MessageQueue.cpp b/osal/linux/MessageQueue.cpp index 3d5d7a5a..ce1da17c 100644 --- a/osal/linux/MessageQueue.cpp +++ b/osal/linux/MessageQueue.cpp @@ -47,7 +47,7 @@ MessageQueue::~MessageQueue() { status = mq_unlink(name); if(status != 0){ sif::error << "MessageQueue::Destructor: mq_unlink Failed with status: " - << strerror(errno) < #include +#include TmTcUnixUdpBridge::TmTcUnixUdpBridge(object_id_t objectId, object_id_t ccsdsPacketDistributor, uint16_t serverPort, @@ -20,6 +21,7 @@ TmTcUnixUdpBridge::TmTcUnixUdpBridge(object_id_t objectId, sif::error << "TmTcUnixUdpBridge::TmTcUnixUdpBridge: Could not open" " UDP socket!" << std::endl; // check errno here. + handleSocketError(); return; } @@ -39,9 +41,6 @@ TmTcUnixUdpBridge::TmTcUnixUdpBridge(object_id_t objectId, // check errno here. return; } - - - } TmTcUnixUdpBridge::~TmTcUnixUdpBridge() { @@ -58,3 +57,19 @@ ReturnValue_t TmTcUnixUdpBridge::receiveTc(uint8_t **recvBuffer, size_t *size) { ReturnValue_t TmTcUnixUdpBridge::sendTm(const uint8_t *data, size_t dataLen) { return HasReturnvaluesIF::RETURN_OK; } + +void TmTcUnixUdpBridge::handleSocketError() { + // See: https://man7.org/linux/man-pages/man2/socket.2.html + switch(errno) { + case(EACCES): + case(EINVAL): + case(EMFILE): + case(ENFILE): + case(EAFNOSUPPORT): + case(ENOBUFS): + case(ENOMEM): + case(EPROTONOSUPPORT): + sif::error << "TmTcUnixBridge::TmTcUnixBridge: Socket creation failed" + << " with " << strerror(errno) << std::endl; + } +} diff --git a/osal/linux/TmTcUnixUdpBridge.h b/osal/linux/TmTcUnixUdpBridge.h index ab2e2d67..ccab1b1f 100644 --- a/osal/linux/TmTcUnixUdpBridge.h +++ b/osal/linux/TmTcUnixUdpBridge.h @@ -25,6 +25,8 @@ private: const int serverSocketOptions = 0; struct sockaddr_in clientAddress; struct sockaddr_in serverAddress; + + void handleSocketError(); }; From 26ab1983dcad5ae88addd3aa9b947db9ee6edfc6 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 5 Jul 2020 18:22:39 +0200 Subject: [PATCH 224/307] new ports --- osal/linux/TmTcUnixUdpBridge.cpp | 43 ++++++++++++++++++++++++++++++++ osal/linux/TmTcUnixUdpBridge.h | 7 ++++-- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/osal/linux/TmTcUnixUdpBridge.cpp b/osal/linux/TmTcUnixUdpBridge.cpp index 3beef3d4..60f4214e 100644 --- a/osal/linux/TmTcUnixUdpBridge.cpp +++ b/osal/linux/TmTcUnixUdpBridge.cpp @@ -39,6 +39,7 @@ TmTcUnixUdpBridge::TmTcUnixUdpBridge(object_id_t objectId, "local port " << setServerPort << " to server socket!" << std::endl; // check errno here. + handleBindError(); return; } } @@ -59,6 +60,7 @@ ReturnValue_t TmTcUnixUdpBridge::sendTm(const uint8_t *data, size_t dataLen) { } void TmTcUnixUdpBridge::handleSocketError() { + // See: https://man7.org/linux/man-pages/man2/socket.2.html switch(errno) { case(EACCES): @@ -71,5 +73,46 @@ void TmTcUnixUdpBridge::handleSocketError() { case(EPROTONOSUPPORT): sif::error << "TmTcUnixBridge::TmTcUnixBridge: Socket creation failed" << " with " << strerror(errno) << std::endl; + break; + default: + sif::error << "TmTcUnixBridge::TmTcUnixBridge: Unknown error" + << std::endl; + break; } } + +void TmTcUnixUdpBridge::handleBindError() { + // See: https://man7.org/linux/man-pages/man2/bind.2.html + switch(errno) { + case(EACCES): + /* + Ephermeral ports can be shown with following command: + sysctl -A | grep ip_local_port_range + */ + sif::error << "TmTcUnixBridge::TmTcUnixBridge: Port access issue." + "Ports 1-1024 are reserved on UNIX systems and require root " + "rights while ephermeral ports should not be used as well." + << std::endl; + break; + case(EADDRINUSE): + case(EBADF): + case(EINVAL): + case(ENOTSOCK): + case(EADDRNOTAVAIL): + case(EFAULT): + case(ELOOP): + case(ENAMETOOLONG): + case(ENOENT): + case(ENOMEM): + case(ENOTDIR): + case(EROFS): + sif::error << "TmTcUnixBridge::TmTcUnixBridge: Socket creation failed" + << " with " << strerror(errno) << std::endl; + break; + default: + sif::error << "TmTcUnixBridge::TmTcUnixBridge: Unknown error" + << std::endl; + break; + } + +} diff --git a/osal/linux/TmTcUnixUdpBridge.h b/osal/linux/TmTcUnixUdpBridge.h index ccab1b1f..7c55ea82 100644 --- a/osal/linux/TmTcUnixUdpBridge.h +++ b/osal/linux/TmTcUnixUdpBridge.h @@ -8,8 +8,10 @@ class TmTcUnixUdpBridge: public TmTcBridge { public: - static constexpr int DEFAULT_UDP_SERVER_PORT = 7; - static constexpr int DEFAULT_UDP_CLIENT_PORT = 2008; + // The ports chosen here should not be used by any other process. + // List of used ports on Linux: /etc/services + static constexpr int DEFAULT_UDP_SERVER_PORT = 7301; + static constexpr int DEFAULT_UDP_CLIENT_PORT = 7302; TmTcUnixUdpBridge(object_id_t objectId, object_id_t ccsdsPacketDistributor, uint16_t serverPort = 0xFFFF,uint16_t clientPort = 0xFFFF); @@ -27,6 +29,7 @@ private: struct sockaddr_in serverAddress; void handleSocketError(); + void handleBindError(); }; From 724fee09ff30d8c1e435870a93cd4800e6ac0c86 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 5 Jul 2020 18:58:16 +0200 Subject: [PATCH 225/307] new task for tc unix polling --- osal/linux/TcUnixUdpPollingTask.cpp | 8 ++++++++ osal/linux/TcUnixUdpPollingTask.h | 28 ++++++++++++++++++++++++++++ osal/linux/TmTcUnixUdpBridge.cpp | 23 ++++++++++++++--------- osal/linux/TmTcUnixUdpBridge.h | 1 - 4 files changed, 50 insertions(+), 10 deletions(-) create mode 100644 osal/linux/TcUnixUdpPollingTask.cpp create mode 100644 osal/linux/TcUnixUdpPollingTask.h diff --git a/osal/linux/TcUnixUdpPollingTask.cpp b/osal/linux/TcUnixUdpPollingTask.cpp new file mode 100644 index 00000000..0703904c --- /dev/null +++ b/osal/linux/TcUnixUdpPollingTask.cpp @@ -0,0 +1,8 @@ +#include + +TcSocketPollingTask::TcSocketPollingTask(object_id_t objectId, + object_id_t tmtcUnixUdpBridge): SystemObject(objectId) { +} + +TcSocketPollingTask::~TcSocketPollingTask() { +} diff --git a/osal/linux/TcUnixUdpPollingTask.h b/osal/linux/TcUnixUdpPollingTask.h new file mode 100644 index 00000000..ffed08a7 --- /dev/null +++ b/osal/linux/TcUnixUdpPollingTask.h @@ -0,0 +1,28 @@ +#ifndef FRAMEWORK_OSAL_LINUX_TCSOCKETPOLLINGTASK_H_ +#define FRAMEWORK_OSAL_LINUX_TCSOCKETPOLLINGTASK_H_ +#include +#include + +/** + * @brief This class can be used to implement the polling of a Unix socket, + * using UDP for now. + * @details + * The task will be blocked while the specified number of bytes has not been + * received, so TC reception is handled inside a separate task. + * This class caches the IP address of the sender. It is assumed there + * is only one sender for now. + */ +class TcSocketPollingTask: public SystemObject, + public ExecutableObjectIF { +public: + TcSocketPollingTask(object_id_t objectId, object_id_t tmtcUnixUdpBridge); + virtual~ TcSocketPollingTask(); + + virtual ReturnValue_t performOperation(uint8_t opCode) override; + virtual ReturnValue_t initialize() override; +private: +}; + + + +#endif /* FRAMEWORK_OSAL_LINUX_TCSOCKETPOLLINGTASK_H_ */ diff --git a/osal/linux/TmTcUnixUdpBridge.cpp b/osal/linux/TmTcUnixUdpBridge.cpp index 60f4214e..ff8b6588 100644 --- a/osal/linux/TmTcUnixUdpBridge.cpp +++ b/osal/linux/TmTcUnixUdpBridge.cpp @@ -47,15 +47,15 @@ TmTcUnixUdpBridge::TmTcUnixUdpBridge(object_id_t objectId, TmTcUnixUdpBridge::~TmTcUnixUdpBridge() { } -ReturnValue_t TmTcUnixUdpBridge::handleTc() { - return HasReturnvaluesIF::RETURN_OK; -} - -ReturnValue_t TmTcUnixUdpBridge::receiveTc(uint8_t **recvBuffer, size_t *size) { - return HasReturnvaluesIF::RETURN_OK; -} - ReturnValue_t TmTcUnixUdpBridge::sendTm(const uint8_t *data, size_t dataLen) { + int flags = 0; + ssize_t result = send(serverSocket, data, dataLen, flags); + if(result < 0) { + //handle error + sif::error << "TmTcUnixUdpBridge::sendTm: Send operation failed " + "with error " << strerror(errno) << std::endl; + } + return HasReturnvaluesIF::RETURN_OK; } @@ -114,5 +114,10 @@ void TmTcUnixUdpBridge::handleBindError() { << std::endl; break; } - +} + + +ReturnValue_t TmTcUnixUdpBridge::receiveTc(uint8_t **recvBuffer, size_t *size) { + // TC reception handled by separate polling task because it is blocking. + return HasReturnvaluesIF::RETURN_OK; } diff --git a/osal/linux/TmTcUnixUdpBridge.h b/osal/linux/TmTcUnixUdpBridge.h index 7c55ea82..a969083d 100644 --- a/osal/linux/TmTcUnixUdpBridge.h +++ b/osal/linux/TmTcUnixUdpBridge.h @@ -18,7 +18,6 @@ public: virtual~ TmTcUnixUdpBridge(); protected: - virtual ReturnValue_t handleTc() override; virtual ReturnValue_t receiveTc(uint8_t ** recvBuffer, size_t * size) override; virtual ReturnValue_t sendTm(const uint8_t * data, size_t dataLen) override; From 327b1e9d2f242c49c331533a6d8c34407bf0060f Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 5 Jul 2020 19:11:21 +0200 Subject: [PATCH 226/307] file renamed --- osal/linux/TcUnixUdpPollingTask.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osal/linux/TcUnixUdpPollingTask.cpp b/osal/linux/TcUnixUdpPollingTask.cpp index 0703904c..c470d96f 100644 --- a/osal/linux/TcUnixUdpPollingTask.cpp +++ b/osal/linux/TcUnixUdpPollingTask.cpp @@ -1,4 +1,4 @@ -#include +#include TcSocketPollingTask::TcSocketPollingTask(object_id_t objectId, object_id_t tmtcUnixUdpBridge): SystemObject(objectId) { From 2395e487aee6c5cc6701a4e0a50de2ea676e4f0c Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 5 Jul 2020 20:42:05 +0200 Subject: [PATCH 227/307] udp polling taks init --- osal/linux/TcUnixUdpPollingTask.cpp | 8 ++++++++ osal/linux/TcUnixUdpPollingTask.h | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/osal/linux/TcUnixUdpPollingTask.cpp b/osal/linux/TcUnixUdpPollingTask.cpp index c470d96f..21ad1d9a 100644 --- a/osal/linux/TcUnixUdpPollingTask.cpp +++ b/osal/linux/TcUnixUdpPollingTask.cpp @@ -6,3 +6,11 @@ TcSocketPollingTask::TcSocketPollingTask(object_id_t objectId, TcSocketPollingTask::~TcSocketPollingTask() { } + +ReturnValue_t TcSocketPollingTask::performOperation(uint8_t opCode) { + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t TcSocketPollingTask::initialize() { + return HasReturnvaluesIF::RETURN_OK; +} diff --git a/osal/linux/TcUnixUdpPollingTask.h b/osal/linux/TcUnixUdpPollingTask.h index ffed08a7..eda7fe5d 100644 --- a/osal/linux/TcUnixUdpPollingTask.h +++ b/osal/linux/TcUnixUdpPollingTask.h @@ -2,6 +2,7 @@ #define FRAMEWORK_OSAL_LINUX_TCSOCKETPOLLINGTASK_H_ #include #include +#include /** * @brief This class can be used to implement the polling of a Unix socket, @@ -14,6 +15,7 @@ */ class TcSocketPollingTask: public SystemObject, public ExecutableObjectIF { + friend class TmTcUnixUdpBridge; public: TcSocketPollingTask(object_id_t objectId, object_id_t tmtcUnixUdpBridge); virtual~ TcSocketPollingTask(); @@ -21,6 +23,8 @@ public: virtual ReturnValue_t performOperation(uint8_t opCode) override; virtual ReturnValue_t initialize() override; private: + //! Sender Address is cached here. + const struct sockaddr senderAddress; }; From ebec074655d40dd60c4553c8b94ce3018d6f7358 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 5 Jul 2020 23:53:13 +0200 Subject: [PATCH 228/307] Split up FIFO into StaticFIFO and normale FIFO --- container/FIFO.h | 88 +++++---------------------- container/FIFOBase.h | 59 ++++++++++++++++++ container/FIFOBase.tpp | 76 +++++++++++++++++++++++ container/StaticFIFO.h | 23 +++++++ globalfunctions/timevalOperations.cpp | 7 +++ globalfunctions/timevalOperations.h | 1 + osal/linux/TcUnixUdpPollingTask.cpp | 66 +++++++++++++++++++- osal/linux/TcUnixUdpPollingTask.h | 30 +++++++-- osal/linux/TmTcUnixUdpBridge.cpp | 19 +++++- osal/linux/TmTcUnixUdpBridge.h | 16 ++++- tmtcservices/CommandingServiceBase.h | 4 +- tmtcservices/TmTcBridge.h | 4 +- 12 files changed, 309 insertions(+), 84 deletions(-) create mode 100644 container/FIFOBase.h create mode 100644 container/FIFOBase.tpp create mode 100644 container/StaticFIFO.h diff --git a/container/FIFO.h b/container/FIFO.h index f70c78b0..217ddbca 100644 --- a/container/FIFO.h +++ b/container/FIFO.h @@ -1,82 +1,26 @@ -#ifndef FIFO_H_ -#define FIFO_H_ +#ifndef FRAMEWORK_CONTAINER_FIFO_H_ +#define FRAMEWORK_CONTAINER_FIFO_H_ -#include +#include +#include /** - * @brief Simple First-In-First-Out data structure + * @brief Simple First-In-First-Out data structure. The maximum size + * can be set in the constructor. THe public interface of + * FIFOBase exposes the user interface for the FIFO. * @tparam T Entry Type * @tparam capacity Maximum capacity */ -template -class FIFO { -private: - uint8_t readIndex, writeIndex, currentSize; - T data[capacity]; - - uint8_t next(uint8_t current) { - ++current; - if (current == capacity) { - current = 0; - } - return current; - } +template +class FIFO: public FIFOBase { public: - FIFO() : - readIndex(0), writeIndex(0), currentSize(0) { - } + FIFO(size_t maxCapacity): FIFOBase(values.data(), maxCapacity) { + values.reserve(maxCapacity); + values.resize(maxCapacity); + }; - bool empty() { - return (currentSize == 0); - } - - bool full() { - return (currentSize == capacity); - } - - uint8_t size(){ - return currentSize; - } - - ReturnValue_t insert(T value) { - if (full()) { - return FULL; - } else { - data[writeIndex] = value; - writeIndex = next(writeIndex); - ++currentSize; - return HasReturnvaluesIF::RETURN_OK; - } - } - - ReturnValue_t retrieve(T *value) { - if (empty()) { - return EMPTY; - } else { - *value = data[readIndex]; - readIndex = next(readIndex); - --currentSize; - return HasReturnvaluesIF::RETURN_OK; - } - } - - ReturnValue_t peek(T * value) { - if(empty()) { - return EMPTY; - } else { - *value = data[readIndex]; - return HasReturnvaluesIF::RETURN_OK; - } - } - - ReturnValue_t pop() { - T value; - return this->retrieve(&value); - } - - static const uint8_t INTERFACE_ID = CLASS_ID::FIFO_CLASS; - static const ReturnValue_t FULL = MAKE_RETURN_CODE(1); - static const ReturnValue_t EMPTY = MAKE_RETURN_CODE(2); +private: + std::vector values; }; -#endif /* FIFO_H_ */ +#endif /* FRAMEWORK_CONTAINER_FIFO_H_ */ diff --git a/container/FIFOBase.h b/container/FIFOBase.h new file mode 100644 index 00000000..c6a74d2f --- /dev/null +++ b/container/FIFOBase.h @@ -0,0 +1,59 @@ +#ifndef FRAMEWORK_CONTAINER_FIFOBASE_H_ +#define FRAMEWORK_CONTAINER_FIFOBASE_H_ + +#include +#include + +template +class FIFOBase { +public: + static const uint8_t INTERFACE_ID = CLASS_ID::FIFO_CLASS; + static const ReturnValue_t FULL = MAKE_RETURN_CODE(1); + static const ReturnValue_t EMPTY = MAKE_RETURN_CODE(2); + + + /** Default ctor, no input arguments required. */ + FIFOBase(T* values, const size_t maxCapacity); + + /** + * Insert value into FIFO + * @param value + * @return + */ + ReturnValue_t insert(T value); + /** + * Retrieve item from FIFO. This removes the item from the FIFO. + * @param value + * @return + */ + ReturnValue_t retrieve(T *value); + /** + * Retrieve item from FIFO without removing it from FIFO. + * @param value + * @return + */ + ReturnValue_t peek(T * value); + /** + * Remove item from FIFO. + * @return + */ + ReturnValue_t pop(); + + bool empty(); + bool full(); + size_t size(); + +private: + T* values; + size_t maxCapacity; + + size_t readIndex = 0; + size_t writeIndex = 0; + size_t currentSize = 0; + + size_t next(size_t current); +}; + +#include + +#endif /* FRAMEWORK_CONTAINER_FIFOBASE_H_ */ diff --git a/container/FIFOBase.tpp b/container/FIFOBase.tpp new file mode 100644 index 00000000..011ce6de --- /dev/null +++ b/container/FIFOBase.tpp @@ -0,0 +1,76 @@ +#ifndef FRAMEWORK_CONTAINER_FIFOBASE_TPP_ +#define FRAMEWORK_CONTAINER_FIFOBASE_TPP_ + +#ifndef FRAMEWORK_CONTAINER_FIFOBASE_H_ +#error Include FIFOBase.h before FIFOBase.tpp! +#endif + +template +inline FIFOBase::FIFOBase(T* values, const size_t maxCapacity): + values(values), maxCapacity(maxCapacity) {}; + +template +inline ReturnValue_t FIFOBase::insert(T value) { + if (full()) { + return FULL; + } else { + values[writeIndex] = value; + writeIndex = next(writeIndex); + ++currentSize; + return HasReturnvaluesIF::RETURN_OK; + } +}; + +template +inline ReturnValue_t FIFOBase::retrieve(T* value) { + if (empty()) { + return EMPTY; + } else { + *value = values[readIndex]; + readIndex = next(readIndex); + --currentSize; + return HasReturnvaluesIF::RETURN_OK; + } +}; + +template +inline ReturnValue_t FIFOBase::peek(T* value) { + if(empty()) { + return EMPTY; + } else { + *value = values[readIndex]; + return HasReturnvaluesIF::RETURN_OK; + } +}; + +template +inline ReturnValue_t FIFOBase::pop() { + T value; + return this->retrieve(&value); +}; + +template +inline bool FIFOBase::empty() { + return (currentSize == 0); +}; + +template +inline bool FIFOBase::full() { + return (currentSize == maxCapacity); +} + +template +inline size_t FIFOBase::size() { + return currentSize; +} + +template +inline size_t FIFOBase::next(size_t current) { + ++current; + if (current == maxCapacity) { + current = 0; + } + return current; +} + +#endif diff --git a/container/StaticFIFO.h b/container/StaticFIFO.h new file mode 100644 index 00000000..651c4989 --- /dev/null +++ b/container/StaticFIFO.h @@ -0,0 +1,23 @@ +#ifndef FRAMEWORK_CONTAINER_STATICFIFO_H_ +#define FRAMEWORK_CONTAINER_STATICFIFO_H_ + +#include +#include + +/** + * @brief Simple First-In-First-Out data structure with size fixed at + * compile time. The public interface of FIFOBase exposes + * the user interface for the FIFO. + * @tparam T Entry Type + * @tparam capacity Maximum capacity + */ +template +class StaticFIFO: public FIFOBase { +public: + StaticFIFO(): FIFOBase(values.data(), capacity) {}; + +private: + std::array values; +}; + +#endif /* FRAMEWORK_CONTAINERS_STATICFIFO_H_ */ diff --git a/globalfunctions/timevalOperations.cpp b/globalfunctions/timevalOperations.cpp index 253b6eb7..1da45d7b 100644 --- a/globalfunctions/timevalOperations.cpp +++ b/globalfunctions/timevalOperations.cpp @@ -90,3 +90,10 @@ double timevalOperations::toDouble(const timeval timeval) { double result = timeval.tv_sec * 1000000. + timeval.tv_usec; return result / 1000000.; } + +timeval timevalOperations::toTimeval(const double seconds) { + timeval tval; + tval.tv_sec = seconds; + tval.tv_usec = seconds *(double) 1e6 - (tval.tv_sec *1e6); + return tval; +} diff --git a/globalfunctions/timevalOperations.h b/globalfunctions/timevalOperations.h index a553e60a..3977d5d9 100644 --- a/globalfunctions/timevalOperations.h +++ b/globalfunctions/timevalOperations.h @@ -41,6 +41,7 @@ namespace timevalOperations { * @return seconds */ double toDouble(const timeval timeval); +timeval toTimeval(const double seconds); } #endif /* TIMEVALOPERATIONS_H_ */ diff --git a/osal/linux/TcUnixUdpPollingTask.cpp b/osal/linux/TcUnixUdpPollingTask.cpp index 21ad1d9a..79dbdce2 100644 --- a/osal/linux/TcUnixUdpPollingTask.cpp +++ b/osal/linux/TcUnixUdpPollingTask.cpp @@ -1,16 +1,80 @@ #include TcSocketPollingTask::TcSocketPollingTask(object_id_t objectId, - object_id_t tmtcUnixUdpBridge): SystemObject(objectId) { + object_id_t tmtcUnixUdpBridge, size_t frameSize, + double timeoutSeconds): SystemObject(objectId), + tmtcBridgeId(tmtcUnixUdpBridge) { + + if(frameSize > 0) { + this->frameSize = frameSize; + } + else { + this->frameSize = DEFAULT_MAX_FRAME_SIZE; + } + + // Set up reception buffer with specified frame size. + // For now, it is assumed that only one frame is held in the buffer! + receptionBuffer.reserve(this->frameSize); + receptionBuffer.resize(this->frameSize); + + if(timeoutSeconds == -1) { + receptionTimeout = DEFAULT_TIMEOUT; + } + else { + receptionTimeout = timevalOperations::toTimeval(timeoutSeconds); + } + + // Set receive timeout. + int result = setsockopt(serverUdpSocket, SOL_SOCKET, SO_RCVTIMEO, + &receptionTimeout, sizeof(receptionTimeout)); + if(result == -1) { + sif::error << "TcSocketPollingTask::TcSocketPollingTask: Setting receive" + "timeout failed with " << strerror(errno) << std::endl; + return; + } } TcSocketPollingTask::~TcSocketPollingTask() { } ReturnValue_t TcSocketPollingTask::performOperation(uint8_t opCode) { + // Poll for new data permanently. The call will block until the specified + // length of bytes has been received or a timeout occured. + while(1) { + //! Sender Address is cached here. + struct sockaddr_in senderAddress; + socklen_t senderSockLen = 0; + ssize_t bytesReceived = recvfrom(serverUdpSocket, + receptionBuffer.data(), frameSize, receptionFlags, + reinterpret_cast(&senderAddress), &senderSockLen); + if(bytesReceived < 0) { + //handle error + sif::error << "TcSocketPollingTask::performOperation: recvfrom " + "failed with " << strerror(errno) << std::endl; + continue; + } + sif::debug << "TcSocketPollingTask::performOperation: " << bytesReceived + << " bytes received" << std::endl; + + ReturnValue_t result = handleSuccessfullTcRead(); + tmtcBridge->checkAndSetClientAddress(senderAddress); + } return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t TcSocketPollingTask::initialize() { + tmtcBridge = objectManager->get(tmtcBridgeId); + if(tmtcBridge == nullptr) { + sif::error << "TcSocketPollingTask::TcSocketPollingTask: Invalid" + " TMTC bridge object!" << std::endl; + return ObjectManagerIF::CHILD_INIT_FAILED; + } + + serverUdpSocket = tmtcBridge->serverSocket; + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t TcSocketPollingTask::handleSuccessfullTcRead() { + return HasReturnvaluesIF::RETURN_OK; } diff --git a/osal/linux/TcUnixUdpPollingTask.h b/osal/linux/TcUnixUdpPollingTask.h index eda7fe5d..09ee6c99 100644 --- a/osal/linux/TcUnixUdpPollingTask.h +++ b/osal/linux/TcUnixUdpPollingTask.h @@ -1,8 +1,11 @@ #ifndef FRAMEWORK_OSAL_LINUX_TCSOCKETPOLLINGTASK_H_ #define FRAMEWORK_OSAL_LINUX_TCSOCKETPOLLINGTASK_H_ #include +#include #include + #include +#include /** * @brief This class can be used to implement the polling of a Unix socket, @@ -17,15 +20,34 @@ class TcSocketPollingTask: public SystemObject, public ExecutableObjectIF { friend class TmTcUnixUdpBridge; public: - TcSocketPollingTask(object_id_t objectId, object_id_t tmtcUnixUdpBridge); + static constexpr size_t DEFAULT_MAX_FRAME_SIZE = 2048; + //! 0.5 default milliseconds timeout for now. + static constexpr timeval DEFAULT_TIMEOUT = {.tv_sec = 0, .tv_usec = 500}; + + TcSocketPollingTask(object_id_t objectId, object_id_t tmtcUnixUdpBridge, + size_t frameSize = 0, double timeoutSeconds = -1); virtual~ TcSocketPollingTask(); virtual ReturnValue_t performOperation(uint8_t opCode) override; virtual ReturnValue_t initialize() override; + private: - //! Sender Address is cached here. - const struct sockaddr senderAddress; -}; + //! TMTC bridge is cached. + object_id_t tmtcBridgeId = objects::NO_OBJECT; + TmTcUnixUdpBridge* tmtcBridge = nullptr; + //! Reception flags: https://linux.die.net/man/2/recvfrom. + int receptionFlags = 0; + + //! Server socket, which is member of TMTC bridge and is assigned in + //! constructor + int serverUdpSocket = 0; + + std::vector receptionBuffer; + + size_t frameSize = 0; + timeval receptionTimeout; + + ReturnValue_t handleSuccessfullTcRead(); diff --git a/osal/linux/TmTcUnixUdpBridge.cpp b/osal/linux/TmTcUnixUdpBridge.cpp index ff8b6588..710761b4 100644 --- a/osal/linux/TmTcUnixUdpBridge.cpp +++ b/osal/linux/TmTcUnixUdpBridge.cpp @@ -1,11 +1,14 @@ #include #include #include +#include TmTcUnixUdpBridge::TmTcUnixUdpBridge(object_id_t objectId, object_id_t ccsdsPacketDistributor, uint16_t serverPort, uint16_t clientPort): TmTcBridge(objectId, ccsdsPacketDistributor) { + mutex = MutexFactory::instance()->createMutex(); + uint16_t setServerPort = DEFAULT_UDP_SERVER_PORT; if(serverPort != 0xFFFF) { setServerPort = serverPort; @@ -16,6 +19,7 @@ TmTcUnixUdpBridge::TmTcUnixUdpBridge(object_id_t objectId, setClientPort = clientPort; } + // Set up UDP socket: https://man7.org/linux/man-pages/man7/ip.7.html serverSocket = socket(AF_INET, SOCK_DGRAM, 0); if(socket < 0) { sif::error << "TmTcUnixUdpBridge::TmTcUnixUdpBridge: Could not open" @@ -26,14 +30,16 @@ TmTcUnixUdpBridge::TmTcUnixUdpBridge(object_id_t objectId, } serverAddress.sin_family = AF_INET; + // Accept packets from any interface. serverAddress.sin_addr.s_addr = htonl(INADDR_ANY); serverAddress.sin_port = htons(setServerPort); setsockopt(serverSocket, SOL_SOCKET, SO_REUSEADDR, &serverSocketOptions, sizeof(serverSocketOptions)); + serverSocketLen = sizeof(serverAddress); int result = bind(serverSocket, reinterpret_cast(&serverAddress), - sizeof(serverAddress)); + serverSocketLen); if(result == -1) { sif::error << "TmTcUnixUdpBridge::TmTcUnixUdpBridge: Could not bind " "local port " << setServerPort << " to server socket!" @@ -81,6 +87,17 @@ void TmTcUnixUdpBridge::handleSocketError() { } } +void TmTcUnixUdpBridge::setTimeout(float timeoutSeconds) { +} + +void TmTcUnixUdpBridge::checkAndSetClientAddress(sockaddr_in newAddress) { + MutexHelper lock(mutex, 10); + // Set new IP address if it has changed. + if(clientAddress.sin_addr.s_addr != newAddress.sin_addr.s_addr) { + clientAddress.sin_addr.s_addr = newAddress.sin_addr.s_addr; + } +} + void TmTcUnixUdpBridge::handleBindError() { // See: https://man7.org/linux/man-pages/man2/bind.2.html switch(errno) { diff --git a/osal/linux/TmTcUnixUdpBridge.h b/osal/linux/TmTcUnixUdpBridge.h index a969083d..15d256cd 100644 --- a/osal/linux/TmTcUnixUdpBridge.h +++ b/osal/linux/TmTcUnixUdpBridge.h @@ -7,16 +7,20 @@ #include class TmTcUnixUdpBridge: public TmTcBridge { + friend class TcSocketPollingTask; public: // The ports chosen here should not be used by any other process. // List of used ports on Linux: /etc/services - static constexpr int DEFAULT_UDP_SERVER_PORT = 7301; - static constexpr int DEFAULT_UDP_CLIENT_PORT = 7302; + static constexpr uint16_t DEFAULT_UDP_SERVER_PORT = 7301; + static constexpr uint16_t DEFAULT_UDP_CLIENT_PORT = 7302; TmTcUnixUdpBridge(object_id_t objectId, object_id_t ccsdsPacketDistributor, uint16_t serverPort = 0xFFFF,uint16_t clientPort = 0xFFFF); virtual~ TmTcUnixUdpBridge(); + void setTimeout(float timeoutSeconds); + void checkAndSetClientAddress(sockaddr_in clientAddress); + protected: virtual ReturnValue_t receiveTc(uint8_t ** recvBuffer, size_t * size) override; @@ -24,8 +28,16 @@ protected: private: int serverSocket = 0; const int serverSocketOptions = 0; + struct sockaddr_in clientAddress; + socklen_t clientSocketLen = 0; + struct sockaddr_in serverAddress; + socklen_t serverSocketLen = 0; + + //! Access to the client address is mutex protected as it is set + //! by another task. + MutexIF* mutex; void handleSocketError(); void handleBindError(); diff --git a/tmtcservices/CommandingServiceBase.h b/tmtcservices/CommandingServiceBase.h index 700503c6..169eebe1 100644 --- a/tmtcservices/CommandingServiceBase.h +++ b/tmtcservices/CommandingServiceBase.h @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include class TcPacketStored; @@ -199,7 +199,7 @@ protected: uint32_t state; Command_t command; object_id_t objectId; - FIFO fifo; + StaticFIFO fifo; }; using CommandMapIter = FixedMap #include -#include +#include class TmTcBridge : public AcceptsTelemetryIF, public ExecutableObjectIF, @@ -143,7 +143,7 @@ protected: * This fifo can be used to store downlink data * which can not be sent at the moment. */ - FIFO tmFifo; + StaticFIFO tmFifo; uint8_t sentPacketsPerCycle = DEFAULT_STORED_DATA_SENT_PER_CYCLE; uint8_t maxNumberOfPacketsStored = DEFAULT_DOWNLINK_PACKETS_STORED; }; From 2158208a2fbbd98c1fa5ced154866803f80d04f1 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 6 Jul 2020 00:33:55 +0200 Subject: [PATCH 229/307] new pus parser --- osal/linux/TcUnixUdpPollingTask.cpp | 1 - osal/linux/TcUnixUdpPollingTask.h | 2 +- tmtcservices/PusParser.cpp | 10 ++++++ tmtcservices/PusParser.h | 51 +++++++++++++++++++++++++++++ 4 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 tmtcservices/PusParser.cpp create mode 100644 tmtcservices/PusParser.h diff --git a/osal/linux/TcUnixUdpPollingTask.cpp b/osal/linux/TcUnixUdpPollingTask.cpp index 79dbdce2..f237a0f2 100644 --- a/osal/linux/TcUnixUdpPollingTask.cpp +++ b/osal/linux/TcUnixUdpPollingTask.cpp @@ -75,6 +75,5 @@ ReturnValue_t TcSocketPollingTask::initialize() { } ReturnValue_t TcSocketPollingTask::handleSuccessfullTcRead() { - return HasReturnvaluesIF::RETURN_OK; } diff --git a/osal/linux/TcUnixUdpPollingTask.h b/osal/linux/TcUnixUdpPollingTask.h index 09ee6c99..a6b0e9d4 100644 --- a/osal/linux/TcUnixUdpPollingTask.h +++ b/osal/linux/TcUnixUdpPollingTask.h @@ -49,6 +49,6 @@ private: ReturnValue_t handleSuccessfullTcRead(); - +}; #endif /* FRAMEWORK_OSAL_LINUX_TCSOCKETPOLLINGTASK_H_ */ diff --git a/tmtcservices/PusParser.cpp b/tmtcservices/PusParser.cpp new file mode 100644 index 00000000..76934e33 --- /dev/null +++ b/tmtcservices/PusParser.cpp @@ -0,0 +1,10 @@ +#include + +PusParser::PusParser(uint16_t maxExpectedPusPackets, + bool storeSplitPackets): indexSizePairFIFO(maxExpectedPusPackets) { +} + +ReturnValue_t PusParser::parsePusPackets(const uint8_t *frame, + size_t frameSize) { + return HasReturnvaluesIF::RETURN_OK; +} diff --git a/tmtcservices/PusParser.h b/tmtcservices/PusParser.h new file mode 100644 index 00000000..8fbf9652 --- /dev/null +++ b/tmtcservices/PusParser.h @@ -0,0 +1,51 @@ +#ifndef FRAMEWORK_TMTCSERVICES_PUSPARSER_H_ +#define FRAMEWORK_TMTCSERVICES_PUSPARSER_H_ + +#include + +#include +#include + +/** + * @brief This small helper class scans a given buffer for PUS packets. + * Can be used if PUS packets are serialized in a tightly packed frame. + * @details + * The parser uses the payload length field of PUS packets to find + * the respective PUS packet sizes. + * + * The parser parses a buffer by taking a pointer and the maximum size to scan. + * If PUS packets are found, they are stored in a FIFO which stores pairs + * consisting of the index in the buffer and the respective packet sizes. + * + * If the parser detects split packets (which means that the size of the + * next packet is larger than the remaining size to scan), it can either + * store that split packet or throw away the packet. + */ +class PusParser { +public: + /** + * Parser constructor. + * @param maxExpectedPusPackets + * Maximum expected number of PUS packets. A good estimate is to divide + * the frame size by the minimum size of a PUS packet (12 bytes) + * @param storeSplitPackets + * Specifies whether split packets are also stored inside the FIFO, + * with the size being the remaining frame size. + */ + PusParser(uint16_t maxExpectedPusPackets, bool storeSplitPackets); + + ReturnValue_t parsePusPackets(const uint8_t* frame, size_t frameSize); +private: + //! The first entry is the index inside the buffer while the second index + //! is the size of the PUS packet starting at that index. + using indexSizePair = std::pair; + //! A FIFO is used to store information about multiple PUS packets + //! inside the receive buffer. The maximum number of entries is defined + //! by the first constructor argument. + FIFO indexSizePairFIFO; + + bool storeSplitPackets = false; +}; + + +#endif /* FRAMEWORK_TMTCSERVICES_PUSPARSER_H_ */ From bb5de8f11041014ad9f6c33c98fc6d6e0822afc3 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 6 Jul 2020 13:41:07 +0200 Subject: [PATCH 230/307] merged new changes --- container/FIFO.h | 11 +++++++++-- container/FIFOBase.h | 8 ++++++-- container/StaticFIFO.h | 11 +++++++++-- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/container/FIFO.h b/container/FIFO.h index 217ddbca..7251321f 100644 --- a/container/FIFO.h +++ b/container/FIFO.h @@ -4,10 +4,15 @@ #include #include +namespace fsfw { + /** * @brief Simple First-In-First-Out data structure. The maximum size - * can be set in the constructor. THe public interface of - * FIFOBase exposes the user interface for the FIFO. + * can be set in the constructor. + * @details + * The maximum capacity can be determined at run-time, so this container + * performs dynamic memory allocation! + * The public interface of FIFOBase exposes the user interface for the FIFO. * @tparam T Entry Type * @tparam capacity Maximum capacity */ @@ -23,4 +28,6 @@ private: std::vector values; }; +} + #endif /* FRAMEWORK_CONTAINER_FIFO_H_ */ diff --git a/container/FIFOBase.h b/container/FIFOBase.h index c6a74d2f..ac5c6e2c 100644 --- a/container/FIFOBase.h +++ b/container/FIFOBase.h @@ -4,6 +4,8 @@ #include #include +namespace fsfw { + template class FIFOBase { public: @@ -11,8 +13,8 @@ public: static const ReturnValue_t FULL = MAKE_RETURN_CODE(1); static const ReturnValue_t EMPTY = MAKE_RETURN_CODE(2); - - /** Default ctor, no input arguments required. */ + /** Default ctor, takes pointer to first entry of underlying container + * and maximum capacity */ FIFOBase(T* values, const size_t maxCapacity); /** @@ -56,4 +58,6 @@ private: #include +} + #endif /* FRAMEWORK_CONTAINER_FIFOBASE_H_ */ diff --git a/container/StaticFIFO.h b/container/StaticFIFO.h index 651c4989..f3128200 100644 --- a/container/StaticFIFO.h +++ b/container/StaticFIFO.h @@ -3,11 +3,16 @@ #include #include +#include + +namespace fsfw { /** * @brief Simple First-In-First-Out data structure with size fixed at - * compile time. The public interface of FIFOBase exposes - * the user interface for the FIFO. + * compile time + * @details + * Performs no dynamic memory allocation. + * The public interface of FIFOBase exposes the user interface for the FIFO. * @tparam T Entry Type * @tparam capacity Maximum capacity */ @@ -20,4 +25,6 @@ private: std::array values; }; +} + #endif /* FRAMEWORK_CONTAINERS_STATICFIFO_H_ */ From b61e1df8bcd2177f06cbdb28e7c4352cee75422c Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 6 Jul 2020 13:43:41 +0200 Subject: [PATCH 231/307] fifo in namespace now --- tmtcservices/CommandingServiceBase.h | 2 +- tmtcservices/PusParser.h | 2 +- tmtcservices/TmTcBridge.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tmtcservices/CommandingServiceBase.h b/tmtcservices/CommandingServiceBase.h index 169eebe1..72fe13f2 100644 --- a/tmtcservices/CommandingServiceBase.h +++ b/tmtcservices/CommandingServiceBase.h @@ -199,7 +199,7 @@ protected: uint32_t state; Command_t command; object_id_t objectId; - StaticFIFO fifo; + fsfw::StaticFIFO fifo; }; using CommandMapIter = FixedMap indexSizePairFIFO; + fsfw::FIFO indexSizePairFIFO; bool storeSplitPackets = false; }; diff --git a/tmtcservices/TmTcBridge.h b/tmtcservices/TmTcBridge.h index a24aa805..23f7dcfa 100644 --- a/tmtcservices/TmTcBridge.h +++ b/tmtcservices/TmTcBridge.h @@ -143,7 +143,7 @@ protected: * This fifo can be used to store downlink data * which can not be sent at the moment. */ - StaticFIFO tmFifo; + fsfw::StaticFIFO tmFifo; uint8_t sentPacketsPerCycle = DEFAULT_STORED_DATA_SENT_PER_CYCLE; uint8_t maxNumberOfPacketsStored = DEFAULT_DOWNLINK_PACKETS_STORED; }; From 78283ddbeecefb733fe68408befb3337ad869173 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 6 Jul 2020 14:09:33 +0200 Subject: [PATCH 232/307] queue map manager: not using std::atomic anymore --- osal/host/QueueMapManager.cpp | 5 ++++- osal/host/QueueMapManager.h | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/osal/host/QueueMapManager.cpp b/osal/host/QueueMapManager.cpp index e7c86f30..89b9a948 100644 --- a/osal/host/QueueMapManager.cpp +++ b/osal/host/QueueMapManager.cpp @@ -17,6 +17,10 @@ QueueMapManager* QueueMapManager::instance() { ReturnValue_t QueueMapManager::addMessageQueue( MessageQueueIF* queueToInsert, MessageQueueId_t* id) { + // Not thread-safe, but it is assumed all message queues are created + // at software initialization now. If this is to be made thread-safe in + // the future, it propably would be sufficient to lock the increment + // operation here uint32_t currentId = queueCounter++; auto returnPair = queueMap.emplace(currentId, queueToInsert); if(not returnPair.second) { @@ -28,7 +32,6 @@ ReturnValue_t QueueMapManager::addMessageQueue( if (id != nullptr) { *id = currentId; } - mapLock = MutexFactory::instance()->createMutex(); return HasReturnvaluesIF::RETURN_OK; } diff --git a/osal/host/QueueMapManager.h b/osal/host/QueueMapManager.h index 499b1622..a2a1b658 100644 --- a/osal/host/QueueMapManager.h +++ b/osal/host/QueueMapManager.h @@ -36,7 +36,7 @@ public: private: //! External instantiation is forbidden. QueueMapManager(); - std::atomic queueCounter = 1; + uint32_t queueCounter = 1; MutexIF* mapLock; QueueMap queueMap; static QueueMapManager* mqManagerInstance; From f442a5889ec4bb213f35668a9320dd4cfedeee94 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 6 Jul 2020 16:34:11 +0200 Subject: [PATCH 233/307] pus parser continued --- returnvalues/FwClassIds.h | 1 + tmtcservices/PusParser.cpp | 33 +++++++++++++++++++++++++++++++++ tmtcservices/PusParser.h | 11 +++++++++++ 3 files changed, 45 insertions(+) diff --git a/returnvalues/FwClassIds.h b/returnvalues/FwClassIds.h index ddee539e..abee534a 100644 --- a/returnvalues/FwClassIds.h +++ b/returnvalues/FwClassIds.h @@ -64,6 +64,7 @@ enum { LOCAL_POOL_OWNER_IF, //LPIF 58 POOL_VARIABLE_IF, //PVA 59 HOUSEKEEPING_MANAGER, //HKM 60 + PUS_PARSER, //PUSP 61 FW_CLASS_ID_COUNT //is actually count + 1 ! }; diff --git a/tmtcservices/PusParser.cpp b/tmtcservices/PusParser.cpp index 76934e33..5f326b44 100644 --- a/tmtcservices/PusParser.cpp +++ b/tmtcservices/PusParser.cpp @@ -1,4 +1,5 @@ #include +#include PusParser::PusParser(uint16_t maxExpectedPusPackets, bool storeSplitPackets): indexSizePairFIFO(maxExpectedPusPackets) { @@ -6,5 +7,37 @@ PusParser::PusParser(uint16_t maxExpectedPusPackets, ReturnValue_t PusParser::parsePusPackets(const uint8_t *frame, size_t frameSize) { + if(frame == nullptr) { + sif::error << "PusParser::parsePusPackets: Frame pointers in invalid!" + << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + + // Size of a pus packet is the value in the packet length field plus 7. + uint16_t packetSize = (frame[4] << 8 | frame[5]) + 7; + if(packetSize > 0) { + indexSizePairFIFO.insert(indexSizePair(0, packetSize)); + return HasReturnvaluesIF::RETURN_OK; + } + else { + return NO_PACKET_FOUND; + } + + if(frameSize > packetSize) { + return readMultiplePackets(frameSize); + + } return HasReturnvaluesIF::RETURN_OK; } + +//ReturnValue_t PusParser::readMultiplePackets(size_t frameSize) { +// size_t endOfBuffer = frameSize - 1; +// size_t endIndex = firstPacketSize; +// size_t startIndex = 0; +// while (endIndex < endOfBuffer) { +// ReturnValue_t result = readNextPacket(&startIndex, &endIndex); +// if(result != RETURN_OK) { +// return; +// } +// } +//} diff --git a/tmtcservices/PusParser.h b/tmtcservices/PusParser.h index ef177079..cdc887ed 100644 --- a/tmtcservices/PusParser.h +++ b/tmtcservices/PusParser.h @@ -23,6 +23,9 @@ */ class PusParser { public: + static constexpr uint8_t INTERFACE_ID = CLASS_ID::PUS_PARSER; + static constexpr ReturnValue_t NO_PACKET_FOUND = MAKE_RETURN_CODE(0x00); + /** * Parser constructor. * @param maxExpectedPusPackets @@ -34,6 +37,12 @@ public: */ PusParser(uint16_t maxExpectedPusPackets, bool storeSplitPackets); + /** + * Parse a given frame for PUS packets + * @param frame + * @param frameSize + * @return -@c NO_PACKET_FOUND if no packet was found. + */ ReturnValue_t parsePusPackets(const uint8_t* frame, size_t frameSize); private: //! The first entry is the index inside the buffer while the second index @@ -45,6 +54,8 @@ private: fsfw::FIFO indexSizePairFIFO; bool storeSplitPackets = false; + + ReturnValue_t readMultiplePackets(size_t frameSize); }; From 8ba75fc3c2fad46fc0e37fe17a627a99cfa3f09a Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 6 Jul 2020 19:36:21 +0200 Subject: [PATCH 234/307] pus parser implemented --- tmtcservices/PusParser.cpp | 113 ++++++++++++++++++++++++++++++------- tmtcservices/PusParser.h | 32 +++++++++-- 2 files changed, 120 insertions(+), 25 deletions(-) diff --git a/tmtcservices/PusParser.cpp b/tmtcservices/PusParser.cpp index 5f326b44..21d44efa 100644 --- a/tmtcservices/PusParser.cpp +++ b/tmtcservices/PusParser.cpp @@ -13,31 +13,106 @@ ReturnValue_t PusParser::parsePusPackets(const uint8_t *frame, return HasReturnvaluesIF::RETURN_FAILED; } - // Size of a pus packet is the value in the packet length field plus 7. - uint16_t packetSize = (frame[4] << 8 | frame[5]) + 7; - if(packetSize > 0) { - indexSizePairFIFO.insert(indexSizePair(0, packetSize)); - return HasReturnvaluesIF::RETURN_OK; + if(indexSizePairFIFO.full()) { + sif::error << "PusParser::parsePusPackets: FIFO is full!" << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; } - else { + + + size_t lengthField = frame[4] << 8 | frame[5]; + + if(lengthField == 0) { return NO_PACKET_FOUND; } - if(frameSize > packetSize) { - return readMultiplePackets(frameSize); + size_t packetSize = lengthField + 7; + if(lengthField > 0) { + // Size of a pus packet is the value in the packet length field plus 7. + if(packetSize > frameSize) + { + if(storeSplitPackets) + { + indexSizePairFIFO.insert(indexSizePair(0, frameSize)); + } + else + { + sif::debug << "TcSerialPollingTask::readNextPacket: Next packet " + "larger than remaining frame," << std::endl; + sif::debug << "Throwing away packet. Detected packet size: " + << packetSize << std::endl; + } + return SPLIT_PACKET; + } + else + { + indexSizePairFIFO.insert(indexSizePair(0, packetSize)); + if(packetSize == frameSize) { + return HasReturnvaluesIF::RETURN_OK; + } + } + } + // packet size is smaller than frame size, parse for more packets. + return readMultiplePackets(frame, frameSize, packetSize); +} + +ReturnValue_t PusParser::readMultiplePackets(const uint8_t *frame, + size_t frameSize, size_t startIndex) { + while (startIndex < frameSize) { + ReturnValue_t result = readNextPacket(frame, frameSize, startIndex); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } } return HasReturnvaluesIF::RETURN_OK; } -//ReturnValue_t PusParser::readMultiplePackets(size_t frameSize) { -// size_t endOfBuffer = frameSize - 1; -// size_t endIndex = firstPacketSize; -// size_t startIndex = 0; -// while (endIndex < endOfBuffer) { -// ReturnValue_t result = readNextPacket(&startIndex, &endIndex); -// if(result != RETURN_OK) { -// return; -// } -// } -//} +fsfw::FIFO* PusParser::fifo(){ + return &indexSizePairFIFO; +} + +PusParser::indexSizePair PusParser::getNextFifoPair() { + indexSizePair nextIndexSizePair; + indexSizePairFIFO.retrieve(&nextIndexSizePair); + return nextIndexSizePair; +} + +ReturnValue_t PusParser::readNextPacket(const uint8_t *frame, + size_t frameSize, size_t& currentIndex) { + // sif::debug << startIndex << std::endl; + uint16_t lengthField = frame[currentIndex + 4] << 8 | + frame[currentIndex + 5]; + if(lengthField == 0) { + // It is assumed that no packet follows. + currentIndex = frameSize; + return HasReturnvaluesIF::RETURN_OK; + } + size_t nextPacketSize = lengthField + 7; + size_t remainingSize = frameSize - currentIndex; + if(nextPacketSize > remainingSize) + { + if(storeSplitPackets) + { + indexSizePairFIFO.insert(indexSizePair(currentIndex, remainingSize)); + } + else + { + sif::debug << "TcSerialPollingTask::readNextPacket: Next packet " + "larger than remaining frame," << std::endl; + sif::debug << "Throwing away packet. Detected packet size: " + << nextPacketSize << std::endl; + } + return SPLIT_PACKET; + } + + ReturnValue_t result = indexSizePairFIFO.insert(indexSizePair(currentIndex, + nextPacketSize)); + if (result != HasReturnvaluesIF::RETURN_OK) { + // FIFO full. + sif::debug << "PusParser: Issue inserting into start index size " + "FIFO, it is full!" << std::endl; + } + currentIndex += nextPacketSize; + + return result; +} diff --git a/tmtcservices/PusParser.h b/tmtcservices/PusParser.h index cdc887ed..82aff57e 100644 --- a/tmtcservices/PusParser.h +++ b/tmtcservices/PusParser.h @@ -23,9 +23,13 @@ */ class PusParser { public: + //! The first entry is the index inside the buffer while the second index + //! is the size of the PUS packet starting at that index. + using indexSizePair = std::pair; + static constexpr uint8_t INTERFACE_ID = CLASS_ID::PUS_PARSER; static constexpr ReturnValue_t NO_PACKET_FOUND = MAKE_RETURN_CODE(0x00); - + static constexpr ReturnValue_t SPLIT_PACKET = MAKE_RETURN_CODE(0x01); /** * Parser constructor. * @param maxExpectedPusPackets @@ -44,10 +48,24 @@ public: * @return -@c NO_PACKET_FOUND if no packet was found. */ ReturnValue_t parsePusPackets(const uint8_t* frame, size_t frameSize); + + /** + * Accessor function to get a reference to the internal FIFO which + * stores pairs of indexi and packet sizes. This FIFO is filled + * by the parsePusPackets() function. + * @return + */ + fsfw::FIFO* fifo(); + + /** + * Retrieve the next index and packet size pair from the FIFO. + * This also removed it from the FIFO. Please note that if the FIFO + * is empty, an empty pair will be returned. + * @return + */ + indexSizePair getNextFifoPair(); private: - //! The first entry is the index inside the buffer while the second index - //! is the size of the PUS packet starting at that index. - using indexSizePair = std::pair; + //! A FIFO is used to store information about multiple PUS packets //! inside the receive buffer. The maximum number of entries is defined //! by the first constructor argument. @@ -55,8 +73,10 @@ private: bool storeSplitPackets = false; - ReturnValue_t readMultiplePackets(size_t frameSize); + ReturnValue_t readMultiplePackets(const uint8_t *frame, size_t frameSize, + size_t startIndex); + ReturnValue_t readNextPacket(const uint8_t *frame, + size_t frameSize, size_t& startIndex); }; - #endif /* FRAMEWORK_TMTCSERVICES_PUSPARSER_H_ */ From fd1e612ea5d931d20177405a827c34bf52ee7c54 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 6 Jul 2020 20:17:05 +0200 Subject: [PATCH 235/307] pus parser fixes --- tmtcservices/PusParser.cpp | 40 +++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/tmtcservices/PusParser.cpp b/tmtcservices/PusParser.cpp index 21d44efa..b43b0519 100644 --- a/tmtcservices/PusParser.cpp +++ b/tmtcservices/PusParser.cpp @@ -18,7 +18,6 @@ ReturnValue_t PusParser::parsePusPackets(const uint8_t *frame, return HasReturnvaluesIF::RETURN_FAILED; } - size_t lengthField = frame[4] << 8 | frame[5]; if(lengthField == 0) { @@ -26,32 +25,32 @@ ReturnValue_t PusParser::parsePusPackets(const uint8_t *frame, } size_t packetSize = lengthField + 7; - if(lengthField > 0) { - // Size of a pus packet is the value in the packet length field plus 7. - if(packetSize > frameSize) + // Size of a pus packet is the value in the packet length field plus 7. + if(packetSize > frameSize) + { + if(storeSplitPackets) { - if(storeSplitPackets) - { - indexSizePairFIFO.insert(indexSizePair(0, frameSize)); - } - else - { - sif::debug << "TcSerialPollingTask::readNextPacket: Next packet " - "larger than remaining frame," << std::endl; - sif::debug << "Throwing away packet. Detected packet size: " - << packetSize << std::endl; - } - return SPLIT_PACKET; + indexSizePairFIFO.insert(indexSizePair(0, frameSize)); } else { - indexSizePairFIFO.insert(indexSizePair(0, packetSize)); - if(packetSize == frameSize) { - return HasReturnvaluesIF::RETURN_OK; - } + sif::debug << "TcSerialPollingTask::readNextPacket: Next packet " + "larger than remaining frame," << std::endl; + sif::debug << "Throwing away packet. Detected packet size: " + << packetSize << std::endl; + } + return SPLIT_PACKET; + } + else + { + indexSizePairFIFO.insert(indexSizePair(0, packetSize)); + if(packetSize == frameSize) { + sif::info << "test2" << std::endl; + return HasReturnvaluesIF::RETURN_OK; } } + // packet size is smaller than frame size, parse for more packets. return readMultiplePackets(frame, frameSize, packetSize); } @@ -59,6 +58,7 @@ ReturnValue_t PusParser::parsePusPackets(const uint8_t *frame, ReturnValue_t PusParser::readMultiplePackets(const uint8_t *frame, size_t frameSize, size_t startIndex) { while (startIndex < frameSize) { + sif::info << "test" << std::endl; ReturnValue_t result = readNextPacket(frame, frameSize, startIndex); if(result != HasReturnvaluesIF::RETURN_OK) { return result; From cb691db807d562c8f84178d48650464c4cb58ecc Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 6 Jul 2020 23:07:38 +0200 Subject: [PATCH 236/307] fifo tweaks, pus parser fixes --- container/FIFO.h | 6 ++---- container/FIFOBase.h | 4 +++- container/FIFOBase.tpp | 5 +++++ tmtcservices/PusParser.cpp | 3 --- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/container/FIFO.h b/container/FIFO.h index 7251321f..19daaf1b 100644 --- a/container/FIFO.h +++ b/container/FIFO.h @@ -19,10 +19,8 @@ namespace fsfw { template class FIFO: public FIFOBase { public: - FIFO(size_t maxCapacity): FIFOBase(values.data(), maxCapacity) { - values.reserve(maxCapacity); - values.resize(maxCapacity); - }; + FIFO(size_t maxCapacity): FIFOBase(values.data(), maxCapacity), + values(maxCapacity) {}; private: std::vector values; diff --git a/container/FIFOBase.h b/container/FIFOBase.h index ac5c6e2c..6ed7d924 100644 --- a/container/FIFOBase.h +++ b/container/FIFOBase.h @@ -45,9 +45,11 @@ public: bool full(); size_t size(); + size_t getMaxCapacity() const; + private: T* values; - size_t maxCapacity; + size_t maxCapacity = 0; size_t readIndex = 0; size_t writeIndex = 0; diff --git a/container/FIFOBase.tpp b/container/FIFOBase.tpp index 011ce6de..48a060ff 100644 --- a/container/FIFOBase.tpp +++ b/container/FIFOBase.tpp @@ -73,4 +73,9 @@ inline size_t FIFOBase::next(size_t current) { return current; } +template +inline size_t FIFOBase::getMaxCapacity() const { + return maxCapacity; +} + #endif diff --git a/tmtcservices/PusParser.cpp b/tmtcservices/PusParser.cpp index b43b0519..175c2893 100644 --- a/tmtcservices/PusParser.cpp +++ b/tmtcservices/PusParser.cpp @@ -45,12 +45,10 @@ ReturnValue_t PusParser::parsePusPackets(const uint8_t *frame, { indexSizePairFIFO.insert(indexSizePair(0, packetSize)); if(packetSize == frameSize) { - sif::info << "test2" << std::endl; return HasReturnvaluesIF::RETURN_OK; } } - // packet size is smaller than frame size, parse for more packets. return readMultiplePackets(frame, frameSize, packetSize); } @@ -58,7 +56,6 @@ ReturnValue_t PusParser::parsePusPackets(const uint8_t *frame, ReturnValue_t PusParser::readMultiplePackets(const uint8_t *frame, size_t frameSize, size_t startIndex) { while (startIndex < frameSize) { - sif::info << "test" << std::endl; ReturnValue_t result = readNextPacket(frame, frameSize, startIndex); if(result != HasReturnvaluesIF::RETURN_OK) { return result; From 4f1f610ae03bd4f0fecc9e19ecafa5803ee8a231 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 7 Jul 2020 16:36:41 +0200 Subject: [PATCH 237/307] doc and improvements for DLE encoder --- globalfunctions/DleEncoder.cpp | 39 +++++++++++---------- globalfunctions/DleEncoder.h | 64 +++++++++++++++++++++++++++++----- returnvalues/FwClassIds.h | 3 +- 3 files changed, 78 insertions(+), 28 deletions(-) diff --git a/globalfunctions/DleEncoder.cpp b/globalfunctions/DleEncoder.cpp index a68f1524..ee934785 100644 --- a/globalfunctions/DleEncoder.cpp +++ b/globalfunctions/DleEncoder.cpp @@ -1,18 +1,16 @@ #include -DleEncoder::DleEncoder() { -} +DleEncoder::DleEncoder() {} -DleEncoder::~DleEncoder() { -} +DleEncoder::~DleEncoder() {} ReturnValue_t DleEncoder::decode(const uint8_t *sourceStream, - uint32_t sourceStreamLen, uint32_t *readLen, uint8_t *destStream, - uint32_t maxDestStreamlen, uint32_t *decodedLen) { - uint32_t encodedIndex = 0, decodedIndex = 0; + size_t sourceStreamLen, size_t *readLen, uint8_t *destStream, + size_t maxDestStreamlen, size_t *decodedLen) { + size_t encodedIndex = 0, decodedIndex = 0; uint8_t nextByte; if (*sourceStream != STX) { - return RETURN_FAILED; + return DECODING_ERROR; } ++encodedIndex; while ((encodedIndex < sourceStreamLen) && (decodedIndex < maxDestStreamlen) @@ -20,14 +18,18 @@ ReturnValue_t DleEncoder::decode(const uint8_t *sourceStream, && (sourceStream[encodedIndex] != STX)) { if (sourceStream[encodedIndex] == DLE) { nextByte = sourceStream[encodedIndex + 1]; - if (nextByte == 0x10) { + // The next byte is a DLE character that was escaped by another + // DLE character, so we can write it to the destination stream. + if (nextByte == DLE) { destStream[decodedIndex] = nextByte; } else { + // The next byte is a STX, DTX or 0x0D character which + // was escaped by a DLE character if ((nextByte == 0x42) || (nextByte == 0x43) || (nextByte == 0x4D)) { destStream[decodedIndex] = nextByte - 0x40; } else { - return RETURN_FAILED; + return DECODING_ERROR; } } ++encodedIndex; @@ -38,7 +40,7 @@ ReturnValue_t DleEncoder::decode(const uint8_t *sourceStream, ++decodedIndex; } if (sourceStream[encodedIndex] != ETX) { - return RETURN_FAILED; + return DECODING_ERROR; } else { *readLen = ++encodedIndex; *decodedLen = decodedIndex; @@ -47,12 +49,12 @@ ReturnValue_t DleEncoder::decode(const uint8_t *sourceStream, } ReturnValue_t DleEncoder::encode(const uint8_t* sourceStream, - uint32_t sourceLen, uint8_t* destStream, uint32_t maxDestLen, - uint32_t* encodedLen, bool addStxEtx) { + size_t sourceLen, uint8_t* destStream, size_t maxDestLen, + size_t* encodedLen, bool addStxEtx) { if (maxDestLen < 2) { - return RETURN_FAILED; + return STREAM_TOO_SHORT; } - uint32_t encodedIndex = 0, sourceIndex = 0; + size_t encodedIndex = 0, sourceIndex = 0; uint8_t nextByte; if (addStxEtx) { destStream[0] = STX; @@ -62,15 +64,16 @@ ReturnValue_t DleEncoder::encode(const uint8_t* sourceStream, nextByte = sourceStream[sourceIndex]; if ((nextByte == STX) || (nextByte == ETX) || (nextByte == 0x0D)) { if (encodedIndex + 1 >= maxDestLen) { - return RETURN_FAILED; + return STREAM_TOO_SHORT; } else { destStream[encodedIndex] = DLE; ++encodedIndex; + // Escaped byte will be actual byte + 0x40. destStream[encodedIndex] = nextByte + 0x40; } } else if (nextByte == DLE) { if (encodedIndex + 1 >= maxDestLen) { - return RETURN_FAILED; + return STREAM_TOO_SHORT; } else { destStream[encodedIndex] = DLE; ++encodedIndex; @@ -90,6 +93,6 @@ ReturnValue_t DleEncoder::encode(const uint8_t* sourceStream, *encodedLen = encodedIndex; return RETURN_OK; } else { - return RETURN_FAILED; + return STREAM_TOO_SHORT; } } diff --git a/globalfunctions/DleEncoder.h b/globalfunctions/DleEncoder.h index fc155600..0f4a4c8f 100644 --- a/globalfunctions/DleEncoder.h +++ b/globalfunctions/DleEncoder.h @@ -1,25 +1,71 @@ -#ifndef DLEENCODER_H_ -#define DLEENCODER_H_ +#ifndef FRAMEWORK_GLOBALFUNCTIONS_DLEENCODER_H_ +#define FRAMEWORK_GLOBALFUNCTIONS_DLEENCODER_H_ #include +#include +/** + * @brief This DLE Encoder (Data Link Encoder) can be used to encode and + * decode arbitrary data with ASCII control characters + * @details + * List of control codes: + * https://en.wikipedia.org/wiki/C0_and_C1_control_codes + * + * This encoder can be used to achieve a basic transport layer when using + * char based transmission systems. + * The passed source strean is converted into a encoded stream by adding + * a STX marker at the startr of the stream and an ETX marker at the end of + * the stream. Any STX, ETX and DLE occurences in the source stream are escaped + * by a DLE character. + */ class DleEncoder: public HasReturnvaluesIF { private: DleEncoder(); virtual ~DleEncoder(); public: + static constexpr uint8_t INTERFACE_ID = CLASS_ID::DLE_ENCODER; + static constexpr ReturnValue_t STREAM_TOO_SHORT = MAKE_RETURN_CODE(0x01); + static constexpr ReturnValue_t DECODING_ERROR = MAKE_RETURN_CODE(0x02); + + //! Start Of Text character. First character is encoded stream static const uint8_t STX = 0x02; + //! End Of Text character. Last character in encoded stream static const uint8_t ETX = 0x03; + //! Data Link Escape character. Used to escape STX, ETX and DLE occurences + //! in the source stream. static const uint8_t DLE = 0x10; - static ReturnValue_t decode(const uint8_t *sourceStream, - uint32_t sourceStreamLen, uint32_t *readLen, uint8_t *destStream, - uint32_t maxDestStreamlen, uint32_t *decodedLen); + /** + * Encodes the give data stream by preceding it with the STX marker + * and ending it with an ETX marker. STX, ETX and DLE characters inside + * the stream are escaped by DLE characters. + * @param sourceStream + * @param sourceLen + * @param destStream + * @param maxDestLen + * @param encodedLen + * @param addStxEtx + * Adding STX and ETX can be omitted, if they are added manually. + * @return + */ + static ReturnValue_t encode(const uint8_t *sourceStream, size_t sourceLen, + uint8_t *destStream, size_t maxDestLen, size_t *encodedLen, + bool addStxEtx = true); - static ReturnValue_t encode(const uint8_t *sourceStream, uint32_t sourceLen, - uint8_t *destStream, uint32_t maxDestLen, uint32_t *encodedLen, - bool addStxEtx = true); + /** + * Converts an encoded stream back + * @param sourceStream + * @param sourceStreamLen + * @param readLen + * @param destStream + * @param maxDestStreamlen + * @param decodedLen + * @return + */ + static ReturnValue_t decode(const uint8_t *sourceStream, + size_t sourceStreamLen, size_t *readLen, uint8_t *destStream, + size_t maxDestStreamlen, size_t *decodedLen); }; -#endif /* DLEENCODER_H_ */ +#endif /* FRAMEWORK_GLOBALFUNCTIONS_DLEENCODER_H_ */ diff --git a/returnvalues/FwClassIds.h b/returnvalues/FwClassIds.h index abee534a..7e4d8953 100644 --- a/returnvalues/FwClassIds.h +++ b/returnvalues/FwClassIds.h @@ -64,7 +64,8 @@ enum { LOCAL_POOL_OWNER_IF, //LPIF 58 POOL_VARIABLE_IF, //PVA 59 HOUSEKEEPING_MANAGER, //HKM 60 - PUS_PARSER, //PUSP 61 + DLE_ENCODER, //DLEE 61 + PUS_PARSER, //PUSP 62 FW_CLASS_ID_COUNT //is actually count + 1 ! }; From 359163886ba2d926cefe8f57b6691818a1e70b8e Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 7 Jul 2020 17:06:30 +0200 Subject: [PATCH 238/307] pus srv5 and 1 moved to framework --- framework.mk | 2 +- pus/Service1TelecommandVerification.cpp | 100 ++++++++++++++ pus/Service1TelecommandVerification.h | 94 ++++++++++++++ pus/Service5EventReporting.cpp | 92 +++++++++++++ pus/Service5EventReporting.h | 86 ++++++++++++ pus/servicepackets/Service1Packets.h | 166 ++++++++++++++++++++++++ pus/servicepackets/Service5Packets.h | 83 ++++++++++++ 7 files changed, 622 insertions(+), 1 deletion(-) create mode 100644 pus/Service1TelecommandVerification.cpp create mode 100644 pus/Service1TelecommandVerification.h create mode 100644 pus/Service5EventReporting.cpp create mode 100644 pus/Service5EventReporting.h create mode 100644 pus/servicepackets/Service1Packets.h create mode 100644 pus/servicepackets/Service5Packets.h diff --git a/framework.mk b/framework.mk index c8822981..bfbd4b1f 100644 --- a/framework.mk +++ b/framework.mk @@ -58,4 +58,4 @@ CXXSRC += $(wildcard $(FRAMEWORK_PATH)/tmtcpacket/*.cpp) CXXSRC += $(wildcard $(FRAMEWORK_PATH)/tmtcpacket/packetmatcher/*.cpp) CXXSRC += $(wildcard $(FRAMEWORK_PATH)/tmtcpacket/pus/*.cpp) CXXSRC += $(wildcard $(FRAMEWORK_PATH)/tmtcservices/*.cpp) -CXXSRC += $(wildcard $(FRAMEWORK_PATH)/test/*.cpp) \ No newline at end of file +CXXSRC += $(wildcard $(FRAMEWORK_PATH)/pus/*.cpp) \ No newline at end of file diff --git a/pus/Service1TelecommandVerification.cpp b/pus/Service1TelecommandVerification.cpp new file mode 100644 index 00000000..4ce2ce54 --- /dev/null +++ b/pus/Service1TelecommandVerification.cpp @@ -0,0 +1,100 @@ +#include +#include + +#include +#include +#include +#include +#include +#include + + +Service1TelecommandVerification::Service1TelecommandVerification( + object_id_t objectId, uint16_t apid, uint8_t serviceId, + object_id_t targetDestination): + SystemObject(objectId), apid(apid), serviceId(serviceId), + targetDestination(targetDestination) { + tmQueue = QueueFactory::instance()->createMessageQueue(); +} + +Service1TelecommandVerification::~Service1TelecommandVerification() {} + +MessageQueueId_t Service1TelecommandVerification::getVerificationQueue(){ + return tmQueue->getId(); +} + + +ReturnValue_t Service1TelecommandVerification::performOperation( + uint8_t operationCode){ + PusVerificationMessage message; + ReturnValue_t status = tmQueue->receiveMessage(&message); + while(status == HasReturnvaluesIF::RETURN_OK) { + status = sendVerificationReport(&message); + if(status != HasReturnvaluesIF::RETURN_OK) { + return status; + } + status = tmQueue->receiveMessage(&message); + } + if (status == MessageQueueIF::EMPTY) { + return HasReturnvaluesIF::RETURN_OK; + } + else { + return status; + } +} + + +ReturnValue_t Service1TelecommandVerification::sendVerificationReport( + PusVerificationMessage* message) { + ReturnValue_t result; + if(message->getReportId() % 2 == 0) { + result = generateFailureReport(message); + } else { + result = generateSuccessReport(message); + } + if(result != HasReturnvaluesIF::RETURN_OK){ + sif::error << "Service1TelecommandVerification::initialize: " + "Sending verification packet failed !" << std::endl; + } + return result; +} + +ReturnValue_t Service1TelecommandVerification::generateFailureReport( + PusVerificationMessage *message) { + FailureReport report( + message->getReportId(), message->getTcPacketId(), + message->getTcSequenceControl(), message->getStep(), + message->getErrorCode(), message->getParameter1(), + message->getParameter2()); + TmPacketStored tmPacket(apid, serviceId, message->getReportId(), + packetSubCounter++, &report); + ReturnValue_t result = tmPacket.sendPacket(tmQueue->getDefaultDestination(), + tmQueue->getId()); + return result; +} + +ReturnValue_t Service1TelecommandVerification::generateSuccessReport( + PusVerificationMessage *message) { + SuccessReport report(message->getReportId(),message->getTcPacketId(), + message->getTcSequenceControl(),message->getStep()); + TmPacketStored tmPacket(apid, serviceId, message->getReportId(), + packetSubCounter++, &report); + ReturnValue_t result = tmPacket.sendPacket(tmQueue->getDefaultDestination(), + tmQueue->getId()); + return result; +} + + +ReturnValue_t Service1TelecommandVerification::initialize() { + // Get target object for TC verification messages + AcceptsTelemetryIF* funnel = objectManager-> + get(targetDestination); + if(funnel == nullptr){ + sif::error << "Service1TelecommandVerification::initialize: Specified" + " TM funnel invalid. Make sure it is set up and implements" + " AcceptsTelemetryIF." << std::endl; + return ObjectManagerIF::CHILD_INIT_FAILED; + } + tmQueue->setDefaultDestination(funnel->getReportReceptionQueue()); + return SystemObject::initialize(); +} diff --git a/pus/Service1TelecommandVerification.h b/pus/Service1TelecommandVerification.h new file mode 100644 index 00000000..1d4b6719 --- /dev/null +++ b/pus/Service1TelecommandVerification.h @@ -0,0 +1,94 @@ +#ifndef MISSION_PUS_SERVICE1TELECOMMANDVERIFICATION_H_ +#define MISSION_PUS_SERVICE1TELECOMMANDVERIFICATION_H_ + +#include +#include +#include +#include +#include +#include + +/** + * @brief Verify TC acceptance, start, progress and execution. + * + * Full Documentation: ECSS-E70-41A p.51 + * + * The telecommand verification service provides the capability for + * explicit verification of each distinct stage of execution of a telecommand + * packet, from on-board acceptance through to completion of execution. + * + * Minimum capabilities of this service: + * + * - TM[1,1]: Telecommand Acceptance Report - Success. + * - TM[1,2]: Telecommand Acceptance Report - Failure. + * + * Additional capabilities of this service: + * + * - TM[1,3]: Telecommand Execution Started Report - Success (Req. 4). + * - TM[1,4]: Telecommand Execution Started Report - Failure (Req. 3). + * - TM[1,5]: Telecommand Execution Progress Report - Success (Req. 6). + * - TM[1,6]: Telecommand Execution Progress Report - Failure (Req. 5). + * - TM[1,7]: Telecommand Execution Completed Report - Success (Req. 8). + * - TM[1,8]: Telecommand Execution Completed Report - Failure (Req. 7). + * + * This Service is not inherited from PUSServiceBase unlike other PUS Services + * because all services implementing PUSServiceBase use this service to + * generate verification reports. + * @ingroup pus_services + */ +class Service1TelecommandVerification: public AcceptsVerifyMessageIF, + public SystemObject, + public ExecutableObjectIF, + public HasReturnvaluesIF { +public: + static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PUS_SERVICE_1; + + Service1TelecommandVerification(object_id_t objectId, + uint16_t apid, uint8_t serviceId, object_id_t targetDestination); + virtual ~Service1TelecommandVerification(); + + /** + * + * @return ID of Verification Queue + */ + virtual MessageQueueId_t getVerificationQueue(); + + /** + * Performs the service periodically as specified in init_mission(). + * Triggers the handlePacket function to send TC verification messages + * @param operationCode + * @return + */ + ReturnValue_t performOperation(uint8_t operationCode = 0) override; + + /** + * Initializes the destination for TC verification messages and initializes + * Service 1 as a system object + * @return + */ + ReturnValue_t initialize() override; +private: + uint16_t apid = 0; + uint8_t serviceId = 0; + + object_id_t targetDestination = objects::NO_OBJECT; + + ReturnValue_t sendVerificationReport(PusVerificationMessage* message); + ReturnValue_t generateFailureReport(PusVerificationMessage* message); + ReturnValue_t generateSuccessReport(PusVerificationMessage* message); + + uint16_t packetSubCounter = 0; + + MessageQueueIF* tmQueue = nullptr; + + enum class Subservice: uint8_t { + VERIFY_ACCEPTANCE_SUCCESS = 1, //!< [EXPORT] : [TM] + VERIFY_ACCEPTANCE_FAILED = 2, //!< [EXPORT] : [TM] + VERIFY_START_SUCCESS = 3, //!< [EXPORT] : [TM] + VERIFY_START_FAILED = 4, //!< [EXPORT] : [TM] + VERIFY_STEP_SUCCESS = 5, //!< [EXPORT] : [TM] + VERIFY_STEP_FAILED = 6 //!< [EXPORT] : [TM] + }; +}; + +#endif /* MISSION_PUS_SERVICE1TELECOMMANDVERIFICATION_H_ */ diff --git a/pus/Service5EventReporting.cpp b/pus/Service5EventReporting.cpp new file mode 100644 index 00000000..fe55059c --- /dev/null +++ b/pus/Service5EventReporting.cpp @@ -0,0 +1,92 @@ +#include +#include + +#include +#include +#include +#include + + +Service5EventReporting::Service5EventReporting(object_id_t objectId, + uint16_t apid, uint8_t serviceId, size_t maxNumberReportsPerCycle): + PusServiceBase(objectId, apid, serviceId), + maxNumberReportsPerCycle(maxNumberReportsPerCycle) { + eventQueue = QueueFactory::instance()->createMessageQueue(); +} + +Service5EventReporting::~Service5EventReporting(){} + +ReturnValue_t Service5EventReporting::performService() { + EventMessage message; + ReturnValue_t status = RETURN_OK; + for(uint8_t counter = 0; + counter < maxNumberReportsPerCycle; + counter++) + { + // Receive messages even if reporting is disabled for now. + status = eventQueue->receiveMessage(&message); + if(status == MessageQueueIF::EMPTY) { + return HasReturnvaluesIF::RETURN_OK; + } + + if(enableEventReport) { + status = generateEventReport(message); + if(status != HasReturnvaluesIF::RETURN_OK) { + return status; + } + } + } + sif::debug << "Service5EventReporting::generateEventReport:" + " Too many events" << std::endl; + return HasReturnvaluesIF::RETURN_OK; +} + + +ReturnValue_t Service5EventReporting::generateEventReport( + EventMessage message) +{ + EventReport report(message.getEventId(),message.getReporter(), + message.getParameter1(),message.getParameter2()); + TmPacketStored tmPacket(PusServiceBase::apid, PusServiceBase::serviceId, + message.getSeverity(), packetSubCounter++, &report); + ReturnValue_t result = tmPacket.sendPacket( + requestQueue->getDefaultDestination(),requestQueue->getId()); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::debug << "Service5EventReporting::generateEventReport:" + " Could not send TM packet" << std::endl; + } + return result; +} + +ReturnValue_t Service5EventReporting::handleRequest(uint8_t subservice) { + switch(subservice) + { + case Subservice::ENABLE: { + enableEventReport = true; + return HasReturnvaluesIF::RETURN_OK; + } + case Subservice::DISABLE: { + enableEventReport = false; + return HasReturnvaluesIF::RETURN_OK; + } + default: + return AcceptsTelecommandsIF::INVALID_SUBSERVICE; + } +} + + +// In addition to the default PUSServiceBase initialization, this service needs +// to be registered to the event manager to listen for events. +ReturnValue_t Service5EventReporting::initialize() { + EventManagerIF* manager = objectManager->get( + objects::EVENT_MANAGER); + if (manager == NULL) { + return RETURN_FAILED; + } + // register Service 5 as listener for events + ReturnValue_t result = manager->registerListener(eventQueue->getId(),true); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + return PusServiceBase::initialize(); +} diff --git a/pus/Service5EventReporting.h b/pus/Service5EventReporting.h new file mode 100644 index 00000000..79b7c5e7 --- /dev/null +++ b/pus/Service5EventReporting.h @@ -0,0 +1,86 @@ +#ifndef FRAMEWORK_PUS_SERVICE5EVENTREPORTING_H_ +#define FRAMEWORK_PUS_SERVICE5EVENTREPORTING_H_ + +#include +#include + +/** + * @brief Report on-board events like information or errors + * @details + * Full Documentation: ECSS-E70-41A p.79 + * Implements the PusServiceBase template class. + * Documentation: Dissertation Baetz p.135,136 + * + * This service provides for the reporting to the service user of information of + * operational significance. + * 1. reporting of failures or anomalies detected on-board; + * 2. reporting of autonomous on-board actions; + * 3. reporting of normal progress of operations and activities, e.g. + * detection of events which are not anomalous (such as payload events), + * reaching of predefined steps in an operation. Some reports can combine + * more than one of these events. + * + * Minimum capabilities of this service: + * + * - TM[5,1]: Normal/Progress Report + * - TM[5,2]: Error/Anomaly Report - Low Severity + * - TM[5,3]: Error/Anomaly Report - Medium Severity + * - TM[5,4]: Error/Anomaly Report - High Severity + * + * Events can be translated by using translator files located in + * /config/objects/ and /config/events/. Description to events can be added by + * adding a comment behind the event definition with [//!<] as leading string + * + * Additional capabilities of this service: + * + * - TC[5,5]: Enable Event Report Generation (Req. 6) + * - TC[5,6]: Disable Event Report Generation (Req. 5) + * @author R. Mueller + * @ingroup pus_services + */ +class Service5EventReporting: public PusServiceBase { +public: + + Service5EventReporting(object_id_t objectId, uint16_t apid, + uint8_t serviceId, size_t maxNumberReportsPerCycle = 10); + virtual ~Service5EventReporting(); + + /*** + * Check for events and generate event reports if required. + * @return + */ + ReturnValue_t performService() override; + + /*** + * Turn event generation on or off. + * @return + */ + ReturnValue_t handleRequest(uint8_t subservice) override; + + /** + * The default PusServiceBase initialize has been overridden but is still + * executed. Registers this service as a listener for events at the + * EventManager. + * @return + */ + ReturnValue_t initialize() override; + + enum Subservice: uint8_t { + NORMAL_REPORT = 1, //!< [EXPORT] : [REPLY] Generate normal report + ERROR_LOW_SEVERITY = 2, //!< [EXPORT] : [REPLY] Generate error report with low severity + ERROR_MED_SEVERITY = 3, //!< [EXPORT] : [REPLY] Generate error report with medium severity + ERROR_HIGH_SEVERITY = 4, //!< [EXPORT] : [REPLY] Generate error report with high severity + ENABLE = 5, //!< [EXPORT] : [COMMAND] Enable report generation + DISABLE = 6 //!< [EXPORT] : [COMMAND] Disable report generation + }; + +private: + uint16_t packetSubCounter = 0; + MessageQueueIF* eventQueue = nullptr; + bool enableEventReport = true; + const uint8_t maxNumberReportsPerCycle; + + ReturnValue_t generateEventReport(EventMessage message); +}; + +#endif /* MISSION_PUS_SERVICE5EVENTREPORTING_H_ */ diff --git a/pus/servicepackets/Service1Packets.h b/pus/servicepackets/Service1Packets.h new file mode 100644 index 00000000..b01942c6 --- /dev/null +++ b/pus/servicepackets/Service1Packets.h @@ -0,0 +1,166 @@ +/** + * @defgroup spacepackets PUS Packet Definitions + * This group contains all implemented TM or TM packages that are sent to + * or sent by the OBC.They are exported later to display + * packet structures in Mission Information Base (MIB). + */ + +#ifndef MISSION_PUS_SERVICEPACKETS_SERVICE1PACKETS_H_ +#define MISSION_PUS_SERVICEPACKETS_SERVICE1PACKETS_H_ + +#include +#include + +/** + * @brief FailureReport class to serialize a failure report + * @brief Subservice 1, 3, 5, 7 + * @ingroup spacepackets + */ +class FailureReport: public SerializeIF { //!< [EXPORT] : [SUBSERVICE] 1, 3, 5, 7 +public: + FailureReport(uint8_t failureSubtype_, uint16_t packetId_, + uint16_t packetSequenceControl_, uint8_t stepNumber_, + ReturnValue_t errorCode_, uint32_t errorParameter1_, + uint32_t errorParameter2_) : + packetId(packetId_), packetSequenceControl(packetSequenceControl_), + stepNumber(stepNumber_), errorCode(errorCode_), + errorParameter1(errorParameter1_), errorParameter2(errorParameter2_), + failureSubtype(failureSubtype_) {} + + /** + * This function is called by the FSFW when calling the tm packet send + * function and supplying the SerializeIF* as parameter + * @param buffer Object content is serialized into the buffer + * @param size + * @param max_size + * @param bigEndian + * @return + */ + virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, SerializeIF::Endianness streamEndianness + ) const override { + ReturnValue_t result = SerializeAdapter::serialize(&packetId, buffer, + size, maxSize, streamEndianness); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = SerializeAdapter::serialize(&packetSequenceControl, buffer, + size, maxSize, streamEndianness); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + if (failureSubtype == TC_VERIFY::PROGRESS_FAILURE) { + result = SerializeAdapter::serialize(&stepNumber, buffer, size, + maxSize, streamEndianness); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + } + result = SerializeAdapter::serialize(&errorCode, buffer, size, + maxSize, streamEndianness); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = SerializeAdapter::serialize(&errorParameter1, buffer, size, + maxSize, streamEndianness); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + + result = SerializeAdapter::serialize(&errorParameter2, buffer, size, + maxSize, streamEndianness); + return result; + } + + + virtual size_t getSerializedSize() const { + size_t size = 0; + size += SerializeAdapter::getSerializedSize(&packetId); + size += sizeof(packetSequenceControl); + if(failureSubtype==TC_VERIFY::PROGRESS_FAILURE){ + size += SerializeAdapter::getSerializedSize(&stepNumber); + } + size += SerializeAdapter::getSerializedSize(&errorCode); + size += SerializeAdapter::getSerializedSize(&errorParameter1); + size += SerializeAdapter::getSerializedSize(&errorParameter2); + return size; + } + + /** + * Deserialization is not allowed for a report. + * @param buffer + * @param size + * @param bigEndian + * @return + */ + ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + SerializeIF::Endianness streamEndianness) override { + return HasReturnvaluesIF::RETURN_FAILED; + } +private: + uint16_t packetId; //!< [EXPORT] : [COMMENT] Packet ID of respective Telecommand + uint16_t packetSequenceControl; //!< [EXPORT] : [COMMENT] Packet SSC of respective Telecommand + uint8_t stepNumber; //!< [EXPORT] : [OPTIONAL][SUBSERVICE] 6 + ReturnValue_t errorCode; //!< [EXPORT] : [COMMENT] Error code which can be looked up in generated error code file + uint32_t errorParameter1; + uint32_t errorParameter2; + const uint8_t failureSubtype; //!< [EXPORT] : [IGNORE] +}; + +/** + * @brief Subservices 2, 4, 6, 8 + * @ingroup spacepackets + */ +class SuccessReport: public SerializeIF { //!< [EXPORT] : [SUBSERVICE] 2, 4, 6, 8 +public: + SuccessReport(uint8_t subtype_, uint16_t packetId_, + uint16_t packetSequenceControl_,uint8_t stepNumber_) : + packetId(packetId_), packetSequenceControl(packetSequenceControl_), + stepNumber(stepNumber_), subtype(subtype_) {} + + virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, SerializeIF::Endianness streamEndianness + ) const override { + ReturnValue_t result = SerializeAdapter::serialize(&packetId, buffer, + size, maxSize, streamEndianness); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = SerializeAdapter::serialize(&packetSequenceControl, buffer, + size, maxSize, streamEndianness); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + if (subtype == TC_VERIFY::PROGRESS_SUCCESS) { + result = SerializeAdapter::serialize(&stepNumber, buffer, size, + maxSize, streamEndianness); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + } + return result; + } + + virtual size_t getSerializedSize() const override { + size_t size = 0; + size += SerializeAdapter::getSerializedSize(&packetId); + size += sizeof(packetSequenceControl); + if(subtype == TC_VERIFY::PROGRESS_SUCCESS){ + size += SerializeAdapter::getSerializedSize(&stepNumber); + } + return size; + + } + + ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + SerializeIF::Endianness streamEndianness) override { + return HasReturnvaluesIF::RETURN_FAILED; + } +private: + uint16_t packetId; //!< [EXPORT] : [COMMENT] Packet ID of respective Telecommand + uint16_t packetSequenceControl; //!< [EXPORT] : [COMMENT] Packet SSC of respective Telecommand + uint8_t stepNumber; //!< [EXPORT] : [OPTIONAL][SUBSERVICE] 6 + const uint8_t subtype; //!< [EXPORT] : [IGNORE] +}; + +#endif /* MISSION_PUS_SERVICEPACKETS_SERVICE1PACKETS_H_ */ diff --git a/pus/servicepackets/Service5Packets.h b/pus/servicepackets/Service5Packets.h new file mode 100644 index 00000000..f8f730c3 --- /dev/null +++ b/pus/servicepackets/Service5Packets.h @@ -0,0 +1,83 @@ +/** + * \file Service5Packets.h + * + * Structure of Event Report. + * It consists of: + * 1. Report ID(RID). This is the Event ID in the FSFW + * 2. Object ID of the reporter (e.g. subsystem) + * 2. Parameter 1 + * 3. Parameter 2 + * + * Created on: 21.05.2019 + * Author: R. Mueller, J. Meier + */ + +#ifndef MISSION_PUS_SERVICEPACKETS_SERVICE5PACKETS_H_ +#define MISSION_PUS_SERVICEPACKETS_SERVICE5PACKETS_H_ + +#include +#include + + +/** + * \brief Subservice 1, 2, 3, 4 + * \ingroup spacepackets + */ +class EventReport: public SerializeIF { //!< [EXPORT] : [SUBSERVICE] 1, 2, 3, 4 +public: + + EventReport(EventId_t reportId_, object_id_t objectId_, uint32_t parameter1_, + uint32_t parameter2_): + reportId(reportId_),objectId(objectId_), parameter1(parameter1_), + parameter2(parameter2_) {} + + virtual ReturnValue_t serialize(uint8_t** buffer, size_t* size, + size_t maxSize, + SerializeIF::Endianness streamEndianness) const override + { + ReturnValue_t result = SerializeAdapter::serialize(&reportId, buffer, + size, maxSize, streamEndianness); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = SerializeAdapter::serialize(&objectId, buffer, size, + maxSize, streamEndianness); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = SerializeAdapter::serialize(¶meter1, buffer, size, + maxSize, streamEndianness); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + result = SerializeAdapter::serialize(¶meter2, buffer, size, + maxSize, streamEndianness); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + return result; + } + + virtual size_t getSerializedSize() const override { + uint32_t size = 0; + size += SerializeAdapter::getSerializedSize(&reportId); + size += SerializeAdapter::getSerializedSize(&objectId); + size += SerializeAdapter::getSerializedSize(¶meter1); + size += SerializeAdapter::getSerializedSize(¶meter2); + return size; + + } + + virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + SerializeIF::Endianness streamEndianness) override { + return HasReturnvaluesIF::RETURN_FAILED; + } +private: + EventId_t reportId; + object_id_t objectId; + uint32_t parameter1; + uint32_t parameter2; +}; + + +#endif /* MISSION_PUS_SERVICEPACKETS_SERVICE5PACKETS_H_ */ From 7698f3f13e4ff5886c6c56145e56111a49a6ff4f Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 7 Jul 2020 17:18:33 +0200 Subject: [PATCH 239/307] moved srv2 to framework --- pus/Service2DeviceAccess.cpp | 178 +++++++++++++++++++++++++++ pus/Service2DeviceAccess.h | 96 +++++++++++++++ pus/servicepackets/Service2Packets.h | 76 ++++++++++++ pus/servicepackets/Service5Packets.h | 25 ++-- 4 files changed, 359 insertions(+), 16 deletions(-) create mode 100644 pus/Service2DeviceAccess.cpp create mode 100644 pus/Service2DeviceAccess.h create mode 100644 pus/servicepackets/Service2Packets.h diff --git a/pus/Service2DeviceAccess.cpp b/pus/Service2DeviceAccess.cpp new file mode 100644 index 00000000..5c6ad506 --- /dev/null +++ b/pus/Service2DeviceAccess.cpp @@ -0,0 +1,178 @@ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +Service2DeviceAccess::Service2DeviceAccess(object_id_t objectId, + uint16_t apid, uint8_t serviceId, object_id_t tcSource, + object_id_t tmDestination): + CommandingServiceBase(objectId, apid, serviceId, + NUM_OF_PARALLEL_COMMANDS, COMMAND_TIMEOUT_SECONDS, + tcSource, tmDestination) {} + +Service2DeviceAccess::~Service2DeviceAccess() {} + +ReturnValue_t Service2DeviceAccess::isValidSubservice(uint8_t subservice) { + switch(static_cast(subservice)){ + case Subservice::RAW_COMMANDING: + case Subservice::TOGGLE_WIRETAPPING: + return HasReturnvaluesIF::RETURN_OK; + default: + sif::error << "Invalid Subservice" << std::endl; + return AcceptsTelecommandsIF::INVALID_SUBSERVICE; + } +} + +ReturnValue_t Service2DeviceAccess::getMessageQueueAndObject( + uint8_t subservice, const uint8_t* tcData, size_t tcDataLen, + MessageQueueId_t* id, object_id_t* objectId) { + ReturnValue_t result = checkAndAcquireTargetID(objectId,tcData,tcDataLen); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + + result = checkInterfaceAndAcquireMessageQueue(id,objectId); + return result; + +} + +ReturnValue_t Service2DeviceAccess::checkAndAcquireTargetID( + object_id_t* objectIdToSet, const uint8_t* tcData, size_t tcDataLen) { + if(SerializeAdapter::deSerialize(objectIdToSet, &tcData, + &tcDataLen, SerializeIF::Endianness::BIG) != RETURN_OK) { + sif::error << "Service 2: Target ID not found. ID: " << + std::hex << objectIdToSet ; + return CommandingServiceBase::INVALID_TC; + } + else { + return HasReturnvaluesIF::RETURN_OK; + } +} + +ReturnValue_t Service2DeviceAccess::checkInterfaceAndAcquireMessageQueue( + MessageQueueId_t * messageQueueToSet, object_id_t *objectId) { + DeviceHandlerIF* possibleTarget = + objectManager->get(*objectId); + if(possibleTarget == nullptr) { + return CommandingServiceBase::INVALID_OBJECT; + } + *messageQueueToSet = possibleTarget->getCommandQueue(); + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t Service2DeviceAccess::prepareCommand(CommandMessage* message, + uint8_t subservice, const uint8_t* tcData, size_t tcDataLen, + uint32_t* state, object_id_t objectId) { + switch(static_cast(subservice)){ + case Subservice::RAW_COMMANDING: { + return prepareRawCommand(dynamic_cast(message), + tcData, tcDataLen); + } + break; + case Subservice::TOGGLE_WIRETAPPING: { + return prepareWiretappingCommand(dynamic_cast(message), + tcData, tcDataLen); + } + break; + default: + return HasReturnvaluesIF::RETURN_FAILED; + } +} + +ReturnValue_t Service2DeviceAccess::prepareRawCommand( + CommandMessage* messageToSet, const uint8_t *tcData,size_t tcDataLen) { + RawCommand RawCommand(tcData,tcDataLen); + // store command into the Inter Process Communication Store + store_address_t storeAddress; + ReturnValue_t result = IPCStore->addData(&storeAddress, + RawCommand.getCommand(), RawCommand.getCommandSize()); + DeviceHandlerMessage::setDeviceHandlerRawCommandMessage(messageToSet, + storeAddress); + return result; +} + +ReturnValue_t Service2DeviceAccess::prepareWiretappingCommand( + CommandMessage *messageToSet, const uint8_t *tcData, + size_t tcDataLen) { + if(tcDataLen != WiretappingToggle::WIRETAPPING_COMMAND_SIZE) { + return CommandingServiceBase::INVALID_TC; + } + WiretappingToggle command; + ReturnValue_t result = command.deSerialize(&tcData, &tcDataLen, + SerializeIF::Endianness::BIG); + DeviceHandlerMessage::setDeviceHandlerWiretappingMessage(messageToSet, + command.getWiretappingMode()); + return result; +} + +ReturnValue_t Service2DeviceAccess::handleReply(const CommandMessage* reply, + Command_t previousCommand, uint32_t* state, + CommandMessage* optionalNextCommand, object_id_t objectId, + bool* isStep) { + switch(reply->getCommand()) { + case CommandMessage::REPLY_COMMAND_OK: + return HasReturnvaluesIF::RETURN_OK; + case CommandMessage::REPLY_REJECTED: + return reply->getReplyRejectedReason(); + default: + return CommandingServiceBase::INVALID_REPLY; + } +} + +// All device handlers set service 2 as default raw receiver for wiretapping +// so we have to handle those unrequested messages. +void Service2DeviceAccess::handleUnrequestedReply(CommandMessage* reply) { + switch(reply->getCommand()) { + case DeviceHandlerMessage::REPLY_RAW_COMMAND: + sendWiretappingTm(reply, + static_cast(Subservice::WIRETAPPING_RAW_TC)); + break; + case DeviceHandlerMessage::REPLY_RAW_REPLY: + sendWiretappingTm(reply, + static_cast(Subservice::RAW_REPLY)); + break; + default: + sif::error << "Unknown message in Service2DeviceAccess::" + "handleUnrequestedReply with command ID " << + reply->getCommand() << std::endl; + break; + } + //Must be reached by all cases to clear message + reply->clear(); +} + +void Service2DeviceAccess::sendWiretappingTm(CommandMessage *reply, + uint8_t subservice) { + // Raw Wiretapping + // Get Address of Data from Message + store_address_t storeAddress = DeviceHandlerMessage::getStoreAddress(reply); + const uint8_t* data = nullptr; + size_t size = 0; + ReturnValue_t result = IPCStore->getData(storeAddress,&data,&size); + if(result != HasReturnvaluesIF::RETURN_OK){ + sif::error << "Service2DeviceAccess::sendWiretappingTm: Data Lost in " + "handleUnrequestedReply with failure ID "<< result + << std::endl; + return; + } + + // Init our dummy packet and correct endianness of object ID before + // sending it back. + WiretappingPacket TmPacket(DeviceHandlerMessage::getDeviceObjectId(reply), + data); + TmPacket.objectId = EndianConverter::convertBigEndian(TmPacket.objectId); + sendTmPacket(subservice,TmPacket.data,size,reinterpret_cast( + &TmPacket.objectId),sizeof(TmPacket.objectId)); +} + +MessageQueueId_t Service2DeviceAccess::getDeviceQueue() { + return commandQueue->getId(); +} + diff --git a/pus/Service2DeviceAccess.h b/pus/Service2DeviceAccess.h new file mode 100644 index 00000000..ecab6101 --- /dev/null +++ b/pus/Service2DeviceAccess.h @@ -0,0 +1,96 @@ +#ifndef FRAMEWORK_PUS_SERVICE2DEVICEACCESS_H_ +#define FRAMEWORK_PUS_SERVICE2DEVICEACCESS_H_ + +#include +#include +#include + +/** + * @brief Raw Commanding and Wiretapping of devices. + * @details + * Full Documentation: ECSS-E-ST-70-41C or ECSS-E-70-41A + * Dissertation Baetz p. 115, 116, 165-167. + * + * This service provides the capability to communicate with devices in their + * native protocols with raw commands through the DeviceHandlerIF. + * + * This is a gateway service. It relays device commands using the software bus. + * This service is very closely tied to the Commanding Service Base + * template class. There is constant interaction between this Service Base und + * a Subclass like this service + * There are 4 adaption points for component implementation through the + * Commanding Service Base. + * + * This service employs custom subservices exclusively. This includes a + * wiretapping subservice to monitor all traffic between target devices and + * this service. + * + * - TC[2,128]: Raw Commanding + * - TC[2,129]: Toggle Wiretapping + * - TM[2,130]: Wiretapping Packet TM + * - TM[2,131]: Wiretapping Packet TC + * @ingroup pus_services + */ +class Service2DeviceAccess : public CommandingServiceBase, + public AcceptsDeviceResponsesIF +{ +public: + Service2DeviceAccess(object_id_t objectId, uint16_t apid, + uint8_t serviceId, object_id_t tcSource, + object_id_t tmDestination); + virtual ~Service2DeviceAccess(); + + static constexpr uint8_t NUM_OF_PARALLEL_COMMANDS = 4; + static constexpr uint16_t COMMAND_TIMEOUT_SECONDS = 60; +protected: + //! CommandingServiceBase (CSB) abstract functions. See CSB documentation. + ReturnValue_t isValidSubservice(uint8_t subservice) override; + ReturnValue_t getMessageQueueAndObject(uint8_t subservice, + const uint8_t *tcData, size_t tcDataLen, MessageQueueId_t *id, + object_id_t *objectId) override; + ReturnValue_t prepareCommand(CommandMessage* message, uint8_t subservice, + const uint8_t *tcData, size_t tcDataLen, uint32_t *state, + object_id_t objectId) override; + ReturnValue_t handleReply(const CommandMessage* reply, + Command_t previousCommand, uint32_t *state, + CommandMessage* optionalNextCommand, object_id_t objectId, + bool *isStep) override; + + /** + * @brief Generates TM packets containing either the TC wiretapping + * packets or the TM wiretapping packets. + * Note that for service 2, all telemetry will be treated as an + * unrequested reply regardless of wiretapping mode. + * @param reply + */ + void handleUnrequestedReply(CommandMessage* reply) override; + + MessageQueueId_t getDeviceQueue() override; +private: + /** + * Generates TM packets for Wiretapping Service + * @param reply + * @param subservice + */ + void sendWiretappingTm(CommandMessage* reply,uint8_t subservice); + + ReturnValue_t checkAndAcquireTargetID(object_id_t* objectIdToSet, + const uint8_t* tcData, size_t tcDataLen); + ReturnValue_t checkInterfaceAndAcquireMessageQueue( + MessageQueueId_t* messageQueueToSet, object_id_t* objectId); + + ReturnValue_t prepareRawCommand(CommandMessage* messageToSet, + const uint8_t* tcData, size_t tcDataLen); + ReturnValue_t prepareWiretappingCommand(CommandMessage* messageToSet, + const uint8_t* tcData, size_t tcDataLen); + + enum class Subservice { + RAW_COMMANDING = 128, //!< [EXPORT] : [COMMAND] Command in device native protocol + TOGGLE_WIRETAPPING = 129, //!< [EXPORT] : [COMMAND] Toggle wiretapping of raw communication + RAW_REPLY = 130, //!< [EXPORT] : [REPLY] Includes wiretapping TM and normal TM raw replies from device + WIRETAPPING_RAW_TC = 131 //!< [EXPORT] : [REPLY] Wiretapping packets of commands built by device handler + }; +}; + + +#endif /* MISSION_PUS_DEVICE2DEVICECOMMANDING_H_ */ diff --git a/pus/servicepackets/Service2Packets.h b/pus/servicepackets/Service2Packets.h new file mode 100644 index 00000000..f292611e --- /dev/null +++ b/pus/servicepackets/Service2Packets.h @@ -0,0 +1,76 @@ +#ifndef FRAMEWORK_PUS_SERVICEPACKETS_SERVICE2PACKETS_H_ +#define FRAMEWORK_PUS_SERVICEPACKETS_SERVICE2PACKETS_H_ + +#include +#include +#include +#include + +/** + * @brief Subservice 128 + * @ingroup spacepackets + */ +class RawCommand { //!< [EXPORT] : [SUBSERVICE] 128 +public: + RawCommand(const uint8_t* buffer, size_t size) { + // Deserialize Adapter to get correct endianness + SerializeAdapter::deSerialize(&objectId, &buffer, &size, + SerializeIF::Endianness::BIG); + commandBuffer = buffer; + // size is decremented by AutoSerializeAdapter, + // remaining size is data size + dataSize = size; + } + object_id_t getObjectId() const { + return objectId; + } + + const uint8_t* getCommand() { + return commandBuffer; + } + + size_t getCommandSize() const { + return dataSize; + } +private: + object_id_t objectId = 0; + const uint8_t* commandBuffer = nullptr; //!< [EXPORT] : [MAXSIZE] 256 Bytes + size_t dataSize = 0; //!< [EXPORT] : [IGNORE] +}; + + +/** + * @brief Subservice 129: Command packet to set wiretapping mode + * @ingroup spacepackets + */ +class WiretappingToggle: public SerialLinkedListAdapter{ //!< [EXPORT] : [SUBSERVICE] 129 +public: + static const size_t WIRETAPPING_COMMAND_SIZE = 5; + WiretappingToggle(){ + setStart(&objectId); + objectId.setNext(&wiretappingMode); + } + + uint8_t getWiretappingMode() const { + return wiretappingMode.entry; + } +private: + SerializeElement objectId; + SerializeElement wiretappingMode; //!< [EXPORT] : [INPUT] Mode 0: OFF, Mode 1: RAW +}; + + +/** + * @brief Subservices 130 and 131: TM packets + * @ingroup spacepackets + */ +class WiretappingPacket { //!< [EXPORT] : [SUBSERVICE] 130, 131 +public: + object_id_t objectId; //!< [EXPORT] : [COMMENT] Object ID of source object + const uint8_t* data; //!< [EXPORT] : [MAXSIZE] Raw Command Max. Size + WiretappingPacket(object_id_t objectId, const uint8_t* buffer): + objectId(objectId), data(buffer) { + } +}; + +#endif /* FRAMEWORK_PUS_SERVICEPACKETS_SERVICE2PACKETS_H_ */ diff --git a/pus/servicepackets/Service5Packets.h b/pus/servicepackets/Service5Packets.h index f8f730c3..14219c93 100644 --- a/pus/servicepackets/Service5Packets.h +++ b/pus/servicepackets/Service5Packets.h @@ -1,17 +1,3 @@ -/** - * \file Service5Packets.h - * - * Structure of Event Report. - * It consists of: - * 1. Report ID(RID). This is the Event ID in the FSFW - * 2. Object ID of the reporter (e.g. subsystem) - * 2. Parameter 1 - * 3. Parameter 2 - * - * Created on: 21.05.2019 - * Author: R. Mueller, J. Meier - */ - #ifndef MISSION_PUS_SERVICEPACKETS_SERVICE5PACKETS_H_ #define MISSION_PUS_SERVICEPACKETS_SERVICE5PACKETS_H_ @@ -20,8 +6,15 @@ /** - * \brief Subservice 1, 2, 3, 4 - * \ingroup spacepackets + * @brief Subservice 1, 2, 3, 4 + * Structure of Event Report. + * It consists of: + * 1. Report ID(RID). This is the Event ID in the FSFW + * 2. Object ID of the reporter (e.g. subsystem) + * 2. Parameter 1 + * 3. Parameter 2 + * + * @ingroup spacepackets */ class EventReport: public SerializeIF { //!< [EXPORT] : [SUBSERVICE] 1, 2, 3, 4 public: From 684b56ac883b0ee0528edc55b492977518611430 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 7 Jul 2020 17:21:47 +0200 Subject: [PATCH 240/307] srv2 tweak: CSB params now configurable --- pus/Service2DeviceAccess.cpp | 5 +++-- pus/Service2DeviceAccess.h | 15 +++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/pus/Service2DeviceAccess.cpp b/pus/Service2DeviceAccess.cpp index 5c6ad506..d1f8faf3 100644 --- a/pus/Service2DeviceAccess.cpp +++ b/pus/Service2DeviceAccess.cpp @@ -12,9 +12,10 @@ Service2DeviceAccess::Service2DeviceAccess(object_id_t objectId, uint16_t apid, uint8_t serviceId, object_id_t tcSource, - object_id_t tmDestination): + object_id_t tmDestination, uint8_t numberOfParallelCommands, + uint16_t commandTimeoutSeconds): CommandingServiceBase(objectId, apid, serviceId, - NUM_OF_PARALLEL_COMMANDS, COMMAND_TIMEOUT_SECONDS, + numberOfParallelCommands, commandTimeoutSeconds, tcSource, tmDestination) {} Service2DeviceAccess::~Service2DeviceAccess() {} diff --git a/pus/Service2DeviceAccess.h b/pus/Service2DeviceAccess.h index ecab6101..20fc30b9 100644 --- a/pus/Service2DeviceAccess.h +++ b/pus/Service2DeviceAccess.h @@ -14,12 +14,12 @@ * This service provides the capability to communicate with devices in their * native protocols with raw commands through the DeviceHandlerIF. * - * This is a gateway service. It relays device commands using the software bus. - * This service is very closely tied to the Commanding Service Base - * template class. There is constant interaction between this Service Base und - * a Subclass like this service + * This is a gateway service. It relays device commands to the software bus. + * This service is very closely tied to the CommandingServiceBase + * template class. + * * There are 4 adaption points for component implementation through the - * Commanding Service Base. + * CommandingServiceBase. * * This service employs custom subservices exclusively. This includes a * wiretapping subservice to monitor all traffic between target devices and @@ -37,11 +37,10 @@ class Service2DeviceAccess : public CommandingServiceBase, public: Service2DeviceAccess(object_id_t objectId, uint16_t apid, uint8_t serviceId, object_id_t tcSource, - object_id_t tmDestination); + object_id_t tmDestination, uint8_t numberOfParallelCommands = 4, + uint16_t commandTimeoutSeconds = 60); virtual ~Service2DeviceAccess(); - static constexpr uint8_t NUM_OF_PARALLEL_COMMANDS = 4; - static constexpr uint16_t COMMAND_TIMEOUT_SECONDS = 60; protected: //! CommandingServiceBase (CSB) abstract functions. See CSB documentation. ReturnValue_t isValidSubservice(uint8_t subservice) override; From 06d389ed1e6157f1fe736c5dacf121eec247ea14 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 7 Jul 2020 17:25:52 +0200 Subject: [PATCH 241/307] increased srv2 readability --- pus/Service2DeviceAccess.cpp | 24 ++++++------------------ pus/Service2DeviceAccess.h | 2 -- 2 files changed, 6 insertions(+), 20 deletions(-) diff --git a/pus/Service2DeviceAccess.cpp b/pus/Service2DeviceAccess.cpp index d1f8faf3..ee48b46d 100644 --- a/pus/Service2DeviceAccess.cpp +++ b/pus/Service2DeviceAccess.cpp @@ -34,29 +34,17 @@ ReturnValue_t Service2DeviceAccess::isValidSubservice(uint8_t subservice) { ReturnValue_t Service2DeviceAccess::getMessageQueueAndObject( uint8_t subservice, const uint8_t* tcData, size_t tcDataLen, MessageQueueId_t* id, object_id_t* objectId) { - ReturnValue_t result = checkAndAcquireTargetID(objectId,tcData,tcDataLen); - if(result != HasReturnvaluesIF::RETURN_OK) { - return result; - } + if(tcDataLen < sizeof(object_id_t)) { + return CommandingServiceBase::INVALID_TC; + } + SerializeAdapter::deSerialize(objectId, &tcData, + &tcDataLen, SerializeIF::Endianness::BIG); - result = checkInterfaceAndAcquireMessageQueue(id,objectId); + ReturnValue_t result = checkInterfaceAndAcquireMessageQueue(id,objectId); return result; } -ReturnValue_t Service2DeviceAccess::checkAndAcquireTargetID( - object_id_t* objectIdToSet, const uint8_t* tcData, size_t tcDataLen) { - if(SerializeAdapter::deSerialize(objectIdToSet, &tcData, - &tcDataLen, SerializeIF::Endianness::BIG) != RETURN_OK) { - sif::error << "Service 2: Target ID not found. ID: " << - std::hex << objectIdToSet ; - return CommandingServiceBase::INVALID_TC; - } - else { - return HasReturnvaluesIF::RETURN_OK; - } -} - ReturnValue_t Service2DeviceAccess::checkInterfaceAndAcquireMessageQueue( MessageQueueId_t * messageQueueToSet, object_id_t *objectId) { DeviceHandlerIF* possibleTarget = diff --git a/pus/Service2DeviceAccess.h b/pus/Service2DeviceAccess.h index 20fc30b9..4dab0fa0 100644 --- a/pus/Service2DeviceAccess.h +++ b/pus/Service2DeviceAccess.h @@ -73,8 +73,6 @@ private: */ void sendWiretappingTm(CommandMessage* reply,uint8_t subservice); - ReturnValue_t checkAndAcquireTargetID(object_id_t* objectIdToSet, - const uint8_t* tcData, size_t tcDataLen); ReturnValue_t checkInterfaceAndAcquireMessageQueue( MessageQueueId_t* messageQueueToSet, object_id_t* objectId); From dd48f7ccadc824b275ea3bf2af0da1c9820ad61b Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 7 Jul 2020 17:28:00 +0200 Subject: [PATCH 242/307] some form improvements --- pus/Service2DeviceAccess.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pus/Service2DeviceAccess.cpp b/pus/Service2DeviceAccess.cpp index ee48b46d..391c1116 100644 --- a/pus/Service2DeviceAccess.cpp +++ b/pus/Service2DeviceAccess.cpp @@ -144,7 +144,7 @@ void Service2DeviceAccess::sendWiretappingTm(CommandMessage *reply, store_address_t storeAddress = DeviceHandlerMessage::getStoreAddress(reply); const uint8_t* data = nullptr; size_t size = 0; - ReturnValue_t result = IPCStore->getData(storeAddress,&data,&size); + ReturnValue_t result = IPCStore->getData(storeAddress, &data, &size); if(result != HasReturnvaluesIF::RETURN_OK){ sif::error << "Service2DeviceAccess::sendWiretappingTm: Data Lost in " "handleUnrequestedReply with failure ID "<< result @@ -157,8 +157,8 @@ void Service2DeviceAccess::sendWiretappingTm(CommandMessage *reply, WiretappingPacket TmPacket(DeviceHandlerMessage::getDeviceObjectId(reply), data); TmPacket.objectId = EndianConverter::convertBigEndian(TmPacket.objectId); - sendTmPacket(subservice,TmPacket.data,size,reinterpret_cast( - &TmPacket.objectId),sizeof(TmPacket.objectId)); + sendTmPacket(subservice, TmPacket.data,size, reinterpret_cast( + &TmPacket.objectId), sizeof(TmPacket.objectId)); } MessageQueueId_t Service2DeviceAccess::getDeviceQueue() { From 399fc0e287048b1fb8e1343185d637c78a791a80 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 7 Jul 2020 17:42:37 +0200 Subject: [PATCH 243/307] fifo replacements --- container/DynamicFIFO.h | 27 +++++++++++++++++++++++++ container/FIFO.h | 23 +++++++++------------ container/FIFOBase.h | 4 ---- container/SimpleRingBuffer.cpp | 6 +++--- container/SimpleRingBuffer.h | 2 +- container/StaticFIFO.h | 30 ---------------------------- tmtcservices/CommandingServiceBase.h | 4 ++-- tmtcservices/PusParser.cpp | 2 +- tmtcservices/PusParser.h | 7 +++---- tmtcservices/TmTcBridge.h | 4 ++-- 10 files changed, 48 insertions(+), 61 deletions(-) create mode 100644 container/DynamicFIFO.h delete mode 100644 container/StaticFIFO.h diff --git a/container/DynamicFIFO.h b/container/DynamicFIFO.h new file mode 100644 index 00000000..3a5242c7 --- /dev/null +++ b/container/DynamicFIFO.h @@ -0,0 +1,27 @@ +#ifndef FRAMEWORK_CONTAINER_DYNAMICFIFO_H_ +#define FRAMEWORK_CONTAINER_DYNAMICFIFO_H_ + +#include +#include + +/** + * @brief Simple First-In-First-Out data structure. The maximum size + * can be set in the constructor. + * @details + * The maximum capacity can be determined at run-time, so this container + * performs dynamic memory allocation! + * The public interface of FIFOBase exposes the user interface for the FIFO. + * @tparam T Entry Type + * @tparam capacity Maximum capacity + */ +template +class DynamicFIFO: public FIFOBase { +public: + DynamicFIFO(size_t maxCapacity): FIFOBase(values.data(), maxCapacity), + values(maxCapacity) {}; + +private: + std::vector values; +}; + +#endif /* FRAMEWORK_CONTAINER_DYNAMICFIFO_H_ */ diff --git a/container/FIFO.h b/container/FIFO.h index 19daaf1b..ecb218fd 100644 --- a/container/FIFO.h +++ b/container/FIFO.h @@ -1,31 +1,26 @@ #ifndef FRAMEWORK_CONTAINER_FIFO_H_ #define FRAMEWORK_CONTAINER_FIFO_H_ +#include #include -#include - -namespace fsfw { +#include /** - * @brief Simple First-In-First-Out data structure. The maximum size - * can be set in the constructor. + * @brief Simple First-In-First-Out data structure with size fixed at + * compile time * @details - * The maximum capacity can be determined at run-time, so this container - * performs dynamic memory allocation! + * Performs no dynamic memory allocation. * The public interface of FIFOBase exposes the user interface for the FIFO. * @tparam T Entry Type * @tparam capacity Maximum capacity */ -template +template class FIFO: public FIFOBase { public: - FIFO(size_t maxCapacity): FIFOBase(values.data(), maxCapacity), - values(maxCapacity) {}; + FIFO(): FIFOBase(values.data(), capacity) {}; private: - std::vector values; + std::array values; }; -} - -#endif /* FRAMEWORK_CONTAINER_FIFO_H_ */ +#endif /* FRAMEWORK_CONTAINERS_STATICFIFO_H_ */ diff --git a/container/FIFOBase.h b/container/FIFOBase.h index 6ed7d924..8bdb333f 100644 --- a/container/FIFOBase.h +++ b/container/FIFOBase.h @@ -4,8 +4,6 @@ #include #include -namespace fsfw { - template class FIFOBase { public: @@ -60,6 +58,4 @@ private: #include -} - #endif /* FRAMEWORK_CONTAINER_FIFOBASE_H_ */ diff --git a/container/SimpleRingBuffer.cpp b/container/SimpleRingBuffer.cpp index 4e50109b..731c9dc9 100644 --- a/container/SimpleRingBuffer.cpp +++ b/container/SimpleRingBuffer.cpp @@ -17,7 +17,7 @@ SimpleRingBuffer::~SimpleRingBuffer() { ReturnValue_t SimpleRingBuffer::writeData(const uint8_t* data, uint32_t amount) { - if (availableWriteSpace() >= amount || overwriteOld) { + if (availableWriteSpace() >= amount or overwriteOld) { uint32_t amountTillWrap = writeTillWrap(); if (amountTillWrap >= amount) { memcpy(&buffer[write], data, amount); @@ -43,7 +43,7 @@ ReturnValue_t SimpleRingBuffer::readData(uint8_t* data, uint32_t amount, return HasReturnvaluesIF::RETURN_FAILED; } } - if (trueAmount != NULL) { + if (trueAmount != nullptr) { *trueAmount = amount; } if (amountTillWrap >= amount) { @@ -65,7 +65,7 @@ ReturnValue_t SimpleRingBuffer::deleteData(uint32_t amount, return HasReturnvaluesIF::RETURN_FAILED; } } - if (trueAmount != NULL) { + if (trueAmount != nullptr) { *trueAmount = amount; } incrementRead(amount, READ_PTR); diff --git a/container/SimpleRingBuffer.h b/container/SimpleRingBuffer.h index b5bc2c1c..30dd184c 100644 --- a/container/SimpleRingBuffer.h +++ b/container/SimpleRingBuffer.h @@ -2,7 +2,7 @@ #define FRAMEWORK_CONTAINER_SIMPLERINGBUFFER_H_ #include -#include +#include /** * @brief Circular buffer implementation, useful for buffering diff --git a/container/StaticFIFO.h b/container/StaticFIFO.h deleted file mode 100644 index f3128200..00000000 --- a/container/StaticFIFO.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef FRAMEWORK_CONTAINER_STATICFIFO_H_ -#define FRAMEWORK_CONTAINER_STATICFIFO_H_ - -#include -#include -#include - -namespace fsfw { - -/** - * @brief Simple First-In-First-Out data structure with size fixed at - * compile time - * @details - * Performs no dynamic memory allocation. - * The public interface of FIFOBase exposes the user interface for the FIFO. - * @tparam T Entry Type - * @tparam capacity Maximum capacity - */ -template -class StaticFIFO: public FIFOBase { -public: - StaticFIFO(): FIFOBase(values.data(), capacity) {}; - -private: - std::array values; -}; - -} - -#endif /* FRAMEWORK_CONTAINERS_STATICFIFO_H_ */ diff --git a/tmtcservices/CommandingServiceBase.h b/tmtcservices/CommandingServiceBase.h index 72fe13f2..700503c6 100644 --- a/tmtcservices/CommandingServiceBase.h +++ b/tmtcservices/CommandingServiceBase.h @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include class TcPacketStored; @@ -199,7 +199,7 @@ protected: uint32_t state; Command_t command; object_id_t objectId; - fsfw::StaticFIFO fifo; + FIFO fifo; }; using CommandMapIter = FixedMap* PusParser::fifo(){ +DynamicFIFO* PusParser::fifo(){ return &indexSizePairFIFO; } diff --git a/tmtcservices/PusParser.h b/tmtcservices/PusParser.h index 82aff57e..88570bb2 100644 --- a/tmtcservices/PusParser.h +++ b/tmtcservices/PusParser.h @@ -1,8 +1,7 @@ #ifndef FRAMEWORK_TMTCSERVICES_PUSPARSER_H_ #define FRAMEWORK_TMTCSERVICES_PUSPARSER_H_ -#include - +#include #include #include @@ -55,7 +54,7 @@ public: * by the parsePusPackets() function. * @return */ - fsfw::FIFO* fifo(); + DynamicFIFO* fifo(); /** * Retrieve the next index and packet size pair from the FIFO. @@ -69,7 +68,7 @@ private: //! A FIFO is used to store information about multiple PUS packets //! inside the receive buffer. The maximum number of entries is defined //! by the first constructor argument. - fsfw::FIFO indexSizePairFIFO; + DynamicFIFO indexSizePairFIFO; bool storeSplitPackets = false; diff --git a/tmtcservices/TmTcBridge.h b/tmtcservices/TmTcBridge.h index 23f7dcfa..5b933c79 100644 --- a/tmtcservices/TmTcBridge.h +++ b/tmtcservices/TmTcBridge.h @@ -1,6 +1,7 @@ #ifndef FRAMEWORK_TMTCSERVICES_TMTCBRIDGE_H_ #define FRAMEWORK_TMTCSERVICES_TMTCBRIDGE_H_ +#include #include #include #include @@ -8,7 +9,6 @@ #include #include -#include class TmTcBridge : public AcceptsTelemetryIF, public ExecutableObjectIF, @@ -143,7 +143,7 @@ protected: * This fifo can be used to store downlink data * which can not be sent at the moment. */ - fsfw::StaticFIFO tmFifo; + FIFO tmFifo; uint8_t sentPacketsPerCycle = DEFAULT_STORED_DATA_SENT_PER_CYCLE; uint8_t maxNumberOfPacketsStored = DEFAULT_DOWNLINK_PACKETS_STORED; }; From 2efcda735f84166665c2c1b42dc604048a7bbb34 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 8 Jul 2020 02:20:38 +0200 Subject: [PATCH 244/307] message arriving. big clean up in tcdistribution folder --- osal/linux/TcUnixUdpPollingTask.cpp | 73 +++++++++++----- osal/linux/TcUnixUdpPollingTask.h | 13 ++- osal/linux/TmTcUnixUdpBridge.cpp | 15 ++-- osal/linux/TmTcUnixUdpBridge.h | 2 +- tcdistribution/CCSDSDistributor.cpp | 39 +++++---- tcdistribution/CCSDSDistributor.h | 87 ++++++++++--------- tcdistribution/PUSDistributor.cpp | 4 +- tcdistribution/PUSDistributor.h | 52 +++++++----- tcdistribution/TcDistributor.cpp | 5 +- tcdistribution/TcDistributor.h | 124 ++++++++++++++-------------- tmtcservices/PusServiceBase.cpp | 11 ++- tmtcservices/TmTcBridge.h | 2 +- 12 files changed, 253 insertions(+), 174 deletions(-) diff --git a/osal/linux/TcUnixUdpPollingTask.cpp b/osal/linux/TcUnixUdpPollingTask.cpp index f237a0f2..83f7a3da 100644 --- a/osal/linux/TcUnixUdpPollingTask.cpp +++ b/osal/linux/TcUnixUdpPollingTask.cpp @@ -1,6 +1,7 @@ #include +#include -TcSocketPollingTask::TcSocketPollingTask(object_id_t objectId, +TcUnixUdpPollingTask::TcUnixUdpPollingTask(object_id_t objectId, object_id_t tmtcUnixUdpBridge, size_t frameSize, double timeoutSeconds): SystemObject(objectId), tmtcBridgeId(tmtcUnixUdpBridge) { @@ -23,23 +24,13 @@ TcSocketPollingTask::TcSocketPollingTask(object_id_t objectId, else { receptionTimeout = timevalOperations::toTimeval(timeoutSeconds); } - - // Set receive timeout. - int result = setsockopt(serverUdpSocket, SOL_SOCKET, SO_RCVTIMEO, - &receptionTimeout, sizeof(receptionTimeout)); - if(result == -1) { - sif::error << "TcSocketPollingTask::TcSocketPollingTask: Setting receive" - "timeout failed with " << strerror(errno) << std::endl; - return; - } } -TcSocketPollingTask::~TcSocketPollingTask() { +TcUnixUdpPollingTask::~TcUnixUdpPollingTask() { } -ReturnValue_t TcSocketPollingTask::performOperation(uint8_t opCode) { - // Poll for new data permanently. The call will block until the specified - // length of bytes has been received or a timeout occured. +ReturnValue_t TcUnixUdpPollingTask::performOperation(uint8_t opCode) { + // Poll for new UDP datagrams in permanent loop. while(1) { //! Sender Address is cached here. struct sockaddr_in senderAddress; @@ -48,21 +39,34 @@ ReturnValue_t TcSocketPollingTask::performOperation(uint8_t opCode) { receptionBuffer.data(), frameSize, receptionFlags, reinterpret_cast(&senderAddress), &senderSockLen); if(bytesReceived < 0) { - //handle error + // handle error sif::error << "TcSocketPollingTask::performOperation: recvfrom " "failed with " << strerror(errno) << std::endl; + if(errno == EAGAIN or errno == EWOULDBLOCK) { + sif::info << "timeout" << std::endl; + } continue; } sif::debug << "TcSocketPollingTask::performOperation: " << bytesReceived << " bytes received" << std::endl; - ReturnValue_t result = handleSuccessfullTcRead(); + ReturnValue_t result = handleSuccessfullTcRead(bytesReceived); + if(result != HasReturnvaluesIF::RETURN_FAILED) { + + } tmtcBridge->checkAndSetClientAddress(senderAddress); } return HasReturnvaluesIF::RETURN_OK; } -ReturnValue_t TcSocketPollingTask::initialize() { +ReturnValue_t TcUnixUdpPollingTask::initialize() { + tcStore = objectManager->get(objects::TC_STORE); + if (tcStore == nullptr) { + sif::error << "TcSerialPollingTask::initialize: TC Store uninitialized!" + << std::endl; + return ObjectManagerIF::CHILD_INIT_FAILED; + } + tmtcBridge = objectManager->get(tmtcBridgeId); if(tmtcBridge == nullptr) { sif::error << "TcSocketPollingTask::TcSocketPollingTask: Invalid" @@ -70,10 +74,41 @@ ReturnValue_t TcSocketPollingTask::initialize() { return ObjectManagerIF::CHILD_INIT_FAILED; } + targetTcDestination = tmtcBridge->getReportReceptionQueue(); + serverUdpSocket = tmtcBridge->serverSocket; + + // Set receive timeout. +// int result = setsockopt(serverUdpSocket, SOL_SOCKET, SO_RCVTIMEO, +// &receptionTimeout, sizeof(receptionTimeout)); +// if(result == -1) { +// sif::error << "TcSocketPollingTask::TcSocketPollingTask: Setting " +// "receive timeout failed with " << strerror(errno) << std::endl; +// return ObjectManagerIF::CHILD_INIT_FAILED; +// } return HasReturnvaluesIF::RETURN_OK; } -ReturnValue_t TcSocketPollingTask::handleSuccessfullTcRead() { - return HasReturnvaluesIF::RETURN_OK; +ReturnValue_t TcUnixUdpPollingTask::handleSuccessfullTcRead(size_t bytesRead) { + store_address_t storeId = 0; + ReturnValue_t result = tcStore->addData(&storeId, + receptionBuffer.data(), bytesRead); + // arrayprinter::print(receptionBuffer.data(), bytesRead); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::debug << "TcSerialPollingTask::transferPusToSoftwareBus: Data " + "storage failed" << std::endl; + sif::debug << "Packet size: " << bytesRead << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + + TmTcMessage message(storeId); + result = MessageQueueSenderIF::sendMessage(targetTcDestination, &message); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "Serial Polling: Sending message to queue failed" + << std::endl; + tcStore->deleteData(storeId); + } + return result; } + + diff --git a/osal/linux/TcUnixUdpPollingTask.h b/osal/linux/TcUnixUdpPollingTask.h index a6b0e9d4..3503d505 100644 --- a/osal/linux/TcUnixUdpPollingTask.h +++ b/osal/linux/TcUnixUdpPollingTask.h @@ -1,5 +1,6 @@ #ifndef FRAMEWORK_OSAL_LINUX_TCSOCKETPOLLINGTASK_H_ #define FRAMEWORK_OSAL_LINUX_TCSOCKETPOLLINGTASK_H_ + #include #include #include @@ -16,7 +17,7 @@ * This class caches the IP address of the sender. It is assumed there * is only one sender for now. */ -class TcSocketPollingTask: public SystemObject, +class TcUnixUdpPollingTask: public SystemObject, public ExecutableObjectIF { friend class TmTcUnixUdpBridge; public: @@ -24,17 +25,21 @@ public: //! 0.5 default milliseconds timeout for now. static constexpr timeval DEFAULT_TIMEOUT = {.tv_sec = 0, .tv_usec = 500}; - TcSocketPollingTask(object_id_t objectId, object_id_t tmtcUnixUdpBridge, + TcUnixUdpPollingTask(object_id_t objectId, object_id_t tmtcUnixUdpBridge, size_t frameSize = 0, double timeoutSeconds = -1); - virtual~ TcSocketPollingTask(); + virtual~ TcUnixUdpPollingTask(); virtual ReturnValue_t performOperation(uint8_t opCode) override; virtual ReturnValue_t initialize() override; +protected: + StorageManagerIF* tcStore = nullptr; + private: //! TMTC bridge is cached. object_id_t tmtcBridgeId = objects::NO_OBJECT; TmTcUnixUdpBridge* tmtcBridge = nullptr; + MessageQueueId_t targetTcDestination = MessageQueueIF::NO_QUEUE; //! Reception flags: https://linux.die.net/man/2/recvfrom. int receptionFlags = 0; @@ -47,7 +52,7 @@ private: size_t frameSize = 0; timeval receptionTimeout; - ReturnValue_t handleSuccessfullTcRead(); + ReturnValue_t handleSuccessfullTcRead(size_t bytesRead); }; diff --git a/osal/linux/TmTcUnixUdpBridge.cpp b/osal/linux/TmTcUnixUdpBridge.cpp index 710761b4..a337b8ae 100644 --- a/osal/linux/TmTcUnixUdpBridge.cpp +++ b/osal/linux/TmTcUnixUdpBridge.cpp @@ -101,7 +101,7 @@ void TmTcUnixUdpBridge::checkAndSetClientAddress(sockaddr_in newAddress) { void TmTcUnixUdpBridge::handleBindError() { // See: https://man7.org/linux/man-pages/man2/bind.2.html switch(errno) { - case(EACCES): + case(EACCES): { /* Ephermeral ports can be shown with following command: sysctl -A | grep ip_local_port_range @@ -110,7 +110,8 @@ void TmTcUnixUdpBridge::handleBindError() { "Ports 1-1024 are reserved on UNIX systems and require root " "rights while ephermeral ports should not be used as well." << std::endl; - break; + } + break; case(EADDRINUSE): case(EBADF): case(EINVAL): @@ -122,15 +123,17 @@ void TmTcUnixUdpBridge::handleBindError() { case(ENOENT): case(ENOMEM): case(ENOTDIR): - case(EROFS): + case(EROFS): { sif::error << "TmTcUnixBridge::TmTcUnixBridge: Socket creation failed" - << " with " << strerror(errno) << std::endl; + << " with " << strerror(errno) << std::endl; break; - default: + } + default: { sif::error << "TmTcUnixBridge::TmTcUnixBridge: Unknown error" - << std::endl; + << std::endl; break; } + } } diff --git a/osal/linux/TmTcUnixUdpBridge.h b/osal/linux/TmTcUnixUdpBridge.h index 15d256cd..2fb606b0 100644 --- a/osal/linux/TmTcUnixUdpBridge.h +++ b/osal/linux/TmTcUnixUdpBridge.h @@ -7,7 +7,7 @@ #include class TmTcUnixUdpBridge: public TmTcBridge { - friend class TcSocketPollingTask; + friend class TcUnixUdpPollingTask; public: // The ports chosen here should not be used by any other process. // List of used ports on Linux: /etc/services diff --git a/tcdistribution/CCSDSDistributor.cpp b/tcdistribution/CCSDSDistributor.cpp index 878b8f7d..199e2ed1 100644 --- a/tcdistribution/CCSDSDistributor.cpp +++ b/tcdistribution/CCSDSDistributor.cpp @@ -2,30 +2,37 @@ #include #include -CCSDSDistributor::CCSDSDistributor( uint16_t setDefaultApid, object_id_t setObjectId ) : - TcDistributor( setObjectId ), default_apid( setDefaultApid ), tcStore(NULL) { +CCSDSDistributor::CCSDSDistributor(uint16_t setDefaultApid, + object_id_t setObjectId): + TcDistributor(setObjectId), defaultApid( setDefaultApid ) { } -CCSDSDistributor::~CCSDSDistributor() { +CCSDSDistributor::~CCSDSDistributor() {} -} - -iterator_t CCSDSDistributor::selectDestination() { -// debug << "CCSDSDistributor::selectDestination received: " << this->currentMessage.getStorageId().pool_index << ", " << this->currentMessage.getStorageId().packet_index << std::endl; - const uint8_t* p_packet = NULL; +TcDistributor::TcMessageQueueMapIter CCSDSDistributor::selectDestination() { +// sif::debug << "CCSDSDistributor::selectDestination received: " << +// this->currentMessage.getStorageId().pool_index << ", " << +// this->currentMessage.getStorageId().packet_index << std::endl; + const uint8_t* packet = nullptr; size_t size = 0; - //TODO check returncode? - this->tcStore->getData( this->currentMessage.getStorageId(), &p_packet, &size ); - SpacePacketBase current_packet( p_packet ); -// info << "CCSDSDistributor::selectDestination has packet with APID " << std::hex << current_packet.getAPID() << std::dec << std::endl; - iterator_t position = this->queueMap.find( current_packet.getAPID() ); + ReturnValue_t result = this->tcStore->getData(currentMessage.getStorageId(), + &packet, &size ); + if(result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "CCSDSDistributor::selectDestination: Getting data from" + "store failed!" << std::endl; + } + SpacePacketBase currentPacket(packet); + +// sif:: info << "CCSDSDistributor::selectDestination has packet with APID " +// << std::hex << currentPacket.getAPID() << std::dec << std::endl; + TcMessageQueueMapIter position = this->queueMap.find(currentPacket.getAPID()); if ( position != this->queueMap.end() ) { return position; } else { - //The APID was not found. Forward packet to main SW-APID anyway to create acceptance failure report. - return this->queueMap.find( this->default_apid ); + //The APID was not found. Forward packet to main SW-APID anyway to + // create acceptance failure report. + return this->queueMap.find( this->defaultApid ); } - } MessageQueueId_t CCSDSDistributor::getRequestQueue() { diff --git a/tcdistribution/CCSDSDistributor.h b/tcdistribution/CCSDSDistributor.h index 9dce34f2..22025f76 100644 --- a/tcdistribution/CCSDSDistributor.h +++ b/tcdistribution/CCSDSDistributor.h @@ -1,58 +1,69 @@ -#ifndef CCSDSDISTRIBUTOR_H_ -#define CCSDSDISTRIBUTOR_H_ +#ifndef FRAMEWORK_TCDISTRIBUTION_CCSDSDISTRIBUTOR_H_ +#define FRAMEWORK_TCDISTRIBUTION_CCSDSDISTRIBUTOR_H_ #include #include #include #include #include + /** - * An instantiation of the CCSDSDistributorIF. - * It receives Space Packets, and selects a destination depending on the APID of the telecommands. + * @brief An instantiation of the CCSDSDistributorIF. + * @details + * It receives Space Packets, and selects a destination depending on the + * APID of the telecommands. * The Secondary Header (with Service/Subservice) is ignored. - * \ingroup tc_distribution + * @ingroup tc_distribution */ -class CCSDSDistributor : public TcDistributor, public CCSDSDistributorIF, public AcceptsTelecommandsIF { -protected: - /** - * This implementation checks if an Application with fitting APID has registered and forwards the - * packet to the according message queue. - * If the packet is not found, it returns the queue to \c default_apid, where a Acceptance Failure - * message should be generated. - * @return Iterator to map entry of found APID or iterator to default APID. - */ - iterator_t selectDestination(); - /** - * The default APID, where packets with unknown APID are sent to. - */ - uint16_t default_apid; - /** - * A reference to the TC storage must be maintained, as this class handles pure Space Packets and there - * exists no SpacePacketStored class. - */ - StorageManagerIF* tcStore; - /** - * The callback here handles the generation of acceptance success/failure messages. - */ - ReturnValue_t callbackAfterSending( ReturnValue_t queueStatus ); +class CCSDSDistributor : public TcDistributor, + public CCSDSDistributorIF, + public AcceptsTelecommandsIF { public: /** - * The constructor sets the default APID and calls the TcDistributor ctor with a certain object id. - * \c tcStore is set in the \c initialize method. - * @param set_default_apid The default APID, where packets with unknown destination are sent to. + * @brief The constructor sets the default APID and calls the + * TcDistributor ctor with a certain object id. + * @details + * @c tcStore is set in the @c initialize method. + * @param set_default_apid The default APID, where packets with unknown + * destination are sent to. */ CCSDSDistributor( uint16_t setDefaultApid, object_id_t setObjectId ); /** * The destructor is empty. */ ~CCSDSDistributor(); - MessageQueueId_t getRequestQueue(); - ReturnValue_t registerApplication( uint16_t apid, MessageQueueId_t id ); - ReturnValue_t registerApplication( AcceptsTelecommandsIF* application ); + + MessageQueueId_t getRequestQueue() override; + ReturnValue_t registerApplication( uint16_t apid, + MessageQueueId_t id) override; + ReturnValue_t registerApplication( + AcceptsTelecommandsIF* application) override; uint16_t getIdentifier(); - ReturnValue_t initialize(); + ReturnValue_t initialize() override; + +protected: + /** + * This implementation checks if an application with fitting APID has + * registered and forwards the packet to the according message queue. + * If the packet is not found, it returns the queue to @c defaultApid, + * where a Acceptance Failure message should be generated. + * @return Iterator to map entry of found APID or iterator to default APID. + */ + TcMessageQueueMapIter selectDestination(); + /** + * The default APID, where packets with unknown APID are sent to. + */ + uint16_t defaultApid; + /** + * A reference to the TC storage must be maintained, as this class handles + * pure Space Packets and there exists no SpacePacketStored class. + */ + StorageManagerIF* tcStore = nullptr; + /** + * The callback here handles the generation of acceptance + * success/failure messages. + */ + ReturnValue_t callbackAfterSending( ReturnValue_t queueStatus ); }; - - -#endif /* CCSDSDISTRIBUTOR_H_ */ +#endif /* FRAMEWORK_TCDISTRIBUTION_CCSDSDISTRIBUTOR_H_ */ diff --git a/tcdistribution/PUSDistributor.cpp b/tcdistribution/PUSDistributor.cpp index bcf6d571..f13b5f8d 100644 --- a/tcdistribution/PUSDistributor.cpp +++ b/tcdistribution/PUSDistributor.cpp @@ -12,9 +12,9 @@ PUSDistributor::PUSDistributor(uint16_t setApid, object_id_t setObjectId, PUSDistributor::~PUSDistributor() {} -iterator_t PUSDistributor::selectDestination() { +TcDistributor::TcMessageQueueMapIter PUSDistributor::selectDestination() { // debug << "PUSDistributor::handlePacket received: " << this->current_packet_id.store_index << ", " << this->current_packet_id.packet_index << std::endl; - iterator_t queueMapIt = this->queueMap.end(); + TcMessageQueueMapIter queueMapIt = this->queueMap.end(); this->currentPacket.setStoreAddress(this->currentMessage.getStorageId()); if (currentPacket.getWholeData() != NULL) { tcStatus = checker.checkPacket(¤tPacket); diff --git a/tcdistribution/PUSDistributor.h b/tcdistribution/PUSDistributor.h index 8d774662..3d6717bd 100644 --- a/tcdistribution/PUSDistributor.h +++ b/tcdistribution/PUSDistributor.h @@ -1,5 +1,5 @@ -#ifndef PUSDISTRIBUTOR_H_ -#define PUSDISTRIBUTOR_H_ +#ifndef FRAMEWORK_TCDISTRIBUTION_PUSDISTRIBUTOR_H_ +#define FRAMEWORK_TCDISTRIBUTION_PUSDISTRIBUTOR_H_ #include #include @@ -9,37 +9,42 @@ #include /** - * This class accepts PUS Telecommands and forwards them to Application services. - * In addition, the class performs a formal packet check and sends acceptance success - * or failure messages. - * \ingroup tc_distribution + * This class accepts PUS Telecommands and forwards them to Application + * services. In addition, the class performs a formal packet check and + * sends acceptance success or failure messages. + * @ingroup tc_distribution */ class PUSDistributor: public TcDistributor, public PUSDistributorIF, public AcceptsTelecommandsIF { public: /** - * The ctor passes \c set_apid to the checker class and calls the TcDistribution ctor with a certain object id. + * The ctor passes @c set_apid to the checker class and calls the + * TcDistribution ctor with a certain object id. * @param setApid The APID of this receiving Application. * @param setObjectId Object ID of the distributor itself - * @param setPacketSource Object ID of the source of TC packets. Must implement CCSDSDistributorIF. + * @param setPacketSource Object ID of the source of TC packets. + * Must implement CCSDSDistributorIF. */ - PUSDistributor(uint16_t setApid, object_id_t setObjectId, object_id_t setPacketSource); + PUSDistributor(uint16_t setApid, object_id_t setObjectId, + object_id_t setPacketSource); /** * The destructor is empty. */ virtual ~PUSDistributor(); - ReturnValue_t registerService(AcceptsTelecommandsIF* service); - MessageQueueId_t getRequestQueue(); - uint16_t getIdentifier(); - ReturnValue_t initialize(); + ReturnValue_t registerService(AcceptsTelecommandsIF* service) override; + MessageQueueId_t getRequestQueue() override; + ReturnValue_t initialize() override; + uint16_t getIdentifier() override; + protected: /** * This attribute contains the class, that performs a formal packet check. */ TcPacketCheck checker; /** - * With this class, verification messages are sent to the TC Verification service. + * With this class, verification messages are sent to the + * TC Verification service. */ VerificationReporter verifyChannel; /** @@ -47,21 +52,26 @@ protected: */ TcPacketStored currentPacket; /** - * With this variable, the current check status is stored to generate acceptance messages later. + * With this variable, the current check status is stored to generate + * acceptance messages later. */ ReturnValue_t tcStatus; const object_id_t packetSource; /** - * This method reads the packet service, checks if such a service is registered and forwards the packet to the destination. - * It also initiates the formal packet check and sending of verification messages. - * @return Iterator to map entry of found service id or iterator to \c map.end(). + * This method reads the packet service, checks if such a service is + * registered and forwards the packet to the destination. + * It also initiates the formal packet check and sending of verification + * messages. + * @return Iterator to map entry of found service id + * or iterator to @c map.end(). */ - iterator_t selectDestination(); + TcMessageQueueMapIter selectDestination(); /** - * The callback here handles the generation of acceptance success/failure messages. + * The callback here handles the generation of acceptance + * success/failure messages. */ ReturnValue_t callbackAfterSending(ReturnValue_t queueStatus); }; -#endif /* PUSDISTRIBUTOR_H_ */ +#endif /* FRAMEWORK_TCDISTRIBUTION_PUSDISTRIBUTOR_H_ */ diff --git a/tcdistribution/TcDistributor.cpp b/tcdistribution/TcDistributor.cpp index 57921459..7bebbb9c 100644 --- a/tcdistribution/TcDistributor.cpp +++ b/tcdistribution/TcDistributor.cpp @@ -15,7 +15,6 @@ TcDistributor::~TcDistributor() { ReturnValue_t TcDistributor::performOperation(uint8_t opCode) { ReturnValue_t status = RETURN_OK; -// debug << "TcDistributor: performing Operation." << std::endl; for (status = tcQueue->receiveMessage(¤tMessage); status == RETURN_OK; status = tcQueue->receiveMessage(¤tMessage)) { status = handlePacket(); @@ -29,7 +28,7 @@ ReturnValue_t TcDistributor::performOperation(uint8_t opCode) { ReturnValue_t TcDistributor::handlePacket() { - iterator_t queueMapIt = this->selectDestination(); + TcMessageQueueMapIter queueMapIt = this->selectDestination(); ReturnValue_t returnValue = RETURN_FAILED; if (queueMapIt != this->queueMap.end()) { returnValue = this->tcQueue->sendMessage(queueMapIt->second, @@ -41,7 +40,7 @@ ReturnValue_t TcDistributor::handlePacket() { void TcDistributor::print() { sif::debug << "Distributor content is: " << std::endl << "ID\t| message queue id" << std::endl; - for (iterator_t it = this->queueMap.begin(); it != this->queueMap.end(); + for (TcMessageQueueMapIter it = this->queueMap.begin(); it != this->queueMap.end(); it++) { sif::debug << it->first << "\t| 0x" << std::hex << it->second << std::dec << std::endl; diff --git a/tcdistribution/TcDistributor.h b/tcdistribution/TcDistributor.h index b80f08e6..5c958de0 100644 --- a/tcdistribution/TcDistributor.h +++ b/tcdistribution/TcDistributor.h @@ -1,5 +1,6 @@ -#ifndef TCDISTRIBUTOR_H_ -#define TCDISTRIBUTOR_H_ +#ifndef FRAMEWORK_TMTCSERVICES_TCDISTRIBUTOR_H_ +#define FRAMEWORK_TMTCSERVICES_TCDISTRIBUTOR_H_ + #include #include #include @@ -9,16 +10,12 @@ #include #include - /** - * \defgroup tc_distribution Telecommand Distribution - * All classes associated with Routing and Distribution of Telecommands belong to this group. + * @defgroup tc_distribution Telecommand Distribution + * All classes associated with Routing and Distribution of Telecommands + * belong to this group. */ -/** - * This typedef simplifies writing down the \c map iterator. - */ -typedef std::map::iterator iterator_t; /** * This is the base class to implement distributors for Space Packets. @@ -28,59 +25,15 @@ typedef std::map::iterator iterator_t; * message queue ids to some identifier. The process of unpacking the * destination information from the packet is handled by the child class * implementations. - * \ingroup tc_distribution + * @ingroup tc_distribution */ -class TcDistributor : public SystemObject, public ExecutableObjectIF, public HasReturnvaluesIF { -private: - /** - * This constant sets the maximum number of packets distributed per call. - */ - static const uint8_t DISTRIBUTER_MAX_PACKETS = 128; -protected: - /** - * This is the receiving queue for incoming Telecommands. - * The child classes must make its queue id public. - */ - MessageQueueIF* tcQueue; - /** - * The last received incoming packet information is stored in this - * member. - * As different child classes unpack the incoming packet differently - * (i.e. as a CCSDS Space Packet or as a PUS Telecommand Packet), it - * is not tried to unpack the packet information within this class. - */ - TmTcMessage currentMessage; - /** - * The map that links certain packet information to a destination. - * The packet information may be the APID of the packet or the service - * identifier. Filling of the map is under control of the different child - * classes. - */ - std::map queueMap; - /** - * This method shall unpack the routing information from the incoming - * packet and select the map entry which represents the packet's target. - * @return An iterator to the map element to forward to or queuMap.end(). - */ - virtual iterator_t selectDestination() = 0; - /** - * The handlePacket method calls the child class's selectDestination method - * and forwards the packet to its destination, if found. - * @return The message queue return value or \c RETURN_FAILED, in case no - * destination was found. - */ - ReturnValue_t handlePacket(); - /** - * This method gives the child class a chance to perform some kind of operation - * after the parent tried to forward the message. - * A typically application would be sending success/failure messages. - * The default implementation just returns \c RETURN_OK. - * @param queueStatus The status of the message queue after an attempt to send the TC. - * @return - \c RETURN_OK on success - * - \c RETURN_FAILED on failure - */ - virtual ReturnValue_t callbackAfterSending( ReturnValue_t queueStatus ); +class TcDistributor : public SystemObject, + public ExecutableObjectIF, + public HasReturnvaluesIF { public: + using TcMessageQueueMap = std::map; + using TcMessageQueueMapIter = std::map::iterator; + static const uint8_t INTERFACE_ID = CLASS_ID::PACKET_DISTRIBUTION; static const ReturnValue_t PACKET_LOST = MAKE_RETURN_CODE( 1 ); static const ReturnValue_t DESTINATION_NOT_FOUND = MAKE_RETURN_CODE( 2 ); @@ -110,6 +63,57 @@ public: * queueMap. */ void print(); + +protected: + /** + * This is the receiving queue for incoming Telecommands. + * The child classes must make its queue id public. + */ + MessageQueueIF* tcQueue; + /** + * The last received incoming packet information is stored in this + * member. + * As different child classes unpack the incoming packet differently + * (i.e. as a CCSDS Space Packet or as a PUS Telecommand Packet), it + * is not tried to unpack the packet information within this class. + */ + TmTcMessage currentMessage; + /** + * The map that links certain packet information to a destination. + * The packet information may be the APID of the packet or the service + * identifier. Filling of the map is under control of the different child + * classes. + */ + TcMessageQueueMap queueMap; + /** + * This method shall unpack the routing information from the incoming + * packet and select the map entry which represents the packet's target. + * @return An iterator to the map element to forward to or queuMap.end(). + */ + virtual TcMessageQueueMapIter selectDestination() = 0; + /** + * The handlePacket method calls the child class's selectDestination method + * and forwards the packet to its destination, if found. + * @return The message queue return value or \c RETURN_FAILED, in case no + * destination was found. + */ + ReturnValue_t handlePacket(); + /** + * This method gives the child class a chance to perform some kind of operation + * after the parent tried to forward the message. + * A typically application would be sending success/failure messages. + * The default implementation just returns \c RETURN_OK. + * @param queueStatus The status of the message queue after an attempt to send the TC. + * @return - \c RETURN_OK on success + * - \c RETURN_FAILED on failure + */ + virtual ReturnValue_t callbackAfterSending( ReturnValue_t queueStatus ); + +private: + /** + * This constant sets the maximum number of packets distributed per call. + */ + static const uint8_t DISTRIBUTER_MAX_PACKETS = 128; }; diff --git a/tmtcservices/PusServiceBase.cpp b/tmtcservices/PusServiceBase.cpp index 82e5ff5c..cb1e633f 100644 --- a/tmtcservices/PusServiceBase.cpp +++ b/tmtcservices/PusServiceBase.cpp @@ -41,9 +41,14 @@ void PusServiceBase::handleRequestQueue() { ReturnValue_t result = RETURN_FAILED; for (uint8_t count = 0; count < PUS_SERVICE_MAX_RECEPTION; count++) { ReturnValue_t status = this->requestQueue->receiveMessage(&message); - // debug << "PusServiceBase::performOperation: Receiving from MQ ID: " - // << std::hex << this->requestQueue.getId() - // << std::dec << " returned: " << status << std::endl; +// if(status != MessageQueueIF::EMPTY) { +// sif::debug << "PusServiceBase::performOperation: Receiving from " +// << "MQ ID: " << std::hex << "0x" << std::setw(8) +// << std::setfill('0') << this->requestQueue->getId() +// << std::dec << " returned: " << status << std::setfill(' ') +// << std::endl; +// } + if (status == RETURN_OK) { this->currentPacket.setStoreAddress(message.getStorageId()); //info << "Service " << (uint16_t) this->serviceId << diff --git a/tmtcservices/TmTcBridge.h b/tmtcservices/TmTcBridge.h index 5b933c79..a009c962 100644 --- a/tmtcservices/TmTcBridge.h +++ b/tmtcservices/TmTcBridge.h @@ -62,7 +62,7 @@ public: * @param virtualChannel * @return */ - MessageQueueId_t getReportReceptionQueue( + virtual MessageQueueId_t getReportReceptionQueue( uint8_t virtualChannel = 0) override; protected: //! Used to send and receive TMTC messages. From 264914e86a1b9a2854dbc8d83ed96445a1255482 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 8 Jul 2020 03:18:09 +0200 Subject: [PATCH 245/307] tmtcbridge tweaks. UDP bridge now working :-D --- osal/linux/MessageQueue.cpp | 8 ++-- osal/linux/PeriodicPosixTask.cpp | 8 ++-- osal/linux/TcUnixUdpPollingTask.cpp | 69 ++++++++++++++++------------ osal/linux/TcUnixUdpPollingTask.h | 8 ++++ osal/linux/TmTcUnixUdpBridge.cpp | 43 +++++++---------- osal/linux/TmTcUnixUdpBridge.h | 7 +-- tcdistribution/CCSDSDistributor.cpp | 4 +- tcdistribution/CCSDSDistributor.h | 8 ++-- tcdistribution/PUSDistributor.cpp | 4 +- tcdistribution/PUSDistributor.h | 2 +- tcdistribution/TcDistributor.cpp | 4 +- tcdistribution/TcDistributor.h | 4 +- tmtcservices/AcceptsTelecommandsIF.h | 10 ++-- tmtcservices/TmTcBridge.cpp | 26 +++++++---- tmtcservices/TmTcBridge.h | 34 ++++++-------- 15 files changed, 121 insertions(+), 118 deletions(-) diff --git a/osal/linux/MessageQueue.cpp b/osal/linux/MessageQueue.cpp index ce1da17c..153f43d3 100644 --- a/osal/linux/MessageQueue.cpp +++ b/osal/linux/MessageQueue.cpp @@ -155,10 +155,10 @@ ReturnValue_t MessageQueue::receiveMessage(MessageQueueMessageIF* message) { } if(message->getMaximumMessageSize() < maxMessageSize) { - sif::error << "MessageQueue::receiveMessage: Message size " - << message->getMaximumMessageSize() << - " too small to receive data!" << std::endl; - return HasReturnvaluesIF::RETURN_FAILED; + sif::error << "MessageQueue::receiveMessage: Message size " + << message->getMaximumMessageSize() + << " too small to receive data!" << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; } unsigned int messagePriority = 0; diff --git a/osal/linux/PeriodicPosixTask.cpp b/osal/linux/PeriodicPosixTask.cpp index b811274b..4b0c77fc 100644 --- a/osal/linux/PeriodicPosixTask.cpp +++ b/osal/linux/PeriodicPosixTask.cpp @@ -68,12 +68,12 @@ void PeriodicPosixTask::taskFunctionality(void) { char name[20] = {0}; int status = pthread_getname_np(pthread_self(),name,sizeof(name)); if(status == 0){ - sif::error << "PeriodicPosixTask " << name << ": Deadline " - "missed." << std::endl; + //sif::error << "PeriodicPosixTask " << name << ": Deadline " + // "missed." << std::endl; } else { - sif::error << "PeriodicPosixTask X: Deadline missed. " << - status << std::endl; + //sif::error << "PeriodicPosixTask X: Deadline missed. " << + // status << std::endl; } if (this->deadlineMissedFunc != nullptr) { this->deadlineMissedFunc(); diff --git a/osal/linux/TcUnixUdpPollingTask.cpp b/osal/linux/TcUnixUdpPollingTask.cpp index 83f7a3da..97fbd044 100644 --- a/osal/linux/TcUnixUdpPollingTask.cpp +++ b/osal/linux/TcUnixUdpPollingTask.cpp @@ -26,8 +26,7 @@ TcUnixUdpPollingTask::TcUnixUdpPollingTask(object_id_t objectId, } } -TcUnixUdpPollingTask::~TcUnixUdpPollingTask() { -} +TcUnixUdpPollingTask::~TcUnixUdpPollingTask() {} ReturnValue_t TcUnixUdpPollingTask::performOperation(uint8_t opCode) { // Poll for new UDP datagrams in permanent loop. @@ -59,6 +58,30 @@ ReturnValue_t TcUnixUdpPollingTask::performOperation(uint8_t opCode) { return HasReturnvaluesIF::RETURN_OK; } + +ReturnValue_t TcUnixUdpPollingTask::handleSuccessfullTcRead(size_t bytesRead) { + store_address_t storeId = 0; + ReturnValue_t result = tcStore->addData(&storeId, + receptionBuffer.data(), bytesRead); + // arrayprinter::print(receptionBuffer.data(), bytesRead); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::debug << "TcSerialPollingTask::transferPusToSoftwareBus: Data " + "storage failed" << std::endl; + sif::debug << "Packet size: " << bytesRead << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + + TmTcMessage message(storeId); + + result = MessageQueueSenderIF::sendMessage(targetTcDestination, &message); + if (result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "Serial Polling: Sending message to queue failed" + << std::endl; + tcStore->deleteData(storeId); + } + return result; +} + ReturnValue_t TcUnixUdpPollingTask::initialize() { tcStore = objectManager->get(objects::TC_STORE); if (tcStore == nullptr) { @@ -74,41 +97,27 @@ ReturnValue_t TcUnixUdpPollingTask::initialize() { return ObjectManagerIF::CHILD_INIT_FAILED; } - targetTcDestination = tmtcBridge->getReportReceptionQueue(); - serverUdpSocket = tmtcBridge->serverSocket; - // Set receive timeout. -// int result = setsockopt(serverUdpSocket, SOL_SOCKET, SO_RCVTIMEO, -// &receptionTimeout, sizeof(receptionTimeout)); -// if(result == -1) { -// sif::error << "TcSocketPollingTask::TcSocketPollingTask: Setting " -// "receive timeout failed with " << strerror(errno) << std::endl; -// return ObjectManagerIF::CHILD_INIT_FAILED; -// } return HasReturnvaluesIF::RETURN_OK; } -ReturnValue_t TcUnixUdpPollingTask::handleSuccessfullTcRead(size_t bytesRead) { - store_address_t storeId = 0; - ReturnValue_t result = tcStore->addData(&storeId, - receptionBuffer.data(), bytesRead); - // arrayprinter::print(receptionBuffer.data(), bytesRead); - if (result != HasReturnvaluesIF::RETURN_OK) { - sif::debug << "TcSerialPollingTask::transferPusToSoftwareBus: Data " - "storage failed" << std::endl; - sif::debug << "Packet size: " << bytesRead << std::endl; - return HasReturnvaluesIF::RETURN_FAILED; - } +ReturnValue_t TcUnixUdpPollingTask::initializeAfterTaskCreation() { + // Initialize the destination after task creation. This ensures + // that the destination will be set in the TMTC bridge. + targetTcDestination = tmtcBridge->getRequestQueue(); + return HasReturnvaluesIF::RETURN_OK; +} - TmTcMessage message(storeId); - result = MessageQueueSenderIF::sendMessage(targetTcDestination, &message); - if (result != HasReturnvaluesIF::RETURN_OK) { - sif::error << "Serial Polling: Sending message to queue failed" - << std::endl; - tcStore->deleteData(storeId); +void TcUnixUdpPollingTask::setTimeout(double timeoutSeconds) { + timeval tval; + tval = timevalOperations::toTimeval(timeoutSeconds); + int result = setsockopt(serverUdpSocket, SOL_SOCKET, SO_RCVTIMEO, + &tval, sizeof(receptionTimeout)); + if(result == -1) { + sif::error << "TcSocketPollingTask::TcSocketPollingTask: Setting " + "receive timeout failed with " << strerror(errno) << std::endl; } - return result; } diff --git a/osal/linux/TcUnixUdpPollingTask.h b/osal/linux/TcUnixUdpPollingTask.h index 3503d505..86591e8d 100644 --- a/osal/linux/TcUnixUdpPollingTask.h +++ b/osal/linux/TcUnixUdpPollingTask.h @@ -29,8 +29,16 @@ public: size_t frameSize = 0, double timeoutSeconds = -1); virtual~ TcUnixUdpPollingTask(); + /** + * Turn on optional timeout for UDP polling. In the default mode, + * the receive function will block until a packet is received. + * @param timeoutSeconds + */ + void setTimeout(double timeoutSeconds); + virtual ReturnValue_t performOperation(uint8_t opCode) override; virtual ReturnValue_t initialize() override; + virtual ReturnValue_t initializeAfterTaskCreation() override; protected: StorageManagerIF* tcStore = nullptr; diff --git a/osal/linux/TmTcUnixUdpBridge.cpp b/osal/linux/TmTcUnixUdpBridge.cpp index a337b8ae..4dc61c50 100644 --- a/osal/linux/TmTcUnixUdpBridge.cpp +++ b/osal/linux/TmTcUnixUdpBridge.cpp @@ -1,8 +1,9 @@ #include #include -#include #include +#include + TmTcUnixUdpBridge::TmTcUnixUdpBridge(object_id_t objectId, object_id_t ccsdsPacketDistributor, uint16_t serverPort, uint16_t clientPort): @@ -14,17 +15,16 @@ TmTcUnixUdpBridge::TmTcUnixUdpBridge(object_id_t objectId, setServerPort = serverPort; } - uint16_t setClientPort = DEFAULT_UDP_CLIENT_PORT; - if(clientPort != 0xFFFF) { - setClientPort = clientPort; - } +// uint16_t setClientPort = DEFAULT_UDP_CLIENT_PORT; +// if(clientPort != 0xFFFF) { +// setClientPort = clientPort; +// } // Set up UDP socket: https://man7.org/linux/man-pages/man7/ip.7.html serverSocket = socket(AF_INET, SOCK_DGRAM, 0); if(socket < 0) { sif::error << "TmTcUnixUdpBridge::TmTcUnixUdpBridge: Could not open" " UDP socket!" << std::endl; - // check errno here. handleSocketError(); return; } @@ -44,7 +44,6 @@ TmTcUnixUdpBridge::TmTcUnixUdpBridge(object_id_t objectId, sif::error << "TmTcUnixUdpBridge::TmTcUnixUdpBridge: Could not bind " "local port " << setServerPort << " to server socket!" << std::endl; - // check errno here. handleBindError(); return; } @@ -57,14 +56,21 @@ ReturnValue_t TmTcUnixUdpBridge::sendTm(const uint8_t *data, size_t dataLen) { int flags = 0; ssize_t result = send(serverSocket, data, dataLen, flags); if(result < 0) { - //handle error + // todo: handle errors sif::error << "TmTcUnixUdpBridge::sendTm: Send operation failed " "with error " << strerror(errno) << std::endl; } - return HasReturnvaluesIF::RETURN_OK; } +void TmTcUnixUdpBridge::checkAndSetClientAddress(sockaddr_in newAddress) { + MutexHelper lock(mutex, 10); + // Set new IP address if it has changed. + if(clientAddress.sin_addr.s_addr != newAddress.sin_addr.s_addr) { + clientAddress.sin_addr.s_addr = newAddress.sin_addr.s_addr; + } +} + void TmTcUnixUdpBridge::handleSocketError() { // See: https://man7.org/linux/man-pages/man2/socket.2.html @@ -87,17 +93,6 @@ void TmTcUnixUdpBridge::handleSocketError() { } } -void TmTcUnixUdpBridge::setTimeout(float timeoutSeconds) { -} - -void TmTcUnixUdpBridge::checkAndSetClientAddress(sockaddr_in newAddress) { - MutexHelper lock(mutex, 10); - // Set new IP address if it has changed. - if(clientAddress.sin_addr.s_addr != newAddress.sin_addr.s_addr) { - clientAddress.sin_addr.s_addr = newAddress.sin_addr.s_addr; - } -} - void TmTcUnixUdpBridge::handleBindError() { // See: https://man7.org/linux/man-pages/man2/bind.2.html switch(errno) { @@ -128,16 +123,10 @@ void TmTcUnixUdpBridge::handleBindError() { << " with " << strerror(errno) << std::endl; break; } - default: { + default: sif::error << "TmTcUnixBridge::TmTcUnixBridge: Unknown error" << std::endl; break; } - } } - -ReturnValue_t TmTcUnixUdpBridge::receiveTc(uint8_t **recvBuffer, size_t *size) { - // TC reception handled by separate polling task because it is blocking. - return HasReturnvaluesIF::RETURN_OK; -} diff --git a/osal/linux/TmTcUnixUdpBridge.h b/osal/linux/TmTcUnixUdpBridge.h index 2fb606b0..538664d8 100644 --- a/osal/linux/TmTcUnixUdpBridge.h +++ b/osal/linux/TmTcUnixUdpBridge.h @@ -1,6 +1,7 @@ #ifndef FRAMEWORK_OSAL_LINUX_TMTCUNIXUDPBRIDGE_H_ #define FRAMEWORK_OSAL_LINUX_TMTCUNIXUDPBRIDGE_H_ +#include #include #include #include @@ -18,13 +19,11 @@ public: uint16_t serverPort = 0xFFFF,uint16_t clientPort = 0xFFFF); virtual~ TmTcUnixUdpBridge(); - void setTimeout(float timeoutSeconds); void checkAndSetClientAddress(sockaddr_in clientAddress); protected: - virtual ReturnValue_t receiveTc(uint8_t ** recvBuffer, - size_t * size) override; virtual ReturnValue_t sendTm(const uint8_t * data, size_t dataLen) override; + private: int serverSocket = 0; const int serverSocketOptions = 0; @@ -43,6 +42,4 @@ private: void handleBindError(); }; - - #endif /* FRAMEWORK_OSAL_LINUX_TMTCUNIXUDPBRIDGE_H_ */ diff --git a/tcdistribution/CCSDSDistributor.cpp b/tcdistribution/CCSDSDistributor.cpp index 199e2ed1..24c93730 100644 --- a/tcdistribution/CCSDSDistributor.cpp +++ b/tcdistribution/CCSDSDistributor.cpp @@ -9,7 +9,7 @@ CCSDSDistributor::CCSDSDistributor(uint16_t setDefaultApid, CCSDSDistributor::~CCSDSDistributor() {} -TcDistributor::TcMessageQueueMapIter CCSDSDistributor::selectDestination() { +TcDistributor::TcMqMapIter CCSDSDistributor::selectDestination() { // sif::debug << "CCSDSDistributor::selectDestination received: " << // this->currentMessage.getStorageId().pool_index << ", " << // this->currentMessage.getStorageId().packet_index << std::endl; @@ -25,7 +25,7 @@ TcDistributor::TcMessageQueueMapIter CCSDSDistributor::selectDestination() { // sif:: info << "CCSDSDistributor::selectDestination has packet with APID " // << std::hex << currentPacket.getAPID() << std::dec << std::endl; - TcMessageQueueMapIter position = this->queueMap.find(currentPacket.getAPID()); + TcMqMapIter position = this->queueMap.find(currentPacket.getAPID()); if ( position != this->queueMap.end() ) { return position; } else { diff --git a/tcdistribution/CCSDSDistributor.h b/tcdistribution/CCSDSDistributor.h index 22025f76..60877753 100644 --- a/tcdistribution/CCSDSDistributor.h +++ b/tcdistribution/CCSDSDistributor.h @@ -24,14 +24,14 @@ public: * TcDistributor ctor with a certain object id. * @details * @c tcStore is set in the @c initialize method. - * @param set_default_apid The default APID, where packets with unknown + * @param setDefaultApid The default APID, where packets with unknown * destination are sent to. */ - CCSDSDistributor( uint16_t setDefaultApid, object_id_t setObjectId ); + CCSDSDistributor(uint16_t setDefaultApid, object_id_t setObjectId); /** * The destructor is empty. */ - ~CCSDSDistributor(); + virtual ~CCSDSDistributor(); MessageQueueId_t getRequestQueue() override; ReturnValue_t registerApplication( uint16_t apid, @@ -49,7 +49,7 @@ protected: * where a Acceptance Failure message should be generated. * @return Iterator to map entry of found APID or iterator to default APID. */ - TcMessageQueueMapIter selectDestination(); + TcMqMapIter selectDestination() override; /** * The default APID, where packets with unknown APID are sent to. */ diff --git a/tcdistribution/PUSDistributor.cpp b/tcdistribution/PUSDistributor.cpp index f13b5f8d..d6e20acf 100644 --- a/tcdistribution/PUSDistributor.cpp +++ b/tcdistribution/PUSDistributor.cpp @@ -12,9 +12,9 @@ PUSDistributor::PUSDistributor(uint16_t setApid, object_id_t setObjectId, PUSDistributor::~PUSDistributor() {} -TcDistributor::TcMessageQueueMapIter PUSDistributor::selectDestination() { +TcDistributor::TcMqMapIter PUSDistributor::selectDestination() { // debug << "PUSDistributor::handlePacket received: " << this->current_packet_id.store_index << ", " << this->current_packet_id.packet_index << std::endl; - TcMessageQueueMapIter queueMapIt = this->queueMap.end(); + TcMqMapIter queueMapIt = this->queueMap.end(); this->currentPacket.setStoreAddress(this->currentMessage.getStorageId()); if (currentPacket.getWholeData() != NULL) { tcStatus = checker.checkPacket(¤tPacket); diff --git a/tcdistribution/PUSDistributor.h b/tcdistribution/PUSDistributor.h index 3d6717bd..4a22f936 100644 --- a/tcdistribution/PUSDistributor.h +++ b/tcdistribution/PUSDistributor.h @@ -66,7 +66,7 @@ protected: * @return Iterator to map entry of found service id * or iterator to @c map.end(). */ - TcMessageQueueMapIter selectDestination(); + TcMqMapIter selectDestination() override; /** * The callback here handles the generation of acceptance * success/failure messages. diff --git a/tcdistribution/TcDistributor.cpp b/tcdistribution/TcDistributor.cpp index 7bebbb9c..0190cc97 100644 --- a/tcdistribution/TcDistributor.cpp +++ b/tcdistribution/TcDistributor.cpp @@ -28,7 +28,7 @@ ReturnValue_t TcDistributor::performOperation(uint8_t opCode) { ReturnValue_t TcDistributor::handlePacket() { - TcMessageQueueMapIter queueMapIt = this->selectDestination(); + TcMqMapIter queueMapIt = this->selectDestination(); ReturnValue_t returnValue = RETURN_FAILED; if (queueMapIt != this->queueMap.end()) { returnValue = this->tcQueue->sendMessage(queueMapIt->second, @@ -40,7 +40,7 @@ ReturnValue_t TcDistributor::handlePacket() { void TcDistributor::print() { sif::debug << "Distributor content is: " << std::endl << "ID\t| message queue id" << std::endl; - for (TcMessageQueueMapIter it = this->queueMap.begin(); it != this->queueMap.end(); + for (TcMqMapIter it = this->queueMap.begin(); it != this->queueMap.end(); it++) { sif::debug << it->first << "\t| 0x" << std::hex << it->second << std::dec << std::endl; diff --git a/tcdistribution/TcDistributor.h b/tcdistribution/TcDistributor.h index 5c958de0..73425302 100644 --- a/tcdistribution/TcDistributor.h +++ b/tcdistribution/TcDistributor.h @@ -32,7 +32,7 @@ class TcDistributor : public SystemObject, public HasReturnvaluesIF { public: using TcMessageQueueMap = std::map; - using TcMessageQueueMapIter = std::map::iterator; + using TcMqMapIter = std::map::iterator; static const uint8_t INTERFACE_ID = CLASS_ID::PACKET_DISTRIBUTION; static const ReturnValue_t PACKET_LOST = MAKE_RETURN_CODE( 1 ); @@ -90,7 +90,7 @@ protected: * packet and select the map entry which represents the packet's target. * @return An iterator to the map element to forward to or queuMap.end(). */ - virtual TcMessageQueueMapIter selectDestination() = 0; + virtual TcMqMapIter selectDestination() = 0; /** * The handlePacket method calls the child class's selectDestination method * and forwards the packet to its destination, if found. diff --git a/tmtcservices/AcceptsTelecommandsIF.h b/tmtcservices/AcceptsTelecommandsIF.h index 0952d3a6..2878dd5d 100644 --- a/tmtcservices/AcceptsTelecommandsIF.h +++ b/tmtcservices/AcceptsTelecommandsIF.h @@ -1,5 +1,5 @@ -#ifndef ACCEPTSTELECOMMANDSIF_H_ -#define ACCEPTSTELECOMMANDSIF_H_ +#ifndef FRAMEWORK_TMTCSERVICES_ACCEPTSTELECOMMANDSIF_H_ +#define FRAMEWORK_TMTCSERVICES_ACCEPTSTELECOMMANDSIF_H_ #include @@ -26,9 +26,9 @@ public: /** * @brief Getter for the service id. * @details Any receiving service (at least any PUS service) shall have a - * service id. If the receiver can handle Telecommands, but for + * service ID. If the receiver can handle Telecommands, but for * some reason has no service id, it shall return 0. - * @return The service id or 0. + * @return The service ID or 0. */ virtual uint16_t getIdentifier() = 0; /** @@ -40,4 +40,4 @@ public: }; -#endif /* ACCEPTSTELECOMMANDSIF_H_ */ +#endif /* FRAMEWORK_TMTCSERVICES_ACCEPTSTELECOMMANDSIF_H_ */ diff --git a/tmtcservices/TmTcBridge.cpp b/tmtcservices/TmTcBridge.cpp index 092884bb..9c3e5b94 100644 --- a/tmtcservices/TmTcBridge.cpp +++ b/tmtcservices/TmTcBridge.cpp @@ -9,7 +9,7 @@ TmTcBridge::TmTcBridge(object_id_t objectId, object_id_t ccsdsPacketDistributor): SystemObject(objectId), ccsdsPacketDistributor(ccsdsPacketDistributor) { - TmTcReceptionQueue = QueueFactory::instance()-> + tmTcReceptionQueue = QueueFactory::instance()-> createMessageQueue(TMTC_RECEPTION_QUEUE_DEPTH); } @@ -55,7 +55,8 @@ ReturnValue_t TmTcBridge::initialize() { if (tcDistributor == NULL) { return RETURN_FAILED; } - TmTcReceptionQueue->setDefaultDestination(tcDistributor->getRequestQueue()); + + tmTcReceptionQueue->setDefaultDestination(tcDistributor->getRequestQueue()); return RETURN_OK; } @@ -73,10 +74,7 @@ ReturnValue_t TmTcBridge::performOperation(uint8_t operationCode) { } ReturnValue_t TmTcBridge::handleTc() { - uint8_t * recvBuffer = nullptr; - size_t recvLen = 0; - ReturnValue_t result = receiveTc(&recvBuffer, &recvLen); - return result; + return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t TmTcBridge::handleTm() { @@ -97,8 +95,8 @@ ReturnValue_t TmTcBridge::handleTmQueue() { TmTcMessage message; const uint8_t* data = nullptr; size_t size = 0; - for (ReturnValue_t result = TmTcReceptionQueue->receiveMessage(&message); - result == RETURN_OK; result = TmTcReceptionQueue->receiveMessage(&message)) + for (ReturnValue_t result = tmTcReceptionQueue->receiveMessage(&message); + result == RETURN_OK; result = tmTcReceptionQueue->receiveMessage(&message)) { if(communicationLinkUp == false) { result = storeDownlinkData(&message); @@ -183,10 +181,20 @@ void TmTcBridge::registerCommDisconnect() { } MessageQueueId_t TmTcBridge::getReportReceptionQueue(uint8_t virtualChannel) { - return TmTcReceptionQueue->getId(); + return tmTcReceptionQueue->getId(); } void TmTcBridge::printData(uint8_t * data, size_t dataLen) { arrayprinter::print(data, dataLen); } + +uint16_t TmTcBridge::getIdentifier() { + // This is no PUS service, so we just return 0 + return 0; +} + +MessageQueueId_t TmTcBridge::getRequestQueue() { + // Default implementation: Relay TC messages to TC distributor directly. + return tmTcReceptionQueue->getDefaultDestination(); +} diff --git a/tmtcservices/TmTcBridge.h b/tmtcservices/TmTcBridge.h index a009c962..3fcbf84c 100644 --- a/tmtcservices/TmTcBridge.h +++ b/tmtcservices/TmTcBridge.h @@ -1,16 +1,18 @@ #ifndef FRAMEWORK_TMTCSERVICES_TMTCBRIDGE_H_ #define FRAMEWORK_TMTCSERVICES_TMTCBRIDGE_H_ -#include +#include #include #include #include #include -#include +#include +#include #include class TmTcBridge : public AcceptsTelemetryIF, + public AcceptsTelecommandsIF, public ExecutableObjectIF, public HasReturnvaluesIF, public SystemObject { @@ -57,17 +59,19 @@ public: */ virtual ReturnValue_t performOperation(uint8_t operationCode = 0) override; - /** - * Return TMTC Reception Queue - * @param virtualChannel - * @return - */ + + /** AcceptsTelemetryIF override */ virtual MessageQueueId_t getReportReceptionQueue( uint8_t virtualChannel = 0) override; + + /** AcceptsTelecommandsIF override */ + virtual uint16_t getIdentifier() override; + virtual MessageQueueId_t getRequestQueue() override; + protected: //! Used to send and receive TMTC messages. //! TmTcMessage is used to transport messages between tasks. - MessageQueueIF* TmTcReceptionQueue = nullptr; + MessageQueueIF* tmTcReceptionQueue = nullptr; StorageManagerIF* tcStore = nullptr; StorageManagerIF* tmStore = nullptr; object_id_t ccsdsPacketDistributor = 0; @@ -79,23 +83,11 @@ protected: * @brief Handle TC reception * @details * Default implementation provided, but is empty. - * Child handler should override this in most cases orsend TC to the - * TC distributor directly with the address of the reception queue by - * calling getReportRecptionQueue() + * In most cases, TC reception will be handled in a separate task anyway. * @return */ virtual ReturnValue_t handleTc(); - /** - * Implemented by child class. Perform receiving of Telecommand, - * for example by implementing specific drivers or wrappers, - * e.g. UART Communication or an ethernet stack - * @param recvBuffer [out] Received data - * @param size [out] Size of received data - * @return - */ - virtual ReturnValue_t receiveTc(uint8_t ** recvBuffer, size_t * size) = 0; - /** * Handle Telemetry. Default implementation provided. * Calls sendTm() From 94f9b1e1ef0ecdbd0f92751284f74dc02310b7c2 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 8 Jul 2020 12:41:15 +0200 Subject: [PATCH 246/307] dle encoder doc finished and hopefully correct --- globalfunctions/DleEncoder.cpp | 128 +++++++++++++++++++-------------- globalfunctions/DleEncoder.h | 21 ++++-- 2 files changed, 89 insertions(+), 60 deletions(-) diff --git a/globalfunctions/DleEncoder.cpp b/globalfunctions/DleEncoder.cpp index ee934785..d727d665 100644 --- a/globalfunctions/DleEncoder.cpp +++ b/globalfunctions/DleEncoder.cpp @@ -4,50 +4,6 @@ DleEncoder::DleEncoder() {} DleEncoder::~DleEncoder() {} -ReturnValue_t DleEncoder::decode(const uint8_t *sourceStream, - size_t sourceStreamLen, size_t *readLen, uint8_t *destStream, - size_t maxDestStreamlen, size_t *decodedLen) { - size_t encodedIndex = 0, decodedIndex = 0; - uint8_t nextByte; - if (*sourceStream != STX) { - return DECODING_ERROR; - } - ++encodedIndex; - while ((encodedIndex < sourceStreamLen) && (decodedIndex < maxDestStreamlen) - && (sourceStream[encodedIndex] != ETX) - && (sourceStream[encodedIndex] != STX)) { - if (sourceStream[encodedIndex] == DLE) { - nextByte = sourceStream[encodedIndex + 1]; - // The next byte is a DLE character that was escaped by another - // DLE character, so we can write it to the destination stream. - if (nextByte == DLE) { - destStream[decodedIndex] = nextByte; - } else { - // The next byte is a STX, DTX or 0x0D character which - // was escaped by a DLE character - if ((nextByte == 0x42) || (nextByte == 0x43) - || (nextByte == 0x4D)) { - destStream[decodedIndex] = nextByte - 0x40; - } else { - return DECODING_ERROR; - } - } - ++encodedIndex; - } else { - destStream[decodedIndex] = sourceStream[encodedIndex]; - } - ++encodedIndex; - ++decodedIndex; - } - if (sourceStream[encodedIndex] != ETX) { - return DECODING_ERROR; - } else { - *readLen = ++encodedIndex; - *decodedLen = decodedIndex; - return RETURN_OK; - } -} - ReturnValue_t DleEncoder::encode(const uint8_t* sourceStream, size_t sourceLen, uint8_t* destStream, size_t maxDestLen, size_t* encodedLen, bool addStxEtx) { @@ -60,39 +16,105 @@ ReturnValue_t DleEncoder::encode(const uint8_t* sourceStream, destStream[0] = STX; ++encodedIndex; } - while ((encodedIndex < maxDestLen) && (sourceIndex < sourceLen)) { + + while (encodedIndex < maxDestLen and sourceIndex < sourceLen) { nextByte = sourceStream[sourceIndex]; - if ((nextByte == STX) || (nextByte == ETX) || (nextByte == 0x0D)) { + // STX, ETX and CR characters in the stream need to be escaped with DLE + if (nextByte == STX or nextByte == ETX or nextByte == CARRIAGE_RETURN) { if (encodedIndex + 1 >= maxDestLen) { return STREAM_TOO_SHORT; - } else { + } + else { destStream[encodedIndex] = DLE; ++encodedIndex; - // Escaped byte will be actual byte + 0x40. + /* Escaped byte will be actual byte + 0x40. This prevents + * STX, ETX, and carriage return characters from appearing + * in the encoded data stream at all, so when polling an + * encoded stream, the transmission can be stopped at ETX. + * 0x40 was chosen at random with special requirements: + * - Prevent going from one control char to another + * - Prevent overflow for common characters */ destStream[encodedIndex] = nextByte + 0x40; } - } else if (nextByte == DLE) { + } + // DLE characters are simply escaped with DLE. + else if (nextByte == DLE) { if (encodedIndex + 1 >= maxDestLen) { return STREAM_TOO_SHORT; - } else { + } + else { destStream[encodedIndex] = DLE; ++encodedIndex; destStream[encodedIndex] = DLE; } - } else { + } + else { destStream[encodedIndex] = nextByte; } ++encodedIndex; ++sourceIndex; } - if ((sourceIndex == sourceLen) && (encodedIndex < maxDestLen)) { + + if (sourceIndex == sourceLen and encodedIndex < maxDestLen) { if (addStxEtx) { destStream[encodedIndex] = ETX; ++encodedIndex; } *encodedLen = encodedIndex; return RETURN_OK; - } else { + } + else { return STREAM_TOO_SHORT; } } + +ReturnValue_t DleEncoder::decode(const uint8_t *sourceStream, + size_t sourceStreamLen, size_t *readLen, uint8_t *destStream, + size_t maxDestStreamlen, size_t *decodedLen) { + size_t encodedIndex = 0, decodedIndex = 0; + uint8_t nextByte; + if (*sourceStream != STX) { + return DECODING_ERROR; + } + ++encodedIndex; + + while ((encodedIndex < sourceStreamLen) && (decodedIndex < maxDestStreamlen) + && (sourceStream[encodedIndex] != ETX) + && (sourceStream[encodedIndex] != STX)) { + if (sourceStream[encodedIndex] == DLE) { + nextByte = sourceStream[encodedIndex + 1]; + // The next byte is a DLE character that was escaped by another + // DLE character, so we can write it to the destination stream. + if (nextByte == DLE) { + destStream[decodedIndex] = nextByte; + } + else { + /* The next byte is a STX, DTX or 0x0D character which + * was escaped by a DLE character. The actual byte was + * also encoded by adding + 0x40 to preven having control chars, + * in the stream at all, so we convert it back. */ + if (nextByte == 0x42 or nextByte == 0x43 or nextByte == 0x4D) { + destStream[decodedIndex] = nextByte - 0x40; + } else { + return DECODING_ERROR; + } + } + ++encodedIndex; + } + else { + destStream[decodedIndex] = sourceStream[encodedIndex]; + } + ++encodedIndex; + ++decodedIndex; + } + + if (sourceStream[encodedIndex] != ETX) { + return DECODING_ERROR; + } + else { + *readLen = ++encodedIndex; + *decodedLen = decodedIndex; + return RETURN_OK; + } +} + diff --git a/globalfunctions/DleEncoder.h b/globalfunctions/DleEncoder.h index 0f4a4c8f..36cb1d3f 100644 --- a/globalfunctions/DleEncoder.h +++ b/globalfunctions/DleEncoder.h @@ -14,9 +14,15 @@ * This encoder can be used to achieve a basic transport layer when using * char based transmission systems. * The passed source strean is converted into a encoded stream by adding - * a STX marker at the startr of the stream and an ETX marker at the end of - * the stream. Any STX, ETX and DLE occurences in the source stream are escaped - * by a DLE character. + * a STX marker at the start of the stream and an ETX marker at the end of + * the stream. Any STX, ETX, DLE and CR occurences in the source stream are + * escaped by a DLE character. The encoder also replaces escaped control chars + * by another char, so STX, ETX and CR should not appear anywhere in the actual + * encoded data stream. + * + * When using a strictly char based reception of packets enoded with DLE, + * STX can be used to notify a reader that actual data will start to arrive + * while ETX can be used to notify the reader that the data has ended. */ class DleEncoder: public HasReturnvaluesIF { private: @@ -29,12 +35,13 @@ public: static constexpr ReturnValue_t DECODING_ERROR = MAKE_RETURN_CODE(0x02); //! Start Of Text character. First character is encoded stream - static const uint8_t STX = 0x02; + static constexpr uint8_t STX = 0x02; //! End Of Text character. Last character in encoded stream - static const uint8_t ETX = 0x03; + static constexpr uint8_t ETX = 0x03; //! Data Link Escape character. Used to escape STX, ETX and DLE occurences //! in the source stream. - static const uint8_t DLE = 0x10; + static constexpr uint8_t DLE = 0x10; + static constexpr uint8_t CARRIAGE_RETURN = 0x0D; /** * Encodes the give data stream by preceding it with the STX marker @@ -54,7 +61,7 @@ public: bool addStxEtx = true); /** - * Converts an encoded stream back + * Converts an encoded stream back. * @param sourceStream * @param sourceStreamLen * @param readLen From 01b10803766e61833eaa9762327a48e0fff76c29 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 8 Jul 2020 12:53:46 +0200 Subject: [PATCH 247/307] readability increase --- globalfunctions/DleEncoder.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/globalfunctions/DleEncoder.cpp b/globalfunctions/DleEncoder.cpp index d727d665..c8f78872 100644 --- a/globalfunctions/DleEncoder.cpp +++ b/globalfunctions/DleEncoder.cpp @@ -17,7 +17,8 @@ ReturnValue_t DleEncoder::encode(const uint8_t* sourceStream, ++encodedIndex; } - while (encodedIndex < maxDestLen and sourceIndex < sourceLen) { + while (encodedIndex < maxDestLen and sourceIndex < sourceLen) + { nextByte = sourceStream[sourceIndex]; // STX, ETX and CR characters in the stream need to be escaped with DLE if (nextByte == STX or nextByte == ETX or nextByte == CARRIAGE_RETURN) { @@ -80,7 +81,8 @@ ReturnValue_t DleEncoder::decode(const uint8_t *sourceStream, while ((encodedIndex < sourceStreamLen) && (decodedIndex < maxDestStreamlen) && (sourceStream[encodedIndex] != ETX) - && (sourceStream[encodedIndex] != STX)) { + && (sourceStream[encodedIndex] != STX)) + { if (sourceStream[encodedIndex] == DLE) { nextByte = sourceStream[encodedIndex + 1]; // The next byte is a DLE character that was escaped by another @@ -95,7 +97,8 @@ ReturnValue_t DleEncoder::decode(const uint8_t *sourceStream, * in the stream at all, so we convert it back. */ if (nextByte == 0x42 or nextByte == 0x43 or nextByte == 0x4D) { destStream[decodedIndex] = nextByte - 0x40; - } else { + } + else { return DECODING_ERROR; } } @@ -104,6 +107,7 @@ ReturnValue_t DleEncoder::decode(const uint8_t *sourceStream, else { destStream[decodedIndex] = sourceStream[encodedIndex]; } + ++encodedIndex; ++decodedIndex; } From b56aa94f99730cee982eebc09dd8fa88a3fbc077 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 8 Jul 2020 12:54:40 +0200 Subject: [PATCH 248/307] additional doc --- globalfunctions/DleEncoder.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/globalfunctions/DleEncoder.h b/globalfunctions/DleEncoder.h index 36cb1d3f..29851dfe 100644 --- a/globalfunctions/DleEncoder.h +++ b/globalfunctions/DleEncoder.h @@ -46,7 +46,8 @@ public: /** * Encodes the give data stream by preceding it with the STX marker * and ending it with an ETX marker. STX, ETX and DLE characters inside - * the stream are escaped by DLE characters. + * the stream are escaped by DLE characters and also replaced by adding + * 0x40 (which is reverted in the decoing process). * @param sourceStream * @param sourceLen * @param destStream From 5ec78b065c4ca0ba486b9837c0e4c0eba40d5b15 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 8 Jul 2020 13:29:57 +0200 Subject: [PATCH 249/307] error handling for invalid dest queues improved --- ipc/MessageQueueIF.h | 14 +++---- objectmanager/frameworkObjects.h | 4 ++ osal/linux/MessageQueue.cpp | 13 ++++--- tmtcservices/VerificationReporter.cpp | 56 +++++++++++++++------------ tmtcservices/VerificationReporter.h | 39 ++++++++++++++----- 5 files changed, 78 insertions(+), 48 deletions(-) diff --git a/ipc/MessageQueueIF.h b/ipc/MessageQueueIF.h index 500f71e2..c0575442 100644 --- a/ipc/MessageQueueIF.h +++ b/ipc/MessageQueueIF.h @@ -18,18 +18,14 @@ public: static const MessageQueueId_t NO_QUEUE = MessageQueueMessageIF::NO_QUEUE; //!< Ugly hack. static const uint8_t INTERFACE_ID = CLASS_ID::MESSAGE_QUEUE_IF; - /** - * No new messages on the queue - */ + //! No new messages on the queue static const ReturnValue_t EMPTY = MAKE_RETURN_CODE(1); - /** - * No space left for more messages - */ + //! No space left for more messages static const ReturnValue_t FULL = MAKE_RETURN_CODE(2); - /** - * Returned if a reply method was called without partner - */ + //! Returned if a reply method was called without partner static const ReturnValue_t NO_REPLY_PARTNER = MAKE_RETURN_CODE(3); + //! Returned if the target destination is invalid. + static constexpr ReturnValue_t DESTINVATION_INVALID = MAKE_RETURN_CODE(4); virtual ~MessageQueueIF() {} /** diff --git a/objectmanager/frameworkObjects.h b/objectmanager/frameworkObjects.h index c3deafc4..46d5feea 100644 --- a/objectmanager/frameworkObjects.h +++ b/objectmanager/frameworkObjects.h @@ -3,6 +3,9 @@ namespace objects { enum framework_objects { + // Default verification reporter. + PUS_SERVICE_1 = 0x53000000, + //Generic IDs for IPC, modes, health, events HEALTH_TABLE = 0x53010000, // MODE_STORE = 0x53010100, @@ -12,6 +15,7 @@ enum framework_objects { //IDs for PUS Packet Communication TC_STORE = 0x534f0100, TM_STORE = 0x534f0200, + NO_OBJECT = 0xFFFFFFFF }; } diff --git a/osal/linux/MessageQueue.cpp b/osal/linux/MessageQueue.cpp index 153f43d3..236e61b6 100644 --- a/osal/linux/MessageQueue.cpp +++ b/osal/linux/MessageQueue.cpp @@ -330,13 +330,16 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo, //MQ_NONBLOCK flag was set in its attributes, and the //specified queue is full. return MessageQueueIF::FULL; - case EBADF: + case EBADF: { //mq_des doesn't represent a valid message queue descriptor, //or mq_des wasn't opened for writing. - sif::error << "MessageQueue::sendMessage: Configuration error " - << strerror(errno) << " in mq_send mqSendTo: " << sendTo - << " sent from " << sentFrom << std::endl; - /*NO BREAK*/ + sif::error << "MessageQueue::sendMessage: Configuration error, MQ" + << " destination invalid." << std::endl; + sif::error << strerror(errno) << " in " + <<"mq_send to: " << sendTo << " sent from " + << sentFrom << std::endl; + return DESTINVATION_INVALID; + } case EINTR: //The call was interrupted by a signal. case EINVAL: diff --git a/tmtcservices/VerificationReporter.cpp b/tmtcservices/VerificationReporter.cpp index bcb4756c..40f7e57f 100644 --- a/tmtcservices/VerificationReporter.cpp +++ b/tmtcservices/VerificationReporter.cpp @@ -1,17 +1,18 @@ -#include -#include -#include #include -object_id_t VerificationReporter::messageReceiver = 0; +#include +#include +#include +#include +#include + +object_id_t VerificationReporter::messageReceiver = objects::PUS_SERVICE_1; VerificationReporter::VerificationReporter() : - acknowledgeQueue() { + acknowledgeQueue(MessageQueueIF::NO_QUEUE) { } -VerificationReporter::~VerificationReporter() { - //Default, empty -} +VerificationReporter::~VerificationReporter() {} void VerificationReporter::sendSuccessReport(uint8_t set_report_id, TcPacketBase* current_packet, uint8_t set_step) { @@ -23,10 +24,11 @@ void VerificationReporter::sendSuccessReport(uint8_t set_report_id, current_packet->getPacketId(), current_packet->getPacketSequenceControl(), 0, set_step); ReturnValue_t status = MessageQueueSenderIF::sendMessage(acknowledgeQueue, - &message); + &message); if (status != HasReturnvaluesIF::RETURN_OK) { sif::error << "VerificationReporter::sendSuccessReport: Error writing " - "to queue. Code: " << std::hex << (uint16_t) status << std::endl; + << "to queue. Code: " << std::hex << status << std::dec + << std::endl; } } @@ -39,10 +41,11 @@ void VerificationReporter::sendSuccessReport(uint8_t set_report_id, PusVerificationMessage message(set_report_id, ackFlags, tcPacketId, tcSequenceControl, 0, set_step); ReturnValue_t status = MessageQueueSenderIF::sendMessage(acknowledgeQueue, - &message); + &message); if (status != HasReturnvaluesIF::RETURN_OK) { sif::error << "VerificationReporter::sendSuccessReport: Error writing " - "to queue. Code: " << std::hex << (uint16_t) status << std::endl; + << "to queue. Code: " << std::hex << status << std::dec + << std::endl; } } @@ -60,9 +63,9 @@ 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: " - << (uint16_t) status << std::endl; + sif::error << "VerificationReporter::sendFailureReport Error writing " + << "to queue. Code: " << std::hex << status << std::dec + << std::endl; } } @@ -78,20 +81,25 @@ 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: " - << (uint16_t) status << std::endl; + sif::error << "VerificationReporter::sendFailureReport Error writing " + << "to queue. Code: " << std::hex << status << std::dec + << std::endl; } } void VerificationReporter::initialize() { + if(messageReceiver == objects::NO_OBJECT) { + sif::warning << "VerificationReporter::initialize: Verification message" + " receiver object ID not set yet in Factory!" << std::endl; + return; + } AcceptsVerifyMessageIF* temp = objectManager->get( messageReceiver); - if (temp != NULL) { - this->acknowledgeQueue = temp->getVerificationQueue(); - } else { - sif::error - << "VerificationReporter::VerificationReporter: Configuration error." - << std::endl; + if (temp == nullptr) { + sif::error << "VerificationReporter::initialize: Message " + << "receiver invalid. Make sure it is set up properly and " + <<"implementsAcceptsVerifyMessageIF" << std::endl; + } + this->acknowledgeQueue = temp->getVerificationQueue(); } diff --git a/tmtcservices/VerificationReporter.h b/tmtcservices/VerificationReporter.h index 370c44c8..f13998d9 100644 --- a/tmtcservices/VerificationReporter.h +++ b/tmtcservices/VerificationReporter.h @@ -1,5 +1,5 @@ -#ifndef VERIFICATIONREPORTER_H_ -#define VERIFICATIONREPORTER_H_ +#ifndef FRAMEWORK_TMTCSERVICES_VERIFICATIONREPORTER_H_ +#define FRAMEWORK_TMTCSERVICES_VERIFICATIONREPORTER_H_ #include #include @@ -8,24 +8,43 @@ namespace Factory{ void setStaticFrameworkObjectIds(); } +/** + * @brief This helper object is used to forward verification messages + * which are generated by the Flight Software Framework. + * @details + * The messages can be relayed to an arbitrary object, for example a dedicated + * Verification Reporter. The destination is set by setting the static framework + * Id VerificationReporter::messageReceiver. The default verification reporter + * will be the PUS service 1, which sends verification messages according + * to the PUS standard. + * + */ class VerificationReporter { friend void (Factory::setStaticFrameworkObjectIds)(); public: VerificationReporter(); virtual ~VerificationReporter(); - void sendSuccessReport( uint8_t set_report_id, TcPacketBase* current_packet, uint8_t set_step = 0 ); - void sendSuccessReport(uint8_t set_report_id, uint8_t ackFlags, uint16_t tcPacketId, uint16_t tcSequenceControl, uint8_t set_step = 0); - void sendFailureReport( uint8_t report_id, TcPacketBase* current_packet, ReturnValue_t error_code = 0, - uint8_t step = 0, uint32_t parameter1 = 0, uint32_t parameter2 = 0 ); + + void sendSuccessReport( uint8_t set_report_id, TcPacketBase* current_packet, + uint8_t set_step = 0 ); + void sendSuccessReport(uint8_t set_report_id, uint8_t ackFlags, + uint16_t tcPacketId, uint16_t tcSequenceControl, + uint8_t set_step = 0); + + void sendFailureReport( uint8_t report_id, TcPacketBase* current_packet, + ReturnValue_t error_code = 0, + uint8_t step = 0, uint32_t parameter1 = 0, + uint32_t parameter2 = 0 ); void sendFailureReport(uint8_t report_id, - uint8_t ackFlags, uint16_t tcPacketId, uint16_t tcSequenceControl, ReturnValue_t error_code = 0, uint8_t step = 0, + uint8_t ackFlags, uint16_t tcPacketId, uint16_t tcSequenceControl, + ReturnValue_t error_code = 0, uint8_t step = 0, uint32_t parameter1 = 0, uint32_t parameter2 = 0); + void initialize(); + private: static object_id_t messageReceiver; MessageQueueId_t acknowledgeQueue; - - }; -#endif /* VERIFICATIONREPORTER_H_ */ +#endif /* FRAMEWORK_TMTCSERVICES_VERIFICATIONREPORTER_H_ */ From 236ad1b85b600acecc741127faa19c72925542fc Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 8 Jul 2020 15:06:46 +0200 Subject: [PATCH 250/307] a lot of debug output added --- osal/linux/TcUnixUdpPollingTask.cpp | 1 + osal/linux/TmTcUnixUdpBridge.cpp | 54 ++++++++++++++++++++------- osal/linux/TmTcUnixUdpBridge.h | 11 ++++-- tmtcservices/PusServiceBase.cpp | 20 +++++----- tmtcservices/TmTcBridge.cpp | 32 ++++++++++------ tmtcservices/TmTcBridge.h | 17 ++++++--- tmtcservices/VerificationReporter.cpp | 8 ++-- 7 files changed, 93 insertions(+), 50 deletions(-) diff --git a/osal/linux/TcUnixUdpPollingTask.cpp b/osal/linux/TcUnixUdpPollingTask.cpp index 97fbd044..122301da 100644 --- a/osal/linux/TcUnixUdpPollingTask.cpp +++ b/osal/linux/TcUnixUdpPollingTask.cpp @@ -53,6 +53,7 @@ ReturnValue_t TcUnixUdpPollingTask::performOperation(uint8_t opCode) { if(result != HasReturnvaluesIF::RETURN_FAILED) { } + tmtcBridge->registerCommConnect(); tmtcBridge->checkAndSetClientAddress(senderAddress); } return HasReturnvaluesIF::RETURN_OK; diff --git a/osal/linux/TmTcUnixUdpBridge.cpp b/osal/linux/TmTcUnixUdpBridge.cpp index 4dc61c50..40e96561 100644 --- a/osal/linux/TmTcUnixUdpBridge.cpp +++ b/osal/linux/TmTcUnixUdpBridge.cpp @@ -3,11 +3,12 @@ #include #include +#include TmTcUnixUdpBridge::TmTcUnixUdpBridge(object_id_t objectId, - object_id_t ccsdsPacketDistributor, uint16_t serverPort, - uint16_t clientPort): - TmTcBridge(objectId, ccsdsPacketDistributor) { + object_id_t tcDestination, object_id_t tmStoreId, object_id_t tcStoreId, + uint16_t serverPort, uint16_t clientPort): + TmTcBridge(objectId, tcDestination, tmStoreId, tcStoreId) { mutex = MutexFactory::instance()->createMutex(); uint16_t setServerPort = DEFAULT_UDP_SERVER_PORT; @@ -15,13 +16,14 @@ TmTcUnixUdpBridge::TmTcUnixUdpBridge(object_id_t objectId, setServerPort = serverPort; } -// uint16_t setClientPort = DEFAULT_UDP_CLIENT_PORT; -// if(clientPort != 0xFFFF) { -// setClientPort = clientPort; -// } + uint16_t setClientPort = DEFAULT_UDP_CLIENT_PORT; + if(clientPort != 0xFFFF) { + setClientPort = clientPort; + } // Set up UDP socket: https://man7.org/linux/man-pages/man7/ip.7.html - serverSocket = socket(AF_INET, SOCK_DGRAM, 0); + //clientSocket = socket(AF_INET, SOCK_DGRAM, 0); + serverSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if(socket < 0) { sif::error << "TmTcUnixUdpBridge::TmTcUnixUdpBridge: Could not open" " UDP socket!" << std::endl; @@ -36,10 +38,14 @@ TmTcUnixUdpBridge::TmTcUnixUdpBridge(object_id_t objectId, setsockopt(serverSocket, SOL_SOCKET, SO_REUSEADDR, &serverSocketOptions, sizeof(serverSocketOptions)); - serverSocketLen = sizeof(serverAddress); + clientAddress.sin_family = AF_INET; + clientAddress.sin_addr.s_addr = htonl(INADDR_ANY); + clientAddress.sin_port = htons(setClientPort); + + serverAddressLen = sizeof(serverAddress); int result = bind(serverSocket, reinterpret_cast(&serverAddress), - serverSocketLen); + serverAddressLen); if(result == -1) { sif::error << "TmTcUnixUdpBridge::TmTcUnixUdpBridge: Could not bind " "local port " << setServerPort << " to server socket!" @@ -54,20 +60,35 @@ TmTcUnixUdpBridge::~TmTcUnixUdpBridge() { ReturnValue_t TmTcUnixUdpBridge::sendTm(const uint8_t *data, size_t dataLen) { int flags = 0; - ssize_t result = send(serverSocket, data, dataLen, flags); - if(result < 0) { + sif::debug << "Client Port: "<(&clientAddress), clientAddressLen); + if(bytesSent < 0) { // todo: handle errors - sif::error << "TmTcUnixUdpBridge::sendTm: Send operation failed " - "with error " << strerror(errno) << std::endl; + sif::error << "TmTcUnixUdpBridge::sendTm: Send operation failed." + << std::endl; + sif::error << "Error: " << strerror(errno) << std::endl; + handleSendError(); } + sif::debug << "TmTcUnixUdpBridge::sendTm: " << bytesSent << " bytes were" + " sent." << std::endl; return HasReturnvaluesIF::RETURN_OK; } void TmTcUnixUdpBridge::checkAndSetClientAddress(sockaddr_in newAddress) { MutexHelper lock(mutex, 10); + + char ipAddress [15]; + sif::debug << "IP Address Sender: "<< inet_ntop(AF_INET, + &newAddress.sin_addr.s_addr, ipAddress, 15) << std::endl; + + sif::debug << "IP Address Old: " << inet_ntop(AF_INET, + &clientAddress.sin_addr.s_addr, ipAddress, 15) << std::endl; // Set new IP address if it has changed. if(clientAddress.sin_addr.s_addr != newAddress.sin_addr.s_addr) { + sif::info << "setting new address" << std::endl; clientAddress.sin_addr.s_addr = newAddress.sin_addr.s_addr; + clientAddressLen = sizeof(clientAddress); } } @@ -130,3 +151,8 @@ void TmTcUnixUdpBridge::handleBindError() { } } +void TmTcUnixUdpBridge::handleSendError() { + + +} + diff --git a/osal/linux/TmTcUnixUdpBridge.h b/osal/linux/TmTcUnixUdpBridge.h index 538664d8..dbddc6c3 100644 --- a/osal/linux/TmTcUnixUdpBridge.h +++ b/osal/linux/TmTcUnixUdpBridge.h @@ -15,8 +15,9 @@ public: static constexpr uint16_t DEFAULT_UDP_SERVER_PORT = 7301; static constexpr uint16_t DEFAULT_UDP_CLIENT_PORT = 7302; - TmTcUnixUdpBridge(object_id_t objectId, object_id_t ccsdsPacketDistributor, - uint16_t serverPort = 0xFFFF,uint16_t clientPort = 0xFFFF); + TmTcUnixUdpBridge(object_id_t objectId, object_id_t tcDestination, + object_id_t tmStoreId, object_id_t tcStoreId, + uint16_t serverPort = 0xFFFF,uint16_t clientPort = 0xFFFF); virtual~ TmTcUnixUdpBridge(); void checkAndSetClientAddress(sockaddr_in clientAddress); @@ -26,13 +27,14 @@ protected: private: int serverSocket = 0; + const int serverSocketOptions = 0; struct sockaddr_in clientAddress; - socklen_t clientSocketLen = 0; + socklen_t clientAddressLen = 0; struct sockaddr_in serverAddress; - socklen_t serverSocketLen = 0; + socklen_t serverAddressLen = 0; //! Access to the client address is mutex protected as it is set //! by another task. @@ -40,6 +42,7 @@ private: void handleSocketError(); void handleBindError(); + void handleSendError(); }; #endif /* FRAMEWORK_OSAL_LINUX_TMTCUNIXUDPBRIDGE_H_ */ diff --git a/tmtcservices/PusServiceBase.cpp b/tmtcservices/PusServiceBase.cpp index cb1e633f..4385609b 100644 --- a/tmtcservices/PusServiceBase.cpp +++ b/tmtcservices/PusServiceBase.cpp @@ -103,19 +103,17 @@ ReturnValue_t PusServiceBase::initialize() { packetDestination); PUSDistributorIF* distributor = objectManager->get( packetSource); - if ((destService != nullptr) && (distributor != nullptr)) { - this->requestQueue->setDefaultDestination( - destService->getReportReceptionQueue()); - distributor->registerService(this); - return RETURN_OK; - } - else { + if (destService == nullptr or distributor == nullptr) { sif::error << "PusServiceBase::PusServiceBase: Service " - << (uint32_t) this->serviceId << ": Configuration error." - << " Make sure packetSource and packetDestination are defined " - "correctly" << std::endl; - return RETURN_FAILED; + << this->serviceId << ": Configuration error. Make sure " + << "packetSource and packetDestination are defined correctly" + << std::endl; + return ObjectManagerIF::CHILD_INIT_FAILED; } + this->requestQueue->setDefaultDestination( + destService->getReportReceptionQueue()); + distributor->registerService(this); + return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t PusServiceBase::initializeAfterTaskCreation() { diff --git a/tmtcservices/TmTcBridge.cpp b/tmtcservices/TmTcBridge.cpp index 9c3e5b94..8c44f7de 100644 --- a/tmtcservices/TmTcBridge.cpp +++ b/tmtcservices/TmTcBridge.cpp @@ -5,9 +5,11 @@ #include #include -TmTcBridge::TmTcBridge(object_id_t objectId, - object_id_t ccsdsPacketDistributor): SystemObject(objectId), - ccsdsPacketDistributor(ccsdsPacketDistributor) +TmTcBridge::TmTcBridge(object_id_t objectId, object_id_t tcDestination, + object_id_t tmStoreId, object_id_t tcStoreId): + SystemObject(objectId),tmStoreId(tmStoreId), tcStoreId(tcStoreId), + tcDestination(tcDestination) + { tmTcReceptionQueue = QueueFactory::instance()-> createMessageQueue(TMTC_RECEPTION_QUEUE_DEPTH); @@ -42,18 +44,24 @@ ReturnValue_t TmTcBridge::setMaxNumberOfPacketsStored( } ReturnValue_t TmTcBridge::initialize() { - tcStore = objectManager->get(objects::TC_STORE); - if (tcStore == NULL) { - return RETURN_FAILED; + tcStore = objectManager->get(tcStoreId); + if (tcStore == nullptr) { + sif::error << "TmTcBridge::initialize: TC store invalid. Make sure" + "it is created and set up properly." << std::endl; + return ObjectManagerIF::CHILD_INIT_FAILED; } - tmStore = objectManager->get(objects::TM_STORE); - if (tmStore == NULL) { - return RETURN_FAILED; + tmStore = objectManager->get(tmStoreId); + if (tmStore == nullptr) { + sif::error << "TmTcBridge::initialize: TM store invalid. Make sure" + "it is created and set up properly." << std::endl; + return ObjectManagerIF::CHILD_INIT_FAILED; } AcceptsTelecommandsIF* tcDistributor = - objectManager->get(ccsdsPacketDistributor); - if (tcDistributor == NULL) { - return RETURN_FAILED; + objectManager->get(tcDestination); + if (tcDistributor == nullptr) { + sif::error << "TmTcBridge::initialize: TC Distributor invalid" + << std::endl; + return ObjectManagerIF::CHILD_INIT_FAILED; } tmTcReceptionQueue->setDefaultDestination(tcDistributor->getRequestQueue()); diff --git a/tmtcservices/TmTcBridge.h b/tmtcservices/TmTcBridge.h index 3fcbf84c..3e3d1b71 100644 --- a/tmtcservices/TmTcBridge.h +++ b/tmtcservices/TmTcBridge.h @@ -24,7 +24,8 @@ public: static constexpr uint8_t DEFAULT_STORED_DATA_SENT_PER_CYCLE = 5; static constexpr uint8_t DEFAULT_DOWNLINK_PACKETS_STORED = 10; - TmTcBridge(object_id_t objectId, object_id_t ccsdsPacketDistributor); + TmTcBridge(object_id_t objectId, object_id_t tcDestination, + object_id_t tmStoreId, object_id_t tcStoreId); virtual ~TmTcBridge(); /** @@ -69,14 +70,20 @@ public: virtual MessageQueueId_t getRequestQueue() override; protected: + //! Cached for initialize function. + object_id_t tmStoreId = objects::NO_OBJECT; + object_id_t tcStoreId = objects::NO_OBJECT; + object_id_t tcDestination = objects::NO_OBJECT; + //! Used to send and receive TMTC messages. //! TmTcMessage is used to transport messages between tasks. MessageQueueIF* tmTcReceptionQueue = nullptr; - StorageManagerIF* tcStore = nullptr; + StorageManagerIF* tmStore = nullptr; - object_id_t ccsdsPacketDistributor = 0; - //! Used to specify whether communication link is up - bool communicationLinkUp = false; + StorageManagerIF* tcStore = nullptr; + + //! Used to specify whether communication link is up by default. + bool communicationLinkUp = true; bool tmStored = false; /** diff --git a/tmtcservices/VerificationReporter.cpp b/tmtcservices/VerificationReporter.cpp index 40f7e57f..79e650f1 100644 --- a/tmtcservices/VerificationReporter.cpp +++ b/tmtcservices/VerificationReporter.cpp @@ -16,7 +16,7 @@ VerificationReporter::~VerificationReporter() {} void VerificationReporter::sendSuccessReport(uint8_t set_report_id, TcPacketBase* current_packet, uint8_t set_step) { - if (this->acknowledgeQueue == 0) { + if (acknowledgeQueue == MessageQueueIF::NO_QUEUE) { this->initialize(); } PusVerificationMessage message(set_report_id, @@ -35,7 +35,7 @@ void VerificationReporter::sendSuccessReport(uint8_t set_report_id, void VerificationReporter::sendSuccessReport(uint8_t set_report_id, uint8_t ackFlags, uint16_t tcPacketId, uint16_t tcSequenceControl, uint8_t set_step) { - if (this->acknowledgeQueue == 0) { + if (acknowledgeQueue == MessageQueueIF::NO_QUEUE) { this->initialize(); } PusVerificationMessage message(set_report_id, ackFlags, tcPacketId, @@ -52,7 +52,7 @@ void VerificationReporter::sendSuccessReport(uint8_t set_report_id, void VerificationReporter::sendFailureReport(uint8_t report_id, TcPacketBase* current_packet, ReturnValue_t error_code, uint8_t step, uint32_t parameter1, uint32_t parameter2) { - if (this->acknowledgeQueue == 0) { + if (acknowledgeQueue == MessageQueueIF::NO_QUEUE) { this->initialize(); } PusVerificationMessage message(report_id, @@ -73,7 +73,7 @@ void VerificationReporter::sendFailureReport(uint8_t report_id, uint8_t ackFlags, uint16_t tcPacketId, uint16_t tcSequenceControl, ReturnValue_t error_code, uint8_t step, uint32_t parameter1, uint32_t parameter2) { - if (this->acknowledgeQueue == 0) { + if (acknowledgeQueue == MessageQueueIF::NO_QUEUE) { this->initialize(); } PusVerificationMessage message(report_id, ackFlags, tcPacketId, From 8046d005a46e734aa2112cbd6f617920da2ec753 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 8 Jul 2020 18:18:54 +0200 Subject: [PATCH 251/307] CSB static framework id setting --- osal/linux/FixedTimeslotTask.cpp | 2 +- osal/linux/TcUnixUdpPollingTask.cpp | 35 +++++++++++++------ osal/linux/TcUnixUdpPollingTask.h | 2 +- osal/linux/TmTcUnixUdpBridge.cpp | 48 ++++++++++++++++---------- pus/Service2DeviceAccess.cpp | 3 +- tcdistribution/PUSDistributor.cpp | 8 ++--- tmtcservices/CommandingServiceBase.cpp | 18 +++++++--- tmtcservices/CommandingServiceBase.h | 28 ++++++++++++--- tmtcservices/PusServiceBase.cpp | 5 ++- 9 files changed, 99 insertions(+), 50 deletions(-) diff --git a/osal/linux/FixedTimeslotTask.cpp b/osal/linux/FixedTimeslotTask.cpp index e5c68f9d..9d7d08f6 100644 --- a/osal/linux/FixedTimeslotTask.cpp +++ b/osal/linux/FixedTimeslotTask.cpp @@ -45,7 +45,7 @@ ReturnValue_t FixedTimeslotTask::addSlot(object_id_t componentId, } sif::error << "Component " << std::hex << componentId << - " not found, not adding it to pst" << std::endl; + " not found, not adding it to pst" << std::dec << std::endl; return HasReturnvaluesIF::RETURN_FAILED; } diff --git a/osal/linux/TcUnixUdpPollingTask.cpp b/osal/linux/TcUnixUdpPollingTask.cpp index 122301da..8cf7b285 100644 --- a/osal/linux/TcUnixUdpPollingTask.cpp +++ b/osal/linux/TcUnixUdpPollingTask.cpp @@ -39,15 +39,14 @@ ReturnValue_t TcUnixUdpPollingTask::performOperation(uint8_t opCode) { reinterpret_cast(&senderAddress), &senderSockLen); if(bytesReceived < 0) { // handle error - sif::error << "TcSocketPollingTask::performOperation: recvfrom " - "failed with " << strerror(errno) << std::endl; - if(errno == EAGAIN or errno == EWOULDBLOCK) { - sif::info << "timeout" << std::endl; - } + sif::error << "TcSocketPollingTask::performOperation: Reception" + "error." << std::endl; + handleReadError(); + continue; } - sif::debug << "TcSocketPollingTask::performOperation: " << bytesReceived - << " bytes received" << std::endl; +// sif::debug << "TcSocketPollingTask::performOperation: " << bytesReceived +// << " bytes received" << std::endl; ReturnValue_t result = handleSuccessfullTcRead(bytesReceived); if(result != HasReturnvaluesIF::RETURN_FAILED) { @@ -61,14 +60,14 @@ ReturnValue_t TcUnixUdpPollingTask::performOperation(uint8_t opCode) { ReturnValue_t TcUnixUdpPollingTask::handleSuccessfullTcRead(size_t bytesRead) { - store_address_t storeId = 0; + store_address_t storeId; ReturnValue_t result = tcStore->addData(&storeId, receptionBuffer.data(), bytesRead); // arrayprinter::print(receptionBuffer.data(), bytesRead); if (result != HasReturnvaluesIF::RETURN_OK) { - sif::debug << "TcSerialPollingTask::transferPusToSoftwareBus: Data " + sif::error << "TcSerialPollingTask::transferPusToSoftwareBus: Data " "storage failed" << std::endl; - sif::debug << "Packet size: " << bytesRead << std::endl; + sif::error << "Packet size: " << bytesRead << std::endl; return HasReturnvaluesIF::RETURN_FAILED; } @@ -121,4 +120,18 @@ void TcUnixUdpPollingTask::setTimeout(double timeoutSeconds) { } } - +void TcUnixUdpPollingTask::handleReadError() { + switch(errno) { + case(EAGAIN): { + // todo: When working in timeout mode, this will occur more often + // and is not an error. + sif::error << "TcUnixUdpPollingTask::handleReadError: Timeout." + << std::endl; + break; + } + default: { + sif::error << "TcUnixUdpPollingTask::handleReadError: " + << strerror(errno) << std::endl; + } + } +} diff --git a/osal/linux/TcUnixUdpPollingTask.h b/osal/linux/TcUnixUdpPollingTask.h index 86591e8d..d8de1458 100644 --- a/osal/linux/TcUnixUdpPollingTask.h +++ b/osal/linux/TcUnixUdpPollingTask.h @@ -61,7 +61,7 @@ private: timeval receptionTimeout; ReturnValue_t handleSuccessfullTcRead(size_t bytesRead); - + void handleReadError(); }; #endif /* FRAMEWORK_OSAL_LINUX_TCSOCKETPOLLINGTASK_H_ */ diff --git a/osal/linux/TmTcUnixUdpBridge.cpp b/osal/linux/TmTcUnixUdpBridge.cpp index 40e96561..92fbbdfa 100644 --- a/osal/linux/TmTcUnixUdpBridge.cpp +++ b/osal/linux/TmTcUnixUdpBridge.cpp @@ -32,17 +32,20 @@ TmTcUnixUdpBridge::TmTcUnixUdpBridge(object_id_t objectId, } serverAddress.sin_family = AF_INET; + // Accept packets from any interface. + //serverAddress.sin_addr.s_addr = inet_addr("127.73.73.0"); serverAddress.sin_addr.s_addr = htonl(INADDR_ANY); serverAddress.sin_port = htons(setServerPort); + serverAddressLen = sizeof(serverAddress); setsockopt(serverSocket, SOL_SOCKET, SO_REUSEADDR, &serverSocketOptions, sizeof(serverSocketOptions)); clientAddress.sin_family = AF_INET; clientAddress.sin_addr.s_addr = htonl(INADDR_ANY); clientAddress.sin_port = htons(setClientPort); + clientAddressLen = sizeof(clientAddress); - serverAddressLen = sizeof(serverAddress); int result = bind(serverSocket, reinterpret_cast(&serverAddress), serverAddressLen); @@ -60,33 +63,38 @@ TmTcUnixUdpBridge::~TmTcUnixUdpBridge() { ReturnValue_t TmTcUnixUdpBridge::sendTm(const uint8_t *data, size_t dataLen) { int flags = 0; - sif::debug << "Client Port: "<(&clientAddress), clientAddressLen); if(bytesSent < 0) { - // todo: handle errors sif::error << "TmTcUnixUdpBridge::sendTm: Send operation failed." << std::endl; - sif::error << "Error: " << strerror(errno) << std::endl; handleSendError(); } - sif::debug << "TmTcUnixUdpBridge::sendTm: " << bytesSent << " bytes were" - " sent." << std::endl; +// sif::debug << "TmTcUnixUdpBridge::sendTm: " << bytesSent << " bytes were" +// " sent." << std::endl; return HasReturnvaluesIF::RETURN_OK; } void TmTcUnixUdpBridge::checkAndSetClientAddress(sockaddr_in newAddress) { MutexHelper lock(mutex, 10); - char ipAddress [15]; - sif::debug << "IP Address Sender: "<< inet_ntop(AF_INET, - &newAddress.sin_addr.s_addr, ipAddress, 15) << std::endl; +// char ipAddress [15]; +// sif::debug << "IP Address Sender: "<< inet_ntop(AF_INET, +// &newAddress.sin_addr.s_addr, ipAddress, 15) << std::endl; +// sif::debug << "IP Address Old: " << inet_ntop(AF_INET, +// &clientAddress.sin_addr.s_addr, ipAddress, 15) << std::endl; - sif::debug << "IP Address Old: " << inet_ntop(AF_INET, - &clientAddress.sin_addr.s_addr, ipAddress, 15) << std::endl; // Set new IP address if it has changed. if(clientAddress.sin_addr.s_addr != newAddress.sin_addr.s_addr) { - sif::info << "setting new address" << std::endl; clientAddress.sin_addr.s_addr = newAddress.sin_addr.s_addr; clientAddressLen = sizeof(clientAddress); } @@ -104,11 +112,11 @@ void TmTcUnixUdpBridge::handleSocketError() { case(ENOBUFS): case(ENOMEM): case(EPROTONOSUPPORT): - sif::error << "TmTcUnixBridge::TmTcUnixBridge: Socket creation failed" + sif::error << "TmTcUnixBridge::handleSocketError: Socket creation failed" << " with " << strerror(errno) << std::endl; break; default: - sif::error << "TmTcUnixBridge::TmTcUnixBridge: Unknown error" + sif::error << "TmTcUnixBridge::handleSocketError: Unknown error" << std::endl; break; } @@ -122,7 +130,7 @@ void TmTcUnixUdpBridge::handleBindError() { Ephermeral ports can be shown with following command: sysctl -A | grep ip_local_port_range */ - sif::error << "TmTcUnixBridge::TmTcUnixBridge: Port access issue." + sif::error << "TmTcUnixBridge::handleBindError: Port access issue." "Ports 1-1024 are reserved on UNIX systems and require root " "rights while ephermeral ports should not be used as well." << std::endl; @@ -140,19 +148,21 @@ void TmTcUnixUdpBridge::handleBindError() { case(ENOMEM): case(ENOTDIR): case(EROFS): { - sif::error << "TmTcUnixBridge::TmTcUnixBridge: Socket creation failed" + sif::error << "TmTcUnixBridge::handleBindError: Socket creation failed" << " with " << strerror(errno) << std::endl; break; } default: - sif::error << "TmTcUnixBridge::TmTcUnixBridge: Unknown error" + sif::error << "TmTcUnixBridge::handleBindError: Unknown error" << std::endl; break; } } void TmTcUnixUdpBridge::handleSendError() { - - + switch(errno) { + default: + sif::error << "Error: " << strerror(errno) << std::endl; + } } diff --git a/pus/Service2DeviceAccess.cpp b/pus/Service2DeviceAccess.cpp index 391c1116..4648aa9c 100644 --- a/pus/Service2DeviceAccess.cpp +++ b/pus/Service2DeviceAccess.cpp @@ -15,8 +15,7 @@ Service2DeviceAccess::Service2DeviceAccess(object_id_t objectId, object_id_t tmDestination, uint8_t numberOfParallelCommands, uint16_t commandTimeoutSeconds): CommandingServiceBase(objectId, apid, serviceId, - numberOfParallelCommands, commandTimeoutSeconds, - tcSource, tmDestination) {} + numberOfParallelCommands, commandTimeoutSeconds) {} Service2DeviceAccess::~Service2DeviceAccess() {} diff --git a/tcdistribution/PUSDistributor.cpp b/tcdistribution/PUSDistributor.cpp index d6e20acf..969380d6 100644 --- a/tcdistribution/PUSDistributor.cpp +++ b/tcdistribution/PUSDistributor.cpp @@ -13,12 +13,12 @@ PUSDistributor::PUSDistributor(uint16_t setApid, object_id_t setObjectId, PUSDistributor::~PUSDistributor() {} TcDistributor::TcMqMapIter PUSDistributor::selectDestination() { -// debug << "PUSDistributor::handlePacket received: " << this->current_packet_id.store_index << ", " << this->current_packet_id.packet_index << std::endl; TcMqMapIter queueMapIt = this->queueMap.end(); this->currentPacket.setStoreAddress(this->currentMessage.getStorageId()); if (currentPacket.getWholeData() != NULL) { tcStatus = checker.checkPacket(¤tPacket); -// info << "PUSDistributor::handlePacket: packetCheck returned with " << (int)tc_status << std::endl; +// sif::debug << "PUSDistributor::handlePacket: packetCheck returned with " +// << (int)tcStatus << std::endl; uint32_t queue_id = currentPacket.getService(); queueMapIt = this->queueMap.find(queue_id); } else { @@ -29,8 +29,8 @@ TcDistributor::TcMqMapIter PUSDistributor::selectDestination() { } if (tcStatus != RETURN_OK) { - sif::debug << "PUSDistributor::handlePacket: error with " << (int) tcStatus - << ", 0x"<< std::hex << (int) tcStatus << std::endl; + sif::debug << "PUSDistributor::handlePacket: Error with " << tcStatus + << ", 0x"<< std::hex << tcStatus << std::dec << std::endl; return this->queueMap.end(); } else { return queueMapIt; diff --git a/tmtcservices/CommandingServiceBase.cpp b/tmtcservices/CommandingServiceBase.cpp index 0c5f5eab..63a3d943 100644 --- a/tmtcservices/CommandingServiceBase.cpp +++ b/tmtcservices/CommandingServiceBase.cpp @@ -8,18 +8,28 @@ #include #include +object_id_t CommandingServiceBase::packetSource = objects::NO_OBJECT; +object_id_t CommandingServiceBase::packetDestination = objects::NO_OBJECT; + CommandingServiceBase::CommandingServiceBase(object_id_t setObjectId, uint16_t apid, uint8_t service, uint8_t numberOfParallelCommands, - uint16_t commandTimeoutSeconds, object_id_t setPacketSource, - object_id_t setPacketDestination, size_t queueDepth) : + uint16_t commandTimeoutSeconds, size_t queueDepth) : SystemObject(setObjectId), apid(apid), service(service), timeoutSeconds(commandTimeoutSeconds), - commandMap(numberOfParallelCommands), packetSource(setPacketSource), - packetDestination(setPacketDestination) { + commandMap(numberOfParallelCommands) { commandQueue = QueueFactory::instance()->createMessageQueue(queueDepth); requestQueue = QueueFactory::instance()->createMessageQueue(queueDepth); } +void CommandingServiceBase::setPacketSource(object_id_t packetSource) { + this->packetSource = packetSource; +} + +void CommandingServiceBase::setPacketDestination( + object_id_t packetDestination) { + this->packetDestination = packetDestination; +} + CommandingServiceBase::~CommandingServiceBase() { QueueFactory::instance()->deleteMessageQueue(commandQueue); diff --git a/tmtcservices/CommandingServiceBase.h b/tmtcservices/CommandingServiceBase.h index 700503c6..e9b5f047 100644 --- a/tmtcservices/CommandingServiceBase.h +++ b/tmtcservices/CommandingServiceBase.h @@ -15,6 +15,10 @@ class TcPacketStored; +namespace Factory{ +void setStaticFrameworkObjectIds(); +} + /** * @brief This class is the basis for all PUS Services, which have to * relay Telecommands to software bus. @@ -33,6 +37,7 @@ class CommandingServiceBase: public SystemObject, public AcceptsTelecommandsIF, public ExecutableObjectIF, public HasReturnvaluesIF { + friend void (Factory::setStaticFrameworkObjectIds)(); public: static const uint8_t INTERFACE_ID = CLASS_ID::COMMAND_SERVICE_BASE; static const ReturnValue_t EXECUTION_COMPLETE = MAKE_RETURN_CODE(1); @@ -57,10 +62,24 @@ public: */ CommandingServiceBase(object_id_t setObjectId, uint16_t apid, uint8_t service, uint8_t numberOfParallelCommands, - uint16_t commandTimeoutSeconds, object_id_t setPacketSource, - object_id_t setPacketDestination, size_t queueDepth = 20); + uint16_t commandTimeoutSeconds, size_t queueDepth = 20); virtual ~CommandingServiceBase(); + /** + * This setter can be used to set the packet source individually instead + * of using the default static framework ID set in the factory. + * This should be called at object initialization and not during run-time! + * @param packetSource + */ + void setPacketSource(object_id_t packetSource); + /** + * This setter can be used to set the packet destination individually + * instead of using the default static framework ID set in the factory. + * This should be called at object initialization and not during run-time! + * @param packetDestination + */ + void setPacketDestination(object_id_t packetDestination); + /*** * This is the periodically called function. * Handle request queue for external commands. @@ -229,9 +248,8 @@ protected: uint32_t failureParameter1 = 0; uint32_t failureParameter2 = 0; - object_id_t packetSource; - - object_id_t packetDestination; + static object_id_t packetSource; + static object_id_t packetDestination; /** * Pointer to the task which executes this component, diff --git a/tmtcservices/PusServiceBase.cpp b/tmtcservices/PusServiceBase.cpp index 4385609b..877eff3e 100644 --- a/tmtcservices/PusServiceBase.cpp +++ b/tmtcservices/PusServiceBase.cpp @@ -79,9 +79,8 @@ void PusServiceBase::handleRequestQueue() { } else { sif::error << "PusServiceBase::performOperation: Service " - << (uint16_t) this->serviceId - << ": Error receiving packet. Code: " << std::hex << status - << std::dec << std::endl; + << this->serviceId << ": Error receiving packet. Code: " + << std::hex << status << std::dec << std::endl; } } } From dc27cc9aff73e6c17eb36281d056bd7c217ba6b6 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 8 Jul 2020 18:37:26 +0200 Subject: [PATCH 252/307] srv8 added to framework --- pus/Service2DeviceAccess.cpp | 7 +- pus/Service2DeviceAccess.h | 3 +- pus/Service8FunctionManagement.cpp | 129 +++++++++++++++++++++++++ pus/Service8FunctionManagement.h | 64 +++++++++++++ pus/servicepackets/Service8Packets.h | 136 +++++++++++++++++++++++++++ 5 files changed, 334 insertions(+), 5 deletions(-) create mode 100644 pus/Service8FunctionManagement.cpp create mode 100644 pus/Service8FunctionManagement.h create mode 100644 pus/servicepackets/Service8Packets.h diff --git a/pus/Service2DeviceAccess.cpp b/pus/Service2DeviceAccess.cpp index 4648aa9c..1d5f21eb 100644 --- a/pus/Service2DeviceAccess.cpp +++ b/pus/Service2DeviceAccess.cpp @@ -11,14 +11,14 @@ #include Service2DeviceAccess::Service2DeviceAccess(object_id_t objectId, - uint16_t apid, uint8_t serviceId, object_id_t tcSource, - object_id_t tmDestination, uint8_t numberOfParallelCommands, + uint16_t apid, uint8_t serviceId, uint8_t numberOfParallelCommands, uint16_t commandTimeoutSeconds): CommandingServiceBase(objectId, apid, serviceId, numberOfParallelCommands, commandTimeoutSeconds) {} Service2DeviceAccess::~Service2DeviceAccess() {} + ReturnValue_t Service2DeviceAccess::isValidSubservice(uint8_t subservice) { switch(static_cast(subservice)){ case Subservice::RAW_COMMANDING: @@ -41,7 +41,6 @@ ReturnValue_t Service2DeviceAccess::getMessageQueueAndObject( ReturnValue_t result = checkInterfaceAndAcquireMessageQueue(id,objectId); return result; - } ReturnValue_t Service2DeviceAccess::checkInterfaceAndAcquireMessageQueue( @@ -55,6 +54,7 @@ ReturnValue_t Service2DeviceAccess::checkInterfaceAndAcquireMessageQueue( return HasReturnvaluesIF::RETURN_OK; } + ReturnValue_t Service2DeviceAccess::prepareCommand(CommandMessage* message, uint8_t subservice, const uint8_t* tcData, size_t tcDataLen, uint32_t* state, object_id_t objectId) { @@ -100,6 +100,7 @@ ReturnValue_t Service2DeviceAccess::prepareWiretappingCommand( return result; } + ReturnValue_t Service2DeviceAccess::handleReply(const CommandMessage* reply, Command_t previousCommand, uint32_t* state, CommandMessage* optionalNextCommand, object_id_t objectId, diff --git a/pus/Service2DeviceAccess.h b/pus/Service2DeviceAccess.h index 4dab0fa0..1a0bede0 100644 --- a/pus/Service2DeviceAccess.h +++ b/pus/Service2DeviceAccess.h @@ -36,8 +36,7 @@ class Service2DeviceAccess : public CommandingServiceBase, { public: Service2DeviceAccess(object_id_t objectId, uint16_t apid, - uint8_t serviceId, object_id_t tcSource, - object_id_t tmDestination, uint8_t numberOfParallelCommands = 4, + uint8_t serviceId, uint8_t numberOfParallelCommands = 4, uint16_t commandTimeoutSeconds = 60); virtual ~Service2DeviceAccess(); diff --git a/pus/Service8FunctionManagement.cpp b/pus/Service8FunctionManagement.cpp new file mode 100644 index 00000000..47afeae6 --- /dev/null +++ b/pus/Service8FunctionManagement.cpp @@ -0,0 +1,129 @@ +#include +#include + +#include +#include +#include +#include +#include +#include + +Service8FunctionManagement::Service8FunctionManagement(object_id_t object_id, + uint16_t apid, uint8_t serviceId, uint8_t numParallelCommands, + uint16_t commandTimeoutSeconds): + CommandingServiceBase(object_id, apid, serviceId, numParallelCommands, + commandTimeoutSeconds) {} + +Service8FunctionManagement::~Service8FunctionManagement() {} + + +ReturnValue_t Service8FunctionManagement::isValidSubservice( + uint8_t subservice) { + switch(static_cast(subservice)) { + case Subservice::DIRECT_COMMANDING: + return HasReturnvaluesIF::RETURN_OK; + default: + return AcceptsTelecommandsIF::INVALID_SUBSERVICE; + } +} + +ReturnValue_t Service8FunctionManagement::getMessageQueueAndObject( + uint8_t subservice, const uint8_t* tcData, size_t tcDataLen, + MessageQueueId_t* id, object_id_t* objectId) { + if(tcDataLen < sizeof(object_id_t)) { + return CommandingServiceBase::INVALID_TC; + } + SerializeAdapter::deSerialize(objectId, &tcData, + &tcDataLen, SerializeIF::Endianness::BIG); + + return checkInterfaceAndAcquireMessageQueue(id,objectId); +} + +ReturnValue_t Service8FunctionManagement::checkInterfaceAndAcquireMessageQueue( + MessageQueueId_t* messageQueueToSet, object_id_t* objectId) { + // check HasActionIF property of target + HasActionsIF* possibleTarget = objectManager->get(*objectId); + if(possibleTarget == nullptr){ + return CommandingServiceBase::INVALID_OBJECT; + } + *messageQueueToSet = possibleTarget->getCommandQueue(); + return HasReturnvaluesIF::RETURN_OK; +} + + +ReturnValue_t Service8FunctionManagement::prepareCommand( + CommandMessage* message, uint8_t subservice, const uint8_t* tcData, + size_t tcDataLen, uint32_t* state, object_id_t objectId) { + ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED; + if(subservice == static_cast(Subservice::DIRECT_COMMANDING)) { + result = prepareDirectCommand(dynamic_cast(message), + tcData, tcDataLen); + } + return result; +} + +ReturnValue_t Service8FunctionManagement::prepareDirectCommand( + CommandMessage *message, const uint8_t *tcData, size_t tcDataLen) { + // Create direct command instance by extracting data from Telecommand + DirectCommand command(tcData,tcDataLen); + + // store additional parameters into the Inter Process Communication Store + store_address_t parameterAddress; + ReturnValue_t result = IPCStore->addData(¶meterAddress, + command.getParameters(),command.getParametersSize()); + + // setCommand expects a Command Message, an Action ID and a store adress + // pointing to additional parameters + ActionMessage::setCommand(message,command.getActionId(),parameterAddress); + return result; +} + + +ReturnValue_t Service8FunctionManagement::handleReply( + const CommandMessage* reply, Command_t previousCommand, + uint32_t* state, CommandMessage* optionalNextCommand, + object_id_t objectId, bool* isStep) { + Command_t replyId = reply->getCommand(); + ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED; + ActionId_t actionId = ActionMessage::getActionId(reply); + ReturnValue_t returnCode = ActionMessage::getReturnCode(reply); + + switch(replyId) { + case ActionMessage::COMPLETION_SUCCESS: { + DirectReply completionReply(objectId, actionId,returnCode); + result = CommandingServiceBase::EXECUTION_COMPLETE; + break; + } + case ActionMessage::STEP_SUCCESS: { + *isStep = true; + result = HasReturnvaluesIF::RETURN_OK; + break; + } + case ActionMessage::DATA_REPLY: { + store_address_t storeId = ActionMessage::getStoreId(reply); + size_t size = 0; + const uint8_t * buffer = nullptr; + result = IPCStore->getData(storeId, &buffer, &size); + if(result != RETURN_OK) { + sif::error << "Service 8: Could not retrieve data for data reply"; + return result; + } + DataReply dataReply(objectId,actionId,buffer,size); + sendTmPacket(static_cast( + Subservice::DIRECT_COMMANDING_DATA_REPLY), &dataReply); + result = IPCStore ->deleteData(storeId); + break; + } + case ActionMessage::STEP_FAILED: + *isStep = true; + /*No break, falls through*/ + case ActionMessage::COMPLETION_FAILED: + result = ActionMessage::getReturnCode(reply); + break; + default: + result = INVALID_REPLY; + } + return result; +} + + diff --git a/pus/Service8FunctionManagement.h b/pus/Service8FunctionManagement.h new file mode 100644 index 00000000..e06c554c --- /dev/null +++ b/pus/Service8FunctionManagement.h @@ -0,0 +1,64 @@ +#ifndef MISSION_SERVICE8FUNCTIONMANAGEMENT_H_ +#define MISSION_SERVICE8FUNCTIONMANAGEMENT_H_ + +#include + +/** + * @brief Functional commanding. + * Full Documentation: ECSS-E-ST-70-41C p.64, p. 451 + * Dissertation Baetz p. 115, 116, 165-167 + * + * This service provides the capability to perform functions of an + * application process and provides high-level commanding as opposed to the + * Raw Access provided by Service 2. Examples for these functions can include + * control and operation of payload or the AOCS subsystem. + * This service will be the primary means to control the spacecraft as it is + * considered safer than the Raw Access provided + * by Service 2 and is generally sufficient for most tasks. + * + * This is a gateway service. It relays device commands using the software bus. + * This service is very closely tied to the Commanding Service Base template + * class. There is constant interaction between this Service Base und a + * subclass like this service. + * + * Service Capability: + * - TC[8,128]: Direct Commanding + * - TM[8,130]: Direct Commanding Data Reply + * + * @ingroup pus_services + */ +class Service8FunctionManagement : public CommandingServiceBase +{ +public: + Service8FunctionManagement(object_id_t objectId, uint16_t apid, + uint8_t serviceId, uint8_t numParallelCommands = 4, + uint16_t commandTimeoutSeconds = 60); + virtual ~Service8FunctionManagement(); + +protected: + /* CSB abstract functions implementation . See CSB documentation. */ + ReturnValue_t isValidSubservice(uint8_t subservice) override; + ReturnValue_t getMessageQueueAndObject(uint8_t subservice, + const uint8_t *tcData, size_t tcDataLen, MessageQueueId_t *id, + object_id_t *objectId) override; + ReturnValue_t prepareCommand(CommandMessage* message, + uint8_t subservice, const uint8_t *tcData, size_t tcDataLen, + uint32_t *state, object_id_t objectId) override; + ReturnValue_t handleReply(const CommandMessage* reply, + Command_t previousCommand, uint32_t *state, + CommandMessage* optionalNextCommand, object_id_t objectId, + bool *isStep) override; + +private: + enum class Subservice { + DIRECT_COMMANDING = 128, //!< [EXPORT] : [COMMAND] Functional commanding + DIRECT_COMMANDING_DATA_REPLY = 130, //!< [EXPORT] : [REPLY] Data reply + }; + + ReturnValue_t checkInterfaceAndAcquireMessageQueue( + MessageQueueId_t* messageQueueToSet, object_id_t* objectId); + ReturnValue_t prepareDirectCommand(CommandMessage* message, + const uint8_t* tcData, size_t tcDataLen); +}; + +#endif /* MISSION_DEVICE2DEVICECOMMANDING_H_ */ diff --git a/pus/servicepackets/Service8Packets.h b/pus/servicepackets/Service8Packets.h new file mode 100644 index 00000000..5ef91280 --- /dev/null +++ b/pus/servicepackets/Service8Packets.h @@ -0,0 +1,136 @@ +/** + * \file Service8Packets.h + * + * \brief Structure of a Direct Command. + * Normal reply (subservice 130) consists of + * 1. Target object ID + * 2. Action ID (taget device has specified functions with action IDs) + * 3. Return Code + * 4. Optional step number for step replies + * + * Data reply (subservice 132) consists of + * 1. Target Object ID + * 2. Action ID + * 3. Data + * + * \date 01.07.2019 + * \author R. Mueller + */ + +#ifndef FRAMEWORK_PUS_SERVICEPACKETS_SERVICE8PACKETS_H_ +#define FRAMEWORK_PUS_SERVICEPACKETS_SERVICE8PACKETS_H_ + +#include +#include +#include +#include +#include +#include + + +/** + * \brief Subservice 128 + * \ingroup spacepackets + */ +class DirectCommand: public SerialLinkedListAdapter { //!< [EXPORT] : [SUBSERVICE] 128 +public: + //typedef uint16_t typeOfMaxData; + //static const typeOfMaxData MAX_DATA = 256; + DirectCommand(const uint8_t* dataBuffer_, uint32_t size_) { + size_t size = sizeof(objectId); + SerializeAdapter::deSerialize(&objectId,&dataBuffer_,&size, + SerializeIF::Endianness::BIG); + size = sizeof(actionId); + SerializeAdapter::deSerialize(&actionId,&dataBuffer_,&size, + SerializeIF::Endianness::BIG); + parameterBuffer = dataBuffer_; + parametersSize = size_ - sizeof(objectId) - sizeof(actionId); + } + ActionId_t getActionId() const { + return actionId; + } + + object_id_t getObjectId() const { + return objectId; + } + + const uint8_t* getParameters() { + return parameterBuffer; + } + + uint32_t getParametersSize() const { + return parametersSize; + } + +private: + DirectCommand(const DirectCommand &command); + object_id_t objectId; + ActionId_t actionId; + uint32_t parametersSize; //!< [EXPORT] : [IGNORE] + const uint8_t * parameterBuffer; //!< [EXPORT] : [MAXSIZE] 65535 Bytes + +}; + + +/** + * \brief Subservice 130 + * \ingroup spacepackets + */ +class DataReply: public SerialLinkedListAdapter { //!< [EXPORT] : [SUBSERVICE] 130 +public: + typedef uint16_t typeOfMaxDataSize; + static const uint16_t MAX_DATA_LENGTH = sizeof(typeOfMaxDataSize); + DataReply(object_id_t objectId_, ActionId_t actionId_, + const uint8_t * replyDataBuffer_ = NULL, uint16_t replyDataSize_ = 0): + objectId(objectId_), actionId(actionId_), replyData(replyDataBuffer_,replyDataSize_){ + setLinks(); + } + +private: + DataReply(const DataReply &reply); + void setLinks() { + setStart(&objectId); + objectId.setNext(&actionId); + actionId.setNext(&replyData); + } + SerializeElement objectId; + SerializeElement actionId; + SerializeElement> replyData; +}; + + +/** + * \brief Subservice 132 + * \ingroup spacepackets + */ +class DirectReply: public SerialLinkedListAdapter { //!< [EXPORT] : [SUBSERVICE] 132 +public: + typedef uint16_t typeOfMaxDataSize; + static const uint16_t MAX_DATA_LENGTH = sizeof(typeOfMaxDataSize); + + DirectReply(object_id_t objectId_, ActionId_t actionId_, ReturnValue_t returnCode_, + bool isStep_ = false, uint8_t step_ = 0): + isStep(isStep_), objectId(objectId_), actionId(actionId_), + returnCode(returnCode_),step(step_) { + setLinks(); + } +private: + + void setLinks() { + setStart(&objectId); + objectId.setNext(&actionId); + actionId.setNext(&returnCode); + if(isStep) { + returnCode.setNext(&step); + } + } + bool isDataReply; //!< [EXPORT] : [IGNORE] + bool isStep; //!< [EXPORT] : [IGNORE] + SerializeElement objectId; //!< [EXPORT] : [IGNORE] + SerializeElement actionId; //!< [EXPORT] : [IGNORE] + SerializeElement returnCode; //!< [EXPORT] : [IGNORE] + SerializeElement step; //!< [EXPORT] : [OPTIONAL] [IGNORE] + +}; + +#endif /* FRAMEWORK_PUS_SERVICEPACKETS_SERVICE8PACKETS_H_ */ From 64c290ffe44ce6a4352152bcb1a04ff643bfd395 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 8 Jul 2020 18:38:58 +0200 Subject: [PATCH 253/307] include guard fix --- pus/Service8FunctionManagement.cpp | 2 +- pus/Service8FunctionManagement.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pus/Service8FunctionManagement.cpp b/pus/Service8FunctionManagement.cpp index 47afeae6..24338464 100644 --- a/pus/Service8FunctionManagement.cpp +++ b/pus/Service8FunctionManagement.cpp @@ -67,7 +67,7 @@ ReturnValue_t Service8FunctionManagement::prepareDirectCommand( // Create direct command instance by extracting data from Telecommand DirectCommand command(tcData,tcDataLen); - // store additional parameters into the Inter Process Communication Store + // store additional parameters into the IPC Store store_address_t parameterAddress; ReturnValue_t result = IPCStore->addData(¶meterAddress, command.getParameters(),command.getParametersSize()); diff --git a/pus/Service8FunctionManagement.h b/pus/Service8FunctionManagement.h index e06c554c..54c98b97 100644 --- a/pus/Service8FunctionManagement.h +++ b/pus/Service8FunctionManagement.h @@ -1,5 +1,5 @@ -#ifndef MISSION_SERVICE8FUNCTIONMANAGEMENT_H_ -#define MISSION_SERVICE8FUNCTIONMANAGEMENT_H_ +#ifndef FRAMEWORK_PUS_SERVICE8FUNCTIONMANAGEMENT_H_ +#define FRAMEWORK_PUS_SERVICE8FUNCTIONMANAGEMENT_H_ #include @@ -61,4 +61,4 @@ private: const uint8_t* tcData, size_t tcDataLen); }; -#endif /* MISSION_DEVICE2DEVICECOMMANDING_H_ */ +#endif /* FRAMEWORK_PUS_SERVICE8FUNCTIONMANAGEMENT_H_ */ From ac9e6e1337acc8a5f68811be1f5da30c69a3e52e Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 9 Jul 2020 00:59:10 +0200 Subject: [PATCH 254/307] continued with local data pool manager --- datapoolglob/GlobalDataSet.h | 6 +- ...LocalDataPoolIF.h => HasLocalDataPoolIF.h} | 4 +- datapoollocal/LocalDataPoolManager.cpp | 14 +-- datapoollocal/LocalDataPoolManager.h | 95 ++++++++++++++----- datapoollocal/LocalDataSet.cpp | 4 +- datapoollocal/LocalDataSet.h | 4 +- datapoollocal/LocalPoolVariable.h | 4 +- datapoollocal/LocalPoolVariable.tpp | 6 +- datapoollocal/LocalPoolVector.h | 2 +- datapoollocal/LocalPoolVector.tpp | 6 +- devicehandlers/DeviceHandlerBase.h | 5 +- 11 files changed, 97 insertions(+), 53 deletions(-) rename datapoollocal/{OwnsLocalDataPoolIF.h => HasLocalDataPoolIF.h} (97%) diff --git a/datapoolglob/GlobalDataSet.h b/datapoolglob/GlobalDataSet.h index 519b08c0..d237cc1b 100644 --- a/datapoolglob/GlobalDataSet.h +++ b/datapoolglob/GlobalDataSet.h @@ -1,5 +1,5 @@ -#ifndef DATASET_H_ -#define DATASET_H_ +#ifndef FRAMEWORK_DATAPOOLGLOB_DATASET_H_ +#define FRAMEWORK_DATAPOOLGLOB_DATASET_H_ #include @@ -93,4 +93,4 @@ private: PoolVariableIF* registeredVariables[DATA_SET_MAX_SIZE]; }; -#endif /* DATASET_H_ */ +#endif /* FRAMEWORK_DATAPOOLGLOB_DATASET_H_ */ diff --git a/datapoollocal/OwnsLocalDataPoolIF.h b/datapoollocal/HasLocalDataPoolIF.h similarity index 97% rename from datapoollocal/OwnsLocalDataPoolIF.h rename to datapoollocal/HasLocalDataPoolIF.h index 6fc10889..0095f894 100644 --- a/datapoollocal/OwnsLocalDataPoolIF.h +++ b/datapoollocal/HasLocalDataPoolIF.h @@ -36,9 +36,9 @@ using LocalDataPoolMapIter = LocalDataPool::iterator; * pragmatic solution I found was to offer the client the full interface * of the LocalDataPoolManager. */ -class OwnsLocalDataPoolIF { +class HasLocalDataPoolIF { public: - virtual~ OwnsLocalDataPoolIF() {}; + virtual~ HasLocalDataPoolIF() {}; static constexpr uint8_t INTERFACE_ID = CLASS_ID::LOCAL_POOL_OWNER_IF; diff --git a/datapoollocal/LocalDataPoolManager.cpp b/datapoollocal/LocalDataPoolManager.cpp index 9c70c74f..02016abf 100644 --- a/datapoollocal/LocalDataPoolManager.cpp +++ b/datapoollocal/LocalDataPoolManager.cpp @@ -7,7 +7,7 @@ #include -LocalDataPoolManager::LocalDataPoolManager(OwnsLocalDataPoolIF* owner, +LocalDataPoolManager::LocalDataPoolManager(HasLocalDataPoolIF* owner, MessageQueueIF* queueToUse, bool appendValidityBuffer): appendValidityBuffer(appendValidityBuffer) { if(owner == nullptr) { @@ -63,7 +63,7 @@ LocalDataPoolManager::~LocalDataPoolManager() {} ReturnValue_t LocalDataPoolManager::initializeHousekeepingPoolEntriesOnce() { if(not mapInitialized) { - ReturnValue_t result = owner->initializePoolEntries(localDpMap); + ReturnValue_t result = owner->initializePoolEntries(localPoolMap); if(result == HasReturnvaluesIF::RETURN_OK) { mapInitialized = true; } @@ -96,8 +96,8 @@ ReturnValue_t LocalDataPoolManager::handleHousekeepingMessage( ReturnValue_t LocalDataPoolManager::printPoolEntry( lp_id_t localPoolId) { - auto poolIter = localDpMap.find(localPoolId); - if (poolIter == localDpMap.end()) { + auto poolIter = localPoolMap.find(localPoolId); + if (poolIter == localPoolMap.end()) { sif::debug << "HousekeepingManager::fechPoolEntry:" " Pool entry not found." << std::endl; return POOL_ENTRY_NOT_FOUND; @@ -110,7 +110,7 @@ MutexIF* LocalDataPoolManager::getMutexHandle() { return mutex; } -const OwnsLocalDataPoolIF* LocalDataPoolManager::getOwner() const { +const HasLocalDataPoolIF* LocalDataPoolManager::getOwner() const { return owner; } @@ -213,4 +213,6 @@ ReturnValue_t LocalDataPoolManager::serializeHkPacketIntoStore( return result; } - +ReturnValue_t LocalDataPoolManager::performHkOperation() { + return HasReturnvaluesIF::RETURN_OK; +} diff --git a/datapoollocal/LocalDataPoolManager.h b/datapoollocal/LocalDataPoolManager.h index 3841b99c..847c309c 100644 --- a/datapoollocal/LocalDataPoolManager.h +++ b/datapoollocal/LocalDataPoolManager.h @@ -1,12 +1,13 @@ -#ifndef FRAMEWORK_HK_HOUSEKEEPINGHELPER_H_ -#define FRAMEWORK_HK_HOUSEKEEPINGHELPER_H_ +#ifndef FRAMEWORK_DATAPOOLLOCAL_LOCALDATAPOOLMANAGER_H_ +#define FRAMEWORK_DATAPOOLLOCAL_LOCALDATAPOOLMANAGER_H_ + #include #include #include #include #include -#include +#include #include #include #include @@ -20,7 +21,7 @@ class LocalDataSet; * @details * The actual data pool structure is a member of this class. Any class which * has a local data pool shall have this class as a member and implement - * the OwnsLocalDataPoolIF. + * the HasLocalDataPoolIF. * * Users of the data pool use the helper classes LocalDataSet, * LocalPoolVariable and LocalPoolVector to access pool entries in @@ -57,16 +58,24 @@ public: * @param queueToUse * @param appendValidityBuffer */ - LocalDataPoolManager(OwnsLocalDataPoolIF* owner, MessageQueueIF* queueToUse, + LocalDataPoolManager(HasLocalDataPoolIF* owner, MessageQueueIF* queueToUse, bool appendValidityBuffer = true); + virtual~ LocalDataPoolManager(); + /** * Initializes the map by calling the map initialization function of the - * owner abd assigns the queue to use. + * owner and assigns the queue to use. * @param queueToUse * @return */ ReturnValue_t initialize(MessageQueueIF* queueToUse, object_id_t hkDestination); + /** + * This should be called in the periodic handler of the owner. + * It performs all the periodic functionalities of the data pool manager. + * @return + */ + ReturnValue_t performHkOperation(); /** * This function is used to set the default HK packet destination. * This destination will usually only be set once. @@ -74,8 +83,6 @@ public: */ void setHkPacketDestination(MessageQueueId_t hkDestination); - virtual~ LocalDataPoolManager(); - /** * Generate a housekeeping packet with a given SID. * @param sid @@ -95,28 +102,64 @@ public: */ ReturnValue_t initializeHousekeepingPoolEntriesOnce(); - const OwnsLocalDataPoolIF* getOwner() const; + const HasLocalDataPoolIF* getOwner() const; ReturnValue_t printPoolEntry(lp_id_t localPoolId); + /** + * Different types of housekeeping reporting are possible. + * 1. PERIODIC: HK packets are generated in fixed intervals + * 2. UPDATED: HK packets are generated if a value was updated + * 3. REQUESTED: HK packets are only generated if explicitely requested + */ + enum class ReportingType: uint8_t { + PERIODIC, + ON_UPDATE, + REQUESTED + }; + /* 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 ! */ - bool mapInitialized = false; - /** This specifies whether a validity buffer is appended at the end - * of generated housekeeping packets. */ - bool appendValidityBuffer = true; + LocalDataPool localPoolMap; + /** 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). */ + HasLocalDataPoolIF* owner = nullptr; - LocalDataPool localDpMap; + /** + * The data pool manager will keep an internal map of HK receivers. + */ + struct HkReceiver { + LocalDataSet* dataSet = nullptr; + MessageQueueId_t destinationQueue = MessageQueueIF::NO_QUEUE; + ReportingType reportingType = ReportingType::PERIODIC; + bool reportingStatus = true; + /** Different members of this union will be used depending on reporting + * type */ + union hkParameter { + /** This parameter will be used for the PERIODIC type */ + dur_seconds_t collectionInterval = 0; + /** This parameter will be used for the ON_UPDATE type */ + bool hkDataChanged; + }; + }; + + /** Using a multimap as the same object might request multiple datasets */ + using HkReceiversMap = std::multimap; + + HkReceiversMap hkReceiversMap; + + /** 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. */ + bool appendValidityBuffer = true; - /** 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). */ - OwnsLocalDataPoolIF* owner = nullptr; /** * @brief Queue used for communication, for example commands. * Is also used to send messages. Can be set either in the constructor @@ -165,10 +208,10 @@ private: template inline ReturnValue_t LocalDataPoolManager::fetchPoolEntry(lp_id_t localPoolId, PoolEntry **poolEntry) { - auto poolIter = localDpMap.find(localPoolId); - if (poolIter == localDpMap.end()) { - sif::debug << "HousekeepingManager::fechPoolEntry:" - " Pool entry not found." << std::endl; + auto poolIter = localPoolMap.find(localPoolId); + if (poolIter == localPoolMap.end()) { + sif::warning << "HousekeepingManager::fechPoolEntry: Pool entry " + "not found." << std::endl; return POOL_ENTRY_NOT_FOUND; } @@ -182,4 +225,4 @@ ReturnValue_t LocalDataPoolManager::fetchPoolEntry(lp_id_t localPoolId, } -#endif /* FRAMEWORK_HK_HOUSEKEEPINGHELPER_H_ */ +#endif /* FRAMEWORK_DATAPOOLLOCAL_LOCALDATAPOOLMANAGER_H_ */ diff --git a/datapoollocal/LocalDataSet.cpp b/datapoollocal/LocalDataSet.cpp index 272a1b6f..2a42cd38 100644 --- a/datapoollocal/LocalDataSet.cpp +++ b/datapoollocal/LocalDataSet.cpp @@ -5,7 +5,7 @@ #include #include -LocalDataSet::LocalDataSet(OwnsLocalDataPoolIF *hkOwner, +LocalDataSet::LocalDataSet(HasLocalDataPoolIF *hkOwner, const size_t maxNumberOfVariables): DataSetBase(poolVarList.data(), maxNumberOfVariables) { poolVarList.reserve(maxNumberOfVariables); @@ -23,7 +23,7 @@ LocalDataSet::LocalDataSet(object_id_t ownerId, DataSetBase(poolVarList.data(), maxNumberOfVariables) { poolVarList.reserve(maxNumberOfVariables); poolVarList.resize(maxNumberOfVariables); - OwnsLocalDataPoolIF* hkOwner = objectManager->get( + HasLocalDataPoolIF* hkOwner = objectManager->get( ownerId); if(hkOwner == nullptr) { sif::error << "LocalDataSet::LocalDataSet: Owner can't be nullptr!" diff --git a/datapoollocal/LocalDataSet.h b/datapoollocal/LocalDataSet.h index 20c647ca..2c70de82 100644 --- a/datapoollocal/LocalDataSet.h +++ b/datapoollocal/LocalDataSet.h @@ -2,7 +2,7 @@ #define FRAMEWORK_DATAPOOLLOCAL_LOCALDATASET_H_ #include #include -#include +#include #include #include @@ -37,7 +37,7 @@ public: * The constructor simply sets the fill_count to zero and sets * the state to "uninitialized". */ - LocalDataSet(OwnsLocalDataPoolIF *hkOwner, + LocalDataSet(HasLocalDataPoolIF *hkOwner, const size_t maxNumberOfVariables); /** diff --git a/datapoollocal/LocalPoolVariable.h b/datapoollocal/LocalPoolVariable.h index 98782b8d..73d691d7 100644 --- a/datapoollocal/LocalPoolVariable.h +++ b/datapoollocal/LocalPoolVariable.h @@ -3,8 +3,8 @@ #include #include +#include #include -#include #include #include @@ -42,7 +42,7 @@ public: * @param dataSet The data set in which the variable shall register itself. * If nullptr, the variable is not registered. */ - LocalPoolVar(lp_id_t poolId, OwnsLocalDataPoolIF* hkOwner, + LocalPoolVar(lp_id_t poolId, HasLocalDataPoolIF* hkOwner, pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE, DataSetIF* dataSet = nullptr); diff --git a/datapoollocal/LocalPoolVariable.tpp b/datapoollocal/LocalPoolVariable.tpp index 7f9fbf13..0b96bb4f 100644 --- a/datapoollocal/LocalPoolVariable.tpp +++ b/datapoollocal/LocalPoolVariable.tpp @@ -7,7 +7,7 @@ template inline LocalPoolVar::LocalPoolVar(lp_id_t poolId, - OwnsLocalDataPoolIF* hkOwner, pool_rwm_t setReadWriteMode, + HasLocalDataPoolIF* hkOwner, pool_rwm_t setReadWriteMode, DataSetIF* dataSet): localPoolId(poolId),readWriteMode(setReadWriteMode) { if(poolId == PoolVariableIF::NO_PARAMETER) { @@ -33,8 +33,8 @@ inline LocalPoolVar::LocalPoolVar(lp_id_t poolId, object_id_t poolOwner, sif::warning << "LocalPoolVector: 0 passed as pool ID, which is the " "NO_PARAMETER value!" << std::endl; } - OwnsLocalDataPoolIF* hkOwner = - objectManager->get(poolOwner); + HasLocalDataPoolIF* hkOwner = + objectManager->get(poolOwner); if(hkOwner == nullptr) { sif::error << "LocalPoolVariable: The supplied pool owner did not implement" "the correct interface HasHkPoolParametersIF!" << std::endl; diff --git a/datapoollocal/LocalPoolVector.h b/datapoollocal/LocalPoolVector.h index f6532894..3083646f 100644 --- a/datapoollocal/LocalPoolVector.h +++ b/datapoollocal/LocalPoolVector.h @@ -46,7 +46,7 @@ public: * @param dataSet The data set in which the variable shall register itself. * If nullptr, the variable is not registered. */ - LocalPoolVector(lp_id_t poolId, OwnsLocalDataPoolIF* hkOwner, + LocalPoolVector(lp_id_t poolId, HasLocalDataPoolIF* hkOwner, pool_rwm_t setReadWriteMode = pool_rwm_t::VAR_READ_WRITE, DataSetIF* dataSet = nullptr); diff --git a/datapoollocal/LocalPoolVector.tpp b/datapoollocal/LocalPoolVector.tpp index 872c49ec..b7f2fe19 100644 --- a/datapoollocal/LocalPoolVector.tpp +++ b/datapoollocal/LocalPoolVector.tpp @@ -7,7 +7,7 @@ template inline LocalPoolVector::LocalPoolVector(lp_id_t poolId, - OwnsLocalDataPoolIF* hkOwner, pool_rwm_t setReadWriteMode, + HasLocalDataPoolIF* hkOwner, pool_rwm_t setReadWriteMode, DataSetIF* dataSet) : localPoolId(poolId), valid(false), readWriteMode(setReadWriteMode) { if(poolId == PoolVariableIF::NO_PARAMETER) { @@ -29,8 +29,8 @@ inline LocalPoolVector::LocalPoolVector(lp_id_t poolId, sif::warning << "LocalPoolVector: 0 passed as pool ID, which is the " "NO_PARAMETER value!" << std::endl; } - OwnsLocalDataPoolIF* hkOwner = - objectManager->get(poolOwner); + HasLocalDataPoolIF* hkOwner = + objectManager->get(poolOwner); if(hkOwner == nullptr) { sif::error << "LocalPoolVariable: The supplied pool owner did not implement" "the correct interface HasHkPoolParametersIF!" << std::endl; diff --git a/devicehandlers/DeviceHandlerBase.h b/devicehandlers/DeviceHandlerBase.h index 3fdab9ed..ce7f7b9f 100644 --- a/devicehandlers/DeviceHandlerBase.h +++ b/devicehandlers/DeviceHandlerBase.h @@ -17,10 +17,9 @@ #include #include #include +#include #include #include -#include - #include namespace Factory{ @@ -88,7 +87,7 @@ class DeviceHandlerBase: public DeviceHandlerIF, public HasHealthIF, public HasActionsIF, public ReceivesParameterMessagesIF, - public OwnsLocalDataPoolIF { + public HasLocalDataPoolIF { friend void (Factory::setStaticFrameworkObjectIds)(); public: /** From 6f50356964da86b311b9e96b08d33de6c2b76233 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 9 Jul 2020 14:26:15 +0200 Subject: [PATCH 255/307] new shared ring buffer --- container/RingBufferBase.h | 73 ++++++++++++++++------------ container/SharedRingBuffer.cpp | 32 ++++++++++++ container/SharedRingBuffer.h | 42 ++++++++++++++++ container/SimpleRingBuffer.cpp | 27 ++++++---- container/SimpleRingBuffer.h | 44 ++++++++++++----- devicehandlers/ChildHandlerBase.cpp | 16 +++--- devicehandlers/ChildHandlerBase.h | 4 +- devicehandlers/DeviceHandlerBase.cpp | 38 ++++++++++----- devicehandlers/DeviceHandlerBase.h | 19 ++++---- globalfunctions/DleEncoder.cpp | 3 +- timemanager/Clock.h | 4 +- 11 files changed, 216 insertions(+), 86 deletions(-) create mode 100644 container/SharedRingBuffer.cpp create mode 100644 container/SharedRingBuffer.h diff --git a/container/RingBufferBase.h b/container/RingBufferBase.h index 1beb51c2..86896b9e 100644 --- a/container/RingBufferBase.h +++ b/container/RingBufferBase.h @@ -7,29 +7,23 @@ template class RingBufferBase { public: - RingBufferBase(uint32_t startAddress, const size_t size, bool overwriteOld) : + RingBufferBase(size_t startAddress, const size_t size, bool overwriteOld) : start(startAddress), write(startAddress), size(size), overwriteOld(overwriteOld) { for (uint8_t count = 0; count < N_READ_PTRS; count++) { read[count] = startAddress; } } - ReturnValue_t readData(uint32_t amount, uint8_t n = 0) { - if (availableReadData(n) >= amount) { - incrementRead(amount, n); - return HasReturnvaluesIF::RETURN_OK; - } else { - return HasReturnvaluesIF::RETURN_FAILED; - } + + virtual ~RingBufferBase() {} + + bool isFull(uint8_t n = 0) { + return (availableWriteSpace(n) == 0); } - ReturnValue_t writeData(uint32_t amount) { - if (availableWriteSpace() >= amount || overwriteOld) { - incrementWrite(amount); - return HasReturnvaluesIF::RETURN_OK; - } else { - return HasReturnvaluesIF::RETURN_FAILED; - } + bool isEmpty(uint8_t n = 0) { + return (availableReadData(n) == 0); } + uint32_t availableReadData(uint8_t n = 0) const { return ((write + size) - read[n]) % size; } @@ -37,54 +31,55 @@ public: //One less to avoid ambiguous full/empty problem. return (((read[n] + size) - write - 1) % size); } - bool isFull(uint8_t n = 0) { - return (availableWriteSpace(n) == 0); - } - bool isEmpty(uint8_t n = 0) { - return (availableReadData(n) == 0); - } - virtual ~RingBufferBase() { - } uint32_t getRead(uint8_t n = 0) const { return read[n]; } + void setRead(uint32_t read, uint8_t n = 0) { if (read >= start && read < (start+size)) { this->read[n] = read; } } + uint32_t getWrite() const { return write; } + void setWrite(uint32_t write) { this->write = write; } + void clear() { write = start; for (uint8_t count = 0; count < N_READ_PTRS; count++) { read[count] = start; } } - uint32_t writeTillWrap() { + + size_t writeTillWrap() { return (start + size) - write; } - uint32_t readTillWrap(uint8_t n = 0) { + + size_t readTillWrap(uint8_t n = 0) { return (start + size) - read[n]; } - uint32_t getStart() const { + + size_t getStart() const { return start; } + bool overwritesOld() const { return overwriteOld; } - uint32_t maxSize() const { + + size_t maxSize() const { return size - 1; } protected: - const uint32_t start; - uint32_t write; - uint32_t read[N_READ_PTRS]; + const size_t start; + size_t write; + size_t read[N_READ_PTRS]; const size_t size; const bool overwriteOld; void incrementWrite(uint32_t amount) { @@ -93,6 +88,24 @@ protected: void incrementRead(uint32_t amount, uint8_t n = 0) { read[n] = ((read[n] + amount - start) % size) + start; } + + ReturnValue_t readData(uint32_t amount, uint8_t n = 0) { + if (availableReadData(n) >= amount) { + incrementRead(amount, n); + return HasReturnvaluesIF::RETURN_OK; + } else { + return HasReturnvaluesIF::RETURN_FAILED; + } + } + + ReturnValue_t writeData(uint32_t amount) { + if (availableWriteSpace() >= amount or overwriteOld) { + incrementWrite(amount); + return HasReturnvaluesIF::RETURN_OK; + } else { + return HasReturnvaluesIF::RETURN_FAILED; + } + } }; #endif /* FRAMEWORK_CONTAINER_RINGBUFFERBASE_H_ */ diff --git a/container/SharedRingBuffer.cpp b/container/SharedRingBuffer.cpp new file mode 100644 index 00000000..36315753 --- /dev/null +++ b/container/SharedRingBuffer.cpp @@ -0,0 +1,32 @@ +#include +#include +#include + +SharedRingBuffer::SharedRingBuffer(const size_t size, bool overwriteOld): + SimpleRingBuffer(size, overwriteOld) { + mutex = MutexFactory::instance()->createMutex(); +} + +SharedRingBuffer::SharedRingBuffer(uint8_t *buffer, const size_t size, + bool overwriteOld): SimpleRingBuffer(buffer, size, overwriteOld) { + mutex = MutexFactory::instance()->createMutex(); +} + +ReturnValue_t SharedRingBuffer::writeDataProtected(const uint8_t *data, + size_t amount, dur_millis_t timeout) { + MutexHelper(mutex, timeout); + return writeData(data,amount); +} + +ReturnValue_t SharedRingBuffer::readDataProtected(uint8_t *data, size_t amount, + dur_millis_t timeout, bool incrementReadPtr, bool readRemaining, + size_t *trueAmount) { + MutexHelper(mutex, timeout); + return readData(data,amount, incrementReadPtr, readRemaining, trueAmount); +} + +ReturnValue_t SharedRingBuffer::deleteDataProtected(size_t amount, + bool deleteRemaining, size_t *trueAmount, dur_millis_t timeout) { + MutexHelper(mutex, timeout); + return deleteData(amount, deleteRemaining, trueAmount); +} diff --git a/container/SharedRingBuffer.h b/container/SharedRingBuffer.h new file mode 100644 index 00000000..41186619 --- /dev/null +++ b/container/SharedRingBuffer.h @@ -0,0 +1,42 @@ +#ifndef FRAMEWORK_CONTAINER_SHAREDRINGBUFFER_H_ +#define FRAMEWORK_CONTAINER_SHAREDRINGBUFFER_H_ +#include +#include +#include + +class SharedRingBuffer: public SimpleRingBuffer { +public: + /** + * This constructor allocates a new internal buffer with the supplied size. + * @param size + * @param overwriteOld + * If the ring buffer is overflowing at a write operartion, the oldest data + * will be overwritten. + */ + SharedRingBuffer(const size_t size, bool overwriteOld); + + /** + * This constructor takes an external buffer with the specified size. + * @param buffer + * @param size + * @param overwriteOld + * If the ring buffer is overflowing at a write operartion, the oldest data + * will be overwritten. + */ + SharedRingBuffer(uint8_t* buffer, const size_t size, bool overwriteOld); + + ReturnValue_t writeDataProtected(const uint8_t* data, size_t amount, + dur_millis_t timeout = 10); + ReturnValue_t readDataProtected(uint8_t *data, size_t amount, + dur_millis_t timeout = 10, bool incrementReadPtr = false, + bool readRemaining = false, size_t *trueAmount = nullptr); + ReturnValue_t deleteDataProtected(size_t amount, + bool deleteRemaining = false, size_t* trueAmount = nullptr, + dur_millis_t timeout = 10); +private: + MutexIF* mutex = nullptr; +}; + + + +#endif /* FRAMEWORK_CONTAINER_SHAREDRINGBUFFER_H_ */ diff --git a/container/SimpleRingBuffer.cpp b/container/SimpleRingBuffer.cpp index 731c9dc9..69d94143 100644 --- a/container/SimpleRingBuffer.cpp +++ b/container/SimpleRingBuffer.cpp @@ -16,12 +16,14 @@ SimpleRingBuffer::~SimpleRingBuffer() { } ReturnValue_t SimpleRingBuffer::writeData(const uint8_t* data, - uint32_t amount) { + size_t amount) { if (availableWriteSpace() >= amount or overwriteOld) { - uint32_t amountTillWrap = writeTillWrap(); + size_t amountTillWrap = writeTillWrap(); if (amountTillWrap >= amount) { + // remaining size in buffer is sufficient to fit full amount. memcpy(&buffer[write], data, amount); - } else { + } + else { memcpy(&buffer[write], data, amountTillWrap); memcpy(buffer, data + amountTillWrap, amount - amountTillWrap); } @@ -32,12 +34,13 @@ ReturnValue_t SimpleRingBuffer::writeData(const uint8_t* data, } } -ReturnValue_t SimpleRingBuffer::readData(uint8_t* data, uint32_t amount, - bool readRemaining, uint32_t* trueAmount) { - uint32_t availableData = availableReadData(READ_PTR); - uint32_t amountTillWrap = readTillWrap(READ_PTR); +ReturnValue_t SimpleRingBuffer::readData(uint8_t* data, size_t amount, + bool incrementReadPtr, bool readRemaining, size_t* trueAmount) { + size_t availableData = availableReadData(READ_PTR); + size_t amountTillWrap = readTillWrap(READ_PTR); if (availableData < amount) { if (readRemaining) { + // more data available than amount specified. amount = availableData; } else { return HasReturnvaluesIF::RETURN_FAILED; @@ -52,12 +55,16 @@ ReturnValue_t SimpleRingBuffer::readData(uint8_t* data, uint32_t amount, memcpy(data, &buffer[read[READ_PTR]], amountTillWrap); memcpy(data + amountTillWrap, buffer, amount - amountTillWrap); } + + if(incrementReadPtr) { + deleteData(amount, readRemaining); + } return HasReturnvaluesIF::RETURN_OK; } -ReturnValue_t SimpleRingBuffer::deleteData(uint32_t amount, - bool deleteRemaining, uint32_t* trueAmount) { - uint32_t availableData = availableReadData(READ_PTR); +ReturnValue_t SimpleRingBuffer::deleteData(size_t amount, + bool deleteRemaining, size_t* trueAmount) { + size_t availableData = availableReadData(READ_PTR); if (availableData < amount) { if (deleteRemaining) { amount = availableData; diff --git a/container/SimpleRingBuffer.h b/container/SimpleRingBuffer.h index 30dd184c..cf78814f 100644 --- a/container/SimpleRingBuffer.h +++ b/container/SimpleRingBuffer.h @@ -18,6 +18,8 @@ public: * This constructor allocates a new internal buffer with the supplied size. * @param size * @param overwriteOld + * If the ring buffer is overflowing at a write operartion, the oldest data + * will be overwritten. */ SimpleRingBuffer(const size_t size, bool overwriteOld); /** @@ -25,41 +27,59 @@ public: * @param buffer * @param size * @param overwriteOld + * If the ring buffer is overflowing at a write operartion, the oldest data + * will be overwritten. */ SimpleRingBuffer(uint8_t* buffer, const size_t size, bool overwriteOld); virtual ~SimpleRingBuffer(); /** - * Write to circular buffer and increment write pointer by amount + * Write to circular buffer and increment write pointer by amount. * @param data * @param amount - * @return + * @return -@c RETURN_OK if write operation was successfull + * -@c RETURN_FAILED if */ - ReturnValue_t writeData(const uint8_t* data, uint32_t amount); + ReturnValue_t writeData(const uint8_t* data, size_t amount); /** - * Read from circular buffer at read pointer + * Read from circular buffer at read pointer. * @param data * @param amount + * @param incrementReadPtr + * If this is set to true, the read pointer will be incremented. + * If readRemaining is set to true, the read pointer will be incremented + * accordingly. * @param readRemaining - * @param trueAmount + * If this is set to true, the data will be read even if the amount + * specified exceeds the read data available. + * @param trueAmount [out] + * If readRemaining was set to true, the true amount read will be assigned + * to the passed value. * @return + * - @c RETURN_OK if data was read successfully + * - @c RETURN_FAILED if not enough data was available and readRemaining + * was set to false. */ - ReturnValue_t readData(uint8_t* data, uint32_t amount, - bool readRemaining = false, uint32_t* trueAmount = nullptr); + ReturnValue_t readData(uint8_t* data, size_t amount, + bool incrementReadPtr = false, bool readRemaining = false, + size_t* trueAmount = nullptr); /** - * Delete data starting by incrementing read pointer + * Delete data by incrementing read pointer. * @param amount * @param deleteRemaining - * @param trueAmount + * If the amount specified is larger than the remaing size to read and this + * is set to true, the remaining amount will be deleted as well + * @param trueAmount [out] + * If deleteRemaining was set to true, the amount deleted will be assigned + * to the passed value. * @return */ - ReturnValue_t deleteData(uint32_t amount, bool deleteRemaining = false, - uint32_t* trueAmount = nullptr); + ReturnValue_t deleteData(size_t amount, bool deleteRemaining = false, + size_t* trueAmount = nullptr); private: -// static const uint8_t TEMP_READ_PTR = 1; static const uint8_t READ_PTR = 0; uint8_t* buffer = nullptr; }; diff --git a/devicehandlers/ChildHandlerBase.cpp b/devicehandlers/ChildHandlerBase.cpp index 3e5bcc60..9e5019b4 100644 --- a/devicehandlers/ChildHandlerBase.cpp +++ b/devicehandlers/ChildHandlerBase.cpp @@ -4,15 +4,19 @@ ChildHandlerBase::ChildHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication, CookieIF * cookie, - uint32_t maxDeviceReplyLen, uint8_t setDeviceSwitch, - object_id_t hkDestination, uint32_t thermalStatePoolId, - uint32_t thermalRequestPoolId, uint32_t parent, + uint8_t setDeviceSwitch, object_id_t hkDestination, + uint32_t thermalStatePoolId, uint32_t thermalRequestPoolId, + object_id_t parent, FailureIsolationBase* customFdir, size_t cmdQueueSize) : DeviceHandlerBase(setObjectId, deviceCommunication, cookie, - hkDestination, setDeviceSwitch, thermalStatePoolId, - thermalRequestPoolId, (customFdir == NULL? &childHandlerFdir : customFdir), + (customFdir == nullptr? &childHandlerFdir : customFdir), cmdQueueSize), parentId(parent), childHandlerFdir(setObjectId) { + this->setDeviceSwitch(setDeviceSwitch); + this->setHkDestination(hkDestination); + this->setThermalStateRequestPoolIds(thermalStatePoolId, + thermalRequestPoolId); + } ChildHandlerBase::~ChildHandlerBase() { @@ -26,7 +30,7 @@ ReturnValue_t ChildHandlerBase::initialize() { MessageQueueId_t parentQueue = 0; - if (parentId != 0) { + if (parentId != objects::NO_OBJECT) { SubsystemBase *parent = objectManager->get(parentId); if (parent == NULL) { return RETURN_FAILED; diff --git a/devicehandlers/ChildHandlerBase.h b/devicehandlers/ChildHandlerBase.h index 10021631..5c216e86 100644 --- a/devicehandlers/ChildHandlerBase.h +++ b/devicehandlers/ChildHandlerBase.h @@ -7,9 +7,9 @@ class ChildHandlerBase: public DeviceHandlerBase { public: ChildHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication, - CookieIF * cookie, uint32_t maxDeviceReplyLen, uint8_t setDeviceSwitch, + CookieIF * cookie, uint8_t setDeviceSwitch, object_id_t hkDestination, uint32_t thermalStatePoolId, - uint32_t thermalRequestPoolId, uint32_t parent, + uint32_t thermalRequestPoolId, object_id_t parent = objects::NO_OBJECT, FailureIsolationBase* customFdir = nullptr, size_t cmdQueueSize = 20); virtual ~ChildHandlerBase(); diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index fcb61ace..08d92130 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -18,43 +18,55 @@ object_id_t DeviceHandlerBase::powerSwitcherId = objects::NO_OBJECT; object_id_t DeviceHandlerBase::rawDataReceiverId = objects::NO_OBJECT; -object_id_t DeviceHandlerBase::defaultFDIRParentId = 0; +object_id_t DeviceHandlerBase::defaultFdirParentId = objects::NO_OBJECT; DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication, CookieIF * comCookie, - uint8_t setDeviceSwitch, object_id_t hkDestination, - uint32_t thermalStatePoolId, uint32_t thermalRequestPoolId, - FailureIsolationBase* fdirInstance, size_t cmdQueueSize) : + 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, nullptr), - deviceThermalStatePoolId(thermalStatePoolId), - deviceThermalRequestPoolId(thermalRequestPoolId), childTransitionFailure(RETURN_OK), fdirInstance(fdirInstance), hkSwitcher(this), defaultFDIRUsed(fdirInstance == nullptr), switchOffWasReported(false), hkDestination(hkDestination), childTransitionDelay(5000), transitionSourceMode(_MODE_POWER_DOWN), - transitionSourceSubMode(SUBMODE_NONE), deviceSwitch(setDeviceSwitch) { + transitionSourceSubMode(SUBMODE_NONE) { commandQueue = QueueFactory::instance()->createMessageQueue(cmdQueueSize, MessageQueueMessage::MAX_MESSAGE_SIZE); insertInCommandMap(RAW_COMMAND_ID); cookieInfo.state = COOKIE_UNUSED; cookieInfo.pendingCommand = deviceCommandMap.end(); if (comCookie == nullptr) { - sif::error << "DeviceHandlerBase: ObjectID 0x" << std::hex << - std::setw(8) << std::setfill('0') << this->getObjectId() << - std::dec << ": Do not pass nullptr as a cookie, consider " - << std::setfill(' ') << "passing a dummy cookie instead!" << - std::endl; + sif::error << "DeviceHandlerBase: ObjectID 0x" << std::hex + << std::setw(8) << std::setfill('0') << this->getObjectId() + << std::dec << ": Do not pass nullptr as a cookie, consider " + << std::setfill(' ') << "passing a dummy cookie instead!" + << std::endl; } if (this->fdirInstance == nullptr) { this->fdirInstance = new DeviceHandlerFailureIsolation(setObjectId, - defaultFDIRParentId); + defaultFdirParentId); } } +void DeviceHandlerBase::setHkDestination(object_id_t hkDestination) { + this->hkDestination = hkDestination; +} + +void DeviceHandlerBase::setThermalStateRequestPoolIds( + uint32_t thermalStatePoolId, uint32_t thermalRequestPoolId) { + this->deviceThermalRequestPoolId = thermalStatePoolId; + this->deviceThermalRequestPoolId = thermalRequestPoolId; +} + + +void DeviceHandlerBase::setDeviceSwitch(uint8_t deviceSwitch) { + this->deviceSwitch = deviceSwitch; +} + DeviceHandlerBase::~DeviceHandlerBase() { delete comCookie; if (defaultFDIRUsed) { diff --git a/devicehandlers/DeviceHandlerBase.h b/devicehandlers/DeviceHandlerBase.h index 3fdab9ed..2adaa80e 100644 --- a/devicehandlers/DeviceHandlerBase.h +++ b/devicehandlers/DeviceHandlerBase.h @@ -106,13 +106,14 @@ public: * @param cmdQueueSize */ 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, + CookieIF * comCookie, FailureIsolationBase* fdirInstance = nullptr, size_t cmdQueueSize = 20); + void setDeviceSwitch(uint8_t deviceSwitch); + void setHkDestination(object_id_t hkDestination); + void setThermalStateRequestPoolIds(uint32_t thermalStatePoolId, + uint32_t thermalRequestPoolId); + /** * @brief This function is the device handler base core component and is * called periodically. @@ -691,14 +692,14 @@ protected: * * can be set to PoolVariableIF::NO_PARAMETER to deactivate thermal checking */ - uint32_t deviceThermalStatePoolId; + uint32_t deviceThermalStatePoolId = PoolVariableIF::NO_PARAMETER; /** * this is the datapool variable with the thermal request of the device * * can be set to PoolVariableIF::NO_PARAMETER to deactivate thermal checking */ - uint32_t deviceThermalRequestPoolId; + uint32_t deviceThermalRequestPoolId = PoolVariableIF::NO_PARAMETER; /** * Optional Error code @@ -724,7 +725,7 @@ protected: static object_id_t rawDataReceiverId; //!< Object which receives RAW data by default. - static object_id_t defaultFDIRParentId; //!< Object which may be the root cause of an identified fault. + static object_id_t defaultFdirParentId; //!< Object which may be the root cause of an identified fault. /** * Helper function to report a missed reply * @@ -1082,7 +1083,7 @@ private: * * for devices using two switches override getSwitches() */ - const uint8_t deviceSwitch; + uint8_t deviceSwitch; /** * read the command queue diff --git a/globalfunctions/DleEncoder.cpp b/globalfunctions/DleEncoder.cpp index c8f78872..f4bd765d 100644 --- a/globalfunctions/DleEncoder.cpp +++ b/globalfunctions/DleEncoder.cpp @@ -81,8 +81,7 @@ ReturnValue_t DleEncoder::decode(const uint8_t *sourceStream, while ((encodedIndex < sourceStreamLen) && (decodedIndex < maxDestStreamlen) && (sourceStream[encodedIndex] != ETX) - && (sourceStream[encodedIndex] != STX)) - { + && (sourceStream[encodedIndex] != STX)) { if (sourceStream[encodedIndex] == DLE) { nextByte = sourceStream[encodedIndex + 1]; // The next byte is a DLE character that was escaped by another diff --git a/timemanager/Clock.h b/timemanager/Clock.h index 121c63df..65e152bf 100644 --- a/timemanager/Clock.h +++ b/timemanager/Clock.h @@ -9,8 +9,8 @@ #include //! Don't use these for time points, type is not large enough for UNIX epoch. -typedef uint32_t dur_millis_t; -typedef double dur_seconds_t; +using dur_millis_t = uint32_t; +using dur_seconds_t = double; class Clock { public: From ecd740a1015f47d60ec73b48d54f632dc6aa38bd Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 9 Jul 2020 15:47:50 +0200 Subject: [PATCH 256/307] ring buffer base calls made protected --- container/RingBufferBase.h | 48 ++++++++++++++++++---------------- container/SharedRingBuffer.cpp | 36 ++++++++++++++++--------- container/SharedRingBuffer.h | 28 ++++++++++++++------ 3 files changed, 68 insertions(+), 44 deletions(-) diff --git a/container/RingBufferBase.h b/container/RingBufferBase.h index 86896b9e..f42a4288 100644 --- a/container/RingBufferBase.h +++ b/container/RingBufferBase.h @@ -24,30 +24,20 @@ public: return (availableReadData(n) == 0); } - uint32_t availableReadData(uint8_t n = 0) const { + size_t availableReadData(uint8_t n = 0) const { return ((write + size) - read[n]) % size; } - uint32_t availableWriteSpace(uint8_t n = 0) const { + size_t availableWriteSpace(uint8_t n = 0) const { //One less to avoid ambiguous full/empty problem. return (((read[n] + size) - write - 1) % size); } - uint32_t getRead(uint8_t n = 0) const { - return read[n]; + bool overwritesOld() const { + return overwriteOld; } - void setRead(uint32_t read, uint8_t n = 0) { - if (read >= start && read < (start+size)) { - this->read[n] = read; - } - } - - uint32_t getWrite() const { - return write; - } - - void setWrite(uint32_t write) { - this->write = write; + size_t maxSize() const { + return size - 1; } void clear() { @@ -69,13 +59,6 @@ public: return start; } - bool overwritesOld() const { - return overwriteOld; - } - - size_t maxSize() const { - return size - 1; - } protected: const size_t start; size_t write; @@ -106,6 +89,25 @@ protected: return HasReturnvaluesIF::RETURN_FAILED; } } + + + size_t getRead(uint8_t n = 0) const { + return read[n]; + } + + void setRead(uint32_t read, uint8_t n = 0) { + if (read >= start && read < (start+size)) { + this->read[n] = read; + } + } + + uint32_t getWrite() const { + return write; + } + + void setWrite(uint32_t write) { + this->write = write; + } }; #endif /* FRAMEWORK_CONTAINER_RINGBUFFERBASE_H_ */ diff --git a/container/SharedRingBuffer.cpp b/container/SharedRingBuffer.cpp index 36315753..64cbc669 100644 --- a/container/SharedRingBuffer.cpp +++ b/container/SharedRingBuffer.cpp @@ -2,31 +2,41 @@ #include #include -SharedRingBuffer::SharedRingBuffer(const size_t size, bool overwriteOld): - SimpleRingBuffer(size, overwriteOld) { +SharedRingBuffer::SharedRingBuffer(object_id_t objectId, const size_t size, + bool overwriteOld, dur_millis_t mutexTimeout): + SystemObject(objectId), SimpleRingBuffer(size, overwriteOld), + mutexTimeout(mutexTimeout) { mutex = MutexFactory::instance()->createMutex(); } -SharedRingBuffer::SharedRingBuffer(uint8_t *buffer, const size_t size, - bool overwriteOld): SimpleRingBuffer(buffer, size, overwriteOld) { +SharedRingBuffer::SharedRingBuffer(object_id_t objectId, uint8_t *buffer, + const size_t size, bool overwriteOld, dur_millis_t mutexTimeout): + SystemObject(objectId), SimpleRingBuffer(buffer, size, overwriteOld), + mutexTimeout(mutexTimeout) { mutex = MutexFactory::instance()->createMutex(); } ReturnValue_t SharedRingBuffer::writeDataProtected(const uint8_t *data, - size_t amount, dur_millis_t timeout) { - MutexHelper(mutex, timeout); - return writeData(data,amount); + size_t amount) { + MutexHelper(mutex, mutexTimeout); + return SimpleRingBuffer::writeData(data,amount); } ReturnValue_t SharedRingBuffer::readDataProtected(uint8_t *data, size_t amount, - dur_millis_t timeout, bool incrementReadPtr, bool readRemaining, + bool incrementReadPtr, bool readRemaining, size_t *trueAmount) { - MutexHelper(mutex, timeout); - return readData(data,amount, incrementReadPtr, readRemaining, trueAmount); + MutexHelper(mutex, mutexTimeout); + return SimpleRingBuffer::readData(data,amount, incrementReadPtr, + readRemaining, trueAmount); } ReturnValue_t SharedRingBuffer::deleteDataProtected(size_t amount, - bool deleteRemaining, size_t *trueAmount, dur_millis_t timeout) { - MutexHelper(mutex, timeout); - return deleteData(amount, deleteRemaining, trueAmount); + bool deleteRemaining, size_t *trueAmount) { + MutexHelper(mutex, mutexTimeout); + return SimpleRingBuffer::deleteData(amount, deleteRemaining, trueAmount); +} + +size_t SharedRingBuffer::getAvailableReadDataProtected(uint8_t n) const { + MutexHelper(mutex, mutexTimeout); + return ((write + size) - read[n]) % size; } diff --git a/container/SharedRingBuffer.h b/container/SharedRingBuffer.h index 41186619..e045b72a 100644 --- a/container/SharedRingBuffer.h +++ b/container/SharedRingBuffer.h @@ -2,9 +2,11 @@ #define FRAMEWORK_CONTAINER_SHAREDRINGBUFFER_H_ #include #include +#include #include -class SharedRingBuffer: public SimpleRingBuffer { +class SharedRingBuffer: public SystemObject, + public SimpleRingBuffer { public: /** * This constructor allocates a new internal buffer with the supplied size. @@ -13,7 +15,8 @@ public: * If the ring buffer is overflowing at a write operartion, the oldest data * will be overwritten. */ - SharedRingBuffer(const size_t size, bool overwriteOld); + SharedRingBuffer(object_id_t objectId, const size_t size, + bool overwriteOld, dur_millis_t mutexTimeout = 10); /** * This constructor takes an external buffer with the specified size. @@ -23,17 +26,26 @@ public: * If the ring buffer is overflowing at a write operartion, the oldest data * will be overwritten. */ - SharedRingBuffer(uint8_t* buffer, const size_t size, bool overwriteOld); + SharedRingBuffer(object_id_t objectId, uint8_t* buffer, const size_t size, + bool overwriteOld, dur_millis_t mutexTimeout = 10); - ReturnValue_t writeDataProtected(const uint8_t* data, size_t amount, - dur_millis_t timeout = 10); + void setMutexTimeout(dur_millis_t newTimeout); + + /** Performs mutex protected SimpleRingBuffer::writeData call */ + ReturnValue_t writeDataProtected(const uint8_t* data, size_t amount); + + /** Performs mutex protected SimpleRingBuffer::readData call */ ReturnValue_t readDataProtected(uint8_t *data, size_t amount, - dur_millis_t timeout = 10, bool incrementReadPtr = false, + bool incrementReadPtr = false, bool readRemaining = false, size_t *trueAmount = nullptr); + + /** Performs mutex protected SimpleRingBuffer::deleteData call */ ReturnValue_t deleteDataProtected(size_t amount, - bool deleteRemaining = false, size_t* trueAmount = nullptr, - dur_millis_t timeout = 10); + bool deleteRemaining = false, size_t* trueAmount = nullptr); + + size_t getAvailableReadDataProtected (uint8_t n = 0) const; private: + dur_millis_t mutexTimeout; MutexIF* mutex = nullptr; }; From 32ef807341f2b868af94a11507db532990a4c771 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 9 Jul 2020 15:49:52 +0200 Subject: [PATCH 257/307] newline --- container/SharedRingBuffer.h | 1 + 1 file changed, 1 insertion(+) diff --git a/container/SharedRingBuffer.h b/container/SharedRingBuffer.h index e045b72a..f7d3bc3c 100644 --- a/container/SharedRingBuffer.h +++ b/container/SharedRingBuffer.h @@ -1,5 +1,6 @@ #ifndef FRAMEWORK_CONTAINER_SHAREDRINGBUFFER_H_ #define FRAMEWORK_CONTAINER_SHAREDRINGBUFFER_H_ + #include #include #include From 5a351474d2de7e2b38c2ccf232f1a9ba6241bf10 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 9 Jul 2020 16:31:33 +0200 Subject: [PATCH 258/307] DHB ctor simplified --- datapoollocal/LocalDataPoolManager.h | 1 + devicehandlers/DeviceHandlerBase.cpp | 12 ++++++++---- devicehandlers/DeviceHandlerBase.h | 1 + fdir/FailureIsolationBase.cpp | 11 ++++++++--- fdir/FailureIsolationBase.h | 7 +++++-- tcdistribution/PUSDistributor.cpp | 2 +- 6 files changed, 24 insertions(+), 10 deletions(-) diff --git a/datapoollocal/LocalDataPoolManager.h b/datapoollocal/LocalDataPoolManager.h index 3841b99c..d5cfb1a3 100644 --- a/datapoollocal/LocalDataPoolManager.h +++ b/datapoollocal/LocalDataPoolManager.h @@ -67,6 +67,7 @@ public: */ 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. diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index 08d92130..48d366b6 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -19,11 +19,11 @@ object_id_t DeviceHandlerBase::powerSwitcherId = objects::NO_OBJECT; object_id_t DeviceHandlerBase::rawDataReceiverId = objects::NO_OBJECT; object_id_t DeviceHandlerBase::defaultFdirParentId = objects::NO_OBJECT; +object_id_t DeviceHandlerBase::defaultHkDestination = objects::NO_OBJECT; DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication, CookieIF * comCookie, - FailureIsolationBase* fdirInstance, - size_t cmdQueueSize) : + FailureIsolationBase* fdirInstance, size_t cmdQueueSize) : SystemObject(setObjectId), mode(MODE_OFF), submode(SUBMODE_NONE), wiretappingMode(OFF), storedRawData(StorageManagerIF::INVALID_ADDRESS), deviceCommunicationId(deviceCommunication), comCookie(comCookie), @@ -31,8 +31,8 @@ DeviceHandlerBase::DeviceHandlerBase(object_id_t setObjectId, actionHelper(this, nullptr), hkManager(this, nullptr), childTransitionFailure(RETURN_OK), fdirInstance(fdirInstance), hkSwitcher(this), defaultFDIRUsed(fdirInstance == nullptr), - switchOffWasReported(false), hkDestination(hkDestination), - childTransitionDelay(5000), transitionSourceMode(_MODE_POWER_DOWN), + switchOffWasReported(false), childTransitionDelay(5000), + transitionSourceMode(_MODE_POWER_DOWN), transitionSourceSubMode(SUBMODE_NONE) { commandQueue = QueueFactory::instance()->createMessageQueue(cmdQueueSize, MessageQueueMessage::MAX_MESSAGE_SIZE); @@ -189,6 +189,10 @@ ReturnValue_t DeviceHandlerBase::initialize() { return result; } + if(hkDestination == objects::NO_OBJECT) { + hkDestination = defaultHkDestination; + } + result = hkManager.initialize(commandQueue, hkDestination); if (result != HasReturnvaluesIF::RETURN_OK) { return result; diff --git a/devicehandlers/DeviceHandlerBase.h b/devicehandlers/DeviceHandlerBase.h index 2adaa80e..52349656 100644 --- a/devicehandlers/DeviceHandlerBase.h +++ b/devicehandlers/DeviceHandlerBase.h @@ -1048,6 +1048,7 @@ private: PowerSwitchIF *powerSwitcher = nullptr; /** Cached for initialize() */ + static object_id_t defaultHkDestination; object_id_t hkDestination = objects::NO_OBJECT; /** diff --git a/fdir/FailureIsolationBase.cpp b/fdir/FailureIsolationBase.cpp index a2fc9ea1..8bc88002 100644 --- a/fdir/FailureIsolationBase.cpp +++ b/fdir/FailureIsolationBase.cpp @@ -29,7 +29,7 @@ ReturnValue_t FailureIsolationBase::initialize() { if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - if (ownerId != 0) { + if (faultTreeParent != objects::NO_OBJECT) { result = manager->subscribeToAllEventsFrom(eventQueue->getId(), ownerId); if (result != HasReturnvaluesIF::RETURN_OK) { return result; @@ -41,10 +41,15 @@ ReturnValue_t FailureIsolationBase::initialize() { return ObjectManagerIF::CHILD_INIT_FAILED; } } - if (faultTreeParent != 0) { + if (faultTreeParent != objects::NO_OBJECT) { ConfirmsFailuresIF* parentIF = objectManager->get( faultTreeParent); - if (parentIF == NULL) { + if (parentIF == nullptr) { + sif::error << "FailureIsolationBase::intialize: Parent object" + << "invalid." << std::endl; + sif::error << "Make sure it implements ConfirmsFailuresIF." + << std::endl; + return ObjectManagerIF::CHILD_INIT_FAILED; return RETURN_FAILED; } eventQueue->setDefaultDestination(parentIF->getEventReceptionQueue()); diff --git a/fdir/FailureIsolationBase.h b/fdir/FailureIsolationBase.h index 894f6356..dea149bd 100644 --- a/fdir/FailureIsolationBase.h +++ b/fdir/FailureIsolationBase.h @@ -17,8 +17,11 @@ public: static const Event FDIR_CHANGED_STATE = MAKE_EVENT(1, SEVERITY::INFO); //!< FDIR has an internal state, which changed from par2 (oldState) to par1 (newState). static const Event FDIR_STARTS_RECOVERY = MAKE_EVENT(2, SEVERITY::MEDIUM); //!< FDIR tries to restart device. Par1: event that caused recovery. static const Event FDIR_TURNS_OFF_DEVICE = MAKE_EVENT(3, SEVERITY::MEDIUM); //!< FDIR turns off device. Par1: event that caused recovery. - FailureIsolationBase(object_id_t owner, object_id_t parent = 0, + + FailureIsolationBase(object_id_t owner, + object_id_t parent = objects::NO_OBJECT, uint8_t messageDepth = 10, uint8_t parameterDomainBase = 0xF0); + virtual ~FailureIsolationBase(); virtual ReturnValue_t initialize(); @@ -26,7 +29,7 @@ public: * This is called by the DHB in performOperation() */ void checkForFailures(); - MessageQueueId_t getEventReceptionQueue(); + MessageQueueId_t getEventReceptionQueue() override; virtual void triggerEvent(Event event, uint32_t parameter1 = 0, uint32_t parameter2 = 0); protected: diff --git a/tcdistribution/PUSDistributor.cpp b/tcdistribution/PUSDistributor.cpp index 969380d6..5eb50103 100644 --- a/tcdistribution/PUSDistributor.cpp +++ b/tcdistribution/PUSDistributor.cpp @@ -50,7 +50,7 @@ ReturnValue_t PUSDistributor::registerService(AcceptsTelecommandsIF* service) { if (not returnPair.second) { //TODO Return Code sif::error << "PUSDistributor::registerService: Service ID already" - "exists in map." << std::endl; + " exists in map." << std::endl; return HasReturnvaluesIF::RETURN_FAILED; } return HasReturnvaluesIF::RETURN_OK; From a5d3d9ea8030d5f14a7c584641b68a5bf4f21d58 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 9 Jul 2020 16:46:57 +0200 Subject: [PATCH 259/307] improved init function --- devicehandlers/DeviceHandlerBase.cpp | 38 ++++++++++++++++++---------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index 48d366b6..b47c58fc 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -122,8 +122,12 @@ ReturnValue_t DeviceHandlerBase::initialize() { communicationInterface = objectManager->get( deviceCommunicationId); - if (communicationInterface == NULL) { - return RETURN_FAILED; + if (communicationInterface == nullptr) { + sif::error << "DeviceHandlerBase::initialize: Communication interface " + "invalid." << std::endl; + sif::error << "Make sure it is set up properly and implements" + " DeviceCommunicationIF" << std::endl; + return ObjectManagerIF::CHILD_INIT_FAILED; } result = communicationInterface->initializeInterface(comCookie); @@ -132,8 +136,10 @@ ReturnValue_t DeviceHandlerBase::initialize() { } IPCStore = objectManager->get(objects::IPC_STORE); - if (IPCStore == NULL) { - return RETURN_FAILED; + if (IPCStore == nullptr) { + sif::error << "DeviceHandlerBase::initialize: IPC store not set up in " + "factory." << std::endl; + return ObjectManagerIF::CHILD_INIT_FAILED; } if(rawDataReceiverId != objects::NO_OBJECT) { @@ -152,8 +158,12 @@ ReturnValue_t DeviceHandlerBase::initialize() { if(powerSwitcherId != objects::NO_OBJECT) { powerSwitcher = objectManager->get(powerSwitcherId); - if (powerSwitcher == NULL) { - return RETURN_FAILED; + if (powerSwitcher == nullptr) { + sif::error << "DeviceHandlerBase::initialize: Power switcher " + << "object ID set but no valid object found." << std::endl; + sif::error << "Make sure the raw receiver object is set up properly" + << " and implements PowerSwitchIF" << std::endl; + return ObjectManagerIF::CHILD_INIT_FAILED; } } @@ -189,14 +199,14 @@ ReturnValue_t DeviceHandlerBase::initialize() { return result; } - if(hkDestination == objects::NO_OBJECT) { - hkDestination = defaultHkDestination; - } - - result = hkManager.initialize(commandQueue, hkDestination); - if (result != HasReturnvaluesIF::RETURN_OK) { - return result; - } +// if(hkDestination == objects::NO_OBJECT) { +// hkDestination = defaultHkDestination; +// } +// +// result = hkManager.initialize(commandQueue, hkDestination); +// if (result != HasReturnvaluesIF::RETURN_OK) { +// return result; +// } fillCommandAndReplyMap(); From da30680d04bffca3ebd17a446fc7cad765a6770f Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 9 Jul 2020 16:54:18 +0200 Subject: [PATCH 260/307] readability improvement --- devicehandlers/DeviceHandlerBase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index b47c58fc..4358503e 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -228,7 +228,7 @@ void DeviceHandlerBase::decrementDeviceReplyMap() { if (iter->second.delayCycles != 0) { iter->second.delayCycles--; if (iter->second.delayCycles == 0) { - if (iter->second.periodic != 0) { + if (iter->second.periodic) { iter->second.delayCycles = iter->second.maxDelayCycles; } replyToReply(iter, TIMEOUT); From ceb61979048feb501a31530ac363aaf53c6b5e43 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 9 Jul 2020 17:01:12 +0200 Subject: [PATCH 261/307] some minor improvements --- devicehandlers/DeviceHandlerBase.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/devicehandlers/DeviceHandlerBase.h b/devicehandlers/DeviceHandlerBase.h index b60acd52..3c5edf55 100644 --- a/devicehandlers/DeviceHandlerBase.h +++ b/devicehandlers/DeviceHandlerBase.h @@ -386,7 +386,7 @@ protected: * - @c RETURN_FAILED else. */ ReturnValue_t insertInCommandAndReplyMap(DeviceCommandId_t deviceCommand, - uint16_t maxDelayCycles, size_t replyLen = 0, bool periodic = 0, + uint16_t maxDelayCycles, size_t replyLen = 0, bool periodic = false, bool hasDifferentReplyId = false, DeviceCommandId_t replyId = 0); /** @@ -400,7 +400,7 @@ protected: * - @c RETURN_FAILED else. */ ReturnValue_t insertInReplyMap(DeviceCommandId_t deviceCommand, - uint16_t maxDelayCycles, size_t replyLen = 0, bool periodic = 0); + uint16_t maxDelayCycles, size_t replyLen = 0, bool periodic = false); /** * @brief A simple command to add a command to the commandList. @@ -426,7 +426,7 @@ protected: */ ReturnValue_t updateReplyMapEntry(DeviceCommandId_t deviceReply, uint16_t delayCycles, uint16_t maxDelayCycles, - bool periodic = 0); + bool periodic = false); /** * @brief Can be implemented by child handler to @@ -1214,5 +1214,5 @@ private: size_t receivedDataLen); }; -#endif /* DEVICEHANDLERBASE_H_ */ +#endif /* FRAMEWORK_DEVICEHANDLERS_DEVICEHANDLERBASE_H_ */ From ad049cc634b1c0aa9b0505bc4de42cb6a89a6679 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 9 Jul 2020 19:41:52 +0200 Subject: [PATCH 262/307] tmtc bridge formatting improvements --- tmtcservices/TmTcBridge.cpp | 27 +++++++++++++++------------ tmtcservices/TmTcBridge.h | 11 +++++++---- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/tmtcservices/TmTcBridge.cpp b/tmtcservices/TmTcBridge.cpp index 8c44f7de..b55803cb 100644 --- a/tmtcservices/TmTcBridge.cpp +++ b/tmtcservices/TmTcBridge.cpp @@ -24,8 +24,9 @@ ReturnValue_t TmTcBridge::setNumberOfSentPacketsPerCycle( return RETURN_OK; } else { - sif::warning << "TmTcBridge: Number of packets sent per cycle " - "exceeds limits. Keeping default value." << std::endl; + sif::warning << "TmTcBridge::setNumberOfSentPacketsPerCycle: Number of " + << "packets sent per cycle exceeds limits. " + << "Keeping default value." << std::endl; return RETURN_FAILED; } } @@ -37,8 +38,9 @@ ReturnValue_t TmTcBridge::setMaxNumberOfPacketsStored( return RETURN_OK; } else { - sif::warning << "TmTcBridge: Number of packets stored " - "exceeds limits. Keeping default value." << std::endl; + sif::warning << "TmTcBridge::setMaxNumberOfPacketsStored: Number of " + << "packets stored exceeds limits. " + << "Keeping default value." << std::endl; return RETURN_FAILED; } } @@ -72,11 +74,13 @@ ReturnValue_t TmTcBridge::performOperation(uint8_t operationCode) { ReturnValue_t result; result = handleTc(); if(result != RETURN_OK) { - sif::error << "TMTC Bridge: Error handling TCs" << std::endl; + sif::debug << "TmTcBridge::performOperation: " + << "Error handling TCs" << std::endl; } result = handleTm(); if (result != RETURN_OK) { - sif::error << "TMTC Bridge: Error handling TMs" << std::endl; + sif::debug << "TmTcBridge::performOperation: " + << "Error handling TMs" << std::endl; } return result; } @@ -88,7 +92,7 @@ ReturnValue_t TmTcBridge::handleTc() { ReturnValue_t TmTcBridge::handleTm() { ReturnValue_t result = handleTmQueue(); if(result != RETURN_OK) { - sif::error << "TMTC Bridge: Reading TM Queue failed" << std::endl; + sif::warning << "TmTcBridge: Reading TM Queue failed" << std::endl; return RETURN_FAILED; } @@ -118,7 +122,7 @@ ReturnValue_t TmTcBridge::handleTmQueue() { result = sendTm(data, size); if (result != RETURN_OK) { - sif::error << "TMTC Bridge: Could not send TM packet"<< std::endl; + sif::warning << "TmTcBridge: Could not send TM packet" << std::endl; tmStore->deleteData(message.getStorageId()); return result; @@ -129,13 +133,12 @@ ReturnValue_t TmTcBridge::handleTmQueue() { } ReturnValue_t TmTcBridge::storeDownlinkData(TmTcMessage *message) { - //debug << "TMTC Bridge: Comm Link down. " - // "Saving packet ID to be sent later\r\n" << std::flush; store_address_t storeId = 0; if(tmFifo.full()) { - sif::error << "TMTC Bridge: TM downlink max. number of stored packet IDs " - "reached! Overwriting old data" << std::endl; + sif::error << "TmTcBridge::storeDownlinkData: TM downlink max. number " + << "of stored packet IDs reached! " + << "Overwriting old data" << std::endl; tmFifo.retrieve(&storeId); tmStore->deleteData(storeId); } diff --git a/tmtcservices/TmTcBridge.h b/tmtcservices/TmTcBridge.h index 3e3d1b71..993cd5b9 100644 --- a/tmtcservices/TmTcBridge.h +++ b/tmtcservices/TmTcBridge.h @@ -76,13 +76,14 @@ protected: object_id_t tcDestination = objects::NO_OBJECT; //! Used to send and receive TMTC messages. - //! TmTcMessage is used to transport messages between tasks. + //! The TmTcMessage class is used to transport messages between tasks. MessageQueueIF* tmTcReceptionQueue = nullptr; StorageManagerIF* tmStore = nullptr; StorageManagerIF* tcStore = nullptr; - //! Used to specify whether communication link is up by default. + //! Used to specify whether communication link is up. Will be true + //! by default, so telemetry will be handled immediately. bool communicationLinkUp = true; bool tmStored = false; @@ -103,7 +104,8 @@ protected: virtual ReturnValue_t handleTm(); /** - * Read the TM Queue and send TM if necessary. Default implementation provided + * Read the TM Queue and send TM if necessary. + * Default implementation provided * @return */ virtual ReturnValue_t handleTmQueue(); @@ -116,7 +118,8 @@ protected: /** * Implemented by child class. Perform sending of Telemetry by implementing - * communication drivers or wrappers, e.g. UART communication or lwIP stack. + * communication drivers or wrappers, e.g. serial communication or a socket + * call. * @param data * @param dataLen * @return From 57418eb877888bed655eb8f3fee2d58b6f4cbe82 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 9 Jul 2020 20:04:49 +0200 Subject: [PATCH 263/307] distrinction between default settings and individual settings for service --- devicehandlers/DeviceHandlerBase.h | 1 + tmtcservices/CommandingServiceBase.cpp | 12 ++++++++++-- tmtcservices/CommandingServiceBase.h | 6 ++++-- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/devicehandlers/DeviceHandlerBase.h b/devicehandlers/DeviceHandlerBase.h index 3c5edf55..61fb701d 100644 --- a/devicehandlers/DeviceHandlerBase.h +++ b/devicehandlers/DeviceHandlerBase.h @@ -1048,6 +1048,7 @@ private: /** Cached for initialize() */ static object_id_t defaultHkDestination; + /** HK destination can also be set individually */ object_id_t hkDestination = objects::NO_OBJECT; /** diff --git a/tmtcservices/CommandingServiceBase.cpp b/tmtcservices/CommandingServiceBase.cpp index 63a3d943..4c9b5375 100644 --- a/tmtcservices/CommandingServiceBase.cpp +++ b/tmtcservices/CommandingServiceBase.cpp @@ -8,8 +8,8 @@ #include #include -object_id_t CommandingServiceBase::packetSource = objects::NO_OBJECT; -object_id_t CommandingServiceBase::packetDestination = objects::NO_OBJECT; +object_id_t CommandingServiceBase::defaultPacketSource = objects::NO_OBJECT; +object_id_t CommandingServiceBase::defaultPacketDestination = objects::NO_OBJECT; CommandingServiceBase::CommandingServiceBase(object_id_t setObjectId, uint16_t apid, uint8_t service, uint8_t numberOfParallelCommands, @@ -62,10 +62,18 @@ ReturnValue_t CommandingServiceBase::initialize() { return result; } + if(packetDestination == objects::NO_OBJECT) { + packetDestination = defaultPacketDestination; + } AcceptsTelemetryIF* packetForwarding = objectManager->get(packetDestination); + + if(packetSource == objects::NO_OBJECT) { + packetSource = defaultPacketSource; + } PUSDistributorIF* distributor = objectManager->get( packetSource); + if (packetForwarding == nullptr or distributor == nullptr) { sif::error << "CommandingServiceBase::intialize: Packet source or " "packet destination invalid!" << std::endl; diff --git a/tmtcservices/CommandingServiceBase.h b/tmtcservices/CommandingServiceBase.h index e9b5f047..ec38bdee 100644 --- a/tmtcservices/CommandingServiceBase.h +++ b/tmtcservices/CommandingServiceBase.h @@ -248,8 +248,10 @@ protected: uint32_t failureParameter1 = 0; uint32_t failureParameter2 = 0; - static object_id_t packetSource; - static object_id_t packetDestination; + static object_id_t defaultPacketSource; + object_id_t packetSource = objects::NO_OBJECT; + static object_id_t defaultPacketDestination; + object_id_t packetDestination = objects::NO_OBJECT; /** * Pointer to the task which executes this component, From cdd877032fe211cd6e9e56940352f608b7e90efb Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 9 Jul 2020 23:20:48 +0200 Subject: [PATCH 264/307] doc for system object IF improved --- objectmanager/SystemObjectIF.h | 56 ++++++++++++++++------------------ 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/objectmanager/SystemObjectIF.h b/objectmanager/SystemObjectIF.h index 7540f80f..b7590509 100644 --- a/objectmanager/SystemObjectIF.h +++ b/objectmanager/SystemObjectIF.h @@ -1,26 +1,19 @@ -/** - * @file SystemObjectIF.h - * @brief This file contains the definition of the SystemObjectIF interface. - * @date 18.09.2012 - * @author Bastian Baetz - */ - -#ifndef SYSTEMOBJECTIF_H_ -#define SYSTEMOBJECTIF_H_ +#ifndef FRAMEWORK_OBJECTMANAGER_SYSTEMOBJECTIF_H_ +#define FRAMEWORK_OBJECTMANAGER_SYSTEMOBJECTIF_H_ #include #include -#include +#include /** - * \defgroup system_objects Software System Object Management - * The classes to create System Objects and classes to manage these are contained in this group. - * System Objects are software elements that can be controlled externally. They all have a unique - * object identifier. + * @defgroup system_objects Software System Object Management + * The classes to create System Objects and classes to manage these are + * contained in this group. System Objects are software elements that can be + * controlled externally. They all have a unique object identifier. */ /** * This is the typedef for object identifiers. - * \ingroup system_objects + * @ingroup system_objects */ typedef uint32_t object_id_t; @@ -29,7 +22,8 @@ typedef uint32_t object_id_t; * list. * It does not provide any method definitions, still it is required to * perform a type check with dynamic_cast. - * \ingroup system_objects + * @author Bastian Baetz + * @ingroup system_objects */ class SystemObjectIF : public EventReportingProxyIF { public: @@ -41,24 +35,28 @@ public: /** * The empty virtual destructor as required for C++ interfaces. */ - virtual ~SystemObjectIF() { - } + virtual ~SystemObjectIF() {} /** - * Initializes all inter-object dependencies. - * This is necessary to avoid circular dependencies of not-fully - * initialized objects on start up. - * @return - \c RETURN_OK in case the initialization was successful - * - \c RETURN_FAILED otherwise + * @brief Initializes the object. + * There are initialization steps which can also be done in the constructor. + * However, there is no clean way to get a returnvalue from a constructor. + * Furthermore some components require other system object to be created + * which might not have been built yet. + * Therefore, a two-step initialization resolves this problem and prevents + * circular dependencies of not-fully initialized objects on start up. + * @return - @c RETURN_OK in case the initialization was successful + * - @c RETURN_FAILED otherwise */ virtual ReturnValue_t initialize() = 0; /** - * Checks, if all object-object interconnections are satisfying for operation. - * Some objects need certain other objects (or a certain number), to be registered as children. - * These checks can be done in this method. - * @return - \c RETURN_OK in case the check was successful - * - \c any other code otherwise + * @brief Checks if all object-object interconnections are satisfying + * for operation. + * Some objects need certain other objects (or a certain number), to be + * registered as children. These checks can be done in this method. + * @return - @c RETURN_OK in case the check was successful + * - @c any other code otherwise */ virtual ReturnValue_t checkObjectConnections() = 0; }; -#endif /* SYSTEMOBJECTIF_H_ */ +#endif /* FRAMEWORK_OBJECTMANAGER_SYSTEMOBJECTIF_H_ */ From 1fde3c2c992f3fd96cd0098bfb23c5ab6fa51589 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 10 Jul 2020 00:19:25 +0200 Subject: [PATCH 265/307] added srv200, CSB doc --- pus/CService200ModeCommanding.cpp | 133 +++++++++++++++++++++++++ pus/CService200ModeCommanding.h | 85 ++++++++++++++++ pus/servicepackets/Service200Packets.h | 56 +++++++++++ tmtcpacket/pus/TmPacketStored.cpp | 1 + tmtcservices/CommandingServiceBase.h | 23 +++-- 5 files changed, 290 insertions(+), 8 deletions(-) create mode 100644 pus/CService200ModeCommanding.cpp create mode 100644 pus/CService200ModeCommanding.h create mode 100644 pus/servicepackets/Service200Packets.h diff --git a/pus/CService200ModeCommanding.cpp b/pus/CService200ModeCommanding.cpp new file mode 100644 index 00000000..753ec38b --- /dev/null +++ b/pus/CService200ModeCommanding.cpp @@ -0,0 +1,133 @@ +#include +#include + +#include +#include +#include +#include + +CService200ModeCommanding::CService200ModeCommanding(object_id_t objectId, + uint16_t apid, uint8_t serviceId): + CommandingServiceBase(objectId, apid, serviceId, + NUMBER_OF_PARALLEL_COMMANDS,COMMAND_TIMEOUT_SECONDS) {} + +CService200ModeCommanding::~CService200ModeCommanding() {} + +ReturnValue_t CService200ModeCommanding::isValidSubservice(uint8_t subservice) { + switch(subservice) { + case(Subservice::COMMAND_MODE_COMMAND): + case(Subservice::COMMAND_MODE_READ): + case(Subservice::COMMAND_MODE_ANNCOUNCE): + return RETURN_OK; + default: + return AcceptsTelecommandsIF::INVALID_SUBSERVICE; + } +} + + +ReturnValue_t CService200ModeCommanding::getMessageQueueAndObject( + uint8_t subservice, const uint8_t *tcData, size_t tcDataLen, + MessageQueueId_t *id, object_id_t *objectId) +{ + ReturnValue_t result = checkAndAcquireTargetID(objectId,tcData,tcDataLen); + if (result != RETURN_OK) { + return result; + } + result = checkInterfaceAndAcquireMessageQueue(id,objectId); + return result; +} + +ReturnValue_t CService200ModeCommanding::checkAndAcquireTargetID( + object_id_t* objectIdToSet, const uint8_t* tcData, uint32_t tcDataLen) { + size_t size = tcDataLen; + if (SerializeAdapter::deSerialize(objectIdToSet, &tcData, &size, + SerializeIF::Endianness::BIG) + != HasReturnvaluesIF::RETURN_OK) + return CommandingServiceBase::INVALID_TC; + else + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t CService200ModeCommanding::checkInterfaceAndAcquireMessageQueue( + MessageQueueId_t* MessageQueueToSet, object_id_t* objectId) { + HasModesIF * possibleTarget = objectManager->get(*objectId); + if(possibleTarget!=NULL){ + *MessageQueueToSet = possibleTarget->getCommandQueue(); + return HasReturnvaluesIF::RETURN_OK; + } else { + return CommandingServiceBase::INVALID_OBJECT; + } +} + + +ReturnValue_t CService200ModeCommanding::prepareCommand( + CommandMessage* message,uint8_t subservice, const uint8_t *tcData, + size_t tcDataLen, uint32_t *state, object_id_t objectId) { + ModePacket modeCommandPacket; + ReturnValue_t result = modeCommandPacket.deSerialize(&tcData, + &tcDataLen, SerializeIF::Endianness::BIG); + if (result != RETURN_OK) { + return result; + } + else { + ModeMessage::setModeMessage(dynamic_cast(message), + ModeMessage::CMD_MODE_COMMAND, modeCommandPacket.getMode(), + modeCommandPacket.getSubmode()); + return result; + } +} + + +ReturnValue_t CService200ModeCommanding::handleReply( + const CommandMessage* reply, Command_t previousCommand, + uint32_t *state, CommandMessage* optionalNextCommand, + object_id_t objectId, bool *isStep) { + Command_t replyId = reply->getCommand(); + ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED; + switch(replyId) { + case(ModeMessage::REPLY_MODE_REPLY): { + result = prepareModeReply(reply, objectId); + break; + } + case(ModeMessage::REPLY_WRONG_MODE_REPLY): { + result = prepareWrongModeReply(reply, objectId); + break; + } + case(ModeMessage::REPLY_CANT_REACH_MODE): { + result = prepareCantReachModeReply(reply, objectId); + break; + } + case(ModeMessage::REPLY_MODE_INFO): + result = INVALID_REPLY; + break; + default: + result = RETURN_FAILED; + } + return result; +} + +ReturnValue_t CService200ModeCommanding::prepareModeReply( + const CommandMessage *reply, object_id_t objectId) { + ModePacket modeReplyPacket(objectId, + ModeMessage::getMode(reply), + ModeMessage::getSubmode(reply)); + return sendTmPacket(Subservice::REPLY_MODE_REPLY, &modeReplyPacket); +} + +ReturnValue_t CService200ModeCommanding::prepareWrongModeReply( + const CommandMessage *reply, object_id_t objectId) { + ModePacket wrongModeReply(objectId, ModeMessage::getMode(reply), + ModeMessage::getSubmode(reply)); + return sendTmPacket(Subservice::REPLY_WRONG_MODE_REPLY, &wrongModeReply); +} + +ReturnValue_t CService200ModeCommanding::prepareCantReachModeReply( + const CommandMessage *reply, object_id_t objectId) { + CantReachModePacket cantReachModePacket(objectId, + ModeMessage::getCantReachModeReason(reply)); + return sendTmPacket(Subservice::REPLY_CANT_REACH_MODE, + &cantReachModePacket); +} + + + diff --git a/pus/CService200ModeCommanding.h b/pus/CService200ModeCommanding.h new file mode 100644 index 00000000..ede61a84 --- /dev/null +++ b/pus/CService200ModeCommanding.h @@ -0,0 +1,85 @@ +#ifndef FRAMEWORK_PUS_CSERVICE200MODECOMMANDING_H_ +#define FRAMEWORK_PUS_CSERVICE200MODECOMMANDING_H_ + +#include + +/** + * @brief Custom PUS service to set mode of all objects implementing HasModesIF + * + * Examples: Device Handlers, Assemblies or Subsystems. + * Full Documentation: ECSS-E-ST-70-41C or ECSS-E-70-41A + * Dissertation Baetz p. 115, 116, 165-167. + * + * This is a gateway service. It relays device commands using the software bus. + * @ingroup pus_services + */ +class CService200ModeCommanding: public CommandingServiceBase { +public: + static constexpr uint8_t NUMBER_OF_PARALLEL_COMMANDS = 4; + static constexpr uint16_t COMMAND_TIMEOUT_SECONDS = 60; + + CService200ModeCommanding(object_id_t objectId, + uint16_t apid, uint8_t serviceId); + virtual~ CService200ModeCommanding(); + +protected: + //! CommandingServiceBase (CSB) abstract functions. See CSB documentation. + ReturnValue_t isValidSubservice(uint8_t subservice) override; + ReturnValue_t getMessageQueueAndObject(uint8_t subservice, + const uint8_t *tcData, size_t tcDataLen, MessageQueueId_t *id, + object_id_t *objectId) override; + ReturnValue_t prepareCommand(CommandMessage* message, + uint8_t subservice, const uint8_t *tcData, size_t tcDataLen, + uint32_t *state, object_id_t objectId) override; + ReturnValue_t handleReply(const CommandMessage* reply, + Command_t previousCommand, uint32_t *state, + CommandMessage* optionalNextCommand, object_id_t objectId, + bool *isStep) override; + +private: + ReturnValue_t checkAndAcquireTargetID(object_id_t* objectIdToSet, + const uint8_t* tcData, uint32_t tcDataLen); + ReturnValue_t checkInterfaceAndAcquireMessageQueue( + MessageQueueId_t* MessageQueueToSet, object_id_t* objectId); + + ReturnValue_t prepareModeReply(const CommandMessage *reply, + object_id_t objectId); + ReturnValue_t prepareWrongModeReply(const CommandMessage *reply, + object_id_t objectId); + ReturnValue_t prepareCantReachModeReply(const CommandMessage *reply, + object_id_t objectId); + + enum Subservice { //!< [EXPORT] : [COMMENT] Mode Commanding Subservices + //!< [EXPORT] : [COMMAND] Command assembly, subsystem or device mode + COMMAND_MODE_COMMAND = 1, + //!< [EXPORT] : [COMMAND] Command to set the specified Mode, + //! regardless of external control flag + COMMAND_MODE_COMMAND_FORCED = 2, + //!< [EXPORT] : [COMMAND] Read the current mode and + //! reply with a REPLY_MODE_REPLY + COMMAND_MODE_READ = 3, + //!< [EXPORT] : [COMMAND] Trigger an ModeInfo Event. + //! This command does NOT have a reply + COMMAND_MODE_ANNCOUNCE = 4, + //!< [EXPORT] : [COMMAND] Trigger a ModeInfo Event and to send this + //! command to every child. This command does NOT have a reply. + COMMAND_MODE_ANNOUNCE_RECURSIVELY = 5, + //!< [EXPORT] : [REPLY] Reply to a CMD_MODE_COMMAND or CMD_MODE_READ + REPLY_MODE_REPLY = 6, + //!< [EXPORT] : [REPLY] Reply in case a mode command can't be executed. + REPLY_CANT_REACH_MODE = 7, + //!< [EXPORT] : [REPLY] Reply to a CMD_MODE_COMMAND, indicating that a + //! mode was commanded and a transition started but was aborted, + //! the parameters contain the mode that was reached + REPLY_WRONG_MODE_REPLY = 8 + }; + + enum modeParameters { + MODE_OFF = 0, + MODE_ON = 1, + MODE_NORMAL = 2, + MODE_RAW = 3 + }; +}; + +#endif /* FRAMEWORK_PUS_CSERVICE200MODECOMMANDING_H_ */ diff --git a/pus/servicepackets/Service200Packets.h b/pus/servicepackets/Service200Packets.h new file mode 100644 index 00000000..fb153e21 --- /dev/null +++ b/pus/servicepackets/Service200Packets.h @@ -0,0 +1,56 @@ +#ifndef FRAMEWORK_PUS_SERVICEPACKETS_SERVICE200PACKETS_H_ +#define FRAMEWORK_PUS_SERVICEPACKETS_SERVICE200PACKETS_H_ + +#include +#include +#include + +/** + * @brief Subservice 1, 2, 3, 4, 5 + * @ingroup spacepackets + */ +class ModePacket : public SerialLinkedListAdapter { //!< [EXPORT] : [SUBSERVICE] 1, 2, 6 +public: + ModePacket() { + setLinks(); + } + + ModePacket(object_id_t objectId, Mode_t mode, Submode_t submode) : + objectId(objectId), mode(mode), submode(submode) { + setLinks(); + } + + Mode_t getMode() { + return mode.entry; + } + + Submode_t getSubmode() { + return submode.entry; + } + +private: + // Forbid copying because of next pointer to member + ModePacket(const ModePacket &command); + void setLinks() { + setStart(&objectId); + objectId.setNext(&mode); + mode.setNext(&submode); + } + SerializeElement objectId; //!< [EXPORT] : [COMMENT] Target or source object + SerializeElement mode; //!< [EXPORT] : [COMMENT] 0: MODE_OFF, 1: MODE_ON, 2: MODE_NORMAL, 3: MODE_RAW + SerializeElement submode; //!< [EXPORT] : [COMMENT] Usually 0, device specific submode possible +}; + +class CantReachModePacket: public SerialLinkedListAdapter { //!< [EXPORT] : [SUBSERVICE] 7 +public: + CantReachModePacket(object_id_t objectId, ReturnValue_t reason): + objectId(objectId), reason(reason) { + setStart(&this->objectId); + this->objectId.setNext(&this->reason); + } + + SerializeElement objectId; //!< [EXPORT] : [COMMENT] Reply source object + SerializeElement reason; //!< [EXPORT] : [COMMENT] Reason the mode could not be reached +}; + +#endif /* FRAMEWORK_PUS_SERVICEPACKETS_SERVICE200PACKETS_H_ */ diff --git a/tmtcpacket/pus/TmPacketStored.cpp b/tmtcpacket/pus/TmPacketStored.cpp index d6a4a69f..6eb852f0 100644 --- a/tmtcpacket/pus/TmPacketStored.cpp +++ b/tmtcpacket/pus/TmPacketStored.cpp @@ -34,6 +34,7 @@ TmPacketStored::TmPacketStored(uint16_t apid, uint8_t service, size + headerSize + sizeof(PUSTmDataFieldHeader) + CRC_SIZE - 1); } +// todo: Endianness flags as optional parameter? TmPacketStored::TmPacketStored(uint16_t apid, uint8_t service, uint8_t subservice, uint8_t packetSubcounter, SerializeIF *content, SerializeIF *header) : diff --git a/tmtcservices/CommandingServiceBase.h b/tmtcservices/CommandingServiceBase.h index ec38bdee..1bd18571 100644 --- a/tmtcservices/CommandingServiceBase.h +++ b/tmtcservices/CommandingServiceBase.h @@ -114,16 +114,17 @@ public: * Implementation of ExecutableObjectIF function * * Used to setup the reference of the task, that executes this component - * @param task_ Pointer to the taskIF of this task + * @param task Pointer to the taskIF of this task */ - virtual void setTaskIF(PeriodicTaskIF* task_); + virtual void setTaskIF(PeriodicTaskIF* task); protected: /** * Check the target subservice * @param subservice[in] - * @return -@c RETURN_OK on success - * -@c INVALID_SUBSERVICE if service is not known + * @return + * -@c RETURN_OK Subservice valid, continue message handling + * -@c INVALID_SUBSERVICE if service is not known, rejects packet. */ virtual ReturnValue_t isValidSubservice(uint8_t subservice) = 0; @@ -136,9 +137,10 @@ protected: * @param tcDataLen * @param id MessageQueue ID is stored here * @param objectId Object ID is extracted and stored here - * @return - @c RETURN_OK on success - * - @c RETURN_FAILED - * - @c CSB or implementation specific return codes + * @return + * - @c RETURN_OK Cotinue message handling + * - @c RETURN_FAILED Reject the packet and generates a start failure + * verification */ virtual ReturnValue_t getMessageQueueAndObject(uint8_t subservice, const uint8_t *tcData, size_t tcDataLen, MessageQueueId_t *id, @@ -157,6 +159,11 @@ protected: * communication * @param objectId Target object ID * @return + * - @c RETURN_OK to generate a verification start message + * - @c EXECUTION_COMPELTE Fire-and-forget command. Generate a completion + * verification message. + * - @c Anything else rejects the packets and generates a start failure + * verification. */ virtual ReturnValue_t prepareCommand(CommandMessage* message, uint8_t subservice, const uint8_t *tcData, size_t tcDataLen, @@ -181,7 +188,7 @@ protected: * @return * - @c RETURN_OK, @c EXECUTION_COMPLETE or @c NO_STEP_MESSAGE to * generate TC verification success - * - @c INVALID_REPLY calls handleUnrequestedReply + * - @c INVALID_REPLY Calls handleUnrequestedReply * - Anything else triggers a TC verification failure. If RETURN_FAILED * is returned and the command ID is CommandMessage::REPLY_REJECTED, * a failure verification message with the reason as the error parameter From 7a4cc1a6b692b39c596bb88e67051af69b97f928 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 10 Jul 2020 01:22:23 +0200 Subject: [PATCH 266/307] hk manager initialized now --- devicehandlers/DeviceHandlerBase.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index 4358503e..c696e4e3 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -199,14 +199,14 @@ ReturnValue_t DeviceHandlerBase::initialize() { return result; } -// if(hkDestination == objects::NO_OBJECT) { -// hkDestination = defaultHkDestination; -// } -// -// result = hkManager.initialize(commandQueue, hkDestination); -// if (result != HasReturnvaluesIF::RETURN_OK) { -// return result; -// } + if(hkDestination == objects::NO_OBJECT) { + hkDestination = defaultHkDestination; + } + + result = hkManager.initialize(commandQueue, hkDestination); + if (result != HasReturnvaluesIF::RETURN_OK) { + return result; + } fillCommandAndReplyMap(); From f3739fd213acd0849399fa4b755ffa7a126da6ab Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 10 Jul 2020 02:44:58 +0200 Subject: [PATCH 267/307] bugfix failure isolation base --- fdir/FailureIsolationBase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdir/FailureIsolationBase.cpp b/fdir/FailureIsolationBase.cpp index 8bc88002..083f5af0 100644 --- a/fdir/FailureIsolationBase.cpp +++ b/fdir/FailureIsolationBase.cpp @@ -29,7 +29,7 @@ ReturnValue_t FailureIsolationBase::initialize() { if (result != HasReturnvaluesIF::RETURN_OK) { return result; } - if (faultTreeParent != objects::NO_OBJECT) { + if (ownerId != objects::NO_OBJECT) { result = manager->subscribeToAllEventsFrom(eventQueue->getId(), ownerId); if (result != HasReturnvaluesIF::RETURN_OK) { return result; From 3551a767a71635c47af18df4b5afbc393416838e Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 10 Jul 2020 03:06:18 +0200 Subject: [PATCH 268/307] removed old code --- devicehandlers/DeviceHandlerBase.cpp | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index c696e4e3..06fb84cc 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -348,7 +348,7 @@ void DeviceHandlerBase::doStateMachine() { if(powerSwitcher == nullptr) { setMode(MODE_OFF); - return; + break; } if (currentUptime - timeoutStart >= powerSwitcher->getSwitchDelayMs()) { @@ -832,21 +832,6 @@ MessageQueueId_t DeviceHandlerBase::getCommandQueue() const { return commandQueue->getId(); } -//ReturnValue_t DeviceHandlerBase::switchCookieChannel(object_id_t newChannelId) { -// DeviceCommunicationIF *newCommunication = objectManager->get< -// DeviceCommunicationIF>(newChannelId); -// -// if (newCommunication != NULL) { -// ReturnValue_t result = newCommunication->reOpen(cookie, ioBoardAddress, -// maxDeviceReplyLen); -// if (result != RETURN_OK) { -// return result; -// } -// return RETURN_OK; -// } -// return RETURN_FAILED; -//} - void DeviceHandlerBase::buildRawDeviceCommand(CommandMessage* commandMessage) { storedRawData = DeviceHandlerMessage::getStoreAddress(commandMessage); ReturnValue_t result = getStorageData(storedRawData, &rawPacket, From bdc6e881986e9048eac100561ac0e0159b1b0eca Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 10 Jul 2020 03:09:32 +0200 Subject: [PATCH 269/307] reordered includes --- devicehandlers/DeviceHandlerBase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index 06fb84cc..af98ba44 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -1,10 +1,10 @@ -#include #include #include #include #include #include +#include #include #include #include From 9cbc1a18b8c305c095f1c70ada691541e1df6bd1 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 10 Jul 2020 03:16:08 +0200 Subject: [PATCH 270/307] csrv200 improvements --- pus/CService200ModeCommanding.cpp | 56 ++++++++++++------------------- storagemanager/StorageAccessor.h | 5 +++ 2 files changed, 26 insertions(+), 35 deletions(-) diff --git a/pus/CService200ModeCommanding.cpp b/pus/CService200ModeCommanding.cpp index 753ec38b..fd6da67e 100644 --- a/pus/CService200ModeCommanding.cpp +++ b/pus/CService200ModeCommanding.cpp @@ -27,36 +27,26 @@ ReturnValue_t CService200ModeCommanding::isValidSubservice(uint8_t subservice) { ReturnValue_t CService200ModeCommanding::getMessageQueueAndObject( uint8_t subservice, const uint8_t *tcData, size_t tcDataLen, - MessageQueueId_t *id, object_id_t *objectId) -{ - ReturnValue_t result = checkAndAcquireTargetID(objectId,tcData,tcDataLen); - if (result != RETURN_OK) { - return result; - } - result = checkInterfaceAndAcquireMessageQueue(id,objectId); - return result; -} + MessageQueueId_t *id, object_id_t *objectId) { + if(tcDataLen < sizeof(object_id_t)) { + return CommandingServiceBase::INVALID_TC; + } + SerializeAdapter::deSerialize(objectId, &tcData, &tcDataLen, + SerializeIF::Endianness::BIG); -ReturnValue_t CService200ModeCommanding::checkAndAcquireTargetID( - object_id_t* objectIdToSet, const uint8_t* tcData, uint32_t tcDataLen) { - size_t size = tcDataLen; - if (SerializeAdapter::deSerialize(objectIdToSet, &tcData, &size, - SerializeIF::Endianness::BIG) - != HasReturnvaluesIF::RETURN_OK) - return CommandingServiceBase::INVALID_TC; - else - return HasReturnvaluesIF::RETURN_OK; + return checkInterfaceAndAcquireMessageQueue(id,objectId); } ReturnValue_t CService200ModeCommanding::checkInterfaceAndAcquireMessageQueue( - MessageQueueId_t* MessageQueueToSet, object_id_t* objectId) { - HasModesIF * possibleTarget = objectManager->get(*objectId); - if(possibleTarget!=NULL){ - *MessageQueueToSet = possibleTarget->getCommandQueue(); - return HasReturnvaluesIF::RETURN_OK; - } else { - return CommandingServiceBase::INVALID_OBJECT; - } + MessageQueueId_t* messageQueueToSet, object_id_t* objectId) { + HasModesIF * destination = objectManager->get(*objectId); + if(destination == nullptr) { + return CommandingServiceBase::INVALID_OBJECT; + + } + + *messageQueueToSet = destination->getCommandQueue(); + return HasReturnvaluesIF::RETURN_OK; } @@ -69,12 +59,11 @@ ReturnValue_t CService200ModeCommanding::prepareCommand( if (result != RETURN_OK) { return result; } - else { - ModeMessage::setModeMessage(dynamic_cast(message), - ModeMessage::CMD_MODE_COMMAND, modeCommandPacket.getMode(), - modeCommandPacket.getSubmode()); - return result; - } + + ModeMessage::setModeMessage(dynamic_cast(message), + ModeMessage::CMD_MODE_COMMAND, modeCommandPacket.getMode(), + modeCommandPacket.getSubmode()); + return result; } @@ -128,6 +117,3 @@ ReturnValue_t CService200ModeCommanding::prepareCantReachModeReply( return sendTmPacket(Subservice::REPLY_CANT_REACH_MODE, &cantReachModePacket); } - - - diff --git a/storagemanager/StorageAccessor.h b/storagemanager/StorageAccessor.h index c5e38306..4b3f1ea9 100644 --- a/storagemanager/StorageAccessor.h +++ b/storagemanager/StorageAccessor.h @@ -25,8 +25,13 @@ public: * @param * @return */ +<<<<<<< Updated upstream StorageAccessor& operator= (StorageAccessor&&); StorageAccessor (StorageAccessor&&); +======= + StorageAccessor& operator=(StorageAccessor&&); + StorageAccessor(StorageAccessor&&); +>>>>>>> Stashed changes ReturnValue_t write(uint8_t *data, size_t size, uint16_t offset = 0); From be8913efeaada850906e19f2d40b6e503b7ec270 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 10 Jul 2020 03:30:52 +0200 Subject: [PATCH 271/307] srv8 improvements --- pus/Service5EventReporting.cpp | 3 +-- pus/Service8FunctionManagement.cpp | 42 +++++++++++++++++------------- pus/Service8FunctionManagement.h | 3 +++ storagemanager/StorageAccessor.h | 12 +++------ 4 files changed, 32 insertions(+), 28 deletions(-) diff --git a/pus/Service5EventReporting.cpp b/pus/Service5EventReporting.cpp index fe55059c..1dfbe229 100644 --- a/pus/Service5EventReporting.cpp +++ b/pus/Service5EventReporting.cpp @@ -59,8 +59,7 @@ ReturnValue_t Service5EventReporting::generateEventReport( } ReturnValue_t Service5EventReporting::handleRequest(uint8_t subservice) { - switch(subservice) - { + switch(subservice) { case Subservice::ENABLE: { enableEventReport = true; return HasReturnvaluesIF::RETURN_OK; diff --git a/pus/Service8FunctionManagement.cpp b/pus/Service8FunctionManagement.cpp index 24338464..812398b9 100644 --- a/pus/Service8FunctionManagement.cpp +++ b/pus/Service8FunctionManagement.cpp @@ -1,7 +1,6 @@ #include #include -#include #include #include #include @@ -54,12 +53,8 @@ ReturnValue_t Service8FunctionManagement::checkInterfaceAndAcquireMessageQueue( ReturnValue_t Service8FunctionManagement::prepareCommand( CommandMessage* message, uint8_t subservice, const uint8_t* tcData, size_t tcDataLen, uint32_t* state, object_id_t objectId) { - ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED; - if(subservice == static_cast(Subservice::DIRECT_COMMANDING)) { - result = prepareDirectCommand(dynamic_cast(message), + return prepareDirectCommand(dynamic_cast(message), tcData, tcDataLen); - } - return result; } ReturnValue_t Service8FunctionManagement::prepareDirectCommand( @@ -100,18 +95,7 @@ ReturnValue_t Service8FunctionManagement::handleReply( break; } case ActionMessage::DATA_REPLY: { - store_address_t storeId = ActionMessage::getStoreId(reply); - size_t size = 0; - const uint8_t * buffer = nullptr; - result = IPCStore->getData(storeId, &buffer, &size); - if(result != RETURN_OK) { - sif::error << "Service 8: Could not retrieve data for data reply"; - return result; - } - DataReply dataReply(objectId,actionId,buffer,size); - sendTmPacket(static_cast( - Subservice::DIRECT_COMMANDING_DATA_REPLY), &dataReply); - result = IPCStore ->deleteData(storeId); + result = handleDataReply(reply, objectId, actionId); break; } case ActionMessage::STEP_FAILED: @@ -126,4 +110,26 @@ ReturnValue_t Service8FunctionManagement::handleReply( return result; } +ReturnValue_t Service8FunctionManagement::handleDataReply( + const CommandMessage* reply, object_id_t objectId, + ActionId_t actionId) { + store_address_t storeId = ActionMessage::getStoreId(reply); + size_t size = 0; + const uint8_t * buffer = nullptr; + ReturnValue_t result = IPCStore->getData(storeId, &buffer, &size); + if(result != RETURN_OK) { + sif::error << "Service 8: Could not retrieve data for data reply" + << std::endl; + return result; + } + DataReply dataReply(objectId, actionId, buffer, size); + result = sendTmPacket(static_cast( + Subservice::DIRECT_COMMANDING_DATA_REPLY), &dataReply); + auto deletionResult = IPCStore->deleteData(storeId); + if(deletionResult != HasReturnvaluesIF::RETURN_OK) { + sif::warning << "Service8FunctionManagement::handleReply: Deletion" + << " of data in pool failed." << std::endl; + } + return result; +} diff --git a/pus/Service8FunctionManagement.h b/pus/Service8FunctionManagement.h index 54c98b97..e2c7a84f 100644 --- a/pus/Service8FunctionManagement.h +++ b/pus/Service8FunctionManagement.h @@ -1,6 +1,7 @@ #ifndef FRAMEWORK_PUS_SERVICE8FUNCTIONMANAGEMENT_H_ #define FRAMEWORK_PUS_SERVICE8FUNCTIONMANAGEMENT_H_ +#include #include /** @@ -59,6 +60,8 @@ private: MessageQueueId_t* messageQueueToSet, object_id_t* objectId); ReturnValue_t prepareDirectCommand(CommandMessage* message, const uint8_t* tcData, size_t tcDataLen); + ReturnValue_t handleDataReply(const CommandMessage* reply, + object_id_t objectId, ActionId_t actionId); }; #endif /* FRAMEWORK_PUS_SERVICE8FUNCTIONMANAGEMENT_H_ */ diff --git a/storagemanager/StorageAccessor.h b/storagemanager/StorageAccessor.h index 4b3f1ea9..d75e06ac 100644 --- a/storagemanager/StorageAccessor.h +++ b/storagemanager/StorageAccessor.h @@ -17,21 +17,17 @@ class StorageAccessor: public ConstStorageAccessor { public: StorageAccessor(store_address_t storeId); StorageAccessor(store_address_t storeId, StorageManagerIF* store); + /** * @brief Move ctor and move assignment allow returning accessors as - * a returnvalue. They prevent resource being free prematurely. - * Refer to: https://github.com/MicrosoftDocs/cpp-docs/blob/master/docs/cpp/ - * move-constructors-and-move-assignment-operators-cpp.md + * a returnvalue. They prevent resource being freed prematurely. + * See: https://github.com/MicrosoftDocs/cpp-docs/blob/master/docs/cpp/ + * move-constructors-and-move-assignment-operators-cpp.md * @param * @return */ -<<<<<<< Updated upstream - StorageAccessor& operator= (StorageAccessor&&); - StorageAccessor (StorageAccessor&&); -======= StorageAccessor& operator=(StorageAccessor&&); StorageAccessor(StorageAccessor&&); ->>>>>>> Stashed changes ReturnValue_t write(uint8_t *data, size_t size, uint16_t offset = 0); From a7d68f8c52886f39d116a9ad0553f26463c753b8 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 10 Jul 2020 13:31:45 +0200 Subject: [PATCH 272/307] deleted copy ctor --- pus/servicepackets/Service200Packets.h | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/pus/servicepackets/Service200Packets.h b/pus/servicepackets/Service200Packets.h index fb153e21..1b5bf236 100644 --- a/pus/servicepackets/Service200Packets.h +++ b/pus/servicepackets/Service200Packets.h @@ -11,6 +11,7 @@ */ class ModePacket : public SerialLinkedListAdapter { //!< [EXPORT] : [SUBSERVICE] 1, 2, 6 public: + ModePacket() { setLinks(); } @@ -28,9 +29,11 @@ public: return submode.entry; } + // Forbid copying, pointers are used. + ModePacket(const ModePacket&) = delete; + ModePacket& operator=(const ModePacket&) = delete; private: - // Forbid copying because of next pointer to member - ModePacket(const ModePacket &command); + void setLinks() { setStart(&objectId); objectId.setNext(&mode); @@ -41,6 +44,10 @@ private: SerializeElement submode; //!< [EXPORT] : [COMMENT] Usually 0, device specific submode possible }; +/** + * @brief Subservice 7 + * @ingroup spacepackets + */ class CantReachModePacket: public SerialLinkedListAdapter { //!< [EXPORT] : [SUBSERVICE] 7 public: CantReachModePacket(object_id_t objectId, ReturnValue_t reason): From e29226c9bba6587460d5db87e3ad3b3d7eab2357 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 10 Jul 2020 14:28:36 +0200 Subject: [PATCH 273/307] srv8 improved --- pus/Service8FunctionManagement.cpp | 9 +++++- pus/servicepackets/Service8Packets.h | 41 ++++++++++++++-------------- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/pus/Service8FunctionManagement.cpp b/pus/Service8FunctionManagement.cpp index 812398b9..50102b04 100644 --- a/pus/Service8FunctionManagement.cpp +++ b/pus/Service8FunctionManagement.cpp @@ -59,8 +59,15 @@ ReturnValue_t Service8FunctionManagement::prepareCommand( ReturnValue_t Service8FunctionManagement::prepareDirectCommand( CommandMessage *message, const uint8_t *tcData, size_t tcDataLen) { + if(tcDataLen < sizeof(object_id_t) + sizeof(ActionId_t)) { + sif::debug << "Service8FunctionManagement::prepareDirectCommand:" + << " TC size smaller thant minimum size of direct command." + << std::endl; + return CommandingServiceBase::INVALID_TC; + } + // Create direct command instance by extracting data from Telecommand - DirectCommand command(tcData,tcDataLen); + DirectCommand command(tcData, tcDataLen); // store additional parameters into the IPC Store store_address_t parameterAddress; diff --git a/pus/servicepackets/Service8Packets.h b/pus/servicepackets/Service8Packets.h index 5ef91280..86681c14 100644 --- a/pus/servicepackets/Service8Packets.h +++ b/pus/servicepackets/Service8Packets.h @@ -8,10 +8,7 @@ * 3. Return Code * 4. Optional step number for step replies * - * Data reply (subservice 132) consists of - * 1. Target Object ID - * 2. Action ID - * 3. Data + * * \date 01.07.2019 * \author R. Mueller @@ -29,23 +26,21 @@ /** - * \brief Subservice 128 - * \ingroup spacepackets + * @brief Subservice 128 + * @ingroup spacepackets */ class DirectCommand: public SerialLinkedListAdapter { //!< [EXPORT] : [SUBSERVICE] 128 public: - //typedef uint16_t typeOfMaxData; - //static const typeOfMaxData MAX_DATA = 256; - DirectCommand(const uint8_t* dataBuffer_, uint32_t size_) { - size_t size = sizeof(objectId); - SerializeAdapter::deSerialize(&objectId,&dataBuffer_,&size, + + DirectCommand(const uint8_t* tcData, size_t size) { + SerializeAdapter::deSerialize(&objectId, &tcData, &size, SerializeIF::Endianness::BIG); - size = sizeof(actionId); - SerializeAdapter::deSerialize(&actionId,&dataBuffer_,&size, + SerializeAdapter::deSerialize(&actionId, &tcData, &size, SerializeIF::Endianness::BIG); - parameterBuffer = dataBuffer_; - parametersSize = size_ - sizeof(objectId) - sizeof(actionId); + parameterBuffer = tcData; + parametersSize = size; } + ActionId_t getActionId() const { return actionId; } @@ -73,8 +68,12 @@ private: /** - * \brief Subservice 130 - * \ingroup spacepackets + * @brief Subservice 130 + * Data reply (subservice 130) consists of + * 1. Target Object ID + * 2. Action ID + * 3. Data + * @ingroup spacepackets */ class DataReply: public SerialLinkedListAdapter { //!< [EXPORT] : [SUBSERVICE] 130 public: @@ -100,8 +99,10 @@ private: /** - * \brief Subservice 132 - * \ingroup spacepackets + * @brief Subservice 132 + * @details + * Not used yet. Telecommand Verification takes care of this. + * @ingroup spacepackets */ class DirectReply: public SerialLinkedListAdapter { //!< [EXPORT] : [SUBSERVICE] 132 public: @@ -124,7 +125,7 @@ private: returnCode.setNext(&step); } } - bool isDataReply; //!< [EXPORT] : [IGNORE] + bool isStep; //!< [EXPORT] : [IGNORE] SerializeElement objectId; //!< [EXPORT] : [IGNORE] SerializeElement actionId; //!< [EXPORT] : [IGNORE] From 36a7f2f9ee86b00370bee48721f470d9392bf93c Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 10 Jul 2020 14:32:25 +0200 Subject: [PATCH 274/307] removed file header comment --- pus/servicepackets/Service8Packets.h | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/pus/servicepackets/Service8Packets.h b/pus/servicepackets/Service8Packets.h index 86681c14..8ea0d108 100644 --- a/pus/servicepackets/Service8Packets.h +++ b/pus/servicepackets/Service8Packets.h @@ -1,19 +1,3 @@ -/** - * \file Service8Packets.h - * - * \brief Structure of a Direct Command. - * Normal reply (subservice 130) consists of - * 1. Target object ID - * 2. Action ID (taget device has specified functions with action IDs) - * 3. Return Code - * 4. Optional step number for step replies - * - - * - * \date 01.07.2019 - * \author R. Mueller - */ - #ifndef FRAMEWORK_PUS_SERVICEPACKETS_SERVICE8PACKETS_H_ #define FRAMEWORK_PUS_SERVICEPACKETS_SERVICE8PACKETS_H_ From 31450362106ebec643d99dd60d963e822516b0a5 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 10 Jul 2020 19:34:18 +0200 Subject: [PATCH 275/307] getter functions for task handle --- osal/FreeRTOS/FixedTimeslotTask.cpp | 3 +++ osal/FreeRTOS/FixedTimeslotTask.h | 2 ++ osal/FreeRTOS/PeriodicTask.cpp | 4 ++++ osal/FreeRTOS/PeriodicTask.h | 2 ++ osal/FreeRTOS/TaskManagement.cpp | 5 +++-- osal/FreeRTOS/TaskManagement.h | 3 ++- 6 files changed, 16 insertions(+), 3 deletions(-) diff --git a/osal/FreeRTOS/FixedTimeslotTask.cpp b/osal/FreeRTOS/FixedTimeslotTask.cpp index 57c927f9..3bd2aafb 100644 --- a/osal/FreeRTOS/FixedTimeslotTask.cpp +++ b/osal/FreeRTOS/FixedTimeslotTask.cpp @@ -157,3 +157,6 @@ ReturnValue_t FixedTimeslotTask::sleepFor(uint32_t ms) { return HasReturnvaluesIF::RETURN_OK; } +TaskHandle_t FixedTimeslotTask::getTaskHandle() const { + return handle; +} diff --git a/osal/FreeRTOS/FixedTimeslotTask.h b/osal/FreeRTOS/FixedTimeslotTask.h index 27d08190..985b4f90 100644 --- a/osal/FreeRTOS/FixedTimeslotTask.h +++ b/osal/FreeRTOS/FixedTimeslotTask.h @@ -57,6 +57,8 @@ public: ReturnValue_t sleepFor(uint32_t ms) override; + TaskHandle_t getTaskHandle() const; + protected: bool started; TaskHandle_t handle; diff --git a/osal/FreeRTOS/PeriodicTask.cpp b/osal/FreeRTOS/PeriodicTask.cpp index 2ebfebf4..6d013a5b 100644 --- a/osal/FreeRTOS/PeriodicTask.cpp +++ b/osal/FreeRTOS/PeriodicTask.cpp @@ -126,6 +126,10 @@ void PeriodicTask::checkMissedDeadline(const TickType_t xLastWakeTime, } } +TaskHandle_t PeriodicTask::getTaskHandle() const { + return handle; +} + void PeriodicTask::handleMissedDeadline() { #ifdef DEBUG sif::warning << "PeriodicTask: " << pcTaskGetName(NULL) << diff --git a/osal/FreeRTOS/PeriodicTask.h b/osal/FreeRTOS/PeriodicTask.h index 09aa6bc7..679686f6 100644 --- a/osal/FreeRTOS/PeriodicTask.h +++ b/osal/FreeRTOS/PeriodicTask.h @@ -69,6 +69,8 @@ public: uint32_t getPeriodMs() const override; ReturnValue_t sleepFor(uint32_t ms) override; + + TaskHandle_t getTaskHandle() const; protected: bool started; TaskHandle_t handle; diff --git a/osal/FreeRTOS/TaskManagement.cpp b/osal/FreeRTOS/TaskManagement.cpp index 7871ab2e..9a1e4447 100644 --- a/osal/FreeRTOS/TaskManagement.cpp +++ b/osal/FreeRTOS/TaskManagement.cpp @@ -18,6 +18,7 @@ TaskHandle_t TaskManagement::getCurrentTaskHandle() { return xTaskGetCurrentTaskHandle(); } -configSTACK_DEPTH_TYPE TaskManagement::getTaskStackHighWatermark() { - return uxTaskGetStackHighWaterMark(TaskManagement::getCurrentTaskHandle()); +configSTACK_DEPTH_TYPE TaskManagement::getTaskStackHighWatermark( + TaskHandle_t task) { + return uxTaskGetStackHighWaterMark(task); } diff --git a/osal/FreeRTOS/TaskManagement.h b/osal/FreeRTOS/TaskManagement.h index 39c24377..cbde510c 100644 --- a/osal/FreeRTOS/TaskManagement.h +++ b/osal/FreeRTOS/TaskManagement.h @@ -57,7 +57,8 @@ public: * @return Smallest value of stack remaining since the task was started in * words. */ - static configSTACK_DEPTH_TYPE getTaskStackHighWatermark(); + static configSTACK_DEPTH_TYPE getTaskStackHighWatermark( + TaskHandle_t task = nullptr); }; #endif /* FRAMEWORK_OSAL_FREERTOS_TASKMANAGEMENT_H_ */ From 444ee80f356a8e6b8e639c1cb847da320a21713b Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Fri, 10 Jul 2020 20:31:10 +0200 Subject: [PATCH 276/307] removed unnecessary case and added more size checks --- pus/Service2DeviceAccess.cpp | 6 ++---- tmtcservices/PusParser.cpp | 29 ++++++++++++++--------------- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/pus/Service2DeviceAccess.cpp b/pus/Service2DeviceAccess.cpp index 1d5f21eb..84d6693d 100644 --- a/pus/Service2DeviceAccess.cpp +++ b/pus/Service2DeviceAccess.cpp @@ -60,13 +60,11 @@ ReturnValue_t Service2DeviceAccess::prepareCommand(CommandMessage* message, uint32_t* state, object_id_t objectId) { switch(static_cast(subservice)){ case Subservice::RAW_COMMANDING: { - return prepareRawCommand(dynamic_cast(message), - tcData, tcDataLen); + return prepareRawCommand(message, tcData, tcDataLen); } break; case Subservice::TOGGLE_WIRETAPPING: { - return prepareWiretappingCommand(dynamic_cast(message), - tcData, tcDataLen); + return prepareWiretappingCommand(message, tcData, tcDataLen); } break; default: diff --git a/tmtcservices/PusParser.cpp b/tmtcservices/PusParser.cpp index 4198e36e..3dd34a84 100644 --- a/tmtcservices/PusParser.cpp +++ b/tmtcservices/PusParser.cpp @@ -7,9 +7,8 @@ PusParser::PusParser(uint16_t maxExpectedPusPackets, ReturnValue_t PusParser::parsePusPackets(const uint8_t *frame, size_t frameSize) { - if(frame == nullptr) { - sif::error << "PusParser::parsePusPackets: Frame pointers in invalid!" - << std::endl; + if(frame == nullptr or frameSize < 5) { + sif::error << "PusParser::parsePusPackets: Frame invalid!" << std::endl; return HasReturnvaluesIF::RETURN_FAILED; } @@ -25,15 +24,13 @@ ReturnValue_t PusParser::parsePusPackets(const uint8_t *frame, } size_t packetSize = lengthField + 7; + // sif::debug << frameSize << std::endl; // Size of a pus packet is the value in the packet length field plus 7. - if(packetSize > frameSize) - { - if(storeSplitPackets) - { + if(packetSize > frameSize) { + if(storeSplitPackets) { indexSizePairFIFO.insert(indexSizePair(0, frameSize)); } - else - { + else { sif::debug << "TcSerialPollingTask::readNextPacket: Next packet " "larger than remaining frame," << std::endl; sif::debug << "Throwing away packet. Detected packet size: " @@ -41,8 +38,7 @@ ReturnValue_t PusParser::parsePusPackets(const uint8_t *frame, } return SPLIT_PACKET; } - else - { + else { indexSizePairFIFO.insert(indexSizePair(0, packetSize)); if(packetSize == frameSize) { return HasReturnvaluesIF::RETURN_OK; @@ -77,6 +73,11 @@ PusParser::indexSizePair PusParser::getNextFifoPair() { ReturnValue_t PusParser::readNextPacket(const uint8_t *frame, size_t frameSize, size_t& currentIndex) { // sif::debug << startIndex << std::endl; + if(currentIndex + 5 > frameSize) { + currentIndex = frameSize; + return HasReturnvaluesIF::RETURN_OK; + } + uint16_t lengthField = frame[currentIndex + 4] << 8 | frame[currentIndex + 5]; if(lengthField == 0) { @@ -88,12 +89,10 @@ ReturnValue_t PusParser::readNextPacket(const uint8_t *frame, size_t remainingSize = frameSize - currentIndex; if(nextPacketSize > remainingSize) { - if(storeSplitPackets) - { + if(storeSplitPackets) { indexSizePairFIFO.insert(indexSizePair(currentIndex, remainingSize)); } - else - { + else { sif::debug << "TcSerialPollingTask::readNextPacket: Next packet " "larger than remaining frame," << std::endl; sif::debug << "Throwing away packet. Detected packet size: " From 6a6395313f8dce6ec9693acddb6b93d3cda9549a Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 11 Jul 2020 01:06:01 +0200 Subject: [PATCH 277/307] added copy ctor and assignment for FIFObase --- container/DynamicFIFO.h | 2 +- container/FIFOBase.h | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/container/DynamicFIFO.h b/container/DynamicFIFO.h index 3a5242c7..fca4c8e8 100644 --- a/container/DynamicFIFO.h +++ b/container/DynamicFIFO.h @@ -18,7 +18,7 @@ template class DynamicFIFO: public FIFOBase { public: DynamicFIFO(size_t maxCapacity): FIFOBase(values.data(), maxCapacity), - values(maxCapacity) {}; + values(maxCapacity) {}; private: std::vector values; diff --git a/container/FIFOBase.h b/container/FIFOBase.h index 8bdb333f..082c596a 100644 --- a/container/FIFOBase.h +++ b/container/FIFOBase.h @@ -3,6 +3,7 @@ #include #include +#include template class FIFOBase { @@ -43,6 +44,23 @@ public: bool full(); size_t size(); + FIFOBase(const FIFOBase& other): readIndex(other.readIndex), + writeIndex(other.writeIndex), currentSize(other.currentSize), + maxCapacity(other.maxCapacity) { + std::memcpy(values, other.values, sizeof(T) * currentSize); + } + + FIFOBase& operator=(const FIFOBase& other) { + if(&other == this) + return *this; + maxCapacity = other.maxCapacity; + readIndex = other.readIndex; + writeIndex = other.writeIndex; + currentSize = other.currentSize; + std::memcpy(values, other.values, sizeof(T) * currentSize); + return *this; + } + size_t getMaxCapacity() const; private: From 35d4267b400a950847447d2adc24e53096e4ef86 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 11 Jul 2020 02:36:04 +0200 Subject: [PATCH 278/307] dynamic fifo bug fixed --- container/DynamicFIFO.h | 21 ++++++++++++++++++--- container/FIFO.h | 12 ++++++++++-- container/FIFOBase.h | 22 ++++------------------ container/FIFOBase.tpp | 8 +++++++- tmtcservices/PusParser.h | 9 +++++---- 5 files changed, 44 insertions(+), 28 deletions(-) diff --git a/container/DynamicFIFO.h b/container/DynamicFIFO.h index fca4c8e8..59adfb3a 100644 --- a/container/DynamicFIFO.h +++ b/container/DynamicFIFO.h @@ -17,11 +17,26 @@ template class DynamicFIFO: public FIFOBase { public: - DynamicFIFO(size_t maxCapacity): FIFOBase(values.data(), maxCapacity), - values(maxCapacity) {}; + DynamicFIFO(size_t maxCapacity): FIFOBase(nullptr, maxCapacity), + fifoVector(maxCapacity) { + // trying to pass the pointer of the uninitialized vector + // to the FIFOBase constructor directly lead to a super evil bug. + // So we do it like this now. + this->setData(fifoVector.data()); + }; + + /** + * @brief Custom copy constructor which prevents setting the + * underlying pointer wrong. + */ + DynamicFIFO(const DynamicFIFO& other): FIFOBase(other), + fifoVector(other.maxCapacity) { + this->setData(fifoVector.data()); + } + private: - std::vector values; + std::vector fifoVector; }; #endif /* FRAMEWORK_CONTAINER_DYNAMICFIFO_H_ */ diff --git a/container/FIFO.h b/container/FIFO.h index ecb218fd..2e332dc2 100644 --- a/container/FIFO.h +++ b/container/FIFO.h @@ -17,10 +17,18 @@ template class FIFO: public FIFOBase { public: - FIFO(): FIFOBase(values.data(), capacity) {}; + FIFO(): FIFOBase(fifoArray.data(), capacity) {}; + + /** + * @brief Custom copy constructor to set pointer correctly. + * @param other + */ + FIFO(const FIFO& other): FIFOBase(other) { + this->setData(fifoArray.data()); + } private: - std::array values; + std::array fifoArray; }; #endif /* FRAMEWORK_CONTAINERS_STATICFIFO_H_ */ diff --git a/container/FIFOBase.h b/container/FIFOBase.h index 082c596a..7f8bde96 100644 --- a/container/FIFOBase.h +++ b/container/FIFOBase.h @@ -44,29 +44,15 @@ public: bool full(); size_t size(); - FIFOBase(const FIFOBase& other): readIndex(other.readIndex), - writeIndex(other.writeIndex), currentSize(other.currentSize), - maxCapacity(other.maxCapacity) { - std::memcpy(values, other.values, sizeof(T) * currentSize); - } - - FIFOBase& operator=(const FIFOBase& other) { - if(&other == this) - return *this; - maxCapacity = other.maxCapacity; - readIndex = other.readIndex; - writeIndex = other.writeIndex; - currentSize = other.currentSize; - std::memcpy(values, other.values, sizeof(T) * currentSize); - return *this; - } size_t getMaxCapacity() const; -private: - T* values; +protected: + void setData(T* data); size_t maxCapacity = 0; + T* values; + size_t readIndex = 0; size_t writeIndex = 0; size_t currentSize = 0; diff --git a/container/FIFOBase.tpp b/container/FIFOBase.tpp index 48a060ff..c73e9d59 100644 --- a/container/FIFOBase.tpp +++ b/container/FIFOBase.tpp @@ -7,7 +7,7 @@ template inline FIFOBase::FIFOBase(T* values, const size_t maxCapacity): - values(values), maxCapacity(maxCapacity) {}; + maxCapacity(maxCapacity), values(values){}; template inline ReturnValue_t FIFOBase::insert(T value) { @@ -78,4 +78,10 @@ inline size_t FIFOBase::getMaxCapacity() const { return maxCapacity; } + +template +inline void FIFOBase::setData(T *data) { + this->values = data; +} + #endif diff --git a/tmtcservices/PusParser.h b/tmtcservices/PusParser.h index 88570bb2..d59673f6 100644 --- a/tmtcservices/PusParser.h +++ b/tmtcservices/PusParser.h @@ -63,11 +63,12 @@ public: * @return */ indexSizePair getNextFifoPair(); -private: - //! A FIFO is used to store information about multiple PUS packets - //! inside the receive buffer. The maximum number of entries is defined - //! by the first constructor argument. +private: + /** A FIFO is used to store information about multiple PUS packets + * inside the receive buffer. The maximum number of entries is defined + * by the first constructor argument. + */ DynamicFIFO indexSizePairFIFO; bool storeSplitPackets = false; From 69946d5276549dce7624540df1de75c94ffc5004 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 11 Jul 2020 11:52:01 +0200 Subject: [PATCH 279/307] FIFO hotfix --- container/DynamicFIFO.h | 21 ++++++++++++++++++--- container/FIFO.h | 12 ++++++++++-- container/FIFOBase.h | 8 ++++++-- container/FIFOBase.tpp | 8 +++++++- 4 files changed, 41 insertions(+), 8 deletions(-) diff --git a/container/DynamicFIFO.h b/container/DynamicFIFO.h index 3a5242c7..59adfb3a 100644 --- a/container/DynamicFIFO.h +++ b/container/DynamicFIFO.h @@ -17,11 +17,26 @@ template class DynamicFIFO: public FIFOBase { public: - DynamicFIFO(size_t maxCapacity): FIFOBase(values.data(), maxCapacity), - values(maxCapacity) {}; + DynamicFIFO(size_t maxCapacity): FIFOBase(nullptr, maxCapacity), + fifoVector(maxCapacity) { + // trying to pass the pointer of the uninitialized vector + // to the FIFOBase constructor directly lead to a super evil bug. + // So we do it like this now. + this->setData(fifoVector.data()); + }; + + /** + * @brief Custom copy constructor which prevents setting the + * underlying pointer wrong. + */ + DynamicFIFO(const DynamicFIFO& other): FIFOBase(other), + fifoVector(other.maxCapacity) { + this->setData(fifoVector.data()); + } + private: - std::vector values; + std::vector fifoVector; }; #endif /* FRAMEWORK_CONTAINER_DYNAMICFIFO_H_ */ diff --git a/container/FIFO.h b/container/FIFO.h index ecb218fd..2e332dc2 100644 --- a/container/FIFO.h +++ b/container/FIFO.h @@ -17,10 +17,18 @@ template class FIFO: public FIFOBase { public: - FIFO(): FIFOBase(values.data(), capacity) {}; + FIFO(): FIFOBase(fifoArray.data(), capacity) {}; + + /** + * @brief Custom copy constructor to set pointer correctly. + * @param other + */ + FIFO(const FIFO& other): FIFOBase(other) { + this->setData(fifoArray.data()); + } private: - std::array values; + std::array fifoArray; }; #endif /* FRAMEWORK_CONTAINERS_STATICFIFO_H_ */ diff --git a/container/FIFOBase.h b/container/FIFOBase.h index 8bdb333f..7f8bde96 100644 --- a/container/FIFOBase.h +++ b/container/FIFOBase.h @@ -3,6 +3,7 @@ #include #include +#include template class FIFOBase { @@ -43,12 +44,15 @@ public: bool full(); size_t size(); + size_t getMaxCapacity() const; -private: - T* values; +protected: + void setData(T* data); size_t maxCapacity = 0; + T* values; + size_t readIndex = 0; size_t writeIndex = 0; size_t currentSize = 0; diff --git a/container/FIFOBase.tpp b/container/FIFOBase.tpp index 48a060ff..c73e9d59 100644 --- a/container/FIFOBase.tpp +++ b/container/FIFOBase.tpp @@ -7,7 +7,7 @@ template inline FIFOBase::FIFOBase(T* values, const size_t maxCapacity): - values(values), maxCapacity(maxCapacity) {}; + maxCapacity(maxCapacity), values(values){}; template inline ReturnValue_t FIFOBase::insert(T value) { @@ -78,4 +78,10 @@ inline size_t FIFOBase::getMaxCapacity() const { return maxCapacity; } + +template +inline void FIFOBase::setData(T *data) { + this->values = data; +} + #endif From e4f795d209f36bbfaa39a1d03e46c759d4a86acd Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 11 Jul 2020 13:38:14 +0200 Subject: [PATCH 280/307] stack high watermark in bytes now --- osal/FreeRTOS/TaskManagement.cpp | 4 ++-- osal/FreeRTOS/TaskManagement.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osal/FreeRTOS/TaskManagement.cpp b/osal/FreeRTOS/TaskManagement.cpp index 9a1e4447..704f9d34 100644 --- a/osal/FreeRTOS/TaskManagement.cpp +++ b/osal/FreeRTOS/TaskManagement.cpp @@ -18,7 +18,7 @@ TaskHandle_t TaskManagement::getCurrentTaskHandle() { return xTaskGetCurrentTaskHandle(); } -configSTACK_DEPTH_TYPE TaskManagement::getTaskStackHighWatermark( +size_t TaskManagement::getTaskStackHighWatermark( TaskHandle_t task) { - return uxTaskGetStackHighWaterMark(task); + return uxTaskGetStackHighWaterMark(task) * sizeof(StackType_t); } diff --git a/osal/FreeRTOS/TaskManagement.h b/osal/FreeRTOS/TaskManagement.h index cbde510c..ea363359 100644 --- a/osal/FreeRTOS/TaskManagement.h +++ b/osal/FreeRTOS/TaskManagement.h @@ -57,7 +57,7 @@ public: * @return Smallest value of stack remaining since the task was started in * words. */ - static configSTACK_DEPTH_TYPE getTaskStackHighWatermark( + static size_t getTaskStackHighWatermark( TaskHandle_t task = nullptr); }; From 799846d89fecc4c17dc6305d17b903217b0687ba Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 11 Jul 2020 14:29:30 +0200 Subject: [PATCH 281/307] little formatting changes --- action/HasActionsIF.h | 2 +- events/Event.h | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/action/HasActionsIF.h b/action/HasActionsIF.h index 9c2a9c01..008d9eaf 100644 --- a/action/HasActionsIF.h +++ b/action/HasActionsIF.h @@ -35,7 +35,7 @@ class HasActionsIF { public: static const uint8_t INTERFACE_ID = CLASS_ID::HAS_ACTIONS_IF; - static const ReturnValue_t IS_BUSY = MAKE_RETURN_CODE(1);//!< + static const ReturnValue_t IS_BUSY = MAKE_RETURN_CODE(1); static const ReturnValue_t INVALID_PARAMETERS = MAKE_RETURN_CODE(2); static const ReturnValue_t EXECUTION_FINISHED = MAKE_RETURN_CODE(3); static const ReturnValue_t INVALID_ACTION_ID = MAKE_RETURN_CODE(4); diff --git a/events/Event.h b/events/Event.h index 96800f34..0a1cfcf2 100644 --- a/events/Event.h +++ b/events/Event.h @@ -1,10 +1,10 @@ -#ifndef EVENTOBJECT_EVENT_H_ -#define EVENTOBJECT_EVENT_H_ +#ifndef FRAMEWORK_EVENTS_EVENT_H_ +#define FRAMEWORK_EVENTS_EVENT_H_ -#include +#include #include //could be move to more suitable location -#include +#include typedef uint16_t EventId_t; typedef uint8_t EventSeverity_t; @@ -21,6 +21,7 @@ EventSeverity_t getSeverity(Event event); Event makeEvent(EventId_t eventId, EventSeverity_t eventSeverity); } + namespace SEVERITY { static const EventSeverity_t INFO = 1; static const EventSeverity_t LOW = 2; @@ -41,4 +42,4 @@ namespace SEVERITY { // static const EventSeverity_t HIGH = 4; //}; -#endif /* EVENTOBJECT_EVENT_H_ */ +#endif /* FRAMEWORK_EVENTS_EVENT_H_ */ From 7d794c76235c8247602b6327034f604d962b71c5 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 11 Jul 2020 18:24:09 +0200 Subject: [PATCH 282/307] task management functions have freertos syntax now --- osal/FreeRTOS/TaskManagement.cpp | 6 +++--- osal/FreeRTOS/TaskManagement.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/osal/FreeRTOS/TaskManagement.cpp b/osal/FreeRTOS/TaskManagement.cpp index 704f9d34..ff552adb 100644 --- a/osal/FreeRTOS/TaskManagement.cpp +++ b/osal/FreeRTOS/TaskManagement.cpp @@ -1,6 +1,6 @@ #include -void TaskManagement::requestContextSwitchFromTask() { +void TaskManagement::vRequestContextSwitchFromTask() { vTaskDelay(0); } @@ -8,9 +8,9 @@ void TaskManagement::requestContextSwitch( CallContext callContext = CallContext::TASK) { if(callContext == CallContext::ISR) { // This function depends on the partmacro.h definition for the specific device - requestContextSwitchFromISR(); + vRequestContextSwitchFromISR(); } else { - requestContextSwitchFromTask(); + vRequestContextSwitchFromTask(); } } diff --git a/osal/FreeRTOS/TaskManagement.h b/osal/FreeRTOS/TaskManagement.h index ea363359..0ae8a6e9 100644 --- a/osal/FreeRTOS/TaskManagement.h +++ b/osal/FreeRTOS/TaskManagement.h @@ -13,7 +13,7 @@ extern "C" { * Architecture dependant portmacro.h function call. * Should be implemented in bsp. */ -extern "C" void requestContextSwitchFromISR(); +extern "C" void vRequestContextSwitchFromISR(); /*! * Used by functions to tell if they are being called from @@ -41,7 +41,7 @@ public: * If task preemption in FreeRTOS is disabled, a context switch * can be requested manually by calling this function. */ - static void requestContextSwitchFromTask(void); + static void vRequestContextSwitchFromTask(void); /** * @return The current task handle From 99aef0cf287fcdf23f9336927c171762e8bf4f7c Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 12 Jul 2020 01:16:32 +0200 Subject: [PATCH 283/307] C++ linkage for yield from ISR function --- osal/FreeRTOS/TaskManagement.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osal/FreeRTOS/TaskManagement.h b/osal/FreeRTOS/TaskManagement.h index 0ae8a6e9..62c68331 100644 --- a/osal/FreeRTOS/TaskManagement.h +++ b/osal/FreeRTOS/TaskManagement.h @@ -13,7 +13,7 @@ extern "C" { * Architecture dependant portmacro.h function call. * Should be implemented in bsp. */ -extern "C" void vRequestContextSwitchFromISR(); +extern void vRequestContextSwitchFromISR(); /*! * Used by functions to tell if they are being called from From b4f292f3d7fc4f606bf1b6d48618bd0cf1878e26 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 12 Jul 2020 18:01:09 +0200 Subject: [PATCH 284/307] new generic freertos task interface --- osal/FreeRTOS/FixedTimeslotTask.cpp | 2 +- osal/FreeRTOS/FixedTimeslotTask.h | 5 +++-- osal/FreeRTOS/FreeRTOSTaskIF.h | 13 +++++++++++++ osal/FreeRTOS/PeriodicTask.cpp | 2 +- osal/FreeRTOS/PeriodicTask.h | 6 ++++-- returnvalues/HasReturnvaluesIF.h | 10 +++++++++- 6 files changed, 31 insertions(+), 7 deletions(-) create mode 100644 osal/FreeRTOS/FreeRTOSTaskIF.h diff --git a/osal/FreeRTOS/FixedTimeslotTask.cpp b/osal/FreeRTOS/FixedTimeslotTask.cpp index 3bd2aafb..630952d2 100644 --- a/osal/FreeRTOS/FixedTimeslotTask.cpp +++ b/osal/FreeRTOS/FixedTimeslotTask.cpp @@ -157,6 +157,6 @@ ReturnValue_t FixedTimeslotTask::sleepFor(uint32_t ms) { return HasReturnvaluesIF::RETURN_OK; } -TaskHandle_t FixedTimeslotTask::getTaskHandle() const { +TaskHandle_t FixedTimeslotTask::getTaskHandle() { return handle; } diff --git a/osal/FreeRTOS/FixedTimeslotTask.h b/osal/FreeRTOS/FixedTimeslotTask.h index 985b4f90..b63cb775 100644 --- a/osal/FreeRTOS/FixedTimeslotTask.h +++ b/osal/FreeRTOS/FixedTimeslotTask.h @@ -1,6 +1,7 @@ #ifndef FRAMEWORK_OSAL_FREERTOS_FIXEDTIMESLOTTASK_H_ #define FRAMEWORK_OSAL_FREERTOS_FIXEDTIMESLOTTASK_H_ +#include #include #include #include @@ -8,7 +9,7 @@ #include #include -class FixedTimeslotTask: public FixedTimeslotTaskIF { +class FixedTimeslotTask: public FixedTimeslotTaskIF, public FreeRTOSTaskIF { public: /** @@ -57,7 +58,7 @@ public: ReturnValue_t sleepFor(uint32_t ms) override; - TaskHandle_t getTaskHandle() const; + TaskHandle_t getTaskHandle() override; protected: bool started; diff --git a/osal/FreeRTOS/FreeRTOSTaskIF.h b/osal/FreeRTOS/FreeRTOSTaskIF.h new file mode 100644 index 00000000..06fda282 --- /dev/null +++ b/osal/FreeRTOS/FreeRTOSTaskIF.h @@ -0,0 +1,13 @@ +#ifndef FRAMEWORK_OSAL_FREERTOS_FREERTOSTASKIF_H_ +#define FRAMEWORK_OSAL_FREERTOS_FREERTOSTASKIF_H_ + +#include +#include + +class FreeRTOSTaskIF { +public: + virtual~ FreeRTOSTaskIF() {} + virtual TaskHandle_t getTaskHandle() = 0; +}; + +#endif /* FRAMEWORK_OSAL_FREERTOS_FREERTOSTASKIF_H_ */ diff --git a/osal/FreeRTOS/PeriodicTask.cpp b/osal/FreeRTOS/PeriodicTask.cpp index 6d013a5b..f960d8bb 100644 --- a/osal/FreeRTOS/PeriodicTask.cpp +++ b/osal/FreeRTOS/PeriodicTask.cpp @@ -126,7 +126,7 @@ void PeriodicTask::checkMissedDeadline(const TickType_t xLastWakeTime, } } -TaskHandle_t PeriodicTask::getTaskHandle() const { +TaskHandle_t PeriodicTask::getTaskHandle() { return handle; } diff --git a/osal/FreeRTOS/PeriodicTask.h b/osal/FreeRTOS/PeriodicTask.h index 679686f6..ca2c5324 100644 --- a/osal/FreeRTOS/PeriodicTask.h +++ b/osal/FreeRTOS/PeriodicTask.h @@ -1,10 +1,12 @@ #ifndef FRAMEWORK_OSAL_FREERTOS_PERIODICTASK_H_ #define FRAMEWORK_OSAL_FREERTOS_PERIODICTASK_H_ +#include #include #include #include + #include #include @@ -17,7 +19,7 @@ class ExecutableObjectIF; * periodic activities of multiple objects. * @ingroup task_handling */ -class PeriodicTask: public PeriodicTaskIF { +class PeriodicTask: public PeriodicTaskIF, public FreeRTOSTaskIF { public: /** * Keep in Mind that you need to call before this vTaskStartScheduler()! @@ -70,7 +72,7 @@ public: ReturnValue_t sleepFor(uint32_t ms) override; - TaskHandle_t getTaskHandle() const; + TaskHandle_t getTaskHandle() override; protected: bool started; TaskHandle_t handle; diff --git a/returnvalues/HasReturnvaluesIF.h b/returnvalues/HasReturnvaluesIF.h index d231f4ee..9b9086d9 100644 --- a/returnvalues/HasReturnvaluesIF.h +++ b/returnvalues/HasReturnvaluesIF.h @@ -15,7 +15,15 @@ public: static const ReturnValue_t RETURN_FAILED = 1; virtual ~HasReturnvaluesIF() {} - static ReturnValue_t makeReturnCode(uint8_t interfaceId, uint8_t number) { + /** + * It is discouraged to use the input parameters 0,0 and 0,1 as this + * will generate the RETURN_OK and RETURN_FAILED returnvalues. + * @param interfaceId + * @param number + * @return + */ + static constexpr ReturnValue_t makeReturnCode(uint8_t interfaceId, + uint8_t number) { return (interfaceId << 8) + number; } }; From 6d99ab3df3e105901cf6af955a034968b7f8364d Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 13 Jul 2020 19:37:33 +0200 Subject: [PATCH 285/307] ncreased readability of DHB function --- devicehandlers/DeviceHandlerBase.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index af98ba44..cc97cd42 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -1264,18 +1264,23 @@ void DeviceHandlerBase::buildInternalCommand(void) { if (mode == MODE_NORMAL) { result = buildNormalDeviceCommand(&deviceCommandId); if (result == BUSY) { + //so we can track misconfigurations sif::debug << std::hex << getObjectId() - << ": DHB::buildInternalCommand busy" << std::endl; //so we can track misconfigurations + << ": DHB::buildInternalCommand: Busy" << std::endl; result = NOTHING_TO_SEND; //no need to report this } - } else if (mode == MODE_RAW) { + } + else if (mode == MODE_RAW) { result = buildChildRawCommand(); deviceCommandId = RAW_COMMAND_ID; - } else if (mode & TRANSITION_MODE_CHILD_ACTION_MASK) { + } + else if (mode & TRANSITION_MODE_CHILD_ACTION_MASK) { result = buildTransitionDeviceCommand(&deviceCommandId); - } else { + } + else { return; } + if (result == NOTHING_TO_SEND) { return; } From 15052cb33304f18d3e5ce95a4b547a2ff0826c99 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 13 Jul 2020 19:54:38 +0200 Subject: [PATCH 286/307] singly linked list update --- container/SinglyLinkedList.h | 61 ++++++++++++++++++++++++------------ 1 file changed, 41 insertions(+), 20 deletions(-) diff --git a/container/SinglyLinkedList.h b/container/SinglyLinkedList.h index 85a92e6a..7d5fc4a9 100644 --- a/container/SinglyLinkedList.h +++ b/container/SinglyLinkedList.h @@ -16,13 +16,8 @@ public: class Iterator { public: LinkedElement *value = nullptr; - //! Creates an uninitialized iterator which points to nullptr. Iterator() {} - /** - * Initialize iterator at specified linked element. - * @param element - */ Iterator(LinkedElement *element) : value(element) { } @@ -77,11 +72,6 @@ private: LinkedElement *next; }; -/** - * @brief SinglyLinkedList data structure which keeps a pointer to its - * first element to perform all operations. - * @tparam T - */ template class SinglyLinkedList { public: @@ -99,12 +89,21 @@ public: return ElementIterator::Iterator(start); } + /** Returns iterator to nulltr */ ElementIterator end() const { - LinkedElement *element = start; - while (element != nullptr) { - element = element->getNext(); - } - return ElementIterator::Iterator(element); + return ElementIterator::Iterator(); + } + + /** + * Returns last element in singly linked list. + * @return + */ + ElementIterator back() const { + LinkedElement *element = start; + while (element != nullptr) { + element = element->getNext(); + } + return ElementIterator::Iterator(element); } size_t getSize() const { @@ -116,15 +115,37 @@ public: } return size; } - void setStart(LinkedElement* setStart) { - start = setStart; + void setStart(LinkedElement* firstElement) { + start = firstElement; } - void setEnd(LinkedElement* setEnd) { - setEnd->setEnd(); + void setNext(LinkedElement* currentElement, + LinkedElement* nextElement) { + currentElement->setNext(nextElement); + } + + void setLast(LinkedElement* lastElement) { + lastElement->setEnd(); } - // SHOULDDO: Insertion operation ? + void insertElement(LinkedElement* element, size_t position) { + LinkedElement *currentElement = start; + for(size_t count = 0; count < position; count++) { + if(currentElement == nullptr) { + return; + } + currentElement = currentElement->getNext(); + } + LinkedElement* elementAfterCurrent = currentElement->next; + currentElement->setNext(element); + if(elementAfterCurrent != nullptr) { + element->setNext(elementAfterCurrent); + } + } + + void insertBack(LinkedElement* lastElement) { + back().value->setNext(lastElement); + } protected: LinkedElement *start = nullptr; From e7b6999c5ea11e776848cb63a11f1e9673af0efa Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Mon, 13 Jul 2020 22:13:19 +0200 Subject: [PATCH 287/307] added back inttypes.h for cleaner code --- timemanager/CCSDSTime.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/timemanager/CCSDSTime.cpp b/timemanager/CCSDSTime.cpp index 47cab911..71b2539d 100644 --- a/timemanager/CCSDSTime.cpp +++ b/timemanager/CCSDSTime.cpp @@ -205,9 +205,10 @@ ReturnValue_t CCSDSTime::convertFromASCII(Clock::TimeOfDay_t* to, const uint8_t* uint8_t hour; uint8_t minute; float second; - //try Code A (yyyy-mm-dd) - int count = sscanf((char *) from, "%4hi-%2hhi-%2hiT%2hhi:%2hhi:%fZ", &year, - &month, &day, &hour, &minute, &second); + //try Code A (yyyy-mm-dd) + int count = sscanf((char *) from, "%4" SCNu16 "-%2" SCNu8 "-%2" SCNu16 + "T%2" SCNu8 ":%2" SCNu8 ":%fZ", &year, &month, &day, + &hour, &minute, &second); if (count == 6) { to->year = year; to->month = month; @@ -219,9 +220,9 @@ ReturnValue_t CCSDSTime::convertFromASCII(Clock::TimeOfDay_t* to, const uint8_t* return RETURN_OK; } - //try Code B (yyyy-ddd) - count = sscanf((char *) from, "%4hi-%3hiT%2hhi:%2hhi:%fZ", &year, &day, - &hour, &minute, &second); + //try Code B (yyyy-ddd) + count = sscanf((char *) from, "%4" SCNu16 "-%3" SCNu16 "T%2" SCNu8 + ":%2" SCNu8 ":%fZ", &year, &day, &hour, &minute, &second); if (count == 5) { uint8_t tempDay; ReturnValue_t result = CCSDSTime::convertDaysOfYear(day, year, &month, From 47b3a428c68ff74a6019eb2c36c9fb253cc427fd Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 16 Jul 2020 12:33:03 +0200 Subject: [PATCH 288/307] removed device switch, not necessary anymore --- devicehandlers/ChildHandlerBase.cpp | 5 ++--- devicehandlers/ChildHandlerBase.h | 6 +++--- devicehandlers/DeviceHandlerBase.cpp | 4 ---- devicehandlers/DeviceHandlerBase.h | 8 -------- 4 files changed, 5 insertions(+), 18 deletions(-) diff --git a/devicehandlers/ChildHandlerBase.cpp b/devicehandlers/ChildHandlerBase.cpp index 9e5019b4..bdc5fa65 100644 --- a/devicehandlers/ChildHandlerBase.cpp +++ b/devicehandlers/ChildHandlerBase.cpp @@ -4,15 +4,14 @@ ChildHandlerBase::ChildHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication, CookieIF * cookie, - uint8_t setDeviceSwitch, object_id_t hkDestination, - uint32_t thermalStatePoolId, uint32_t thermalRequestPoolId, + object_id_t hkDestination, uint32_t thermalStatePoolId, + uint32_t thermalRequestPoolId, object_id_t parent, FailureIsolationBase* customFdir, size_t cmdQueueSize) : DeviceHandlerBase(setObjectId, deviceCommunication, cookie, (customFdir == nullptr? &childHandlerFdir : customFdir), cmdQueueSize), parentId(parent), childHandlerFdir(setObjectId) { - this->setDeviceSwitch(setDeviceSwitch); this->setHkDestination(hkDestination); this->setThermalStateRequestPoolIds(thermalStatePoolId, thermalRequestPoolId); diff --git a/devicehandlers/ChildHandlerBase.h b/devicehandlers/ChildHandlerBase.h index 5c216e86..c8ac9541 100644 --- a/devicehandlers/ChildHandlerBase.h +++ b/devicehandlers/ChildHandlerBase.h @@ -7,9 +7,9 @@ class ChildHandlerBase: public DeviceHandlerBase { public: ChildHandlerBase(object_id_t setObjectId, object_id_t deviceCommunication, - CookieIF * cookie, uint8_t setDeviceSwitch, - object_id_t hkDestination, uint32_t thermalStatePoolId, - uint32_t thermalRequestPoolId, object_id_t parent = objects::NO_OBJECT, + CookieIF * cookie, object_id_t hkDestination, + uint32_t thermalStatePoolId, uint32_t thermalRequestPoolId, + object_id_t parent = objects::NO_OBJECT, FailureIsolationBase* customFdir = nullptr, size_t cmdQueueSize = 20); virtual ~ChildHandlerBase(); diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index cc97cd42..c13611b3 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -63,10 +63,6 @@ void DeviceHandlerBase::setThermalStateRequestPoolIds( } -void DeviceHandlerBase::setDeviceSwitch(uint8_t deviceSwitch) { - this->deviceSwitch = deviceSwitch; -} - DeviceHandlerBase::~DeviceHandlerBase() { delete comCookie; if (defaultFDIRUsed) { diff --git a/devicehandlers/DeviceHandlerBase.h b/devicehandlers/DeviceHandlerBase.h index 61fb701d..034653dc 100644 --- a/devicehandlers/DeviceHandlerBase.h +++ b/devicehandlers/DeviceHandlerBase.h @@ -108,7 +108,6 @@ public: CookieIF * comCookie, FailureIsolationBase* fdirInstance = nullptr, size_t cmdQueueSize = 20); - void setDeviceSwitch(uint8_t deviceSwitch); void setHkDestination(object_id_t hkDestination); void setThermalStateRequestPoolIds(uint32_t thermalStatePoolId, uint32_t thermalRequestPoolId); @@ -1079,13 +1078,6 @@ private: */ Submode_t transitionSourceSubMode; - /** - * the switch of the device - * - * for devices using two switches override getSwitches() - */ - uint8_t deviceSwitch; - /** * read the command queue */ From aaafed7b28bc7110321f0a092a81beb8002990bb Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 16 Jul 2020 12:38:21 +0200 Subject: [PATCH 289/307] health table init now mandatory, better diagnostic output for uninit health table or invalid health helper owner --- devicehandlers/DeviceHandlerBase.cpp | 39 +++++++--------------------- devicehandlers/DeviceHandlerBase.h | 1 - health/HealthHelper.cpp | 15 ++++++++--- 3 files changed, 21 insertions(+), 34 deletions(-) diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index c13611b3..b4ad0fda 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -164,12 +164,8 @@ ReturnValue_t DeviceHandlerBase::initialize() { } result = healthHelper.initialize(); - if (result == RETURN_OK) { - healthHelperActive = true; - } - else { - sif::warning << "DeviceHandlerBase::initialize: Health Helper " - "initialization failure." << std::endl; + if (result != RETURN_OK) { + return result; } result = modeHelper.initialize(); @@ -246,11 +242,9 @@ void DeviceHandlerBase::readCommandQueue() { return; } - if(healthHelperActive) { - result = healthHelper.handleHealthCommand(&command); - if (result == RETURN_OK) { - return; - } + result = healthHelper.handleHealthCommand(&command); + if (result == RETURN_OK) { + return; } result = modeHelper.handleModeCommand(&command); @@ -1028,9 +1022,7 @@ void DeviceHandlerBase::getMode(Mode_t* mode, Submode_t* submode) { } void DeviceHandlerBase::setToExternalControl() { - if(healthHelperActive) { - healthHelper.setHealth(EXTERNAL_CONTROL); - } + healthHelper.setHealth(EXTERNAL_CONTROL); } void DeviceHandlerBase::announceMode(bool recursive) { @@ -1050,25 +1042,12 @@ void DeviceHandlerBase::missedReply(DeviceCommandId_t id) { } HasHealthIF::HealthState DeviceHandlerBase::getHealth() { - if(healthHelperActive) { - return healthHelper.getHealth(); - } - else { - sif::warning << "DeviceHandlerBase::getHealth: Health helper not active" - << std::endl; - return HasHealthIF::HEALTHY; - } + return healthHelper.getHealth(); } ReturnValue_t DeviceHandlerBase::setHealth(HealthState health) { - if(healthHelperActive) { - healthHelper.setHealth(health); - } - else { - sif::warning << "DeviceHandlerBase::getHealth: Health helper not active" - << std::endl; - } - return HasReturnvaluesIF::RETURN_OK; + healthHelper.setHealth(health); + return HasReturnvaluesIF::RETURN_OK; } void DeviceHandlerBase::checkSwitchState() { diff --git a/devicehandlers/DeviceHandlerBase.h b/devicehandlers/DeviceHandlerBase.h index 034653dc..a2906368 100644 --- a/devicehandlers/DeviceHandlerBase.h +++ b/devicehandlers/DeviceHandlerBase.h @@ -609,7 +609,6 @@ protected: /** Health helper for HasHealthIF */ HealthHelper healthHelper; - bool healthHelperActive = false; /** Mode helper for HasModesIF */ ModeHelper modeHelper; /** Parameter helper for ReceivesParameterMessagesIF */ diff --git a/health/HealthHelper.cpp b/health/HealthHelper.cpp index e01e6fbb..a39305a3 100644 --- a/health/HealthHelper.cpp +++ b/health/HealthHelper.cpp @@ -39,10 +39,19 @@ void HealthHelper::setParentQeueue(MessageQueueId_t parentQueue) { ReturnValue_t HealthHelper::initialize() { healthTable = objectManager->get(objects::HEALTH_TABLE); eventSender = objectManager->get(objectId); - // TODO: Better returnvalues - if ((healthTable == NULL) || eventSender == NULL) { - return HasReturnvaluesIF::RETURN_FAILED; + + if (healthTable == nullptr) { + sif::error << "HealthHelper::initialize: Health table object needs" + "to be created in factory." << std::endl; + return ObjectManagerIF::CHILD_INIT_FAILED; } + + if(eventSender == nullptr) { + sif::error << "HealthHelper::initialize: Owner has to implement " + "ReportingProxyIF." << std::endl; + return ObjectManagerIF::CHILD_INIT_FAILED; + } + ReturnValue_t result = healthTable->registerObject(objectId, HasHealthIF::HEALTHY); if (result != HasReturnvaluesIF::RETURN_OK) { From b4d6d970bc9890c24b4abb3c671dad2104aac383 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Thu, 16 Jul 2020 12:41:05 +0200 Subject: [PATCH 290/307] removed HK manager virtual functions --- devicehandlers/DeviceHandlerBase.cpp | 12 ------------ devicehandlers/DeviceHandlerBase.h | 5 ----- 2 files changed, 17 deletions(-) diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index b4ad0fda..282f20b2 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -1366,18 +1366,6 @@ LocalDataPoolManager* DeviceHandlerBase::getHkManagerHandle() { return &hkManager; } -ReturnValue_t DeviceHandlerBase::addDataSet(sid_t sid) { - return HasReturnvaluesIF::RETURN_OK; -} - -ReturnValue_t DeviceHandlerBase::removeDataSet(sid_t sid) { - return HasReturnvaluesIF::RETURN_OK; -} - -ReturnValue_t DeviceHandlerBase::changeCollectionInterval(sid_t sid, - dur_seconds_t newInterval) { - return HasReturnvaluesIF::RETURN_OK; -} ReturnValue_t DeviceHandlerBase::initializeAfterTaskCreation() { // In this function, the task handle should be valid if the task diff --git a/devicehandlers/DeviceHandlerBase.h b/devicehandlers/DeviceHandlerBase.h index a2906368..ddbf6041 100644 --- a/devicehandlers/DeviceHandlerBase.h +++ b/devicehandlers/DeviceHandlerBase.h @@ -486,11 +486,6 @@ protected: /** Get the HK manager object handle */ virtual LocalDataPoolManager* getHkManagerHandle() override; - virtual ReturnValue_t addDataSet(sid_t sid) override; - virtual ReturnValue_t removeDataSet(sid_t sid) override; - virtual ReturnValue_t changeCollectionInterval(sid_t sid, - dur_seconds_t newInterval) override; - /** * @brief Hook function for child handlers which is called once per * performOperation(). Default implementation is empty. From e179288c00ffedf8e160b399db15a0ec26395ea2 Mon Sep 17 00:00:00 2001 From: Steffen Gaisser Date: Thu, 25 Jun 2020 18:09:32 +0200 Subject: [PATCH 291/307] Fixed spelling mistake in HealthHelper --- devicehandlers/ChildHandlerBase.cpp | 2 +- devicehandlers/DeviceHandlerBase.cpp | 2 +- devicehandlers/HealthDevice.cpp | 2 +- health/HealthHelper.cpp | 4 ++-- health/HealthHelper.h | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/devicehandlers/ChildHandlerBase.cpp b/devicehandlers/ChildHandlerBase.cpp index bdc5fa65..2e4428e5 100644 --- a/devicehandlers/ChildHandlerBase.cpp +++ b/devicehandlers/ChildHandlerBase.cpp @@ -39,7 +39,7 @@ ReturnValue_t ChildHandlerBase::initialize() { parent->registerChild(getObjectId()); } - healthHelper.setParentQeueue(parentQueue); + healthHelper.setParentQueue(parentQueue); modeHelper.setParentQueue(parentQueue); diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index 282f20b2..9f4c7baf 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -1134,7 +1134,7 @@ ReturnValue_t DeviceHandlerBase::handleDeviceHandlerMessage( void DeviceHandlerBase::setParentQueue(MessageQueueId_t parentQueueId) { modeHelper.setParentQueue(parentQueueId); - healthHelper.setParentQeueue(parentQueueId); + healthHelper.setParentQueue(parentQueueId); } bool DeviceHandlerBase::isAwaitingReply() { diff --git a/devicehandlers/HealthDevice.cpp b/devicehandlers/HealthDevice.cpp index 0bce34ec..8367a6bc 100644 --- a/devicehandlers/HealthDevice.cpp +++ b/devicehandlers/HealthDevice.cpp @@ -38,7 +38,7 @@ MessageQueueId_t HealthDevice::getCommandQueue() const { } void HealthDevice::setParentQueue(MessageQueueId_t parentQueue) { - healthHelper.setParentQeueue(parentQueue); + healthHelper.setParentQueue(parentQueue); } bool HealthDevice::hasHealthChanged() { diff --git a/health/HealthHelper.cpp b/health/HealthHelper.cpp index a39305a3..ba8504c2 100644 --- a/health/HealthHelper.cpp +++ b/health/HealthHelper.cpp @@ -28,11 +28,11 @@ HasHealthIF::HealthState HealthHelper::getHealth() { } ReturnValue_t HealthHelper::initialize(MessageQueueId_t parentQueue) { - setParentQeueue(parentQueue); + setParentQueue(parentQueue); return initialize(); } -void HealthHelper::setParentQeueue(MessageQueueId_t parentQueue) { +void HealthHelper::setParentQueue(MessageQueueId_t parentQueue) { this->parentQueue = parentQueue; } diff --git a/health/HealthHelper.h b/health/HealthHelper.h index a17a69f3..e112ad2c 100644 --- a/health/HealthHelper.h +++ b/health/HealthHelper.h @@ -79,7 +79,7 @@ public: /** * @param parentQueue the Queue id of the parent object. Set to 0 if no parent present */ - void setParentQeueue(MessageQueueId_t parentQueue); + void setParentQueue(MessageQueueId_t parentQueue); /** * From 6425c0dd4c43ba0fa0711d5d894ae76a1858782f Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sun, 26 Jul 2020 03:12:04 +0200 Subject: [PATCH 292/307] better init error output --- osal/FreeRTOS/Mutex.cpp | 2 +- osal/FreeRTOS/Mutex.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/osal/FreeRTOS/Mutex.cpp b/osal/FreeRTOS/Mutex.cpp index 6d90c3f6..8a5c444d 100644 --- a/osal/FreeRTOS/Mutex.cpp +++ b/osal/FreeRTOS/Mutex.cpp @@ -8,7 +8,7 @@ const uint32_t MutexIF::BLOCKING = portMAX_DELAY; Mutex::Mutex() { handle = xSemaphoreCreateMutex(); if(handle == nullptr) { - sif::error << "Mutex: Creation failure" << std::endl; + sif::error << "Mutex::Mutex(FreeRTOS): Creation failure" << std::endl; } } diff --git a/osal/FreeRTOS/Mutex.h b/osal/FreeRTOS/Mutex.h index d6e0aab9..37f1791c 100644 --- a/osal/FreeRTOS/Mutex.h +++ b/osal/FreeRTOS/Mutex.h @@ -20,6 +20,7 @@ public: ~Mutex(); ReturnValue_t lockMutex(uint32_t timeoutMs = MutexIF::BLOCKING) override; ReturnValue_t unlockMutex() override; + private: SemaphoreHandle_t handle; }; From afc16ef2d72dd6662ecb19c4a08a9aedc2119aab Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 28 Jul 2020 12:49:18 +0200 Subject: [PATCH 293/307] new servicei nterface buffer /stream --- serviceinterface/ServiceInterfaceBuffer.cpp | 12 ++++++------ serviceinterface/ServiceInterfaceBuffer.h | 2 +- serviceinterface/ServiceInterfaceStream.cpp | 2 +- serviceinterface/ServiceInterfaceStream.h | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/serviceinterface/ServiceInterfaceBuffer.cpp b/serviceinterface/ServiceInterfaceBuffer.cpp index 5c80862c..8c510eac 100644 --- a/serviceinterface/ServiceInterfaceBuffer.cpp +++ b/serviceinterface/ServiceInterfaceBuffer.cpp @@ -78,9 +78,9 @@ int ServiceInterfaceBuffer::sync(void) { } size_t preambleSize = 0; - auto preamble = getPreamble(&preambleSize); + std::string* preamble = getPreamble(&preambleSize); // Write logMessage and time - this->putChars(preamble.data(), preamble.data() + preambleSize); + this->putChars(preamble->data(), preamble->data() + preambleSize); // Handle output this->putChars(pbase(), pptr()); // This tells that buffer is empty again @@ -92,7 +92,7 @@ bool ServiceInterfaceBuffer::isBuffered() const { return buffered; } -std::string ServiceInterfaceBuffer::getPreamble(size_t * preambleSize) { +std::string* ServiceInterfaceBuffer::getPreamble(size_t * preambleSize) { Clock::TimeOfDay_t loggerTime; Clock::getDateAndTime(&loggerTime); size_t currentSize = 0; @@ -110,18 +110,18 @@ std::string ServiceInterfaceBuffer::getPreamble(size_t * preambleSize) { loggerTime.usecond /1000); if(charCount < 0) { printf("ServiceInterfaceBuffer: Failure parsing preamble\r\n"); - return ""; + return &preamble; } if(charCount > MAX_PREAMBLE_SIZE) { printf("ServiceInterfaceBuffer: Char count too large for maximum " "preamble size"); - return ""; + return &preamble; } currentSize += charCount; if(preambleSize != nullptr) { *preambleSize = currentSize; } - return preamble; + return &preamble; } diff --git a/serviceinterface/ServiceInterfaceBuffer.h b/serviceinterface/ServiceInterfaceBuffer.h index 39ea25c2..7a2ce2ee 100644 --- a/serviceinterface/ServiceInterfaceBuffer.h +++ b/serviceinterface/ServiceInterfaceBuffer.h @@ -60,7 +60,7 @@ private: //! In this function, the characters are parsed. void putChars(char const* begin, char const* end); - std::string getPreamble(size_t * preambleSize = nullptr); + std::string* getPreamble(size_t * preambleSize = nullptr); }; #endif diff --git a/serviceinterface/ServiceInterfaceStream.cpp b/serviceinterface/ServiceInterfaceStream.cpp index 76481ed1..31bc7c73 100644 --- a/serviceinterface/ServiceInterfaceStream.cpp +++ b/serviceinterface/ServiceInterfaceStream.cpp @@ -9,7 +9,7 @@ void ServiceInterfaceStream::setActive( bool myActive) { this->streambuf.isActive = myActive; } -std::string ServiceInterfaceStream::getPreamble() { +std::string* ServiceInterfaceStream::getPreamble() { return streambuf.getPreamble(); } diff --git a/serviceinterface/ServiceInterfaceStream.h b/serviceinterface/ServiceInterfaceStream.h index 9e19c228..dc111459 100644 --- a/serviceinterface/ServiceInterfaceStream.h +++ b/serviceinterface/ServiceInterfaceStream.h @@ -33,7 +33,7 @@ public: * the unbuffered mode. * @return Preamle consisting of log message and timestamp. */ - std::string getPreamble(); + std::string* getPreamble(); /** * This prints an error with a preamble. Useful if using the unbuffered From 69f9ff02f047917c2c6a622bcb6fc6244d60564f Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 28 Jul 2020 17:00:51 +0200 Subject: [PATCH 294/307] better returnvalue for failed comIF init --- devicehandlers/DeviceHandlerBase.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index 9f4c7baf..1e7ebf04 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -128,7 +128,9 @@ ReturnValue_t DeviceHandlerBase::initialize() { result = communicationInterface->initializeInterface(comCookie); if (result != RETURN_OK) { - return result; + sif::error << "DeviceHandlerBase::initialize: Initializing " + "communication interface failed!" << std::endl; + return result; } IPCStore = objectManager->get(objects::IPC_STORE); From 9acf82cf510be6dfd0f7e94601cdf4795213e5f4 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 28 Jul 2020 18:12:10 +0200 Subject: [PATCH 295/307] doc improved --- devicehandlers/DeviceHandlerBase.h | 2 ++ devicehandlers/DeviceHandlerIF.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/devicehandlers/DeviceHandlerBase.h b/devicehandlers/DeviceHandlerBase.h index ddbf6041..632db5e0 100644 --- a/devicehandlers/DeviceHandlerBase.h +++ b/devicehandlers/DeviceHandlerBase.h @@ -379,6 +379,8 @@ protected: * @param deviceCommand Identifier of the command to add. * @param maxDelayCycles The maximum number of delay cycles the command * waits until it times out. + * @param replyLen Will be supplied to the requestReceiveMessage call of + * the communication interface. * @param periodic Indicates if the command is periodic (i.e. it is sent * by the device repeatedly without request) or not. Default is aperiodic (0) * @return - @c RETURN_OK when the command was successfully inserted, diff --git a/devicehandlers/DeviceHandlerIF.h b/devicehandlers/DeviceHandlerIF.h index cb190344..59302080 100644 --- a/devicehandlers/DeviceHandlerIF.h +++ b/devicehandlers/DeviceHandlerIF.h @@ -98,7 +98,7 @@ public: static const uint8_t INTERFACE_ID = CLASS_ID::DEVICE_HANDLER_IF; // Standard codes used when building commands. - static const ReturnValue_t NO_COMMAND_DATA = MAKE_RETURN_CODE(0xA0); //!< If the command size is 0. Checked in DHB + static const ReturnValue_t NO_COMMAND_DATA = MAKE_RETURN_CODE(0xA0); //!< If no command data was given when expected. static const ReturnValue_t COMMAND_NOT_SUPPORTED = MAKE_RETURN_CODE(0xA1); //!< Command ID not in commandMap. Checked in DHB static const ReturnValue_t COMMAND_ALREADY_SENT = MAKE_RETURN_CODE(0xA2); //!< Command was already executed. Checked in DHB static const ReturnValue_t COMMAND_WAS_NOT_SENT = MAKE_RETURN_CODE(0xA3); From 9fa9421ba58d4c6793aa19886ce6ee17e7f85d71 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 28 Jul 2020 20:57:05 +0200 Subject: [PATCH 296/307] important bugfix --- fdir/FailureIsolationBase.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fdir/FailureIsolationBase.cpp b/fdir/FailureIsolationBase.cpp index 083f5af0..4df56dcd 100644 --- a/fdir/FailureIsolationBase.cpp +++ b/fdir/FailureIsolationBase.cpp @@ -104,9 +104,9 @@ MessageQueueId_t FailureIsolationBase::getEventReceptionQueue() { ReturnValue_t FailureIsolationBase::sendConfirmationRequest(EventMessage* event, MessageQueueId_t destination) { event->setMessageId(EventMessage::CONFIRMATION_REQUEST); - if (destination != 0) { + if (destination != MessageQueueIF::NO_QUEUE) { return eventQueue->sendMessage(destination, event); - } else if (faultTreeParent != 0) { + } else if (faultTreeParent != objects::NO_OBJECT) { return eventQueue->sendToDefault(event); } return RETURN_FAILED; From c64aa9f7f55e4afbc5f21cf149bfc71a889a06e5 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 28 Jul 2020 21:00:11 +0200 Subject: [PATCH 297/307] another important bugfix --- fdir/FailureIsolationBase.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdir/FailureIsolationBase.h b/fdir/FailureIsolationBase.h index dea149bd..6010baca 100644 --- a/fdir/FailureIsolationBase.h +++ b/fdir/FailureIsolationBase.h @@ -45,7 +45,7 @@ protected: virtual ReturnValue_t confirmFault(EventMessage* event); virtual void decrementFaultCounters() = 0; ReturnValue_t sendConfirmationRequest(EventMessage* event, - MessageQueueId_t destination = 0); + MessageQueueId_t destination = MessageQueueIF::NO_QUEUE); void throwFdirEvent(Event event, uint32_t parameter1 = 0, uint32_t parameter2 = 0); private: From 276c3b172e18df8b7f457e23fb43c22e9c332553 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 29 Jul 2020 15:32:36 +0200 Subject: [PATCH 298/307] better diagnostic warning for DHB --- devicehandlers/DeviceHandlerBase.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/devicehandlers/DeviceHandlerBase.cpp b/devicehandlers/DeviceHandlerBase.cpp index 1e7ebf04..a4346afb 100644 --- a/devicehandlers/DeviceHandlerBase.cpp +++ b/devicehandlers/DeviceHandlerBase.cpp @@ -680,16 +680,24 @@ void DeviceHandlerBase::parseReply(const uint8_t* receivedData, switch (result) { case RETURN_OK: handleReply(receivedData, foundId, foundLen); + if(foundLen == 0) { + sif::warning << "DeviceHandlerBase::parseReply: foundLen is 0!" + " Packet parsing will be stuck." << std::endl; + } break; case APERIODIC_REPLY: { result = interpretDeviceReply(foundId, receivedData); if (result != RETURN_OK) { - replyRawReplyIfnotWiretapped(receivedData, foundLen); - triggerEvent(DEVICE_INTERPRETING_REPLY_FAILED, result, - foundId); + replyRawReplyIfnotWiretapped(receivedData, foundLen); + triggerEvent(DEVICE_INTERPRETING_REPLY_FAILED, result, + foundId); } + if(foundLen == 0) { + sif::warning << "DeviceHandlerBase::parseReply: foundLen is 0!" + " Packet parsing will be stuck." << std::endl; + } + break; } - break; case IGNORE_REPLY_DATA: break; case IGNORE_FULL_PACKET: From 18899a4c828262258699d9c80beab12cd251b506 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Wed, 29 Jul 2020 20:07:24 +0200 Subject: [PATCH 299/307] hotfix for deadline checking --- osal/FreeRTOS/FixedTimeslotTask.cpp | 19 +++++++++---------- osal/FreeRTOS/PeriodicTask.cpp | 19 +++++++++---------- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/osal/FreeRTOS/FixedTimeslotTask.cpp b/osal/FreeRTOS/FixedTimeslotTask.cpp index 630952d2..1dc45b1d 100644 --- a/osal/FreeRTOS/FixedTimeslotTask.cpp +++ b/osal/FreeRTOS/FixedTimeslotTask.cpp @@ -125,19 +125,18 @@ void FixedTimeslotTask::checkMissedDeadline(const TickType_t xLastWakeTime, * it. */ TickType_t currentTickCount = xTaskGetTickCount(); TickType_t timeToWake = xLastWakeTime + interval; - // Tick count has overflown - if(currentTickCount < xLastWakeTime) { - // Time to wake has overflown as well. If the tick count - // is larger than the time to wake, a deadline was missed. - if(timeToWake < xLastWakeTime and - currentTickCount > timeToWake) { + // Time to wake has not overflown. + if(timeToWake > xLastWakeTime) { + /* If the current time has overflown exclusively or the current + * tick count is simply larger than the time to wake, a deadline was + * missed */ + if((currentTickCount < xLastWakeTime) or (currentTickCount > timeToWake)) { handleMissedDeadline(); } } - // No tick count overflow. If the timeToWake has not overflown - // and the current tick count is larger than the time to wake, - // a deadline was missed. - else if(timeToWake > xLastWakeTime and currentTickCount > timeToWake) { + /* Time to wake has overflown. A deadline was missed if the current time + * is larger than the time to wake */ + else if((timeToWake < xLastWakeTime) and (currentTickCount > timeToWake)) { handleMissedDeadline(); } } diff --git a/osal/FreeRTOS/PeriodicTask.cpp b/osal/FreeRTOS/PeriodicTask.cpp index f960d8bb..817cb06f 100644 --- a/osal/FreeRTOS/PeriodicTask.cpp +++ b/osal/FreeRTOS/PeriodicTask.cpp @@ -109,19 +109,18 @@ void PeriodicTask::checkMissedDeadline(const TickType_t xLastWakeTime, * it. */ TickType_t currentTickCount = xTaskGetTickCount(); TickType_t timeToWake = xLastWakeTime + interval; - // Tick count has overflown - if(currentTickCount < xLastWakeTime) { - // Time to wake has overflown as well. If the tick count - // is larger than the time to wake, a deadline was missed. - if(timeToWake < xLastWakeTime and - currentTickCount > timeToWake) { + // Time to wake has not overflown. + if(timeToWake > xLastWakeTime) { + /* If the current time has overflown exclusively or the current + * tick count is simply larger than the time to wake, a deadline was + * missed */ + if((currentTickCount < xLastWakeTime) or (currentTickCount > timeToWake)) { handleMissedDeadline(); } } - // No tick count overflow. If the timeToWake has not overflown - // and the current tick count is larger than the time to wake, - // a deadline was missed. - else if(timeToWake > xLastWakeTime and currentTickCount > timeToWake) { + /* Time to wake has overflown. A deadline was missed if the current time + * is larger than the time to wake */ + else if((timeToWake < xLastWakeTime) and (currentTickCount > timeToWake)) { handleMissedDeadline(); } } From 58a4f4f8a1d9608b671cd6fab087afea5d086dc1 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 1 Aug 2020 16:39:17 +0200 Subject: [PATCH 300/307] command message bugfix, CSB improvement parameter helper diagnostic message --- ipc/CommandMessage.cpp | 1 + parameters/ParameterHelper.cpp | 7 ++++--- parameters/ParameterHelper.h | 6 ++++++ tmtcservices/CommandingServiceBase.cpp | 8 ++++---- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/ipc/CommandMessage.cpp b/ipc/CommandMessage.cpp index 8c296abd..cc1185c7 100644 --- a/ipc/CommandMessage.cpp +++ b/ipc/CommandMessage.cpp @@ -88,6 +88,7 @@ void CommandMessage::setToUnknownCommand() { void CommandMessage::setReplyRejected(ReturnValue_t reason, Command_t initialCommand) { + setCommand(REPLY_REJECTED); setParameter(reason); setParameter2(initialCommand); } diff --git a/parameters/ParameterHelper.cpp b/parameters/ParameterHelper.cpp index e40ed675..53f1229f 100644 --- a/parameters/ParameterHelper.cpp +++ b/parameters/ParameterHelper.cpp @@ -26,7 +26,6 @@ ReturnValue_t ParameterHelper::handleParameterMessage(CommandMessage *message) { } break; case ParameterMessage::CMD_PARAMETER_LOAD: { - uint8_t domain = HasParametersIF::getDomain( ParameterMessage::getParameterId(message)); uint16_t parameterId = HasParametersIF::getMatrixId( @@ -34,12 +33,14 @@ ReturnValue_t ParameterHelper::handleParameterMessage(CommandMessage *message) { uint8_t index = HasParametersIF::getIndex( ParameterMessage::getParameterId(message)); - const uint8_t *storedStream; - size_t storedStreamSize; + const uint8_t *storedStream = nullptr; + size_t storedStreamSize = 0; result = storage->getData( ParameterMessage::getStoreId(message), &storedStream, &storedStreamSize); if (result != HasReturnvaluesIF::RETURN_OK) { + sif::error << "ParameterHelper::handleParameterMessage: Getting" + " store data failed for load command." << std::endl; break; } diff --git a/parameters/ParameterHelper.h b/parameters/ParameterHelper.h index 352cf0a9..538aaac6 100644 --- a/parameters/ParameterHelper.h +++ b/parameters/ParameterHelper.h @@ -5,6 +5,12 @@ #include #include +/** + * @brief Helper class to handle parameter messages + * @details + * This class simplfiies handling of parameter messages, which are sent + * to a class which implements ReceivesParameterMessagesIF. + */ class ParameterHelper { public: ParameterHelper(ReceivesParameterMessagesIF *owner); diff --git a/tmtcservices/CommandingServiceBase.cpp b/tmtcservices/CommandingServiceBase.cpp index 4c9b5375..80a28093 100644 --- a/tmtcservices/CommandingServiceBase.cpp +++ b/tmtcservices/CommandingServiceBase.cpp @@ -126,11 +126,11 @@ void CommandingServiceBase::handleCommandMessage(CommandMessage* reply) { &nextCommand, iter->objectId, &isStep); /* If the child implementation does not implement special handling for - * rejected replies (RETURN_FAILED is returned), a failure verification - * will be generated with the reason as the return code and the initial - * command as failure parameter 1 */ + * rejected replies (RETURN_FAILED or INVALID_REPLY is returned), a + * failure verification will be generated with the reason as the + * return code and the initial command as failure parameter 1 */ if(reply->getCommand() == CommandMessage::REPLY_REJECTED and - result == RETURN_FAILED) { + (result == RETURN_FAILED or result == INVALID_REPLY)) { result = reply->getReplyRejectedReason(); failureParameter1 = iter->command; } From 66eac57e3bb77c73a4030d1320a64b42e5841641 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 1 Aug 2020 16:54:54 +0200 Subject: [PATCH 301/307] csb update --- tmtcservices/CommandingServiceBase.cpp | 6 +++--- tmtcservices/CommandingServiceBase.h | 17 ++++++++--------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/tmtcservices/CommandingServiceBase.cpp b/tmtcservices/CommandingServiceBase.cpp index 80a28093..330fd00f 100644 --- a/tmtcservices/CommandingServiceBase.cpp +++ b/tmtcservices/CommandingServiceBase.cpp @@ -129,7 +129,7 @@ void CommandingServiceBase::handleCommandMessage(CommandMessage* reply) { * rejected replies (RETURN_FAILED or INVALID_REPLY is returned), a * failure verification will be generated with the reason as the * return code and the initial command as failure parameter 1 */ - if(reply->getCommand() == CommandMessage::REPLY_REJECTED and + if((reply->getCommand() == CommandMessage::REPLY_REJECTED) and (result == RETURN_FAILED or result == INVALID_REPLY)) { result = reply->getReplyRejectedReason(); failureParameter1 = iter->command; @@ -230,8 +230,8 @@ void CommandingServiceBase::handleRequestQueue() { address = message.getStorageId(); packet.setStoreAddress(address); - if (packet.getSubService() == 0 - or isValidSubservice(packet.getSubService()) != RETURN_OK) { + if ((packet.getSubService() == 0) + or (isValidSubservice(packet.getSubService()) != RETURN_OK)) { rejectPacket(TC_VERIFY::START_FAILURE, &packet, INVALID_SUBSERVICE); continue; } diff --git a/tmtcservices/CommandingServiceBase.h b/tmtcservices/CommandingServiceBase.h index 1bd18571..b3a15985 100644 --- a/tmtcservices/CommandingServiceBase.h +++ b/tmtcservices/CommandingServiceBase.h @@ -87,7 +87,7 @@ public: * @param opCode is unused here at the moment * @return RETURN_OK */ - virtual ReturnValue_t performOperation(uint8_t opCode); + virtual ReturnValue_t performOperation(uint8_t opCode) override; virtual uint16_t getIdentifier(); @@ -116,7 +116,7 @@ public: * Used to setup the reference of the task, that executes this component * @param task Pointer to the taskIF of this task */ - virtual void setTaskIF(PeriodicTaskIF* task); + virtual void setTaskIF(PeriodicTaskIF* task) override; protected: /** @@ -173,9 +173,7 @@ protected: * This function is implemented by child services to specify how replies * to a command from another software component are handled. * @param reply - * This is the reply which can be accessed via the command message - * interface. The internal message pointer can be passed to different - * command message implementations (see CommandMessageIF) + * This is the reply in form of a generic read-only command message. * @param previousCommand * Command_t of related command * @param state [out/in] @@ -189,10 +187,11 @@ protected: * - @c RETURN_OK, @c EXECUTION_COMPLETE or @c NO_STEP_MESSAGE to * generate TC verification success * - @c INVALID_REPLY Calls handleUnrequestedReply - * - Anything else triggers a TC verification failure. If RETURN_FAILED - * is returned and the command ID is CommandMessage::REPLY_REJECTED, - * a failure verification message with the reason as the error parameter - * and the initial command as failure parameter 1. + * - Anything else triggers a TC verification failure. If RETURN_FAILED or + * INVALID_REPLY is returned and the command ID is + * CommandMessage::REPLY_REJECTED, a failure verification message with + * the reason as the error parameter and the initial command as + * failure parameter 1 is generated. */ virtual ReturnValue_t handleReply(const CommandMessage* reply, Command_t previousCommand, uint32_t *state, From ebf5d41a7880f4c866fa1eb29113ecc960bd0efc Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Sat, 1 Aug 2020 19:03:03 +0200 Subject: [PATCH 302/307] parameters IF doc and improvement --- parameters/HasParametersIF.h | 19 +++++-- parameters/ParameterWrapper.cpp | 24 ++++----- parameters/ParameterWrapper.h | 91 +++++++++++++++++++++------------ 3 files changed, 84 insertions(+), 50 deletions(-) diff --git a/parameters/HasParametersIF.h b/parameters/HasParametersIF.h index fbb69445..02f36318 100644 --- a/parameters/HasParametersIF.h +++ b/parameters/HasParametersIF.h @@ -5,8 +5,23 @@ #include #include +/** Each parameter is identified with a unique parameter ID */ typedef uint32_t ParameterId_t; +/** + * @brief This interface is used by components which have modifiable + * parameters, e.g. atittude controllers + * @details + * Each parameter has a unique parameter ID. The first byte of the parameter + * ID is the domain ID which can be used to identify unqiue spacecraft domains + * (e.g. control and sensor domain in the AOCS controller). + * + * The second and third byte represent the matrix ID, which can represent + * a 8-bit row and column number and the last byte... + * + * Yeah, it it matrix ID oder parameter ID now and is index a 16 bit number + * of a 8 bit number now? + */ class HasParametersIF { public: static const uint8_t INTERFACE_ID = CLASS_ID::HAS_PARAMETERS_IF; @@ -32,13 +47,11 @@ public: return (domainId << 24) + (parameterId << 8) + index; } - virtual ~HasParametersIF() { - } + virtual ~HasParametersIF() {} /** * Always set parameter before checking newValues! * - * * @param domainId * @param parameterId * @param parameterWrapper diff --git a/parameters/ParameterWrapper.cpp b/parameters/ParameterWrapper.cpp index 7daf738c..521a6644 100644 --- a/parameters/ParameterWrapper.cpp +++ b/parameters/ParameterWrapper.cpp @@ -1,20 +1,19 @@ #include ParameterWrapper::ParameterWrapper() : - pointsToStream(false), type(Type::UNKNOWN_TYPE), rows(0), columns(0), data( - NULL), readonlyData(NULL) { + pointsToStream(false), type(Type::UNKNOWN_TYPE) { } ParameterWrapper::ParameterWrapper(Type type, uint8_t rows, uint8_t columns, void *data) : - pointsToStream(false), type(type), rows(rows), columns(columns), data( - data), readonlyData(data) { + pointsToStream(false), type(type), rows(rows), columns(columns), + data(data), readonlyData(data) { } ParameterWrapper::ParameterWrapper(Type type, uint8_t rows, uint8_t columns, const void *data) : - pointsToStream(false), type(type), rows(rows), columns(columns), data( - NULL), readonlyData(data) { + pointsToStream(false), type(type), rows(rows), columns(columns), + data(nullptr), readonlyData(data) { } ParameterWrapper::~ParameterWrapper() { @@ -266,15 +265,14 @@ ReturnValue_t ParameterWrapper::copyFrom(const ParameterWrapper *from, result = UNKNOW_DATATYPE; break; } - } else { + } + else { //need a type to do arithmetic - uint8_t *toDataWithType = (uint8_t*) data; + uint8_t* typedData = static_cast(data); for (uint8_t fromRow = 0; fromRow < from->rows; fromRow++) { - memcpy( - toDataWithType - + (((startingRow + fromRow) * columns) - + startingColumn) * typeSize, - from->readonlyData, typeSize * from->columns); + uint8_t offset = (((startingRow + fromRow) * columns) + startingColumn) * typeSize; + std::memcpy(typedData + offset, from->readonlyData, + typeSize * from->columns); } } diff --git a/parameters/ParameterWrapper.h b/parameters/ParameterWrapper.h index a00c997c..eec101f2 100644 --- a/parameters/ParameterWrapper.h +++ b/parameters/ParameterWrapper.h @@ -1,5 +1,5 @@ -#ifndef PARAMETERWRAPPER_H_ -#define PARAMETERWRAPPER_H_ +#ifndef FRAMEWORK_PARAMETERS_PARAMETERWRAPPER_H_ +#define FRAMEWORK_PARAMETERS_PARAMETERWRAPPER_H_ #include #include @@ -7,6 +7,10 @@ #include #include +/** + * @brief + * @details + */ class ParameterWrapper: public SerializeIF { friend class DataPoolParameterWrapper; public: @@ -36,32 +40,21 @@ public: virtual ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, Endianness streamEndianness, uint16_t startWritingAtIndex = 0); + /** + * Get a specific parameter value by supplying the row and the column. + * @tparam T Type of target data + * @param value [out] Pointer to storage location + * @param row + * @param column + * @return + * -@c RETURN_OK if element was retrieved successfully + * -@c NOT_SET data has not been set yet + * -@c DATATYPE_MISSMATCH Invalid supplied type + * -@c OUT_OF_BOUNDS Invalid row and/or column. + */ template - ReturnValue_t getElement(T *value, uint8_t row = 0, uint8_t column = 0) const { - if (readonlyData == NULL){ - return NOT_SET; - } - - if (PodTypeConversion::type != type) { - return DATATYPE_MISSMATCH; - } - - if ((row >= rows) || (column >= columns)) { - return OUT_OF_BOUNDS; - } - - if (pointsToStream) { - const uint8_t *streamWithtype = (const uint8_t *) readonlyData; - streamWithtype += (row * columns + column) * type.getSize(); - int32_t size = type.getSize(); - return SerializeAdapter::deSerialize(value, &streamWithtype, - &size, true); - } else { - const T *dataWithType = (const T *) readonlyData; - *value = dataWithType[row * columns + column]; - return HasReturnvaluesIF::RETURN_OK; - } - } + ReturnValue_t getElement(T *value, uint8_t row = 0, + uint8_t column = 0) const; template void set(T *data, uint8_t rows, uint8_t columns) { @@ -111,21 +104,22 @@ public: void setMatrix(const T& member) { this->set(member[0], sizeof(member)/sizeof(member[0]), sizeof(member[0])/sizeof(member[0][0])); } + ReturnValue_t set(const uint8_t *stream, size_t streamSize, - const uint8_t **remainingStream = NULL, size_t *remainingSize = - NULL); + const uint8_t **remainingStream = nullptr, + size_t *remainingSize = nullptr); ReturnValue_t copyFrom(const ParameterWrapper *from, uint16_t startWritingAtIndex); private: - bool pointsToStream; + bool pointsToStream = false; Type type; - uint8_t rows; - uint8_t columns; - void *data; - const void *readonlyData; + uint8_t rows = 0; + uint8_t columns = 0; + void *data = nullptr; + const void *readonlyData = nullptr; template ReturnValue_t serializeData(uint8_t** buffer, size_t* size, @@ -136,4 +130,33 @@ private: const void *from, uint8_t fromRows, uint8_t fromColumns); }; +template +inline ReturnValue_t ParameterWrapper::getElement(T *value, uint8_t row, + uint8_t column) const { + if (readonlyData == nullptr){ + return NOT_SET; + } + + if (PodTypeConversion::type != type) { + return DATATYPE_MISSMATCH; + } + + if ((row >= rows) or (column >= columns)) { + return OUT_OF_BOUNDS; + } + + if (pointsToStream) { + const uint8_t *streamWithType = static_cast(readonlyData); + streamWithType += (row * columns + column) * type.getSize(); + int32_t size = type.getSize(); + return SerializeAdapter::deSerialize(value, &streamWithType, + &size, true); + } + else { + const T *dataWithType = static_cast(readonlyData); + *value = dataWithType[row * columns + column]; + return HasReturnvaluesIF::RETURN_OK; + } +} + #endif /* PARAMETERWRAPPER_H_ */ From f240827bbdd9ad7542e21ca5810235e6acb20c96 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 4 Aug 2020 00:59:19 +0200 Subject: [PATCH 303/307] added getFreeElement --- container/SimpleRingBuffer.h | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/container/SimpleRingBuffer.h b/container/SimpleRingBuffer.h index cf78814f..9a548815 100644 --- a/container/SimpleRingBuffer.h +++ b/container/SimpleRingBuffer.h @@ -16,12 +16,17 @@ class SimpleRingBuffer: public RingBufferBase<> { public: /** * This constructor allocates a new internal buffer with the supplied size. + * * @param size - * @param overwriteOld - * If the ring buffer is overflowing at a write operartion, the oldest data - * will be overwritten. + * @param overwriteOld If the ring buffer is overflowing at a write + * operation, the oldest data will be overwritten. + * @param maxExcessBytes These additional bytes will be allocated in addtion + * to the specified size to accomodate contiguous write operations + * with getFreeElement. + * */ - SimpleRingBuffer(const size_t size, bool overwriteOld); + SimpleRingBuffer(const size_t size, bool overwriteOld, + size_t maxExcessBytes = 0); /** * This constructor takes an external buffer with the specified size. * @param buffer @@ -29,8 +34,13 @@ public: * @param overwriteOld * If the ring buffer is overflowing at a write operartion, the oldest data * will be overwritten. + * @param maxExcessBytes + * If the buffer can accomodate additional bytes for contigous write + * operations with getFreeElement, this is the maximum allowed additional + * size */ - SimpleRingBuffer(uint8_t* buffer, const size_t size, bool overwriteOld); + SimpleRingBuffer(uint8_t* buffer, const size_t size, bool overwriteOld, + size_t maxExcessBytes = 0); virtual ~SimpleRingBuffer(); @@ -43,6 +53,17 @@ public: */ ReturnValue_t writeData(const uint8_t* data, size_t amount); + /** + * Returns a pointer to a free element. If the remaining buffer is + * not large enough, the data will be written past the actual size + * and the amount of excess bytes will be cached. + * @param writePointer Pointer to a pointer which can be used to write + * contiguous blocks into the ring buffer + * @param amount + * @return + */ + ReturnValue_t getFreeElement(uint8_t** writePointer, size_t amount); + /** * Read from circular buffer at read pointer. * @param data @@ -82,6 +103,8 @@ public: private: static const uint8_t READ_PTR = 0; uint8_t* buffer = nullptr; + const size_t maxExcessBytes; + size_t excessBytes = 0; }; #endif /* FRAMEWORK_CONTAINER_SIMPLERINGBUFFER_H_ */ From 0ead44bea976bba70676fc40ed9716f2ae6b84d8 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 4 Aug 2020 01:07:59 +0200 Subject: [PATCH 304/307] getFreeElement implemented --- container/SimpleRingBuffer.cpp | 44 ++++++++++++++++++++++++++++++---- container/SimpleRingBuffer.h | 8 +++++++ 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/container/SimpleRingBuffer.cpp b/container/SimpleRingBuffer.cpp index 69d94143..3cc1ffdf 100644 --- a/container/SimpleRingBuffer.cpp +++ b/container/SimpleRingBuffer.cpp @@ -1,20 +1,43 @@ #include #include -SimpleRingBuffer::SimpleRingBuffer(const size_t size, bool overwriteOld) : - RingBufferBase<>(0, size, overwriteOld) { - buffer = new uint8_t[size]; +SimpleRingBuffer::SimpleRingBuffer(const size_t size, bool overwriteOld, + size_t maxExcessBytes) : + RingBufferBase<>(0, size, overwriteOld), + maxExcessBytes(maxExcessBytes) { + buffer = new uint8_t[size + maxExcessBytes]; } SimpleRingBuffer::SimpleRingBuffer(uint8_t *buffer, const size_t size, - bool overwriteOld): - RingBufferBase<>(0, size, overwriteOld), buffer(buffer) {} + bool overwriteOld, size_t maxExcessBytes): + RingBufferBase<>(0, size, overwriteOld), buffer(buffer), + maxExcessBytes(maxExcessBytes) {} SimpleRingBuffer::~SimpleRingBuffer() { delete[] buffer; } + +ReturnValue_t SimpleRingBuffer::getFreeElement(uint8_t **writePointer, + size_t amount) { + if (availableWriteSpace() >= amount or overwriteOld) { + size_t amountTillWrap = writeTillWrap(); + if (amountTillWrap < amount) { + if((amount - amountTillWrap + excessBytes) > maxExcessBytes) { + return HasReturnvaluesIF::RETURN_FAILED; + } + excessBytes += amount - amountTillWrap; + } + *writePointer = &buffer[write]; + incrementWrite(amount); + return HasReturnvaluesIF::RETURN_OK; + } + else { + return HasReturnvaluesIF::RETURN_FAILED; + } +} + ReturnValue_t SimpleRingBuffer::writeData(const uint8_t* data, size_t amount) { if (availableWriteSpace() >= amount or overwriteOld) { @@ -62,6 +85,17 @@ ReturnValue_t SimpleRingBuffer::readData(uint8_t* data, size_t amount, return HasReturnvaluesIF::RETURN_OK; } +size_t SimpleRingBuffer::getExcessBytes() const { + return excessBytes; +} + +void SimpleRingBuffer::moveExcessBytesToStart() { + if(excessBytes > 0) { + std::memcpy(buffer, &buffer[size], excessBytes); + excessBytes = 0; + } +} + ReturnValue_t SimpleRingBuffer::deleteData(size_t amount, bool deleteRemaining, size_t* trueAmount) { size_t availableData = availableReadData(READ_PTR); diff --git a/container/SimpleRingBuffer.h b/container/SimpleRingBuffer.h index 9a548815..4bb3a4e8 100644 --- a/container/SimpleRingBuffer.h +++ b/container/SimpleRingBuffer.h @@ -64,6 +64,14 @@ public: */ ReturnValue_t getFreeElement(uint8_t** writePointer, size_t amount); + size_t getExcessBytes() const; + /** + * Helper functions which moves any excess bytes to the start + * of the ring buffer. + * @return + */ + void moveExcessBytesToStart(); + /** * Read from circular buffer at read pointer. * @param data From 4e9e465360b2b4757699e79b265c12358ac5e8db Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 4 Aug 2020 02:00:00 +0200 Subject: [PATCH 305/307] shared ring buffer continued --- container/SimpleRingBuffer.cpp | 20 ++++++++++++++++---- container/SimpleRingBuffer.h | 2 +- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/container/SimpleRingBuffer.cpp b/container/SimpleRingBuffer.cpp index 3cc1ffdf..cad1a48e 100644 --- a/container/SimpleRingBuffer.cpp +++ b/container/SimpleRingBuffer.cpp @@ -2,16 +2,28 @@ #include SimpleRingBuffer::SimpleRingBuffer(const size_t size, bool overwriteOld, - size_t maxExcessBytes) : + size_t maxExcessBytes) : RingBufferBase<>(0, size, overwriteOld), maxExcessBytes(maxExcessBytes) { + if(maxExcessBytes > size) { + this->maxExcessBytes = size; + } + else { + this->maxExcessBytes = maxExcessBytes; + } buffer = new uint8_t[size + maxExcessBytes]; } SimpleRingBuffer::SimpleRingBuffer(uint8_t *buffer, const size_t size, - bool overwriteOld, size_t maxExcessBytes): - RingBufferBase<>(0, size, overwriteOld), buffer(buffer), - maxExcessBytes(maxExcessBytes) {} + bool overwriteOld, size_t maxExcessBytes): + RingBufferBase<>(0, size, overwriteOld), buffer(buffer) { + if(maxExcessBytes > size) { + this->maxExcessBytes = size; + } + else { + this->maxExcessBytes = maxExcessBytes; + } +} SimpleRingBuffer::~SimpleRingBuffer() { diff --git a/container/SimpleRingBuffer.h b/container/SimpleRingBuffer.h index 4bb3a4e8..2627541f 100644 --- a/container/SimpleRingBuffer.h +++ b/container/SimpleRingBuffer.h @@ -111,7 +111,7 @@ public: private: static const uint8_t READ_PTR = 0; uint8_t* buffer = nullptr; - const size_t maxExcessBytes; + size_t maxExcessBytes; size_t excessBytes = 0; }; From 6b475792a4a7c57a5006a010c554dda8b31d41b7 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 4 Aug 2020 02:25:10 +0200 Subject: [PATCH 306/307] shared ring buffer continued --- container/SharedRingBuffer.cpp | 19 +++++++++++++------ container/SharedRingBuffer.h | 9 +++++++-- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/container/SharedRingBuffer.cpp b/container/SharedRingBuffer.cpp index 64cbc669..86277a80 100644 --- a/container/SharedRingBuffer.cpp +++ b/container/SharedRingBuffer.cpp @@ -3,19 +3,26 @@ #include SharedRingBuffer::SharedRingBuffer(object_id_t objectId, const size_t size, - bool overwriteOld, dur_millis_t mutexTimeout): - SystemObject(objectId), SimpleRingBuffer(size, overwriteOld), - mutexTimeout(mutexTimeout) { + bool overwriteOld, size_t maxExcessBytes, dur_millis_t mutexTimeout): + SystemObject(objectId), SimpleRingBuffer(size, overwriteOld, + maxExcessBytes), mutexTimeout(mutexTimeout) { mutex = MutexFactory::instance()->createMutex(); } SharedRingBuffer::SharedRingBuffer(object_id_t objectId, uint8_t *buffer, - const size_t size, bool overwriteOld, dur_millis_t mutexTimeout): - SystemObject(objectId), SimpleRingBuffer(buffer, size, overwriteOld), - mutexTimeout(mutexTimeout) { + const size_t size, bool overwriteOld, size_t maxExcessBytes, + dur_millis_t mutexTimeout): + SystemObject(objectId), SimpleRingBuffer(buffer, size, overwriteOld, + maxExcessBytes), mutexTimeout(mutexTimeout) { mutex = MutexFactory::instance()->createMutex(); } +ReturnValue_t SharedRingBuffer::getFreeElementProtected(uint8_t** writePtr, + size_t amount) { + MutexHelper(mutex, mutexTimeout); + return SimpleRingBuffer::getFreeElement(writePtr,amount); +} + ReturnValue_t SharedRingBuffer::writeDataProtected(const uint8_t *data, size_t amount) { MutexHelper(mutex, mutexTimeout); diff --git a/container/SharedRingBuffer.h b/container/SharedRingBuffer.h index f7d3bc3c..7fed7b22 100644 --- a/container/SharedRingBuffer.h +++ b/container/SharedRingBuffer.h @@ -17,7 +17,8 @@ public: * will be overwritten. */ SharedRingBuffer(object_id_t objectId, const size_t size, - bool overwriteOld, dur_millis_t mutexTimeout = 10); + bool overwriteOld, size_t maxExcessBytes, + dur_millis_t mutexTimeout = 10); /** * This constructor takes an external buffer with the specified size. @@ -28,10 +29,14 @@ public: * will be overwritten. */ SharedRingBuffer(object_id_t objectId, uint8_t* buffer, const size_t size, - bool overwriteOld, dur_millis_t mutexTimeout = 10); + bool overwriteOld, size_t maxExcessBytes, + dur_millis_t mutexTimeout = 10); void setMutexTimeout(dur_millis_t newTimeout); + /** Performs mutex protected SimpleRingBuffer::getFreeElement call */ + ReturnValue_t getFreeElementProtected(uint8_t** writePtr, size_t amount); + /** Performs mutex protected SimpleRingBuffer::writeData call */ ReturnValue_t writeDataProtected(const uint8_t* data, size_t amount); From 4dcfa5125edf80f2bc6bde7861e1da394b4d7a4e Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 4 Aug 2020 11:47:47 +0200 Subject: [PATCH 307/307] added additional calls --- container/SharedRingBuffer.cpp | 10 ++++++++++ container/SharedRingBuffer.h | 8 ++++++++ container/SimpleRingBuffer.cpp | 2 +- container/SimpleRingBuffer.h | 4 ++-- 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/container/SharedRingBuffer.cpp b/container/SharedRingBuffer.cpp index 86277a80..2fde2851 100644 --- a/container/SharedRingBuffer.cpp +++ b/container/SharedRingBuffer.cpp @@ -43,6 +43,16 @@ ReturnValue_t SharedRingBuffer::deleteDataProtected(size_t amount, return SimpleRingBuffer::deleteData(amount, deleteRemaining, trueAmount); } +size_t SharedRingBuffer::getExcessBytes() const { + MutexHelper(mutex, mutexTimeout); + return SimpleRingBuffer::getExcessBytes(); +} + +void SharedRingBuffer::moveExcessBytesToStart() { + MutexHelper(mutex, mutexTimeout); + return SimpleRingBuffer::moveExcessBytesToStart(); +} + size_t SharedRingBuffer::getAvailableReadDataProtected(uint8_t n) const { MutexHelper(mutex, mutexTimeout); return ((write + size) - read[n]) % size; diff --git a/container/SharedRingBuffer.h b/container/SharedRingBuffer.h index 7fed7b22..8d68b967 100644 --- a/container/SharedRingBuffer.h +++ b/container/SharedRingBuffer.h @@ -34,6 +34,14 @@ public: void setMutexTimeout(dur_millis_t newTimeout); + virtual size_t getExcessBytes() const override; + /** + * Helper functions which moves any excess bytes to the start + * of the ring buffer. + * @return + */ + virtual void moveExcessBytesToStart() override; + /** Performs mutex protected SimpleRingBuffer::getFreeElement call */ ReturnValue_t getFreeElementProtected(uint8_t** writePtr, size_t amount); diff --git a/container/SimpleRingBuffer.cpp b/container/SimpleRingBuffer.cpp index cad1a48e..36880813 100644 --- a/container/SimpleRingBuffer.cpp +++ b/container/SimpleRingBuffer.cpp @@ -39,7 +39,7 @@ ReturnValue_t SimpleRingBuffer::getFreeElement(uint8_t **writePointer, if((amount - amountTillWrap + excessBytes) > maxExcessBytes) { return HasReturnvaluesIF::RETURN_FAILED; } - excessBytes += amount - amountTillWrap; + excessBytes = amount - amountTillWrap; } *writePointer = &buffer[write]; incrementWrite(amount); diff --git a/container/SimpleRingBuffer.h b/container/SimpleRingBuffer.h index 2627541f..0784e415 100644 --- a/container/SimpleRingBuffer.h +++ b/container/SimpleRingBuffer.h @@ -64,13 +64,13 @@ public: */ ReturnValue_t getFreeElement(uint8_t** writePointer, size_t amount); - size_t getExcessBytes() const; + virtual size_t getExcessBytes() const; /** * Helper functions which moves any excess bytes to the start * of the ring buffer. * @return */ - void moveExcessBytesToStart(); + virtual void moveExcessBytesToStart(); /** * Read from circular buffer at read pointer.