From 10f6ce3a0caebf662005b741e570b517fadc8893 Mon Sep 17 00:00:00 2001 From: tomatze Date: Mon, 31 May 2021 13:49:56 +0200 Subject: [PATCH 01/38] added dummy CFDPDistributor --- tcdistribution/CFDPDistributor.cpp | 138 +++++++++++++++++++++++++++++ tcdistribution/CFDPDistributor.h | 78 ++++++++++++++++ tcdistribution/CFDPDistributorIF.h | 27 ++++++ tcdistribution/CMakeLists.txt | 1 + 4 files changed, 244 insertions(+) create mode 100644 tcdistribution/CFDPDistributor.cpp create mode 100644 tcdistribution/CFDPDistributor.h create mode 100644 tcdistribution/CFDPDistributorIF.h diff --git a/tcdistribution/CFDPDistributor.cpp b/tcdistribution/CFDPDistributor.cpp new file mode 100644 index 00000000..9fe29499 --- /dev/null +++ b/tcdistribution/CFDPDistributor.cpp @@ -0,0 +1,138 @@ +#include "CCSDSDistributorIF.h" +#include "CFDPDistributor.h" + +#include "../serviceinterface/ServiceInterface.h" + +#define CFDP_DISTRIBUTOR_DEBUGGING 0 + +CFDPDistributor::CFDPDistributor(uint16_t setApid, object_id_t setObjectId, + object_id_t setPacketSource) : + TcDistributor(setObjectId), checker(setApid), verifyChannel(), + tcStatus(RETURN_FAILED), packetSource(setPacketSource) {} + +CFDPDistributor::~CFDPDistributor() {} + +CFDPDistributor::TcMqMapIter CFDPDistributor::selectDestination() { +#if FSFW_CPP_OSTREAM_ENABLED == 1 && CFDP_DISTRIBUTOR_DEBUGGING == 1 + store_address_t storeId = this->currentMessage.getStorageId()); + sif:: debug << "CFDPDistributor::handlePacket received: " << storeId.poolIndex << ", " << + storeId.packetIndex << std::endl; +#endif + TcMqMapIter queueMapIt = this->queueMap.end(); + if(this->currentPacket == nullptr) { + return queueMapIt; + } + this->currentPacket->setStoreAddress(this->currentMessage.getStorageId()); + if (currentPacket->getWholeData() != nullptr) { + tcStatus = checker.checkPacket(currentPacket); + if(tcStatus != HasReturnvaluesIF::RETURN_OK) { +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::debug << "CFDPDistributor::handlePacket: Packet format invalid, code " << + static_cast(tcStatus) << std::endl; +#else + sif::printDebug("CFDPDistributor::handlePacket: Packet format invalid, code %d\n", + static_cast(tcStatus)); +#endif +#endif + } + uint32_t queue_id = currentPacket->getService(); + queueMapIt = this->queueMap.find(queue_id); + } + else { + tcStatus = PACKET_LOST; + } + + if (queueMapIt == this->queueMap.end()) { + tcStatus = DESTINATION_NOT_FOUND; +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::debug << "CFDPDistributor::handlePacket: Destination not found" << std::endl; +#else + sif::printDebug("CFDPDistributor::handlePacket: Destination not found\n"); +#endif /* !FSFW_CPP_OSTREAM_ENABLED == 1 */ +#endif + } + + if (tcStatus != RETURN_OK) { + return this->queueMap.end(); + } + else { + return queueMapIt; + } + +} + + +ReturnValue_t CFDPDistributor::registerService(AcceptsTelecommandsIF* service) { + uint16_t serviceId = service->getIdentifier(); +#if PUS_DISTRIBUTOR_DEBUGGING == 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::info << "Service ID: " << static_cast(serviceId) << std::endl; +#else + sif::printInfo("Service ID: %d\n", static_cast(serviceId)); +#endif +#endif + MessageQueueId_t queue = service->getRequestQueue(); + auto returnPair = queueMap.emplace(serviceId, queue); + if (not returnPair.second) { +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "PUSDistributor::registerService: Service ID already" + " exists in map" << std::endl; +#else + sif::printError("PUSDistributor::registerService: Service ID already exists in map\n"); +#endif +#endif + return SERVICE_ID_ALREADY_EXISTS; + } + return HasReturnvaluesIF::RETURN_OK; +} + +MessageQueueId_t CFDPDistributor::getRequestQueue() { + return tcQueue->getId(); +} + +ReturnValue_t CFDPDistributor::callbackAfterSending(ReturnValue_t queueStatus) { + if (queueStatus != RETURN_OK) { + tcStatus = queueStatus; + } + if (tcStatus != RETURN_OK) { + this->verifyChannel.sendFailureReport(tc_verification::ACCEPTANCE_FAILURE, + currentPacket, tcStatus); + // A failed packet is deleted immediately after reporting, + // otherwise it will block memory. + currentPacket->deletePacket(); + return RETURN_FAILED; + } else { + this->verifyChannel.sendSuccessReport(tc_verification::ACCEPTANCE_SUCCESS, + currentPacket); + return RETURN_OK; + } +} + +uint16_t CFDPDistributor::getIdentifier() { + return checker.getApid(); +} + +ReturnValue_t CFDPDistributor::initialize() { + currentPacket = new TcPacketStored(); + if(currentPacket == nullptr) { + // Should not happen, memory allocation failed! + return ObjectManagerIF::CHILD_INIT_FAILED; + } + + CCSDSDistributorIF* ccsdsDistributor = + objectManager->get(packetSource); + if (ccsdsDistributor == nullptr) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "CFDPDistributor::initialize: Packet source invalid" << std::endl; + sif::error << " Make sure it exists and implements CCSDSDistributorIF!" << std::endl; +#else + sif::printError("CFDPDistributor::initialize: Packet source invalid\n"); + sif::printError("Make sure it exists and implements CCSDSDistributorIF\n"); +#endif + return RETURN_FAILED; + } + return ccsdsDistributor->registerApplication(this); +} diff --git a/tcdistribution/CFDPDistributor.h b/tcdistribution/CFDPDistributor.h new file mode 100644 index 00000000..1a5865ed --- /dev/null +++ b/tcdistribution/CFDPDistributor.h @@ -0,0 +1,78 @@ +#ifndef FSFW_TCDISTRIBUTION_CFDPDISTRIBUTOR_H_ +#define FSFW_TCDISTRIBUTION_CFDPDISTRIBUTOR_H_ + +#include "CFDPDistributorIF.h" +#include "TcDistributor.h" +#include "TcPacketCheck.h" + +#include "../returnvalues/HasReturnvaluesIF.h" +#include "../tmtcservices/AcceptsTelecommandsIF.h" +#include "../tmtcservices/VerificationReporter.h" + +/** + * This class accepts CFDP Telecommands and forwards them to Application + * services. + * @ingroup tc_distribution + */ +class CFDPDistributor: public TcDistributor, + public CFDPDistributorIF, + public AcceptsTelecommandsIF { +public: + /** + * The ctor passes @c set_apid to the checker class and calls the + * TcDistribution ctor with a certain object id. + * @param setApid The APID of this receiving Application. + * @param setObjectId Object ID of the distributor itself + * @param setPacketSource Object ID of the source of TC packets. + * Must implement CCSDSDistributorIF. + */ + CFDPDistributor(uint16_t setApid, object_id_t setObjectId, + object_id_t setPacketSource); + /** + * The destructor is empty. + */ + virtual ~CFDPDistributor(); + ReturnValue_t registerService(AcceptsTelecommandsIF* service) override; + MessageQueueId_t getRequestQueue() override; + ReturnValue_t initialize() override; + uint16_t getIdentifier() override; + +protected: + /** + * This attribute contains the class, that performs a formal packet check. + */ + TcPacketCheck checker; + /** + * With this class, verification messages are sent to the + * TC Verification service. + */ + VerificationReporter verifyChannel; + /** + * The currently handled packet is stored here. + */ + TcPacketStored* currentPacket = nullptr; + /** + * With this variable, the current check status is stored to generate + * acceptance messages later. + */ + ReturnValue_t tcStatus; + + const object_id_t packetSource; + + /** + * This method reads the packet service, checks if such a service is + * registered and forwards the packet to the destination. + * It also initiates the formal packet check and sending of verification + * messages. + * @return Iterator to map entry of found service id + * or iterator to @c map.end(). + */ + TcMqMapIter selectDestination() override; + /** + * The callback here handles the generation of acceptance + * success/failure messages. + */ + ReturnValue_t callbackAfterSending(ReturnValue_t queueStatus) override; +}; + +#endif /* FSFW_TCDISTRIBUTION_CFDPDISTRIBUTOR_H_ */ diff --git a/tcdistribution/CFDPDistributorIF.h b/tcdistribution/CFDPDistributorIF.h new file mode 100644 index 00000000..dd017c97 --- /dev/null +++ b/tcdistribution/CFDPDistributorIF.h @@ -0,0 +1,27 @@ +#ifndef FSFW_TCDISTRIBUTION_CFDPDISTRIBUTORIF_H_ +#define FSFW_TCDISTRIBUTION_CFDPDISTRIBUTORIF_H_ + +#include "../tmtcservices/AcceptsTelecommandsIF.h" +#include "../ipc/MessageQueueSenderIF.h" + +/** + * This interface allows CFDP Services to register themselves at a CFDP Distributor. + * @ingroup tc_distribution + */ +class CFDPDistributorIF { +public: + /** + * The empty virtual destructor. + */ + virtual ~CFDPDistributorIF() { + } +/** + * With this method, Services can register themselves at the PUS Distributor. + * @param service A pointer to the registering Service. + * @return - @c RETURN_OK on success, + * - @c RETURN_FAILED on failure. + */ + virtual ReturnValue_t registerService( AcceptsTelecommandsIF* service ) = 0; +}; + +#endif /* FSFW_TCDISTRIBUTION_CFDPDISTRIBUTORIF_H_ */ diff --git a/tcdistribution/CMakeLists.txt b/tcdistribution/CMakeLists.txt index 17dc186c..e89792ed 100644 --- a/tcdistribution/CMakeLists.txt +++ b/tcdistribution/CMakeLists.txt @@ -2,6 +2,7 @@ target_sources(${LIB_FSFW_NAME} PRIVATE CCSDSDistributor.cpp PUSDistributor.cpp + CFDPDistributor.cpp TcDistributor.cpp TcPacketCheck.cpp ) From 52bf1d4714125d63a87555dac94397e4bb51a5b9 Mon Sep 17 00:00:00 2001 From: tomatze Date: Thu, 10 Jun 2021 14:29:07 +0200 Subject: [PATCH 02/38] CFDPDistributor corrected some debug prints --- tcdistribution/CFDPDistributor.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tcdistribution/CFDPDistributor.cpp b/tcdistribution/CFDPDistributor.cpp index 9fe29499..5e07a1db 100644 --- a/tcdistribution/CFDPDistributor.cpp +++ b/tcdistribution/CFDPDistributor.cpp @@ -66,7 +66,7 @@ CFDPDistributor::TcMqMapIter CFDPDistributor::selectDestination() { ReturnValue_t CFDPDistributor::registerService(AcceptsTelecommandsIF* service) { uint16_t serviceId = service->getIdentifier(); -#if PUS_DISTRIBUTOR_DEBUGGING == 1 +#if CFDP_DISTRIBUTOR_DEBUGGING == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::info << "Service ID: " << static_cast(serviceId) << std::endl; #else @@ -78,10 +78,10 @@ ReturnValue_t CFDPDistributor::registerService(AcceptsTelecommandsIF* service) { if (not returnPair.second) { #if FSFW_VERBOSE_LEVEL >= 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "PUSDistributor::registerService: Service ID already" + sif::error << "CFDPDistributor::registerService: Service ID already" " exists in map" << std::endl; #else - sif::printError("PUSDistributor::registerService: Service ID already exists in map\n"); + sif::printError("CFDPDistributor::registerService: Service ID already exists in map\n"); #endif #endif return SERVICE_ID_ALREADY_EXISTS; From 5954002ae0e5a0c0e08d2d798ee300d002d5c5e2 Mon Sep 17 00:00:00 2001 From: tomatze Date: Sat, 12 Jun 2021 18:45:23 +0200 Subject: [PATCH 03/38] added missing sif::printDebug --- tcdistribution/CFDPDistributor.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tcdistribution/CFDPDistributor.cpp b/tcdistribution/CFDPDistributor.cpp index 5e07a1db..245fece2 100644 --- a/tcdistribution/CFDPDistributor.cpp +++ b/tcdistribution/CFDPDistributor.cpp @@ -13,10 +13,14 @@ CFDPDistributor::CFDPDistributor(uint16_t setApid, object_id_t setObjectId, CFDPDistributor::~CFDPDistributor() {} CFDPDistributor::TcMqMapIter CFDPDistributor::selectDestination() { -#if FSFW_CPP_OSTREAM_ENABLED == 1 && CFDP_DISTRIBUTOR_DEBUGGING == 1 - store_address_t storeId = this->currentMessage.getStorageId()); - sif:: debug << "CFDPDistributor::handlePacket received: " << storeId.poolIndex << ", " << +#if CFDP_DISTRIBUTOR_DEBUGGING == 1 + store_address_t storeId = this->currentMessage.getStorageId(); +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::debug << "CFDPDistributor::handlePacket received: " << storeId.poolIndex << ", " << storeId.packetIndex << std::endl; +#else + sif::printDebug("CFDPDistributor::handlePacket received: %d, %d\n", storeId.poolIndex, storeId.packetIndex); +#endif #endif TcMqMapIter queueMapIt = this->queueMap.end(); if(this->currentPacket == nullptr) { From 2500a5f4f735ffeed344656275e5a8d2cd4ed45f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 24 Jun 2021 09:36:13 +0200 Subject: [PATCH 04/38] fixes for updated FSFW --- tcdistribution/CFDPDistributor.cpp | 11 +++++++---- tcdistribution/CFDPDistributor.h | 3 ++- tcdistribution/CMakeLists.txt | 2 +- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/tcdistribution/CFDPDistributor.cpp b/tcdistribution/CFDPDistributor.cpp index 245fece2..b344f7bb 100644 --- a/tcdistribution/CFDPDistributor.cpp +++ b/tcdistribution/CFDPDistributor.cpp @@ -1,6 +1,8 @@ + #include "CCSDSDistributorIF.h" #include "CFDPDistributor.h" +#include "../objectmanager/ObjectManager.h" #include "../serviceinterface/ServiceInterface.h" #define CFDP_DISTRIBUTOR_DEBUGGING 0 @@ -19,7 +21,8 @@ CFDPDistributor::TcMqMapIter CFDPDistributor::selectDestination() { sif::debug << "CFDPDistributor::handlePacket received: " << storeId.poolIndex << ", " << storeId.packetIndex << std::endl; #else - sif::printDebug("CFDPDistributor::handlePacket received: %d, %d\n", storeId.poolIndex, storeId.packetIndex); + sif::printDebug("CFDPDistributor::handlePacket received: %d, %d\n", storeId.poolIndex, + storeId.packetIndex); #endif #endif TcMqMapIter queueMapIt = this->queueMap.end(); @@ -120,14 +123,14 @@ uint16_t CFDPDistributor::getIdentifier() { } ReturnValue_t CFDPDistributor::initialize() { - currentPacket = new TcPacketStored(); + currentPacket = new TcPacketStoredPus(); if(currentPacket == nullptr) { // Should not happen, memory allocation failed! return ObjectManagerIF::CHILD_INIT_FAILED; } - CCSDSDistributorIF* ccsdsDistributor = - objectManager->get(packetSource); + CCSDSDistributorIF* ccsdsDistributor = ObjectManager::instance()->get( + packetSource); if (ccsdsDistributor == nullptr) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::error << "CFDPDistributor::initialize: Packet source invalid" << std::endl; diff --git a/tcdistribution/CFDPDistributor.h b/tcdistribution/CFDPDistributor.h index 1a5865ed..ae5df11d 100644 --- a/tcdistribution/CFDPDistributor.h +++ b/tcdistribution/CFDPDistributor.h @@ -5,6 +5,7 @@ #include "TcDistributor.h" #include "TcPacketCheck.h" +#include "../tmtcpacket/pus/tc.h" #include "../returnvalues/HasReturnvaluesIF.h" #include "../tmtcservices/AcceptsTelecommandsIF.h" #include "../tmtcservices/VerificationReporter.h" @@ -50,7 +51,7 @@ protected: /** * The currently handled packet is stored here. */ - TcPacketStored* currentPacket = nullptr; + TcPacketStoredPus* currentPacket = nullptr; /** * With this variable, the current check status is stored to generate * acceptance messages later. diff --git a/tcdistribution/CMakeLists.txt b/tcdistribution/CMakeLists.txt index 40fcc81a..359b8a81 100644 --- a/tcdistribution/CMakeLists.txt +++ b/tcdistribution/CMakeLists.txt @@ -3,6 +3,6 @@ target_sources(${LIB_FSFW_NAME} PRIVATE PUSDistributor.cpp TcDistributor.cpp TcPacketCheck.cpp - CCSDSDistributor.cpp + CFDPDistributor.cpp ) From 53cada41efe4bfe02f33e9b4baea8807a2bfdd14 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 24 Jun 2021 09:47:28 +0200 Subject: [PATCH 05/38] whitespace corrections --- tcdistribution/CCSDSDistributor.cpp | 116 ++++++++++++++-------------- tcdistribution/CCSDSDistributor.h | 81 +++++++++---------- tcdistribution/CCSDSDistributorIF.h | 49 ++++++------ tcdistribution/CFDPDistributor.cpp | 1 - tcdistribution/CFDPDistributor.h | 109 +++++++++++++------------- tcdistribution/PUSDistributor.h | 106 ++++++++++++------------- tcdistribution/PUSDistributorIF.h | 24 +++--- 7 files changed, 243 insertions(+), 243 deletions(-) diff --git a/tcdistribution/CCSDSDistributor.cpp b/tcdistribution/CCSDSDistributor.cpp index 7380866a..97c79e5f 100644 --- a/tcdistribution/CCSDSDistributor.cpp +++ b/tcdistribution/CCSDSDistributor.cpp @@ -7,8 +7,8 @@ #define CCSDS_DISTRIBUTOR_DEBUGGING 0 CCSDSDistributor::CCSDSDistributor(uint16_t setDefaultApid, - object_id_t setObjectId): - TcDistributor(setObjectId), defaultApid( setDefaultApid ) { + object_id_t setObjectId): + TcDistributor(setObjectId), defaultApid( setDefaultApid ) { } CCSDSDistributor::~CCSDSDistributor() {} @@ -16,97 +16,97 @@ CCSDSDistributor::~CCSDSDistributor() {} TcDistributor::TcMqMapIter CCSDSDistributor::selectDestination() { #if CCSDS_DISTRIBUTOR_DEBUGGING == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::debug << "CCSDSDistributor::selectDestination received: " << - this->currentMessage.getStorageId().poolIndex << ", " << - this->currentMessage.getStorageId().packetIndex << std::endl; + sif::debug << "CCSDSDistributor::selectDestination received: " << + this->currentMessage.getStorageId().poolIndex << ", " << + this->currentMessage.getStorageId().packetIndex << std::endl; #else - sif::printDebug("CCSDSDistributor::selectDestination received: %d, %d\n", - currentMessage.getStorageId().poolIndex, currentMessage.getStorageId().packetIndex); + sif::printDebug("CCSDSDistributor::selectDestination received: %d, %d\n", + currentMessage.getStorageId().poolIndex, currentMessage.getStorageId().packetIndex); #endif #endif - const uint8_t* packet = nullptr; - size_t size = 0; - ReturnValue_t result = this->tcStore->getData(currentMessage.getStorageId(), - &packet, &size ); - if(result != HasReturnvaluesIF::RETURN_OK) { + const uint8_t* packet = nullptr; + size_t size = 0; + ReturnValue_t result = this->tcStore->getData(currentMessage.getStorageId(), + &packet, &size ); + if(result != HasReturnvaluesIF::RETURN_OK) { #if FSFW_VERBOSE_LEVEL >= 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "CCSDSDistributor::selectDestination: Getting data from" - " store failed!" << std::endl; + sif::error << "CCSDSDistributor::selectDestination: Getting data from" + " store failed!" << std::endl; #else - sif::printError("CCSDSDistributor::selectDestination: Getting data from" + sif::printError("CCSDSDistributor::selectDestination: Getting data from" " store failed!\n"); #endif #endif - } - SpacePacketBase currentPacket(packet); + } + SpacePacketBase currentPacket(packet); #if FSFW_CPP_OSTREAM_ENABLED == 1 && CCSDS_DISTRIBUTOR_DEBUGGING == 1 - sif::info << "CCSDSDistributor::selectDestination has packet with APID " << std::hex << - currentPacket.getAPID() << std::dec << std::endl; + sif::info << "CCSDSDistributor::selectDestination has packet with APID " << std::hex << + currentPacket.getAPID() << std::dec << std::endl; #endif - TcMqMapIter position = this->queueMap.find(currentPacket.getAPID()); - if ( position != this->queueMap.end() ) { - return position; - } else { - //The APID was not found. Forward packet to main SW-APID anyway to - // create acceptance failure report. - return this->queueMap.find( this->defaultApid ); - } + TcMqMapIter position = this->queueMap.find(currentPacket.getAPID()); + if ( position != this->queueMap.end() ) { + return position; + } else { + //The APID was not found. Forward packet to main SW-APID anyway to + // create acceptance failure report. + return this->queueMap.find( this->defaultApid ); + } } MessageQueueId_t CCSDSDistributor::getRequestQueue() { - return tcQueue->getId(); + return tcQueue->getId(); } ReturnValue_t CCSDSDistributor::registerApplication( - AcceptsTelecommandsIF* application) { - ReturnValue_t returnValue = RETURN_OK; - auto insertPair = this->queueMap.emplace(application->getIdentifier(), - application->getRequestQueue()); - if(not insertPair.second) { - returnValue = RETURN_FAILED; - } - return returnValue; + AcceptsTelecommandsIF* application) { + ReturnValue_t returnValue = RETURN_OK; + auto insertPair = this->queueMap.emplace(application->getIdentifier(), + application->getRequestQueue()); + if(not insertPair.second) { + returnValue = RETURN_FAILED; + } + return returnValue; } ReturnValue_t CCSDSDistributor::registerApplication(uint16_t apid, - MessageQueueId_t id) { - ReturnValue_t returnValue = RETURN_OK; - auto insertPair = this->queueMap.emplace(apid, id); - if(not insertPair.second) { - returnValue = RETURN_FAILED; - } - return returnValue; + MessageQueueId_t id) { + ReturnValue_t returnValue = RETURN_OK; + auto insertPair = this->queueMap.emplace(apid, id); + if(not insertPair.second) { + returnValue = RETURN_FAILED; + } + return returnValue; } uint16_t CCSDSDistributor::getIdentifier() { - return 0; + return 0; } ReturnValue_t CCSDSDistributor::initialize() { - ReturnValue_t status = this->TcDistributor::initialize(); - this->tcStore = ObjectManager::instance()->get( objects::TC_STORE ); - if (this->tcStore == nullptr) { + ReturnValue_t status = this->TcDistributor::initialize(); + this->tcStore = ObjectManager::instance()->get( objects::TC_STORE ); + if (this->tcStore == nullptr) { #if FSFW_VERBOSE_LEVEL >= 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "CCSDSDistributor::initialize: Could not initialize" - " TC store!" << std::endl; + sif::error << "CCSDSDistributor::initialize: Could not initialize" + " TC store!" << std::endl; #else - sif::printError("CCSDSDistributor::initialize: Could not initialize" + sif::printError("CCSDSDistributor::initialize: Could not initialize" " TC store!\n"); #endif #endif - status = RETURN_FAILED; - } - return status; + status = RETURN_FAILED; + } + return status; } ReturnValue_t CCSDSDistributor::callbackAfterSending( - ReturnValue_t queueStatus) { - if (queueStatus != RETURN_OK) { - tcStore->deleteData(currentMessage.getStorageId()); - } - return RETURN_OK; + ReturnValue_t queueStatus) { + if (queueStatus != RETURN_OK) { + tcStore->deleteData(currentMessage.getStorageId()); + } + return RETURN_OK; } diff --git a/tcdistribution/CCSDSDistributor.h b/tcdistribution/CCSDSDistributor.h index e8d54c9c..f8995bc5 100644 --- a/tcdistribution/CCSDSDistributor.h +++ b/tcdistribution/CCSDSDistributor.h @@ -15,56 +15,57 @@ * The Secondary Header (with Service/Subservice) is ignored. * @ingroup tc_distribution */ -class CCSDSDistributor : public TcDistributor, - public CCSDSDistributorIF, - public AcceptsTelecommandsIF { +class CCSDSDistributor: + public TcDistributor, + public CCSDSDistributorIF, + public AcceptsTelecommandsIF { public: - /** - * @brief The constructor sets the default APID and calls the - * TcDistributor ctor with a certain object id. - * @details - * @c tcStore is set in the @c initialize method. - * @param setDefaultApid The default APID, where packets with unknown - * destination are sent to. - */ - CCSDSDistributor(uint16_t setDefaultApid, object_id_t setObjectId); - /** - * The destructor is empty. - */ - virtual ~CCSDSDistributor(); + /** + * @brief The constructor sets the default APID and calls the + * TcDistributor ctor with a certain object id. + * @details + * @c tcStore is set in the @c initialize method. + * @param setDefaultApid The default APID, where packets with unknown + * destination are sent to. + */ + CCSDSDistributor(uint16_t setDefaultApid, object_id_t setObjectId); + /** + * The destructor is empty. + */ + virtual ~CCSDSDistributor(); - MessageQueueId_t getRequestQueue() override; - ReturnValue_t registerApplication( uint16_t apid, - MessageQueueId_t id) override; - ReturnValue_t registerApplication( - AcceptsTelecommandsIF* application) override; - uint16_t getIdentifier() override; - ReturnValue_t initialize() override; + MessageQueueId_t getRequestQueue() override; + ReturnValue_t registerApplication( uint16_t apid, + MessageQueueId_t id) override; + ReturnValue_t registerApplication( + AcceptsTelecommandsIF* application) override; + uint16_t getIdentifier() override; + ReturnValue_t initialize() override; protected: - /** - * This implementation checks if an application with fitting APID has - * registered and forwards the packet to the according message queue. - * If the packet is not found, it returns the queue to @c defaultApid, - * where a Acceptance Failure message should be generated. - * @return Iterator to map entry of found APID or iterator to default APID. - */ - TcMqMapIter selectDestination() override; + /** + * This implementation checks if an application with fitting APID has + * registered and forwards the packet to the according message queue. + * If the packet is not found, it returns the queue to @c defaultApid, + * where a Acceptance Failure message should be generated. + * @return Iterator to map entry of found APID or iterator to default APID. + */ + TcMqMapIter selectDestination() override; /** * The callback here handles the generation of acceptance * success/failure messages. */ ReturnValue_t callbackAfterSending( ReturnValue_t queueStatus ) override; - /** - * The default APID, where packets with unknown APID are sent to. - */ - uint16_t defaultApid; - /** - * A reference to the TC storage must be maintained, as this class handles - * pure Space Packets and there exists no SpacePacketStored class. - */ - StorageManagerIF* tcStore = nullptr; + /** + * The default APID, where packets with unknown APID are sent to. + */ + uint16_t defaultApid; + /** + * A reference to the TC storage must be maintained, as this class handles + * pure Space Packets and there exists no SpacePacketStored class. + */ + StorageManagerIF* tcStore = nullptr; }; diff --git a/tcdistribution/CCSDSDistributorIF.h b/tcdistribution/CCSDSDistributorIF.h index 6334a35a..4e4c2a5b 100644 --- a/tcdistribution/CCSDSDistributorIF.h +++ b/tcdistribution/CCSDSDistributorIF.h @@ -13,31 +13,30 @@ */ class CCSDSDistributorIF { public: - /** - * With this call, a class implementing the CCSDSApplicationIF can register - * at the distributor. - * @param application A pointer to the Application to register. - * @return - @c RETURN_OK on success, - * - @c RETURN_FAILED on failure. - */ - virtual ReturnValue_t registerApplication( - AcceptsTelecommandsIF* application) = 0; - /** - * With this call, other Applications can register to the CCSDS distributor. - * This is done by passing an APID and a MessageQueueId to the method. - * @param apid The APID to register. - * @param id The MessageQueueId of the message queue to send the - * TC Packets to. - * @return - @c RETURN_OK on success, - * - @c RETURN_FAILED on failure. - */ - virtual ReturnValue_t registerApplication( uint16_t apid, - MessageQueueId_t id) = 0; - /** - * The empty virtual destructor. - */ - virtual ~CCSDSDistributorIF() { - } + /** + * With this call, a class implementing the CCSDSApplicationIF can register + * at the distributor. + * @param application A pointer to the Application to register. + * @return - @c RETURN_OK on success, + * - @c RETURN_FAILED on failure. + */ + virtual ReturnValue_t registerApplication( + AcceptsTelecommandsIF* application) = 0; + /** + * With this call, other Applications can register to the CCSDS distributor. + * This is done by passing an APID and a MessageQueueId to the method. + * @param apid The APID to register. + * @param id The MessageQueueId of the message queue to send the + * TC Packets to. + * @return - @c RETURN_OK on success, + * - @c RETURN_FAILED on failure. + */ + virtual ReturnValue_t registerApplication( uint16_t apid, + MessageQueueId_t id) = 0; + /** + * The empty virtual destructor. + */ + virtual ~CCSDSDistributorIF() {} }; diff --git a/tcdistribution/CFDPDistributor.cpp b/tcdistribution/CFDPDistributor.cpp index b344f7bb..1b257517 100644 --- a/tcdistribution/CFDPDistributor.cpp +++ b/tcdistribution/CFDPDistributor.cpp @@ -1,4 +1,3 @@ - #include "CCSDSDistributorIF.h" #include "CFDPDistributor.h" diff --git a/tcdistribution/CFDPDistributor.h b/tcdistribution/CFDPDistributor.h index ae5df11d..d61357b2 100644 --- a/tcdistribution/CFDPDistributor.h +++ b/tcdistribution/CFDPDistributor.h @@ -15,65 +15,66 @@ * services. * @ingroup tc_distribution */ -class CFDPDistributor: public TcDistributor, - public CFDPDistributorIF, - public AcceptsTelecommandsIF { +class CFDPDistributor: + public TcDistributor, + public CFDPDistributorIF, + public AcceptsTelecommandsIF { public: - /** - * The ctor passes @c set_apid to the checker class and calls the - * TcDistribution ctor with a certain object id. - * @param setApid The APID of this receiving Application. - * @param setObjectId Object ID of the distributor itself - * @param setPacketSource Object ID of the source of TC packets. - * Must implement CCSDSDistributorIF. - */ - CFDPDistributor(uint16_t setApid, object_id_t setObjectId, - object_id_t setPacketSource); - /** - * The destructor is empty. - */ - virtual ~CFDPDistributor(); - ReturnValue_t registerService(AcceptsTelecommandsIF* service) override; - MessageQueueId_t getRequestQueue() override; - ReturnValue_t initialize() override; - uint16_t getIdentifier() override; + /** + * The ctor passes @c set_apid to the checker class and calls the + * TcDistribution ctor with a certain object id. + * @param setApid The APID of this receiving Application. + * @param setObjectId Object ID of the distributor itself + * @param setPacketSource Object ID of the source of TC packets. + * Must implement CCSDSDistributorIF. + */ + CFDPDistributor(uint16_t setApid, object_id_t setObjectId, + object_id_t setPacketSource); + /** + * The destructor is empty. + */ + virtual ~CFDPDistributor(); + ReturnValue_t registerService(AcceptsTelecommandsIF* service) override; + MessageQueueId_t getRequestQueue() override; + ReturnValue_t initialize() override; + uint16_t getIdentifier() override; protected: - /** - * This attribute contains the class, that performs a formal packet check. - */ - TcPacketCheck checker; - /** - * With this class, verification messages are sent to the - * TC Verification service. - */ - VerificationReporter verifyChannel; - /** - * The currently handled packet is stored here. - */ - TcPacketStoredPus* currentPacket = nullptr; - /** - * With this variable, the current check status is stored to generate - * acceptance messages later. - */ - ReturnValue_t tcStatus; + /** + * This attribute contains the class, that performs a formal packet check. + */ + TcPacketCheck checker; + /** + * With this class, verification messages are sent to the + * TC Verification service. + */ + VerificationReporter verifyChannel; + /** + * The currently handled packet is stored here. + */ + TcPacketStoredPus* currentPacket = nullptr; + /** + * With this variable, the current check status is stored to generate + * acceptance messages later. + */ + ReturnValue_t tcStatus; - const object_id_t packetSource; + const object_id_t packetSource; - /** - * This method reads the packet service, checks if such a service is - * registered and forwards the packet to the destination. - * It also initiates the formal packet check and sending of verification - * messages. - * @return Iterator to map entry of found service id - * or iterator to @c map.end(). - */ - TcMqMapIter selectDestination() override; - /** - * The callback here handles the generation of acceptance - * success/failure messages. - */ - ReturnValue_t callbackAfterSending(ReturnValue_t queueStatus) override; + /** + * This method reads the packet service, checks if such a service is + * registered and forwards the packet to the destination. + * It also initiates the formal packet check and sending of verification + * messages. + * @return Iterator to map entry of found service id + * or iterator to @c map.end(). + */ + TcMqMapIter selectDestination() override; + /** + * The callback here handles the generation of acceptance + * success/failure messages. + */ + ReturnValue_t callbackAfterSending(ReturnValue_t queueStatus) override; }; #endif /* FSFW_TCDISTRIBUTION_CFDPDISTRIBUTOR_H_ */ diff --git a/tcdistribution/PUSDistributor.h b/tcdistribution/PUSDistributor.h index c6f863f0..db93fbb3 100644 --- a/tcdistribution/PUSDistributor.h +++ b/tcdistribution/PUSDistributor.h @@ -17,65 +17,65 @@ * @ingroup tc_distribution */ class PUSDistributor: public TcDistributor, - public PUSDistributorIF, - public AcceptsTelecommandsIF { +public PUSDistributorIF, +public AcceptsTelecommandsIF { public: - /** - * The ctor passes @c set_apid to the checker class and calls the - * TcDistribution ctor with a certain object id. - * @param setApid The APID of this receiving Application. - * @param setObjectId Object ID of the distributor itself - * @param setPacketSource Object ID of the source of TC packets. - * Must implement CCSDSDistributorIF. - */ - PUSDistributor(uint16_t setApid, object_id_t setObjectId, - object_id_t setPacketSource); - /** - * The destructor is empty. - */ - virtual ~PUSDistributor(); - ReturnValue_t registerService(AcceptsTelecommandsIF* service) override; - MessageQueueId_t getRequestQueue() override; - ReturnValue_t initialize() override; - uint16_t getIdentifier() override; + /** + * The ctor passes @c set_apid to the checker class and calls the + * TcDistribution ctor with a certain object id. + * @param setApid The APID of this receiving Application. + * @param setObjectId Object ID of the distributor itself + * @param setPacketSource Object ID of the source of TC packets. + * Must implement CCSDSDistributorIF. + */ + PUSDistributor(uint16_t setApid, object_id_t setObjectId, + object_id_t setPacketSource); + /** + * The destructor is empty. + */ + virtual ~PUSDistributor(); + ReturnValue_t registerService(AcceptsTelecommandsIF* service) override; + MessageQueueId_t getRequestQueue() override; + ReturnValue_t initialize() override; + uint16_t getIdentifier() override; protected: - /** - * This attribute contains the class, that performs a formal packet check. - */ - TcPacketCheck checker; - /** - * With this class, verification messages are sent to the - * TC Verification service. - */ - VerificationReporter verifyChannel; - /** - * The currently handled packet is stored here. - */ - TcPacketStoredPus* currentPacket = nullptr; + /** + * This attribute contains the class, that performs a formal packet check. + */ + TcPacketCheck checker; + /** + * With this class, verification messages are sent to the + * TC Verification service. + */ + VerificationReporter verifyChannel; + /** + * The currently handled packet is stored here. + */ + TcPacketStoredPus* currentPacket = nullptr; - /** - * With this variable, the current check status is stored to generate - * acceptance messages later. - */ - ReturnValue_t tcStatus; + /** + * With this variable, the current check status is stored to generate + * acceptance messages later. + */ + ReturnValue_t tcStatus; - const object_id_t packetSource; + const object_id_t packetSource; - /** - * This method reads the packet service, checks if such a service is - * registered and forwards the packet to the destination. - * It also initiates the formal packet check and sending of verification - * messages. - * @return Iterator to map entry of found service id - * or iterator to @c map.end(). - */ - TcMqMapIter selectDestination() override; - /** - * The callback here handles the generation of acceptance - * success/failure messages. - */ - ReturnValue_t callbackAfterSending(ReturnValue_t queueStatus) override; + /** + * This method reads the packet service, checks if such a service is + * registered and forwards the packet to the destination. + * It also initiates the formal packet check and sending of verification + * messages. + * @return Iterator to map entry of found service id + * or iterator to @c map.end(). + */ + TcMqMapIter selectDestination() override; + /** + * The callback here handles the generation of acceptance + * success/failure messages. + */ + ReturnValue_t callbackAfterSending(ReturnValue_t queueStatus) override; }; #endif /* FSFW_TCDISTRIBUTION_PUSDISTRIBUTOR_H_ */ diff --git a/tcdistribution/PUSDistributorIF.h b/tcdistribution/PUSDistributorIF.h index 0125c08f..e4a66758 100644 --- a/tcdistribution/PUSDistributorIF.h +++ b/tcdistribution/PUSDistributorIF.h @@ -10,18 +10,18 @@ */ class PUSDistributorIF { public: - /** - * The empty virtual destructor. - */ - virtual ~PUSDistributorIF() { - } -/** - * With this method, Services can register themselves at the PUS Distributor. - * @param service A pointer to the registering Service. - * @return - @c RETURN_OK on success, - * - @c RETURN_FAILED on failure. - */ - virtual ReturnValue_t registerService( AcceptsTelecommandsIF* service ) = 0; + /** + * The empty virtual destructor. + */ + virtual ~PUSDistributorIF() { + } + /** + * With this method, Services can register themselves at the PUS Distributor. + * @param service A pointer to the registering Service. + * @return - @c RETURN_OK on success, + * - @c RETURN_FAILED on failure. + */ + virtual ReturnValue_t registerService( AcceptsTelecommandsIF* service ) = 0; }; #endif /* FSFW_TCDISTRIBUTION_PUSDISTRIBUTORIF_H_ */ From 8a4ce91501b36e60dd484387772feb182187ae71 Mon Sep 17 00:00:00 2001 From: tomatze Date: Sun, 4 Jul 2021 15:39:07 +0200 Subject: [PATCH 06/38] fixed copied comment --- tcdistribution/CFDPDistributorIF.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tcdistribution/CFDPDistributorIF.h b/tcdistribution/CFDPDistributorIF.h index dd017c97..5f70e542 100644 --- a/tcdistribution/CFDPDistributorIF.h +++ b/tcdistribution/CFDPDistributorIF.h @@ -16,7 +16,7 @@ public: virtual ~CFDPDistributorIF() { } /** - * With this method, Services can register themselves at the PUS Distributor. + * With this method, Services can register themselves at the CFDP Distributor. * @param service A pointer to the registering Service. * @return - @c RETURN_OK on success, * - @c RETURN_FAILED on failure. From 4860d984f348ea2ae77f1fe2f128ef05bb542012 Mon Sep 17 00:00:00 2001 From: tomatze Date: Sun, 4 Jul 2021 16:20:26 +0200 Subject: [PATCH 07/38] refactored TcPacketCheck into TcPacketCheckIF to implement a CFDP packet checker --- tcdistribution/CFDPDistributor.h | 5 ++- tcdistribution/CMakeLists.txt | 3 +- tcdistribution/PUSDistributor.h | 5 ++- tcdistribution/TcPacketCheckCFDP.cpp | 13 +++++++ tcdistribution/TcPacketCheckCFDP.h | 35 +++++++++++++++++++ tcdistribution/TcPacketCheckIF.h | 32 +++++++++++++++++ ...TcPacketCheck.cpp => TcPacketCheckPUS.cpp} | 8 ++--- .../{TcPacketCheck.h => TcPacketCheckPUS.h} | 25 ++++++------- 8 files changed, 101 insertions(+), 25 deletions(-) create mode 100644 tcdistribution/TcPacketCheckCFDP.cpp create mode 100644 tcdistribution/TcPacketCheckCFDP.h create mode 100644 tcdistribution/TcPacketCheckIF.h rename tcdistribution/{TcPacketCheck.cpp => TcPacketCheckPUS.cpp} (85%) rename tcdistribution/{TcPacketCheck.h => TcPacketCheckPUS.h} (75%) diff --git a/tcdistribution/CFDPDistributor.h b/tcdistribution/CFDPDistributor.h index d61357b2..3b4c31f2 100644 --- a/tcdistribution/CFDPDistributor.h +++ b/tcdistribution/CFDPDistributor.h @@ -1,10 +1,9 @@ #ifndef FSFW_TCDISTRIBUTION_CFDPDISTRIBUTOR_H_ #define FSFW_TCDISTRIBUTION_CFDPDISTRIBUTOR_H_ +#include "TcPacketCheckCFDP.h" #include "CFDPDistributorIF.h" #include "TcDistributor.h" -#include "TcPacketCheck.h" - #include "../tmtcpacket/pus/tc.h" #include "../returnvalues/HasReturnvaluesIF.h" #include "../tmtcservices/AcceptsTelecommandsIF.h" @@ -43,7 +42,7 @@ protected: /** * This attribute contains the class, that performs a formal packet check. */ - TcPacketCheck checker; + TcPacketCheckCFDP checker; /** * With this class, verification messages are sent to the * TC Verification service. diff --git a/tcdistribution/CMakeLists.txt b/tcdistribution/CMakeLists.txt index 359b8a81..7118c38c 100644 --- a/tcdistribution/CMakeLists.txt +++ b/tcdistribution/CMakeLists.txt @@ -2,7 +2,8 @@ target_sources(${LIB_FSFW_NAME} PRIVATE CCSDSDistributor.cpp PUSDistributor.cpp TcDistributor.cpp - TcPacketCheck.cpp + TcPacketCheckPUS.cpp + TcPacketCheckCFDP.cpp CFDPDistributor.cpp ) diff --git a/tcdistribution/PUSDistributor.h b/tcdistribution/PUSDistributor.h index db93fbb3..1c9d4dfc 100644 --- a/tcdistribution/PUSDistributor.h +++ b/tcdistribution/PUSDistributor.h @@ -1,10 +1,9 @@ #ifndef FSFW_TCDISTRIBUTION_PUSDISTRIBUTOR_H_ #define FSFW_TCDISTRIBUTION_PUSDISTRIBUTOR_H_ +#include "TcPacketCheckPUS.h" #include "PUSDistributorIF.h" #include "TcDistributor.h" -#include "TcPacketCheck.h" - #include "../tmtcpacket/pus/tc.h" #include "../returnvalues/HasReturnvaluesIF.h" #include "../tmtcservices/AcceptsTelecommandsIF.h" @@ -43,7 +42,7 @@ protected: /** * This attribute contains the class, that performs a formal packet check. */ - TcPacketCheck checker; + TcPacketCheckPUS checker; /** * With this class, verification messages are sent to the * TC Verification service. diff --git a/tcdistribution/TcPacketCheckCFDP.cpp b/tcdistribution/TcPacketCheckCFDP.cpp new file mode 100644 index 00000000..2b0e3d32 --- /dev/null +++ b/tcdistribution/TcPacketCheckCFDP.cpp @@ -0,0 +1,13 @@ +#include "TcPacketCheckCFDP.h" + + +TcPacketCheckCFDP::TcPacketCheckCFDP(uint16_t setApid): apid(setApid) { +} + +ReturnValue_t TcPacketCheckCFDP::checkPacket(TcPacketStoredBase* currentPacket) { + return RETURN_OK; +} + +uint16_t TcPacketCheckCFDP::getApid() const { + return apid; +} diff --git a/tcdistribution/TcPacketCheckCFDP.h b/tcdistribution/TcPacketCheckCFDP.h new file mode 100644 index 00000000..41a65f08 --- /dev/null +++ b/tcdistribution/TcPacketCheckCFDP.h @@ -0,0 +1,35 @@ +#ifndef FSFW_TCDISTRIBUTION_TCPACKETCHECKCFDP_H_ +#define FSFW_TCDISTRIBUTION_TCPACKETCHECKCFDP_H_ + +#include "TcPacketCheckIF.h" + +#include "../FSFW.h" + +class TcPacketStoredBase; + +/** + * This class performs a formal packet check for incoming CFDP Packets. + * @ingroup tc_distribution + */ +class TcPacketCheckCFDP : + public TcPacketCheckIF, + public HasReturnvaluesIF { +protected: + /** + * The packet id each correct packet should have. + * It is composed of the APID and some static fields. + */ + uint16_t apid; +public: + /** + * The constructor only sets the APID attribute. + * @param set_apid The APID to set. + */ + TcPacketCheckCFDP(uint16_t setApid); + + ReturnValue_t checkPacket(TcPacketStoredBase* currentPacket) override; + + uint16_t getApid() const; +}; + +#endif /* FSFW_TCDISTRIBUTION_TCPACKETCHECKCFDP_H_ */ diff --git a/tcdistribution/TcPacketCheckIF.h b/tcdistribution/TcPacketCheckIF.h new file mode 100644 index 00000000..58c17021 --- /dev/null +++ b/tcdistribution/TcPacketCheckIF.h @@ -0,0 +1,32 @@ +#ifndef FSFW_TCDISTRIBUTION_TCPACKETCHECKIF_H_ +#define FSFW_TCDISTRIBUTION_TCPACKETCHECKIF_H_ + +#include "../returnvalues/HasReturnvaluesIF.h" + +// TODO TcPacketStoredBase is currently only for PUS packets. not for CFDP packets +class TcPacketStoredBase; + +/** + * This interface is used by PacketCheckers for PUS packets and CFDP packets . + * @ingroup tc_distribution + */ +class TcPacketCheckIF { +public: + /** + * The empty virtual destructor. + */ + virtual ~TcPacketCheckIF() { + } + + /** + * This is the actual method to formally check a certain Packet. + * The packet's Application Data can not be checked here. + * @param current_packet The packet to check + * @return - @c RETURN_OK on success. + * - @c INCORRECT_CHECKSUM if checksum is invalid. + * - @c ILLEGAL_APID if APID does not match. + */ + virtual ReturnValue_t checkPacket(TcPacketStoredBase* currentPacket) = 0; +}; + +#endif /* FSFW_TCDISTRIBUTION_TCPACKETCHECKIF_H_ */ diff --git a/tcdistribution/TcPacketCheck.cpp b/tcdistribution/TcPacketCheckPUS.cpp similarity index 85% rename from tcdistribution/TcPacketCheck.cpp rename to tcdistribution/TcPacketCheckPUS.cpp index b3a025a4..a338585e 100644 --- a/tcdistribution/TcPacketCheck.cpp +++ b/tcdistribution/TcPacketCheckPUS.cpp @@ -1,4 +1,4 @@ -#include "TcPacketCheck.h" +#include "TcPacketCheckPUS.h" #include "../globalfunctions/CRC.h" #include "../tmtcpacket/pus/tc/TcPacketBase.h" @@ -7,10 +7,10 @@ #include "../storagemanager/StorageManagerIF.h" #include "../tmtcservices/VerificationCodes.h" -TcPacketCheck::TcPacketCheck(uint16_t setApid): apid(setApid) { +TcPacketCheckPUS::TcPacketCheckPUS(uint16_t setApid): apid(setApid) { } -ReturnValue_t TcPacketCheck::checkPacket(TcPacketStoredBase* currentPacket) { +ReturnValue_t TcPacketCheckPUS::checkPacket(TcPacketStoredBase* currentPacket) { TcPacketBase* tcPacketBase = currentPacket->getPacketBase(); if(tcPacketBase == nullptr) { return RETURN_FAILED; @@ -41,6 +41,6 @@ ReturnValue_t TcPacketCheck::checkPacket(TcPacketStoredBase* currentPacket) { return RETURN_OK; } -uint16_t TcPacketCheck::getApid() const { +uint16_t TcPacketCheckPUS::getApid() const { return apid; } diff --git a/tcdistribution/TcPacketCheck.h b/tcdistribution/TcPacketCheckPUS.h similarity index 75% rename from tcdistribution/TcPacketCheck.h rename to tcdistribution/TcPacketCheckPUS.h index 7106b7e4..85b30378 100644 --- a/tcdistribution/TcPacketCheck.h +++ b/tcdistribution/TcPacketCheckPUS.h @@ -1,5 +1,7 @@ -#ifndef FSFW_TCDISTRIBUTION_TCPACKETCHECK_H_ -#define FSFW_TCDISTRIBUTION_TCPACKETCHECK_H_ +#ifndef FSFW_TCDISTRIBUTION_TCPACKETCHECKPUS_H_ +#define FSFW_TCDISTRIBUTION_TCPACKETCHECKPUS_H_ + +#include "TcPacketCheckIF.h" #include "../FSFW.h" #include "../returnvalues/HasReturnvaluesIF.h" @@ -12,7 +14,9 @@ class TcPacketStoredBase; * Currently, it only checks if the APID and CRC are correct. * @ingroup tc_distribution */ -class TcPacketCheck : public HasReturnvaluesIF { +class TcPacketCheckPUS : + public TcPacketCheckIF, + public HasReturnvaluesIF { protected: /** * Describes the version number a packet must have to pass. @@ -49,18 +53,11 @@ public: * The constructor only sets the APID attribute. * @param set_apid The APID to set. */ - TcPacketCheck(uint16_t setApid); - /** - * This is the actual method to formally check a certain Telecommand Packet. - * The packet's Application Data can not be checked here. - * @param current_packet The packt to check - * @return - @c RETURN_OK on success. - * - @c INCORRECT_CHECKSUM if checksum is invalid. - * - @c ILLEGAL_APID if APID does not match. - */ - ReturnValue_t checkPacket(TcPacketStoredBase* currentPacket); + TcPacketCheckPUS(uint16_t setApid); + + ReturnValue_t checkPacket(TcPacketStoredBase* currentPacket) override; uint16_t getApid() const; }; -#endif /* FSFW_TCDISTRIBUTION_TCPACKETCHECK_H_ */ +#endif /* FSFW_TCDISTRIBUTION_TCPACKETCHECKPUS_H_ */ From eb896157226b913fbc447a6143ef4e8ff16b4c66 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 15 Jul 2021 20:06:20 +0200 Subject: [PATCH 08/38] update fsfw, fixes for CFDP --- CMakeLists.txt | 2 +- src/core/tcdistribution/CFDPDistributor.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5ea8c9b1..fa721031 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,7 +29,7 @@ elseif(${CMAKE_CXX_STANDARD} LESS 11) endif() # Backwards comptability -if(OS_FSFW) +if(OS_FSFW AND NOT FSFW_OSAL) message(WARNING "Please pass the FSFW OSAL as FSFW_OSAL instead of OS_FSFW") set(FSFW_OSAL OS_FSFW) endif() diff --git a/src/core/tcdistribution/CFDPDistributor.cpp b/src/core/tcdistribution/CFDPDistributor.cpp index 1b257517..9266a7fa 100644 --- a/src/core/tcdistribution/CFDPDistributor.cpp +++ b/src/core/tcdistribution/CFDPDistributor.cpp @@ -1,8 +1,8 @@ -#include "CCSDSDistributorIF.h" -#include "CFDPDistributor.h" +#include "fsfw/tcdistribution/CCSDSDistributorIF.h" +#include "fsfw/tcdistribution/CFDPDistributor.h" -#include "../objectmanager/ObjectManager.h" -#include "../serviceinterface/ServiceInterface.h" +#include "fsfw/objectmanager/ObjectManager.h" +#include "fsfw/serviceinterface/ServiceInterface.h" #define CFDP_DISTRIBUTOR_DEBUGGING 0 From a6e5b267a3e8bc788a179bf3313e58b72400e0e4 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 16 Jul 2021 16:11:58 +0200 Subject: [PATCH 09/38] moved mutex.cpp --- inc/fsfw/osal/host/MessageQueue.h | 2 +- inc/fsfw/osal/host/Mutex.cpp | 32 ------------------------------- src/osal/host/Mutex.cpp | 32 +++++++++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 33 deletions(-) delete mode 100644 inc/fsfw/osal/host/Mutex.cpp create mode 100644 src/osal/host/Mutex.cpp diff --git a/inc/fsfw/osal/host/MessageQueue.h b/inc/fsfw/osal/host/MessageQueue.h index 1c9b5e33..36a7ca4d 100644 --- a/inc/fsfw/osal/host/MessageQueue.h +++ b/inc/fsfw/osal/host/MessageQueue.h @@ -1,7 +1,7 @@ #ifndef FRAMEWORK_OSAL_HOST_MESSAGEQUEUE_H_ #define FRAMEWORK_OSAL_HOST_MESSAGEQUEUE_H_ -#include "../../internalError/InternalErrorReporterIF.h" +#include "fsfw/internalerror/InternalErrorReporterIF.h" #include "../../ipc/MessageQueueIF.h" #include "../../ipc/MessageQueueMessage.h" #include "../../ipc/MutexIF.h" diff --git a/inc/fsfw/osal/host/Mutex.cpp b/inc/fsfw/osal/host/Mutex.cpp deleted file mode 100644 index 892028b2..00000000 --- a/inc/fsfw/osal/host/Mutex.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#include "Mutex.h" -#include "../../serviceinterface/ServiceInterfaceStream.h" - -Mutex::Mutex() {} - -ReturnValue_t Mutex::lockMutex(TimeoutType timeoutType, uint32_t timeoutMs) { - if(timeoutType == TimeoutType::BLOCKING) { - mutex.lock(); - return HasReturnvaluesIF::RETURN_OK; - } - else if(timeoutType == TimeoutType::POLLING) { - if(mutex.try_lock()) { - return HasReturnvaluesIF::RETURN_OK; - } - } - else if(timeoutType == TimeoutType::WAITING){ - auto chronoMs = std::chrono::milliseconds(timeoutMs); - if(mutex.try_lock_for(chronoMs)) { - return HasReturnvaluesIF::RETURN_OK; - } - } - return MutexIF::MUTEX_TIMEOUT; -} - -ReturnValue_t Mutex::unlockMutex() { - mutex.unlock(); - return HasReturnvaluesIF::RETURN_OK; -} - -std::timed_mutex* Mutex::getMutexHandle() { - return &mutex; -} diff --git a/src/osal/host/Mutex.cpp b/src/osal/host/Mutex.cpp new file mode 100644 index 00000000..7a56f7cb --- /dev/null +++ b/src/osal/host/Mutex.cpp @@ -0,0 +1,32 @@ +#include "fsfw/osal/host/Mutex.h" +#include "fsfw/serviceinterface/ServiceInterface.h" +# +Mutex::Mutex() {} + +ReturnValue_t Mutex::lockMutex(TimeoutType timeoutType, uint32_t timeoutMs) { + if(timeoutType == TimeoutType::BLOCKING) { + mutex.lock(); + return HasReturnvaluesIF::RETURN_OK; + } + else if(timeoutType == TimeoutType::POLLING) { + if(mutex.try_lock()) { + return HasReturnvaluesIF::RETURN_OK; + } + } + else if(timeoutType == TimeoutType::WAITING){ + auto chronoMs = std::chrono::milliseconds(timeoutMs); + if(mutex.try_lock_for(chronoMs)) { + return HasReturnvaluesIF::RETURN_OK; + } + } + return MutexIF::MUTEX_TIMEOUT; +} + +ReturnValue_t Mutex::unlockMutex() { + mutex.unlock(); + return HasReturnvaluesIF::RETURN_OK; +} + +std::timed_mutex* Mutex::getMutexHandle() { + return &mutex; +} From 974d25dbb1862eb02689a354c5ef5c72c8769002 Mon Sep 17 00:00:00 2001 From: tomatze Date: Sun, 18 Jul 2021 20:36:47 +0200 Subject: [PATCH 10/38] added CFDPHandler (not working yet) --- inc/fsfw/cfdp/CFDPHandler.h | 63 ++++++++++++++ inc/fsfw/objectmanager/frameworkObjects.h | 3 + inc/fsfw/tcdistribution/CFDPDistributor.h | 19 ++--- inc/fsfw/tcdistribution/CFDPDistributorIF.h | 14 +-- inc/fsfw/tmtcpacket/cfdp/CFDPPacket.h | 27 ++++++ inc/fsfw/tmtcpacket/cfdp/CFDPPacketStored.h | 64 ++++++++++++++ src/core/CMakeLists.txt | 1 + src/core/cfdp/CFDPHandler.cpp | 59 +++++++++++++ src/core/cfdp/CMakeLists.txt | 4 + src/core/tcdistribution/CFDPDistributor.cpp | 78 ++++++++--------- src/core/tmtcpacket/CMakeLists.txt | 1 + src/core/tmtcpacket/cfdp/CFDPPacket.cpp | 20 +++++ src/core/tmtcpacket/cfdp/CFDPPacketStored.cpp | 85 +++++++++++++++++++ src/core/tmtcpacket/cfdp/CMakeLists.txt | 4 + 14 files changed, 377 insertions(+), 65 deletions(-) create mode 100644 inc/fsfw/cfdp/CFDPHandler.h create mode 100644 inc/fsfw/tmtcpacket/cfdp/CFDPPacket.h create mode 100644 inc/fsfw/tmtcpacket/cfdp/CFDPPacketStored.h create mode 100644 src/core/cfdp/CFDPHandler.cpp create mode 100644 src/core/cfdp/CMakeLists.txt create mode 100644 src/core/tmtcpacket/cfdp/CFDPPacket.cpp create mode 100644 src/core/tmtcpacket/cfdp/CFDPPacketStored.cpp create mode 100644 src/core/tmtcpacket/cfdp/CMakeLists.txt diff --git a/inc/fsfw/cfdp/CFDPHandler.h b/inc/fsfw/cfdp/CFDPHandler.h new file mode 100644 index 00000000..ad561af7 --- /dev/null +++ b/inc/fsfw/cfdp/CFDPHandler.h @@ -0,0 +1,63 @@ +#ifndef FSFW_CFDP_CFDPHANDLER_H_ +#define FSFW_CFDP_CFDPHANDLER_H_ + +#include "fsfw/tmtcservices/AcceptsTelecommandsIF.h" +#include "fsfw/objectmanager/SystemObject.h" +#include "fsfw/returnvalues/HasReturnvaluesIF.h" +#include "fsfw/tasks/ExecutableObjectIF.h" +#include "fsfw/tcdistribution/CFDPDistributor.h" + +#include "fsfw/ipc/MessageQueueIF.h" + +namespace Factory{ +void setStaticFrameworkObjectIds(); +} + +class CFDPHandler : + public ExecutableObjectIF, + public AcceptsTelecommandsIF, + public SystemObject, + public HasReturnvaluesIF { + friend void (Factory::setStaticFrameworkObjectIds)(); +public: + CFDPHandler(object_id_t setObjectId, CFDPDistributor* distributor); + /** + * The destructor is empty. + */ + virtual ~CFDPHandler(); + + virtual ReturnValue_t handleRequest(uint8_t subservice); + + virtual ReturnValue_t performService(); + virtual ReturnValue_t initialize() override; + virtual uint16_t getIdentifier() override; + MessageQueueId_t getRequestQueue() override; + ReturnValue_t performOperation(uint8_t opCode) override; +protected: + /** + * This is a complete instance of the telecommand reception queue + * of the class. It is initialized on construction of the class. + */ + MessageQueueIF* requestQueue = nullptr; + + CFDPDistributor* distributor = nullptr; + + /** + * The current CFDP packet to be processed. + * It is deleted after handleRequest was executed. + */ + CFDPPacketStored currentPacket; + + static object_id_t packetSource; + + static object_id_t packetDestination; +private: + /** + * This constant sets the maximum number of packets accepted per call. + * Remember that one packet must be completely handled in one + * #handleRequest call. + */ + static const uint8_t CFDP_HANDLER_MAX_RECEPTION = 10; +}; + +#endif /* FSFW_CFDP_CFDPHANDLER_H_ */ diff --git a/inc/fsfw/objectmanager/frameworkObjects.h b/inc/fsfw/objectmanager/frameworkObjects.h index 36010807..acbb5f01 100644 --- a/inc/fsfw/objectmanager/frameworkObjects.h +++ b/inc/fsfw/objectmanager/frameworkObjects.h @@ -19,6 +19,9 @@ enum framework_objects: object_id_t { PUS_SERVICE_200_MODE_MGMT = 0x53000200, PUS_SERVICE_201_HEALTH = 0x53000201, + /* CFDP Distributer */ + CFDP_PACKET_DISTRIBUTOR = 0x53001000, + //Generic IDs for IPC, modes, health, events HEALTH_TABLE = 0x53010000, // MODE_STORE = 0x53010100, diff --git a/inc/fsfw/tcdistribution/CFDPDistributor.h b/inc/fsfw/tcdistribution/CFDPDistributor.h index 3b4c31f2..12436be2 100644 --- a/inc/fsfw/tcdistribution/CFDPDistributor.h +++ b/inc/fsfw/tcdistribution/CFDPDistributor.h @@ -1,10 +1,9 @@ #ifndef FSFW_TCDISTRIBUTION_CFDPDISTRIBUTOR_H_ #define FSFW_TCDISTRIBUTION_CFDPDISTRIBUTOR_H_ -#include "TcPacketCheckCFDP.h" #include "CFDPDistributorIF.h" #include "TcDistributor.h" -#include "../tmtcpacket/pus/tc.h" +#include "../tmtcpacket/cfdp/CFDPPacketStored.h" #include "../returnvalues/HasReturnvaluesIF.h" #include "../tmtcservices/AcceptsTelecommandsIF.h" #include "../tmtcservices/VerificationReporter.h" @@ -33,25 +32,17 @@ public: * The destructor is empty. */ virtual ~CFDPDistributor(); - ReturnValue_t registerService(AcceptsTelecommandsIF* service) override; + ReturnValue_t registerHandler(AcceptsTelecommandsIF* handler) override; MessageQueueId_t getRequestQueue() override; ReturnValue_t initialize() override; uint16_t getIdentifier() override; protected: - /** - * This attribute contains the class, that performs a formal packet check. - */ - TcPacketCheckCFDP checker; - /** - * With this class, verification messages are sent to the - * TC Verification service. - */ - VerificationReporter verifyChannel; + uint16_t apid; /** * The currently handled packet is stored here. */ - TcPacketStoredPus* currentPacket = nullptr; + CFDPPacketStored* currentPacket = nullptr; /** * With this variable, the current check status is stored to generate * acceptance messages later. @@ -73,7 +64,7 @@ protected: * The callback here handles the generation of acceptance * success/failure messages. */ - ReturnValue_t callbackAfterSending(ReturnValue_t queueStatus) override; + //ReturnValue_t callbackAfterSending(ReturnValue_t queueStatus) override; }; #endif /* FSFW_TCDISTRIBUTION_CFDPDISTRIBUTOR_H_ */ diff --git a/inc/fsfw/tcdistribution/CFDPDistributorIF.h b/inc/fsfw/tcdistribution/CFDPDistributorIF.h index 5f70e542..f1c85772 100644 --- a/inc/fsfw/tcdistribution/CFDPDistributorIF.h +++ b/inc/fsfw/tcdistribution/CFDPDistributorIF.h @@ -15,13 +15,13 @@ public: */ virtual ~CFDPDistributorIF() { } -/** - * With this method, Services can register themselves at the CFDP Distributor. - * @param service A pointer to the registering Service. - * @return - @c RETURN_OK on success, - * - @c RETURN_FAILED on failure. - */ - virtual ReturnValue_t registerService( AcceptsTelecommandsIF* service ) = 0; + /** + * With this method, Handlers can register themselves at the CFDP Distributor. + * @param handler A pointer to the registering Handler. + * @return - @c RETURN_OK on success, + * - @c RETURN_FAILED on failure. + */ + virtual ReturnValue_t registerHandler(AcceptsTelecommandsIF* handler) = 0; }; #endif /* FSFW_TCDISTRIBUTION_CFDPDISTRIBUTORIF_H_ */ diff --git a/inc/fsfw/tmtcpacket/cfdp/CFDPPacket.h b/inc/fsfw/tmtcpacket/cfdp/CFDPPacket.h new file mode 100644 index 00000000..f288a8ae --- /dev/null +++ b/inc/fsfw/tmtcpacket/cfdp/CFDPPacket.h @@ -0,0 +1,27 @@ +#ifndef FSFW_INC_FSFW_TMTCPACKET_CFDP_CFDPPACKET_H_ +#define FSFW_INC_FSFW_TMTCPACKET_CFDP_CFDPPACKET_H_ + +#include "fsfw/tmtcpacket/SpacePacketBase.h" + +class CFDPPacket : public SpacePacketBase { +public: + /** + * This is the default constructor. + * It sets its internal data pointer to the address passed and also + * forwards the data pointer to the parent SpacePacketBase class. + * @param setData The position where the packet data lies. + */ + CFDPPacket( const uint8_t* setData ); + /** + * This is the empty default destructor. + */ + virtual ~CFDPPacket(); + + /** + * This is a debugging helper method that prints the whole packet content + * to the screen. + */ + void print(); +}; + +#endif /* FSFW_INC_FSFW_TMTCPACKET_CFDP_CFDPPACKET_H_ */ diff --git a/inc/fsfw/tmtcpacket/cfdp/CFDPPacketStored.h b/inc/fsfw/tmtcpacket/cfdp/CFDPPacketStored.h new file mode 100644 index 00000000..8bc0f281 --- /dev/null +++ b/inc/fsfw/tmtcpacket/cfdp/CFDPPacketStored.h @@ -0,0 +1,64 @@ +#ifndef FSFW_INC_FSFW_TMTCPACKET_CFDP_CFDPPACKETSTORED_H_ +#define FSFW_INC_FSFW_TMTCPACKET_CFDP_CFDPPACKETSTORED_H_ + +#include "../pus/tc/TcPacketStoredBase.h" +#include "CFDPPacket.h" + +class CFDPPacketStored: + public CFDPPacket { +public: + /** + * Create stored packet with existing data. + * @param data + * @param size + */ + CFDPPacketStored(const uint8_t* data, size_t size); + /** + * Create stored packet from existing packet in store + * @param setAddress + */ + CFDPPacketStored(store_address_t setAddress); + CFDPPacketStored(); + + /** + * Getter function for the raw data. + * @param dataPtr [out] Pointer to the data pointer to set + * @param dataSize [out] Address of size to set. + * @return -@c RETURN_OK if data was retrieved successfully. + */ + ReturnValue_t getData(const uint8_t ** dataPtr, size_t* dataSize); + + void setStoreAddress(store_address_t setAddress); + + store_address_t getStoreAddress(); + + ReturnValue_t deletePacket(); + +private: + + bool isSizeCorrect(); +protected: + /** + * This is a pointer to the store all instances of the class use. + * If the store is not yet set (i.e. @c store is NULL), every constructor + * call tries to set it and throws an error message in case of failures. + * The default store is objects::TC_STORE. + */ + static StorageManagerIF* store; + /** + * The address where the packet data of the object instance is stored. + */ + store_address_t storeAddress; + /** + * A helper method to check if a store is assigned to the class. + * If not, the method tries to retrieve the store from the global + * ObjectManager. + * @return @li @c true if the store is linked or could be created. + * @li @c false otherwise. + */ + bool checkAndSetStore(); +}; + + + +#endif /* FSFW_INC_FSFW_TMTCPACKET_CFDP_CFDPPACKETSTORED_H_ */ diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 4a2f7a2c..f769d95c 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -1,4 +1,5 @@ add_subdirectory(action) +add_subdirectory(cfdp) add_subdirectory(container) add_subdirectory(controller) add_subdirectory(datapool) diff --git a/src/core/cfdp/CFDPHandler.cpp b/src/core/cfdp/CFDPHandler.cpp new file mode 100644 index 00000000..d1c40546 --- /dev/null +++ b/src/core/cfdp/CFDPHandler.cpp @@ -0,0 +1,59 @@ +#include "fsfw/cfdp/CFDPHandler.h" + +#include "fsfw/tmtcservices/AcceptsTelemetryIF.h" +#include "fsfw/ipc/QueueFactory.h" +#include "fsfw/objectmanager/ObjectManager.h" + +object_id_t CFDPHandler::packetSource = 0; +object_id_t CFDPHandler::packetDestination = 0; + +CFDPHandler::CFDPHandler(object_id_t setObjectId, CFDPDistributor* dist) : SystemObject(setObjectId) { + requestQueue = QueueFactory::instance()->createMessageQueue(CFDP_HANDLER_MAX_RECEPTION); + distributor = dist; +} + +CFDPHandler::~CFDPHandler() {} + +ReturnValue_t CFDPHandler::initialize() { + ReturnValue_t result = SystemObject::initialize(); + if (result != RETURN_OK) { + return result; + } + this->distributor->registerHandler(this); + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t CFDPHandler::handleRequest(uint8_t subservice) { +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::debug << "CFDPHandler::handleRequest" << std::endl; +#else + sif::printDebug("CFDPHandler::handleRequest"); +#endif /* !FSFW_CPP_OSTREAM_ENABLED == 1 */ +#endif + return RETURN_OK; +} + +ReturnValue_t CFDPHandler::performOperation(uint8_t opCode) { + ReturnValue_t result = this->performService(); + return result; +} + +ReturnValue_t CFDPHandler::performService() { +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::debug << "CFDPHandler::performService" << std::endl; +#else + sif::printDebug("CFDPHandler::performService"); +#endif /* !FSFW_CPP_OSTREAM_ENABLED == 1 */ +#endif + return RETURN_OK; +} + +uint16_t CFDPHandler::getIdentifier() { + return 0; +} + +MessageQueueId_t CFDPHandler::getRequestQueue() { + return this->requestQueue->getId(); +} diff --git a/src/core/cfdp/CMakeLists.txt b/src/core/cfdp/CMakeLists.txt new file mode 100644 index 00000000..9410743f --- /dev/null +++ b/src/core/cfdp/CMakeLists.txt @@ -0,0 +1,4 @@ +target_sources(${LIB_FSFW_NAME} + PRIVATE + CFDPHandler.cpp +) diff --git a/src/core/tcdistribution/CFDPDistributor.cpp b/src/core/tcdistribution/CFDPDistributor.cpp index 9266a7fa..37294988 100644 --- a/src/core/tcdistribution/CFDPDistributor.cpp +++ b/src/core/tcdistribution/CFDPDistributor.cpp @@ -1,15 +1,18 @@ #include "fsfw/tcdistribution/CCSDSDistributorIF.h" #include "fsfw/tcdistribution/CFDPDistributor.h" +#include "fsfw/tmtcpacket/cfdp/CFDPPacketStored.h" + #include "fsfw/objectmanager/ObjectManager.h" -#include "fsfw/serviceinterface/ServiceInterface.h" #define CFDP_DISTRIBUTOR_DEBUGGING 0 CFDPDistributor::CFDPDistributor(uint16_t setApid, object_id_t setObjectId, object_id_t setPacketSource) : - TcDistributor(setObjectId), checker(setApid), verifyChannel(), - tcStatus(RETURN_FAILED), packetSource(setPacketSource) {} + TcDistributor(setObjectId), + tcStatus(RETURN_FAILED), packetSource(setPacketSource) { + this->apid = setApid; +} CFDPDistributor::~CFDPDistributor() {} @@ -30,20 +33,7 @@ CFDPDistributor::TcMqMapIter CFDPDistributor::selectDestination() { } this->currentPacket->setStoreAddress(this->currentMessage.getStorageId()); if (currentPacket->getWholeData() != nullptr) { - tcStatus = checker.checkPacket(currentPacket); - if(tcStatus != HasReturnvaluesIF::RETURN_OK) { -#if FSFW_VERBOSE_LEVEL >= 1 -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::debug << "CFDPDistributor::handlePacket: Packet format invalid, code " << - static_cast(tcStatus) << std::endl; -#else - sif::printDebug("CFDPDistributor::handlePacket: Packet format invalid, code %d\n", - static_cast(tcStatus)); -#endif -#endif - } - uint32_t queue_id = currentPacket->getService(); - queueMapIt = this->queueMap.find(queue_id); + queueMapIt = this->queueMap.find(0); } else { tcStatus = PACKET_LOST; @@ -70,24 +60,24 @@ CFDPDistributor::TcMqMapIter CFDPDistributor::selectDestination() { } -ReturnValue_t CFDPDistributor::registerService(AcceptsTelecommandsIF* service) { - uint16_t serviceId = service->getIdentifier(); +ReturnValue_t CFDPDistributor::registerHandler(AcceptsTelecommandsIF* handler) { + uint16_t handlerId = handler->getIdentifier(); //should be 0, because CFDPHandler does not set a set a service-ID #if CFDP_DISTRIBUTOR_DEBUGGING == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::info << "Service ID: " << static_cast(serviceId) << std::endl; + sif::info << "CFDPDistributor::registerHandler: Handler ID: " << static_cast(handlerId) << std::endl; #else - sif::printInfo("Service ID: %d\n", static_cast(serviceId)); + sif::printInfo("CFDPDistributor::registerHandler: Handler ID: %d\n", static_cast(handlerId)); #endif #endif - MessageQueueId_t queue = service->getRequestQueue(); - auto returnPair = queueMap.emplace(serviceId, queue); + MessageQueueId_t queue = handler->getRequestQueue(); + auto returnPair = queueMap.emplace(handlerId, queue); if (not returnPair.second) { #if FSFW_VERBOSE_LEVEL >= 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "CFDPDistributor::registerService: Service ID already" + sif::error << "CFDPDistributor::registerHandler: Service ID already" " exists in map" << std::endl; #else - sif::printError("CFDPDistributor::registerService: Service ID already exists in map\n"); + sif::printError("CFDPDistributor::registerHandler: Service ID already exists in map\n"); #endif #endif return SERVICE_ID_ALREADY_EXISTS; @@ -99,30 +89,30 @@ MessageQueueId_t CFDPDistributor::getRequestQueue() { return tcQueue->getId(); } -ReturnValue_t CFDPDistributor::callbackAfterSending(ReturnValue_t queueStatus) { - if (queueStatus != RETURN_OK) { - tcStatus = queueStatus; - } - if (tcStatus != RETURN_OK) { - this->verifyChannel.sendFailureReport(tc_verification::ACCEPTANCE_FAILURE, - currentPacket, tcStatus); - // A failed packet is deleted immediately after reporting, - // otherwise it will block memory. - currentPacket->deletePacket(); - return RETURN_FAILED; - } else { - this->verifyChannel.sendSuccessReport(tc_verification::ACCEPTANCE_SUCCESS, - currentPacket); - return RETURN_OK; - } -} +//ReturnValue_t CFDPDistributor::callbackAfterSending(ReturnValue_t queueStatus) { +// if (queueStatus != RETURN_OK) { +// tcStatus = queueStatus; +// } +// if (tcStatus != RETURN_OK) { +// this->verifyChannel.sendFailureReport(tc_verification::ACCEPTANCE_FAILURE, +// currentPacket, tcStatus); +// // A failed packet is deleted immediately after reporting, +// // otherwise it will block memory. +// currentPacket->deletePacket(); +// return RETURN_FAILED; +// } else { +// this->verifyChannel.sendSuccessReport(tc_verification::ACCEPTANCE_SUCCESS, +// currentPacket); +// return RETURN_OK; +// } +//} uint16_t CFDPDistributor::getIdentifier() { - return checker.getApid(); + return this->apid; } ReturnValue_t CFDPDistributor::initialize() { - currentPacket = new TcPacketStoredPus(); + currentPacket = new CFDPPacketStored(); if(currentPacket == nullptr) { // Should not happen, memory allocation failed! return ObjectManagerIF::CHILD_INIT_FAILED; diff --git a/src/core/tmtcpacket/CMakeLists.txt b/src/core/tmtcpacket/CMakeLists.txt index fdc884ec..e1deaba9 100644 --- a/src/core/tmtcpacket/CMakeLists.txt +++ b/src/core/tmtcpacket/CMakeLists.txt @@ -3,5 +3,6 @@ target_sources(${LIB_FSFW_NAME} PRIVATE SpacePacketBase.cpp ) +add_subdirectory(cfdp) add_subdirectory(packetmatcher) add_subdirectory(pus) \ No newline at end of file diff --git a/src/core/tmtcpacket/cfdp/CFDPPacket.cpp b/src/core/tmtcpacket/cfdp/CFDPPacket.cpp new file mode 100644 index 00000000..6172201e --- /dev/null +++ b/src/core/tmtcpacket/cfdp/CFDPPacket.cpp @@ -0,0 +1,20 @@ +#include "fsfw/tmtcpacket/cfdp/CFDPPacket.h" + +#include "fsfw/globalfunctions/CRC.h" +#include "fsfw/globalfunctions/arrayprinter.h" +#include "fsfw/serviceinterface/ServiceInterface.h" + +#include + +CFDPPacket::CFDPPacket(const uint8_t* setData): SpacePacketBase(setData) {} + +CFDPPacket::~CFDPPacket() {} + +void CFDPPacket::print() { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::info << "CFDPPacket::print:" << std::endl; +#else + sif::printInfo("CFDPPacket::print:\n"); +#endif + arrayprinter::print(getWholeData(), getFullSize()); +} diff --git a/src/core/tmtcpacket/cfdp/CFDPPacketStored.cpp b/src/core/tmtcpacket/cfdp/CFDPPacketStored.cpp new file mode 100644 index 00000000..f0160e3b --- /dev/null +++ b/src/core/tmtcpacket/cfdp/CFDPPacketStored.cpp @@ -0,0 +1,85 @@ +#include "fsfw/tmtcpacket/cfdp/CFDPPacketStored.h" +#include "fsfw/objectmanager/ObjectManager.h" + +StorageManagerIF* CFDPPacketStored::store = nullptr; + +CFDPPacketStored::CFDPPacketStored(): CFDPPacket(nullptr) { +} + +CFDPPacketStored::CFDPPacketStored(store_address_t setAddress): CFDPPacket(nullptr) { + this->setStoreAddress(setAddress); +} + +CFDPPacketStored::CFDPPacketStored(const uint8_t* data, size_t size): CFDPPacket(data) { + if (this->getFullSize() != size) { + return; + } + if (this->checkAndSetStore()) { + ReturnValue_t status = store->addData(&storeAddress, data, size); + if (status != HasReturnvaluesIF::RETURN_OK) { + this->setData(nullptr); + } + const uint8_t* storePtr = nullptr; + // Repoint base data pointer to the data in the store. + store->getData(storeAddress, &storePtr, &size); + this->setData(storePtr); + } +} + +ReturnValue_t CFDPPacketStored::deletePacket() { + ReturnValue_t result = this->store->deleteData(this->storeAddress); + this->storeAddress.raw = StorageManagerIF::INVALID_ADDRESS; + this->setData(nullptr); + return result; +} + +//CFDPPacket* CFDPPacketStored::getPacketBase() { +// return this; +//} +void CFDPPacketStored::setStoreAddress(store_address_t setAddress) { + this->storeAddress = setAddress; + const uint8_t* tempData = nullptr; + size_t tempSize; + ReturnValue_t status = StorageManagerIF::RETURN_FAILED; + if (this->checkAndSetStore()) { + status = this->store->getData(this->storeAddress, &tempData, &tempSize); + } + if (status == StorageManagerIF::RETURN_OK) { + this->setData(tempData); + } + else { + this->setData(nullptr); + this->storeAddress.raw = StorageManagerIF::INVALID_ADDRESS; + } +} + +store_address_t CFDPPacketStored::getStoreAddress() { + return this->storeAddress; +} + +bool CFDPPacketStored::checkAndSetStore() { + if (this->store == nullptr) { + this->store = ObjectManager::instance()->get(objects::TC_STORE); + if (this->store == nullptr) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "CFDPPacketStored::CFDPPacketStored: TC Store not found!" + << std::endl; +#endif + return false; + } + } + return true; +} + +bool CFDPPacketStored::isSizeCorrect() { + const uint8_t* temp_data = nullptr; + size_t temp_size; + ReturnValue_t status = this->store->getData(this->storeAddress, &temp_data, + &temp_size); + if (status == StorageManagerIF::RETURN_OK) { + if (this->getFullSize() == temp_size) { + return true; + } + } + return false; +} diff --git a/src/core/tmtcpacket/cfdp/CMakeLists.txt b/src/core/tmtcpacket/cfdp/CMakeLists.txt new file mode 100644 index 00000000..0b7ab18a --- /dev/null +++ b/src/core/tmtcpacket/cfdp/CMakeLists.txt @@ -0,0 +1,4 @@ +target_sources(${LIB_FSFW_NAME} PRIVATE + CFDPPacket.cpp + CFDPPacketStored.cpp +) From f84d255903f429052bd4710084f0259f92646993 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 20 Jul 2021 18:46:17 +0200 Subject: [PATCH 11/38] using info instead of debug --- src/fsfw/events/EventManager.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/fsfw/events/EventManager.cpp b/src/fsfw/events/EventManager.cpp index 5aa82434..6b63a7d9 100644 --- a/src/fsfw/events/EventManager.cpp +++ b/src/fsfw/events/EventManager.cpp @@ -157,7 +157,7 @@ void EventManager::printUtility(sif::OutputTypes printType, EventMessage *messag message->getReporter() << std::setfill(' ') << std::dec; } sif::info << " reported event with ID " << message->getEventId() << std::endl; - sif::debug << translateEvents(message->getEvent()) << " | " <getEvent()) << " | " <getParameter1() << " | P1 Dec: " << std::dec << message->getParameter1() << std::hex << " | P2 Hex: 0x" << message->getParameter2() << " | P2 Dec: " << std::dec << message->getParameter2() << std::endl; @@ -170,9 +170,10 @@ void EventManager::printUtility(sif::OutputTypes printType, EventMessage *messag sif::printInfo("Event Manager: Reporter ID 0x%08x reported event with ID %d\n", message->getReporter(), message->getEventId()); } - sif::printInfo("P1 Hex: 0x%x | P1 Dec: %d | P2 Hex: 0x%x | P2 Dec: %d\n", - message->getParameter1(), message->getParameter1(), - message->getParameter2(), message->getParameter2()); + + sif::printInfo("%s | P1 Hex: 0x%x | P1 Dec: %d | P2 Hex: 0x%x | P2 Dec: %d\n", + translateEvents(message->getEvent()), message->getParameter1(), + message->getParameter1(), message->getParameter2(), message->getParameter2()); #endif /* FSFW_CPP_OSTREAM_ENABLED == 0 */ } else { From d339bf2c9e88025de6f25ea4fae30d6e7d89032d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 21 Jul 2021 09:43:17 +0200 Subject: [PATCH 12/38] deleted src/osal/host folder --- src/osal/host/Mutex.cpp | 32 -------------------------------- 1 file changed, 32 deletions(-) delete mode 100644 src/osal/host/Mutex.cpp diff --git a/src/osal/host/Mutex.cpp b/src/osal/host/Mutex.cpp deleted file mode 100644 index 7a56f7cb..00000000 --- a/src/osal/host/Mutex.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#include "fsfw/osal/host/Mutex.h" -#include "fsfw/serviceinterface/ServiceInterface.h" -# -Mutex::Mutex() {} - -ReturnValue_t Mutex::lockMutex(TimeoutType timeoutType, uint32_t timeoutMs) { - if(timeoutType == TimeoutType::BLOCKING) { - mutex.lock(); - return HasReturnvaluesIF::RETURN_OK; - } - else if(timeoutType == TimeoutType::POLLING) { - if(mutex.try_lock()) { - return HasReturnvaluesIF::RETURN_OK; - } - } - else if(timeoutType == TimeoutType::WAITING){ - auto chronoMs = std::chrono::milliseconds(timeoutMs); - if(mutex.try_lock_for(chronoMs)) { - return HasReturnvaluesIF::RETURN_OK; - } - } - return MutexIF::MUTEX_TIMEOUT; -} - -ReturnValue_t Mutex::unlockMutex() { - mutex.unlock(); - return HasReturnvaluesIF::RETURN_OK; -} - -std::timed_mutex* Mutex::getMutexHandle() { - return &mutex; -} From e137ddc89738fa223abedf95eeb338c095ecaf4f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 21 Jul 2021 11:23:57 +0200 Subject: [PATCH 13/38] improved HasFileSystemIF api --- src/fsfw/memory/FileSystemArgsIF.h | 14 ++++++++++++++ src/fsfw/memory/HasFileSystemIF.h | 25 ++++++++++++++++--------- 2 files changed, 30 insertions(+), 9 deletions(-) create mode 100644 src/fsfw/memory/FileSystemArgsIF.h diff --git a/src/fsfw/memory/FileSystemArgsIF.h b/src/fsfw/memory/FileSystemArgsIF.h new file mode 100644 index 00000000..4ed34873 --- /dev/null +++ b/src/fsfw/memory/FileSystemArgsIF.h @@ -0,0 +1,14 @@ +#ifndef FSFW_SRC_FSFW_MEMORY_FILESYSTEMARGS_H_ +#define FSFW_SRC_FSFW_MEMORY_FILESYSTEMARGS_H_ + +/** + * Empty base interface which can be implemented by to pass arguments via the HasFileSystemIF. + * Users can then dynamic_cast the base pointer to the require child pointer. + */ +class FileSystemArgsIF { +public: + FileSystemArgsIF(); + virtual~ FileSystemArgsIF(); +}; + +#endif /* FSFW_SRC_FSFW_MEMORY_FILESYSTEMARGS_H_ */ diff --git a/src/fsfw/memory/HasFileSystemIF.h b/src/fsfw/memory/HasFileSystemIF.h index ec941f59..d8d100c0 100644 --- a/src/fsfw/memory/HasFileSystemIF.h +++ b/src/fsfw/memory/HasFileSystemIF.h @@ -1,9 +1,10 @@ #ifndef FSFW_MEMORY_HASFILESYSTEMIF_H_ #define FSFW_MEMORY_HASFILESYSTEMIF_H_ -#include "../returnvalues/HasReturnvaluesIF.h" -#include "../returnvalues/FwClassIds.h" -#include "../ipc/messageQueueDefinitions.h" +#include "FileSystemArgsIF.h" +#include "fsfw/returnvalues/HasReturnvaluesIF.h" +#include "fsfw/returnvalues/FwClassIds.h" +#include "fsfw/ipc/messageQueueDefinitions.h" #include @@ -59,7 +60,7 @@ public: */ virtual ReturnValue_t appendToFile(const char* repositoryPath, const char* filename, const uint8_t* data, size_t size, - uint16_t packetNumber, void* args = nullptr) = 0; + uint16_t packetNumber, FileSystemArgsIF* args = nullptr) = 0; /** * @brief Generic function to create a new file. @@ -72,7 +73,7 @@ public: */ virtual ReturnValue_t createFile(const char* repositoryPath, const char* filename, const uint8_t* data = nullptr, - size_t size = 0, void* args = nullptr) = 0; + size_t size = 0, FileSystemArgsIF* args = nullptr) = 0; /** * @brief Generic function to delete a file. @@ -81,16 +82,19 @@ public: * @param args Any other arguments which an implementation might require * @return */ - virtual ReturnValue_t deleteFile(const char* repositoryPath, - const char* filename, void* args = nullptr) = 0; + virtual ReturnValue_t removeFile(const char* repositoryPath, + const char* filename, FileSystemArgsIF* args = nullptr) = 0; /** * @brief Generic function to create a directory * @param repositoryPath + * @param Equivalent to the -p flag in Unix systems. If some required parent directories + * do not exist, create them as well * @param args Any other arguments which an implementation might require * @return */ - virtual ReturnValue_t createDirectory(const char* repositoryPath, void* args = nullptr) = 0; + virtual ReturnValue_t createDirectory(const char* repositoryPath, bool createParentDirs, + FileSystemArgsIF* args = nullptr) = 0; /** * @brief Generic function to remove a directory @@ -98,7 +102,10 @@ public: * @param args Any other arguments which an implementation might require */ virtual ReturnValue_t removeDirectory(const char* repositoryPath, - bool deleteRecurively = false, void* args = nullptr) = 0; + bool deleteRecurively = false, FileSystemArgsIF* args = nullptr) = 0; + + virtual ReturnValue_t renameFile(const char* repositoryPath, const char* oldFilename, + const char* newFilename, FileSystemArgsIF* args = nullptr) = 0; }; From 86ae5d03cd18fd939b98b8fd7568272031c3447f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 21 Jul 2021 11:34:18 +0200 Subject: [PATCH 14/38] API updated --- src/fsfw/memory/FileSystemArgsIF.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/fsfw/memory/FileSystemArgsIF.h b/src/fsfw/memory/FileSystemArgsIF.h index 4ed34873..67d423ff 100644 --- a/src/fsfw/memory/FileSystemArgsIF.h +++ b/src/fsfw/memory/FileSystemArgsIF.h @@ -7,8 +7,7 @@ */ class FileSystemArgsIF { public: - FileSystemArgsIF(); - virtual~ FileSystemArgsIF(); + virtual~ FileSystemArgsIF() {}; }; #endif /* FSFW_SRC_FSFW_MEMORY_FILESYSTEMARGS_H_ */ From b0e1480383227c410c4d8b890424fe7df785bc97 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 21 Jul 2021 21:56:31 +0200 Subject: [PATCH 15/38] pushed cfdp update --- src/fsfw/tcdistribution/CFDPDistributor.cpp | 27 ++++++++++++++----- src/fsfw/tcdistribution/CFDPDistributor.h | 2 ++ src/fsfw/tcdistribution/TcPacketCheckCFDP.cpp | 4 +-- src/fsfw/tcdistribution/TcPacketCheckCFDP.h | 4 +-- src/fsfw/tcdistribution/TcPacketCheckIF.h | 5 ++-- src/fsfw/tcdistribution/TcPacketCheckPUS.cpp | 8 +++--- src/fsfw/tcdistribution/TcPacketCheckPUS.h | 2 +- src/fsfw/tmtcservices/CommandingServiceBase.h | 1 - 8 files changed, 34 insertions(+), 19 deletions(-) diff --git a/src/fsfw/tcdistribution/CFDPDistributor.cpp b/src/fsfw/tcdistribution/CFDPDistributor.cpp index 37294988..d112dd8d 100644 --- a/src/fsfw/tcdistribution/CFDPDistributor.cpp +++ b/src/fsfw/tcdistribution/CFDPDistributor.cpp @@ -5,20 +5,21 @@ #include "fsfw/objectmanager/ObjectManager.h" -#define CFDP_DISTRIBUTOR_DEBUGGING 0 +#ifndef FSFW_CFDP_DISTRIBUTOR_DEBUGGING +#define FSFW_CFDP_DISTRIBUTOR_DEBUGGING 1 +#endif CFDPDistributor::CFDPDistributor(uint16_t setApid, object_id_t setObjectId, - object_id_t setPacketSource) : - TcDistributor(setObjectId), + object_id_t setPacketSource): + TcDistributor(setObjectId), apid(setApid), checker(setApid), tcStatus(RETURN_FAILED), packetSource(setPacketSource) { - this->apid = setApid; } CFDPDistributor::~CFDPDistributor() {} CFDPDistributor::TcMqMapIter CFDPDistributor::selectDestination() { -#if CFDP_DISTRIBUTOR_DEBUGGING == 1 - store_address_t storeId = this->currentMessage.getStorageId(); +#if FSFW_CFDP_DISTRIBUTOR_DEBUGGING == 1 + store_address_t storeId = this->currentMessage.getStorageId(); #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::debug << "CFDPDistributor::handlePacket received: " << storeId.poolIndex << ", " << storeId.packetIndex << std::endl; @@ -33,6 +34,18 @@ CFDPDistributor::TcMqMapIter CFDPDistributor::selectDestination() { } this->currentPacket->setStoreAddress(this->currentMessage.getStorageId()); if (currentPacket->getWholeData() != nullptr) { + tcStatus = checker.checkPacket(currentPacket); + if(tcStatus != HasReturnvaluesIF::RETURN_OK) { +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::debug << "PUSDistributor::handlePacket: Packet format invalid, code " << + static_cast(tcStatus) << std::endl; +#else + sif::printDebug("PUSDistributor::handlePacket: Packet format invalid, code %d\n", + static_cast(tcStatus)); +#endif +#endif + } queueMapIt = this->queueMap.find(0); } else { @@ -62,7 +75,7 @@ CFDPDistributor::TcMqMapIter CFDPDistributor::selectDestination() { ReturnValue_t CFDPDistributor::registerHandler(AcceptsTelecommandsIF* handler) { uint16_t handlerId = handler->getIdentifier(); //should be 0, because CFDPHandler does not set a set a service-ID -#if CFDP_DISTRIBUTOR_DEBUGGING == 1 +#if FSFW_CFDP_DISTRIBUTOR_DEBUGGING == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::info << "CFDPDistributor::registerHandler: Handler ID: " << static_cast(handlerId) << std::endl; #else diff --git a/src/fsfw/tcdistribution/CFDPDistributor.h b/src/fsfw/tcdistribution/CFDPDistributor.h index 12436be2..5c7513b3 100644 --- a/src/fsfw/tcdistribution/CFDPDistributor.h +++ b/src/fsfw/tcdistribution/CFDPDistributor.h @@ -1,6 +1,7 @@ #ifndef FSFW_TCDISTRIBUTION_CFDPDISTRIBUTOR_H_ #define FSFW_TCDISTRIBUTION_CFDPDISTRIBUTOR_H_ +#include #include "CFDPDistributorIF.h" #include "TcDistributor.h" #include "../tmtcpacket/cfdp/CFDPPacketStored.h" @@ -43,6 +44,7 @@ protected: * The currently handled packet is stored here. */ CFDPPacketStored* currentPacket = nullptr; + TcPacketCheckCFDP checker; /** * With this variable, the current check status is stored to generate * acceptance messages later. diff --git a/src/fsfw/tcdistribution/TcPacketCheckCFDP.cpp b/src/fsfw/tcdistribution/TcPacketCheckCFDP.cpp index f3811a04..43e5511b 100644 --- a/src/fsfw/tcdistribution/TcPacketCheckCFDP.cpp +++ b/src/fsfw/tcdistribution/TcPacketCheckCFDP.cpp @@ -1,10 +1,10 @@ #include "fsfw/tcdistribution/TcPacketCheckCFDP.h" - +#include "fsfw/tmtcpacket/cfdp/CFDPPacketStored.h" TcPacketCheckCFDP::TcPacketCheckCFDP(uint16_t setApid): apid(setApid) { } -ReturnValue_t TcPacketCheckCFDP::checkPacket(TcPacketStoredBase* currentPacket) { +ReturnValue_t TcPacketCheckCFDP::checkPacket(SpacePacketBase* currentPacket) { return RETURN_OK; } diff --git a/src/fsfw/tcdistribution/TcPacketCheckCFDP.h b/src/fsfw/tcdistribution/TcPacketCheckCFDP.h index 49f4391d..8205fe4b 100644 --- a/src/fsfw/tcdistribution/TcPacketCheckCFDP.h +++ b/src/fsfw/tcdistribution/TcPacketCheckCFDP.h @@ -5,7 +5,7 @@ #include "fsfw/FSFW.h" -class TcPacketStoredBase; +class CFDPPacketStored; /** * This class performs a formal packet check for incoming CFDP Packets. @@ -27,7 +27,7 @@ public: */ TcPacketCheckCFDP(uint16_t setApid); - ReturnValue_t checkPacket(TcPacketStoredBase* currentPacket) override; + ReturnValue_t checkPacket(SpacePacketBase* currentPacket) override; uint16_t getApid() const; }; diff --git a/src/fsfw/tcdistribution/TcPacketCheckIF.h b/src/fsfw/tcdistribution/TcPacketCheckIF.h index 58c17021..ac1dfef9 100644 --- a/src/fsfw/tcdistribution/TcPacketCheckIF.h +++ b/src/fsfw/tcdistribution/TcPacketCheckIF.h @@ -3,8 +3,7 @@ #include "../returnvalues/HasReturnvaluesIF.h" -// TODO TcPacketStoredBase is currently only for PUS packets. not for CFDP packets -class TcPacketStoredBase; +class SpacePacketBase; /** * This interface is used by PacketCheckers for PUS packets and CFDP packets . @@ -26,7 +25,7 @@ public: * - @c INCORRECT_CHECKSUM if checksum is invalid. * - @c ILLEGAL_APID if APID does not match. */ - virtual ReturnValue_t checkPacket(TcPacketStoredBase* currentPacket) = 0; + virtual ReturnValue_t checkPacket(SpacePacketBase* currentPacket) = 0; }; #endif /* FSFW_TCDISTRIBUTION_TCPACKETCHECKIF_H_ */ diff --git a/src/fsfw/tcdistribution/TcPacketCheckPUS.cpp b/src/fsfw/tcdistribution/TcPacketCheckPUS.cpp index 5f9cfaf6..06acb518 100644 --- a/src/fsfw/tcdistribution/TcPacketCheckPUS.cpp +++ b/src/fsfw/tcdistribution/TcPacketCheckPUS.cpp @@ -1,6 +1,7 @@ #include "fsfw/tcdistribution/TcPacketCheckPUS.h" #include "fsfw/globalfunctions/CRC.h" +#include "fsfw/tmtcpacket/pus/tc/TcPacketStoredPus.h" #include "fsfw/tmtcpacket/pus/tc/TcPacketBase.h" #include "fsfw/tmtcpacket/pus/tc/TcPacketStoredBase.h" #include "fsfw/serviceinterface/ServiceInterface.h" @@ -10,8 +11,9 @@ TcPacketCheckPUS::TcPacketCheckPUS(uint16_t setApid): apid(setApid) { } -ReturnValue_t TcPacketCheckPUS::checkPacket(TcPacketStoredBase* currentPacket) { - TcPacketBase* tcPacketBase = currentPacket->getPacketBase(); +ReturnValue_t TcPacketCheckPUS::checkPacket(SpacePacketBase* currentPacket) { + TcPacketStoredBase* storedPacket = dynamic_cast(currentPacket); + TcPacketBase* tcPacketBase = storedPacket->getPacketBase(); if(tcPacketBase == nullptr) { return RETURN_FAILED; } @@ -29,7 +31,7 @@ ReturnValue_t TcPacketCheckPUS::checkPacket(TcPacketStoredBase* currentPacket) { if (tcPacketBase->getAPID() != this->apid) return ILLEGAL_APID; - if (not currentPacket->isSizeCorrect()) { + if (not storedPacket->isSizeCorrect()) { return INCOMPLETE_PACKET; } diff --git a/src/fsfw/tcdistribution/TcPacketCheckPUS.h b/src/fsfw/tcdistribution/TcPacketCheckPUS.h index f07cf89d..ae4c7789 100644 --- a/src/fsfw/tcdistribution/TcPacketCheckPUS.h +++ b/src/fsfw/tcdistribution/TcPacketCheckPUS.h @@ -55,7 +55,7 @@ public: */ TcPacketCheckPUS(uint16_t setApid); - ReturnValue_t checkPacket(TcPacketStoredBase* currentPacket) override; + ReturnValue_t checkPacket(SpacePacketBase* currentPacket) override; uint16_t getApid() const; }; diff --git a/src/fsfw/tmtcservices/CommandingServiceBase.h b/src/fsfw/tmtcservices/CommandingServiceBase.h index b6709693..ba026009 100644 --- a/src/fsfw/tmtcservices/CommandingServiceBase.h +++ b/src/fsfw/tmtcservices/CommandingServiceBase.h @@ -14,7 +14,6 @@ #include "fsfw/container/FIFO.h" #include "fsfw/serialize/SerializeIF.h" -class TcPacketStored; class TcPacketStoredBase; namespace Factory{ From 7606f585feb5267208465642a099443ffc1d2c9c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 4 Aug 2021 11:16:22 +0200 Subject: [PATCH 16/38] refactored test folder --- CMakeLists.txt | 1 + tests/src/fsfw_tests/unit/CMakeLists.txt | 13 ++++++++++ .../fsfw_tests/unit}/CatchDefinitions.cpp | 0 .../fsfw_tests/unit}/CatchDefinitions.h | 0 .../fsfw_tests/unit}/CatchFactory.cpp | 16 +++++++------ tests/src/fsfw_tests/unit/CatchFactory.h | 24 +++++++++++++++++++ .../fsfw_tests/unit}/CatchRunner.cpp | 6 ++--- tests/src/fsfw_tests/unit/CatchRunner.h | 14 +++++++++++ .../fsfw_tests/unit}/CatchSetup.cpp | 15 +++++------- .../unit/action/TestActionHelper.cpp | 5 +--- .../fsfw_tests/unit/action/TestActionHelper.h | 3 +-- .../unit/container/RingBufferTest.cpp | 2 +- .../unit/container/TestArrayList.cpp | 3 ++- .../unit/container/TestDynamicFifo.cpp | 3 ++- .../fsfw_tests/unit/container/TestFifo.cpp | 3 ++- .../unit/container/TestFixedArrayList.cpp | 3 ++- .../unit/container/TestFixedMap.cpp | 3 ++- .../container/TestFixedOrderedMultimap.cpp | 3 ++- .../unit/container/TestPlacementFactory.cpp | 3 ++- .../unit/datapoollocal/DataSetTest.cpp | 7 +++--- .../datapoollocal/LocalPoolManagerTest.cpp | 9 +++---- .../unit/datapoollocal/LocalPoolOwnerBase.h | 2 +- .../datapoollocal/LocalPoolVariableTest.cpp | 4 ++-- .../datapoollocal/LocalPoolVectorTest.cpp | 3 ++- .../unit/mocks/MessageQueueMockBase.h | 9 ++++--- .../fsfw_tests/unit/osal/TestMessageQueue.cpp | 3 ++- .../fsfw_tests/unit}/printChar.cpp | 0 .../core => src/fsfw_tests/unit}/printChar.h | 0 .../serialize/TestSerialBufferAdapter.cpp | 4 +++- .../unit/serialize/TestSerialLinkedPacket.cpp | 3 +-- .../unit/serialize/TestSerialization.cpp | 2 +- .../unit/storagemanager/TestNewAccessor.cpp | 5 +++- .../unit/storagemanager/TestPool.cpp | 3 ++- tests/user/CMakeLists.txt | 4 ++-- tests/user/testcfg/TestsConfig.h.in | 2 ++ tests/user/unittest/CMakeLists.txt | 1 - tests/user/unittest/core/CMakeLists.txt | 13 ---------- tests/user/unittest/core/CatchFactory.h | 16 ------------- tests/user/unittest/core/core.mk | 3 --- 39 files changed, 123 insertions(+), 90 deletions(-) rename tests/{user/unittest/core => src/fsfw_tests/unit}/CatchDefinitions.cpp (100%) rename tests/{user/unittest/core => src/fsfw_tests/unit}/CatchDefinitions.h (100%) rename tests/{user/unittest/core => src/fsfw_tests/unit}/CatchFactory.cpp (91%) create mode 100644 tests/src/fsfw_tests/unit/CatchFactory.h rename tests/{user/unittest/core => src/fsfw_tests/unit}/CatchRunner.cpp (78%) create mode 100644 tests/src/fsfw_tests/unit/CatchRunner.h rename tests/{user/unittest/core => src/fsfw_tests/unit}/CatchSetup.cpp (57%) rename tests/{user/unittest/core => src/fsfw_tests/unit}/printChar.cpp (100%) rename tests/{user/unittest/core => src/fsfw_tests/unit}/printChar.h (100%) delete mode 100644 tests/user/unittest/CMakeLists.txt delete mode 100644 tests/user/unittest/core/CMakeLists.txt delete mode 100644 tests/user/unittest/core/CatchFactory.h delete mode 100644 tests/user/unittest/core/core.mk diff --git a/CMakeLists.txt b/CMakeLists.txt index df62908c..feaa4b81 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,6 +10,7 @@ endif() option(FSFW_WARNING_SHADOW_LOCAL_GCC "Enable -Wshadow=local warning in GCC" ON) # Options to exclude parts of the FSFW from compilation. option(FSFW_ADD_INTERNAL_TESTS "Add internal unit tests" ON) +option(FSFW_ADD_UNITTESTS "Add regular unittests. Requires Catch2" OFF) option(FSFW_ADD_HAL "Add Hardware Abstraction Layer" ON) # Optional sources diff --git a/tests/src/fsfw_tests/unit/CMakeLists.txt b/tests/src/fsfw_tests/unit/CMakeLists.txt index 255063f3..01e4d19c 100644 --- a/tests/src/fsfw_tests/unit/CMakeLists.txt +++ b/tests/src/fsfw_tests/unit/CMakeLists.txt @@ -1,3 +1,16 @@ +target_sources(${TARGET_NAME} PRIVATE + CatchDefinitions.cpp + CatchFactory.cpp + printChar.cpp +) + +if(FSFW_CUSTOM_UNITTEST_RUNNER) + target_sources(${TARGET_NAME} PRIVATE + CatchRunner.cpp + CatchSetup.cpp + ) +endif() + add_subdirectory(action) add_subdirectory(container) add_subdirectory(osal) diff --git a/tests/user/unittest/core/CatchDefinitions.cpp b/tests/src/fsfw_tests/unit/CatchDefinitions.cpp similarity index 100% rename from tests/user/unittest/core/CatchDefinitions.cpp rename to tests/src/fsfw_tests/unit/CatchDefinitions.cpp diff --git a/tests/user/unittest/core/CatchDefinitions.h b/tests/src/fsfw_tests/unit/CatchDefinitions.h similarity index 100% rename from tests/user/unittest/core/CatchDefinitions.h rename to tests/src/fsfw_tests/unit/CatchDefinitions.h diff --git a/tests/user/unittest/core/CatchFactory.cpp b/tests/src/fsfw_tests/unit/CatchFactory.cpp similarity index 91% rename from tests/user/unittest/core/CatchFactory.cpp rename to tests/src/fsfw_tests/unit/CatchFactory.cpp index ff591b8e..010ab5dd 100644 --- a/tests/user/unittest/core/CatchFactory.cpp +++ b/tests/src/fsfw_tests/unit/CatchFactory.cpp @@ -1,17 +1,21 @@ #include "CatchFactory.h" +#include "datapoollocal/LocalPoolOwnerBase.h" +#include "mocks/HkReceiverMock.h" + #include #include #include #include -#include +#include #include #include #include #include #include -#include -#include + + +#if FSFW_ADD_DEFAULT_FACTORY_FUNCTIONS == 1 /** * @brief Produces system objects. @@ -26,7 +30,7 @@ * * @ingroup init */ -void Factory::produce(void) { +void Factory::produceFrameworkObjects(void* args) { setStaticFrameworkObjectIds(); new EventManager(objects::EVENT_MANAGER); new HealthTable(objects::HEALTH_TABLE); @@ -55,7 +59,6 @@ void Factory::produce(void) { }; new PoolManager(objects::IPC_STORE, poolCfg); } - } void Factory::setStaticFrameworkObjectIds() { @@ -77,5 +80,4 @@ void Factory::setStaticFrameworkObjectIds() { TmPacketBase::timeStamperId = objects::NO_OBJECT; } - - +#endif diff --git a/tests/src/fsfw_tests/unit/CatchFactory.h b/tests/src/fsfw_tests/unit/CatchFactory.h new file mode 100644 index 00000000..ae0629e5 --- /dev/null +++ b/tests/src/fsfw_tests/unit/CatchFactory.h @@ -0,0 +1,24 @@ +#ifndef FSFW_CATCHFACTORY_H_ +#define FSFW_CATCHFACTORY_H_ + +#include "TestConfig.h" +#include "fsfw/objectmanager/SystemObjectIF.h" +#include "fsfw/objectmanager/ObjectManager.h" + +// TODO: It is possible to solve this more cleanly using a special class which +// is allowed to set the object IDs and has virtual functions. +#if FSFW_ADD_DEFAULT_FACTORY_FUNCTIONS == 1 + +namespace Factory { + /** + * @brief Creates all SystemObject elements which are persistent + * during execution. + */ + void produceFrameworkObjects(void* args); + void setStaticFrameworkObjectIds(); + +} + +#endif /* FSFW_ADD_DEFAULT_FSFW_FACTORY == 1 */ + +#endif /* FSFW_CATCHFACTORY_H_ */ diff --git a/tests/user/unittest/core/CatchRunner.cpp b/tests/src/fsfw_tests/unit/CatchRunner.cpp similarity index 78% rename from tests/user/unittest/core/CatchRunner.cpp rename to tests/src/fsfw_tests/unit/CatchRunner.cpp index 886d641f..c96db7f4 100644 --- a/tests/user/unittest/core/CatchRunner.cpp +++ b/tests/src/fsfw_tests/unit/CatchRunner.cpp @@ -6,7 +6,7 @@ * from the eclipse market place to get colored characters. */ -#include +#include "CatchRunner.h" #define CATCH_CONFIG_COLOUR_WINDOWS @@ -14,11 +14,11 @@ extern int customSetup(); -int main( int argc, char* argv[] ) { +int fsfwtest::customMain(int argc, char* argv[]) { customSetup(); // Catch internal function call - int result = Catch::Session().run( argc, argv ); + int result = Catch::Session().run(argc, argv); // global clean-up return result; diff --git a/tests/src/fsfw_tests/unit/CatchRunner.h b/tests/src/fsfw_tests/unit/CatchRunner.h new file mode 100644 index 00000000..720625c6 --- /dev/null +++ b/tests/src/fsfw_tests/unit/CatchRunner.h @@ -0,0 +1,14 @@ +#ifndef FSFW_TESTS_USER_UNITTEST_CORE_CATCHRUNNER_H_ +#define FSFW_TESTS_USER_UNITTEST_CORE_CATCHRUNNER_H_ + +namespace fsfwtest { + +/** + * Can be called by upper level main() if default Catch2 main is overriden + * @return + */ +int customMain(int argc, char* argv[]); + +} + +#endif /* FSFW_TESTS_USER_UNITTEST_CORE_CATCHRUNNER_H_ */ diff --git a/tests/user/unittest/core/CatchSetup.cpp b/tests/src/fsfw_tests/unit/CatchSetup.cpp similarity index 57% rename from tests/user/unittest/core/CatchSetup.cpp rename to tests/src/fsfw_tests/unit/CatchSetup.cpp index bda31400..a0791bc9 100644 --- a/tests/user/unittest/core/CatchSetup.cpp +++ b/tests/src/fsfw_tests/unit/CatchSetup.cpp @@ -5,10 +5,9 @@ #include #endif -#include -#include -#include -#include +#include "fsfw/objectmanager/ObjectManager.h" +#include "fsfw/storagemanager/StorageManagerIF.h" +#include "fsfw/serviceinterface/ServiceInterface.h" /* Global instantiations normally done in main.cpp */ @@ -24,13 +23,11 @@ ServiceInterfaceStream warning("WARNING"); } #endif -/* Global object manager */ -ObjectManagerIF *objectManager; - int customSetup() { // global setup - objectManager = new ObjectManager(Factory::produce); - objectManager -> initialize(); + ObjectManager* objMan = ObjectManager::instance(); + objMan->setObjectFactoryFunction(Factory::produceFrameworkObjects, nullptr); + objMan->initialize(); return 0; } diff --git a/tests/src/fsfw_tests/unit/action/TestActionHelper.cpp b/tests/src/fsfw_tests/unit/action/TestActionHelper.cpp index 126979f6..3129b001 100644 --- a/tests/src/fsfw_tests/unit/action/TestActionHelper.cpp +++ b/tests/src/fsfw_tests/unit/action/TestActionHelper.cpp @@ -1,13 +1,10 @@ #include "TestActionHelper.h" - -#include +#include "fsfw_tests/unit/mocks/MessageQueueMockBase.h" #include #include -#include #include - #include diff --git a/tests/src/fsfw_tests/unit/action/TestActionHelper.h b/tests/src/fsfw_tests/unit/action/TestActionHelper.h index 641ea2c6..34b228c0 100644 --- a/tests/src/fsfw_tests/unit/action/TestActionHelper.h +++ b/tests/src/fsfw_tests/unit/action/TestActionHelper.h @@ -1,12 +1,11 @@ #ifndef UNITTEST_HOSTED_TESTACTIONHELPER_H_ #define UNITTEST_HOSTED_TESTACTIONHELPER_H_ +#include "fsfw_tests/unit/CatchDefinitions.h" #include #include -#include #include - class ActionHelperOwnerMockBase: public HasActionsIF { public: bool getCommandQueueCalled = false; diff --git a/tests/src/fsfw_tests/unit/container/RingBufferTest.cpp b/tests/src/fsfw_tests/unit/container/RingBufferTest.cpp index 32a2502d..819401ab 100644 --- a/tests/src/fsfw_tests/unit/container/RingBufferTest.cpp +++ b/tests/src/fsfw_tests/unit/container/RingBufferTest.cpp @@ -1,4 +1,4 @@ -#include +#include "fsfw_tests/unit/CatchDefinitions.h" #include #include diff --git a/tests/src/fsfw_tests/unit/container/TestArrayList.cpp b/tests/src/fsfw_tests/unit/container/TestArrayList.cpp index 1fd330b6..9417144c 100644 --- a/tests/src/fsfw_tests/unit/container/TestArrayList.cpp +++ b/tests/src/fsfw_tests/unit/container/TestArrayList.cpp @@ -1,8 +1,9 @@ +#include "fsfw_tests/unit/CatchDefinitions.h" + #include #include #include -#include /** * @brief Array List test diff --git a/tests/src/fsfw_tests/unit/container/TestDynamicFifo.cpp b/tests/src/fsfw_tests/unit/container/TestDynamicFifo.cpp index 2b572d52..a1bab3ba 100644 --- a/tests/src/fsfw_tests/unit/container/TestDynamicFifo.cpp +++ b/tests/src/fsfw_tests/unit/container/TestDynamicFifo.cpp @@ -1,9 +1,10 @@ +#include "fsfw_tests/unit/CatchDefinitions.h" + #include #include #include #include -#include TEST_CASE( "Dynamic Fifo Tests", "[TestDynamicFifo]") { INFO("Dynamic Fifo Tests"); diff --git a/tests/src/fsfw_tests/unit/container/TestFifo.cpp b/tests/src/fsfw_tests/unit/container/TestFifo.cpp index fbcd40cc..311dd8fd 100644 --- a/tests/src/fsfw_tests/unit/container/TestFifo.cpp +++ b/tests/src/fsfw_tests/unit/container/TestFifo.cpp @@ -1,9 +1,10 @@ +#include "fsfw_tests/unit/CatchDefinitions.h" + #include #include #include #include -#include TEST_CASE( "Static Fifo Tests", "[TestFifo]") { INFO("Fifo Tests"); diff --git a/tests/src/fsfw_tests/unit/container/TestFixedArrayList.cpp b/tests/src/fsfw_tests/unit/container/TestFixedArrayList.cpp index 1a85f30d..ed597f73 100644 --- a/tests/src/fsfw_tests/unit/container/TestFixedArrayList.cpp +++ b/tests/src/fsfw_tests/unit/container/TestFixedArrayList.cpp @@ -1,8 +1,9 @@ +#include "fsfw_tests/unit/CatchDefinitions.h" + #include #include #include -#include TEST_CASE( "FixedArrayList Tests", "[TestFixedArrayList]") { diff --git a/tests/src/fsfw_tests/unit/container/TestFixedMap.cpp b/tests/src/fsfw_tests/unit/container/TestFixedMap.cpp index 297171ca..488418b9 100644 --- a/tests/src/fsfw_tests/unit/container/TestFixedMap.cpp +++ b/tests/src/fsfw_tests/unit/container/TestFixedMap.cpp @@ -1,8 +1,9 @@ +#include "fsfw_tests/unit/CatchDefinitions.h" + #include #include #include -#include template class FixedMap; diff --git a/tests/src/fsfw_tests/unit/container/TestFixedOrderedMultimap.cpp b/tests/src/fsfw_tests/unit/container/TestFixedOrderedMultimap.cpp index a47d6efb..23d91744 100644 --- a/tests/src/fsfw_tests/unit/container/TestFixedOrderedMultimap.cpp +++ b/tests/src/fsfw_tests/unit/container/TestFixedOrderedMultimap.cpp @@ -1,8 +1,9 @@ +#include "fsfw_tests/unit/CatchDefinitions.h" + #include #include #include -#include TEST_CASE( "FixedOrderedMultimap Tests", "[TestFixedOrderedMultimap]") { INFO("FixedOrderedMultimap Tests"); diff --git a/tests/src/fsfw_tests/unit/container/TestPlacementFactory.cpp b/tests/src/fsfw_tests/unit/container/TestPlacementFactory.cpp index 14cf8eb4..1e328fc7 100644 --- a/tests/src/fsfw_tests/unit/container/TestPlacementFactory.cpp +++ b/tests/src/fsfw_tests/unit/container/TestPlacementFactory.cpp @@ -1,10 +1,11 @@ +#include "fsfw_tests/unit/CatchDefinitions.h" + #include #include #include #include #include -#include TEST_CASE( "PlacementFactory Tests", "[TestPlacementFactory]") { INFO("PlacementFactory Tests"); diff --git a/tests/src/fsfw_tests/unit/datapoollocal/DataSetTest.cpp b/tests/src/fsfw_tests/unit/datapoollocal/DataSetTest.cpp index b8748eb4..94b13f2f 100644 --- a/tests/src/fsfw_tests/unit/datapoollocal/DataSetTest.cpp +++ b/tests/src/fsfw_tests/unit/datapoollocal/DataSetTest.cpp @@ -1,7 +1,5 @@ #include "LocalPoolOwnerBase.h" - -#include -#include +#include "fsfw_tests/unit/CatchDefinitions.h" #include #include @@ -10,7 +8,8 @@ #include #include -#include +#include +#include TEST_CASE("DataSetTest" , "[DataSetTest]") { LocalPoolOwnerBase* poolOwner = ObjectManager::instance()-> diff --git a/tests/src/fsfw_tests/unit/datapoollocal/LocalPoolManagerTest.cpp b/tests/src/fsfw_tests/unit/datapoollocal/LocalPoolManagerTest.cpp index 4a4d08fb..7b2f9412 100644 --- a/tests/src/fsfw_tests/unit/datapoollocal/LocalPoolManagerTest.cpp +++ b/tests/src/fsfw_tests/unit/datapoollocal/LocalPoolManagerTest.cpp @@ -1,7 +1,5 @@ #include "LocalPoolOwnerBase.h" - -#include -#include +#include "fsfw_tests/unit/CatchDefinitions.h" #include #include @@ -10,7 +8,10 @@ #include #include #include -#include + +#include +#include + #include diff --git a/tests/src/fsfw_tests/unit/datapoollocal/LocalPoolOwnerBase.h b/tests/src/fsfw_tests/unit/datapoollocal/LocalPoolOwnerBase.h index c0e41ddf..ea5bb7e0 100644 --- a/tests/src/fsfw_tests/unit/datapoollocal/LocalPoolOwnerBase.h +++ b/tests/src/fsfw_tests/unit/datapoollocal/LocalPoolOwnerBase.h @@ -2,6 +2,7 @@ #define FSFW_UNITTEST_TESTS_DATAPOOLLOCAL_LOCALPOOLOWNERBASE_H_ #include "objects/systemObjectList.h" +#include "../mocks/MessageQueueMockBase.h" #include #include @@ -10,7 +11,6 @@ #include #include #include -#include #include namespace lpool { diff --git a/tests/src/fsfw_tests/unit/datapoollocal/LocalPoolVariableTest.cpp b/tests/src/fsfw_tests/unit/datapoollocal/LocalPoolVariableTest.cpp index 514d8125..648a76e2 100644 --- a/tests/src/fsfw_tests/unit/datapoollocal/LocalPoolVariableTest.cpp +++ b/tests/src/fsfw_tests/unit/datapoollocal/LocalPoolVariableTest.cpp @@ -1,10 +1,10 @@ #include "LocalPoolOwnerBase.h" +#include "fsfw_tests/unit/CatchDefinitions.h" -#include #include #include -#include +#include TEST_CASE("LocalPoolVariable" , "[LocPoolVarTest]") { LocalPoolOwnerBase* poolOwner = ObjectManager::instance()-> diff --git a/tests/src/fsfw_tests/unit/datapoollocal/LocalPoolVectorTest.cpp b/tests/src/fsfw_tests/unit/datapoollocal/LocalPoolVectorTest.cpp index 5b3dd105..3f846dec 100644 --- a/tests/src/fsfw_tests/unit/datapoollocal/LocalPoolVectorTest.cpp +++ b/tests/src/fsfw_tests/unit/datapoollocal/LocalPoolVectorTest.cpp @@ -1,9 +1,10 @@ #include "LocalPoolOwnerBase.h" +#include "fsfw_tests/unit/CatchDefinitions.h" #include #include #include -#include + TEST_CASE("LocalPoolVector" , "[LocPoolVecTest]") { LocalPoolOwnerBase* poolOwner = ObjectManager::instance()-> diff --git a/tests/src/fsfw_tests/unit/mocks/MessageQueueMockBase.h b/tests/src/fsfw_tests/unit/mocks/MessageQueueMockBase.h index 3000f7fb..93a00b7a 100644 --- a/tests/src/fsfw_tests/unit/mocks/MessageQueueMockBase.h +++ b/tests/src/fsfw_tests/unit/mocks/MessageQueueMockBase.h @@ -1,9 +1,12 @@ #ifndef FSFW_UNITTEST_TESTS_MOCKS_MESSAGEQUEUEMOCKBASE_H_ #define FSFW_UNITTEST_TESTS_MOCKS_MESSAGEQUEUEMOCKBASE_H_ -#include -#include -#include +#include "fsfw_tests/unit/CatchDefinitions.h" + +#include "fsfw/ipc/CommandMessage.h" +#include "fsfw/ipc/MessageQueueIF.h" +#include "fsfw/ipc/MessageQueueMessage.h" + #include #include diff --git a/tests/src/fsfw_tests/unit/osal/TestMessageQueue.cpp b/tests/src/fsfw_tests/unit/osal/TestMessageQueue.cpp index e33b7240..07197bf7 100644 --- a/tests/src/fsfw_tests/unit/osal/TestMessageQueue.cpp +++ b/tests/src/fsfw_tests/unit/osal/TestMessageQueue.cpp @@ -1,8 +1,9 @@ +#include "fsfw_tests/unit/CatchDefinitions.h" + #include #include #include -#include #include diff --git a/tests/user/unittest/core/printChar.cpp b/tests/src/fsfw_tests/unit/printChar.cpp similarity index 100% rename from tests/user/unittest/core/printChar.cpp rename to tests/src/fsfw_tests/unit/printChar.cpp diff --git a/tests/user/unittest/core/printChar.h b/tests/src/fsfw_tests/unit/printChar.h similarity index 100% rename from tests/user/unittest/core/printChar.h rename to tests/src/fsfw_tests/unit/printChar.h diff --git a/tests/src/fsfw_tests/unit/serialize/TestSerialBufferAdapter.cpp b/tests/src/fsfw_tests/unit/serialize/TestSerialBufferAdapter.cpp index 1938746d..01d75881 100644 --- a/tests/src/fsfw_tests/unit/serialize/TestSerialBufferAdapter.cpp +++ b/tests/src/fsfw_tests/unit/serialize/TestSerialBufferAdapter.cpp @@ -1,7 +1,9 @@ +#include "fsfw_tests/unit/CatchDefinitions.h" + #include #include -#include + #include diff --git a/tests/src/fsfw_tests/unit/serialize/TestSerialLinkedPacket.cpp b/tests/src/fsfw_tests/unit/serialize/TestSerialLinkedPacket.cpp index b90ae9f8..b6bb214d 100644 --- a/tests/src/fsfw_tests/unit/serialize/TestSerialLinkedPacket.cpp +++ b/tests/src/fsfw_tests/unit/serialize/TestSerialLinkedPacket.cpp @@ -1,10 +1,9 @@ #include "TestSerialLinkedPacket.h" -#include +#include "fsfw_tests/unit/CatchDefinitions.h" #include #include -#include #include diff --git a/tests/src/fsfw_tests/unit/serialize/TestSerialization.cpp b/tests/src/fsfw_tests/unit/serialize/TestSerialization.cpp index 3de581ec..64deae3b 100644 --- a/tests/src/fsfw_tests/unit/serialize/TestSerialization.cpp +++ b/tests/src/fsfw_tests/unit/serialize/TestSerialization.cpp @@ -1,8 +1,8 @@ +#include "fsfw_tests/unit/CatchDefinitions.h" #include #include #include -#include #include diff --git a/tests/src/fsfw_tests/unit/storagemanager/TestNewAccessor.cpp b/tests/src/fsfw_tests/unit/storagemanager/TestNewAccessor.cpp index 10d05c6b..bd1634b7 100644 --- a/tests/src/fsfw_tests/unit/storagemanager/TestNewAccessor.cpp +++ b/tests/src/fsfw_tests/unit/storagemanager/TestNewAccessor.cpp @@ -1,6 +1,9 @@ +#include "fsfw_tests/unit/CatchDefinitions.h" + #include + #include -#include + #include #include diff --git a/tests/src/fsfw_tests/unit/storagemanager/TestPool.cpp b/tests/src/fsfw_tests/unit/storagemanager/TestPool.cpp index d05a3dd6..013ecf86 100644 --- a/tests/src/fsfw_tests/unit/storagemanager/TestPool.cpp +++ b/tests/src/fsfw_tests/unit/storagemanager/TestPool.cpp @@ -1,8 +1,9 @@ +#include "fsfw_tests/unit/CatchDefinitions.h" + #include #include #include -#include #include diff --git a/tests/user/CMakeLists.txt b/tests/user/CMakeLists.txt index df16c756..2e1fdee3 100644 --- a/tests/user/CMakeLists.txt +++ b/tests/user/CMakeLists.txt @@ -32,7 +32,7 @@ if(NOT FSFW_OSAL) set(FSFW_OSAL host CACHE STRING "OS for the FSFW.") endif() -option(CUSTOM_UNITTEST_RUNNER +option(FSFW_CUSTOM_UNITTEST_RUNNER "Specify whether custom main or Catch2 main is used" TRUE ) @@ -49,7 +49,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED True) # Set names and variables set(TARGET_NAME ${CMAKE_PROJECT_NAME}) -if(CUSTOM_UNITTEST_RUNNER) +if(FSFW_CUSTOM_UNITTEST_RUNNER) set(CATCH2_TARGET Catch2) else() set(CATCH2_TARGET Catch2WithMain) diff --git a/tests/user/testcfg/TestsConfig.h.in b/tests/user/testcfg/TestsConfig.h.in index 0341583d..7d950070 100644 --- a/tests/user/testcfg/TestsConfig.h.in +++ b/tests/user/testcfg/TestsConfig.h.in @@ -1,6 +1,8 @@ #ifndef FSFW_UNITTEST_CONFIG_TESTSCONFIG_H_ #define FSFW_UNITTEST_CONFIG_TESTSCONFIG_H_ +#define FSFW_ADD_DEFAULT_FACTORY_FUNCTIONS 1 + #ifdef __cplusplus #include "objects/systemObjectList.h" diff --git a/tests/user/unittest/CMakeLists.txt b/tests/user/unittest/CMakeLists.txt deleted file mode 100644 index ad6d4787..00000000 --- a/tests/user/unittest/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -add_subdirectory(core) diff --git a/tests/user/unittest/core/CMakeLists.txt b/tests/user/unittest/core/CMakeLists.txt deleted file mode 100644 index 0989926c..00000000 --- a/tests/user/unittest/core/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -target_sources(${TARGET_NAME} PRIVATE - CatchDefinitions.cpp - CatchFactory.cpp - CatchRunner.cpp - CatchSetup.cpp - printChar.cpp -) - -if(CUSTOM_UNITTEST_RUNNER) - target_sources(${TARGET_NAME} PRIVATE - CatchRunner.cpp - ) -endif() \ No newline at end of file diff --git a/tests/user/unittest/core/CatchFactory.h b/tests/user/unittest/core/CatchFactory.h deleted file mode 100644 index 024f762e..00000000 --- a/tests/user/unittest/core/CatchFactory.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef FSFW_CATCHFACTORY_H_ -#define FSFW_CATCHFACTORY_H_ - -#include - -namespace Factory { - /** - * @brief Creates all SystemObject elements which are persistent - * during execution. - */ - void produce(void* args); - void setStaticFrameworkObjectIds(); - -} - -#endif /* FSFW_CATCHFACTORY_H_ */ diff --git a/tests/user/unittest/core/core.mk b/tests/user/unittest/core/core.mk deleted file mode 100644 index 3e5626d3..00000000 --- a/tests/user/unittest/core/core.mk +++ /dev/null @@ -1,3 +0,0 @@ -CXXSRC += $(wildcard $(CURRENTPATH)/*.cpp) - -INCLUDES += $(CURRENTPATH) \ No newline at end of file From 739f682dee822f5c807a608a773c7873151b2639 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 6 Aug 2021 17:44:38 +0200 Subject: [PATCH 17/38] this interface is more pus conformant --- src/fsfw/memory/HasFileSystemIF.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/fsfw/memory/HasFileSystemIF.h b/src/fsfw/memory/HasFileSystemIF.h index d8d100c0..be2f8923 100644 --- a/src/fsfw/memory/HasFileSystemIF.h +++ b/src/fsfw/memory/HasFileSystemIF.h @@ -93,15 +93,15 @@ public: * @param args Any other arguments which an implementation might require * @return */ - virtual ReturnValue_t createDirectory(const char* repositoryPath, bool createParentDirs, - FileSystemArgsIF* args = nullptr) = 0; + virtual ReturnValue_t createDirectory(const char* repositoryPath, const char* dirname, + bool createParentDirs, FileSystemArgsIF* args = nullptr) = 0; /** * @brief Generic function to remove a directory * @param repositoryPath * @param args Any other arguments which an implementation might require */ - virtual ReturnValue_t removeDirectory(const char* repositoryPath, + virtual ReturnValue_t removeDirectory(const char* repositoryPath, const char* dirname, bool deleteRecurively = false, FileSystemArgsIF* args = nullptr) = 0; virtual ReturnValue_t renameFile(const char* repositoryPath, const char* oldFilename, From 9e9fa047f7e782cc48813aa7d9e327bd49006e39 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 7 Aug 2021 00:30:53 +0200 Subject: [PATCH 18/38] printf support for cmd executor --- src/fsfw/osal/linux/CommandExecutor.cpp | 27 ++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/fsfw/osal/linux/CommandExecutor.cpp b/src/fsfw/osal/linux/CommandExecutor.cpp index 5d131472..f0b6dd31 100644 --- a/src/fsfw/osal/linux/CommandExecutor.cpp +++ b/src/fsfw/osal/linux/CommandExecutor.cpp @@ -62,8 +62,13 @@ ReturnValue_t CommandExecutor::close() { void CommandExecutor::printLastError(std::string funcName) const { if(lastError != 0) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 sif::error << funcName << " pclose failed with code " << lastError << ": " << strerror(lastError) << std::endl; +#else + sif::printError("%s pclose failed with code %d: %s", funcName, lastError, + strerror(lastError)); +#endif } } @@ -98,15 +103,23 @@ ReturnValue_t CommandExecutor::check(bool& bytesRead) { ssize_t readBytes = read(currentFd, readVec.data(), readVec.size()); if(readBytes == 0) { // Should not happen +#if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "CommandExecutor::check: " "No bytes read after poll event.." << std::endl; +#else + sif::printWarning("CommandExecutor::check: No bytes read after poll event..\n"); +#endif break; } else if(readBytes > 0) { bytesRead = true; if(printOutput) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 // It is assumed the command output is line terminated sif::info << currentCmd << " | " << readVec.data(); +#else + sif::printInfo("%s | %s", currentCmd, readVec.data()); +#endif } if(ringBuffer != nullptr) { ringBuffer->writeData(reinterpret_cast( @@ -120,17 +133,25 @@ ReturnValue_t CommandExecutor::check(bool& bytesRead) { return BYTES_READ; } else { +#if FSFW_CPP_OSTREAM_ENABLED == 1 // Should also not happen sif::warning << "CommandExecutor::check: Error " << errno << ": " << strerror(errno) << std::endl; +#else + sif::printWarning("CommandExecutor::check: Error %d: %s\n", errno, strerror(errno)); +#endif } } else if(waiter.revents & POLLERR) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "CommandExecuter::check: Poll error" << std::endl; +#else + sif::printWarning("CommandExecuter::check: Poll error\n"); +#endif return COMMAND_ERROR; } else if(waiter.revents & POLLHUP) { - int result = pclose(currentCmdFile); + result = pclose(currentCmdFile); if(result != 0) { lastError = result; return HasReturnvaluesIF::RETURN_FAILED; @@ -165,7 +186,11 @@ ReturnValue_t CommandExecutor::executeBlocking() { while(fgets(readVec.data(), readVec.size(), currentCmdFile) != nullptr) { std::string output(readVec.data()); if(printOutput) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 sif::info << currentCmd << " | " << output; +#else + sif::printInfo("%s | %s", currentCmd, output); +#endif } if(ringBuffer != nullptr) { ringBuffer->writeData(reinterpret_cast(output.data()), output.size()); From 94bb91dbfb621fe724930b44e961f19c960be887 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 16 Aug 2021 10:58:11 +0200 Subject: [PATCH 19/38] reverted to old action helper --- src/fsfw/action/ActionHelper.cpp | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/fsfw/action/ActionHelper.cpp b/src/fsfw/action/ActionHelper.cpp index 3e9d121a..3dfe8b50 100644 --- a/src/fsfw/action/ActionHelper.cpp +++ b/src/fsfw/action/ActionHelper.cpp @@ -55,19 +55,7 @@ void ActionHelper::setQueueToUse(MessageQueueIF* queue) { void ActionHelper::prepareExecution(MessageQueueId_t commandedBy, ActionId_t actionId, store_address_t dataAddress) { - if(ipcStore == nullptr) { -#if FSFW_VERBOSE_LEVEL >= 1 -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "ActionHelper::prepareExecution: IPC Store not set. Call initialize first" - << std::endl; -#else - sif::printWarning("ActionHelper::prepareExecution: " - "IPC Store not set. Call initialize first\n"); -#endif -#endif /* FSFW_VERBOSE_LEVEL >= 1 */ - return; - } - const uint8_t* dataPtr = nullptr; + const uint8_t* dataPtr = NULL; size_t size = 0; ReturnValue_t result = ipcStore->getData(dataAddress, &dataPtr, &size); if (result != HasReturnvaluesIF::RETURN_OK) { From ddac936a2cc33b83792e14c73bf680256fff3720 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 16 Aug 2021 10:59:28 +0200 Subject: [PATCH 20/38] adds some utility to linux timer --- src/fsfw/osal/linux/Timer.cpp | 12 ++++++++++++ src/fsfw/osal/linux/Timer.h | 4 ++++ 2 files changed, 16 insertions(+) diff --git a/src/fsfw/osal/linux/Timer.cpp b/src/fsfw/osal/linux/Timer.cpp index dca3112d..899ca4a5 100644 --- a/src/fsfw/osal/linux/Timer.cpp +++ b/src/fsfw/osal/linux/Timer.cpp @@ -27,6 +27,7 @@ int Timer::setTimer(uint32_t intervalMs) { timer.it_value.tv_nsec = (intervalMs * 1000000) % (1000000000); timer.it_interval.tv_sec = 0; timer.it_interval.tv_nsec = 0; + set = true; return timer_settime(timerId, 0, &timer, NULL); } @@ -43,3 +44,14 @@ int Timer::getTimer(uint32_t* remainingTimeMs){ return status; } + +bool Timer::isSet() const { + return this->set; +} + +void Timer::resetTimer() { + if(not this->set) { + set = false; + } + setTimer(0); +} diff --git a/src/fsfw/osal/linux/Timer.h b/src/fsfw/osal/linux/Timer.h index f94bca59..6d8c1b9e 100644 --- a/src/fsfw/osal/linux/Timer.h +++ b/src/fsfw/osal/linux/Timer.h @@ -38,7 +38,11 @@ public: */ int getTimer(uint32_t* remainingTimeMs); + bool isSet() const; + void resetTimer(); + private: + bool set = true; timer_t timerId; }; From 9e36bbc11ddb7a548a2b8705d87226f4a6d1c44c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 16 Aug 2021 11:02:36 +0200 Subject: [PATCH 21/38] small bugfix --- src/fsfw/osal/linux/Timer.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/fsfw/osal/linux/Timer.cpp b/src/fsfw/osal/linux/Timer.cpp index 899ca4a5..7b11e7d3 100644 --- a/src/fsfw/osal/linux/Timer.cpp +++ b/src/fsfw/osal/linux/Timer.cpp @@ -50,8 +50,6 @@ bool Timer::isSet() const { } void Timer::resetTimer() { - if(not this->set) { - set = false; - } + set = false; setTimer(0); } From 73cd58f2dd76466bb4da5064437e30d18f0da1d2 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 16 Aug 2021 11:15:24 +0200 Subject: [PATCH 22/38] internal unit test structural improvements --- tests/src/fsfw_tests/internal/InternalUnitTester.cpp | 6 +++--- tests/src/fsfw_tests/internal/osal/CMakeLists.txt | 6 +++--- tests/src/fsfw_tests/internal/osal/testCmdExecutor.cpp | 3 +++ tests/src/fsfw_tests/internal/osal/testCmdExecutor.h | 10 ++++++++++ .../internal/osal/{IntTestMq.cpp => testMq.cpp} | 2 +- .../fsfw_tests/internal/osal/{IntTestMq.h => testMq.h} | 0 .../internal/osal/{IntTestMutex.cpp => testMutex.cpp} | 2 +- .../internal/osal/{IntTestMutex.h => testMutex.h} | 0 .../osal/{IntTestSemaphore.cpp => testSemaphore.cpp} | 2 +- .../osal/{IntTestSemaphore.h => testSemaphore.h} | 0 10 files changed, 22 insertions(+), 9 deletions(-) create mode 100644 tests/src/fsfw_tests/internal/osal/testCmdExecutor.cpp create mode 100644 tests/src/fsfw_tests/internal/osal/testCmdExecutor.h rename tests/src/fsfw_tests/internal/osal/{IntTestMq.cpp => testMq.cpp} (96%) rename tests/src/fsfw_tests/internal/osal/{IntTestMq.h => testMq.h} (100%) rename tests/src/fsfw_tests/internal/osal/{IntTestMutex.cpp => testMutex.cpp} (96%) rename tests/src/fsfw_tests/internal/osal/{IntTestMutex.h => testMutex.h} (100%) rename tests/src/fsfw_tests/internal/osal/{IntTestSemaphore.cpp => testSemaphore.cpp} (98%) rename tests/src/fsfw_tests/internal/osal/{IntTestSemaphore.h => testSemaphore.h} (100%) diff --git a/tests/src/fsfw_tests/internal/InternalUnitTester.cpp b/tests/src/fsfw_tests/internal/InternalUnitTester.cpp index f9fc1932..e4f64dd3 100644 --- a/tests/src/fsfw_tests/internal/InternalUnitTester.cpp +++ b/tests/src/fsfw_tests/internal/InternalUnitTester.cpp @@ -1,9 +1,9 @@ #include "fsfw_tests/internal/InternalUnitTester.h" #include "fsfw_tests/internal/UnittDefinitions.h" -#include "fsfw_tests/internal/osal/IntTestMq.h" -#include "fsfw_tests/internal/osal/IntTestSemaphore.h" -#include "fsfw_tests/internal/osal/IntTestMutex.h" +#include "fsfw_tests/internal/osal/testMq.h" +#include "fsfw_tests/internal/osal/testSemaphore.h" +#include "fsfw_tests/internal/osal/testMutex.h" #include "fsfw_tests/internal/serialize/IntTestSerialization.h" #include "fsfw_tests/internal/globalfunctions/TestArrayPrinter.h" diff --git a/tests/src/fsfw_tests/internal/osal/CMakeLists.txt b/tests/src/fsfw_tests/internal/osal/CMakeLists.txt index 84316089..76d2f143 100644 --- a/tests/src/fsfw_tests/internal/osal/CMakeLists.txt +++ b/tests/src/fsfw_tests/internal/osal/CMakeLists.txt @@ -1,5 +1,5 @@ target_sources(${LIB_FSFW_NAME} PRIVATE - IntTestMq.cpp - IntTestMutex.cpp - IntTestSemaphore.cpp + testMq.cpp + testMutex.cpp + TestSemaphore.cpp ) diff --git a/tests/src/fsfw_tests/internal/osal/testCmdExecutor.cpp b/tests/src/fsfw_tests/internal/osal/testCmdExecutor.cpp new file mode 100644 index 00000000..6f6a3469 --- /dev/null +++ b/tests/src/fsfw_tests/internal/osal/testCmdExecutor.cpp @@ -0,0 +1,3 @@ +#include "testCmdExecutor.h" + + diff --git a/tests/src/fsfw_tests/internal/osal/testCmdExecutor.h b/tests/src/fsfw_tests/internal/osal/testCmdExecutor.h new file mode 100644 index 00000000..4779dde9 --- /dev/null +++ b/tests/src/fsfw_tests/internal/osal/testCmdExecutor.h @@ -0,0 +1,10 @@ +#ifndef FSFW_TESTS_SRC_FSFW_TESTS_INTERNAL_OSAL_TESTCMDEXECUTOR_H_ +#define FSFW_TESTS_SRC_FSFW_TESTS_INTERNAL_OSAL_TESTCMDEXECUTOR_H_ + +namespace testcmdexec { + +} + + + +#endif /* FSFW_TESTS_SRC_FSFW_TESTS_INTERNAL_OSAL_TESTCMDEXECUTOR_H_ */ diff --git a/tests/src/fsfw_tests/internal/osal/IntTestMq.cpp b/tests/src/fsfw_tests/internal/osal/testMq.cpp similarity index 96% rename from tests/src/fsfw_tests/internal/osal/IntTestMq.cpp rename to tests/src/fsfw_tests/internal/osal/testMq.cpp index 6c31b354..8a252910 100644 --- a/tests/src/fsfw_tests/internal/osal/IntTestMq.cpp +++ b/tests/src/fsfw_tests/internal/osal/testMq.cpp @@ -1,4 +1,4 @@ -#include "fsfw_tests/internal/osal/IntTestMq.h" +#include "testMq.h" #include "fsfw_tests/internal/UnittDefinitions.h" #include diff --git a/tests/src/fsfw_tests/internal/osal/IntTestMq.h b/tests/src/fsfw_tests/internal/osal/testMq.h similarity index 100% rename from tests/src/fsfw_tests/internal/osal/IntTestMq.h rename to tests/src/fsfw_tests/internal/osal/testMq.h diff --git a/tests/src/fsfw_tests/internal/osal/IntTestMutex.cpp b/tests/src/fsfw_tests/internal/osal/testMutex.cpp similarity index 96% rename from tests/src/fsfw_tests/internal/osal/IntTestMutex.cpp rename to tests/src/fsfw_tests/internal/osal/testMutex.cpp index b1699a46..e204675a 100644 --- a/tests/src/fsfw_tests/internal/osal/IntTestMutex.cpp +++ b/tests/src/fsfw_tests/internal/osal/testMutex.cpp @@ -1,4 +1,4 @@ -#include "fsfw_tests/internal/osal/IntTestMutex.h" +#include "testMutex.h" #include "fsfw_tests/internal/UnittDefinitions.h" #include diff --git a/tests/src/fsfw_tests/internal/osal/IntTestMutex.h b/tests/src/fsfw_tests/internal/osal/testMutex.h similarity index 100% rename from tests/src/fsfw_tests/internal/osal/IntTestMutex.h rename to tests/src/fsfw_tests/internal/osal/testMutex.h diff --git a/tests/src/fsfw_tests/internal/osal/IntTestSemaphore.cpp b/tests/src/fsfw_tests/internal/osal/testSemaphore.cpp similarity index 98% rename from tests/src/fsfw_tests/internal/osal/IntTestSemaphore.cpp rename to tests/src/fsfw_tests/internal/osal/testSemaphore.cpp index 8b79f33b..c124f038 100644 --- a/tests/src/fsfw_tests/internal/osal/IntTestSemaphore.cpp +++ b/tests/src/fsfw_tests/internal/osal/testSemaphore.cpp @@ -1,4 +1,4 @@ -#include "fsfw_tests/internal/osal/IntTestSemaphore.h" +#include "testSemaphore.h" #include "fsfw_tests/internal/UnittDefinitions.h" #include diff --git a/tests/src/fsfw_tests/internal/osal/IntTestSemaphore.h b/tests/src/fsfw_tests/internal/osal/testSemaphore.h similarity index 100% rename from tests/src/fsfw_tests/internal/osal/IntTestSemaphore.h rename to tests/src/fsfw_tests/internal/osal/testSemaphore.h From 517d52f55df804ef22fab9c7be6708e2560b180d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 16 Aug 2021 11:27:46 +0200 Subject: [PATCH 23/38] using better defines --- .../src/fsfw_tests/internal/InternalUnitTester.cpp | 9 ++++++--- tests/src/fsfw_tests/internal/InternalUnitTester.h | 1 + tests/src/fsfw_tests/internal/osal/IntTestMutex.cpp | 11 ++++++----- .../fsfw_tests/internal/osal/IntTestSemaphore.cpp | 13 +++++++------ 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/tests/src/fsfw_tests/internal/InternalUnitTester.cpp b/tests/src/fsfw_tests/internal/InternalUnitTester.cpp index f9fc1932..20998d64 100644 --- a/tests/src/fsfw_tests/internal/InternalUnitTester.cpp +++ b/tests/src/fsfw_tests/internal/InternalUnitTester.cpp @@ -16,15 +16,18 @@ InternalUnitTester::~InternalUnitTester() {} ReturnValue_t InternalUnitTester::performTests( const struct InternalUnitTester::TestConfig& testConfig) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::info << "Running internal unit tests.." << std::endl; + sif::info << "Running internal unit tests.. Error messages might follow" << + std::endl; #else sif::printInfo("Running internal unit tests..\n"); #endif testserialize::test_serialization(); testmq::testMq(); - testsemaph::testBinSemaph(); - testsemaph::testCountingSemaph(); + if(testConfig.testSemaphores) { + testsemaph::testBinSemaph(); + testsemaph::testCountingSemaph(); + } testmutex::testMutex(); if(testConfig.testArrayPrinter) { arrayprinter::testArrayPrinter(); diff --git a/tests/src/fsfw_tests/internal/InternalUnitTester.h b/tests/src/fsfw_tests/internal/InternalUnitTester.h index 50c89d77..433a0f1f 100644 --- a/tests/src/fsfw_tests/internal/InternalUnitTester.h +++ b/tests/src/fsfw_tests/internal/InternalUnitTester.h @@ -18,6 +18,7 @@ class InternalUnitTester: public HasReturnvaluesIF { public: struct TestConfig { bool testArrayPrinter = false; + bool testSemaphores = true; }; InternalUnitTester(); diff --git a/tests/src/fsfw_tests/internal/osal/IntTestMutex.cpp b/tests/src/fsfw_tests/internal/osal/IntTestMutex.cpp index b1699a46..d9184cd8 100644 --- a/tests/src/fsfw_tests/internal/osal/IntTestMutex.cpp +++ b/tests/src/fsfw_tests/internal/osal/IntTestMutex.cpp @@ -1,10 +1,12 @@ #include "fsfw_tests/internal/osal/IntTestMutex.h" #include "fsfw_tests/internal/UnittDefinitions.h" +#include "fsfw/platform.h" #include -#if defined(WIN32) || defined(UNIX) -#include +#if defined PLATFORM_WIN || defined PLATFORM_UNIX +#include "fsfw/osal/host/Mutex.h" + #include #include #endif @@ -20,7 +22,7 @@ void testmutex::testMutex() { // timed_mutex from the C++ library specifies undefined behaviour if // the timed mutex is locked twice from the same thread. // TODO: we should pass a define like FSFW_OSAL_HOST to the build. -#if defined(WIN32) || defined(UNIX) +#if defined PLATFORM_WIN || defined PLATFORM_UNIX // This calls the function from // another thread and stores the returnvalue in a future. auto future = std::async(&MutexIF::lockMutex, mutex, MutexIF::TimeoutType::WAITING, 1); @@ -37,8 +39,7 @@ void testmutex::testMutex() { unitt::put_error(id); } - // TODO: we should pass a define like FSFW_OSAL_HOST to the build. -#if !defined(WIN32) && !defined(UNIX) +#if !defined PLATFORM_WIN && !defined PLATFORM_UNIX result = mutex->unlockMutex(); if(result != MutexIF::CURR_THREAD_DOES_NOT_OWN_MUTEX) { unitt::put_error(id); diff --git a/tests/src/fsfw_tests/internal/osal/IntTestSemaphore.cpp b/tests/src/fsfw_tests/internal/osal/IntTestSemaphore.cpp index 8b79f33b..4b28f961 100644 --- a/tests/src/fsfw_tests/internal/osal/IntTestSemaphore.cpp +++ b/tests/src/fsfw_tests/internal/osal/IntTestSemaphore.cpp @@ -1,9 +1,10 @@ +#include "fsfw/FSFW.h" #include "fsfw_tests/internal/osal/IntTestSemaphore.h" #include "fsfw_tests/internal/UnittDefinitions.h" -#include -#include -#include +#include "fsfw/tasks/SemaphoreFactory.h" +#include "fsfw/serviceinterface/ServiceInterface.h" +#include "fsfw/timemanager/Stopwatch.h" #include @@ -16,7 +17,7 @@ void testsemaph::testBinSemaph() { } testBinSemaphoreImplementation(binSemaph, id); SemaphoreFactory::instance()->deleteSemaphore(binSemaph); -#if defined(freeRTOS) +#if defined FSFW_OSAL_FREERTOS SemaphoreIF* binSemaphUsingTask = SemaphoreFactory::instance()->createBinarySemaphore(1); testBinSemaphoreImplementation(binSemaphUsingTask, id); @@ -36,7 +37,7 @@ void testsemaph::testCountingSemaph() { } testBinSemaphoreImplementation(countingSemaph, id); SemaphoreFactory::instance()->deleteSemaphore(countingSemaph); -#if defined(freeRTOS) +#if defined FSFW_OSAL_FREERTOS countingSemaph = SemaphoreFactory::instance()-> createCountingSemaphore(1, 1, 1); testBinSemaphoreImplementation(countingSemaph, id); @@ -50,7 +51,7 @@ void testsemaph::testCountingSemaph() { createCountingSemaphore(3,3); testCountingSemaphImplementation(countingSemaph, id); SemaphoreFactory::instance()->deleteSemaphore(countingSemaph); -#if defined(freeRTOS) +#if defined FSFW_OSAL_FREERTOS countingSemaph = SemaphoreFactory::instance()-> createCountingSemaphore(3, 0, 1); uint8_t semaphCount = countingSemaph->getSemaphoreCounter(); From 80263b647da6d22489a223428c53ab0a5c97c6cf Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 16 Aug 2021 11:42:14 +0200 Subject: [PATCH 24/38] nothing --- tests/src/fsfw_tests/internal/osal/testCmdExecutor.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/src/fsfw_tests/internal/osal/testCmdExecutor.cpp b/tests/src/fsfw_tests/internal/osal/testCmdExecutor.cpp index 6f6a3469..f0bed8ad 100644 --- a/tests/src/fsfw_tests/internal/osal/testCmdExecutor.cpp +++ b/tests/src/fsfw_tests/internal/osal/testCmdExecutor.cpp @@ -1,3 +1 @@ #include "testCmdExecutor.h" - - From 20ee0ed2c41fbc57afb8d482526742dccb964d1c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 17 Aug 2021 14:57:09 +0200 Subject: [PATCH 25/38] STX and ETX escaping are optional now --- src/fsfw/globalfunctions/DleEncoder.cpp | 68 +++++++++++-------- src/fsfw/globalfunctions/DleEncoder.h | 30 +++++--- .../fsfw_tests/internal/osal/CMakeLists.txt | 2 +- 3 files changed, 60 insertions(+), 40 deletions(-) diff --git a/src/fsfw/globalfunctions/DleEncoder.cpp b/src/fsfw/globalfunctions/DleEncoder.cpp index 11df8ad7..a25381dd 100644 --- a/src/fsfw/globalfunctions/DleEncoder.cpp +++ b/src/fsfw/globalfunctions/DleEncoder.cpp @@ -6,7 +6,7 @@ DleEncoder::~DleEncoder() {} ReturnValue_t DleEncoder::encode(const uint8_t* sourceStream, size_t sourceLen, uint8_t* destStream, size_t maxDestLen, - size_t* encodedLen, bool addStxEtx) { + size_t* encodedLen, bool addStxEtx, bool escapeStxEtx, bool escapeCr) { if (maxDestLen < 2) { return STREAM_TOO_SHORT; } @@ -17,26 +17,28 @@ ReturnValue_t DleEncoder::encode(const uint8_t* sourceStream, ++encodedIndex; } - while (encodedIndex < maxDestLen and sourceIndex < sourceLen) - { + while (encodedIndex < maxDestLen and sourceIndex < sourceLen) { nextByte = sourceStream[sourceIndex]; // STX, ETX and CR characters in the stream need to be escaped with DLE - if (nextByte == STX_CHAR or nextByte == ETX_CHAR or nextByte == CARRIAGE_RETURN) { - if (encodedIndex + 1 >= maxDestLen) { - return STREAM_TOO_SHORT; - } - else { - destStream[encodedIndex] = DLE_CHAR; - ++encodedIndex; - /* Escaped byte will be actual byte + 0x40. This prevents - * STX, ETX, and carriage return characters from appearing - * in the encoded data stream at all, so when polling an - * encoded stream, the transmission can be stopped at ETX. - * 0x40 was chosen at random with special requirements: - * - Prevent going from one control char to another - * - Prevent overflow for common characters */ - destStream[encodedIndex] = nextByte + 0x40; - } + if ((nextByte == STX_CHAR or nextByte == ETX_CHAR) or + (escapeCr and nextByte == CARRIAGE_RETURN)) { + if(escapeStxEtx) { + if (encodedIndex + 1 >= maxDestLen) { + return STREAM_TOO_SHORT; + } + else { + destStream[encodedIndex] = DLE_CHAR; + ++encodedIndex; + /* Escaped byte will be actual byte + 0x40. This prevents + * STX, ETX, and carriage return characters from appearing + * in the encoded data stream at all, so when polling an + * encoded stream, the transmission can be stopped at ETX. + * 0x40 was chosen at random with special requirements: + * - Prevent going from one control char to another + * - Prevent overflow for common characters */ + destStream[encodedIndex] = nextByte + 0x40; + } + } } // DLE characters are simply escaped with DLE. else if (nextByte == DLE_CHAR) { @@ -71,7 +73,7 @@ ReturnValue_t DleEncoder::encode(const uint8_t* sourceStream, ReturnValue_t DleEncoder::decode(const uint8_t *sourceStream, size_t sourceStreamLen, size_t *readLen, uint8_t *destStream, - size_t maxDestStreamlen, size_t *decodedLen) { + size_t maxDestStreamlen, size_t *decodedLen, bool escapeStxEtx, bool escapeCr) { size_t encodedIndex = 0, decodedIndex = 0; uint8_t nextByte; if (*sourceStream != STX_CHAR) { @@ -90,16 +92,22 @@ ReturnValue_t DleEncoder::decode(const uint8_t *sourceStream, destStream[decodedIndex] = nextByte; } else { - /* The next byte is a STX, DTX or 0x0D character which - * was escaped by a DLE character. The actual byte was - * also encoded by adding + 0x40 to prevent having control chars, - * in the stream at all, so we convert it back. */ - if (nextByte == 0x42 or nextByte == 0x43 or nextByte == 0x4D) { - destStream[decodedIndex] = nextByte - 0x40; - } - else { - return DECODING_ERROR; - } + if(escapeStxEtx) { + /* The next byte is a STX, DTX or 0x0D character which + * was escaped by a DLE character. The actual byte was + * also encoded by adding + 0x40 to prevent having control chars, + * in the stream at all, so we convert it back. */ + if ((nextByte == STX_CHAR + 0x40 or nextByte == ETX_CHAR + 0x40) or + (escapeCr and nextByte == CARRIAGE_RETURN + 0x40)) { + destStream[decodedIndex] = nextByte - 0x40; + } + else { + return DECODING_ERROR; + } + } + else { + return DECODING_ERROR; + } } ++encodedIndex; } diff --git a/src/fsfw/globalfunctions/DleEncoder.h b/src/fsfw/globalfunctions/DleEncoder.h index 6d073f9a..163a32b0 100644 --- a/src/fsfw/globalfunctions/DleEncoder.h +++ b/src/fsfw/globalfunctions/DleEncoder.h @@ -13,9 +13,9 @@ * * This encoder can be used to achieve a basic transport layer when using * char based transmission systems. - * The passed source strean is converted into a encoded stream by adding + * The passed source stream is converted into a encoded stream by adding * a STX marker at the start of the stream and an ETX marker at the end of - * the stream. Any STX, ETX, DLE and CR occurrences in the source stream are + * the stream. Any STX, ETX, DLE and CR occurrences in the source stream can be * escaped by a DLE character. The encoder also replaces escaped control chars * by another char, so STX, ETX and CR should not appear anywhere in the actual * encoded data stream. @@ -45,21 +45,28 @@ public: /** * Encodes the give data stream by preceding it with the STX marker - * and ending it with an ETX marker. STX, ETX and DLE characters inside - * the stream are escaped by DLE characters and also replaced by adding - * 0x40 (which is reverted in the decoding process). + * and ending it with an ETX marker. DLE characters inside + * the stream are escaped by DLE characters. STX, ETX and CR characters can be escaped with a + * DLE character as well. The escaped characters are also encoded by adding + * 0x40 (which is reverted in the decoding process). This is performed so the source stream + * does not have STX/ETX/CR occurrences anymore, so the receiving side can simply parse for + * start and end markers * @param sourceStream * @param sourceLen * @param destStream * @param maxDestLen * @param encodedLen - * @param addStxEtx - * Adding STX and ETX can be omitted, if they are added manually. + * @param addStxEtx Adding STX start marker and ETX end marker can be omitted, + * if they are added manually + * @param escapeStxEtx STX and ETX occurrences in the given source stream will be escaped and + * encoded by adding 0x40 + * @param escapeCr CR characters in the given source stream will be escaped and encoded + * by adding 0x40 * @return */ static ReturnValue_t encode(const uint8_t *sourceStream, size_t sourceLen, uint8_t *destStream, size_t maxDestLen, size_t *encodedLen, - bool addStxEtx = true); + bool addStxEtx = true, bool escapeStxEtx = true, bool escapeCr = false); /** * Converts an encoded stream back. @@ -69,11 +76,16 @@ public: * @param destStream * @param maxDestStreamlen * @param decodedLen + * @param escapeStxEtx STX and ETX characters were escaped in the encoded stream and need to + * be decoded back as well + * @param escapeCr CR characters were escaped in the encoded stream and need to + * be decoded back as well by subtracting 0x40 * @return */ static ReturnValue_t decode(const uint8_t *sourceStream, size_t sourceStreamLen, size_t *readLen, uint8_t *destStream, - size_t maxDestStreamlen, size_t *decodedLen); + size_t maxDestStreamlen, size_t *decodedLen, bool escapeStxEtx = true, + bool escapeCr = false); }; #endif /* FRAMEWORK_GLOBALFUNCTIONS_DLEENCODER_H_ */ diff --git a/tests/src/fsfw_tests/internal/osal/CMakeLists.txt b/tests/src/fsfw_tests/internal/osal/CMakeLists.txt index 76d2f143..8d79d759 100644 --- a/tests/src/fsfw_tests/internal/osal/CMakeLists.txt +++ b/tests/src/fsfw_tests/internal/osal/CMakeLists.txt @@ -1,5 +1,5 @@ target_sources(${LIB_FSFW_NAME} PRIVATE testMq.cpp testMutex.cpp - TestSemaphore.cpp + testSemaphore.cpp ) From 4b72e246c36bab632d9efd92ff1d8e6cd533b6a9 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 17 Aug 2021 15:05:29 +0200 Subject: [PATCH 26/38] improved DLE encoder --- src/fsfw/globalfunctions/DleEncoder.cpp | 67 ++++++++++++++----------- src/fsfw/globalfunctions/DleEncoder.h | 66 +++++++++++++++--------- 2 files changed, 79 insertions(+), 54 deletions(-) diff --git a/src/fsfw/globalfunctions/DleEncoder.cpp b/src/fsfw/globalfunctions/DleEncoder.cpp index 11df8ad7..d6f3cc87 100644 --- a/src/fsfw/globalfunctions/DleEncoder.cpp +++ b/src/fsfw/globalfunctions/DleEncoder.cpp @@ -1,6 +1,7 @@ #include "fsfw/globalfunctions/DleEncoder.h" -DleEncoder::DleEncoder() {} +DleEncoder::DleEncoder(bool escapeStxEtx, bool escapeCr): escapeStxEtx(escapeStxEtx), + escapeCr(escapeCr) {} DleEncoder::~DleEncoder() {} @@ -17,26 +18,28 @@ ReturnValue_t DleEncoder::encode(const uint8_t* sourceStream, ++encodedIndex; } - while (encodedIndex < maxDestLen and sourceIndex < sourceLen) - { + while (encodedIndex < maxDestLen and sourceIndex < sourceLen) { nextByte = sourceStream[sourceIndex]; // STX, ETX and CR characters in the stream need to be escaped with DLE - if (nextByte == STX_CHAR or nextByte == ETX_CHAR or nextByte == CARRIAGE_RETURN) { - if (encodedIndex + 1 >= maxDestLen) { - return STREAM_TOO_SHORT; - } - else { - destStream[encodedIndex] = DLE_CHAR; - ++encodedIndex; - /* Escaped byte will be actual byte + 0x40. This prevents - * STX, ETX, and carriage return characters from appearing - * in the encoded data stream at all, so when polling an - * encoded stream, the transmission can be stopped at ETX. - * 0x40 was chosen at random with special requirements: - * - Prevent going from one control char to another - * - Prevent overflow for common characters */ - destStream[encodedIndex] = nextByte + 0x40; - } + if ((nextByte == STX_CHAR or nextByte == ETX_CHAR) or + (this->escapeCr and nextByte == CARRIAGE_RETURN)) { + if(this->escapeStxEtx) { + if (encodedIndex + 1 >= maxDestLen) { + return STREAM_TOO_SHORT; + } + else { + destStream[encodedIndex] = DLE_CHAR; + ++encodedIndex; + /* Escaped byte will be actual byte + 0x40. This prevents + * STX, ETX, and carriage return characters from appearing + * in the encoded data stream at all, so when polling an + * encoded stream, the transmission can be stopped at ETX. + * 0x40 was chosen at random with special requirements: + * - Prevent going from one control char to another + * - Prevent overflow for common characters */ + destStream[encodedIndex] = nextByte + 0x40; + } + } } // DLE characters are simply escaped with DLE. else if (nextByte == DLE_CHAR) { @@ -90,16 +93,22 @@ ReturnValue_t DleEncoder::decode(const uint8_t *sourceStream, destStream[decodedIndex] = nextByte; } else { - /* The next byte is a STX, DTX or 0x0D character which - * was escaped by a DLE character. The actual byte was - * also encoded by adding + 0x40 to prevent having control chars, - * in the stream at all, so we convert it back. */ - if (nextByte == 0x42 or nextByte == 0x43 or nextByte == 0x4D) { - destStream[decodedIndex] = nextByte - 0x40; - } - else { - return DECODING_ERROR; - } + if(this->escapeStxEtx) { + /* The next byte is a STX, DTX or 0x0D character which + * was escaped by a DLE character. The actual byte was + * also encoded by adding + 0x40 to prevent having control chars, + * in the stream at all, so we convert it back. */ + if ((nextByte == STX_CHAR + 0x40 or nextByte == ETX_CHAR + 0x40) or + (this->escapeCr and nextByte == CARRIAGE_RETURN + 0x40)) { + destStream[decodedIndex] = nextByte - 0x40; + } + else { + return DECODING_ERROR; + } + } + else { + return DECODING_ERROR; + } } ++encodedIndex; } diff --git a/src/fsfw/globalfunctions/DleEncoder.h b/src/fsfw/globalfunctions/DleEncoder.h index 6d073f9a..38d4dc75 100644 --- a/src/fsfw/globalfunctions/DleEncoder.h +++ b/src/fsfw/globalfunctions/DleEncoder.h @@ -1,7 +1,7 @@ #ifndef FRAMEWORK_GLOBALFUNCTIONS_DLEENCODER_H_ #define FRAMEWORK_GLOBALFUNCTIONS_DLEENCODER_H_ -#include "../returnvalues/HasReturnvaluesIF.h" +#include "fsfw/returnvalues/HasReturnvaluesIF.h" #include /** @@ -13,9 +13,9 @@ * * This encoder can be used to achieve a basic transport layer when using * char based transmission systems. - * The passed source strean is converted into a encoded stream by adding + * The passed source stream is converted into a encoded stream by adding * a STX marker at the start of the stream and an ETX marker at the end of - * the stream. Any STX, ETX, DLE and CR occurrences in the source stream are + * the stream. Any STX, ETX, DLE and CR occurrences in the source stream can be * escaped by a DLE character. The encoder also replaces escaped control chars * by another char, so STX, ETX and CR should not appear anywhere in the actual * encoded data stream. @@ -26,38 +26,45 @@ */ class DleEncoder: public HasReturnvaluesIF { private: - DleEncoder(); - virtual ~DleEncoder(); + DleEncoder(bool escapeStxEtx = true, bool escapeCr = false); + virtual ~DleEncoder(); public: - static constexpr uint8_t INTERFACE_ID = CLASS_ID::DLE_ENCODER; - static constexpr ReturnValue_t STREAM_TOO_SHORT = MAKE_RETURN_CODE(0x01); - static constexpr ReturnValue_t DECODING_ERROR = MAKE_RETURN_CODE(0x02); + static constexpr uint8_t INTERFACE_ID = CLASS_ID::DLE_ENCODER; + static constexpr ReturnValue_t STREAM_TOO_SHORT = MAKE_RETURN_CODE(0x01); + static constexpr ReturnValue_t DECODING_ERROR = MAKE_RETURN_CODE(0x02); - //! Start Of Text character. First character is encoded stream - static constexpr uint8_t STX_CHAR = 0x02; - //! End Of Text character. Last character in encoded stream - static constexpr uint8_t ETX_CHAR = 0x03; - //! Data Link Escape character. Used to escape STX, ETX and DLE occurrences - //! in the source stream. - static constexpr uint8_t DLE_CHAR = 0x10; - static constexpr uint8_t CARRIAGE_RETURN = 0x0D; + //! Start Of Text character. First character is encoded stream + static constexpr uint8_t STX_CHAR = 0x02; + //! End Of Text character. Last character in encoded stream + static constexpr uint8_t ETX_CHAR = 0x03; + //! Data Link Escape character. Used to escape STX, ETX and DLE occurrences + //! in the source stream. + static constexpr uint8_t DLE_CHAR = 0x10; + static constexpr uint8_t CARRIAGE_RETURN = 0x0D; /** * Encodes the give data stream by preceding it with the STX marker - * and ending it with an ETX marker. STX, ETX and DLE characters inside - * the stream are escaped by DLE characters and also replaced by adding - * 0x40 (which is reverted in the decoding process). + * and ending it with an ETX marker. DLE characters inside + * the stream are escaped by DLE characters. STX, ETX and CR characters can be escaped with a + * DLE character as well. The escaped characters are also encoded by adding + * 0x40 (which is reverted in the decoding process). This is performed so the source stream + * does not have STX/ETX/CR occurrences anymore, so the receiving side can simply parse for + * start and end markers * @param sourceStream * @param sourceLen * @param destStream * @param maxDestLen * @param encodedLen - * @param addStxEtx - * Adding STX and ETX can be omitted, if they are added manually. + * @param addStxEtx Adding STX start marker and ETX end marker can be omitted, + * if they are added manually + * @param escapeStxEtx STX and ETX occurrences in the given source stream will be escaped and + * encoded by adding 0x40 + * @param escapeCr CR characters in the given source stream will be escaped and encoded + * by adding 0x40 * @return */ - static ReturnValue_t encode(const uint8_t *sourceStream, size_t sourceLen, + ReturnValue_t encode(const uint8_t *sourceStream, size_t sourceLen, uint8_t *destStream, size_t maxDestLen, size_t *encodedLen, bool addStxEtx = true); @@ -69,11 +76,20 @@ public: * @param destStream * @param maxDestStreamlen * @param decodedLen + * @param escapeStxEtx STX and ETX characters were escaped in the encoded stream and need to + * be decoded back as well + * @param escapeCr CR characters were escaped in the encoded stream and need to + * be decoded back as well by subtracting 0x40 * @return */ - static ReturnValue_t decode(const uint8_t *sourceStream, - size_t sourceStreamLen, size_t *readLen, uint8_t *destStream, - size_t maxDestStreamlen, size_t *decodedLen); + ReturnValue_t decode(const uint8_t *sourceStream, + size_t sourceStreamLen, size_t *readLen, uint8_t *destStream, + size_t maxDestStreamlen, size_t *decodedLen); + +private: + + bool escapeStxEtx; + bool escapeCr; }; #endif /* FRAMEWORK_GLOBALFUNCTIONS_DLEENCODER_H_ */ From ea5a14e54c3d0c8ce7ecaa36c7e1e341a67b2811 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 17 Aug 2021 15:11:55 +0200 Subject: [PATCH 27/38] ctor and dtor public now --- src/fsfw/globalfunctions/DleEncoder.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/fsfw/globalfunctions/DleEncoder.h b/src/fsfw/globalfunctions/DleEncoder.h index 36d73cf6..778419a9 100644 --- a/src/fsfw/globalfunctions/DleEncoder.h +++ b/src/fsfw/globalfunctions/DleEncoder.h @@ -25,11 +25,15 @@ * while ETX can be used to notify the reader that the data has ended. */ class DleEncoder: public HasReturnvaluesIF { -private: +public: + /** + * Create an encoder instance with the given configuration. + * @param escapeStxEtx + * @param escapeCr + */ DleEncoder(bool escapeStxEtx = true, bool escapeCr = false); virtual ~DleEncoder(); -public: static constexpr uint8_t INTERFACE_ID = CLASS_ID::DLE_ENCODER; static constexpr ReturnValue_t STREAM_TOO_SHORT = MAKE_RETURN_CODE(0x01); static constexpr ReturnValue_t DECODING_ERROR = MAKE_RETURN_CODE(0x02); From e7a3a3d35f80e2caa5784f452e43f471082947a0 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 17 Aug 2021 15:13:15 +0200 Subject: [PATCH 28/38] removed unrequired arguments --- src/fsfw/globalfunctions/DleEncoder.cpp | 2 +- src/fsfw/globalfunctions/DleEncoder.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fsfw/globalfunctions/DleEncoder.cpp b/src/fsfw/globalfunctions/DleEncoder.cpp index 7565b74b..d6f3cc87 100644 --- a/src/fsfw/globalfunctions/DleEncoder.cpp +++ b/src/fsfw/globalfunctions/DleEncoder.cpp @@ -7,7 +7,7 @@ DleEncoder::~DleEncoder() {} ReturnValue_t DleEncoder::encode(const uint8_t* sourceStream, size_t sourceLen, uint8_t* destStream, size_t maxDestLen, - size_t* encodedLen, bool addStxEtx, bool escapeStxEtx, bool escapeCr) { + size_t* encodedLen, bool addStxEtx) { if (maxDestLen < 2) { return STREAM_TOO_SHORT; } diff --git a/src/fsfw/globalfunctions/DleEncoder.h b/src/fsfw/globalfunctions/DleEncoder.h index 778419a9..c78fe197 100644 --- a/src/fsfw/globalfunctions/DleEncoder.h +++ b/src/fsfw/globalfunctions/DleEncoder.h @@ -70,7 +70,7 @@ public: */ ReturnValue_t encode(const uint8_t *sourceStream, size_t sourceLen, uint8_t *destStream, size_t maxDestLen, size_t *encodedLen, - bool addStxEtx = true, bool escapeStxEtx = true, bool escapeCr = false); + bool addStxEtx = true); /** * Converts an encoded stream back. From ece7dce6f7ee33b04473a41f698ff15414520a02 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 17 Aug 2021 15:13:58 +0200 Subject: [PATCH 29/38] ctor and dtor public now --- src/fsfw/globalfunctions/DleEncoder.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/fsfw/globalfunctions/DleEncoder.h b/src/fsfw/globalfunctions/DleEncoder.h index 38d4dc75..c78fe197 100644 --- a/src/fsfw/globalfunctions/DleEncoder.h +++ b/src/fsfw/globalfunctions/DleEncoder.h @@ -25,11 +25,15 @@ * while ETX can be used to notify the reader that the data has ended. */ class DleEncoder: public HasReturnvaluesIF { -private: +public: + /** + * Create an encoder instance with the given configuration. + * @param escapeStxEtx + * @param escapeCr + */ DleEncoder(bool escapeStxEtx = true, bool escapeCr = false); virtual ~DleEncoder(); -public: static constexpr uint8_t INTERFACE_ID = CLASS_ID::DLE_ENCODER; static constexpr ReturnValue_t STREAM_TOO_SHORT = MAKE_RETURN_CODE(0x01); static constexpr ReturnValue_t DECODING_ERROR = MAKE_RETURN_CODE(0x02); From 5fcac4d85b5eba9f28f9f7fae8dedb8f1f39928a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 17 Aug 2021 15:39:24 +0200 Subject: [PATCH 30/38] added proper non-escaped variant --- src/fsfw/globalfunctions/DleEncoder.cpp | 159 +++++++++++++++++------- src/fsfw/globalfunctions/DleEncoder.h | 8 ++ 2 files changed, 121 insertions(+), 46 deletions(-) diff --git a/src/fsfw/globalfunctions/DleEncoder.cpp b/src/fsfw/globalfunctions/DleEncoder.cpp index d6f3cc87..0cc3ad2a 100644 --- a/src/fsfw/globalfunctions/DleEncoder.cpp +++ b/src/fsfw/globalfunctions/DleEncoder.cpp @@ -14,6 +14,10 @@ ReturnValue_t DleEncoder::encode(const uint8_t* sourceStream, size_t encodedIndex = 0, sourceIndex = 0; uint8_t nextByte; if (addStxEtx) { + if(not escapeStxEtx) { + destStream[0] = DLE_CHAR; + ++encodedIndex; + } destStream[0] = STX_CHAR; ++encodedIndex; } @@ -61,6 +65,10 @@ ReturnValue_t DleEncoder::encode(const uint8_t* sourceStream, if (sourceIndex == sourceLen and encodedIndex < maxDestLen) { if (addStxEtx) { + if(not escapeStxEtx) { + destStream[encodedIndex] = DLE_CHAR; + ++encodedIndex; + } destStream[encodedIndex] = ETX_CHAR; ++encodedIndex; } @@ -72,62 +80,121 @@ ReturnValue_t DleEncoder::encode(const uint8_t* sourceStream, } } +ReturnValue_t DleEncoder::encodeEscaped(const uint8_t *sourceStream, size_t sourceLen, + uint8_t *destStream, size_t maxDestLen, size_t *encodedLen, bool addStxEtx) { +} + +ReturnValue_t DleEncoder::encodeNonEscaped(const uint8_t *sourceStream, size_t sourceLen, + uint8_t *destStream, size_t maxDestLen, size_t *encodedLen, bool addStxEtx) { +} + ReturnValue_t DleEncoder::decode(const uint8_t *sourceStream, size_t sourceStreamLen, size_t *readLen, uint8_t *destStream, size_t maxDestStreamlen, size_t *decodedLen) { size_t encodedIndex = 0, decodedIndex = 0; uint8_t nextByte; - if (*sourceStream != STX_CHAR) { - return DECODING_ERROR; + if(not escapeStxEtx) { + if (*sourceStream != DLE_CHAR) { + return DECODING_ERROR; + } + ++encodedIndex; } + if (sourceStream[encodedIndex] != STX_CHAR) { + return DECODING_ERROR; + } + ++encodedIndex; - while ((encodedIndex < sourceStreamLen) && (decodedIndex < maxDestStreamlen) - && (sourceStream[encodedIndex] != ETX_CHAR) - && (sourceStream[encodedIndex] != STX_CHAR)) { - if (sourceStream[encodedIndex] == DLE_CHAR) { - nextByte = sourceStream[encodedIndex + 1]; - // The next byte is a DLE character that was escaped by another - // DLE character, so we can write it to the destination stream. - if (nextByte == DLE_CHAR) { - destStream[decodedIndex] = nextByte; - } - else { - if(this->escapeStxEtx) { - /* The next byte is a STX, DTX or 0x0D character which - * was escaped by a DLE character. The actual byte was - * also encoded by adding + 0x40 to prevent having control chars, - * in the stream at all, so we convert it back. */ - if ((nextByte == STX_CHAR + 0x40 or nextByte == ETX_CHAR + 0x40) or - (this->escapeCr and nextByte == CARRIAGE_RETURN + 0x40)) { - destStream[decodedIndex] = nextByte - 0x40; - } - else { - return DECODING_ERROR; - } - } - else { - return DECODING_ERROR; - } - } - ++encodedIndex; - } - else { - destStream[decodedIndex] = sourceStream[encodedIndex]; - } - - ++encodedIndex; - ++decodedIndex; - } - - if (sourceStream[encodedIndex] != ETX_CHAR) { - *readLen = ++encodedIndex; - return DECODING_ERROR; + if(escapeStxEtx) { + return decodeStreamEscaped(encodedIndex, decodedIndex, sourceStream, sourceStreamLen, + readLen, destStream, maxDestStreamlen, decodedLen); } else { - *readLen = ++encodedIndex; - *decodedLen = decodedIndex; - return RETURN_OK; + return decodeStreamNonEscaped(encodedIndex, decodedIndex, sourceStream, sourceStreamLen, + readLen, destStream, maxDestStreamlen, decodedLen); } } +ReturnValue_t DleEncoder::decodeStreamEscaped(size_t encodedIndex, size_t decodedIndex, + const uint8_t *sourceStream, size_t sourceStreamLen, size_t *readLen, uint8_t *destStream, + size_t maxDestStreamlen, size_t *decodedLen) { + uint8_t nextByte; + while ((encodedIndex < sourceStreamLen) && (decodedIndex < maxDestStreamlen) + && (sourceStream[encodedIndex] != ETX_CHAR) + && (sourceStream[encodedIndex] != STX_CHAR)) { + if (sourceStream[encodedIndex] == DLE_CHAR) { + nextByte = sourceStream[encodedIndex + 1]; + // The next byte is a DLE character that was escaped by another + // DLE character, so we can write it to the destination stream. + if (nextByte == DLE_CHAR) { + destStream[decodedIndex] = nextByte; + } + else { + if(this->escapeStxEtx) { + /* The next byte is a STX, DTX or 0x0D character which + * was escaped by a DLE character. The actual byte was + * also encoded by adding + 0x40 to prevent having control chars, + * in the stream at all, so we convert it back. */ + if ((nextByte == STX_CHAR + 0x40 or nextByte == ETX_CHAR + 0x40) or + (this->escapeCr and nextByte == CARRIAGE_RETURN + 0x40)) { + destStream[decodedIndex] = nextByte - 0x40; + } + else { + return DECODING_ERROR; + } + } + else { + return DECODING_ERROR; + } + } + ++encodedIndex; + } + else { + destStream[decodedIndex] = sourceStream[encodedIndex]; + } + + ++encodedIndex; + ++decodedIndex; + } + if (sourceStream[encodedIndex] != ETX_CHAR) { + *readLen = ++encodedIndex; + return DECODING_ERROR; + } + else { + *readLen = ++encodedIndex; + *decodedLen = decodedIndex; + return RETURN_OK; + } +} + +ReturnValue_t DleEncoder::decodeStreamNonEscaped(size_t encodedIndex, size_t decodedIndex, + const uint8_t *sourceStream, size_t sourceStreamLen, size_t *readLen, uint8_t *destStream, + size_t maxDestStreamlen, size_t *decodedLen) { + uint8_t nextByte; + while ((encodedIndex < sourceStreamLen) && (decodedIndex < maxDestStreamlen)) { + if (sourceStream[encodedIndex] == DLE_CHAR) { + nextByte = sourceStream[encodedIndex + 1]; + if(nextByte == STX_CHAR) { + *readLen = ++encodedIndex; + return DECODING_ERROR; + } + else if(nextByte == DLE_CHAR) { + // The next byte is a DLE character that was escaped by another + // DLE character, so we can write it to the destination stream. + destStream[decodedIndex] = nextByte; + ++encodedIndex; + } + else if(nextByte == ETX_CHAR) { + // End of stream reached + return RETURN_OK; + } + } + else { + destStream[decodedIndex] = sourceStream[encodedIndex]; + } + ++encodedIndex; + ++decodedIndex; + } + return DECODING_ERROR; +} + diff --git a/src/fsfw/globalfunctions/DleEncoder.h b/src/fsfw/globalfunctions/DleEncoder.h index c78fe197..47bb2a69 100644 --- a/src/fsfw/globalfunctions/DleEncoder.h +++ b/src/fsfw/globalfunctions/DleEncoder.h @@ -90,6 +90,14 @@ public: size_t sourceStreamLen, size_t *readLen, uint8_t *destStream, size_t maxDestStreamlen, size_t *decodedLen); + ReturnValue_t decodeStreamEscaped(size_t encodedIndex, size_t decodedIndex, + const uint8_t *sourceStream, size_t sourceStreamLen, size_t *readLen, + uint8_t *destStream, size_t maxDestStreamlen, size_t *decodedLen); + + ReturnValue_t decodeStreamNonEscaped(size_t encodedIndex, size_t decodedIndex, + const uint8_t *sourceStream, size_t sourceStreamLen, size_t *readLen, + uint8_t *destStream, size_t maxDestStreamlen, size_t *decodedLen); + private: bool escapeStxEtx; From 28f2db2c113bb2e34b641c9fbed8dd3568ca83c4 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 17 Aug 2021 15:40:51 +0200 Subject: [PATCH 31/38] some fixes --- src/fsfw/globalfunctions/DleEncoder.cpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/fsfw/globalfunctions/DleEncoder.cpp b/src/fsfw/globalfunctions/DleEncoder.cpp index 0cc3ad2a..81131910 100644 --- a/src/fsfw/globalfunctions/DleEncoder.cpp +++ b/src/fsfw/globalfunctions/DleEncoder.cpp @@ -80,19 +80,10 @@ ReturnValue_t DleEncoder::encode(const uint8_t* sourceStream, } } -ReturnValue_t DleEncoder::encodeEscaped(const uint8_t *sourceStream, size_t sourceLen, - uint8_t *destStream, size_t maxDestLen, size_t *encodedLen, bool addStxEtx) { -} - -ReturnValue_t DleEncoder::encodeNonEscaped(const uint8_t *sourceStream, size_t sourceLen, - uint8_t *destStream, size_t maxDestLen, size_t *encodedLen, bool addStxEtx) { -} - ReturnValue_t DleEncoder::decode(const uint8_t *sourceStream, size_t sourceStreamLen, size_t *readLen, uint8_t *destStream, size_t maxDestStreamlen, size_t *decodedLen) { size_t encodedIndex = 0, decodedIndex = 0; - uint8_t nextByte; if(not escapeStxEtx) { if (*sourceStream != DLE_CHAR) { return DECODING_ERROR; From 1cbd72dcfb3636e47e9af2fdce3b77aa98fe5370 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 17 Aug 2021 15:50:47 +0200 Subject: [PATCH 32/38] more refactoring --- src/fsfw/globalfunctions/DleEncoder.cpp | 24 +++++++++++++++--------- src/fsfw/globalfunctions/DleEncoder.h | 10 ++++------ 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/fsfw/globalfunctions/DleEncoder.cpp b/src/fsfw/globalfunctions/DleEncoder.cpp index 81131910..6ad5e5fa 100644 --- a/src/fsfw/globalfunctions/DleEncoder.cpp +++ b/src/fsfw/globalfunctions/DleEncoder.cpp @@ -83,7 +83,7 @@ ReturnValue_t DleEncoder::encode(const uint8_t* sourceStream, ReturnValue_t DleEncoder::decode(const uint8_t *sourceStream, size_t sourceStreamLen, size_t *readLen, uint8_t *destStream, size_t maxDestStreamlen, size_t *decodedLen) { - size_t encodedIndex = 0, decodedIndex = 0; + size_t encodedIndex = 0; if(not escapeStxEtx) { if (*sourceStream != DLE_CHAR) { return DECODING_ERROR; @@ -94,21 +94,22 @@ ReturnValue_t DleEncoder::decode(const uint8_t *sourceStream, return DECODING_ERROR; } - ++encodedIndex; - if(escapeStxEtx) { - return decodeStreamEscaped(encodedIndex, decodedIndex, sourceStream, sourceStreamLen, + return decodeStreamEscaped(sourceStream, sourceStreamLen, readLen, destStream, maxDestStreamlen, decodedLen); } else { - return decodeStreamNonEscaped(encodedIndex, decodedIndex, sourceStream, sourceStreamLen, + return decodeStreamNonEscaped(sourceStream, sourceStreamLen, readLen, destStream, maxDestStreamlen, decodedLen); } } -ReturnValue_t DleEncoder::decodeStreamEscaped(size_t encodedIndex, size_t decodedIndex, - const uint8_t *sourceStream, size_t sourceStreamLen, size_t *readLen, uint8_t *destStream, +ReturnValue_t DleEncoder::decodeStreamEscaped(const uint8_t *sourceStream, size_t sourceStreamLen, + size_t *readLen, uint8_t *destStream, size_t maxDestStreamlen, size_t *decodedLen) { + // Skip start marker, was already checked + size_t encodedIndex = 1; + size_t decodedIndex = 0; uint8_t nextByte; while ((encodedIndex < sourceStreamLen) && (decodedIndex < maxDestStreamlen) && (sourceStream[encodedIndex] != ETX_CHAR) @@ -158,9 +159,12 @@ ReturnValue_t DleEncoder::decodeStreamEscaped(size_t encodedIndex, size_t decode } } -ReturnValue_t DleEncoder::decodeStreamNonEscaped(size_t encodedIndex, size_t decodedIndex, - const uint8_t *sourceStream, size_t sourceStreamLen, size_t *readLen, uint8_t *destStream, +ReturnValue_t DleEncoder::decodeStreamNonEscaped(const uint8_t *sourceStream, + size_t sourceStreamLen, size_t *readLen, uint8_t *destStream, size_t maxDestStreamlen, size_t *decodedLen) { + // Skip start marker, was already checked + size_t encodedIndex = 2; + size_t decodedIndex = 0; uint8_t nextByte; while ((encodedIndex < sourceStreamLen) && (decodedIndex < maxDestStreamlen)) { if (sourceStream[encodedIndex] == DLE_CHAR) { @@ -177,6 +181,8 @@ ReturnValue_t DleEncoder::decodeStreamNonEscaped(size_t encodedIndex, size_t dec } else if(nextByte == ETX_CHAR) { // End of stream reached + *readLen = encodedIndex + 2; + *decodedLen = decodedIndex; return RETURN_OK; } } diff --git a/src/fsfw/globalfunctions/DleEncoder.h b/src/fsfw/globalfunctions/DleEncoder.h index 47bb2a69..fab0e502 100644 --- a/src/fsfw/globalfunctions/DleEncoder.h +++ b/src/fsfw/globalfunctions/DleEncoder.h @@ -90,13 +90,11 @@ public: size_t sourceStreamLen, size_t *readLen, uint8_t *destStream, size_t maxDestStreamlen, size_t *decodedLen); - ReturnValue_t decodeStreamEscaped(size_t encodedIndex, size_t decodedIndex, - const uint8_t *sourceStream, size_t sourceStreamLen, size_t *readLen, - uint8_t *destStream, size_t maxDestStreamlen, size_t *decodedLen); + ReturnValue_t decodeStreamEscaped(const uint8_t *sourceStream, size_t sourceStreamLen, + size_t *readLen, uint8_t *destStream, size_t maxDestStreamlen, size_t *decodedLen); - ReturnValue_t decodeStreamNonEscaped(size_t encodedIndex, size_t decodedIndex, - const uint8_t *sourceStream, size_t sourceStreamLen, size_t *readLen, - uint8_t *destStream, size_t maxDestStreamlen, size_t *decodedLen); + ReturnValue_t decodeStreamNonEscaped(const uint8_t *sourceStream, size_t sourceStreamLen, + size_t *readLen, uint8_t *destStream, size_t maxDestStreamlen, size_t *decodedLen); private: From d1f46522059947eb0bc43470ef155c2f50081e15 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 17 Aug 2021 16:00:10 +0200 Subject: [PATCH 33/38] documentation updated --- src/fsfw/globalfunctions/DleEncoder.h | 33 ++++++++++++--------------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/src/fsfw/globalfunctions/DleEncoder.h b/src/fsfw/globalfunctions/DleEncoder.h index fab0e502..cc7dbc22 100644 --- a/src/fsfw/globalfunctions/DleEncoder.h +++ b/src/fsfw/globalfunctions/DleEncoder.h @@ -12,24 +12,29 @@ * https://en.wikipedia.org/wiki/C0_and_C1_control_codes * * This encoder can be used to achieve a basic transport layer when using - * char based transmission systems. - * The passed source stream is converted into a encoded stream by adding - * a STX marker at the start of the stream and an ETX marker at the end of - * the stream. Any STX, ETX, DLE and CR occurrences in the source stream can be - * escaped by a DLE character. The encoder also replaces escaped control chars - * by another char, so STX, ETX and CR should not appear anywhere in the actual - * encoded data stream. + * char based transmission systems. There are two implemented variants: * - * When using a strictly char based reception of packets encoded with DLE, + * 1. Escaped variant + * + * The encoded stream starts with a STX marker and ends with an ETX marker. + * STX and ETX occurrences in the stream are escaped and internally encoded as well so the + * receiver side can simply check for STX and ETX markers as frame delimiters. When using a + * strictly char based reception of packets encoded with DLE, * STX can be used to notify a reader that actual data will start to arrive * while ETX can be used to notify the reader that the data has ended. + * + * 2. Non-escaped variant + * + * The encoded stream starts with DLE STX and ends with DLE ETX. All DLE occurrences in the stream + * are escaped with DLE. If the received detects a DLE char, it needs to read the next char + * and to determine whether a start (STX) or end (ETX) of a frame has been detected. */ class DleEncoder: public HasReturnvaluesIF { public: /** * Create an encoder instance with the given configuration. - * @param escapeStxEtx - * @param escapeCr + * @param escapeStxEtx Determines whether the algorithm works in escaped or non-escaped mode + * @param escapeCr In escaped mode, escape all CR occurrences as well */ DleEncoder(bool escapeStxEtx = true, bool escapeCr = false); virtual ~DleEncoder(); @@ -62,10 +67,6 @@ public: * @param encodedLen * @param addStxEtx Adding STX start marker and ETX end marker can be omitted, * if they are added manually - * @param escapeStxEtx STX and ETX occurrences in the given source stream will be escaped and - * encoded by adding 0x40 - * @param escapeCr CR characters in the given source stream will be escaped and encoded - * by adding 0x40 * @return */ ReturnValue_t encode(const uint8_t *sourceStream, size_t sourceLen, @@ -80,10 +81,6 @@ public: * @param destStream * @param maxDestStreamlen * @param decodedLen - * @param escapeStxEtx STX and ETX characters were escaped in the encoded stream and need to - * be decoded back as well - * @param escapeCr CR characters were escaped in the encoded stream and need to - * be decoded back as well by subtracting 0x40 * @return */ ReturnValue_t decode(const uint8_t *sourceStream, From 654b23869f607c6c89b78dc3bebdab8a2b7be291 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 17 Aug 2021 16:00:39 +0200 Subject: [PATCH 34/38] several imporovements --- src/fsfw/globalfunctions/DleEncoder.cpp | 24 ++++++++------ src/fsfw/globalfunctions/DleEncoder.h | 43 +++++++++++-------------- 2 files changed, 34 insertions(+), 33 deletions(-) diff --git a/src/fsfw/globalfunctions/DleEncoder.cpp b/src/fsfw/globalfunctions/DleEncoder.cpp index 81131910..6ad5e5fa 100644 --- a/src/fsfw/globalfunctions/DleEncoder.cpp +++ b/src/fsfw/globalfunctions/DleEncoder.cpp @@ -83,7 +83,7 @@ ReturnValue_t DleEncoder::encode(const uint8_t* sourceStream, ReturnValue_t DleEncoder::decode(const uint8_t *sourceStream, size_t sourceStreamLen, size_t *readLen, uint8_t *destStream, size_t maxDestStreamlen, size_t *decodedLen) { - size_t encodedIndex = 0, decodedIndex = 0; + size_t encodedIndex = 0; if(not escapeStxEtx) { if (*sourceStream != DLE_CHAR) { return DECODING_ERROR; @@ -94,21 +94,22 @@ ReturnValue_t DleEncoder::decode(const uint8_t *sourceStream, return DECODING_ERROR; } - ++encodedIndex; - if(escapeStxEtx) { - return decodeStreamEscaped(encodedIndex, decodedIndex, sourceStream, sourceStreamLen, + return decodeStreamEscaped(sourceStream, sourceStreamLen, readLen, destStream, maxDestStreamlen, decodedLen); } else { - return decodeStreamNonEscaped(encodedIndex, decodedIndex, sourceStream, sourceStreamLen, + return decodeStreamNonEscaped(sourceStream, sourceStreamLen, readLen, destStream, maxDestStreamlen, decodedLen); } } -ReturnValue_t DleEncoder::decodeStreamEscaped(size_t encodedIndex, size_t decodedIndex, - const uint8_t *sourceStream, size_t sourceStreamLen, size_t *readLen, uint8_t *destStream, +ReturnValue_t DleEncoder::decodeStreamEscaped(const uint8_t *sourceStream, size_t sourceStreamLen, + size_t *readLen, uint8_t *destStream, size_t maxDestStreamlen, size_t *decodedLen) { + // Skip start marker, was already checked + size_t encodedIndex = 1; + size_t decodedIndex = 0; uint8_t nextByte; while ((encodedIndex < sourceStreamLen) && (decodedIndex < maxDestStreamlen) && (sourceStream[encodedIndex] != ETX_CHAR) @@ -158,9 +159,12 @@ ReturnValue_t DleEncoder::decodeStreamEscaped(size_t encodedIndex, size_t decode } } -ReturnValue_t DleEncoder::decodeStreamNonEscaped(size_t encodedIndex, size_t decodedIndex, - const uint8_t *sourceStream, size_t sourceStreamLen, size_t *readLen, uint8_t *destStream, +ReturnValue_t DleEncoder::decodeStreamNonEscaped(const uint8_t *sourceStream, + size_t sourceStreamLen, size_t *readLen, uint8_t *destStream, size_t maxDestStreamlen, size_t *decodedLen) { + // Skip start marker, was already checked + size_t encodedIndex = 2; + size_t decodedIndex = 0; uint8_t nextByte; while ((encodedIndex < sourceStreamLen) && (decodedIndex < maxDestStreamlen)) { if (sourceStream[encodedIndex] == DLE_CHAR) { @@ -177,6 +181,8 @@ ReturnValue_t DleEncoder::decodeStreamNonEscaped(size_t encodedIndex, size_t dec } else if(nextByte == ETX_CHAR) { // End of stream reached + *readLen = encodedIndex + 2; + *decodedLen = decodedIndex; return RETURN_OK; } } diff --git a/src/fsfw/globalfunctions/DleEncoder.h b/src/fsfw/globalfunctions/DleEncoder.h index 47bb2a69..cc7dbc22 100644 --- a/src/fsfw/globalfunctions/DleEncoder.h +++ b/src/fsfw/globalfunctions/DleEncoder.h @@ -12,24 +12,29 @@ * https://en.wikipedia.org/wiki/C0_and_C1_control_codes * * This encoder can be used to achieve a basic transport layer when using - * char based transmission systems. - * The passed source stream is converted into a encoded stream by adding - * a STX marker at the start of the stream and an ETX marker at the end of - * the stream. Any STX, ETX, DLE and CR occurrences in the source stream can be - * escaped by a DLE character. The encoder also replaces escaped control chars - * by another char, so STX, ETX and CR should not appear anywhere in the actual - * encoded data stream. + * char based transmission systems. There are two implemented variants: * - * When using a strictly char based reception of packets encoded with DLE, + * 1. Escaped variant + * + * The encoded stream starts with a STX marker and ends with an ETX marker. + * STX and ETX occurrences in the stream are escaped and internally encoded as well so the + * receiver side can simply check for STX and ETX markers as frame delimiters. When using a + * strictly char based reception of packets encoded with DLE, * STX can be used to notify a reader that actual data will start to arrive * while ETX can be used to notify the reader that the data has ended. + * + * 2. Non-escaped variant + * + * The encoded stream starts with DLE STX and ends with DLE ETX. All DLE occurrences in the stream + * are escaped with DLE. If the received detects a DLE char, it needs to read the next char + * and to determine whether a start (STX) or end (ETX) of a frame has been detected. */ class DleEncoder: public HasReturnvaluesIF { public: /** * Create an encoder instance with the given configuration. - * @param escapeStxEtx - * @param escapeCr + * @param escapeStxEtx Determines whether the algorithm works in escaped or non-escaped mode + * @param escapeCr In escaped mode, escape all CR occurrences as well */ DleEncoder(bool escapeStxEtx = true, bool escapeCr = false); virtual ~DleEncoder(); @@ -62,10 +67,6 @@ public: * @param encodedLen * @param addStxEtx Adding STX start marker and ETX end marker can be omitted, * if they are added manually - * @param escapeStxEtx STX and ETX occurrences in the given source stream will be escaped and - * encoded by adding 0x40 - * @param escapeCr CR characters in the given source stream will be escaped and encoded - * by adding 0x40 * @return */ ReturnValue_t encode(const uint8_t *sourceStream, size_t sourceLen, @@ -80,23 +81,17 @@ public: * @param destStream * @param maxDestStreamlen * @param decodedLen - * @param escapeStxEtx STX and ETX characters were escaped in the encoded stream and need to - * be decoded back as well - * @param escapeCr CR characters were escaped in the encoded stream and need to - * be decoded back as well by subtracting 0x40 * @return */ ReturnValue_t decode(const uint8_t *sourceStream, size_t sourceStreamLen, size_t *readLen, uint8_t *destStream, size_t maxDestStreamlen, size_t *decodedLen); - ReturnValue_t decodeStreamEscaped(size_t encodedIndex, size_t decodedIndex, - const uint8_t *sourceStream, size_t sourceStreamLen, size_t *readLen, - uint8_t *destStream, size_t maxDestStreamlen, size_t *decodedLen); + ReturnValue_t decodeStreamEscaped(const uint8_t *sourceStream, size_t sourceStreamLen, + size_t *readLen, uint8_t *destStream, size_t maxDestStreamlen, size_t *decodedLen); - ReturnValue_t decodeStreamNonEscaped(size_t encodedIndex, size_t decodedIndex, - const uint8_t *sourceStream, size_t sourceStreamLen, size_t *readLen, - uint8_t *destStream, size_t maxDestStreamlen, size_t *decodedLen); + ReturnValue_t decodeStreamNonEscaped(const uint8_t *sourceStream, size_t sourceStreamLen, + size_t *readLen, uint8_t *destStream, size_t maxDestStreamlen, size_t *decodedLen); private: From 8780c5ddcdb055052ab27ddae55c498d59455d24 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 17 Aug 2021 16:02:54 +0200 Subject: [PATCH 35/38] comment typos --- src/fsfw/globalfunctions/DleEncoder.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fsfw/globalfunctions/DleEncoder.h b/src/fsfw/globalfunctions/DleEncoder.h index cc7dbc22..cd2164f8 100644 --- a/src/fsfw/globalfunctions/DleEncoder.h +++ b/src/fsfw/globalfunctions/DleEncoder.h @@ -26,8 +26,8 @@ * 2. Non-escaped variant * * The encoded stream starts with DLE STX and ends with DLE ETX. All DLE occurrences in the stream - * are escaped with DLE. If the received detects a DLE char, it needs to read the next char - * and to determine whether a start (STX) or end (ETX) of a frame has been detected. + * are escaped with DLE. If the receiver detects a DLE char, it needs to read the next char + * to determine whether a start (STX) or end (ETX) of a frame has been detected. */ class DleEncoder: public HasReturnvaluesIF { public: From 94c2e703e03425ba89737d8c2feeb59b7bf681f5 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 18 Aug 2021 13:17:48 +0200 Subject: [PATCH 36/38] made two functions private and removed unnecessary if check --- src/fsfw/globalfunctions/DleEncoder.cpp | 19 +++++++------------ src/fsfw/globalfunctions/DleEncoder.h | 4 ++-- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/fsfw/globalfunctions/DleEncoder.cpp b/src/fsfw/globalfunctions/DleEncoder.cpp index 6ad5e5fa..e30eee22 100644 --- a/src/fsfw/globalfunctions/DleEncoder.cpp +++ b/src/fsfw/globalfunctions/DleEncoder.cpp @@ -122,18 +122,13 @@ ReturnValue_t DleEncoder::decodeStreamEscaped(const uint8_t *sourceStream, size_ destStream[decodedIndex] = nextByte; } else { - if(this->escapeStxEtx) { - /* The next byte is a STX, DTX or 0x0D character which - * was escaped by a DLE character. The actual byte was - * also encoded by adding + 0x40 to prevent having control chars, - * in the stream at all, so we convert it back. */ - if ((nextByte == STX_CHAR + 0x40 or nextByte == ETX_CHAR + 0x40) or - (this->escapeCr and nextByte == CARRIAGE_RETURN + 0x40)) { - destStream[decodedIndex] = nextByte - 0x40; - } - else { - return DECODING_ERROR; - } + /* The next byte is a STX, DTX or 0x0D character which + * was escaped by a DLE character. The actual byte was + * also encoded by adding + 0x40 to prevent having control chars, + * in the stream at all, so we convert it back. */ + if ((nextByte == STX_CHAR + 0x40 or nextByte == ETX_CHAR + 0x40) or + (this->escapeCr and nextByte == CARRIAGE_RETURN + 0x40)) { + destStream[decodedIndex] = nextByte - 0x40; } else { return DECODING_ERROR; diff --git a/src/fsfw/globalfunctions/DleEncoder.h b/src/fsfw/globalfunctions/DleEncoder.h index cd2164f8..292e00f8 100644 --- a/src/fsfw/globalfunctions/DleEncoder.h +++ b/src/fsfw/globalfunctions/DleEncoder.h @@ -87,14 +87,14 @@ public: size_t sourceStreamLen, size_t *readLen, uint8_t *destStream, size_t maxDestStreamlen, size_t *decodedLen); +private: + ReturnValue_t decodeStreamEscaped(const uint8_t *sourceStream, size_t sourceStreamLen, size_t *readLen, uint8_t *destStream, size_t maxDestStreamlen, size_t *decodedLen); ReturnValue_t decodeStreamNonEscaped(const uint8_t *sourceStream, size_t sourceStreamLen, size_t *readLen, uint8_t *destStream, size_t maxDestStreamlen, size_t *decodedLen); -private: - bool escapeStxEtx; bool escapeCr; }; From 026f7f00deeff546a73d57f5570448d176c15615 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 18 Aug 2021 13:33:00 +0200 Subject: [PATCH 37/38] separated encoder functions as well --- src/fsfw/globalfunctions/DleEncoder.cpp | 179 ++++++++++++++++-------- src/fsfw/globalfunctions/DleEncoder.h | 8 ++ 2 files changed, 125 insertions(+), 62 deletions(-) diff --git a/src/fsfw/globalfunctions/DleEncoder.cpp b/src/fsfw/globalfunctions/DleEncoder.cpp index e30eee22..a043cbf7 100644 --- a/src/fsfw/globalfunctions/DleEncoder.cpp +++ b/src/fsfw/globalfunctions/DleEncoder.cpp @@ -8,76 +8,131 @@ DleEncoder::~DleEncoder() {} ReturnValue_t DleEncoder::encode(const uint8_t* sourceStream, size_t sourceLen, uint8_t* destStream, size_t maxDestLen, size_t* encodedLen, bool addStxEtx) { - if (maxDestLen < 2) { - return STREAM_TOO_SHORT; - } - size_t encodedIndex = 0, sourceIndex = 0; - uint8_t nextByte; + size_t minAllowedLen = 0; + if(escapeStxEtx) { + minAllowedLen = 2; + + } + else { + minAllowedLen = 1; + + } + if(maxDestLen < minAllowedLen) { + return STREAM_TOO_SHORT; + } if (addStxEtx) { if(not escapeStxEtx) { destStream[0] = DLE_CHAR; - ++encodedIndex; } destStream[0] = STX_CHAR; - ++encodedIndex; } - while (encodedIndex < maxDestLen and sourceIndex < sourceLen) { - nextByte = sourceStream[sourceIndex]; - // STX, ETX and CR characters in the stream need to be escaped with DLE - if ((nextByte == STX_CHAR or nextByte == ETX_CHAR) or - (this->escapeCr and nextByte == CARRIAGE_RETURN)) { - if(this->escapeStxEtx) { - if (encodedIndex + 1 >= maxDestLen) { - return STREAM_TOO_SHORT; - } - else { - destStream[encodedIndex] = DLE_CHAR; - ++encodedIndex; - /* Escaped byte will be actual byte + 0x40. This prevents - * STX, ETX, and carriage return characters from appearing - * in the encoded data stream at all, so when polling an - * encoded stream, the transmission can be stopped at ETX. - * 0x40 was chosen at random with special requirements: - * - Prevent going from one control char to another - * - Prevent overflow for common characters */ - destStream[encodedIndex] = nextByte + 0x40; - } - } - } - // DLE characters are simply escaped with DLE. - else if (nextByte == DLE_CHAR) { - if (encodedIndex + 1 >= maxDestLen) { - return STREAM_TOO_SHORT; - } - else { - destStream[encodedIndex] = DLE_CHAR; - ++encodedIndex; - destStream[encodedIndex] = DLE_CHAR; - } - } - else { - destStream[encodedIndex] = nextByte; - } - ++encodedIndex; - ++sourceIndex; - } + if(escapeStxEtx) { + return encodeStreamEscaped(sourceStream, sourceLen, + destStream, maxDestLen, encodedLen, addStxEtx); + } + else { + return encodeStreamNonEscaped(sourceStream, sourceLen, + destStream, maxDestLen, encodedLen, addStxEtx); + } - if (sourceIndex == sourceLen and encodedIndex < maxDestLen) { - if (addStxEtx) { - if(not escapeStxEtx) { - destStream[encodedIndex] = DLE_CHAR; - ++encodedIndex; - } - destStream[encodedIndex] = ETX_CHAR; - ++encodedIndex; - } - *encodedLen = encodedIndex; - return RETURN_OK; - } - else { - return STREAM_TOO_SHORT; - } +} + +ReturnValue_t DleEncoder::encodeStreamEscaped(const uint8_t *sourceStream, size_t sourceLen, + uint8_t *destStream, size_t maxDestLen, size_t *encodedLen, + bool addStxEtx) { + size_t encodedIndex = 2; + size_t sourceIndex = 0; + uint8_t nextByte = 0; + while (encodedIndex < maxDestLen and sourceIndex < sourceLen) { + nextByte = sourceStream[sourceIndex]; + // STX, ETX and CR characters in the stream need to be escaped with DLE + if ((nextByte == STX_CHAR or nextByte == ETX_CHAR) or + (this->escapeCr and nextByte == CARRIAGE_RETURN)) { + if (encodedIndex + 1 >= maxDestLen) { + return STREAM_TOO_SHORT; + } + else { + destStream[encodedIndex] = DLE_CHAR; + ++encodedIndex; + /* Escaped byte will be actual byte + 0x40. This prevents + * STX, ETX, and carriage return characters from appearing + * in the encoded data stream at all, so when polling an + * encoded stream, the transmission can be stopped at ETX. + * 0x40 was chosen at random with special requirements: + * - Prevent going from one control char to another + * - Prevent overflow for common characters */ + destStream[encodedIndex] = nextByte + 0x40; + } + } + // DLE characters are simply escaped with DLE. + else if (nextByte == DLE_CHAR) { + if (encodedIndex + 1 >= maxDestLen) { + return STREAM_TOO_SHORT; + } + else { + destStream[encodedIndex] = DLE_CHAR; + ++encodedIndex; + destStream[encodedIndex] = DLE_CHAR; + } + } + else { + destStream[encodedIndex] = nextByte; + } + ++encodedIndex; + ++sourceIndex; + } + + if (sourceIndex == sourceLen and encodedIndex < maxDestLen) { + if (addStxEtx) { + destStream[encodedIndex] = ETX_CHAR; + ++encodedIndex; + } + *encodedLen = encodedIndex; + return RETURN_OK; + } + else { + return STREAM_TOO_SHORT; + } +} + +ReturnValue_t DleEncoder::encodeStreamNonEscaped(const uint8_t *sourceStream, size_t sourceLen, + uint8_t *destStream, size_t maxDestLen, size_t *encodedLen, + bool addStxEtx) { + size_t encodedIndex = 1; + size_t sourceIndex = 0; + uint8_t nextByte = 0; + while (encodedIndex < maxDestLen and sourceIndex < sourceLen) { + nextByte = sourceStream[sourceIndex]; + // DLE characters are simply escaped with DLE. + if (nextByte == DLE_CHAR) { + if (encodedIndex + 1 >= maxDestLen) { + return STREAM_TOO_SHORT; + } + else { + destStream[encodedIndex] = DLE_CHAR; + ++encodedIndex; + destStream[encodedIndex] = DLE_CHAR; + } + } + else { + destStream[encodedIndex] = nextByte; + } + ++encodedIndex; + ++sourceIndex; + } + + if (sourceIndex == sourceLen and encodedIndex < maxDestLen) { + if (addStxEtx) { + destStream[encodedIndex] = ETX_CHAR; + ++encodedIndex; + } + *encodedLen = encodedIndex; + return RETURN_OK; + } + else { + return STREAM_TOO_SHORT; + } } ReturnValue_t DleEncoder::decode(const uint8_t *sourceStream, diff --git a/src/fsfw/globalfunctions/DleEncoder.h b/src/fsfw/globalfunctions/DleEncoder.h index 292e00f8..dc178a0e 100644 --- a/src/fsfw/globalfunctions/DleEncoder.h +++ b/src/fsfw/globalfunctions/DleEncoder.h @@ -89,6 +89,14 @@ public: private: + ReturnValue_t encodeStreamEscaped(const uint8_t *sourceStream, size_t sourceLen, + uint8_t *destStream, size_t maxDestLen, size_t *encodedLen, + bool addStxEtx = true); + + ReturnValue_t encodeStreamNonEscaped(const uint8_t *sourceStream, size_t sourceLen, + uint8_t *destStream, size_t maxDestLen, size_t *encodedLen, + bool addStxEtx = true); + ReturnValue_t decodeStreamEscaped(const uint8_t *sourceStream, size_t sourceStreamLen, size_t *readLen, uint8_t *destStream, size_t maxDestStreamlen, size_t *decodedLen); From 57b13731e0cb4c1d3666e90f855017f2fefbfe34 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 18 Aug 2021 18:03:38 +0200 Subject: [PATCH 38/38] added first DLE unit tests --- src/fsfw/globalfunctions/DleEncoder.cpp | 2 +- .../unit/globalfunctions/CMakeLists.txt | 1 + .../unit/globalfunctions/testDleEncoder.cpp | 62 +++++++++++++++++++ 3 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 tests/src/fsfw_tests/unit/globalfunctions/testDleEncoder.cpp diff --git a/src/fsfw/globalfunctions/DleEncoder.cpp b/src/fsfw/globalfunctions/DleEncoder.cpp index a043cbf7..ae3f9f9f 100644 --- a/src/fsfw/globalfunctions/DleEncoder.cpp +++ b/src/fsfw/globalfunctions/DleEncoder.cpp @@ -41,7 +41,7 @@ ReturnValue_t DleEncoder::encode(const uint8_t* sourceStream, ReturnValue_t DleEncoder::encodeStreamEscaped(const uint8_t *sourceStream, size_t sourceLen, uint8_t *destStream, size_t maxDestLen, size_t *encodedLen, bool addStxEtx) { - size_t encodedIndex = 2; + size_t encodedIndex = 1; size_t sourceIndex = 0; uint8_t nextByte = 0; while (encodedIndex < maxDestLen and sourceIndex < sourceLen) { diff --git a/tests/src/fsfw_tests/unit/globalfunctions/CMakeLists.txt b/tests/src/fsfw_tests/unit/globalfunctions/CMakeLists.txt index 8e57e01b..617c7f5a 100644 --- a/tests/src/fsfw_tests/unit/globalfunctions/CMakeLists.txt +++ b/tests/src/fsfw_tests/unit/globalfunctions/CMakeLists.txt @@ -1,2 +1,3 @@ target_sources(${TARGET_NAME} PRIVATE + testDleEncoder.cpp ) diff --git a/tests/src/fsfw_tests/unit/globalfunctions/testDleEncoder.cpp b/tests/src/fsfw_tests/unit/globalfunctions/testDleEncoder.cpp new file mode 100644 index 00000000..b484e7cb --- /dev/null +++ b/tests/src/fsfw_tests/unit/globalfunctions/testDleEncoder.cpp @@ -0,0 +1,62 @@ +#include "fsfw/globalfunctions/DleEncoder.h" +#include "fsfw_tests/unit/CatchDefinitions.h" +#include "catch2/catch_test_macros.hpp" + +#include + +const std::array TEST_ARRAY_0 = { 0 }; +const std::array TEST_ARRAY_1 = { 0, DleEncoder::DLE_CHAR, 5}; +const std::array TEST_ARRAY_2 = { 0, DleEncoder::STX_CHAR, 5}; +const std::array TEST_ARRAY_3 = { 0, DleEncoder::CARRIAGE_RETURN, DleEncoder::ETX_CHAR}; + +TEST_CASE("DleEncoder" , "[DleEncoder]") { + + DleEncoder dleEncoder; + std::array buffer; + SECTION("Encoding") { + size_t encodedLen = 0; + ReturnValue_t result = dleEncoder.encode(TEST_ARRAY_0.data(), TEST_ARRAY_0.size(), + buffer.data(), buffer.size(), &encodedLen); + REQUIRE(result == retval::CATCH_OK); + std::vector expected = {DleEncoder::STX_CHAR, 0, 0, 0, 0, 0, + DleEncoder::ETX_CHAR}; + for(size_t idx = 0; idx < expected.size(); idx++) { + REQUIRE(buffer[idx] == expected[idx]); + } + REQUIRE(encodedLen == 7); + + result = dleEncoder.encode(TEST_ARRAY_1.data(), TEST_ARRAY_1.size(), + buffer.data(), buffer.size(), &encodedLen); + REQUIRE(result == retval::CATCH_OK); + expected = std::vector{DleEncoder::STX_CHAR, 0, DleEncoder::DLE_CHAR, + DleEncoder::DLE_CHAR, 5, DleEncoder::ETX_CHAR}; + for(size_t idx = 0; idx < expected.size(); idx++) { + REQUIRE(buffer[idx] == expected[idx]); + } + REQUIRE(encodedLen == expected.size()); + + result = dleEncoder.encode(TEST_ARRAY_2.data(), TEST_ARRAY_2.size(), + buffer.data(), buffer.size(), &encodedLen); + REQUIRE(result == retval::CATCH_OK); + expected = std::vector{DleEncoder::STX_CHAR, 0, DleEncoder::DLE_CHAR, + DleEncoder::STX_CHAR + 0x40, 5, DleEncoder::ETX_CHAR}; + for(size_t idx = 0; idx < expected.size(); idx++) { + REQUIRE(buffer[idx] == expected[idx]); + } + REQUIRE(encodedLen == expected.size()); + + result = dleEncoder.encode(TEST_ARRAY_3.data(), TEST_ARRAY_3.size(), + buffer.data(), buffer.size(), &encodedLen); + REQUIRE(result == retval::CATCH_OK); + expected = std::vector{DleEncoder::STX_CHAR, 0, DleEncoder::CARRIAGE_RETURN, + DleEncoder::DLE_CHAR, DleEncoder::ETX_CHAR + 0x40, DleEncoder::ETX_CHAR}; + for(size_t idx = 0; idx < expected.size(); idx++) { + REQUIRE(buffer[idx] == expected[idx]); + } + REQUIRE(encodedLen == expected.size()); + } + + SECTION("Decoding") { + + } +}