2021-12-03 15:37:49 +01:00
|
|
|
#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;
|
|
|
|
}
|
2021-12-03 15:37:49 +01:00
|
|
|
}
|
|
|
|
|
2022-02-02 10:29:30 +01:00
|
|
|
cfdp::Tlv::Tlv() : value(static_cast<uint8_t *>(nullptr), 0, true) {}
|
2021-12-03 15:37:49 +01:00
|
|
|
|
|
|
|
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;
|
2021-12-03 15:37:49 +01:00
|
|
|
*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);
|
2021-12-03 15:37:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
2021-12-03 15:37:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2023-08-16 13:10:21 +02:00
|
|
|
rawData = *buffer;
|
2022-02-02 10:29:30 +01:00
|
|
|
uint8_t rawType = **buffer;
|
|
|
|
if (not checkType(rawType)) {
|
|
|
|
return INVALID_TLV_TYPE;
|
|
|
|
}
|
2021-12-03 15:37:49 +01:00
|
|
|
|
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;
|
2021-12-03 15:37:49 +01:00
|
|
|
|
2022-02-02 10:29:30 +01:00
|
|
|
size_t lengthField = **buffer;
|
|
|
|
if (lengthField == 0) {
|
|
|
|
zeroLen = true;
|
2021-12-03 15:37:49 +01:00
|
|
|
*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;
|
2021-12-03 15:37:49 +01:00
|
|
|
}
|
|
|
|
|
2022-02-02 10:29:30 +01:00
|
|
|
const uint8_t *cfdp::Tlv::getValue() const { return value.getConstBuffer(); }
|
2021-12-03 15:37:49 +01:00
|
|
|
|
2022-09-15 18:41:15 +02:00
|
|
|
cfdp::TlvType cfdp::Tlv::getType() const { return type; }
|
2021-12-03 15:37:49 +01:00
|
|
|
|
|
|
|
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;
|
2021-12-03 15:37:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
2021-12-03 15:37:49 +01:00
|
|
|
}
|
|
|
|
|
2022-02-02 10:29:30 +01:00
|
|
|
uint8_t cfdp::Tlv::getLengthField() const { return this->value.getSerializedSize() - 1; }
|
2021-12-03 15:37:49 +01:00
|
|
|
|
2022-09-15 18:41:15 +02:00
|
|
|
void cfdp::Tlv::setType(TlvType type) { this->type = type; }
|
2023-08-16 13:10:21 +02:00
|
|
|
|
|
|
|
const uint8_t *cfdp::Tlv::getRawData() const { return rawData; }
|