// -------------------------------------------------------------- #ifndef _FRAME_HPP_ #define _FRAME_HPP_ #include #include // -------------------------------------------------------------- // Constants // -------------------------------------------------------------- #define FRAME_CRC16_IV 0x0000 #define FRAME_CRC16_POLY 0x1021 #define FRAME_PREAMBLE_IV 0x55 #define FRAME_SCRAMBLER_SEED 0x12345678 #define FRAME_SCRAMBLER_POLY 0x80C18601 #define FRAME_NUM_BYTES_PER_FRAME 256 //#define FRAME_TYPE_IDLE 0x01 //#define FRAME_TYPE_DATA 0x02 // -------------------------------------------------------------- // Types // -------------------------------------------------------------- enum frame_type { FRAME_TYPE_UNKNOWN = 0, FRAME_TYPE_IDLE, FRAME_TYPE_DATA }; #pragma pack(push) #pragma pack(1) typedef struct _frame_hdr_t { uint8_t preamble[2]; uint32_t prn_state; uint16_t crc16; uint16_t type; uint16_t length; } frame_hdr_t; typedef struct _frame_t { frame_hdr_t hdr; uint8_t data[FRAME_NUM_BYTES_PER_FRAME]; } frame_t; #pragma pack(pop) typedef struct _frame_statistics_t { uint32_t numTotalFrame; uint32_t numInvalidFrame; uint32_t numIdleFrame; uint32_t numDataFrame; uint32_t numDataBytes; } frame_statistics_t; #define SIZEOF_SYMBOL_BITS (8*sizeof(symbol_t)) #define SIZEOF_DATA_BITS (8*sizeof(data_t)) // -------------------------------------------------------------- // Scrambler // -------------------------------------------------------------- class Scrambler { public: Scrambler(uint32_t state, uint32_t poly); ~Scrambler(); uint32_t stateGet(); void stateSet(uint32_t state); uint8_t process(uint8_t src); void process(uint8_t *pSrcDst, uint32_t len); private: uint32_t m_state; uint32_t m_poly; }; class IFormatter { public: IFormatter() {} virtual ~IFormatter() {} virtual void onFrame(void *pFrame, uint32_t size) = 0; }; class Formatter { public: Formatter(IFormatter *pFrameHandler); ~Formatter(); void idle(); void process(uint8_t data); void process(void *pData, uint32_t len); frame_statistics_t getStats(); void resetStats(); private: Scrambler m_scrambler; IFormatter *m_pFrameHandler; frame_t m_frame; uint32_t m_dataCount; uint32_t m_idleCount; frame_statistics_t m_frameStats; void commit(frame_type frameType, uint32_t m_dataCount); }; class ISymbolizer { public: ISymbolizer() {} virtual ~ISymbolizer() {} virtual void onSymbol(symbol_t symbol) = 0; }; class Symbolizer : public IFormatter { public: Symbolizer(ISymbolizer *pSymbolHandler); ~Symbolizer(); void process(data_t src); void process(void *pSrc, uint32_t len); void setNumBitsPerSymbol(uint32_t nBitsPerSym); private: uint32_t m_nBitsPerSym; ISymbolizer *m_pSymbolHandler; uint32_t m_symbolBitCount; symbol_t m_lastSymbol; symbol_t m_symbolMask; symbol_t differentialEncode(symbol_t symbol); void onFrame(void *pFrame, uint32_t size) override; }; class IData { public: IData() {} virtual ~IData() {} virtual void onData(data_t data) = 0; virtual void onReset() = 0; }; class IDeFormatter { public: IDeFormatter() {} virtual ~IDeFormatter() {} virtual void onData(void *pData, uint32_t size) = 0; }; class DeFormatter : public IData { public: DeFormatter(IDeFormatter *pDataHandler); ~DeFormatter(); void process(uint8_t data); frame_statistics_t getStats(); void resetStats(); private: IDeFormatter *m_pDataHandler; Scrambler m_scrambler; uint32_t m_dataCount; frame_t m_frame; frame_statistics_t m_frameStats; bool m_enable; void onData(data_t data) override; void onReset() override; }; class DeSymbolizer { public: DeSymbolizer(IData *pDataHandler); ~DeSymbolizer(); void process(symbol_t src); void setNumBitsPerSymbol(uint32_t nBitsPerSym); private: uint32_t m_nBitsPerSym; IData *m_pDataHandler; uint32_t m_bitCount; uint32_t m_dataBitCount; symbol_t m_lastSymbol; symbol_t m_symbolMask; symbol_t differentialDecode(symbol_t symbol); }; class FrameReceiver { public: FrameReceiver(IDeFormatter *pRawFrameHandler) : m_deformatter(pRawFrameHandler) , m_desymbolizer( &m_deformatter) , m_framesCount(0) , m_byteCount(0) { } ~FrameReceiver() { } frame_statistics_t getStats() { return m_deformatter.getStats(); } void resetStats() { m_deformatter.resetStats(); } void setNumBitsPerSymbol(uint32_t nBitsPerSym) { m_desymbolizer.setNumBitsPerSymbol(nBitsPerSym); m_deformatter.resetStats(); } void process(symbol_t symbol) { m_desymbolizer.process(symbol); } private: DeFormatter m_deformatter; DeSymbolizer m_desymbolizer; uint32_t m_framesCount; uint32_t m_byteCount; }; class UnitFrameTransmitter { public: UnitFrameTransmitter(uint32_t nBitsPerSym, ISymbolizer *pReceiver) : m_symbolizer(pReceiver) , m_formatter(&m_symbolizer) { m_symbolizer.setNumBitsPerSymbol(nBitsPerSym); } ~UnitFrameTransmitter() { } void process() { uint32_t i; for (i=0; i < 12; i++) { m_formatter.process((uint8_t)i); } for (i=0; i < 100; i++) { m_formatter.idle(); } for (i=0; i < 100; i++) { m_formatter.process((uint8_t)i); } m_formatter.idle(); } private: Symbolizer m_symbolizer; Formatter m_formatter; }; class UnitFrameReceiver : public ISymbolizer, public IDeFormatter { public: UnitFrameReceiver(uint32_t nBitsPerSym) : m_deformatter(this) , m_desymbolizer(&m_deformatter) { m_desymbolizer.setNumBitsPerSymbol(nBitsPerSym); } ~UnitFrameReceiver() { } private: DeFormatter m_deformatter; DeSymbolizer m_desymbolizer; void onSymbol(symbol_t symbol) override { m_desymbolizer.process(symbol); } void onData(void *pData, uint32_t size) override { // Received raw data (void)pData; (void)size; } }; // -------------------------------------------------------------- #endif // _FRAME_HPP_