Added support for custom checksums

pull/14/head
Ondřej Hruška 7 years ago
parent b74bda7cf5
commit 91e1c25c6d
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 14
      TF_Config.example.h
  2. 83
      TinyFrame.c
  3. 65
      TinyFrame.h
  4. 1
      demo/multipart_tx/TF_Config.h
  5. 1
      demo/simple/TF_Config.h
  6. 1
      demo/socket_demo/TF_Config.h

@ -8,6 +8,7 @@
#define TF_CONFIG_H #define TF_CONFIG_H
#include <stdint.h> #include <stdint.h>
#include <stdio.h> // used by the TF_Error() macro defined below
//#include <esp8266.h> // when using with esphttpd //#include <esp8266.h> // when using with esphttpd
//----------------------------- FRAME FORMAT --------------------------------- //----------------------------- FRAME FORMAT ---------------------------------
@ -28,11 +29,11 @@
#define TF_LEN_BYTES 2 #define TF_LEN_BYTES 2
#define TF_TYPE_BYTES 1 #define TF_TYPE_BYTES 1
// Checksum type // Checksum type. Options:
//#define TF_CKSUM_TYPE TF_CKSUM_NONE // TF_CKSUM_NONE, TF_CKSUM_XOR, TF_CKSUM_CRC16, TF_CKSUM_CRC32
//#define TF_CKSUM_TYPE TF_CKSUM_XOR // TF_CKSUM_CUSTOM8, TF_CKSUM_CUSTOM16, TF_CKSUM_CUSTOM32
#define TF_CKSUM_TYPE TF_CKSUM_CRC16 // Custom checksums require you to implement checksum functions (see TinyFrame.h)
//#define TF_CKSUM_TYPE TF_CKSUM_CRC32 #define TF_CKSUM_TYPE TF_CKSUM_CUSTOM8
// Use a SOF byte to mark the start of a frame // Use a SOF byte to mark the start of a frame
#define TF_USE_SOF_BYTE 1 #define TF_USE_SOF_BYTE 1
@ -69,6 +70,9 @@ typedef uint8_t TF_COUNT;
// ticks = number of calls to TF_Tick() // ticks = number of calls to TF_Tick()
#define TF_PARSER_TIMEOUT_TICKS 10 #define TF_PARSER_TIMEOUT_TICKS 10
// Whether to use mutex - requires you to implement TF_ClaimTx() and TF_ReleaseTx()
#define TF_USE_MUTEX 1
// Error reporting function. To disable debug, change to empty define // Error reporting function. To disable debug, change to empty define
#define TF_Error(format, ...) printf("[TF] " format "\n", ##__VA_ARGS__) #define TF_Error(format, ...) printf("[TF] " format "\n", ##__VA_ARGS__)

