basic impl which allows naked no closure file transfer

This commit is contained in:
Robin Müller 2022-09-05 10:26:35 +02:00
parent 3147f67fbd
commit 134d5a1411
No known key found for this signature in database
GPG Key ID: 11D4952C8CCEF814
10 changed files with 111 additions and 23 deletions

View File

@ -40,7 +40,7 @@ static constexpr ReturnValue_t FILESTORE_RESPONSE_CANT_PARSE_FS_MESSAGE =
//! Checksum types according to the SANA Checksum Types registry
//! https://sanaregistry.org/r/checksum_identifiers/
enum ChecksumType {
enum ChecksumTypes {
// Modular legacy checksum
MODULAR = 0,
CRC_32_PROXIMITY_1 = 1,

View File

@ -1,5 +1,7 @@
#include "DestHandler.h"
#include <etl/crc32.h>
#include <utility>
#include "fsfw/FSFW.h"
@ -177,6 +179,8 @@ ReturnValue_t cfdp::DestHandler::handleFileDataPdu(const cfdp::PacketInfo& info)
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "File write error" << std::endl;
#endif
} else {
tp.deliveryStatus = FileDeliveryStatus::RETAINED_IN_FILESTORE;
}
return result;
}
@ -300,7 +304,18 @@ ReturnValue_t cfdp::DestHandler::startTransaction(MetadataPduReader& reader, Met
cfdp::CfdpStates cfdp::DestHandler::getCfdpState() const { return cfdpState; }
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 (tp.closureRequested) {
step = TransactionStep::SENDING_FINISHED_PDU;
@ -310,8 +325,60 @@ ReturnValue_t cfdp::DestHandler::handleTransferCompletion() {
} else if (cfdpState == CfdpStates::BUSY_CLASS_2_ACKED) {
step = TransactionStep::SENDING_FINISHED_PDU;
}
return OK;
}
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;
}

View File

