CFDP FSFW Integration #111
@ -40,7 +40,7 @@ static constexpr ReturnValue_t FILESTORE_RESPONSE_CANT_PARSE_FS_MESSAGE =
|
|||||||
|
|
||||||
//! Checksum types according to the SANA Checksum Types registry
|
//! Checksum types according to the SANA Checksum Types registry
|
||||||
//! https://sanaregistry.org/r/checksum_identifiers/
|
//! https://sanaregistry.org/r/checksum_identifiers/
|
||||||
enum ChecksumType {
|
enum ChecksumTypes {
|
||||||
// Modular legacy checksum
|
// Modular legacy checksum
|
||||||
MODULAR = 0,
|
MODULAR = 0,
|
||||||
CRC_32_PROXIMITY_1 = 1,
|
CRC_32_PROXIMITY_1 = 1,
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#include "DestHandler.h"
|
#include "DestHandler.h"
|
||||||
|
|
||||||
|
#include <etl/crc32.h>
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "fsfw/FSFW.h"
|
#include "fsfw/FSFW.h"
|
||||||
@ -177,6 +179,8 @@ ReturnValue_t cfdp::DestHandler::handleFileDataPdu(const cfdp::PacketInfo& info)
|
|||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::error << "File write error" << std::endl;
|
sif::error << "File write error" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
} else {
|
||||||
|
tp.deliveryStatus = FileDeliveryStatus::RETAINED_IN_FILESTORE;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -300,7 +304,18 @@ ReturnValue_t cfdp::DestHandler::startTransaction(MetadataPduReader& reader, Met
|
|||||||
cfdp::CfdpStates cfdp::DestHandler::getCfdpState() const { return cfdpState; }
|
cfdp::CfdpStates cfdp::DestHandler::getCfdpState() const { return cfdpState; }
|
||||||
|
|
||||||
ReturnValue_t cfdp::DestHandler::handleTransferCompletion() {
|
ReturnValue_t cfdp::DestHandler::handleTransferCompletion() {
|
||||||
// TODO: Checksum verification and notice of completion
|
ReturnValue_t result;
|
||||||
|
if (tp.checksumType != ChecksumTypes::NULL_CHECKSUM) {
|
||||||
|
result = checksumVerification();
|
||||||
|
if (result != OK) {
|
||||||
|
// TODO: Warning / error handling?
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tp.conditionCode = ConditionCode::NO_ERROR;
|
||||||
|
}
|
||||||
|
result = noticeOfCompletion();
|
||||||
|
if (result != OK) {
|
||||||
|
}
|
||||||
if (cfdpState == CfdpStates::BUSY_CLASS_1_NACKED) {
|
if (cfdpState == CfdpStates::BUSY_CLASS_1_NACKED) {
|
||||||
if (tp.closureRequested) {
|
if (tp.closureRequested) {
|
||||||
step = TransactionStep::SENDING_FINISHED_PDU;
|
step = TransactionStep::SENDING_FINISHED_PDU;
|
||||||
@ -310,8 +325,60 @@ ReturnValue_t cfdp::DestHandler::handleTransferCompletion() {
|
|||||||
} else if (cfdpState == CfdpStates::BUSY_CLASS_2_ACKED) {
|
} else if (cfdpState == CfdpStates::BUSY_CLASS_2_ACKED) {
|
||||||
step = TransactionStep::SENDING_FINISHED_PDU;
|
step = TransactionStep::SENDING_FINISHED_PDU;
|
||||||
}
|
}
|
||||||
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cfdp::DestHandler::finish() {
|
void cfdp::DestHandler::finish() {
|
||||||
// TODO: Clear PDU list, reset state to be ready for next transfer
|
tp.reset();
|
||||||
|
dp.packetListRef.clear();
|
||||||
|
cfdpState = CfdpStates::IDLE;
|
||||||
|
step = TransactionStep::IDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t cfdp::DestHandler::checksumVerification() {
|
||||||
|
std::array<uint8_t, 1024> buf{};
|
||||||
|
// TODO: Checksum verification and notice of completion
|
||||||
|
etl::crc32 crcCalc;
|
||||||
|
uint64_t currentOffset = 0;
|
||||||
|
FileOpParams params(tp.sourceName.data(), buf.size());
|
||||||
|
while (currentOffset < tp.fileSize.value()) {
|
||||||
|
uint64_t readLen = 0;
|
||||||
|
if (currentOffset + buf.size() > tp.fileSize.value()) {
|
||||||
|
readLen = tp.fileSize.value() - currentOffset;
|
||||||
|
} else {
|
||||||
|
readLen = buf.size();
|
||||||
|
}
|
||||||
|
if (readLen > 0) {
|
||||||
|
params.offset = currentOffset;
|
||||||
|
params.size = readLen;
|
||||||
|
auto result = dp.user.vfs.readFromFile(params, buf.data(), buf.size());
|
||||||
|
if (result != OK) {
|
||||||
|
// TODO: Better error handling
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
crcCalc.add(buf.begin(), buf.begin() + readLen);
|
||||||
|
}
|
||||||
|
currentOffset += readLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t value = crcCalc.value();
|
||||||
|
if (value == tp.crc) {
|
||||||
|
tp.conditionCode = ConditionCode::NO_ERROR;
|
||||||
|
tp.deliveryCode = FileDeliveryCode::DATA_COMPLETE;
|
||||||
|
} else {
|
||||||
|
// TODO: Proper error handling
|
||||||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
sif::error << "CRC check for file " << tp.sourceName.data() << " failed" << std::endl;
|
||||||
|
#endif
|
||||||
|
tp.conditionCode = ConditionCode::FILE_CHECKSUM_FAILURE;
|
||||||
|
}
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
ReturnValue_t cfdp::DestHandler::noticeOfCompletion() {
|
||||||
|
if (dp.cfg.indicCfg.transactionFinishedIndicRequired) {
|
||||||
|
TransactionFinishedParams params(tp.transactionId, tp.conditionCode, tp.deliveryCode,
|
||||||
|
tp.deliveryStatus);
|
||||||
|
dp.user.transactionFinishedIndication(params);
|
||||||
|
}
|
||||||
|
return OK;
|
||||||
}
|
}
|
||||||
|
@ -98,13 +98,32 @@ class DestHandler {
|
|||||||
explicit TransactionParams(size_t maxFileNameLen)
|
explicit TransactionParams(size_t maxFileNameLen)
|
||||||
: sourceName(maxFileNameLen), destName(maxFileNameLen) {}
|
: sourceName(maxFileNameLen), destName(maxFileNameLen) {}
|
||||||
|
|
||||||
ChecksumType checksumType = ChecksumType::NULL_CHECKSUM;
|
void reset() {
|
||||||
|
pduConf = PduConfig();
|
||||||
|
transactionId = TransactionId();
|
||||||
|
std::fill(sourceName.begin(), sourceName.end(), '\0');
|
||||||
|
std::fill(destName.begin(), destName.end(), '\0');
|
||||||
|
fileSize.setFileSize(0, false);
|
||||||
|
conditionCode = ConditionCode::NO_ERROR;
|
||||||
|
deliveryCode = FileDeliveryCode::DATA_INCOMPLETE;
|
||||||
|
deliveryStatus = FileDeliveryStatus::DISCARDED_DELIBERATELY;
|
||||||
|
crc = 0;
|
||||||
|
progress = 0;
|
||||||
|
remoteCfg = nullptr;
|
||||||
|
closureRequested = false;
|
||||||
|
checksumType = ChecksumTypes::NULL_CHECKSUM;
|
||||||
|
}
|
||||||
|
|
||||||
|
ChecksumTypes checksumType = ChecksumTypes::NULL_CHECKSUM;
|
||||||
bool closureRequested = false;
|
bool closureRequested = false;
|
||||||
std::vector<char> sourceName;
|
std::vector<char> sourceName;
|
||||||
std::vector<char> destName;
|
std::vector<char> destName;
|
||||||
cfdp::FileSize fileSize;
|
cfdp::FileSize fileSize;
|
||||||
TransactionId transactionId;
|
TransactionId transactionId;
|
||||||
PduConfig pduConf;
|
PduConfig pduConf;
|
||||||
|
ConditionCode conditionCode = ConditionCode::NO_ERROR;
|
||||||
|
FileDeliveryCode deliveryCode = FileDeliveryCode::DATA_INCOMPLETE;
|
||||||
|
FileDeliveryStatus deliveryStatus = FileDeliveryStatus::DISCARDED_DELIBERATELY;
|
||||||
uint32_t crc = 0;
|
uint32_t crc = 0;
|
||||||
uint64_t progress = 0;
|
uint64_t progress = 0;
|
||||||
RemoteEntityCfg* remoteCfg = nullptr;
|
RemoteEntityCfg* remoteCfg = nullptr;
|
||||||
@ -124,6 +143,8 @@ class DestHandler {
|
|||||||
ReturnValue_t handleEofPdu(const PacketInfo& info);
|
ReturnValue_t handleEofPdu(const PacketInfo& info);
|
||||||
ReturnValue_t handleMetadataParseError(const uint8_t* rawData, size_t maxSize);
|
ReturnValue_t handleMetadataParseError(const uint8_t* rawData, size_t maxSize);
|
||||||
ReturnValue_t handleTransferCompletion();
|
ReturnValue_t handleTransferCompletion();
|
||||||
|
ReturnValue_t noticeOfCompletion();
|
||||||
|
ReturnValue_t checksumVerification();
|
||||||
void finish();
|
void finish();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -14,11 +14,11 @@
|
|||||||
namespace cfdp {
|
namespace cfdp {
|
||||||
|
|
||||||
struct TransactionFinishedParams {
|
struct TransactionFinishedParams {
|
||||||
TransactionFinishedParams(TransactionId id, ConditionCode code, FileDeliveryStatus status,
|
TransactionFinishedParams(const TransactionId& id, ConditionCode code, FileDeliveryCode delivCode,
|
||||||
FileDeliveryCode delivCode)
|
FileDeliveryStatus status)
|
||||||
: id(std::move(id)), condCode(code), status(status), deliveryCode(delivCode) {}
|
: id(id), condCode(code), status(status), deliveryCode(delivCode) {}
|
||||||
|
|
||||||
TransactionId id;
|
const TransactionId& id;
|
||||||
ConditionCode condCode;
|
ConditionCode condCode;
|
||||||
FileDeliveryStatus status;
|
FileDeliveryStatus status;
|
||||||
FileDeliveryCode deliveryCode;
|
FileDeliveryCode deliveryCode;
|
||||||
|
@ -32,7 +32,7 @@ struct RemoteEntityCfg {
|
|||||||
bool closureRequested = false;
|
bool closureRequested = false;
|
||||||
bool crcOnTransmission = false;
|
bool crcOnTransmission = false;
|
||||||
TransmissionModes defaultTransmissionMode = TransmissionModes::UNACKNOWLEDGED;
|
TransmissionModes defaultTransmissionMode = TransmissionModes::UNACKNOWLEDGED;
|
||||||
ChecksumType defaultChecksum = ChecksumType::NULL_CHECKSUM;
|
ChecksumTypes defaultChecksum = ChecksumTypes::NULL_CHECKSUM;
|
||||||
const uint8_t version = CFDP_VERSION_2;
|
const uint8_t version = CFDP_VERSION_2;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include "MetadataInfo.h"
|
#include "MetadataInfo.h"
|
||||||
|
|
||||||
MetadataInfo::MetadataInfo(bool closureRequested, cfdp::ChecksumType checksumType,
|
MetadataInfo::MetadataInfo(bool closureRequested, cfdp::ChecksumTypes checksumType,
|
||||||
cfdp::FileSize& fileSize, cfdp::StringLv& sourceFileName,
|
cfdp::FileSize& fileSize, cfdp::StringLv& sourceFileName,
|
||||||
cfdp::StringLv& destFileName)
|
cfdp::StringLv& destFileName)
|
||||||
: MetadataInfo(fileSize, sourceFileName, destFileName) {
|
: MetadataInfo(fileSize, sourceFileName, destFileName) {
|
||||||
@ -23,9 +23,9 @@ void MetadataInfo::setOptionsArray(cfdp::Tlv** optionsArray_, std::optional<size
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cfdp::ChecksumType MetadataInfo::getChecksumType() const { return checksumType; }
|
cfdp::ChecksumTypes MetadataInfo::getChecksumType() const { return checksumType; }
|
||||||
|
|
||||||
void MetadataInfo::setChecksumType(cfdp::ChecksumType checksumType_) {
|
void MetadataInfo::setChecksumType(cfdp::ChecksumTypes checksumType_) {
|
||||||
checksumType = checksumType_;
|
checksumType = checksumType_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,15 +13,15 @@ class MetadataInfo {
|
|||||||
public:
|
public:
|
||||||
MetadataInfo(cfdp::FileSize& fileSize, cfdp::StringLv& sourceFileName,
|
MetadataInfo(cfdp::FileSize& fileSize, cfdp::StringLv& sourceFileName,
|
||||||
cfdp::StringLv& destFileName);
|
cfdp::StringLv& destFileName);
|
||||||
MetadataInfo(bool closureRequested, cfdp::ChecksumType checksumType, cfdp::FileSize& fileSize,
|
MetadataInfo(bool closureRequested, cfdp::ChecksumTypes checksumType, cfdp::FileSize& fileSize,
|
||||||
cfdp::StringLv& sourceFileName, cfdp::StringLv& destFileName);
|
cfdp::StringLv& sourceFileName, cfdp::StringLv& destFileName);
|
||||||
|
|
||||||
size_t getSerializedSize(bool fssLarge = false);
|
size_t getSerializedSize(bool fssLarge = false);
|
||||||
|
|
||||||
void setOptionsArray(cfdp::Tlv** optionsArray, std::optional<size_t> optionsLen,
|
void setOptionsArray(cfdp::Tlv** optionsArray, std::optional<size_t> optionsLen,
|
||||||
std::optional<size_t> maxOptionsLen);
|
std::optional<size_t> maxOptionsLen);
|
||||||
[[nodiscard]] cfdp::ChecksumType getChecksumType() const;
|
[[nodiscard]] cfdp::ChecksumTypes getChecksumType() const;
|
||||||
void setChecksumType(cfdp::ChecksumType checksumType);
|
void setChecksumType(cfdp::ChecksumTypes checksumType);
|
||||||
[[nodiscard]] bool isClosureRequested() const;
|
[[nodiscard]] bool isClosureRequested() const;
|
||||||
void setClosureRequested(bool closureRequested = false);
|
void setClosureRequested(bool closureRequested = false);
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ class MetadataInfo {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
bool closureRequested = false;
|
bool closureRequested = false;
|
||||||
cfdp::ChecksumType checksumType = cfdp::ChecksumType::NULL_CHECKSUM;
|
cfdp::ChecksumTypes checksumType = cfdp::ChecksumTypes::NULL_CHECKSUM;
|
||||||
cfdp::FileSize& fileSize;
|
cfdp::FileSize& fileSize;
|
||||||
cfdp::StringLv& sourceFileName;
|
cfdp::StringLv& sourceFileName;
|
||||||
cfdp::StringLv& destFileName;
|
cfdp::StringLv& destFileName;
|
||||||
|
@ -15,7 +15,7 @@ ReturnValue_t MetadataPduReader::parseData() {
|
|||||||
return SerializeIF::STREAM_TOO_SHORT;
|
return SerializeIF::STREAM_TOO_SHORT;
|
||||||
}
|
}
|
||||||
info.setClosureRequested((*buf >> 6) & 0x01);
|
info.setClosureRequested((*buf >> 6) & 0x01);
|
||||||
info.setChecksumType(static_cast<cfdp::ChecksumType>(*buf & 0x0f));
|
info.setChecksumType(static_cast<cfdp::ChecksumTypes>(*buf & 0x0f));
|
||||||
remSize -= 1;
|
remSize -= 1;
|
||||||
buf += 1;
|
buf += 1;
|
||||||
auto endianness = getEndianness();
|
auto endianness = getEndianness();
|
||||||
|
@ -30,7 +30,7 @@ TEST_CASE("CFDP Distributor", "[cfdp][distributor]") {
|
|||||||
cfdp::StringLv sourceFileName(sourceFileString);
|
cfdp::StringLv sourceFileName(sourceFileString);
|
||||||
std::string destFileString = "hello2.txt";
|
std::string destFileString = "hello2.txt";
|
||||||
cfdp::StringLv destFileName(destFileString);
|
cfdp::StringLv destFileName(destFileString);
|
||||||
MetadataInfo metadataInfo(false, cfdp::ChecksumType::CRC_32, fileSize, sourceFileName,
|
MetadataInfo metadataInfo(false, cfdp::ChecksumTypes::CRC_32, fileSize, sourceFileName,
|
||||||
destFileName);
|
destFileName);
|
||||||
MetadataPduCreator creator(pduConf, metadataInfo);
|
MetadataPduCreator creator(pduConf, metadataInfo);
|
||||||
uint8_t* dataPtr = nullptr;
|
uint8_t* dataPtr = nullptr;
|
||||||
|
@ -23,7 +23,7 @@ TEST_CASE("Metadata PDU", "[cfdp][pdu]") {
|
|||||||
cfdp::StringLv sourceFileName(firstFileName);
|
cfdp::StringLv sourceFileName(firstFileName);
|
||||||
cfdp::StringLv destFileName;
|
cfdp::StringLv destFileName;
|
||||||
FileSize fileSize(35);
|
FileSize fileSize(35);
|
||||||
MetadataInfo info(false, ChecksumType::MODULAR, fileSize, sourceFileName, destFileName);
|
MetadataInfo info(false, ChecksumTypes::MODULAR, fileSize, sourceFileName, destFileName);
|
||||||
|
|
||||||
FilestoreResponseTlv response(FilestoreActionCode::CREATE_DIRECTORY, FSR_CREATE_NOT_ALLOWED,
|
FilestoreResponseTlv response(FilestoreActionCode::CREATE_DIRECTORY, FSR_CREATE_NOT_ALLOWED,
|
||||||
sourceFileName, nullptr);
|
sourceFileName, nullptr);
|
||||||
@ -74,7 +74,7 @@ TEST_CASE("Metadata PDU", "[cfdp][pdu]") {
|
|||||||
REQUIRE(info.getMaxOptionsLen() == 2);
|
REQUIRE(info.getMaxOptionsLen() == 2);
|
||||||
info.setMaxOptionsLen(3);
|
info.setMaxOptionsLen(3);
|
||||||
REQUIRE(info.getMaxOptionsLen() == 3);
|
REQUIRE(info.getMaxOptionsLen() == 3);
|
||||||
info.setChecksumType(cfdp::ChecksumType::CRC_32C);
|
info.setChecksumType(cfdp::ChecksumTypes::CRC_32C);
|
||||||
info.setClosureRequested(true);
|
info.setClosureRequested(true);
|
||||||
uint8_t* buffer = mdBuffer.data();
|
uint8_t* buffer = mdBuffer.data();
|
||||||
size_t sz = 0;
|
size_t sz = 0;
|
||||||
@ -83,8 +83,8 @@ TEST_CASE("Metadata PDU", "[cfdp][pdu]") {
|
|||||||
result = serializer.serialize(&buffer, &sz, mdBuffer.size(), SerializeIF::Endianness::NETWORK);
|
result = serializer.serialize(&buffer, &sz, mdBuffer.size(), SerializeIF::Endianness::NETWORK);
|
||||||
REQUIRE(result == returnvalue::OK);
|
REQUIRE(result == returnvalue::OK);
|
||||||
REQUIRE((mdBuffer[1] << 8 | mdBuffer[2]) == 37);
|
REQUIRE((mdBuffer[1] << 8 | mdBuffer[2]) == 37);
|
||||||
auto checksumType = static_cast<cfdp::ChecksumType>(mdBuffer[11] & 0x0f);
|
auto checksumType = static_cast<cfdp::ChecksumTypes>(mdBuffer[11] & 0x0f);
|
||||||
REQUIRE(checksumType == cfdp::ChecksumType::CRC_32C);
|
REQUIRE(checksumType == cfdp::ChecksumTypes::CRC_32C);
|
||||||
bool closureRequested = mdBuffer[11] >> 6 & 0x01;
|
bool closureRequested = mdBuffer[11] >> 6 & 0x01;
|
||||||
REQUIRE(closureRequested == true);
|
REQUIRE(closureRequested == true);
|
||||||
// The size of the two options is 19. Summing up:
|
// The size of the two options is 19. Summing up:
|
||||||
@ -130,7 +130,7 @@ TEST_CASE("Metadata PDU", "[cfdp][pdu]") {
|
|||||||
size_t maxSize = 4;
|
size_t maxSize = 4;
|
||||||
info.setOptionsArray(options.data(), sizeOfOptions, maxSize);
|
info.setOptionsArray(options.data(), sizeOfOptions, maxSize);
|
||||||
REQUIRE(info.getOptionsLen() == 2);
|
REQUIRE(info.getOptionsLen() == 2);
|
||||||
info.setChecksumType(cfdp::ChecksumType::CRC_32C);
|
info.setChecksumType(cfdp::ChecksumTypes::CRC_32C);
|
||||||
info.setClosureRequested(true);
|
info.setClosureRequested(true);
|
||||||
uint8_t* buffer = mdBuffer.data();
|
uint8_t* buffer = mdBuffer.data();
|
||||||
size_t sz = 0;
|
size_t sz = 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user