simple serial protocol

Dependents:   AwsomeStation LoRaBaseStation LoRaTerminal

Files at this revision

API Documentation at this revision

Comitter:
rba90
Date:
Fri Sep 02 02:39:04 2016 +0000
Parent:
10:2a710d0bab2c
Commit message:
The CommandPacket is reconstructed.

Changed in this revision

CommandPacket.cpp Show diff for this revision Revisions of this file
CommandPacket.h Show diff for this revision Revisions of this file
CommandPacket2.cpp Show annotated file Show diff for this revision Revisions of this file
CommandPacket2.h Show annotated file Show diff for this revision Revisions of this file
SerialInterfaceProtocol.cpp Show annotated file Show diff for this revision Revisions of this file
SerialInterfaceProtocol.h Show annotated file Show diff for this revision Revisions of this file
--- a/CommandPacket.cpp	Thu Sep 01 04:15:40 2016 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,114 +0,0 @@
-#include "CommandPacket.h"
-#include "mbed.h"
-
-#define CHECKSUM_DEBUG
-
-uint8_t generate_checksum(uint8_t *data, uint8_t length, uint8_t offset)
-{
-    uint8_t s = 0;
-
-    if (data)
-    {
-        // take the sum of all data bytes preceding checksum field
-        for(uint8_t i = 0; i < length; i++)
-        {
-            s += data[i + offset];
-        }
-
-        // calculate two's complement of the remainder
-        s = 0xff - s + 1;
-    }
-
-    return s;
-}
-
-uint8_t hexchar_to_uint8(uint8_t ch)
-{
-    uint8_t val = 0;
-
-    if (ch >= '0' && ch <= '9')
-    {
-        val = ch - '0';
-    }
-    else if (ch >= 'A' && ch <= 'F')
-    {
-        val  = ch - 'A';
-        val += 10;
-    }
-    else if (ch >= 'a' && ch <= 'f')
-    {
-        val = ch - 'a';
-        val += 10;
-    }
-
-    return val;
-}
-
-
-bool CommandPacket::verify()
-{
-    return checksum == generate_checksum();
-}
-
-CommandPacket::CommandPacket()
-{
-    // reset internal error number
-    errno = NO_ERROR;
-
-    // set public variables
-    sflag = '<';
-    command = 0x0;
-    length = 0x0;
-    memset(payload, 0x0, sizeof(payload));
-    checksum = 0x0;
-    eflag = '>';
-}
-
-int CommandPacket::serialize(uint8_t *output)
-{
-    // create buffer for payload
-    uint8_t buffer[length * 2];
-    memset(buffer, 0x0, sizeof(buffer));
-
-    for (int i = 0; i < length; i++)
-    {
-        sprintf((char *) (buffer + i * 2), "%02X", payload[i]);
-    }
-
-    // assume the user provide output buffer large enough
-    sprintf((char *) output, "%c%02X%02X%s%02X%c",
-        sflag,
-        command,
-        length,
-        (char *) buffer,
-        generate_checksum(),
-        eflag
-    );
-
-    return length;
-}
-
-uint8_t CommandPacket::generate_checksum()
-{
-    // checksum is defined by the sum of all characters between sflag and checksum field
-    uint8_t s = 0;
-
-    // include command
-    s += command;
-
-    // include length
-    s += length;
-
-    // include payload
-    for (int i = 0; i < length; i++)
-    {
-        s += payload[i];
-    }
-
-    // calculate two's complement of the remainder
-    s = 0xff - s + 1;
-
-    return s;
-}
-
-
--- a/CommandPacket.h	Thu Sep 01 04:15:40 2016 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-#ifndef COMMAND_PACKET_H_
-#define COMMAND_PACKET_H_
-
-#include "stdint.h"
-
-// command packet consists of following parts
-// u4 sflag
-// u8 command
-// u8 length
-// u8 payload[len]
-// u8 checksum
-// u4 eflag
-
-uint8_t generate_checksum(uint8_t *payload, uint8_t length, uint8_t offset=0);
-uint8_t hexchar_to_uint8(uint8_t ch);
-
-class CommandPacket
-{
-public:
-    typedef enum
-    {
-        CP_SFLAG = '<',
-        CP_EFLAG = '>'
-    } CPFlag_t;
-
-    typedef enum
-    {
-        NONE = 0,
-        SFLAG,
-        COMMAND_H,
-        COMMAND_L,
-        LENGTH_H,
-        LENGTH_L,
-        PAYLOAD_H,
-        PAYLOAD_L,
-        CHECKSUM_H,
-        CHECKSUM_L,
-        EFLAG
-    } State_t;
-
-    typedef enum
-    {
-        NO_ERROR = 0,
-        INVALID_SFLAG_ERROR,
-        INVALID_EFLAG_ERROR,
-        INVALID_CMD_ERROR,
-        INVALID_CS_ERROR,
-        INVALID_EXEC_ERROR
-    } Error_t;
-
-public:
-    Error_t errno;
-
-public:
-    uint8_t sflag;
-    uint8_t command;
-    uint8_t length;
-    uint8_t payload[256 + 1]; // payload include terminator
-    uint8_t checksum;
-    uint8_t eflag;
-
-public:
-    CommandPacket();
-    ~CommandPacket() {};
-
-    bool verify();
-    int serialize(uint8_t *output);
-    uint8_t generate_checksum();
-};
-
-
-
-
-#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CommandPacket2.cpp	Fri Sep 02 02:39:04 2016 +0000
@@ -0,0 +1,175 @@
+#include "CommandPacket2.h"
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdio.h>
+
+CommandPacket2::CommandPacket2()
+{
+    // initialize payload
+    memset(_payload, 0x0, sizeof(_payload));
+    
+    // reset is verified state
+    _isVerified = false;
+}
+
+CommandPacket2::~CommandPacket2()
+{
+    
+}
+
+void CommandPacket2::setSFlag(uint8_t sflag)
+{
+    _sflag = sflag;
+    _isVerified = false;
+}
+
+void CommandPacket2::setCommand(uint8_t command)
+{
+    _command = command;
+    _isVerified = false;
+}
+
+void CommandPacket2::setLength(uint8_t length)
+{
+    _length = length;
+    _isVerified = false;
+}
+
+void CommandPacket2::setPayload(uint8_t idx, uint8_t payload)
+{
+    _payload[idx] = payload;
+    _isVerified = false;
+}
+
+void CommandPacket2::setChecksum(uint8_t checksum)
+{
+    _checksum = checksum;
+    _isVerified = false;
+}
+
+void CommandPacket2::setEFlag(uint8_t eflag)
+{
+    _eflag = eflag;
+    _isVerified = false;
+}
+
+uint8_t CommandPacket2::getSFlag()
+{
+    return _sflag;
+}
+
+uint8_t CommandPacket2::getCommand()
+{
+    return _command;
+}
+
+uint8_t CommandPacket2::getLength()
+{
+    return _length;
+}
+
+uint8_t CommandPacket2::getPayload(uint8_t idx)
+{
+    return _payload[idx];
+}
+
+uint8_t CommandPacket2::getEFlag()
+{
+    return _eflag;
+}
+
+uint8_t CommandPacket2::getChecksum()
+{
+    return _checksum;
+}
+
+bool CommandPacket2::verify()
+{
+    if (_isVerified)
+    {
+        return true;
+    }
+    else
+    {
+        return _checksum == calculate_checksum();
+    }
+}
+
+uint8_t CommandPacket2::calculate_checksum()
+{
+    // take the sum of all user defined data bytes preceding checksum field
+    uint8_t s = 0;
+    
+    // add command
+    s += _command;
+    
+    // add length
+    s += _length;
+    
+    // add payload
+    for (uint8_t i = 0; i < _length; i++)
+    {
+        s += _payload[i];
+    }
+    
+    // calculate two's complement of the remainder
+    s = 0xff - s + 1;
+    
+    return s;
+}
+
+void CommandPacket2::generateChecksum()
+{
+    _checksum = calculate_checksum();
+    
+    _isVerified = true;
+}
+
+int CommandPacket2::serialize(uint8_t *buffer)
+{
+    // the user need to make sure that they have enough space for buffer
+    if (!buffer) return 0;
+    
+    char octet[3];
+    int offset = 0;
+    
+    // cast content to output buffer
+    // sflag
+    buffer[offset] = _sflag;
+    offset += 1;
+    
+    // command
+    memset(octet, 0x0, sizeof(octet));
+    sprintf(octet, "%02X", _command);
+    memcpy(buffer + offset, octet, 2);
+    offset += 2;
+    
+    // length
+    memset(octet, 0x0, sizeof(octet));
+    sprintf(octet, "%02X", _length);
+    memcpy(buffer + offset, octet, 2);
+    offset += 2;
+    
+    // payload
+    for (uint8_t i = 0; i < _length; i++)
+    {
+        memset(octet, 0x0, sizeof(octet));
+        sprintf(octet, "%02X", _payload[i]);
+        memcpy(buffer + offset, octet, 2);
+        offset += 2;
+    }
+    
+    // checksum
+    memset(octet, 0x0, sizeof(octet));
+    sprintf(octet, "%02X", _checksum);
+    memcpy(buffer + offset, octet, 2);
+    offset += 2;
+    
+    // eflag
+    buffer[offset] = _eflag;
+    offset += 1;
+    
+    return offset;
+}
+        
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CommandPacket2.h	Fri Sep 02 02:39:04 2016 +0000
@@ -0,0 +1,67 @@
+// command packet consists of following parts
+// u4 sflag
+// u8 command
+// u8 length
+// u8 payload[len]
+// u8 checksum
+// u4 eflag
+
+
+#ifndef COMMAND_PACKET2_H_
+#define COMMAND_PACKET2_H_
+
+#include <stdint.h>
+
+class CommandPacket2
+{
+// public types
+public:
+    typedef enum
+    {
+        CP_SFLAG = '<',
+        CP_EFLAG = '>'
+    } CPFlag_t;
+    
+// private properties
+private:
+    uint8_t _sflag;
+    uint8_t _command;
+    uint8_t _length;
+    uint8_t _payload[256];
+    uint8_t _checksum;
+    uint8_t _eflag;
+    
+    bool _isVerified;
+    
+// private methods
+private:
+    uint8_t calculate_checksum();
+    
+// public methods
+public:
+    CommandPacket2();
+    ~CommandPacket2();
+    
+    void setSFlag(uint8_t sflag=CP_SFLAG);
+    void setCommand(uint8_t command);
+    void setLength(uint8_t length);
+    void setPayload(uint8_t idx, uint8_t payload);
+    void setChecksum(uint8_t checksum);
+    void setEFlag(uint8_t eflag=CP_EFLAG);
+    
+    uint8_t getSFlag();
+    uint8_t getCommand();
+    uint8_t getLength();
+    uint8_t getPayload(uint8_t idx);
+    uint8_t getEFlag();
+    uint8_t getChecksum();
+    
+    
+    
+    bool verify();
+    void generateChecksum();
+    int serialize(uint8_t *buffer);
+    
+};
+
+#endif
\ No newline at end of file
--- a/SerialInterfaceProtocol.cpp	Thu Sep 01 04:15:40 2016 +0000
+++ b/SerialInterfaceProtocol.cpp	Fri Sep 02 02:39:04 2016 +0000
@@ -1,5 +1,6 @@
+#include "mbed.h"
 #include "SerialInterfaceProtocol.h"