@ -98,13 +98,32 @@ class DestHandler {
explicit TransactionParams(size_t 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;
std::vector<char> sourceName;
std::vector<char> destName;
cfdp::FileSize fileSize;
TransactionId transactionId;
PduConfig pduConf;
ConditionCode conditionCode = ConditionCode::NO_ERROR;
FileDeliveryCode deliveryCode = FileDeliveryCode::DATA_INCOMPLETE;
FileDeliveryStatus deliveryStatus = FileDeliveryStatus::DISCARDED_DELIBERATELY;
uint32_t crc = 0;
uint64_t progress = 0;
RemoteEntityCfg* remoteCfg = nullptr;
@ -124,6 +143,8 @@ class DestHandler {
ReturnValue_t handleEofPdu(const PacketInfo& info);
ReturnValue_t handleMetadataParseError(const uint8_t* rawData, size_t maxSize);
ReturnValue_t handleTransferCompletion();
ReturnValue_t noticeOfCompletion();
ReturnValue_t checksumVerification();
void finish();
};

View File

@ -14,11 +14,11 @@
namespace cfdp {
struct TransactionFinishedParams {
TransactionFinishedParams(TransactionId id, ConditionCode code, FileDeliveryStatus status,
FileDeliveryCode delivCode)
: id(std::move(id)), condCode(code), status(status), deliveryCode(delivCode) {}
TransactionFinishedParams(const TransactionId& id, ConditionCode code, FileDeliveryCode delivCode,
FileDeliveryStatus status)
: id(id), condCode(code), status(status), deliveryCode(delivCode) {}
TransactionId id;
const TransactionId& id;
ConditionCode condCode;
FileDeliveryStatus status;
FileDeliveryCode deliveryCode;

View File

@ -32,7 +32,7 @@ struct RemoteEntityCfg {
bool closureRequested = false;
bool crcOnTransmission = false;
TransmissionModes defaultTransmissionMode = TransmissionModes::UNACKNOWLEDGED;
ChecksumType defaultChecksum = ChecksumType::NULL_CHECKSUM;
ChecksumTypes defaultChecksum = ChecksumTypes::NULL_CHECKSUM;
const uint8_t version = CFDP_VERSION_2;
};

View File

@ -1,6 +1,6 @@
#include "MetadataInfo.h"
MetadataInfo::MetadataInfo(bool closureRequested, cfdp::ChecksumType checksumType,
MetadataInfo::MetadataInfo(bool closureRequested, cfdp::ChecksumTypes checksumType,
cfdp::FileSize& fileSize, cfdp::StringLv& sourceFileName,
cfdp::StringLv& 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_;
}

View File

@ -13,15 +13,15 @@ class MetadataInfo {
public:
MetadataInfo(cfdp::FileSize& fileSize, cfdp::StringLv& sourceFileName,
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);
size_t getSerializedSize(bool fssLarge = false);
void setOptionsArray(cfdp::Tlv** optionsArray, std::optional<size_t> optionsLen,
std::optional<size_t> maxOptionsLen);
[[nodiscard]] cfdp::ChecksumType getChecksumType() const;
void setChecksumType(cfdp::ChecksumType checksumType);
[[nodiscard]] cfdp::ChecksumTypes getChecksumType() const;
void setChecksumType(cfdp::ChecksumTypes checksumType);
[[nodiscard]] bool isClosureRequested() const;
void setClosureRequested(bool closureRequested = false);
@ -42,7 +42,7 @@ class MetadataInfo {
private:
bool closureRequested = false;
cfdp::ChecksumType checksumType = cfdp::ChecksumType::NULL_CHECKSUM;
cfdp::ChecksumTypes checksumType = cfdp::ChecksumTypes::NULL_CHECKSUM;
cfdp::FileSize& fileSize;
cfdp::StringLv& sourceFileName;
cfdp::StringLv& destFileName;

View File

@ -15,7 +15,7 @@ ReturnValue_t MetadataPduReader::parseData() {
return SerializeIF::STREAM_TOO_SHORT;
}
info.setClosureRequested((*buf >> 6) & 0x01);
info.setChecksumType(static_cast<cfdp::ChecksumType>(*buf & 0x0f));
info.setChecksumType(static_cast<cfdp::ChecksumTypes>(*buf & 0x0f));
remSize -= 1;
buf += 1;
auto endianness = getEndianness();

View File

@ -30,7 +30,7 @@ TEST_CASE("CFDP Distributor", "[cfdp][distributor]") {
cfdp::StringLv sourceFileName(sourceFileString);
std::string destFileString = "hello2.txt";
cfdp::StringLv destFileName(destFileString);
MetadataInfo metadataInfo(false, cfdp::ChecksumType::CRC_32, fileSize, sourceFileName,
MetadataInfo metadataInfo(false, cfdp::ChecksumTypes::CRC_32, fileSize, sourceFileName,
destFileName);
MetadataPduCreator creator(pduConf, metadataInfo);
uint8_t* dataPtr = nullptr;

View File

@ -23,7 +23,7 @@ TEST_CASE("Metadata PDU", "[cfdp][pdu]") {
cfdp::StringLv sourceFileName(firstFileName);
cfdp::StringLv destFileName;
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,
sourceFileName, nullptr);
@ -74,7 +74,7 @@ TEST_CASE("Metadata PDU", "[cfdp][pdu]") {
REQUIRE(info.getMaxOptionsLen() == 2);
info.setMaxOptionsLen(3);
REQUIRE(info.getMaxOptionsLen() == 3);
info.setChecksumType(cfdp::ChecksumType::CRC_32C);
info.setChecksumType(cfdp::ChecksumTypes::CRC_32C);
info.setClosureRequested(true);
uint8_t* buffer = mdBuffer.data();
size_t sz = 0;
@ -83,8 +83,8 @@ TEST_CASE("Metadata PDU", "[cfdp][pdu]") {
result = serializer.serialize(&buffer, &sz, mdBuffer.size(), SerializeIF::Endianness::NETWORK);
REQUIRE(result == returnvalue::OK);
REQUIRE((mdBuffer[1] << 8 | mdBuffer[2]) == 37);
auto checksumType = static_cast<cfdp::ChecksumType>(mdBuffer[11] & 0x0f);
REQUIRE(checksumType == cfdp::ChecksumType::CRC_32C);
auto checksumType = static_cast<cfdp::ChecksumTypes>(mdBuffer[11] & 0x0f);
REQUIRE(checksumType == cfdp::ChecksumTypes::CRC_32C);
bool closureRequested = mdBuffer[11] >> 6 & 0x01;
REQUIRE(closureRequested == true);
// The size of the two options is 19. Summing up:
@ -130,7 +130,7 @@ TEST_CASE("Metadata PDU", "[cfdp][pdu]") {
size_t maxSize = 4;
info.setOptionsArray(options.data(), sizeOfOptions, maxSize);
REQUIRE(info.getOptionsLen() == 2);
info.setChecksumType(cfdp::ChecksumType::CRC_32C);
info.setChecksumType(cfdp::ChecksumTypes::CRC_32C);
info.setClosureRequested(true);
uint8_t* buffer = mdBuffer.data();
size_t sz = 0;