125 lines
4.3 KiB
C++
125 lines
4.3 KiB
C++
|
#include "FilestoreResponseTlv.h"
|
||
|
|
||
|
FilestoreResponseTlv::FilestoreResponseTlv(cfdp::FilestoreActionCode actionCode, uint8_t statusCode,
|
||
|
cfdp::Lv& firstFileName, cfdp::Lv* fsMsg): FilestoreTlvBase(actionCode, firstFileName),
|
||
|
statusCode(statusCode), filestoreMsg(fsMsg) {
|
||
|
}
|
||
|
|
||
|
FilestoreResponseTlv::FilestoreResponseTlv(cfdp::Lv &firstFileName, cfdp::Lv* fsMsg):
|
||
|
FilestoreTlvBase(firstFileName), statusCode(0), filestoreMsg(fsMsg) {
|
||
|
}
|
||
|
|
||
|
uint8_t FilestoreResponseTlv::getLengthField() const {
|
||
|
size_t optFieldsLen = 0;
|
||
|
if(secondFileName != nullptr) {
|
||
|
optFieldsLen += secondFileName->getSerializedSize();
|
||
|
}
|
||
|
if(filestoreMsg != nullptr) {
|
||
|
optFieldsLen += filestoreMsg->getSerializedSize();
|
||
|
} else {
|
||
|
optFieldsLen += 1;
|
||
|
}
|
||
|
return 1 + firstFileName.getSerializedSize() + optFieldsLen;
|
||
|
}
|
||
|
|
||
|
void FilestoreResponseTlv::setSecondFileName(cfdp::Lv *secondFileName) {
|
||
|
this->secondFileName = secondFileName;
|
||
|
}
|
||
|
|
||
|
void FilestoreResponseTlv::setFilestoreMessage(cfdp::Lv *filestoreMsg) {
|
||
|
this->filestoreMsg = filestoreMsg;
|
||
|
}
|
||
|
|
||
|
ReturnValue_t FilestoreResponseTlv::serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||
|
Endianness streamEndianness) const {
|
||
|
ReturnValue_t result = commonSerialize(buffer, size, maxSize, streamEndianness,
|
||
|
true, this->statusCode);
|
||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||
|
return result;
|
||
|
}
|
||
|
result = firstFileName.serialize(buffer, size, maxSize, streamEndianness);
|
||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||
|
return result;
|
||
|
}
|
||
|
if(requiresSecondFileName()) {
|
||
|
if(secondFileName == nullptr) {
|
||
|
secondFileNameMissing();
|
||
|
return cfdp::FILESTORE_REQUIRES_SECOND_FILE;
|
||
|
}
|
||
|
}
|
||
|
if(filestoreMsg != nullptr) {
|
||
|
result = filestoreMsg->serialize(buffer, size, maxSize, streamEndianness);
|
||
|
}
|
||
|
else {
|
||
|
if(*size == maxSize) {
|
||
|
return SerializeIF::BUFFER_TOO_SHORT;
|
||
|
}
|
||
|
**buffer = 0;
|
||
|
*buffer += 1;
|
||
|
*size +=1;
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
ReturnValue_t FilestoreResponseTlv::deSerialize(const uint8_t **buffer, size_t *size,
|
||
|
Endianness streamEndianness) {
|
||
|
ReturnValue_t result = commonDeserialize(buffer, size, streamEndianness);
|
||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||
|
return result;
|
||
|
}
|
||
|
return deSerializeFromValue(buffer, size, streamEndianness);
|
||
|
}
|
||
|
|
||
|
ReturnValue_t FilestoreResponseTlv::deSerializeFromValue(const uint8_t **buffer, size_t *size,
|
||
|
Endianness streamEndianness) {
|
||
|
|
||
|
// The common function above checks whether at least one byte is remaining
|
||
|
this->actionCode = static_cast<cfdp::FilestoreActionCode>((**buffer >> 4) & 0x0f);
|
||
|
this->statusCode = **buffer & 0x0f;
|
||
|
*buffer += 1;
|
||
|
*size -= 1;
|
||
|
ReturnValue_t result = firstFileName.deSerialize(buffer, size, streamEndianness);
|
||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||
|
return result;
|
||
|
}
|
||
|
if(requiresSecondFileName()) {
|
||
|
if(secondFileName == nullptr) {
|
||
|
return cfdp::FILESTORE_REQUIRES_SECOND_FILE;
|
||
|
}
|
||
|
result = secondFileName->deSerialize(buffer, size, streamEndianness);
|
||
|
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||
|
return result;
|
||
|
}
|
||
|
}
|
||
|
// If the filestore message is not empty, the deserialization is only considered successfully
|
||
|
// if the filestore message can be parsed. Also, if data follows after the FS response,
|
||
|
// the FS msg needs to be set as well.
|
||
|
if(*size == 0 or (*size > 1 and filestoreMsg == nullptr)) {
|
||
|
// Filestore message missing or can't parse it
|
||
|
return cfdp::FILESTORE_RESPONSE_CANT_PARSE_FS_MESSAGE;
|
||
|
}
|
||
|
if(filestoreMsg == nullptr) {
|
||
|
*size -= 1;
|
||
|
*buffer += 1;
|
||
|
// Ignore empty filestore message
|
||
|
return HasReturnvaluesIF::RETURN_OK;
|
||
|
}
|
||
|
return filestoreMsg->deSerialize(buffer, size, streamEndianness);
|
||
|
}
|
||
|
|
||
|
ReturnValue_t FilestoreResponseTlv::deSerialize(const cfdp::Tlv &tlv, Endianness endianness) {
|
||
|
const uint8_t* ptr = tlv.getValue();
|
||
|
size_t remSz = tlv.getSerializedSize();
|
||
|
|
||
|
return deSerializeFromValue(&ptr, &remSz, endianness);
|
||
|
}
|
||
|
|
||
|
uint8_t FilestoreResponseTlv::getStatusCode() const {
|
||
|
return statusCode;
|
||
|
}
|
||
|
|
||
|
|
||
|
cfdp::TlvTypes FilestoreResponseTlv::getType() const {
|
||
|
return cfdp::TlvTypes::FILESTORE_RESPONSE;
|
||
|
}
|