A library to send and receive packets over serial, uses MODSERIAL

Dependents:   SimpleSerialProtocolExample SerialFileReceiver

Revision:
2:43794e0b738f
Child:
3:5caff50e14a7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Codec.h	Thu Sep 18 17:37:04 2014 +0000
@@ -0,0 +1,151 @@
+#ifndef SIMPLE_SERIAL_PROTOCOL_CODEC
+#define SIMPLE_SERIAL_PROTOCOL_CODEC
+
+#include "Ringbuffer.h"
+#include "Packet.h"
+
+namespace SimpleSerialProtocol {
+
+class ICodec {
+public:
+    ICodec(){}
+    virtual ~ICodec(){}
+    virtual bool encode(Packet* packet, RingBuffer* buffer) = 0;
+    virtual void decode(Packet* packet, char data) = 0;
+    virtual uint32_t getStreamErrors() = 0;
+    virtual uint32_t getPacketErrors() = 0;
+};
+
+class Codec: public ICodec {
+public:
+    Codec(){
+        state = PACKET_STARTA;
+        header_read = 0;
+        data_read = 0;
+        stream_errors = 0;
+        packet_errors = 0;
+    }
+    virtual ~Codec(){}
+    
+    virtual uint32_t getStreamErrors() {
+        return stream_errors;
+    }
+    virtual uint32_t getPacketErrors() {
+        return packet_errors;    
+    }
+    
+    virtual bool encode(Packet* packet, RingBuffer* buffer){
+        if (packet!=0) {
+            
+            if((buffer->size() - buffer->available()) < packet->_size + 4){
+                return false;    
+            }
+            
+            buffer->write(255);
+            buffer->write(127);
+            buffer->write(packet->_size);
+            for (int i = 0; i < packet->_size; i++) {
+                 buffer->write(packet->_data[i]);
+            }
+            buffer->write(checksum(packet));
+            
+            return true;
+            
+        }
+        return 0;
+    }
+    
+    virtual void decode(Packet* packet, char data){
+        switch (state) {
+            case PACKET_STARTA:
+                if(data == PACKET_BYTE1){
+                    state = PACKET_STARTB;
+                }
+                break;
+                
+            case PACKET_STARTB:
+                if(data == PACKET_BYTE2){
+                    state = HEADER_RECEIVE;
+                } else {
+                    state = PACKET_STARTA;
+                    stream_errors ++; 
+                }
+                break;
+
+            case HEADER_RECEIVE:
+                header[header_read++] = data;
+                if(header_read == PACKET_HEADER_SIZE){
+                    packet->_size = header[0];
+                    state = DATA_RECEIVE;
+                }
+                break;
+
+            case DATA_RECEIVE:
+                if (data_read < packet->_size) {
+                    packet->_data[data_read++] = data;
+                    if (data_read == packet->_size) {
+                        state = DATA_VALIDATE;
+                    }
+                } else {
+                    state = PACKET_STARTA;
+                    header_read = 0;
+                    data_read = 0;
+                }
+                break;
+
+            case DATA_VALIDATE:
+                packet->_type = packet->_data[0];
+                packet->_checksum = data;
+                if (checksum(packet) == packet->_checksum) {
+                    packet->_valid = true;
+                } else {
+                    packet_errors ++;    
+                }
+                state = PACKET_STARTA;
+                header_read = 0;
+                data_read = 0;
+                break;
+
+            default:
+                state = PACKET_STARTA;
+                header_read = 0;
+                data_read = 0;
+                break;
+        }
+    }
+    
+    virtual uint16_t checksum(Packet* packet){
+        uint8_t tmp_checksum = 16;
+        for (int i = 0; i < packet->_size; i++) {
+            tmp_checksum ^= packet->_data[i];
+        }
+        return tmp_checksum;
+    }
+    
+    
+    enum {
+        PACKET_STARTA,
+        PACKET_STARTB,
+        HEADER_RECEIVE,
+        DATA_RECEIVE,
+        DATA_VALIDATE,
+    };
+    
+    enum {
+        PACKET_BYTE1 = 255,
+        PACKET_BYTE2 = 127,
+        PACKET_HEADER_SIZE = 1, 
+    };
+    
+    uint8_t state;
+    char header[PACKET_HEADER_SIZE];
+    uint8_t header_read; 
+    uint32_t data_read;
+    uint32_t stream_errors;
+    uint32_t packet_errors;
+    
+};
+    
+}
+
+#endif
\ No newline at end of file