From 7add782470a979535af5d844a7d83a3e5965f62f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 30 Jun 2023 11:36:19 +0200 Subject: [PATCH 001/101] start CFDP source handler --- .gitignore | 2 +- src/fsfw/cfdp/handler/SourceHandler.cpp | 3 +++ src/fsfw/cfdp/handler/SourceHandler.h | 10 +++++++++- unittests/CatchFactory.cpp | 2 +- 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index eb461072..a5a8d2ba 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ # PyCharm and CLion -/.idea/* +.idea/* !/.idea/runConfigurations !/.idea/cmake.xml !/.idea/codeStyles diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index 513b25f3..7fac0f81 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -1 +1,4 @@ #include "SourceHandler.h" + +SourceHandler::SourceHandler(SourceHandlerParams params) { +} diff --git a/src/fsfw/cfdp/handler/SourceHandler.h b/src/fsfw/cfdp/handler/SourceHandler.h index 319cf258..5db71d36 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.h +++ b/src/fsfw/cfdp/handler/SourceHandler.h @@ -1,6 +1,14 @@ #ifndef FSFW_CFDP_CFDPSOURCEHANDLER_H #define FSFW_CFDP_CFDPSOURCEHANDLER_H -class SourceHandler {}; +struct SourceHandlerParams { + +}; + +class SourceHandler { +public: + SourceHandler(SourceHandlerParams params); +private: +}; #endif // FSFW_CFDP_CFDPSOURCEHANDLER_H diff --git a/unittests/CatchFactory.cpp b/unittests/CatchFactory.cpp index 37c62f94..62c2bc13 100644 --- a/unittests/CatchFactory.cpp +++ b/unittests/CatchFactory.cpp @@ -32,7 +32,7 @@ void Factory::produceFrameworkObjects(void* args) { setStaticFrameworkObjectIds(); new EventManager(objects::EVENT_MANAGER, 120); new HealthTable(objects::HEALTH_TABLE); - new InternalErrorReporter(objects::INTERNAL_ERROR_REPORTER); + new InternalErrorReporter(objects::INTERNAL_ERROR_REPORTER, 20, false, 5.0); { PoolManager::LocalPoolConfig poolCfg = {{100, 16}, {50, 32}, {25, 64}, {15, 128}, {5, 1024}}; From 1be09a23106564f178d89c88d22139798a2408ad Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 30 Jun 2023 11:48:25 +0200 Subject: [PATCH 002/101] the C++ tooling is shit --- .idea/cmake.xml | 8 ++++++++ src/fsfw/cfdp/handler/DestHandler.h | 6 +++--- src/fsfw/cfdp/handler/SourceHandler.cpp | 3 +-- src/fsfw/cfdp/handler/SourceHandler.h | 20 +++++++++++++++----- 4 files changed, 27 insertions(+), 10 deletions(-) create mode 100644 .idea/cmake.xml diff --git a/.idea/cmake.xml b/.idea/cmake.xml new file mode 100644 index 00000000..8986ec94 --- /dev/null +++ b/.idea/cmake.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/src/fsfw/cfdp/handler/DestHandler.h b/src/fsfw/cfdp/handler/DestHandler.h index 9057b3f5..ba4e27f4 100644 --- a/src/fsfw/cfdp/handler/DestHandler.h +++ b/src/fsfw/cfdp/handler/DestHandler.h @@ -61,8 +61,8 @@ struct DestHandlerParams { size_t maxFilenameLen = 255; }; -struct FsfwParams { - FsfwParams(AcceptsTelemetryIF& packetDest, MessageQueueIF* msgQueue, +struct FsfwDestParams { + FsfwDestParams(AcceptsTelemetryIF& packetDest, MessageQueueIF* msgQueue, EventReportingProxyIF* eventReporter, StorageManagerIF& tcStore, StorageManagerIF& tmStore) : FsfwParams(packetDest, msgQueue, eventReporter) { @@ -70,7 +70,7 @@ struct FsfwParams { this->tmStore = &tmStore; } - FsfwParams(AcceptsTelemetryIF& packetDest, MessageQueueIF* msgQueue, + FsfwDestParams(AcceptsTelemetryIF& packetDest, MessageQueueIF* msgQueue, EventReportingProxyIF* eventReporter) : packetDest(packetDest), msgQueue(msgQueue), eventReporter(eventReporter) {} AcceptsTelemetryIF& packetDest; diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index 7fac0f81..37be1844 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -1,4 +1,3 @@ #include "SourceHandler.h" -SourceHandler::SourceHandler(SourceHandlerParams params) { -} +SourceHandler::SourceHandler(SourceHandlerParams params) {} diff --git a/src/fsfw/cfdp/handler/SourceHandler.h b/src/fsfw/cfdp/handler/SourceHandler.h index 5db71d36..1295f348 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.h +++ b/src/fsfw/cfdp/handler/SourceHandler.h @@ -1,14 +1,24 @@ #ifndef FSFW_CFDP_CFDPSOURCEHANDLER_H #define FSFW_CFDP_CFDPSOURCEHANDLER_H -struct SourceHandlerParams { - -}; +struct SourceHandlerParams {}; class SourceHandler { -public: + public: SourceHandler(SourceHandlerParams params); -private: + + private: + enum class TransactionStep : uint8_t { + IDLE = 0, + TRANSACTION_START = 1, + CRC_PROCEDURE = 2, + SENDING_METADATA = 3, + SENDING_FILE_DATA = 4, + SENDING_EOF = 5, + WAIT_FOR_ACK = 6, + WAIT_FOR_FINISH = 7, + NOTICE_OF_COMPLETION = 8 + }; }; #endif // FSFW_CFDP_CFDPSOURCEHANDLER_H From 7d713219c553aea2de3917c142174ee719d3ec6d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 30 Jun 2023 11:59:22 +0200 Subject: [PATCH 003/101] continue source handler --- src/fsfw/cfdp/handler/DestHandler.cpp | 229 +++++++++++---------- src/fsfw/cfdp/handler/DestHandler.h | 30 +-- src/fsfw/cfdp/handler/SourceHandler.cpp | 2 +- src/fsfw/cfdp/handler/SourceHandler.h | 15 +- src/fsfw/cfdp/handler/defs.h | 17 ++ unittests/cfdp/handler/testDestHandler.cpp | 2 +- 6 files changed, 161 insertions(+), 134 deletions(-) diff --git a/src/fsfw/cfdp/handler/DestHandler.cpp b/src/fsfw/cfdp/handler/DestHandler.cpp index 4ffa797f..76beb855 100644 --- a/src/fsfw/cfdp/handler/DestHandler.cpp +++ b/src/fsfw/cfdp/handler/DestHandler.cpp @@ -14,13 +14,13 @@ using namespace returnvalue; -cfdp::DestHandler::DestHandler(DestHandlerParams params, FsfwParams fsfwParams) +cfdp::DestHandler::DestHandler(DestHandlerParams params, FsfwDestParams fsfwParams) : tlvVec(params.maxTlvsInOnePdu), userTlvVec(params.maxTlvsInOnePdu), - dp(std::move(params)), - fp(fsfwParams), - tp(params.maxFilenameLen) { - tp.pduConf.direction = cfdp::Direction::TOWARDS_SENDER; + destParams(std::move(params)), + fsfwParams(fsfwParams), + transactionParams(params.maxFilenameLen) { + transactionParams.pduConf.direction = cfdp::Direction::TOWARDS_SENDER; } const cfdp::DestHandler::FsmResult& cfdp::DestHandler::performStateMachine() { @@ -28,13 +28,14 @@ const cfdp::DestHandler::FsmResult& cfdp::DestHandler::performStateMachine() { uint8_t errorIdx = 0; fsmRes.resetOfIteration(); if (fsmRes.step == TransactionStep::IDLE) { - for (auto infoIter = dp.packetListRef.begin(); infoIter != dp.packetListRef.end();) { + for (auto infoIter = destParams.packetListRef.begin(); + infoIter != destParams.packetListRef.end();) { if (infoIter->pduType == PduType::FILE_DIRECTIVE and infoIter->directiveType == FileDirective::METADATA) { result = handleMetadataPdu(*infoIter); checkAndHandleError(result, errorIdx); // Store data was deleted in PDU handler because a store guard is used - dp.packetListRef.erase(infoIter++); + destParams.packetListRef.erase(infoIter++); } else { infoIter++; } @@ -42,11 +43,12 @@ const cfdp::DestHandler::FsmResult& cfdp::DestHandler::performStateMachine() { if (fsmRes.step == TransactionStep::IDLE) { // To decrease the already high complexity of the software, all packets arriving before // a metadata PDU are deleted. - for (auto infoIter = dp.packetListRef.begin(); infoIter != dp.packetListRef.end();) { - fp.tcStore->deleteData(infoIter->storeId); + for (auto infoIter = destParams.packetListRef.begin(); + infoIter != destParams.packetListRef.end();) { + fsfwParams.tcStore->deleteData(infoIter->storeId); infoIter++; } - dp.packetListRef.clear(); + destParams.packetListRef.clear(); } if (fsmRes.step != TransactionStep::IDLE) { @@ -56,19 +58,20 @@ const cfdp::DestHandler::FsmResult& cfdp::DestHandler::performStateMachine() { } if (fsmRes.state == CfdpStates::BUSY_CLASS_1_NACKED) { if (fsmRes.step == TransactionStep::RECEIVING_FILE_DATA_PDUS) { - for (auto infoIter = dp.packetListRef.begin(); infoIter != dp.packetListRef.end();) { + for (auto infoIter = destParams.packetListRef.begin(); + infoIter != destParams.packetListRef.end();) { if (infoIter->pduType == PduType::FILE_DATA) { result = handleFileDataPdu(*infoIter); checkAndHandleError(result, errorIdx); // Store data was deleted in PDU handler because a store guard is used - dp.packetListRef.erase(infoIter++); + destParams.packetListRef.erase(infoIter++); } else if (infoIter->pduType == PduType::FILE_DIRECTIVE and infoIter->directiveType == FileDirective::EOF_DIRECTIVE) { // TODO: Support for check timer missing result = handleEofPdu(*infoIter); checkAndHandleError(result, errorIdx); // Store data was deleted in PDU handler because a store guard is used - dp.packetListRef.erase(infoIter++); + destParams.packetListRef.erase(infoIter++); } else { infoIter++; } @@ -95,29 +98,29 @@ const cfdp::DestHandler::FsmResult& cfdp::DestHandler::performStateMachine() { } ReturnValue_t cfdp::DestHandler::passPacket(PacketInfo packet) { - if (dp.packetListRef.full()) { + if (destParams.packetListRef.full()) { return FAILED; } - dp.packetListRef.push_back(packet); + destParams.packetListRef.push_back(packet); return OK; } ReturnValue_t cfdp::DestHandler::initialize() { - if (fp.tmStore == nullptr) { - fp.tmStore = ObjectManager::instance()->get(objects::TM_STORE); - if (fp.tmStore == nullptr) { + if (fsfwParams.tmStore == nullptr) { + fsfwParams.tmStore = ObjectManager::instance()->get(objects::TM_STORE); + if (fsfwParams.tmStore == nullptr) { return FAILED; } } - if (fp.tcStore == nullptr) { - fp.tcStore = ObjectManager::instance()->get(objects::TC_STORE); - if (fp.tcStore == nullptr) { + if (fsfwParams.tcStore == nullptr) { + fsfwParams.tcStore = ObjectManager::instance()->get(objects::TC_STORE); + if (fsfwParams.tcStore == nullptr) { return FAILED; } } - if (fp.msgQueue == nullptr) { + if (fsfwParams.msgQueue == nullptr) { return FAILED; } return OK; @@ -125,14 +128,14 @@ ReturnValue_t cfdp::DestHandler::initialize() { ReturnValue_t cfdp::DestHandler::handleMetadataPdu(const PacketInfo& info) { // Process metadata PDU - auto constAccessorPair = fp.tcStore->getData(info.storeId); + auto constAccessorPair = fsfwParams.tcStore->getData(info.storeId); if (constAccessorPair.first != OK) { // TODO: This is not a CFDP error. Event and/or warning? return constAccessorPair.first; } cfdp::StringLv sourceFileName; cfdp::StringLv destFileName; - MetadataInfo metadataInfo(tp.fileSize, sourceFileName, destFileName); + MetadataInfo metadataInfo(transactionParams.fileSize, sourceFileName, destFileName); cfdp::Tlv* tlvArrayAsPtr = tlvVec.data(); metadataInfo.setOptionsArray(&tlvArrayAsPtr, std::nullopt, tlvVec.size()); MetadataPduReader reader(constAccessorPair.second.data(), constAccessorPair.second.size(), @@ -150,7 +153,7 @@ ReturnValue_t cfdp::DestHandler::handleMetadataPdu(const PacketInfo& info) { ReturnValue_t cfdp::DestHandler::handleFileDataPdu(const cfdp::PacketInfo& info) { // Process file data PDU - auto constAccessorPair = fp.tcStore->getData(info.storeId); + auto constAccessorPair = fsfwParams.tcStore->getData(info.storeId); if (constAccessorPair.first != OK) { // TODO: This is not a CFDP error. Event and/or warning? return constAccessorPair.first; @@ -164,46 +167,46 @@ ReturnValue_t cfdp::DestHandler::handleFileDataPdu(const cfdp::PacketInfo& info) } size_t fileSegmentLen = 0; const uint8_t* fileData = fdInfo.getFileData(&fileSegmentLen); - FileOpParams fileOpParams(tp.destName.data(), fileSegmentLen); + FileOpParams fileOpParams(transactionParams.destName.data(), fileSegmentLen); fileOpParams.offset = offset.value(); - if (dp.cfg.indicCfg.fileSegmentRecvIndicRequired) { + if (destParams.cfg.indicCfg.fileSegmentRecvIndicRequired) { FileSegmentRecvdParams segParams; segParams.offset = offset.value(); - segParams.id = tp.transactionId; + segParams.id = transactionParams.transactionId; segParams.length = fileSegmentLen; segParams.recContState = fdInfo.getRecordContinuationState(); size_t segmentMetadatLen = 0; auto* segMetadata = fdInfo.getSegmentMetadata(&segmentMetadatLen); segParams.segmentMetadata = {segMetadata, segmentMetadatLen}; - dp.user.fileSegmentRecvdIndication(segParams); + destParams.user.fileSegmentRecvdIndication(segParams); } - result = dp.user.vfs.writeToFile(fileOpParams, fileData); + result = destParams.user.vfs.writeToFile(fileOpParams, fileData); if (result != returnvalue::OK) { // TODO: Proper Error handling #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::error << "cfdp::DestHandler: VFS file write error with code 0x" << std::hex << std::setw(2) << result << std::endl; #endif - tp.vfsErrorCount++; - if (tp.vfsErrorCount < 3) { + transactionParams.vfsErrorCount++; + if (transactionParams.vfsErrorCount < 3) { // TODO: Provide execution step as parameter - fp.eventReporter->forwardEvent(events::FILESTORE_ERROR, static_cast(fsmRes.step), - result); + fsfwParams.eventReporter->forwardEvent(events::FILESTORE_ERROR, + static_cast(fsmRes.step), result); } return result; } else { - tp.deliveryStatus = FileDeliveryStatus::RETAINED_IN_FILESTORE; - tp.vfsErrorCount = 0; + transactionParams.deliveryStatus = FileDeliveryStatus::RETAINED_IN_FILESTORE; + transactionParams.vfsErrorCount = 0; } - if (offset.value() + fileSegmentLen > tp.progress) { - tp.progress = offset.value() + fileSegmentLen; + if (offset.value() + fileSegmentLen > transactionParams.progress) { + transactionParams.progress = offset.value() + fileSegmentLen; } return result; } ReturnValue_t cfdp::DestHandler::handleEofPdu(const cfdp::PacketInfo& info) { // Process EOF PDU - auto constAccessorPair = fp.tcStore->getData(info.storeId); + auto constAccessorPair = fsfwParams.tcStore->getData(info.storeId); if (constAccessorPair.first != OK) { // TODO: This is not a CFDP error. Event and/or warning? return constAccessorPair.first; @@ -216,16 +219,16 @@ ReturnValue_t cfdp::DestHandler::handleEofPdu(const cfdp::PacketInfo& info) { } // TODO: Error handling if (eofInfo.getConditionCode() == ConditionCode::NO_ERROR) { - tp.crc = eofInfo.getChecksum(); + transactionParams.crc = eofInfo.getChecksum(); uint64_t fileSizeFromEof = eofInfo.getFileSize().value(); // CFDP 4.6.1.2.9: Declare file size error if progress exceeds file size - if (fileSizeFromEof > tp.progress) { + if (fileSizeFromEof > transactionParams.progress) { // TODO: File size error } - tp.fileSize.setFileSize(fileSizeFromEof, std::nullopt); + transactionParams.fileSize.setFileSize(fileSizeFromEof, std::nullopt); } - if (dp.cfg.indicCfg.eofRecvIndicRequired) { - dp.user.eofRecvIndication(getTransactionId()); + if (destParams.cfg.indicCfg.eofRecvIndicRequired) { + destParams.user.eofRecvIndication(getTransactionId()); } if (fsmRes.step == TransactionStep::RECEIVING_FILE_DATA_PDUS) { if (fsmRes.state == CfdpStates::BUSY_CLASS_1_NACKED) { @@ -260,7 +263,7 @@ ReturnValue_t cfdp::DestHandler::handleMetadataParseError(ReturnValue_t result, cfdp::EntityId destId; headerReader.getDestId(destId); RemoteEntityCfg* remoteCfg; - if (not dp.remoteCfgTable.getRemoteCfg(destId, &remoteCfg)) { + if (not destParams.remoteCfgTable.getRemoteCfg(destId, &remoteCfg)) { // TODO: No remote config for dest ID. I consider this a configuration error, which is not // covered by the standard. // Warning or error, yield or cache appropriate returnvalue @@ -283,42 +286,42 @@ ReturnValue_t cfdp::DestHandler::startTransaction(MetadataPduReader& reader, Met size_t sourceNameSize = 0; const uint8_t* sourceNamePtr = info.getSourceFileName().getValue(&sourceNameSize); - if (sourceNameSize + 1 > tp.sourceName.size()) { + if (sourceNameSize + 1 > transactionParams.sourceName.size()) { fileErrorHandler(events::FILENAME_TOO_LARGE_ERROR, 0, "source filename too large"); return FAILED; } - std::memcpy(tp.sourceName.data(), sourceNamePtr, sourceNameSize); - tp.sourceName[sourceNameSize] = '\0'; + std::memcpy(transactionParams.sourceName.data(), sourceNamePtr, sourceNameSize); + transactionParams.sourceName[sourceNameSize] = '\0'; size_t destNameSize = 0; const uint8_t* destNamePtr = info.getDestFileName().getValue(&destNameSize); - if (destNameSize + 1 > tp.destName.size()) { + if (destNameSize + 1 > transactionParams.destName.size()) { fileErrorHandler(events::FILENAME_TOO_LARGE_ERROR, 0, "dest filename too large"); return FAILED; } - std::memcpy(tp.destName.data(), destNamePtr, destNameSize); - tp.destName[destNameSize] = '\0'; + std::memcpy(transactionParams.destName.data(), destNamePtr, destNameSize); + transactionParams.destName[destNameSize] = '\0'; // If both dest name size and source name size are 0, we are dealing with a metadata only PDU, // so there is no need to create a file or truncate an existing file if (destNameSize > 0 and sourceNameSize > 0) { - FilesystemParams fparams(tp.destName.data()); + FilesystemParams fparams(transactionParams.destName.data()); // handling to allow only specifying target directory. Example: // Source path /test/hello.txt, dest path /tmp -> dest path /tmp/hello.txt - if (dp.user.vfs.isDirectory(tp.destName.data())) { + if (destParams.user.vfs.isDirectory(transactionParams.destName.data())) { result = tryBuildingAbsoluteDestName(destNameSize); if (result != OK) { return result; } } - if (dp.user.vfs.fileExists(fparams)) { - result = dp.user.vfs.truncateFile(fparams); + if (destParams.user.vfs.fileExists(fparams)) { + result = destParams.user.vfs.truncateFile(fparams); if (result != returnvalue::OK) { fileErrorHandler(events::FILESTORE_ERROR, result, "file truncation error"); return FAILED; // TODO: Relevant for filestore rejection error? } } else { - result = dp.user.vfs.createFile(fparams); + result = destParams.user.vfs.createFile(fparams); if (result != OK) { fileErrorHandler(events::FILESTORE_ERROR, result, "file creation error"); return FAILED; @@ -328,7 +331,7 @@ ReturnValue_t cfdp::DestHandler::startTransaction(MetadataPduReader& reader, Met } EntityId sourceId; reader.getSourceId(sourceId); - if (not dp.remoteCfgTable.getRemoteCfg(sourceId, &tp.remoteCfg)) { + if (not destParams.remoteCfgTable.getRemoteCfg(sourceId, &transactionParams.remoteCfg)) { // TODO: Warning, event etc. #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "cfdp::DestHandler" << __func__ @@ -343,20 +346,20 @@ ReturnValue_t cfdp::DestHandler::startTransaction(MetadataPduReader& reader, Met } else if (reader.getTransmissionMode() == TransmissionMode::ACKNOWLEDGED) { fsmRes.state = CfdpStates::BUSY_CLASS_2_ACKED; } - tp.checksumType = info.getChecksumType(); - tp.closureRequested = info.isClosureRequested(); - reader.fillConfig(tp.pduConf); - tp.pduConf.direction = Direction::TOWARDS_SENDER; - tp.transactionId.entityId = tp.pduConf.sourceId; - tp.transactionId.seqNum = tp.pduConf.seqNum; + transactionParams.checksumType = info.getChecksumType(); + transactionParams.closureRequested = info.isClosureRequested(); + reader.fillConfig(transactionParams.pduConf); + transactionParams.pduConf.direction = Direction::TOWARDS_SENDER; + transactionParams.transactionId.entityId = transactionParams.pduConf.sourceId; + transactionParams.transactionId.seqNum = transactionParams.pduConf.seqNum; fsmRes.step = TransactionStep::RECEIVING_FILE_DATA_PDUS; - MetadataRecvdParams params(tp.transactionId, tp.pduConf.sourceId); - params.fileSize = tp.fileSize.getSize(); - params.destFileName = tp.destName.data(); - params.sourceFileName = tp.sourceName.data(); + MetadataRecvdParams params(transactionParams.transactionId, transactionParams.pduConf.sourceId); + params.fileSize = transactionParams.fileSize.getSize(); + params.destFileName = transactionParams.destName.data(); + params.sourceFileName = transactionParams.sourceName.data(); params.msgsToUserArray = dynamic_cast(userTlvVec.data()); params.msgsToUserLen = info.getOptionsLen(); - dp.user.metadataRecvdIndication(params); + destParams.user.metadataRecvdIndication(params); return result; } @@ -364,19 +367,19 @@ cfdp::CfdpStates cfdp::DestHandler::getCfdpState() const { return fsmRes.state; ReturnValue_t cfdp::DestHandler::handleTransferCompletion() { ReturnValue_t result; - if (tp.checksumType != ChecksumType::NULL_CHECKSUM) { + if (transactionParams.checksumType != ChecksumType::NULL_CHECKSUM) { result = checksumVerification(); if (result != OK) { // TODO: Warning / error handling? } } else { - tp.conditionCode = ConditionCode::NO_ERROR; + transactionParams.conditionCode = ConditionCode::NO_ERROR; } result = noticeOfCompletion(); if (result != OK) { } if (fsmRes.state == CfdpStates::BUSY_CLASS_1_NACKED) { - if (tp.closureRequested) { + if (transactionParams.closureRequested) { fsmRes.step = TransactionStep::SENDING_FINISHED_PDU; } else { finish(); @@ -388,39 +391,41 @@ ReturnValue_t cfdp::DestHandler::handleTransferCompletion() { } ReturnValue_t cfdp::DestHandler::tryBuildingAbsoluteDestName(size_t destNameSize) { - char baseNameBuf[tp.destName.size()]{}; - FilesystemParams fparamsSrc(tp.sourceName.data()); + // A path may only have a maximum of 256 characters in CFDP, so this buffer should be sufficient + // for all use-cases. + char baseNameBuf[512]{}; + FilesystemParams fparamsSrc(transactionParams.sourceName.data()); size_t baseNameLen = 0; - ReturnValue_t result = - dp.user.vfs.getBaseFilename(fparamsSrc, baseNameBuf, sizeof(baseNameBuf), baseNameLen); + ReturnValue_t result = destParams.user.vfs.getBaseFilename(fparamsSrc, baseNameBuf, + sizeof(baseNameBuf), baseNameLen); if (result != returnvalue::OK or baseNameLen == 0) { fileErrorHandler(events::FILENAME_TOO_LARGE_ERROR, 0, "error retrieving source base name"); return FAILED; } // Destination name + slash + base name + null termination - if (destNameSize + 1 + baseNameLen + 1 > tp.destName.size()) { + if (destNameSize + 1 + baseNameLen + 1 > transactionParams.destName.size()) { fileErrorHandler(events::FILENAME_TOO_LARGE_ERROR, 0, "dest filename too large after adding source base name"); return FAILED; } - tp.destName[destNameSize++] = '/'; - std::memcpy(tp.destName.data() + destNameSize, baseNameBuf, baseNameLen); + transactionParams.destName[destNameSize++] = '/'; + std::memcpy(transactionParams.destName.data() + destNameSize, baseNameBuf, baseNameLen); destNameSize += baseNameLen; - tp.destName[destNameSize++] = '\0'; + transactionParams.destName[destNameSize++] = '\0'; return OK; } void cfdp::DestHandler::fileErrorHandler(Event event, ReturnValue_t result, const char* info) { - fp.eventReporter->forwardEvent(events::FILENAME_TOO_LARGE_ERROR, - static_cast(fsmRes.step), result); + fsfwParams.eventReporter->forwardEvent(events::FILENAME_TOO_LARGE_ERROR, + static_cast(fsmRes.step), result); #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "cfdp::DestHandler: " << info << std::endl; #endif } void cfdp::DestHandler::finish() { - tp.reset(); - dp.packetListRef.clear(); + transactionParams.reset(); + destParams.packetListRef.clear(); fsmRes.state = CfdpStates::IDLE; fsmRes.step = TransactionStep::IDLE; } @@ -430,18 +435,18 @@ ReturnValue_t cfdp::DestHandler::checksumVerification() { // TODO: Checksum verification and notice of completion etl::crc32 crcCalc; uint64_t currentOffset = 0; - FileOpParams params(tp.destName.data(), tp.fileSize.value()); - while (currentOffset < tp.fileSize.value()) { + FileOpParams params(transactionParams.destName.data(), transactionParams.fileSize.value()); + while (currentOffset < transactionParams.fileSize.value()) { uint64_t readLen; - if (currentOffset + buf.size() > tp.fileSize.value()) { - readLen = tp.fileSize.value() - currentOffset; + if (currentOffset + buf.size() > transactionParams.fileSize.value()) { + readLen = transactionParams.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()); + auto result = destParams.user.vfs.readFromFile(params, buf.data(), buf.size()); if (result != OK) { // TODO: I think this is a case for a filestore rejection, but it might sense to print // a warning or trigger an event because this should generally not happen @@ -453,40 +458,42 @@ ReturnValue_t cfdp::DestHandler::checksumVerification() { } uint32_t value = crcCalc.value(); - if (value == tp.crc) { - tp.conditionCode = ConditionCode::NO_ERROR; - tp.deliveryCode = FileDeliveryCode::DATA_COMPLETE; + if (value == transactionParams.crc) { + transactionParams.conditionCode = ConditionCode::NO_ERROR; + transactionParams.deliveryCode = FileDeliveryCode::DATA_COMPLETE; } else { // TODO: Proper error handling #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "CRC check for file " << tp.destName.data() << " failed" << std::endl; #endif - tp.conditionCode = ConditionCode::FILE_CHECKSUM_FAILURE; + transactionParams.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); + if (destParams.cfg.indicCfg.transactionFinishedIndicRequired) { + TransactionFinishedParams params( + transactionParams.transactionId, transactionParams.conditionCode, + transactionParams.deliveryCode, transactionParams.deliveryStatus); + destParams.user.transactionFinishedIndication(params); } return OK; } ReturnValue_t cfdp::DestHandler::sendFinishedPdu() { - FinishedInfo info(tp.conditionCode, tp.deliveryCode, tp.deliveryStatus); - FinishPduCreator finishedPdu(tp.pduConf, info); + FinishedInfo info(transactionParams.conditionCode, transactionParams.deliveryCode, + transactionParams.deliveryStatus); + FinishPduCreator finishedPdu(transactionParams.pduConf, info); store_address_t storeId; uint8_t* dataPtr = nullptr; ReturnValue_t result = - fp.tmStore->getFreeElement(&storeId, finishedPdu.getSerializedSize(), &dataPtr); + fsfwParams.tmStore->getFreeElement(&storeId, finishedPdu.getSerializedSize(), &dataPtr); if (result != OK) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "cfdp::DestHandler:sendFinishedPdu: Getting store slot failed" << std::endl; #endif - fp.eventReporter->forwardEvent(events::STORE_ERROR, result, 0); + fsfwParams.eventReporter->forwardEvent(events::STORE_ERROR, result, 0); return result; } size_t serLen = 0; @@ -496,16 +503,16 @@ ReturnValue_t cfdp::DestHandler::sendFinishedPdu() { sif::warning << "cfdp::DestHandler::sendFinishedPdu: Serializing Finished PDU failed" << std::endl; #endif - fp.eventReporter->forwardEvent(events::SERIALIZATION_ERROR, result, 0); + fsfwParams.eventReporter->forwardEvent(events::SERIALIZATION_ERROR, result, 0); return result; } TmTcMessage msg(storeId); - result = fp.msgQueue->sendMessage(fp.packetDest.getReportReceptionQueue(), &msg); + result = fsfwParams.msgQueue->sendMessage(fsfwParams.packetDest.getReportReceptionQueue(), &msg); if (result != OK) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "cfdp::DestHandler::sendFinishedPdu: Sending PDU failed" << std::endl; #endif - fp.eventReporter->forwardEvent(events::MSG_QUEUE_ERROR, result, 0); + fsfwParams.eventReporter->forwardEvent(events::MSG_QUEUE_ERROR, result, 0); return result; } fsmRes.packetsSent++; @@ -525,7 +532,9 @@ const cfdp::DestHandler::FsmResult& cfdp::DestHandler::updateFsmRes(uint8_t erro return fsmRes; } -const cfdp::TransactionId& cfdp::DestHandler::getTransactionId() const { return tp.transactionId; } +const cfdp::TransactionId& cfdp::DestHandler::getTransactionId() const { + return transactionParams.transactionId; +} void cfdp::DestHandler::checkAndHandleError(ReturnValue_t result, uint8_t& errorIdx) { if (result != OK and errorIdx < 3) { @@ -534,13 +543,15 @@ void cfdp::DestHandler::checkAndHandleError(ReturnValue_t result, uint8_t& error } } -void cfdp::DestHandler::setMsgQueue(MessageQueueIF& queue) { fp.msgQueue = &queue; } +void cfdp::DestHandler::setMsgQueue(MessageQueueIF& queue) { fsfwParams.msgQueue = &queue; } void cfdp::DestHandler::setEventReporter(EventReportingProxyIF& reporter) { - fp.eventReporter = &reporter; + fsfwParams.eventReporter = &reporter; } -const cfdp::DestHandlerParams& cfdp::DestHandler::getDestHandlerParams() const { return dp; } +const cfdp::DestHandlerParams& cfdp::DestHandler::getDestHandlerParams() const { + return destParams; +} -StorageManagerIF* cfdp::DestHandler::getTmStore() const { return fp.tmStore; } -StorageManagerIF* cfdp::DestHandler::getTcStore() const { return fp.tcStore; } +StorageManagerIF* cfdp::DestHandler::getTmStore() const { return fsfwParams.tmStore; } +StorageManagerIF* cfdp::DestHandler::getTcStore() const { return fsfwParams.tcStore; } diff --git a/src/fsfw/cfdp/handler/DestHandler.h b/src/fsfw/cfdp/handler/DestHandler.h index ba4e27f4..fb7cd880 100644 --- a/src/fsfw/cfdp/handler/DestHandler.h +++ b/src/fsfw/cfdp/handler/DestHandler.h @@ -20,23 +20,9 @@ namespace cfdp { -struct PacketInfo { - PacketInfo(PduType type, store_address_t storeId, - std::optional directive = std::nullopt) - : pduType(type), directiveType(directive), storeId(storeId) {} - - PduType pduType = PduType::FILE_DATA; - std::optional directiveType = FileDirective::INVALID_DIRECTIVE; - store_address_t storeId = store_address_t::invalid(); - PacketInfo() = default; -}; - template using LostSegmentsList = etl::set, SIZE>; -template -using PacketInfoList = etl::list; using LostSegmentsListBase = etl::iset>; -using PacketInfoListBase = etl::ilist; struct DestHandlerParams { DestHandlerParams(LocalEntityCfg cfg, UserBase& user, RemoteConfigTableIF& remoteCfgTable, @@ -63,15 +49,15 @@ struct DestHandlerParams { struct FsfwDestParams { FsfwDestParams(AcceptsTelemetryIF& packetDest, MessageQueueIF* msgQueue, - EventReportingProxyIF* eventReporter, StorageManagerIF& tcStore, - StorageManagerIF& tmStore) - : FsfwParams(packetDest, msgQueue, eventReporter) { + EventReportingProxyIF* eventReporter, StorageManagerIF& tcStore, + StorageManagerIF& tmStore) + : FsfwDestParams(packetDest, msgQueue, eventReporter) { this->tcStore = &tcStore; this->tmStore = &tmStore; } FsfwDestParams(AcceptsTelemetryIF& packetDest, MessageQueueIF* msgQueue, - EventReportingProxyIF* eventReporter) + EventReportingProxyIF* eventReporter) : packetDest(packetDest), msgQueue(msgQueue), eventReporter(eventReporter) {} AcceptsTelemetryIF& packetDest; MessageQueueIF* msgQueue; @@ -115,7 +101,7 @@ class DestHandler { */ ReturnValue_t PARTIAL_SUCCESS = returnvalue::makeCode(0, 2); ReturnValue_t FAILURE = returnvalue::makeCode(0, 3); - explicit DestHandler(DestHandlerParams handlerParams, FsfwParams fsfwParams); + explicit DestHandler(DestHandlerParams handlerParams, FsfwDestParams fsfwParams); /** * @@ -179,9 +165,9 @@ class DestHandler { std::vector tlvVec; std::vector userTlvVec; - DestHandlerParams dp; - FsfwParams fp; - TransactionParams tp; + DestHandlerParams destParams; + FsfwDestParams fsfwParams; + TransactionParams transactionParams; FsmResult fsmRes; ReturnValue_t startTransaction(MetadataPduReader& reader, MetadataInfo& info); diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index 37be1844..eb3722d1 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -1,3 +1,3 @@ #include "SourceHandler.h" -SourceHandler::SourceHandler(SourceHandlerParams params) {} +SourceHandler::SourceHandler(SourceHandlerParams params, FsfwSourceParams fsfwParams) {} diff --git a/src/fsfw/cfdp/handler/SourceHandler.h b/src/fsfw/cfdp/handler/SourceHandler.h index 1295f348..75f2f1e0 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.h +++ b/src/fsfw/cfdp/handler/SourceHandler.h @@ -1,11 +1,24 @@ #ifndef FSFW_CFDP_CFDPSOURCEHANDLER_H #define FSFW_CFDP_CFDPSOURCEHANDLER_H +#include + +#include "fsfw/events/EventReportingProxyIF.h" +#include "fsfw/storagemanager/StorageManagerIF.h" + struct SourceHandlerParams {}; +struct FsfwSourceParams { + FsfwSourceParams(EventReportingProxyIF* eventReporter, StorageManagerIF& tcStore) + : tcStore(&tcStore){}; + + EventReportingProxyIF* eventReporter = nullptr; + StorageManagerIF* tcStore = nullptr; +}; + class SourceHandler { public: - SourceHandler(SourceHandlerParams params); + SourceHandler(SourceHandlerParams params, FsfwSourceParams fsfwParams); private: enum class TransactionStep : uint8_t { diff --git a/src/fsfw/cfdp/handler/defs.h b/src/fsfw/cfdp/handler/defs.h index 5f17ca2d..29fe360e 100644 --- a/src/fsfw/cfdp/handler/defs.h +++ b/src/fsfw/cfdp/handler/defs.h @@ -1,12 +1,29 @@ #ifndef FSFW_CFDP_HANDLER_DEFS_H #define FSFW_CFDP_HANDLER_DEFS_H +#include "fsfw/storagemanager/storeAddress.h" + namespace cfdp { enum class CfdpStates { IDLE, BUSY_CLASS_1_NACKED, BUSY_CLASS_2_ACKED, SUSPENDED }; static constexpr uint8_t SSID = SUBSYSTEM_ID::CFDP; +struct PacketInfo { + PacketInfo(PduType type, store_address_t storeId, + std::optional directive = std::nullopt) + : pduType(type), directiveType(directive), storeId(storeId) {} + + PduType pduType = PduType::FILE_DATA; + std::optional directiveType = FileDirective::INVALID_DIRECTIVE; + store_address_t storeId = store_address_t::invalid(); + PacketInfo() = default; +}; + +template +using PacketInfoList = etl::list; +using PacketInfoListBase = etl::ilist; + namespace events { static constexpr Event STORE_ERROR = event::makeEvent(SSID, 0, severity::LOW); diff --git a/unittests/cfdp/handler/testDestHandler.cpp b/unittests/cfdp/handler/testDestHandler.cpp index 0224a20b..a1fa5b8b 100644 --- a/unittests/cfdp/handler/testDestHandler.cpp +++ b/unittests/cfdp/handler/testDestHandler.cpp @@ -38,7 +38,7 @@ TEST_CASE("CFDP Dest Handler", "[cfdp]") { LocalPool::LocalPoolConfig storeCfg = {{10, 32}, {10, 64}, {10, 128}, {10, 1024}}; StorageManagerMock tcStore(2, storeCfg); StorageManagerMock tmStore(3, storeCfg); - FsfwParams fp(tmReceiver, &mqMock, &eventReporterMock); + FsfwDestParams fp(tmReceiver, &mqMock, &eventReporterMock); RemoteEntityCfg cfg(remoteId); remoteCfgTableMock.addRemoteConfig(cfg); fp.tcStore = &tcStore; From 1b23aa42463dd3188b99d44fd42a6ce7b5f3d5a1 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 30 Jun 2023 12:01:18 +0200 Subject: [PATCH 004/101] bugfixes and improvements for dest handler --- src/fsfw/cfdp/handler/DestHandler.cpp | 6 +++--- src/fsfw/cfdp/handler/DestHandler.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/fsfw/cfdp/handler/DestHandler.cpp b/src/fsfw/cfdp/handler/DestHandler.cpp index 76beb855..92950e37 100644 --- a/src/fsfw/cfdp/handler/DestHandler.cpp +++ b/src/fsfw/cfdp/handler/DestHandler.cpp @@ -415,9 +415,9 @@ ReturnValue_t cfdp::DestHandler::tryBuildingAbsoluteDestName(size_t destNameSize return OK; } -void cfdp::DestHandler::fileErrorHandler(Event event, ReturnValue_t result, const char* info) { - fsfwParams.eventReporter->forwardEvent(events::FILENAME_TOO_LARGE_ERROR, - static_cast(fsmRes.step), result); +void cfdp::DestHandler::fileErrorHandler(Event event, ReturnValue_t result, + const char* info) const { + fsfwParams.eventReporter->forwardEvent(event, static_cast(fsmRes.step), result); #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "cfdp::DestHandler: " << info << std::endl; #endif diff --git a/src/fsfw/cfdp/handler/DestHandler.h b/src/fsfw/cfdp/handler/DestHandler.h index fb7cd880..5b42124f 100644 --- a/src/fsfw/cfdp/handler/DestHandler.h +++ b/src/fsfw/cfdp/handler/DestHandler.h @@ -181,7 +181,7 @@ class DestHandler { ReturnValue_t sendFinishedPdu(); ReturnValue_t noticeOfCompletion(); ReturnValue_t checksumVerification(); - void fileErrorHandler(Event event, ReturnValue_t result, const char* info); + void fileErrorHandler(Event event, ReturnValue_t result, const char* info) const; const FsmResult& updateFsmRes(uint8_t errors); void checkAndHandleError(ReturnValue_t result, uint8_t& errorIdx); void finish(); From cf927ecee754af68495a37f68f260c08af6f5113 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 14 Jul 2023 15:56:38 +0200 Subject: [PATCH 005/101] added bare structure of FSM --- src/fsfw/cfdp/handler/DestHandler.cpp | 22 ++++++------- src/fsfw/cfdp/handler/DestHandler.h | 4 +-- src/fsfw/cfdp/handler/SourceHandler.cpp | 36 ++++++++++++++++++++++ src/fsfw/cfdp/handler/SourceHandler.h | 7 +++++ src/fsfw/cfdp/handler/defs.h | 2 +- unittests/cfdp/handler/testDestHandler.cpp | 10 +++--- 6 files changed, 62 insertions(+), 19 deletions(-) diff --git a/src/fsfw/cfdp/handler/DestHandler.cpp b/src/fsfw/cfdp/handler/DestHandler.cpp index 92950e37..6ba9a918 100644 --- a/src/fsfw/cfdp/handler/DestHandler.cpp +++ b/src/fsfw/cfdp/handler/DestHandler.cpp @@ -56,7 +56,7 @@ const cfdp::DestHandler::FsmResult& cfdp::DestHandler::performStateMachine() { } return updateFsmRes(errorIdx); } - if (fsmRes.state == CfdpStates::BUSY_CLASS_1_NACKED) { + if (fsmRes.state == CfdpState::BUSY_CLASS_1_NACKED) { if (fsmRes.step == TransactionStep::RECEIVING_FILE_DATA_PDUS) { for (auto infoIter = destParams.packetListRef.begin(); infoIter != destParams.packetListRef.end();) { @@ -88,7 +88,7 @@ const cfdp::DestHandler::FsmResult& cfdp::DestHandler::performStateMachine() { } return updateFsmRes(errorIdx); } - if (fsmRes.state == CfdpStates::BUSY_CLASS_2_ACKED) { + if (fsmRes.state == CfdpState::BUSY_CLASS_2_ACKED) { // TODO: Will be implemented at a later stage #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "CFDP state machine for acknowledged mode not implemented yet" << std::endl; @@ -231,9 +231,9 @@ ReturnValue_t cfdp::DestHandler::handleEofPdu(const cfdp::PacketInfo& info) { destParams.user.eofRecvIndication(getTransactionId()); } if (fsmRes.step == TransactionStep::RECEIVING_FILE_DATA_PDUS) { - if (fsmRes.state == CfdpStates::BUSY_CLASS_1_NACKED) { + if (fsmRes.state == CfdpState::BUSY_CLASS_1_NACKED) { fsmRes.step = TransactionStep::TRANSFER_COMPLETION; - } else if (fsmRes.state == CfdpStates::BUSY_CLASS_2_ACKED) { + } else if (fsmRes.state == CfdpState::BUSY_CLASS_2_ACKED) { fsmRes.step = TransactionStep::SENDING_ACK_PDU; } } @@ -278,7 +278,7 @@ ReturnValue_t cfdp::DestHandler::handleMetadataParseError(ReturnValue_t result, } ReturnValue_t cfdp::DestHandler::startTransaction(MetadataPduReader& reader, MetadataInfo& info) { - if (fsmRes.state != CfdpStates::IDLE) { + if (fsmRes.state != CfdpState::IDLE) { // According to standard, discard metadata PDU if we are busy return OK; } @@ -342,9 +342,9 @@ ReturnValue_t cfdp::DestHandler::startTransaction(MetadataPduReader& reader, Met } fsmRes.step = TransactionStep::TRANSACTION_START; if (reader.getTransmissionMode() == TransmissionMode::UNACKNOWLEDGED) { - fsmRes.state = CfdpStates::BUSY_CLASS_1_NACKED; + fsmRes.state = CfdpState::BUSY_CLASS_1_NACKED; } else if (reader.getTransmissionMode() == TransmissionMode::ACKNOWLEDGED) { - fsmRes.state = CfdpStates::BUSY_CLASS_2_ACKED; + fsmRes.state = CfdpState::BUSY_CLASS_2_ACKED; } transactionParams.checksumType = info.getChecksumType(); transactionParams.closureRequested = info.isClosureRequested(); @@ -363,7 +363,7 @@ ReturnValue_t cfdp::DestHandler::startTransaction(MetadataPduReader& reader, Met return result; } -cfdp::CfdpStates cfdp::DestHandler::getCfdpState() const { return fsmRes.state; } +cfdp::CfdpState cfdp::DestHandler::getCfdpState() const { return fsmRes.state; } ReturnValue_t cfdp::DestHandler::handleTransferCompletion() { ReturnValue_t result; @@ -378,13 +378,13 @@ ReturnValue_t cfdp::DestHandler::handleTransferCompletion() { result = noticeOfCompletion(); if (result != OK) { } - if (fsmRes.state == CfdpStates::BUSY_CLASS_1_NACKED) { + if (fsmRes.state == CfdpState::BUSY_CLASS_1_NACKED) { if (transactionParams.closureRequested) { fsmRes.step = TransactionStep::SENDING_FINISHED_PDU; } else { finish(); } - } else if (fsmRes.state == CfdpStates::BUSY_CLASS_2_ACKED) { + } else if (fsmRes.state == CfdpState::BUSY_CLASS_2_ACKED) { fsmRes.step = TransactionStep::SENDING_FINISHED_PDU; } return OK; @@ -426,7 +426,7 @@ void cfdp::DestHandler::fileErrorHandler(Event event, ReturnValue_t result, void cfdp::DestHandler::finish() { transactionParams.reset(); destParams.packetListRef.clear(); - fsmRes.state = CfdpStates::IDLE; + fsmRes.state = CfdpState::IDLE; fsmRes.step = TransactionStep::IDLE; } diff --git a/src/fsfw/cfdp/handler/DestHandler.h b/src/fsfw/cfdp/handler/DestHandler.h index 5b42124f..c4793838 100644 --- a/src/fsfw/cfdp/handler/DestHandler.h +++ b/src/fsfw/cfdp/handler/DestHandler.h @@ -84,7 +84,7 @@ class DestHandler { ReturnValue_t result = returnvalue::OK; CallStatus callStatus = CallStatus::CALL_AFTER_DELAY; TransactionStep step = TransactionStep::IDLE; - CfdpStates state = CfdpStates::IDLE; + CfdpState state = CfdpState::IDLE; uint32_t packetsSent = 0; uint8_t errors = 0; std::array errorCodes = {}; @@ -117,7 +117,7 @@ class DestHandler { ReturnValue_t initialize(); - [[nodiscard]] CfdpStates getCfdpState() const; + [[nodiscard]] CfdpState getCfdpState() const; [[nodiscard]] TransactionStep getTransactionStep() const; [[nodiscard]] const TransactionId& getTransactionId() const; [[nodiscard]] const DestHandlerParams& getDestHandlerParams() const; diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index eb3722d1..49570717 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -1,3 +1,39 @@ #include "SourceHandler.h" SourceHandler::SourceHandler(SourceHandlerParams params, FsfwSourceParams fsfwParams) {} + +void SourceHandler::fsmNacked() { + if (step == TransactionStep::IDLE) { + step = TransactionStep::TRANSACTION_START; + } + if (step == TransactionStep::TRANSACTION_START) { + // TODO: Use put request information to start the transaction + step = TransactionStep::CRC_PROCEDURE; + } + if (step == TransactionStep::CRC_PROCEDURE) { + // TODO: Perform CRC procedure: Generate the CRC32 from the file. + } + if (step == TransactionStep::SENDING_METADATA) { + // TODO: Prepare and send metadata PDU + } + if (step == TransactionStep::SENDING_FILE_DATA) { + // TODO: Prepare and send file data PDUs + } + if (step == TransactionStep::SENDING_EOF) { + // TODO: Send EOF PDU + } + if (step == TransactionStep::WAIT_FOR_FINISH) { + // TODO: In case this is a request with closure, wait for finish. + } + if (step == TransactionStep::NOTICE_OF_COMPLETION) { + // TODO: Notice of completion + } +} +void SourceHandler::stateMachine() { + if (state == cfdp::CfdpState::IDLE) { + return; + } + if (state == cfdp::CfdpState::BUSY_CLASS_1_NACKED) { + return fsmNacked(); + } +} diff --git a/src/fsfw/cfdp/handler/SourceHandler.h b/src/fsfw/cfdp/handler/SourceHandler.h index 75f2f1e0..52299c9f 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.h +++ b/src/fsfw/cfdp/handler/SourceHandler.h @@ -3,6 +3,7 @@ #include +#include "defs.h" #include "fsfw/events/EventReportingProxyIF.h" #include "fsfw/storagemanager/StorageManagerIF.h" @@ -20,6 +21,8 @@ class SourceHandler { public: SourceHandler(SourceHandlerParams params, FsfwSourceParams fsfwParams); + void stateMachine(); + private: enum class TransactionStep : uint8_t { IDLE = 0, @@ -32,6 +35,10 @@ class SourceHandler { WAIT_FOR_FINISH = 7, NOTICE_OF_COMPLETION = 8 }; + cfdp::CfdpState state; + TransactionStep step; + + void fsmNacked(); }; #endif // FSFW_CFDP_CFDPSOURCEHANDLER_H diff --git a/src/fsfw/cfdp/handler/defs.h b/src/fsfw/cfdp/handler/defs.h index 29fe360e..b507a78d 100644 --- a/src/fsfw/cfdp/handler/defs.h +++ b/src/fsfw/cfdp/handler/defs.h @@ -5,7 +5,7 @@ namespace cfdp { -enum class CfdpStates { IDLE, BUSY_CLASS_1_NACKED, BUSY_CLASS_2_ACKED, SUSPENDED }; +enum class CfdpState { IDLE, BUSY_CLASS_1_NACKED, BUSY_CLASS_2_ACKED, SUSPENDED }; static constexpr uint8_t SSID = SUBSYSTEM_ID::CFDP; diff --git a/unittests/cfdp/handler/testDestHandler.cpp b/unittests/cfdp/handler/testDestHandler.cpp index a1fa5b8b..4d082418 100644 --- a/unittests/cfdp/handler/testDestHandler.cpp +++ b/unittests/cfdp/handler/testDestHandler.cpp @@ -87,7 +87,7 @@ TEST_CASE("CFDP Dest Handler", "[cfdp]") { userMock.metadataRecvd.pop(); REQUIRE(fsMock.fileMap.find(destName) != fsMock.fileMap.end()); REQUIRE(res.result == OK); - REQUIRE(res.state == CfdpStates::BUSY_CLASS_1_NACKED); + REQUIRE(res.state == CfdpState::BUSY_CLASS_1_NACKED); REQUIRE(res.step == DestHandler::TransactionStep::RECEIVING_FILE_DATA_PDUS); }; @@ -102,7 +102,7 @@ TEST_CASE("CFDP Dest Handler", "[cfdp]") { auto eofCheck = [&](const cfdp::DestHandler::FsmResult& res, const TransactionId& id) { REQUIRE(res.result == OK); - REQUIRE(res.state == CfdpStates::IDLE); + REQUIRE(res.state == CfdpState::IDLE); REQUIRE(res.errors == 0); REQUIRE(res.step == DestHandler::TransactionStep::IDLE); // Assert that the packet was deleted after handling @@ -120,7 +120,7 @@ TEST_CASE("CFDP Dest Handler", "[cfdp]") { auto fileDataPduCheck = [&](const cfdp::DestHandler::FsmResult& res, const std::vector& idsToCheck) { REQUIRE(res.result == OK); - REQUIRE(res.state == CfdpStates::BUSY_CLASS_1_NACKED); + REQUIRE(res.state == CfdpState::BUSY_CLASS_1_NACKED); REQUIRE(res.step == DestHandler::TransactionStep::RECEIVING_FILE_DATA_PDUS); for (const auto id : idsToCheck) { REQUIRE(not tcStore.hasDataAtId(id)); @@ -129,7 +129,7 @@ TEST_CASE("CFDP Dest Handler", "[cfdp]") { }; SECTION("State") { - CHECK(destHandler.getCfdpState() == CfdpStates::IDLE); + CHECK(destHandler.getCfdpState() == CfdpState::IDLE); CHECK(destHandler.getTransactionStep() == DestHandler::TransactionStep::IDLE); } @@ -138,7 +138,7 @@ TEST_CASE("CFDP Dest Handler", "[cfdp]") { CHECK(res.result == OK); CHECK(res.callStatus == CallStatus::CALL_AFTER_DELAY); CHECK(res.errors == 0); - CHECK(destHandler.getCfdpState() == CfdpStates::IDLE); + CHECK(destHandler.getCfdpState() == CfdpState::IDLE); CHECK(destHandler.getTransactionStep() == DestHandler::TransactionStep::IDLE); } From a6cc5171da982ed8a13dd72149ae9fcf3dc494c0 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 17 Jul 2023 09:53:23 +0200 Subject: [PATCH 006/101] continue source handler --- src/fsfw/cfdp/handler/DestHandler.cpp | 1 - src/fsfw/cfdp/handler/SourceHandler.cpp | 50 +++++++++++++++++++++++-- src/fsfw/cfdp/handler/SourceHandler.h | 32 ++++++++++++++-- src/fsfw/cfdp/handler/UserBase.h | 1 + src/fsfw/cfdp/handler/defs.h | 2 + 5 files changed, 78 insertions(+), 8 deletions(-) diff --git a/src/fsfw/cfdp/handler/DestHandler.cpp b/src/fsfw/cfdp/handler/DestHandler.cpp index 6ba9a918..6f4e17d0 100644 --- a/src/fsfw/cfdp/handler/DestHandler.cpp +++ b/src/fsfw/cfdp/handler/DestHandler.cpp @@ -432,7 +432,6 @@ void cfdp::DestHandler::finish() { ReturnValue_t cfdp::DestHandler::checksumVerification() { std::array buf{}; - // TODO: Checksum verification and notice of completion etl::crc32 crcCalc; uint64_t currentOffset = 0; FileOpParams params(transactionParams.destName.data(), transactionParams.fileSize.value()); diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index 49570717..50d0de3d 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -1,8 +1,17 @@ #include "SourceHandler.h" -SourceHandler::SourceHandler(SourceHandlerParams params, FsfwSourceParams fsfwParams) {} +#include -void SourceHandler::fsmNacked() { +#include + +#include "fsfw/filesystem/HasFileSystemIF.h" + +using namespace returnvalue; + +cfdp::SourceHandler::SourceHandler(SourceHandlerParams params, FsfwSourceParams fsfwParams) + : transactionParams(params.maxFilePathSize), sourceParams(std::move(params)) {} + +void cfdp::SourceHandler::fsmNacked() { if (step == TransactionStep::IDLE) { step = TransactionStep::TRANSACTION_START; } @@ -11,7 +20,10 @@ void SourceHandler::fsmNacked() { step = TransactionStep::CRC_PROCEDURE; } if (step == TransactionStep::CRC_PROCEDURE) { - // TODO: Perform CRC procedure: Generate the CRC32 from the file. + ReturnValue_t result = checksumGeneration(); + if (result != OK) { + // TODO: Some error handling + } } if (step == TransactionStep::SENDING_METADATA) { // TODO: Prepare and send metadata PDU @@ -29,7 +41,7 @@ void SourceHandler::fsmNacked() { // TODO: Notice of completion } } -void SourceHandler::stateMachine() { +void cfdp::SourceHandler::stateMachine() { if (state == cfdp::CfdpState::IDLE) { return; } @@ -37,3 +49,33 @@ void SourceHandler::stateMachine() { return fsmNacked(); } } + +ReturnValue_t cfdp::SourceHandler::checksumGeneration() { + std::array buf{}; + etl::crc32 crcCalc; + uint64_t currentOffset = 0; + FileOpParams params(transactionParams.destName.data(), transactionParams.fileSize.value()); + while (currentOffset < transactionParams.fileSize.value()) { + uint64_t readLen; + if (currentOffset + buf.size() > transactionParams.fileSize.value()) { + readLen = transactionParams.fileSize.value() - currentOffset; + } else { + readLen = buf.size(); + } + if (readLen > 0) { + params.offset = currentOffset; + params.size = readLen; + auto result = sourceParams.user.vfs.readFromFile(params, buf.data(), buf.size()); + if (result != OK) { + // TODO: I think this is a case for a filestore rejection, but it might sense to print + // a warning or trigger an event because this should generally not happen + return FAILED; + } + crcCalc.add(buf.begin(), buf.begin() + readLen); + } + currentOffset += readLen; + } + + transactionParams.crc = crcCalc.value(); + return OK; +} diff --git a/src/fsfw/cfdp/handler/SourceHandler.h b/src/fsfw/cfdp/handler/SourceHandler.h index 52299c9f..a0dc4163 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.h +++ b/src/fsfw/cfdp/handler/SourceHandler.h @@ -2,12 +2,24 @@ #define FSFW_CFDP_CFDPSOURCEHANDLER_H #include +#include +#include "UserBase.h" #include "defs.h" +#include "fsfw/cfdp/FileSize.h" +#include "fsfw/cfdp/handler/mib.h" #include "fsfw/events/EventReportingProxyIF.h" #include "fsfw/storagemanager/StorageManagerIF.h" -struct SourceHandlerParams {}; +namespace cfdp { + +struct SourceHandlerParams { + SourceHandlerParams(LocalEntityCfg cfg, UserBase& user) : cfg(std::move(cfg)), user(user) {} + + LocalEntityCfg cfg; + UserBase& user; + size_t maxFilePathSize = 256; +}; struct FsfwSourceParams { FsfwSourceParams(EventReportingProxyIF* eventReporter, StorageManagerIF& tcStore) @@ -35,10 +47,24 @@ class SourceHandler { WAIT_FOR_FINISH = 7, NOTICE_OF_COMPLETION = 8 }; - cfdp::CfdpState state; - TransactionStep step; + struct TransactionParams { + // Initialize char vectors with length + 1 for 0 termination + explicit TransactionParams(size_t maxFileNameLen) + : sourceName(maxFileNameLen + 1), destName(maxFileNameLen + 1) {} + + uint32_t crc{}; + std::vector sourceName; + std::vector destName; + cfdp::FileSize fileSize; + } transactionParams; + cfdp::CfdpState state = cfdp::CfdpState::IDLE; + TransactionStep step = TransactionStep::IDLE; + SourceHandlerParams sourceParams; void fsmNacked(); + ReturnValue_t checksumGeneration(); }; +} // namespace cfdp + #endif // FSFW_CFDP_CFDPSOURCEHANDLER_H diff --git a/src/fsfw/cfdp/handler/UserBase.h b/src/fsfw/cfdp/handler/UserBase.h index e367b4a8..d0ddeaa5 100644 --- a/src/fsfw/cfdp/handler/UserBase.h +++ b/src/fsfw/cfdp/handler/UserBase.h @@ -65,6 +65,7 @@ struct FileSegmentRecvdParams { */ class UserBase { friend class DestHandler; + friend class SourceHandler; public: explicit UserBase(HasFileSystemIF& vfs); diff --git a/src/fsfw/cfdp/handler/defs.h b/src/fsfw/cfdp/handler/defs.h index b507a78d..f4d96814 100644 --- a/src/fsfw/cfdp/handler/defs.h +++ b/src/fsfw/cfdp/handler/defs.h @@ -1,6 +1,8 @@ #ifndef FSFW_CFDP_HANDLER_DEFS_H #define FSFW_CFDP_HANDLER_DEFS_H +#include + #include "fsfw/storagemanager/storeAddress.h" namespace cfdp { From 35712070cf66bf3d8c60c952ab65f5be504a395e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 17 Jul 2023 10:15:06 +0200 Subject: [PATCH 007/101] source handler --- src/fsfw/cfdp/handler/SourceHandler.cpp | 6 +++++- src/fsfw/cfdp/handler/SourceHandler.h | 25 +++++++++++++++++++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index 50d0de3d..2b64de7a 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -9,7 +9,9 @@ using namespace returnvalue; cfdp::SourceHandler::SourceHandler(SourceHandlerParams params, FsfwSourceParams fsfwParams) - : transactionParams(params.maxFilePathSize), sourceParams(std::move(params)) {} + : transactionParams(params.maxFilePathSize), + sourceParams(std::move(params)), + fsfwParams(fsfwParams) {} void cfdp::SourceHandler::fsmNacked() { if (step == TransactionStep::IDLE) { @@ -79,3 +81,5 @@ ReturnValue_t cfdp::SourceHandler::checksumGeneration() { transactionParams.crc = crcCalc.value(); return OK; } + +ReturnValue_t cfdp::SourceHandler::putRequest() { return 0; } diff --git a/src/fsfw/cfdp/handler/SourceHandler.h b/src/fsfw/cfdp/handler/SourceHandler.h index a0dc4163..211b436b 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.h +++ b/src/fsfw/cfdp/handler/SourceHandler.h @@ -10,6 +10,7 @@ #include "fsfw/cfdp/handler/mib.h" #include "fsfw/events/EventReportingProxyIF.h" #include "fsfw/storagemanager/StorageManagerIF.h" +#include "fsfw/tmtcservices/AcceptsTelemetryIF.h" namespace cfdp { @@ -21,18 +22,37 @@ struct SourceHandlerParams { size_t maxFilePathSize = 256; }; +// TODO: This class in identical to the ones used by the destination handler. Consider unifying +// them. struct FsfwSourceParams { - FsfwSourceParams(EventReportingProxyIF* eventReporter, StorageManagerIF& tcStore) - : tcStore(&tcStore){}; + FsfwSourceParams(AcceptsTelemetryIF& packetDest, MessageQueueIF* msgQueue, + EventReportingProxyIF* eventReporter, StorageManagerIF& tcStore, + StorageManagerIF& tmStore) + : FsfwSourceParams(packetDest, msgQueue, eventReporter) { + this->tcStore = &tcStore; + this->tmStore = &tmStore; + } + FsfwSourceParams(AcceptsTelemetryIF& packetDest, MessageQueueIF* msgQueue, + EventReportingProxyIF* eventReporter) + : packetDest(packetDest), msgQueue(msgQueue), eventReporter(eventReporter) {} + AcceptsTelemetryIF& packetDest; + MessageQueueIF* msgQueue; EventReportingProxyIF* eventReporter = nullptr; StorageManagerIF* tcStore = nullptr; + StorageManagerIF* tmStore = nullptr; }; class SourceHandler { public: SourceHandler(SourceHandlerParams params, FsfwSourceParams fsfwParams); + /** + * Pass a put request to the source handler, which might initiate a CFDP transaction and start + * the state machine + * @return + */ + ReturnValue_t putRequest(); void stateMachine(); private: @@ -60,6 +80,7 @@ class SourceHandler { cfdp::CfdpState state = cfdp::CfdpState::IDLE; TransactionStep step = TransactionStep::IDLE; SourceHandlerParams sourceParams; + FsfwSourceParams fsfwParams; void fsmNacked(); ReturnValue_t checksumGeneration(); From f44110a7f584bccfb4151b65516ada9a33819311 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 17 Jul 2023 10:25:09 +0200 Subject: [PATCH 008/101] share the FSFW Param block --- src/fsfw/cfdp/handler/DestHandler.cpp | 2 +- src/fsfw/cfdp/handler/DestHandler.h | 23 ++------------------ src/fsfw/cfdp/handler/SourceHandler.cpp | 2 +- src/fsfw/cfdp/handler/SourceHandler.h | 25 ++-------------------- src/fsfw/cfdp/handler/defs.h | 21 ++++++++++++++++++ unittests/cfdp/handler/testDestHandler.cpp | 2 +- 6 files changed, 28 insertions(+), 47 deletions(-) diff --git a/src/fsfw/cfdp/handler/DestHandler.cpp b/src/fsfw/cfdp/handler/DestHandler.cpp index 6f4e17d0..fbd1785a 100644 --- a/src/fsfw/cfdp/handler/DestHandler.cpp +++ b/src/fsfw/cfdp/handler/DestHandler.cpp @@ -14,7 +14,7 @@ using namespace returnvalue; -cfdp::DestHandler::DestHandler(DestHandlerParams params, FsfwDestParams fsfwParams) +cfdp::DestHandler::DestHandler(DestHandlerParams params, FsfwParams fsfwParams) : tlvVec(params.maxTlvsInOnePdu), userTlvVec(params.maxTlvsInOnePdu), destParams(std::move(params)), diff --git a/src/fsfw/cfdp/handler/DestHandler.h b/src/fsfw/cfdp/handler/DestHandler.h index c4793838..cf55c416 100644 --- a/src/fsfw/cfdp/handler/DestHandler.h +++ b/src/fsfw/cfdp/handler/DestHandler.h @@ -47,25 +47,6 @@ struct DestHandlerParams { size_t maxFilenameLen = 255; }; -struct FsfwDestParams { - FsfwDestParams(AcceptsTelemetryIF& packetDest, MessageQueueIF* msgQueue, - EventReportingProxyIF* eventReporter, StorageManagerIF& tcStore, - StorageManagerIF& tmStore) - : FsfwDestParams(packetDest, msgQueue, eventReporter) { - this->tcStore = &tcStore; - this->tmStore = &tmStore; - } - - FsfwDestParams(AcceptsTelemetryIF& packetDest, MessageQueueIF* msgQueue, - EventReportingProxyIF* eventReporter) - : packetDest(packetDest), msgQueue(msgQueue), eventReporter(eventReporter) {} - AcceptsTelemetryIF& packetDest; - MessageQueueIF* msgQueue; - EventReportingProxyIF* eventReporter = nullptr; - StorageManagerIF* tcStore = nullptr; - StorageManagerIF* tmStore = nullptr; -}; - enum class CallStatus { DONE, CALL_AFTER_DELAY, CALL_AGAIN }; class DestHandler { @@ -101,7 +82,7 @@ class DestHandler { */ ReturnValue_t PARTIAL_SUCCESS = returnvalue::makeCode(0, 2); ReturnValue_t FAILURE = returnvalue::makeCode(0, 3); - explicit DestHandler(DestHandlerParams handlerParams, FsfwDestParams fsfwParams); + explicit DestHandler(DestHandlerParams handlerParams, FsfwParams fsfwParams); /** * @@ -166,7 +147,7 @@ class DestHandler { std::vector tlvVec; std::vector userTlvVec; DestHandlerParams destParams; - FsfwDestParams fsfwParams; + cfdp::FsfwParams fsfwParams; TransactionParams transactionParams; FsmResult fsmRes; diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index 2b64de7a..69610634 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -8,7 +8,7 @@ using namespace returnvalue; -cfdp::SourceHandler::SourceHandler(SourceHandlerParams params, FsfwSourceParams fsfwParams) +cfdp::SourceHandler::SourceHandler(SourceHandlerParams params, FsfwParams fsfwParams) : transactionParams(params.maxFilePathSize), sourceParams(std::move(params)), fsfwParams(fsfwParams) {} diff --git a/src/fsfw/cfdp/handler/SourceHandler.h b/src/fsfw/cfdp/handler/SourceHandler.h index 211b436b..0bc3d741 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.h +++ b/src/fsfw/cfdp/handler/SourceHandler.h @@ -22,30 +22,9 @@ struct SourceHandlerParams { size_t maxFilePathSize = 256; }; -// TODO: This class in identical to the ones used by the destination handler. Consider unifying -// them. -struct FsfwSourceParams { - FsfwSourceParams(AcceptsTelemetryIF& packetDest, MessageQueueIF* msgQueue, - EventReportingProxyIF* eventReporter, StorageManagerIF& tcStore, - StorageManagerIF& tmStore) - : FsfwSourceParams(packetDest, msgQueue, eventReporter) { - this->tcStore = &tcStore; - this->tmStore = &tmStore; - } - - FsfwSourceParams(AcceptsTelemetryIF& packetDest, MessageQueueIF* msgQueue, - EventReportingProxyIF* eventReporter) - : packetDest(packetDest), msgQueue(msgQueue), eventReporter(eventReporter) {} - AcceptsTelemetryIF& packetDest; - MessageQueueIF* msgQueue; - EventReportingProxyIF* eventReporter = nullptr; - StorageManagerIF* tcStore = nullptr; - StorageManagerIF* tmStore = nullptr; -}; - class SourceHandler { public: - SourceHandler(SourceHandlerParams params, FsfwSourceParams fsfwParams); + SourceHandler(SourceHandlerParams params, FsfwParams fsfwParams); /** * Pass a put request to the source handler, which might initiate a CFDP transaction and start @@ -80,7 +59,7 @@ class SourceHandler { cfdp::CfdpState state = cfdp::CfdpState::IDLE; TransactionStep step = TransactionStep::IDLE; SourceHandlerParams sourceParams; - FsfwSourceParams fsfwParams; + cfdp::FsfwParams fsfwParams; void fsmNacked(); ReturnValue_t checksumGeneration(); diff --git a/src/fsfw/cfdp/handler/defs.h b/src/fsfw/cfdp/handler/defs.h index f4d96814..8098ed99 100644 --- a/src/fsfw/cfdp/handler/defs.h +++ b/src/fsfw/cfdp/handler/defs.h @@ -3,7 +3,9 @@ #include +#include "fsfw/storagemanager/StorageManagerIF.h" #include "fsfw/storagemanager/storeAddress.h" +#include "fsfw/tmtcservices/AcceptsTelemetryIF.h" namespace cfdp { @@ -22,6 +24,25 @@ struct PacketInfo { PacketInfo() = default; }; +struct FsfwParams { + FsfwParams(AcceptsTelemetryIF& packetDest, MessageQueueIF* msgQueue, + EventReportingProxyIF* eventReporter, StorageManagerIF& tcStore, + StorageManagerIF& tmStore) + : FsfwParams(packetDest, msgQueue, eventReporter) { + this->tcStore = &tcStore; + this->tmStore = &tmStore; + } + + FsfwParams(AcceptsTelemetryIF& packetDest, MessageQueueIF* msgQueue, + EventReportingProxyIF* eventReporter) + : packetDest(packetDest), msgQueue(msgQueue), eventReporter(eventReporter) {} + AcceptsTelemetryIF& packetDest; + MessageQueueIF* msgQueue; + EventReportingProxyIF* eventReporter = nullptr; + StorageManagerIF* tcStore = nullptr; + StorageManagerIF* tmStore = nullptr; +}; + template using PacketInfoList = etl::list; using PacketInfoListBase = etl::ilist; diff --git a/unittests/cfdp/handler/testDestHandler.cpp b/unittests/cfdp/handler/testDestHandler.cpp index 4d082418..d0aea3d5 100644 --- a/unittests/cfdp/handler/testDestHandler.cpp +++ b/unittests/cfdp/handler/testDestHandler.cpp @@ -38,7 +38,7 @@ TEST_CASE("CFDP Dest Handler", "[cfdp]") { LocalPool::LocalPoolConfig storeCfg = {{10, 32}, {10, 64}, {10, 128}, {10, 1024}}; StorageManagerMock tcStore(2, storeCfg); StorageManagerMock tmStore(3, storeCfg); - FsfwDestParams fp(tmReceiver, &mqMock, &eventReporterMock); + FsfwParams fp(tmReceiver, &mqMock, &eventReporterMock); RemoteEntityCfg cfg(remoteId); remoteCfgTableMock.addRemoteConfig(cfg); fp.tcStore = &tcStore; From 1cbcfc08ffb940ff4d9267945c82cb35a62d3ea7 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 17 Jul 2023 10:46:12 +0200 Subject: [PATCH 009/101] reorder includes --- src/fsfw/cfdp/handler/SourceHandler.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index 69610634..74dd6774 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -1,10 +1,9 @@ #include "SourceHandler.h" +#include "fsfw/filesystem/HasFileSystemIF.h" #include - #include -#include "fsfw/filesystem/HasFileSystemIF.h" using namespace returnvalue; From 3b1da852299919035f8b34c3e5082909774d1f4a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 17 Jul 2023 11:37:20 +0200 Subject: [PATCH 010/101] start setting up source handler --- src/fsfw/cfdp/handler/SourceHandler.cpp | 3 +- unittests/cfdp/handler/testSourceHandler.cpp | 36 +++++++++++++++++++- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index 74dd6774..69610634 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -1,9 +1,10 @@ #include "SourceHandler.h" -#include "fsfw/filesystem/HasFileSystemIF.h" #include + #include +#include "fsfw/filesystem/HasFileSystemIF.h" using namespace returnvalue; diff --git a/unittests/cfdp/handler/testSourceHandler.cpp b/unittests/cfdp/handler/testSourceHandler.cpp index 570ecb08..f12e2442 100644 --- a/unittests/cfdp/handler/testSourceHandler.cpp +++ b/unittests/cfdp/handler/testSourceHandler.cpp @@ -1,3 +1,37 @@ #include -TEST_CASE("CFDP Source Handler", "[cfdp]") {} \ No newline at end of file +#include "fsfw/cfdp.h" +#include "fsfw/cfdp/handler/SourceHandler.h" +#include "fsfw/cfdp/pdu/EofPduCreator.h" +#include "fsfw/cfdp/pdu/FileDataCreator.h" +#include "fsfw/cfdp/pdu/MetadataPduCreator.h" +#include "mocks/AcceptsTmMock.h" +#include "mocks/EventReportingProxyMock.h" +#include "mocks/FilesystemMock.h" +#include "mocks/MessageQueueMock.h" +#include "mocks/StorageManagerMock.h" +#include "mocks/cfdp/FaultHandlerMock.h" +#include "mocks/cfdp/RemoteConfigTableMock.h" +#include "mocks/cfdp/UserMock.h" + +TEST_CASE("CFDP Source Handler", "[cfdp]") { + using namespace cfdp; + using namespace returnvalue; + MessageQueueId_t destQueueId = 2; + AcceptsTmMock tmReceiver(destQueueId); + MessageQueueMock mqMock(destQueueId); + EntityId localId = EntityId(UnsignedByteField(2)); + EntityId remoteId = EntityId(UnsignedByteField(3)); + FaultHandlerMock fhMock; + LocalEntityCfg localEntityCfg(localId, IndicationCfg(), fhMock); + FilesystemMock fsMock; + UserMock userMock(fsMock); + SourceHandlerParams dp(localEntityCfg, userMock); + + EventReportingProxyMock eventReporterMock; + LocalPool::LocalPoolConfig storeCfg = {{10, 32}, {10, 64}, {10, 128}, {10, 1024}}; + StorageManagerMock tcStore(2, storeCfg); + StorageManagerMock tmStore(3, storeCfg); + FsfwParams fp(tmReceiver, &mqMock, &eventReporterMock); + auto sourceHandler = SourceHandler(dp, fp); +} \ No newline at end of file From 95b77ed8260100fb388e1242ca1be7b5ddb5f4de Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 17 Jul 2023 13:28:32 +0200 Subject: [PATCH 011/101] put request support baseline --- src/fsfw/cfdp/handler/SourceHandler.cpp | 2 +- src/fsfw/cfdp/handler/SourceHandler.h | 2 +- src/fsfw/cfdp/handler/defs.h | 10 ++++++++++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index 69610634..bcc67039 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -82,4 +82,4 @@ ReturnValue_t cfdp::SourceHandler::checksumGeneration() { return OK; } -ReturnValue_t cfdp::SourceHandler::putRequest() { return 0; } +ReturnValue_t cfdp::SourceHandler::putRequest(PutRequestFull& putRequest) { return 0; } diff --git a/src/fsfw/cfdp/handler/SourceHandler.h b/src/fsfw/cfdp/handler/SourceHandler.h index 0bc3d741..f3009aeb 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.h +++ b/src/fsfw/cfdp/handler/SourceHandler.h @@ -31,7 +31,7 @@ class SourceHandler { * the state machine * @return */ - ReturnValue_t putRequest(); + ReturnValue_t putRequest(PutRequestFull& putRequest); void stateMachine(); private: diff --git a/src/fsfw/cfdp/handler/defs.h b/src/fsfw/cfdp/handler/defs.h index 8098ed99..06bcd87e 100644 --- a/src/fsfw/cfdp/handler/defs.h +++ b/src/fsfw/cfdp/handler/defs.h @@ -47,6 +47,16 @@ template using PacketInfoList = etl::list; using PacketInfoListBase = etl::ilist; +struct PutRequestFull { + EntityId destId; + TransmissionMode transmissionMode; + char destName[524]; + size_t destNameSize; + char sourceName[524]; + size_t sourceNameSize; + bool closureRequested; +}; + namespace events { static constexpr Event STORE_ERROR = event::makeEvent(SSID, 0, severity::LOW); From 6322a315662c81aa85a9bbcea1c4931bbd61a98a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 17 Jul 2023 13:43:48 +0200 Subject: [PATCH 012/101] some fixes --- src/fsfw/cfdp/handler/DestHandler.cpp | 5 +++-- src/fsfw/cfdp/handler/SourceHandler.cpp | 4 +++- src/fsfw/cfdp/handler/SourceHandler.h | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/fsfw/cfdp/handler/DestHandler.cpp b/src/fsfw/cfdp/handler/DestHandler.cpp index fbd1785a..4018e7d6 100644 --- a/src/fsfw/cfdp/handler/DestHandler.cpp +++ b/src/fsfw/cfdp/handler/DestHandler.cpp @@ -336,7 +336,7 @@ ReturnValue_t cfdp::DestHandler::startTransaction(MetadataPduReader& reader, Met #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "cfdp::DestHandler" << __func__ << ": No remote configuration found for destination ID " - << tp.pduConf.sourceId.getValue() << std::endl; + << transactionParams.pduConf.sourceId.getValue() << std::endl; #endif return FAILED; } @@ -463,7 +463,8 @@ ReturnValue_t cfdp::DestHandler::checksumVerification() { } else { // TODO: Proper error handling #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "CRC check for file " << tp.destName.data() << " failed" << std::endl; + sif::warning << "CRC check for file " << transactionParams.destName.data() << " failed" + << std::endl; #endif transactionParams.conditionCode = ConditionCode::FILE_CHECKSUM_FAILURE; } diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index bcc67039..05c4f315 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -82,4 +82,6 @@ ReturnValue_t cfdp::SourceHandler::checksumGeneration() { return OK; } -ReturnValue_t cfdp::SourceHandler::putRequest(PutRequestFull& putRequest) { return 0; } +ReturnValue_t cfdp::SourceHandler::putRequest(PutRequestFull& putRequest, RemoteEntityCfg& cfg) { + return 0; +} diff --git a/src/fsfw/cfdp/handler/SourceHandler.h b/src/fsfw/cfdp/handler/SourceHandler.h index f3009aeb..eced72be 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.h +++ b/src/fsfw/cfdp/handler/SourceHandler.h @@ -31,7 +31,7 @@ class SourceHandler { * the state machine * @return */ - ReturnValue_t putRequest(PutRequestFull& putRequest); + ReturnValue_t putRequest(PutRequestFull& putRequest, RemoteEntityCfg& cfg); void stateMachine(); private: From 06ef498a18a10683a6ec86225f88213f0625b838 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 17 Jul 2023 14:48:37 +0200 Subject: [PATCH 013/101] start implementing put request function --- src/fsfw/cfdp/handler/SourceHandler.cpp | 14 ++++++++++++++ src/fsfw/cfdp/handler/SourceHandler.h | 3 +++ 2 files changed, 17 insertions(+) diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index 05c4f315..e439cc29 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -83,5 +83,19 @@ ReturnValue_t cfdp::SourceHandler::checksumGeneration() { } ReturnValue_t cfdp::SourceHandler::putRequest(PutRequestFull& putRequest, RemoteEntityCfg& cfg) { + transactionParams.closureRequested = putRequest.closureRequested; + transactionParams.destId = putRequest.destId; + transactionParams.transmissionMode = putRequest.transmissionMode; + if (transactionParams.transmissionMode == TransmissionMode::ACKNOWLEDGED) { + } + if (putRequest.sourceNameSize > transactionParams.sourceName.size()) { + return FAILED; + } + std::memcpy(transactionParams.sourceName.data(), putRequest.sourceName, + putRequest.sourceNameSize); + if (putRequest.destNameSize > transactionParams.destName.size()) { + return FAILED; + } + std::memcpy(transactionParams.destName.data(), putRequest.destName, putRequest.destNameSize); return 0; } diff --git a/src/fsfw/cfdp/handler/SourceHandler.h b/src/fsfw/cfdp/handler/SourceHandler.h index eced72be..197f0978 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.h +++ b/src/fsfw/cfdp/handler/SourceHandler.h @@ -55,6 +55,9 @@ class SourceHandler { std::vector sourceName; std::vector destName; cfdp::FileSize fileSize; + EntityId destId; + TransmissionMode transmissionMode; + bool closureRequested; } transactionParams; cfdp::CfdpState state = cfdp::CfdpState::IDLE; TransactionStep step = TransactionStep::IDLE; From 972dc7e19e5048852c8e36f2bea42307d5fda672 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 17 Jul 2023 14:54:45 +0200 Subject: [PATCH 014/101] continue source handler --- src/fsfw/cfdp/handler/SourceHandler.cpp | 3 ++- src/fsfw/cfdp/handler/SourceHandler.h | 1 + src/fsfw/cfdp/handler/mib.h | 3 ++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index e439cc29..49c6160d 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -97,5 +97,6 @@ ReturnValue_t cfdp::SourceHandler::putRequest(PutRequestFull& putRequest, Remote return FAILED; } std::memcpy(transactionParams.destName.data(), putRequest.destName, putRequest.destNameSize); - return 0; + currentRemoteCfg = cfg; + return OK; } diff --git a/src/fsfw/cfdp/handler/SourceHandler.h b/src/fsfw/cfdp/handler/SourceHandler.h index 197f0978..4f15c39e 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.h +++ b/src/fsfw/cfdp/handler/SourceHandler.h @@ -63,6 +63,7 @@ class SourceHandler { TransactionStep step = TransactionStep::IDLE; SourceHandlerParams sourceParams; cfdp::FsfwParams fsfwParams; + RemoteEntityCfg currentRemoteCfg; void fsmNacked(); ReturnValue_t checksumGeneration(); diff --git a/src/fsfw/cfdp/handler/mib.h b/src/fsfw/cfdp/handler/mib.h index 553596a6..5d6ec8ad 100644 --- a/src/fsfw/cfdp/handler/mib.h +++ b/src/fsfw/cfdp/handler/mib.h @@ -27,6 +27,7 @@ struct LocalEntityCfg { }; struct RemoteEntityCfg { + RemoteEntityCfg() = default; explicit RemoteEntityCfg(EntityId id) : remoteId(std::move(id)) {} EntityId remoteId; size_t maxFileSegmentLen = 2048; @@ -34,7 +35,7 @@ struct RemoteEntityCfg { bool crcOnTransmission = false; TransmissionMode defaultTransmissionMode = TransmissionMode::UNACKNOWLEDGED; ChecksumType defaultChecksum = ChecksumType::NULL_CHECKSUM; - const uint8_t version = CFDP_VERSION_2; + uint8_t version = CFDP_VERSION_2; }; } // namespace cfdp From 8fcc4eab609ed703ef5d62f759d8911e7b41ef3a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 17 Jul 2023 15:03:08 +0200 Subject: [PATCH 015/101] some internal state handling --- src/fsfw/cfdp/handler/SourceHandler.cpp | 10 ++++++++++ src/fsfw/cfdp/handler/defs.h | 16 ++++++++++------ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index 49c6160d..85dfcef9 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -26,6 +26,7 @@ void cfdp::SourceHandler::fsmNacked() { if (result != OK) { // TODO: Some error handling } + step = TransactionStep::SENDING_METADATA; } if (step == TransactionStep::SENDING_METADATA) { // TODO: Prepare and send metadata PDU @@ -83,9 +84,18 @@ ReturnValue_t cfdp::SourceHandler::checksumGeneration() { } ReturnValue_t cfdp::SourceHandler::putRequest(PutRequestFull& putRequest, RemoteEntityCfg& cfg) { + if (state != CfdpState::IDLE) { + return SOURCE_TRANSACTION_PENDING; + } transactionParams.closureRequested = putRequest.closureRequested; transactionParams.destId = putRequest.destId; transactionParams.transmissionMode = putRequest.transmissionMode; + if (transactionParams.transmissionMode == TransmissionMode::ACKNOWLEDGED) { + state = cfdp::CfdpState::BUSY_CLASS_2_ACKED; + } else if (transactionParams.transmissionMode == TransmissionMode::UNACKNOWLEDGED) { + state = cfdp::CfdpState::BUSY_CLASS_1_NACKED; + } + step = TransactionStep::IDLE; if (transactionParams.transmissionMode == TransmissionMode::ACKNOWLEDGED) { } if (putRequest.sourceNameSize > transactionParams.sourceName.size()) { diff --git a/src/fsfw/cfdp/handler/defs.h b/src/fsfw/cfdp/handler/defs.h index 06bcd87e..395d991a 100644 --- a/src/fsfw/cfdp/handler/defs.h +++ b/src/fsfw/cfdp/handler/defs.h @@ -12,6 +12,7 @@ namespace cfdp { enum class CfdpState { IDLE, BUSY_CLASS_1_NACKED, BUSY_CLASS_2_ACKED, SUSPENDED }; static constexpr uint8_t SSID = SUBSYSTEM_ID::CFDP; +static constexpr uint8_t CID = CLASS_ID::CFDP; struct PacketInfo { PacketInfo(PduType type, store_address_t storeId, @@ -48,13 +49,14 @@ using PacketInfoList = etl::list; using PacketInfoListBase = etl::ilist; struct PutRequestFull { + public: EntityId destId; - TransmissionMode transmissionMode; - char destName[524]; - size_t destNameSize; - char sourceName[524]; - size_t sourceNameSize; - bool closureRequested; + TransmissionMode transmissionMode = TransmissionMode::UNACKNOWLEDGED; + char destName[524]{}; + size_t destNameSize = 0; + char sourceName[524]{}; + size_t sourceNameSize = 0; + bool closureRequested = true; }; namespace events { @@ -68,5 +70,7 @@ static constexpr Event FILENAME_TOO_LARGE_ERROR = event::makeEvent(SSID, 4, seve } // namespace events +static constexpr ReturnValue_t SOURCE_TRANSACTION_PENDING = returnvalue::makeCode(CID, 0); + } // namespace cfdp #endif // FSFW_CFDP_HANDLER_DEFS_H From 4dc6398fd5b1f3599f3961c4a34dfe0994eb42a4 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 17 Jul 2023 15:11:51 +0200 Subject: [PATCH 016/101] continue source FSM --- src/fsfw/cfdp/handler/SourceHandler.cpp | 42 ++++++++++++++++++++++--- src/fsfw/cfdp/handler/SourceHandler.h | 3 ++ 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index 85dfcef9..a3c92b3b 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -14,6 +14,7 @@ cfdp::SourceHandler::SourceHandler(SourceHandlerParams params, FsfwParams fsfwPa fsfwParams(fsfwParams) {} void cfdp::SourceHandler::fsmNacked() { + ReturnValue_t result; if (step == TransactionStep::IDLE) { step = TransactionStep::TRANSACTION_START; } @@ -22,26 +23,41 @@ void cfdp::SourceHandler::fsmNacked() { step = TransactionStep::CRC_PROCEDURE; } if (step == TransactionStep::CRC_PROCEDURE) { - ReturnValue_t result = checksumGeneration(); + result = checksumGeneration(); if (result != OK) { // TODO: Some error handling } step = TransactionStep::SENDING_METADATA; } if (step == TransactionStep::SENDING_METADATA) { - // TODO: Prepare and send metadata PDU + result = prepareAndSendMetadataPdu(); + if (result != OK) { + // TODO: Error handling + } } if (step == TransactionStep::SENDING_FILE_DATA) { - // TODO: Prepare and send file data PDUs + result = prepareNextFileDataPdu(); + if (result != OK) { + // TODO: Error handling + } } if (step == TransactionStep::SENDING_EOF) { - // TODO: Send EOF PDU + result = prepareEofPdu(); + if (result != OK) { + // TODO: Error handling + } } if (step == TransactionStep::WAIT_FOR_FINISH) { // TODO: In case this is a request with closure, wait for finish. + // Done, issue notice of completion + step = TransactionStep::NOTICE_OF_COMPLETION; } if (step == TransactionStep::NOTICE_OF_COMPLETION) { // TODO: Notice of completion + // We are done, go back to idle state. + // TODO: Possible reset state? + step = TransactionStep::IDLE; + state = CfdpState::IDLE; } } void cfdp::SourceHandler::stateMachine() { @@ -110,3 +126,21 @@ ReturnValue_t cfdp::SourceHandler::putRequest(PutRequestFull& putRequest, Remote currentRemoteCfg = cfg; return OK; } + +ReturnValue_t cfdp::SourceHandler::prepareAndSendMetadataPdu() { + // TODO: Implement + // Advance FSM if everythings works + step = TransactionStep::SENDING_FILE_DATA; + return OK; +} +ReturnValue_t cfdp::SourceHandler::prepareNextFileDataPdu() { + // TODO: Implement + // Advance FSM after all file data PDUs were sent + step = TransactionStep::SENDING_EOF; + return OK; +} +ReturnValue_t cfdp::SourceHandler::prepareEofPdu() { + // TODO: Implement + step = TransactionStep::WAIT_FOR_FINISH; + return OK; +} diff --git a/src/fsfw/cfdp/handler/SourceHandler.h b/src/fsfw/cfdp/handler/SourceHandler.h index 4f15c39e..36949aac 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.h +++ b/src/fsfw/cfdp/handler/SourceHandler.h @@ -67,6 +67,9 @@ class SourceHandler { void fsmNacked(); ReturnValue_t checksumGeneration(); + ReturnValue_t prepareAndSendMetadataPdu(); + ReturnValue_t prepareNextFileDataPdu(); + ReturnValue_t prepareEofPdu(); }; } // namespace cfdp From b53c48863fb6f8c065aca7f566b361e7db97c65c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 17 Jul 2023 15:21:22 +0200 Subject: [PATCH 017/101] start introducing FSM result --- src/fsfw/cfdp/handler/DestHandler.h | 2 -- src/fsfw/cfdp/handler/SourceHandler.cpp | 23 +++++++++++++++-------- src/fsfw/cfdp/handler/SourceHandler.h | 19 +++++++++++++++---- src/fsfw/cfdp/handler/defs.h | 2 ++ 4 files changed, 32 insertions(+), 14 deletions(-) diff --git a/src/fsfw/cfdp/handler/DestHandler.h b/src/fsfw/cfdp/handler/DestHandler.h index cf55c416..7777c08f 100644 --- a/src/fsfw/cfdp/handler/DestHandler.h +++ b/src/fsfw/cfdp/handler/DestHandler.h @@ -47,8 +47,6 @@ struct DestHandlerParams { size_t maxFilenameLen = 255; }; -enum class CallStatus { DONE, CALL_AFTER_DELAY, CALL_AGAIN }; - class DestHandler { public: enum class TransactionStep : uint8_t { diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index a3c92b3b..37f29419 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -13,13 +13,12 @@ cfdp::SourceHandler::SourceHandler(SourceHandlerParams params, FsfwParams fsfwPa sourceParams(std::move(params)), fsfwParams(fsfwParams) {} -void cfdp::SourceHandler::fsmNacked() { +cfdp::SourceHandler::FsmResult& cfdp::SourceHandler::fsmNacked() { ReturnValue_t result; if (step == TransactionStep::IDLE) { step = TransactionStep::TRANSACTION_START; } if (step == TransactionStep::TRANSACTION_START) { - // TODO: Use put request information to start the transaction step = TransactionStep::CRC_PROCEDURE; } if (step == TransactionStep::CRC_PROCEDURE) { @@ -34,18 +33,21 @@ void cfdp::SourceHandler::fsmNacked() { if (result != OK) { // TODO: Error handling } + return fsmResult; } if (step == TransactionStep::SENDING_FILE_DATA) { - result = prepareNextFileDataPdu(); + result = prepareAndSendNextFileDataPdu(); if (result != OK) { // TODO: Error handling } + return fsmResult; } if (step == TransactionStep::SENDING_EOF) { - result = prepareEofPdu(); + result = prepareAndSendEofPdu(); if (result != OK) { // TODO: Error handling } + return fsmResult; } if (step == TransactionStep::WAIT_FOR_FINISH) { // TODO: In case this is a request with closure, wait for finish. @@ -59,14 +61,17 @@ void cfdp::SourceHandler::fsmNacked() { step = TransactionStep::IDLE; state = CfdpState::IDLE; } + return fsmResult; } -void cfdp::SourceHandler::stateMachine() { + +cfdp::SourceHandler::FsmResult& cfdp::SourceHandler::stateMachine() { if (state == cfdp::CfdpState::IDLE) { - return; + return fsmResult; } if (state == cfdp::CfdpState::BUSY_CLASS_1_NACKED) { return fsmNacked(); } + return fsmResult; } ReturnValue_t cfdp::SourceHandler::checksumGeneration() { @@ -133,13 +138,15 @@ ReturnValue_t cfdp::SourceHandler::prepareAndSendMetadataPdu() { step = TransactionStep::SENDING_FILE_DATA; return OK; } -ReturnValue_t cfdp::SourceHandler::prepareNextFileDataPdu() { + +ReturnValue_t cfdp::SourceHandler::prepareAndSendNextFileDataPdu() { // TODO: Implement // Advance FSM after all file data PDUs were sent step = TransactionStep::SENDING_EOF; return OK; } -ReturnValue_t cfdp::SourceHandler::prepareEofPdu() { + +ReturnValue_t cfdp::SourceHandler::prepareAndSendEofPdu() { // TODO: Implement step = TransactionStep::WAIT_FOR_FINISH; return OK; diff --git a/src/fsfw/cfdp/handler/SourceHandler.h b/src/fsfw/cfdp/handler/SourceHandler.h index 36949aac..72ee6a26 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.h +++ b/src/fsfw/cfdp/handler/SourceHandler.h @@ -24,6 +24,16 @@ struct SourceHandlerParams { class SourceHandler { public: + struct FsmResult { + public: + ReturnValue_t result = returnvalue::OK; + CallStatus callStatus = CallStatus::CALL_AFTER_DELAY; + CfdpState state = CfdpState::IDLE; + uint32_t packetsSent = 0; + uint8_t errors = 0; + std::array errorCodes = {}; + }; + SourceHandler(SourceHandlerParams params, FsfwParams fsfwParams); /** @@ -32,7 +42,7 @@ class SourceHandler { * @return */ ReturnValue_t putRequest(PutRequestFull& putRequest, RemoteEntityCfg& cfg); - void stateMachine(); + FsmResult& stateMachine(); private: enum class TransactionStep : uint8_t { @@ -64,12 +74,13 @@ class SourceHandler { SourceHandlerParams sourceParams; cfdp::FsfwParams fsfwParams; RemoteEntityCfg currentRemoteCfg; + FsmResult fsmResult; - void fsmNacked(); + FsmResult& fsmNacked(); ReturnValue_t checksumGeneration(); ReturnValue_t prepareAndSendMetadataPdu(); - ReturnValue_t prepareNextFileDataPdu(); - ReturnValue_t prepareEofPdu(); + ReturnValue_t prepareAndSendNextFileDataPdu(); + ReturnValue_t prepareAndSendEofPdu(); }; } // namespace cfdp diff --git a/src/fsfw/cfdp/handler/defs.h b/src/fsfw/cfdp/handler/defs.h index 395d991a..56f231b3 100644 --- a/src/fsfw/cfdp/handler/defs.h +++ b/src/fsfw/cfdp/handler/defs.h @@ -59,6 +59,8 @@ struct PutRequestFull { bool closureRequested = true; }; +enum class CallStatus { DONE, CALL_AFTER_DELAY, CALL_AGAIN }; + namespace events { static constexpr Event STORE_ERROR = event::makeEvent(SSID, 0, severity::LOW); From 5e9d402598b67ec9dce8e54b6d745d71cae10a35 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 17 Jul 2023 16:40:44 +0200 Subject: [PATCH 018/101] getFileSize API for fsfw --- src/fsfw/cfdp/handler/SourceHandler.cpp | 14 ++++++++++++-- src/fsfw/cfdp/handler/defs.h | 1 + src/fsfw/filesystem/HasFileSystemIF.h | 2 ++ src/fsfw_hal/host/HostFilesystem.cpp | 8 ++++++++ src/fsfw_hal/host/HostFilesystem.h | 1 + unittests/mocks/FilesystemMock.cpp | 10 ++++++++++ unittests/mocks/FilesystemMock.h | 1 + 7 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index 37f29419..fd33226a 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -4,6 +4,7 @@ #include +#include "fsfw/cfdp/pdu/MetadataPduCreator.h" #include "fsfw/filesystem/HasFileSystemIF.h" using namespace returnvalue; @@ -124,6 +125,13 @@ ReturnValue_t cfdp::SourceHandler::putRequest(PutRequestFull& putRequest, Remote } std::memcpy(transactionParams.sourceName.data(), putRequest.sourceName, putRequest.sourceNameSize); + FilesystemParams params(transactionParams.sourceName.data()); + if (!sourceParams.user.vfs.fileExists(params)) { + return FILE_DOES_NOT_EXIST; + } + size_t fileSize = 0; + sourceParams.user.vfs.getFileSize(params, fileSize); + transactionParams.fileSize.setFileSize(fileSize, false); if (putRequest.destNameSize > transactionParams.destName.size()) { return FAILED; } @@ -133,8 +141,10 @@ ReturnValue_t cfdp::SourceHandler::putRequest(PutRequestFull& putRequest, Remote } ReturnValue_t cfdp::SourceHandler::prepareAndSendMetadataPdu() { - // TODO: Implement - // Advance FSM if everythings works + // FileSize fileSize(); + // auto metadataInfo = MetadataInfo(); + // TODO: Implement + // Advance FSM if everythings works step = TransactionStep::SENDING_FILE_DATA; return OK; } diff --git a/src/fsfw/cfdp/handler/defs.h b/src/fsfw/cfdp/handler/defs.h index 56f231b3..dc300e7e 100644 --- a/src/fsfw/cfdp/handler/defs.h +++ b/src/fsfw/cfdp/handler/defs.h @@ -73,6 +73,7 @@ static constexpr Event FILENAME_TOO_LARGE_ERROR = event::makeEvent(SSID, 4, seve } // namespace events static constexpr ReturnValue_t SOURCE_TRANSACTION_PENDING = returnvalue::makeCode(CID, 0); +static constexpr ReturnValue_t FILE_DOES_NOT_EXIST = returnvalue::makeCode(CID, 1); } // namespace cfdp #endif // FSFW_CFDP_HANDLER_DEFS_H diff --git a/src/fsfw/filesystem/HasFileSystemIF.h b/src/fsfw/filesystem/HasFileSystemIF.h index a507938e..db3e8ddf 100644 --- a/src/fsfw/filesystem/HasFileSystemIF.h +++ b/src/fsfw/filesystem/HasFileSystemIF.h @@ -80,6 +80,8 @@ class HasFileSystemIF { virtual bool isDirectory(const char* path) = 0; + virtual bool getFileSize(FilesystemParams params, size_t& fileSize) = 0; + virtual bool fileExists(FilesystemParams params) = 0; /** diff --git a/src/fsfw_hal/host/HostFilesystem.cpp b/src/fsfw_hal/host/HostFilesystem.cpp index 20984f77..e2f8d808 100644 --- a/src/fsfw_hal/host/HostFilesystem.cpp +++ b/src/fsfw_hal/host/HostFilesystem.cpp @@ -184,3 +184,11 @@ ReturnValue_t HostFilesystem::getBaseFilename(FilesystemParams params, char *nam baseNameLen = baseName.size(); return returnvalue::OK; } + +bool HostFilesystem::getFileSize(FilesystemParams params, size_t &fileSize) { + if (!fileExists(params)) { + return false; + } + fileSize = std::filesystem::file_size(params.path); + return true; +} diff --git a/src/fsfw_hal/host/HostFilesystem.h b/src/fsfw_hal/host/HostFilesystem.h index da217aec..1946ab9a 100644 --- a/src/fsfw_hal/host/HostFilesystem.h +++ b/src/fsfw_hal/host/HostFilesystem.h @@ -11,6 +11,7 @@ class HostFilesystem : public HasFileSystemIF { ReturnValue_t getBaseFilename(FilesystemParams params, char *nameBuf, size_t maxLen, size_t &baseNameLen) override; + virtual bool getFileSize(FilesystemParams params, size_t &fileSize) override; bool isDirectory(const char *path) override; bool fileExists(FilesystemParams params) override; ReturnValue_t truncateFile(FilesystemParams params) override; diff --git a/unittests/mocks/FilesystemMock.cpp b/unittests/mocks/FilesystemMock.cpp index 24850227..6efa12f2 100644 --- a/unittests/mocks/FilesystemMock.cpp +++ b/unittests/mocks/FilesystemMock.cpp @@ -145,3 +145,13 @@ ReturnValue_t FilesystemMock::getBaseFilename(FilesystemParams params, char *nam } bool FilesystemMock::isDirectory(const char *path) { return false; } + +bool FilesystemMock::getFileSize(FilesystemParams params, size_t &fileSize) { + std::string filename(params.path); + auto iter = fileMap.find(filename); + if (iter == fileMap.end()) { + fileSize = iter->second.fileRaw.size(); + return true; + } + return false; +} diff --git a/unittests/mocks/FilesystemMock.h b/unittests/mocks/FilesystemMock.h index 2ddbefc3..b24d5c4c 100644 --- a/unittests/mocks/FilesystemMock.h +++ b/unittests/mocks/FilesystemMock.h @@ -62,6 +62,7 @@ class FilesystemMock : public HasFileSystemIF { bool isDirectory(const char *path) override; bool fileExists(FilesystemParams params) override; ReturnValue_t truncateFile(FilesystemParams params) override; + bool getFileSize(FilesystemParams params, size_t &fileSize) override; ReturnValue_t writeToFile(FileOpParams params, const uint8_t *data) override; ReturnValue_t readFromFile(FileOpParams params, uint8_t **buffer, size_t &readSize, From 1d97327f79d7157720ab491c9f1089f473daeb9d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 17 Jul 2023 18:56:10 +0200 Subject: [PATCH 019/101] start implementing metadata PDU generation --- src/fsfw/cfdp/handler/SourceHandler.cpp | 2 +- src/fsfw/cfdp/handler/SourceHandler.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index fd33226a..38a7a84d 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -142,7 +142,7 @@ ReturnValue_t cfdp::SourceHandler::putRequest(PutRequestFull& putRequest, Remote ReturnValue_t cfdp::SourceHandler::prepareAndSendMetadataPdu() { // FileSize fileSize(); - // auto metadataInfo = MetadataInfo(); + // auto metadataInfo = MetadataInfo(transactionParams.pduConf, transactionParams.fileSize); // TODO: Implement // Advance FSM if everythings works step = TransactionStep::SENDING_FILE_DATA; diff --git a/src/fsfw/cfdp/handler/SourceHandler.h b/src/fsfw/cfdp/handler/SourceHandler.h index 72ee6a26..f3cfecb2 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.h +++ b/src/fsfw/cfdp/handler/SourceHandler.h @@ -68,6 +68,7 @@ class SourceHandler { EntityId destId; TransmissionMode transmissionMode; bool closureRequested; + PduConfig pduConf; } transactionParams; cfdp::CfdpState state = cfdp::CfdpState::IDLE; TransactionStep step = TransactionStep::IDLE; From 8e62143ac87a35ce2d9c4e40ae3b52a73cbe11c5 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 18 Jul 2023 09:38:46 +0200 Subject: [PATCH 020/101] continue impl --- src/fsfw/cfdp/handler/SourceHandler.cpp | 103 +++++++++++++++++------- src/fsfw/cfdp/handler/SourceHandler.h | 16 ++-- 2 files changed, 83 insertions(+), 36 deletions(-) diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index 38a7a84d..3268db31 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -6,13 +6,13 @@ #include "fsfw/cfdp/pdu/MetadataPduCreator.h" #include "fsfw/filesystem/HasFileSystemIF.h" +#include "fsfw/objectmanager.h" +#include "fsfw/tmtcservices/TmTcMessage.h" using namespace returnvalue; cfdp::SourceHandler::SourceHandler(SourceHandlerParams params, FsfwParams fsfwParams) - : transactionParams(params.maxFilePathSize), - sourceParams(std::move(params)), - fsfwParams(fsfwParams) {} + : sourceParams(std::move(params)), fsfwParams(fsfwParams) {} cfdp::SourceHandler::FsmResult& cfdp::SourceHandler::fsmNacked() { ReturnValue_t result; @@ -109,42 +109,70 @@ ReturnValue_t cfdp::SourceHandler::putRequest(PutRequestFull& putRequest, Remote if (state != CfdpState::IDLE) { return SOURCE_TRANSACTION_PENDING; } - transactionParams.closureRequested = putRequest.closureRequested; - transactionParams.destId = putRequest.destId; - transactionParams.transmissionMode = putRequest.transmissionMode; - if (transactionParams.transmissionMode == TransmissionMode::ACKNOWLEDGED) { - state = cfdp::CfdpState::BUSY_CLASS_2_ACKED; - } else if (transactionParams.transmissionMode == TransmissionMode::UNACKNOWLEDGED) { - state = cfdp::CfdpState::BUSY_CLASS_1_NACKED; - } - step = TransactionStep::IDLE; - if (transactionParams.transmissionMode == TransmissionMode::ACKNOWLEDGED) { - } if (putRequest.sourceNameSize > transactionParams.sourceName.size()) { return FAILED; } - std::memcpy(transactionParams.sourceName.data(), putRequest.sourceName, - putRequest.sourceNameSize); - FilesystemParams params(transactionParams.sourceName.data()); - if (!sourceParams.user.vfs.fileExists(params)) { - return FILE_DOES_NOT_EXIST; - } - size_t fileSize = 0; - sourceParams.user.vfs.getFileSize(params, fileSize); - transactionParams.fileSize.setFileSize(fileSize, false); if (putRequest.destNameSize > transactionParams.destName.size()) { return FAILED; } std::memcpy(transactionParams.destName.data(), putRequest.destName, putRequest.destNameSize); + std::memcpy(transactionParams.sourceName.data(), putRequest.sourceName, + putRequest.sourceNameSize); + transactionParams.sourceNameSize = putRequest.sourceNameSize; + transactionParams.destNameSize = putRequest.destNameSize; + FilesystemParams params(transactionParams.sourceName.data()); + if (!sourceParams.user.vfs.fileExists(params)) { + return FILE_DOES_NOT_EXIST; + } + transactionParams.closureRequested = putRequest.closureRequested; + transactionParams.pduConf.mode = putRequest.transmissionMode; + transactionParams.pduConf.destId = putRequest.destId; + // Only used for PDU forwarding, file is sent to file receiver regularly here. + transactionParams.pduConf.direction = Direction::TOWARDS_RECEIVER; + transactionParams.pduConf.sourceId = sourceParams.cfg.localId; + + if (transactionParams.pduConf.mode == TransmissionMode::ACKNOWLEDGED) { + state = cfdp::CfdpState::BUSY_CLASS_2_ACKED; + } else if (transactionParams.pduConf.mode == TransmissionMode::UNACKNOWLEDGED) { + state = cfdp::CfdpState::BUSY_CLASS_1_NACKED; + } + step = TransactionStep::IDLE; + size_t fileSize = 0; + sourceParams.user.vfs.getFileSize(params, fileSize); + transactionParams.pduConf.largeFile = false; + if (fileSize > UINT32_MAX) { + transactionParams.pduConf.largeFile = true; + } + transactionParams.fileSize.setFileSize(fileSize, transactionParams.pduConf.largeFile); currentRemoteCfg = cfg; return OK; } ReturnValue_t cfdp::SourceHandler::prepareAndSendMetadataPdu() { - // FileSize fileSize(); - // auto metadataInfo = MetadataInfo(transactionParams.pduConf, transactionParams.fileSize); - // TODO: Implement - // Advance FSM if everythings works + cfdp::StringLv sourceName(transactionParams.sourceName.data(), transactionParams.sourceNameSize); + cfdp::StringLv destName(transactionParams.sourceName.data(), transactionParams.sourceNameSize); + auto metadataInfo = MetadataInfo(transactionParams.fileSize, sourceName, destName); + auto metadataPdu = MetadataPduCreator(transactionParams.pduConf, metadataInfo); + uint8_t* dataPtr; + store_address_t storeId; + ReturnValue_t result = + fsfwParams.tcStore->getFreeElement(&storeId, metadataPdu.getSerializedSize(), &dataPtr); + if (result != OK) { + // TODO: Better error handling? + return result; + } + size_t serializedLen = 0; + result = metadataPdu.serializeBe(dataPtr, serializedLen, metadataPdu.getSerializedSize()); + if (result != OK) { + return result; + } + TmTcMessage tcMsg(storeId); + result = + fsfwParams.msgQueue->sendMessage(fsfwParams.packetDest.getReportReceptionQueue(), &tcMsg); + if (result != OK) { + return result; + } + // Advance FSM if everything works step = TransactionStep::SENDING_FILE_DATA; return OK; } @@ -161,3 +189,24 @@ ReturnValue_t cfdp::SourceHandler::prepareAndSendEofPdu() { step = TransactionStep::WAIT_FOR_FINISH; return OK; } + +ReturnValue_t cfdp::SourceHandler::initialize() { + if (fsfwParams.tmStore == nullptr) { + fsfwParams.tmStore = ObjectManager::instance()->get(objects::TM_STORE); + if (fsfwParams.tmStore == nullptr) { + return FAILED; + } + } + + if (fsfwParams.tcStore == nullptr) { + fsfwParams.tcStore = ObjectManager::instance()->get(objects::TC_STORE); + if (fsfwParams.tcStore == nullptr) { + return FAILED; + } + } + + if (fsfwParams.msgQueue == nullptr) { + return FAILED; + } + return OK; +} diff --git a/src/fsfw/cfdp/handler/SourceHandler.h b/src/fsfw/cfdp/handler/SourceHandler.h index f3cfecb2..70d1feb8 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.h +++ b/src/fsfw/cfdp/handler/SourceHandler.h @@ -44,6 +44,8 @@ class SourceHandler { ReturnValue_t putRequest(PutRequestFull& putRequest, RemoteEntityCfg& cfg); FsmResult& stateMachine(); + ReturnValue_t initialize(); + private: enum class TransactionStep : uint8_t { IDLE = 0, @@ -57,17 +59,13 @@ class SourceHandler { NOTICE_OF_COMPLETION = 8 }; struct TransactionParams { - // Initialize char vectors with length + 1 for 0 termination - explicit TransactionParams(size_t maxFileNameLen) - : sourceName(maxFileNameLen + 1), destName(maxFileNameLen + 1) {} - uint32_t crc{}; - std::vector sourceName; - std::vector destName; + std::array sourceName{}; + size_t sourceNameSize = 0; + std::array destName{}; + size_t destNameSize = 0; cfdp::FileSize fileSize; - EntityId destId; - TransmissionMode transmissionMode; - bool closureRequested; + bool closureRequested = false; PduConfig pduConf; } transactionParams; cfdp::CfdpState state = cfdp::CfdpState::IDLE; From 896b7a73582b9b0990f16f37f35c0cc46d14b270 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 19 Jul 2023 00:12:14 +0200 Subject: [PATCH 021/101] start FD PDU handling --- src/fsfw/cfdp/handler/SourceHandler.cpp | 3 +++ src/fsfw/cfdp/handler/SourceHandler.h | 1 + 2 files changed, 4 insertions(+) diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index 3268db31..074bd73f 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -4,6 +4,7 @@ #include +#include "fsfw/cfdp/pdu/FileDataCreator.h" #include "fsfw/cfdp/pdu/MetadataPduCreator.h" #include "fsfw/filesystem/HasFileSystemIF.h" #include "fsfw/objectmanager.h" @@ -179,6 +180,8 @@ ReturnValue_t cfdp::SourceHandler::prepareAndSendMetadataPdu() { ReturnValue_t cfdp::SourceHandler::prepareAndSendNextFileDataPdu() { // TODO: Implement + // auto fileDataInfo = FileDataInfo(transactionParams.fileSize); + // auto fileDataPdu = FileDataCreator(); // Advance FSM after all file data PDUs were sent step = TransactionStep::SENDING_EOF; return OK; diff --git a/src/fsfw/cfdp/handler/SourceHandler.h b/src/fsfw/cfdp/handler/SourceHandler.h index 70d1feb8..98850472 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.h +++ b/src/fsfw/cfdp/handler/SourceHandler.h @@ -65,6 +65,7 @@ class SourceHandler { std::array destName{}; size_t destNameSize = 0; cfdp::FileSize fileSize; + size_t currentFilePos = 0; bool closureRequested = false; PduConfig pduConf; } transactionParams; From 1561b9a24706b0ce2bc4dc3bbb79e6a905a122f6 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 19 Jul 2023 13:44:52 +0200 Subject: [PATCH 022/101] implemented fle data PDUs --- src/fsfw/cfdp/{FileSize.h => Fss.h} | 6 +- src/fsfw/cfdp/handler/DestHandler.cpp | 2 +- src/fsfw/cfdp/handler/DestHandler.h | 2 +- src/fsfw/cfdp/handler/SourceHandler.cpp | 83 +++++++++++++++------- src/fsfw/cfdp/handler/SourceHandler.h | 11 +-- src/fsfw/cfdp/handler/defs.h | 1 + src/fsfw/cfdp/pdu/EofInfo.cpp | 4 +- src/fsfw/cfdp/pdu/EofInfo.h | 8 +-- src/fsfw/cfdp/pdu/FileDataCreator.cpp | 2 +- src/fsfw/cfdp/pdu/FileDataInfo.cpp | 6 +- src/fsfw/cfdp/pdu/FileDataInfo.h | 10 +-- src/fsfw/cfdp/pdu/KeepAlivePduCreator.cpp | 2 +- src/fsfw/cfdp/pdu/KeepAlivePduCreator.h | 6 +- src/fsfw/cfdp/pdu/KeepAlivePduReader.cpp | 5 +- src/fsfw/cfdp/pdu/KeepAlivePduReader.h | 8 +-- src/fsfw/cfdp/pdu/MetadataInfo.cpp | 6 +- src/fsfw/cfdp/pdu/MetadataInfo.h | 11 ++- src/fsfw/cfdp/pdu/NakInfo.cpp | 6 +- src/fsfw/cfdp/pdu/NakInfo.h | 14 ++-- src/fsfw/cfdp/pdu/NakPduCreator.h | 2 +- unittests/cfdp/handler/testDestHandler.cpp | 16 ++--- unittests/cfdp/handler/testDistributor.cpp | 2 +- unittests/cfdp/pdu/testEofPdu.cpp | 2 +- unittests/cfdp/pdu/testFileData.cpp | 4 +- unittests/cfdp/pdu/testKeepAlivePdu.cpp | 2 +- unittests/cfdp/pdu/testMetadataPdu.cpp | 2 +- unittests/cfdp/pdu/testNakPdu.cpp | 12 ++-- unittests/cfdp/testCfdp.cpp | 4 +- 28 files changed, 135 insertions(+), 104 deletions(-) rename src/fsfw/cfdp/{FileSize.h => Fss.h} (93%) diff --git a/src/fsfw/cfdp/FileSize.h b/src/fsfw/cfdp/Fss.h similarity index 93% rename from src/fsfw/cfdp/FileSize.h rename to src/fsfw/cfdp/Fss.h index b0b48452..fbfc1e9a 100644 --- a/src/fsfw/cfdp/FileSize.h +++ b/src/fsfw/cfdp/Fss.h @@ -8,11 +8,11 @@ namespace cfdp { -struct FileSize : public SerializeIF { +struct Fss : public SerializeIF { public: - FileSize() = default; + Fss() = default; - explicit FileSize(uint64_t fileSize, bool isLarge = false) { setFileSize(fileSize, isLarge); }; + explicit Fss(uint64_t fileSize, bool isLarge = false) { setFileSize(fileSize, isLarge); }; [[nodiscard]] uint64_t value() const { return fileSize; } diff --git a/src/fsfw/cfdp/handler/DestHandler.cpp b/src/fsfw/cfdp/handler/DestHandler.cpp index 4018e7d6..f44f5d41 100644 --- a/src/fsfw/cfdp/handler/DestHandler.cpp +++ b/src/fsfw/cfdp/handler/DestHandler.cpp @@ -158,7 +158,7 @@ ReturnValue_t cfdp::DestHandler::handleFileDataPdu(const cfdp::PacketInfo& info) // TODO: This is not a CFDP error. Event and/or warning? return constAccessorPair.first; } - cfdp::FileSize offset; + cfdp::Fss offset; FileDataInfo fdInfo(offset); FileDataReader reader(constAccessorPair.second.data(), constAccessorPair.second.size(), fdInfo); ReturnValue_t result = reader.parseData(); diff --git a/src/fsfw/cfdp/handler/DestHandler.h b/src/fsfw/cfdp/handler/DestHandler.h index 7777c08f..40fe5e10 100644 --- a/src/fsfw/cfdp/handler/DestHandler.h +++ b/src/fsfw/cfdp/handler/DestHandler.h @@ -131,7 +131,7 @@ class DestHandler { uint16_t vfsErrorCount = 0; std::vector sourceName; std::vector destName; - cfdp::FileSize fileSize; + cfdp::Fss fileSize; TransactionId transactionId; PduConfig pduConf; ConditionCode conditionCode = ConditionCode::NO_ERROR; diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index 074bd73f..45d9d4e6 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -125,6 +125,9 @@ ReturnValue_t cfdp::SourceHandler::putRequest(PutRequestFull& putRequest, Remote if (!sourceParams.user.vfs.fileExists(params)) { return FILE_DOES_NOT_EXIST; } + if (cfg.maxFileSegmentLen > fileBuf.size() or cfg.maxFileSegmentLen == 0) { + return FILE_SEGMENT_LEN_INVALID; + } transactionParams.closureRequested = putRequest.closureRequested; transactionParams.pduConf.mode = putRequest.transmissionMode; transactionParams.pduConf.destId = putRequest.destId; @@ -138,52 +141,60 @@ ReturnValue_t cfdp::SourceHandler::putRequest(PutRequestFull& putRequest, Remote state = cfdp::CfdpState::BUSY_CLASS_1_NACKED; } step = TransactionStep::IDLE; - size_t fileSize = 0; + uint64_t fileSize = 0; sourceParams.user.vfs.getFileSize(params, fileSize); transactionParams.pduConf.largeFile = false; if (fileSize > UINT32_MAX) { transactionParams.pduConf.largeFile = true; } transactionParams.fileSize.setFileSize(fileSize, transactionParams.pduConf.largeFile); - currentRemoteCfg = cfg; + transactionParams.remoteCfg = cfg; return OK; } ReturnValue_t cfdp::SourceHandler::prepareAndSendMetadataPdu() { cfdp::StringLv sourceName(transactionParams.sourceName.data(), transactionParams.sourceNameSize); - cfdp::StringLv destName(transactionParams.sourceName.data(), transactionParams.sourceNameSize); + cfdp::StringLv destName(transactionParams.destName.data(), transactionParams.destNameSize); auto metadataInfo = MetadataInfo(transactionParams.fileSize, sourceName, destName); auto metadataPdu = MetadataPduCreator(transactionParams.pduConf, metadataInfo); - uint8_t* dataPtr; - store_address_t storeId; - ReturnValue_t result = - fsfwParams.tcStore->getFreeElement(&storeId, metadataPdu.getSerializedSize(), &dataPtr); - if (result != OK) { - // TODO: Better error handling? - return result; - } - size_t serializedLen = 0; - result = metadataPdu.serializeBe(dataPtr, serializedLen, metadataPdu.getSerializedSize()); - if (result != OK) { - return result; - } - TmTcMessage tcMsg(storeId); - result = - fsfwParams.msgQueue->sendMessage(fsfwParams.packetDest.getReportReceptionQueue(), &tcMsg); - if (result != OK) { - return result; - } + sendGenericPdu(metadataPdu); // Advance FSM if everything works step = TransactionStep::SENDING_FILE_DATA; return OK; } ReturnValue_t cfdp::SourceHandler::prepareAndSendNextFileDataPdu() { - // TODO: Implement - // auto fileDataInfo = FileDataInfo(transactionParams.fileSize); - // auto fileDataPdu = FileDataCreator(); - // Advance FSM after all file data PDUs were sent - step = TransactionStep::SENDING_EOF; + cfdp::Fss offset(transactionParams.progress); + uint64_t readLen; + uint64_t fileSize = transactionParams.fileSize.value(); + if (fileSize == 0) { + // We are done, no need to send file data PDUs for an empty file. + step = TransactionStep::SENDING_EOF; + return OK; + } + if (fileSize < transactionParams.remoteCfg.maxFileSegmentLen) { + readLen = transactionParams.fileSize.value(); + } else { + if (transactionParams.progress + transactionParams.remoteCfg.maxFileSegmentLen > fileSize) { + readLen = fileSize - transactionParams.progress; + } else { + readLen = transactionParams.remoteCfg.maxFileSegmentLen; + } + } + FileOpParams fileParams(transactionParams.sourceName.data(), readLen); + ReturnValue_t result = + sourceParams.user.vfs.readFromFile(fileParams, fileBuf.data(), fileBuf.size()); + if (result != returnvalue::OK) { + return result; + } + auto fileDataInfo = FileDataInfo(offset, fileBuf.data(), readLen); + auto fileDataPdu = FileDataCreator(transactionParams.pduConf, fileDataInfo); + sendGenericPdu(fileDataPdu); + transactionParams.progress += readLen; + if (transactionParams.progress >= fileSize) { + // Advance FSM after all file data PDUs were sent. + step = TransactionStep::SENDING_EOF; + } return OK; } @@ -213,3 +224,21 @@ ReturnValue_t cfdp::SourceHandler::initialize() { } return OK; } + +ReturnValue_t cfdp::SourceHandler::sendGenericPdu(const SerializeIF& pdu) const { + uint8_t* dataPtr; + store_address_t storeId; + ReturnValue_t result = + fsfwParams.tcStore->getFreeElement(&storeId, pdu.getSerializedSize(), &dataPtr); + if (result != OK) { + // TODO: Better error handling? + return result; + } + size_t serializedLen = 0; + result = pdu.serializeBe(dataPtr, serializedLen, pdu.getSerializedSize()); + if (result != OK) { + return result; + } + TmTcMessage tcMsg(storeId); + return fsfwParams.msgQueue->sendMessage(fsfwParams.packetDest.getReportReceptionQueue(), &tcMsg); +} diff --git a/src/fsfw/cfdp/handler/SourceHandler.h b/src/fsfw/cfdp/handler/SourceHandler.h index 98850472..059c9864 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.h +++ b/src/fsfw/cfdp/handler/SourceHandler.h @@ -6,7 +6,7 @@ #include "UserBase.h" #include "defs.h" -#include "fsfw/cfdp/FileSize.h" +#include "fsfw/cfdp/Fss.h" #include "fsfw/cfdp/handler/mib.h" #include "fsfw/events/EventReportingProxyIF.h" #include "fsfw/storagemanager/StorageManagerIF.h" @@ -64,16 +64,17 @@ class SourceHandler { size_t sourceNameSize = 0; std::array destName{}; size_t destNameSize = 0; - cfdp::FileSize fileSize; - size_t currentFilePos = 0; + cfdp::Fss fileSize; + size_t progress = 0; bool closureRequested = false; + RemoteEntityCfg remoteCfg; PduConfig pduConf; } transactionParams; cfdp::CfdpState state = cfdp::CfdpState::IDLE; TransactionStep step = TransactionStep::IDLE; + std::array fileBuf{}; SourceHandlerParams sourceParams; cfdp::FsfwParams fsfwParams; - RemoteEntityCfg currentRemoteCfg; FsmResult fsmResult; FsmResult& fsmNacked(); @@ -81,6 +82,8 @@ class SourceHandler { ReturnValue_t prepareAndSendMetadataPdu(); ReturnValue_t prepareAndSendNextFileDataPdu(); ReturnValue_t prepareAndSendEofPdu(); + + ReturnValue_t sendGenericPdu(const SerializeIF& pdu) const; }; } // namespace cfdp diff --git a/src/fsfw/cfdp/handler/defs.h b/src/fsfw/cfdp/handler/defs.h index dc300e7e..81a8895c 100644 --- a/src/fsfw/cfdp/handler/defs.h +++ b/src/fsfw/cfdp/handler/defs.h @@ -74,6 +74,7 @@ static constexpr Event FILENAME_TOO_LARGE_ERROR = event::makeEvent(SSID, 4, seve static constexpr ReturnValue_t SOURCE_TRANSACTION_PENDING = returnvalue::makeCode(CID, 0); static constexpr ReturnValue_t FILE_DOES_NOT_EXIST = returnvalue::makeCode(CID, 1); +static constexpr ReturnValue_t FILE_SEGMENT_LEN_INVALID = returnvalue::makeCode(CID, 1); } // namespace cfdp #endif // FSFW_CFDP_HANDLER_DEFS_H diff --git a/src/fsfw/cfdp/pdu/EofInfo.cpp b/src/fsfw/cfdp/pdu/EofInfo.cpp index 98e79df7..e3df5c88 100644 --- a/src/fsfw/cfdp/pdu/EofInfo.cpp +++ b/src/fsfw/cfdp/pdu/EofInfo.cpp @@ -1,6 +1,6 @@ #include "EofInfo.h" -EofInfo::EofInfo(cfdp::ConditionCode conditionCode, uint32_t checksum, cfdp::FileSize fileSize, +EofInfo::EofInfo(cfdp::ConditionCode conditionCode, uint32_t checksum, cfdp::Fss fileSize, EntityIdTlv* faultLoc) : conditionCode(conditionCode), checksum(checksum), fileSize(fileSize), faultLoc(faultLoc) {} @@ -16,7 +16,7 @@ cfdp::ConditionCode EofInfo::getConditionCode() const { return conditionCode; } EntityIdTlv* EofInfo::getFaultLoc() const { return faultLoc; } -cfdp::FileSize& EofInfo::getFileSize() { return fileSize; } +cfdp::Fss& EofInfo::getFileSize() { return fileSize; } void EofInfo::setChecksum(uint32_t checksum) { this->checksum = checksum; } diff --git a/src/fsfw/cfdp/pdu/EofInfo.h b/src/fsfw/cfdp/pdu/EofInfo.h index 4b4fb057..59bfed31 100644 --- a/src/fsfw/cfdp/pdu/EofInfo.h +++ b/src/fsfw/cfdp/pdu/EofInfo.h @@ -1,14 +1,14 @@ #ifndef FSFW_SRC_FSFW_CFDP_PDU_EOFINFO_H_ #define FSFW_SRC_FSFW_CFDP_PDU_EOFINFO_H_ -#include "../FileSize.h" +#include "../Fss.h" #include "../definitions.h" #include "fsfw/cfdp/tlv/EntityIdTlv.h" struct EofInfo { public: explicit EofInfo(EntityIdTlv* faultLoc = nullptr); - EofInfo(cfdp::ConditionCode conditionCode, uint32_t checksum, cfdp::FileSize fileSize, + EofInfo(cfdp::ConditionCode conditionCode, uint32_t checksum, cfdp::Fss fileSize, EntityIdTlv* faultLoc = nullptr); size_t getSerializedSize(bool fssLarge = false); @@ -17,7 +17,7 @@ struct EofInfo { [[nodiscard]] cfdp::ConditionCode getConditionCode() const; [[nodiscard]] EntityIdTlv* getFaultLoc() const; - cfdp::FileSize& getFileSize(); + cfdp::Fss& getFileSize(); void setChecksum(uint32_t checksum); void setConditionCode(cfdp::ConditionCode conditionCode); void setFaultLoc(EntityIdTlv* faultLoc); @@ -26,7 +26,7 @@ struct EofInfo { private: cfdp::ConditionCode conditionCode; uint32_t checksum; - cfdp::FileSize fileSize; + cfdp::Fss fileSize; EntityIdTlv* faultLoc = nullptr; }; diff --git a/src/fsfw/cfdp/pdu/FileDataCreator.cpp b/src/fsfw/cfdp/pdu/FileDataCreator.cpp index 956752fb..70779a51 100644 --- a/src/fsfw/cfdp/pdu/FileDataCreator.cpp +++ b/src/fsfw/cfdp/pdu/FileDataCreator.cpp @@ -37,7 +37,7 @@ ReturnValue_t FileDataCreator::serialize(uint8_t** buffer, size_t* size, size_t *buffer += segmentMetadataLen; *size += segmentMetadataLen; } - cfdp::FileSize& offset = info.getOffset(); + cfdp::Fss& offset = info.getOffset(); result = offset.serialize(this->getLargeFileFlag(), buffer, size, maxSize, streamEndianness); if (result != returnvalue::OK) { return result; diff --git a/src/fsfw/cfdp/pdu/FileDataInfo.cpp b/src/fsfw/cfdp/pdu/FileDataInfo.cpp index 19fc00cd..ec12e9da 100644 --- a/src/fsfw/cfdp/pdu/FileDataInfo.cpp +++ b/src/fsfw/cfdp/pdu/FileDataInfo.cpp @@ -1,9 +1,9 @@ #include "FileDataInfo.h" -FileDataInfo::FileDataInfo(cfdp::FileSize &offset, const uint8_t *fileData, size_t fileSize) +FileDataInfo::FileDataInfo(cfdp::Fss &offset, const uint8_t *fileData, size_t fileSize) : offset(offset), fileData(fileData), fileSize(fileSize) {} -FileDataInfo::FileDataInfo(cfdp::FileSize &offset) : offset(offset) {} +FileDataInfo::FileDataInfo(cfdp::Fss &offset) : offset(offset) {} void FileDataInfo::setSegmentMetadataFlag(bool enable) { if (enable) { @@ -71,7 +71,7 @@ const uint8_t *FileDataInfo::getSegmentMetadata(size_t *segmentMetadataLen_) { return segmentMetadata; } -cfdp::FileSize &FileDataInfo::getOffset() { return offset; } +cfdp::Fss &FileDataInfo::getOffset() { return offset; } void FileDataInfo::setRecordContinuationState(cfdp::RecordContinuationState recContState) { this->recContState = recContState; diff --git a/src/fsfw/cfdp/pdu/FileDataInfo.h b/src/fsfw/cfdp/pdu/FileDataInfo.h index 36908d8b..2721cda2 100644 --- a/src/fsfw/cfdp/pdu/FileDataInfo.h +++ b/src/fsfw/cfdp/pdu/FileDataInfo.h @@ -1,17 +1,17 @@ #ifndef FSFW_SRC_FSFW_CFDP_PDU_FILEDATAINFO_H_ #define FSFW_SRC_FSFW_CFDP_PDU_FILEDATAINFO_H_ -#include +#include #include class FileDataInfo { public: - explicit FileDataInfo(cfdp::FileSize& offset); - FileDataInfo(cfdp::FileSize& offset, const uint8_t* fileData, size_t fileSize); + explicit FileDataInfo(cfdp::Fss& offset); + FileDataInfo(cfdp::Fss& offset, const uint8_t* fileData, size_t fileSize); [[nodiscard]] size_t getSerializedSize(bool largeFile = false) const; - cfdp::FileSize& getOffset(); + cfdp::Fss& getOffset(); const uint8_t* getFileData(size_t* fileSize = nullptr) const; void setFileData(const uint8_t* fileData, size_t fileSize); @@ -33,7 +33,7 @@ class FileDataInfo { private: cfdp::SegmentMetadataFlag segmentMetadataFlag = cfdp::SegmentMetadataFlag::NOT_PRESENT; cfdp::SegmentationControl segCtrl = cfdp::SegmentationControl::NO_RECORD_BOUNDARIES_PRESERVATION; - cfdp::FileSize& offset; + cfdp::Fss& offset; const uint8_t* fileData = nullptr; size_t fileSize = 0; cfdp::RecordContinuationState recContState = cfdp::RecordContinuationState::NO_START_NO_END; diff --git a/src/fsfw/cfdp/pdu/KeepAlivePduCreator.cpp b/src/fsfw/cfdp/pdu/KeepAlivePduCreator.cpp index 40747751..2afcd427 100644 --- a/src/fsfw/cfdp/pdu/KeepAlivePduCreator.cpp +++ b/src/fsfw/cfdp/pdu/KeepAlivePduCreator.cpp @@ -1,6 +1,6 @@ #include "KeepAlivePduCreator.h" -KeepAlivePduCreator::KeepAlivePduCreator(PduConfig &conf, cfdp::FileSize &progress) +KeepAlivePduCreator::KeepAlivePduCreator(PduConfig &conf, cfdp::Fss &progress) : FileDirectiveCreator(conf, cfdp::FileDirective::KEEP_ALIVE, 4), progress(progress) { updateDirectiveFieldLen(); } diff --git a/src/fsfw/cfdp/pdu/KeepAlivePduCreator.h b/src/fsfw/cfdp/pdu/KeepAlivePduCreator.h index aa4bf0fd..97ce6095 100644 --- a/src/fsfw/cfdp/pdu/KeepAlivePduCreator.h +++ b/src/fsfw/cfdp/pdu/KeepAlivePduCreator.h @@ -1,12 +1,12 @@ #ifndef FSFW_CFDP_PDU_KEEPALIVEPDUSERIALIZER_H_ #define FSFW_CFDP_PDU_KEEPALIVEPDUSERIALIZER_H_ -#include "fsfw/cfdp/FileSize.h" +#include "fsfw/cfdp/Fss.h" #include "fsfw/cfdp/pdu/FileDirectiveCreator.h" class KeepAlivePduCreator : public FileDirectiveCreator { public: - KeepAlivePduCreator(PduConfig& conf, cfdp::FileSize& progress); + KeepAlivePduCreator(PduConfig& conf, cfdp::Fss& progress); void updateDirectiveFieldLen(); @@ -16,7 +16,7 @@ class KeepAlivePduCreator : public FileDirectiveCreator { Endianness streamEndianness) const override; private: - cfdp::FileSize& progress; + cfdp::Fss& progress; }; #endif /* FSFW_CFDP_PDU_KEEPALIVEPDUSERIALIZER_H_ */ diff --git a/src/fsfw/cfdp/pdu/KeepAlivePduReader.cpp b/src/fsfw/cfdp/pdu/KeepAlivePduReader.cpp index d3362cf9..73ddc678 100644 --- a/src/fsfw/cfdp/pdu/KeepAlivePduReader.cpp +++ b/src/fsfw/cfdp/pdu/KeepAlivePduReader.cpp @@ -1,7 +1,6 @@ #include "KeepAlivePduReader.h" -KeepAlivePduReader::KeepAlivePduReader(const uint8_t* pduBuf, size_t maxSize, - cfdp::FileSize& progress) +KeepAlivePduReader::KeepAlivePduReader(const uint8_t* pduBuf, size_t maxSize, cfdp::Fss& progress) : FileDirectiveReader(pduBuf, maxSize), progress(progress) {} ReturnValue_t KeepAlivePduReader::parseData() { @@ -15,4 +14,4 @@ ReturnValue_t KeepAlivePduReader::parseData() { return progress.deSerialize(&buffer, &remLen, getEndianness()); } -cfdp::FileSize& KeepAlivePduReader::getProgress() { return progress; } +cfdp::Fss& KeepAlivePduReader::getProgress() { return progress; } diff --git a/src/fsfw/cfdp/pdu/KeepAlivePduReader.h b/src/fsfw/cfdp/pdu/KeepAlivePduReader.h index 38e061f1..553101c9 100644 --- a/src/fsfw/cfdp/pdu/KeepAlivePduReader.h +++ b/src/fsfw/cfdp/pdu/KeepAlivePduReader.h @@ -1,19 +1,19 @@ #ifndef FSFW_CFDP_PDU_KEEPALIVEREADER_H_ #define FSFW_CFDP_PDU_KEEPALIVEREADER_H_ -#include "fsfw/cfdp/FileSize.h" +#include "fsfw/cfdp/Fss.h" #include "fsfw/cfdp/pdu/FileDirectiveReader.h" class KeepAlivePduReader : public FileDirectiveReader { public: - KeepAlivePduReader(const uint8_t* pduBuf, size_t maxSize, cfdp::FileSize& progress); + KeepAlivePduReader(const uint8_t* pduBuf, size_t maxSize, cfdp::Fss& progress); ReturnValue_t parseData() override; - cfdp::FileSize& getProgress(); + cfdp::Fss& getProgress(); private: - cfdp::FileSize& progress; + cfdp::Fss& progress; }; #endif /* FSFW_CFDP_PDU_KEEPALIVEPDUREADER_H_ */ diff --git a/src/fsfw/cfdp/pdu/MetadataInfo.cpp b/src/fsfw/cfdp/pdu/MetadataInfo.cpp index d88bdd87..180549e5 100644 --- a/src/fsfw/cfdp/pdu/MetadataInfo.cpp +++ b/src/fsfw/cfdp/pdu/MetadataInfo.cpp @@ -1,14 +1,14 @@ #include "MetadataInfo.h" MetadataInfo::MetadataInfo(bool closureRequested, cfdp::ChecksumType checksumType, - cfdp::FileSize& fileSize, cfdp::StringLv& sourceFileName, + cfdp::Fss& fileSize, cfdp::StringLv& sourceFileName, cfdp::StringLv& destFileName) : MetadataInfo(fileSize, sourceFileName, destFileName) { this->closureRequested = closureRequested; this->checksumType = checksumType; } -MetadataInfo::MetadataInfo(cfdp::FileSize& fileSize, cfdp::StringLv& sourceFileName, +MetadataInfo::MetadataInfo(cfdp::Fss& fileSize, cfdp::StringLv& sourceFileName, cfdp::StringLv& destFileName) : fileSize(fileSize), sourceFileName(sourceFileName), destFileName(destFileName) {} @@ -37,7 +37,7 @@ void MetadataInfo::setClosureRequested(bool closureRequested_) { cfdp::StringLv& MetadataInfo::getDestFileName() { return destFileName; } -cfdp::FileSize& MetadataInfo::getFileSize() { return fileSize; } +cfdp::Fss& MetadataInfo::getFileSize() { return fileSize; } ReturnValue_t MetadataInfo::getOptions(cfdp::Tlv*** optionsArray_, size_t* optionsLen_, size_t* maxOptsLen) { diff --git a/src/fsfw/cfdp/pdu/MetadataInfo.h b/src/fsfw/cfdp/pdu/MetadataInfo.h index 95f4544a..7ae269a9 100644 --- a/src/fsfw/cfdp/pdu/MetadataInfo.h +++ b/src/fsfw/cfdp/pdu/MetadataInfo.h @@ -3,7 +3,7 @@ #include -#include "fsfw/cfdp/FileSize.h" +#include "fsfw/cfdp/Fss.h" #include "fsfw/cfdp/definitions.h" #include "fsfw/cfdp/tlv/Lv.h" #include "fsfw/cfdp/tlv/StringLv.h" @@ -11,9 +11,8 @@ class MetadataInfo { public: - MetadataInfo(cfdp::FileSize& fileSize, cfdp::StringLv& sourceFileName, - cfdp::StringLv& destFileName); - MetadataInfo(bool closureRequested, cfdp::ChecksumType checksumType, cfdp::FileSize& fileSize, + MetadataInfo(cfdp::Fss& fileSize, cfdp::StringLv& sourceFileName, cfdp::StringLv& destFileName); + MetadataInfo(bool closureRequested, cfdp::ChecksumType checksumType, cfdp::Fss& fileSize, cfdp::StringLv& sourceFileName, cfdp::StringLv& destFileName); size_t getSerializedSize(bool fssLarge = false); @@ -30,7 +29,7 @@ class MetadataInfo { cfdp::StringLv& getDestFileName(); cfdp::StringLv& getSourceFileName(); - cfdp::FileSize& getFileSize(); + cfdp::Fss& getFileSize(); [[nodiscard]] bool hasOptions() const; [[nodiscard]] bool canHoldOptions() const; @@ -43,7 +42,7 @@ class MetadataInfo { private: bool closureRequested = false; cfdp::ChecksumType checksumType = cfdp::ChecksumType::NULL_CHECKSUM; - cfdp::FileSize& fileSize; + cfdp::Fss& fileSize; cfdp::StringLv& sourceFileName; cfdp::StringLv& destFileName; diff --git a/src/fsfw/cfdp/pdu/NakInfo.cpp b/src/fsfw/cfdp/pdu/NakInfo.cpp index 14d06cb0..8ae317f4 100644 --- a/src/fsfw/cfdp/pdu/NakInfo.cpp +++ b/src/fsfw/cfdp/pdu/NakInfo.cpp @@ -1,6 +1,6 @@ #include "NakInfo.h" -NakInfo::NakInfo(cfdp::FileSize startOfScope, cfdp::FileSize endOfScope) +NakInfo::NakInfo(cfdp::Fss startOfScope, cfdp::Fss endOfScope) : startOfScope(startOfScope), endOfScope(endOfScope) {} size_t NakInfo::getSerializedSize(bool fssLarge) { @@ -57,9 +57,9 @@ void NakInfo::setSegmentRequests(SegmentRequest* segmentRequests, size_t* segmen } } -cfdp::FileSize& NakInfo::getStartOfScope() { return startOfScope; } +cfdp::Fss& NakInfo::getStartOfScope() { return startOfScope; } -cfdp::FileSize& NakInfo::getEndOfScope() { return endOfScope; } +cfdp::Fss& NakInfo::getEndOfScope() { return endOfScope; } size_t NakInfo::getSegmentRequestsLen() const { return segmentRequestsLen; } diff --git a/src/fsfw/cfdp/pdu/NakInfo.h b/src/fsfw/cfdp/pdu/NakInfo.h index 02d6b6f4..f8f6b147 100644 --- a/src/fsfw/cfdp/pdu/NakInfo.h +++ b/src/fsfw/cfdp/pdu/NakInfo.h @@ -3,21 +3,21 @@ #include -#include "fsfw/cfdp/FileSize.h" +#include "fsfw/cfdp/Fss.h" class NakInfo { public: - using SegmentRequest = std::pair; + using SegmentRequest = std::pair; - NakInfo(cfdp::FileSize startOfScope, cfdp::FileSize endOfScope); + NakInfo(cfdp::Fss startOfScope, cfdp::Fss endOfScope); void setSegmentRequests(SegmentRequest* segmentRequests, size_t* segmentRequestLen, size_t* maxSegmentRequestLen); size_t getSerializedSize(bool fssLarge = false); - cfdp::FileSize& getStartOfScope(); - cfdp::FileSize& getEndOfScope(); + cfdp::Fss& getStartOfScope(); + cfdp::Fss& getEndOfScope(); bool hasSegmentRequests() const; bool canHoldSegmentRequests() const; @@ -31,8 +31,8 @@ class NakInfo { void setSegmentRequestLen(size_t readLen); private: - cfdp::FileSize startOfScope; - cfdp::FileSize endOfScope; + cfdp::Fss startOfScope; + cfdp::Fss endOfScope; SegmentRequest* segmentRequests = nullptr; size_t segmentRequestsLen = 0; size_t maxSegmentRequestsLen = 0; diff --git a/src/fsfw/cfdp/pdu/NakPduCreator.h b/src/fsfw/cfdp/pdu/NakPduCreator.h index bfcff78d..601078fc 100644 --- a/src/fsfw/cfdp/pdu/NakPduCreator.h +++ b/src/fsfw/cfdp/pdu/NakPduCreator.h @@ -4,7 +4,7 @@ #include #include "NakInfo.h" -#include "fsfw/cfdp/FileSize.h" +#include "fsfw/cfdp/Fss.h" #include "fsfw/cfdp/definitions.h" #include "fsfw/cfdp/pdu/FileDirectiveCreator.h" diff --git a/unittests/cfdp/handler/testDestHandler.cpp b/unittests/cfdp/handler/testDestHandler.cpp index d0aea3d5..792d919c 100644 --- a/unittests/cfdp/handler/testDestHandler.cpp +++ b/unittests/cfdp/handler/testDestHandler.cpp @@ -50,7 +50,7 @@ TEST_CASE("CFDP Dest Handler", "[cfdp]") { auto destHandler = DestHandler(dp, fp); CHECK(destHandler.initialize() == OK); - auto metadataPreparation = [&](FileSize cfdpFileSize, ChecksumType checksumType) { + auto metadataPreparation = [&](Fss cfdpFileSize, ChecksumType checksumType) { std::string srcNameString = "hello.txt"; std::string destNameString = "hello-cpy.txt"; StringLv srcName(srcNameString); @@ -91,7 +91,7 @@ TEST_CASE("CFDP Dest Handler", "[cfdp]") { REQUIRE(res.step == DestHandler::TransactionStep::RECEIVING_FILE_DATA_PDUS); }; - auto eofPreparation = [&](FileSize cfdpFileSize, uint32_t crc) { + auto eofPreparation = [&](Fss cfdpFileSize, uint32_t crc) { EofInfo eofInfo(cfdp::ConditionCode::NO_ERROR, crc, std::move(cfdpFileSize)); EofPduCreator eofCreator(conf, eofInfo); REQUIRE(tcStore.getFreeElement(&storeId, eofCreator.getSerializedSize(), &buf) == OK); @@ -145,7 +145,7 @@ TEST_CASE("CFDP Dest Handler", "[cfdp]") { SECTION("Empty File Transfer") { const DestHandler::FsmResult& res = destHandler.performStateMachine(); CHECK(res.result == OK); - FileSize cfdpFileSize(0); + Fss cfdpFileSize(0); metadataPreparation(cfdpFileSize, ChecksumType::NULL_CHECKSUM); destHandler.performStateMachine(); metadataCheck(res, "hello.txt", "hello-cpy.txt", 0); @@ -165,14 +165,14 @@ TEST_CASE("CFDP Dest Handler", "[cfdp]") { etl::crc32 crcCalc; crcCalc.add(fileData.begin(), fileData.end()); uint32_t crc32 = crcCalc.value(); - FileSize cfdpFileSize(fileData.size()); + Fss cfdpFileSize(fileData.size()); metadataPreparation(cfdpFileSize, ChecksumType::CRC_32); destHandler.performStateMachine(); metadataCheck(res, "hello.txt", "hello-cpy.txt", fileData.size()); destHandler.performStateMachine(); REQUIRE(res.callStatus == CallStatus::CALL_AFTER_DELAY); auto transactionId = destHandler.getTransactionId(); - FileSize offset(0); + Fss offset(0); FileDataInfo fdPduInfo(offset, reinterpret_cast(fileData.data()), fileData.size()); FileDataCreator fdPduCreator(conf, fdPduInfo); @@ -201,7 +201,7 @@ TEST_CASE("CFDP Dest Handler", "[cfdp]") { etl::crc32 crcCalc; crcCalc.add(largerFileData.begin(), largerFileData.end()); uint32_t crc32 = crcCalc.value(); - FileSize cfdpFileSize(largerFileData.size()); + Fss cfdpFileSize(largerFileData.size()); metadataPreparation(cfdpFileSize, ChecksumType::CRC_32); destHandler.performStateMachine(); metadataCheck(res, "hello.txt", "hello-cpy.txt", largerFileData.size()); @@ -211,7 +211,7 @@ TEST_CASE("CFDP Dest Handler", "[cfdp]") { std::vector idsToCheck; { - FileSize offset(0); + Fss offset(0); FileDataInfo fdPduInfo(offset, reinterpret_cast(largerFileData.data()), largerFileData.size() / 2); FileDataCreator fdPduCreator(conf, fdPduInfo); @@ -223,7 +223,7 @@ TEST_CASE("CFDP Dest Handler", "[cfdp]") { } { - FileSize offset(512); + Fss offset(512); FileDataInfo fdPduInfo(offset, reinterpret_cast(largerFileData.data() + 512), largerFileData.size() / 2); FileDataCreator fdPduCreator(conf, fdPduInfo); diff --git a/unittests/cfdp/handler/testDistributor.cpp b/unittests/cfdp/handler/testDistributor.cpp index 8b6c46af..04c035a7 100644 --- a/unittests/cfdp/handler/testDistributor.cpp +++ b/unittests/cfdp/handler/testDistributor.cpp @@ -21,7 +21,7 @@ TEST_CASE("CFDP Distributor", "[cfdp][distributor]") { auto tcAcceptor = AcceptsTcMock("CFDP Receiver", 0, receiverQueueId); // Set up Metadata PDU for generate test data. - cfdp::FileSize fileSize(12); + cfdp::Fss fileSize(12); const cfdp::EntityId& sourceId(groundEntityId); const cfdp::EntityId& destId(obswEntityId); cfdp::TransactionSeqNum seqNum(UnsignedByteField(12)); diff --git a/unittests/cfdp/pdu/testEofPdu.cpp b/unittests/cfdp/pdu/testEofPdu.cpp index 83e61780..0eb0342b 100644 --- a/unittests/cfdp/pdu/testEofPdu.cpp +++ b/unittests/cfdp/pdu/testEofPdu.cpp @@ -14,7 +14,7 @@ TEST_CASE("EOF PDU", "[cfdp][pdu]") { size_t sz = 0; EntityId destId(WidthInBytes::TWO_BYTES, 2); EntityIdTlv faultLoc(destId); - FileSize fileSize(12); + Fss fileSize(12); // We can already set the fault location, it will be ignored EofInfo eofInfo(cfdp::ConditionCode::NO_ERROR, 5, fileSize, &faultLoc); TransactionSeqNum seqNum(WidthInBytes::TWO_BYTES, 15); diff --git a/unittests/cfdp/pdu/testFileData.cpp b/unittests/cfdp/pdu/testFileData.cpp index 39139378..6eed1dd3 100644 --- a/unittests/cfdp/pdu/testFileData.cpp +++ b/unittests/cfdp/pdu/testFileData.cpp @@ -22,7 +22,7 @@ TEST_CASE("File Data PDU", "[cfdp][pdu]") { for (uint8_t idx = 0; idx < 10; idx++) { fileBuffer[idx] = idx; } - FileSize offset(50); + Fss offset(50); FileDataInfo info(offset, fileBuffer.data(), 10); SECTION("Serialization") { @@ -107,7 +107,7 @@ TEST_CASE("File Data PDU", "[cfdp][pdu]") { serializer.serialize(&buffer, &sz, fileDataBuffer.size(), SerializeIF::Endianness::NETWORK); REQUIRE(result == returnvalue::OK); - FileSize emptyOffset; + Fss emptyOffset; FileDataInfo emptyInfo(emptyOffset); FileDataReader deserializer(fileDataBuffer.data(), fileDataBuffer.size(), emptyInfo); result = deserializer.parseData(); diff --git a/unittests/cfdp/pdu/testKeepAlivePdu.cpp b/unittests/cfdp/pdu/testKeepAlivePdu.cpp index d07bccae..f8eeda42 100644 --- a/unittests/cfdp/pdu/testKeepAlivePdu.cpp +++ b/unittests/cfdp/pdu/testKeepAlivePdu.cpp @@ -16,7 +16,7 @@ TEST_CASE("Keep Alive PDU", "[cfdp][pdu]") { EntityId sourceId(WidthInBytes::TWO_BYTES, 1); PduConfig pduConf(sourceId, destId, TransmissionMode::ACKNOWLEDGED, seqNum); - FileSize progress(0x50); + Fss progress(0x50); SECTION("Serialize") { KeepAlivePduCreator serializer(pduConf, progress); diff --git a/unittests/cfdp/pdu/testMetadataPdu.cpp b/unittests/cfdp/pdu/testMetadataPdu.cpp index a9f8bf86..747a2dc3 100644 --- a/unittests/cfdp/pdu/testMetadataPdu.cpp +++ b/unittests/cfdp/pdu/testMetadataPdu.cpp @@ -22,7 +22,7 @@ TEST_CASE("Metadata PDU", "[cfdp][pdu]") { std::string firstFileName = "hello.txt"; cfdp::StringLv sourceFileName(firstFileName); cfdp::StringLv destFileName; - FileSize fileSize(35); + Fss fileSize(35); MetadataInfo info(false, ChecksumType::MODULAR, fileSize, sourceFileName, destFileName); FilestoreResponseTlv response(FilestoreActionCode::CREATE_DIRECTORY, FSR_CREATE_NOT_ALLOWED, diff --git a/unittests/cfdp/pdu/testNakPdu.cpp b/unittests/cfdp/pdu/testNakPdu.cpp index 7974dab1..c3650c63 100644 --- a/unittests/cfdp/pdu/testNakPdu.cpp +++ b/unittests/cfdp/pdu/testNakPdu.cpp @@ -17,8 +17,8 @@ TEST_CASE("NAK PDU", "[cfdp][pdu]") { EntityId sourceId(WidthInBytes::TWO_BYTES, 1); PduConfig pduConf(sourceId, destId, TransmissionMode::ACKNOWLEDGED, seqNum); - FileSize startOfScope(50); - FileSize endOfScope(1050); + Fss startOfScope(50); + Fss endOfScope(1050); NakInfo info(startOfScope, endOfScope); SECTION("Serializer") { NakPduCreator serializer(pduConf, info); @@ -40,8 +40,8 @@ TEST_CASE("NAK PDU", "[cfdp][pdu]") { REQUIRE(result == returnvalue::OK); REQUIRE(scope == 1050); - NakInfo::SegmentRequest segReq0(cfdp::FileSize(2020), cfdp::FileSize(2520)); - NakInfo::SegmentRequest segReq1(cfdp::FileSize(2932), cfdp::FileSize(3021)); + NakInfo::SegmentRequest segReq0(cfdp::Fss(2020), cfdp::Fss(2520)); + NakInfo::SegmentRequest segReq1(cfdp::Fss(2932), cfdp::Fss(3021)); // Now add 2 segment requests to NAK info and serialize them as well std::array segReqs = {segReq0, segReq1}; size_t segReqsLen = segReqs.size(); @@ -100,8 +100,8 @@ TEST_CASE("NAK PDU", "[cfdp][pdu]") { REQUIRE(info.getStartOfScope().getSize() == 50); REQUIRE(info.getEndOfScope().getSize() == 1050); - NakInfo::SegmentRequest segReq0(cfdp::FileSize(2020), cfdp::FileSize(2520)); - NakInfo::SegmentRequest segReq1(cfdp::FileSize(2932), cfdp::FileSize(3021)); + NakInfo::SegmentRequest segReq0(cfdp::Fss(2020), cfdp::Fss(2520)); + NakInfo::SegmentRequest segReq1(cfdp::Fss(2932), cfdp::Fss(3021)); // Now add 2 segment requests to NAK info and serialize them as well std::array segReqs = {segReq0, segReq1}; size_t segReqsLen = segReqs.size(); diff --git a/unittests/cfdp/testCfdp.cpp b/unittests/cfdp/testCfdp.cpp index 467b5b2d..60b14b77 100644 --- a/unittests/cfdp/testCfdp.cpp +++ b/unittests/cfdp/testCfdp.cpp @@ -2,7 +2,7 @@ #include #include -#include "fsfw/cfdp/FileSize.h" +#include "fsfw/cfdp/Fss.h" #include "fsfw/cfdp/pdu/FileDirectiveCreator.h" #include "fsfw/cfdp/pdu/FileDirectiveReader.h" #include "fsfw/globalfunctions/arrayprinter.h" @@ -79,7 +79,7 @@ TEST_CASE("CFDP Base", "[cfdp]") { std::array fssBuf = {}; uint8_t* buffer = fssBuf.data(); size_t size = 0; - cfdp::FileSize fss; + cfdp::Fss fss; REQUIRE(fss.getSize() == 0); fss.setFileSize(0x20, false); result = fss.serialize(&buffer, &size, fssBuf.size(), SerializeIF::Endianness::MACHINE); From 1bfb695b41c6b60e2d2743b382ba0a8a8cd7a485 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 19 Jul 2023 14:02:03 +0200 Subject: [PATCH 023/101] some minor tweaks --- src/fsfw/cfdp/Fss.h | 3 +++ src/fsfw/cfdp/handler/SourceHandler.cpp | 2 ++ src/fsfw/cfdp/pdu/EofInfo.cpp | 19 ++++++++++++------- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/fsfw/cfdp/Fss.h b/src/fsfw/cfdp/Fss.h index fbfc1e9a..f7110122 100644 --- a/src/fsfw/cfdp/Fss.h +++ b/src/fsfw/cfdp/Fss.h @@ -8,6 +8,9 @@ namespace cfdp { +/** + * Helper type for the CFDP File Size Sensitive (FSS) fields. + */ struct Fss : public SerializeIF { public: Fss() = default; diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index 45d9d4e6..affdf9f0 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -4,6 +4,7 @@ #include +#include "fsfw/cfdp/pdu/EofPduCreator.h" #include "fsfw/cfdp/pdu/FileDataCreator.h" #include "fsfw/cfdp/pdu/MetadataPduCreator.h" #include "fsfw/filesystem/HasFileSystemIF.h" @@ -200,6 +201,7 @@ ReturnValue_t cfdp::SourceHandler::prepareAndSendNextFileDataPdu() { ReturnValue_t cfdp::SourceHandler::prepareAndSendEofPdu() { // TODO: Implement + auto eofInfo = EofInfo(); step = TransactionStep::WAIT_FOR_FINISH; return OK; } diff --git a/src/fsfw/cfdp/pdu/EofInfo.cpp b/src/fsfw/cfdp/pdu/EofInfo.cpp index e3df5c88..b226fe7f 100644 --- a/src/fsfw/cfdp/pdu/EofInfo.cpp +++ b/src/fsfw/cfdp/pdu/EofInfo.cpp @@ -1,8 +1,13 @@ #include "EofInfo.h" +#include + EofInfo::EofInfo(cfdp::ConditionCode conditionCode, uint32_t checksum, cfdp::Fss fileSize, EntityIdTlv* faultLoc) - : conditionCode(conditionCode), checksum(checksum), fileSize(fileSize), faultLoc(faultLoc) {} + : conditionCode(conditionCode), + checksum(checksum), + fileSize(std::move(fileSize)), + faultLoc(faultLoc) {} EofInfo::EofInfo(EntityIdTlv* faultLoc) : conditionCode(cfdp::ConditionCode::NO_CONDITION_FIELD), @@ -18,13 +23,13 @@ EntityIdTlv* EofInfo::getFaultLoc() const { return faultLoc; } cfdp::Fss& EofInfo::getFileSize() { return fileSize; } -void EofInfo::setChecksum(uint32_t checksum) { this->checksum = checksum; } +void EofInfo::setChecksum(uint32_t checksum_) { this->checksum = checksum_; } -void EofInfo::setConditionCode(cfdp::ConditionCode conditionCode) { - this->conditionCode = conditionCode; +void EofInfo::setConditionCode(cfdp::ConditionCode conditionCode_) { + this->conditionCode = conditionCode_; } -void EofInfo::setFaultLoc(EntityIdTlv* faultLoc) { this->faultLoc = faultLoc; } +void EofInfo::setFaultLoc(EntityIdTlv* faultLoc_) { this->faultLoc = faultLoc_; } size_t EofInfo::getSerializedSize(bool fssLarge) { // Condition code + spare + 4 byte checksum @@ -42,6 +47,6 @@ size_t EofInfo::getSerializedSize(bool fssLarge) { return size; } -ReturnValue_t EofInfo::setFileSize(size_t fileSize, bool isLarge) { - return this->fileSize.setFileSize(fileSize, isLarge); +ReturnValue_t EofInfo::setFileSize(size_t fileSize_, bool isLarge) { + return this->fileSize.setFileSize(fileSize_, isLarge); } From 6c9c4ee047b061bd48f8a5c184b41ffb5875e103 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 19 Jul 2023 14:06:15 +0200 Subject: [PATCH 024/101] add EOF impl --- src/fsfw/cfdp/handler/SourceHandler.cpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index affdf9f0..74333a69 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -158,7 +158,10 @@ ReturnValue_t cfdp::SourceHandler::prepareAndSendMetadataPdu() { cfdp::StringLv destName(transactionParams.destName.data(), transactionParams.destNameSize); auto metadataInfo = MetadataInfo(transactionParams.fileSize, sourceName, destName); auto metadataPdu = MetadataPduCreator(transactionParams.pduConf, metadataInfo); - sendGenericPdu(metadataPdu); + ReturnValue_t result = sendGenericPdu(metadataPdu); + if (result != OK) { + return result; + } // Advance FSM if everything works step = TransactionStep::SENDING_FILE_DATA; return OK; @@ -190,7 +193,10 @@ ReturnValue_t cfdp::SourceHandler::prepareAndSendNextFileDataPdu() { } auto fileDataInfo = FileDataInfo(offset, fileBuf.data(), readLen); auto fileDataPdu = FileDataCreator(transactionParams.pduConf, fileDataInfo); - sendGenericPdu(fileDataPdu); + result = sendGenericPdu(fileDataPdu); + if (result != OK) { + return result; + } transactionParams.progress += readLen; if (transactionParams.progress >= fileSize) { // Advance FSM after all file data PDUs were sent. @@ -200,8 +206,13 @@ ReturnValue_t cfdp::SourceHandler::prepareAndSendNextFileDataPdu() { } ReturnValue_t cfdp::SourceHandler::prepareAndSendEofPdu() { - // TODO: Implement - auto eofInfo = EofInfo(); + // TODO: Checksum + auto eofInfo = EofInfo(ConditionCode::NO_ERROR, 0, transactionParams.fileSize); + auto eofPdu = EofPduCreator(transactionParams.pduConf, eofInfo); + ReturnValue_t result = sendGenericPdu(eofPdu); + if (result != OK) { + return result; + } step = TransactionStep::WAIT_FOR_FINISH; return OK; } From 273fd3ebfd9feeedf912957f076a625bfc91af5a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 19 Jul 2023 23:22:55 +0200 Subject: [PATCH 025/101] added sequence count provider abstraction --- src/fsfw/CMakeLists.txt | 1 + src/fsfw/cfdp/VarLenFields.cpp | 29 ++++++++++++---- src/fsfw/cfdp/VarLenFields.h | 5 +-- src/fsfw/cfdp/definitions.h | 1 + src/fsfw/cfdp/handler/SourceHandler.cpp | 23 ++++++++++++- src/fsfw/cfdp/handler/SourceHandler.h | 9 +++-- src/fsfw/cfdp/pdu/HeaderReader.cpp | 16 ++++++--- src/fsfw/cfdp/pdu/PduHeaderReader.h | 3 +- src/fsfw/util/CMakeLists.txt | 1 + src/fsfw/util/ProvidesSeqCountIF.h | 19 +++++++++++ src/fsfw/util/SeqCountProvider.h | 24 ++++++++++++++ unittests/cfdp/handler/testSourceHandler.cpp | 4 ++- unittests/cfdp/pdu/testCfdpHeader.cpp | 30 ++++++++--------- unittests/cfdp/testTlv.cpp | 2 +- unittests/util/CMakeLists.txt | 3 +- unittests/util/testSeqCountProvider.cpp | 35 ++++++++++++++++++++ 16 files changed, 171 insertions(+), 34 deletions(-) create mode 100644 src/fsfw/util/CMakeLists.txt create mode 100644 src/fsfw/util/ProvidesSeqCountIF.h create mode 100644 src/fsfw/util/SeqCountProvider.h create mode 100644 unittests/util/testSeqCountProvider.cpp diff --git a/src/fsfw/CMakeLists.txt b/src/fsfw/CMakeLists.txt index e645d34f..c8d4dc37 100644 --- a/src/fsfw/CMakeLists.txt +++ b/src/fsfw/CMakeLists.txt @@ -32,6 +32,7 @@ add_subdirectory(timemanager) add_subdirectory(tmtcpacket) add_subdirectory(tmtcservices) add_subdirectory(filesystem) +add_subdirectory(util) # Optional diff --git a/src/fsfw/cfdp/VarLenFields.cpp b/src/fsfw/cfdp/VarLenFields.cpp index b9e0b3a8..d5f4747a 100644 --- a/src/fsfw/cfdp/VarLenFields.cpp +++ b/src/fsfw/cfdp/VarLenFields.cpp @@ -3,8 +3,8 @@ #include "fsfw/serialize/SerializeAdapter.h" #include "fsfw/serviceinterface.h" -cfdp::VarLenField::VarLenField(cfdp::WidthInBytes width, size_t value) : VarLenField() { - ReturnValue_t result = this->setValue(width, value); +cfdp::VarLenField::VarLenField(cfdp::WidthInBytes width, uint64_t value) : VarLenField() { + ReturnValue_t result = this->setValueAndWidth(width, value); if (result != returnvalue::OK) { #if FSFW_DISABLE_PRINTOUT == 0 #if FSFW_CPP_OSTREAM_ENABLED == 1 @@ -20,8 +20,8 @@ cfdp::VarLenField::VarLenField() : width(cfdp::WidthInBytes::ONE_BYTE) { value.o cfdp::WidthInBytes cfdp::VarLenField::getWidth() const { return width; } -ReturnValue_t cfdp::VarLenField::setValue(cfdp::WidthInBytes widthInBytes, size_t value_) { - switch (widthInBytes) { +ReturnValue_t cfdp::VarLenField::setValueAndWidth(cfdp::WidthInBytes width_, uint64_t value_) { + switch (width_) { case (cfdp::WidthInBytes::ONE_BYTE): { if (value_ > UINT8_MAX) { return returnvalue::FAILED; @@ -43,15 +43,18 @@ ReturnValue_t cfdp::VarLenField::setValue(cfdp::WidthInBytes widthInBytes, size_ this->value.fourBytes = value_; break; } + case (cfdp::WidthInBytes::EIGHT_BYTES): { + this->value.eightBytes = value_; + } default: { break; } } - this->width = widthInBytes; + this->width = width_; return returnvalue::OK; } -size_t cfdp::VarLenField::getValue() const { +uint64_t cfdp::VarLenField::getValue() const { switch (width) { case (cfdp::WidthInBytes::ONE_BYTE): { return value.oneByte; @@ -62,6 +65,9 @@ size_t cfdp::VarLenField::getValue() const { case (cfdp::WidthInBytes::FOUR_BYTES): { return value.fourBytes; } + case (cfdp::WidthInBytes::EIGHT_BYTES): { + return value.eightBytes; + } } return 0; } @@ -84,6 +90,10 @@ ReturnValue_t cfdp::VarLenField::serialize(uint8_t **buffer, size_t *size, size_ case (cfdp::WidthInBytes::FOUR_BYTES): { return SerializeAdapter::serialize(&value.fourBytes, buffer, size, maxSize, streamEndianness); } + case (cfdp::WidthInBytes::EIGHT_BYTES): { + return SerializeAdapter::serialize(&value.eightBytes, buffer, size, maxSize, + streamEndianness); + } default: { return returnvalue::FAILED; } @@ -98,6 +108,10 @@ ReturnValue_t cfdp::VarLenField::deSerialize(cfdp::WidthInBytes width_, const ui return deSerialize(buffer, size, streamEndianness); } +ReturnValue_t cfdp::VarLenField::setValue(uint64_t value_) { + return setValueAndWidth(getWidth(), value_); +} + ReturnValue_t cfdp::VarLenField::deSerialize(const uint8_t **buffer, size_t *size, Endianness streamEndianness) { switch (width) { @@ -112,6 +126,9 @@ ReturnValue_t cfdp::VarLenField::deSerialize(const uint8_t **buffer, size_t *siz case (cfdp::WidthInBytes::FOUR_BYTES): { return SerializeAdapter::deSerialize(&value.fourBytes, buffer, size, streamEndianness); } + case (cfdp::WidthInBytes::EIGHT_BYTES): { + return SerializeAdapter::deSerialize(&value.eightBytes, buffer, size, streamEndianness); + } default: { return returnvalue::FAILED; } diff --git a/src/fsfw/cfdp/VarLenFields.h b/src/fsfw/cfdp/VarLenFields.h index 37602c75..cdfcc775 100644 --- a/src/fsfw/cfdp/VarLenFields.h +++ b/src/fsfw/cfdp/VarLenFields.h @@ -31,7 +31,8 @@ class VarLenField : public SerializeIF { bool operator!=(const VarLenField &other) const; bool operator<(const VarLenField &other) const; - ReturnValue_t setValue(cfdp::WidthInBytes, size_t value); + ReturnValue_t setValueAndWidth(cfdp::WidthInBytes width, uint64_t value); + ReturnValue_t setValue(uint64_t value); ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize, Endianness streamEndianness) const override; @@ -64,7 +65,7 @@ template cfdp::VarLenField::VarLenField(UnsignedByteField byteField) : width(static_cast(sizeof(T))) { static_assert((sizeof(T) % 2) == 0); - setValue(width, byteField.getValue()); + setValueAndWidth(width, byteField.getValue()); } struct EntityId : public VarLenField { diff --git a/src/fsfw/cfdp/definitions.h b/src/fsfw/cfdp/definitions.h index 2d7a37fc..3faa8294 100644 --- a/src/fsfw/cfdp/definitions.h +++ b/src/fsfw/cfdp/definitions.h @@ -68,6 +68,7 @@ enum WidthInBytes : uint8_t { ONE_BYTE = 1, TWO_BYTES = 2, FOUR_BYTES = 4, + EIGHT_BYTES = 8 }; enum FileDirective : uint8_t { diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index 74333a69..0c4c6ed8 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -9,12 +9,31 @@ #include "fsfw/cfdp/pdu/MetadataPduCreator.h" #include "fsfw/filesystem/HasFileSystemIF.h" #include "fsfw/objectmanager.h" +#include "fsfw/serviceinterface.h" #include "fsfw/tmtcservices/TmTcMessage.h" using namespace returnvalue; cfdp::SourceHandler::SourceHandler(SourceHandlerParams params, FsfwParams fsfwParams) - : sourceParams(std::move(params)), fsfwParams(fsfwParams) {} + : sourceParams(std::move(params)), fsfwParams(fsfwParams) { + // The entity ID portion of the transaction ID will always remain fixed. + transactionParams.id.entityId = sourceParams.cfg.localId; + if (sourceParams.seqCountProvider.bitWidth() == 8) { + transactionParams.seqCountWidth = cfdp::WidthInBytes::ONE_BYTE; + } else if (sourceParams.seqCountProvider.bitWidth() == 16) { + transactionParams.seqCountWidth = cfdp::WidthInBytes::TWO_BYTES; + } else if (sourceParams.seqCountProvider.bitWidth() == 32) { + transactionParams.seqCountWidth = cfdp::WidthInBytes::FOUR_BYTES; + } else { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "cfdp::SourceHandler: Seq count provider bit width " + << sourceParams.seqCountProvider.bitWidth() << " not allowed" << std::endl; +#else +#endif + // Yeah, what am I supposed to do here? Can't throw an exception in the FSFW.. + transactionParams.seqCountWidth = cfdp::WidthInBytes::ONE_BYTE; + } +} cfdp::SourceHandler::FsmResult& cfdp::SourceHandler::fsmNacked() { ReturnValue_t result; @@ -22,6 +41,7 @@ cfdp::SourceHandler::FsmResult& cfdp::SourceHandler::fsmNacked() { step = TransactionStep::TRANSACTION_START; } if (step == TransactionStep::TRANSACTION_START) { + sourceParams.user.transactionIndication(transactionParams.id); step = TransactionStep::CRC_PROCEDURE; } if (step == TransactionStep::CRC_PROCEDURE) { @@ -135,6 +155,7 @@ ReturnValue_t cfdp::SourceHandler::putRequest(PutRequestFull& putRequest, Remote // Only used for PDU forwarding, file is sent to file receiver regularly here. transactionParams.pduConf.direction = Direction::TOWARDS_RECEIVER; transactionParams.pduConf.sourceId = sourceParams.cfg.localId; + transactionParams.id.seqNum.setValue(sourceParams.seqCountProvider.getAndIncrement()); if (transactionParams.pduConf.mode == TransmissionMode::ACKNOWLEDGED) { state = cfdp::CfdpState::BUSY_CLASS_2_ACKED; diff --git a/src/fsfw/cfdp/handler/SourceHandler.h b/src/fsfw/cfdp/handler/SourceHandler.h index 059c9864..b517d709 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.h +++ b/src/fsfw/cfdp/handler/SourceHandler.h @@ -11,15 +11,17 @@ #include "fsfw/events/EventReportingProxyIF.h" #include "fsfw/storagemanager/StorageManagerIF.h" #include "fsfw/tmtcservices/AcceptsTelemetryIF.h" +#include "fsfw/util/ProvidesSeqCountIF.h" namespace cfdp { struct SourceHandlerParams { - SourceHandlerParams(LocalEntityCfg cfg, UserBase& user) : cfg(std::move(cfg)), user(user) {} + SourceHandlerParams(LocalEntityCfg cfg, UserBase& user, ProvidesSeqCountIF& seqCountProvider) + : cfg(std::move(cfg)), user(user), seqCountProvider(seqCountProvider) {} LocalEntityCfg cfg; UserBase& user; - size_t maxFilePathSize = 256; + ProvidesSeqCountIF& seqCountProvider; }; class SourceHandler { @@ -69,6 +71,9 @@ class SourceHandler { bool closureRequested = false; RemoteEntityCfg remoteCfg; PduConfig pduConf; + cfdp::TransactionId id{}; + cfdp::WidthInBytes seqCountWidth; + uint32_t seqNum = 0; } transactionParams; cfdp::CfdpState state = cfdp::CfdpState::IDLE; TransactionStep step = TransactionStep::IDLE; diff --git a/src/fsfw/cfdp/pdu/HeaderReader.cpp b/src/fsfw/cfdp/pdu/HeaderReader.cpp index de3d2906..4d853920 100644 --- a/src/fsfw/cfdp/pdu/HeaderReader.cpp +++ b/src/fsfw/cfdp/pdu/HeaderReader.cpp @@ -103,11 +103,11 @@ void PduHeaderReader::getTransactionSeqNum(cfdp::TransactionSeqNum &seqNum) cons } void PduHeaderReader::assignVarLenField(cfdp::VarLenField *field, cfdp::WidthInBytes width, - void *sourcePtr) const { + void *sourcePtr) { switch (width) { case (cfdp::WidthInBytes::ONE_BYTE): { auto *fieldTyped = static_cast(sourcePtr); - field->setValue(width, *fieldTyped); + field->setValueAndWidth(width, *fieldTyped); break; } case (cfdp::WidthInBytes::TWO_BYTES): { @@ -115,7 +115,7 @@ void PduHeaderReader::assignVarLenField(cfdp::VarLenField *field, cfdp::WidthInB size_t deserSize = 0; SerializeAdapter::deSerialize(&fieldTyped, static_cast(sourcePtr), &deserSize, SerializeIF::Endianness::NETWORK); - field->setValue(width, fieldTyped); + field->setValueAndWidth(width, fieldTyped); break; } case (cfdp::WidthInBytes::FOUR_BYTES): { @@ -123,7 +123,15 @@ void PduHeaderReader::assignVarLenField(cfdp::VarLenField *field, cfdp::WidthInB size_t deserSize = 0; SerializeAdapter::deSerialize(&fieldTyped, static_cast(sourcePtr), &deserSize, SerializeIF::Endianness::NETWORK); - field->setValue(width, fieldTyped); + field->setValueAndWidth(width, fieldTyped); + break; + } + case (cfdp::WidthInBytes::EIGHT_BYTES): { + uint64_t fieldTyped = 0; + size_t deserSize = 0; + SerializeAdapter::deSerialize(&fieldTyped, static_cast(sourcePtr), &deserSize, + SerializeIF::Endianness::NETWORK); + field->setValueAndWidth(width, fieldTyped); break; } } diff --git a/src/fsfw/cfdp/pdu/PduHeaderReader.h b/src/fsfw/cfdp/pdu/PduHeaderReader.h index a2e122cd..d910e0e3 100644 --- a/src/fsfw/cfdp/pdu/PduHeaderReader.h +++ b/src/fsfw/cfdp/pdu/PduHeaderReader.h @@ -105,7 +105,8 @@ class PduHeaderReader : public RedirectableDataPointerIF, public PduHeaderIF { * @return */ ReturnValue_t setData(uint8_t* dataPtr, size_t maxSize, void* args) override; - void assignVarLenField(cfdp::VarLenField* field, cfdp::WidthInBytes width, void* sourcePtr) const; + static void assignVarLenField(cfdp::VarLenField* field, cfdp::WidthInBytes width, + void* sourcePtr); void* sourceIdRaw = nullptr; void* seqNumRaw = nullptr; void* destIdRaw = nullptr; diff --git a/src/fsfw/util/CMakeLists.txt b/src/fsfw/util/CMakeLists.txt new file mode 100644 index 00000000..a0d48465 --- /dev/null +++ b/src/fsfw/util/CMakeLists.txt @@ -0,0 +1 @@ +target_sources(${LIB_FSFW_NAME} PRIVATE) diff --git a/src/fsfw/util/ProvidesSeqCountIF.h b/src/fsfw/util/ProvidesSeqCountIF.h new file mode 100644 index 00000000..d88f9024 --- /dev/null +++ b/src/fsfw/util/ProvidesSeqCountIF.h @@ -0,0 +1,19 @@ +#pragma once + +#include + +class ProvidesSeqCountIF { + public: + virtual ~ProvidesSeqCountIF() = default; + + [[nodiscard]] virtual unsigned int bitWidth() const = 0; + + virtual uint64_t get() = 0; + virtual void increment() = 0; + + virtual uint64_t getAndIncrement() { + uint64_t val = get(); + increment(); + return val; + } +}; diff --git a/src/fsfw/util/SeqCountProvider.h b/src/fsfw/util/SeqCountProvider.h new file mode 100644 index 00000000..f5c3a5ca --- /dev/null +++ b/src/fsfw/util/SeqCountProvider.h @@ -0,0 +1,24 @@ +#pragma once + +#include + +#include "ProvidesSeqCountIF.h" + +template +class SeqCountProvider : public ProvidesSeqCountIF { + static_assert(std::is_same::value || std::is_same::value || + std::is_same::value, + "Only uint8_t, uint16_t, and uint32_t are allowed."); + + public: + [[nodiscard]] unsigned int bitWidth() const override { return sizeof(T) * 8; } + uint64_t get() override { return counter; } + void increment() override { counter++; } + + private: + T counter{}; +}; + +using SeqCountProviderU8 = SeqCountProvider; +using SeqCountProviderU16 = SeqCountProvider; +using SeqCountProviderU32 = SeqCountProvider; diff --git a/unittests/cfdp/handler/testSourceHandler.cpp b/unittests/cfdp/handler/testSourceHandler.cpp index f12e2442..29b12f99 100644 --- a/unittests/cfdp/handler/testSourceHandler.cpp +++ b/unittests/cfdp/handler/testSourceHandler.cpp @@ -5,6 +5,7 @@ #include "fsfw/cfdp/pdu/EofPduCreator.h" #include "fsfw/cfdp/pdu/FileDataCreator.h" #include "fsfw/cfdp/pdu/MetadataPduCreator.h" +#include "fsfw/util/SeqCountProvider.h" #include "mocks/AcceptsTmMock.h" #include "mocks/EventReportingProxyMock.h" #include "mocks/FilesystemMock.h" @@ -26,7 +27,8 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { LocalEntityCfg localEntityCfg(localId, IndicationCfg(), fhMock); FilesystemMock fsMock; UserMock userMock(fsMock); - SourceHandlerParams dp(localEntityCfg, userMock); + SeqCountProviderU16 seqCountProvider; + SourceHandlerParams dp(localEntityCfg, userMock, seqCountProvider); EventReportingProxyMock eventReporterMock; LocalPool::LocalPoolConfig storeCfg = {{10, 32}, {10, 64}, {10, 128}, {10, 1024}}; diff --git a/unittests/cfdp/pdu/testCfdpHeader.cpp b/unittests/cfdp/pdu/testCfdpHeader.cpp index 1fc7dfd4..447e3722 100644 --- a/unittests/cfdp/pdu/testCfdpHeader.cpp +++ b/unittests/cfdp/pdu/testCfdpHeader.cpp @@ -110,9 +110,9 @@ TEST_CASE("CFDP Header", "[cfdp]") { } SECTION("Other variable sized fields") { - pduConf.seqNum.setValue(cfdp::WidthInBytes::TWO_BYTES, 0x0fff); - pduConf.sourceId.setValue(cfdp::WidthInBytes::FOUR_BYTES, 0xff00ff00); - pduConf.destId.setValue(cfdp::WidthInBytes::FOUR_BYTES, 0x00ff00ff); + pduConf.seqNum.setValueAndWidth(cfdp::WidthInBytes::TWO_BYTES, 0x0fff); + pduConf.sourceId.setValueAndWidth(cfdp::WidthInBytes::FOUR_BYTES, 0xff00ff00); + pduConf.destId.setValueAndWidth(cfdp::WidthInBytes::FOUR_BYTES, 0x00ff00ff); REQUIRE(pduConf.sourceId.getSerializedSize() == 4); REQUIRE(creator.getSerializedSize() == 14); REQUIRE(creator.serialize(&serTarget, &serSize, serBuf.size(), @@ -146,9 +146,9 @@ TEST_CASE("CFDP Header", "[cfdp]") { } SECTION("Buffer Too Short") { - pduConf.seqNum.setValue(cfdp::WidthInBytes::TWO_BYTES, 0x0fff); - pduConf.sourceId.setValue(cfdp::WidthInBytes::FOUR_BYTES, 0xff00ff00); - pduConf.destId.setValue(cfdp::WidthInBytes::FOUR_BYTES, 0x00ff00ff); + pduConf.seqNum.setValueAndWidth(cfdp::WidthInBytes::TWO_BYTES, 0x0fff); + pduConf.sourceId.setValueAndWidth(cfdp::WidthInBytes::FOUR_BYTES, 0xff00ff00); + pduConf.destId.setValueAndWidth(cfdp::WidthInBytes::FOUR_BYTES, 0x00ff00ff); for (uint8_t idx = 0; idx < 14; idx++) { REQUIRE(creator.serialize(&serTarget, &serSize, idx, SerializeIF::Endianness::BIG) == SerializeIF::BUFFER_TOO_SHORT); @@ -157,11 +157,11 @@ TEST_CASE("CFDP Header", "[cfdp]") { } SECTION("Invalid Variable Sized Fields") { - result = pduConf.sourceId.setValue(cfdp::WidthInBytes::ONE_BYTE, 0xfff); + result = pduConf.sourceId.setValueAndWidth(cfdp::WidthInBytes::ONE_BYTE, 0xfff); REQUIRE(result == returnvalue::FAILED); - result = pduConf.sourceId.setValue(cfdp::WidthInBytes::TWO_BYTES, 0xfffff); + result = pduConf.sourceId.setValueAndWidth(cfdp::WidthInBytes::TWO_BYTES, 0xfffff); REQUIRE(result == returnvalue::FAILED); - result = pduConf.sourceId.setValue(cfdp::WidthInBytes::FOUR_BYTES, 0xfffffffff); + result = pduConf.sourceId.setValueAndWidth(cfdp::WidthInBytes::FOUR_BYTES, 0xfffffffff); REQUIRE(result == returnvalue::FAILED); } @@ -207,7 +207,7 @@ TEST_CASE("CFDP Header", "[cfdp]") { SerializeIF::Endianness::MACHINE); REQUIRE(pduConf.sourceId.getValue() == 0xf0f0f0f0); - pduConf.sourceId.setValue(cfdp::WidthInBytes::ONE_BYTE, 1); + pduConf.sourceId.setValueAndWidth(cfdp::WidthInBytes::ONE_BYTE, 1); serTarget = serBuf.data(); serSize = 1; result = pduConf.sourceId.serialize(&serTarget, &serSize, 1, SerializeIF::Endianness::MACHINE); @@ -257,11 +257,11 @@ TEST_CASE("CFDP Header", "[cfdp]") { creator.setSegmentationControl(cfdp::SegmentationControl::RECORD_BOUNDARIES_PRESERVATION); creator.setPduType(cfdp::PduType::FILE_DATA); creator.setSegmentMetadataFlag(cfdp::SegmentMetadataFlag::PRESENT); - result = pduConf.seqNum.setValue(cfdp::WidthInBytes::TWO_BYTES, 0x0fff); + result = pduConf.seqNum.setValueAndWidth(cfdp::WidthInBytes::TWO_BYTES, 0x0fff); REQUIRE(result == returnvalue::OK); - result = pduConf.sourceId.setValue(cfdp::WidthInBytes::FOUR_BYTES, 0xff00ff00); + result = pduConf.sourceId.setValueAndWidth(cfdp::WidthInBytes::FOUR_BYTES, 0xff00ff00); REQUIRE(result == returnvalue::OK); - result = pduConf.destId.setValue(cfdp::WidthInBytes::FOUR_BYTES, 0x00ff00ff); + result = pduConf.destId.setValueAndWidth(cfdp::WidthInBytes::FOUR_BYTES, 0x00ff00ff); REQUIRE(result == returnvalue::OK); serTarget = serBuf.data(); serSize = 0; @@ -302,8 +302,8 @@ TEST_CASE("CFDP Header", "[cfdp]") { SECTION("Manipulate Source Dest ID") { serTarget = serBuf.data(); serSize = 0; - pduConf.sourceId.setValue(cfdp::WidthInBytes::ONE_BYTE, 22); - pduConf.destId.setValue(cfdp::WidthInBytes::ONE_BYTE, 48); + pduConf.sourceId.setValueAndWidth(cfdp::WidthInBytes::ONE_BYTE, 22); + pduConf.destId.setValueAndWidth(cfdp::WidthInBytes::ONE_BYTE, 48); result = creator.serialize(&serTarget, &serSize, serBuf.size(), SerializeIF::Endianness::BIG); reader.getSourceId(sourceDestId); REQUIRE(sourceDestId.getWidth() == cfdp::WidthInBytes::ONE_BYTE); diff --git a/unittests/cfdp/testTlv.cpp b/unittests/cfdp/testTlv.cpp index 979bfac5..020365f8 100644 --- a/unittests/cfdp/testTlv.cpp +++ b/unittests/cfdp/testTlv.cpp @@ -40,7 +40,7 @@ TEST_CASE("CFDP TLV", "[cfdp][tlv]") { SECTION("TLV Other Value") { auto tlv = Tlv(TlvType::ENTITY_ID, rawBuf.data(), deserSize); // Set new value - sourceId.setValue(cfdp::WidthInBytes::FOUR_BYTES, 12); + sourceId.setValueAndWidth(cfdp::WidthInBytes::FOUR_BYTES, 12); REQUIRE(sourceId.serialize(&serPtr, &deserSize, rawBuf.size(), SerializeIF::Endianness::NETWORK) == returnvalue::OK); tlv.setValue(rawBuf.data(), cfdp::WidthInBytes::FOUR_BYTES); diff --git a/unittests/util/CMakeLists.txt b/unittests/util/CMakeLists.txt index fb660d54..47c10569 100644 --- a/unittests/util/CMakeLists.txt +++ b/unittests/util/CMakeLists.txt @@ -1 +1,2 @@ -target_sources(${FSFW_TEST_TGT} PRIVATE testUnsignedByteField.cpp) +target_sources(${FSFW_TEST_TGT} PRIVATE testUnsignedByteField.cpp + testSeqCountProvider.cpp) diff --git a/unittests/util/testSeqCountProvider.cpp b/unittests/util/testSeqCountProvider.cpp new file mode 100644 index 00000000..fce8bf43 --- /dev/null +++ b/unittests/util/testSeqCountProvider.cpp @@ -0,0 +1,35 @@ +#include + +#include "fsfw/util/SeqCountProvider.h" + +TEST_CASE("Seq Count Providers", "[util]") { + auto genericProviderTest = [](ProvidesSeqCountIF& provider, unsigned expectedWidth) { + CHECK(provider.get() == 0); + CHECK(provider.bitWidth() == expectedWidth); + CHECK(provider.getAndIncrement() == 0); + CHECK(provider.getAndIncrement() == 1); + CHECK(provider.get() == 2); + provider.increment(); + provider.increment(); + CHECK(provider.get() == 4); + }; + { + SeqCountProviderU16 provider; + genericProviderTest(provider, 16); + } + + { + SeqCountProviderU32 provider; + genericProviderTest(provider, 32); + } + + { + SeqCountProviderU8 provider; + genericProviderTest(provider, 8); + for (unsigned i = 4; i < UINT8_MAX + 1; i++) { + provider.increment(); + } + // Verify wrap-around. + CHECK(provider.get() == 0); + } +} From 42c215ef70bc75a9247b727f5aa5811490c5fa55 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 19 Jul 2023 23:24:43 +0200 Subject: [PATCH 026/101] some additional notes --- src/fsfw/util/SeqCountProvider.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/fsfw/util/SeqCountProvider.h b/src/fsfw/util/SeqCountProvider.h index f5c3a5ca..fe16431f 100644 --- a/src/fsfw/util/SeqCountProvider.h +++ b/src/fsfw/util/SeqCountProvider.h @@ -13,6 +13,7 @@ class SeqCountProvider : public ProvidesSeqCountIF { public: [[nodiscard]] unsigned int bitWidth() const override { return sizeof(T) * 8; } uint64_t get() override { return counter; } + // I'm also abusing the primitive C variable overflow wrap around here. void increment() override { counter++; } private: From 9c8434d856e47b5fd63fe76aef08c8d8bd10e1ef Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 19 Jul 2023 23:43:40 +0200 Subject: [PATCH 027/101] LOOKING GOOOD --- src/fsfw/cfdp/handler/SourceHandler.cpp | 45 ++++++++++++++++++++----- src/fsfw/cfdp/handler/SourceHandler.h | 14 ++++++-- 2 files changed, 48 insertions(+), 11 deletions(-) diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index 0c4c6ed8..501eb9fd 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -29,6 +29,8 @@ cfdp::SourceHandler::SourceHandler(SourceHandlerParams params, FsfwParams fsfwPa sif::error << "cfdp::SourceHandler: Seq count provider bit width " << sourceParams.seqCountProvider.bitWidth() << " not allowed" << std::endl; #else + sif::printError("cfdp::SourceHandler: Seq count provider bit width %d not allowed\n", + sourceParams.seqCountProvider.bitWidth()); #endif // Yeah, what am I supposed to do here? Can't throw an exception in the FSFW.. transactionParams.seqCountWidth = cfdp::WidthInBytes::ONE_BYTE; @@ -70,7 +72,14 @@ cfdp::SourceHandler::FsmResult& cfdp::SourceHandler::fsmNacked() { if (result != OK) { // TODO: Error handling } - return fsmResult; + if (sourceParams.cfg.indicCfg.eofSentIndicRequired) { + sourceParams.user.eofSentIndication(transactionParams.id); + } + if (transactionParams.closureRequested) { + step = TransactionStep::WAIT_FOR_FINISH; + return fsmResult; + } + step = TransactionStep::NOTICE_OF_COMPLETION; } if (step == TransactionStep::WAIT_FOR_FINISH) { // TODO: In case this is a request with closure, wait for finish. @@ -78,11 +87,8 @@ cfdp::SourceHandler::FsmResult& cfdp::SourceHandler::fsmNacked() { step = TransactionStep::NOTICE_OF_COMPLETION; } if (step == TransactionStep::NOTICE_OF_COMPLETION) { - // TODO: Notice of completion - // We are done, go back to idle state. - // TODO: Possible reset state? - step = TransactionStep::IDLE; - state = CfdpState::IDLE; + noticeOfCompletion(); + reset(); } return fsmResult; } @@ -98,6 +104,11 @@ cfdp::SourceHandler::FsmResult& cfdp::SourceHandler::stateMachine() { } ReturnValue_t cfdp::SourceHandler::checksumGeneration() { + if (transactionParams.fileSize.value() == 0) { + // NULL checksum for empty file. + transactionParams.crc = 0; + return OK; + } std::array buf{}; etl::crc32 crcCalc; uint64_t currentOffset = 0; @@ -227,14 +238,13 @@ ReturnValue_t cfdp::SourceHandler::prepareAndSendNextFileDataPdu() { } ReturnValue_t cfdp::SourceHandler::prepareAndSendEofPdu() { - // TODO: Checksum - auto eofInfo = EofInfo(ConditionCode::NO_ERROR, 0, transactionParams.fileSize); + auto eofInfo = + EofInfo(ConditionCode::NO_ERROR, transactionParams.crc, transactionParams.fileSize); auto eofPdu = EofPduCreator(transactionParams.pduConf, eofInfo); ReturnValue_t result = sendGenericPdu(eofPdu); if (result != OK) { return result; } - step = TransactionStep::WAIT_FOR_FINISH; return OK; } @@ -276,3 +286,20 @@ ReturnValue_t cfdp::SourceHandler::sendGenericPdu(const SerializeIF& pdu) const TmTcMessage tcMsg(storeId); return fsfwParams.msgQueue->sendMessage(fsfwParams.packetDest.getReportReceptionQueue(), &tcMsg); } + +ReturnValue_t cfdp::SourceHandler::noticeOfCompletion() { + if (sourceParams.cfg.indicCfg.transactionFinishedIndicRequired) { + cfdp::TransactionFinishedParams params(transactionParams.id, ConditionCode::NO_ERROR, + FileDeliveryCode::DATA_COMPLETE, + FileDeliveryStatus::RETAINED_IN_FILESTORE); + sourceParams.user.transactionFinishedIndication(params); + } + return OK; +} + +ReturnValue_t cfdp::SourceHandler::reset() { + step = TransactionStep::IDLE; + state = cfdp::CfdpState::IDLE; + transactionParams.reset(); + return OK; +} diff --git a/src/fsfw/cfdp/handler/SourceHandler.h b/src/fsfw/cfdp/handler/SourceHandler.h index b517d709..31fafcb2 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.h +++ b/src/fsfw/cfdp/handler/SourceHandler.h @@ -73,8 +73,16 @@ class SourceHandler { PduConfig pduConf; cfdp::TransactionId id{}; cfdp::WidthInBytes seqCountWidth; - uint32_t seqNum = 0; + + void reset() { + sourceNameSize = 0; + destNameSize = 0; + fileSize.setFileSize(0, false); + progress = 0; + closureRequested = false; + } } transactionParams; + cfdp::CfdpState state = cfdp::CfdpState::IDLE; TransactionStep step = TransactionStep::IDLE; std::array fileBuf{}; @@ -87,8 +95,10 @@ class SourceHandler { ReturnValue_t prepareAndSendMetadataPdu(); ReturnValue_t prepareAndSendNextFileDataPdu(); ReturnValue_t prepareAndSendEofPdu(); + ReturnValue_t noticeOfCompletion(); + ReturnValue_t reset(); - ReturnValue_t sendGenericPdu(const SerializeIF& pdu) const; + [[nodiscard]] ReturnValue_t sendGenericPdu(const SerializeIF& pdu) const; }; } // namespace cfdp From e00e198ff150f089d9f00c2be8f963507ddd685f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 21 Jul 2023 16:09:52 +0200 Subject: [PATCH 028/101] this seems to work --- src/fsfw/cfdp/handler/CMakeLists.txt | 6 +- src/fsfw/cfdp/handler/DestHandler.cpp | 9 ++- src/fsfw/cfdp/handler/MetadataParser.cpp | 1 + src/fsfw/cfdp/handler/MetadataParser.h | 12 ++++ src/fsfw/cfdp/handler/PutRequestReader.cpp | 1 + src/fsfw/cfdp/handler/PutRequestReader.h | 29 +++++++++ src/fsfw/cfdp/handler/SourceHandler.cpp | 2 +- src/fsfw/cfdp/handler/defs.h | 1 + src/fsfw/cfdp/pdu/MetadataInfo.cpp | 53 ---------------- src/fsfw/cfdp/pdu/MetadataInfo.h | 14 ----- src/fsfw/cfdp/pdu/MetadataPduCreator.cpp | 25 +++++--- src/fsfw/cfdp/pdu/MetadataPduCreator.h | 5 +- src/fsfw/cfdp/pdu/MetadataPduReader.cpp | 23 +++---- src/fsfw/cfdp/pdu/MetadataPduReader.h | 7 ++- unittests/cfdp/handler/testDestHandler.cpp | 2 +- unittests/cfdp/handler/testDistributor.cpp | 2 +- unittests/cfdp/pdu/testMetadataPdu.cpp | 70 ++++++++++++---------- 17 files changed, 134 insertions(+), 128 deletions(-) create mode 100644 src/fsfw/cfdp/handler/MetadataParser.cpp create mode 100644 src/fsfw/cfdp/handler/MetadataParser.h create mode 100644 src/fsfw/cfdp/handler/PutRequestReader.cpp create mode 100644 src/fsfw/cfdp/handler/PutRequestReader.h diff --git a/src/fsfw/cfdp/handler/CMakeLists.txt b/src/fsfw/cfdp/handler/CMakeLists.txt index 7ad995c0..540bceca 100644 --- a/src/fsfw/cfdp/handler/CMakeLists.txt +++ b/src/fsfw/cfdp/handler/CMakeLists.txt @@ -1,2 +1,4 @@ -target_sources(${LIB_FSFW_NAME} PRIVATE SourceHandler.cpp DestHandler.cpp - FaultHandlerBase.cpp UserBase.cpp) +target_sources( + ${LIB_FSFW_NAME} + PRIVATE SourceHandler.cpp DestHandler.cpp MetadataParser.cpp + PutRequestReader.cpp FaultHandlerBase.cpp UserBase.cpp) diff --git a/src/fsfw/cfdp/handler/DestHandler.cpp b/src/fsfw/cfdp/handler/DestHandler.cpp index f44f5d41..03a360b7 100644 --- a/src/fsfw/cfdp/handler/DestHandler.cpp +++ b/src/fsfw/cfdp/handler/DestHandler.cpp @@ -136,10 +136,8 @@ ReturnValue_t cfdp::DestHandler::handleMetadataPdu(const PacketInfo& info) { cfdp::StringLv sourceFileName; cfdp::StringLv destFileName; MetadataInfo metadataInfo(transactionParams.fileSize, sourceFileName, destFileName); - cfdp::Tlv* tlvArrayAsPtr = tlvVec.data(); - metadataInfo.setOptionsArray(&tlvArrayAsPtr, std::nullopt, tlvVec.size()); MetadataPduReader reader(constAccessorPair.second.data(), constAccessorPair.second.size(), - metadataInfo); + metadataInfo, nullptr, 0); ReturnValue_t result = reader.parseData(); // TODO: The standard does not really specify what happens if this kind of error happens // I think it might be a good idea to cache some sort of error code, which @@ -357,8 +355,9 @@ ReturnValue_t cfdp::DestHandler::startTransaction(MetadataPduReader& reader, Met params.fileSize = transactionParams.fileSize.getSize(); params.destFileName = transactionParams.destName.data(); params.sourceFileName = transactionParams.sourceName.data(); - params.msgsToUserArray = dynamic_cast(userTlvVec.data()); - params.msgsToUserLen = info.getOptionsLen(); + // TODO: Is this really correct? Implement this correctly.. + // params.msgsToUserArray = dynamic_cast(userTlvVec.data()); + // params.msgsToUserLen = reader.getNumberOfParsedOptions(); destParams.user.metadataRecvdIndication(params); return result; } diff --git a/src/fsfw/cfdp/handler/MetadataParser.cpp b/src/fsfw/cfdp/handler/MetadataParser.cpp new file mode 100644 index 00000000..63510efc --- /dev/null +++ b/src/fsfw/cfdp/handler/MetadataParser.cpp @@ -0,0 +1 @@ +#include "MetadataParser.h" diff --git a/src/fsfw/cfdp/handler/MetadataParser.h b/src/fsfw/cfdp/handler/MetadataParser.h new file mode 100644 index 00000000..914c34c7 --- /dev/null +++ b/src/fsfw/cfdp/handler/MetadataParser.h @@ -0,0 +1,12 @@ +#pragma once + +namespace cfdp { + +class MetadataParser { + public: + MetadataParser(); + + private: +}; + +} // namespace cfdp \ No newline at end of file diff --git a/src/fsfw/cfdp/handler/PutRequestReader.cpp b/src/fsfw/cfdp/handler/PutRequestReader.cpp new file mode 100644 index 00000000..0b262fc9 --- /dev/null +++ b/src/fsfw/cfdp/handler/PutRequestReader.cpp @@ -0,0 +1 @@ +#include "PutRequestReader.h" diff --git a/src/fsfw/cfdp/handler/PutRequestReader.h b/src/fsfw/cfdp/handler/PutRequestReader.h new file mode 100644 index 00000000..bcef8222 --- /dev/null +++ b/src/fsfw/cfdp/handler/PutRequestReader.h @@ -0,0 +1,29 @@ +#pragma once + +#include +#include + +#include "fsfw/cfdp/VarLenFields.h" +#include "fsfw/cfdp/tlv/FilestoreRequestTlv.h" +#include "fsfw/cfdp/tlv/MessageToUserTlv.h" + +namespace cfdp { + +class PutRequest { + public: + EntityId destId; + std::optional transmissionMode; + char destName[524]{}; + std::optional destNameSize; + char sourceName[524]{}; + std::optional sourceNameSize; + std::optional closureRequested; + std::vector messagesToUser; + std::vector fsRequest; + + [[nodiscard]] bool isMetadataOnly() const { + return !destNameSize.has_value() and !sourceNameSize.has_value(); + } +}; + +} // namespace cfdp diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index 74333a69..64fa6583 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -157,7 +157,7 @@ ReturnValue_t cfdp::SourceHandler::prepareAndSendMetadataPdu() { cfdp::StringLv sourceName(transactionParams.sourceName.data(), transactionParams.sourceNameSize); cfdp::StringLv destName(transactionParams.destName.data(), transactionParams.destNameSize); auto metadataInfo = MetadataInfo(transactionParams.fileSize, sourceName, destName); - auto metadataPdu = MetadataPduCreator(transactionParams.pduConf, metadataInfo); + auto metadataPdu = MetadataPduCreator(transactionParams.pduConf, metadataInfo, nullptr, 0); ReturnValue_t result = sendGenericPdu(metadataPdu); if (result != OK) { return result; diff --git a/src/fsfw/cfdp/handler/defs.h b/src/fsfw/cfdp/handler/defs.h index 81a8895c..97ef009c 100644 --- a/src/fsfw/cfdp/handler/defs.h +++ b/src/fsfw/cfdp/handler/defs.h @@ -57,6 +57,7 @@ struct PutRequestFull { char sourceName[524]{}; size_t sourceNameSize = 0; bool closureRequested = true; + // MessageToUserTlv }; enum class CallStatus { DONE, CALL_AFTER_DELAY, CALL_AGAIN }; diff --git a/src/fsfw/cfdp/pdu/MetadataInfo.cpp b/src/fsfw/cfdp/pdu/MetadataInfo.cpp index 180549e5..3ec38f41 100644 --- a/src/fsfw/cfdp/pdu/MetadataInfo.cpp +++ b/src/fsfw/cfdp/pdu/MetadataInfo.cpp @@ -12,17 +12,6 @@ MetadataInfo::MetadataInfo(cfdp::Fss& fileSize, cfdp::StringLv& sourceFileName, cfdp::StringLv& destFileName) : fileSize(fileSize), sourceFileName(sourceFileName), destFileName(destFileName) {} -void MetadataInfo::setOptionsArray(cfdp::Tlv** optionsArray_, std::optional optionsLen_, - std::optional maxOptionsLen_) { - this->optionsArray = optionsArray_; - if (maxOptionsLen_) { - this->maxOptionsLen = maxOptionsLen_.value(); - } - if (optionsLen_) { - this->optionsLen = optionsLen_.value(); - } -} - cfdp::ChecksumType MetadataInfo::getChecksumType() const { return checksumType; } void MetadataInfo::setChecksumType(cfdp::ChecksumType checksumType_) { @@ -39,35 +28,6 @@ cfdp::StringLv& MetadataInfo::getDestFileName() { return destFileName; } cfdp::Fss& MetadataInfo::getFileSize() { return fileSize; } -ReturnValue_t MetadataInfo::getOptions(cfdp::Tlv*** optionsArray_, size_t* optionsLen_, - size_t* maxOptsLen) { - if (optionsArray_ == nullptr or optionsArray == nullptr) { - return returnvalue::FAILED; - } - *optionsArray_ = optionsArray; - if (optionsLen_ != nullptr) { - *optionsLen_ = this->optionsLen; - } - if (maxOptsLen != nullptr) { - *maxOptsLen = this->maxOptionsLen; - } - return returnvalue::OK; -} - -bool MetadataInfo::hasOptions() const { - if (optionsArray != nullptr and optionsLen > 0) { - return true; - } - return false; -} - -bool MetadataInfo::canHoldOptions() const { - if (optionsArray != nullptr and maxOptionsLen > 0) { - return true; - } - return false; -} - size_t MetadataInfo::getSerializedSize(bool fssLarge) { // 1 byte + minimal FSS 4 bytes size_t size = 5; @@ -76,11 +36,6 @@ size_t MetadataInfo::getSerializedSize(bool fssLarge) { } size += sourceFileName.getSerializedSize(); size += destFileName.getSerializedSize(); - if (hasOptions()) { - for (size_t idx = 0; idx < optionsLen; idx++) { - size += optionsArray[idx]->getSerializedSize(); - } - } return size; } @@ -92,12 +47,4 @@ void MetadataInfo::setSourceFileName(cfdp::StringLv& sourceFileName_) { this->sourceFileName = sourceFileName_; } -size_t MetadataInfo::getMaxOptionsLen() const { return maxOptionsLen; } - -void MetadataInfo::setMaxOptionsLen(size_t maxOptionsLen_) { this->maxOptionsLen = maxOptionsLen_; } - -size_t MetadataInfo::getOptionsLen() const { return optionsLen; } - -void MetadataInfo::setOptionsLen(size_t optionsLen_) { this->optionsLen = optionsLen_; } - cfdp::StringLv& MetadataInfo::getSourceFileName() { return sourceFileName; } diff --git a/src/fsfw/cfdp/pdu/MetadataInfo.h b/src/fsfw/cfdp/pdu/MetadataInfo.h index 7ae269a9..eef1447e 100644 --- a/src/fsfw/cfdp/pdu/MetadataInfo.h +++ b/src/fsfw/cfdp/pdu/MetadataInfo.h @@ -17,8 +17,6 @@ class MetadataInfo { size_t getSerializedSize(bool fssLarge = false); - void setOptionsArray(cfdp::Tlv** optionsArray, std::optional optionsLen, - std::optional maxOptionsLen); [[nodiscard]] cfdp::ChecksumType getChecksumType() const; void setChecksumType(cfdp::ChecksumType checksumType); [[nodiscard]] bool isClosureRequested() const; @@ -31,24 +29,12 @@ class MetadataInfo { cfdp::StringLv& getSourceFileName(); cfdp::Fss& getFileSize(); - [[nodiscard]] bool hasOptions() const; - [[nodiscard]] bool canHoldOptions() const; - ReturnValue_t getOptions(cfdp::Tlv*** optionsArray, size_t* optionsLen, size_t* maxOptsLen); - void setOptionsLen(size_t optionsLen); - [[nodiscard]] size_t getOptionsLen() const; - void setMaxOptionsLen(size_t maxOptionsLen); - [[nodiscard]] size_t getMaxOptionsLen() const; - private: bool closureRequested = false; cfdp::ChecksumType checksumType = cfdp::ChecksumType::NULL_CHECKSUM; cfdp::Fss& fileSize; cfdp::StringLv& sourceFileName; cfdp::StringLv& destFileName; - - cfdp::Tlv** optionsArray = nullptr; - size_t optionsLen = 0; - size_t maxOptionsLen = 0; }; #endif /* FSFW_SRC_FSFW_CFDP_PDU_METADATAINFO_H_ */ diff --git a/src/fsfw/cfdp/pdu/MetadataPduCreator.cpp b/src/fsfw/cfdp/pdu/MetadataPduCreator.cpp index 536a48f4..e31e7903 100644 --- a/src/fsfw/cfdp/pdu/MetadataPduCreator.cpp +++ b/src/fsfw/cfdp/pdu/MetadataPduCreator.cpp @@ -1,12 +1,22 @@ #include "MetadataPduCreator.h" -MetadataPduCreator::MetadataPduCreator(PduConfig &conf, MetadataInfo &info) - : FileDirectiveCreator(conf, cfdp::FileDirective::METADATA, 5), info(info) { +MetadataPduCreator::MetadataPduCreator(PduConfig &conf, MetadataInfo &info, + cfdp::Tlv **optionsArray, size_t optionsLen) + : FileDirectiveCreator(conf, cfdp::FileDirective::METADATA, 5), + info(info), + optionsArray(optionsArray), + optionsLen(optionsLen) { updateDirectiveFieldLen(); } void MetadataPduCreator::updateDirectiveFieldLen() { - setDirectiveDataFieldLen(info.getSerializedSize(getLargeFileFlag())); + size_t dirFieldLen = info.getSerializedSize(HeaderCreator::getLargeFileFlag()); + if (optionsLen > 0 and optionsArray != nullptr) { + for (size_t idx = 0; idx < optionsLen; idx++) { + dirFieldLen += optionsArray[idx]->getSerializedSize(); + } + } + setDirectiveDataFieldLen(dirFieldLen); } size_t MetadataPduCreator::getSerializedSize() const { @@ -38,12 +48,9 @@ ReturnValue_t MetadataPduCreator::serialize(uint8_t **buffer, size_t *size, size return result; } - if (info.hasOptions()) { - cfdp::Tlv **optsArray = nullptr; - size_t optsLen = 0; - info.getOptions(&optsArray, &optsLen, nullptr); - for (size_t idx = 0; idx < optsLen; idx++) { - result = optsArray[idx]->serialize(buffer, size, maxSize, streamEndianness); + if (optionsLen > 0 and optionsArray != nullptr) { + for (size_t idx = 0; idx < optionsLen; idx++) { + result = optionsArray[idx]->serialize(buffer, size, maxSize, streamEndianness); if (result != returnvalue::OK) { return result; } diff --git a/src/fsfw/cfdp/pdu/MetadataPduCreator.h b/src/fsfw/cfdp/pdu/MetadataPduCreator.h index 4486a79c..a6f8331c 100644 --- a/src/fsfw/cfdp/pdu/MetadataPduCreator.h +++ b/src/fsfw/cfdp/pdu/MetadataPduCreator.h @@ -6,7 +6,8 @@ class MetadataPduCreator : public FileDirectiveCreator { public: - MetadataPduCreator(PduConfig& conf, MetadataInfo& info); + MetadataPduCreator(PduConfig& conf, MetadataInfo& info, cfdp::Tlv** optionsArray, + size_t optionsLen); void updateDirectiveFieldLen(); @@ -18,6 +19,8 @@ class MetadataPduCreator : public FileDirectiveCreator { private: MetadataInfo& info; + cfdp::Tlv** optionsArray; + size_t optionsLen; }; #endif /* FSFW_CFDP_PDU_METADATAPDUCREATOR_H_ */ diff --git a/src/fsfw/cfdp/pdu/MetadataPduReader.cpp b/src/fsfw/cfdp/pdu/MetadataPduReader.cpp index 66025140..104ef2ae 100644 --- a/src/fsfw/cfdp/pdu/MetadataPduReader.cpp +++ b/src/fsfw/cfdp/pdu/MetadataPduReader.cpp @@ -1,9 +1,14 @@ #include "MetadataPduReader.h" -MetadataPduReader::MetadataPduReader(const uint8_t* pduBuf, size_t maxSize, MetadataInfo& info) - : FileDirectiveReader(pduBuf, maxSize), info(info) {} +MetadataPduReader::MetadataPduReader(const uint8_t* pduBuf, size_t maxSize, MetadataInfo& info, + cfdp::Tlv* optionsArray, size_t optArrayMaxSize) + : FileDirectiveReader(pduBuf, maxSize), + info(info), + optionArray(optionsArray), + optionArrayMaxSize(optArrayMaxSize) {} ReturnValue_t MetadataPduReader::parseData() { + parsedOptions = 0; ReturnValue_t result = FileDirectiveReader::parseData(); if (result != returnvalue::OK) { return result; @@ -32,26 +37,24 @@ ReturnValue_t MetadataPduReader::parseData() { return result; } - info.setOptionsLen(0); if (remSize > 0) { - if (not info.canHoldOptions()) { + if (optionArrayMaxSize == 0 or optionArray == nullptr) { return cfdp::METADATA_CANT_PARSE_OPTIONS; } - cfdp::Tlv** optionsArray = nullptr; - size_t optsMaxLen = 0; size_t optsIdx = 0; - info.getOptions(&optionsArray, nullptr, &optsMaxLen); while (remSize > 0) { - if (optsIdx > optsMaxLen) { + if (optsIdx > optionArrayMaxSize) { return cfdp::METADATA_CANT_PARSE_OPTIONS; } - result = optionsArray[optsIdx]->deSerialize(&buf, &remSize, endianness); + result = optionArray[optsIdx].deSerialize(&buf, &remSize, endianness); if (result != returnvalue::OK) { return result; } optsIdx++; } - info.setOptionsLen(optsIdx); + parsedOptions = optsIdx; } return result; } + +size_t MetadataPduReader::getNumberOfParsedOptions() const { return parsedOptions; } diff --git a/src/fsfw/cfdp/pdu/MetadataPduReader.h b/src/fsfw/cfdp/pdu/MetadataPduReader.h index 3e8c0f30..ff5f52a8 100644 --- a/src/fsfw/cfdp/pdu/MetadataPduReader.h +++ b/src/fsfw/cfdp/pdu/MetadataPduReader.h @@ -6,12 +6,17 @@ class MetadataPduReader : public FileDirectiveReader { public: - MetadataPduReader(const uint8_t* pduBuf, size_t maxSize, MetadataInfo& info); + MetadataPduReader(const uint8_t* pduBuf, size_t maxSize, MetadataInfo& info, + cfdp::Tlv* optionsArray, size_t optArrayMaxSize); ReturnValue_t parseData() override; + [[nodiscard]] size_t getNumberOfParsedOptions() const; private: MetadataInfo& info; + cfdp::Tlv* optionArray; + size_t optionArrayMaxSize; + size_t parsedOptions = 0; }; #endif /* FSFW_CFDP_PDU_METADATAPDUREADER_H_ */ diff --git a/unittests/cfdp/handler/testDestHandler.cpp b/unittests/cfdp/handler/testDestHandler.cpp index 792d919c..752cc4f2 100644 --- a/unittests/cfdp/handler/testDestHandler.cpp +++ b/unittests/cfdp/handler/testDestHandler.cpp @@ -61,7 +61,7 @@ TEST_CASE("CFDP Dest Handler", "[cfdp]") { conf.destId = localId; conf.mode = TransmissionMode::UNACKNOWLEDGED; conf.seqNum = seqNum; - MetadataPduCreator metadataCreator(conf, info); + MetadataPduCreator metadataCreator(conf, info, nullptr, 0); REQUIRE(tcStore.getFreeElement(&storeId, metadataCreator.getSerializedSize(), &buf) == OK); REQUIRE(metadataCreator.serialize(buf, serLen, metadataCreator.getSerializedSize()) == OK); PacketInfo packetInfo(metadataCreator.getPduType(), storeId, diff --git a/unittests/cfdp/handler/testDistributor.cpp b/unittests/cfdp/handler/testDistributor.cpp index 04c035a7..7d38e5c5 100644 --- a/unittests/cfdp/handler/testDistributor.cpp +++ b/unittests/cfdp/handler/testDistributor.cpp @@ -32,7 +32,7 @@ TEST_CASE("CFDP Distributor", "[cfdp][distributor]") { cfdp::StringLv destFileName(destFileString); MetadataInfo metadataInfo(false, cfdp::ChecksumType::CRC_32, fileSize, sourceFileName, destFileName); - MetadataPduCreator creator(pduConf, metadataInfo); + MetadataPduCreator creator(pduConf, metadataInfo, nullptr, 0); uint8_t* dataPtr = nullptr; SECTION("State") { diff --git a/unittests/cfdp/pdu/testMetadataPdu.cpp b/unittests/cfdp/pdu/testMetadataPdu.cpp index 747a2dc3..ba2fb4da 100644 --- a/unittests/cfdp/pdu/testMetadataPdu.cpp +++ b/unittests/cfdp/pdu/testMetadataPdu.cpp @@ -6,11 +6,10 @@ #include "fsfw/cfdp/pdu/MetadataPduReader.h" #include "fsfw/cfdp/tlv/FilestoreResponseTlv.h" #include "fsfw/cfdp/tlv/MessageToUserTlv.h" -#include "fsfw/globalfunctions/arrayprinter.h" TEST_CASE("Metadata PDU", "[cfdp][pdu]") { using namespace cfdp; - ReturnValue_t result = returnvalue::OK; + ReturnValue_t result; std::array mdBuffer = {}; uint8_t* buffer = mdBuffer.data(); size_t sz = 0; @@ -30,15 +29,15 @@ TEST_CASE("Metadata PDU", "[cfdp][pdu]") { std::array msg = {0x41, 0x42, 0x43}; cfdp::Tlv responseTlv; std::array responseBuf = {}; - uint8_t* responseBufPtr = responseBuf.data(); response.convertToTlv(responseTlv, buffer, responseBuf.size(), SerializeIF::Endianness::MACHINE); MessageToUserTlv msgToUser(msg.data(), msg.size()); std::array options{&responseTlv, &msgToUser}; + std::array tlvDeser{}; REQUIRE(options[0]->getSerializedSize() == 2 + 1 + 10 + 1); REQUIRE(options[1]->getSerializedSize() == 5); SECTION("Serialize") { - MetadataPduCreator serializer(pduConf, info); + MetadataPduCreator serializer(pduConf, info, nullptr, 0); result = serializer.serialize(&buffer, &sz, mdBuffer.size(), SerializeIF::Endianness::NETWORK); REQUIRE(result == returnvalue::OK); REQUIRE(serializer.getWholePduSize() == 27); @@ -65,19 +64,15 @@ TEST_CASE("Metadata PDU", "[cfdp][pdu]") { REQUIRE(mdBuffer[24] == 'x'); REQUIRE(mdBuffer[25] == 't'); REQUIRE(mdBuffer[26] == 0); + } + SECTION("Serialize with 2 options") { std::string otherFileName = "hello2.txt"; cfdp::StringLv otherFileNameLv(otherFileName.data(), otherFileName.size()); info.setSourceFileName(otherFileNameLv); - size_t sizeOfOptions = options.size(); - info.setOptionsArray(options.data(), sizeOfOptions, sizeOfOptions); - REQUIRE(info.getMaxOptionsLen() == 2); - info.setMaxOptionsLen(3); - REQUIRE(info.getMaxOptionsLen() == 3); + MetadataPduCreator serializer(pduConf, info, options.data(), options.size()); info.setChecksumType(cfdp::ChecksumType::CRC_32C); info.setClosureRequested(true); - uint8_t* buffer = mdBuffer.data(); - size_t sz = 0; serializer.updateDirectiveFieldLen(); result = serializer.serialize(&buffer, &sz, mdBuffer.size(), SerializeIF::Endianness::NETWORK); @@ -98,14 +93,14 @@ TEST_CASE("Metadata PDU", "[cfdp][pdu]") { // TLV unittests REQUIRE(sz == 10 + 37); for (size_t maxSz = 0; maxSz < sz; maxSz++) { - uint8_t* buffer = mdBuffer.data(); - size_t sz = 0; + buffer = mdBuffer.data(); + sz = 0; result = serializer.serialize(&buffer, &sz, maxSz, SerializeIF::Endianness::NETWORK); REQUIRE(result == SerializeIF::BUFFER_TOO_SHORT); } for (size_t initSz = 1; initSz < 47; initSz++) { - uint8_t* buffer = mdBuffer.data(); - size_t sz = initSz; + buffer = mdBuffer.data(); + sz = initSz; result = serializer.serialize(&buffer, &sz, 46, SerializeIF::Endianness::NETWORK); REQUIRE(result == SerializeIF::BUFFER_TOO_SHORT); } @@ -113,34 +108,33 @@ TEST_CASE("Metadata PDU", "[cfdp][pdu]") { } SECTION("Deserialize") { - MetadataPduCreator serializer(pduConf, info); + MetadataPduCreator serializer(pduConf, info, nullptr, 0); result = serializer.serialize(&buffer, &sz, mdBuffer.size(), SerializeIF::Endianness::NETWORK); REQUIRE(result == returnvalue::OK); - MetadataPduReader deserializer(mdBuffer.data(), mdBuffer.size(), info); + MetadataPduReader deserializer(mdBuffer.data(), mdBuffer.size(), info, nullptr, 0); result = deserializer.parseData(); REQUIRE(result == returnvalue::OK); size_t fullSize = deserializer.getWholePduSize(); for (size_t maxSz = 0; maxSz < fullSize; maxSz++) { - MetadataPduReader invalidSzDeser(mdBuffer.data(), maxSz, info); + MetadataPduReader invalidSzDeser(mdBuffer.data(), maxSz, info, nullptr, 0); result = invalidSzDeser.parseData(); REQUIRE(result != returnvalue::OK); } - size_t sizeOfOptions = options.size(); - size_t maxSize = 4; - info.setOptionsArray(options.data(), sizeOfOptions, maxSize); - REQUIRE(info.getOptionsLen() == 2); + } + + SECTION("Deserialize with 2 options") { + MetadataPduCreator serializer(pduConf, info, options.data(), options.size()); info.setChecksumType(cfdp::ChecksumType::CRC_32C); info.setClosureRequested(true); - uint8_t* buffer = mdBuffer.data(); - size_t sz = 0; serializer.updateDirectiveFieldLen(); info.setSourceFileName(sourceFileName); result = serializer.serialize(&buffer, &sz, mdBuffer.size(), SerializeIF::Endianness::NETWORK); REQUIRE(result == returnvalue::OK); - MetadataPduReader deserializer2(mdBuffer.data(), mdBuffer.size(), info); + MetadataPduReader deserializer2(mdBuffer.data(), mdBuffer.size(), info, tlvDeser.data(), + tlvDeser.max_size()); result = deserializer2.parseData(); REQUIRE(result == returnvalue::OK); REQUIRE(options[0]->getType() == cfdp::TlvType::FILESTORE_RESPONSE); @@ -151,12 +145,15 @@ TEST_CASE("Metadata PDU", "[cfdp][pdu]") { for (size_t invalidFieldLen = 0; invalidFieldLen < 36; invalidFieldLen++) { mdBuffer[1] = (invalidFieldLen >> 8) & 0xff; mdBuffer[2] = invalidFieldLen & 0xff; + if (invalidFieldLen == 17) { + volatile uint32_t dummy = 0; + } result = deserializer2.parseData(); if (invalidFieldLen == 17) { - REQUIRE(info.getOptionsLen() == 0); + REQUIRE(deserializer2.getNumberOfParsedOptions() == 0); } if (invalidFieldLen == 31) { - REQUIRE(info.getOptionsLen() == 1); + REQUIRE(deserializer2.getNumberOfParsedOptions() == 1); } // This is the precise length where there are no options or one option if (invalidFieldLen != 17 and invalidFieldLen != 31) { @@ -165,11 +162,24 @@ TEST_CASE("Metadata PDU", "[cfdp][pdu]") { } mdBuffer[1] = (36 >> 8) & 0xff; mdBuffer[2] = 36 & 0xff; - info.setOptionsArray(nullptr, std::nullopt, std::nullopt); + } + + SECTION("Can not parse options") { + MetadataPduCreator serializer(pduConf, info, options.data(), options.size()); + info.setChecksumType(cfdp::ChecksumType::CRC_32C); + info.setClosureRequested(true); + buffer = mdBuffer.data(); + sz = 0; + serializer.updateDirectiveFieldLen(); + + info.setSourceFileName(sourceFileName); + result = serializer.serialize(&buffer, &sz, mdBuffer.size(), SerializeIF::Endianness::NETWORK); + REQUIRE(result == returnvalue::OK); + + MetadataPduReader deserializer2(mdBuffer.data(), mdBuffer.size(), info, nullptr, 0); REQUIRE(deserializer2.parseData() == cfdp::METADATA_CANT_PARSE_OPTIONS); - info.setOptionsArray(options.data(), sizeOfOptions, std::nullopt); for (size_t maxSz = 0; maxSz < 46; maxSz++) { - MetadataPduReader invalidSzDeser(mdBuffer.data(), maxSz, info); + MetadataPduReader invalidSzDeser(mdBuffer.data(), maxSz, info, nullptr, 0); if (not invalidSzDeser.isNull()) { result = invalidSzDeser.parseData(); REQUIRE(result == SerializeIF::STREAM_TOO_SHORT); From 045054fce03de42b057dd41e47339abc4a742620 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 21 Jul 2023 16:12:17 +0200 Subject: [PATCH 029/101] start implementing metadata parser --- src/fsfw/cfdp/handler/MetadataParser.cpp | 2 ++ src/fsfw/cfdp/handler/MetadataParser.h | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/fsfw/cfdp/handler/MetadataParser.cpp b/src/fsfw/cfdp/handler/MetadataParser.cpp index 63510efc..2c90815f 100644 --- a/src/fsfw/cfdp/handler/MetadataParser.cpp +++ b/src/fsfw/cfdp/handler/MetadataParser.cpp @@ -1 +1,3 @@ #include "MetadataParser.h" + +cfdp::MetadataParser::MetadataParser(MetadataPduReader& reader) {} diff --git a/src/fsfw/cfdp/handler/MetadataParser.h b/src/fsfw/cfdp/handler/MetadataParser.h index 914c34c7..4c7df335 100644 --- a/src/fsfw/cfdp/handler/MetadataParser.h +++ b/src/fsfw/cfdp/handler/MetadataParser.h @@ -1,10 +1,12 @@ #pragma once +#include "fsfw/cfdp/pdu/MetadataPduReader.h" + namespace cfdp { class MetadataParser { public: - MetadataParser(); + explicit MetadataParser(MetadataPduReader& reader); private: }; From 69fd6d0f6a9278114914c72693bd944de9ca22ff Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 21 Jul 2023 16:35:05 +0200 Subject: [PATCH 030/101] lets see how we can do this --- src/fsfw/cfdp/handler/CMakeLists.txt | 2 +- src/fsfw/cfdp/handler/MetadataParser.h | 1 + src/fsfw/cfdp/handler/PutRequest.cpp | 5 +++++ src/fsfw/cfdp/handler/{PutRequestReader.h => PutRequest.h} | 4 +--- src/fsfw/cfdp/handler/PutRequestReader.cpp | 1 - 5 files changed, 8 insertions(+), 5 deletions(-) create mode 100644 src/fsfw/cfdp/handler/PutRequest.cpp rename src/fsfw/cfdp/handler/{PutRequestReader.h => PutRequest.h} (83%) delete mode 100644 src/fsfw/cfdp/handler/PutRequestReader.cpp diff --git a/src/fsfw/cfdp/handler/CMakeLists.txt b/src/fsfw/cfdp/handler/CMakeLists.txt index 540bceca..ea3d7633 100644 --- a/src/fsfw/cfdp/handler/CMakeLists.txt +++ b/src/fsfw/cfdp/handler/CMakeLists.txt @@ -1,4 +1,4 @@ target_sources( ${LIB_FSFW_NAME} PRIVATE SourceHandler.cpp DestHandler.cpp MetadataParser.cpp - PutRequestReader.cpp FaultHandlerBase.cpp UserBase.cpp) +PutRequest.cpp FaultHandlerBase.cpp UserBase.cpp) diff --git a/src/fsfw/cfdp/handler/MetadataParser.h b/src/fsfw/cfdp/handler/MetadataParser.h index 4c7df335..3ab7478a 100644 --- a/src/fsfw/cfdp/handler/MetadataParser.h +++ b/src/fsfw/cfdp/handler/MetadataParser.h @@ -9,6 +9,7 @@ class MetadataParser { explicit MetadataParser(MetadataPduReader& reader); private: + }; } // namespace cfdp \ No newline at end of file diff --git a/src/fsfw/cfdp/handler/PutRequest.cpp b/src/fsfw/cfdp/handler/PutRequest.cpp new file mode 100644 index 00000000..73f4c876 --- /dev/null +++ b/src/fsfw/cfdp/handler/PutRequest.cpp @@ -0,0 +1,5 @@ +#include "PutRequest.h" + +[[nodiscard]] bool cfdp::PutRequest::isMetadataOnly() const { + return !destNameSize.has_value() and !sourceNameSize.has_value(); +} diff --git a/src/fsfw/cfdp/handler/PutRequestReader.h b/src/fsfw/cfdp/handler/PutRequest.h similarity index 83% rename from src/fsfw/cfdp/handler/PutRequestReader.h rename to src/fsfw/cfdp/handler/PutRequest.h index bcef8222..834985bc 100644 --- a/src/fsfw/cfdp/handler/PutRequestReader.h +++ b/src/fsfw/cfdp/handler/PutRequest.h @@ -21,9 +21,7 @@ class PutRequest { std::vector messagesToUser; std::vector fsRequest; - [[nodiscard]] bool isMetadataOnly() const { - return !destNameSize.has_value() and !sourceNameSize.has_value(); - } + [[nodiscard]] bool isMetadataOnly() const; }; } // namespace cfdp diff --git a/src/fsfw/cfdp/handler/PutRequestReader.cpp b/src/fsfw/cfdp/handler/PutRequestReader.cpp deleted file mode 100644 index 0b262fc9..00000000 --- a/src/fsfw/cfdp/handler/PutRequestReader.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "PutRequestReader.h" From 5d3f00da7f7c88a872f23e5015535e9615e6f4aa Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 24 Jul 2023 10:06:45 +0200 Subject: [PATCH 031/101] that should do the job --- src/fsfw/cfdp/handler/CMakeLists.txt | 5 ++--- src/fsfw/cfdp/handler/DestHandler.cpp | 16 +++++++++++----- src/fsfw/cfdp/handler/DestHandler.h | 8 ++++++-- src/fsfw/cfdp/handler/MetadataParser.cpp | 3 --- src/fsfw/cfdp/handler/MetadataParser.h | 15 --------------- src/fsfw/cfdp/tlv/MessageToUserTlv.cpp | 3 +++ src/fsfw/cfdp/tlv/MessageToUserTlv.h | 1 + 7 files changed, 23 insertions(+), 28 deletions(-) delete mode 100644 src/fsfw/cfdp/handler/MetadataParser.cpp delete mode 100644 src/fsfw/cfdp/handler/MetadataParser.h diff --git a/src/fsfw/cfdp/handler/CMakeLists.txt b/src/fsfw/cfdp/handler/CMakeLists.txt index ea3d7633..ddbcc470 100644 --- a/src/fsfw/cfdp/handler/CMakeLists.txt +++ b/src/fsfw/cfdp/handler/CMakeLists.txt @@ -1,4 +1,3 @@ target_sources( - ${LIB_FSFW_NAME} - PRIVATE SourceHandler.cpp DestHandler.cpp MetadataParser.cpp -PutRequest.cpp FaultHandlerBase.cpp UserBase.cpp) + ${LIB_FSFW_NAME} PRIVATE SourceHandler.cpp DestHandler.cpp PutRequest.cpp + FaultHandlerBase.cpp UserBase.cpp) diff --git a/src/fsfw/cfdp/handler/DestHandler.cpp b/src/fsfw/cfdp/handler/DestHandler.cpp index 03a360b7..6f1e9f40 100644 --- a/src/fsfw/cfdp/handler/DestHandler.cpp +++ b/src/fsfw/cfdp/handler/DestHandler.cpp @@ -16,7 +16,7 @@ using namespace returnvalue; cfdp::DestHandler::DestHandler(DestHandlerParams params, FsfwParams fsfwParams) : tlvVec(params.maxTlvsInOnePdu), - userTlvVec(params.maxTlvsInOnePdu), + msgToUserVec(params.maxTlvsInOnePdu), destParams(std::move(params)), fsfwParams(fsfwParams), transactionParams(params.maxFilenameLen) { @@ -137,7 +137,7 @@ ReturnValue_t cfdp::DestHandler::handleMetadataPdu(const PacketInfo& info) { cfdp::StringLv destFileName; MetadataInfo metadataInfo(transactionParams.fileSize, sourceFileName, destFileName); MetadataPduReader reader(constAccessorPair.second.data(), constAccessorPair.second.size(), - metadataInfo, nullptr, 0); + metadataInfo, tlvVec.data(), tlvVec.size()); ReturnValue_t result = reader.parseData(); // TODO: The standard does not really specify what happens if this kind of error happens // I think it might be a good idea to cache some sort of error code, which @@ -355,9 +355,15 @@ ReturnValue_t cfdp::DestHandler::startTransaction(MetadataPduReader& reader, Met params.fileSize = transactionParams.fileSize.getSize(); params.destFileName = transactionParams.destName.data(); params.sourceFileName = transactionParams.sourceName.data(); - // TODO: Is this really correct? Implement this correctly.. - // params.msgsToUserArray = dynamic_cast(userTlvVec.data()); - // params.msgsToUserLen = reader.getNumberOfParsedOptions(); + unsigned tlvIdx = 0; + for (const auto& opt : tlvVec) { + if (opt.getType() == TlvType::MSG_TO_USER) { + msgToUserVec[tlvIdx] = MessageToUserTlv(opt.getValue(), opt.getLengthField()); + tlvIdx++; + } + } + params.msgsToUserArray = msgToUserVec.data(); + params.msgsToUserLen = tlvIdx; destParams.user.metadataRecvdIndication(params); return result; } diff --git a/src/fsfw/cfdp/handler/DestHandler.h b/src/fsfw/cfdp/handler/DestHandler.h index 40fe5e10..dc98d0e0 100644 --- a/src/fsfw/cfdp/handler/DestHandler.h +++ b/src/fsfw/cfdp/handler/DestHandler.h @@ -13,6 +13,7 @@ #include "fsfw/cfdp/handler/mib.h" #include "fsfw/cfdp/pdu/MetadataPduReader.h" #include "fsfw/cfdp/pdu/PduConfig.h" +#include "fsfw/cfdp/tlv/MessageToUserTlv.h" #include "fsfw/container/DynamicFIFO.h" #include "fsfw/storagemanager/StorageManagerIF.h" #include "fsfw/storagemanager/storeAddress.h" @@ -30,6 +31,9 @@ struct DestHandlerParams { // TODO: This container can potentially take tons of space. For a better // memory efficient implementation, an additional abstraction could be // be used so users can use uint32_t as the pair type + // TODO: Actually, we can provide a better abstraction via interface, which + // allows using something like a bounded map. This simplifies + // the implementation significantly. LostSegmentsListBase& lostSegmentsContainer) : cfg(std::move(cfg)), user(user), @@ -43,7 +47,7 @@ struct DestHandlerParams { PacketInfoListBase& packetListRef; LostSegmentsListBase& lostSegmentsContainer; - uint8_t maxTlvsInOnePdu = 10; + uint8_t maxTlvsInOnePdu = 20; size_t maxFilenameLen = 255; }; @@ -143,7 +147,7 @@ class DestHandler { }; std::vector tlvVec; - std::vector userTlvVec; + std::vector msgToUserVec; DestHandlerParams destParams; cfdp::FsfwParams fsfwParams; TransactionParams transactionParams; diff --git a/src/fsfw/cfdp/handler/MetadataParser.cpp b/src/fsfw/cfdp/handler/MetadataParser.cpp deleted file mode 100644 index 2c90815f..00000000 --- a/src/fsfw/cfdp/handler/MetadataParser.cpp +++ /dev/null @@ -1,3 +0,0 @@ -#include "MetadataParser.h" - -cfdp::MetadataParser::MetadataParser(MetadataPduReader& reader) {} diff --git a/src/fsfw/cfdp/handler/MetadataParser.h b/src/fsfw/cfdp/handler/MetadataParser.h deleted file mode 100644 index 3ab7478a..00000000 --- a/src/fsfw/cfdp/handler/MetadataParser.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "fsfw/cfdp/pdu/MetadataPduReader.h" - -namespace cfdp { - -class MetadataParser { - public: - explicit MetadataParser(MetadataPduReader& reader); - - private: - -}; - -} // namespace cfdp \ No newline at end of file diff --git a/src/fsfw/cfdp/tlv/MessageToUserTlv.cpp b/src/fsfw/cfdp/tlv/MessageToUserTlv.cpp index 9a3e55ff..884dff38 100644 --- a/src/fsfw/cfdp/tlv/MessageToUserTlv.cpp +++ b/src/fsfw/cfdp/tlv/MessageToUserTlv.cpp @@ -7,3 +7,6 @@ MessageToUserTlv::MessageToUserTlv() : Tlv() {} MessageToUserTlv::MessageToUserTlv(const std::vector& data) : Tlv(cfdp::TlvType::MSG_TO_USER, data.data(), data.size()) {} + +MessageToUserTlv::MessageToUserTlv(const uint8_t* value, size_t size) + : Tlv(cfdp::TlvType::MSG_TO_USER, value, size) {} diff --git a/src/fsfw/cfdp/tlv/MessageToUserTlv.h b/src/fsfw/cfdp/tlv/MessageToUserTlv.h index e7f63ed2..0f393a72 100644 --- a/src/fsfw/cfdp/tlv/MessageToUserTlv.h +++ b/src/fsfw/cfdp/tlv/MessageToUserTlv.h @@ -9,6 +9,7 @@ class MessageToUserTlv : public cfdp::Tlv { public: MessageToUserTlv(); MessageToUserTlv(uint8_t* value, size_t size); + MessageToUserTlv(const uint8_t* value, size_t size); explicit MessageToUserTlv(const std::vector& data); private: From 98cbf38432517e640c6a0a1dffa0477572b94fe6 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 24 Jul 2023 10:11:16 +0200 Subject: [PATCH 032/101] this is going to be complex.. --- src/fsfw/cfdp/handler/PutRequest.cpp | 9 +++++++++ src/fsfw/cfdp/handler/PutRequest.h | 7 ++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/fsfw/cfdp/handler/PutRequest.cpp b/src/fsfw/cfdp/handler/PutRequest.cpp index 73f4c876..cf75c7d1 100644 --- a/src/fsfw/cfdp/handler/PutRequest.cpp +++ b/src/fsfw/cfdp/handler/PutRequest.cpp @@ -3,3 +3,12 @@ [[nodiscard]] bool cfdp::PutRequest::isMetadataOnly() const { return !destNameSize.has_value() and !sourceNameSize.has_value(); } +ReturnValue_t cfdp::PutRequest::serialize(uint8_t **buffer, size_t *size, size_t maxSize, + SerializeIF::Endianness streamEndianness) const { + return returnvalue::OK; +} +ReturnValue_t cfdp::PutRequest::deSerialize(const uint8_t **buffer, size_t *size, + SerializeIF::Endianness streamEndianness) { + return returnvalue::OK; +} +size_t cfdp::PutRequest::getSerializedSize() const { return 0; } diff --git a/src/fsfw/cfdp/handler/PutRequest.h b/src/fsfw/cfdp/handler/PutRequest.h index 834985bc..ec13eab6 100644 --- a/src/fsfw/cfdp/handler/PutRequest.h +++ b/src/fsfw/cfdp/handler/PutRequest.h @@ -9,7 +9,7 @@ namespace cfdp { -class PutRequest { +class PutRequest: public SerializeIF { public: EntityId destId; std::optional transmissionMode; @@ -21,6 +21,11 @@ class PutRequest { std::vector messagesToUser; std::vector fsRequest; + [[nodiscard]] ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize, + Endianness streamEndianness) const override; + ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size, + Endianness streamEndianness) override; + [[nodiscard]] size_t getSerializedSize() const override; [[nodiscard]] bool isMetadataOnly() const; }; From e4665c9394bcb23f3121e962a00046a64b3b530f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 24 Jul 2023 10:52:38 +0200 Subject: [PATCH 033/101] continue with the msg to user / put request architecture --- src/fsfw/cfdp/handler/CMakeLists.txt | 5 ++- src/fsfw/cfdp/handler/MsgToUserParser.cpp | 1 + src/fsfw/cfdp/handler/MsgToUserParser.h | 1 + src/fsfw/cfdp/handler/PutRequest.cpp | 47 ++++++++++++++++++++++- src/fsfw/cfdp/handler/PutRequest.h | 33 +++++++++------- 5 files changed, 71 insertions(+), 16 deletions(-) create mode 100644 src/fsfw/cfdp/handler/MsgToUserParser.cpp create mode 100644 src/fsfw/cfdp/handler/MsgToUserParser.h diff --git a/src/fsfw/cfdp/handler/CMakeLists.txt b/src/fsfw/cfdp/handler/CMakeLists.txt index ddbcc470..710c5862 100644 --- a/src/fsfw/cfdp/handler/CMakeLists.txt +++ b/src/fsfw/cfdp/handler/CMakeLists.txt @@ -1,3 +1,4 @@ target_sources( - ${LIB_FSFW_NAME} PRIVATE SourceHandler.cpp DestHandler.cpp PutRequest.cpp - FaultHandlerBase.cpp UserBase.cpp) + ${LIB_FSFW_NAME} + PRIVATE SourceHandler.cpp DestHandler.cpp PutRequest.cpp MsgToUserParser.cpp + FaultHandlerBase.cpp UserBase.cpp) diff --git a/src/fsfw/cfdp/handler/MsgToUserParser.cpp b/src/fsfw/cfdp/handler/MsgToUserParser.cpp new file mode 100644 index 00000000..6477a37a --- /dev/null +++ b/src/fsfw/cfdp/handler/MsgToUserParser.cpp @@ -0,0 +1 @@ +#include "MsgToUserParser.h" diff --git a/src/fsfw/cfdp/handler/MsgToUserParser.h b/src/fsfw/cfdp/handler/MsgToUserParser.h new file mode 100644 index 00000000..6f70f09b --- /dev/null +++ b/src/fsfw/cfdp/handler/MsgToUserParser.h @@ -0,0 +1 @@ +#pragma once diff --git a/src/fsfw/cfdp/handler/PutRequest.cpp b/src/fsfw/cfdp/handler/PutRequest.cpp index cf75c7d1..0952f43b 100644 --- a/src/fsfw/cfdp/handler/PutRequest.cpp +++ b/src/fsfw/cfdp/handler/PutRequest.cpp @@ -1,10 +1,55 @@ #include "PutRequest.h" +using namespace returnvalue; [[nodiscard]] bool cfdp::PutRequest::isMetadataOnly() const { - return !destNameSize.has_value() and !sourceNameSize.has_value(); + return destNameSize > 0 and sourceNameSize > 0; } ReturnValue_t cfdp::PutRequest::serialize(uint8_t **buffer, size_t *size, size_t maxSize, SerializeIF::Endianness streamEndianness) const { + ReturnValue_t result = destId.serialize(buffer, size, maxSize, streamEndianness); + if (result != OK) { + return result; + } + if (*size + 1 > maxSize) { + return SerializeIF::BUFFER_TOO_SHORT; + } + **buffer = metadataOnly; + *size += 1; + if (transmissionMode) { + **buffer = transmissionMode; + *size += 1; + *buffer += 1; + } + if (!metadataOnly) { + result = SerializeAdapter::serialize(&sourceNameSize, buffer, size, maxSize, streamEndianness); + if (result != OK) { + return result; + } + if (*size + sourceNameSize > maxSize) { + return SerializeIF::BUFFER_TOO_SHORT; + } + std::memcpy(*buffer, sourceName, sourceNameSize); + *buffer += sourceNameSize; + *size += sourceNameSize; + result = SerializeAdapter::serialize(&destNameSize, buffer, size, maxSize, streamEndianness); + if (result != OK) { + return result; + } + std::memcpy(*buffer, destName, destNameSize); + *buffer += destNameSize; + *size += destNameSize; + if (*size + 1 > maxSize) { + **buffer = transmissionMode; + *size += 1; + *buffer += 1; + } + if (*size + 1 > maxSize) { + **buffer = closureRequested; + *size += 1; + *buffer += 1; + } + } + return returnvalue::OK; } ReturnValue_t cfdp::PutRequest::deSerialize(const uint8_t **buffer, size_t *size, diff --git a/src/fsfw/cfdp/handler/PutRequest.h b/src/fsfw/cfdp/handler/PutRequest.h index ec13eab6..5f47a7ad 100644 --- a/src/fsfw/cfdp/handler/PutRequest.h +++ b/src/fsfw/cfdp/handler/PutRequest.h @@ -9,24 +9,31 @@ namespace cfdp { -class PutRequest: public SerializeIF { +class PutRequest : public SerializeIF { public: EntityId destId; - std::optional transmissionMode; - char destName[524]{}; - std::optional destNameSize; - char sourceName[524]{}; - std::optional sourceNameSize; - std::optional closureRequested; - std::vector messagesToUser; - std::vector fsRequest; + bool metadataOnly = true; + char* destName = nullptr; + uint64_t destNameSize = 0; + char* sourceName = nullptr; + uint64_t sourceNameSize = 0; + TransmissionMode transmissionMode = TransmissionMode::UNACKNOWLEDGED; + bool closureRequested = false; - [[nodiscard]] ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize, - Endianness streamEndianness) const override; - ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size, - Endianness streamEndianness) override; + [[nodiscard]] ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize, + Endianness streamEndianness) const override; + ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, + Endianness streamEndianness) override; [[nodiscard]] size_t getSerializedSize() const override; [[nodiscard]] bool isMetadataOnly() const; + + private: + size_t msgsToUsersTotalSize = 0; + uint32_t numOfMsgsToUser = 0; + uint8_t* messagesToUserStartPtr = nullptr; + size_t fsRequestsTotalSize = 0; + uint32_t numOfFsRequests = 0; + uint8_t* fsRequest = nullptr; }; } // namespace cfdp From a1f36a0dd80b38b14fd517e0892739b61039bf87 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 24 Jul 2023 10:58:18 +0200 Subject: [PATCH 034/101] put request --- src/fsfw/cfdp/handler/PutRequest.cpp | 39 ++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/src/fsfw/cfdp/handler/PutRequest.cpp b/src/fsfw/cfdp/handler/PutRequest.cpp index 0952f43b..9c8677cd 100644 --- a/src/fsfw/cfdp/handler/PutRequest.cpp +++ b/src/fsfw/cfdp/handler/PutRequest.cpp @@ -1,6 +1,7 @@ #include "PutRequest.h" using namespace returnvalue; + [[nodiscard]] bool cfdp::PutRequest::isMetadataOnly() const { return destNameSize > 0 and sourceNameSize > 0; } @@ -35,6 +36,9 @@ ReturnValue_t cfdp::PutRequest::serialize(uint8_t **buffer, size_t *size, size_t if (result != OK) { return result; } + if (*size + destNameSize > maxSize) { + return SerializeIF::BUFFER_TOO_SHORT; + } std::memcpy(*buffer, destName, destNameSize); *buffer += destNameSize; *size += destNameSize; @@ -49,11 +53,42 @@ ReturnValue_t cfdp::PutRequest::serialize(uint8_t **buffer, size_t *size, size_t *buffer += 1; } } + result = + SerializeAdapter::serialize(&msgsToUsersTotalSize, buffer, size, maxSize, streamEndianness); + if (result != OK) { + return result; + } + result = SerializeAdapter::serialize(&numOfMsgsToUser, buffer, size, maxSize, streamEndianness); + if (result != OK) { + return result; + } + if (*size + msgsToUsersTotalSize > maxSize) { + return SerializeIF::BUFFER_TOO_SHORT; + } + std::memcpy(*buffer, messagesToUserStartPtr, msgsToUsersTotalSize); + *buffer += msgsToUsersTotalSize; + *size += msgsToUsersTotalSize; - return returnvalue::OK; + result = + SerializeAdapter::serialize(&fsRequestsTotalSize, buffer, size, maxSize, streamEndianness); + if (result != OK) { + return result; + } + result = SerializeAdapter::serialize(&numOfFsRequests, buffer, size, maxSize, streamEndianness); + if (result != OK) { + return result; + } + if (*size + fsRequestsTotalSize > maxSize) { + return SerializeIF::BUFFER_TOO_SHORT; + } + std::memcpy(*buffer, fsRequest, fsRequestsTotalSize); + *buffer += fsRequestsTotalSize; + *size += fsRequestsTotalSize; + return OK; } + ReturnValue_t cfdp::PutRequest::deSerialize(const uint8_t **buffer, size_t *size, SerializeIF::Endianness streamEndianness) { - return returnvalue::OK; + return OK; } size_t cfdp::PutRequest::getSerializedSize() const { return 0; } From b0b6c68720d648df77d38c4fda2067522f5df0f0 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 24 Jul 2023 11:05:11 +0200 Subject: [PATCH 035/101] we already have CFDP messages --- src/fsfw/cfdp/CfdpMessage.cpp | 5 +++-- src/fsfw/cfdp/CfdpMessage.h | 4 +++- src/fsfw/cfdp/handler/PutRequest.cpp | 24 ++++++++++-------------- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/fsfw/cfdp/CfdpMessage.cpp b/src/fsfw/cfdp/CfdpMessage.cpp index ea4e2c98..f5bff8fd 100644 --- a/src/fsfw/cfdp/CfdpMessage.cpp +++ b/src/fsfw/cfdp/CfdpMessage.cpp @@ -4,8 +4,9 @@ CfdpMessage::CfdpMessage() = default; CfdpMessage::~CfdpMessage() = default; -void CfdpMessage::setCommand(CommandMessage *message, store_address_t cfdpPacket) { - message->setParameter(cfdpPacket.raw); +void CfdpMessage::setPutRequest(CommandMessage *message, store_address_t putRequest) { + message->setCommand(PUT_REQUEST); + message->setParameter(putRequest.raw); } store_address_t CfdpMessage::getStoreId(const CommandMessage *message) { diff --git a/src/fsfw/cfdp/CfdpMessage.h b/src/fsfw/cfdp/CfdpMessage.h index a3ee9421..b75902eb 100644 --- a/src/fsfw/cfdp/CfdpMessage.h +++ b/src/fsfw/cfdp/CfdpMessage.h @@ -11,9 +11,11 @@ class CfdpMessage { public: static const uint8_t MESSAGE_ID = messagetypes::CFDP; + static const Command_t PUT_REQUEST = MAKE_COMMAND_ID(1); + static const Command_t CANCEL_REQUEST = MAKE_COMMAND_ID(1); virtual ~CfdpMessage(); - static void setCommand(CommandMessage* message, store_address_t cfdpPacket); + static void setPutRequest(CommandMessage* message, store_address_t putRequest); static store_address_t getStoreId(const CommandMessage* message); diff --git a/src/fsfw/cfdp/handler/PutRequest.cpp b/src/fsfw/cfdp/handler/PutRequest.cpp index 9c8677cd..fa84592e 100644 --- a/src/fsfw/cfdp/handler/PutRequest.cpp +++ b/src/fsfw/cfdp/handler/PutRequest.cpp @@ -11,7 +11,7 @@ ReturnValue_t cfdp::PutRequest::serialize(uint8_t **buffer, size_t *size, size_t if (result != OK) { return result; } - if (*size + 1 > maxSize) { + if (*size + getSerializedSize() > maxSize) { return SerializeIF::BUFFER_TOO_SHORT; } **buffer = metadataOnly; @@ -26,9 +26,6 @@ ReturnValue_t cfdp::PutRequest::serialize(uint8_t **buffer, size_t *size, size_t if (result != OK) { return result; } - if (*size + sourceNameSize > maxSize) { - return SerializeIF::BUFFER_TOO_SHORT; - } std::memcpy(*buffer, sourceName, sourceNameSize); *buffer += sourceNameSize; *size += sourceNameSize; @@ -36,9 +33,6 @@ ReturnValue_t cfdp::PutRequest::serialize(uint8_t **buffer, size_t *size, size_t if (result != OK) { return result; } - if (*size + destNameSize > maxSize) { - return SerializeIF::BUFFER_TOO_SHORT; - } std::memcpy(*buffer, destName, destNameSize); *buffer += destNameSize; *size += destNameSize; @@ -62,9 +56,6 @@ ReturnValue_t cfdp::PutRequest::serialize(uint8_t **buffer, size_t *size, size_t if (result != OK) { return result; } - if (*size + msgsToUsersTotalSize > maxSize) { - return SerializeIF::BUFFER_TOO_SHORT; - } std::memcpy(*buffer, messagesToUserStartPtr, msgsToUsersTotalSize); *buffer += msgsToUsersTotalSize; *size += msgsToUsersTotalSize; @@ -78,9 +69,6 @@ ReturnValue_t cfdp::PutRequest::serialize(uint8_t **buffer, size_t *size, size_t if (result != OK) { return result; } - if (*size + fsRequestsTotalSize > maxSize) { - return SerializeIF::BUFFER_TOO_SHORT; - } std::memcpy(*buffer, fsRequest, fsRequestsTotalSize); *buffer += fsRequestsTotalSize; *size += fsRequestsTotalSize; @@ -91,4 +79,12 @@ ReturnValue_t cfdp::PutRequest::deSerialize(const uint8_t **buffer, size_t *size SerializeIF::Endianness streamEndianness) { return OK; } -size_t cfdp::PutRequest::getSerializedSize() const { return 0; } +size_t cfdp::PutRequest::getSerializedSize() const { + size_t baseSize = destId.getSerializedSize() + 1; + if (!metadataOnly) { + baseSize += sizeof(sourceNameSize) + sourceNameSize + sizeof(destNameSize) + destNameSize + 2; + } + baseSize += sizeof(msgsToUsersTotalSize) + sizeof(numOfMsgsToUser) + msgsToUsersTotalSize + + sizeof(fsRequestsTotalSize) + sizeof(numOfFsRequests) + fsRequestsTotalSize; + return baseSize; +} From 7bf7336d4ad36fac298297c97c723a6fb7a4439f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 24 Jul 2023 11:15:50 +0200 Subject: [PATCH 036/101] almost done --- src/fsfw/cfdp/handler/PutRequest.cpp | 36 +++++++++++++--------------- src/fsfw/cfdp/handler/PutRequest.h | 32 ++++++++++++++++--------- 2 files changed, 37 insertions(+), 31 deletions(-) diff --git a/src/fsfw/cfdp/handler/PutRequest.cpp b/src/fsfw/cfdp/handler/PutRequest.cpp index fa84592e..daefcca8 100644 --- a/src/fsfw/cfdp/handler/PutRequest.cpp +++ b/src/fsfw/cfdp/handler/PutRequest.cpp @@ -2,9 +2,18 @@ using namespace returnvalue; -[[nodiscard]] bool cfdp::PutRequest::isMetadataOnly() const { - return destNameSize > 0 and sourceNameSize > 0; -} +cfdp::PutRequest::PutRequest(cfdp::EntityId destId, const uint8_t *msgsToUser, + size_t msgsToUserTotalSize, const uint8_t *fsRequests, + size_t fsRequestsSize) + : destId(std::move(destId)), + metadataOnly(true), + msgsToUsersTotalSize(msgsToUserTotalSize), + msgsToUserStartPtr(msgsToUser), + fsRequestsTotalSize(fsRequestsSize), + fsRequestStartPtr(fsRequests) {} + +[[nodiscard]] bool cfdp::PutRequest::isMetadataOnly() const { return metadataOnly; } + ReturnValue_t cfdp::PutRequest::serialize(uint8_t **buffer, size_t *size, size_t maxSize, SerializeIF::Endianness streamEndianness) const { ReturnValue_t result = destId.serialize(buffer, size, maxSize, streamEndianness); @@ -16,11 +25,6 @@ ReturnValue_t cfdp::PutRequest::serialize(uint8_t **buffer, size_t *size, size_t } **buffer = metadataOnly; *size += 1; - if (transmissionMode) { - **buffer = transmissionMode; - *size += 1; - *buffer += 1; - } if (!metadataOnly) { result = SerializeAdapter::serialize(&sourceNameSize, buffer, size, maxSize, streamEndianness); if (result != OK) { @@ -52,11 +56,7 @@ ReturnValue_t cfdp::PutRequest::serialize(uint8_t **buffer, size_t *size, size_t if (result != OK) { return result; } - result = SerializeAdapter::serialize(&numOfMsgsToUser, buffer, size, maxSize, streamEndianness); - if (result != OK) { - return result; - } - std::memcpy(*buffer, messagesToUserStartPtr, msgsToUsersTotalSize); + std::memcpy(*buffer, msgsToUserStartPtr, msgsToUsersTotalSize); *buffer += msgsToUsersTotalSize; *size += msgsToUsersTotalSize; @@ -65,11 +65,7 @@ ReturnValue_t cfdp::PutRequest::serialize(uint8_t **buffer, size_t *size, size_t if (result != OK) { return result; } - result = SerializeAdapter::serialize(&numOfFsRequests, buffer, size, maxSize, streamEndianness); - if (result != OK) { - return result; - } - std::memcpy(*buffer, fsRequest, fsRequestsTotalSize); + std::memcpy(*buffer, fsRequestStartPtr, fsRequestsTotalSize); *buffer += fsRequestsTotalSize; *size += fsRequestsTotalSize; return OK; @@ -84,7 +80,7 @@ size_t cfdp::PutRequest::getSerializedSize() const { if (!metadataOnly) { baseSize += sizeof(sourceNameSize) + sourceNameSize + sizeof(destNameSize) + destNameSize + 2; } - baseSize += sizeof(msgsToUsersTotalSize) + sizeof(numOfMsgsToUser) + msgsToUsersTotalSize + - sizeof(fsRequestsTotalSize) + sizeof(numOfFsRequests) + fsRequestsTotalSize; + baseSize += sizeof(msgsToUsersTotalSize) + msgsToUsersTotalSize + sizeof(fsRequestsTotalSize) + + fsRequestsTotalSize; return baseSize; } diff --git a/src/fsfw/cfdp/handler/PutRequest.h b/src/fsfw/cfdp/handler/PutRequest.h index 5f47a7ad..8009e0f8 100644 --- a/src/fsfw/cfdp/handler/PutRequest.h +++ b/src/fsfw/cfdp/handler/PutRequest.h @@ -12,14 +12,17 @@ namespace cfdp { class PutRequest : public SerializeIF { public: EntityId destId; - bool metadataOnly = true; - char* destName = nullptr; - uint64_t destNameSize = 0; - char* sourceName = nullptr; - uint64_t sourceNameSize = 0; - TransmissionMode transmissionMode = TransmissionMode::UNACKNOWLEDGED; - bool closureRequested = false; + /** + * Metadata only constructor. + * @param destId + * @param msgsToUser + * @param msgsToUserTotalSize + * @param fsRequests + * @param fsRequestsSize + */ + PutRequest(EntityId destId, const uint8_t* msgsToUser, size_t msgsToUserTotalSize, + const uint8_t* fsRequests, size_t fsRequestsSize); [[nodiscard]] ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize, Endianness streamEndianness) const override; ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, @@ -28,12 +31,19 @@ class PutRequest : public SerializeIF { [[nodiscard]] bool isMetadataOnly() const; private: + bool metadataOnly = true; + // Transaction parameters. Omitted if the put request is metadata only. + char* destName = nullptr; + uint64_t destNameSize = 0; + char* sourceName = nullptr; + uint64_t sourceNameSize = 0; + TransmissionMode transmissionMode = TransmissionMode::UNACKNOWLEDGED; + bool closureRequested = false; + // Metadata size_t msgsToUsersTotalSize = 0; - uint32_t numOfMsgsToUser = 0; - uint8_t* messagesToUserStartPtr = nullptr; + const uint8_t* msgsToUserStartPtr = nullptr; size_t fsRequestsTotalSize = 0; - uint32_t numOfFsRequests = 0; - uint8_t* fsRequest = nullptr; + const uint8_t* fsRequestStartPtr = nullptr; }; } // namespace cfdp From 2585028e75f7fb22275f122240475443537b5e37 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 24 Jul 2023 11:33:37 +0200 Subject: [PATCH 037/101] put request serializable now --- src/fsfw/cfdp/handler/PutRequest.cpp | 78 ++++++++++++++++++++++++---- src/fsfw/cfdp/handler/PutRequest.h | 16 ++++-- 2 files changed, 79 insertions(+), 15 deletions(-) diff --git a/src/fsfw/cfdp/handler/PutRequest.cpp b/src/fsfw/cfdp/handler/PutRequest.cpp index daefcca8..1ebfe6ae 100644 --- a/src/fsfw/cfdp/handler/PutRequest.cpp +++ b/src/fsfw/cfdp/handler/PutRequest.cpp @@ -6,6 +6,7 @@ cfdp::PutRequest::PutRequest(cfdp::EntityId destId, const uint8_t *msgsToUser, size_t msgsToUserTotalSize, const uint8_t *fsRequests, size_t fsRequestsSize) : destId(std::move(destId)), + destIdWidth(destId.getWidth()), metadataOnly(true), msgsToUsersTotalSize(msgsToUserTotalSize), msgsToUserStartPtr(msgsToUser), @@ -23,8 +24,10 @@ ReturnValue_t cfdp::PutRequest::serialize(uint8_t **buffer, size_t *size, size_t if (*size + getSerializedSize() > maxSize) { return SerializeIF::BUFFER_TOO_SHORT; } - **buffer = metadataOnly; - *size += 1; + result = SerializeAdapter::serialize(&metadataOnly, buffer, size, maxSize, streamEndianness); + if (result != OK) { + return result; + } if (!metadataOnly) { result = SerializeAdapter::serialize(&sourceNameSize, buffer, size, maxSize, streamEndianness); if (result != OK) { @@ -40,15 +43,15 @@ ReturnValue_t cfdp::PutRequest::serialize(uint8_t **buffer, size_t *size, size_t std::memcpy(*buffer, destName, destNameSize); *buffer += destNameSize; *size += destNameSize; - if (*size + 1 > maxSize) { - **buffer = transmissionMode; - *size += 1; - *buffer += 1; + result = + SerializeAdapter::serialize(&transmissionMode, buffer, size, maxSize, streamEndianness); + if (result != OK) { + return result; } - if (*size + 1 > maxSize) { - **buffer = closureRequested; - *size += 1; - *buffer += 1; + result = + SerializeAdapter::serialize(&closureRequested, buffer, size, maxSize, streamEndianness); + if (result != OK) { + return result; } } result = @@ -73,8 +76,63 @@ ReturnValue_t cfdp::PutRequest::serialize(uint8_t **buffer, size_t *size, size_t ReturnValue_t cfdp::PutRequest::deSerialize(const uint8_t **buffer, size_t *size, SerializeIF::Endianness streamEndianness) { + ReturnValue_t result = + SerializeAdapter::deSerialize(&destIdWidth, buffer, size, streamEndianness); + if (result != OK) { + return result; + } + + result = destId.deSerialize(static_cast(destIdWidth), buffer, size, + streamEndianness); + if (result != OK) { + return result; + } + result = SerializeAdapter::deSerialize(&metadataOnly, buffer, size, streamEndianness); + if (result != OK) { + return result; + } + if (!metadataOnly) { + result = SerializeAdapter::deSerialize(&sourceNameSize, buffer, size, streamEndianness); + if (result != OK) { + return result; + } + sourceName = reinterpret_cast(*buffer); + *buffer += sourceNameSize; + *size += sourceNameSize; + result = SerializeAdapter::deSerialize(&destNameSize, buffer, size, streamEndianness); + if (result != OK) { + return result; + } + destName = reinterpret_cast(*buffer); + *buffer += destNameSize; + *size += destNameSize; + result = SerializeAdapter::deSerialize(&transmissionMode, buffer, size, streamEndianness); + if (result != OK) { + return result; + } + result = SerializeAdapter::deSerialize(&closureRequested, buffer, size, streamEndianness); + if (result != OK) { + return result; + } + } + result = SerializeAdapter::deSerialize(&msgsToUsersTotalSize, buffer, size, streamEndianness); + if (result != OK) { + return result; + } + msgsToUserStartPtr = *buffer; + *buffer += msgsToUsersTotalSize; + *size += msgsToUsersTotalSize; + + result = SerializeAdapter::deSerialize(&fsRequestsTotalSize, buffer, size, streamEndianness); + if (result != OK) { + return result; + } + fsRequestStartPtr = *buffer; + *buffer += fsRequestsTotalSize; + *size += fsRequestsTotalSize; return OK; } + size_t cfdp::PutRequest::getSerializedSize() const { size_t baseSize = destId.getSerializedSize() + 1; if (!metadataOnly) { diff --git a/src/fsfw/cfdp/handler/PutRequest.h b/src/fsfw/cfdp/handler/PutRequest.h index 8009e0f8..ba9fbc9a 100644 --- a/src/fsfw/cfdp/handler/PutRequest.h +++ b/src/fsfw/cfdp/handler/PutRequest.h @@ -23,6 +23,11 @@ class PutRequest : public SerializeIF { */ PutRequest(EntityId destId, const uint8_t* msgsToUser, size_t msgsToUserTotalSize, const uint8_t* fsRequests, size_t fsRequestsSize); + /** + * Default constructor for deserialization. + */ + PutRequest() = default; + [[nodiscard]] ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize, Endianness streamEndianness) const override; ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, @@ -31,14 +36,15 @@ class PutRequest : public SerializeIF { [[nodiscard]] bool isMetadataOnly() const; private: - bool metadataOnly = true; + uint8_t destIdWidth; + uint8_t metadataOnly = true; // Transaction parameters. Omitted if the put request is metadata only. - char* destName = nullptr; + const char* destName = nullptr; uint64_t destNameSize = 0; - char* sourceName = nullptr; + const char* sourceName = nullptr; uint64_t sourceNameSize = 0; - TransmissionMode transmissionMode = TransmissionMode::UNACKNOWLEDGED; - bool closureRequested = false; + uint8_t transmissionMode = TransmissionMode::UNACKNOWLEDGED; + uint8_t closureRequested = false; // Metadata size_t msgsToUsersTotalSize = 0; const uint8_t* msgsToUserStartPtr = nullptr; From 0943863ec60d32033d86ed0b4698b74645ade5e0 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 24 Jul 2023 11:35:26 +0200 Subject: [PATCH 038/101] need to think about that parser again.. --- src/fsfw/cfdp/handler/MsgToUserParser.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/fsfw/cfdp/handler/MsgToUserParser.h b/src/fsfw/cfdp/handler/MsgToUserParser.h index 6f70f09b..ca7ac9cd 100644 --- a/src/fsfw/cfdp/handler/MsgToUserParser.h +++ b/src/fsfw/cfdp/handler/MsgToUserParser.h @@ -1 +1,9 @@ #pragma once + +namespace cfdp { + +class MsgsToUserParser { + +}; + +} From 66704dc5716821209cb29b0ef9532814b01df3dc Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 24 Jul 2023 11:57:33 +0200 Subject: [PATCH 039/101] getting tricky again.. --- src/fsfw/cfdp/definitions.h | 14 ++++++++++++++ src/fsfw/cfdp/handler/MsgToUserParser.cpp | 15 +++++++++++++++ src/fsfw/cfdp/handler/MsgToUserParser.h | 17 ++++++++++++++++- src/fsfw/cfdp/tlv/MessageToUserTlv.cpp | 11 +++++++++++ src/fsfw/cfdp/tlv/MessageToUserTlv.h | 2 ++ 5 files changed, 58 insertions(+), 1 deletion(-) diff --git a/src/fsfw/cfdp/definitions.h b/src/fsfw/cfdp/definitions.h index 3faa8294..34b8d774 100644 --- a/src/fsfw/cfdp/definitions.h +++ b/src/fsfw/cfdp/definitions.h @@ -143,6 +143,20 @@ enum RecordContinuationState { CONTAINS_START_AND_END = 0b11 }; +enum class ProxyOpMessageType : uint8_t { + PUT_REQUEST = 0x00, + MSG_TO_USR = 0x01, + FS_REQUEST = 0x02, + FAULT_HANDLER_OVERRIDE = 0x03, + TRANSMISSION_MODE = 0x04, + FLOW_LABEL = 0x05, + SEG_CTRL = 0x06, + PUT_RESPONSE = 0x07, + FS_RESPONSE = 0x08, + PUT_CANCEL = 0x09, + CLOSURE = 0x0b +}; + } // namespace cfdp #endif /* FSFW_SRC_FSFW_CFDP_PDU_DEFINITIONS_H_ */ diff --git a/src/fsfw/cfdp/handler/MsgToUserParser.cpp b/src/fsfw/cfdp/handler/MsgToUserParser.cpp index 6477a37a..c5efe91d 100644 --- a/src/fsfw/cfdp/handler/MsgToUserParser.cpp +++ b/src/fsfw/cfdp/handler/MsgToUserParser.cpp @@ -1 +1,16 @@ #include "MsgToUserParser.h" + +#include "fsfw/cfdp/tlv/MessageToUserTlv.h" +#include "fsfw/ipc/QueueFactory.h" + +cfdp::MsgsToUserParser::MsgsToUserParser(StorageManagerIF& ipcStore, uint32_t messageQueueDepth) + : ipcStore(ipcStore) { + messageQueue = QueueFactory::instance()->createMessageQueue(messageQueueDepth); +} +ReturnValue_t cfdp::MsgsToUserParser::parseMsgs(const uint8_t* msgsToUserPtr, + size_t sizeOfMessages) { + size_t currentIdx = 0; + while (currentIdx < sizeOfMessages) { + } + return 0; +} diff --git a/src/fsfw/cfdp/handler/MsgToUserParser.h b/src/fsfw/cfdp/handler/MsgToUserParser.h index ca7ac9cd..a5448df2 100644 --- a/src/fsfw/cfdp/handler/MsgToUserParser.h +++ b/src/fsfw/cfdp/handler/MsgToUserParser.h @@ -1,9 +1,24 @@ #pragma once +#include "fsfw/ipc/MessageQueueIF.h" +#include "fsfw/storagemanager/StorageManagerIF.h" + namespace cfdp { +/** + * This class parses messages to user for special CFDP messages and converts them to appropriate + * CFDP requests sent via the IPC store where applicable. It also provides an API to retrieve + * custom messages which are not special CFDP messages from a provided bytestream. + */ class MsgsToUserParser { + public: + MsgsToUserParser(StorageManagerIF& ipcStore, uint32_t queueDepth); + ReturnValue_t parseMsgs(const uint8_t* msgsToUserPtr, size_t sizeOfMessages); + + private: + MessageQueueIF* messageQueue; + StorageManagerIF& ipcStore; }; -} +} // namespace cfdp diff --git a/src/fsfw/cfdp/tlv/MessageToUserTlv.cpp b/src/fsfw/cfdp/tlv/MessageToUserTlv.cpp index 884dff38..ef3ae8f2 100644 --- a/src/fsfw/cfdp/tlv/MessageToUserTlv.cpp +++ b/src/fsfw/cfdp/tlv/MessageToUserTlv.cpp @@ -10,3 +10,14 @@ MessageToUserTlv::MessageToUserTlv(const std::vector& data) MessageToUserTlv::MessageToUserTlv(const uint8_t* value, size_t size) : Tlv(cfdp::TlvType::MSG_TO_USER, value, size) {} + +bool MessageToUserTlv::isReservedCfdpMessage(uint8_t& messageType) const { + if (cfdp::Tlv::getLengthField() < 5) { + return false; + } + if (std::strcmp(reinterpret_cast(getValue()), "cfdp") == 0) { + messageType = getValue()[4]; + return true; + } + return false; +} diff --git a/src/fsfw/cfdp/tlv/MessageToUserTlv.h b/src/fsfw/cfdp/tlv/MessageToUserTlv.h index 0f393a72..64b80d61 100644 --- a/src/fsfw/cfdp/tlv/MessageToUserTlv.h +++ b/src/fsfw/cfdp/tlv/MessageToUserTlv.h @@ -12,6 +12,8 @@ class MessageToUserTlv : public cfdp::Tlv { MessageToUserTlv(const uint8_t* value, size_t size); explicit MessageToUserTlv(const std::vector& data); + bool isReservedCfdpMessage(uint8_t& messageType) const; + private: }; From 52fc0958f7f61de2901e45d92ff6587311b6ac12 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 24 Jul 2023 11:58:06 +0200 Subject: [PATCH 040/101] iniitalize field --- src/fsfw/cfdp/handler/PutRequest.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fsfw/cfdp/handler/PutRequest.h b/src/fsfw/cfdp/handler/PutRequest.h index ba9fbc9a..8ade55d0 100644 --- a/src/fsfw/cfdp/handler/PutRequest.h +++ b/src/fsfw/cfdp/handler/PutRequest.h @@ -36,7 +36,7 @@ class PutRequest : public SerializeIF { [[nodiscard]] bool isMetadataOnly() const; private: - uint8_t destIdWidth; + uint8_t destIdWidth = 0; uint8_t metadataOnly = true; // Transaction parameters. Omitted if the put request is metadata only. const char* destName = nullptr; From 33df8e8cc53cef5aa62b149a3104f6e889043c69 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 24 Jul 2023 16:38:11 +0200 Subject: [PATCH 041/101] this parser should do the job --- src/fsfw/cfdp/handler/MsgToUserParser.cpp | 82 +++++++++++++++++++++-- src/fsfw/cfdp/handler/MsgToUserParser.h | 8 ++- src/fsfw/cfdp/handler/PutRequest.cpp | 24 +++++++ src/fsfw/cfdp/handler/PutRequest.h | 3 + src/fsfw/cfdp/tlv/StringLv.cpp | 4 ++ src/fsfw/cfdp/tlv/StringLv.h | 1 + 6 files changed, 112 insertions(+), 10 deletions(-) diff --git a/src/fsfw/cfdp/handler/MsgToUserParser.cpp b/src/fsfw/cfdp/handler/MsgToUserParser.cpp index c5efe91d..3279c176 100644 --- a/src/fsfw/cfdp/handler/MsgToUserParser.cpp +++ b/src/fsfw/cfdp/handler/MsgToUserParser.cpp @@ -1,16 +1,84 @@ #include "MsgToUserParser.h" +#include "fsfw/cfdp/CfdpMessage.h" +#include "fsfw/cfdp/handler/PutRequest.h" #include "fsfw/cfdp/tlv/MessageToUserTlv.h" +#include "fsfw/ipc/CommandMessage.h" #include "fsfw/ipc/QueueFactory.h" -cfdp::MsgsToUserParser::MsgsToUserParser(StorageManagerIF& ipcStore, uint32_t messageQueueDepth) - : ipcStore(ipcStore) { - messageQueue = QueueFactory::instance()->createMessageQueue(messageQueueDepth); -} -ReturnValue_t cfdp::MsgsToUserParser::parseMsgs(const uint8_t* msgsToUserPtr, - size_t sizeOfMessages) { +using namespace returnvalue; + +cfdp::MsgsToUserParser::MsgsToUserParser(StorageManagerIF& ipcStore, MessageQueueIF& msgQueue, + MessageQueueId_t userDestination) + : msgQueue(msgQueue), ipcStore(ipcStore) {} + +ReturnValue_t cfdp::MsgsToUserParser::parseMessages(const uint8_t* msgsToUserPtr, + size_t sizeOfMessages) { + ReturnValue_t result; size_t currentIdx = 0; + const uint8_t* currentPtr = msgsToUserPtr; + MessageToUserTlv tlv; + size_t deserSize = sizeOfMessages; + PutRequest putRequest; + bool needToSendPutRequest = false; while (currentIdx < sizeOfMessages) { + result = tlv.deSerialize(¤tPtr, &deserSize, SerializeIF::Endianness::NETWORK); + if (result != returnvalue::OK) { + return result; + } + uint8_t messageType = 0; + if (tlv.isReservedCfdpMessage(messageType)) { + if (messageType == static_cast(ProxyOpMessageType::PUT_REQUEST)) { + cfdp::Lv entityIdLv; + result = entityIdLv.deSerialize(¤tPtr, &deserSize, SerializeIF::Endianness::NETWORK); + if (result != returnvalue::OK) { + return result; + } + size_t entityIdSize = 0; + const uint8_t* deserStart = entityIdLv.getValue(&entityIdSize); + result = putRequest.destId.deSerialize(static_cast(entityIdSize), + &deserStart, &entityIdSize, + SerializeIF::Endianness::NETWORK); + if (result != OK) { + return result; + } + cfdp::StringLv sourceFileName; + result = + sourceFileName.deSerialize(¤tPtr, &deserSize, SerializeIF::Endianness::NETWORK); + if (result != OK) { + return result; + } + cfdp::StringLv destFileName; + result = + destFileName.deSerialize(¤tPtr, &deserSize, SerializeIF::Endianness::NETWORK); + if (result != OK) { + return result; + } + putRequest.setSourceAndDestName(sourceFileName, destFileName); + needToSendPutRequest = true; + } + } + currentIdx += tlv.getSerializedSize(); } - return 0; + if (needToSendPutRequest) { + store_address_t storeId; + uint8_t* dataPtr; + result = ipcStore.getFreeElement(&storeId, putRequest.getSerializedSize(), &dataPtr); + if (result != OK) { + return result; + } + size_t serLen = 0; + result = putRequest.serialize(&dataPtr, &serLen, putRequest.getSerializedSize(), + SerializeIF::Endianness::MACHINE); + if (result != OK) { + return result; + } + CommandMessage msg; + CfdpMessage::setPutRequest(&msg, storeId); + result = msgQueue.sendMessage(userDestination, &msg); + if (result != OK) { + return result; + } + } + return OK; } diff --git a/src/fsfw/cfdp/handler/MsgToUserParser.h b/src/fsfw/cfdp/handler/MsgToUserParser.h index a5448df2..b2ef04c3 100644 --- a/src/fsfw/cfdp/handler/MsgToUserParser.h +++ b/src/fsfw/cfdp/handler/MsgToUserParser.h @@ -12,13 +12,15 @@ namespace cfdp { */ class MsgsToUserParser { public: - MsgsToUserParser(StorageManagerIF& ipcStore, uint32_t queueDepth); + MsgsToUserParser(StorageManagerIF& ipcStore, MessageQueueIF& msgQueue, + MessageQueueId_t userDestination); - ReturnValue_t parseMsgs(const uint8_t* msgsToUserPtr, size_t sizeOfMessages); + ReturnValue_t parseMessages(const uint8_t* msgsToUserPtr, size_t sizeOfMessages); private: - MessageQueueIF* messageQueue; + MessageQueueIF& msgQueue; StorageManagerIF& ipcStore; + MessageQueueId_t userDestination; }; } // namespace cfdp diff --git a/src/fsfw/cfdp/handler/PutRequest.cpp b/src/fsfw/cfdp/handler/PutRequest.cpp index 1ebfe6ae..45fe016a 100644 --- a/src/fsfw/cfdp/handler/PutRequest.cpp +++ b/src/fsfw/cfdp/handler/PutRequest.cpp @@ -43,11 +43,21 @@ ReturnValue_t cfdp::PutRequest::serialize(uint8_t **buffer, size_t *size, size_t std::memcpy(*buffer, destName, destNameSize); *buffer += destNameSize; *size += destNameSize; + result = + SerializeAdapter::serialize(&hasTransmissionMode, buffer, size, maxSize, streamEndianness); + if (result != OK) { + return result; + } result = SerializeAdapter::serialize(&transmissionMode, buffer, size, maxSize, streamEndianness); if (result != OK) { return result; } + result = + SerializeAdapter::serialize(&hasClosureRequested, buffer, size, maxSize, streamEndianness); + if (result != OK) { + return result; + } result = SerializeAdapter::serialize(&closureRequested, buffer, size, maxSize, streamEndianness); if (result != OK) { @@ -106,10 +116,18 @@ ReturnValue_t cfdp::PutRequest::deSerialize(const uint8_t **buffer, size_t *size destName = reinterpret_cast(*buffer); *buffer += destNameSize; *size += destNameSize; + result = SerializeAdapter::deSerialize(&hasTransmissionMode, buffer, size, streamEndianness); + if (result != OK) { + return result; + } result = SerializeAdapter::deSerialize(&transmissionMode, buffer, size, streamEndianness); if (result != OK) { return result; } + result = SerializeAdapter::deSerialize(&hasClosureRequested, buffer, size, streamEndianness); + if (result != OK) { + return result; + } result = SerializeAdapter::deSerialize(&closureRequested, buffer, size, streamEndianness); if (result != OK) { return result; @@ -142,3 +160,9 @@ size_t cfdp::PutRequest::getSerializedSize() const { fsRequestsTotalSize; return baseSize; } + +void cfdp::PutRequest::setSourceAndDestName(cfdp::StringLv &sourceName_, + cfdp::StringLv &destName_) { + this->sourceName = sourceName_.getString(sourceNameSize); + this->destName = destName_.getString(sourceNameSize); +} diff --git a/src/fsfw/cfdp/handler/PutRequest.h b/src/fsfw/cfdp/handler/PutRequest.h index 8ade55d0..b842f4e2 100644 --- a/src/fsfw/cfdp/handler/PutRequest.h +++ b/src/fsfw/cfdp/handler/PutRequest.h @@ -33,6 +33,7 @@ class PutRequest : public SerializeIF { ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, Endianness streamEndianness) override; [[nodiscard]] size_t getSerializedSize() const override; + void setSourceAndDestName(cfdp::StringLv& sourceName, cfdp::StringLv& destName); [[nodiscard]] bool isMetadataOnly() const; private: @@ -43,7 +44,9 @@ class PutRequest : public SerializeIF { uint64_t destNameSize = 0; const char* sourceName = nullptr; uint64_t sourceNameSize = 0; + bool hasTransmissionMode = false; uint8_t transmissionMode = TransmissionMode::UNACKNOWLEDGED; + bool hasClosureRequested = false; uint8_t closureRequested = false; // Metadata size_t msgsToUsersTotalSize = 0; diff --git a/src/fsfw/cfdp/tlv/StringLv.cpp b/src/fsfw/cfdp/tlv/StringLv.cpp index 60c278a7..551a23a9 100644 --- a/src/fsfw/cfdp/tlv/StringLv.cpp +++ b/src/fsfw/cfdp/tlv/StringLv.cpp @@ -7,3 +7,7 @@ cfdp::StringLv::StringLv(const char* filename, size_t len) : Lv(reinterpret_cast(filename), len) {} cfdp::StringLv::StringLv() : Lv() {} + +const char* cfdp::StringLv::getString(size_t& fileSize) const { + return reinterpret_cast(getValue(&fileSize)); +} diff --git a/src/fsfw/cfdp/tlv/StringLv.h b/src/fsfw/cfdp/tlv/StringLv.h index 6c200b8b..c837c976 100644 --- a/src/fsfw/cfdp/tlv/StringLv.h +++ b/src/fsfw/cfdp/tlv/StringLv.h @@ -13,6 +13,7 @@ class StringLv : public Lv { explicit StringLv(const std::string& fileName); explicit StringLv(const char* filename, size_t len); + const char* getString(size_t& fileSize) const; // Delete the move constructor to avoid passing in a temporary StringLv(const std::string&&) = delete; }; From e8b9897ee3769be29a9ca74bf0c4b5fb7bcfa9b7 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 24 Jul 2023 16:40:25 +0200 Subject: [PATCH 042/101] even better name --- src/fsfw/cfdp/handler/CMakeLists.txt | 4 ++-- ...MsgToUserParser.cpp => ReservedMessageParser.cpp} | 12 ++++++------ .../{MsgToUserParser.h => ReserverMessageParser.h} | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) rename src/fsfw/cfdp/handler/{MsgToUserParser.cpp => ReservedMessageParser.cpp} (85%) rename src/fsfw/cfdp/handler/{MsgToUserParser.h => ReserverMessageParser.h} (67%) diff --git a/src/fsfw/cfdp/handler/CMakeLists.txt b/src/fsfw/cfdp/handler/CMakeLists.txt index 710c5862..8ba2fec8 100644 --- a/src/fsfw/cfdp/handler/CMakeLists.txt +++ b/src/fsfw/cfdp/handler/CMakeLists.txt @@ -1,4 +1,4 @@ target_sources( ${LIB_FSFW_NAME} - PRIVATE SourceHandler.cpp DestHandler.cpp PutRequest.cpp MsgToUserParser.cpp - FaultHandlerBase.cpp UserBase.cpp) + PRIVATE SourceHandler.cpp DestHandler.cpp PutRequest.cpp + ReservedMessageParser.cpp FaultHandlerBase.cpp UserBase.cpp) diff --git a/src/fsfw/cfdp/handler/MsgToUserParser.cpp b/src/fsfw/cfdp/handler/ReservedMessageParser.cpp similarity index 85% rename from src/fsfw/cfdp/handler/MsgToUserParser.cpp rename to src/fsfw/cfdp/handler/ReservedMessageParser.cpp index 3279c176..f080cd27 100644 --- a/src/fsfw/cfdp/handler/MsgToUserParser.cpp +++ b/src/fsfw/cfdp/handler/ReservedMessageParser.cpp @@ -1,5 +1,4 @@ -#include "MsgToUserParser.h" - +#include "ReserverMessageParser.h" #include "fsfw/cfdp/CfdpMessage.h" #include "fsfw/cfdp/handler/PutRequest.h" #include "fsfw/cfdp/tlv/MessageToUserTlv.h" @@ -8,12 +7,13 @@ using namespace returnvalue; -cfdp::MsgsToUserParser::MsgsToUserParser(StorageManagerIF& ipcStore, MessageQueueIF& msgQueue, - MessageQueueId_t userDestination) +cfdp::ReservedMessageParser::ReservedMessageParser(StorageManagerIF& ipcStore, + MessageQueueIF& msgQueue, + MessageQueueId_t userDestination) : msgQueue(msgQueue), ipcStore(ipcStore) {} -ReturnValue_t cfdp::MsgsToUserParser::parseMessages(const uint8_t* msgsToUserPtr, - size_t sizeOfMessages) { +ReturnValue_t cfdp::ReservedMessageParser::parseForReserverMessages(const uint8_t* msgsToUserPtr, + size_t sizeOfMessages) { ReturnValue_t result; size_t currentIdx = 0; const uint8_t* currentPtr = msgsToUserPtr; diff --git a/src/fsfw/cfdp/handler/MsgToUserParser.h b/src/fsfw/cfdp/handler/ReserverMessageParser.h similarity index 67% rename from src/fsfw/cfdp/handler/MsgToUserParser.h rename to src/fsfw/cfdp/handler/ReserverMessageParser.h index b2ef04c3..fc661949 100644 --- a/src/fsfw/cfdp/handler/MsgToUserParser.h +++ b/src/fsfw/cfdp/handler/ReserverMessageParser.h @@ -10,12 +10,12 @@ namespace cfdp { * CFDP requests sent via the IPC store where applicable. It also provides an API to retrieve * custom messages which are not special CFDP messages from a provided bytestream. */ -class MsgsToUserParser { +class ReservedMessageParser { public: - MsgsToUserParser(StorageManagerIF& ipcStore, MessageQueueIF& msgQueue, - MessageQueueId_t userDestination); + ReservedMessageParser(StorageManagerIF& ipcStore, MessageQueueIF& msgQueue, + MessageQueueId_t userDestination); - ReturnValue_t parseMessages(const uint8_t* msgsToUserPtr, size_t sizeOfMessages); + ReturnValue_t parseForReserverMessages(const uint8_t* msgsToUserPtr, size_t sizeOfMessages); private: MessageQueueIF& msgQueue; From 437851db3ed21c15449af4ba338461907a20976c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 24 Jul 2023 16:40:44 +0200 Subject: [PATCH 043/101] naming --- src/fsfw/cfdp/handler/ReservedMessageParser.cpp | 2 +- src/fsfw/cfdp/handler/ReserverMessageParser.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fsfw/cfdp/handler/ReservedMessageParser.cpp b/src/fsfw/cfdp/handler/ReservedMessageParser.cpp index f080cd27..518b64bb 100644 --- a/src/fsfw/cfdp/handler/ReservedMessageParser.cpp +++ b/src/fsfw/cfdp/handler/ReservedMessageParser.cpp @@ -12,7 +12,7 @@ cfdp::ReservedMessageParser::ReservedMessageParser(StorageManagerIF& ipcStore, MessageQueueId_t userDestination) : msgQueue(msgQueue), ipcStore(ipcStore) {} -ReturnValue_t cfdp::ReservedMessageParser::parseForReserverMessages(const uint8_t* msgsToUserPtr, +ReturnValue_t cfdp::ReservedMessageParser::parse(const uint8_t* msgsToUserPtr, size_t sizeOfMessages) { ReturnValue_t result; size_t currentIdx = 0; diff --git a/src/fsfw/cfdp/handler/ReserverMessageParser.h b/src/fsfw/cfdp/handler/ReserverMessageParser.h index fc661949..9de4a4a4 100644 --- a/src/fsfw/cfdp/handler/ReserverMessageParser.h +++ b/src/fsfw/cfdp/handler/ReserverMessageParser.h @@ -15,7 +15,7 @@ class ReservedMessageParser { ReservedMessageParser(StorageManagerIF& ipcStore, MessageQueueIF& msgQueue, MessageQueueId_t userDestination); - ReturnValue_t parseForReserverMessages(const uint8_t* msgsToUserPtr, size_t sizeOfMessages); + ReturnValue_t parse(const uint8_t* msgsToUserPtr, size_t sizeOfMessages); private: MessageQueueIF& msgQueue; From 844c90a6259529f7a203f6876d132e7c638ee16f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 24 Jul 2023 16:42:13 +0200 Subject: [PATCH 044/101] constructor fix --- src/fsfw/cfdp/handler/ReservedMessageParser.cpp | 5 +++-- .../{ReserverMessageParser.h => ReservedMessageParser.h} | 0 2 files changed, 3 insertions(+), 2 deletions(-) rename src/fsfw/cfdp/handler/{ReserverMessageParser.h => ReservedMessageParser.h} (100%) diff --git a/src/fsfw/cfdp/handler/ReservedMessageParser.cpp b/src/fsfw/cfdp/handler/ReservedMessageParser.cpp index 518b64bb..e53db173 100644 --- a/src/fsfw/cfdp/handler/ReservedMessageParser.cpp +++ b/src/fsfw/cfdp/handler/ReservedMessageParser.cpp @@ -1,4 +1,5 @@ -#include "ReserverMessageParser.h" +#include "ReservedMessageParser.h" + #include "fsfw/cfdp/CfdpMessage.h" #include "fsfw/cfdp/handler/PutRequest.h" #include "fsfw/cfdp/tlv/MessageToUserTlv.h" @@ -10,7 +11,7 @@ using namespace returnvalue; cfdp::ReservedMessageParser::ReservedMessageParser(StorageManagerIF& ipcStore, MessageQueueIF& msgQueue, MessageQueueId_t userDestination) - : msgQueue(msgQueue), ipcStore(ipcStore) {} + : msgQueue(msgQueue), ipcStore(ipcStore), userDestination(userDestination) {} ReturnValue_t cfdp::ReservedMessageParser::parse(const uint8_t* msgsToUserPtr, size_t sizeOfMessages) { diff --git a/src/fsfw/cfdp/handler/ReserverMessageParser.h b/src/fsfw/cfdp/handler/ReservedMessageParser.h similarity index 100% rename from src/fsfw/cfdp/handler/ReserverMessageParser.h rename to src/fsfw/cfdp/handler/ReservedMessageParser.h From 8581f9a6f3959c83a82b0c2d74e3132d8a33cb4f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 24 Jul 2023 18:01:25 +0200 Subject: [PATCH 045/101] start implementing reserved message creator --- .../cfdp/handler/ReservedMessageParser.cpp | 2 +- src/fsfw/cfdp/tlv/CMakeLists.txt | 3 ++- src/fsfw/cfdp/tlv/ReservedMessageCreator.cpp | 23 +++++++++++++++++++ src/fsfw/cfdp/tlv/ReservedMessageCreator.h | 22 ++++++++++++++++++ unittests/cfdp/handler/CMakeLists.txt | 5 ++-- .../cfdp/handler/testReservedMsgParser.cpp | 18 +++++++++++++++ 6 files changed, 69 insertions(+), 4 deletions(-) create mode 100644 src/fsfw/cfdp/tlv/ReservedMessageCreator.cpp create mode 100644 src/fsfw/cfdp/tlv/ReservedMessageCreator.h create mode 100644 unittests/cfdp/handler/testReservedMsgParser.cpp diff --git a/src/fsfw/cfdp/handler/ReservedMessageParser.cpp b/src/fsfw/cfdp/handler/ReservedMessageParser.cpp index e53db173..93254483 100644 --- a/src/fsfw/cfdp/handler/ReservedMessageParser.cpp +++ b/src/fsfw/cfdp/handler/ReservedMessageParser.cpp @@ -14,7 +14,7 @@ cfdp::ReservedMessageParser::ReservedMessageParser(StorageManagerIF& ipcStore, : msgQueue(msgQueue), ipcStore(ipcStore), userDestination(userDestination) {} ReturnValue_t cfdp::ReservedMessageParser::parse(const uint8_t* msgsToUserPtr, - size_t sizeOfMessages) { + size_t sizeOfMessages) { ReturnValue_t result; size_t currentIdx = 0; const uint8_t* currentPtr = msgsToUserPtr; diff --git a/src/fsfw/cfdp/tlv/CMakeLists.txt b/src/fsfw/cfdp/tlv/CMakeLists.txt index 617b1b0f..09adf941 100644 --- a/src/fsfw/cfdp/tlv/CMakeLists.txt +++ b/src/fsfw/cfdp/tlv/CMakeLists.txt @@ -8,4 +8,5 @@ target_sources( StringLv.cpp FlowLabelTlv.cpp MessageToUserTlv.cpp - FaultHandlerOverrideTlv.cpp) + FaultHandlerOverrideTlv.cpp + ReservedMessageCreator.cpp) diff --git a/src/fsfw/cfdp/tlv/ReservedMessageCreator.cpp b/src/fsfw/cfdp/tlv/ReservedMessageCreator.cpp new file mode 100644 index 00000000..a4ce0a99 --- /dev/null +++ b/src/fsfw/cfdp/tlv/ReservedMessageCreator.cpp @@ -0,0 +1,23 @@ +#include "ReservedMessageCreator.h" + +cfdp::ReservedMessageCreator::ReservedMessageCreator(uint8_t messageType, uint8_t *msgData, + size_t msgLen) + : messageType(messageType), msgData(msgData), msgSize(msgLen) {} +ReturnValue_t cfdp::ReservedMessageCreator::serialize( + uint8_t **buffer, size_t *size, size_t maxSize, + SerializeIF::Endianness streamEndianness) const { + if (*size + getSerializedSize() > maxSize) { + return SerializeIF::BUFFER_TOO_SHORT; + } + return returnvalue::OK; +} + +size_t cfdp::ReservedMessageCreator::getSerializedSize() const { + // 3 bytes type and length and value, 4 bytes CFDP, 1 byte reserved message type, message data. + return 3 + 5 + msgSize; +} + +ReturnValue_t cfdp::ReservedMessageCreator::deSerialize(const uint8_t **buffer, size_t *size, + SerializeIF::Endianness streamEndianness) { + return returnvalue::FAILED; +} diff --git a/src/fsfw/cfdp/tlv/ReservedMessageCreator.h b/src/fsfw/cfdp/tlv/ReservedMessageCreator.h new file mode 100644 index 00000000..89878635 --- /dev/null +++ b/src/fsfw/cfdp/tlv/ReservedMessageCreator.h @@ -0,0 +1,22 @@ +#pragma once + +#include "Tlv.h" + +namespace cfdp { + +class ReservedMessageCreator : public SerializeIF { + public: + ReservedMessageCreator(uint8_t messageType, uint8_t *msgData, size_t msgLen); + [[nodiscard]] ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize, + Endianness streamEndianness) const override; + [[nodiscard]] size_t getSerializedSize() const override; + ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size, + Endianness streamEndianness) override; + + private: + uint8_t messageType; + uint8_t *msgData; + size_t msgSize; +}; + +} // namespace cfdp diff --git a/unittests/cfdp/handler/CMakeLists.txt b/unittests/cfdp/handler/CMakeLists.txt index f70e5dfb..c5da0627 100644 --- a/unittests/cfdp/handler/CMakeLists.txt +++ b/unittests/cfdp/handler/CMakeLists.txt @@ -1,3 +1,4 @@ target_sources( - ${FSFW_TEST_TGT} PRIVATE testDistributor.cpp testDestHandler.cpp - testSourceHandler.cpp testFaultHandler.cpp) + ${FSFW_TEST_TGT} + PRIVATE testDistributor.cpp testDestHandler.cpp testReservedMsgParser.cpp + testSourceHandler.cpp testFaultHandler.cpp) diff --git a/unittests/cfdp/handler/testReservedMsgParser.cpp b/unittests/cfdp/handler/testReservedMsgParser.cpp new file mode 100644 index 00000000..ea038b6a --- /dev/null +++ b/unittests/cfdp/handler/testReservedMsgParser.cpp @@ -0,0 +1,18 @@ +#include + +#include "fsfw/cfdp/handler/ReservedMessageParser.h" +#include "mocks/MessageQueueMock.h" +#include "mocks/StorageManagerMock.h" + +TEST_CASE("Reserved Message Parser", "[cfdp]") { + using namespace cfdp; + using namespace returnvalue; + + MessageQueueId_t destQueueId = 2; + MessageQueueMock msgQueue(destQueueId); + LocalPool::LocalPoolConfig storeCfg = {{10, 32}, {10, 64}, {10, 128}, {10, 1024}}; + StorageManagerMock ipcStore(0, storeCfg); + ReservedMessageParser parser(ipcStore, msgQueue, destQueueId); + + // parser.parse() +} From 8f0974d83eef0330cbe50d8a390e1bf32dc943f8 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 24 Jul 2023 18:07:20 +0200 Subject: [PATCH 046/101] finished reserved msg creator function --- src/fsfw/cfdp/tlv/ReservedMessageCreator.cpp | 18 ++++++++++++++++-- src/fsfw/cfdp/tlv/ReservedMessageCreator.h | 2 ++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/fsfw/cfdp/tlv/ReservedMessageCreator.cpp b/src/fsfw/cfdp/tlv/ReservedMessageCreator.cpp index a4ce0a99..5eaf72c6 100644 --- a/src/fsfw/cfdp/tlv/ReservedMessageCreator.cpp +++ b/src/fsfw/cfdp/tlv/ReservedMessageCreator.cpp @@ -3,18 +3,32 @@ cfdp::ReservedMessageCreator::ReservedMessageCreator(uint8_t messageType, uint8_t *msgData, size_t msgLen) : messageType(messageType), msgData(msgData), msgSize(msgLen) {} + ReturnValue_t cfdp::ReservedMessageCreator::serialize( uint8_t **buffer, size_t *size, size_t maxSize, SerializeIF::Endianness streamEndianness) const { if (*size + getSerializedSize() > maxSize) { return SerializeIF::BUFFER_TOO_SHORT; } + **buffer = TlvType::MSG_TO_USER; + *buffer += 1; + *size += 1; + **buffer = getSerializedSize() - 1; + *size += 1; + *buffer += 1; + std::memcpy(*buffer, MSG_HEADER, 4); + *buffer += 4; + *size += 4; + **buffer = messageType; + *buffer += 1; + *size += 1; + std::memcpy(*buffer, msgData, msgSize); return returnvalue::OK; } size_t cfdp::ReservedMessageCreator::getSerializedSize() const { - // 3 bytes type and length and value, 4 bytes CFDP, 1 byte reserved message type, message data. - return 3 + 5 + msgSize; + // 2 bytes type and length, 4 bytes CFDP, 1 byte reserved message type, message data. + return 2 + 5 + msgSize; } ReturnValue_t cfdp::ReservedMessageCreator::deSerialize(const uint8_t **buffer, size_t *size, diff --git a/src/fsfw/cfdp/tlv/ReservedMessageCreator.h b/src/fsfw/cfdp/tlv/ReservedMessageCreator.h index 89878635..363791c8 100644 --- a/src/fsfw/cfdp/tlv/ReservedMessageCreator.h +++ b/src/fsfw/cfdp/tlv/ReservedMessageCreator.h @@ -6,6 +6,8 @@ namespace cfdp { class ReservedMessageCreator : public SerializeIF { public: + static constexpr char MSG_HEADER[] = "cfdp"; + ReservedMessageCreator(uint8_t messageType, uint8_t *msgData, size_t msgLen); [[nodiscard]] ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize, Endianness streamEndianness) const override; From 244e2d0737902519670f505e9bd42fc110fd1548 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 25 Jul 2023 13:58:22 +0200 Subject: [PATCH 047/101] start adding message parser unittests --- src/fsfw/cfdp/VarLenFields.h | 13 +++++ src/fsfw/cfdp/tlv/ReservedMessageCreator.cpp | 4 +- unittests/cfdp/CMakeLists.txt | 5 +- .../cfdp/handler/testReservedMsgParser.cpp | 27 +++++++++- unittests/cfdp/testReservedMsgCreator.cpp | 49 +++++++++++++++++++ 5 files changed, 93 insertions(+), 5 deletions(-) create mode 100644 unittests/cfdp/testReservedMsgCreator.cpp diff --git a/src/fsfw/cfdp/VarLenFields.h b/src/fsfw/cfdp/VarLenFields.h index cdfcc775..db094db6 100644 --- a/src/fsfw/cfdp/VarLenFields.h +++ b/src/fsfw/cfdp/VarLenFields.h @@ -74,6 +74,19 @@ struct EntityId : public VarLenField { template explicit EntityId(UnsignedByteField byteField) : VarLenField(byteField) {} EntityId(cfdp::WidthInBytes width, size_t entityId) : VarLenField(width, entityId) {} + + ReturnValue_t serializeAsLv(uint8_t **buffer, size_t *size, size_t maxSize) { + if (buffer == nullptr or size == nullptr) { + return returnvalue::FAILED; + } + if (*size + 1 + getWidth() > maxSize) { + return SerializeIF::BUFFER_TOO_SHORT; + } + **buffer = getWidth(); + *buffer += 1; + *size += 1; + return serialize(buffer, size, maxSize, SerializeIF::Endianness::NETWORK); + } }; struct TransactionSeqNum : public VarLenField { diff --git a/src/fsfw/cfdp/tlv/ReservedMessageCreator.cpp b/src/fsfw/cfdp/tlv/ReservedMessageCreator.cpp index 5eaf72c6..d37338ed 100644 --- a/src/fsfw/cfdp/tlv/ReservedMessageCreator.cpp +++ b/src/fsfw/cfdp/tlv/ReservedMessageCreator.cpp @@ -13,7 +13,7 @@ ReturnValue_t cfdp::ReservedMessageCreator::serialize( **buffer = TlvType::MSG_TO_USER; *buffer += 1; *size += 1; - **buffer = getSerializedSize() - 1; + **buffer = getSerializedSize() - 2; *size += 1; *buffer += 1; std::memcpy(*buffer, MSG_HEADER, 4); @@ -23,6 +23,8 @@ ReturnValue_t cfdp::ReservedMessageCreator::serialize( *buffer += 1; *size += 1; std::memcpy(*buffer, msgData, msgSize); + *buffer += msgSize; + *size += msgSize; return returnvalue::OK; } diff --git a/unittests/cfdp/CMakeLists.txt b/unittests/cfdp/CMakeLists.txt index 1867a534..aba30ede 100644 --- a/unittests/cfdp/CMakeLists.txt +++ b/unittests/cfdp/CMakeLists.txt @@ -1,5 +1,6 @@ -target_sources(${FSFW_TEST_TGT} PRIVATE testCfdp.cpp testOtherTlvs.cpp - testTlv.cpp testLvs.cpp) +target_sources( + ${FSFW_TEST_TGT} PRIVATE testCfdp.cpp testOtherTlvs.cpp + testReservedMsgCreator.cpp testTlv.cpp testLvs.cpp) add_subdirectory(handler) add_subdirectory(pdu) diff --git a/unittests/cfdp/handler/testReservedMsgParser.cpp b/unittests/cfdp/handler/testReservedMsgParser.cpp index ea038b6a..035cef5f 100644 --- a/unittests/cfdp/handler/testReservedMsgParser.cpp +++ b/unittests/cfdp/handler/testReservedMsgParser.cpp @@ -1,6 +1,10 @@ #include +#include "fsfw/cfdp/VarLenFields.h" #include "fsfw/cfdp/handler/ReservedMessageParser.h" +#include "fsfw/cfdp/tlv/Lv.h" +#include "fsfw/cfdp/tlv/ReservedMessageCreator.h" +#include "fsfw/cfdp/tlv/StringLv.h" #include "mocks/MessageQueueMock.h" #include "mocks/StorageManagerMock.h" @@ -8,11 +12,30 @@ TEST_CASE("Reserved Message Parser", "[cfdp]") { using namespace cfdp; using namespace returnvalue; + std::string srcFileName = "hello.txt"; + std::string destFileName = "hello2.txt"; MessageQueueId_t destQueueId = 2; MessageQueueMock msgQueue(destQueueId); LocalPool::LocalPoolConfig storeCfg = {{10, 32}, {10, 64}, {10, 128}, {10, 1024}}; StorageManagerMock ipcStore(0, storeCfg); - ReservedMessageParser parser(ipcStore, msgQueue, destQueueId); + std::array buffer{}; + uint8_t msgBuf[32]{}; + EntityId entityId(cfdp::WidthInBytes::ONE_BYTE, 5); + uint8_t* msgBufPtr = msgBuf; + size_t serLen = 0; + cfdp::StringLv srcName(srcFileName); + cfdp::StringLv destName(destFileName); + CHECK(entityId.serializeAsLv(&msgBufPtr, &serLen, sizeof(msgBuf)) == OK); + CHECK(srcName.serialize(&msgBufPtr, &serLen, sizeof(msgBuf), SerializeIF::Endianness::NETWORK) == + OK); + CHECK(destName.serialize(&msgBufPtr, &serLen, sizeof(msgBuf), SerializeIF::Endianness::NETWORK) == + OK); + ReservedMessageCreator creator(static_cast(ProxyOpMessageType::PUT_REQUEST), msgBuf, + serLen); + serLen = 0; + ReturnValue_t result = creator.serializeBe(buffer.data(), serLen, buffer.size()); + CHECK(result == returnvalue::OK); - // parser.parse() + ReservedMessageParser parser(ipcStore, msgQueue, destQueueId); + CHECK(parser.parse(buffer.data(), buffer.max_size()) == OK); } diff --git a/unittests/cfdp/testReservedMsgCreator.cpp b/unittests/cfdp/testReservedMsgCreator.cpp new file mode 100644 index 00000000..1873becf --- /dev/null +++ b/unittests/cfdp/testReservedMsgCreator.cpp @@ -0,0 +1,49 @@ +#include +#include + +#include "fsfw/cfdp/VarLenFields.h" +#include "fsfw/cfdp/tlv/ReservedMessageCreator.h" +#include "fsfw/cfdp/tlv/StringLv.h" + +TEST_CASE("Reserved Message Creator", "[cfdp][tlv]") { + using namespace cfdp; + using namespace returnvalue; + + std::string srcFileName = "hello.txt"; + std::string destFileName = "hello2.txt"; + std::array buffer{}; + uint8_t msgBuf[32]{}; + EntityId entityId(cfdp::WidthInBytes::ONE_BYTE, 5); + uint8_t* msgBufPtr = msgBuf; + size_t serLen = 0; + cfdp::StringLv srcName(srcFileName); + cfdp::StringLv destName(destFileName); + CHECK(entityId.serializeAsLv(&msgBufPtr, &serLen, sizeof(msgBuf)) == OK); + CHECK(srcName.serialize(&msgBufPtr, &serLen, sizeof(msgBuf), SerializeIF::Endianness::NETWORK) == + OK); + CHECK(destName.serialize(&msgBufPtr, &serLen, sizeof(msgBuf), SerializeIF::Endianness::NETWORK) == + OK); + ReservedMessageCreator creator(static_cast(ProxyOpMessageType::PUT_REQUEST), msgBuf, + serLen); + serLen = 0; + ReturnValue_t result = creator.serializeBe(buffer.data(), serLen, buffer.size()); + CHECK(result == returnvalue::OK); + CHECK(buffer[0] == TlvType::MSG_TO_USER); + // 4 bytes "cfdp" header, 1 byte message type, entity ID LV, source name LV and dest name LV + CHECK(buffer[1] == + 5 + 1 + entityId.getSerializedSize() + 1 + srcFileName.size() + 1 + destFileName.size()); + CHECK(buffer[2] == 'c'); + CHECK(buffer[3] == 'f'); + CHECK(buffer[4] == 'd'); + CHECK(buffer[5] == 'p'); + CHECK(buffer[6] == static_cast(ProxyOpMessageType::PUT_REQUEST)); + CHECK(buffer[7] == 1); + CHECK(buffer[8] == entityId.getValue()); + CHECK(buffer[9] == srcFileName.size()); + size_t currentIdx = 10; + CHECK(std::string(reinterpret_cast(buffer.data()) + currentIdx, + srcFileName.size()) == srcFileName); + currentIdx += srcFileName.size() + 1; + CHECK(std::string(reinterpret_cast(buffer.data()) + currentIdx, + destFileName.size()) == destFileName); +} From 314cba363fcd07cc106430f315241f2242c4c407 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 25 Jul 2023 16:16:35 +0200 Subject: [PATCH 048/101] contnue msg parser unittest --- src/fsfw/cfdp/handler/ReservedMessageParser.cpp | 2 +- src/fsfw/cfdp/tlv/Lv.cpp | 6 ++---- src/fsfw/cfdp/tlv/MessageToUserTlv.cpp | 7 ++++++- src/fsfw/cfdp/tlv/MessageToUserTlv.h | 3 ++- src/fsfw/objectmanager/ObjectManager.cpp | 4 ++-- unittests/cfdp/handler/testReservedMsgParser.cpp | 5 ++++- 6 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/fsfw/cfdp/handler/ReservedMessageParser.cpp b/src/fsfw/cfdp/handler/ReservedMessageParser.cpp index 93254483..4f3785f4 100644 --- a/src/fsfw/cfdp/handler/ReservedMessageParser.cpp +++ b/src/fsfw/cfdp/handler/ReservedMessageParser.cpp @@ -28,7 +28,7 @@ ReturnValue_t cfdp::ReservedMessageParser::parse(const uint8_t* msgsToUserPtr, return result; } uint8_t messageType = 0; - if (tlv.isReservedCfdpMessage(messageType)) { + if (tlv.isReservedCfdpMessage(messageType, ¤tPtr, deserSize)) { if (messageType == static_cast(ProxyOpMessageType::PUT_REQUEST)) { cfdp::Lv entityIdLv; result = entityIdLv.deSerialize(¤tPtr, &deserSize, SerializeIF::Endianness::NETWORK); diff --git a/src/fsfw/cfdp/tlv/Lv.cpp b/src/fsfw/cfdp/tlv/Lv.cpp index e7fa414a..215b9b3b 100644 --- a/src/fsfw/cfdp/tlv/Lv.cpp +++ b/src/fsfw/cfdp/tlv/Lv.cpp @@ -49,10 +49,8 @@ ReturnValue_t cfdp::Lv::serialize(uint8_t** buffer, size_t* size, size_t maxSize } size_t cfdp::Lv::getSerializedSize() const { - if (zeroLen) { + if (zeroLen or value.getConstBuffer() == nullptr) { return 1; - } else if (value.getConstBuffer() == nullptr) { - return 0; } return value.getSerializedSize(); } @@ -85,7 +83,7 @@ ReturnValue_t cfdp::Lv::deSerialize(const uint8_t** buffer, size_t* size, const uint8_t* cfdp::Lv::getValue(size_t* size) const { if (size != nullptr) { // Length without length field - *size = value.getSerializedSize() - 1; + *size = getSerializedSize() - 1; } return value.getConstBuffer(); } diff --git a/src/fsfw/cfdp/tlv/MessageToUserTlv.cpp b/src/fsfw/cfdp/tlv/MessageToUserTlv.cpp index ef3ae8f2..eaf17b67 100644 --- a/src/fsfw/cfdp/tlv/MessageToUserTlv.cpp +++ b/src/fsfw/cfdp/tlv/MessageToUserTlv.cpp @@ -11,12 +11,17 @@ MessageToUserTlv::MessageToUserTlv(const std::vector& data) MessageToUserTlv::MessageToUserTlv(const uint8_t* value, size_t size) : Tlv(cfdp::TlvType::MSG_TO_USER, value, size) {} -bool MessageToUserTlv::isReservedCfdpMessage(uint8_t& messageType) const { +bool MessageToUserTlv::isReservedCfdpMessage(uint8_t& messageType, const uint8_t** msgDataStart, + size_t& msgLen) const { if (cfdp::Tlv::getLengthField() < 5) { return false; } if (std::strcmp(reinterpret_cast(getValue()), "cfdp") == 0) { messageType = getValue()[4]; + if (msgDataStart != nullptr) { + *msgDataStart = getValue() + 5; + } + msgLen = cfdp::Tlv::getSerializedSize() - 5; return true; } return false; diff --git a/src/fsfw/cfdp/tlv/MessageToUserTlv.h b/src/fsfw/cfdp/tlv/MessageToUserTlv.h index 64b80d61..7018a386 100644 --- a/src/fsfw/cfdp/tlv/MessageToUserTlv.h +++ b/src/fsfw/cfdp/tlv/MessageToUserTlv.h @@ -12,7 +12,8 @@ class MessageToUserTlv : public cfdp::Tlv { MessageToUserTlv(const uint8_t* value, size_t size); explicit MessageToUserTlv(const std::vector& data); - bool isReservedCfdpMessage(uint8_t& messageType) const; + bool isReservedCfdpMessage(uint8_t& messageType, const uint8_t** msgDataStart, + size_t& msgLen) const; private: }; diff --git a/src/fsfw/objectmanager/ObjectManager.cpp b/src/fsfw/objectmanager/ObjectManager.cpp index 2193d3a5..f2b45d59 100644 --- a/src/fsfw/objectmanager/ObjectManager.cpp +++ b/src/fsfw/objectmanager/ObjectManager.cpp @@ -116,8 +116,8 @@ void ObjectManager::initialize() { << std::dec << std::setfill(' ') << std::endl; #else sif::printError( - "ObjectManager::initialize: Object 0x%08x failed to initialize with code 0x%04x\n", var, - it.first); + "ObjectManager::initialize: Object 0x%08x failed to initialize with code 0x%04x\n", + it.first, result); #endif #endif errorCount++; diff --git a/unittests/cfdp/handler/testReservedMsgParser.cpp b/unittests/cfdp/handler/testReservedMsgParser.cpp index 035cef5f..e7f8da8b 100644 --- a/unittests/cfdp/handler/testReservedMsgParser.cpp +++ b/unittests/cfdp/handler/testReservedMsgParser.cpp @@ -5,6 +5,7 @@ #include "fsfw/cfdp/tlv/Lv.h" #include "fsfw/cfdp/tlv/ReservedMessageCreator.h" #include "fsfw/cfdp/tlv/StringLv.h" +#include "fsfw/globalfunctions/arrayprinter.h" #include "mocks/MessageQueueMock.h" #include "mocks/StorageManagerMock.h" @@ -20,6 +21,7 @@ TEST_CASE("Reserved Message Parser", "[cfdp]") { StorageManagerMock ipcStore(0, storeCfg); std::array buffer{}; uint8_t msgBuf[32]{}; + EntityId entityId(cfdp::WidthInBytes::ONE_BYTE, 5); uint8_t* msgBufPtr = msgBuf; size_t serLen = 0; @@ -35,7 +37,8 @@ TEST_CASE("Reserved Message Parser", "[cfdp]") { serLen = 0; ReturnValue_t result = creator.serializeBe(buffer.data(), serLen, buffer.size()); CHECK(result == returnvalue::OK); + arrayprinter::print(buffer.data(), serLen); ReservedMessageParser parser(ipcStore, msgQueue, destQueueId); - CHECK(parser.parse(buffer.data(), buffer.max_size()) == OK); + CHECK(parser.parse(buffer.data(), serLen) == OK); } From 8f5a8b13d3317dc9300da2576d547c0cb308ffe7 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 26 Jul 2023 16:25:42 +0200 Subject: [PATCH 049/101] parsing finally works --- src/fsfw/cfdp/handler/PutRequest.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/fsfw/cfdp/handler/PutRequest.cpp b/src/fsfw/cfdp/handler/PutRequest.cpp index 45fe016a..b3afda30 100644 --- a/src/fsfw/cfdp/handler/PutRequest.cpp +++ b/src/fsfw/cfdp/handler/PutRequest.cpp @@ -17,13 +17,16 @@ cfdp::PutRequest::PutRequest(cfdp::EntityId destId, const uint8_t *msgsToUser, ReturnValue_t cfdp::PutRequest::serialize(uint8_t **buffer, size_t *size, size_t maxSize, SerializeIF::Endianness streamEndianness) const { - ReturnValue_t result = destId.serialize(buffer, size, maxSize, streamEndianness); - if (result != OK) { - return result; + if(buffer == nullptr or size == nullptr) { + return FAILED; } if (*size + getSerializedSize() > maxSize) { return SerializeIF::BUFFER_TOO_SHORT; } + ReturnValue_t result = destId.serialize(buffer, size, maxSize, streamEndianness); + if (result != OK) { + return result; + } result = SerializeAdapter::serialize(&metadataOnly, buffer, size, maxSize, streamEndianness); if (result != OK) { return result; @@ -152,7 +155,7 @@ ReturnValue_t cfdp::PutRequest::deSerialize(const uint8_t **buffer, size_t *size } size_t cfdp::PutRequest::getSerializedSize() const { - size_t baseSize = destId.getSerializedSize() + 1; + size_t baseSize = 1 + destId.getSerializedSize(); if (!metadataOnly) { baseSize += sizeof(sourceNameSize) + sourceNameSize + sizeof(destNameSize) + destNameSize + 2; } @@ -164,5 +167,5 @@ size_t cfdp::PutRequest::getSerializedSize() const { void cfdp::PutRequest::setSourceAndDestName(cfdp::StringLv &sourceName_, cfdp::StringLv &destName_) { this->sourceName = sourceName_.getString(sourceNameSize); - this->destName = destName_.getString(sourceNameSize); + this->destName = destName_.getString(destNameSize); } From e8bf8b957583c1cb00e05407d3082a18a8c7989e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 26 Jul 2023 16:36:21 +0200 Subject: [PATCH 050/101] looking good --- unittests/cfdp/handler/testReservedMsgParser.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/unittests/cfdp/handler/testReservedMsgParser.cpp b/unittests/cfdp/handler/testReservedMsgParser.cpp index e7f8da8b..0b9f5782 100644 --- a/unittests/cfdp/handler/testReservedMsgParser.cpp +++ b/unittests/cfdp/handler/testReservedMsgParser.cpp @@ -4,6 +4,7 @@ #include "fsfw/cfdp/handler/ReservedMessageParser.h" #include "fsfw/cfdp/tlv/Lv.h" #include "fsfw/cfdp/tlv/ReservedMessageCreator.h" +#include "fsfw/cfdp/CfdpMessage.h" #include "fsfw/cfdp/tlv/StringLv.h" #include "fsfw/globalfunctions/arrayprinter.h" #include "mocks/MessageQueueMock.h" @@ -16,7 +17,7 @@ TEST_CASE("Reserved Message Parser", "[cfdp]") { std::string srcFileName = "hello.txt"; std::string destFileName = "hello2.txt"; MessageQueueId_t destQueueId = 2; - MessageQueueMock msgQueue(destQueueId); + MessageQueueMock msgQueue(1); LocalPool::LocalPoolConfig storeCfg = {{10, 32}, {10, 64}, {10, 128}, {10, 1024}}; StorageManagerMock ipcStore(0, storeCfg); std::array buffer{}; @@ -41,4 +42,13 @@ TEST_CASE("Reserved Message Parser", "[cfdp]") { ReservedMessageParser parser(ipcStore, msgQueue, destQueueId); CHECK(parser.parse(buffer.data(), serLen) == OK); + CommandMessage msg; + CHECK(msgQueue.wasMessageSent()); + CHECK(msgQueue.numberOfSentMessages() == 1); + CHECK(msgQueue.getNextSentMessage(destQueueId, msg) == OK); + store_address_t storeId = CfdpMessage::getStoreId(&msg); + const uint8_t* data; + size_t packetLen; + ipcStore.getData(storeId, &data, &packetLen); + CHECK(packetLen > 0); } From bb186fc965d56ce77c3255d7af3aa2224506d8a0 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 26 Jul 2023 16:58:58 +0200 Subject: [PATCH 051/101] more bugfixes --- src/fsfw/cfdp/VarLenFields.h | 15 ++++++++++++++- src/fsfw/cfdp/handler/PutRequest.cpp | 18 +++++++----------- src/fsfw/cfdp/handler/PutRequest.h | 1 - .../cfdp/handler/testReservedMsgParser.cpp | 11 ++++++++--- 4 files changed, 29 insertions(+), 16 deletions(-) diff --git a/src/fsfw/cfdp/VarLenFields.h b/src/fsfw/cfdp/VarLenFields.h index db094db6..f6dbc2b0 100644 --- a/src/fsfw/cfdp/VarLenFields.h +++ b/src/fsfw/cfdp/VarLenFields.h @@ -75,7 +75,7 @@ struct EntityId : public VarLenField { explicit EntityId(UnsignedByteField byteField) : VarLenField(byteField) {} EntityId(cfdp::WidthInBytes width, size_t entityId) : VarLenField(width, entityId) {} - ReturnValue_t serializeAsLv(uint8_t **buffer, size_t *size, size_t maxSize) { + ReturnValue_t serializeAsLv(uint8_t **buffer, size_t *size, size_t maxSize) const { if (buffer == nullptr or size == nullptr) { return returnvalue::FAILED; } @@ -87,6 +87,19 @@ struct EntityId : public VarLenField { *size += 1; return serialize(buffer, size, maxSize, SerializeIF::Endianness::NETWORK); } + + ReturnValue_t deSerializeFromLv(const uint8_t **buffer, size_t *deserLen) { + if (buffer == nullptr or deserLen == nullptr) { + return returnvalue::FAILED; + } + if (*deserLen < 2) { + return SerializeIF::STREAM_TOO_SHORT; + } + auto width = static_cast(**buffer); + *buffer += 1; + *deserLen -= 1; + return VarLenField::deSerialize(width, buffer, deserLen, SerializeIF::Endianness::NETWORK); + } }; struct TransactionSeqNum : public VarLenField { diff --git a/src/fsfw/cfdp/handler/PutRequest.cpp b/src/fsfw/cfdp/handler/PutRequest.cpp index b3afda30..4cc91a3b 100644 --- a/src/fsfw/cfdp/handler/PutRequest.cpp +++ b/src/fsfw/cfdp/handler/PutRequest.cpp @@ -6,7 +6,6 @@ cfdp::PutRequest::PutRequest(cfdp::EntityId destId, const uint8_t *msgsToUser, size_t msgsToUserTotalSize, const uint8_t *fsRequests, size_t fsRequestsSize) : destId(std::move(destId)), - destIdWidth(destId.getWidth()), metadataOnly(true), msgsToUsersTotalSize(msgsToUserTotalSize), msgsToUserStartPtr(msgsToUser), @@ -17,13 +16,13 @@ cfdp::PutRequest::PutRequest(cfdp::EntityId destId, const uint8_t *msgsToUser, ReturnValue_t cfdp::PutRequest::serialize(uint8_t **buffer, size_t *size, size_t maxSize, SerializeIF::Endianness streamEndianness) const { - if(buffer == nullptr or size == nullptr) { + if (buffer == nullptr or size == nullptr) { return FAILED; } if (*size + getSerializedSize() > maxSize) { return SerializeIF::BUFFER_TOO_SHORT; } - ReturnValue_t result = destId.serialize(buffer, size, maxSize, streamEndianness); + ReturnValue_t result = destId.serializeAsLv(buffer, size, maxSize); if (result != OK) { return result; } @@ -89,14 +88,10 @@ ReturnValue_t cfdp::PutRequest::serialize(uint8_t **buffer, size_t *size, size_t ReturnValue_t cfdp::PutRequest::deSerialize(const uint8_t **buffer, size_t *size, SerializeIF::Endianness streamEndianness) { - ReturnValue_t result = - SerializeAdapter::deSerialize(&destIdWidth, buffer, size, streamEndianness); - if (result != OK) { - return result; + if (buffer == nullptr or size == nullptr) { + return FAILED; } - - result = destId.deSerialize(static_cast(destIdWidth), buffer, size, - streamEndianness); + ReturnValue_t result = destId.deSerializeFromLv(buffer, size); if (result != OK) { return result; } @@ -155,7 +150,8 @@ ReturnValue_t cfdp::PutRequest::deSerialize(const uint8_t **buffer, size_t *size } size_t cfdp::PutRequest::getSerializedSize() const { - size_t baseSize = 1 + destId.getSerializedSize(); + // Entity ID LV (1 leading size byte) and the metadata only flag. + size_t baseSize = 1 + destId.getSerializedSize() + 1; if (!metadataOnly) { baseSize += sizeof(sourceNameSize) + sourceNameSize + sizeof(destNameSize) + destNameSize + 2; } diff --git a/src/fsfw/cfdp/handler/PutRequest.h b/src/fsfw/cfdp/handler/PutRequest.h index b842f4e2..e323c6e3 100644 --- a/src/fsfw/cfdp/handler/PutRequest.h +++ b/src/fsfw/cfdp/handler/PutRequest.h @@ -37,7 +37,6 @@ class PutRequest : public SerializeIF { [[nodiscard]] bool isMetadataOnly() const; private: - uint8_t destIdWidth = 0; uint8_t metadataOnly = true; // Transaction parameters. Omitted if the put request is metadata only. const char* destName = nullptr; diff --git a/unittests/cfdp/handler/testReservedMsgParser.cpp b/unittests/cfdp/handler/testReservedMsgParser.cpp index 0b9f5782..622ebafe 100644 --- a/unittests/cfdp/handler/testReservedMsgParser.cpp +++ b/unittests/cfdp/handler/testReservedMsgParser.cpp @@ -1,12 +1,14 @@ #include +#include "fsfw/cfdp/CfdpMessage.h" #include "fsfw/cfdp/VarLenFields.h" +#include "fsfw/cfdp/handler/PutRequest.h" #include "fsfw/cfdp/handler/ReservedMessageParser.h" #include "fsfw/cfdp/tlv/Lv.h" #include "fsfw/cfdp/tlv/ReservedMessageCreator.h" -#include "fsfw/cfdp/CfdpMessage.h" #include "fsfw/cfdp/tlv/StringLv.h" #include "fsfw/globalfunctions/arrayprinter.h" +#include "fsfw/serialize.h" #include "mocks/MessageQueueMock.h" #include "mocks/StorageManagerMock.h" @@ -41,7 +43,7 @@ TEST_CASE("Reserved Message Parser", "[cfdp]") { arrayprinter::print(buffer.data(), serLen); ReservedMessageParser parser(ipcStore, msgQueue, destQueueId); - CHECK(parser.parse(buffer.data(), serLen) == OK); + REQUIRE(parser.parse(buffer.data(), serLen) == OK); CommandMessage msg; CHECK(msgQueue.wasMessageSent()); CHECK(msgQueue.numberOfSentMessages() == 1); @@ -49,6 +51,9 @@ TEST_CASE("Reserved Message Parser", "[cfdp]") { store_address_t storeId = CfdpMessage::getStoreId(&msg); const uint8_t* data; size_t packetLen; - ipcStore.getData(storeId, &data, &packetLen); + CHECK(ipcStore.getData(storeId, &data, &packetLen) == OK); CHECK(packetLen > 0); + PutRequest putRequest; + size_t dummy = packetLen; + CHECK(putRequest.deSerialize(&data, &dummy, SerializeIF::Endianness::MACHINE) == OK); } From fde277cd06bb91c394eace935101633b889dbbde Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 26 Jul 2023 17:17:51 +0200 Subject: [PATCH 052/101] start adding dedicated put request handler --- src/fsfw/cfdp/handler/PutRequest.cpp | 38 ++++++++----------- src/fsfw/cfdp/handler/PutRequest.h | 21 +++++++--- .../cfdp/handler/ReservedMessageParser.cpp | 13 ++----- unittests/cfdp/handler/CMakeLists.txt | 2 +- unittests/cfdp/handler/testPutRequest.cpp | 3 ++ .../cfdp/handler/testReservedMsgParser.cpp | 7 +++- 6 files changed, 43 insertions(+), 41 deletions(-) create mode 100644 unittests/cfdp/handler/testPutRequest.cpp diff --git a/src/fsfw/cfdp/handler/PutRequest.cpp b/src/fsfw/cfdp/handler/PutRequest.cpp index 4cc91a3b..9cda11e3 100644 --- a/src/fsfw/cfdp/handler/PutRequest.cpp +++ b/src/fsfw/cfdp/handler/PutRequest.cpp @@ -31,20 +31,14 @@ ReturnValue_t cfdp::PutRequest::serialize(uint8_t **buffer, size_t *size, size_t return result; } if (!metadataOnly) { - result = SerializeAdapter::serialize(&sourceNameSize, buffer, size, maxSize, streamEndianness); + result = sourceName.serialize(buffer, size, maxSize, streamEndianness); if (result != OK) { return result; } - std::memcpy(*buffer, sourceName, sourceNameSize); - *buffer += sourceNameSize; - *size += sourceNameSize; - result = SerializeAdapter::serialize(&destNameSize, buffer, size, maxSize, streamEndianness); + result = destName.serialize(buffer, size, maxSize, streamEndianness); if (result != OK) { return result; } - std::memcpy(*buffer, destName, destNameSize); - *buffer += destNameSize; - *size += destNameSize; result = SerializeAdapter::serialize(&hasTransmissionMode, buffer, size, maxSize, streamEndianness); if (result != OK) { @@ -100,21 +94,11 @@ ReturnValue_t cfdp::PutRequest::deSerialize(const uint8_t **buffer, size_t *size return result; } if (!metadataOnly) { - result = SerializeAdapter::deSerialize(&sourceNameSize, buffer, size, streamEndianness); + result = sourceName.deSerialize(buffer, size, streamEndianness); if (result != OK) { return result; } - sourceName = reinterpret_cast(*buffer); - *buffer += sourceNameSize; - *size += sourceNameSize; - result = SerializeAdapter::deSerialize(&destNameSize, buffer, size, streamEndianness); - if (result != OK) { - return result; - } - destName = reinterpret_cast(*buffer); - *buffer += destNameSize; - *size += destNameSize; - result = SerializeAdapter::deSerialize(&hasTransmissionMode, buffer, size, streamEndianness); + result = destName.deSerialize(buffer, size, streamEndianness); if (result != OK) { return result; } @@ -153,7 +137,7 @@ size_t cfdp::PutRequest::getSerializedSize() const { // Entity ID LV (1 leading size byte) and the metadata only flag. size_t baseSize = 1 + destId.getSerializedSize() + 1; if (!metadataOnly) { - baseSize += sizeof(sourceNameSize) + sourceNameSize + sizeof(destNameSize) + destNameSize + 2; + baseSize += sourceName.getSerializedSize() + destName.getSerializedSize() + 2; } baseSize += sizeof(msgsToUsersTotalSize) + msgsToUsersTotalSize + sizeof(fsRequestsTotalSize) + fsRequestsTotalSize; @@ -162,6 +146,14 @@ size_t cfdp::PutRequest::getSerializedSize() const { void cfdp::PutRequest::setSourceAndDestName(cfdp::StringLv &sourceName_, cfdp::StringLv &destName_) { - this->sourceName = sourceName_.getString(sourceNameSize); - this->destName = destName_.getString(destNameSize); + this->sourceName = sourceName_; + this->destName = destName_; } + +const cfdp::StringLv &cfdp::PutRequest::getSourceName() const { return sourceName; } + +const cfdp::StringLv &cfdp::PutRequest::getDestName() const { return destName; } + +const cfdp::EntityId &cfdp::PutRequest::getDestId() const { return destId; } + +void cfdp::PutRequest::setDestId(cfdp::EntityId id) { destId = std::move(id); } diff --git a/src/fsfw/cfdp/handler/PutRequest.h b/src/fsfw/cfdp/handler/PutRequest.h index e323c6e3..a64b35d3 100644 --- a/src/fsfw/cfdp/handler/PutRequest.h +++ b/src/fsfw/cfdp/handler/PutRequest.h @@ -11,8 +11,6 @@ namespace cfdp { class PutRequest : public SerializeIF { public: - EntityId destId; - /** * Metadata only constructor. * @param destId @@ -34,15 +32,26 @@ class PutRequest : public SerializeIF { Endianness streamEndianness) override; [[nodiscard]] size_t getSerializedSize() const override; void setSourceAndDestName(cfdp::StringLv& sourceName, cfdp::StringLv& destName); + + [[nodiscard]] const cfdp::StringLv& getSourceName() const; + [[nodiscard]] const cfdp::StringLv& getDestName() const; + [[nodiscard]] bool isMetadataOnly() const; + [[nodiscard]] const EntityId& getDestId() const; + void setDestId(EntityId id); + private: + EntityId destId; uint8_t metadataOnly = true; // Transaction parameters. Omitted if the put request is metadata only. - const char* destName = nullptr; - uint64_t destNameSize = 0; - const char* sourceName = nullptr; - uint64_t sourceNameSize = 0; + cfdp::StringLv sourceName; + + cfdp::StringLv destName; + // const char* destName = nullptr; + // uint64_t destNameSize = 0; + // const char* sourceName = nullptr; + // uint64_t sourceNameSize = 0; bool hasTransmissionMode = false; uint8_t transmissionMode = TransmissionMode::UNACKNOWLEDGED; bool hasClosureRequested = false; diff --git a/src/fsfw/cfdp/handler/ReservedMessageParser.cpp b/src/fsfw/cfdp/handler/ReservedMessageParser.cpp index 4f3785f4..ab08915b 100644 --- a/src/fsfw/cfdp/handler/ReservedMessageParser.cpp +++ b/src/fsfw/cfdp/handler/ReservedMessageParser.cpp @@ -30,19 +30,12 @@ ReturnValue_t cfdp::ReservedMessageParser::parse(const uint8_t* msgsToUserPtr, uint8_t messageType = 0; if (tlv.isReservedCfdpMessage(messageType, ¤tPtr, deserSize)) { if (messageType == static_cast(ProxyOpMessageType::PUT_REQUEST)) { - cfdp::Lv entityIdLv; - result = entityIdLv.deSerialize(¤tPtr, &deserSize, SerializeIF::Endianness::NETWORK); + EntityId entityIdLv; + entityIdLv.deSerializeFromLv(¤tPtr, &deserSize); if (result != returnvalue::OK) { return result; } - size_t entityIdSize = 0; - const uint8_t* deserStart = entityIdLv.getValue(&entityIdSize); - result = putRequest.destId.deSerialize(static_cast(entityIdSize), - &deserStart, &entityIdSize, - SerializeIF::Endianness::NETWORK); - if (result != OK) { - return result; - } + putRequest.setDestId(entityIdLv); cfdp::StringLv sourceFileName; result = sourceFileName.deSerialize(¤tPtr, &deserSize, SerializeIF::Endianness::NETWORK); diff --git a/unittests/cfdp/handler/CMakeLists.txt b/unittests/cfdp/handler/CMakeLists.txt index c5da0627..6a8b25ec 100644 --- a/unittests/cfdp/handler/CMakeLists.txt +++ b/unittests/cfdp/handler/CMakeLists.txt @@ -1,4 +1,4 @@ target_sources( ${FSFW_TEST_TGT} PRIVATE testDistributor.cpp testDestHandler.cpp testReservedMsgParser.cpp - testSourceHandler.cpp testFaultHandler.cpp) + testPutRequest.cpp testSourceHandler.cpp testFaultHandler.cpp) diff --git a/unittests/cfdp/handler/testPutRequest.cpp b/unittests/cfdp/handler/testPutRequest.cpp new file mode 100644 index 00000000..501bf325 --- /dev/null +++ b/unittests/cfdp/handler/testPutRequest.cpp @@ -0,0 +1,3 @@ +#include + +TEST_CASE("Put Request", "[cfdp]") {} diff --git a/unittests/cfdp/handler/testReservedMsgParser.cpp b/unittests/cfdp/handler/testReservedMsgParser.cpp index 622ebafe..2d5b942d 100644 --- a/unittests/cfdp/handler/testReservedMsgParser.cpp +++ b/unittests/cfdp/handler/testReservedMsgParser.cpp @@ -55,5 +55,10 @@ TEST_CASE("Reserved Message Parser", "[cfdp]") { CHECK(packetLen > 0); PutRequest putRequest; size_t dummy = packetLen; - CHECK(putRequest.deSerialize(&data, &dummy, SerializeIF::Endianness::MACHINE) == OK); + REQUIRE(putRequest.deSerialize(&data, &dummy, SerializeIF::Endianness::MACHINE) == OK); + CHECK(putRequest.getDestId().getValue() == entityId.getValue()); + CHECK(putRequest.getDestId().getWidth() == entityId.getWidth()); + // size_t sourceNameSize = 0; + // const char* sourceNameStart + // CHECK(putRequest.getSourceName(sourceNameSize)); } From 291c75c01f088cc0c103269232d8761755514240 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 26 Jul 2023 17:29:35 +0200 Subject: [PATCH 053/101] test put request --- unittests/cfdp/handler/testPutRequest.cpp | 39 ++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/unittests/cfdp/handler/testPutRequest.cpp b/unittests/cfdp/handler/testPutRequest.cpp index 501bf325..9c0c0f1f 100644 --- a/unittests/cfdp/handler/testPutRequest.cpp +++ b/unittests/cfdp/handler/testPutRequest.cpp @@ -1,3 +1,40 @@ +#include #include -TEST_CASE("Put Request", "[cfdp]") {} +#include "fsfw/cfdp/handler/PutRequest.h" +#include "fsfw/cfdp/tlv/ReservedMessageCreator.h" + +TEST_CASE("Put Request", "[cfdp]") { + using namespace cfdp; + using namespace returnvalue; + + std::array reservedMsgCustomData{}; + std::array reservedMsgBuf{}; + std::array buffer{}; + EntityId destId(WidthInBytes::ONE_BYTE, 5); + std::string srcFileName = "hello.txt"; + std::string destFileName = "hello2.txt"; + uint8_t* msgBufPtr = reservedMsgCustomData.data(); + size_t msgSize = 0; + cfdp::StringLv srcName(srcFileName); + cfdp::StringLv destName(destFileName); + CHECK(destId.serializeAsLv(&msgBufPtr, &msgSize, reservedMsgCustomData.size()) == OK); + CHECK(srcName.serialize(&msgBufPtr, &msgSize, reservedMsgCustomData.size(), + SerializeIF::Endianness::NETWORK) == OK); + CHECK(destName.serialize(&msgBufPtr, &msgSize, reservedMsgCustomData.size(), + SerializeIF::Endianness::NETWORK) == OK); + ReservedMessageCreator creator(static_cast(ProxyOpMessageType::PUT_REQUEST), + reservedMsgCustomData.data(), msgSize); + msgSize = 0; + ReturnValue_t result = creator.serializeBe(buffer.data(), msgSize, buffer.size()); + CHECK(result == returnvalue::OK); + + SECTION("Put Request with reserved message") { + PutRequest putRequest(destId, reservedMsgCustomData.data(), msgSize, nullptr, 0); + uint8_t* bufPtr = buffer.data(); + size_t serLen = 0; + REQUIRE(putRequest.serialize(&bufPtr, &serLen, buffer.size(), + SerializeIF::Endianness::NETWORK) == OK); + CHECK(putRequest.getSerializedSize() == serLen); + } +} From 947f2b86855bb75308dd69bbcb748013cfdabeff Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 26 Jul 2023 17:47:27 +0200 Subject: [PATCH 054/101] add some additional API --- src/fsfw/cfdp/handler/PutRequest.cpp | 18 ++++++++++++++++++ src/fsfw/cfdp/handler/PutRequest.h | 17 +++++++++++++---- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/fsfw/cfdp/handler/PutRequest.cpp b/src/fsfw/cfdp/handler/PutRequest.cpp index 9cda11e3..e828f5e0 100644 --- a/src/fsfw/cfdp/handler/PutRequest.cpp +++ b/src/fsfw/cfdp/handler/PutRequest.cpp @@ -12,6 +12,10 @@ cfdp::PutRequest::PutRequest(cfdp::EntityId destId, const uint8_t *msgsToUser, fsRequestsTotalSize(fsRequestsSize), fsRequestStartPtr(fsRequests) {} +cfdp::PutRequest::PutRequest(cfdp::EntityId destId, cfdp::StringLv &sourceName, + cfdp::StringLv &destName) + : destId(std::move(destId)), sourceName(sourceName), destName(destName) {} + [[nodiscard]] bool cfdp::PutRequest::isMetadataOnly() const { return metadataOnly; } ReturnValue_t cfdp::PutRequest::serialize(uint8_t **buffer, size_t *size, size_t maxSize, @@ -157,3 +161,17 @@ const cfdp::StringLv &cfdp::PutRequest::getDestName() const { return destName; } const cfdp::EntityId &cfdp::PutRequest::getDestId() const { return destId; } void cfdp::PutRequest::setDestId(cfdp::EntityId id) { destId = std::move(id); } + +void cfdp::PutRequest::setTransmissionMode(cfdp::TransmissionMode transmissionMode_) { + this->transmissionMode = transmissionMode_; + hasTransmissionMode = true; +} + +void cfdp::PutRequest::clearTransmissionMode() { hasTransmissionMode = false; } + +void cfdp::PutRequest::clearClosureRequest() { hasClosureRequested = false; } + +void cfdp::PutRequest::setClosureRequest(bool closureRequested_) { + this->closureRequested = closureRequested_; + hasClosureRequested = true; +} diff --git a/src/fsfw/cfdp/handler/PutRequest.h b/src/fsfw/cfdp/handler/PutRequest.h index a64b35d3..76e4bbf2 100644 --- a/src/fsfw/cfdp/handler/PutRequest.h +++ b/src/fsfw/cfdp/handler/PutRequest.h @@ -21,6 +21,14 @@ class PutRequest : public SerializeIF { */ PutRequest(EntityId destId, const uint8_t* msgsToUser, size_t msgsToUserTotalSize, const uint8_t* fsRequests, size_t fsRequestsSize); + /** + * Put request to initiate file transfers. + * @param destId + * @param sourceName + * @param destName + */ + PutRequest(EntityId destId, cfdp::StringLv& sourceName, cfdp::StringLv& destName); + /** * Default constructor for deserialization. */ @@ -36,6 +44,11 @@ class PutRequest : public SerializeIF { [[nodiscard]] const cfdp::StringLv& getSourceName() const; [[nodiscard]] const cfdp::StringLv& getDestName() const; + void setTransmissionMode(cfdp::TransmissionMode transmissionMode); + void clearTransmissionMode(); + void setClosureRequest(bool closureRequested); + void clearClosureRequest(); + [[nodiscard]] bool isMetadataOnly() const; [[nodiscard]] const EntityId& getDestId() const; @@ -48,10 +61,6 @@ class PutRequest : public SerializeIF { cfdp::StringLv sourceName; cfdp::StringLv destName; - // const char* destName = nullptr; - // uint64_t destNameSize = 0; - // const char* sourceName = nullptr; - // uint64_t sourceNameSize = 0; bool hasTransmissionMode = false; uint8_t transmissionMode = TransmissionMode::UNACKNOWLEDGED; bool hasClosureRequested = false; From 5679b139addd617579b90b724433cae4906acfdf Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 26 Jul 2023 18:20:32 +0200 Subject: [PATCH 055/101] reserved message unittest working --- src/fsfw/cfdp/VarLenFields.cpp | 1 + src/fsfw/cfdp/handler/PutRequest.cpp | 11 ++++++++++- src/fsfw/cfdp/handler/PutRequest.h | 2 ++ unittests/cfdp/handler/testPutRequest.cpp | 22 ++++++++++++++++++++-- 4 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/fsfw/cfdp/VarLenFields.cpp b/src/fsfw/cfdp/VarLenFields.cpp index d5f4747a..ee3ee76f 100644 --- a/src/fsfw/cfdp/VarLenFields.cpp +++ b/src/fsfw/cfdp/VarLenFields.cpp @@ -117,6 +117,7 @@ ReturnValue_t cfdp::VarLenField::deSerialize(const uint8_t **buffer, size_t *siz switch (width) { case (cfdp::WidthInBytes::ONE_BYTE): { value.oneByte = **buffer; + *buffer += 1; *size += 1; return returnvalue::OK; } diff --git a/src/fsfw/cfdp/handler/PutRequest.cpp b/src/fsfw/cfdp/handler/PutRequest.cpp index e828f5e0..e0cafba1 100644 --- a/src/fsfw/cfdp/handler/PutRequest.cpp +++ b/src/fsfw/cfdp/handler/PutRequest.cpp @@ -106,6 +106,10 @@ ReturnValue_t cfdp::PutRequest::deSerialize(const uint8_t **buffer, size_t *size if (result != OK) { return result; } + result = SerializeAdapter::deSerialize(&hasTransmissionMode, buffer, size, streamEndianness); + if (result != OK) { + return result; + } result = SerializeAdapter::deSerialize(&transmissionMode, buffer, size, streamEndianness); if (result != OK) { return result; @@ -141,7 +145,7 @@ size_t cfdp::PutRequest::getSerializedSize() const { // Entity ID LV (1 leading size byte) and the metadata only flag. size_t baseSize = 1 + destId.getSerializedSize() + 1; if (!metadataOnly) { - baseSize += sourceName.getSerializedSize() + destName.getSerializedSize() + 2; + baseSize += sourceName.getSerializedSize() + destName.getSerializedSize() + 4; } baseSize += sizeof(msgsToUsersTotalSize) + msgsToUsersTotalSize + sizeof(fsRequestsTotalSize) + fsRequestsTotalSize; @@ -175,3 +179,8 @@ void cfdp::PutRequest::setClosureRequest(bool closureRequested_) { this->closureRequested = closureRequested_; hasClosureRequested = true; } + +const uint8_t *cfdp::PutRequest::getMessagesToUser(size_t &totalSize) { + totalSize = this->msgsToUsersTotalSize; + return msgsToUserStartPtr; +} diff --git a/src/fsfw/cfdp/handler/PutRequest.h b/src/fsfw/cfdp/handler/PutRequest.h index 76e4bbf2..9b7edc0a 100644 --- a/src/fsfw/cfdp/handler/PutRequest.h +++ b/src/fsfw/cfdp/handler/PutRequest.h @@ -49,6 +49,8 @@ class PutRequest : public SerializeIF { void setClosureRequest(bool closureRequested); void clearClosureRequest(); + const uint8_t* getMessagesToUser(size_t& msgSize); + [[nodiscard]] bool isMetadataOnly() const; [[nodiscard]] const EntityId& getDestId() const; diff --git a/unittests/cfdp/handler/testPutRequest.cpp b/unittests/cfdp/handler/testPutRequest.cpp index 9c0c0f1f..e49ec1dd 100644 --- a/unittests/cfdp/handler/testPutRequest.cpp +++ b/unittests/cfdp/handler/testPutRequest.cpp @@ -26,15 +26,33 @@ TEST_CASE("Put Request", "[cfdp]") { ReservedMessageCreator creator(static_cast(ProxyOpMessageType::PUT_REQUEST), reservedMsgCustomData.data(), msgSize); msgSize = 0; - ReturnValue_t result = creator.serializeBe(buffer.data(), msgSize, buffer.size()); + ReturnValue_t result = creator.serializeBe(reservedMsgBuf.data(), msgSize, buffer.size()); CHECK(result == returnvalue::OK); SECTION("Put Request with reserved message") { - PutRequest putRequest(destId, reservedMsgCustomData.data(), msgSize, nullptr, 0); + PutRequest putRequest(destId, reservedMsgBuf.data(), msgSize, nullptr, 0); uint8_t* bufPtr = buffer.data(); size_t serLen = 0; REQUIRE(putRequest.serialize(&bufPtr, &serLen, buffer.size(), SerializeIF::Endianness::NETWORK) == OK); + CHECK(putRequest.getSerializedSize() == serLen); + PutRequest requestDeserialized; + size_t deserLen = putRequest.getSerializedSize(); + const uint8_t* deserPtr = buffer.data(); + REQUIRE(requestDeserialized.deSerialize(&deserPtr, &deserLen, SerializeIF::Endianness::NETWORK) == OK); + CHECK(requestDeserialized.getDestId().getWidth() == destId.getWidth()); + CHECK(requestDeserialized.getDestId().getValue() == destId.getValue()); + size_t totalMsgsSize = 0; + const uint8_t* msgsToUserStart = requestDeserialized.getMessagesToUser(totalMsgsSize); + CHECK(totalMsgsSize == msgSize); + cfdp::Tlv genericTlv; + genericTlv.deSerialize(&msgsToUserStart, &totalMsgsSize, SerializeIF::Endianness::NETWORK); + CHECK(genericTlv.getType() == TlvType::MSG_TO_USER); + CHECK(genericTlv.getLengthField() == genericTlv.getSerializedSize() - 2); + CHECK(genericTlv.getValue()[0] == 'c'); + CHECK(genericTlv.getValue()[1] == 'f'); + CHECK(genericTlv.getValue()[2] == 'd'); + CHECK(genericTlv.getValue()[3] == 'p'); } } From 0f208ec75a5d0a0151a06614ed0b6be9e5250f3f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 27 Jul 2023 14:55:46 +0200 Subject: [PATCH 056/101] seems to work well --- src/fsfw/cfdp/handler/DestHandler.cpp | 18 +++++---- src/fsfw/cfdp/handler/DestHandler.h | 4 +- src/fsfw/cfdp/handler/PutRequest.cpp | 7 ++-- .../cfdp/handler/ReservedMessageParser.cpp | 4 +- src/fsfw/cfdp/handler/SourceHandler.cpp | 5 ++- src/fsfw/cfdp/handler/UserBase.h | 7 ++-- .../{MetadataInfo.h => MetadataGenericInfo.h} | 18 +++------ src/fsfw/cfdp/pdu/MetadataInfo.cpp | 39 +++++------------- src/fsfw/cfdp/pdu/MetadataPduCreator.cpp | 14 +++++-- src/fsfw/cfdp/pdu/MetadataPduCreator.h | 13 ++++-- src/fsfw/cfdp/pdu/MetadataPduReader.cpp | 13 ++++-- src/fsfw/cfdp/pdu/MetadataPduReader.h | 12 ++++-- src/fsfw/cfdp/tlv/Lv.cpp | 40 +++++++++++-------- src/fsfw/cfdp/tlv/Lv.h | 8 +++- unittests/cfdp/handler/testDestHandler.cpp | 6 +-- unittests/cfdp/handler/testDistributor.cpp | 5 +-- unittests/cfdp/handler/testPutRequest.cpp | 3 +- .../cfdp/handler/testReservedMsgParser.cpp | 7 ++-- unittests/cfdp/pdu/testMetadataPdu.cpp | 27 +++++++------ unittests/cfdp/testLvs.cpp | 16 +++++--- 20 files changed, 142 insertions(+), 124 deletions(-) rename src/fsfw/cfdp/pdu/{MetadataInfo.h => MetadataGenericInfo.h} (53%) diff --git a/src/fsfw/cfdp/handler/DestHandler.cpp b/src/fsfw/cfdp/handler/DestHandler.cpp index 6f1e9f40..83801df7 100644 --- a/src/fsfw/cfdp/handler/DestHandler.cpp +++ b/src/fsfw/cfdp/handler/DestHandler.cpp @@ -17,9 +17,9 @@ using namespace returnvalue; cfdp::DestHandler::DestHandler(DestHandlerParams params, FsfwParams fsfwParams) : tlvVec(params.maxTlvsInOnePdu), msgToUserVec(params.maxTlvsInOnePdu), + transactionParams(params.maxFilenameLen), destParams(std::move(params)), - fsfwParams(fsfwParams), - transactionParams(params.maxFilenameLen) { + fsfwParams(fsfwParams) { transactionParams.pduConf.direction = cfdp::Direction::TOWARDS_SENDER; } @@ -135,7 +135,7 @@ ReturnValue_t cfdp::DestHandler::handleMetadataPdu(const PacketInfo& info) { } cfdp::StringLv sourceFileName; cfdp::StringLv destFileName; - MetadataInfo metadataInfo(transactionParams.fileSize, sourceFileName, destFileName); + MetadataGenericInfo metadataInfo(transactionParams.fileSize); MetadataPduReader reader(constAccessorPair.second.data(), constAccessorPair.second.size(), metadataInfo, tlvVec.data(), tlvVec.size()); ReturnValue_t result = reader.parseData(); @@ -275,7 +275,8 @@ ReturnValue_t cfdp::DestHandler::handleMetadataParseError(ReturnValue_t result, return returnvalue::FAILED; } -ReturnValue_t cfdp::DestHandler::startTransaction(MetadataPduReader& reader, MetadataInfo& info) { +ReturnValue_t cfdp::DestHandler::startTransaction(MetadataPduReader& reader, + MetadataGenericInfo& info) { if (fsmRes.state != CfdpState::IDLE) { // According to standard, discard metadata PDU if we are busy return OK; @@ -283,7 +284,7 @@ ReturnValue_t cfdp::DestHandler::startTransaction(MetadataPduReader& reader, Met ReturnValue_t result = OK; size_t sourceNameSize = 0; - const uint8_t* sourceNamePtr = info.getSourceFileName().getValue(&sourceNameSize); + const uint8_t* sourceNamePtr = reader.getSourceFileName().getValue(&sourceNameSize); if (sourceNameSize + 1 > transactionParams.sourceName.size()) { fileErrorHandler(events::FILENAME_TOO_LARGE_ERROR, 0, "source filename too large"); return FAILED; @@ -291,7 +292,7 @@ ReturnValue_t cfdp::DestHandler::startTransaction(MetadataPduReader& reader, Met std::memcpy(transactionParams.sourceName.data(), sourceNamePtr, sourceNameSize); transactionParams.sourceName[sourceNameSize] = '\0'; size_t destNameSize = 0; - const uint8_t* destNamePtr = info.getDestFileName().getValue(&destNameSize); + const uint8_t* destNamePtr = reader.getDestFileName().getValue(&destNameSize); if (destNameSize + 1 > transactionParams.destName.size()) { fileErrorHandler(events::FILENAME_TOO_LARGE_ERROR, 0, "dest filename too large"); return FAILED; @@ -350,9 +351,10 @@ ReturnValue_t cfdp::DestHandler::startTransaction(MetadataPduReader& reader, Met transactionParams.pduConf.direction = Direction::TOWARDS_SENDER; transactionParams.transactionId.entityId = transactionParams.pduConf.sourceId; transactionParams.transactionId.seqNum = transactionParams.pduConf.seqNum; + transactionParams.fileSize = info.getFileSize(); fsmRes.step = TransactionStep::RECEIVING_FILE_DATA_PDUS; - MetadataRecvdParams params(transactionParams.transactionId, transactionParams.pduConf.sourceId); - params.fileSize = transactionParams.fileSize.getSize(); + MetadataRecvdParams params(transactionParams.transactionId, transactionParams.pduConf.sourceId, + transactionParams.fileSize); params.destFileName = transactionParams.destName.data(); params.sourceFileName = transactionParams.sourceName.data(); unsigned tlvIdx = 0; diff --git a/src/fsfw/cfdp/handler/DestHandler.h b/src/fsfw/cfdp/handler/DestHandler.h index dc98d0e0..c9436b35 100644 --- a/src/fsfw/cfdp/handler/DestHandler.h +++ b/src/fsfw/cfdp/handler/DestHandler.h @@ -148,12 +148,12 @@ class DestHandler { std::vector tlvVec; std::vector msgToUserVec; + TransactionParams transactionParams; DestHandlerParams destParams; cfdp::FsfwParams fsfwParams; - TransactionParams transactionParams; FsmResult fsmRes; - ReturnValue_t startTransaction(MetadataPduReader& reader, MetadataInfo& info); + ReturnValue_t startTransaction(MetadataPduReader& reader, MetadataGenericInfo& info); ReturnValue_t handleMetadataPdu(const PacketInfo& info); ReturnValue_t handleFileDataPdu(const PacketInfo& info); ReturnValue_t handleEofPdu(const PacketInfo& info); diff --git a/src/fsfw/cfdp/handler/PutRequest.cpp b/src/fsfw/cfdp/handler/PutRequest.cpp index e0cafba1..899cf11b 100644 --- a/src/fsfw/cfdp/handler/PutRequest.cpp +++ b/src/fsfw/cfdp/handler/PutRequest.cpp @@ -14,7 +14,7 @@ cfdp::PutRequest::PutRequest(cfdp::EntityId destId, const uint8_t *msgsToUser, cfdp::PutRequest::PutRequest(cfdp::EntityId destId, cfdp::StringLv &sourceName, cfdp::StringLv &destName) - : destId(std::move(destId)), sourceName(sourceName), destName(destName) {} + : destId(std::move(destId)), sourceName(std::move(sourceName)), destName(std::move(destName)) {} [[nodiscard]] bool cfdp::PutRequest::isMetadataOnly() const { return metadataOnly; } @@ -154,8 +154,9 @@ size_t cfdp::PutRequest::getSerializedSize() const { void cfdp::PutRequest::setSourceAndDestName(cfdp::StringLv &sourceName_, cfdp::StringLv &destName_) { - this->sourceName = sourceName_; - this->destName = destName_; + metadataOnly = false; + this->sourceName = std::move(sourceName_); + this->destName = std::move(destName_); } const cfdp::StringLv &cfdp::PutRequest::getSourceName() const { return sourceName; } diff --git a/src/fsfw/cfdp/handler/ReservedMessageParser.cpp b/src/fsfw/cfdp/handler/ReservedMessageParser.cpp index ab08915b..1165adb1 100644 --- a/src/fsfw/cfdp/handler/ReservedMessageParser.cpp +++ b/src/fsfw/cfdp/handler/ReservedMessageParser.cpp @@ -20,6 +20,8 @@ ReturnValue_t cfdp::ReservedMessageParser::parse(const uint8_t* msgsToUserPtr, const uint8_t* currentPtr = msgsToUserPtr; MessageToUserTlv tlv; size_t deserSize = sizeOfMessages; + cfdp::StringLv sourceFileName; + cfdp::StringLv destFileName; PutRequest putRequest; bool needToSendPutRequest = false; while (currentIdx < sizeOfMessages) { @@ -36,13 +38,11 @@ ReturnValue_t cfdp::ReservedMessageParser::parse(const uint8_t* msgsToUserPtr, return result; } putRequest.setDestId(entityIdLv); - cfdp::StringLv sourceFileName; result = sourceFileName.deSerialize(¤tPtr, &deserSize, SerializeIF::Endianness::NETWORK); if (result != OK) { return result; } - cfdp::StringLv destFileName; result = destFileName.deSerialize(¤tPtr, &deserSize, SerializeIF::Endianness::NETWORK); if (result != OK) { diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index b591ed23..cfe4cc23 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -188,8 +188,9 @@ ReturnValue_t cfdp::SourceHandler::putRequest(PutRequestFull& putRequest, Remote ReturnValue_t cfdp::SourceHandler::prepareAndSendMetadataPdu() { cfdp::StringLv sourceName(transactionParams.sourceName.data(), transactionParams.sourceNameSize); cfdp::StringLv destName(transactionParams.destName.data(), transactionParams.destNameSize); - auto metadataInfo = MetadataInfo(transactionParams.fileSize, sourceName, destName); - auto metadataPdu = MetadataPduCreator(transactionParams.pduConf, metadataInfo, nullptr, 0); + auto metadataInfo = MetadataGenericInfo(transactionParams.fileSize); + auto metadataPdu = + MetadataPduCreator(transactionParams.pduConf, metadataInfo, sourceName, destName, nullptr, 0); ReturnValue_t result = sendGenericPdu(metadataPdu); if (result != OK) { return result; diff --git a/src/fsfw/cfdp/handler/UserBase.h b/src/fsfw/cfdp/handler/UserBase.h index d0ddeaa5..47df48c0 100644 --- a/src/fsfw/cfdp/handler/UserBase.h +++ b/src/fsfw/cfdp/handler/UserBase.h @@ -6,6 +6,7 @@ #include #include "StatusReportIF.h" +#include "fsfw/cfdp/Fss.h" #include "fsfw/cfdp/VarLenFields.h" #include "fsfw/cfdp/tlv/FilestoreResponseTlv.h" #include "fsfw/cfdp/tlv/MessageToUserTlv.h" @@ -27,11 +28,11 @@ struct TransactionFinishedParams { }; struct MetadataRecvdParams { - MetadataRecvdParams(const TransactionId& id, const EntityId& sourceId) - : id(id), sourceId(sourceId) {} + MetadataRecvdParams(const TransactionId& id, const EntityId& sourceId, Fss fileSize) + : id(id), sourceId(sourceId), fileSize(std::move(fileSize)) {} const TransactionId& id; const EntityId& sourceId; - uint64_t fileSize = 0; + Fss fileSize{}; const char* sourceFileName = ""; const char* destFileName = ""; size_t msgsToUserLen = 0; diff --git a/src/fsfw/cfdp/pdu/MetadataInfo.h b/src/fsfw/cfdp/pdu/MetadataGenericInfo.h similarity index 53% rename from src/fsfw/cfdp/pdu/MetadataInfo.h rename to src/fsfw/cfdp/pdu/MetadataGenericInfo.h index eef1447e..e8f89266 100644 --- a/src/fsfw/cfdp/pdu/MetadataInfo.h +++ b/src/fsfw/cfdp/pdu/MetadataGenericInfo.h @@ -9,32 +9,24 @@ #include "fsfw/cfdp/tlv/StringLv.h" #include "fsfw/cfdp/tlv/Tlv.h" -class MetadataInfo { +class MetadataGenericInfo { public: - MetadataInfo(cfdp::Fss& fileSize, cfdp::StringLv& sourceFileName, cfdp::StringLv& destFileName); - MetadataInfo(bool closureRequested, cfdp::ChecksumType checksumType, cfdp::Fss& fileSize, - cfdp::StringLv& sourceFileName, cfdp::StringLv& destFileName); + explicit MetadataGenericInfo(cfdp::Fss fileSize); + MetadataGenericInfo(bool closureRequested, cfdp::ChecksumType checksumType, cfdp::Fss fileSize); - size_t getSerializedSize(bool fssLarge = false); + static size_t getSerializedSize(bool fssLarge = false); [[nodiscard]] cfdp::ChecksumType getChecksumType() const; void setChecksumType(cfdp::ChecksumType checksumType); [[nodiscard]] bool isClosureRequested() const; void setClosureRequested(bool closureRequested = false); - void setDestFileName(cfdp::StringLv& destFileName); - void setSourceFileName(cfdp::StringLv& sourceFileName); - - cfdp::StringLv& getDestFileName(); - cfdp::StringLv& getSourceFileName(); cfdp::Fss& getFileSize(); private: bool closureRequested = false; cfdp::ChecksumType checksumType = cfdp::ChecksumType::NULL_CHECKSUM; - cfdp::Fss& fileSize; - cfdp::StringLv& sourceFileName; - cfdp::StringLv& destFileName; + cfdp::Fss fileSize; }; #endif /* FSFW_SRC_FSFW_CFDP_PDU_METADATAINFO_H_ */ diff --git a/src/fsfw/cfdp/pdu/MetadataInfo.cpp b/src/fsfw/cfdp/pdu/MetadataInfo.cpp index 3ec38f41..efbe620e 100644 --- a/src/fsfw/cfdp/pdu/MetadataInfo.cpp +++ b/src/fsfw/cfdp/pdu/MetadataInfo.cpp @@ -1,50 +1,33 @@ -#include "MetadataInfo.h" +#include "MetadataGenericInfo.h" -MetadataInfo::MetadataInfo(bool closureRequested, cfdp::ChecksumType checksumType, - cfdp::Fss& fileSize, cfdp::StringLv& sourceFileName, - cfdp::StringLv& destFileName) - : MetadataInfo(fileSize, sourceFileName, destFileName) { +MetadataGenericInfo::MetadataGenericInfo(bool closureRequested, cfdp::ChecksumType checksumType, + cfdp::Fss fileSize) + : MetadataGenericInfo(std::move(fileSize)) { this->closureRequested = closureRequested; this->checksumType = checksumType; } -MetadataInfo::MetadataInfo(cfdp::Fss& fileSize, cfdp::StringLv& sourceFileName, - cfdp::StringLv& destFileName) - : fileSize(fileSize), sourceFileName(sourceFileName), destFileName(destFileName) {} +MetadataGenericInfo::MetadataGenericInfo(cfdp::Fss fileSize) : fileSize(std::move(fileSize)) {} -cfdp::ChecksumType MetadataInfo::getChecksumType() const { return checksumType; } +cfdp::ChecksumType MetadataGenericInfo::getChecksumType() const { return checksumType; } -void MetadataInfo::setChecksumType(cfdp::ChecksumType checksumType_) { +void MetadataGenericInfo::setChecksumType(cfdp::ChecksumType checksumType_) { checksumType = checksumType_; } -bool MetadataInfo::isClosureRequested() const { return closureRequested; } +bool MetadataGenericInfo::isClosureRequested() const { return closureRequested; } -void MetadataInfo::setClosureRequested(bool closureRequested_) { +void MetadataGenericInfo::setClosureRequested(bool closureRequested_) { closureRequested = closureRequested_; } -cfdp::StringLv& MetadataInfo::getDestFileName() { return destFileName; } +cfdp::Fss& MetadataGenericInfo::getFileSize() { return fileSize; } -cfdp::Fss& MetadataInfo::getFileSize() { return fileSize; } - -size_t MetadataInfo::getSerializedSize(bool fssLarge) { +size_t MetadataGenericInfo::getSerializedSize(bool fssLarge) { // 1 byte + minimal FSS 4 bytes size_t size = 5; if (fssLarge) { size += 4; } - size += sourceFileName.getSerializedSize(); - size += destFileName.getSerializedSize(); return size; } - -void MetadataInfo::setDestFileName(cfdp::StringLv& destFileName_) { - this->destFileName = destFileName_; -} - -void MetadataInfo::setSourceFileName(cfdp::StringLv& sourceFileName_) { - this->sourceFileName = sourceFileName_; -} - -cfdp::StringLv& MetadataInfo::getSourceFileName() { return sourceFileName; } diff --git a/src/fsfw/cfdp/pdu/MetadataPduCreator.cpp b/src/fsfw/cfdp/pdu/MetadataPduCreator.cpp index e31e7903..9f8633cb 100644 --- a/src/fsfw/cfdp/pdu/MetadataPduCreator.cpp +++ b/src/fsfw/cfdp/pdu/MetadataPduCreator.cpp @@ -1,16 +1,20 @@ #include "MetadataPduCreator.h" -MetadataPduCreator::MetadataPduCreator(PduConfig &conf, MetadataInfo &info, +MetadataPduCreator::MetadataPduCreator(PduConfig &conf, MetadataGenericInfo &info, + cfdp::StringLv &srcFileName, cfdp::StringLv &destFileName, cfdp::Tlv **optionsArray, size_t optionsLen) : FileDirectiveCreator(conf, cfdp::FileDirective::METADATA, 5), info(info), + srcFileName(srcFileName), + destFileName(destFileName), optionsArray(optionsArray), optionsLen(optionsLen) { updateDirectiveFieldLen(); } void MetadataPduCreator::updateDirectiveFieldLen() { - size_t dirFieldLen = info.getSerializedSize(HeaderCreator::getLargeFileFlag()); + size_t dirFieldLen = MetadataGenericInfo::getSerializedSize(HeaderCreator::getLargeFileFlag()) + + srcFileName.getSerializedSize() + destFileName.getSerializedSize(); if (optionsLen > 0 and optionsArray != nullptr) { for (size_t idx = 0; idx < optionsLen; idx++) { dirFieldLen += optionsArray[idx]->getSerializedSize(); @@ -39,11 +43,11 @@ ReturnValue_t MetadataPduCreator::serialize(uint8_t **buffer, size_t *size, size if (result != returnvalue::OK) { return result; } - result = info.getSourceFileName().serialize(buffer, size, maxSize, streamEndianness); + result = srcFileName.serialize(buffer, size, maxSize, streamEndianness); if (result != returnvalue::OK) { return result; } - result = info.getDestFileName().serialize(buffer, size, maxSize, streamEndianness); + result = destFileName.serialize(buffer, size, maxSize, streamEndianness); if (result != returnvalue::OK) { return result; } @@ -58,3 +62,5 @@ ReturnValue_t MetadataPduCreator::serialize(uint8_t **buffer, size_t *size, size } return result; } +const cfdp::StringLv &MetadataPduCreator::getSourceFileName() const { return srcFileName; } +const cfdp::StringLv &MetadataPduCreator::getDestFileName() const { return destFileName; } diff --git a/src/fsfw/cfdp/pdu/MetadataPduCreator.h b/src/fsfw/cfdp/pdu/MetadataPduCreator.h index a6f8331c..e1c931e5 100644 --- a/src/fsfw/cfdp/pdu/MetadataPduCreator.h +++ b/src/fsfw/cfdp/pdu/MetadataPduCreator.h @@ -2,23 +2,28 @@ #define FSFW_CFDP_PDU_METADATAPDUCREATOR_H_ #include "fsfw/cfdp/pdu/FileDirectiveCreator.h" -#include "fsfw/cfdp/pdu/MetadataInfo.h" +#include "fsfw/cfdp/pdu/MetadataGenericInfo.h" class MetadataPduCreator : public FileDirectiveCreator { public: - MetadataPduCreator(PduConfig& conf, MetadataInfo& info, cfdp::Tlv** optionsArray, - size_t optionsLen); + MetadataPduCreator(PduConfig& conf, MetadataGenericInfo& info, cfdp::StringLv& srcFileName, + cfdp::StringLv& destFileName, cfdp::Tlv** optionsArray, size_t optionsLen); void updateDirectiveFieldLen(); [[nodiscard]] size_t getSerializedSize() const override; + const cfdp::StringLv& getSourceFileName() const; + const cfdp::StringLv& getDestFileName() const; + ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize, Endianness streamEndianness) const override; using FileDirectiveCreator::serialize; private: - MetadataInfo& info; + MetadataGenericInfo& info; + cfdp::StringLv& srcFileName; + cfdp::StringLv& destFileName; cfdp::Tlv** optionsArray; size_t optionsLen; }; diff --git a/src/fsfw/cfdp/pdu/MetadataPduReader.cpp b/src/fsfw/cfdp/pdu/MetadataPduReader.cpp index 104ef2ae..69a7d4aa 100644 --- a/src/fsfw/cfdp/pdu/MetadataPduReader.cpp +++ b/src/fsfw/cfdp/pdu/MetadataPduReader.cpp @@ -1,7 +1,8 @@ #include "MetadataPduReader.h" -MetadataPduReader::MetadataPduReader(const uint8_t* pduBuf, size_t maxSize, MetadataInfo& info, - cfdp::Tlv* optionsArray, size_t optArrayMaxSize) +MetadataPduReader::MetadataPduReader(const uint8_t* pduBuf, size_t maxSize, + MetadataGenericInfo& info, cfdp::Tlv* optionsArray, + size_t optArrayMaxSize) : FileDirectiveReader(pduBuf, maxSize), info(info), optionArray(optionsArray), @@ -28,11 +29,11 @@ ReturnValue_t MetadataPduReader::parseData() { if (result != returnvalue::OK) { return result; } - result = info.getSourceFileName().deSerialize(&buf, &remSize, endianness); + result = srcFileName.deSerialize(&buf, &remSize, endianness); if (result != returnvalue::OK) { return result; } - result = info.getDestFileName().deSerialize(&buf, &remSize, endianness); + result = destFileName.deSerialize(&buf, &remSize, endianness); if (result != returnvalue::OK) { return result; } @@ -58,3 +59,7 @@ ReturnValue_t MetadataPduReader::parseData() { } size_t MetadataPduReader::getNumberOfParsedOptions() const { return parsedOptions; } + +const cfdp::StringLv& MetadataPduReader::getSourceFileName() const { return srcFileName; } + +const cfdp::StringLv& MetadataPduReader::getDestFileName() const { return destFileName; } diff --git a/src/fsfw/cfdp/pdu/MetadataPduReader.h b/src/fsfw/cfdp/pdu/MetadataPduReader.h index ff5f52a8..89174f2f 100644 --- a/src/fsfw/cfdp/pdu/MetadataPduReader.h +++ b/src/fsfw/cfdp/pdu/MetadataPduReader.h @@ -2,18 +2,24 @@ #define FSFW_CFDP_PDU_METADATAPDUREADER_H_ #include "fsfw/cfdp/pdu/FileDirectiveReader.h" -#include "fsfw/cfdp/pdu/MetadataInfo.h" +#include "fsfw/cfdp/pdu/MetadataGenericInfo.h" class MetadataPduReader : public FileDirectiveReader { public: - MetadataPduReader(const uint8_t* pduBuf, size_t maxSize, MetadataInfo& info, + MetadataPduReader(const uint8_t* pduBuf, size_t maxSize, MetadataGenericInfo& info, cfdp::Tlv* optionsArray, size_t optArrayMaxSize); ReturnValue_t parseData() override; + + const cfdp::StringLv& getSourceFileName() const; + const cfdp::StringLv& getDestFileName() const; + [[nodiscard]] size_t getNumberOfParsedOptions() const; private: - MetadataInfo& info; + cfdp::StringLv srcFileName; + cfdp::StringLv destFileName; + MetadataGenericInfo& info; cfdp::Tlv* optionArray; size_t optionArrayMaxSize; size_t parsedOptions = 0; diff --git a/src/fsfw/cfdp/tlv/Lv.cpp b/src/fsfw/cfdp/tlv/Lv.cpp index 215b9b3b..3bbfb5b9 100644 --- a/src/fsfw/cfdp/tlv/Lv.cpp +++ b/src/fsfw/cfdp/tlv/Lv.cpp @@ -14,23 +14,6 @@ cfdp::Lv::Lv(const std::vector& data) : value(data.data(), data.size(), cfdp::Lv::Lv() : value(static_cast(nullptr), 0, true) {} -cfdp::Lv::Lv(const Lv& other) - : value(other.value.getConstBuffer(), other.value.getSerializedSize() - 1, true) { - if (other.value.getSerializedSize() - 1 > 0) { - zeroLen = false; - } -} - -cfdp::Lv& cfdp::Lv::operator=(const Lv& other) { - size_t otherSize = 0; - auto* otherVal = const_cast(other.getValue(&otherSize)); - if (otherVal == nullptr or otherSize == 0) { - this->zeroLen = true; - } - this->value.setConstBuffer(otherVal, otherSize); - return *this; -} - ReturnValue_t cfdp::Lv::serialize(uint8_t** buffer, size_t* size, size_t maxSize, Endianness streamEndianness) const { if (maxSize < 1) { @@ -87,3 +70,26 @@ const uint8_t* cfdp::Lv::getValue(size_t* size) const { } return value.getConstBuffer(); } +cfdp::Lv::Lv(cfdp::Lv&& other) noexcept + : value(other.value.getConstBuffer(), other.value.getSerializedSize() - 1, true) { + if (other.value.getSerializedSize() - 1 > 0) { + zeroLen = false; + } + // Leave other class in intact state. + other.zeroLen = false; + other.value = SerialBufferAdapter(); +} + +cfdp::Lv& cfdp::Lv::operator=(cfdp::Lv&& other) noexcept { + size_t otherSize = 0; + this->zeroLen = false; + auto* otherVal = const_cast(other.getValue(&otherSize)); + if (otherVal == nullptr or otherSize == 0) { + this->zeroLen = true; + } + this->value.setConstBuffer(otherVal, otherSize); + // Leave other class in intact state. + other.zeroLen = false; + other.value = SerialBufferAdapter(); + return *this; +} diff --git a/src/fsfw/cfdp/tlv/Lv.h b/src/fsfw/cfdp/tlv/Lv.h index efabfdef..a17d4617 100644 --- a/src/fsfw/cfdp/tlv/Lv.h +++ b/src/fsfw/cfdp/tlv/Lv.h @@ -18,8 +18,12 @@ class Lv : public SerializeIF { Lv(const uint8_t* value, size_t size); Lv(); - Lv(const Lv&); - Lv& operator=(const Lv&); + // Semantically, this class is a zero-copy helper, so the copy ctor and copy assigment do not + // really make sense here. + Lv(const Lv&) = delete; + Lv& operator=(const Lv&) = delete; + Lv(Lv&&) noexcept; + Lv& operator=(Lv&&) noexcept; ReturnValue_t serialize(uint8_t** buffer, size_t* size, size_t maxSize, Endianness streamEndianness) const override; diff --git a/unittests/cfdp/handler/testDestHandler.cpp b/unittests/cfdp/handler/testDestHandler.cpp index 752cc4f2..2b6e4a4e 100644 --- a/unittests/cfdp/handler/testDestHandler.cpp +++ b/unittests/cfdp/handler/testDestHandler.cpp @@ -55,13 +55,13 @@ TEST_CASE("CFDP Dest Handler", "[cfdp]") { std::string destNameString = "hello-cpy.txt"; StringLv srcName(srcNameString); StringLv destName(destNameString); - MetadataInfo info(false, checksumType, cfdpFileSize, srcName, destName); + MetadataGenericInfo info(false, checksumType, std::move(cfdpFileSize)); TransactionSeqNum seqNum(UnsignedByteField(1)); conf.sourceId = remoteId; conf.destId = localId; conf.mode = TransmissionMode::UNACKNOWLEDGED; conf.seqNum = seqNum; - MetadataPduCreator metadataCreator(conf, info, nullptr, 0); + MetadataPduCreator metadataCreator(conf, info, srcName, destName, nullptr, 0); REQUIRE(tcStore.getFreeElement(&storeId, metadataCreator.getSerializedSize(), &buf) == OK); REQUIRE(metadataCreator.serialize(buf, serLen, metadataCreator.getSerializedSize()) == OK); PacketInfo packetInfo(metadataCreator.getPduType(), storeId, @@ -81,7 +81,7 @@ TEST_CASE("CFDP Dest Handler", "[cfdp]") { auto& idMetadataPair = userMock.metadataRecvd.back(); REQUIRE(idMetadataPair.first == destHandler.getTransactionId()); REQUIRE(idMetadataPair.second.sourceId.getValue() == 3); - REQUIRE(idMetadataPair.second.fileSize == fileLen); + REQUIRE(idMetadataPair.second.fileSize.getSize(nullptr) == fileLen); REQUIRE(strcmp(idMetadataPair.second.destFileName, destName) == 0); REQUIRE(strcmp(idMetadataPair.second.sourceFileName, sourceName) == 0); userMock.metadataRecvd.pop(); diff --git a/unittests/cfdp/handler/testDistributor.cpp b/unittests/cfdp/handler/testDistributor.cpp index 7d38e5c5..f6685c89 100644 --- a/unittests/cfdp/handler/testDistributor.cpp +++ b/unittests/cfdp/handler/testDistributor.cpp @@ -30,9 +30,8 @@ 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, - destFileName); - MetadataPduCreator creator(pduConf, metadataInfo, nullptr, 0); + MetadataGenericInfo metadataInfo(false, cfdp::ChecksumType::CRC_32, fileSize); + MetadataPduCreator creator(pduConf, metadataInfo, sourceFileName, destFileName, nullptr, 0); uint8_t* dataPtr = nullptr; SECTION("State") { diff --git a/unittests/cfdp/handler/testPutRequest.cpp b/unittests/cfdp/handler/testPutRequest.cpp index e49ec1dd..6dcf5ca8 100644 --- a/unittests/cfdp/handler/testPutRequest.cpp +++ b/unittests/cfdp/handler/testPutRequest.cpp @@ -40,7 +40,8 @@ TEST_CASE("Put Request", "[cfdp]") { PutRequest requestDeserialized; size_t deserLen = putRequest.getSerializedSize(); const uint8_t* deserPtr = buffer.data(); - REQUIRE(requestDeserialized.deSerialize(&deserPtr, &deserLen, SerializeIF::Endianness::NETWORK) == OK); + REQUIRE(requestDeserialized.deSerialize(&deserPtr, &deserLen, + SerializeIF::Endianness::NETWORK) == OK); CHECK(requestDeserialized.getDestId().getWidth() == destId.getWidth()); CHECK(requestDeserialized.getDestId().getValue() == destId.getValue()); size_t totalMsgsSize = 0; diff --git a/unittests/cfdp/handler/testReservedMsgParser.cpp b/unittests/cfdp/handler/testReservedMsgParser.cpp index 2d5b942d..eeb4317e 100644 --- a/unittests/cfdp/handler/testReservedMsgParser.cpp +++ b/unittests/cfdp/handler/testReservedMsgParser.cpp @@ -58,7 +58,8 @@ TEST_CASE("Reserved Message Parser", "[cfdp]") { REQUIRE(putRequest.deSerialize(&data, &dummy, SerializeIF::Endianness::MACHINE) == OK); CHECK(putRequest.getDestId().getValue() == entityId.getValue()); CHECK(putRequest.getDestId().getWidth() == entityId.getWidth()); - // size_t sourceNameSize = 0; - // const char* sourceNameStart - // CHECK(putRequest.getSourceName(sourceNameSize)); + size_t sourceNameSize = 0; + auto& sourceNameLv = putRequest.getSourceName(); + sourceNameLv.getString(sourceNameSize); + CHECK(sourceNameSize == srcFileName.size()); } diff --git a/unittests/cfdp/pdu/testMetadataPdu.cpp b/unittests/cfdp/pdu/testMetadataPdu.cpp index ba2fb4da..38b5c11e 100644 --- a/unittests/cfdp/pdu/testMetadataPdu.cpp +++ b/unittests/cfdp/pdu/testMetadataPdu.cpp @@ -22,7 +22,7 @@ TEST_CASE("Metadata PDU", "[cfdp][pdu]") { cfdp::StringLv sourceFileName(firstFileName); cfdp::StringLv destFileName; Fss fileSize(35); - MetadataInfo info(false, ChecksumType::MODULAR, fileSize, sourceFileName, destFileName); + MetadataGenericInfo info(false, ChecksumType::MODULAR, fileSize); FilestoreResponseTlv response(FilestoreActionCode::CREATE_DIRECTORY, FSR_CREATE_NOT_ALLOWED, sourceFileName, nullptr); @@ -37,13 +37,13 @@ TEST_CASE("Metadata PDU", "[cfdp][pdu]") { REQUIRE(options[1]->getSerializedSize() == 5); SECTION("Serialize") { - MetadataPduCreator serializer(pduConf, info, nullptr, 0); + MetadataPduCreator serializer(pduConf, info, sourceFileName, destFileName, nullptr, 0); result = serializer.serialize(&buffer, &sz, mdBuffer.size(), SerializeIF::Endianness::NETWORK); REQUIRE(result == returnvalue::OK); REQUIRE(serializer.getWholePduSize() == 27); - REQUIRE(info.getSourceFileName().getSerializedSize() == 10); - REQUIRE(info.getDestFileName().getSerializedSize() == 1); - REQUIRE(info.getSerializedSize() == 16); + REQUIRE(serializer.getSourceFileName().getSerializedSize() == 10); + REQUIRE(serializer.getDestFileName().getSerializedSize() == 1); + REQUIRE(info.getSerializedSize() == 5); REQUIRE((mdBuffer[1] << 8 | mdBuffer[2]) == 17); REQUIRE(mdBuffer[10] == FileDirective::METADATA); // no closure requested and checksum type is modular => 0x00 @@ -69,8 +69,8 @@ TEST_CASE("Metadata PDU", "[cfdp][pdu]") { SECTION("Serialize with 2 options") { std::string otherFileName = "hello2.txt"; cfdp::StringLv otherFileNameLv(otherFileName.data(), otherFileName.size()); - info.setSourceFileName(otherFileNameLv); - MetadataPduCreator serializer(pduConf, info, options.data(), options.size()); + MetadataPduCreator serializer(pduConf, info, otherFileNameLv, destFileName, options.data(), + options.size()); info.setChecksumType(cfdp::ChecksumType::CRC_32C); info.setClosureRequested(true); serializer.updateDirectiveFieldLen(); @@ -104,11 +104,10 @@ TEST_CASE("Metadata PDU", "[cfdp][pdu]") { result = serializer.serialize(&buffer, &sz, 46, SerializeIF::Endianness::NETWORK); REQUIRE(result == SerializeIF::BUFFER_TOO_SHORT); } - info.setDestFileName(destFileName); } SECTION("Deserialize") { - MetadataPduCreator serializer(pduConf, info, nullptr, 0); + MetadataPduCreator serializer(pduConf, info, sourceFileName, destFileName, nullptr, 0); result = serializer.serialize(&buffer, &sz, mdBuffer.size(), SerializeIF::Endianness::NETWORK); REQUIRE(result == returnvalue::OK); @@ -124,12 +123,13 @@ TEST_CASE("Metadata PDU", "[cfdp][pdu]") { } SECTION("Deserialize with 2 options") { - MetadataPduCreator serializer(pduConf, info, options.data(), options.size()); + MetadataPduCreator serializer(pduConf, info, sourceFileName, destFileName, options.data(), + options.size()); info.setChecksumType(cfdp::ChecksumType::CRC_32C); info.setClosureRequested(true); serializer.updateDirectiveFieldLen(); - info.setSourceFileName(sourceFileName); + // info.setSourceFileName(sourceFileName); result = serializer.serialize(&buffer, &sz, mdBuffer.size(), SerializeIF::Endianness::NETWORK); REQUIRE(result == returnvalue::OK); @@ -165,14 +165,15 @@ TEST_CASE("Metadata PDU", "[cfdp][pdu]") { } SECTION("Can not parse options") { - MetadataPduCreator serializer(pduConf, info, options.data(), options.size()); + MetadataPduCreator serializer(pduConf, info, sourceFileName, destFileName, options.data(), + options.size()); info.setChecksumType(cfdp::ChecksumType::CRC_32C); info.setClosureRequested(true); buffer = mdBuffer.data(); sz = 0; serializer.updateDirectiveFieldLen(); - info.setSourceFileName(sourceFileName); + // info.setSourceFileName(sourceFileName); result = serializer.serialize(&buffer, &sz, mdBuffer.size(), SerializeIF::Endianness::NETWORK); REQUIRE(result == returnvalue::OK); diff --git a/unittests/cfdp/testLvs.cpp b/unittests/cfdp/testLvs.cpp index 22094568..8415f0d8 100644 --- a/unittests/cfdp/testLvs.cpp +++ b/unittests/cfdp/testLvs.cpp @@ -23,12 +23,6 @@ TEST_CASE("CFDP LV", "[cfdp][lv]") { auto lv = cfdp::Lv(lvRawBuf.data(), 2); REQUIRE(lv.getSerializedSize() == 3); - SECTION("Copy") { - auto lvCopy = cfdp::Lv(lv); - REQUIRE(lvCopy.getSerializedSize() == 3); - REQUIRE(lv.getValue(nullptr) == lvCopy.getValue(nullptr)); - } - serPtr = rawBuf.data(); deserSize = 0; REQUIRE(lv.serialize(&serPtr, &deserSize, rawBuf.size(), SerializeIF::Endianness::NETWORK) == @@ -41,6 +35,16 @@ TEST_CASE("CFDP LV", "[cfdp][lv]") { REQUIRE(sourceIdRaw == 0x0ff0); } + SECTION("Move LV") { + std::array lvRawBuf{}; + serPtr = lvRawBuf.data(); + REQUIRE(sourceId.serialize(&serPtr, &deserSize, lvRawBuf.size(), + SerializeIF::Endianness::NETWORK) == returnvalue::OK); + auto lv = cfdp::Lv(lvRawBuf.data(), 2); + auto lvMovedCopy = cfdp::Lv(std::move(lv)); + REQUIRE(lvMovedCopy.getSerializedSize() == 3); + } + SECTION("Empty Serialization") { auto lvEmpty = Lv(); REQUIRE(lvEmpty.getSerializedSize() == 1); From f49e607881145ef06521f521e3b58c52cb3bbe7b Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 27 Jul 2023 15:07:14 +0200 Subject: [PATCH 057/101] finally it works --- unittests/cfdp/handler/testReservedMsgParser.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/unittests/cfdp/handler/testReservedMsgParser.cpp b/unittests/cfdp/handler/testReservedMsgParser.cpp index eeb4317e..eb6c1aa9 100644 --- a/unittests/cfdp/handler/testReservedMsgParser.cpp +++ b/unittests/cfdp/handler/testReservedMsgParser.cpp @@ -60,6 +60,12 @@ TEST_CASE("Reserved Message Parser", "[cfdp]") { CHECK(putRequest.getDestId().getWidth() == entityId.getWidth()); size_t sourceNameSize = 0; auto& sourceNameLv = putRequest.getSourceName(); - sourceNameLv.getString(sourceNameSize); + const char* sourceString = sourceNameLv.getString(sourceNameSize); CHECK(sourceNameSize == srcFileName.size()); + CHECK(std::strncmp(sourceString, srcFileName.c_str(), sourceNameSize) == 0); + size_t destNameSize = 0; + auto& destNameLv = putRequest.getDestName(); + const char* destString = destNameLv.getString(destNameSize); + CHECK(destNameSize == destFileName.size()); + CHECK(std::strncmp(destString, destFileName.c_str(), destNameSize) == 0); } From a856f91c67f10374708cb551232a55942149ff6d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 27 Jul 2023 17:15:01 +0200 Subject: [PATCH 058/101] nice --- src/fsfw/cfdp/handler/PutRequest.cpp | 14 ++++++++ src/fsfw/cfdp/handler/PutRequest.h | 7 +++- src/fsfw/cfdp/handler/SourceHandler.cpp | 37 +++++++++++++------- src/fsfw/cfdp/handler/SourceHandler.h | 34 ++++++++++-------- src/fsfw/cfdp/handler/defs.h | 17 +++------ src/fsfw/cfdp/tlv/Lv.cpp | 2 ++ src/fsfw/cfdp/tlv/Lv.h | 2 ++ unittests/cfdp/handler/testSourceHandler.cpp | 21 +++++++++++ 8 files changed, 92 insertions(+), 42 deletions(-) diff --git a/src/fsfw/cfdp/handler/PutRequest.cpp b/src/fsfw/cfdp/handler/PutRequest.cpp index 899cf11b..a1abcc14 100644 --- a/src/fsfw/cfdp/handler/PutRequest.cpp +++ b/src/fsfw/cfdp/handler/PutRequest.cpp @@ -185,3 +185,17 @@ const uint8_t *cfdp::PutRequest::getMessagesToUser(size_t &totalSize) { totalSize = this->msgsToUsersTotalSize; return msgsToUserStartPtr; } + +bool cfdp::PutRequest::getClosureRequested(bool &closureRequested_) const { + if (hasClosureRequested) { + closureRequested_ = this->closureRequested; + } + return hasClosureRequested; +} + +bool cfdp::PutRequest::getTransmissionMode(cfdp::TransmissionMode &mode) const { + if (hasTransmissionMode) { + mode = static_cast(this->transmissionMode); + } + return hasTransmissionMode; +} diff --git a/src/fsfw/cfdp/handler/PutRequest.h b/src/fsfw/cfdp/handler/PutRequest.h index 9b7edc0a..6bf46c60 100644 --- a/src/fsfw/cfdp/handler/PutRequest.h +++ b/src/fsfw/cfdp/handler/PutRequest.h @@ -22,7 +22,9 @@ class PutRequest : public SerializeIF { PutRequest(EntityId destId, const uint8_t* msgsToUser, size_t msgsToUserTotalSize, const uint8_t* fsRequests, size_t fsRequestsSize); /** - * Put request to initiate file transfers. + * Put request to initiate file transfers. By default, the transmission mode and closure requested + * parameter are not present, thereby being derived from the remote configuration for a + * particular destination ID. * @param destId * @param sourceName * @param destName @@ -53,6 +55,9 @@ class PutRequest : public SerializeIF { [[nodiscard]] bool isMetadataOnly() const; + bool getTransmissionMode(TransmissionMode& mode) const; + bool getClosureRequested(bool& closureRequested) const; + [[nodiscard]] const EntityId& getDestId() const; void setDestId(EntityId id); diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index cfe4cc23..e46edf6c 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -138,21 +138,23 @@ ReturnValue_t cfdp::SourceHandler::checksumGeneration() { return OK; } -ReturnValue_t cfdp::SourceHandler::putRequest(PutRequestFull& putRequest, RemoteEntityCfg& cfg) { +ReturnValue_t cfdp::SourceHandler::transactionStart(PutRequest& putRequest, RemoteEntityCfg& cfg) { if (state != CfdpState::IDLE) { return SOURCE_TRANSACTION_PENDING; } - if (putRequest.sourceNameSize > transactionParams.sourceName.size()) { - return FAILED; + if (cfg.remoteId != putRequest.getDestId()) { + return WRONG_REMOTE_CFG_ENTITY_ID; } - if (putRequest.destNameSize > transactionParams.destName.size()) { - return FAILED; + if (putRequest.getSourceName().getValueLen() == 0) { + return SOURCE_NAME_EMPTY; } - std::memcpy(transactionParams.destName.data(), putRequest.destName, putRequest.destNameSize); - std::memcpy(transactionParams.sourceName.data(), putRequest.sourceName, - putRequest.sourceNameSize); - transactionParams.sourceNameSize = putRequest.sourceNameSize; - transactionParams.destNameSize = putRequest.destNameSize; + if (putRequest.getDestName().getValueLen() == 0) { + return DEST_NAME_EMPTY; + } + const char* srcNamePtr = putRequest.getSourceName().getString(transactionParams.sourceNameSize); + const char* destNamePtr = putRequest.getDestName().getString(transactionParams.destNameSize); + std::strncpy(transactionParams.sourceName.data(), srcNamePtr, transactionParams.sourceNameSize); + std::strncpy(transactionParams.destName.data(), destNamePtr, transactionParams.destNameSize); FilesystemParams params(transactionParams.sourceName.data()); if (!sourceParams.user.vfs.fileExists(params)) { return FILE_DOES_NOT_EXIST; @@ -160,9 +162,15 @@ ReturnValue_t cfdp::SourceHandler::putRequest(PutRequestFull& putRequest, Remote if (cfg.maxFileSegmentLen > fileBuf.size() or cfg.maxFileSegmentLen == 0) { return FILE_SEGMENT_LEN_INVALID; } - transactionParams.closureRequested = putRequest.closureRequested; - transactionParams.pduConf.mode = putRequest.transmissionMode; - transactionParams.pduConf.destId = putRequest.destId; + // If transmission mode is not set, use default transmission mode for the remote entity. + if (not putRequest.getTransmissionMode(transactionParams.pduConf.mode)) { + transactionParams.pduConf.mode = cfg.defaultTransmissionMode; + } + // If closure request field is not set, use default option for the remote entity. + if (not putRequest.getClosureRequested(transactionParams.closureRequested)) { + transactionParams.closureRequested = cfg.closureRequested; + } + transactionParams.pduConf.destId = putRequest.getDestId(); // Only used for PDU forwarding, file is sent to file receiver regularly here. transactionParams.pduConf.direction = Direction::TOWARDS_RECEIVER; transactionParams.pduConf.sourceId = sourceParams.cfg.localId; @@ -304,3 +312,6 @@ ReturnValue_t cfdp::SourceHandler::reset() { transactionParams.reset(); return OK; } +cfdp::CfdpState cfdp::SourceHandler::getState() const { return state; } + +cfdp::SourceHandler::TransactionStep cfdp::SourceHandler::getStep() const { return step; } diff --git a/src/fsfw/cfdp/handler/SourceHandler.h b/src/fsfw/cfdp/handler/SourceHandler.h index 31fafcb2..acac6dfd 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.h +++ b/src/fsfw/cfdp/handler/SourceHandler.h @@ -7,6 +7,7 @@ #include "UserBase.h" #include "defs.h" #include "fsfw/cfdp/Fss.h" +#include "fsfw/cfdp/handler/PutRequest.h" #include "fsfw/cfdp/handler/mib.h" #include "fsfw/events/EventReportingProxyIF.h" #include "fsfw/storagemanager/StorageManagerIF.h" @@ -26,6 +27,17 @@ struct SourceHandlerParams { class SourceHandler { public: + enum class TransactionStep : uint8_t { + IDLE = 0, + TRANSACTION_START = 1, + CRC_PROCEDURE = 2, + SENDING_METADATA = 3, + SENDING_FILE_DATA = 4, + SENDING_EOF = 5, + WAIT_FOR_ACK = 6, + WAIT_FOR_FINISH = 7, + NOTICE_OF_COMPLETION = 8 + }; struct FsmResult { public: ReturnValue_t result = returnvalue::OK; @@ -38,33 +50,25 @@ class SourceHandler { SourceHandler(SourceHandlerParams params, FsfwParams fsfwParams); + [[nodiscard]] CfdpState getState() const; + [[nodiscard]] TransactionStep getStep() const; + /** * Pass a put request to the source handler, which might initiate a CFDP transaction and start * the state machine * @return */ - ReturnValue_t putRequest(PutRequestFull& putRequest, RemoteEntityCfg& cfg); + ReturnValue_t transactionStart(PutRequest& putRequest, RemoteEntityCfg& cfg); FsmResult& stateMachine(); ReturnValue_t initialize(); private: - enum class TransactionStep : uint8_t { - IDLE = 0, - TRANSACTION_START = 1, - CRC_PROCEDURE = 2, - SENDING_METADATA = 3, - SENDING_FILE_DATA = 4, - SENDING_EOF = 5, - WAIT_FOR_ACK = 6, - WAIT_FOR_FINISH = 7, - NOTICE_OF_COMPLETION = 8 - }; struct TransactionParams { uint32_t crc{}; - std::array sourceName{}; + std::array sourceName{}; size_t sourceNameSize = 0; - std::array destName{}; + std::array destName{}; size_t destNameSize = 0; cfdp::Fss fileSize; size_t progress = 0; @@ -72,7 +76,7 @@ class SourceHandler { RemoteEntityCfg remoteCfg; PduConfig pduConf; cfdp::TransactionId id{}; - cfdp::WidthInBytes seqCountWidth; + cfdp::WidthInBytes seqCountWidth{}; void reset() { sourceNameSize = 0; diff --git a/src/fsfw/cfdp/handler/defs.h b/src/fsfw/cfdp/handler/defs.h index 97ef009c..c1a3fbfd 100644 --- a/src/fsfw/cfdp/handler/defs.h +++ b/src/fsfw/cfdp/handler/defs.h @@ -48,18 +48,6 @@ template using PacketInfoList = etl::list; using PacketInfoListBase = etl::ilist; -struct PutRequestFull { - public: - EntityId destId; - TransmissionMode transmissionMode = TransmissionMode::UNACKNOWLEDGED; - char destName[524]{}; - size_t destNameSize = 0; - char sourceName[524]{}; - size_t sourceNameSize = 0; - bool closureRequested = true; - // MessageToUserTlv -}; - enum class CallStatus { DONE, CALL_AFTER_DELAY, CALL_AGAIN }; namespace events { @@ -75,7 +63,10 @@ static constexpr Event FILENAME_TOO_LARGE_ERROR = event::makeEvent(SSID, 4, seve static constexpr ReturnValue_t SOURCE_TRANSACTION_PENDING = returnvalue::makeCode(CID, 0); static constexpr ReturnValue_t FILE_DOES_NOT_EXIST = returnvalue::makeCode(CID, 1); -static constexpr ReturnValue_t FILE_SEGMENT_LEN_INVALID = returnvalue::makeCode(CID, 1); +static constexpr ReturnValue_t FILE_SEGMENT_LEN_INVALID = returnvalue::makeCode(CID, 2); +static constexpr ReturnValue_t SOURCE_NAME_EMPTY = returnvalue::makeCode(CID, 3); +static constexpr ReturnValue_t DEST_NAME_EMPTY = returnvalue::makeCode(CID, 4); +static constexpr ReturnValue_t WRONG_REMOTE_CFG_ENTITY_ID = returnvalue::makeCode(CID, 5); } // namespace cfdp #endif // FSFW_CFDP_HANDLER_DEFS_H diff --git a/src/fsfw/cfdp/tlv/Lv.cpp b/src/fsfw/cfdp/tlv/Lv.cpp index 3bbfb5b9..0daec472 100644 --- a/src/fsfw/cfdp/tlv/Lv.cpp +++ b/src/fsfw/cfdp/tlv/Lv.cpp @@ -93,3 +93,5 @@ cfdp::Lv& cfdp::Lv::operator=(cfdp::Lv&& other) noexcept { other.value = SerialBufferAdapter(); return *this; } + +size_t cfdp::Lv::getValueLen() const { return getSerializedSize() - 1; } diff --git a/src/fsfw/cfdp/tlv/Lv.h b/src/fsfw/cfdp/tlv/Lv.h index a17d4617..c1ab78de 100644 --- a/src/fsfw/cfdp/tlv/Lv.h +++ b/src/fsfw/cfdp/tlv/Lv.h @@ -40,6 +40,8 @@ class Lv : public SerializeIF { ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, Endianness streamEndianness) override; + size_t getValueLen() const; + /** * Get value field and its size. * @param size Optionally retrieve size. Size will be the size of the actual value field diff --git a/unittests/cfdp/handler/testSourceHandler.cpp b/unittests/cfdp/handler/testSourceHandler.cpp index 29b12f99..879e5ca2 100644 --- a/unittests/cfdp/handler/testSourceHandler.cpp +++ b/unittests/cfdp/handler/testSourceHandler.cpp @@ -1,6 +1,8 @@ #include +#include #include "fsfw/cfdp.h" +#include "fsfw/cfdp/handler/PutRequest.h" #include "fsfw/cfdp/handler/SourceHandler.h" #include "fsfw/cfdp/pdu/EofPduCreator.h" #include "fsfw/cfdp/pdu/FileDataCreator.h" @@ -18,6 +20,7 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { using namespace cfdp; using namespace returnvalue; + using namespace std::filesystem; MessageQueueId_t destQueueId = 2; AcceptsTmMock tmReceiver(destQueueId); MessageQueueMock mqMock(destQueueId); @@ -36,4 +39,22 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { StorageManagerMock tmStore(3, storeCfg); FsfwParams fp(tmReceiver, &mqMock, &eventReporterMock); auto sourceHandler = SourceHandler(dp, fp); + + SECTION("Test Basic") { + CHECK(sourceHandler.getState() == CfdpState::IDLE); + CHECK(sourceHandler.getStep() == SourceHandler::TransactionStep::IDLE); + } + + SECTION("Transfer empty file") { + RemoteEntityCfg cfg; + EntityId id(cfdp::WidthInBytes::ONE_BYTE, 5); + cfg.remoteId = id; + FilesystemParams srcFileName("/tmp/cfdp-test.txt"); + fsMock.createFile(srcFileName); + cfdp::StringLv srcNameLv(srcFileName.path, std::strlen(srcFileName.path)); + FilesystemParams destFileName("/tmp/cfdp-test.txt"); + cfdp::StringLv destNameLv(destFileName.path, std::strlen(destFileName.path)); + PutRequest putRequest(id, srcNameLv, destNameLv); + CHECK(sourceHandler.transactionStart(putRequest, cfg) == OK); + } } \ No newline at end of file From 3167988951c2cb333b813d3e982a1feb75323a9f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 3 Aug 2023 13:03:58 +0200 Subject: [PATCH 059/101] continue source handler --- src/fsfw/cfdp/handler/SourceHandler.cpp | 2 ++ unittests/action/TestActionHelper.cpp | 6 +++--- unittests/cfdp/handler/testSourceHandler.cpp | 14 ++++++++++++++ unittests/datapoollocal/testLocalPoolManager.cpp | 6 +++--- unittests/mocks/AcceptsTmMock.h | 4 ++-- unittests/mocks/MessageQueueMock.cpp | 2 +- unittests/mocks/MessageQueueMock.h | 2 +- unittests/mocks/StorageManagerMock.h | 1 + unittests/tmtcservices/testSendHelper.cpp | 2 +- unittests/tmtcservices/testStoreAndSendHelper.cpp | 2 +- 10 files changed, 29 insertions(+), 12 deletions(-) diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index e46edf6c..bbfc6475 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -40,6 +40,7 @@ cfdp::SourceHandler::SourceHandler(SourceHandlerParams params, FsfwParams fsfwPa cfdp::SourceHandler::FsmResult& cfdp::SourceHandler::fsmNacked() { ReturnValue_t result; if (step == TransactionStep::IDLE) { + fsmResult.packetsSent = 0; step = TransactionStep::TRANSACTION_START; } if (step == TransactionStep::TRANSACTION_START) { @@ -203,6 +204,7 @@ ReturnValue_t cfdp::SourceHandler::prepareAndSendMetadataPdu() { if (result != OK) { return result; } + fsmResult.packetsSent += 1; // Advance FSM if everything works step = TransactionStep::SENDING_FILE_DATA; return OK; diff --git a/unittests/action/TestActionHelper.cpp b/unittests/action/TestActionHelper.cpp index de021bb8..3b22dcee 100644 --- a/unittests/action/TestActionHelper.cpp +++ b/unittests/action/TestActionHelper.cpp @@ -57,7 +57,7 @@ TEST_CASE("Action Helper", "[action]") { step += 1; CHECK(testMqMock.wasMessageSent()); CommandMessage testMessage; - REQUIRE(testMqMock.getNextSentMessage(testMessage) == returnvalue::OK); + REQUIRE(testMqMock.getNextSentMessageToDefaultDest(testMessage) == returnvalue::OK); REQUIRE(testMessage.getCommand() == static_cast(ActionMessage::STEP_FAILED)); REQUIRE(testMessage.getParameter() == static_cast(testActionId)); uint32_t parameter2 = ((uint32_t)step << 16) | (uint32_t)status; @@ -71,7 +71,7 @@ TEST_CASE("Action Helper", "[action]") { actionHelper.finish(false, testMqMock.getId(), testActionId, status); CHECK(testMqMock.wasMessageSent()); CommandMessage testMessage; - REQUIRE(testMqMock.getNextSentMessage(testMessage) == returnvalue::OK); + REQUIRE(testMqMock.getNextSentMessageToDefaultDest(testMessage) == returnvalue::OK); REQUIRE(testMessage.getCommand() == static_cast(ActionMessage::COMPLETION_FAILED)); REQUIRE(ActionMessage::getActionId(&testMessage) == testActionId); REQUIRE(ActionMessage::getReturnCode(&testMessage) == static_cast(status)); @@ -87,7 +87,7 @@ TEST_CASE("Action Helper", "[action]") { REQUIRE(ipcStore->getData(toLongParamAddress).first == static_cast(StorageManagerIF::DATA_DOES_NOT_EXIST)); CommandMessage testMessage; - REQUIRE(testMqMock.getNextSentMessage(testMessage) == returnvalue::OK); + REQUIRE(testMqMock.getNextSentMessageToDefaultDest(testMessage) == returnvalue::OK); REQUIRE(testMessage.getCommand() == static_cast(ActionMessage::STEP_FAILED)); REQUIRE(ActionMessage::getReturnCode(&testMessage) == 0xAFFE); REQUIRE(ActionMessage::getStep(&testMessage) == 0); diff --git a/unittests/cfdp/handler/testSourceHandler.cpp b/unittests/cfdp/handler/testSourceHandler.cpp index 879e5ca2..ab5dbf80 100644 --- a/unittests/cfdp/handler/testSourceHandler.cpp +++ b/unittests/cfdp/handler/testSourceHandler.cpp @@ -2,11 +2,13 @@ #include #include "fsfw/cfdp.h" +#include "fsfw/cfdp/CfdpMessage.h" #include "fsfw/cfdp/handler/PutRequest.h" #include "fsfw/cfdp/handler/SourceHandler.h" #include "fsfw/cfdp/pdu/EofPduCreator.h" #include "fsfw/cfdp/pdu/FileDataCreator.h" #include "fsfw/cfdp/pdu/MetadataPduCreator.h" +#include "fsfw/storagemanager/StorageManagerIF.h" #include "fsfw/util/SeqCountProvider.h" #include "mocks/AcceptsTmMock.h" #include "mocks/EventReportingProxyMock.h" @@ -38,7 +40,10 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { StorageManagerMock tcStore(2, storeCfg); StorageManagerMock tmStore(3, storeCfg); FsfwParams fp(tmReceiver, &mqMock, &eventReporterMock); + fp.tcStore = &tcStore; + fp.tmStore = &tmStore; auto sourceHandler = SourceHandler(dp, fp); + CHECK(sourceHandler.initialize() == OK); SECTION("Test Basic") { CHECK(sourceHandler.getState() == CfdpState::IDLE); @@ -46,6 +51,7 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { } SECTION("Transfer empty file") { + // using StorageManagerIF::getData; RemoteEntityCfg cfg; EntityId id(cfdp::WidthInBytes::ONE_BYTE, 5); cfg.remoteId = id; @@ -56,5 +62,13 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { cfdp::StringLv destNameLv(destFileName.path, std::strlen(destFileName.path)); PutRequest putRequest(id, srcNameLv, destNameLv); CHECK(sourceHandler.transactionStart(putRequest, cfg) == OK); + SourceHandler::FsmResult& fsmResult = sourceHandler.stateMachine(); + CHECK(fsmResult.packetsSent == 1); + CHECK(mqMock.numberOfSentMessages() == 1); + CommandMessage msg; + CHECK(mqMock.getNextSentMessage(destQueueId, msg) == OK); + store_address_t storeId = CfdpMessage::getStoreId(&msg); + auto accessor = tmStore.getData(storeId); + // CHECK(fsmResult.) } } \ No newline at end of file diff --git a/unittests/datapoollocal/testLocalPoolManager.cpp b/unittests/datapoollocal/testLocalPoolManager.cpp index e463a123..1913474e 100644 --- a/unittests/datapoollocal/testLocalPoolManager.cpp +++ b/unittests/datapoollocal/testLocalPoolManager.cpp @@ -82,7 +82,7 @@ TEST_CASE("Local Pool Manager Tests", "[LocManTest]") { REQUIRE(poolOwnerMock.getNextSentMessage(subscriberId, messageSent) == returnvalue::OK); CHECK(messageSent.getCommand() == static_cast(HousekeepingMessage::UPDATE_NOTIFICATION_SET)); - REQUIRE(poolOwnerMock.getNextSentMessage(messageSent) == returnvalue::OK); + REQUIRE(poolOwnerMock.getNextSentMessageToDefaultDest(messageSent) == returnvalue::OK); CHECK(messageSent.getCommand() == static_cast(HousekeepingMessage::HK_REPORT)); /* Clear message to avoid memory leak, our mock won't do it for us (yet) */ CommandMessageCleaner::clearCommandMessage(&messageSent); @@ -259,11 +259,11 @@ TEST_CASE("Local Pool Manager Tests", "[LocManTest]") { CHECK(messageSent.getCommand() == static_cast(HousekeepingMessage::UPDATE_NOTIFICATION_SET)); REQUIRE(poolOwnerMock.clearLastSentMessage(subscriberId) == returnvalue::OK); - REQUIRE(poolOwnerMock.getNextSentMessage(messageSent) == returnvalue::OK); + REQUIRE(poolOwnerMock.getNextSentMessageToDefaultDest(messageSent) == returnvalue::OK); CHECK(messageSent.getCommand() == static_cast(HousekeepingMessage::HK_REPORT)); REQUIRE(poolOwnerMock.clearLastSentMessage() == returnvalue::OK); REQUIRE(poolOwnerMock.getNextSentMessage(subscriberId, messageSent) == MessageQueueIF::EMPTY); - REQUIRE(poolOwnerMock.getNextSentMessage(messageSent) == MessageQueueIF::EMPTY); + REQUIRE(poolOwnerMock.getNextSentMessageToDefaultDest(messageSent) == MessageQueueIF::EMPTY); } SECTION("PeriodicHKAndMessaging") { diff --git a/unittests/mocks/AcceptsTmMock.h b/unittests/mocks/AcceptsTmMock.h index b12e1094..c736c952 100644 --- a/unittests/mocks/AcceptsTmMock.h +++ b/unittests/mocks/AcceptsTmMock.h @@ -9,8 +9,8 @@ class AcceptsTmMock : public SystemObject, public AcceptsTelemetryIF { AcceptsTmMock(object_id_t registeredId, MessageQueueId_t queueToReturn); explicit AcceptsTmMock(MessageQueueId_t queueToReturn); - MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel) const override; - const char* getName() const override; + [[nodiscard]] MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel) const override; + [[nodiscard]] const char* getName() const override; MessageQueueId_t returnedQueue; }; diff --git a/unittests/mocks/MessageQueueMock.cpp b/unittests/mocks/MessageQueueMock.cpp index cac5a0d9..96a6ee86 100644 --- a/unittests/mocks/MessageQueueMock.cpp +++ b/unittests/mocks/MessageQueueMock.cpp @@ -124,7 +124,7 @@ ReturnValue_t MessageQueueMock::getNextSentMessage(MessageQueueId_t id, return returnvalue::OK; } -ReturnValue_t MessageQueueMock::getNextSentMessage(MessageQueueMessageIF& message) { +ReturnValue_t MessageQueueMock::getNextSentMessageToDefaultDest(MessageQueueMessageIF& message) { return getNextSentMessage(MessageQueueBase::getDefaultDestination(), message); } diff --git a/unittests/mocks/MessageQueueMock.h b/unittests/mocks/MessageQueueMock.h index 52ba5dfe..cacb72e4 100644 --- a/unittests/mocks/MessageQueueMock.h +++ b/unittests/mocks/MessageQueueMock.h @@ -26,7 +26,7 @@ class MessageQueueMock : public MessageQueueBase { explicit MessageQueueMock(MessageQueueId_t queueId); //! Get next message which was sent to the default destination - ReturnValue_t getNextSentMessage(MessageQueueMessageIF& message); + ReturnValue_t getNextSentMessageToDefaultDest(MessageQueueMessageIF& message); //! Get message which was sent to a specific ID ReturnValue_t getNextSentMessage(MessageQueueId_t id, MessageQueueMessageIF& message); [[nodiscard]] bool wasMessageSent() const; diff --git a/unittests/mocks/StorageManagerMock.h b/unittests/mocks/StorageManagerMock.h index a0a59a47..ce5f3811 100644 --- a/unittests/mocks/StorageManagerMock.h +++ b/unittests/mocks/StorageManagerMock.h @@ -32,6 +32,7 @@ class StorageManagerMock : public LocalPool { std::pair nextFreeElementCallFails; using LocalPool::getFreeElement; + using StorageManagerIF::getData; void reset(); }; diff --git a/unittests/tmtcservices/testSendHelper.cpp b/unittests/tmtcservices/testSendHelper.cpp index 43816835..07315e44 100644 --- a/unittests/tmtcservices/testSendHelper.cpp +++ b/unittests/tmtcservices/testSendHelper.cpp @@ -71,7 +71,7 @@ TEST_CASE("TM Send Helper", "[tm-send-helper]") { REQUIRE(msgQueue.wasMessageSent()); REQUIRE(msgQueue.numberOfSentMessagesToDefault() == 1); TmTcMessage msg; - REQUIRE(msgQueue.getNextSentMessage(msg) == returnvalue::OK); + REQUIRE(msgQueue.getNextSentMessageToDefaultDest(msg) == returnvalue::OK); REQUIRE(msg.getStorageId() == storeId); REQUIRE(pool.hasDataAtId(msg.getStorageId())); } diff --git a/unittests/tmtcservices/testStoreAndSendHelper.cpp b/unittests/tmtcservices/testStoreAndSendHelper.cpp index 46418dfe..6fe9f8e2 100644 --- a/unittests/tmtcservices/testStoreAndSendHelper.cpp +++ b/unittests/tmtcservices/testStoreAndSendHelper.cpp @@ -52,7 +52,7 @@ TEST_CASE("TM Store And Send Helper", "[tm-store-send-helper]") { REQUIRE(msgQueue.wasMessageSent()); REQUIRE(msgQueue.numberOfSentMessagesToDefault() == 1); TmTcMessage msg; - REQUIRE(msgQueue.getNextSentMessage(msg) == returnvalue::OK); + REQUIRE(msgQueue.getNextSentMessageToDefaultDest(msg) == returnvalue::OK); REQUIRE(msg.getStorageId() == storeId); REQUIRE(pool.hasDataAtId(msg.getStorageId())); storeHelper.deletePacket(); From c075f27e200b86d231b4d5ba80e791753e41c06f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 3 Aug 2023 13:57:55 +0200 Subject: [PATCH 060/101] start verifying metadata PDU --- src/fsfw/cfdp/handler/SourceHandler.cpp | 6 +++--- src/fsfw/cfdp/pdu/MetadataGenericInfo.h | 1 + unittests/cfdp/handler/testSourceHandler.cpp | 14 ++++++++++++-- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index bbfc6475..05c17617 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -284,7 +284,7 @@ ReturnValue_t cfdp::SourceHandler::sendGenericPdu(const SerializeIF& pdu) const uint8_t* dataPtr; store_address_t storeId; ReturnValue_t result = - fsfwParams.tcStore->getFreeElement(&storeId, pdu.getSerializedSize(), &dataPtr); + fsfwParams.tmStore->getFreeElement(&storeId, pdu.getSerializedSize(), &dataPtr); if (result != OK) { // TODO: Better error handling? return result; @@ -294,8 +294,8 @@ ReturnValue_t cfdp::SourceHandler::sendGenericPdu(const SerializeIF& pdu) const if (result != OK) { return result; } - TmTcMessage tcMsg(storeId); - return fsfwParams.msgQueue->sendMessage(fsfwParams.packetDest.getReportReceptionQueue(), &tcMsg); + TmTcMessage tmMsg(storeId); + return fsfwParams.msgQueue->sendMessage(fsfwParams.packetDest.getReportReceptionQueue(), &tmMsg); } ReturnValue_t cfdp::SourceHandler::noticeOfCompletion() { diff --git a/src/fsfw/cfdp/pdu/MetadataGenericInfo.h b/src/fsfw/cfdp/pdu/MetadataGenericInfo.h index e8f89266..59caabb3 100644 --- a/src/fsfw/cfdp/pdu/MetadataGenericInfo.h +++ b/src/fsfw/cfdp/pdu/MetadataGenericInfo.h @@ -11,6 +11,7 @@ class MetadataGenericInfo { public: + MetadataGenericInfo() = default; explicit MetadataGenericInfo(cfdp::Fss fileSize); MetadataGenericInfo(bool closureRequested, cfdp::ChecksumType checksumType, cfdp::Fss fileSize); diff --git a/unittests/cfdp/handler/testSourceHandler.cpp b/unittests/cfdp/handler/testSourceHandler.cpp index ab5dbf80..0055dc54 100644 --- a/unittests/cfdp/handler/testSourceHandler.cpp +++ b/unittests/cfdp/handler/testSourceHandler.cpp @@ -8,6 +8,7 @@ #include "fsfw/cfdp/pdu/EofPduCreator.h" #include "fsfw/cfdp/pdu/FileDataCreator.h" #include "fsfw/cfdp/pdu/MetadataPduCreator.h" +#include "fsfw/cfdp/pdu/MetadataPduReader.h" #include "fsfw/storagemanager/StorageManagerIF.h" #include "fsfw/util/SeqCountProvider.h" #include "mocks/AcceptsTmMock.h" @@ -66,9 +67,18 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { CHECK(fsmResult.packetsSent == 1); CHECK(mqMock.numberOfSentMessages() == 1); CommandMessage msg; - CHECK(mqMock.getNextSentMessage(destQueueId, msg) == OK); + REQUIRE(mqMock.getNextSentMessage(destQueueId, msg) == OK); store_address_t storeId = CfdpMessage::getStoreId(&msg); auto accessor = tmStore.getData(storeId); - // CHECK(fsmResult.) + REQUIRE(accessor.first == OK); + const uint8_t* pduPtr = accessor.second.data(); + MetadataGenericInfo metadataInfo; + MetadataPduReader metadataReader(pduPtr, accessor.second.size(), metadataInfo, nullptr, 0); + size_t srcFileSize = 0; + REQUIRE(metadataReader.parseData() == OK); + const char* srcNameRead = metadataReader.getSourceFileName().getString(srcFileSize); + REQUIRE(srcNameRead != nullptr); + std::string srcNameReadStr(srcNameRead, srcFileSize); + CHECK(std::string(srcFileName.path) == srcNameReadStr); } } \ No newline at end of file From 0cccf260210aff7db9a4aa0c4dee386203be96be Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 3 Aug 2023 14:34:21 +0200 Subject: [PATCH 061/101] should not be problematic but somehow is.. --- src/fsfw/cfdp/handler/SourceHandler.cpp | 2 + unittests/cfdp/handler/testSourceHandler.cpp | 10 ++-- unittests/cfdp/pdu/testMetadataPdu.cpp | 50 ++++++++++++++++---- 3 files changed, 49 insertions(+), 13 deletions(-) diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index 05c17617..4365b824 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -8,6 +8,7 @@ #include "fsfw/cfdp/pdu/FileDataCreator.h" #include "fsfw/cfdp/pdu/MetadataPduCreator.h" #include "fsfw/filesystem/HasFileSystemIF.h" +#include "fsfw/globalfunctions/arrayprinter.h" #include "fsfw/objectmanager.h" #include "fsfw/serviceinterface.h" #include "fsfw/tmtcservices/TmTcMessage.h" @@ -294,6 +295,7 @@ ReturnValue_t cfdp::SourceHandler::sendGenericPdu(const SerializeIF& pdu) const if (result != OK) { return result; } + arrayprinter::print(dataPtr, serializedLen); TmTcMessage tmMsg(storeId); return fsfwParams.msgQueue->sendMessage(fsfwParams.packetDest.getReportReceptionQueue(), &tmMsg); } diff --git a/unittests/cfdp/handler/testSourceHandler.cpp b/unittests/cfdp/handler/testSourceHandler.cpp index 0055dc54..e0c3a7a7 100644 --- a/unittests/cfdp/handler/testSourceHandler.cpp +++ b/unittests/cfdp/handler/testSourceHandler.cpp @@ -9,7 +9,9 @@ #include "fsfw/cfdp/pdu/FileDataCreator.h" #include "fsfw/cfdp/pdu/MetadataPduCreator.h" #include "fsfw/cfdp/pdu/MetadataPduReader.h" +#include "fsfw/globalfunctions/arrayprinter.h" #include "fsfw/storagemanager/StorageManagerIF.h" +#include "fsfw/tmtcservices/TmTcMessage.h" #include "fsfw/util/SeqCountProvider.h" #include "mocks/AcceptsTmMock.h" #include "mocks/EventReportingProxyMock.h" @@ -66,15 +68,15 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { SourceHandler::FsmResult& fsmResult = sourceHandler.stateMachine(); CHECK(fsmResult.packetsSent == 1); CHECK(mqMock.numberOfSentMessages() == 1); - CommandMessage msg; - REQUIRE(mqMock.getNextSentMessage(destQueueId, msg) == OK); - store_address_t storeId = CfdpMessage::getStoreId(&msg); - auto accessor = tmStore.getData(storeId); + TmTcMessage tmtcMessage; + REQUIRE(mqMock.getNextSentMessage(destQueueId, tmtcMessage) == OK); + auto accessor = tmStore.getData(tmtcMessage.getStorageId()); REQUIRE(accessor.first == OK); const uint8_t* pduPtr = accessor.second.data(); MetadataGenericInfo metadataInfo; MetadataPduReader metadataReader(pduPtr, accessor.second.size(), metadataInfo, nullptr, 0); size_t srcFileSize = 0; + arrayprinter::print(pduPtr, accessor.second.size()); REQUIRE(metadataReader.parseData() == OK); const char* srcNameRead = metadataReader.getSourceFileName().getString(srcFileSize); REQUIRE(srcNameRead != nullptr); diff --git a/unittests/cfdp/pdu/testMetadataPdu.cpp b/unittests/cfdp/pdu/testMetadataPdu.cpp index 38b5c11e..fbf3da08 100644 --- a/unittests/cfdp/pdu/testMetadataPdu.cpp +++ b/unittests/cfdp/pdu/testMetadataPdu.cpp @@ -36,15 +36,7 @@ TEST_CASE("Metadata PDU", "[cfdp][pdu]") { REQUIRE(options[0]->getSerializedSize() == 2 + 1 + 10 + 1); REQUIRE(options[1]->getSerializedSize() == 5); - SECTION("Serialize") { - MetadataPduCreator serializer(pduConf, info, sourceFileName, destFileName, nullptr, 0); - result = serializer.serialize(&buffer, &sz, mdBuffer.size(), SerializeIF::Endianness::NETWORK); - REQUIRE(result == returnvalue::OK); - REQUIRE(serializer.getWholePduSize() == 27); - REQUIRE(serializer.getSourceFileName().getSerializedSize() == 10); - REQUIRE(serializer.getDestFileName().getSerializedSize() == 1); - REQUIRE(info.getSerializedSize() == 5); - REQUIRE((mdBuffer[1] << 8 | mdBuffer[2]) == 17); + auto metadataCheckPartOne = [&]() { REQUIRE(mdBuffer[10] == FileDirective::METADATA); // no closure requested and checksum type is modular => 0x00 REQUIRE(mdBuffer[11] == 0x00); @@ -63,9 +55,49 @@ TEST_CASE("Metadata PDU", "[cfdp][pdu]") { REQUIRE(mdBuffer[23] == 't'); REQUIRE(mdBuffer[24] == 'x'); REQUIRE(mdBuffer[25] == 't'); + }; + SECTION("Serialize with empty dest name") { + MetadataPduCreator serializer(pduConf, info, sourceFileName, destFileName, nullptr, 0); + result = serializer.serialize(&buffer, &sz, mdBuffer.size(), SerializeIF::Endianness::NETWORK); + REQUIRE(result == returnvalue::OK); + // 10 byte heater + 1 byte PDU directive field + 1 byte PDU content + FSS field (4) + source + // name field (10) + dest name field (1). + REQUIRE(serializer.getWholePduSize() == 27); + REQUIRE(serializer.getSourceFileName().getSerializedSize() == 10); + REQUIRE(serializer.getDestFileName().getSerializedSize() == 1); + REQUIRE(info.getSerializedSize() == 5); + REQUIRE((mdBuffer[1] << 8 | mdBuffer[2]) == 17); + REQUIRE(serializer.getSerializedSize() == serializer.getWholePduSize()); + metadataCheckPartOne(); REQUIRE(mdBuffer[26] == 0); } + SECTION("Serialize with dest name") { + std::string secondFileName = "hello2.txt"; + cfdp::StringLv destFileName2(secondFileName); + MetadataPduCreator serializer(pduConf, info, sourceFileName, destFileName2, nullptr, 0); + result = serializer.serialize(&buffer, &sz, mdBuffer.size(), SerializeIF::Endianness::NETWORK); + REQUIRE(result == returnvalue::OK); + // 10 byte heater + 1 byte PDU directive field + 1 byte PDU content + FSS field (4) + source + // name field (10) + dest name field (11). + REQUIRE(serializer.getWholePduSize() == 37); + REQUIRE((mdBuffer[1] << 8 | mdBuffer[2]) == 27); + REQUIRE(serializer.getSerializedSize() == serializer.getWholePduSize()); + metadataCheckPartOne(); + // Size of destination name field + REQUIRE(mdBuffer[26] == 10); + REQUIRE(mdBuffer[27] == 'h'); + REQUIRE(mdBuffer[28] == 'e'); + REQUIRE(mdBuffer[29] == 'l'); + REQUIRE(mdBuffer[30] == 'l'); + REQUIRE(mdBuffer[31] == 'o'); + REQUIRE(mdBuffer[32] == '2'); + REQUIRE(mdBuffer[33] == '.'); + REQUIRE(mdBuffer[34] == 't'); + REQUIRE(mdBuffer[35] == 'x'); + REQUIRE(mdBuffer[36] == 't'); + } + SECTION("Serialize with 2 options") { std::string otherFileName = "hello2.txt"; cfdp::StringLv otherFileNameLv(otherFileName.data(), otherFileName.size()); From daf75547a45be74eb27b1456d76ac00704af98e9 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 3 Aug 2023 15:13:26 +0200 Subject: [PATCH 062/101] insidious bug --- src/fsfw/cfdp/VarLenFields.cpp | 2 ++ src/fsfw/cfdp/VarLenFields.h | 1 + src/fsfw/cfdp/handler/SourceHandler.cpp | 18 ++++++++++++------ src/fsfw/cfdp/handler/SourceHandler.h | 2 +- unittests/cfdp/handler/testSourceHandler.cpp | 3 ++- unittests/cfdp/pdu/testMetadataPdu.cpp | 4 +++- 6 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/fsfw/cfdp/VarLenFields.cpp b/src/fsfw/cfdp/VarLenFields.cpp index ee3ee76f..d0582467 100644 --- a/src/fsfw/cfdp/VarLenFields.cpp +++ b/src/fsfw/cfdp/VarLenFields.cpp @@ -153,3 +153,5 @@ bool cfdp::VarLenField::operator==(const cfdp::VarLenField &other) const { bool cfdp::VarLenField::operator!=(const cfdp::VarLenField &other) const { return not(*this == other); } + +void cfdp::VarLenField::setWidth(cfdp::WidthInBytes width_) { this->width = width_; } diff --git a/src/fsfw/cfdp/VarLenFields.h b/src/fsfw/cfdp/VarLenFields.h index f6dbc2b0..3143a857 100644 --- a/src/fsfw/cfdp/VarLenFields.h +++ b/src/fsfw/cfdp/VarLenFields.h @@ -32,6 +32,7 @@ class VarLenField : public SerializeIF { bool operator<(const VarLenField &other) const; ReturnValue_t setValueAndWidth(cfdp::WidthInBytes width, uint64_t value); + void setWidth(cfdp::WidthInBytes width); ReturnValue_t setValue(uint64_t value); ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize, diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index 4365b824..0b92fb74 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -19,12 +19,15 @@ cfdp::SourceHandler::SourceHandler(SourceHandlerParams params, FsfwParams fsfwPa : sourceParams(std::move(params)), fsfwParams(fsfwParams) { // The entity ID portion of the transaction ID will always remain fixed. transactionParams.id.entityId = sourceParams.cfg.localId; + transactionParams.pduConf.sourceId = sourceParams.cfg.localId; if (sourceParams.seqCountProvider.bitWidth() == 8) { - transactionParams.seqCountWidth = cfdp::WidthInBytes::ONE_BYTE; + transactionParams.pduConf.seqNum.setWidth(cfdp::WidthInBytes::ONE_BYTE); } else if (sourceParams.seqCountProvider.bitWidth() == 16) { - transactionParams.seqCountWidth = cfdp::WidthInBytes::TWO_BYTES; + transactionParams.pduConf.seqNum.setWidth(cfdp::WidthInBytes::TWO_BYTES); } else if (sourceParams.seqCountProvider.bitWidth() == 32) { - transactionParams.seqCountWidth = cfdp::WidthInBytes::FOUR_BYTES; + transactionParams.pduConf.seqNum.setWidth(cfdp::WidthInBytes::FOUR_BYTES); + } else if (sourceParams.seqCountProvider.bitWidth() == 64) { + transactionParams.pduConf.seqNum.setWidth(cfdp::WidthInBytes::EIGHT_BYTES); } else { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::error << "cfdp::SourceHandler: Seq count provider bit width " @@ -34,7 +37,7 @@ cfdp::SourceHandler::SourceHandler(SourceHandlerParams params, FsfwParams fsfwPa sourceParams.seqCountProvider.bitWidth()); #endif // Yeah, what am I supposed to do here? Can't throw an exception in the FSFW.. - transactionParams.seqCountWidth = cfdp::WidthInBytes::ONE_BYTE; + transactionParams.pduConf.seqNum.setWidth(cfdp::WidthInBytes::ONE_BYTE); } } @@ -172,10 +175,13 @@ ReturnValue_t cfdp::SourceHandler::transactionStart(PutRequest& putRequest, Remo if (not putRequest.getClosureRequested(transactionParams.closureRequested)) { transactionParams.closureRequested = cfg.closureRequested; } - transactionParams.pduConf.destId = putRequest.getDestId(); + const EntityId& destId = putRequest.getDestId(); + transactionParams.pduConf.destId = destId; + // Adapt source ID width to necessary width. The width of the source and destination ID must be + // the same. + transactionParams.pduConf.sourceId.setWidth(destId.getWidth()); // Only used for PDU forwarding, file is sent to file receiver regularly here. transactionParams.pduConf.direction = Direction::TOWARDS_RECEIVER; - transactionParams.pduConf.sourceId = sourceParams.cfg.localId; transactionParams.id.seqNum.setValue(sourceParams.seqCountProvider.getAndIncrement()); if (transactionParams.pduConf.mode == TransmissionMode::ACKNOWLEDGED) { diff --git a/src/fsfw/cfdp/handler/SourceHandler.h b/src/fsfw/cfdp/handler/SourceHandler.h index acac6dfd..ea7d95a4 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.h +++ b/src/fsfw/cfdp/handler/SourceHandler.h @@ -76,7 +76,7 @@ class SourceHandler { RemoteEntityCfg remoteCfg; PduConfig pduConf; cfdp::TransactionId id{}; - cfdp::WidthInBytes seqCountWidth{}; + // cfdp::WidthInBytes seqCountWidth{}; void reset() { sourceNameSize = 0; diff --git a/unittests/cfdp/handler/testSourceHandler.cpp b/unittests/cfdp/handler/testSourceHandler.cpp index e0c3a7a7..1ab5cadc 100644 --- a/unittests/cfdp/handler/testSourceHandler.cpp +++ b/unittests/cfdp/handler/testSourceHandler.cpp @@ -61,7 +61,7 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { FilesystemParams srcFileName("/tmp/cfdp-test.txt"); fsMock.createFile(srcFileName); cfdp::StringLv srcNameLv(srcFileName.path, std::strlen(srcFileName.path)); - FilesystemParams destFileName("/tmp/cfdp-test.txt"); + FilesystemParams destFileName("/tmp/cfdp-test2.txt"); cfdp::StringLv destNameLv(destFileName.path, std::strlen(destFileName.path)); PutRequest putRequest(id, srcNameLv, destNameLv); CHECK(sourceHandler.transactionStart(putRequest, cfg) == OK); @@ -73,6 +73,7 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { auto accessor = tmStore.getData(tmtcMessage.getStorageId()); REQUIRE(accessor.first == OK); const uint8_t* pduPtr = accessor.second.data(); + CHECK(accessor.second.size() == 55); MetadataGenericInfo metadataInfo; MetadataPduReader metadataReader(pduPtr, accessor.second.size(), metadataInfo, nullptr, 0); size_t srcFileSize = 0; diff --git a/unittests/cfdp/pdu/testMetadataPdu.cpp b/unittests/cfdp/pdu/testMetadataPdu.cpp index fbf3da08..e13b4717 100644 --- a/unittests/cfdp/pdu/testMetadataPdu.cpp +++ b/unittests/cfdp/pdu/testMetadataPdu.cpp @@ -56,10 +56,12 @@ TEST_CASE("Metadata PDU", "[cfdp][pdu]") { REQUIRE(mdBuffer[24] == 'x'); REQUIRE(mdBuffer[25] == 't'); }; + SECTION("Serialize with empty dest name") { MetadataPduCreator serializer(pduConf, info, sourceFileName, destFileName, nullptr, 0); result = serializer.serialize(&buffer, &sz, mdBuffer.size(), SerializeIF::Endianness::NETWORK); REQUIRE(result == returnvalue::OK); + CHECK(sz == serializer.getSerializedSize()); // 10 byte heater + 1 byte PDU directive field + 1 byte PDU content + FSS field (4) + source // name field (10) + dest name field (1). REQUIRE(serializer.getWholePduSize() == 27); @@ -81,6 +83,7 @@ TEST_CASE("Metadata PDU", "[cfdp][pdu]") { // 10 byte heater + 1 byte PDU directive field + 1 byte PDU content + FSS field (4) + source // name field (10) + dest name field (11). REQUIRE(serializer.getWholePduSize() == 37); + CHECK(sz == serializer.getSerializedSize()); REQUIRE((mdBuffer[1] << 8 | mdBuffer[2]) == 27); REQUIRE(serializer.getSerializedSize() == serializer.getWholePduSize()); metadataCheckPartOne(); @@ -161,7 +164,6 @@ TEST_CASE("Metadata PDU", "[cfdp][pdu]") { info.setClosureRequested(true); serializer.updateDirectiveFieldLen(); - // info.setSourceFileName(sourceFileName); result = serializer.serialize(&buffer, &sz, mdBuffer.size(), SerializeIF::Endianness::NETWORK); REQUIRE(result == returnvalue::OK); From dffce43e6b662f098e964e66f2026111c6bd2477 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 3 Aug 2023 15:30:38 +0200 Subject: [PATCH 063/101] metadata PDU seems to be correct --- src/fsfw/cfdp/handler/SourceHandler.cpp | 18 +++++++---- src/fsfw/cfdp/handler/SourceHandler.h | 1 - src/fsfw/cfdp/pdu/MetadataPduReader.h | 4 +-- src/fsfw/cfdp/tlv/StringLv.cpp | 7 +++- src/fsfw/cfdp/tlv/StringLv.h | 3 +- .../cfdp/handler/testReservedMsgParser.cpp | 12 +++---- unittests/cfdp/handler/testSourceHandler.cpp | 32 +++++++++++-------- 7 files changed, 44 insertions(+), 33 deletions(-) diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index 0b92fb74..e31903ae 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -156,8 +156,8 @@ ReturnValue_t cfdp::SourceHandler::transactionStart(PutRequest& putRequest, Remo if (putRequest.getDestName().getValueLen() == 0) { return DEST_NAME_EMPTY; } - const char* srcNamePtr = putRequest.getSourceName().getString(transactionParams.sourceNameSize); - const char* destNamePtr = putRequest.getDestName().getString(transactionParams.destNameSize); + const char* srcNamePtr = putRequest.getSourceName().getCString(transactionParams.sourceNameSize); + const char* destNamePtr = putRequest.getDestName().getCString(transactionParams.destNameSize); std::strncpy(transactionParams.sourceName.data(), srcNamePtr, transactionParams.sourceNameSize); std::strncpy(transactionParams.destName.data(), destNamePtr, transactionParams.destNameSize); FilesystemParams params(transactionParams.sourceName.data()); @@ -176,10 +176,15 @@ ReturnValue_t cfdp::SourceHandler::transactionStart(PutRequest& putRequest, Remo transactionParams.closureRequested = cfg.closureRequested; } const EntityId& destId = putRequest.getDestId(); - transactionParams.pduConf.destId = destId; - // Adapt source ID width to necessary width. The width of the source and destination ID must be - // the same. - transactionParams.pduConf.sourceId.setWidth(destId.getWidth()); + // The width of the source and destination ID must be the same. Use the larger ID value to + // ensure the width is large enough for both IDs + if (destId.getWidth() > transactionParams.pduConf.sourceId.getWidth()) { + transactionParams.pduConf.destId = destId; + transactionParams.pduConf.sourceId.setWidth(destId.getWidth()); + } else { + transactionParams.pduConf.destId.setValueAndWidth(transactionParams.pduConf.sourceId.getWidth(), + destId.getValue()); + } // Only used for PDU forwarding, file is sent to file receiver regularly here. transactionParams.pduConf.direction = Direction::TOWARDS_RECEIVER; transactionParams.id.seqNum.setValue(sourceParams.seqCountProvider.getAndIncrement()); @@ -301,7 +306,6 @@ ReturnValue_t cfdp::SourceHandler::sendGenericPdu(const SerializeIF& pdu) const if (result != OK) { return result; } - arrayprinter::print(dataPtr, serializedLen); TmTcMessage tmMsg(storeId); return fsfwParams.msgQueue->sendMessage(fsfwParams.packetDest.getReportReceptionQueue(), &tmMsg); } diff --git a/src/fsfw/cfdp/handler/SourceHandler.h b/src/fsfw/cfdp/handler/SourceHandler.h index ea7d95a4..c31ebc26 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.h +++ b/src/fsfw/cfdp/handler/SourceHandler.h @@ -76,7 +76,6 @@ class SourceHandler { RemoteEntityCfg remoteCfg; PduConfig pduConf; cfdp::TransactionId id{}; - // cfdp::WidthInBytes seqCountWidth{}; void reset() { sourceNameSize = 0; diff --git a/src/fsfw/cfdp/pdu/MetadataPduReader.h b/src/fsfw/cfdp/pdu/MetadataPduReader.h index 89174f2f..e619d4f5 100644 --- a/src/fsfw/cfdp/pdu/MetadataPduReader.h +++ b/src/fsfw/cfdp/pdu/MetadataPduReader.h @@ -11,8 +11,8 @@ class MetadataPduReader : public FileDirectiveReader { ReturnValue_t parseData() override; - const cfdp::StringLv& getSourceFileName() const; - const cfdp::StringLv& getDestFileName() const; + [[nodiscard]] const cfdp::StringLv& getSourceFileName() const; + [[nodiscard]] const cfdp::StringLv& getDestFileName() const; [[nodiscard]] size_t getNumberOfParsedOptions() const; diff --git a/src/fsfw/cfdp/tlv/StringLv.cpp b/src/fsfw/cfdp/tlv/StringLv.cpp index 551a23a9..ce290460 100644 --- a/src/fsfw/cfdp/tlv/StringLv.cpp +++ b/src/fsfw/cfdp/tlv/StringLv.cpp @@ -8,6 +8,11 @@ cfdp::StringLv::StringLv(const char* filename, size_t len) cfdp::StringLv::StringLv() : Lv() {} -const char* cfdp::StringLv::getString(size_t& fileSize) const { +const char* cfdp::StringLv::getCString(size_t& fileSize) const { return reinterpret_cast(getValue(&fileSize)); } + +std::string cfdp::StringLv::getString() const { + size_t fileSize; + return {getCString(fileSize), fileSize}; +} diff --git a/src/fsfw/cfdp/tlv/StringLv.h b/src/fsfw/cfdp/tlv/StringLv.h index c837c976..3a1dba36 100644 --- a/src/fsfw/cfdp/tlv/StringLv.h +++ b/src/fsfw/cfdp/tlv/StringLv.h @@ -13,7 +13,8 @@ class StringLv : public Lv { explicit StringLv(const std::string& fileName); explicit StringLv(const char* filename, size_t len); - const char* getString(size_t& fileSize) const; + const char* getCString(size_t& fileSize) const; + std::string getString() const; // Delete the move constructor to avoid passing in a temporary StringLv(const std::string&&) = delete; }; diff --git a/unittests/cfdp/handler/testReservedMsgParser.cpp b/unittests/cfdp/handler/testReservedMsgParser.cpp index eb6c1aa9..3379f563 100644 --- a/unittests/cfdp/handler/testReservedMsgParser.cpp +++ b/unittests/cfdp/handler/testReservedMsgParser.cpp @@ -58,14 +58,10 @@ TEST_CASE("Reserved Message Parser", "[cfdp]") { REQUIRE(putRequest.deSerialize(&data, &dummy, SerializeIF::Endianness::MACHINE) == OK); CHECK(putRequest.getDestId().getValue() == entityId.getValue()); CHECK(putRequest.getDestId().getWidth() == entityId.getWidth()); - size_t sourceNameSize = 0; auto& sourceNameLv = putRequest.getSourceName(); - const char* sourceString = sourceNameLv.getString(sourceNameSize); - CHECK(sourceNameSize == srcFileName.size()); - CHECK(std::strncmp(sourceString, srcFileName.c_str(), sourceNameSize) == 0); - size_t destNameSize = 0; + std::string srcNameRead = sourceNameLv.getString(); + CHECK(srcNameRead == srcFileName); auto& destNameLv = putRequest.getDestName(); - const char* destString = destNameLv.getString(destNameSize); - CHECK(destNameSize == destFileName.size()); - CHECK(std::strncmp(destString, destFileName.c_str(), destNameSize) == 0); + std::string destNameRead = destNameLv.getString(); + CHECK(destNameRead == destFileName); } diff --git a/unittests/cfdp/handler/testSourceHandler.cpp b/unittests/cfdp/handler/testSourceHandler.cpp index 1ab5cadc..ec93f2bf 100644 --- a/unittests/cfdp/handler/testSourceHandler.cpp +++ b/unittests/cfdp/handler/testSourceHandler.cpp @@ -54,18 +54,21 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { } SECTION("Transfer empty file") { - // using StorageManagerIF::getData; RemoteEntityCfg cfg; - EntityId id(cfdp::WidthInBytes::ONE_BYTE, 5); + EntityId id(cfdp::WidthInBytes::TWO_BYTES, 5); cfg.remoteId = id; - FilesystemParams srcFileName("/tmp/cfdp-test.txt"); - fsMock.createFile(srcFileName); - cfdp::StringLv srcNameLv(srcFileName.path, std::strlen(srcFileName.path)); - FilesystemParams destFileName("/tmp/cfdp-test2.txt"); - cfdp::StringLv destNameLv(destFileName.path, std::strlen(destFileName.path)); + std::string srcFileName = "/tmp/cfdp-test.txt"; + std::string destFileName = "/tmp/cfdp-test2.txt"; + FilesystemParams srcFileNameFs(srcFileName.c_str()); + fsMock.createFile(srcFileNameFs); + cfdp::StringLv srcNameLv(srcFileNameFs.path, std::strlen(srcFileNameFs.path)); + FilesystemParams destFileNameFs(destFileName.c_str()); + cfdp::StringLv destNameLv(destFileNameFs.path, std::strlen(destFileNameFs.path)); PutRequest putRequest(id, srcNameLv, destNameLv); CHECK(sourceHandler.transactionStart(putRequest, cfg) == OK); SourceHandler::FsmResult& fsmResult = sourceHandler.stateMachine(); + + // Verify metadata PDU was sent. CHECK(fsmResult.packetsSent == 1); CHECK(mqMock.numberOfSentMessages() == 1); TmTcMessage tmtcMessage; @@ -76,12 +79,15 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { CHECK(accessor.second.size() == 55); MetadataGenericInfo metadataInfo; MetadataPduReader metadataReader(pduPtr, accessor.second.size(), metadataInfo, nullptr, 0); - size_t srcFileSize = 0; - arrayprinter::print(pduPtr, accessor.second.size()); REQUIRE(metadataReader.parseData() == OK); - const char* srcNameRead = metadataReader.getSourceFileName().getString(srcFileSize); - REQUIRE(srcNameRead != nullptr); - std::string srcNameReadStr(srcNameRead, srcFileSize); - CHECK(std::string(srcFileName.path) == srcNameReadStr); + std::string srcNameRead = metadataReader.getSourceFileName().getString(); + CHECK(srcNameRead == srcFileName); + std::string destNameRead = metadataReader.getDestFileName().getString(); + CHECK(destNameRead == destFileName); + CHECK(metadataInfo.getChecksumType() == ChecksumType::NULL_CHECKSUM); + CHECK(metadataInfo.getFileSize().value() == 0); + CHECK(!metadataInfo.isClosureRequested()); + + // Verify EOF PDU was sent. No file data PDU is sent for an empty file. } } \ No newline at end of file From 12e52a92f2570a56ffae1714e56b9f0872011b5b Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 3 Aug 2023 15:49:23 +0200 Subject: [PATCH 064/101] empty file transfer test done --- src/fsfw/cfdp/handler/SourceHandler.cpp | 23 ++++--- src/fsfw/cfdp/handler/SourceHandler.h | 4 +- unittests/cfdp/handler/testSourceHandler.cpp | 65 +++++++++++++------- 3 files changed, 61 insertions(+), 31 deletions(-) diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index e31903ae..3ce1b898 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -44,7 +44,6 @@ cfdp::SourceHandler::SourceHandler(SourceHandlerParams params, FsfwParams fsfwPa cfdp::SourceHandler::FsmResult& cfdp::SourceHandler::fsmNacked() { ReturnValue_t result; if (step == TransactionStep::IDLE) { - fsmResult.packetsSent = 0; step = TransactionStep::TRANSACTION_START; } if (step == TransactionStep::TRANSACTION_START) { @@ -66,11 +65,14 @@ cfdp::SourceHandler::FsmResult& cfdp::SourceHandler::fsmNacked() { return fsmResult; } if (step == TransactionStep::SENDING_FILE_DATA) { - result = prepareAndSendNextFileDataPdu(); + bool noFdPdu = false; + result = prepareAndSendNextFileDataPdu(noFdPdu); if (result != OK) { // TODO: Error handling } - return fsmResult; + if (!noFdPdu) { + return fsmResult; + } } if (step == TransactionStep::SENDING_EOF) { result = prepareAndSendEofPdu(); @@ -99,6 +101,7 @@ cfdp::SourceHandler::FsmResult& cfdp::SourceHandler::fsmNacked() { } cfdp::SourceHandler::FsmResult& cfdp::SourceHandler::stateMachine() { + fsmResult.packetsSent = 0; if (state == cfdp::CfdpState::IDLE) { return fsmResult; } @@ -216,19 +219,20 @@ ReturnValue_t cfdp::SourceHandler::prepareAndSendMetadataPdu() { if (result != OK) { return result; } - fsmResult.packetsSent += 1; // Advance FSM if everything works step = TransactionStep::SENDING_FILE_DATA; return OK; } -ReturnValue_t cfdp::SourceHandler::prepareAndSendNextFileDataPdu() { +ReturnValue_t cfdp::SourceHandler::prepareAndSendNextFileDataPdu(bool& noFileDataPdu) { cfdp::Fss offset(transactionParams.progress); uint64_t readLen; uint64_t fileSize = transactionParams.fileSize.value(); + noFileDataPdu = false; if (fileSize == 0) { // We are done, no need to send file data PDUs for an empty file. step = TransactionStep::SENDING_EOF; + noFileDataPdu = true; return OK; } if (fileSize < transactionParams.remoteCfg.maxFileSegmentLen) { @@ -292,7 +296,7 @@ ReturnValue_t cfdp::SourceHandler::initialize() { return OK; } -ReturnValue_t cfdp::SourceHandler::sendGenericPdu(const SerializeIF& pdu) const { +ReturnValue_t cfdp::SourceHandler::sendGenericPdu(const SerializeIF& pdu) { uint8_t* dataPtr; store_address_t storeId; ReturnValue_t result = @@ -307,7 +311,12 @@ ReturnValue_t cfdp::SourceHandler::sendGenericPdu(const SerializeIF& pdu) const return result; } TmTcMessage tmMsg(storeId); - return fsfwParams.msgQueue->sendMessage(fsfwParams.packetDest.getReportReceptionQueue(), &tmMsg); + result = + fsfwParams.msgQueue->sendMessage(fsfwParams.packetDest.getReportReceptionQueue(), &tmMsg); + if (result == OK) { + fsmResult.packetsSent += 1; + } + return result; } ReturnValue_t cfdp::SourceHandler::noticeOfCompletion() { diff --git a/src/fsfw/cfdp/handler/SourceHandler.h b/src/fsfw/cfdp/handler/SourceHandler.h index c31ebc26..afbbdf1f 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.h +++ b/src/fsfw/cfdp/handler/SourceHandler.h @@ -96,12 +96,12 @@ class SourceHandler { FsmResult& fsmNacked(); ReturnValue_t checksumGeneration(); ReturnValue_t prepareAndSendMetadataPdu(); - ReturnValue_t prepareAndSendNextFileDataPdu(); + ReturnValue_t prepareAndSendNextFileDataPdu(bool& noFileDataPdu); ReturnValue_t prepareAndSendEofPdu(); ReturnValue_t noticeOfCompletion(); ReturnValue_t reset(); - [[nodiscard]] ReturnValue_t sendGenericPdu(const SerializeIF& pdu) const; + [[nodiscard]] ReturnValue_t sendGenericPdu(const SerializeIF& pdu); }; } // namespace cfdp diff --git a/unittests/cfdp/handler/testSourceHandler.cpp b/unittests/cfdp/handler/testSourceHandler.cpp index ec93f2bf..a46eae44 100644 --- a/unittests/cfdp/handler/testSourceHandler.cpp +++ b/unittests/cfdp/handler/testSourceHandler.cpp @@ -2,15 +2,12 @@ #include #include "fsfw/cfdp.h" -#include "fsfw/cfdp/CfdpMessage.h" #include "fsfw/cfdp/handler/PutRequest.h" #include "fsfw/cfdp/handler/SourceHandler.h" #include "fsfw/cfdp/pdu/EofPduCreator.h" -#include "fsfw/cfdp/pdu/FileDataCreator.h" +#include "fsfw/cfdp/pdu/EofPduReader.h" #include "fsfw/cfdp/pdu/MetadataPduCreator.h" #include "fsfw/cfdp/pdu/MetadataPduReader.h" -#include "fsfw/globalfunctions/arrayprinter.h" -#include "fsfw/storagemanager/StorageManagerIF.h" #include "fsfw/tmtcservices/TmTcMessage.h" #include "fsfw/util/SeqCountProvider.h" #include "mocks/AcceptsTmMock.h" @@ -68,26 +65,50 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { CHECK(sourceHandler.transactionStart(putRequest, cfg) == OK); SourceHandler::FsmResult& fsmResult = sourceHandler.stateMachine(); - // Verify metadata PDU was sent. - CHECK(fsmResult.packetsSent == 1); - CHECK(mqMock.numberOfSentMessages() == 1); TmTcMessage tmtcMessage; - REQUIRE(mqMock.getNextSentMessage(destQueueId, tmtcMessage) == OK); - auto accessor = tmStore.getData(tmtcMessage.getStorageId()); - REQUIRE(accessor.first == OK); - const uint8_t* pduPtr = accessor.second.data(); - CHECK(accessor.second.size() == 55); - MetadataGenericInfo metadataInfo; - MetadataPduReader metadataReader(pduPtr, accessor.second.size(), metadataInfo, nullptr, 0); - REQUIRE(metadataReader.parseData() == OK); - std::string srcNameRead = metadataReader.getSourceFileName().getString(); - CHECK(srcNameRead == srcFileName); - std::string destNameRead = metadataReader.getDestFileName().getString(); - CHECK(destNameRead == destFileName); - CHECK(metadataInfo.getChecksumType() == ChecksumType::NULL_CHECKSUM); - CHECK(metadataInfo.getFileSize().value() == 0); - CHECK(!metadataInfo.isClosureRequested()); + const uint8_t* pduPtr; + // Verify metadata PDU was sent. + { + CHECK(fsmResult.packetsSent == 1); + CHECK(mqMock.numberOfSentMessages() == 1); + REQUIRE(mqMock.getNextSentMessage(destQueueId, tmtcMessage) == OK); + auto accessor = tmStore.getData(tmtcMessage.getStorageId()); + REQUIRE(accessor.first == OK); + pduPtr = accessor.second.data(); + CHECK(accessor.second.size() == 55); + MetadataGenericInfo metadataInfo; + MetadataPduReader metadataReader(pduPtr, accessor.second.size(), metadataInfo, nullptr, 0); + REQUIRE(metadataReader.parseData() == OK); + std::string srcNameRead = metadataReader.getSourceFileName().getString(); + CHECK(srcNameRead == srcFileName); + std::string destNameRead = metadataReader.getDestFileName().getString(); + CHECK(destNameRead == destFileName); + CHECK(metadataInfo.getChecksumType() == ChecksumType::NULL_CHECKSUM); + CHECK(metadataInfo.getFileSize().value() == 0); + CHECK(!metadataInfo.isClosureRequested()); + } // Verify EOF PDU was sent. No file data PDU is sent for an empty file. + { + mqMock.clearMessages(); + fsmResult = sourceHandler.stateMachine(); + CHECK(fsmResult.packetsSent == 1); + 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, + // 4 byte FSS + CHECK(accessor.second.size() == 20); + EofInfo eofInfo; + EofPduReader eofReader(pduPtr, accessor.second.size(), eofInfo); + REQUIRE(eofReader.parseData() == OK); + CHECK(eofInfo.getChecksum() == 0); + CHECK(eofInfo.getConditionCode() == ConditionCode::NO_ERROR); + CHECK(eofInfo.getFileSize().value() == 0); + } + CHECK(sourceHandler.getStep() == SourceHandler::TransactionStep::IDLE); + CHECK(sourceHandler.getState() == CfdpState::IDLE); } } \ No newline at end of file From 9a1437980ff0c865cb677a14ae4f3b29b30fd77b Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 3 Aug 2023 15:50:27 +0200 Subject: [PATCH 065/101] add empty stubs --- unittests/cfdp/handler/testSourceHandler.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/unittests/cfdp/handler/testSourceHandler.cpp b/unittests/cfdp/handler/testSourceHandler.cpp index a46eae44..8acdcd4c 100644 --- a/unittests/cfdp/handler/testSourceHandler.cpp +++ b/unittests/cfdp/handler/testSourceHandler.cpp @@ -111,4 +111,7 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { CHECK(sourceHandler.getStep() == SourceHandler::TransactionStep::IDLE); CHECK(sourceHandler.getState() == CfdpState::IDLE); } + + SECTION("Transfer small file") {} + SECTION("Transfer two segment file") {} } \ No newline at end of file From 6c6b5520599f4855570c22db91b3bb5226173abe Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 3 Aug 2023 17:43:03 +0200 Subject: [PATCH 066/101] start small file transfer test --- src/fsfw/cfdp/handler/SourceHandler.cpp | 9 +- src/fsfw/cfdp/handler/SourceHandler.h | 1 + src/fsfw/filesystem/HasFileSystemIF.h | 2 +- unittests/cfdp/handler/testSourceHandler.cpp | 133 +++++++++++-------- unittests/mocks/FilesystemMock.cpp | 8 +- 5 files changed, 94 insertions(+), 59 deletions(-) diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index 3ce1b898..5d6f0929 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -204,6 +204,11 @@ ReturnValue_t cfdp::SourceHandler::transactionStart(PutRequest& putRequest, Remo if (fileSize > UINT32_MAX) { transactionParams.pduConf.largeFile = true; } + if (fileSize == 0) { + transactionParams.checksumType = ChecksumType::NULL_CHECKSUM; + } else { + transactionParams.checksumType = ChecksumType::CRC_32; + } transactionParams.fileSize.setFileSize(fileSize, transactionParams.pduConf.largeFile); transactionParams.remoteCfg = cfg; return OK; @@ -212,7 +217,9 @@ ReturnValue_t cfdp::SourceHandler::transactionStart(PutRequest& putRequest, Remo ReturnValue_t cfdp::SourceHandler::prepareAndSendMetadataPdu() { cfdp::StringLv sourceName(transactionParams.sourceName.data(), transactionParams.sourceNameSize); cfdp::StringLv destName(transactionParams.destName.data(), transactionParams.destNameSize); - auto metadataInfo = MetadataGenericInfo(transactionParams.fileSize); + auto metadataInfo = + MetadataGenericInfo(transactionParams.closureRequested, transactionParams.checksumType, + transactionParams.fileSize); auto metadataPdu = MetadataPduCreator(transactionParams.pduConf, metadataInfo, sourceName, destName, nullptr, 0); ReturnValue_t result = sendGenericPdu(metadataPdu); diff --git a/src/fsfw/cfdp/handler/SourceHandler.h b/src/fsfw/cfdp/handler/SourceHandler.h index afbbdf1f..dfdf94ad 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.h +++ b/src/fsfw/cfdp/handler/SourceHandler.h @@ -73,6 +73,7 @@ class SourceHandler { cfdp::Fss fileSize; size_t progress = 0; bool closureRequested = false; + ChecksumType checksumType = ChecksumType::NULL_CHECKSUM; RemoteEntityCfg remoteCfg; PduConfig pduConf; cfdp::TransactionId id{}; diff --git a/src/fsfw/filesystem/HasFileSystemIF.h b/src/fsfw/filesystem/HasFileSystemIF.h index db3e8ddf..3f7088d6 100644 --- a/src/fsfw/filesystem/HasFileSystemIF.h +++ b/src/fsfw/filesystem/HasFileSystemIF.h @@ -17,7 +17,7 @@ struct FilesystemParams { }; struct FileOpParams { - FileOpParams(const char* path, size_t size) : fsParams(path), size(size) {} + FileOpParams(const char* path, size_t opSize) : fsParams(path), size(opSize) {} [[nodiscard]] const char* path() const { return fsParams.path; } diff --git a/unittests/cfdp/handler/testSourceHandler.cpp b/unittests/cfdp/handler/testSourceHandler.cpp index 8acdcd4c..b76bc24a 100644 --- a/unittests/cfdp/handler/testSourceHandler.cpp +++ b/unittests/cfdp/handler/testSourceHandler.cpp @@ -43,75 +43,102 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { fp.tcStore = &tcStore; fp.tmStore = &tmStore; auto sourceHandler = SourceHandler(dp, fp); + + RemoteEntityCfg cfg; + EntityId id(cfdp::WidthInBytes::TWO_BYTES, 5); + cfg.remoteId = id; + std::string srcFileName = "/tmp/cfdp-test.txt"; + std::string destFileName = "/tmp/cfdp-test2.txt"; + FilesystemParams srcFileNameFs(srcFileName.c_str()); + fsMock.createFile(srcFileNameFs); + cfdp::StringLv srcNameLv(srcFileNameFs.path, std::strlen(srcFileNameFs.path)); + FilesystemParams destFileNameFs(destFileName.c_str()); + cfdp::StringLv destNameLv(destFileNameFs.path, std::strlen(destFileNameFs.path)); + PutRequest putRequest(id, srcNameLv, destNameLv); CHECK(sourceHandler.initialize() == OK); + auto genericMetadataCheck = [&](SourceHandler::FsmResult& fsmResult, size_t expectedFileSize) { + TmTcMessage tmtcMessage; + const uint8_t* pduPtr; + CHECK(fsmResult.packetsSent == 1); + CHECK(mqMock.numberOfSentMessages() == 1); + REQUIRE(mqMock.getNextSentMessage(destQueueId, tmtcMessage) == OK); + auto accessor = tmStore.getData(tmtcMessage.getStorageId()); + REQUIRE(accessor.first == OK); + pduPtr = accessor.second.data(); + CHECK(accessor.second.size() == 55); + MetadataGenericInfo metadataInfo; + MetadataPduReader metadataReader(pduPtr, accessor.second.size(), metadataInfo, nullptr, 0); + REQUIRE(metadataReader.parseData() == OK); + std::string srcNameRead = metadataReader.getSourceFileName().getString(); + CHECK(srcNameRead == srcFileName); + std::string destNameRead = metadataReader.getDestFileName().getString(); + CHECK(destNameRead == destFileName); + if (expectedFileSize == 0) { + CHECK(metadataInfo.getChecksumType() == ChecksumType::NULL_CHECKSUM); + } else { + CHECK(metadataInfo.getChecksumType() == ChecksumType::CRC_32); + } + CHECK(metadataInfo.getFileSize().value() == expectedFileSize); + CHECK(!metadataInfo.isClosureRequested()); + mqMock.clearMessages(); + }; + auto genericEofCheck = [&](SourceHandler::FsmResult& fsmResult, size_t expectedFileSize, + uint32_t expectedChecksum) { + TmTcMessage tmtcMessage; + const uint8_t* pduPtr; + CHECK(fsmResult.packetsSent == 1); + 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, + // 4 byte FSS + CHECK(accessor.second.size() == 20); + EofInfo eofInfo; + EofPduReader eofReader(pduPtr, accessor.second.size(), eofInfo); + REQUIRE(eofReader.parseData() == OK); + CHECK(eofInfo.getChecksum() == expectedChecksum); + CHECK(eofInfo.getConditionCode() == ConditionCode::NO_ERROR); + CHECK(eofInfo.getFileSize().value() == expectedFileSize); + }; SECTION("Test Basic") { CHECK(sourceHandler.getState() == CfdpState::IDLE); CHECK(sourceHandler.getStep() == SourceHandler::TransactionStep::IDLE); } SECTION("Transfer empty file") { - RemoteEntityCfg cfg; - EntityId id(cfdp::WidthInBytes::TWO_BYTES, 5); - cfg.remoteId = id; - std::string srcFileName = "/tmp/cfdp-test.txt"; - std::string destFileName = "/tmp/cfdp-test2.txt"; - FilesystemParams srcFileNameFs(srcFileName.c_str()); - fsMock.createFile(srcFileNameFs); - cfdp::StringLv srcNameLv(srcFileNameFs.path, std::strlen(srcFileNameFs.path)); - FilesystemParams destFileNameFs(destFileName.c_str()); - cfdp::StringLv destNameLv(destFileNameFs.path, std::strlen(destFileNameFs.path)); - PutRequest putRequest(id, srcNameLv, destNameLv); CHECK(sourceHandler.transactionStart(putRequest, cfg) == OK); + SourceHandler::FsmResult& fsmResult = sourceHandler.stateMachine(); - - TmTcMessage tmtcMessage; - const uint8_t* pduPtr; // Verify metadata PDU was sent. - { - CHECK(fsmResult.packetsSent == 1); - CHECK(mqMock.numberOfSentMessages() == 1); - REQUIRE(mqMock.getNextSentMessage(destQueueId, tmtcMessage) == OK); - auto accessor = tmStore.getData(tmtcMessage.getStorageId()); - REQUIRE(accessor.first == OK); - pduPtr = accessor.second.data(); - CHECK(accessor.second.size() == 55); - MetadataGenericInfo metadataInfo; - MetadataPduReader metadataReader(pduPtr, accessor.second.size(), metadataInfo, nullptr, 0); - REQUIRE(metadataReader.parseData() == OK); - std::string srcNameRead = metadataReader.getSourceFileName().getString(); - CHECK(srcNameRead == srcFileName); - std::string destNameRead = metadataReader.getDestFileName().getString(); - CHECK(destNameRead == destFileName); - CHECK(metadataInfo.getChecksumType() == ChecksumType::NULL_CHECKSUM); - CHECK(metadataInfo.getFileSize().value() == 0); - CHECK(!metadataInfo.isClosureRequested()); - } + genericMetadataCheck(fsmResult, 0); + fsmResult = sourceHandler.stateMachine(); // Verify EOF PDU was sent. No file data PDU is sent for an empty file. - { - mqMock.clearMessages(); - fsmResult = sourceHandler.stateMachine(); - CHECK(fsmResult.packetsSent == 1); - 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, - // 4 byte FSS - CHECK(accessor.second.size() == 20); - EofInfo eofInfo; - EofPduReader eofReader(pduPtr, accessor.second.size(), eofInfo); - REQUIRE(eofReader.parseData() == OK); - CHECK(eofInfo.getChecksum() == 0); - CHECK(eofInfo.getConditionCode() == ConditionCode::NO_ERROR); - CHECK(eofInfo.getFileSize().value() == 0); - } + genericEofCheck(fsmResult, 0, 0); + CHECK(sourceHandler.getStep() == SourceHandler::TransactionStep::IDLE); CHECK(sourceHandler.getState() == CfdpState::IDLE); } - SECTION("Transfer small file") {} + SECTION("Transfer small file") { + fsMock.createFile(srcFileNameFs); + std::string fileContent = "hello world\n"; + size_t expectedFileSize = fileContent.size(); + FileOpParams params(srcFileName.c_str(), expectedFileSize); + fsMock.writeToFile(params, reinterpret_cast(fileContent.data())); + CHECK(sourceHandler.transactionStart(putRequest, cfg) == OK); + SourceHandler::FsmResult& fsmResult = sourceHandler.stateMachine(); + + // Verify metadata PDU was sent. + genericMetadataCheck(fsmResult, expectedFileSize); + fsmResult = sourceHandler.stateMachine(); + // TODO: Verify one file data PDU was sent. + + // TODO: Verify one EOF PDU was sent. + } + SECTION("Transfer two segment file") {} } \ No newline at end of file diff --git a/unittests/mocks/FilesystemMock.cpp b/unittests/mocks/FilesystemMock.cpp index 6efa12f2..faee7e71 100644 --- a/unittests/mocks/FilesystemMock.cpp +++ b/unittests/mocks/FilesystemMock.cpp @@ -80,7 +80,7 @@ ReturnValue_t FilesystemMock::removeDirectory(FilesystemParams params, bool dele ReturnValue_t FilesystemMock::rename(const char *oldPath, const char *newPath, FileSystemArgsIF *args) { - renameQueue.push(RenameInfo(oldPath, newPath)); + renameQueue.emplace(oldPath, newPath); return returnvalue::OK; } @@ -90,7 +90,7 @@ void FilesystemMock::createOrAddToFile(FileOpParams params, const uint8_t *data) if (iter == fileMap.end()) { FileSegmentQueue queue; if (params.size > 0) { - queue.push(FileWriteInfo(filename, params.offset, data, params.size)); + queue.emplace(filename, params.offset, data, params.size); } FileInfo info; info.fileSegQueue = queue; @@ -100,7 +100,7 @@ void FilesystemMock::createOrAddToFile(FileOpParams params, const uint8_t *data) fileMap.emplace(filename, info); } else { FileInfo &info = iter->second; - info.fileSegQueue.push(FileWriteInfo(filename, params.offset, data, params.size)); + info.fileSegQueue.emplace(filename, params.offset, data, params.size); if (data == nullptr) { return; } @@ -149,7 +149,7 @@ bool FilesystemMock::isDirectory(const char *path) { return false; } bool FilesystemMock::getFileSize(FilesystemParams params, size_t &fileSize) { std::string filename(params.path); auto iter = fileMap.find(filename); - if (iter == fileMap.end()) { + if (iter != fileMap.end()) { fileSize = iter->second.fileRaw.size(); return true; } From 8ddd6eb18df7d1b67b207791189cfb5f5afb16ca Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 3 Aug 2023 17:44:30 +0200 Subject: [PATCH 067/101] some improvements for test --- unittests/cfdp/handler/testSourceHandler.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/unittests/cfdp/handler/testSourceHandler.cpp b/unittests/cfdp/handler/testSourceHandler.cpp index b76bc24a..1b319d5a 100644 --- a/unittests/cfdp/handler/testSourceHandler.cpp +++ b/unittests/cfdp/handler/testSourceHandler.cpp @@ -111,13 +111,14 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { SECTION("Transfer empty file") { CHECK(sourceHandler.transactionStart(putRequest, cfg) == OK); + size_t expectedFileSize = 0; SourceHandler::FsmResult& fsmResult = sourceHandler.stateMachine(); // Verify metadata PDU was sent. - genericMetadataCheck(fsmResult, 0); + genericMetadataCheck(fsmResult, expectedFileSize); fsmResult = sourceHandler.stateMachine(); - // Verify EOF PDU was sent. No file data PDU is sent for an empty file. - genericEofCheck(fsmResult, 0, 0); + // Verify EOF PDU was sent. No file data PDU is sent for an empty file and the checksum is 0. + genericEofCheck(fsmResult, expectedFileSize, 0); CHECK(sourceHandler.getStep() == SourceHandler::TransactionStep::IDLE); CHECK(sourceHandler.getState() == CfdpState::IDLE); From e8451cac31c5717687f48db55b235ba3421edec1 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 4 Aug 2023 14:21:36 +0200 Subject: [PATCH 068/101] add one test condition --- unittests/cfdp/handler/testSourceHandler.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/unittests/cfdp/handler/testSourceHandler.cpp b/unittests/cfdp/handler/testSourceHandler.cpp index 1b319d5a..a2e5e55f 100644 --- a/unittests/cfdp/handler/testSourceHandler.cpp +++ b/unittests/cfdp/handler/testSourceHandler.cpp @@ -137,6 +137,7 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { genericMetadataCheck(fsmResult, expectedFileSize); fsmResult = sourceHandler.stateMachine(); // TODO: Verify one file data PDU was sent. + CHECK(fsmResult.packetsSent == 1); // TODO: Verify one EOF PDU was sent. } From 7c875f106707ffa48f3ca256428a5cf880549217 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 4 Aug 2023 15:17:53 +0200 Subject: [PATCH 069/101] unittest for small file transfer done --- src/fsfw/cfdp/handler/DestHandler.cpp | 11 ++--- src/fsfw/cfdp/handler/SourceHandler.cpp | 2 +- src/fsfw/cfdp/pdu/FileDataInfo.cpp | 6 +-- src/fsfw/cfdp/pdu/FileDataInfo.h | 6 +-- unittests/cfdp/handler/testSourceHandler.cpp | 51 +++++++++++++++----- unittests/cfdp/pdu/testFileData.cpp | 3 +- 6 files changed, 51 insertions(+), 28 deletions(-) diff --git a/src/fsfw/cfdp/handler/DestHandler.cpp b/src/fsfw/cfdp/handler/DestHandler.cpp index 83801df7..4814917f 100644 --- a/src/fsfw/cfdp/handler/DestHandler.cpp +++ b/src/fsfw/cfdp/handler/DestHandler.cpp @@ -156,8 +156,7 @@ ReturnValue_t cfdp::DestHandler::handleFileDataPdu(const cfdp::PacketInfo& info) // TODO: This is not a CFDP error. Event and/or warning? return constAccessorPair.first; } - cfdp::Fss offset; - FileDataInfo fdInfo(offset); + FileDataInfo fdInfo; FileDataReader reader(constAccessorPair.second.data(), constAccessorPair.second.size(), fdInfo); ReturnValue_t result = reader.parseData(); if (result != OK) { @@ -166,10 +165,10 @@ ReturnValue_t cfdp::DestHandler::handleFileDataPdu(const cfdp::PacketInfo& info) size_t fileSegmentLen = 0; const uint8_t* fileData = fdInfo.getFileData(&fileSegmentLen); FileOpParams fileOpParams(transactionParams.destName.data(), fileSegmentLen); - fileOpParams.offset = offset.value(); + fileOpParams.offset = fdInfo.getOffset().value(); if (destParams.cfg.indicCfg.fileSegmentRecvIndicRequired) { FileSegmentRecvdParams segParams; - segParams.offset = offset.value(); + segParams.offset = fdInfo.getOffset().value(); segParams.id = transactionParams.transactionId; segParams.length = fileSegmentLen; segParams.recContState = fdInfo.getRecordContinuationState(); @@ -196,8 +195,8 @@ ReturnValue_t cfdp::DestHandler::handleFileDataPdu(const cfdp::PacketInfo& info) transactionParams.deliveryStatus = FileDeliveryStatus::RETAINED_IN_FILESTORE; transactionParams.vfsErrorCount = 0; } - if (offset.value() + fileSegmentLen > transactionParams.progress) { - transactionParams.progress = offset.value() + fileSegmentLen; + if (fdInfo.getOffset().value() + fileSegmentLen > transactionParams.progress) { + transactionParams.progress = fdInfo.getOffset().value() + fileSegmentLen; } return result; } diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index 5d6f0929..b35880c9 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -120,7 +120,7 @@ ReturnValue_t cfdp::SourceHandler::checksumGeneration() { std::array buf{}; etl::crc32 crcCalc; 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()) { uint64_t readLen; if (currentOffset + buf.size() > transactionParams.fileSize.value()) { diff --git a/src/fsfw/cfdp/pdu/FileDataInfo.cpp b/src/fsfw/cfdp/pdu/FileDataInfo.cpp index ec12e9da..8248a727 100644 --- a/src/fsfw/cfdp/pdu/FileDataInfo.cpp +++ b/src/fsfw/cfdp/pdu/FileDataInfo.cpp @@ -1,9 +1,9 @@ #include "FileDataInfo.h" -FileDataInfo::FileDataInfo(cfdp::Fss &offset, const uint8_t *fileData, size_t fileSize) - : offset(offset), fileData(fileData), fileSize(fileSize) {} +#include -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) { if (enable) { diff --git a/src/fsfw/cfdp/pdu/FileDataInfo.h b/src/fsfw/cfdp/pdu/FileDataInfo.h index 2721cda2..b2b975ad 100644 --- a/src/fsfw/cfdp/pdu/FileDataInfo.h +++ b/src/fsfw/cfdp/pdu/FileDataInfo.h @@ -6,8 +6,8 @@ class FileDataInfo { public: - explicit FileDataInfo(cfdp::Fss& offset); - FileDataInfo(cfdp::Fss& offset, const uint8_t* fileData, size_t fileSize); + FileDataInfo() = default; + FileDataInfo(cfdp::Fss offset, const uint8_t* fileData, size_t fileSize); [[nodiscard]] size_t getSerializedSize(bool largeFile = false) const; @@ -33,7 +33,7 @@ class FileDataInfo { private: cfdp::SegmentMetadataFlag segmentMetadataFlag = cfdp::SegmentMetadataFlag::NOT_PRESENT; cfdp::SegmentationControl segCtrl = cfdp::SegmentationControl::NO_RECORD_BOUNDARIES_PRESERVATION; - cfdp::Fss& offset; + cfdp::Fss offset; const uint8_t* fileData = nullptr; size_t fileSize = 0; cfdp::RecordContinuationState recContState = cfdp::RecordContinuationState::NO_START_NO_END; diff --git a/unittests/cfdp/handler/testSourceHandler.cpp b/unittests/cfdp/handler/testSourceHandler.cpp index a2e5e55f..e7f62def 100644 --- a/unittests/cfdp/handler/testSourceHandler.cpp +++ b/unittests/cfdp/handler/testSourceHandler.cpp @@ -1,3 +1,5 @@ +#include + #include #include @@ -6,6 +8,7 @@ #include "fsfw/cfdp/handler/SourceHandler.h" #include "fsfw/cfdp/pdu/EofPduCreator.h" #include "fsfw/cfdp/pdu/EofPduReader.h" +#include "fsfw/cfdp/pdu/FileDataReader.h" #include "fsfw/cfdp/pdu/MetadataPduCreator.h" #include "fsfw/cfdp/pdu/MetadataPduReader.h" #include "fsfw/tmtcservices/TmTcMessage.h" @@ -57,15 +60,20 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { PutRequest putRequest(id, srcNameLv, destNameLv); CHECK(sourceHandler.initialize() == OK); - auto genericMetadataCheck = [&](SourceHandler::FsmResult& fsmResult, size_t expectedFileSize) { - TmTcMessage tmtcMessage; - const uint8_t* pduPtr; + auto onePduSentCheck = [&](SourceHandler::FsmResult& fsmResult, TmTcMessage& tmtcMessage, + const uint8_t** pduPtr) { CHECK(fsmResult.packetsSent == 1); CHECK(mqMock.numberOfSentMessages() == 1); REQUIRE(mqMock.getNextSentMessage(destQueueId, tmtcMessage) == OK); auto accessor = tmStore.getData(tmtcMessage.getStorageId()); 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); MetadataGenericInfo metadataInfo; MetadataPduReader metadataReader(pduPtr, accessor.second.size(), metadataInfo, nullptr, 0); @@ -87,12 +95,7 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { uint32_t expectedChecksum) { TmTcMessage tmtcMessage; const uint8_t* pduPtr; - CHECK(fsmResult.packetsSent == 1); - CHECK(mqMock.numberOfSentMessages() == 1); - REQUIRE(mqMock.getNextSentMessage(destQueueId, tmtcMessage) == OK); - auto accessor = tmStore.getData(tmtcMessage.getStorageId()); - REQUIRE(accessor.first == OK); - pduPtr = accessor.second.data(); + auto accessor = onePduSentCheck(fsmResult, tmtcMessage, &pduPtr); // 10 byte PDU header, 1 byte directive field, 1 byte condition code, 4 byte checksum, // 4 byte FSS CHECK(accessor.second.size() == 20); @@ -136,10 +139,32 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { // Verify metadata PDU was sent. genericMetadataCheck(fsmResult, expectedFileSize); fsmResult = sourceHandler.stateMachine(); - // TODO: Verify one file data PDU was sent. - CHECK(fsmResult.packetsSent == 1); + TmTcMessage tmtcMessage; + 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(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") {} diff --git a/unittests/cfdp/pdu/testFileData.cpp b/unittests/cfdp/pdu/testFileData.cpp index 6eed1dd3..80b02603 100644 --- a/unittests/cfdp/pdu/testFileData.cpp +++ b/unittests/cfdp/pdu/testFileData.cpp @@ -107,8 +107,7 @@ TEST_CASE("File Data PDU", "[cfdp][pdu]") { serializer.serialize(&buffer, &sz, fileDataBuffer.size(), SerializeIF::Endianness::NETWORK); REQUIRE(result == returnvalue::OK); - Fss emptyOffset; - FileDataInfo emptyInfo(emptyOffset); + FileDataInfo emptyInfo; FileDataReader deserializer(fileDataBuffer.data(), fileDataBuffer.size(), emptyInfo); result = deserializer.parseData(); REQUIRE(result == returnvalue::OK); From 7aeb25e064ea7d97fb4e98a9771ccf74a67e882a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 14 Aug 2023 11:26:57 +0200 Subject: [PATCH 070/101] unittest for transfer with 2 segments --- unittests/cfdp/handler/testSourceHandler.cpp | 64 +++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/unittests/cfdp/handler/testSourceHandler.cpp b/unittests/cfdp/handler/testSourceHandler.cpp index e7f62def..c268130b 100644 --- a/unittests/cfdp/handler/testSourceHandler.cpp +++ b/unittests/cfdp/handler/testSourceHandler.cpp @@ -2,6 +2,7 @@ #include #include +#include #include "fsfw/cfdp.h" #include "fsfw/cfdp/handler/PutRequest.h" @@ -26,6 +27,8 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { using namespace cfdp; using namespace returnvalue; using namespace std::filesystem; + const size_t MAX_FILE_SEGMENT_SIZE = 255; + MessageQueueId_t destQueueId = 2; AcceptsTmMock tmReceiver(destQueueId); MessageQueueMock mqMock(destQueueId); @@ -48,6 +51,7 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { auto sourceHandler = SourceHandler(dp, fp); RemoteEntityCfg cfg; + cfg.maxFileSegmentLen = MAX_FILE_SEGMENT_SIZE; EntityId id(cfdp::WidthInBytes::TWO_BYTES, 5); cfg.remoteId = id; std::string srcFileName = "/tmp/cfdp-test.txt"; @@ -138,6 +142,8 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { // Verify metadata PDU was sent. genericMetadataCheck(fsmResult, expectedFileSize); + + // Verify that a small file data PDU was sent. fsmResult = sourceHandler.stateMachine(); TmTcMessage tmtcMessage; const uint8_t* pduPtr; @@ -167,5 +173,61 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { 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 distU8(0, 255); + std::array 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(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]); + } + } } \ No newline at end of file From 15629abf1996e0e8a0b1ece54beb7d2d419fd655 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 14 Aug 2023 12:13:29 +0200 Subject: [PATCH 071/101] the joys of UB or whatever that crap was --- src/fsfw/cfdp/handler/SourceHandler.cpp | 17 +++++++++++++++-- src/fsfw/cfdp/handler/SourceHandler.h | 2 ++ unittests/cfdp/handler/testSourceHandler.cpp | 4 ++-- unittests/mocks/FilesystemMock.cpp | 3 ++- 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index b35880c9..0ba10f5a 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -39,6 +39,7 @@ cfdp::SourceHandler::SourceHandler(SourceHandlerParams params, FsfwParams fsfwPa // Yeah, what am I supposed to do here? Can't throw an exception in the FSFW.. transactionParams.pduConf.seqNum.setWidth(cfdp::WidthInBytes::ONE_BYTE); } + transactionParams.pduConf.seqNum.setValue(0); } cfdp::SourceHandler::FsmResult& cfdp::SourceHandler::fsmNacked() { @@ -190,7 +191,8 @@ ReturnValue_t cfdp::SourceHandler::transactionStart(PutRequest& putRequest, Remo } // Only used for PDU forwarding, file is sent to file receiver regularly here. transactionParams.pduConf.direction = Direction::TOWARDS_RECEIVER; - transactionParams.id.seqNum.setValue(sourceParams.seqCountProvider.getAndIncrement()); + transactionParams.pduConf.seqNum.setValue(sourceParams.seqCountProvider.getAndIncrement()); + transactionParams.id.seqNum = transactionParams.pduConf.seqNum; if (transactionParams.pduConf.mode == TransmissionMode::ACKNOWLEDGED) { state = cfdp::CfdpState::BUSY_CLASS_2_ACKED; @@ -210,6 +212,7 @@ ReturnValue_t cfdp::SourceHandler::transactionStart(PutRequest& putRequest, Remo transactionParams.checksumType = ChecksumType::CRC_32; } transactionParams.fileSize.setFileSize(fileSize, transactionParams.pduConf.largeFile); + transactionParams.progress = 0; transactionParams.remoteCfg = cfg; return OK; } @@ -252,9 +255,11 @@ ReturnValue_t cfdp::SourceHandler::prepareAndSendNextFileDataPdu(bool& noFileDat } } FileOpParams fileParams(transactionParams.sourceName.data(), readLen); + fileParams.offset = transactionParams.progress; ReturnValue_t result = sourceParams.user.vfs.readFromFile(fileParams, fileBuf.data(), fileBuf.size()); if (result != returnvalue::OK) { + addError(result); return result; } auto fileDataInfo = FileDataInfo(offset, fileBuf.data(), readLen); @@ -309,12 +314,13 @@ ReturnValue_t cfdp::SourceHandler::sendGenericPdu(const SerializeIF& pdu) { ReturnValue_t result = fsfwParams.tmStore->getFreeElement(&storeId, pdu.getSerializedSize(), &dataPtr); if (result != OK) { - // TODO: Better error handling? + addError(result); return result; } size_t serializedLen = 0; result = pdu.serializeBe(dataPtr, serializedLen, pdu.getSerializedSize()); if (result != OK) { + addError(result); return result; } TmTcMessage tmMsg(storeId); @@ -345,3 +351,10 @@ ReturnValue_t cfdp::SourceHandler::reset() { cfdp::CfdpState cfdp::SourceHandler::getState() const { return state; } cfdp::SourceHandler::TransactionStep cfdp::SourceHandler::getStep() const { return step; } + +void cfdp::SourceHandler::addError(ReturnValue_t error) { + if (errorIndex < fsmResult.errorCodes.size()) { + fsmResult.errorCodes[errorIndex] = error; + errorIndex++; + } +} diff --git a/src/fsfw/cfdp/handler/SourceHandler.h b/src/fsfw/cfdp/handler/SourceHandler.h index dfdf94ad..8e491d9d 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.h +++ b/src/fsfw/cfdp/handler/SourceHandler.h @@ -92,6 +92,7 @@ class SourceHandler { std::array fileBuf{}; SourceHandlerParams sourceParams; cfdp::FsfwParams fsfwParams; + uint8_t errorIndex = 0; FsmResult fsmResult; FsmResult& fsmNacked(); @@ -103,6 +104,7 @@ class SourceHandler { ReturnValue_t reset(); [[nodiscard]] ReturnValue_t sendGenericPdu(const SerializeIF& pdu); + void addError(ReturnValue_t error); }; } // namespace cfdp diff --git a/unittests/cfdp/handler/testSourceHandler.cpp b/unittests/cfdp/handler/testSourceHandler.cpp index c268130b..da07a036 100644 --- a/unittests/cfdp/handler/testSourceHandler.cpp +++ b/unittests/cfdp/handler/testSourceHandler.cpp @@ -197,8 +197,8 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { TmTcMessage tmtcMessage; const uint8_t* pduPtr; FileDataInfo fdInfo; - auto accessor = onePduSentCheck(fsmResult, tmtcMessage, &pduPtr); { + 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); @@ -216,7 +216,7 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { // Check second file data PDU. fsmResult = sourceHandler.stateMachine(); - accessor = onePduSentCheck(fsmResult, tmtcMessage, &pduPtr); + auto 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); diff --git a/unittests/mocks/FilesystemMock.cpp b/unittests/mocks/FilesystemMock.cpp index faee7e71..51c0c686 100644 --- a/unittests/mocks/FilesystemMock.cpp +++ b/unittests/mocks/FilesystemMock.cpp @@ -39,7 +39,8 @@ ReturnValue_t FilesystemMock::readFromFile(FileOpParams params, uint8_t **buffer if (readSize + readLen > maxSize) { return SerializeIF::STREAM_TOO_SHORT; } - std::copy(info.fileRaw.data() + params.offset, info.fileRaw.data() + readLen, *buffer); + std::copy(info.fileRaw.data() + params.offset, info.fileRaw.data() + params.offset + readLen, + *buffer); *buffer += readLen; readSize += readLen; } From b094ba145f596bf7f94448da1c3baf07daebe919 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 14 Aug 2023 12:15:35 +0200 Subject: [PATCH 072/101] multi file segment works --- unittests/cfdp/handler/testSourceHandler.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/unittests/cfdp/handler/testSourceHandler.cpp b/unittests/cfdp/handler/testSourceHandler.cpp index da07a036..1e32b769 100644 --- a/unittests/cfdp/handler/testSourceHandler.cpp +++ b/unittests/cfdp/handler/testSourceHandler.cpp @@ -229,5 +229,17 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { for (unsigned i = 0; i < fileDataSize; i++) { CHECK(fileData[i] == largerFileData[MAX_FILE_SEGMENT_SIZE + i]); } + mqMock.clearMessages(); + + // Check EOF and verify checksum. + fsmResult = sourceHandler.stateMachine(); + + etl::crc32 crcCalc; + crcCalc.add(largerFileData.data(), largerFileData.data() + largerFileData.size()); + // Verify EOF PDU was sent. + genericEofCheck(fsmResult, expectedFileSize, crcCalc.value()); + + CHECK(sourceHandler.getStep() == SourceHandler::TransactionStep::IDLE); + CHECK(sourceHandler.getState() == CfdpState::IDLE); } } \ No newline at end of file From e4aae7574759803e282d0e07e4e2329f68e571e5 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 14 Aug 2023 12:19:55 +0200 Subject: [PATCH 073/101] more checks --- src/fsfw/cfdp/handler/SourceHandler.cpp | 6 +++--- src/fsfw/cfdp/handler/SourceHandler.h | 1 - unittests/cfdp/handler/testSourceHandler.cpp | 3 +++ 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index 0ba10f5a..9460f65a 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -353,8 +353,8 @@ cfdp::CfdpState cfdp::SourceHandler::getState() const { return state; } cfdp::SourceHandler::TransactionStep cfdp::SourceHandler::getStep() const { return step; } void cfdp::SourceHandler::addError(ReturnValue_t error) { - if (errorIndex < fsmResult.errorCodes.size()) { - fsmResult.errorCodes[errorIndex] = error; - errorIndex++; + if (fsmResult.errors < fsmResult.errorCodes.size()) { + fsmResult.errorCodes[fsmResult.errors] = error; + fsmResult.errors++; } } diff --git a/src/fsfw/cfdp/handler/SourceHandler.h b/src/fsfw/cfdp/handler/SourceHandler.h index 8e491d9d..3aaaf789 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.h +++ b/src/fsfw/cfdp/handler/SourceHandler.h @@ -92,7 +92,6 @@ class SourceHandler { std::array fileBuf{}; SourceHandlerParams sourceParams; cfdp::FsfwParams fsfwParams; - uint8_t errorIndex = 0; FsmResult fsmResult; FsmResult& fsmNacked(); diff --git a/unittests/cfdp/handler/testSourceHandler.cpp b/unittests/cfdp/handler/testSourceHandler.cpp index 1e32b769..01d29a56 100644 --- a/unittests/cfdp/handler/testSourceHandler.cpp +++ b/unittests/cfdp/handler/testSourceHandler.cpp @@ -66,6 +66,7 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { auto onePduSentCheck = [&](SourceHandler::FsmResult& fsmResult, TmTcMessage& tmtcMessage, const uint8_t** pduPtr) { + CHECK(fsmResult.errors == 0); CHECK(fsmResult.packetsSent == 1); CHECK(mqMock.numberOfSentMessages() == 1); REQUIRE(mqMock.getNextSentMessage(destQueueId, tmtcMessage) == OK); @@ -75,6 +76,7 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { return std::move(accessor); }; auto genericMetadataCheck = [&](SourceHandler::FsmResult& fsmResult, size_t expectedFileSize) { + CHECK(fsmResult.errors == 0); TmTcMessage tmtcMessage; const uint8_t* pduPtr; auto accessor = onePduSentCheck(fsmResult, tmtcMessage, &pduPtr); @@ -97,6 +99,7 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { }; auto genericEofCheck = [&](SourceHandler::FsmResult& fsmResult, size_t expectedFileSize, uint32_t expectedChecksum) { + CHECK(fsmResult.errors == 0); TmTcMessage tmtcMessage; const uint8_t* pduPtr; auto accessor = onePduSentCheck(fsmResult, tmtcMessage, &pduPtr); From eae7c44874ed951d25126531bf246ff8dfb4db2c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 14 Aug 2023 13:19:32 +0200 Subject: [PATCH 074/101] reset error count --- src/fsfw/cfdp/handler/SourceHandler.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index 9460f65a..91ccd337 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -103,6 +103,7 @@ cfdp::SourceHandler::FsmResult& cfdp::SourceHandler::fsmNacked() { cfdp::SourceHandler::FsmResult& cfdp::SourceHandler::stateMachine() { fsmResult.packetsSent = 0; + fsmResult.errors = 0;gits if (state == cfdp::CfdpState::IDLE) { return fsmResult; } From 0fc2c7b5e97c37710134c4a6e855cf56fe7043f8 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 14 Aug 2023 13:19:48 +0200 Subject: [PATCH 075/101] oops --- src/fsfw/cfdp/handler/SourceHandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index 91ccd337..105a8f17 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -103,7 +103,7 @@ cfdp::SourceHandler::FsmResult& cfdp::SourceHandler::fsmNacked() { cfdp::SourceHandler::FsmResult& cfdp::SourceHandler::stateMachine() { fsmResult.packetsSent = 0; - fsmResult.errors = 0;gits + fsmResult.errors = 0; if (state == cfdp::CfdpState::IDLE) { return fsmResult; } From b7056a7467c5fc34320996fbef815be1b4cd5857 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 14 Aug 2023 13:24:22 +0200 Subject: [PATCH 076/101] additional checks --- unittests/cfdp/handler/testSourceHandler.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/unittests/cfdp/handler/testSourceHandler.cpp b/unittests/cfdp/handler/testSourceHandler.cpp index 01d29a56..c9ffcdf8 100644 --- a/unittests/cfdp/handler/testSourceHandler.cpp +++ b/unittests/cfdp/handler/testSourceHandler.cpp @@ -75,7 +75,8 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { *pduPtr = accessor.second.data(); return std::move(accessor); }; - auto genericMetadataCheck = [&](SourceHandler::FsmResult& fsmResult, size_t expectedFileSize) { + auto genericMetadataCheck = [&](SourceHandler::FsmResult& fsmResult, size_t expectedFileSize, + uint16_t expectedSeqNum) { CHECK(fsmResult.errors == 0); TmTcMessage tmtcMessage; const uint8_t* pduPtr; @@ -86,6 +87,9 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { REQUIRE(metadataReader.parseData() == OK); std::string srcNameRead = metadataReader.getSourceFileName().getString(); CHECK(srcNameRead == srcFileName); + TransactionSeqNum seqNum; + metadataReader.getTransactionSeqNum(seqNum); + CHECK(seqNum.getValue() == expectedSeqNum); std::string destNameRead = metadataReader.getDestFileName().getString(); CHECK(destNameRead == destFileName); if (expectedFileSize == 0) { @@ -124,7 +128,7 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { size_t expectedFileSize = 0; SourceHandler::FsmResult& fsmResult = sourceHandler.stateMachine(); // Verify metadata PDU was sent. - genericMetadataCheck(fsmResult, expectedFileSize); + genericMetadataCheck(fsmResult, expectedFileSize, 0); fsmResult = sourceHandler.stateMachine(); // Verify EOF PDU was sent. No file data PDU is sent for an empty file and the checksum is 0. @@ -144,7 +148,7 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { SourceHandler::FsmResult& fsmResult = sourceHandler.stateMachine(); // Verify metadata PDU was sent. - genericMetadataCheck(fsmResult, expectedFileSize); + genericMetadataCheck(fsmResult, expectedFileSize, 0); // Verify that a small file data PDU was sent. fsmResult = sourceHandler.stateMachine(); @@ -193,7 +197,7 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { CHECK(sourceHandler.transactionStart(putRequest, cfg) == OK); SourceHandler::FsmResult& fsmResult = sourceHandler.stateMachine(); // Verify metadata PDU was sent. - genericMetadataCheck(fsmResult, expectedFileSize); + genericMetadataCheck(fsmResult, expectedFileSize, 0); // Check first file data PDU. It should have the maximum file segment size. fsmResult = sourceHandler.stateMachine(); From cd8d64830c6c5bb08e2da45ee87bec72d2059f9b Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 14 Aug 2023 13:33:47 +0200 Subject: [PATCH 077/101] more checks --- unittests/cfdp/handler/testSourceHandler.cpp | 15 +++++++++++---- unittests/mocks/cfdp/UserMock.cpp | 7 ++++--- unittests/mocks/cfdp/UserMock.h | 1 + 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/unittests/cfdp/handler/testSourceHandler.cpp b/unittests/cfdp/handler/testSourceHandler.cpp index c9ffcdf8..08def58f 100644 --- a/unittests/cfdp/handler/testSourceHandler.cpp +++ b/unittests/cfdp/handler/testSourceHandler.cpp @@ -33,7 +33,7 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { AcceptsTmMock tmReceiver(destQueueId); MessageQueueMock mqMock(destQueueId); EntityId localId = EntityId(UnsignedByteField(2)); - EntityId remoteId = EntityId(UnsignedByteField(3)); + EntityId remoteId = EntityId(UnsignedByteField(5)); FaultHandlerMock fhMock; LocalEntityCfg localEntityCfg(localId, IndicationCfg(), fhMock); FilesystemMock fsMock; @@ -52,8 +52,7 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { RemoteEntityCfg cfg; cfg.maxFileSegmentLen = MAX_FILE_SEGMENT_SIZE; - EntityId id(cfdp::WidthInBytes::TWO_BYTES, 5); - cfg.remoteId = id; + cfg.remoteId = remoteId; std::string srcFileName = "/tmp/cfdp-test.txt"; std::string destFileName = "/tmp/cfdp-test2.txt"; FilesystemParams srcFileNameFs(srcFileName.c_str()); @@ -61,7 +60,7 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { cfdp::StringLv srcNameLv(srcFileNameFs.path, std::strlen(srcFileNameFs.path)); FilesystemParams destFileNameFs(destFileName.c_str()); cfdp::StringLv destNameLv(destFileNameFs.path, std::strlen(destFileNameFs.path)); - PutRequest putRequest(id, srcNameLv, destNameLv); + PutRequest putRequest(remoteId, srcNameLv, destNameLv); CHECK(sourceHandler.initialize() == OK); auto onePduSentCheck = [&](SourceHandler::FsmResult& fsmResult, TmTcMessage& tmtcMessage, @@ -90,6 +89,14 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { TransactionSeqNum seqNum; metadataReader.getTransactionSeqNum(seqNum); CHECK(seqNum.getValue() == expectedSeqNum); + CHECK(userMock.transactionIndicRecvd.size() == 1); + CHECK(userMock.transactionIndicRecvd.back() == TransactionId(localId, seqNum)); + EntityId srcId; + metadataReader.getSourceId(srcId); + EntityId destId; + metadataReader.getDestId(destId); + CHECK(srcId.getValue() == localId.getValue()); + CHECK(destId.getValue() == remoteId.getValue()); std::string destNameRead = metadataReader.getDestFileName().getString(); CHECK(destNameRead == destFileName); if (expectedFileSize == 0) { diff --git a/unittests/mocks/cfdp/UserMock.cpp b/unittests/mocks/cfdp/UserMock.cpp index ca15a5e6..6614d38d 100644 --- a/unittests/mocks/cfdp/UserMock.cpp +++ b/unittests/mocks/cfdp/UserMock.cpp @@ -4,7 +4,8 @@ namespace cfdp { cfdp::UserMock::UserMock(HasFileSystemIF& vfs) : UserBase(vfs) {} -void UserMock::transactionIndication(const TransactionId& id) {} +void UserMock::transactionIndication(const TransactionId& id) { transactionIndicRecvd.emplace(id); } + void UserMock::eofSentIndication(const TransactionId& id) {} void UserMock::abandonedIndication(const TransactionId& id, cfdp::ConditionCode code, uint64_t progress) {} @@ -12,11 +13,11 @@ void UserMock::abandonedIndication(const TransactionId& id, cfdp::ConditionCode void UserMock::eofRecvIndication(const TransactionId& id) { eofsRevd.push(id); } void UserMock::transactionFinishedIndication(const TransactionFinishedParams& finishedParams) { - finishedRecvd.push({finishedParams.id, finishedParams}); + finishedRecvd.emplace(finishedParams.id, finishedParams); } void UserMock::metadataRecvdIndication(const MetadataRecvdParams& params) { - metadataRecvd.push({params.id, params}); + metadataRecvd.emplace(params.id, params); } void UserMock::fileSegmentRecvdIndication(const FileSegmentRecvdParams& params) {} diff --git a/unittests/mocks/cfdp/UserMock.h b/unittests/mocks/cfdp/UserMock.h index e2a4a483..36e56d73 100644 --- a/unittests/mocks/cfdp/UserMock.h +++ b/unittests/mocks/cfdp/UserMock.h @@ -23,6 +23,7 @@ class UserMock : public UserBase { void resumedIndication(const TransactionId& id, size_t progress) override; void faultIndication(const TransactionId& id, ConditionCode code, size_t progress) override; + std::queue transactionIndicRecvd; std::queue> metadataRecvd; std::queue eofsRevd; std::queue> finishedRecvd; From 5ff464252f19b5a40a0e7c3f1ad23abb9318cdcf Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 14 Aug 2023 13:40:25 +0200 Subject: [PATCH 078/101] added some user checks --- unittests/cfdp/handler/testDestHandler.cpp | 4 ++-- unittests/cfdp/handler/testSourceHandler.cpp | 19 +++++++++++++------ unittests/mocks/cfdp/UserMock.cpp | 6 +++--- unittests/mocks/cfdp/UserMock.h | 3 ++- 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/unittests/cfdp/handler/testDestHandler.cpp b/unittests/cfdp/handler/testDestHandler.cpp index 2b6e4a4e..5ed0cd4e 100644 --- a/unittests/cfdp/handler/testDestHandler.cpp +++ b/unittests/cfdp/handler/testDestHandler.cpp @@ -108,8 +108,8 @@ TEST_CASE("CFDP Dest Handler", "[cfdp]") { // Assert that the packet was deleted after handling REQUIRE(not tcStore.hasDataAtId(storeId)); REQUIRE(packetInfoList.empty()); - REQUIRE(userMock.eofsRevd.size() == 1); - auto& eofId = userMock.eofsRevd.back(); + REQUIRE(userMock.eofRecvdRecvd.size() == 1); + auto& eofId = userMock.eofRecvdRecvd.back(); CHECK(eofId == id); REQUIRE(userMock.finishedRecvd.size() == 1); auto& idParamPair = userMock.finishedRecvd.back(); diff --git a/unittests/cfdp/handler/testSourceHandler.cpp b/unittests/cfdp/handler/testSourceHandler.cpp index 08def58f..5d5ff8f3 100644 --- a/unittests/cfdp/handler/testSourceHandler.cpp +++ b/unittests/cfdp/handler/testSourceHandler.cpp @@ -109,7 +109,7 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { mqMock.clearMessages(); }; auto genericEofCheck = [&](SourceHandler::FsmResult& fsmResult, size_t expectedFileSize, - uint32_t expectedChecksum) { + uint32_t expectedChecksum, uint16_t expectedSeqNum) { CHECK(fsmResult.errors == 0); TmTcMessage tmtcMessage; const uint8_t* pduPtr; @@ -120,6 +120,11 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { EofInfo eofInfo; EofPduReader eofReader(pduPtr, accessor.second.size(), eofInfo); REQUIRE(eofReader.parseData() == OK); + TransactionSeqNum seqNum; + eofReader.getTransactionSeqNum(seqNum); + CHECK(seqNum.getValue() == expectedSeqNum); + CHECK(userMock.eofSentRecvd.size() == 1); + CHECK(userMock.eofSentRecvd.back() == TransactionId(localId, seqNum)); CHECK(eofInfo.getChecksum() == expectedChecksum); CHECK(eofInfo.getConditionCode() == ConditionCode::NO_ERROR); CHECK(eofInfo.getFileSize().value() == expectedFileSize); @@ -139,13 +144,14 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { fsmResult = sourceHandler.stateMachine(); // Verify EOF PDU was sent. No file data PDU is sent for an empty file and the checksum is 0. - genericEofCheck(fsmResult, expectedFileSize, 0); + genericEofCheck(fsmResult, expectedFileSize, 0, 0); CHECK(sourceHandler.getStep() == SourceHandler::TransactionStep::IDLE); CHECK(sourceHandler.getState() == CfdpState::IDLE); } SECTION("Transfer small file") { + uint16_t expectedSeqNum = 0; fsMock.createFile(srcFileNameFs); std::string fileContent = "hello world\n"; size_t expectedFileSize = fileContent.size(); @@ -155,7 +161,7 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { SourceHandler::FsmResult& fsmResult = sourceHandler.stateMachine(); // Verify metadata PDU was sent. - genericMetadataCheck(fsmResult, expectedFileSize, 0); + genericMetadataCheck(fsmResult, expectedFileSize, expectedSeqNum); // Verify that a small file data PDU was sent. fsmResult = sourceHandler.stateMachine(); @@ -181,13 +187,14 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { etl::crc32 crcCalc; crcCalc.add(fileContent.data(), fileContent.data() + fileContent.size()); // Verify EOF PDU was sent. - genericEofCheck(fsmResult, expectedFileSize, crcCalc.value()); + genericEofCheck(fsmResult, expectedFileSize, crcCalc.value(), expectedSeqNum); CHECK(sourceHandler.getStep() == SourceHandler::TransactionStep::IDLE); CHECK(sourceHandler.getState() == CfdpState::IDLE); } SECTION("Transfer two segment file") { + uint16_t expectedSeqNum = 0; // Create 400 bytes of random data. This should result in two file segments, with one // having the maximum size. std::random_device dev; @@ -204,7 +211,7 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { CHECK(sourceHandler.transactionStart(putRequest, cfg) == OK); SourceHandler::FsmResult& fsmResult = sourceHandler.stateMachine(); // Verify metadata PDU was sent. - genericMetadataCheck(fsmResult, expectedFileSize, 0); + genericMetadataCheck(fsmResult, expectedFileSize, expectedSeqNum); // Check first file data PDU. It should have the maximum file segment size. fsmResult = sourceHandler.stateMachine(); @@ -251,7 +258,7 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { etl::crc32 crcCalc; crcCalc.add(largerFileData.data(), largerFileData.data() + largerFileData.size()); // Verify EOF PDU was sent. - genericEofCheck(fsmResult, expectedFileSize, crcCalc.value()); + genericEofCheck(fsmResult, expectedFileSize, crcCalc.value(), expectedSeqNum); CHECK(sourceHandler.getStep() == SourceHandler::TransactionStep::IDLE); CHECK(sourceHandler.getState() == CfdpState::IDLE); diff --git a/unittests/mocks/cfdp/UserMock.cpp b/unittests/mocks/cfdp/UserMock.cpp index 6614d38d..78223506 100644 --- a/unittests/mocks/cfdp/UserMock.cpp +++ b/unittests/mocks/cfdp/UserMock.cpp @@ -6,11 +6,11 @@ cfdp::UserMock::UserMock(HasFileSystemIF& vfs) : UserBase(vfs) {} void UserMock::transactionIndication(const TransactionId& id) { transactionIndicRecvd.emplace(id); } -void UserMock::eofSentIndication(const TransactionId& id) {} +void UserMock::eofSentIndication(const TransactionId& id) { eofSentRecvd.emplace(id); } void UserMock::abandonedIndication(const TransactionId& id, cfdp::ConditionCode code, uint64_t progress) {} -void UserMock::eofRecvIndication(const TransactionId& id) { eofsRevd.push(id); } +void UserMock::eofRecvIndication(const TransactionId& id) { eofRecvdRecvd.push(id); } void UserMock::transactionFinishedIndication(const TransactionFinishedParams& finishedParams) { finishedRecvd.emplace(finishedParams.id, finishedParams); @@ -28,7 +28,7 @@ void UserMock::faultIndication(const TransactionId& id, cfdp::ConditionCode code } void UserMock::reset() { - std::queue().swap(eofsRevd); + std::queue().swap(eofRecvdRecvd); std::queue>().swap(metadataRecvd); std::queue>().swap(finishedRecvd); } diff --git a/unittests/mocks/cfdp/UserMock.h b/unittests/mocks/cfdp/UserMock.h index 36e56d73..ad9e152d 100644 --- a/unittests/mocks/cfdp/UserMock.h +++ b/unittests/mocks/cfdp/UserMock.h @@ -25,7 +25,8 @@ class UserMock : public UserBase { std::queue transactionIndicRecvd; std::queue> metadataRecvd; - std::queue eofsRevd; + std::queue eofRecvdRecvd; + std::queue eofSentRecvd; std::queue> finishedRecvd; void reset(); }; From e1816ed23017f51226182603376825ed5583cb2a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 14 Aug 2023 13:45:13 +0200 Subject: [PATCH 079/101] that should be all indications --- unittests/cfdp/handler/testSourceHandler.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/unittests/cfdp/handler/testSourceHandler.cpp b/unittests/cfdp/handler/testSourceHandler.cpp index 5d5ff8f3..64f6c050 100644 --- a/unittests/cfdp/handler/testSourceHandler.cpp +++ b/unittests/cfdp/handler/testSourceHandler.cpp @@ -123,8 +123,11 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { TransactionSeqNum seqNum; eofReader.getTransactionSeqNum(seqNum); CHECK(seqNum.getValue() == expectedSeqNum); + auto transactionId = TransactionId(localId, seqNum); CHECK(userMock.eofSentRecvd.size() == 1); - CHECK(userMock.eofSentRecvd.back() == TransactionId(localId, seqNum)); + CHECK(userMock.eofSentRecvd.back() == transactionId); + CHECK(userMock.finishedRecvd.size() == 1); + CHECK(userMock.finishedRecvd.back().first == transactionId); CHECK(eofInfo.getChecksum() == expectedChecksum); CHECK(eofInfo.getConditionCode() == ConditionCode::NO_ERROR); CHECK(eofInfo.getFileSize().value() == expectedFileSize); From 67c38f327ed22afacecf3e2a6fdc589c6812f77f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 14 Aug 2023 13:54:11 +0200 Subject: [PATCH 080/101] rename source file --- src/fsfw/cfdp/pdu/CMakeLists.txt | 2 +- src/fsfw/cfdp/pdu/{MetadataInfo.cpp => MetadataGenericInfo.cpp} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename src/fsfw/cfdp/pdu/{MetadataInfo.cpp => MetadataGenericInfo.cpp} (100%) diff --git a/src/fsfw/cfdp/pdu/CMakeLists.txt b/src/fsfw/cfdp/pdu/CMakeLists.txt index c08a4b29..89de7b86 100644 --- a/src/fsfw/cfdp/pdu/CMakeLists.txt +++ b/src/fsfw/cfdp/pdu/CMakeLists.txt @@ -17,7 +17,7 @@ target_sources( FinishedInfo.cpp FinishedPduCreator.cpp FinishedPduReader.cpp - MetadataInfo.cpp + MetadataGenericInfo.cpp MetadataPduCreator.cpp MetadataPduReader.cpp KeepAlivePduCreator.cpp diff --git a/src/fsfw/cfdp/pdu/MetadataInfo.cpp b/src/fsfw/cfdp/pdu/MetadataGenericInfo.cpp similarity index 100% rename from src/fsfw/cfdp/pdu/MetadataInfo.cpp rename to src/fsfw/cfdp/pdu/MetadataGenericInfo.cpp From 036667a969c82272eeb65adfdb068e34e318ef75 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 14 Aug 2023 15:58:01 +0200 Subject: [PATCH 081/101] type improvements --- src/fsfw/cfdp/VarLenFields.h | 4 ++-- src/fsfw/filesystem/HasFileSystemIF.h | 2 +- src/fsfw_hal/host/HostFilesystem.cpp | 2 +- src/fsfw_hal/host/HostFilesystem.h | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/fsfw/cfdp/VarLenFields.h b/src/fsfw/cfdp/VarLenFields.h index 3143a857..69835c37 100644 --- a/src/fsfw/cfdp/VarLenFields.h +++ b/src/fsfw/cfdp/VarLenFields.h @@ -25,7 +25,7 @@ class VarLenField : public SerializeIF { template explicit VarLenField(UnsignedByteField byteField); - VarLenField(cfdp::WidthInBytes width, size_t value); + VarLenField(cfdp::WidthInBytes width, uint64_t value); bool operator==(const VarLenField &other) const; bool operator!=(const VarLenField &other) const; @@ -44,7 +44,7 @@ class VarLenField : public SerializeIF { Endianness streamEndianness); [[nodiscard]] cfdp::WidthInBytes getWidth() const; - [[nodiscard]] size_t getValue() const; + [[nodiscard]] uint64_t getValue() const; #if FSFW_CPP_OSTREAM_ENABLED == 1 friend std::ostream &operator<<(std::ostream &os, const VarLenField &id) { diff --git a/src/fsfw/filesystem/HasFileSystemIF.h b/src/fsfw/filesystem/HasFileSystemIF.h index 3f7088d6..4f041135 100644 --- a/src/fsfw/filesystem/HasFileSystemIF.h +++ b/src/fsfw/filesystem/HasFileSystemIF.h @@ -80,7 +80,7 @@ class HasFileSystemIF { virtual bool isDirectory(const char* path) = 0; - virtual bool getFileSize(FilesystemParams params, size_t& fileSize) = 0; + virtual bool getFileSize(FilesystemParams params, uint64_t& fileSize) = 0; virtual bool fileExists(FilesystemParams params) = 0; diff --git a/src/fsfw_hal/host/HostFilesystem.cpp b/src/fsfw_hal/host/HostFilesystem.cpp index e2f8d808..b574c6c0 100644 --- a/src/fsfw_hal/host/HostFilesystem.cpp +++ b/src/fsfw_hal/host/HostFilesystem.cpp @@ -185,7 +185,7 @@ ReturnValue_t HostFilesystem::getBaseFilename(FilesystemParams params, char *nam return returnvalue::OK; } -bool HostFilesystem::getFileSize(FilesystemParams params, size_t &fileSize) { +bool HostFilesystem::getFileSize(FilesystemParams params, uint64_t &fileSize) { if (!fileExists(params)) { return false; } diff --git a/src/fsfw_hal/host/HostFilesystem.h b/src/fsfw_hal/host/HostFilesystem.h index 1946ab9a..fd745e09 100644 --- a/src/fsfw_hal/host/HostFilesystem.h +++ b/src/fsfw_hal/host/HostFilesystem.h @@ -11,7 +11,7 @@ class HostFilesystem : public HasFileSystemIF { ReturnValue_t getBaseFilename(FilesystemParams params, char *nameBuf, size_t maxLen, size_t &baseNameLen) override; - virtual bool getFileSize(FilesystemParams params, size_t &fileSize) override; + virtual bool getFileSize(FilesystemParams params, uint64_t &fileSize) override; bool isDirectory(const char *path) override; bool fileExists(FilesystemParams params) override; ReturnValue_t truncateFile(FilesystemParams params) override; From 60dcacf432aa0a7b739f8fdf8bf4aaa37ac614e5 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 14 Aug 2023 20:47:27 +0200 Subject: [PATCH 082/101] further tweaks for both CFDP handlers --- src/fsfw/cfdp/handler/DestHandler.cpp | 2 +- src/fsfw/cfdp/handler/DestHandler.h | 2 +- src/fsfw/cfdp/handler/SourceHandler.cpp | 13 ++++++++++--- src/fsfw/cfdp/handler/SourceHandler.h | 2 +- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/fsfw/cfdp/handler/DestHandler.cpp b/src/fsfw/cfdp/handler/DestHandler.cpp index 4814917f..953cad86 100644 --- a/src/fsfw/cfdp/handler/DestHandler.cpp +++ b/src/fsfw/cfdp/handler/DestHandler.cpp @@ -23,7 +23,7 @@ cfdp::DestHandler::DestHandler(DestHandlerParams params, FsfwParams fsfwParams) transactionParams.pduConf.direction = cfdp::Direction::TOWARDS_SENDER; } -const cfdp::DestHandler::FsmResult& cfdp::DestHandler::performStateMachine() { +const cfdp::DestHandler::FsmResult& cfdp::DestHandler::stateMachine() { ReturnValue_t result; uint8_t errorIdx = 0; fsmRes.resetOfIteration(); diff --git a/src/fsfw/cfdp/handler/DestHandler.h b/src/fsfw/cfdp/handler/DestHandler.h index c9436b35..0940ab70 100644 --- a/src/fsfw/cfdp/handler/DestHandler.h +++ b/src/fsfw/cfdp/handler/DestHandler.h @@ -92,7 +92,7 @@ class DestHandler { * - @c returnvalue::OK State machine OK for this execution cycle * - @c CALL_FSM_AGAIN State machine should be called again. */ - const FsmResult& performStateMachine(); + const FsmResult& stateMachine(); void setMsgQueue(MessageQueueIF& queue); void setEventReporter(EventReportingProxyIF& reporter); diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index 105a8f17..959dfb00 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -63,6 +63,7 @@ cfdp::SourceHandler::FsmResult& cfdp::SourceHandler::fsmNacked() { if (result != OK) { // TODO: Error handling } + fsmResult.callStatus = CallStatus::CALL_AGAIN; return fsmResult; } if (step == TransactionStep::SENDING_FILE_DATA) { @@ -72,6 +73,7 @@ cfdp::SourceHandler::FsmResult& cfdp::SourceHandler::fsmNacked() { // TODO: Error handling } if (!noFdPdu) { + fsmResult.callStatus = CallStatus::CALL_AGAIN; return fsmResult; } } @@ -85,9 +87,12 @@ cfdp::SourceHandler::FsmResult& cfdp::SourceHandler::fsmNacked() { } if (transactionParams.closureRequested) { step = TransactionStep::WAIT_FOR_FINISH; - return fsmResult; + fsmResult.callStatus = CallStatus::CALL_AFTER_DELAY; + } else { + step = TransactionStep::NOTICE_OF_COMPLETION; + fsmResult.callStatus = CallStatus::CALL_AGAIN; } - step = TransactionStep::NOTICE_OF_COMPLETION; + return fsmResult; } if (step == TransactionStep::WAIT_FOR_FINISH) { // TODO: In case this is a request with closure, wait for finish. @@ -101,9 +106,10 @@ cfdp::SourceHandler::FsmResult& cfdp::SourceHandler::fsmNacked() { return fsmResult; } -cfdp::SourceHandler::FsmResult& cfdp::SourceHandler::stateMachine() { +const cfdp::SourceHandler::FsmResult& cfdp::SourceHandler::stateMachine() { fsmResult.packetsSent = 0; fsmResult.errors = 0; + fsmResult.callStatus = CallStatus::DONE; if (state == cfdp::CfdpState::IDLE) { return fsmResult; } @@ -346,6 +352,7 @@ ReturnValue_t cfdp::SourceHandler::noticeOfCompletion() { ReturnValue_t cfdp::SourceHandler::reset() { step = TransactionStep::IDLE; state = cfdp::CfdpState::IDLE; + fsmResult.callStatus = CallStatus::DONE; transactionParams.reset(); return OK; } diff --git a/src/fsfw/cfdp/handler/SourceHandler.h b/src/fsfw/cfdp/handler/SourceHandler.h index 3aaaf789..60634e0a 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.h +++ b/src/fsfw/cfdp/handler/SourceHandler.h @@ -59,7 +59,7 @@ class SourceHandler { * @return */ ReturnValue_t transactionStart(PutRequest& putRequest, RemoteEntityCfg& cfg); - FsmResult& stateMachine(); + const FsmResult& stateMachine(); ReturnValue_t initialize(); From 22df8f61474d03f518edf2f9d6a57e1944f587e7 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 14 Aug 2023 21:01:29 +0200 Subject: [PATCH 083/101] fix the tests --- unittests/cfdp/handler/testDestHandler.cpp | 30 +++++------ unittests/cfdp/handler/testSourceHandler.cpp | 52 ++++++++++++-------- 2 files changed, 46 insertions(+), 36 deletions(-) diff --git a/unittests/cfdp/handler/testDestHandler.cpp b/unittests/cfdp/handler/testDestHandler.cpp index 5ed0cd4e..4aa2dc32 100644 --- a/unittests/cfdp/handler/testDestHandler.cpp +++ b/unittests/cfdp/handler/testDestHandler.cpp @@ -134,7 +134,7 @@ TEST_CASE("CFDP Dest Handler", "[cfdp]") { } SECTION("Idle State Machine Iteration") { - auto res = destHandler.performStateMachine(); + auto res = destHandler.stateMachine(); CHECK(res.result == OK); CHECK(res.callStatus == CallStatus::CALL_AFTER_DELAY); CHECK(res.errors == 0); @@ -143,23 +143,23 @@ TEST_CASE("CFDP Dest Handler", "[cfdp]") { } SECTION("Empty File Transfer") { - const DestHandler::FsmResult& res = destHandler.performStateMachine(); + const DestHandler::FsmResult& res = destHandler.stateMachine(); CHECK(res.result == OK); Fss cfdpFileSize(0); metadataPreparation(cfdpFileSize, ChecksumType::NULL_CHECKSUM); - destHandler.performStateMachine(); + destHandler.stateMachine(); metadataCheck(res, "hello.txt", "hello-cpy.txt", 0); - destHandler.performStateMachine(); + destHandler.stateMachine(); REQUIRE(res.callStatus == CallStatus::CALL_AFTER_DELAY); auto transactionId = destHandler.getTransactionId(); eofPreparation(cfdpFileSize, 0); // After EOF, operation is done because no closure was requested - destHandler.performStateMachine(); + destHandler.stateMachine(); eofCheck(res, transactionId); } SECTION("Small File Transfer") { - const DestHandler::FsmResult& res = destHandler.performStateMachine(); + const DestHandler::FsmResult& res = destHandler.stateMachine(); CHECK(res.result == OK); std::string fileData = "hello test data"; etl::crc32 crcCalc; @@ -167,9 +167,9 @@ TEST_CASE("CFDP Dest Handler", "[cfdp]") { uint32_t crc32 = crcCalc.value(); Fss cfdpFileSize(fileData.size()); metadataPreparation(cfdpFileSize, ChecksumType::CRC_32); - destHandler.performStateMachine(); + destHandler.stateMachine(); metadataCheck(res, "hello.txt", "hello-cpy.txt", fileData.size()); - destHandler.performStateMachine(); + destHandler.stateMachine(); REQUIRE(res.callStatus == CallStatus::CALL_AFTER_DELAY); auto transactionId = destHandler.getTransactionId(); Fss offset(0); @@ -180,16 +180,16 @@ TEST_CASE("CFDP Dest Handler", "[cfdp]") { REQUIRE(fdPduCreator.serialize(buf, serLen, fdPduCreator.getSerializedSize()) == OK); PacketInfo packetInfo(fdPduCreator.getPduType(), storeId, std::nullopt); packetInfoList.push_back(packetInfo); - destHandler.performStateMachine(); + destHandler.stateMachine(); fileDataPduCheck(res, {storeId}); eofPreparation(cfdpFileSize, crc32); // After EOF, operation is done because no closure was requested - destHandler.performStateMachine(); + destHandler.stateMachine(); eofCheck(res, transactionId); } SECTION("Segmented File Transfer") { - const DestHandler::FsmResult& res = destHandler.performStateMachine(); + const DestHandler::FsmResult& res = destHandler.stateMachine(); CHECK(res.result == OK); std::random_device dev; std::mt19937 rng(dev()); @@ -203,9 +203,9 @@ TEST_CASE("CFDP Dest Handler", "[cfdp]") { uint32_t crc32 = crcCalc.value(); Fss cfdpFileSize(largerFileData.size()); metadataPreparation(cfdpFileSize, ChecksumType::CRC_32); - destHandler.performStateMachine(); + destHandler.stateMachine(); metadataCheck(res, "hello.txt", "hello-cpy.txt", largerFileData.size()); - destHandler.performStateMachine(); + destHandler.stateMachine(); REQUIRE(res.callStatus == CallStatus::CALL_AFTER_DELAY); auto transactionId = destHandler.getTransactionId(); @@ -234,11 +234,11 @@ TEST_CASE("CFDP Dest Handler", "[cfdp]") { packetInfoList.push_back(packetInfo); } - destHandler.performStateMachine(); + destHandler.stateMachine(); fileDataPduCheck(res, idsToCheck); eofPreparation(cfdpFileSize, crc32); // After EOF, operation is done because no closure was requested - destHandler.performStateMachine(); + destHandler.stateMachine(); eofCheck(res, transactionId); } } \ No newline at end of file diff --git a/unittests/cfdp/handler/testSourceHandler.cpp b/unittests/cfdp/handler/testSourceHandler.cpp index 64f6c050..04e79713 100644 --- a/unittests/cfdp/handler/testSourceHandler.cpp +++ b/unittests/cfdp/handler/testSourceHandler.cpp @@ -63,7 +63,7 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { PutRequest putRequest(remoteId, srcNameLv, destNameLv); CHECK(sourceHandler.initialize() == OK); - auto onePduSentCheck = [&](SourceHandler::FsmResult& fsmResult, TmTcMessage& tmtcMessage, + auto onePduSentCheck = [&](const SourceHandler::FsmResult& fsmResult, TmTcMessage& tmtcMessage, const uint8_t** pduPtr) { CHECK(fsmResult.errors == 0); CHECK(fsmResult.packetsSent == 1); @@ -74,8 +74,8 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { *pduPtr = accessor.second.data(); return std::move(accessor); }; - auto genericMetadataCheck = [&](SourceHandler::FsmResult& fsmResult, size_t expectedFileSize, - uint16_t expectedSeqNum) { + auto genericMetadataCheck = [&](const SourceHandler::FsmResult& fsmResult, + size_t expectedFileSize, uint16_t expectedSeqNum) { CHECK(fsmResult.errors == 0); TmTcMessage tmtcMessage; const uint8_t* pduPtr; @@ -108,7 +108,7 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { CHECK(!metadataInfo.isClosureRequested()); mqMock.clearMessages(); }; - auto genericEofCheck = [&](SourceHandler::FsmResult& fsmResult, size_t expectedFileSize, + auto genericEofCheck = [&](const SourceHandler::FsmResult& fsmResult, size_t expectedFileSize, uint32_t expectedChecksum, uint16_t expectedSeqNum) { CHECK(fsmResult.errors == 0); TmTcMessage tmtcMessage; @@ -126,12 +126,19 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { auto transactionId = TransactionId(localId, seqNum); CHECK(userMock.eofSentRecvd.size() == 1); CHECK(userMock.eofSentRecvd.back() == transactionId); - CHECK(userMock.finishedRecvd.size() == 1); - CHECK(userMock.finishedRecvd.back().first == transactionId); CHECK(eofInfo.getChecksum() == expectedChecksum); CHECK(eofInfo.getConditionCode() == ConditionCode::NO_ERROR); CHECK(eofInfo.getFileSize().value() == expectedFileSize); }; + auto genericNoticeOfCompletionCheck = [&](const SourceHandler::FsmResult& fsmResult, + uint16_t expectedSeqNum) { + CHECK(userMock.finishedRecvd.size() == 1); + CHECK(userMock.finishedRecvd.back().first == + TransactionId(localId, TransactionSeqNum(cfdp::WidthInBytes::TWO_BYTES, expectedSeqNum))); + CHECK(sourceHandler.getStep() == SourceHandler::TransactionStep::IDLE); + CHECK(sourceHandler.getState() == CfdpState::IDLE); + }; + SECTION("Test Basic") { CHECK(sourceHandler.getState() == CfdpState::IDLE); CHECK(sourceHandler.getStep() == SourceHandler::TransactionStep::IDLE); @@ -141,16 +148,17 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { CHECK(sourceHandler.transactionStart(putRequest, cfg) == OK); size_t expectedFileSize = 0; - SourceHandler::FsmResult& fsmResult = sourceHandler.stateMachine(); + const SourceHandler::FsmResult& fsmResult = sourceHandler.stateMachine(); // Verify metadata PDU was sent. genericMetadataCheck(fsmResult, expectedFileSize, 0); - fsmResult = sourceHandler.stateMachine(); + sourceHandler.stateMachine(); // Verify EOF PDU was sent. No file data PDU is sent for an empty file and the checksum is 0. genericEofCheck(fsmResult, expectedFileSize, 0, 0); - CHECK(sourceHandler.getStep() == SourceHandler::TransactionStep::IDLE); - CHECK(sourceHandler.getState() == CfdpState::IDLE); + // Verify notice of completion. + sourceHandler.stateMachine(); + genericNoticeOfCompletionCheck(fsmResult, 0); } SECTION("Transfer small file") { @@ -161,13 +169,13 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { FileOpParams params(srcFileName.c_str(), expectedFileSize); fsMock.writeToFile(params, reinterpret_cast(fileContent.data())); CHECK(sourceHandler.transactionStart(putRequest, cfg) == OK); - SourceHandler::FsmResult& fsmResult = sourceHandler.stateMachine(); + const SourceHandler::FsmResult& fsmResult = sourceHandler.stateMachine(); // Verify metadata PDU was sent. genericMetadataCheck(fsmResult, expectedFileSize, expectedSeqNum); // Verify that a small file data PDU was sent. - fsmResult = sourceHandler.stateMachine(); + sourceHandler.stateMachine(); TmTcMessage tmtcMessage; const uint8_t* pduPtr; auto accessor = onePduSentCheck(fsmResult, tmtcMessage, &pduPtr); @@ -185,15 +193,16 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { CHECK(dataReadBack == fileContent); mqMock.clearMessages(); - fsmResult = sourceHandler.stateMachine(); + sourceHandler.stateMachine(); etl::crc32 crcCalc; crcCalc.add(fileContent.data(), fileContent.data() + fileContent.size()); // Verify EOF PDU was sent. genericEofCheck(fsmResult, expectedFileSize, crcCalc.value(), expectedSeqNum); - CHECK(sourceHandler.getStep() == SourceHandler::TransactionStep::IDLE); - CHECK(sourceHandler.getState() == CfdpState::IDLE); + // Verify notice of completion. + sourceHandler.stateMachine(); + genericNoticeOfCompletionCheck(fsmResult, expectedSeqNum); } SECTION("Transfer two segment file") { @@ -212,12 +221,12 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { FileOpParams params(srcFileName.c_str(), expectedFileSize); fsMock.writeToFile(params, reinterpret_cast(largerFileData.data())); CHECK(sourceHandler.transactionStart(putRequest, cfg) == OK); - SourceHandler::FsmResult& fsmResult = sourceHandler.stateMachine(); + const SourceHandler::FsmResult& fsmResult = sourceHandler.stateMachine(); // Verify metadata PDU was sent. genericMetadataCheck(fsmResult, expectedFileSize, expectedSeqNum); // Check first file data PDU. It should have the maximum file segment size. - fsmResult = sourceHandler.stateMachine(); + sourceHandler.stateMachine(); TmTcMessage tmtcMessage; const uint8_t* pduPtr; FileDataInfo fdInfo; @@ -239,7 +248,7 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { mqMock.clearMessages(); // Check second file data PDU. - fsmResult = sourceHandler.stateMachine(); + sourceHandler.stateMachine(); auto 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). @@ -256,14 +265,15 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { mqMock.clearMessages(); // Check EOF and verify checksum. - fsmResult = sourceHandler.stateMachine(); + sourceHandler.stateMachine(); etl::crc32 crcCalc; crcCalc.add(largerFileData.data(), largerFileData.data() + largerFileData.size()); // Verify EOF PDU was sent. genericEofCheck(fsmResult, expectedFileSize, crcCalc.value(), expectedSeqNum); - CHECK(sourceHandler.getStep() == SourceHandler::TransactionStep::IDLE); - CHECK(sourceHandler.getState() == CfdpState::IDLE); + // Verify notice of completion. + sourceHandler.stateMachine(); + genericNoticeOfCompletionCheck(fsmResult, expectedSeqNum); } } \ No newline at end of file From cb1aaea6cd10f34bf46adf8f91f86af1fb42041a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 14 Aug 2023 21:04:22 +0200 Subject: [PATCH 084/101] add more checks --- unittests/cfdp/handler/testSourceHandler.cpp | 31 ++++++++++++-------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/unittests/cfdp/handler/testSourceHandler.cpp b/unittests/cfdp/handler/testSourceHandler.cpp index 04e79713..7fbec9a1 100644 --- a/unittests/cfdp/handler/testSourceHandler.cpp +++ b/unittests/cfdp/handler/testSourceHandler.cpp @@ -77,6 +77,7 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { auto genericMetadataCheck = [&](const SourceHandler::FsmResult& fsmResult, size_t expectedFileSize, uint16_t expectedSeqNum) { CHECK(fsmResult.errors == 0); + CHECK(fsmResult.callStatus == CallStatus::CALL_AGAIN); TmTcMessage tmtcMessage; const uint8_t* pduPtr; auto accessor = onePduSentCheck(fsmResult, tmtcMessage, &pduPtr); @@ -111,6 +112,7 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { auto genericEofCheck = [&](const SourceHandler::FsmResult& fsmResult, size_t expectedFileSize, uint32_t expectedChecksum, uint16_t expectedSeqNum) { CHECK(fsmResult.errors == 0); + CHECK(fsmResult.callStatus == CallStatus::CALL_AGAIN); TmTcMessage tmtcMessage; const uint8_t* pduPtr; auto accessor = onePduSentCheck(fsmResult, tmtcMessage, &pduPtr); @@ -132,6 +134,7 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { }; auto genericNoticeOfCompletionCheck = [&](const SourceHandler::FsmResult& fsmResult, uint16_t expectedSeqNum) { + CHECK(fsmResult.callStatus == CallStatus::DONE); CHECK(userMock.finishedRecvd.size() == 1); CHECK(userMock.finishedRecvd.back().first == TransactionId(localId, TransactionSeqNum(cfdp::WidthInBytes::TWO_BYTES, expectedSeqNum))); @@ -231,6 +234,7 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { const uint8_t* pduPtr; FileDataInfo fdInfo; { + CHECK(fsmResult.callStatus == CallStatus::CALL_AGAIN); auto accessor = onePduSentCheck(fsmResult, tmtcMessage, &pduPtr); FileDataReader fdReader(pduPtr, accessor.second.size(), fdInfo); // 10 byte PDU header, 4 byte offset, 255 byte file data @@ -249,18 +253,21 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") { // Check second file data PDU. sourceHandler.stateMachine(); - auto 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]); + { + CHECK(fsmResult.callStatus == CallStatus::CALL_AGAIN); + auto 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]); + } } mqMock.clearMessages(); From 8c1168524049ef0e5b2144b6c04aeb01538053c2 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 14 Aug 2023 21:19:35 +0200 Subject: [PATCH 085/101] introduce handling for full target queue --- src/fsfw/cfdp/handler/SourceHandler.cpp | 5 ++++- src/fsfw/cfdp/handler/defs.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index 959dfb00..b9d06b92 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -333,7 +333,10 @@ ReturnValue_t cfdp::SourceHandler::sendGenericPdu(const SerializeIF& pdu) { TmTcMessage tmMsg(storeId); result = fsfwParams.msgQueue->sendMessage(fsfwParams.packetDest.getReportReceptionQueue(), &tmMsg); - if (result == OK) { + if (result == MessageQueueIF::FULL) { + fsmResult.callStatus = CallStatus::CALL_AFTER_DELAY; + return TARGET_MSG_QUEUE_FULL; + } else if (result == OK) { fsmResult.packetsSent += 1; } return result; diff --git a/src/fsfw/cfdp/handler/defs.h b/src/fsfw/cfdp/handler/defs.h index c1a3fbfd..7c1c4bf7 100644 --- a/src/fsfw/cfdp/handler/defs.h +++ b/src/fsfw/cfdp/handler/defs.h @@ -67,6 +67,7 @@ static constexpr ReturnValue_t FILE_SEGMENT_LEN_INVALID = returnvalue::makeCode( static constexpr ReturnValue_t SOURCE_NAME_EMPTY = returnvalue::makeCode(CID, 3); static constexpr ReturnValue_t DEST_NAME_EMPTY = returnvalue::makeCode(CID, 4); static constexpr ReturnValue_t WRONG_REMOTE_CFG_ENTITY_ID = returnvalue::makeCode(CID, 5); +static constexpr ReturnValue_t TARGET_MSG_QUEUE_FULL = returnvalue::makeCode(CID, 6); } // namespace cfdp #endif // FSFW_CFDP_HANDLER_DEFS_H From 073cb4b3d5f9955d940848fc6d5233090771c213 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 16 Aug 2023 13:10:21 +0200 Subject: [PATCH 086/101] adaptions for reserved message handling --- .../cfdp/handler/ReservedMessageParser.cpp | 20 ++++++++----------- src/fsfw/cfdp/handler/ReservedMessageParser.h | 3 ++- src/fsfw/cfdp/tlv/MessageToUserTlv.cpp | 2 +- src/fsfw/cfdp/tlv/Tlv.cpp | 3 +++ src/fsfw/cfdp/tlv/Tlv.h | 2 ++ .../cfdp/handler/testReservedMsgParser.cpp | 6 +++--- 6 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/fsfw/cfdp/handler/ReservedMessageParser.cpp b/src/fsfw/cfdp/handler/ReservedMessageParser.cpp index 1165adb1..88d909c1 100644 --- a/src/fsfw/cfdp/handler/ReservedMessageParser.cpp +++ b/src/fsfw/cfdp/handler/ReservedMessageParser.cpp @@ -13,24 +13,21 @@ cfdp::ReservedMessageParser::ReservedMessageParser(StorageManagerIF& ipcStore, MessageQueueId_t userDestination) : msgQueue(msgQueue), ipcStore(ipcStore), userDestination(userDestination) {} -ReturnValue_t cfdp::ReservedMessageParser::parse(const uint8_t* msgsToUserPtr, - size_t sizeOfMessages) { +ReturnValue_t cfdp::ReservedMessageParser::parse(const MessageToUserTlv* msgsToUserArray, + size_t numMsgToUser) { ReturnValue_t result; - size_t currentIdx = 0; - const uint8_t* currentPtr = msgsToUserPtr; - MessageToUserTlv tlv; - size_t deserSize = sizeOfMessages; cfdp::StringLv sourceFileName; cfdp::StringLv destFileName; PutRequest putRequest; + const uint8_t* currentPtr = nullptr; + size_t deserSize = 0; bool needToSendPutRequest = false; - while (currentIdx < sizeOfMessages) { - result = tlv.deSerialize(¤tPtr, &deserSize, SerializeIF::Endianness::NETWORK); - if (result != returnvalue::OK) { - return result; + for (size_t idx = 0; idx < numMsgToUser; idx++) { + if (&msgsToUserArray[idx] == nullptr) { + continue; } uint8_t messageType = 0; - if (tlv.isReservedCfdpMessage(messageType, ¤tPtr, deserSize)) { + if (msgsToUserArray[idx].isReservedCfdpMessage(messageType, ¤tPtr, deserSize)) { if (messageType == static_cast(ProxyOpMessageType::PUT_REQUEST)) { EntityId entityIdLv; entityIdLv.deSerializeFromLv(¤tPtr, &deserSize); @@ -52,7 +49,6 @@ ReturnValue_t cfdp::ReservedMessageParser::parse(const uint8_t* msgsToUserPtr, needToSendPutRequest = true; } } - currentIdx += tlv.getSerializedSize(); } if (needToSendPutRequest) { store_address_t storeId; diff --git a/src/fsfw/cfdp/handler/ReservedMessageParser.h b/src/fsfw/cfdp/handler/ReservedMessageParser.h index 9de4a4a4..2b5c89b2 100644 --- a/src/fsfw/cfdp/handler/ReservedMessageParser.h +++ b/src/fsfw/cfdp/handler/ReservedMessageParser.h @@ -1,5 +1,6 @@ #pragma once +#include "fsfw/cfdp/tlv/MessageToUserTlv.h" #include "fsfw/ipc/MessageQueueIF.h" #include "fsfw/storagemanager/StorageManagerIF.h" @@ -15,7 +16,7 @@ class ReservedMessageParser { ReservedMessageParser(StorageManagerIF& ipcStore, MessageQueueIF& msgQueue, MessageQueueId_t userDestination); - ReturnValue_t parse(const uint8_t* msgsToUserPtr, size_t sizeOfMessages); + ReturnValue_t parse(const MessageToUserTlv* msgsToUserArray, size_t numMsgsToUser); private: MessageQueueIF& msgQueue; diff --git a/src/fsfw/cfdp/tlv/MessageToUserTlv.cpp b/src/fsfw/cfdp/tlv/MessageToUserTlv.cpp index eaf17b67..714379b6 100644 --- a/src/fsfw/cfdp/tlv/MessageToUserTlv.cpp +++ b/src/fsfw/cfdp/tlv/MessageToUserTlv.cpp @@ -16,7 +16,7 @@ bool MessageToUserTlv::isReservedCfdpMessage(uint8_t& messageType, const uint8_t if (cfdp::Tlv::getLengthField() < 5) { return false; } - if (std::strcmp(reinterpret_cast(getValue()), "cfdp") == 0) { + if (std::strncmp(reinterpret_cast(getValue()), "cfdp", 4) == 0) { messageType = getValue()[4]; if (msgDataStart != nullptr) { *msgDataStart = getValue() + 5; diff --git a/src/fsfw/cfdp/tlv/Tlv.cpp b/src/fsfw/cfdp/tlv/Tlv.cpp index c3fce612..39635e53 100644 --- a/src/fsfw/cfdp/tlv/Tlv.cpp +++ b/src/fsfw/cfdp/tlv/Tlv.cpp @@ -54,6 +54,7 @@ ReturnValue_t cfdp::Tlv::deSerialize(const uint8_t **buffer, size_t *size, return STREAM_TOO_SHORT; } + rawData = *buffer; uint8_t rawType = **buffer; if (not checkType(rawType)) { return INVALID_TLV_TYPE; @@ -102,3 +103,5 @@ void cfdp::Tlv::setValue(uint8_t *value, size_t len) { uint8_t cfdp::Tlv::getLengthField() const { return this->value.getSerializedSize() - 1; } void cfdp::Tlv::setType(TlvType type) { this->type = type; } + +const uint8_t *cfdp::Tlv::getRawData() const { return rawData; } diff --git a/src/fsfw/cfdp/tlv/Tlv.h b/src/fsfw/cfdp/tlv/Tlv.h index 786a3b79..deea12c3 100644 --- a/src/fsfw/cfdp/tlv/Tlv.h +++ b/src/fsfw/cfdp/tlv/Tlv.h @@ -47,6 +47,7 @@ class Tlv : public TlvIF { void setValue(uint8_t *value, size_t len); [[nodiscard]] const uint8_t *getValue() const; + [[nodiscard]] const uint8_t *getRawData() const; void setType(TlvType type); [[nodiscard]] TlvType getType() const override; [[nodiscard]] uint8_t getLengthField() const override; @@ -55,6 +56,7 @@ class Tlv : public TlvIF { bool checkType(uint8_t rawType); bool zeroLen = true; + const uint8_t *rawData = nullptr; TlvType type = TlvType::INVALID_TLV; SerialBufferAdapter value; }; diff --git a/unittests/cfdp/handler/testReservedMsgParser.cpp b/unittests/cfdp/handler/testReservedMsgParser.cpp index 3379f563..e87dc06d 100644 --- a/unittests/cfdp/handler/testReservedMsgParser.cpp +++ b/unittests/cfdp/handler/testReservedMsgParser.cpp @@ -40,10 +40,10 @@ TEST_CASE("Reserved Message Parser", "[cfdp]") { serLen = 0; ReturnValue_t result = creator.serializeBe(buffer.data(), serLen, buffer.size()); CHECK(result == returnvalue::OK); - arrayprinter::print(buffer.data(), serLen); - + MessageToUserTlv msgToUser; + CHECK(msgToUser.deSerializeBe(buffer.data(), serLen, buffer.size()) == OK); ReservedMessageParser parser(ipcStore, msgQueue, destQueueId); - REQUIRE(parser.parse(buffer.data(), serLen) == OK); + REQUIRE(parser.parse(&msgToUser, 1) == OK); CommandMessage msg; CHECK(msgQueue.wasMessageSent()); CHECK(msgQueue.numberOfSentMessages() == 1); From 9ef63825f3d8486b05c3f6193ae0503833e6f8a4 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 16 Aug 2023 13:15:34 +0200 Subject: [PATCH 087/101] optimization --- src/fsfw/cfdp/handler/DestHandler.cpp | 8 ++++---- src/fsfw/cfdp/handler/UserBase.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/fsfw/cfdp/handler/DestHandler.cpp b/src/fsfw/cfdp/handler/DestHandler.cpp index 953cad86..999cb155 100644 --- a/src/fsfw/cfdp/handler/DestHandler.cpp +++ b/src/fsfw/cfdp/handler/DestHandler.cpp @@ -356,15 +356,15 @@ ReturnValue_t cfdp::DestHandler::startTransaction(MetadataPduReader& reader, transactionParams.fileSize); params.destFileName = transactionParams.destName.data(); params.sourceFileName = transactionParams.sourceName.data(); - unsigned tlvIdx = 0; + params.numberOfMsgsToUser = 0; for (const auto& opt : tlvVec) { if (opt.getType() == TlvType::MSG_TO_USER) { - msgToUserVec[tlvIdx] = MessageToUserTlv(opt.getValue(), opt.getLengthField()); - tlvIdx++; + msgToUserVec[params.numberOfMsgsToUser] = + MessageToUserTlv(opt.getValue(), opt.getLengthField()); + params.numberOfMsgsToUser++; } } params.msgsToUserArray = msgToUserVec.data(); - params.msgsToUserLen = tlvIdx; destParams.user.metadataRecvdIndication(params); return result; } diff --git a/src/fsfw/cfdp/handler/UserBase.h b/src/fsfw/cfdp/handler/UserBase.h index 47df48c0..6141eea9 100644 --- a/src/fsfw/cfdp/handler/UserBase.h +++ b/src/fsfw/cfdp/handler/UserBase.h @@ -35,7 +35,7 @@ struct MetadataRecvdParams { Fss fileSize{}; const char* sourceFileName = ""; const char* destFileName = ""; - size_t msgsToUserLen = 0; + size_t numberOfMsgsToUser = 0; const MessageToUserTlv* msgsToUserArray = nullptr; }; From ea2e58249dc02bfa4114c3759db65fd7e7ffd72b Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 30 Aug 2023 11:18:49 +0200 Subject: [PATCH 088/101] API improvements --- src/fsfw/cfdp/handler/DestHandler.cpp | 6 +++--- src/fsfw/cfdp/handler/DestHandler.h | 2 +- src/fsfw/cfdp/pdu/MetadataGenericInfo.cpp | 4 +++- src/fsfw/cfdp/pdu/MetadataGenericInfo.h | 4 +++- src/fsfw/cfdp/pdu/MetadataPduReader.cpp | 4 +++- src/fsfw/cfdp/pdu/MetadataPduReader.h | 1 + 6 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/fsfw/cfdp/handler/DestHandler.cpp b/src/fsfw/cfdp/handler/DestHandler.cpp index 999cb155..4bb1cf5c 100644 --- a/src/fsfw/cfdp/handler/DestHandler.cpp +++ b/src/fsfw/cfdp/handler/DestHandler.cpp @@ -146,7 +146,7 @@ ReturnValue_t cfdp::DestHandler::handleMetadataPdu(const PacketInfo& info) { return handleMetadataParseError(result, constAccessorPair.second.data(), constAccessorPair.second.size()); } - return startTransaction(reader, metadataInfo); + return startTransaction(reader); } ReturnValue_t cfdp::DestHandler::handleFileDataPdu(const cfdp::PacketInfo& info) { @@ -274,8 +274,7 @@ ReturnValue_t cfdp::DestHandler::handleMetadataParseError(ReturnValue_t result, return returnvalue::FAILED; } -ReturnValue_t cfdp::DestHandler::startTransaction(MetadataPduReader& reader, - MetadataGenericInfo& info) { +ReturnValue_t cfdp::DestHandler::startTransaction(const MetadataPduReader& reader) { if (fsmRes.state != CfdpState::IDLE) { // According to standard, discard metadata PDU if we are busy return OK; @@ -344,6 +343,7 @@ ReturnValue_t cfdp::DestHandler::startTransaction(MetadataPduReader& reader, } else if (reader.getTransmissionMode() == TransmissionMode::ACKNOWLEDGED) { fsmRes.state = CfdpState::BUSY_CLASS_2_ACKED; } + auto& info = reader.getGenericInfo(); transactionParams.checksumType = info.getChecksumType(); transactionParams.closureRequested = info.isClosureRequested(); reader.fillConfig(transactionParams.pduConf); diff --git a/src/fsfw/cfdp/handler/DestHandler.h b/src/fsfw/cfdp/handler/DestHandler.h index 0940ab70..de1104c8 100644 --- a/src/fsfw/cfdp/handler/DestHandler.h +++ b/src/fsfw/cfdp/handler/DestHandler.h @@ -153,7 +153,7 @@ class DestHandler { cfdp::FsfwParams fsfwParams; FsmResult fsmRes; - ReturnValue_t startTransaction(MetadataPduReader& reader, MetadataGenericInfo& info); + ReturnValue_t startTransaction(const MetadataPduReader& reader); ReturnValue_t handleMetadataPdu(const PacketInfo& info); ReturnValue_t handleFileDataPdu(const PacketInfo& info); ReturnValue_t handleEofPdu(const PacketInfo& info); diff --git a/src/fsfw/cfdp/pdu/MetadataGenericInfo.cpp b/src/fsfw/cfdp/pdu/MetadataGenericInfo.cpp index efbe620e..f3b1c751 100644 --- a/src/fsfw/cfdp/pdu/MetadataGenericInfo.cpp +++ b/src/fsfw/cfdp/pdu/MetadataGenericInfo.cpp @@ -21,7 +21,7 @@ void MetadataGenericInfo::setClosureRequested(bool closureRequested_) { closureRequested = closureRequested_; } -cfdp::Fss& MetadataGenericInfo::getFileSize() { return fileSize; } +const cfdp::Fss& MetadataGenericInfo::getFileSize() const { return fileSize; } size_t MetadataGenericInfo::getSerializedSize(bool fssLarge) { // 1 byte + minimal FSS 4 bytes @@ -31,3 +31,5 @@ size_t MetadataGenericInfo::getSerializedSize(bool fssLarge) { } return size; } + +cfdp::Fss& MetadataGenericInfo::getMutFileSize() { return fileSize; } diff --git a/src/fsfw/cfdp/pdu/MetadataGenericInfo.h b/src/fsfw/cfdp/pdu/MetadataGenericInfo.h index 59caabb3..73a54972 100644 --- a/src/fsfw/cfdp/pdu/MetadataGenericInfo.h +++ b/src/fsfw/cfdp/pdu/MetadataGenericInfo.h @@ -22,7 +22,9 @@ class MetadataGenericInfo { [[nodiscard]] bool isClosureRequested() const; void setClosureRequested(bool closureRequested = false); - cfdp::Fss& getFileSize(); + [[nodiscard]] const cfdp::Fss& getFileSize() const; + + cfdp::Fss& getMutFileSize(); private: bool closureRequested = false; diff --git a/src/fsfw/cfdp/pdu/MetadataPduReader.cpp b/src/fsfw/cfdp/pdu/MetadataPduReader.cpp index 69a7d4aa..e6160ce8 100644 --- a/src/fsfw/cfdp/pdu/MetadataPduReader.cpp +++ b/src/fsfw/cfdp/pdu/MetadataPduReader.cpp @@ -25,7 +25,7 @@ ReturnValue_t MetadataPduReader::parseData() { remSize -= 1; buf += 1; auto endianness = getEndianness(); - result = info.getFileSize().deSerialize(&buf, &remSize, endianness); + result = info.getMutFileSize().deSerialize(&buf, &remSize, endianness); if (result != returnvalue::OK) { return result; } @@ -63,3 +63,5 @@ size_t MetadataPduReader::getNumberOfParsedOptions() const { return parsedOption const cfdp::StringLv& MetadataPduReader::getSourceFileName() const { return srcFileName; } const cfdp::StringLv& MetadataPduReader::getDestFileName() const { return destFileName; } + +const MetadataGenericInfo& MetadataPduReader::getGenericInfo() const { return info; } diff --git a/src/fsfw/cfdp/pdu/MetadataPduReader.h b/src/fsfw/cfdp/pdu/MetadataPduReader.h index e619d4f5..a409928e 100644 --- a/src/fsfw/cfdp/pdu/MetadataPduReader.h +++ b/src/fsfw/cfdp/pdu/MetadataPduReader.h @@ -11,6 +11,7 @@ class MetadataPduReader : public FileDirectiveReader { ReturnValue_t parseData() override; + [[nodiscard]] const MetadataGenericInfo& getGenericInfo() const; [[nodiscard]] const cfdp::StringLv& getSourceFileName() const; [[nodiscard]] const cfdp::StringLv& getDestFileName() const; From fb1500e041c4d89316a9bceabc89ed870c8032be Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 30 Aug 2023 11:34:38 +0200 Subject: [PATCH 089/101] continue --- src/fsfw/cfdp/handler/DestHandler.cpp | 28 ++++++++++++---------- src/fsfw/cfdp/tlv/Lv.cpp | 2 ++ src/fsfw/cfdp/tlv/Lv.h | 2 ++ src/fsfw/serialize/SerialBufferAdapter.cpp | 8 ------- src/fsfw/serialize/SerialBufferAdapter.h | 10 ++++++++ 5 files changed, 30 insertions(+), 20 deletions(-) diff --git a/src/fsfw/cfdp/handler/DestHandler.cpp b/src/fsfw/cfdp/handler/DestHandler.cpp index 4bb1cf5c..65a62663 100644 --- a/src/fsfw/cfdp/handler/DestHandler.cpp +++ b/src/fsfw/cfdp/handler/DestHandler.cpp @@ -282,21 +282,25 @@ ReturnValue_t cfdp::DestHandler::startTransaction(const MetadataPduReader& reade ReturnValue_t result = OK; size_t sourceNameSize = 0; - const uint8_t* sourceNamePtr = reader.getSourceFileName().getValue(&sourceNameSize); - if (sourceNameSize + 1 > transactionParams.sourceName.size()) { - fileErrorHandler(events::FILENAME_TOO_LARGE_ERROR, 0, "source filename too large"); - return FAILED; + if (not reader.getSourceFileName().isEmpty()) { + const uint8_t* sourceNamePtr = reader.getSourceFileName().getValue(&sourceNameSize); + if (sourceNameSize + 1 > transactionParams.sourceName.size()) { + fileErrorHandler(events::FILENAME_TOO_LARGE_ERROR, 0, "source filename too large"); + return FAILED; + } + std::memcpy(transactionParams.sourceName.data(), sourceNamePtr, sourceNameSize); + transactionParams.sourceName[sourceNameSize] = '\0'; } - std::memcpy(transactionParams.sourceName.data(), sourceNamePtr, sourceNameSize); - transactionParams.sourceName[sourceNameSize] = '\0'; size_t destNameSize = 0; - const uint8_t* destNamePtr = reader.getDestFileName().getValue(&destNameSize); - if (destNameSize + 1 > transactionParams.destName.size()) { - fileErrorHandler(events::FILENAME_TOO_LARGE_ERROR, 0, "dest filename too large"); - return FAILED; + if (not reader.getDestFileName().isEmpty()) { + const uint8_t* destNamePtr = reader.getDestFileName().getValue(&destNameSize); + if (destNameSize + 1 > transactionParams.destName.size()) { + fileErrorHandler(events::FILENAME_TOO_LARGE_ERROR, 0, "dest filename too large"); + return FAILED; + } + std::memcpy(transactionParams.destName.data(), destNamePtr, destNameSize); + transactionParams.destName[destNameSize] = '\0'; } - std::memcpy(transactionParams.destName.data(), destNamePtr, destNameSize); - transactionParams.destName[destNameSize] = '\0'; // If both dest name size and source name size are 0, we are dealing with a metadata only PDU, // so there is no need to create a file or truncate an existing file diff --git a/src/fsfw/cfdp/tlv/Lv.cpp b/src/fsfw/cfdp/tlv/Lv.cpp index 0daec472..0972d973 100644 --- a/src/fsfw/cfdp/tlv/Lv.cpp +++ b/src/fsfw/cfdp/tlv/Lv.cpp @@ -95,3 +95,5 @@ cfdp::Lv& cfdp::Lv::operator=(cfdp::Lv&& other) noexcept { } size_t cfdp::Lv::getValueLen() const { return getSerializedSize() - 1; } + +bool cfdp::Lv::isEmpty() const { return zeroLen; } diff --git a/src/fsfw/cfdp/tlv/Lv.h b/src/fsfw/cfdp/tlv/Lv.h index c1ab78de..ee8e18c6 100644 --- a/src/fsfw/cfdp/tlv/Lv.h +++ b/src/fsfw/cfdp/tlv/Lv.h @@ -50,6 +50,8 @@ class Lv : public SerializeIF { */ const uint8_t* getValue(size_t* size) const; + bool isEmpty() const; + private: bool zeroLen = true; SerialBufferAdapter value; diff --git a/src/fsfw/serialize/SerialBufferAdapter.cpp b/src/fsfw/serialize/SerialBufferAdapter.cpp index 01eb76f9..3d0de695 100644 --- a/src/fsfw/serialize/SerialBufferAdapter.cpp +++ b/src/fsfw/serialize/SerialBufferAdapter.cpp @@ -107,14 +107,6 @@ uint8_t* SerialBufferAdapter::getBuffer() { template const uint8_t* SerialBufferAdapter::getConstBuffer() const { - if (constBuffer == nullptr) { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "SerialBufferAdapter::getConstBuffer:" - " Buffers are unitialized!" - << std::endl; -#endif - return nullptr; - } return constBuffer; } diff --git a/src/fsfw/serialize/SerialBufferAdapter.h b/src/fsfw/serialize/SerialBufferAdapter.h index 9030d7cc..37bc69b3 100644 --- a/src/fsfw/serialize/SerialBufferAdapter.h +++ b/src/fsfw/serialize/SerialBufferAdapter.h @@ -63,7 +63,17 @@ class SerialBufferAdapter : public SerializeIF { ReturnValue_t deSerialize(const uint8_t** buffer, size_t* size, Endianness streamEndianness) override; + /** + * Please note that this function can also return a nullpointer in case the length field contains + * 0. + * @return + */ uint8_t* getBuffer(); + /** + * Please note that this function can also return a nullpointer in case the length field contains + * 0. + * @return + */ [[nodiscard]] const uint8_t* getConstBuffer() const; void setConstBuffer(const uint8_t* buf, count_t bufLen); From 6e53582dc9c3cb22ddc796461975bc91b1f53e20 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 31 Aug 2023 14:59:09 +0200 Subject: [PATCH 090/101] split up CFDP retval domains --- src/fsfw/cfdp/handler/defs.h | 4 +++- src/fsfw/returnvalues/FwClassIds.h | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/fsfw/cfdp/handler/defs.h b/src/fsfw/cfdp/handler/defs.h index 7c1c4bf7..cafc3afc 100644 --- a/src/fsfw/cfdp/handler/defs.h +++ b/src/fsfw/cfdp/handler/defs.h @@ -12,7 +12,7 @@ namespace cfdp { enum class CfdpState { IDLE, BUSY_CLASS_1_NACKED, BUSY_CLASS_2_ACKED, SUSPENDED }; static constexpr uint8_t SSID = SUBSYSTEM_ID::CFDP; -static constexpr uint8_t CID = CLASS_ID::CFDP; +static constexpr uint8_t CID = CLASS_ID::CFDP_HANDLER; struct PacketInfo { PacketInfo(PduType type, store_address_t storeId, @@ -58,6 +58,8 @@ static constexpr Event SERIALIZATION_ERROR = event::makeEvent(SSID, 2, severity: static constexpr Event FILESTORE_ERROR = event::makeEvent(SSID, 3, severity::LOW); //! [EXPORT] : [COMMENT] P1: Transaction step ID, P2: 0 for source file name, 1 for dest file name static constexpr Event FILENAME_TOO_LARGE_ERROR = event::makeEvent(SSID, 4, severity::LOW); +//! [EXPORT] : [COMMENT] CFDP request handling failed. P2: Returncode. +static constexpr Event HANDLING_CFDP_REQUEST_FAILED = event::makeEvent(SSID, 5, severity::LOW); } // namespace events diff --git a/src/fsfw/returnvalues/FwClassIds.h b/src/fsfw/returnvalues/FwClassIds.h index 9a5cc812..9a4fa992 100644 --- a/src/fsfw/returnvalues/FwClassIds.h +++ b/src/fsfw/returnvalues/FwClassIds.h @@ -61,7 +61,8 @@ enum : uint8_t { HAS_ACTIONS_IF, // HF DEVICE_COMMUNICATION_IF, // DC BSP, // BSP - CFDP, // CFDP + CFDP_BASE, // CFDP + CFDP_HANDLER, // CFDP TIME_STAMPER_IF, // TSI SGP4PROPAGATOR_CLASS, // SGP4 MUTEX_IF, // MUX From dfcfb035bed4469aad2dad034567309d0dda7d29 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 31 Aug 2023 15:09:22 +0200 Subject: [PATCH 091/101] fix some retval duplications --- src/fsfw/cfdp/definitions.h | 2 +- src/fsfw/osal/common/TcpTmTcServer.h | 1 + src/fsfw_hal/stm32h7/spi/SpiComIF.cpp | 4 ++-- src/fsfw_hal/stm32h7/spi/spiDefinitions.h | 5 ----- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/fsfw/cfdp/definitions.h b/src/fsfw/cfdp/definitions.h index 34b8d774..d19d8532 100644 --- a/src/fsfw/cfdp/definitions.h +++ b/src/fsfw/cfdp/definitions.h @@ -17,7 +17,7 @@ static constexpr char CFDP_VERSION_2_NAME[] = "CCSDS 727.0-B-5"; static constexpr uint8_t CFDP_VERSION_2 = 0b001; static constexpr uint8_t VERSION_BITS = CFDP_VERSION_2 << 5; -static constexpr uint8_t CFDP_CLASS_ID = CLASS_ID::CFDP; +static constexpr uint8_t CFDP_CLASS_ID = CLASS_ID::CFDP_BASE; static constexpr ReturnValue_t INVALID_TLV_TYPE = returnvalue::makeCode(CFDP_CLASS_ID, 1); static constexpr ReturnValue_t INVALID_DIRECTIVE_FIELD = returnvalue::makeCode(CFDP_CLASS_ID, 2); diff --git a/src/fsfw/osal/common/TcpTmTcServer.h b/src/fsfw/osal/common/TcpTmTcServer.h index b8c6ea2c..2b549d87 100644 --- a/src/fsfw/osal/common/TcpTmTcServer.h +++ b/src/fsfw/osal/common/TcpTmTcServer.h @@ -123,6 +123,7 @@ class TcpTmTcServer : public SystemObject, public TcpIpBase, public ExecutableOb StorageManagerIF* tmStore = nullptr; private: + //! [EXPORT] : [SKIP] static constexpr ReturnValue_t CONN_BROKEN = returnvalue::makeCode(1, 0); //! TMTC bridge is cached. object_id_t tmtcBridgeId = objects::NO_OBJECT; diff --git a/src/fsfw_hal/stm32h7/spi/SpiComIF.cpp b/src/fsfw_hal/stm32h7/spi/SpiComIF.cpp index 4d688bd5..611b34dc 100644 --- a/src/fsfw_hal/stm32h7/spi/SpiComIF.cpp +++ b/src/fsfw_hal/stm32h7/spi/SpiComIF.cpp @@ -282,7 +282,7 @@ ReturnValue_t SpiComIF::handlePollingSendOperation(uint8_t *recvPtr, SPI_HandleT #endif #endif spiCookie.setTransferState(spi::TransferStates::FAILURE); - return spi::HAL_TIMEOUT_RETVAL; + return spi::TIMEOUT; } case (HAL_ERROR): default: { @@ -296,7 +296,7 @@ ReturnValue_t SpiComIF::handlePollingSendOperation(uint8_t *recvPtr, SPI_HandleT #endif #endif spiCookie.setTransferState(spi::TransferStates::FAILURE); - return spi::HAL_ERROR_RETVAL; + return spi::GENERIC_ERROR; } } return returnvalue::OK; diff --git a/src/fsfw_hal/stm32h7/spi/spiDefinitions.h b/src/fsfw_hal/stm32h7/spi/spiDefinitions.h index cf05d986..60c662b1 100644 --- a/src/fsfw_hal/stm32h7/spi/spiDefinitions.h +++ b/src/fsfw_hal/stm32h7/spi/spiDefinitions.h @@ -9,11 +9,6 @@ namespace spi { -static constexpr uint8_t HAL_SPI_ID = CLASS_ID::HAL_SPI; -static constexpr ReturnValue_t HAL_TIMEOUT_RETVAL = returnvalue::makeCode(HAL_SPI_ID, 0); -static constexpr ReturnValue_t HAL_BUSY_RETVAL = returnvalue::makeCode(HAL_SPI_ID, 1); -static constexpr ReturnValue_t HAL_ERROR_RETVAL = returnvalue::makeCode(HAL_SPI_ID, 2); - enum class TransferStates { IDLE, WAIT, SUCCESS, FAILURE }; enum SpiBus { SPI_1, SPI_2 }; From 470f589bde405c39f5a7fbf191b11b8b48058128 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 4 Sep 2023 11:01:55 +0200 Subject: [PATCH 092/101] need to rework this fsm.. but works now --- src/fsfw/cfdp/handler/DestHandler.cpp | 11 +++++++++-- src/fsfw/cfdp/handler/DestHandler.h | 2 ++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/fsfw/cfdp/handler/DestHandler.cpp b/src/fsfw/cfdp/handler/DestHandler.cpp index 65a62663..d9c8793d 100644 --- a/src/fsfw/cfdp/handler/DestHandler.cpp +++ b/src/fsfw/cfdp/handler/DestHandler.cpp @@ -302,9 +302,11 @@ ReturnValue_t cfdp::DestHandler::startTransaction(const MetadataPduReader& reade transactionParams.destName[destNameSize] = '\0'; } + transactionParams.metadataOnly = true; // If both dest name size and source name size are 0, we are dealing with a metadata only PDU, // so there is no need to create a file or truncate an existing file if (destNameSize > 0 and sourceNameSize > 0) { + transactionParams.metadataOnly = false; FilesystemParams fparams(transactionParams.destName.data()); // handling to allow only specifying target directory. Example: // Source path /test/hello.txt, dest path /tmp -> dest path /tmp/hello.txt @@ -341,12 +343,18 @@ ReturnValue_t cfdp::DestHandler::startTransaction(const MetadataPduReader& reade #endif return FAILED; } - fsmRes.step = TransactionStep::TRANSACTION_START; if (reader.getTransmissionMode() == TransmissionMode::UNACKNOWLEDGED) { fsmRes.state = CfdpState::BUSY_CLASS_1_NACKED; } else if (reader.getTransmissionMode() == TransmissionMode::ACKNOWLEDGED) { fsmRes.state = CfdpState::BUSY_CLASS_2_ACKED; } + if (transactionParams.metadataOnly) { + fsmRes.step = TransactionStep::TRANSFER_COMPLETION; + } else { + // Kind of ugly, make FSM working on packet per packet basis.. + fsmRes.step = TransactionStep::TRANSACTION_START; + fsmRes.step = TransactionStep::RECEIVING_FILE_DATA_PDUS; + } auto& info = reader.getGenericInfo(); transactionParams.checksumType = info.getChecksumType(); transactionParams.closureRequested = info.isClosureRequested(); @@ -355,7 +363,6 @@ ReturnValue_t cfdp::DestHandler::startTransaction(const MetadataPduReader& reade transactionParams.transactionId.entityId = transactionParams.pduConf.sourceId; transactionParams.transactionId.seqNum = transactionParams.pduConf.seqNum; transactionParams.fileSize = info.getFileSize(); - fsmRes.step = TransactionStep::RECEIVING_FILE_DATA_PDUS; MetadataRecvdParams params(transactionParams.transactionId, transactionParams.pduConf.sourceId, transactionParams.fileSize); params.destFileName = transactionParams.destName.data(); diff --git a/src/fsfw/cfdp/handler/DestHandler.h b/src/fsfw/cfdp/handler/DestHandler.h index de1104c8..370cb274 100644 --- a/src/fsfw/cfdp/handler/DestHandler.h +++ b/src/fsfw/cfdp/handler/DestHandler.h @@ -125,11 +125,13 @@ class DestHandler { crc = 0; progress = 0; remoteCfg = nullptr; + metadataOnly = false; closureRequested = false; vfsErrorCount = 0; checksumType = ChecksumType::NULL_CHECKSUM; } + bool metadataOnly = false; ChecksumType checksumType = ChecksumType::NULL_CHECKSUM; bool closureRequested = false; uint16_t vfsErrorCount = 0; From 448fbd0d388fe0b19de9b65ee7853681306fd546 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 5 Sep 2023 16:04:48 +0200 Subject: [PATCH 093/101] this should be less confusing, saner defaults --- src/fsfw/cfdp/handler/RemoteConfigTableIF.h | 4 ++-- src/fsfw/cfdp/handler/mib.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/fsfw/cfdp/handler/RemoteConfigTableIF.h b/src/fsfw/cfdp/handler/RemoteConfigTableIF.h index d0e6121d..1c1603c9 100644 --- a/src/fsfw/cfdp/handler/RemoteConfigTableIF.h +++ b/src/fsfw/cfdp/handler/RemoteConfigTableIF.h @@ -16,7 +16,7 @@ class RemoteConfigTableIF { */ class OneRemoteConfigProvider : public RemoteConfigTableIF { public: - explicit OneRemoteConfigProvider(RemoteEntityCfg cfg) : cfg(std::move(cfg)) {} + explicit OneRemoteConfigProvider(RemoteEntityCfg& cfg) : cfg(cfg) {} bool getRemoteCfg(const EntityId& remoteId, cfdp::RemoteEntityCfg** cfg_) override { if (remoteId != cfg.remoteId) { @@ -27,7 +27,7 @@ class OneRemoteConfigProvider : public RemoteConfigTableIF { } private: - RemoteEntityCfg cfg; + RemoteEntityCfg& cfg; }; } // namespace cfdp diff --git a/src/fsfw/cfdp/handler/mib.h b/src/fsfw/cfdp/handler/mib.h index 5d6ec8ad..7e4454ef 100644 --- a/src/fsfw/cfdp/handler/mib.h +++ b/src/fsfw/cfdp/handler/mib.h @@ -30,7 +30,7 @@ struct RemoteEntityCfg { RemoteEntityCfg() = default; explicit RemoteEntityCfg(EntityId id) : remoteId(std::move(id)) {} EntityId remoteId; - size_t maxFileSegmentLen = 2048; + size_t maxFileSegmentLen = 1024; bool closureRequested = false; bool crcOnTransmission = false; TransmissionMode defaultTransmissionMode = TransmissionMode::UNACKNOWLEDGED; From c1431984947275f7c2c33c1e671b0e4d17c77f71 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 6 Sep 2023 10:11:09 +0200 Subject: [PATCH 094/101] debugging --- src/fsfw/cfdp/handler/SourceHandler.cpp | 20 ++++++++++++++------ src/fsfw/cfdp/handler/defs.h | 1 + 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index b9d06b92..dcb5d68a 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -11,6 +11,7 @@ #include "fsfw/globalfunctions/arrayprinter.h" #include "fsfw/objectmanager.h" #include "fsfw/serviceinterface.h" +#include "fsfw/tasks/TaskFactory.h" #include "fsfw/tmtcservices/TmTcMessage.h" using namespace returnvalue; @@ -69,13 +70,10 @@ cfdp::SourceHandler::FsmResult& cfdp::SourceHandler::fsmNacked() { if (step == TransactionStep::SENDING_FILE_DATA) { bool noFdPdu = false; result = prepareAndSendNextFileDataPdu(noFdPdu); - if (result != OK) { - // TODO: Error handling - } - if (!noFdPdu) { + if (result == OK and !noFdPdu) { fsmResult.callStatus = CallStatus::CALL_AGAIN; - return fsmResult; } + return fsmResult; } if (step == TransactionStep::SENDING_EOF) { result = prepareAndSendEofPdu(); @@ -269,16 +267,20 @@ ReturnValue_t cfdp::SourceHandler::prepareAndSendNextFileDataPdu(bool& noFileDat addError(result); return result; } + sif::debug << "sending next fd pdu, offset " << offset.value() << "" << std::endl; auto fileDataInfo = FileDataInfo(offset, fileBuf.data(), readLen); auto fileDataPdu = FileDataCreator(transactionParams.pduConf, fileDataInfo); result = sendGenericPdu(fileDataPdu); if (result != OK) { + sif::debug << "SENDING generic PDU failed" << std::endl; return result; } transactionParams.progress += readLen; if (transactionParams.progress >= fileSize) { // Advance FSM after all file data PDUs were sent. step = TransactionStep::SENDING_EOF; + sif::debug << "done" << std::endl; + TaskFactory::delayTask(10000); } return OK; } @@ -322,6 +324,10 @@ ReturnValue_t cfdp::SourceHandler::sendGenericPdu(const SerializeIF& pdu) { fsfwParams.tmStore->getFreeElement(&storeId, pdu.getSerializedSize(), &dataPtr); if (result != OK) { addError(result); + fsmResult.callStatus = CallStatus::CALL_AFTER_DELAY; + if(result == StorageManagerIF::DATA_STORAGE_FULL) { + return TM_STORE_FULL; + } return result; } size_t serializedLen = 0; @@ -333,8 +339,10 @@ ReturnValue_t cfdp::SourceHandler::sendGenericPdu(const SerializeIF& pdu) { TmTcMessage tmMsg(storeId); result = fsfwParams.msgQueue->sendMessage(fsfwParams.packetDest.getReportReceptionQueue(), &tmMsg); - if (result == MessageQueueIF::FULL) { + if(result != OK) { fsmResult.callStatus = CallStatus::CALL_AFTER_DELAY; + } + if (result == MessageQueueIF::FULL) { return TARGET_MSG_QUEUE_FULL; } else if (result == OK) { fsmResult.packetsSent += 1; diff --git a/src/fsfw/cfdp/handler/defs.h b/src/fsfw/cfdp/handler/defs.h index cafc3afc..4356835d 100644 --- a/src/fsfw/cfdp/handler/defs.h +++ b/src/fsfw/cfdp/handler/defs.h @@ -70,6 +70,7 @@ static constexpr ReturnValue_t SOURCE_NAME_EMPTY = returnvalue::makeCode(CID, 3) static constexpr ReturnValue_t DEST_NAME_EMPTY = returnvalue::makeCode(CID, 4); static constexpr ReturnValue_t WRONG_REMOTE_CFG_ENTITY_ID = returnvalue::makeCode(CID, 5); static constexpr ReturnValue_t TARGET_MSG_QUEUE_FULL = returnvalue::makeCode(CID, 6); +static constexpr ReturnValue_t TM_STORE_FULL = returnvalue::makeCode(CID, 7); } // namespace cfdp #endif // FSFW_CFDP_HANDLER_DEFS_H From c4e18cc2f33c12d637d19d66c7ba731cb457a7a2 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 6 Sep 2023 11:45:02 +0200 Subject: [PATCH 095/101] what was i thinking here? --- src/fsfw/cfdp/handler/SourceHandler.cpp | 4 ++-- src/fsfw/tmtcservices/TmTcBridge.cpp | 14 ++------------ src/fsfw/tmtcservices/TmTcBridge.h | 7 +++---- 3 files changed, 7 insertions(+), 18 deletions(-) diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index dcb5d68a..351359c2 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -325,7 +325,7 @@ ReturnValue_t cfdp::SourceHandler::sendGenericPdu(const SerializeIF& pdu) { if (result != OK) { addError(result); fsmResult.callStatus = CallStatus::CALL_AFTER_DELAY; - if(result == StorageManagerIF::DATA_STORAGE_FULL) { + if (result == StorageManagerIF::DATA_STORAGE_FULL) { return TM_STORE_FULL; } return result; @@ -339,7 +339,7 @@ ReturnValue_t cfdp::SourceHandler::sendGenericPdu(const SerializeIF& pdu) { TmTcMessage tmMsg(storeId); result = fsfwParams.msgQueue->sendMessage(fsfwParams.packetDest.getReportReceptionQueue(), &tmMsg); - if(result != OK) { + if (result != OK) { fsmResult.callStatus = CallStatus::CALL_AFTER_DELAY; } if (result == MessageQueueIF::FULL) { diff --git a/src/fsfw/tmtcservices/TmTcBridge.cpp b/src/fsfw/tmtcservices/TmTcBridge.cpp index f098103e..5c819222 100644 --- a/src/fsfw/tmtcservices/TmTcBridge.cpp +++ b/src/fsfw/tmtcservices/TmTcBridge.cpp @@ -23,18 +23,8 @@ TmTcBridge::TmTcBridge(const char* name, object_id_t objectId, object_id_t tcDes TmTcBridge::~TmTcBridge() { QueueFactory::instance()->deleteMessageQueue(tmTcReceptionQueue); } -ReturnValue_t TmTcBridge::setNumberOfSentPacketsPerCycle(uint8_t sentPacketsPerCycle) { - if (sentPacketsPerCycle <= LIMIT_STORED_DATA_SENT_PER_CYCLE) { - this->sentPacketsPerCycle = sentPacketsPerCycle; - return returnvalue::OK; - } else { -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "TmTcBridge::setNumberOfSentPacketsPerCycle: Number of " - << "packets sent per cycle exceeds limits. " - << "Keeping default value." << std::endl; -#endif - return returnvalue::FAILED; - } +void TmTcBridge::setNumberOfSentPacketsPerCycle(uint32_t sentPacketsPerCycle_) { + this->sentPacketsPerCycle = sentPacketsPerCycle_; } ReturnValue_t TmTcBridge::setMaxNumberOfPacketsStored(unsigned int maxNumberOfPacketsStored) { diff --git a/src/fsfw/tmtcservices/TmTcBridge.h b/src/fsfw/tmtcservices/TmTcBridge.h index 858793cc..c87be45c 100644 --- a/src/fsfw/tmtcservices/TmTcBridge.h +++ b/src/fsfw/tmtcservices/TmTcBridge.h @@ -15,10 +15,9 @@ class TmTcBridge : public AcceptsTelemetryIF, public ExecutableObjectIF, public SystemObject { public: - static constexpr uint8_t LIMIT_STORED_DATA_SENT_PER_CYCLE = 15; static constexpr unsigned int LIMIT_DOWNLINK_PACKETS_STORED = 500; - static constexpr uint8_t DEFAULT_STORED_DATA_SENT_PER_CYCLE = 5; + static constexpr uint8_t DEFAULT_STORED_DATA_SENT_PER_CYCLE = 20; static constexpr uint8_t DEFAULT_DOWNLINK_PACKETS_STORED = 10; TmTcBridge(const char* name, object_id_t objectId, object_id_t tcDestination, @@ -32,7 +31,7 @@ class TmTcBridge : public AcceptsTelemetryIF, * @return -@c returnvalue::OK if value was set successfully * -@c returnvalue::FAILED otherwise, stored value stays the same */ - ReturnValue_t setNumberOfSentPacketsPerCycle(uint8_t sentPacketsPerCycle); + void setNumberOfSentPacketsPerCycle(uint32_t sentPacketsPerCycle); /** * Set number of packets sent per performOperation().Please note that this @@ -151,7 +150,7 @@ class TmTcBridge : public AcceptsTelemetryIF, * This FIFO can be used to store downlink data which can not be sent at the moment. */ DynamicFIFO* tmFifo = nullptr; - uint8_t sentPacketsPerCycle = DEFAULT_STORED_DATA_SENT_PER_CYCLE; + uint32_t sentPacketsPerCycle = DEFAULT_STORED_DATA_SENT_PER_CYCLE; unsigned int maxNumberOfPacketsStored = DEFAULT_DOWNLINK_PACKETS_STORED; }; From c199cbedaa4b7f6ba0b88fae26412cfa65f36739 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 6 Sep 2023 13:40:18 +0200 Subject: [PATCH 096/101] some improvements, remove debugging stuff --- src/fsfw/cfdp/handler/SourceHandler.cpp | 4 ---- src/fsfw/osal/common/TcpTmTcBridge.cpp | 2 +- src/fsfw/tmtcservices/TmTcBridge.cpp | 4 ++-- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index 351359c2..60a947e3 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -267,20 +267,16 @@ ReturnValue_t cfdp::SourceHandler::prepareAndSendNextFileDataPdu(bool& noFileDat addError(result); return result; } - sif::debug << "sending next fd pdu, offset " << offset.value() << "" << std::endl; auto fileDataInfo = FileDataInfo(offset, fileBuf.data(), readLen); auto fileDataPdu = FileDataCreator(transactionParams.pduConf, fileDataInfo); result = sendGenericPdu(fileDataPdu); if (result != OK) { - sif::debug << "SENDING generic PDU failed" << std::endl; return result; } transactionParams.progress += readLen; if (transactionParams.progress >= fileSize) { // Advance FSM after all file data PDUs were sent. step = TransactionStep::SENDING_EOF; - sif::debug << "done" << std::endl; - TaskFactory::delayTask(10000); } return OK; } diff --git a/src/fsfw/osal/common/TcpTmTcBridge.cpp b/src/fsfw/osal/common/TcpTmTcBridge.cpp index 0bf3ab28..80c2ddd1 100644 --- a/src/fsfw/osal/common/TcpTmTcBridge.cpp +++ b/src/fsfw/osal/common/TcpTmTcBridge.cpp @@ -21,7 +21,7 @@ TcpTmTcBridge::TcpTmTcBridge(object_id_t objectId, object_id_t tcDestination, : TmTcBridge("TCP TMTC Bridge", objectId, tcDestination, msgQueueDepth, tmStoreId, tcStoreId) { mutex = MutexFactory::instance()->createMutex(); // Connection is always up, TM is requested by connecting to server and receiving packets - registerCommConnect(); + TmTcBridge::registerCommConnect(); } ReturnValue_t TcpTmTcBridge::initialize() { diff --git a/src/fsfw/tmtcservices/TmTcBridge.cpp b/src/fsfw/tmtcservices/TmTcBridge.cpp index 5c819222..9801b21e 100644 --- a/src/fsfw/tmtcservices/TmTcBridge.cpp +++ b/src/fsfw/tmtcservices/TmTcBridge.cpp @@ -134,8 +134,8 @@ ReturnValue_t TmTcBridge::handleTmQueue() { #endif #endif /* FSFW_VERBOSE_LEVEL >= 3 */ - if (communicationLinkUp == false or packetSentCounter >= sentPacketsPerCycle) { - ReturnValue_t result = storeDownlinkData(&message); + if (!communicationLinkUp or packetSentCounter >= sentPacketsPerCycle) { + result = storeDownlinkData(&message); if (result != returnvalue::OK) { tmStore->deleteData(message.getStorageId()); } From 42a0b153031e90191fb11606c23a51a6c3576aaf Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 6 Sep 2023 20:49:53 +0200 Subject: [PATCH 097/101] hardcore bug --- src/fsfw/cfdp/handler/SourceHandler.cpp | 1 + src/fsfw/storagemanager/LocalPool.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index 60a947e3..141afcef 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -371,5 +371,6 @@ void cfdp::SourceHandler::addError(ReturnValue_t error) { if (fsmResult.errors < fsmResult.errorCodes.size()) { fsmResult.errorCodes[fsmResult.errors] = error; fsmResult.errors++; + fsmResult.result = error; } } diff --git a/src/fsfw/storagemanager/LocalPool.cpp b/src/fsfw/storagemanager/LocalPool.cpp index b62c19b6..9a4b53a6 100644 --- a/src/fsfw/storagemanager/LocalPool.cpp +++ b/src/fsfw/storagemanager/LocalPool.cpp @@ -89,7 +89,7 @@ ReturnValue_t LocalPool::deleteData(store_address_t storeId) { ReturnValue_t status = returnvalue::OK; size_type pageSize = getSubpoolElementSize(storeId.poolIndex); if ((pageSize != 0) and (storeId.packetIndex < numberOfElements[storeId.poolIndex])) { - uint16_t packetPosition = getRawPosition(storeId); + size_type packetPosition = getRawPosition(storeId); uint8_t* ptr = &store[storeId.poolIndex][packetPosition]; std::memset(ptr, 0, pageSize); // Set free list From 420c0625a5ecba5f29f6d45743b4ba254e9864e6 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 11 Sep 2023 15:38:06 +0200 Subject: [PATCH 098/101] result was not stored properly --- src/fsfw/cfdp/handler/ReservedMessageParser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fsfw/cfdp/handler/ReservedMessageParser.cpp b/src/fsfw/cfdp/handler/ReservedMessageParser.cpp index 88d909c1..0f3ffdd4 100644 --- a/src/fsfw/cfdp/handler/ReservedMessageParser.cpp +++ b/src/fsfw/cfdp/handler/ReservedMessageParser.cpp @@ -30,7 +30,7 @@ ReturnValue_t cfdp::ReservedMessageParser::parse(const MessageToUserTlv* msgsToU if (msgsToUserArray[idx].isReservedCfdpMessage(messageType, ¤tPtr, deserSize)) { if (messageType == static_cast(ProxyOpMessageType::PUT_REQUEST)) { EntityId entityIdLv; - entityIdLv.deSerializeFromLv(¤tPtr, &deserSize); + result = entityIdLv.deSerializeFromLv(¤tPtr, &deserSize); if (result != returnvalue::OK) { return result; } From 5bd020193bb5a2a1b9e5ceadb12234f1cf75dd44 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 11 Sep 2023 15:38:46 +0200 Subject: [PATCH 099/101] initialize result --- src/fsfw/cfdp/handler/ReservedMessageParser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fsfw/cfdp/handler/ReservedMessageParser.cpp b/src/fsfw/cfdp/handler/ReservedMessageParser.cpp index 0f3ffdd4..ffd2fdc6 100644 --- a/src/fsfw/cfdp/handler/ReservedMessageParser.cpp +++ b/src/fsfw/cfdp/handler/ReservedMessageParser.cpp @@ -15,7 +15,7 @@ cfdp::ReservedMessageParser::ReservedMessageParser(StorageManagerIF& ipcStore, ReturnValue_t cfdp::ReservedMessageParser::parse(const MessageToUserTlv* msgsToUserArray, size_t numMsgToUser) { - ReturnValue_t result; + ReturnValue_t result = returnvalue::OK; cfdp::StringLv sourceFileName; cfdp::StringLv destFileName; PutRequest putRequest; From 497f9472373fe3883419c6d0c5f6a9dce9e1e38a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 14 Sep 2023 15:04:54 +0200 Subject: [PATCH 100/101] add missing 0 termination --- src/fsfw/cfdp/handler/SourceHandler.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index 141afcef..eba21b7d 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -169,6 +169,10 @@ ReturnValue_t cfdp::SourceHandler::transactionStart(PutRequest& putRequest, Remo const char* destNamePtr = putRequest.getDestName().getCString(transactionParams.destNameSize); std::strncpy(transactionParams.sourceName.data(), srcNamePtr, transactionParams.sourceNameSize); std::strncpy(transactionParams.destName.data(), destNamePtr, transactionParams.destNameSize); + // Add 0 termination. The source and dest name size can not be larger than UINT8_MAX, so this + // operation is safe. + transactionParams.sourceName[transactionParams.sourceNameSize] = '\0'; + transactionParams.destName[transactionParams.destNameSize] = '\0'; FilesystemParams params(transactionParams.sourceName.data()); if (!sourceParams.user.vfs.fileExists(params)) { return FILE_DOES_NOT_EXIST; From 6021257a87a439ed5c54d7f3c0646332093bbb88 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 19 Oct 2023 10:21:18 +0200 Subject: [PATCH 101/101] unittest fix --- src/fsfw/cfdp/handler/SourceHandler.cpp | 14 +++++--------- src/fsfw/cfdp/handler/SourceHandler.h | 1 - 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/fsfw/cfdp/handler/SourceHandler.cpp b/src/fsfw/cfdp/handler/SourceHandler.cpp index eba21b7d..f0f89607 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.cpp +++ b/src/fsfw/cfdp/handler/SourceHandler.cpp @@ -50,19 +50,16 @@ cfdp::SourceHandler::FsmResult& cfdp::SourceHandler::fsmNacked() { } if (step == TransactionStep::TRANSACTION_START) { sourceParams.user.transactionIndication(transactionParams.id); - step = TransactionStep::CRC_PROCEDURE; - } - if (step == TransactionStep::CRC_PROCEDURE) { result = checksumGeneration(); if (result != OK) { - // TODO: Some error handling + addError(result); } step = TransactionStep::SENDING_METADATA; } if (step == TransactionStep::SENDING_METADATA) { result = prepareAndSendMetadataPdu(); if (result != OK) { - // TODO: Error handling + addError(result); } fsmResult.callStatus = CallStatus::CALL_AGAIN; return fsmResult; @@ -72,13 +69,13 @@ cfdp::SourceHandler::FsmResult& cfdp::SourceHandler::fsmNacked() { result = prepareAndSendNextFileDataPdu(noFdPdu); if (result == OK and !noFdPdu) { fsmResult.callStatus = CallStatus::CALL_AGAIN; + return fsmResult; } - return fsmResult; } if (step == TransactionStep::SENDING_EOF) { result = prepareAndSendEofPdu(); if (result != OK) { - // TODO: Error handling + addError(result); } if (sourceParams.cfg.indicCfg.eofSentIndicRequired) { sourceParams.user.eofSentIndication(transactionParams.id); @@ -139,8 +136,7 @@ ReturnValue_t cfdp::SourceHandler::checksumGeneration() { params.size = readLen; auto result = sourceParams.user.vfs.readFromFile(params, buf.data(), buf.size()); if (result != OK) { - // TODO: I think this is a case for a filestore rejection, but it might sense to print - // a warning or trigger an event because this should generally not happen + addError(result); return FAILED; } crcCalc.add(buf.begin(), buf.begin() + readLen); diff --git a/src/fsfw/cfdp/handler/SourceHandler.h b/src/fsfw/cfdp/handler/SourceHandler.h index 60634e0a..d1d3fab2 100644 --- a/src/fsfw/cfdp/handler/SourceHandler.h +++ b/src/fsfw/cfdp/handler/SourceHandler.h @@ -30,7 +30,6 @@ class SourceHandler { enum class TransactionStep : uint8_t { IDLE = 0, TRANSACTION_START = 1, - CRC_PROCEDURE = 2, SENDING_METADATA = 3, SENDING_FILE_DATA = 4, SENDING_EOF = 5,