#ifndef MISSION_DEVICES_DEVICEDEFINITIONS_SPBASE_H_ #define MISSION_DEVICES_DEVICEDEFINITIONS_SPBASE_H_ #include #include #include namespace ploc { struct SpTcParams { SpTcParams(SpacePacketCreator& creator) : creator(creator) {} SpTcParams(SpacePacketCreator& creator, uint8_t* buf, size_t maxSize) : creator(creator), buf(buf), maxSize(maxSize) {} void setPayloadLen(size_t payloadLen_) { dataFieldLen = payloadLen_ + 2; } void setDataFieldLen(size_t dataFieldLen_) { dataFieldLen = dataFieldLen_; } SpacePacketCreator& creator; uint8_t* buf = nullptr; size_t maxSize = 0; size_t dataFieldLen = 0; }; class SpTcBase { public: SpTcBase(SpTcParams params) : spParams(params) { updateFields(); } SpTcBase(SpTcParams params, uint16_t apid, uint16_t seqCount) : spParams(params) { spParams.creator.setApid(apid); spParams.creator.setSeqCount(seqCount); updateFields(); } void updateFields() { payloadStart = spParams.buf + ccsds::HEADER_LEN; spParams.creator.setDataLen(spParams.dataFieldLen - 1); spParams.creator.setPacketType(ccsds::PacketType::TC); } const uint8_t* getFullPacket() const { return spParams.buf; } size_t getFullPacketLen() const { return spParams.creator.getFullPacketLen(); } uint16_t getApid() const { return spParams.creator.getApid(); } ReturnValue_t checkPayloadLen() { if (ccsds::HEADER_LEN + spParams.dataFieldLen > spParams.maxSize) { return SerializeIF::BUFFER_TOO_SHORT; } return result::OK; } ReturnValue_t serializeHeader() { updateFields(); size_t serLen = 0; return spParams.creator.serializeBe(spParams.buf, serLen, spParams.maxSize); } ReturnValue_t checkSizeAndSerializeHeader() { ReturnValue_t result = checkPayloadLen(); if (result != result::OK) { return result; } return serializeHeader(); } ReturnValue_t calcCrc() { /* Calculate crc */ uint16_t crc = CRC::crc16ccitt(spParams.buf, ccsds::HEADER_LEN + spParams.dataFieldLen - 2); /* Add crc to packet data field of space packet */ size_t serializedSize = 0; return SerializeAdapter::serialize(&crc, &payloadStart, &serializedSize, sizeof(crc), SerializeIF::Endianness::BIG); } protected: ploc::SpTcParams spParams; uint8_t* payloadStart; }; /** * @brief Class for handling tm replies of the supervisor. */ class SpTmReader : public SpacePacketReader { public: SpTmReader() = default; /** * @brief Constructor creates idle packet and sets length field to maximum allowed size. */ SpTmReader(const uint8_t* buf, size_t maxSize) : SpacePacketReader(buf, maxSize) {} ReturnValue_t setData(const uint8_t* buf, size_t maxSize) { return setReadOnlyData(buf, maxSize); } /** * @brief Returns the payload data length (data field length without CRC) */ uint16_t getPayloadDataLength() { return getPacketDataLen() - 2; } ReturnValue_t checkCrc() { const uint8_t* crcPtr = getFullData() + getFullPacketLen() - CRC_SIZE; uint16_t receivedCrc = *(crcPtr) << 8 | *(crcPtr + 1); uint16_t recalculatedCrc = CRC::crc16ccitt(getFullData(), getFullPacketLen() - CRC_SIZE); if (recalculatedCrc != receivedCrc) { return HasReturnvaluesIF::RETURN_FAILED; } return HasReturnvaluesIF::RETURN_OK; } }; } // namespace ploc #endif /* MISSION_DEVICES_DEVICEDEFINITIONS_SPBASE_H_ */