fsfw/src/fsfw/cfdp/VarLenFields.h

136 lines
4.1 KiB
C
Raw Normal View History

2022-08-09 14:39:03 +02:00
#ifndef FSFW_CFDP_PDU_VARLENFIELD_H_
#define FSFW_CFDP_PDU_VARLENFIELD_H_
#include <cstddef>
#include <cstdint>
2022-08-09 18:51:44 +02:00
#include <utility>
2022-08-03 13:15:49 +02:00
#include "fsfw/cfdp/definitions.h"
2022-02-02 10:29:30 +01:00
#include "fsfw/serialize/SerializeIF.h"
2022-09-14 14:00:20 +02:00
#include "fsfw/serviceinterface.h"
2022-08-03 13:15:49 +02:00
#include "fsfw/util/UnsignedByteField.h"
2022-08-09 14:39:03 +02:00
namespace cfdp {
2022-02-02 10:29:30 +01:00
class VarLenField : public SerializeIF {
public:
union LengthFieldLen {
uint8_t oneByte;
uint16_t twoBytes;
uint32_t fourBytes;
uint64_t eightBytes;
};
VarLenField();
2022-08-03 13:15:49 +02:00
template <typename T>
explicit VarLenField(UnsignedByteField<T> byteField);
2022-08-09 14:39:03 +02:00
2023-08-14 15:58:01 +02:00
VarLenField(cfdp::WidthInBytes width, uint64_t value);
2022-08-03 15:12:29 +02:00
bool operator==(const VarLenField &other) const;
2022-09-08 16:25:19 +02:00
bool operator!=(const VarLenField &other) const;
2022-08-03 15:12:29 +02:00
bool operator<(const VarLenField &other) const;
ReturnValue_t setValueAndWidth(cfdp::WidthInBytes width, uint64_t value);
2023-08-03 15:13:26 +02:00
void setWidth(cfdp::WidthInBytes width);
ReturnValue_t setValue(uint64_t value);
2022-02-02 10:29:30 +01:00
ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
Endianness streamEndianness) const override;
2022-08-03 13:15:49 +02:00
[[nodiscard]] size_t getSerializedSize() const override;
2022-02-02 10:29:30 +01:00
ReturnValue_t deSerialize(cfdp::WidthInBytes width, const uint8_t **buffer, size_t *size,
Endianness streamEndianness);
2022-08-03 13:15:49 +02:00
[[nodiscard]] cfdp::WidthInBytes getWidth() const;
2023-08-14 15:58:01 +02:00
[[nodiscard]] uint64_t getValue() const;
2022-09-14 14:00:20 +02:00
#if FSFW_CPP_OSTREAM_ENABLED == 1
friend std::ostream &operator<<(std::ostream &os, const VarLenField &id) {
os << "dec: " << id.getValue() << ", hex: " << std::hex << std::setw(id.getWidth())
<< std::setfill('0') << id.getValue() << std::dec << std::setfill('0');
return os;
}
#endif
2022-02-02 10:29:30 +01:00
private:
ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size,
Endianness streamEndianness) override;
2022-02-02 10:29:30 +01:00
cfdp::WidthInBytes width;
2022-08-03 13:34:49 +02:00
LengthFieldLen value{};
};
2022-08-03 13:34:49 +02:00
template <typename T>
cfdp::VarLenField::VarLenField(UnsignedByteField<T> byteField)
2022-08-09 14:39:03 +02:00
: width(static_cast<cfdp::WidthInBytes>(sizeof(T))) {
2022-08-03 13:34:49 +02:00
static_assert((sizeof(T) % 2) == 0);
setValueAndWidth(width, byteField.getValue());
2022-08-03 13:34:49 +02:00
}
2022-08-09 18:51:44 +02:00
struct EntityId : public VarLenField {
public:
EntityId() : VarLenField() {}
template <typename T>
explicit EntityId(UnsignedByteField<T> byteField) : VarLenField(byteField) {}
EntityId(cfdp::WidthInBytes width, size_t entityId) : VarLenField(width, entityId) {}
2023-07-25 13:58:22 +02:00
2023-07-26 16:58:58 +02:00
ReturnValue_t serializeAsLv(uint8_t **buffer, size_t *size, size_t maxSize) const {
2023-07-25 13:58:22 +02:00
if (buffer == nullptr or size == nullptr) {
return returnvalue::FAILED;
}
if (*size + 1 + getWidth() > maxSize) {
return SerializeIF::BUFFER_TOO_SHORT;
}
**buffer = getWidth();
*buffer += 1;
*size += 1;
return serialize(buffer, size, maxSize, SerializeIF::Endianness::NETWORK);
}
2023-07-26 16:58:58 +02:00
ReturnValue_t deSerializeFromLv(const uint8_t **buffer, size_t *deserLen) {
if (buffer == nullptr or deserLen == nullptr) {
return returnvalue::FAILED;
}
if (*deserLen < 2) {
return SerializeIF::STREAM_TOO_SHORT;
}
auto width = static_cast<WidthInBytes>(**buffer);
*buffer += 1;
*deserLen -= 1;
return VarLenField::deSerialize(width, buffer, deserLen, SerializeIF::Endianness::NETWORK);
}
2022-08-09 18:51:44 +02:00
};
struct TransactionSeqNum : public VarLenField {
public:
TransactionSeqNum() : VarLenField() {}
template <typename T>
explicit TransactionSeqNum(UnsignedByteField<T> byteField) : VarLenField(byteField) {}
TransactionSeqNum(cfdp::WidthInBytes width, size_t seqNum) : VarLenField(width, seqNum) {}
};
struct TransactionId {
2022-08-23 20:30:41 +02:00
TransactionId() = default;
2022-08-09 18:51:44 +02:00
TransactionId(EntityId entityId, TransactionSeqNum seqNum)
: entityId(std::move(entityId)), seqNum(std::move(seqNum)) {}
2022-09-06 13:16:00 +02:00
bool operator==(const TransactionId &other) const {
2022-08-09 18:51:44 +02:00
return entityId == other.entityId and seqNum == other.seqNum;
}
2022-09-14 14:00:20 +02:00
#if FSFW_CPP_OSTREAM_ENABLED == 1
friend std::ostream &operator<<(std::ostream &os, const TransactionId &id) {
os << "Source ID { " << id.entityId << " }, Sequence Number " << id.seqNum.getValue();
return os;
}
#endif
2022-08-09 18:51:44 +02:00
EntityId entityId;
TransactionSeqNum seqNum;
};
2022-02-02 10:29:30 +01:00
} // namespace cfdp
2022-08-09 14:39:03 +02:00
#endif /* FSFW_CFDP_PDU_VARLENFIELD_H_ */