From 683cf8a047013571dc206d60c52810b8a92905a4 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 8 Sep 2022 11:08:40 +0200 Subject: [PATCH] some additional tests --- src/fsfw/cfdp/CfdpDistributor.cpp | 3 +- src/fsfw/cfdp/CfdpDistributor.h | 4 +- src/fsfw/cfdp/handler/DestHandler.cpp | 6 +- src/fsfw/cfdp/handler/DestHandler.h | 1 + src/fsfw/cfdp/pdu/FileDataReader.cpp | 8 +- src/fsfw/cfdp/pdu/FileDataReader.h | 4 +- src/fsfw/cfdp/pdu/FileDirectiveReader.cpp | 8 +- src/fsfw/cfdp/pdu/FileDirectiveReader.h | 4 +- src/fsfw/cfdp/pdu/HeaderReader.cpp | 67 +++-- .../pdu/{HeaderReader.h => PduHeaderReader.h} | 13 +- unittests/cfdp/pdu/testCfdpHeader.cpp | 253 +++++++++--------- unittests/cfdp/pdu/testKeepAlivePdu.cpp | 12 +- unittests/cfdp/pdu/testPromptPdu.cpp | 2 +- 13 files changed, 205 insertions(+), 180 deletions(-) rename src/fsfw/cfdp/pdu/{HeaderReader.h => PduHeaderReader.h} (88%) diff --git a/src/fsfw/cfdp/CfdpDistributor.cpp b/src/fsfw/cfdp/CfdpDistributor.cpp index d0237959..b233e67e 100644 --- a/src/fsfw/cfdp/CfdpDistributor.cpp +++ b/src/fsfw/cfdp/CfdpDistributor.cpp @@ -21,7 +21,8 @@ ReturnValue_t CfdpDistributor::selectDestination(MessageQueueId_t& destId) { if (accessorPair.first != returnvalue::OK) { return accessorPair.first; } - ReturnValue_t result = pduReader.setData(accessorPair.second.data(), accessorPair.second.size()); + ReturnValue_t result = + pduReader.setReadOnlyData(accessorPair.second.data(), accessorPair.second.size()); if (result != returnvalue::OK) { return result; } diff --git a/src/fsfw/cfdp/CfdpDistributor.h b/src/fsfw/cfdp/CfdpDistributor.h index 39ce0d27..13d000eb 100644 --- a/src/fsfw/cfdp/CfdpDistributor.h +++ b/src/fsfw/cfdp/CfdpDistributor.h @@ -4,7 +4,7 @@ #include #include -#include "fsfw/cfdp/pdu/HeaderReader.h" +#include "fsfw/cfdp/pdu/PduHeaderReader.h" #include "fsfw/returnvalues/returnvalue.h" #include "fsfw/tcdistribution/CfdpPacketChecker.h" #include "fsfw/tcdistribution/TcDistributorBase.h" @@ -60,7 +60,7 @@ class CfdpDistributor : public TcDistributorBase, public AcceptsTelecommandsIF { const char* name; MessageQueueId_t queueId; }; - HeaderReader pduReader; + PduHeaderReader pduReader; ReturnValue_t lastTcError = returnvalue::OK; ReturnValue_t lastTmError = returnvalue::OK; // I don't think a regular OBSW will have more than 1 or 2 of these destinations, so I think diff --git a/src/fsfw/cfdp/handler/DestHandler.cpp b/src/fsfw/cfdp/handler/DestHandler.cpp index 3660f75c..3ddf96ff 100644 --- a/src/fsfw/cfdp/handler/DestHandler.cpp +++ b/src/fsfw/cfdp/handler/DestHandler.cpp @@ -8,7 +8,7 @@ #include "fsfw/cfdp/pdu/EofPduReader.h" #include "fsfw/cfdp/pdu/FileDataReader.h" #include "fsfw/cfdp/pdu/FinishedPduCreator.h" -#include "fsfw/cfdp/pdu/HeaderReader.h" +#include "fsfw/cfdp/pdu/PduHeaderReader.h" #include "fsfw/objectmanager.h" #include "fsfw/tmtcservices/TmTcMessage.h" @@ -236,7 +236,7 @@ ReturnValue_t cfdp::DestHandler::handleMetadataParseError(ReturnValue_t result, sif::warning << "Parsing Metadata PDU failed with code " << result << std::endl; #else #endif - HeaderReader headerReader(rawData, maxSize); + PduHeaderReader headerReader(rawData, maxSize); result = headerReader.parseData(); if (result != OK) { // TODO: Now this really should not happen. Warning or error, @@ -461,3 +461,5 @@ void cfdp::DestHandler::setMsgQueue(MessageQueueIF& queue) { fp.msgQueue = &queu void cfdp::DestHandler::setEventReporter(EventReportingProxyIF& reporter) { fp.eventReporter = &reporter; } + +const cfdp::DestHandlerParams& cfdp::DestHandler::getDestHandlerParams() const { return dp; } diff --git a/src/fsfw/cfdp/handler/DestHandler.h b/src/fsfw/cfdp/handler/DestHandler.h index 5507045f..975ccaaf 100644 --- a/src/fsfw/cfdp/handler/DestHandler.h +++ b/src/fsfw/cfdp/handler/DestHandler.h @@ -126,6 +126,7 @@ class DestHandler { [[nodiscard]] CfdpStates getCfdpState() const; [[nodiscard]] TransactionStep getTransactionStep() const; [[nodiscard]] const TransactionId& getTransactionId() const; + [[nodiscard]] const DestHandlerParams& getDestHandlerParams() const; private: struct TransactionParams { diff --git a/src/fsfw/cfdp/pdu/FileDataReader.cpp b/src/fsfw/cfdp/pdu/FileDataReader.cpp index 8eac4c3f..9155ef28 100644 --- a/src/fsfw/cfdp/pdu/FileDataReader.cpp +++ b/src/fsfw/cfdp/pdu/FileDataReader.cpp @@ -1,16 +1,16 @@ #include "FileDataReader.h" FileDataReader::FileDataReader(const uint8_t* pduBuf, size_t maxSize, FileDataInfo& info) - : HeaderReader(pduBuf, maxSize), info(info) {} + : PduHeaderReader(pduBuf, maxSize), info(info) {} ReturnValue_t FileDataReader::parseData() { - ReturnValue_t result = HeaderReader::parseData(); + ReturnValue_t result = PduHeaderReader::parseData(); if (result != returnvalue::OK) { return result; } - size_t currentIdx = HeaderReader::getHeaderSize(); + size_t currentIdx = PduHeaderReader::getHeaderSize(); const uint8_t* buf = pointers.rawPtr + currentIdx; - size_t remSize = HeaderReader::getWholePduSize() - currentIdx; + size_t remSize = PduHeaderReader::getWholePduSize() - currentIdx; if (remSize < 1) { return SerializeIF::STREAM_TOO_SHORT; } diff --git a/src/fsfw/cfdp/pdu/FileDataReader.h b/src/fsfw/cfdp/pdu/FileDataReader.h index 62e0f89b..aa962e2b 100644 --- a/src/fsfw/cfdp/pdu/FileDataReader.h +++ b/src/fsfw/cfdp/pdu/FileDataReader.h @@ -3,9 +3,9 @@ #include "../definitions.h" #include "FileDataInfo.h" -#include "HeaderReader.h" +#include "PduHeaderReader.h" -class FileDataReader : public HeaderReader { +class FileDataReader : public PduHeaderReader { public: FileDataReader(const uint8_t* pduBuf, size_t maxSize, FileDataInfo& info); diff --git a/src/fsfw/cfdp/pdu/FileDirectiveReader.cpp b/src/fsfw/cfdp/pdu/FileDirectiveReader.cpp index 4099efd9..5d43ebb0 100644 --- a/src/fsfw/cfdp/pdu/FileDirectiveReader.cpp +++ b/src/fsfw/cfdp/pdu/FileDirectiveReader.cpp @@ -1,12 +1,12 @@ #include "FileDirectiveReader.h" FileDirectiveReader::FileDirectiveReader(const uint8_t *pduBuf, size_t maxSize) - : HeaderReader(pduBuf, maxSize) {} + : PduHeaderReader(pduBuf, maxSize) {} cfdp::FileDirectives FileDirectiveReader::getFileDirective() const { return fileDirective; } ReturnValue_t FileDirectiveReader::parseData() { - ReturnValue_t result = HeaderReader::parseData(); + ReturnValue_t result = PduHeaderReader::parseData(); if (result != returnvalue::OK) { return result; } @@ -16,7 +16,7 @@ ReturnValue_t FileDirectiveReader::parseData() { if (FileDirectiveReader::getWholePduSize() > maxSize) { return SerializeIF::STREAM_TOO_SHORT; } - size_t currentIdx = HeaderReader::getHeaderSize(); + size_t currentIdx = PduHeaderReader::getHeaderSize(); if (not checkFileDirective(pointers.rawPtr[currentIdx])) { return cfdp::INVALID_DIRECTIVE_FIELDS; } @@ -26,7 +26,7 @@ ReturnValue_t FileDirectiveReader::parseData() { size_t FileDirectiveReader::getHeaderSize() const { // return size of header plus the directive byte - return HeaderReader::getHeaderSize() + 1; + return PduHeaderReader::getHeaderSize() + 1; } bool FileDirectiveReader::checkFileDirective(uint8_t rawByte) { diff --git a/src/fsfw/cfdp/pdu/FileDirectiveReader.h b/src/fsfw/cfdp/pdu/FileDirectiveReader.h index 69dd44cd..83a71c71 100644 --- a/src/fsfw/cfdp/pdu/FileDirectiveReader.h +++ b/src/fsfw/cfdp/pdu/FileDirectiveReader.h @@ -2,7 +2,7 @@ #define FSFW_SRC_FSFW_CFDP_PDU_FILEDIRECTIVEDESERIALIZER_H_ #include "../definitions.h" -#include "fsfw/cfdp/pdu/HeaderReader.h" +#include "fsfw/cfdp/pdu/PduHeaderReader.h" /** * @brief This class is used to deserialize a PDU file directive header from raw memory. @@ -11,7 +11,7 @@ * This is a zero-copy implementation and #parseData needs to be called to ensure the data is * valid. */ -class FileDirectiveReader : public HeaderReader { +class FileDirectiveReader : public PduHeaderReader { public: FileDirectiveReader(const uint8_t* pduBuf, size_t maxSize); diff --git a/src/fsfw/cfdp/pdu/HeaderReader.cpp b/src/fsfw/cfdp/pdu/HeaderReader.cpp index e2f070db..3417a57c 100644 --- a/src/fsfw/cfdp/pdu/HeaderReader.cpp +++ b/src/fsfw/cfdp/pdu/HeaderReader.cpp @@ -1,12 +1,14 @@ -#include "HeaderReader.h" - #include #include -HeaderReader::HeaderReader(const uint8_t *pduBuf, size_t maxSize) { setData(pduBuf, maxSize); } +#include "PduHeaderReader.h" -ReturnValue_t HeaderReader::parseData() { +PduHeaderReader::PduHeaderReader(const uint8_t *pduBuf, size_t maxSize) { + setReadOnlyData(pduBuf, maxSize); +} + +ReturnValue_t PduHeaderReader::parseData() { if (pointers.rawPtr == nullptr) { return returnvalue::FAILED; } @@ -20,10 +22,15 @@ ReturnValue_t HeaderReader::parseData() { cfdp::WidthInBytes widthSeqNum = getLenSeqNum(); seqNumRaw = static_cast(sourceIdRaw) + static_cast(widthEntityIds); destIdRaw = static_cast(seqNumRaw) + static_cast(widthSeqNum); + if (getWholePduSize() > PduHeaderReader::getHeaderSize()) { + pointers.dataFieldStart = reinterpret_cast(destIdRaw) + widthEntityIds; + } else { + pointers.dataFieldStart = nullptr; + } return returnvalue::OK; } -ReturnValue_t HeaderReader::setData(uint8_t *dataPtr, size_t maxSize_, void *args) { +ReturnValue_t PduHeaderReader::setData(uint8_t *dataPtr, size_t maxSize_, void *args) { if (dataPtr == nullptr) { return returnvalue::FAILED; } @@ -35,68 +42,68 @@ ReturnValue_t HeaderReader::setData(uint8_t *dataPtr, size_t maxSize_, void *arg return returnvalue::OK; } -size_t HeaderReader::getHeaderSize() const { +size_t PduHeaderReader::getHeaderSize() const { if (pointers.fixedHeader != nullptr) { return getLenEntityIds() * 2 + getLenSeqNum() + 4; } return 0; } -size_t HeaderReader::getPduDataFieldLen() const { +size_t PduHeaderReader::getPduDataFieldLen() const { return (pointers.fixedHeader->pduDataFieldLenH << 8) | pointers.fixedHeader->pduDataFieldLenL; } -size_t HeaderReader::getWholePduSize() const { - return getPduDataFieldLen() + HeaderReader::getHeaderSize(); +size_t PduHeaderReader::getWholePduSize() const { + return getPduDataFieldLen() + PduHeaderReader::getHeaderSize(); } -cfdp::PduType HeaderReader::getPduType() const { +cfdp::PduType PduHeaderReader::getPduType() const { return static_cast((pointers.fixedHeader->firstByte >> 4) & 0x01); } -cfdp::Direction HeaderReader::getDirection() const { +cfdp::Direction PduHeaderReader::getDirection() const { return static_cast((pointers.fixedHeader->firstByte >> 3) & 0x01); } -cfdp::TransmissionModes HeaderReader::getTransmissionMode() const { +cfdp::TransmissionModes PduHeaderReader::getTransmissionMode() const { return static_cast((pointers.fixedHeader->firstByte >> 2) & 0x01); } -bool HeaderReader::getCrcFlag() const { return (pointers.fixedHeader->firstByte >> 1) & 0x01; } +bool PduHeaderReader::getCrcFlag() const { return (pointers.fixedHeader->firstByte >> 1) & 0x01; } -bool HeaderReader::getLargeFileFlag() const { return pointers.fixedHeader->firstByte & 0x01; } +bool PduHeaderReader::getLargeFileFlag() const { return pointers.fixedHeader->firstByte & 0x01; } -cfdp::SegmentationControl HeaderReader::getSegmentationControl() const { +cfdp::SegmentationControl PduHeaderReader::getSegmentationControl() const { return static_cast((pointers.fixedHeader->fourthByte >> 7) & 0x01); } -cfdp::WidthInBytes HeaderReader::getLenEntityIds() const { +cfdp::WidthInBytes PduHeaderReader::getLenEntityIds() const { return static_cast((pointers.fixedHeader->fourthByte >> 4) & 0x07); } -cfdp::WidthInBytes HeaderReader::getLenSeqNum() const { +cfdp::WidthInBytes PduHeaderReader::getLenSeqNum() const { return static_cast(pointers.fixedHeader->fourthByte & 0x07); } -cfdp::SegmentMetadataFlag HeaderReader::getSegmentMetadataFlag() const { +cfdp::SegmentMetadataFlag PduHeaderReader::getSegmentMetadataFlag() const { return static_cast((pointers.fixedHeader->fourthByte >> 3) & 0x01); } -void HeaderReader::getSourceId(cfdp::EntityId &sourceId) const { +void PduHeaderReader::getSourceId(cfdp::EntityId &sourceId) const { assignVarLenField(dynamic_cast(&sourceId), getLenEntityIds(), this->sourceIdRaw); } -void HeaderReader::getDestId(cfdp::EntityId &destId) const { +void PduHeaderReader::getDestId(cfdp::EntityId &destId) const { assignVarLenField(dynamic_cast(&destId), getLenEntityIds(), this->destIdRaw); } -void HeaderReader::getTransactionSeqNum(cfdp::TransactionSeqNum &seqNum) const { +void PduHeaderReader::getTransactionSeqNum(cfdp::TransactionSeqNum &seqNum) const { assignVarLenField(dynamic_cast(&seqNum), getLenSeqNum(), this->seqNumRaw); } -void HeaderReader::assignVarLenField(cfdp::VarLenField *field, cfdp::WidthInBytes width, - void *sourcePtr) const { +void PduHeaderReader::assignVarLenField(cfdp::VarLenField *field, cfdp::WidthInBytes width, + void *sourcePtr) const { switch (width) { case (cfdp::WidthInBytes::ONE_BYTE): { auto *fieldTyped = static_cast(sourcePtr); @@ -122,25 +129,25 @@ void HeaderReader::assignVarLenField(cfdp::VarLenField *field, cfdp::WidthInByte } } -size_t HeaderReader::getMaxSize() const { return maxSize; } +size_t PduHeaderReader::getMaxSize() const { return maxSize; } -bool HeaderReader::hasSegmentMetadataFlag() const { +bool PduHeaderReader::hasSegmentMetadataFlag() const { if (this->getSegmentMetadataFlag() == cfdp::SegmentMetadataFlag::PRESENT) { return true; } return false; } -ReturnValue_t HeaderReader::setData(const uint8_t *dataPtr, size_t maxSize_) { +ReturnValue_t PduHeaderReader::setReadOnlyData(const uint8_t *dataPtr, size_t maxSize_) { return setData(const_cast(dataPtr), maxSize_, nullptr); } -bool HeaderReader::isNull() const { +bool PduHeaderReader::isNull() const { return pointers.rawPtr == nullptr or pointers.fixedHeader == nullptr; } -HeaderReader::operator bool() const { return not isNull(); } +PduHeaderReader::operator bool() const { return not isNull(); } -void HeaderReader::fillConfig(PduConfig &cfg) const { +void PduHeaderReader::fillConfig(PduConfig &cfg) const { cfg.largeFile = getLargeFileFlag(); cfg.crcFlag = getCrcFlag(); cfg.mode = getTransmissionMode(); @@ -149,3 +156,5 @@ void HeaderReader::fillConfig(PduConfig &cfg) const { getSourceId(cfg.sourceId); getDestId(cfg.destId); } + +const uint8_t *PduHeaderReader::getPduDataField() const { return pointers.dataFieldStart; } diff --git a/src/fsfw/cfdp/pdu/HeaderReader.h b/src/fsfw/cfdp/pdu/PduHeaderReader.h similarity index 88% rename from src/fsfw/cfdp/pdu/HeaderReader.h rename to src/fsfw/cfdp/pdu/PduHeaderReader.h index 533320b7..7809f59c 100644 --- a/src/fsfw/cfdp/pdu/HeaderReader.h +++ b/src/fsfw/cfdp/pdu/PduHeaderReader.h @@ -23,16 +23,16 @@ struct PduHeaderFixedStruct { * This is a zero-copy implementation and #parseData needs to be called to ensure the data is * valid. */ -class HeaderReader : public RedirectableDataPointerIF, public PduHeaderIF { +class PduHeaderReader : public RedirectableDataPointerIF, public PduHeaderIF { public: - HeaderReader() = default; + PduHeaderReader() = default; /** * Initialize a PDU header from raw data. This is a zero-copy implementation and #parseData * needs to be called to ensure the data is valid * @param pduBuf * @param maxSize */ - HeaderReader(const uint8_t* pduBuf, size_t maxSize); + PduHeaderReader(const uint8_t* pduBuf, size_t maxSize); /** * This needs to be called before accessing the PDU fields to avoid segmentation faults. @@ -74,6 +74,7 @@ class HeaderReader : public RedirectableDataPointerIF, public PduHeaderIF { ReturnValue_t deserResult = returnvalue::OK; [[nodiscard]] size_t getMaxSize() const; + [[nodiscard]] const uint8_t* getPduDataField() const; /** * Can also be used to reset the pointer to a nullptr, but the getter functions will not @@ -83,11 +84,12 @@ class HeaderReader : public RedirectableDataPointerIF, public PduHeaderIF { * @param args * @return */ - ReturnValue_t setData(const uint8_t* dataPtr, size_t maxSize); + ReturnValue_t setReadOnlyData(const uint8_t* dataPtr, size_t maxSize); protected: struct Pointers { PduHeaderFixedStruct* fixedHeader = nullptr; + const uint8_t* dataFieldStart = nullptr; const uint8_t* rawPtr = nullptr; }; @@ -96,8 +98,7 @@ class HeaderReader : public RedirectableDataPointerIF, public PduHeaderIF { private: /** - * Can also be used to reset the pointer to a nullptr, but the getter functions will not - * perform nullptr checks! + * This is a reader class and setting mutable data is forbidden. Use @setReadOnlyData instead. * @param dataPtr * @param maxSize * @param args diff --git a/unittests/cfdp/pdu/testCfdpHeader.cpp b/unittests/cfdp/pdu/testCfdpHeader.cpp index 99a0c470..6d22154b 100644 --- a/unittests/cfdp/pdu/testCfdpHeader.cpp +++ b/unittests/cfdp/pdu/testCfdpHeader.cpp @@ -1,10 +1,14 @@ #include #include +#include "fsfw/cfdp/pdu/FinishedInfo.h" +#include "fsfw/cfdp/pdu/FinishedPduCreator.h" #include "fsfw/cfdp/pdu/HeaderCreator.h" -#include "fsfw/cfdp/pdu/HeaderReader.h" +#include "fsfw/cfdp/pdu/PduHeaderReader.h" #include "fsfw/returnvalues/returnvalue.h" +using namespace returnvalue; + TEST_CASE("CFDP Header", "[cfdp]") { using namespace cfdp; std::array serBuf{}; @@ -17,63 +21,62 @@ TEST_CASE("CFDP Header", "[cfdp]") { uint8_t* serTarget = serBuf.data(); const uint8_t* deserTarget = serTarget; size_t serSize = 0; - auto headerSerializer = HeaderCreator(pduConf, cfdp::PduType::FILE_DIRECTIVE, 0); + auto creator = HeaderCreator(pduConf, cfdp::PduType::FILE_DIRECTIVE, 0); SECTION("Header State") { REQUIRE(seqNum.getSerializedSize() == 1); - REQUIRE(headerSerializer.getPduDataFieldLen() == 0); - REQUIRE(headerSerializer.getSerializedSize() == 7); - REQUIRE(headerSerializer.getWholePduSize() == 7); - REQUIRE(headerSerializer.getCrcFlag() == false); - REQUIRE(headerSerializer.getDirection() == cfdp::Direction::TOWARDS_RECEIVER); - REQUIRE(headerSerializer.getLargeFileFlag() == false); - REQUIRE(headerSerializer.getLenEntityIds() == 1); - REQUIRE(headerSerializer.getLenSeqNum() == 1); - REQUIRE(headerSerializer.getPduType() == cfdp::PduType::FILE_DIRECTIVE); - REQUIRE(headerSerializer.getSegmentMetadataFlag() == cfdp::SegmentMetadataFlag::NOT_PRESENT); - REQUIRE(headerSerializer.getSegmentationControl() == false); - REQUIRE(headerSerializer.getTransmissionMode() == cfdp::TransmissionModes::ACKNOWLEDGED); + REQUIRE(creator.getPduDataFieldLen() == 0); + REQUIRE(creator.getSerializedSize() == 7); + REQUIRE(creator.getWholePduSize() == 7); + REQUIRE(creator.getCrcFlag() == false); + REQUIRE(creator.getDirection() == cfdp::Direction::TOWARDS_RECEIVER); + REQUIRE(creator.getLargeFileFlag() == false); + REQUIRE(creator.getLenEntityIds() == 1); + REQUIRE(creator.getLenSeqNum() == 1); + REQUIRE(creator.getPduType() == cfdp::PduType::FILE_DIRECTIVE); + REQUIRE(creator.getSegmentMetadataFlag() == cfdp::SegmentMetadataFlag::NOT_PRESENT); + REQUIRE(creator.getSegmentationControl() == false); + REQUIRE(creator.getTransmissionMode() == cfdp::TransmissionModes::ACKNOWLEDGED); cfdp::TransactionSeqNum seqNumLocal; - headerSerializer.getTransactionSeqNum(seqNumLocal); + creator.getTransactionSeqNum(seqNumLocal); REQUIRE(seqNumLocal.getWidth() == cfdp::WidthInBytes::ONE_BYTE); REQUIRE(seqNumLocal.getValue() == 2); cfdp::EntityId sourceDestId; - headerSerializer.getSourceId(sourceDestId); + creator.getSourceId(sourceDestId); REQUIRE(sourceDestId.getWidth() == cfdp::WidthInBytes::ONE_BYTE); REQUIRE(sourceDestId.getValue() == 0); - headerSerializer.getDestId(sourceDestId); + creator.getDestId(sourceDestId); REQUIRE(sourceDestId.getWidth() == cfdp::WidthInBytes::ONE_BYTE); REQUIRE(sourceDestId.getValue() == 1); } SECTION("Deserialization fails") { const uint8_t** dummyPtr = nullptr; - REQUIRE(headerSerializer.deSerialize(dummyPtr, &serSize, SerializeIF::Endianness::NETWORK) == + REQUIRE(creator.deSerialize(dummyPtr, &serSize, SerializeIF::Endianness::NETWORK) == returnvalue::FAILED); } SECTION("Serialization fails") { - REQUIRE(headerSerializer.serialize(nullptr, &serSize, serBuf.size(), - SerializeIF::Endianness::NETWORK) == returnvalue::FAILED); + REQUIRE(creator.serialize(nullptr, &serSize, serBuf.size(), SerializeIF::Endianness::NETWORK) == + returnvalue::FAILED); } SECTION("Buffer Too Short") { for (uint8_t idx = 0; idx < 7; idx++) { - result = headerSerializer.serialize(&serTarget, &serSize, idx, SerializeIF::Endianness::BIG); + result = creator.serialize(&serTarget, &serSize, idx, SerializeIF::Endianness::BIG); REQUIRE(result == static_cast(SerializeIF::BUFFER_TOO_SHORT)); } } SECTION("Set Data Field Len") { // Set PDU data field len - headerSerializer.setPduDataFieldLen(0x0ff0); - REQUIRE(headerSerializer.getPduDataFieldLen() == 0x0ff0); - REQUIRE(headerSerializer.getSerializedSize() == 7); - REQUIRE(headerSerializer.getWholePduSize() == 7 + 0x0ff0); + creator.setPduDataFieldLen(0x0ff0); + REQUIRE(creator.getPduDataFieldLen() == 0x0ff0); + REQUIRE(creator.getSerializedSize() == 7); + REQUIRE(creator.getWholePduSize() == 7 + 0x0ff0); serTarget = serBuf.data(); serSize = 0; - result = headerSerializer.serialize(&serTarget, &serSize, serBuf.size(), - SerializeIF::Endianness::BIG); + result = creator.serialize(&serTarget, &serSize, serBuf.size(), SerializeIF::Endianness::BIG); REQUIRE(serBuf[1] == 0x0f); REQUIRE(serBuf[2] == 0xf0); } @@ -83,28 +86,27 @@ TEST_CASE("CFDP Header", "[cfdp]") { pduConf.largeFile = true; pduConf.direction = cfdp::Direction::TOWARDS_SENDER; pduConf.mode = cfdp::TransmissionModes::UNACKNOWLEDGED; - headerSerializer.setSegmentationControl( - cfdp::SegmentationControl::RECORD_BOUNDARIES_PRESERVATION); - headerSerializer.setPduType(cfdp::PduType::FILE_DATA); - headerSerializer.setSegmentMetadataFlag(cfdp::SegmentMetadataFlag::PRESENT); + creator.setSegmentationControl(cfdp::SegmentationControl::RECORD_BOUNDARIES_PRESERVATION); + creator.setPduType(cfdp::PduType::FILE_DATA); + creator.setSegmentMetadataFlag(cfdp::SegmentMetadataFlag::PRESENT); serTarget = serBuf.data(); serSize = 0; SECTION("Regular") { // Everything except version bit flipped to one now - REQUIRE(headerSerializer.serialize(&serTarget, &serSize, serBuf.size(), - SerializeIF::Endianness::BIG) == returnvalue::OK); + REQUIRE(creator.serialize(&serTarget, &serSize, serBuf.size(), + SerializeIF::Endianness::BIG) == returnvalue::OK); CHECK(serBuf[0] == 0x3f); CHECK(serBuf[3] == 0x99); - REQUIRE(headerSerializer.getCrcFlag() == true); - REQUIRE(headerSerializer.getDirection() == cfdp::Direction::TOWARDS_SENDER); - REQUIRE(headerSerializer.getLargeFileFlag() == true); - REQUIRE(headerSerializer.getLenEntityIds() == 1); - REQUIRE(headerSerializer.getLenSeqNum() == 1); - REQUIRE(headerSerializer.getPduType() == cfdp::PduType::FILE_DATA); - REQUIRE(headerSerializer.getSegmentMetadataFlag() == cfdp::SegmentMetadataFlag::PRESENT); - REQUIRE(headerSerializer.getTransmissionMode() == cfdp::TransmissionModes::UNACKNOWLEDGED); - REQUIRE(headerSerializer.getSegmentationControl() == true); + REQUIRE(creator.getCrcFlag() == true); + REQUIRE(creator.getDirection() == cfdp::Direction::TOWARDS_SENDER); + REQUIRE(creator.getLargeFileFlag() == true); + REQUIRE(creator.getLenEntityIds() == 1); + REQUIRE(creator.getLenSeqNum() == 1); + REQUIRE(creator.getPduType() == cfdp::PduType::FILE_DATA); + REQUIRE(creator.getSegmentMetadataFlag() == cfdp::SegmentMetadataFlag::PRESENT); + REQUIRE(creator.getTransmissionMode() == cfdp::TransmissionModes::UNACKNOWLEDGED); + REQUIRE(creator.getSegmentationControl() == true); } SECTION("Other variable sized fields") { @@ -112,18 +114,18 @@ TEST_CASE("CFDP Header", "[cfdp]") { pduConf.sourceId.setValue(cfdp::WidthInBytes::FOUR_BYTES, 0xff00ff00); pduConf.destId.setValue(cfdp::WidthInBytes::FOUR_BYTES, 0x00ff00ff); REQUIRE(pduConf.sourceId.getSerializedSize() == 4); - REQUIRE(headerSerializer.getSerializedSize() == 14); - REQUIRE(headerSerializer.serialize(&serTarget, &serSize, serBuf.size(), - SerializeIF::Endianness::BIG) == returnvalue::OK); - REQUIRE(headerSerializer.getCrcFlag() == true); - REQUIRE(headerSerializer.getDirection() == cfdp::Direction::TOWARDS_SENDER); - REQUIRE(headerSerializer.getLargeFileFlag() == true); - REQUIRE(headerSerializer.getLenEntityIds() == 4); - REQUIRE(headerSerializer.getLenSeqNum() == 2); - REQUIRE(headerSerializer.getPduType() == cfdp::PduType::FILE_DATA); - REQUIRE(headerSerializer.getSegmentMetadataFlag() == cfdp::SegmentMetadataFlag::PRESENT); - REQUIRE(headerSerializer.getTransmissionMode() == cfdp::TransmissionModes::UNACKNOWLEDGED); - REQUIRE(headerSerializer.getSegmentationControl() == true); + REQUIRE(creator.getSerializedSize() == 14); + REQUIRE(creator.serialize(&serTarget, &serSize, serBuf.size(), + SerializeIF::Endianness::BIG) == returnvalue::OK); + REQUIRE(creator.getCrcFlag() == true); + REQUIRE(creator.getDirection() == cfdp::Direction::TOWARDS_SENDER); + REQUIRE(creator.getLargeFileFlag() == true); + REQUIRE(creator.getLenEntityIds() == 4); + REQUIRE(creator.getLenSeqNum() == 2); + REQUIRE(creator.getPduType() == cfdp::PduType::FILE_DATA); + REQUIRE(creator.getSegmentMetadataFlag() == cfdp::SegmentMetadataFlag::PRESENT); + REQUIRE(creator.getTransmissionMode() == cfdp::TransmissionModes::UNACKNOWLEDGED); + REQUIRE(creator.getSegmentationControl() == true); // Last three bits are 2 now (length of seq number) and bit 1 to bit 3 is 4 (len entity IDs) REQUIRE(serBuf[3] == 0b11001010); uint32_t entityId = 0; @@ -148,9 +150,8 @@ TEST_CASE("CFDP Header", "[cfdp]") { pduConf.sourceId.setValue(cfdp::WidthInBytes::FOUR_BYTES, 0xff00ff00); pduConf.destId.setValue(cfdp::WidthInBytes::FOUR_BYTES, 0x00ff00ff); for (uint8_t idx = 0; idx < 14; idx++) { - REQUIRE( - headerSerializer.serialize(&serTarget, &serSize, idx, SerializeIF::Endianness::BIG) == - SerializeIF::BUFFER_TOO_SHORT); + REQUIRE(creator.serialize(&serTarget, &serSize, idx, SerializeIF::Endianness::BIG) == + SerializeIF::BUFFER_TOO_SHORT); } } } @@ -165,8 +166,7 @@ TEST_CASE("CFDP Header", "[cfdp]") { } SECTION("Header Serialization") { - result = headerSerializer.serialize(&serTarget, &serSize, serBuf.size(), - SerializeIF::Endianness::BIG); + result = creator.serialize(&serTarget, &serSize, serBuf.size(), SerializeIF::Endianness::BIG); REQUIRE(result == returnvalue::OK); REQUIRE(serSize == 7); // Only version bits are set @@ -214,40 +214,49 @@ TEST_CASE("CFDP Header", "[cfdp]") { REQUIRE(result == static_cast(SerializeIF::BUFFER_TOO_SHORT)); } - SECTION("Header Deserialization") { - REQUIRE(headerSerializer.serialize(&serTarget, &serSize, serBuf.size(), - SerializeIF::Endianness::BIG) == returnvalue::OK); + SECTION("Header Deserialization 0") { + REQUIRE(creator.serialize(&serTarget, &serSize, serBuf.size(), SerializeIF::Endianness::BIG) == + returnvalue::OK); REQUIRE(serBuf[1] == 0); REQUIRE(serBuf[2] == 0); // Entity and Transaction Sequence number are 1 byte large REQUIRE(serBuf[3] == 0b00010001); REQUIRE(serSize == 7); // Deser call not strictly necessary - auto headerDeser = HeaderReader(serBuf.data(), serBuf.size()); + auto reader = PduHeaderReader(serBuf.data(), serBuf.size()); - ReturnValue_t serResult = headerDeser.parseData(); + ReturnValue_t serResult = reader.parseData(); REQUIRE(serResult == returnvalue::OK); - REQUIRE(headerDeser.getPduDataFieldLen() == 0); - REQUIRE(headerDeser.getHeaderSize() == 7); - REQUIRE(headerDeser.getWholePduSize() == 7); - REQUIRE(headerDeser.getCrcFlag() == false); - REQUIRE(headerDeser.getDirection() == cfdp::Direction::TOWARDS_RECEIVER); - REQUIRE(headerDeser.getLargeFileFlag() == false); - REQUIRE(headerDeser.getLenEntityIds() == 1); - REQUIRE(headerDeser.getLenSeqNum() == 1); - REQUIRE(headerDeser.getPduType() == cfdp::PduType::FILE_DIRECTIVE); - REQUIRE(headerDeser.getSegmentMetadataFlag() == cfdp::SegmentMetadataFlag::NOT_PRESENT); - REQUIRE(headerDeser.getSegmentationControl() == false); - REQUIRE(headerDeser.getTransmissionMode() == cfdp::TransmissionModes::ACKNOWLEDGED); + REQUIRE(reader.getPduDataFieldLen() == 0); + REQUIRE(reader.getHeaderSize() == 7); + REQUIRE(reader.getWholePduSize() == 7); + REQUIRE(reader.getCrcFlag() == false); + REQUIRE(reader.getDirection() == cfdp::Direction::TOWARDS_RECEIVER); + REQUIRE(reader.getLargeFileFlag() == false); + REQUIRE(reader.getLenEntityIds() == 1); + REQUIRE(reader.getLenSeqNum() == 1); + REQUIRE(reader.getPduType() == cfdp::PduType::FILE_DIRECTIVE); + REQUIRE(reader.getSegmentMetadataFlag() == cfdp::SegmentMetadataFlag::NOT_PRESENT); + REQUIRE(reader.getSegmentationControl() == false); + REQUIRE(reader.getTransmissionMode() == cfdp::TransmissionModes::ACKNOWLEDGED); + // No PDU data contained, so the PDU data field is empty + REQUIRE(reader.getPduDataField() == nullptr); + size_t deSerSize = reader.getWholePduSize(); + serTarget = serBuf.data(); + const auto** serTargetConst = const_cast(&serTarget); + result = reader.parseData(); + REQUIRE(result == returnvalue::OK); + } + + SECTION("Header Deserialization 1") { pduConf.crcFlag = true; pduConf.largeFile = true; pduConf.direction = cfdp::Direction::TOWARDS_SENDER; pduConf.mode = cfdp::TransmissionModes::UNACKNOWLEDGED; - headerSerializer.setSegmentationControl( - cfdp::SegmentationControl::RECORD_BOUNDARIES_PRESERVATION); - headerSerializer.setPduType(cfdp::PduType::FILE_DATA); - headerSerializer.setSegmentMetadataFlag(cfdp::SegmentMetadataFlag::PRESENT); + 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); REQUIRE(result == returnvalue::OK); result = pduConf.sourceId.setValue(cfdp::WidthInBytes::FOUR_BYTES, 0xff00ff00); @@ -256,61 +265,63 @@ TEST_CASE("CFDP Header", "[cfdp]") { REQUIRE(result == returnvalue::OK); serTarget = serBuf.data(); serSize = 0; - result = headerSerializer.serialize(&serTarget, &serSize, serBuf.size(), - SerializeIF::Endianness::BIG); - headerDeser = HeaderReader(serBuf.data(), serBuf.size()); - - result = headerDeser.parseData(); - REQUIRE(result == returnvalue::OK); + result = creator.serialize(&serTarget, &serSize, serBuf.size(), SerializeIF::Endianness::BIG); + PduHeaderReader reader(serBuf.data(), serBuf.size()); + REQUIRE(reader.parseData() == returnvalue::OK); // Everything except version bit flipped to one now REQUIRE(serBuf[0] == 0x3f); REQUIRE(serBuf[3] == 0b11001010); - REQUIRE(headerDeser.getWholePduSize() == 14); + REQUIRE(reader.getWholePduSize() == 14); - REQUIRE(headerDeser.getCrcFlag() == true); - REQUIRE(headerDeser.getDirection() == cfdp::Direction::TOWARDS_SENDER); - REQUIRE(headerDeser.getLargeFileFlag() == true); - REQUIRE(headerDeser.getLenEntityIds() == 4); - REQUIRE(headerDeser.getLenSeqNum() == 2); - REQUIRE(headerDeser.getPduType() == cfdp::PduType::FILE_DATA); - REQUIRE(headerDeser.getSegmentMetadataFlag() == cfdp::SegmentMetadataFlag::PRESENT); - REQUIRE(headerDeser.getSegmentationControl() == true); - REQUIRE(headerDeser.getTransmissionMode() == cfdp::TransmissionModes::UNACKNOWLEDGED); + REQUIRE(reader.getCrcFlag() == true); + REQUIRE(reader.getDirection() == cfdp::Direction::TOWARDS_SENDER); + REQUIRE(reader.getLargeFileFlag() == true); + REQUIRE(reader.getLenEntityIds() == 4); + REQUIRE(reader.getLenSeqNum() == 2); + REQUIRE(reader.getPduType() == cfdp::PduType::FILE_DATA); + REQUIRE(reader.getSegmentMetadataFlag() == cfdp::SegmentMetadataFlag::PRESENT); + REQUIRE(reader.getSegmentationControl() == true); + REQUIRE(reader.getTransmissionMode() == cfdp::TransmissionModes::UNACKNOWLEDGED); + // Again, no data field set because this is a header only + REQUIRE(reader.getPduDataField() == nullptr); cfdp::TransactionSeqNum seqNumLocal; - headerDeser.getTransactionSeqNum(seqNumLocal); + reader.getTransactionSeqNum(seqNumLocal); REQUIRE(seqNumLocal.getWidth() == cfdp::WidthInBytes::TWO_BYTES); REQUIRE(seqNumLocal.getValue() == 0x0fff); cfdp::EntityId sourceDestId; - headerDeser.getSourceId(sourceDestId); + reader.getSourceId(sourceDestId); REQUIRE(sourceDestId.getWidth() == cfdp::WidthInBytes::FOUR_BYTES); REQUIRE(sourceDestId.getValue() == 0xff00ff00); - headerDeser.getDestId(sourceDestId); + reader.getDestId(sourceDestId); REQUIRE(sourceDestId.getWidth() == cfdp::WidthInBytes::FOUR_BYTES); REQUIRE(sourceDestId.getValue() == 0x00ff00ff); + CHECK(reader.setReadOnlyData(nullptr, -1) != returnvalue::OK); + REQUIRE(reader.getHeaderSize() == 14); - size_t deSerSize = headerDeser.getWholePduSize(); - serTarget = serBuf.data(); - const auto** serTargetConst = const_cast(&serTarget); - result = headerDeser.parseData(); - REQUIRE(result == returnvalue::OK); + 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); + result = creator.serialize(&serTarget, &serSize, serBuf.size(), SerializeIF::Endianness::BIG); + reader.getSourceId(sourceDestId); + REQUIRE(sourceDestId.getWidth() == cfdp::WidthInBytes::ONE_BYTE); + REQUIRE(sourceDestId.getValue() == 22); + } + } - CHECK(headerDeser.setData(nullptr, -1) != returnvalue::OK); - REQUIRE(headerDeser.getHeaderSize() == 14); - headerDeser.setData(serBuf.data(), serBuf.size()); - - serTarget = serBuf.data(); - serSize = 0; - pduConf.sourceId.setValue(cfdp::WidthInBytes::ONE_BYTE, 22); - pduConf.destId.setValue(cfdp::WidthInBytes::ONE_BYTE, 48); - result = headerSerializer.serialize(&serTarget, &serSize, serBuf.size(), - SerializeIF::Endianness::BIG); - REQUIRE(result == returnvalue::OK); - REQUIRE(headerDeser.getWholePduSize() == 8); - headerDeser.setData(serBuf.data(), serBuf.size()); - - headerDeser.getSourceId(sourceDestId); - REQUIRE(sourceDestId.getWidth() == cfdp::WidthInBytes::ONE_BYTE); - REQUIRE(sourceDestId.getValue() == 22); + SECTION("Verify data field pointer") { + FinishedInfo info(cfdp::ConditionCode::INACTIVITY_DETECTED, + cfdp::FileDeliveryCode::DATA_INCOMPLETE, + cfdp::FileDeliveryStatus::DISCARDED_DELIBERATELY); + FinishPduCreator finishCreator(pduConf, info); + REQUIRE(finishCreator.serialize(serBuf.data(), serSize, serBuf.size()) == OK); + // This PDU contains the directive code and some finishes PDU properties packed into one byte + // in addition to the header + REQUIRE(finishCreator.getSerializedSize() == 9); + PduHeaderReader reader(serBuf.data(), serBuf.size()); + REQUIRE(reader.parseData() == returnvalue::OK); + REQUIRE(reader.getPduDataField() == serBuf.data() + 7); } } diff --git a/unittests/cfdp/pdu/testKeepAlivePdu.cpp b/unittests/cfdp/pdu/testKeepAlivePdu.cpp index b82feb32..34a529e9 100644 --- a/unittests/cfdp/pdu/testKeepAlivePdu.cpp +++ b/unittests/cfdp/pdu/testKeepAlivePdu.cpp @@ -61,19 +61,19 @@ TEST_CASE("Keep Alive PDU", "[cfdp][pdu]") { // Set another file size progress.setFileSize(200, false); - KeepAlivePduDeserializer deserializer(kaBuffer.data(), kaBuffer.size(), progress); - result = deserializer.parseData(); + KeepAlivePduDeserializer reader(kaBuffer.data(), kaBuffer.size(), progress); + result = reader.parseData(); REQUIRE(result == returnvalue::OK); - auto& progRef = deserializer.getProgress(); + auto& progRef = reader.getProgress(); // Should have been overwritten REQUIRE(progRef.getSize() == 0x50); - sz = deserializer.getWholePduSize(); + sz = reader.getWholePduSize(); // invalid max size for (size_t invalidMaxSz = 0; invalidMaxSz < sz; invalidMaxSz++) { - ReturnValue_t setResult = deserializer.setData(kaBuffer.data(), invalidMaxSz); + ReturnValue_t setResult = reader.setReadOnlyData(kaBuffer.data(), invalidMaxSz); if (setResult == returnvalue::OK) { - result = deserializer.parseData(); + result = reader.parseData(); REQUIRE(result != returnvalue::OK); } } diff --git a/unittests/cfdp/pdu/testPromptPdu.cpp b/unittests/cfdp/pdu/testPromptPdu.cpp index ffabf9a4..1efd751d 100644 --- a/unittests/cfdp/pdu/testPromptPdu.cpp +++ b/unittests/cfdp/pdu/testPromptPdu.cpp @@ -59,7 +59,7 @@ TEST_CASE("Prompt PDU", "[cfdp][pdu]") { rawBuf[2] = 2; for (size_t invalidMaxSz = 0; invalidMaxSz < sz; invalidMaxSz++) { - ReturnValue_t setResult = deserializer.setData(rawBuf.data(), invalidMaxSz); + ReturnValue_t setResult = deserializer.setReadOnlyData(rawBuf.data(), invalidMaxSz); if (setResult == returnvalue::OK) { result = deserializer.parseData(); REQUIRE(result != returnvalue::OK);