CFDP SOURCE handler #157

Merged
muellerr merged 107 commits from cfdp-source-handler into develop 2023-10-19 10:59:55 +02:00
Showing only changes of commit 7aeb25e064 - Show all commits

View File

@ -2,6 +2,7 @@
#include <catch2/catch_test_macros.hpp> #include <catch2/catch_test_macros.hpp>
#include <filesystem> #include <filesystem>
#include <random>
#include "fsfw/cfdp.h" #include "fsfw/cfdp.h"
#include "fsfw/cfdp/handler/PutRequest.h" #include "fsfw/cfdp/handler/PutRequest.h"
@ -26,6 +27,8 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") {
using namespace cfdp; using namespace cfdp;
using namespace returnvalue; using namespace returnvalue;
using namespace std::filesystem; using namespace std::filesystem;
const size_t MAX_FILE_SEGMENT_SIZE = 255;
MessageQueueId_t destQueueId = 2; MessageQueueId_t destQueueId = 2;
AcceptsTmMock tmReceiver(destQueueId); AcceptsTmMock tmReceiver(destQueueId);
MessageQueueMock mqMock(destQueueId); MessageQueueMock mqMock(destQueueId);
@ -48,6 +51,7 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") {
auto sourceHandler = SourceHandler(dp, fp); auto sourceHandler = SourceHandler(dp, fp);
RemoteEntityCfg cfg; RemoteEntityCfg cfg;
cfg.maxFileSegmentLen = MAX_FILE_SEGMENT_SIZE;
EntityId id(cfdp::WidthInBytes::TWO_BYTES, 5); EntityId id(cfdp::WidthInBytes::TWO_BYTES, 5);
cfg.remoteId = id; cfg.remoteId = id;
std::string srcFileName = "/tmp/cfdp-test.txt"; std::string srcFileName = "/tmp/cfdp-test.txt";
@ -138,6 +142,8 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") {
// Verify metadata PDU was sent. // Verify metadata PDU was sent.
genericMetadataCheck(fsmResult, expectedFileSize); genericMetadataCheck(fsmResult, expectedFileSize);
// Verify that a small file data PDU was sent.
fsmResult = sourceHandler.stateMachine(); fsmResult = sourceHandler.stateMachine();
TmTcMessage tmtcMessage; TmTcMessage tmtcMessage;
const uint8_t* pduPtr; const uint8_t* pduPtr;
@ -167,5 +173,61 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") {
CHECK(sourceHandler.getState() == CfdpState::IDLE); CHECK(sourceHandler.getState() == CfdpState::IDLE);
} }
SECTION("Transfer two segment file") {} SECTION("Transfer two segment file") {
// Create 400 bytes of random data. This should result in two file segments, with one
// having the maximum size.
std::random_device dev;
std::mt19937 rng(dev());
std::uniform_int_distribution<std::mt19937::result_type> distU8(0, 255);
std::array<uint8_t, 400> largerFileData{};
for (auto& val : largerFileData) {
val = distU8(rng);
}
size_t expectedFileSize = largerFileData.size();
fsMock.createFile(srcFileNameFs);
FileOpParams params(srcFileName.c_str(), expectedFileSize);
fsMock.writeToFile(params, reinterpret_cast<const uint8_t*>(largerFileData.data()));
CHECK(sourceHandler.transactionStart(putRequest, cfg) == OK);
SourceHandler::FsmResult& fsmResult = sourceHandler.stateMachine();
// Verify metadata PDU was sent.
genericMetadataCheck(fsmResult, expectedFileSize);
// Check first file data PDU. It should have the maximum file segment size.
fsmResult = sourceHandler.stateMachine();
TmTcMessage tmtcMessage;
const uint8_t* pduPtr;
FileDataInfo fdInfo;
auto accessor = onePduSentCheck(fsmResult, tmtcMessage, &pduPtr);
{
FileDataReader fdReader(pduPtr, accessor.second.size(), fdInfo);
// 10 byte PDU header, 4 byte offset, 255 byte file data
CHECK(accessor.second.size() == 269);
CHECK(fdReader.parseData() == OK);
CHECK(fdInfo.getOffset().value() == 0);
size_t fileSize = 0;
const uint8_t* fileData = fdInfo.getFileData(&fileSize);
// Maximum file segment size.
REQUIRE(fileSize == MAX_FILE_SEGMENT_SIZE);
for (unsigned i = 0; i < fileSize; i++) {
CHECK(fileData[i] == largerFileData[i]);
}
}
mqMock.clearMessages();
// Check second file data PDU.
fsmResult = sourceHandler.stateMachine();
accessor = onePduSentCheck(fsmResult, tmtcMessage, &pduPtr);
FileDataReader fdReader(pduPtr, accessor.second.size(), fdInfo);
// 10 byte PDU header, 4 byte offset, remaining file data (400 - 255 == 145).
CHECK(accessor.second.size() == 10 + 4 + largerFileData.size() - MAX_FILE_SEGMENT_SIZE);
CHECK(fdReader.parseData() == OK);
CHECK(fdInfo.getOffset().value() == MAX_FILE_SEGMENT_SIZE);
size_t fileDataSize = 0;
const uint8_t* fileData = fdInfo.getFileData(&fileDataSize);
// Maximum file segment size.
REQUIRE(fileDataSize == largerFileData.size() - MAX_FILE_SEGMENT_SIZE);
for (unsigned i = 0; i < fileDataSize; i++) {
CHECK(fileData[i] == largerFileData[MAX_FILE_SEGMENT_SIZE + i]);
}
}
} }