fsfw/unittests/cfdp/pdu/testNakPdu.cpp

153 lines
6.9 KiB
C++

#include <array>
#include <catch2/catch_test_macros.hpp>
#include "fsfw/cfdp/pdu/NakPduCreator.h"
#include "fsfw/cfdp/pdu/NakPduReader.h"
#include "fsfw/cfdp/pdu/PduConfig.h"
#include "fsfw/globalfunctions/arrayprinter.h"
TEST_CASE("NAK PDU", "[cfdp][pdu]") {
using namespace cfdp;
ReturnValue_t result = returnvalue::OK;
std::array<uint8_t, 256> nakBuffer = {};
uint8_t* buffer = nakBuffer.data();
size_t sz = 0;
EntityId destId(WidthInBytes::TWO_BYTES, 2);
TransactionSeqNum seqNum(WidthInBytes::TWO_BYTES, 15);
EntityId sourceId(WidthInBytes::TWO_BYTES, 1);
PduConfig pduConf(sourceId, destId, TransmissionMode::ACKNOWLEDGED, seqNum);
Fss startOfScope(50);
Fss endOfScope(1050);
NakInfo info(startOfScope, endOfScope);
SECTION("Serializer") {
NakPduCreator serializer(pduConf, info);
result = serializer.serialize(&buffer, &sz, nakBuffer.size(), SerializeIF::Endianness::NETWORK);
REQUIRE(result == returnvalue::OK);
REQUIRE(serializer.getSerializedSize() == 19);
REQUIRE(serializer.FileDirectiveCreator::getSerializedSize() == 11);
REQUIRE(sz == 19);
REQUIRE(serializer.getPduDataFieldLen() == 9);
REQUIRE(((nakBuffer[1] << 8) | nakBuffer[2]) == 0x09);
REQUIRE(nakBuffer[10] == cfdp::FileDirective::NAK);
uint32_t scope = 0;
result = SerializeAdapter::deSerialize(&scope, nakBuffer.data() + 11, nullptr,
SerializeIF::Endianness::NETWORK);
REQUIRE(result == returnvalue::OK);
REQUIRE(scope == 50);
result = SerializeAdapter::deSerialize(&scope, nakBuffer.data() + 15, nullptr,
SerializeIF::Endianness::NETWORK);
REQUIRE(result == returnvalue::OK);
REQUIRE(scope == 1050);
NakInfo::SegmentRequest segReq0(cfdp::Fss(2020), cfdp::Fss(2520));
NakInfo::SegmentRequest segReq1(cfdp::Fss(2932), cfdp::Fss(3021));
// Now add 2 segment requests to NAK info and serialize them as well
std::array<NakInfo::SegmentRequest, 2> segReqs = {segReq0, segReq1};
size_t segReqsLen = segReqs.size();
info.setSegmentRequests(segReqs.data(), &segReqsLen, &segReqsLen);
uint8_t* buffer = nakBuffer.data();
size_t sz = 0;
serializer.updateDirectiveFieldLen();
result = serializer.serialize(&buffer, &sz, nakBuffer.size(), SerializeIF::Endianness::NETWORK);
REQUIRE(result == returnvalue::OK);
REQUIRE(serializer.getSerializedSize() == 35);
REQUIRE(serializer.getPduDataFieldLen() == 25);
REQUIRE(((nakBuffer[1] << 8) | nakBuffer[2]) == 25);
uint32_t segReqScopes = 0;
result = SerializeAdapter::deSerialize(&segReqScopes, nakBuffer.data() + 19, nullptr,
SerializeIF::Endianness::NETWORK);
REQUIRE(result == returnvalue::OK);
REQUIRE(segReqScopes == 2020);
result = SerializeAdapter::deSerialize(&segReqScopes, nakBuffer.data() + 23, nullptr,
SerializeIF::Endianness::NETWORK);
REQUIRE(result == returnvalue::OK);
REQUIRE(segReqScopes == 2520);
result = SerializeAdapter::deSerialize(&segReqScopes, nakBuffer.data() + 27, nullptr,
SerializeIF::Endianness::NETWORK);
REQUIRE(result == returnvalue::OK);
REQUIRE(segReqScopes == 2932);
result = SerializeAdapter::deSerialize(&segReqScopes, nakBuffer.data() + 31, nullptr,
SerializeIF::Endianness::NETWORK);
REQUIRE(result == returnvalue::OK);
REQUIRE(segReqScopes == 3021);
for (size_t maxSz = 0; maxSz < 35; maxSz++) {
uint8_t* buffer = nakBuffer.data();
size_t sz = 0;
result = serializer.serialize(&buffer, &sz, maxSz, SerializeIF::Endianness::NETWORK);
REQUIRE(result == SerializeIF::BUFFER_TOO_SHORT);
}
for (size_t sz = 35; sz > 0; sz--) {
uint8_t* buffer = nakBuffer.data();
size_t locSize = sz;
result = serializer.serialize(&buffer, &locSize, 35, SerializeIF::Endianness::NETWORK);
REQUIRE(result == SerializeIF::BUFFER_TOO_SHORT);
}
}
SECTION("Deserializer") {
NakPduCreator serializer(pduConf, info);
result = serializer.serialize(&buffer, &sz, nakBuffer.size(), SerializeIF::Endianness::NETWORK);
REQUIRE(result == returnvalue::OK);
info.getStartOfScope().setFileSize(0, false);
info.getEndOfScope().setFileSize(0, false);
NakPduReader deserializer(nakBuffer.data(), nakBuffer.size(), info);
result = deserializer.parseData();
REQUIRE(result == returnvalue::OK);
REQUIRE(deserializer.getWholePduSize() == 19);
REQUIRE(info.getStartOfScope().getSize() == 50);
REQUIRE(info.getEndOfScope().getSize() == 1050);
NakInfo::SegmentRequest segReq0(cfdp::Fss(2020), cfdp::Fss(2520));
NakInfo::SegmentRequest segReq1(cfdp::Fss(2932), cfdp::Fss(3021));
// Now add 2 segment requests to NAK info and serialize them as well
std::array<NakInfo::SegmentRequest, 2> segReqs = {segReq0, segReq1};
size_t segReqsLen = segReqs.size();
info.setSegmentRequests(segReqs.data(), &segReqsLen, &segReqsLen);
uint8_t* buffer = nakBuffer.data();
size_t sz = 0;
serializer.updateDirectiveFieldLen();
result = serializer.serialize(&buffer, &sz, nakBuffer.size(), SerializeIF::Endianness::NETWORK);
REQUIRE(result == returnvalue::OK);
NakPduReader deserializeWithSegReqs(nakBuffer.data(), nakBuffer.size(), info);
result = deserializeWithSegReqs.parseData();
REQUIRE(result == returnvalue::OK);
NakInfo::SegmentRequest* segReqsPtr = nullptr;
size_t readSegReqs = 0;
info.getSegmentRequests(&segReqsPtr, &readSegReqs, nullptr);
REQUIRE(readSegReqs == 2);
REQUIRE(segReqsPtr[0].first.getSize() == 2020);
REQUIRE(segReqsPtr[0].second.getSize() == 2520);
REQUIRE(segReqsPtr[1].first.getSize() == 2932);
REQUIRE(segReqsPtr[1].second.getSize() == 3021);
REQUIRE(deserializeWithSegReqs.getPduDataFieldLen() == 25);
REQUIRE(info.getSegmentRequestsLen() == 2);
for (size_t idx = 0; idx < 34; idx++) {
NakPduReader faultyDeserializer(nakBuffer.data(), idx, info);
result = faultyDeserializer.parseData();
REQUIRE(result != returnvalue::OK);
}
for (size_t pduFieldLen = 0; pduFieldLen < 25; pduFieldLen++) {
nakBuffer[1] = (pduFieldLen >> 8) & 0xff;
nakBuffer[2] = pduFieldLen & 0xff;
NakPduReader faultyDeserializer(nakBuffer.data(), nakBuffer.size(), info);
result = faultyDeserializer.parseData();
if (pduFieldLen == 9) {
REQUIRE(info.getSegmentRequestsLen() == 0);
} else if (pduFieldLen == 17) {
REQUIRE(info.getSegmentRequestsLen() == 1);
} else if (pduFieldLen == 25) {
REQUIRE(info.getSegmentRequestsLen() == 2);
}
if (pduFieldLen != 9 and pduFieldLen != 17 and pduFieldLen != 25) {
REQUIRE(result != returnvalue::OK);
}
}
info.setMaxSegmentRequestLen(5);
REQUIRE(info.getSegmentRequestsMaxLen() == 5);
}
}