@ -1,6 +1,6 @@
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
#include "TinyFrame.h" #include "TinyFrame.h"
#include <malloc.h> #include <stdlib.h> // - for malloc() if dynamic constructor is used
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Compatibility with ESP8266 SDK // Compatibility with ESP8266 SDK
@ -18,27 +18,36 @@
// mandate configurable field sizes unless we use u32 everywhere (and possibly shorten // mandate configurable field sizes unless we use u32 everywhere (and possibly shorten
// it when encoding to the buffer). I don't really like this idea so much. -MP // it when encoding to the buffer). I don't really like this idea so much. -MP
#if TF_USE_MUTEX==0
/** Claim the TX interface before composing and sending a frame */
static inline void TF_ClaimTx(TinyFrame *tf) { (void)tf; }
/** Free the TX interface after composing and sending a frame */
static inline void TF_ReleaseTx(TinyFrame *tf) { (void)tf; }
#endif
//region Checksums //region Checksums
#define CKSUM_RESET(cksum) do { (cksum) = TF_CksumStart(); } while (0)
#define CKSUM_ADD(cksum, byte) do { (cksum) = TF_CksumAdd((cksum), (byte)); } while (0)
#define CKSUM_FINALIZE(cksum) do { (cksum) = TF_CksumEnd((cksum)); } while (0)
#if TF_CKSUM_TYPE == TF_CKSUM_NONE #if TF_CKSUM_TYPE == TF_CKSUM_NONE
// NONE TF_CKSUM TF_CksumStart(void) { return 0; }
#define CKSUM_RESET(cksum) TF_CKSUM TF_CksumAdd(TF_CKSUM cksum, uint8_t byte) { return cksum; }
#define CKSUM_ADD(cksum, byte) TF_CKSUM TF_CksumEnd(TF_CKSUM cksum) { return cksum; }
#define CKSUM_FINALIZE(cksum)
#elif TF_CKSUM_TYPE == TF_CKSUM_XOR #elif TF_CKSUM_TYPE == TF_CKSUM_XOR
// ~XOR TF_CKSUM TF_CksumStart(void) { return 0; }
#define CKSUM_RESET(cksum) do { (cksum) = 0; } while (0) TF_CKSUM TF_CksumAdd(TF_CKSUM cksum, uint8_t byte) { return cksum ^ byte; }
#define CKSUM_ADD(cksum, byte) do { (cksum) ^= (byte); } while(0) TF_CKSUM TF_CksumEnd(TF_CKSUM cksum) { return (TF_CKSUM) ~cksum; }
#define CKSUM_FINALIZE(cksum) do { (cksum) = (TF_CKSUM)~cksum; } while(0)
#elif TF_CKSUM_TYPE == TF_CKSUM_CRC16 #elif TF_CKSUM_TYPE == TF_CKSUM_CRC16
// TODO try to replace with an algorithm // TODO try to replace with an algorithm
/** CRC table for the CRC-16. The poly is 0x8005 (x^16 + x^15 + x^2 + 1) */ /** CRC table for the CRC-16. The poly is 0x8005 (x^16 + x^15 + x^2 + 1) */
static const uint16_t crc16_table[256] = { static const uint16_t crc16_table[256] = {
0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
@ -71,21 +80,16 @@ static const uint16_t crc16_table[256] = {
0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
}; };
static inline uint16_t crc16_byte(uint16_t cksum, const uint8_t byte)
{
return (cksum >> 8) ^ crc16_table[(cksum ^ byte) & 0xff];
}
#define CKSUM_RESET(cksum) do { (cksum) = 0; } while (0) TF_CKSUM TF_CksumStart(void) { return 0; }
#define CKSUM_ADD(cksum, byte) do { (cksum) = crc16_byte((cksum), (byte)); } while(0) TF_CKSUM TF_CksumAdd(TF_CKSUM cksum, uint8_t byte) { return (cksum >> 8) ^ crc16_table[(cksum ^ byte) & 0xff]; }
#define CKSUM_FINALIZE(cksum) TF_CKSUM TF_CksumEnd(TF_CKSUM cksum) { return cksum; }
#elif TF_CKSUM_TYPE == TF_CKSUM_CRC32 #elif TF_CKSUM_TYPE == TF_CKSUM_CRC32
// TODO try to replace with an algorithm // TODO try to replace with an algorithm
static const uint32_t crc32_table[] = { /* CRC polynomial 0xedb88320 */ static const uint32_t crc32_table[] = { /* CRC polynomial 0xedb88320 */
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
@ -129,16 +133,11 @@ static const uint32_t crc32_table[] = { /* CRC polynomial 0xedb88320 */
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
}; };
static inline uint32_t crc32_byte(uint32_t cksum, const uint8_t byte) TF_CKSUM TF_CksumStart(void) { return (TF_CKSUM)0xFFFFFFFF; }
{ TF_CKSUM TF_CksumAdd(TF_CKSUM cksum, uint8_t byte) { return crc32_table[((cksum) ^ ((uint8_t)byte)) & 0xff] ^ ((cksum) >> 8); }
return (crc32_table[((cksum) ^ ((uint8_t)byte)) & 0xff] ^ ((cksum) >> 8)); TF_CKSUM TF_CksumEnd(TF_CKSUM cksum) { return (TF_CKSUM) ~cksum; }
}
#define CKSUM_RESET(cksum) do { (cksum) = (TF_CKSUM)0xFFFFFFFF; } while (0)
#define CKSUM_ADD(cksum, byte) do { (cksum) = crc32_byte(cksum, byte); } while(0)
#define CKSUM_FINALIZE(cksum) do { (cksum) = (TF_CKSUM)~(cksum); } while(0)
#endif #endif
@ -586,8 +585,8 @@ void _TF_FN TF_AcceptChar(TinyFrame *tf, unsigned char c)
if (tf->rxi == tf->len) { if (tf->rxi == tf->len) {
#if TF_CKSUM_TYPE == TF_CKSUM_NONE #if TF_CKSUM_TYPE == TF_CKSUM_NONE
// All done // All done
TF_HandleReceivedMessage(); TF_HandleReceivedMessage(tf);
TF_ResetParser(); TF_ResetParser(tf);
#else #else
// Enter DATA_CKSUM state // Enter DATA_CKSUM state
tf->state = TFState_DATA_CKSUM; tf->state = TFState_DATA_CKSUM;
@ -898,19 +897,3 @@ void _TF_FN TF_Tick(TinyFrame *tf)
} }
} }
} }
/** Default impl for claiming write mutex; can be specific to the instance */
void __attribute__((weak)) TF_ClaimTx(TinyFrame *tf)
{
(void) tf;
// do nothing
}
/** Default impl for releasing write mutex; can be specific to the instance */
void __attribute__((weak)) TF_ReleaseTx(TinyFrame *tf)
{
(void) tf;
// do nothing
}

