From 4f1f610ae03bd4f0fecc9e19ecafa5803ee8a231 Mon Sep 17 00:00:00 2001 From: "Robin.Mueller" Date: Tue, 7 Jul 2020 16:36:41 +0200 Subject: [PATCH] doc and improvements for DLE encoder --- globalfunctions/DleEncoder.cpp | 39 +++++++++++---------- globalfunctions/DleEncoder.h | 64 +++++++++++++++++++++++++++++----- returnvalues/FwClassIds.h | 3 +- 3 files changed, 78 insertions(+), 28 deletions(-) diff --git a/globalfunctions/DleEncoder.cpp b/globalfunctions/DleEncoder.cpp index a68f1524..ee934785 100644 --- a/globalfunctions/DleEncoder.cpp +++ b/globalfunctions/DleEncoder.cpp @@ -1,18 +1,16 @@ #include -DleEncoder::DleEncoder() { -} +DleEncoder::DleEncoder() {} -DleEncoder::~DleEncoder() { -} +DleEncoder::~DleEncoder() {} ReturnValue_t DleEncoder::decode(const uint8_t *sourceStream, - uint32_t sourceStreamLen, uint32_t *readLen, uint8_t *destStream, - uint32_t maxDestStreamlen, uint32_t *decodedLen) { - uint32_t encodedIndex = 0, decodedIndex = 0; + 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) { - return RETURN_FAILED; + return DECODING_ERROR; } ++encodedIndex; while ((encodedIndex < sourceStreamLen) && (decodedIndex < maxDestStreamlen) @@ -20,14 +18,18 @@ ReturnValue_t DleEncoder::decode(const uint8_t *sourceStream, && (sourceStream[encodedIndex] != STX)) { if (sourceStream[encodedIndex] == DLE) { nextByte = sourceStream[encodedIndex + 1]; - if (nextByte == 0x10) { + // 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) { destStream[decodedIndex] = nextByte; } else { + // The next byte is a STX, DTX or 0x0D character which + // was escaped by a DLE character if ((nextByte == 0x42) || (nextByte == 0x43) || (nextByte == 0x4D)) { destStream[decodedIndex] = nextByte - 0x40; } else { - return RETURN_FAILED; + return DECODING_ERROR; } } ++encodedIndex; @@ -38,7 +40,7 @@ ReturnValue_t DleEncoder::decode(const uint8_t *sourceStream, ++decodedIndex; } if (sourceStream[encodedIndex] != ETX) { - return RETURN_FAILED; + return DECODING_ERROR; } else { *readLen = ++encodedIndex; *decodedLen = decodedIndex; @@ -47,12 +49,12 @@ ReturnValue_t DleEncoder::decode(const uint8_t *sourceStream, } ReturnValue_t DleEncoder::encode(const uint8_t* sourceStream, - uint32_t sourceLen, uint8_t* destStream, uint32_t maxDestLen, - uint32_t* encodedLen, bool addStxEtx) { + size_t sourceLen, uint8_t* destStream, size_t maxDestLen, + size_t* encodedLen, bool addStxEtx) { if (maxDestLen < 2) { - return RETURN_FAILED; + return STREAM_TOO_SHORT; } - uint32_t encodedIndex = 0, sourceIndex = 0; + size_t encodedIndex = 0, sourceIndex = 0; uint8_t nextByte; if (addStxEtx) { destStream[0] = STX; @@ -62,15 +64,16 @@ ReturnValue_t DleEncoder::encode(const uint8_t* sourceStream, nextByte = sourceStream[sourceIndex]; if ((nextByte == STX) || (nextByte == ETX) || (nextByte == 0x0D)) { if (encodedIndex + 1 >= maxDestLen) { - return RETURN_FAILED; + return STREAM_TOO_SHORT; } else { destStream[encodedIndex] = DLE; ++encodedIndex; + // Escaped byte will be actual byte + 0x40. destStream[encodedIndex] = nextByte + 0x40; } } else if (nextByte == DLE) { if (encodedIndex + 1 >= maxDestLen) { - return RETURN_FAILED; + return STREAM_TOO_SHORT; } else { destStream[encodedIndex] = DLE; ++encodedIndex; @@ -90,6 +93,6 @@ ReturnValue_t DleEncoder::encode(const uint8_t* sourceStream, *encodedLen = encodedIndex; return RETURN_OK; } else { - return RETURN_FAILED; + return STREAM_TOO_SHORT; } } diff --git a/globalfunctions/DleEncoder.h b/globalfunctions/DleEncoder.h index fc155600..0f4a4c8f 100644 --- a/globalfunctions/DleEncoder.h +++ b/globalfunctions/DleEncoder.h @@ -1,25 +1,71 @@ -#ifndef DLEENCODER_H_ -#define DLEENCODER_H_ +#ifndef FRAMEWORK_GLOBALFUNCTIONS_DLEENCODER_H_ +#define FRAMEWORK_GLOBALFUNCTIONS_DLEENCODER_H_ #include +#include +/** + * @brief This DLE Encoder (Data Link Encoder) can be used to encode and + * decode arbitrary data with ASCII control characters + * @details + * List of control codes: + * 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 strean is converted into a encoded stream by adding + * a STX marker at the startr of the stream and an ETX marker at the end of + * the stream. Any STX, ETX and DLE occurences in the source stream are escaped + * by a DLE character. + */ class DleEncoder: public HasReturnvaluesIF { private: DleEncoder(); 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); + + //! Start Of Text character. First character is encoded stream static const uint8_t STX = 0x02; + //! End Of Text character. Last character in encoded stream static const uint8_t ETX = 0x03; + //! Data Link Escape character. Used to escape STX, ETX and DLE occurences + //! in the source stream. static const uint8_t DLE = 0x10; - static ReturnValue_t decode(const uint8_t *sourceStream, - uint32_t sourceStreamLen, uint32_t *readLen, uint8_t *destStream, - uint32_t maxDestStreamlen, uint32_t *decodedLen); + /** + * 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. + * @param sourceStream + * @param sourceLen + * @param destStream + * @param maxDestLen + * @param encodedLen + * @param addStxEtx + * Adding STX and ETX can be omitted, if they are added manually. + * @return + */ + static ReturnValue_t encode(const uint8_t *sourceStream, size_t sourceLen, + uint8_t *destStream, size_t maxDestLen, size_t *encodedLen, + bool addStxEtx = true); - static ReturnValue_t encode(const uint8_t *sourceStream, uint32_t sourceLen, - uint8_t *destStream, uint32_t maxDestLen, uint32_t *encodedLen, - bool addStxEtx = true); + /** + * Converts an encoded stream back + * @param sourceStream + * @param sourceStreamLen + * @param readLen + * @param destStream + * @param maxDestStreamlen + * @param decodedLen + * @return + */ + static ReturnValue_t decode(const uint8_t *sourceStream, + size_t sourceStreamLen, size_t *readLen, uint8_t *destStream, + size_t maxDestStreamlen, size_t *decodedLen); }; -#endif /* DLEENCODER_H_ */ +#endif /* FRAMEWORK_GLOBALFUNCTIONS_DLEENCODER_H_ */ diff --git a/returnvalues/FwClassIds.h b/returnvalues/FwClassIds.h index abee534a..7e4d8953 100644 --- a/returnvalues/FwClassIds.h +++ b/returnvalues/FwClassIds.h @@ -64,7 +64,8 @@ enum { LOCAL_POOL_OWNER_IF, //LPIF 58 POOL_VARIABLE_IF, //PVA 59 HOUSEKEEPING_MANAGER, //HKM 60 - PUS_PARSER, //PUSP 61 + DLE_ENCODER, //DLEE 61 + PUS_PARSER, //PUSP 62 FW_CLASS_ID_COUNT //is actually count + 1 ! };