From 20adc1c9813697744a37c375027114370131695c Mon Sep 17 00:00:00 2001 From: "Jakob.Meier" <–meierj@irs.uni-stuttgart.de> Date: Sat, 7 Aug 2021 14:28:12 +0200 Subject: [PATCH 01/27] queue nullptr check in action helper --- action/ActionHelper.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/action/ActionHelper.cpp b/action/ActionHelper.cpp index 73007ea3..aaa19ac4 100644 --- a/action/ActionHelper.cpp +++ b/action/ActionHelper.cpp @@ -33,6 +33,17 @@ ReturnValue_t ActionHelper::initialize(MessageQueueIF* queueToUse_) { setQueueToUse(queueToUse_); } + if(queueToUse == nullptr) { +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "ActionHelper::initialize: No queue set" << std::endl; +#else + sif::printWarning("ActionHelper::initialize: No queue set\n"); +#endif +#endif /* FSFW_VERBOSE_LEVEL >= 1 */ + return HasReturnvaluesIF::RETURN_FAILED; + } + return HasReturnvaluesIF::RETURN_OK; } From ccaa0aa24f75ff26b59ae75f4a57d476aaa22d18 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 9 Aug 2021 16:57:24 +0200 Subject: [PATCH 02/27] Cleaning up TCP and UDP code Same port number used as before, but some inconsistencies fixed --- src/fsfw/osal/common/TcpTmTcBridge.cpp | 2 +- src/fsfw/osal/common/TcpTmTcBridge.h | 2 +- src/fsfw/osal/common/TcpTmTcServer.cpp | 4 ++-- src/fsfw/osal/common/TcpTmTcServer.h | 3 +-- src/fsfw/osal/common/UdpTmTcBridge.cpp | 4 ++-- src/fsfw/osal/common/UdpTmTcBridge.h | 2 +- 6 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/fsfw/osal/common/TcpTmTcBridge.cpp b/src/fsfw/osal/common/TcpTmTcBridge.cpp index 24f1a281..f873d5c7 100644 --- a/src/fsfw/osal/common/TcpTmTcBridge.cpp +++ b/src/fsfw/osal/common/TcpTmTcBridge.cpp @@ -17,7 +17,7 @@ #endif -const std::string TcpTmTcBridge::DEFAULT_UDP_SERVER_PORT = tcpip::DEFAULT_SERVER_PORT; +const std::string TcpTmTcBridge::DEFAULT_SERVER_PORT = tcpip::DEFAULT_SERVER_PORT; TcpTmTcBridge::TcpTmTcBridge(object_id_t objectId, object_id_t tcDestination, object_id_t tmStoreId, object_id_t tcStoreId): diff --git a/src/fsfw/osal/common/TcpTmTcBridge.h b/src/fsfw/osal/common/TcpTmTcBridge.h index 6cfacb9f..be0d0d52 100644 --- a/src/fsfw/osal/common/TcpTmTcBridge.h +++ b/src/fsfw/osal/common/TcpTmTcBridge.h @@ -30,7 +30,7 @@ class TcpTmTcBridge: friend class TcpTmTcServer; public: /* The ports chosen here should not be used by any other process. */ - static const std::string DEFAULT_UDP_SERVER_PORT; + static const std::string DEFAULT_SERVER_PORT; /** * Constructor diff --git a/src/fsfw/osal/common/TcpTmTcServer.cpp b/src/fsfw/osal/common/TcpTmTcServer.cpp index f94449bb..057cd538 100644 --- a/src/fsfw/osal/common/TcpTmTcServer.cpp +++ b/src/fsfw/osal/common/TcpTmTcServer.cpp @@ -22,14 +22,14 @@ #define FSFW_TCP_RECV_WIRETAPPING_ENABLED 0 #endif -const std::string TcpTmTcServer::DEFAULT_TCP_SERVER_PORT = "7303"; +const std::string TcpTmTcServer::DEFAULT_SERVER_PORT = TcpTmTcBridge::DEFAULT_SERVER_PORT; TcpTmTcServer::TcpTmTcServer(object_id_t objectId, object_id_t tmtcTcpBridge, size_t receptionBufferSize, std::string customTcpServerPort): SystemObject(objectId), tmtcBridgeId(tmtcTcpBridge), tcpPort(customTcpServerPort), receptionBuffer(receptionBufferSize) { if(tcpPort == "") { - tcpPort = DEFAULT_TCP_SERVER_PORT; + tcpPort = DEFAULT_SERVER_PORT; } } diff --git a/src/fsfw/osal/common/TcpTmTcServer.h b/src/fsfw/osal/common/TcpTmTcServer.h index f7c36d69..6588f111 100644 --- a/src/fsfw/osal/common/TcpTmTcServer.h +++ b/src/fsfw/osal/common/TcpTmTcServer.h @@ -41,8 +41,7 @@ class TcpTmTcServer: public TcpIpBase, public ExecutableObjectIF { public: - /* The ports chosen here should not be used by any other process. */ - static const std::string DEFAULT_TCP_SERVER_PORT; + static const std::string DEFAULT_SERVER_PORT; static constexpr size_t ETHERNET_MTU_SIZE = 1500; diff --git a/src/fsfw/osal/common/UdpTmTcBridge.cpp b/src/fsfw/osal/common/UdpTmTcBridge.cpp index 7015cf4a..db2546cd 100644 --- a/src/fsfw/osal/common/UdpTmTcBridge.cpp +++ b/src/fsfw/osal/common/UdpTmTcBridge.cpp @@ -17,13 +17,13 @@ #define FSFW_UDP_SEND_WIRETAPPING_ENABLED 0 #endif -const std::string UdpTmTcBridge::DEFAULT_UDP_SERVER_PORT = tcpip::DEFAULT_SERVER_PORT; +const std::string UdpTmTcBridge::DEFAULT_SERVER_PORT = tcpip::DEFAULT_SERVER_PORT; UdpTmTcBridge::UdpTmTcBridge(object_id_t objectId, object_id_t tcDestination, std::string udpServerPort, object_id_t tmStoreId, object_id_t tcStoreId): TmTcBridge(objectId, tcDestination, tmStoreId, tcStoreId) { if(udpServerPort == "") { - this->udpServerPort = DEFAULT_UDP_SERVER_PORT; + this->udpServerPort = DEFAULT_SERVER_PORT; } else { this->udpServerPort = udpServerPort; diff --git a/src/fsfw/osal/common/UdpTmTcBridge.h b/src/fsfw/osal/common/UdpTmTcBridge.h index 7a346de5..93c7511e 100644 --- a/src/fsfw/osal/common/UdpTmTcBridge.h +++ b/src/fsfw/osal/common/UdpTmTcBridge.h @@ -28,7 +28,7 @@ class UdpTmTcBridge: friend class UdpTcPollingTask; public: /* The ports chosen here should not be used by any other process. */ - static const std::string DEFAULT_UDP_SERVER_PORT; + static const std::string DEFAULT_SERVER_PORT; UdpTmTcBridge(object_id_t objectId, object_id_t tcDestination, std::string udpServerPort = "", object_id_t tmStoreId = objects::TM_STORE, From 14a30f30db15805cca98c984d238a3bccd32882b Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 9 Aug 2021 18:12:25 +0200 Subject: [PATCH 03/27] More improvements for TCP/UDP port definition --- src/fsfw/osal/common/TcpTmTcBridge.cpp | 3 --- src/fsfw/osal/common/TcpTmTcBridge.h | 4 +--- src/fsfw/osal/common/TcpTmTcServer.cpp | 6 +++++- src/fsfw/osal/common/TcpTmTcServer.h | 19 +++++++++++-------- src/fsfw/osal/common/UdpTmTcBridge.h | 4 ++-- src/fsfw/osal/common/tcpipCommon.h | 4 ++-- 6 files changed, 21 insertions(+), 19 deletions(-) diff --git a/src/fsfw/osal/common/TcpTmTcBridge.cpp b/src/fsfw/osal/common/TcpTmTcBridge.cpp index f873d5c7..3cd03c36 100644 --- a/src/fsfw/osal/common/TcpTmTcBridge.cpp +++ b/src/fsfw/osal/common/TcpTmTcBridge.cpp @@ -1,6 +1,5 @@ #include "fsfw/platform.h" #include "fsfw/osal/common/TcpTmTcBridge.h" -#include "fsfw/osal/common/tcpipHelpers.h" #include "fsfw/serviceinterface/ServiceInterface.h" #include "fsfw/ipc/MutexGuard.h" @@ -17,8 +16,6 @@ #endif -const std::string TcpTmTcBridge::DEFAULT_SERVER_PORT = tcpip::DEFAULT_SERVER_PORT; - TcpTmTcBridge::TcpTmTcBridge(object_id_t objectId, object_id_t tcDestination, object_id_t tmStoreId, object_id_t tcStoreId): TmTcBridge(objectId, tcDestination, tmStoreId, tcStoreId) { diff --git a/src/fsfw/osal/common/TcpTmTcBridge.h b/src/fsfw/osal/common/TcpTmTcBridge.h index be0d0d52..dc46f1f0 100644 --- a/src/fsfw/osal/common/TcpTmTcBridge.h +++ b/src/fsfw/osal/common/TcpTmTcBridge.h @@ -2,7 +2,7 @@ #define FSFW_OSAL_COMMON_TCPTMTCBRIDGE_H_ #include "TcpIpBase.h" -#include "../../tmtcservices/TmTcBridge.h" +#include "fsfw/tmtcservices/TmTcBridge.h" #ifdef _WIN32 @@ -29,8 +29,6 @@ class TcpTmTcBridge: public TmTcBridge { friend class TcpTmTcServer; public: - /* The ports chosen here should not be used by any other process. */ - static const std::string DEFAULT_SERVER_PORT; /** * Constructor diff --git a/src/fsfw/osal/common/TcpTmTcServer.cpp b/src/fsfw/osal/common/TcpTmTcServer.cpp index 057cd538..11ab71af 100644 --- a/src/fsfw/osal/common/TcpTmTcServer.cpp +++ b/src/fsfw/osal/common/TcpTmTcServer.cpp @@ -22,7 +22,7 @@ #define FSFW_TCP_RECV_WIRETAPPING_ENABLED 0 #endif -const std::string TcpTmTcServer::DEFAULT_SERVER_PORT = TcpTmTcBridge::DEFAULT_SERVER_PORT; +const std::string TcpTmTcServer::DEFAULT_SERVER_PORT = tcpip::DEFAULT_SERVER_PORT; TcpTmTcServer::TcpTmTcServer(object_id_t objectId, object_id_t tmtcTcpBridge, size_t receptionBufferSize, std::string customTcpServerPort): @@ -200,6 +200,10 @@ void TcpTmTcServer::setTcpBacklog(uint8_t tcpBacklog) { this->tcpBacklog = tcpBacklog; } +std::string TcpTmTcServer::getTcpPort() const { + return tcpPort; +} + ReturnValue_t TcpTmTcServer::handleTmSending(socket_t connSocket) { // Access to the FIFO is mutex protected because it is filled by the bridge MutexGuard(tmtcBridge->mutex, tmtcBridge->timeoutType, tmtcBridge->mutexTimeoutMs); diff --git a/src/fsfw/osal/common/TcpTmTcServer.h b/src/fsfw/osal/common/TcpTmTcServer.h index 6588f111..c6916080 100644 --- a/src/fsfw/osal/common/TcpTmTcServer.h +++ b/src/fsfw/osal/common/TcpTmTcServer.h @@ -3,13 +3,14 @@ #include "TcpIpBase.h" -#include "../../platform.h" -#include "../../ipc/messageQueueDefinitions.h" -#include "../../ipc/MessageQueueIF.h" -#include "../../objectmanager/frameworkObjects.h" -#include "../../objectmanager/SystemObject.h" -#include "../../storagemanager/StorageManagerIF.h" -#include "../../tasks/ExecutableObjectIF.h" +#include "fsfw/platform.h" +#include "fsfw/osal/common/tcpipHelpers.h" +#include "fsfw/ipc/messageQueueDefinitions.h" +#include "fsfw/ipc/MessageQueueIF.h" +#include "fsfw/objectmanager/frameworkObjects.h" +#include "fsfw/objectmanager/SystemObject.h" +#include "fsfw/storagemanager/StorageManagerIF.h" +#include "fsfw/tasks/ExecutableObjectIF.h" #ifdef PLATFORM_UNIX #include @@ -43,7 +44,7 @@ class TcpTmTcServer: public: static const std::string DEFAULT_SERVER_PORT; - static constexpr size_t ETHERNET_MTU_SIZE = 1500; + static constexpr size_t ETHERNET_MTU_SIZE = 1500; /** * TCP Server Constructor @@ -64,6 +65,8 @@ public: ReturnValue_t performOperation(uint8_t opCode) override; ReturnValue_t initializeAfterTaskCreation() override; + std::string getTcpPort() const; + protected: StorageManagerIF* tcStore = nullptr; StorageManagerIF* tmStore = nullptr; diff --git a/src/fsfw/osal/common/UdpTmTcBridge.h b/src/fsfw/osal/common/UdpTmTcBridge.h index 93c7511e..dc695c81 100644 --- a/src/fsfw/osal/common/UdpTmTcBridge.h +++ b/src/fsfw/osal/common/UdpTmTcBridge.h @@ -2,8 +2,8 @@ #define FSFW_OSAL_COMMON_TMTCUDPBRIDGE_H_ #include "TcpIpBase.h" -#include "../../platform.h" -#include "../../tmtcservices/TmTcBridge.h" +#include "fsfw/platform.h" +#include "fsfw/tmtcservices/TmTcBridge.h" #ifdef PLATFORM_WIN #include diff --git a/src/fsfw/osal/common/tcpipCommon.h b/src/fsfw/osal/common/tcpipCommon.h index ce7a90cd..5a04144e 100644 --- a/src/fsfw/osal/common/tcpipCommon.h +++ b/src/fsfw/osal/common/tcpipCommon.h @@ -1,7 +1,7 @@ #ifndef FSFW_OSAL_COMMON_TCPIPCOMMON_H_ #define FSFW_OSAL_COMMON_TCPIPCOMMON_H_ -#include "../../timemanager/clockDefinitions.h" +#include "fsfw/timemanager/clockDefinitions.h" #include #ifdef _WIN32 @@ -13,7 +13,7 @@ namespace tcpip { -const char* const DEFAULT_SERVER_PORT = "7301"; +static constexpr char DEFAULT_SERVER_PORT[] = "7301"; enum class Protocol { UDP, From eecb69d230399b2e05c0729cfad9d8cdf00e25b4 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 9 Aug 2021 18:22:22 +0200 Subject: [PATCH 04/27] getter function for UDP port --- src/fsfw/osal/common/UdpTmTcBridge.cpp | 4 ++++ src/fsfw/osal/common/UdpTmTcBridge.h | 2 ++ 2 files changed, 6 insertions(+) diff --git a/src/fsfw/osal/common/UdpTmTcBridge.cpp b/src/fsfw/osal/common/UdpTmTcBridge.cpp index db2546cd..734a2b15 100644 --- a/src/fsfw/osal/common/UdpTmTcBridge.cpp +++ b/src/fsfw/osal/common/UdpTmTcBridge.cpp @@ -108,6 +108,10 @@ UdpTmTcBridge::~UdpTmTcBridge() { } } +std::string UdpTmTcBridge::getUdpPort() const { + return udpServerPort; +} + ReturnValue_t UdpTmTcBridge::sendTm(const uint8_t *data, size_t dataLen) { int flags = 0; diff --git a/src/fsfw/osal/common/UdpTmTcBridge.h b/src/fsfw/osal/common/UdpTmTcBridge.h index dc695c81..4d634e64 100644 --- a/src/fsfw/osal/common/UdpTmTcBridge.h +++ b/src/fsfw/osal/common/UdpTmTcBridge.h @@ -44,6 +44,8 @@ public: void checkAndSetClientAddress(sockaddr& clientAddress); + std::string getUdpPort() const; + protected: virtual ReturnValue_t sendTm(const uint8_t * data, size_t dataLen) override; From cfb8bc5dfdb146f66187e38eafe9af8b18a0d031 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 16 Aug 2021 11:20:15 +0200 Subject: [PATCH 05/27] fsfw version update --- src/fsfw/FSFWVersion.h | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/fsfw/FSFWVersion.h b/src/fsfw/FSFWVersion.h index df2d49a5..1d0da280 100644 --- a/src/fsfw/FSFWVersion.h +++ b/src/fsfw/FSFWVersion.h @@ -1,12 +1,10 @@ -#ifndef FSFW_DEFAULTCFG_VERSION_H_ -#define FSFW_DEFAULTCFG_VERSION_H_ +#ifndef FSFW_VERSION_H_ +#define FSFW_VERSION_H_ const char* const FSFW_VERSION_NAME = "ASTP"; #define FSFW_VERSION 1 -#define FSFW_SUBVERSION 0 -#define FSFW_REVISION 0 +#define FSFW_SUBVERSION 3 +#define FSFW_REVISION 0 - - -#endif /* FSFW_DEFAULTCFG_VERSION_H_ */ +#endif /* FSFW_VERSION_H_ */ From 6e9a0ddcf46d8988e96a6aa6de97178625462993 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 16 Aug 2021 11:23:44 +0200 Subject: [PATCH 06/27] cmakedefine for OSAL type --- CMakeLists.txt | 37 +++++++++++++++---------------------- src/fsfw/FSFW.h.in | 5 +++++ 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b7865300..9a1f7d1a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,35 +62,28 @@ endif() set(FSFW_OSAL_DEFINITION FSFW_OSAL_HOST) if(FSFW_OSAL MATCHES host) - set(OS_FSFW_NAME "Host") + set(OS_FSFW_NAME "Host") + set(FSFW_OSAL_HOST ON) elseif(FSFW_OSAL MATCHES linux) - set(OS_FSFW_NAME "Linux") - set(FSFW_OSAL_DEFINITION FSFW_OSAL_LINUX) + set(OS_FSFW_NAME "Linux") + set(FSFW_OSAL_LINUX ON) elseif(FSFW_OSAL MATCHES freertos) - set(OS_FSFW_NAME "FreeRTOS") - set(FSFW_OSAL_DEFINITION FSFW_OSAL_FREERTOS) - target_link_libraries(${LIB_FSFW_NAME} PRIVATE + set(OS_FSFW_NAME "FreeRTOS") + set(FSFW_OSAL_FREERTOS ON) + target_link_libraries(${LIB_FSFW_NAME} PRIVATE ${LIB_OS_NAME} - ) + ) elseif(FSFW_OSAL STREQUAL rtems) - set(OS_FSFW_NAME "RTEMS") - set(FSFW_OSAL_DEFINITION FSFW_OSAL_RTEMS) + set(OS_FSFW_NAME "RTEMS") + set(FSFW_OSAL_RTEMS ON) else() - message(WARNING - "Invalid operating system for FSFW specified! Setting to host.." - ) - set(OS_FSFW_NAME "Host") - set(OS_FSFW "host") + message(WARNING + "Invalid operating system for FSFW specified! Setting to host.." + ) + set(OS_FSFW_NAME "Host") + set(OS_FSFW "host") endif() -target_compile_definitions(${LIB_FSFW_NAME} PRIVATE - ${FSFW_OSAL_DEFINITION} -) - -target_compile_definitions(${LIB_FSFW_NAME} INTERFACE - ${FSFW_OSAL_DEFINITION} -) - message(STATUS "Compiling FSFW for the ${OS_FSFW_NAME} operating system.") add_subdirectory(src) diff --git a/src/fsfw/FSFW.h.in b/src/fsfw/FSFW.h.in index 4d4b8aee..f0eb9365 100644 --- a/src/fsfw/FSFW.h.in +++ b/src/fsfw/FSFW.h.in @@ -3,6 +3,11 @@ #include "FSFWConfig.h" +#cmakedefine FSFW_OSAL_RTEMS +#cmakedefine FSFW_OSAL_FREERTOS +#cmakedefine FSFW_OSAL_LINUX +#cmakedefine FSFW_OSAL_HOST + #cmakedefine FSFW_ADD_RMAP #cmakedefine FSFW_ADD_DATALINKLAYER #cmakedefine FSFW_ADD_TMSTORAGE From db3284c2b8cc6492a50476025a93cab509e02d77 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 16 Aug 2021 14:52:11 +0200 Subject: [PATCH 07/27] subversion update --- src/fsfw/FSFWVersion.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fsfw/FSFWVersion.h b/src/fsfw/FSFWVersion.h index 1d0da280..f8e89694 100644 --- a/src/fsfw/FSFWVersion.h +++ b/src/fsfw/FSFWVersion.h @@ -4,7 +4,7 @@ const char* const FSFW_VERSION_NAME = "ASTP"; #define FSFW_VERSION 1 -#define FSFW_SUBVERSION 3 +#define FSFW_SUBVERSION 2 #define FSFW_REVISION 0 #endif /* FSFW_VERSION_H_ */ From fa14ebbe1f0aa5f8888e53d3476b93acf1a82cdb Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 16 Aug 2021 15:19:03 +0200 Subject: [PATCH 08/27] additional check --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9a1f7d1a..4a1ec8c4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,7 +38,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() From 4b72e246c36bab632d9efd92ff1d8e6cd533b6a9 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 17 Aug 2021 15:05:29 +0200 Subject: [PATCH 09/27] 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 ece7dce6f7ee33b04473a41f698ff15414520a02 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 17 Aug 2021 15:13:58 +0200 Subject: [PATCH 10/27] 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 11/27] 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 12/27] 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 654b23869f607c6c89b78dc3bebdab8a2b7be291 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 17 Aug 2021 16:00:39 +0200 Subject: [PATCH 13/27] 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 14/27] 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 3cec9f5f8054e2003c66affc39f45ed73cba2398 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 18 Aug 2021 13:18:42 +0200 Subject: [PATCH 15/27] Made two functions private, small tweak --- 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 5dcf0e44b65f5d986b71881c731207f8bbc47029 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 18 Aug 2021 13:33:31 +0200 Subject: [PATCH 16/27] encoder functions split up --- 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 98e3ed897c9f81837cffa24da41d4cbb50cea72d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 19 Aug 2021 17:17:19 +0200 Subject: [PATCH 17/27] small tweak --- hal/src/fsfw_hal/linux/spi/SpiComIF.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp b/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp index 6697bc92..48bf7449 100644 --- a/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp +++ b/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp @@ -90,7 +90,7 @@ ReturnValue_t SpiComIF::initializeInterface(CookieIF *cookie) { int fileDescriptor = 0; UnixFileGuard fileHelper(spiCookie->getSpiDevice(), &fileDescriptor, O_RDWR, - "SpiComIF::initializeInterface: "); + "SpiComIF::initializeInterface"); if(fileHelper.getOpenResult() != HasReturnvaluesIF::RETURN_OK) { return fileHelper.getOpenResult(); } From dfc44fce071a29ce1de05eaecd76e795b09ea8fc Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 8 Sep 2021 23:33:10 +0200 Subject: [PATCH 18/27] added DLE encoder test files --- .../unit/globalfunctions/CMakeLists.txt | 1 + .../unit/globalfunctions/testDleEncoder.cpp | 69 +++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 tests/src/fsfw_tests/unit/globalfunctions/testDleEncoder.cpp 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..01ac3568 --- /dev/null +++ b/tests/src/fsfw_tests/unit/globalfunctions/testDleEncoder.cpp @@ -0,0 +1,69 @@ +#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()); + + result = dleEncoder.encode(TEST_ARRAY_3.data(), TEST_ARRAY_3.size(), + buffer.data(), 0, &encodedLen); + REQUIRE(result == DleEncoder::STREAM_TOO_SHORT); + result = dleEncoder.encode(TEST_ARRAY_1.data(), TEST_ARRAY_1.size(), + buffer.data(), 4, &encodedLen); + REQUIRE(result == DleEncoder::STREAM_TOO_SHORT); + } + + SECTION("Decoding") { + + } +} From b5063117f62393be273dbbcdf10532055a848ec3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 9 Sep 2021 00:02:17 +0200 Subject: [PATCH 19/27] added check to avoid seg fault --- src/fsfw/globalfunctions/DleEncoder.cpp | 20 +++++++++++--------- tests/src/fsfw_tests/unit/CatchFactory.h | 2 +- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/fsfw/globalfunctions/DleEncoder.cpp b/src/fsfw/globalfunctions/DleEncoder.cpp index a043cbf7..5ab9fae6 100644 --- a/src/fsfw/globalfunctions/DleEncoder.cpp +++ b/src/fsfw/globalfunctions/DleEncoder.cpp @@ -10,12 +10,10 @@ ReturnValue_t DleEncoder::encode(const uint8_t* sourceStream, size_t* encodedLen, bool addStxEtx) { size_t minAllowedLen = 0; if(escapeStxEtx) { - minAllowedLen = 2; - + minAllowedLen = 1; } else { - minAllowedLen = 1; - + minAllowedLen = 2; } if(maxDestLen < minAllowedLen) { return STREAM_TOO_SHORT; @@ -41,7 +39,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) { @@ -99,7 +97,7 @@ ReturnValue_t DleEncoder::encodeStreamEscaped(const uint8_t *sourceStream, size_ 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 encodedIndex = 2; size_t sourceIndex = 0; uint8_t nextByte = 0; while (encodedIndex < maxDestLen and sourceIndex < sourceLen) { @@ -166,10 +164,14 @@ ReturnValue_t DleEncoder::decodeStreamEscaped(const uint8_t *sourceStream, size_ size_t encodedIndex = 1; size_t decodedIndex = 0; uint8_t nextByte; - while ((encodedIndex < sourceStreamLen) && (decodedIndex < maxDestStreamlen) - && (sourceStream[encodedIndex] != ETX_CHAR) - && (sourceStream[encodedIndex] != STX_CHAR)) { + while ((encodedIndex < sourceStreamLen) + and (decodedIndex < maxDestStreamlen) + and (sourceStream[encodedIndex] != ETX_CHAR) + and (sourceStream[encodedIndex] != STX_CHAR)) { if (sourceStream[encodedIndex] == DLE_CHAR) { + if(encodedIndex + 1 >= sourceStreamLen) { + return DECODING_ERROR; + } 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. diff --git a/tests/src/fsfw_tests/unit/CatchFactory.h b/tests/src/fsfw_tests/unit/CatchFactory.h index ae0629e5..38ec46bd 100644 --- a/tests/src/fsfw_tests/unit/CatchFactory.h +++ b/tests/src/fsfw_tests/unit/CatchFactory.h @@ -1,7 +1,7 @@ #ifndef FSFW_CATCHFACTORY_H_ #define FSFW_CATCHFACTORY_H_ -#include "TestConfig.h" +#include "TestsConfig.h" #include "fsfw/objectmanager/SystemObjectIF.h" #include "fsfw/objectmanager/ObjectManager.h" From 35b53e9a1707dd4502f1d58ac912564be23557aa Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 9 Sep 2021 01:06:54 +0200 Subject: [PATCH 20/27] continuing tests --- src/fsfw/globalfunctions/DleEncoder.cpp | 8 +- src/fsfw/globalfunctions/DleEncoder.h | 3 + .../unit/globalfunctions/testDleEncoder.cpp | 120 +++++++++++------- 3 files changed, 84 insertions(+), 47 deletions(-) diff --git a/src/fsfw/globalfunctions/DleEncoder.cpp b/src/fsfw/globalfunctions/DleEncoder.cpp index 5ab9fae6..02e4aba4 100644 --- a/src/fsfw/globalfunctions/DleEncoder.cpp +++ b/src/fsfw/globalfunctions/DleEncoder.cpp @@ -22,7 +22,7 @@ ReturnValue_t DleEncoder::encode(const uint8_t* sourceStream, if(not escapeStxEtx) { destStream[0] = DLE_CHAR; } - destStream[0] = STX_CHAR; + destStream[1] = STX_CHAR; } if(escapeStxEtx) { @@ -220,6 +220,9 @@ ReturnValue_t DleEncoder::decodeStreamNonEscaped(const uint8_t *sourceStream, uint8_t nextByte; while ((encodedIndex < sourceStreamLen) && (decodedIndex < maxDestStreamlen)) { if (sourceStream[encodedIndex] == DLE_CHAR) { + if(encodedIndex + 1 >= sourceStreamLen) { + return DECODING_ERROR; + } nextByte = sourceStream[encodedIndex + 1]; if(nextByte == STX_CHAR) { *readLen = ++encodedIndex; @@ -247,3 +250,6 @@ ReturnValue_t DleEncoder::decodeStreamNonEscaped(const uint8_t *sourceStream, return DECODING_ERROR; } +void DleEncoder::setEscapeMode(bool escapeStxEtx) { + this->escapeStxEtx = escapeStxEtx; +} diff --git a/src/fsfw/globalfunctions/DleEncoder.h b/src/fsfw/globalfunctions/DleEncoder.h index dc178a0e..e4871bf0 100644 --- a/src/fsfw/globalfunctions/DleEncoder.h +++ b/src/fsfw/globalfunctions/DleEncoder.h @@ -37,6 +37,9 @@ public: * @param escapeCr In escaped mode, escape all CR occurrences as well */ DleEncoder(bool escapeStxEtx = true, bool escapeCr = false); + + void setEscapeMode(bool escapeStxEtx); + virtual ~DleEncoder(); static constexpr uint8_t INTERFACE_ID = CLASS_ID::DLE_ENCODER; diff --git a/tests/src/fsfw_tests/unit/globalfunctions/testDleEncoder.cpp b/tests/src/fsfw_tests/unit/globalfunctions/testDleEncoder.cpp index 01ac3568..91eb9052 100644 --- a/tests/src/fsfw_tests/unit/globalfunctions/testDleEncoder.cpp +++ b/tests/src/fsfw_tests/unit/globalfunctions/testDleEncoder.cpp @@ -4,58 +4,82 @@ #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}; +const std::vector TEST_ARRAY_0 = { 0, 0, 0, 0, 0 }; +const std::vector TEST_ARRAY_1 = { 0, DleEncoder::DLE_CHAR, 5}; +const std::vector TEST_ARRAY_2 = { 0, DleEncoder::STX_CHAR, 5}; +const std::vector TEST_ARRAY_3 = { 0, DleEncoder::CARRIAGE_RETURN, DleEncoder::ETX_CHAR}; +const std::vector TEST_ARRAY_4 = { DleEncoder::DLE_CHAR, DleEncoder::ETX_CHAR, + DleEncoder::STX_CHAR }; + +const std::vector TEST_ARRAY_0_ENCODED_ESCAPED = { + DleEncoder::STX_CHAR, 0, 0, 0, 0, 0, DleEncoder::ETX_CHAR +}; +const std::vector TEST_ARRAY_0_ENCODED_NON_ESCAPED = { + DleEncoder::DLE_CHAR, DleEncoder::STX_CHAR, 0, 0, 0, 0, 0, + DleEncoder::DLE_CHAR, DleEncoder::ETX_CHAR +}; + +const std::vector TEST_ARRAY_1_ENCODED_ESCAPED = { + DleEncoder::STX_CHAR, 0, DleEncoder::DLE_CHAR, DleEncoder::DLE_CHAR, 5, DleEncoder::ETX_CHAR +}; +const std::vector TEST_ARRAY_2_ENCODED_ESCAPED = { + DleEncoder::STX_CHAR, 0, DleEncoder::DLE_CHAR, DleEncoder::STX_CHAR + 0x40, + 5, DleEncoder::ETX_CHAR +}; +const std::vector TEST_ARRAY_3_ENCODED_ESCAPED = { + DleEncoder::STX_CHAR, 0, DleEncoder::CARRIAGE_RETURN, + DleEncoder::DLE_CHAR, DleEncoder::ETX_CHAR + 0x40, DleEncoder::ETX_CHAR +}; +const std::vector TEST_ARRAY_4_ENCODED_ESCAPED = { + DleEncoder::STX_CHAR, DleEncoder::DLE_CHAR, DleEncoder::DLE_CHAR, + DleEncoder::DLE_CHAR, DleEncoder::ETX_CHAR + 0x40, DleEncoder::DLE_CHAR, + DleEncoder::STX_CHAR + 0x40, DleEncoder::ETX_CHAR +}; + TEST_CASE("DleEncoder" , "[DleEncoder]") { - DleEncoder dleEncoder; std::array buffer; + + size_t encodedLen = 0; + size_t readLen = 0; + size_t decodedLen = 0; + + auto testLambdaEncode = [&](DleEncoder& encoder, const std::vector& vecToEncode, + const std::vector& expectedVec) { + ReturnValue_t result = encoder.encode(vecToEncode.data(), vecToEncode.size(), + buffer.data(), buffer.size(), &encodedLen); + REQUIRE(result == retval::CATCH_OK); + for(size_t idx = 0; idx < expectedVec.size(); idx++) { + REQUIRE(buffer[idx] == expectedVec[idx]); + } + REQUIRE(encodedLen == expectedVec.size()); + }; + + auto testLambdaDecode = [&](DleEncoder& encoder, const std::vector& testVecEncoded, + const std::vector& expectedVec) { + ReturnValue_t result = encoder.decode(testVecEncoded.data(), + testVecEncoded.size(), + &readLen, buffer.data(), buffer.size(), &decodedLen); + REQUIRE(result == retval::CATCH_OK); + REQUIRE(readLen == testVecEncoded.size()); + REQUIRE(decodedLen == expectedVec.size()); + for(size_t idx = 0; idx < decodedLen; idx++) { + REQUIRE(buffer[idx] == expectedVec[idx]); + } + }; + 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); + testLambdaEncode(dleEncoder, TEST_ARRAY_0, TEST_ARRAY_0_ENCODED_ESCAPED); + testLambdaEncode(dleEncoder, TEST_ARRAY_1, TEST_ARRAY_1_ENCODED_ESCAPED); + testLambdaEncode(dleEncoder, TEST_ARRAY_2, TEST_ARRAY_2_ENCODED_ESCAPED); + testLambdaEncode(dleEncoder, TEST_ARRAY_3, TEST_ARRAY_3_ENCODED_ESCAPED); + testLambdaEncode(dleEncoder, TEST_ARRAY_4, TEST_ARRAY_4_ENCODED_ESCAPED); - 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()); + dleEncoder.setEscapeMode(false); + testLambdaEncode(dleEncoder, TEST_ARRAY_0, TEST_ARRAY_0_ENCODED_NON_ESCAPED); - 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()); - - result = dleEncoder.encode(TEST_ARRAY_3.data(), TEST_ARRAY_3.size(), + ReturnValue_t result = dleEncoder.encode(TEST_ARRAY_3.data(), TEST_ARRAY_3.size(), buffer.data(), 0, &encodedLen); REQUIRE(result == DleEncoder::STREAM_TOO_SHORT); result = dleEncoder.encode(TEST_ARRAY_1.data(), TEST_ARRAY_1.size(), @@ -64,6 +88,10 @@ TEST_CASE("DleEncoder" , "[DleEncoder]") { } SECTION("Decoding") { - + testLambdaDecode(dleEncoder, TEST_ARRAY_0_ENCODED_ESCAPED, TEST_ARRAY_0); + testLambdaDecode(dleEncoder, TEST_ARRAY_1_ENCODED_ESCAPED, TEST_ARRAY_1); + testLambdaDecode(dleEncoder, TEST_ARRAY_2_ENCODED_ESCAPED, TEST_ARRAY_2); + testLambdaDecode(dleEncoder, TEST_ARRAY_3_ENCODED_ESCAPED, TEST_ARRAY_3); + testLambdaDecode(dleEncoder, TEST_ARRAY_4_ENCODED_ESCAPED, TEST_ARRAY_4); } } From d05eb23ea73499f37b9dc3d7c6b5389c43a53c2c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 9 Sep 2021 01:28:21 +0200 Subject: [PATCH 21/27] debugged and tested non-escaped encoder --- src/fsfw/globalfunctions/DleEncoder.cpp | 9 ++--- .../unit/globalfunctions/testDleEncoder.cpp | 34 ++++++++++++++++--- 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/src/fsfw/globalfunctions/DleEncoder.cpp b/src/fsfw/globalfunctions/DleEncoder.cpp index 02e4aba4..f17df055 100644 --- a/src/fsfw/globalfunctions/DleEncoder.cpp +++ b/src/fsfw/globalfunctions/DleEncoder.cpp @@ -19,10 +19,11 @@ ReturnValue_t DleEncoder::encode(const uint8_t* sourceStream, return STREAM_TOO_SHORT; } if (addStxEtx) { + size_t currentIdx = 0; if(not escapeStxEtx) { - destStream[0] = DLE_CHAR; + destStream[currentIdx++] = DLE_CHAR; } - destStream[1] = STX_CHAR; + destStream[currentIdx] = STX_CHAR; } if(escapeStxEtx) { @@ -122,8 +123,8 @@ ReturnValue_t DleEncoder::encodeStreamNonEscaped(const uint8_t *sourceStream, si if (sourceIndex == sourceLen and encodedIndex < maxDestLen) { if (addStxEtx) { - destStream[encodedIndex] = ETX_CHAR; - ++encodedIndex; + destStream[encodedIndex++] = DLE_CHAR; + destStream[encodedIndex++] = ETX_CHAR; } *encodedLen = encodedIndex; return RETURN_OK; diff --git a/tests/src/fsfw_tests/unit/globalfunctions/testDleEncoder.cpp b/tests/src/fsfw_tests/unit/globalfunctions/testDleEncoder.cpp index 91eb9052..bb8ee40f 100644 --- a/tests/src/fsfw_tests/unit/globalfunctions/testDleEncoder.cpp +++ b/tests/src/fsfw_tests/unit/globalfunctions/testDleEncoder.cpp @@ -22,19 +22,39 @@ const std::vector TEST_ARRAY_0_ENCODED_NON_ESCAPED = { const std::vector TEST_ARRAY_1_ENCODED_ESCAPED = { DleEncoder::STX_CHAR, 0, DleEncoder::DLE_CHAR, DleEncoder::DLE_CHAR, 5, DleEncoder::ETX_CHAR }; +const std::vector TEST_ARRAY_1_ENCODED_NON_ESCAPED = { + DleEncoder::DLE_CHAR, DleEncoder::STX_CHAR, 0, DleEncoder::DLE_CHAR, DleEncoder::DLE_CHAR, + 5, DleEncoder::DLE_CHAR, DleEncoder::ETX_CHAR +}; + const std::vector TEST_ARRAY_2_ENCODED_ESCAPED = { DleEncoder::STX_CHAR, 0, DleEncoder::DLE_CHAR, DleEncoder::STX_CHAR + 0x40, 5, DleEncoder::ETX_CHAR }; +const std::vector TEST_ARRAY_2_ENCODED_NON_ESCAPED = { + DleEncoder::DLE_CHAR, DleEncoder::STX_CHAR, 0, + DleEncoder::STX_CHAR, 5, DleEncoder::DLE_CHAR, DleEncoder::ETX_CHAR +}; + const std::vector TEST_ARRAY_3_ENCODED_ESCAPED = { DleEncoder::STX_CHAR, 0, DleEncoder::CARRIAGE_RETURN, - DleEncoder::DLE_CHAR, DleEncoder::ETX_CHAR + 0x40, DleEncoder::ETX_CHAR + DleEncoder::DLE_CHAR, DleEncoder::ETX_CHAR + 0x40, DleEncoder::ETX_CHAR }; +const std::vector TEST_ARRAY_3_ENCODED_NON_ESCAPED = { + DleEncoder::DLE_CHAR, DleEncoder::STX_CHAR, 0, + DleEncoder::CARRIAGE_RETURN, DleEncoder::ETX_CHAR, DleEncoder::DLE_CHAR, + DleEncoder::ETX_CHAR +}; + const std::vector TEST_ARRAY_4_ENCODED_ESCAPED = { DleEncoder::STX_CHAR, DleEncoder::DLE_CHAR, DleEncoder::DLE_CHAR, DleEncoder::DLE_CHAR, DleEncoder::ETX_CHAR + 0x40, DleEncoder::DLE_CHAR, DleEncoder::STX_CHAR + 0x40, DleEncoder::ETX_CHAR }; +const std::vector TEST_ARRAY_4_ENCODED_NON_ESCAPED = { + DleEncoder::DLE_CHAR, DleEncoder::STX_CHAR, DleEncoder::DLE_CHAR, DleEncoder::DLE_CHAR, + DleEncoder::ETX_CHAR, DleEncoder::STX_CHAR, DleEncoder::DLE_CHAR, DleEncoder::ETX_CHAR +}; TEST_CASE("DleEncoder" , "[DleEncoder]") { @@ -75,16 +95,20 @@ TEST_CASE("DleEncoder" , "[DleEncoder]") { testLambdaEncode(dleEncoder, TEST_ARRAY_2, TEST_ARRAY_2_ENCODED_ESCAPED); testLambdaEncode(dleEncoder, TEST_ARRAY_3, TEST_ARRAY_3_ENCODED_ESCAPED); testLambdaEncode(dleEncoder, TEST_ARRAY_4, TEST_ARRAY_4_ENCODED_ESCAPED); - - dleEncoder.setEscapeMode(false); - testLambdaEncode(dleEncoder, TEST_ARRAY_0, TEST_ARRAY_0_ENCODED_NON_ESCAPED); - ReturnValue_t result = dleEncoder.encode(TEST_ARRAY_3.data(), TEST_ARRAY_3.size(), buffer.data(), 0, &encodedLen); REQUIRE(result == DleEncoder::STREAM_TOO_SHORT); result = dleEncoder.encode(TEST_ARRAY_1.data(), TEST_ARRAY_1.size(), buffer.data(), 4, &encodedLen); REQUIRE(result == DleEncoder::STREAM_TOO_SHORT); + + dleEncoder.setEscapeMode(false); + testLambdaEncode(dleEncoder, TEST_ARRAY_0, TEST_ARRAY_0_ENCODED_NON_ESCAPED); + testLambdaEncode(dleEncoder, TEST_ARRAY_1, TEST_ARRAY_1_ENCODED_NON_ESCAPED); + testLambdaEncode(dleEncoder, TEST_ARRAY_2, TEST_ARRAY_2_ENCODED_NON_ESCAPED); + testLambdaEncode(dleEncoder, TEST_ARRAY_3, TEST_ARRAY_3_ENCODED_NON_ESCAPED); + testLambdaEncode(dleEncoder, TEST_ARRAY_4, TEST_ARRAY_4_ENCODED_NON_ESCAPED); + dleEncoder.setEscapeMode(true); } SECTION("Decoding") { From 3d336c08f20cbae3703660787c1169bc8d31bcb8 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 9 Sep 2021 10:47:54 +0200 Subject: [PATCH 22/27] tests almost complete --- src/fsfw/globalfunctions/DleEncoder.cpp | 5 +- .../unit/globalfunctions/testDleEncoder.cpp | 69 ++++++++++++++++--- 2 files changed, 65 insertions(+), 9 deletions(-) diff --git a/src/fsfw/globalfunctions/DleEncoder.cpp b/src/fsfw/globalfunctions/DleEncoder.cpp index f17df055..e9e5e856 100644 --- a/src/fsfw/globalfunctions/DleEncoder.cpp +++ b/src/fsfw/globalfunctions/DleEncoder.cpp @@ -15,7 +15,7 @@ ReturnValue_t DleEncoder::encode(const uint8_t* sourceStream, else { minAllowedLen = 2; } - if(maxDestLen < minAllowedLen) { + if(minAllowedLen > maxDestLen) { return STREAM_TOO_SHORT; } if (addStxEtx) { @@ -123,6 +123,9 @@ ReturnValue_t DleEncoder::encodeStreamNonEscaped(const uint8_t *sourceStream, si if (sourceIndex == sourceLen and encodedIndex < maxDestLen) { if (addStxEtx) { + if(encodedIndex + 2 >= maxDestLen) { + return STREAM_TOO_SHORT; + } destStream[encodedIndex++] = DLE_CHAR; destStream[encodedIndex++] = ETX_CHAR; } diff --git a/tests/src/fsfw_tests/unit/globalfunctions/testDleEncoder.cpp b/tests/src/fsfw_tests/unit/globalfunctions/testDleEncoder.cpp index bb8ee40f..42701377 100644 --- a/tests/src/fsfw_tests/unit/globalfunctions/testDleEncoder.cpp +++ b/tests/src/fsfw_tests/unit/globalfunctions/testDleEncoder.cpp @@ -59,6 +59,7 @@ const std::vector TEST_ARRAY_4_ENCODED_NON_ESCAPED = { TEST_CASE("DleEncoder" , "[DleEncoder]") { DleEncoder dleEncoder; + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; std::array buffer; size_t encodedLen = 0; @@ -67,7 +68,7 @@ TEST_CASE("DleEncoder" , "[DleEncoder]") { auto testLambdaEncode = [&](DleEncoder& encoder, const std::vector& vecToEncode, const std::vector& expectedVec) { - ReturnValue_t result = encoder.encode(vecToEncode.data(), vecToEncode.size(), + result = encoder.encode(vecToEncode.data(), vecToEncode.size(), buffer.data(), buffer.size(), &encodedLen); REQUIRE(result == retval::CATCH_OK); for(size_t idx = 0; idx < expectedVec.size(); idx++) { @@ -78,7 +79,7 @@ TEST_CASE("DleEncoder" , "[DleEncoder]") { auto testLambdaDecode = [&](DleEncoder& encoder, const std::vector& testVecEncoded, const std::vector& expectedVec) { - ReturnValue_t result = encoder.decode(testVecEncoded.data(), + result = encoder.decode(testVecEncoded.data(), testVecEncoded.size(), &readLen, buffer.data(), buffer.size(), &decodedLen); REQUIRE(result == retval::CATCH_OK); @@ -95,12 +96,25 @@ TEST_CASE("DleEncoder" , "[DleEncoder]") { testLambdaEncode(dleEncoder, TEST_ARRAY_2, TEST_ARRAY_2_ENCODED_ESCAPED); testLambdaEncode(dleEncoder, TEST_ARRAY_3, TEST_ARRAY_3_ENCODED_ESCAPED); testLambdaEncode(dleEncoder, TEST_ARRAY_4, TEST_ARRAY_4_ENCODED_ESCAPED); - ReturnValue_t result = dleEncoder.encode(TEST_ARRAY_3.data(), TEST_ARRAY_3.size(), - buffer.data(), 0, &encodedLen); - REQUIRE(result == DleEncoder::STREAM_TOO_SHORT); - result = dleEncoder.encode(TEST_ARRAY_1.data(), TEST_ARRAY_1.size(), - buffer.data(), 4, &encodedLen); - REQUIRE(result == DleEncoder::STREAM_TOO_SHORT); + + auto testFaultyEncoding = [&](const std::vector& vecToEncode, + const std::vector& expectedVec) { + + for(size_t faultyDestSize = 0; faultyDestSize < expectedVec.size(); faultyDestSize ++) { + if(faultyDestSize == 8) { + + } + result = dleEncoder.encode(vecToEncode.data(), vecToEncode.size(), + buffer.data(), faultyDestSize, &encodedLen); + REQUIRE(result == DleEncoder::STREAM_TOO_SHORT); + } + }; + + testFaultyEncoding(TEST_ARRAY_0, TEST_ARRAY_0_ENCODED_ESCAPED); + testFaultyEncoding(TEST_ARRAY_1, TEST_ARRAY_1_ENCODED_ESCAPED); + testFaultyEncoding(TEST_ARRAY_2, TEST_ARRAY_2_ENCODED_ESCAPED); + testFaultyEncoding(TEST_ARRAY_3, TEST_ARRAY_3_ENCODED_ESCAPED); + testFaultyEncoding(TEST_ARRAY_4, TEST_ARRAY_4_ENCODED_ESCAPED); dleEncoder.setEscapeMode(false); testLambdaEncode(dleEncoder, TEST_ARRAY_0, TEST_ARRAY_0_ENCODED_NON_ESCAPED); @@ -108,6 +122,12 @@ TEST_CASE("DleEncoder" , "[DleEncoder]") { testLambdaEncode(dleEncoder, TEST_ARRAY_2, TEST_ARRAY_2_ENCODED_NON_ESCAPED); testLambdaEncode(dleEncoder, TEST_ARRAY_3, TEST_ARRAY_3_ENCODED_NON_ESCAPED); testLambdaEncode(dleEncoder, TEST_ARRAY_4, TEST_ARRAY_4_ENCODED_NON_ESCAPED); + + testFaultyEncoding(TEST_ARRAY_0, TEST_ARRAY_0_ENCODED_NON_ESCAPED); + testFaultyEncoding(TEST_ARRAY_1, TEST_ARRAY_1_ENCODED_NON_ESCAPED); + testFaultyEncoding(TEST_ARRAY_2, TEST_ARRAY_2_ENCODED_NON_ESCAPED); + testFaultyEncoding(TEST_ARRAY_3, TEST_ARRAY_3_ENCODED_NON_ESCAPED); + testFaultyEncoding(TEST_ARRAY_4, TEST_ARRAY_4_ENCODED_NON_ESCAPED); dleEncoder.setEscapeMode(true); } @@ -117,5 +137,38 @@ TEST_CASE("DleEncoder" , "[DleEncoder]") { testLambdaDecode(dleEncoder, TEST_ARRAY_2_ENCODED_ESCAPED, TEST_ARRAY_2); testLambdaDecode(dleEncoder, TEST_ARRAY_3_ENCODED_ESCAPED, TEST_ARRAY_3); testLambdaDecode(dleEncoder, TEST_ARRAY_4_ENCODED_ESCAPED, TEST_ARRAY_4); + + auto testFaultyDecoding = [&](const std::vector& vecToDecode, + const std::vector& expectedVec) { + for(size_t faultyDestSizes = 0; + faultyDestSizes < expectedVec.size(); + faultyDestSizes ++) { + result = dleEncoder.decode(vecToDecode.data(), + vecToDecode.size(), &readLen, + buffer.data(), faultyDestSizes, &decodedLen); + REQUIRE(result == static_cast(DleEncoder::DECODING_ERROR)); + } + }; + + testFaultyDecoding(TEST_ARRAY_0_ENCODED_ESCAPED, TEST_ARRAY_0); + testFaultyDecoding(TEST_ARRAY_1_ENCODED_ESCAPED, TEST_ARRAY_1); + testFaultyDecoding(TEST_ARRAY_2_ENCODED_ESCAPED, TEST_ARRAY_2); + testFaultyDecoding(TEST_ARRAY_3_ENCODED_ESCAPED, TEST_ARRAY_3); + testFaultyDecoding(TEST_ARRAY_4_ENCODED_ESCAPED, TEST_ARRAY_4); + + dleEncoder.setEscapeMode(false); + testLambdaDecode(dleEncoder, TEST_ARRAY_0_ENCODED_NON_ESCAPED, TEST_ARRAY_0); + testLambdaDecode(dleEncoder, TEST_ARRAY_1_ENCODED_NON_ESCAPED, TEST_ARRAY_1); + testLambdaDecode(dleEncoder, TEST_ARRAY_2_ENCODED_NON_ESCAPED, TEST_ARRAY_2); + testLambdaDecode(dleEncoder, TEST_ARRAY_3_ENCODED_NON_ESCAPED, TEST_ARRAY_3); + testLambdaDecode(dleEncoder, TEST_ARRAY_4_ENCODED_NON_ESCAPED, TEST_ARRAY_4); + + testFaultyDecoding(TEST_ARRAY_0_ENCODED_NON_ESCAPED, TEST_ARRAY_0); + testFaultyDecoding(TEST_ARRAY_1_ENCODED_NON_ESCAPED, TEST_ARRAY_1); + testFaultyDecoding(TEST_ARRAY_2_ENCODED_NON_ESCAPED, TEST_ARRAY_2); + testFaultyDecoding(TEST_ARRAY_3_ENCODED_NON_ESCAPED, TEST_ARRAY_3); + testFaultyDecoding(TEST_ARRAY_4_ENCODED_NON_ESCAPED, TEST_ARRAY_4); + + dleEncoder.setEscapeMode(true); } } From ea573b0523ea205ef36c8f4c91c61d948bab29c7 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 9 Sep 2021 11:12:42 +0200 Subject: [PATCH 23/27] a few more tests with faulty source data --- src/fsfw/globalfunctions/DleEncoder.cpp | 3 ++ .../unit/globalfunctions/testDleEncoder.cpp | 54 +++++++++++++++++-- 2 files changed, 54 insertions(+), 3 deletions(-) diff --git a/src/fsfw/globalfunctions/DleEncoder.cpp b/src/fsfw/globalfunctions/DleEncoder.cpp index e9e5e856..0db557b6 100644 --- a/src/fsfw/globalfunctions/DleEncoder.cpp +++ b/src/fsfw/globalfunctions/DleEncoder.cpp @@ -244,6 +244,9 @@ ReturnValue_t DleEncoder::decodeStreamNonEscaped(const uint8_t *sourceStream, *decodedLen = decodedIndex; return RETURN_OK; } + else { + return DECODING_ERROR; + } } else { destStream[decodedIndex] = sourceStream[encodedIndex]; diff --git a/tests/src/fsfw_tests/unit/globalfunctions/testDleEncoder.cpp b/tests/src/fsfw_tests/unit/globalfunctions/testDleEncoder.cpp index 42701377..4cc3326e 100644 --- a/tests/src/fsfw_tests/unit/globalfunctions/testDleEncoder.cpp +++ b/tests/src/fsfw_tests/unit/globalfunctions/testDleEncoder.cpp @@ -101,9 +101,6 @@ TEST_CASE("DleEncoder" , "[DleEncoder]") { const std::vector& expectedVec) { for(size_t faultyDestSize = 0; faultyDestSize < expectedVec.size(); faultyDestSize ++) { - if(faultyDestSize == 8) { - - } result = dleEncoder.encode(vecToEncode.data(), vecToEncode.size(), buffer.data(), faultyDestSize, &encodedLen); REQUIRE(result == DleEncoder::STREAM_TOO_SHORT); @@ -138,6 +135,28 @@ TEST_CASE("DleEncoder" , "[DleEncoder]") { testLambdaDecode(dleEncoder, TEST_ARRAY_3_ENCODED_ESCAPED, TEST_ARRAY_3); testLambdaDecode(dleEncoder, TEST_ARRAY_4_ENCODED_ESCAPED, TEST_ARRAY_4); + // Faulty source data + auto testArray1EncodedFaulty = TEST_ARRAY_1_ENCODED_ESCAPED; + testArray1EncodedFaulty[3] = 0; + result = dleEncoder.decode(testArray1EncodedFaulty.data(), testArray1EncodedFaulty.size(), + &readLen, buffer.data(), buffer.size(), &encodedLen); + REQUIRE(result == static_cast(DleEncoder::DECODING_ERROR)); + auto testArray2EncodedFaulty = TEST_ARRAY_2_ENCODED_ESCAPED; + testArray2EncodedFaulty[5] = 0; + result = dleEncoder.decode(testArray2EncodedFaulty.data(), testArray2EncodedFaulty.size(), + &readLen, buffer.data(), buffer.size(), &encodedLen); + REQUIRE(result == static_cast(DleEncoder::DECODING_ERROR)); + auto testArray4EncodedFaulty = TEST_ARRAY_4_ENCODED_ESCAPED; + testArray4EncodedFaulty[2] = 0; + result = dleEncoder.decode(testArray4EncodedFaulty.data(), testArray4EncodedFaulty.size(), + &readLen, buffer.data(), buffer.size(), &encodedLen); + REQUIRE(result == static_cast(DleEncoder::DECODING_ERROR)); + auto testArray4EncodedFaulty2 = TEST_ARRAY_4_ENCODED_ESCAPED; + testArray4EncodedFaulty2[4] = 0; + result = dleEncoder.decode(testArray4EncodedFaulty2.data(), testArray4EncodedFaulty2.size(), + &readLen, buffer.data(), buffer.size(), &encodedLen); + REQUIRE(result == static_cast(DleEncoder::DECODING_ERROR)); + auto testFaultyDecoding = [&](const std::vector& vecToDecode, const std::vector& expectedVec) { for(size_t faultyDestSizes = 0; @@ -169,6 +188,35 @@ TEST_CASE("DleEncoder" , "[DleEncoder]") { testFaultyDecoding(TEST_ARRAY_3_ENCODED_NON_ESCAPED, TEST_ARRAY_3); testFaultyDecoding(TEST_ARRAY_4_ENCODED_NON_ESCAPED, TEST_ARRAY_4); + // Faulty source data + testArray1EncodedFaulty = TEST_ARRAY_1_ENCODED_NON_ESCAPED; + auto prevVal = testArray1EncodedFaulty[0]; + testArray1EncodedFaulty[0] = 0; + result = dleEncoder.decode(testArray1EncodedFaulty.data(), testArray1EncodedFaulty.size(), + &readLen, buffer.data(), buffer.size(), &encodedLen); + REQUIRE(result == static_cast(DleEncoder::DECODING_ERROR)); + testArray1EncodedFaulty[0] = prevVal; + testArray1EncodedFaulty[1] = 0; + result = dleEncoder.decode(testArray1EncodedFaulty.data(), testArray1EncodedFaulty.size(), + &readLen, buffer.data(), buffer.size(), &encodedLen); + REQUIRE(result == static_cast(DleEncoder::DECODING_ERROR)); + + testArray1EncodedFaulty = TEST_ARRAY_1_ENCODED_NON_ESCAPED; + testArray1EncodedFaulty[6] = 0; + result = dleEncoder.decode(testArray1EncodedFaulty.data(), testArray1EncodedFaulty.size(), + &readLen, buffer.data(), buffer.size(), &encodedLen); + REQUIRE(result == static_cast(DleEncoder::DECODING_ERROR)); + testArray1EncodedFaulty = TEST_ARRAY_1_ENCODED_NON_ESCAPED; + testArray1EncodedFaulty[7] = 0; + result = dleEncoder.decode(testArray1EncodedFaulty.data(), testArray1EncodedFaulty.size(), + &readLen, buffer.data(), buffer.size(), &encodedLen); + REQUIRE(result == static_cast(DleEncoder::DECODING_ERROR)); + testArray4EncodedFaulty = TEST_ARRAY_4_ENCODED_NON_ESCAPED; + testArray4EncodedFaulty[3] = 0; + result = dleEncoder.decode(testArray4EncodedFaulty.data(), testArray4EncodedFaulty.size(), + &readLen, buffer.data(), buffer.size(), &encodedLen); + REQUIRE(result == static_cast(DleEncoder::DECODING_ERROR)); + dleEncoder.setEscapeMode(true); } } From 7c7a8a5df7510e9a35f6bd6f88d21cad54454548 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 11 Sep 2021 19:18:18 +0200 Subject: [PATCH 24/27] added improvements from code review --- src/fsfw/globalfunctions/DleEncoder.cpp | 93 ++++++++++++------- src/fsfw/globalfunctions/DleEncoder.h | 5 + .../unit/globalfunctions/testDleEncoder.cpp | 2 +- 3 files changed, 65 insertions(+), 35 deletions(-) diff --git a/src/fsfw/globalfunctions/DleEncoder.cpp b/src/fsfw/globalfunctions/DleEncoder.cpp index 0db557b6..35ba84d5 100644 --- a/src/fsfw/globalfunctions/DleEncoder.cpp +++ b/src/fsfw/globalfunctions/DleEncoder.cpp @@ -8,22 +8,12 @@ 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 minAllowedLen = 0; - if(escapeStxEtx) { - minAllowedLen = 1; - } - else { - minAllowedLen = 2; - } - if(minAllowedLen > maxDestLen) { - return STREAM_TOO_SHORT; - } if (addStxEtx) { size_t currentIdx = 0; if(not escapeStxEtx) { destStream[currentIdx++] = DLE_CHAR; } - destStream[currentIdx] = STX_CHAR; + } if(escapeStxEtx) { @@ -40,9 +30,15 @@ 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 = 1; + size_t encodedIndex = 0; size_t sourceIndex = 0; uint8_t nextByte = 0; + if(addStxEtx) { + if(maxDestLen < 1) { + return STREAM_TOO_SHORT; + } + destStream[encodedIndex++] = STX_CHAR; + } while (encodedIndex < maxDestLen and sourceIndex < sourceLen) { nextByte = sourceStream[sourceIndex]; // STX, ETX and CR characters in the stream need to be escaped with DLE @@ -82,8 +78,11 @@ ReturnValue_t DleEncoder::encodeStreamEscaped(const uint8_t *sourceStream, size_ ++sourceIndex; } - if (sourceIndex == sourceLen and encodedIndex < maxDestLen) { + if (sourceIndex == sourceLen) { if (addStxEtx) { + if(encodedIndex + 1 >= maxDestLen) { + return STREAM_TOO_SHORT; + } destStream[encodedIndex] = ETX_CHAR; ++encodedIndex; } @@ -98,9 +97,16 @@ ReturnValue_t DleEncoder::encodeStreamEscaped(const uint8_t *sourceStream, size_ 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 = 2; + size_t encodedIndex = 0; size_t sourceIndex = 0; uint8_t nextByte = 0; + if(addStxEtx) { + if(maxDestLen < 2) { + return STREAM_TOO_SHORT; + } + destStream[encodedIndex++] = DLE_CHAR; + destStream[encodedIndex++] = STX_CHAR; + } while (encodedIndex < maxDestLen and sourceIndex < sourceLen) { nextByte = sourceStream[sourceIndex]; // DLE characters are simply escaped with DLE. @@ -121,7 +127,7 @@ ReturnValue_t DleEncoder::encodeStreamNonEscaped(const uint8_t *sourceStream, si ++sourceIndex; } - if (sourceIndex == sourceLen and encodedIndex < maxDestLen) { + if (sourceIndex == sourceLen) { if (addStxEtx) { if(encodedIndex + 2 >= maxDestLen) { return STREAM_TOO_SHORT; @@ -140,17 +146,6 @@ ReturnValue_t DleEncoder::encodeStreamNonEscaped(const uint8_t *sourceStream, si 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; - if(not escapeStxEtx) { - if (*sourceStream != DLE_CHAR) { - return DECODING_ERROR; - } - ++encodedIndex; - } - if (sourceStream[encodedIndex] != STX_CHAR) { - return DECODING_ERROR; - } - if(escapeStxEtx) { return decodeStreamEscaped(sourceStream, sourceStreamLen, readLen, destStream, maxDestStreamlen, decodedLen); @@ -164,10 +159,15 @@ ReturnValue_t DleEncoder::decode(const uint8_t *sourceStream, 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 encodedIndex = 0; size_t decodedIndex = 0; uint8_t nextByte; + if(maxDestStreamlen < 1) { + return STREAM_TOO_SHORT; + } + if (sourceStream[encodedIndex++] != STX_CHAR) { + return DECODING_ERROR; + } while ((encodedIndex < sourceStreamLen) and (decodedIndex < maxDestStreamlen) and (sourceStream[encodedIndex] != ETX_CHAR) @@ -192,6 +192,8 @@ ReturnValue_t DleEncoder::decodeStreamEscaped(const uint8_t *sourceStream, size_ destStream[decodedIndex] = nextByte - 0x40; } else { + // Set readLen so user can resume parsing after incorrect data + *readLen = encodedIndex + 2; return DECODING_ERROR; } } @@ -205,8 +207,13 @@ ReturnValue_t DleEncoder::decodeStreamEscaped(const uint8_t *sourceStream, size_ ++decodedIndex; } if (sourceStream[encodedIndex] != ETX_CHAR) { - *readLen = ++encodedIndex; - return DECODING_ERROR; + if(decodedIndex == maxDestStreamlen) { + return STREAM_TOO_SHORT; + } + else { + *readLen = ++encodedIndex; + return DECODING_ERROR; + } } else { *readLen = ++encodedIndex; @@ -218,18 +225,29 @@ ReturnValue_t DleEncoder::decodeStreamEscaped(const uint8_t *sourceStream, size_ 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 encodedIndex = 0; size_t decodedIndex = 0; uint8_t nextByte; + if(maxDestStreamlen < 2) { + return STREAM_TOO_SHORT; + } + if (sourceStream[encodedIndex++] != DLE_CHAR) { + return DECODING_ERROR; + } + if (sourceStream[encodedIndex++] != STX_CHAR) { + return DECODING_ERROR; + } while ((encodedIndex < sourceStreamLen) && (decodedIndex < maxDestStreamlen)) { if (sourceStream[encodedIndex] == DLE_CHAR) { if(encodedIndex + 1 >= sourceStreamLen) { + *readLen = encodedIndex; return DECODING_ERROR; } nextByte = sourceStream[encodedIndex + 1]; if(nextByte == STX_CHAR) { - *readLen = ++encodedIndex; + // Set readLen so the DLE/STX char combination is preserved. Could be start of + // another frame + *readLen = encodedIndex; return DECODING_ERROR; } else if(nextByte == DLE_CHAR) { @@ -245,6 +263,7 @@ ReturnValue_t DleEncoder::decodeStreamNonEscaped(const uint8_t *sourceStream, return RETURN_OK; } else { + *readLen = encodedIndex; return DECODING_ERROR; } } @@ -254,7 +273,13 @@ ReturnValue_t DleEncoder::decodeStreamNonEscaped(const uint8_t *sourceStream, ++encodedIndex; ++decodedIndex; } - return DECODING_ERROR; + *readLen = encodedIndex; + if(decodedIndex == maxDestStreamlen) { + return STREAM_TOO_SHORT; + } + else { + return DECODING_ERROR; + } } void DleEncoder::setEscapeMode(bool escapeStxEtx) { diff --git a/src/fsfw/globalfunctions/DleEncoder.h b/src/fsfw/globalfunctions/DleEncoder.h index e4871bf0..09fa2726 100644 --- a/src/fsfw/globalfunctions/DleEncoder.h +++ b/src/fsfw/globalfunctions/DleEncoder.h @@ -71,6 +71,8 @@ public: * @param addStxEtx Adding STX start marker and ETX end marker can be omitted, * if they are added manually * @return + * - RETURN_OK for successful encoding operation + * - STREAM_TOO_SHORT if the destination stream is too short */ ReturnValue_t encode(const uint8_t *sourceStream, size_t sourceLen, uint8_t *destStream, size_t maxDestLen, size_t *encodedLen, @@ -85,6 +87,9 @@ public: * @param maxDestStreamlen * @param decodedLen * @return + * - RETURN_OK for successful decode operation + * - DECODE_ERROR if the source stream is invalid + * - STREAM_TOO_SHORT if the destination stream is too short */ ReturnValue_t decode(const uint8_t *sourceStream, size_t sourceStreamLen, size_t *readLen, uint8_t *destStream, diff --git a/tests/src/fsfw_tests/unit/globalfunctions/testDleEncoder.cpp b/tests/src/fsfw_tests/unit/globalfunctions/testDleEncoder.cpp index 4cc3326e..a82ac73a 100644 --- a/tests/src/fsfw_tests/unit/globalfunctions/testDleEncoder.cpp +++ b/tests/src/fsfw_tests/unit/globalfunctions/testDleEncoder.cpp @@ -165,7 +165,7 @@ TEST_CASE("DleEncoder" , "[DleEncoder]") { result = dleEncoder.decode(vecToDecode.data(), vecToDecode.size(), &readLen, buffer.data(), faultyDestSizes, &decodedLen); - REQUIRE(result == static_cast(DleEncoder::DECODING_ERROR)); + REQUIRE(result == static_cast(DleEncoder::STREAM_TOO_SHORT)); } }; From d36d849e6994356c045e17924a60a00b13ae75e3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 11 Sep 2021 19:21:21 +0200 Subject: [PATCH 25/27] removed part which is now not necessary anymore --- src/fsfw/globalfunctions/DleEncoder.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/fsfw/globalfunctions/DleEncoder.cpp b/src/fsfw/globalfunctions/DleEncoder.cpp index 35ba84d5..04e4985c 100644 --- a/src/fsfw/globalfunctions/DleEncoder.cpp +++ b/src/fsfw/globalfunctions/DleEncoder.cpp @@ -8,14 +8,6 @@ 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 (addStxEtx) { - size_t currentIdx = 0; - if(not escapeStxEtx) { - destStream[currentIdx++] = DLE_CHAR; - } - - } - if(escapeStxEtx) { return encodeStreamEscaped(sourceStream, sourceLen, destStream, maxDestLen, encodedLen, addStxEtx); From dae27a8e105a5d0e9c0f8bd5bda6b6d2826441b3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 11 Sep 2021 19:22:51 +0200 Subject: [PATCH 26/27] indentation --- src/fsfw/globalfunctions/DleEncoder.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/fsfw/globalfunctions/DleEncoder.cpp b/src/fsfw/globalfunctions/DleEncoder.cpp index 04e4985c..df9a909e 100644 --- a/src/fsfw/globalfunctions/DleEncoder.cpp +++ b/src/fsfw/globalfunctions/DleEncoder.cpp @@ -1,13 +1,13 @@ #include "fsfw/globalfunctions/DleEncoder.h" -DleEncoder::DleEncoder(bool escapeStxEtx, bool escapeCr): escapeStxEtx(escapeStxEtx), - escapeCr(escapeCr) {} +DleEncoder::DleEncoder(bool escapeStxEtx, bool escapeCr): + escapeStxEtx(escapeStxEtx), escapeCr(escapeCr) {} 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 sourceLen, uint8_t* destStream, size_t maxDestLen, + size_t* encodedLen, bool addStxEtx) { if(escapeStxEtx) { return encodeStreamEscaped(sourceStream, sourceLen, destStream, maxDestLen, encodedLen, addStxEtx); @@ -136,16 +136,16 @@ ReturnValue_t DleEncoder::encodeStreamNonEscaped(const uint8_t *sourceStream, si } ReturnValue_t DleEncoder::decode(const uint8_t *sourceStream, - size_t sourceStreamLen, size_t *readLen, uint8_t *destStream, - size_t maxDestStreamlen, size_t *decodedLen) { - if(escapeStxEtx) { - return decodeStreamEscaped(sourceStream, sourceStreamLen, - readLen, destStream, maxDestStreamlen, decodedLen); - } - else { + size_t sourceStreamLen, size_t *readLen, uint8_t *destStream, + size_t maxDestStreamlen, size_t *decodedLen) { + if(escapeStxEtx) { + return decodeStreamEscaped(sourceStream, sourceStreamLen, + readLen, destStream, maxDestStreamlen, decodedLen); + } + else { return decodeStreamNonEscaped(sourceStream, sourceStreamLen, readLen, destStream, maxDestStreamlen, decodedLen); - } + } } ReturnValue_t DleEncoder::decodeStreamEscaped(const uint8_t *sourceStream, size_t sourceStreamLen, From abacfbf2d5550c189e5c0b48f3eb794eb8525f02 Mon Sep 17 00:00:00 2001 From: Ulrich Mohr Date: Mon, 13 Sep 2021 10:38:36 +0200 Subject: [PATCH 27/27] added setting of readLen according to review --- src/fsfw/globalfunctions/DleEncoder.cpp | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/fsfw/globalfunctions/DleEncoder.cpp b/src/fsfw/globalfunctions/DleEncoder.cpp index df9a909e..47ea5c4e 100644 --- a/src/fsfw/globalfunctions/DleEncoder.cpp +++ b/src/fsfw/globalfunctions/DleEncoder.cpp @@ -154,6 +154,11 @@ ReturnValue_t DleEncoder::decodeStreamEscaped(const uint8_t *sourceStream, size_ size_t encodedIndex = 0; size_t decodedIndex = 0; uint8_t nextByte; + + //init to 0 so that we can just return in the first checks (which do not consume anything from + //the source stream) + *readLen = 0; + if(maxDestStreamlen < 1) { return STREAM_TOO_SHORT; } @@ -166,6 +171,8 @@ ReturnValue_t DleEncoder::decodeStreamEscaped(const uint8_t *sourceStream, size_ and (sourceStream[encodedIndex] != STX_CHAR)) { if (sourceStream[encodedIndex] == DLE_CHAR) { if(encodedIndex + 1 >= sourceStreamLen) { + //reached the end of the sourceStream + *readLen = sourceStreamLen; return DECODING_ERROR; } nextByte = sourceStream[encodedIndex + 1]; @@ -200,6 +207,8 @@ ReturnValue_t DleEncoder::decodeStreamEscaped(const uint8_t *sourceStream, size_ } if (sourceStream[encodedIndex] != ETX_CHAR) { if(decodedIndex == maxDestStreamlen) { + //so far we did not find anything wrong here, so let user try again + *readLen = 0; return STREAM_TOO_SHORT; } else { @@ -220,6 +229,11 @@ ReturnValue_t DleEncoder::decodeStreamNonEscaped(const uint8_t *sourceStream, size_t encodedIndex = 0; size_t decodedIndex = 0; uint8_t nextByte; + + //init to 0 so that we can just return in the first checks (which do not consume anything from + //the source stream) + *readLen = 0; + if(maxDestStreamlen < 2) { return STREAM_TOO_SHORT; } @@ -227,6 +241,7 @@ ReturnValue_t DleEncoder::decodeStreamNonEscaped(const uint8_t *sourceStream, return DECODING_ERROR; } if (sourceStream[encodedIndex++] != STX_CHAR) { + *readLen = 1; return DECODING_ERROR; } while ((encodedIndex < sourceStreamLen) && (decodedIndex < maxDestStreamlen)) { @@ -265,11 +280,13 @@ ReturnValue_t DleEncoder::decodeStreamNonEscaped(const uint8_t *sourceStream, ++encodedIndex; ++decodedIndex; } - *readLen = encodedIndex; + if(decodedIndex == maxDestStreamlen) { + //so far we did not find anything wrong here, so let user try again + *readLen = 0; return STREAM_TOO_SHORT; - } - else { + } else { + *readLen = encodedIndex; return DECODING_ERROR; } }