#ifndef MISSION_PAYLOAD_PLOCSPBASE_H_ #define MISSION_PAYLOAD_PLOCSPBASE_H_ #include #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) {} // Set full payload length. Must also consider the two CRC bytes void setFullPayloadLen(size_t fullPayloadLen_) { fullPayloadLen = fullPayloadLen_; } SpacePacketCreator& creator; uint8_t* buf = nullptr; size_t maxSize = 0; size_t fullPayloadLen = 0; }; class SpTcBase { public: SpTcBase(SpTcParams params) : SpTcBase(params, 0x00, 1, 0) {} SpTcBase(SpTcParams params, uint16_t apid, size_t payloadLen) : SpTcBase(params, apid, payloadLen, 0) {} SpTcBase(SpTcParams params, uint16_t apid, size_t payloadLen, uint16_t seqCount) : spParams(params) { spParams.creator.setApid(apid); spParams.creator.setSeqCount(seqCount); payloadStart = spParams.buf + ccsds::HEADER_LEN; spParams.fullPayloadLen = payloadLen; updateSpFields(); } void updateSpFields() { updateLenFromParams(); spParams.creator.setPacketType(ccsds::PacketType::TC); } void updateLenFromParams() { spParams.creator.setDataLenField(spParams.fullPayloadLen - 1); } const uint8_t* getFullPacket() const { return spParams.buf; } const uint8_t* getPacketData() const { return spParams.buf + ccsds::HEADER_LEN; } size_t getFullPacketLen() const { return spParams.creator.getFullPacketLen(); } uint16_t getApid() const { return spParams.creator.getApid(); } uint16_t getSeqCount() const { return spParams.creator.getSequenceCount(); } ReturnValue_t checkPayloadLen() { if (ccsds::HEADER_LEN + spParams.fullPayloadLen > spParams.maxSize) { return SerializeIF::BUFFER_TOO_SHORT; } return returnvalue::OK; } ReturnValue_t serializeHeader() { updateSpFields(); size_t serLen = 0; return spParams.creator.serializeBe(spParams.buf, serLen, spParams.maxSize); } ReturnValue_t checkSizeAndSerializeHeader() { ReturnValue_t result = checkPayloadLen(); if (result != returnvalue::OK) { return result; } return serializeHeader(); } ReturnValue_t calcAndSetCrc() { /* Calculate crc */ uint16_t crc = CRC::crc16ccitt(spParams.buf, getFullPacketLen() - 2); /* Add crc to packet data field of space packet */ size_t serializedSize = 0; return SerializeAdapter::serialize(&crc, spParams.buf + getFullPacketLen() - 2, &serializedSize, spParams.maxSize, 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); } ReturnValue_t checkCrc() const { if (CRC::crc16ccitt(getFullData(), getFullPacketLen()) != 0) { return returnvalue::FAILED; } return returnvalue::OK; } }; } // namespace ploc #endif /* MISSION_PAYLOAD_PLOCSPBASE_H_ */