CFDP SOURCE handler #157

Merged
muellerr merged 107 commits from cfdp-source-handler into develop 2023-10-19 10:59:55 +02:00
6 changed files with 51 additions and 28 deletions
Showing only changes of commit 7c875f1067 - Show all commits

View File

@ -156,8 +156,7 @@ ReturnValue_t cfdp::DestHandler::handleFileDataPdu(const cfdp::PacketInfo& info)
// TODO: This is not a CFDP error. Event and/or warning? // TODO: This is not a CFDP error. Event and/or warning?
return constAccessorPair.first; return constAccessorPair.first;
} }
cfdp::Fss offset; FileDataInfo fdInfo;
FileDataInfo fdInfo(offset);
FileDataReader reader(constAccessorPair.second.data(), constAccessorPair.second.size(), fdInfo); FileDataReader reader(constAccessorPair.second.data(), constAccessorPair.second.size(), fdInfo);
ReturnValue_t result = reader.parseData(); ReturnValue_t result = reader.parseData();
if (result != OK) { if (result != OK) {
@ -166,10 +165,10 @@ ReturnValue_t cfdp::DestHandler::handleFileDataPdu(const cfdp::PacketInfo& info)
size_t fileSegmentLen = 0; size_t fileSegmentLen = 0;
const uint8_t* fileData = fdInfo.getFileData(&fileSegmentLen); const uint8_t* fileData = fdInfo.getFileData(&fileSegmentLen);
FileOpParams fileOpParams(transactionParams.destName.data(), fileSegmentLen); FileOpParams fileOpParams(transactionParams.destName.data(), fileSegmentLen);
fileOpParams.offset = offset.value(); fileOpParams.offset = fdInfo.getOffset().value();
if (destParams.cfg.indicCfg.fileSegmentRecvIndicRequired) { if (destParams.cfg.indicCfg.fileSegmentRecvIndicRequired) {
FileSegmentRecvdParams segParams; FileSegmentRecvdParams segParams;
segParams.offset = offset.value(); segParams.offset = fdInfo.getOffset().value();
segParams.id = transactionParams.transactionId; segParams.id = transactionParams.transactionId;
segParams.length = fileSegmentLen; segParams.length = fileSegmentLen;
segParams.recContState = fdInfo.getRecordContinuationState(); segParams.recContState = fdInfo.getRecordContinuationState();
@ -196,8 +195,8 @@ ReturnValue_t cfdp::DestHandler::handleFileDataPdu(const cfdp::PacketInfo& info)
transactionParams.deliveryStatus = FileDeliveryStatus::RETAINED_IN_FILESTORE; transactionParams.deliveryStatus = FileDeliveryStatus::RETAINED_IN_FILESTORE;
transactionParams.vfsErrorCount = 0; transactionParams.vfsErrorCount = 0;
} }
if (offset.value() + fileSegmentLen > transactionParams.progress) { if (fdInfo.getOffset().value() + fileSegmentLen > transactionParams.progress) {
transactionParams.progress = offset.value() + fileSegmentLen; transactionParams.progress = fdInfo.getOffset().value() + fileSegmentLen;
} }
return result; return result;
} }

View File

