diff --git a/linux/devices/devicedefinitions/PlocSupervisorDefinitions.h b/linux/devices/devicedefinitions/PlocSupervisorDefinitions.h index 462ee632..83c28dab 100644 --- a/linux/devices/devicedefinitions/PlocSupervisorDefinitions.h +++ b/linux/devices/devicedefinitions/PlocSupervisorDefinitions.h @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include "linux/devices/devicedefinitions/SupvReturnValuesIF.h" @@ -274,10 +274,47 @@ static const uint32_t ERASE_MEMORY = 60000; static const uint32_t UPDATE_STATUS_REPORT = 70000; } // namespace recv_timeout +class SpacePacketBase { +public: + SpacePacketBase(SpacePacketCreator& creator, uint8_t* buf, size_t payloadLen, size_t maxSize) + : creator(creator), buf(buf), payloadLen(payloadLen), maxSize(maxSize) { + creator.setDataLen(payloadLen - 1); + creator.setPacketType(ccsds::PacketType::TC); + payloadStart = buf + ccsds::HEADER_LEN; + } + + ReturnValue_t checkPayloadLen() { + if(ccsds::HEADER_LEN + payloadLen > maxSize) { + return SerializeIF::BUFFER_TOO_SHORT; + } + return result::OK; + } + + ReturnValue_t serialize() { + size_t serLen = 0; + return creator.serializeBe(buf, serLen, maxSize); + } + + ReturnValue_t checkSizeAndSerialize() { + ReturnValue_t result = checkPayloadLen(); + if(result != result::OK) { + return result; + } + return serialize(); + } + +protected: + SpacePacketCreator& creator; + uint8_t* buf; + size_t payloadLen; + uint8_t* payloadStart; + size_t maxSize; +}; + /** * @brief This class creates a space packet containing only the header data and the CRC. */ -class ApidOnlyPacket : public SpacePacket { +class ApidOnlyPacket: public SpacePacketBase { public: /** * @brief Constructor @@ -286,20 +323,33 @@ class ApidOnlyPacket : public SpacePacket { * * @note Sequence count of empty packet is always 1. */ - ApidOnlyPacket(uint16_t apid) : SpacePacket(LENGTH_EMPTY_TC - 1, true, apid, 1) { calcCrc(); } + ApidOnlyPacket(uint16_t apid, SpacePacketCreator& creator, uint8_t* buf, size_t maxSize) + : SpacePacketBase(creator, buf, LENGTH_EMPTY_TC, maxSize) { + creator.setApid(apid); + + } + + ReturnValue_t buildPacket() { + ReturnValue_t result = checkSizeAndSerialize(); + if(result != result::OK) { + return result; + } + calcCrc(); + return result::OK; + } private: + /** * @brief CRC calculation which involves only the header in an empty packet */ void calcCrc() { /* Calculate crc */ - uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, sizeof(CCSDSPrimaryHeader)); + uint16_t crc = CRC::crc16ccitt(buf, ccsds::HEADER_LEN); /* Add crc to packet data field of space packet */ size_t serializedSize = 0; - uint8_t* crcPos = this->localData.fields.buffer; - SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), + SerializeAdapter::serialize(&crc, &payloadStart, &serializedSize, sizeof(crc), SerializeIF::Endianness::BIG); } }; @@ -308,7 +358,7 @@ class ApidOnlyPacket : public SpacePacket { * @brief This class can be used to generate the space packet selecting the boot image of * of the MPSoC. */ -class MPSoCBootSelect : public SpacePacket { +class MPSoCBootSelect : public SpacePacketBase { public: static const uint8_t NVM0 = 0; static const uint8_t NVM1 = 1; @@ -323,13 +373,23 @@ class MPSoCBootSelect : public SpacePacket { * * @note Selection of partitions is currently not supported. */ - MPSoCBootSelect(uint8_t mem = 0, uint8_t bp0 = 0, uint8_t bp1 = 0, uint8_t bp2 = 0) - : SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SEL_MPSOC_BOOT_IMAGE, DEFAULT_SEQUENCE_COUNT), - mem(mem), - bp0(bp0), - bp1(bp1), - bp2(bp2) { + MPSoCBootSelect(SpacePacketCreator& creator, uint8_t* buf, size_t maxSize) + : SpacePacketBase(creator, buf, DATA_FIELD_LENGTH - 1, maxSize) { + creator.setApid(APID_SEL_MPSOC_BOOT_IMAGE); + creator.setSeqCount(DEFAULT_SEQUENCE_COUNT); + } + + ReturnValue_t buildPacket(uint8_t mem_ = 0, uint8_t bp0_ = 0, uint8_t bp1_ = 0, uint8_t bp2_ = 0) { + mem = mem_; + bp0 = bp0_; + bp1 = bp1_; + bp2 = bp2_; + auto res = checkSizeAndSerialize(); + if(res != result::OK) { + return res; + } initPacket(); + return res; } private: @@ -348,18 +408,16 @@ class MPSoCBootSelect : public SpacePacket { uint8_t bp2 = 0; void initPacket() { - uint8_t* data_field_start = this->localData.fields.buffer; - std::memcpy(data_field_start + MEM_OFFSET, &mem, sizeof(mem)); - std::memcpy(data_field_start + BP0_OFFSET, &bp0, sizeof(bp0)); - std::memcpy(data_field_start + BP1_OFFSET, &bp1, sizeof(bp1)); - std::memcpy(data_field_start + BP2_OFFSET, &bp2, sizeof(bp2)); + std::memcpy(payloadStart + MEM_OFFSET, &mem, sizeof(mem)); + std::memcpy(payloadStart + BP0_OFFSET, &bp0, sizeof(bp0)); + std::memcpy(payloadStart + BP1_OFFSET, &bp1, sizeof(bp1)); + std::memcpy(payloadStart + BP2_OFFSET, &bp2, sizeof(bp2)); /* Calculate crc */ - uint16_t crc = CRC::crc16ccitt(this->localData.byteStream, - sizeof(CCSDSPrimaryHeader) + DATA_FIELD_LENGTH - 2); + uint16_t crc = CRC::crc16ccitt(buf, ccsds::HEADER_LEN + DATA_FIELD_LENGTH - 2); /* Add crc to packet data field of space packet */ size_t serializedSize = 0; - uint8_t* crcPos = this->localData.fields.buffer + CRC_OFFSET; + uint8_t* crcPos = payloadStart + CRC_OFFSET; SerializeAdapter::serialize(&crc, &crcPos, &serializedSize, sizeof(crc), SerializeIF::Endianness::BIG); } @@ -369,7 +427,7 @@ class MPSoCBootSelect : public SpacePacket { * @brief This class creates the command to enable or disable the NVMs connected to the * supervisor. */ -class EnableNvms : public SpacePacket { +class EnableNvms : public SpacePacketCreator { public: /** * @brief Constructor @@ -412,7 +470,7 @@ class EnableNvms : public SpacePacket { /** * @brief This class generates the space packet to update the time of the PLOC supervisor. */ -class SetTimeRef : public SpacePacket { +class SetTimeRef : public SpacePacketCreator { public: SetTimeRef(Clock::TimeOfDay_t* time) : SpacePacket(DATA_FIELD_LENGTH - 1, true, APID_SET_TIME_REF, DEFAULT_SEQUENCE_COUNT) { @@ -467,7 +525,7 @@ class SetTimeRef : public SpacePacket { /** * @brief This class can be used to generate the set boot timout command. */ -class SetBootTimeout : public SpacePacket { +class SetBootTimeout : public SpacePacketCreator { public: /** * @brief Constructor @@ -503,7 +561,7 @@ class SetBootTimeout : public SpacePacket { /** * @brief This class can be used to generate the space packet to set the maximum boot tries. */ -class SetRestartTries : public SpacePacket { +class SetRestartTries : public SpacePacketCreator { public: /** * @brief Constructor