@ -4,13 +4,13 @@
/** /**
* TinyFrame protocol library * TinyFrame protocol library
* *
* (c) Ondřej Hruška 2017, MIT License * (c) Ondřej Hruška 2017-2018, MIT License
* no liability/warranty, free for any use, must retain this notice & license * no liability/warranty, free for any use, must retain this notice & license
* *
* Upstream URL: https://github.com/MightyPork/TinyFrame * Upstream URL: https://github.com/MightyPork/TinyFrame
*/ */
#define TF_VERSION "2.1.0" #define TF_VERSION "2.2.0"
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
#include <stdint.h> // for uint8_t etc #include <stdint.h> // for uint8_t etc
@ -19,11 +19,14 @@
#include <string.h> // for memset() #include <string.h> // for memset()
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Select checksum type (0 = none, 8 = ~XOR, 16 = CRC16 0x8005, 32 = CRC32) // Checksum type (0 = none, 8 = ~XOR, 16 = CRC16 0x8005, 32 = CRC32)
#define TF_CKSUM_NONE 0 #define TF_CKSUM_NONE 0
#define TF_CKSUM_XOR 8 #define TF_CKSUM_XOR 8
#define TF_CKSUM_CRC16 16 #define TF_CKSUM_CRC16 16
#define TF_CKSUM_CRC32 32 #define TF_CKSUM_CRC32 32
#define TF_CKSUM_CUSTOM8 1
#define TF_CKSUM_CUSTOM16 2
#define TF_CKSUM_CUSTOM32 3
#include "TF_Config.h" #include "TF_Config.h"
@ -62,17 +65,17 @@ typedef uint32_t TF_ID;
#endif #endif
#if TF_CKSUM_TYPE == TF_CKSUM_XOR || TF_CKSUM_TYPE == TF_CKSUM_NONE #if (TF_CKSUM_TYPE == TF_CKSUM_XOR) || (TF_CKSUM_TYPE == TF_CKSUM_NONE) || (TF_CKSUM_TYPE == TF_CKSUM_CUSTOM8)
// ~XOR (if 0, still use 1 byte - it won't be used) // ~XOR (if 0, still use 1 byte - it won't be used)
typedef uint8_t TF_CKSUM; typedef uint8_t TF_CKSUM;
#elif TF_CKSUM_TYPE == TF_CKSUM_CRC16 #elif (TF_CKSUM_TYPE == TF_CKSUM_CRC16) || (TF_CKSUM_TYPE == TF_CKSUM_CUSTOM16)
// CRC16 // CRC16
typedef uint16_t TF_CKSUM; typedef uint16_t TF_CKSUM;
#elif TF_CKSUM_TYPE == TF_CKSUM_CRC32 #elif (TF_CKSUM_TYPE == TF_CKSUM_CRC32) || (TF_CKSUM_TYPE == TF_CKSUM_CUSTOM32)
// CRC32 // CRC32
typedef uint32_t TF_CKSUM; typedef uint32_t TF_CKSUM;
#else #else
#error Bad value for TF_CKSUM_TYPE, must be 8, 16 or 32 #error Bad value for TF_CKSUM_TYPE
#endif #endif
//endregion //endregion
@ -100,7 +103,7 @@ typedef enum {
} TF_Result; } TF_Result;
/** Data structure for sending / receiving messages */ /** Data structure for sending / receiving messages */
typedef struct _TF_MSG_STRUCT_ { typedef struct TF_Msg_ {
TF_ID frame_id; //!< message ID TF_ID frame_id; //!< message ID
bool is_response; //!< internal flag, set when using the Respond function. frame_id is then kept unchanged. bool is_response; //!< internal flag, set when using the Respond function. frame_id is then kept unchanged.
TF_TYPE type; //!< received or sent message type TF_TYPE type; //!< received or sent message type
@ -135,7 +138,7 @@ typedef TF_Result (*TF_Listener)(TinyFrame *tf, TF_Msg *msg);
// region Internal // region Internal
enum TFState_ { enum TF_State_ {
TFState_SOF = 0, //!< Wait for SOF TFState_SOF = 0, //!< Wait for SOF
TFState_LEN, //!< Wait for Number Of Bytes TFState_LEN, //!< Wait for Number Of Bytes
TFState_HEAD_CKSUM, //!< Wait for header Checksum TFState_HEAD_CKSUM, //!< Wait for header Checksum
@ -178,7 +181,7 @@ struct TinyFrame_ {
TF_ID next_id; //!< Next frame / frame chain ID TF_ID next_id; //!< Next frame / frame chain ID
/* Parser state */ /* Parser state */
enum TFState_ state; enum TF_State_ state;
TF_TICKS parser_timeout_ticks; TF_TICKS parser_timeout_ticks;
TF_ID id; //!< Incoming packet ID TF_ID id; //!< Incoming packet ID
TF_LEN len; //!< Payload length TF_LEN len; //!< Payload length
@ -375,10 +378,44 @@ void TF_Tick(TinyFrame *tf);
*/ */
extern void TF_WriteImpl(TinyFrame *tf, const uint8_t *buff, size_t len); extern void TF_WriteImpl(TinyFrame *tf, const uint8_t *buff, size_t len);
/** Claim the TX interface before composing and sending a frame */ // Mutex functions
extern void TF_ClaimTx(TinyFrame *tf); #if TF_USE_MUTEX
/** Free the TX interface after composing and sending a frame */ /** Claim the TX interface before composing and sending a frame */
extern void TF_ReleaseTx(TinyFrame *tf); extern void TF_ClaimTx(TinyFrame *tf);
/** Free the TX interface after composing and sending a frame */
extern void TF_ReleaseTx(TinyFrame *tf);
#endif
// Custom checksum functions
#if (TF_CKSUM_TYPE == TF_CKSUM_CUSTOM8) || (TF_CKSUM_TYPE == TF_CKSUM_CUSTOM16) || (TF_CKSUM_TYPE == TF_CKSUM_CUSTOM32)
/**
* Initialize a checksum
*
* @return initial checksum value
*/
extern TF_CKSUM TF_CksumStart(void);
/**
* Update a checksum with a byte
*
* @param cksum - previous checksum value
* @param byte - byte to add
* @return updated checksum value
*/
extern TF_CKSUM TF_CksumAdd(TF_CKSUM cksum, uint8_t byte);
/**
* Finalize the checksum calculation
*
* @param cksum - previous checksum value
* @return final checksum value
*/
extern TF_CKSUM TF_CksumEnd(TF_CKSUM cksum);
#endif
#endif #endif

@ -6,6 +6,7 @@
#define TF_CONFIG_H #define TF_CONFIG_H
#include <stdint.h> #include <stdint.h>
#include <stdio.h>
#define TF_ID_BYTES 1 #define TF_ID_BYTES 1
#define TF_LEN_BYTES 2 #define TF_LEN_BYTES 2

@ -6,6 +6,7 @@
#define TF_CONFIG_H #define TF_CONFIG_H
#include <stdint.h> #include <stdint.h>
#include <stdio.h>
#define TF_ID_BYTES 1 #define TF_ID_BYTES 1
#define TF_LEN_BYTES 2 #define TF_LEN_BYTES 2

@ -6,6 +6,7 @@
#define TF_CONFIG_H #define TF_CONFIG_H
#include <stdint.h> #include <stdint.h>
#include <stdio.h>
#define TF_ID_BYTES 1 #define TF_ID_BYTES 1
#define TF_LEN_BYTES 2 #define TF_LEN_BYTES 2

Loading…
Cancel
Save