@ -120,7 +120,7 @@ ReturnValue_t cfdp::SourceHandler::checksumGeneration() {
std::array<uint8_t, 1024> buf{}; std::array<uint8_t, 1024> buf{};
etl::crc32 crcCalc; etl::crc32 crcCalc;
uint64_t currentOffset = 0; uint64_t currentOffset = 0;
FileOpParams params(transactionParams.destName.data(), transactionParams.fileSize.value()); FileOpParams params(transactionParams.sourceName.data(), transactionParams.fileSize.value());
while (currentOffset < transactionParams.fileSize.value()) { while (currentOffset < transactionParams.fileSize.value()) {
uint64_t readLen; uint64_t readLen;
if (currentOffset + buf.size() > transactionParams.fileSize.value()) { if (currentOffset + buf.size() > transactionParams.fileSize.value()) {

View File

@ -1,9 +1,9 @@
#include "FileDataInfo.h" #include "FileDataInfo.h"
FileDataInfo::FileDataInfo(cfdp::Fss &offset, const uint8_t *fileData, size_t fileSize) #include <utility>
: offset(offset), fileData(fileData), fileSize(fileSize) {}
FileDataInfo::FileDataInfo(cfdp::Fss &offset) : offset(offset) {} FileDataInfo::FileDataInfo(cfdp::Fss offset, const uint8_t *fileData, size_t fileSize)
: offset(std::move(offset)), fileData(fileData), fileSize(fileSize) {}
void FileDataInfo::setSegmentMetadataFlag(bool enable) { void FileDataInfo::setSegmentMetadataFlag(bool enable) {
if (enable) { if (enable) {

View File

@ -6,8 +6,8 @@
class FileDataInfo { class FileDataInfo {
public: public:
explicit FileDataInfo(cfdp::Fss& offset); FileDataInfo() = default;
FileDataInfo(cfdp::Fss& offset, const uint8_t* fileData, size_t fileSize); FileDataInfo(cfdp::Fss offset, const uint8_t* fileData, size_t fileSize);
[[nodiscard]] size_t getSerializedSize(bool largeFile = false) const; [[nodiscard]] size_t getSerializedSize(bool largeFile = false) const;
@ -33,7 +33,7 @@ class FileDataInfo {
private: private:
cfdp::SegmentMetadataFlag segmentMetadataFlag = cfdp::SegmentMetadataFlag::NOT_PRESENT; cfdp::SegmentMetadataFlag segmentMetadataFlag = cfdp::SegmentMetadataFlag::NOT_PRESENT;
cfdp::SegmentationControl segCtrl = cfdp::SegmentationControl::NO_RECORD_BOUNDARIES_PRESERVATION; cfdp::SegmentationControl segCtrl = cfdp::SegmentationControl::NO_RECORD_BOUNDARIES_PRESERVATION;
cfdp::Fss& offset; cfdp::Fss offset;
const uint8_t* fileData = nullptr; const uint8_t* fileData = nullptr;
size_t fileSize = 0; size_t fileSize = 0;
cfdp::RecordContinuationState recContState = cfdp::RecordContinuationState::NO_START_NO_END; cfdp::RecordContinuationState recContState = cfdp::RecordContinuationState::NO_START_NO_END;

View File

@ -1,3 +1,5 @@
#include <etl/crc32.h>
#include <catch2/catch_test_macros.hpp> #include <catch2/catch_test_macros.hpp>
#include <filesystem> #include <filesystem>
@ -6,6 +8,7 @@
#include "fsfw/cfdp/handler/SourceHandler.h" #include "fsfw/cfdp/handler/SourceHandler.h"
#include "fsfw/cfdp/pdu/EofPduCreator.h" #include "fsfw/cfdp/pdu/EofPduCreator.h"
#include "fsfw/cfdp/pdu/EofPduReader.h" #include "fsfw/cfdp/pdu/EofPduReader.h"
#include "fsfw/cfdp/pdu/FileDataReader.h"
#include "fsfw/cfdp/pdu/MetadataPduCreator.h" #include "fsfw/cfdp/pdu/MetadataPduCreator.h"
#include "fsfw/cfdp/pdu/MetadataPduReader.h" #include "fsfw/cfdp/pdu/MetadataPduReader.h"
#include "fsfw/tmtcservices/TmTcMessage.h" #include "fsfw/tmtcservices/TmTcMessage.h"
@ -57,15 +60,20 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") {
PutRequest putRequest(id, srcNameLv, destNameLv); PutRequest putRequest(id, srcNameLv, destNameLv);
CHECK(sourceHandler.initialize() == OK); CHECK(sourceHandler.initialize() == OK);
auto genericMetadataCheck = [&](SourceHandler::FsmResult& fsmResult, size_t expectedFileSize) { auto onePduSentCheck = [&](SourceHandler::FsmResult& fsmResult, TmTcMessage& tmtcMessage,
TmTcMessage tmtcMessage; const uint8_t** pduPtr) {
const uint8_t* pduPtr;
CHECK(fsmResult.packetsSent == 1); CHECK(fsmResult.packetsSent == 1);
CHECK(mqMock.numberOfSentMessages() == 1); CHECK(mqMock.numberOfSentMessages() == 1);
REQUIRE(mqMock.getNextSentMessage(destQueueId, tmtcMessage) == OK); REQUIRE(mqMock.getNextSentMessage(destQueueId, tmtcMessage) == OK);
auto accessor = tmStore.getData(tmtcMessage.getStorageId()); auto accessor = tmStore.getData(tmtcMessage.getStorageId());
REQUIRE(accessor.first == OK); REQUIRE(accessor.first == OK);
pduPtr = accessor.second.data(); *pduPtr = accessor.second.data();
return std::move(accessor);
};
auto genericMetadataCheck = [&](SourceHandler::FsmResult& fsmResult, size_t expectedFileSize) {
TmTcMessage tmtcMessage;
const uint8_t* pduPtr;
auto accessor = onePduSentCheck(fsmResult, tmtcMessage, &pduPtr);
CHECK(accessor.second.size() == 55); CHECK(accessor.second.size() == 55);
MetadataGenericInfo metadataInfo; MetadataGenericInfo metadataInfo;
MetadataPduReader metadataReader(pduPtr, accessor.second.size(), metadataInfo, nullptr, 0); MetadataPduReader metadataReader(pduPtr, accessor.second.size(), metadataInfo, nullptr, 0);
@ -87,12 +95,7 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") {
uint32_t expectedChecksum) { uint32_t expectedChecksum) {
TmTcMessage tmtcMessage; TmTcMessage tmtcMessage;
const uint8_t* pduPtr; const uint8_t* pduPtr;
CHECK(fsmResult.packetsSent == 1); auto accessor = onePduSentCheck(fsmResult, tmtcMessage, &pduPtr);
CHECK(mqMock.numberOfSentMessages() == 1);
REQUIRE(mqMock.getNextSentMessage(destQueueId, tmtcMessage) == OK);
auto accessor = tmStore.getData(tmtcMessage.getStorageId());
REQUIRE(accessor.first == OK);
pduPtr = accessor.second.data();
// 10 byte PDU header, 1 byte directive field, 1 byte condition code, 4 byte checksum, // 10 byte PDU header, 1 byte directive field, 1 byte condition code, 4 byte checksum,
// 4 byte FSS // 4 byte FSS
CHECK(accessor.second.size() == 20); CHECK(accessor.second.size() == 20);
@ -136,10 +139,32 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") {
// Verify metadata PDU was sent. // Verify metadata PDU was sent.
genericMetadataCheck(fsmResult, expectedFileSize); genericMetadataCheck(fsmResult, expectedFileSize);
fsmResult = sourceHandler.stateMachine(); fsmResult = sourceHandler.stateMachine();
// TODO: Verify one file data PDU was sent. TmTcMessage tmtcMessage;
CHECK(fsmResult.packetsSent == 1); const uint8_t* pduPtr;
auto accessor = onePduSentCheck(fsmResult, tmtcMessage, &pduPtr);
FileDataInfo fdInfo;
FileDataReader fdReader(pduPtr, accessor.second.size(), fdInfo);
// 10 byte PDU header, 4 byte offset, 12 bytes file data.
CHECK(accessor.second.size() == 26);
CHECK(fdReader.parseData() == OK);
CHECK(fdInfo.getOffset().value() == 0);
size_t fileSize = 0;
const uint8_t* fileData = fdInfo.getFileData(&fileSize);
REQUIRE(fileSize == fileContent.size());
CHECK(fileData != nullptr);
std::string dataReadBack(reinterpret_cast<const char*>(fileData), fileSize);
CHECK(dataReadBack == fileContent);
mqMock.clearMessages();
// TODO: Verify one EOF PDU was sent. fsmResult = sourceHandler.stateMachine();
etl::crc32 crcCalc;
crcCalc.add(fileContent.data(), fileContent.data() + fileContent.size());
// Verify EOF PDU was sent.
genericEofCheck(fsmResult, expectedFileSize, crcCalc.value());
CHECK(sourceHandler.getStep() == SourceHandler::TransactionStep::IDLE);
CHECK(sourceHandler.getState() == CfdpState::IDLE);
} }
SECTION("Transfer two segment file") {} SECTION("Transfer two segment file") {}

View File

@ -107,8 +107,7 @@ TEST_CASE("File Data PDU", "[cfdp][pdu]") {
serializer.serialize(&buffer, &sz, fileDataBuffer.size(), SerializeIF::Endianness::NETWORK); serializer.serialize(&buffer, &sz, fileDataBuffer.size(), SerializeIF::Endianness::NETWORK);
REQUIRE(result == returnvalue::OK); REQUIRE(result == returnvalue::OK);
Fss emptyOffset; FileDataInfo emptyInfo;
FileDataInfo emptyInfo(emptyOffset);
FileDataReader deserializer(fileDataBuffer.data(), fileDataBuffer.size(), emptyInfo); FileDataReader deserializer(fileDataBuffer.data(), fileDataBuffer.size(), emptyInfo);
result = deserializer.parseData(); result = deserializer.parseData();
REQUIRE(result == returnvalue::OK); REQUIRE(result == returnvalue::OK);