-#include "mbed.h"
+#include "CommandPacket2.h"
 
 SerialInterfaceProtocol::SerialInterfaceProtocol(SerialBuffer_t *in, SerialBuffer_t *out)
 {
@@ -14,7 +15,7 @@
     }
     
     // init internal state machine
-    state = CommandPacket::NONE;
+    state = NONE;
     
     // init internal state
     isChecksumEnabled = false;
@@ -37,13 +38,25 @@
 
 int SerialInterfaceProtocol::execute(uint8_t *response, uint8_t *response_length)
 {
+    // read command from packet buffer
+    uint8_t command = PacketBuffer.getCommand();
     
     // execute the command if it's already been registered
-    if (CommandVectorTable[PacketBuffer.command] != NULL)
-    {       
-        return CommandVectorTable[PacketBuffer.command](
-            PacketBuffer.payload, 
-            PacketBuffer.length,
+    if (CommandVectorTable[command] != NULL)
+    {
+        // extract length and payload from packet buffer
+        uint8_t length = PacketBuffer.getLength();
+        uint8_t payload[length];
+        memset(payload, 0x0, length);
+        
+        for (uint8_t i = 0; i < length; i++)
+        {
+            payload[i] = PacketBuffer.getPayload(i);
+        }
+        
+        return CommandVectorTable[command](
+            payload, 
+            length,
             response, 
             response_length
         );
@@ -58,7 +71,7 @@
     if (response_length != 0)
     {
         respond(
-            0xD0 | ((uint8_t) PacketBuffer.errno & 0x0F), 
+            0xD0 | ((uint8_t) errno & 0x0F), 
             response, 
             response_length
         );
@@ -66,7 +79,7 @@
     else
     {
         respond(
-            0xE0 | ((uint8_t) PacketBuffer.errno & 0x0F), 
+            0xE0 | ((uint8_t) errno & 0x0F), 
             response, 
             response_length
         );
@@ -77,30 +90,36 @@
 
 int SerialInterfaceProtocol::respond(uint8_t command, uint8_t *response, uint8_t response_length)
 {
-    // prepare for packet buffer
-    PacketBuffer.sflag = CommandPacket::CP_SFLAG;
+    // create a new packet buffer
+    CommandPacket2 responsePacket;
+    
+    // set sflag
+    responsePacket.setSFlag();  // use default sflag
     
     // return flag as specified by the user
-    PacketBuffer.command = command;
+    responsePacket.setCommand(command);
     
     // copy buffer length
-    PacketBuffer.length = response_length;
+    responsePacket.setLength(response_length);
     
     // copy buffer to payload
-    memcpy(PacketBuffer.payload, response, response_length);
+    for (uint8_t i = 0; i < response_length; i++)
+    {
+        responsePacket.setPayload(i, response[i]);
+    }
     
     // generate checksum
-    PacketBuffer.checksum = PacketBuffer.generate_checksum();
+    responsePacket.generateChecksum();
     
     // end flag
-    PacketBuffer.eflag = CommandPacket::CP_EFLAG;
+    responsePacket.setEFlag();
     
     // serialize the packet
-    int total_len = PacketBuffer.length * 2 + 8;
+    int total_len = response_length * 2 + 8;
     uint8_t buffer[total_len];
     memset(buffer, 0x0, total_len);
     
-    PacketBuffer.serialize(buffer);
+    responsePacket.serialize(buffer);
     
 #ifdef DEBUG_SIP
     printf("SIP::respond:total: %d chars\r\n", total_len);
@@ -122,6 +141,13 @@
 void SerialInterfaceProtocol::poll()
 {
     static uint8_t payload_counter = 0;
+    
+    // temp variable for building full byte from hex strings
+    static uint8_t command = 0;
+    static uint8_t length = 0;
+    static uint8_t payload = 0;
+    static uint8_t checksum = 0;
+    
     uint8_t response[SIP_MAX_RESP_LEN];
     uint8_t response_length;
     
@@ -132,105 +158,119 @@
         ch = SerialInputBuffer->dequeue();
         
         // reset state to keep sync
-        if (ch == CommandPacket::CP_SFLAG)
+        if (ch == CommandPacket2::CP_SFLAG)
         {
-            state = CommandPacket::SFLAG;
+            state = SFLAG;
             
             // reset variable
             payload_counter = 0;
-            memset(PacketBuffer.payload, 0x0, sizeof(PacketBuffer.payload));
-            PacketBuffer.errno = CommandPacket::NO_ERROR;
+            errno = NO_ERROR;
         }
         
         switch (state)
         {
-            case CommandPacket::SFLAG:
-                PacketBuffer.sflag = ch;
-                state = CommandPacket::COMMAND_H;
+            case SFLAG:
+                PacketBuffer.setSFlag(ch);
+                state = COMMAND_H;
 #ifdef DEBUG_SIP
-                printf("CommandPacket::SFLAG: 0x%x\r\n", PacketBuffer.sflag);
+                printf("SIP::SFLAG: 0x%x\r\n", PacketBuffer.getSFlag());
 #endif
                 break;
                 
-            case CommandPacket::COMMAND_H:
-                PacketBuffer.command = hexchar_to_uint8(ch) << 4;
-                state = CommandPacket::COMMAND_L;
+            case COMMAND_H:
+                command = hexchar_to_uint8(ch) << 4;
+                state = COMMAND_L;
 #ifdef DEBUG_SIP
-                printf("CommandPacket::COMMAND_H: 0x%x\r\n", PacketBuffer.command);
+                printf("SIP::COMMAND_H: 0x%x\r\n", command);
 #endif
                 break;
                 
-            case CommandPacket::COMMAND_L:
-                PacketBuffer.command |= (hexchar_to_uint8(ch) & 0x0f);
-                state = CommandPacket::LENGTH_H;
+            case COMMAND_L:
+                command |= (hexchar_to_uint8(ch) & 0x0f);
+                
+                // store command
+                PacketBuffer.setCommand(command);
+                
+                state = LENGTH_H;
 #ifdef DEBUG_SIP
-                printf("CommandPacket::COMMAND_L: 0x%x\r\n", PacketBuffer.command);
+                printf("SIP::COMMAND_L: 0x%x\r\n", command);
 #endif
                 break;
                 
-            case CommandPacket::LENGTH_H:
-                PacketBuffer.length = hexchar_to_uint8(ch) << 4;
-                state = CommandPacket::LENGTH_L;
+            case LENGTH_H:
+                length = hexchar_to_uint8(ch) << 4;
+                state = LENGTH_L;
 #ifdef DEBUG_SIP
-                printf("CommandPacket::LENGTH_H: 0x%x\r\n", PacketBuffer.length);
+                printf("SIP::LENGTH_H: 0x%x\r\n", length);
 #endif
                 break;
                 
-            case CommandPacket::LENGTH_L:
-                PacketBuffer.length |= (hexchar_to_uint8(ch) & 0x0f);
-                if (PacketBuffer.length != 0) // if the length is not zero, then proceed to payload state
+            case LENGTH_L:
+                length |= (hexchar_to_uint8(ch) & 0x0f);
+                
+                // store length
+                PacketBuffer.setLength(length);
+                
+                if (length != 0) // if the length is not zero, then proceed to payload state
                 {
-                    state = CommandPacket::PAYLOAD_H;
+                    state = PAYLOAD_H;
                 }
                 else // otherwise proceed to checksum state
                 {
-                    state = CommandPacket::CHECKSUM_H;
+                    state = CHECKSUM_H;
                 }
 #ifdef DEBUG_SIP
-                printf("CommandPacket::LENGTH_L: 0x%x\r\n", PacketBuffer.length);
+                printf("SIP::LENGTH_L: 0x%x\r\n", length);
 #endif
                 break;
             
-            case CommandPacket::PAYLOAD_H:
-                PacketBuffer.payload[payload_counter] = hexchar_to_uint8(ch) << 4; // store higher 4 bits of payload
-                state = CommandPacket::PAYLOAD_L;
+            case PAYLOAD_H:
+                payload = hexchar_to_uint8(ch) << 4; // store higher 4 bits of payload
+                state = PAYLOAD_L;
 #ifdef DEBUG_SIP
-                printf("CommandPacket::PAYLOAD_H: 0x%x\r\n", PacketBuffer.payload[payload_counter]);
+                printf("SIP::PAYLOAD_H: 0x%x\r\n", payload);
 #endif
                 break;
                 
-            case CommandPacket::PAYLOAD_L:
-                PacketBuffer.payload[payload_counter++] |= (hexchar_to_uint8(ch) & 0x0f); // store lower 4 bits of payload
-                if (payload_counter < PacketBuffer.length) // append ch to payload until reach the length
+            case PAYLOAD_L:
+                payload |= (hexchar_to_uint8(ch) & 0x0f); // store lower 4 bits of payload
+                
+                // store payload
+                PacketBuffer.setPayload(payload_counter++, payload);
+                
+                if (payload_counter < PacketBuffer.getLength()) // append ch to payload until reach the length
                 {
-                    state = CommandPacket::PAYLOAD_H;
+                    state = PAYLOAD_H;
                 }
                 else
                 {
-                    state = CommandPacket::CHECKSUM_H;
+                    state = CHECKSUM_H;
                 }
 #ifdef DEBUG_SIP
-                printf("CommandPacket::PAYLOAD_L: 0x%x\r\n", PacketBuffer.payload[payload_counter - 1]);
+                printf("SIP::PAYLOAD_L: 0x%x\r\n", payload);
 #endif
                 break;
                 
-            case CommandPacket::CHECKSUM_H:
-                PacketBuffer.checksum = hexchar_to_uint8(ch) << 4;
-                state = CommandPacket::CHECKSUM_L;
+            case CHECKSUM_H:
+                checksum = hexchar_to_uint8(ch) << 4;
+                state = CHECKSUM_L;
 #ifdef DEBUG_SIP
-                printf("CommandPacket::CHECKSUM_H: 0x%x\r\n", PacketBuffer.checksum);
+                printf("SIP::CHECKSUM_H: 0x%x\r\n", checksum);
 #endif
                 break;
                 
-            case CommandPacket::CHECKSUM_L:
-                PacketBuffer.checksum |= (hexchar_to_uint8(ch) & 0x0f);
+            case CHECKSUM_L:
+                checksum |= (hexchar_to_uint8(ch) & 0x0f);
+                
+                // store checksum
+                PacketBuffer.setChecksum(checksum);
                 
                 // checksum can be turned off
                 if (isChecksumEnabled)
                 {
                     if (PacketBuffer.verify()) // checksum match
                     {
-                        state = CommandPacket::EFLAG;
+                        state = EFLAG;
                     }
                     else // checksum mismatch
                     {
@@ -239,27 +279,27 @@
                         memset(response, 0x0, sizeof(response));
                         
                         // prepare for checksum error response
-                        PacketBuffer.errno = CommandPacket::INVALID_CS_ERROR;
+                        errno = INVALID_CS_ERROR;
                         assemble(response, response_length);
                         
-                        state = CommandPacket::NONE;
+                        state = NONE;
                     }
                 }
                 else
                 {
-                    state = CommandPacket::EFLAG;
+                    state = EFLAG;
                 }
                 
                 
 #ifdef DEBUG_SIP
-                printf("CommandPacket::CHECKSUM_L: 0x%x\r\n", PacketBuffer.checksum);
+                printf("SIP::CHECKSUM_L: 0x%x\r\n", checksum);
 #endif
                 break;
                 
-            case CommandPacket::EFLAG:
-                if (ch == CommandPacket::CP_EFLAG)
+            case EFLAG:
+                if (ch == CommandPacket2::CP_EFLAG)
                 {
-                    PacketBuffer.eflag = ch;
+                    PacketBuffer.setEFlag(ch);
                     
                     // clear response and response length
                     response_length = 0;
@@ -270,36 +310,36 @@
                     
                     if (ret < 0) // command not registered
                     {
-                        PacketBuffer.errno = CommandPacket::INVALID_CMD_ERROR;
+                        errno = INVALID_CMD_ERROR;
                     }
                     else if (ret != 0) // error to execute
                     {
-                        PacketBuffer.errno = CommandPacket::INVALID_EXEC_ERROR;
+                        errno = INVALID_EXEC_ERROR;
                     }
                     else
                     {
-                        PacketBuffer.errno = CommandPacket::NO_ERROR;
+                        errno = NO_ERROR;
                     }
                     
                     assemble(response, response_length);
                 }
-                state = CommandPacket::NONE;
+                state = NONE;
 #ifdef DEBUG_SIP
-                printf("CommandPacket::EFLAG: 0x%x\r\n", PacketBuffer.eflag);
+                printf("SIP::EFLAG: 0x%x\r\n", PacketBuffer.getEFlag());
 #endif
                 break;
                 
-            case CommandPacket::NONE:
+            case NONE:
                 // clear response and response length
                 response_length = 0;
                 memset(response, 0x0, sizeof(response));
                 
                 // Execute error generator
-                PacketBuffer.errno = CommandPacket::INVALID_SFLAG_ERROR;
+                errno = INVALID_SFLAG_ERROR;
                 assemble(response, response_length);
                 
 #ifdef DEBUG_SIP
-                printf("CommandPacket::NONE\r\n");
+                printf("SIP::NONE\r\n");
 #endif
                 break;
                 
@@ -317,4 +357,26 @@
 void SerialInterfaceProtocol::enableChecksum()
 {
     isChecksumEnabled = true;
-}
\ No newline at end of file
+}
+
+uint8_t hexchar_to_uint8(uint8_t ch)
+{
+    uint8_t val = 0;
+
+    if (ch >= '0' && ch <= '9')
+    {
+        val = ch - '0';
+    }
+    else if (ch >= 'A' && ch <= 'F')
+    {
+        val  = ch - 'A';
+        val += 10;
+    }
+    else if (ch >= 'a' && ch <= 'f')
+    {
+        val = ch - 'a';
+        val += 10;
+    }
+
+    return val;
+}
--- a/SerialInterfaceProtocol.h	Thu Sep 01 04:15:40 2016 +0000
+++ b/SerialInterfaceProtocol.h	Fri Sep 02 02:39:04 2016 +0000
@@ -5,8 +5,8 @@
 
 #include "mbed.h"
 #include "stdint.h"
-#include "CommandPacket.h"
 #include "RingBuffer.h"
+#include "CommandPacket2.h"
 
 #define SIP_CMD_VECTOR_TABLE_SZ 256
 #define SIP_MAX_RESP_LEN 256
@@ -15,10 +15,36 @@
 typedef int (*callback_func)(uint8_t *payload, uint8_t payload_length, uint8_t *response, uint8_t *response_length); 
 typedef CircularBuffer<uint8_t> SerialBuffer_t;
 
+uint8_t hexchar_to_uint8(uint8_t ch);
+
 class SerialInterfaceProtocol
 {
 public:
     // namespace
+    typedef enum
+    {
+        NONE = 0,
+        SFLAG,
+        COMMAND_H,
+        COMMAND_L,
+        LENGTH_H,
+        LENGTH_L,
+        PAYLOAD_H,
+        PAYLOAD_L,
+        CHECKSUM_H,
+        CHECKSUM_L,
+        EFLAG
+    } State_t;
+
+    typedef enum
+    {
+        NO_ERROR = 0,
+        INVALID_SFLAG_ERROR,
+        INVALID_EFLAG_ERROR,
+        INVALID_CMD_ERROR,
+        INVALID_CS_ERROR,
+        INVALID_EXEC_ERROR
+    } Error_t;
     
 protected:
     // internal variable
@@ -27,10 +53,15 @@
     // buffered interface
     SerialBuffer_t *SerialInputBuffer;
     SerialBuffer_t *SerialOutputBuffer;
-    CommandPacket PacketBuffer;
+    
+    // internal packet buffer (the SIP could issue one command at a time)
+    CommandPacket2 PacketBuffer;
     
     // state machine
-    CommandPacket::State_t state;
+    State_t state;
+    
+    // error code
+    Error_t errno;
     
     // internal state
     bool isChecksumEnabled;