CFDP SOURCE handler #157
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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()) {
|
||||||
|
@ -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) {
|
||||||
|
@ -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;
|
||||||
|
@ -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") {}
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user