fsfw/src/fsfw/cfdp/tlv/Tlv.cpp

108 lines
2.5 KiB
C++
Raw Normal View History

#include "Tlv.h"
2022-09-15 18:41:15 +02:00
cfdp::Tlv::Tlv(TlvType type, const uint8_t *value, size_t size)
2022-02-02 10:29:30 +01:00
: type(type), value(value, size, true) {
if (size > 0) {
zeroLen = false;
}
}
2022-02-02 10:29:30 +01:00
cfdp::Tlv::Tlv() : value(static_cast<uint8_t *>(nullptr), 0, true) {}
ReturnValue_t cfdp::Tlv::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
2022-02-02 10:29:30 +01:00
Endianness streamEndianness) const {
if (buffer == nullptr or size == nullptr) {
2022-08-15 20:28:16 +02:00
return returnvalue::FAILED;
2022-02-02 10:29:30 +01:00
}
if (*size + 2 > maxSize) {
return BUFFER_TOO_SHORT;
}
2022-09-15 18:41:15 +02:00
if (type == TlvType::INVALID_TLV) {
2022-02-02 10:29:30 +01:00
return INVALID_TLV_TYPE;
}
**buffer = type;
*size += 1;
*buffer += 1;
if (zeroLen) {
**buffer = 0;
*size += 1;
*buffer += 1;
2022-08-15 20:28:16 +02:00
return returnvalue::OK;
2022-02-02 10:29:30 +01:00
}
if (value.getConstBuffer() == nullptr) {
2022-08-15 20:28:16 +02:00
return returnvalue::FAILED;
2022-02-02 10:29:30 +01:00
}
return value.serialize(buffer, size, maxSize, streamEndianness);
}
size_t cfdp::Tlv::getSerializedSize() const {
2022-02-02 10:29:30 +01:00
if (zeroLen) {
return 2;
} else if (value.getConstBuffer() == nullptr) {
return 0;
}
return value.getSerializedSize() + 1;
}
ReturnValue_t cfdp::Tlv::deSerialize(const uint8_t **buffer, size_t *size,
2022-02-02 10:29:30 +01:00
Endianness streamEndianness) {
if (buffer == nullptr or size == nullptr) {
2022-08-15 20:28:16 +02:00
return returnvalue::FAILED;
2022-02-02 10:29:30 +01:00
}
if (*size < 2) {
return STREAM_TOO_SHORT;
}
rawData = *buffer;
2022-02-02 10:29:30 +01:00
uint8_t rawType = **buffer;
if (not checkType(rawType)) {
return INVALID_TLV_TYPE;
}
2022-09-15 18:41:15 +02:00
type = static_cast<TlvType>(rawType);
2022-02-02 10:29:30 +01:00
*buffer += 1;
*size -= 1;
2022-02-02 10:29:30 +01:00
size_t lengthField = **buffer;
if (lengthField == 0) {
zeroLen = true;
*buffer += 1;
*size -= 1;
2022-08-15 20:28:16 +02:00
return returnvalue::OK;
2022-02-02 10:29:30 +01:00
}
if (lengthField + 1 > *size) {
return SerializeIF::STREAM_TOO_SHORT;
}
zeroLen = false;
// Zero-copy implementation
2022-09-05 16:31:56 +02:00
value.setConstBuffer(*buffer + 1, lengthField);
2022-02-02 10:29:30 +01:00
*buffer += 1 + lengthField;
*size -= 1 + lengthField;
2022-08-15 20:28:16 +02:00
return returnvalue::OK;
}
2022-02-02 10:29:30 +01:00
const uint8_t *cfdp::Tlv::getValue() const { return value.getConstBuffer(); }
2022-09-15 18:41:15 +02:00
cfdp::TlvType cfdp::Tlv::getType() const { return type; }
bool cfdp::Tlv::checkType(uint8_t rawType) {
2022-02-02 10:29:30 +01:00
if (rawType != 0x03 and rawType <= 6) {
return true;
}
return false;
}
void cfdp::Tlv::setValue(uint8_t *value, size_t len) {
2022-02-02 10:29:30 +01:00
if (len > 0) {
zeroLen = false;
}
2022-09-05 16:31:56 +02:00
this->value.setConstBuffer(value, len);
}
2022-02-02 10:29:30 +01:00
uint8_t cfdp::Tlv::getLengthField() const { return this->value.getSerializedSize() - 1; }
2022-09-15 18:41:15 +02:00
void cfdp::Tlv::setType(TlvType type) { this->type = type; }
const uint8_t *cfdp::Tlv::getRawData() const { return rawData; }