Just a small test for frames and serial (RS232) communication, with ideas from http://eli.thegreenplace.net/2009/08/20/frames-and-protocols-for-the-serial-port-in-python/

Dependencies:   mbed

Revision:
0:566fc5f530fe
diff -r 000000000000 -r 566fc5f530fe parser.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/parser.c	Wed May 02 06:01:00 2012 +0000
@@ -0,0 +1,113 @@
+/*
+ *
+ */
+
+#include "mbed.h"
+#include "parser.h"
+
+int wrap_protocol(char *c, string *message, list<string> *messages, char header, char footer, char dle ) {
+
+    static int state = 0;
+    static int dle_state = 0;
+    static int index;
+    static int size;
+
+
+    switch (state) {
+        case 0: // start sending a header if there is a valid message available
+            if (!messages->empty()) {
+                *message =  messages->front();
+                messages->pop_front();      // now that we have the message, delete it from the list
+                index = 0;                  // initialize sending the actual message
+                size = message->size();
+                state = 1;
+                *c = header;
+                return WRAP_SEND;
+            }
+            return WRAP_ABORT;
+
+        case 1:
+            if ((size == 0) || (index==size)) {
+                *c = footer;
+                state = 0;
+                return WRAP_FINISHED;
+            }
+
+            *c = (*message)[index];
+
+            if ( dle_state == 1 ) {
+                dle_state = 0;
+                index++;
+                return WRAP_SEND;
+            }
+
+            if ( (*c == header) || (*c == footer) || (*c == dle) ) {
+                dle_state = 1;
+                *c = dle;
+                return WRAP_SEND;
+            }
+
+            index++;
+            return WRAP_SEND;
+    }
+
+    // if we reach this point, something went wrong!
+    return WRAP_ABORT;
+}
+
+void unwrap_protocol(char *c, string *buffer, list<string> *messages, unsigned int max_message_size,
+                     unsigned int max_messages, char header, char footer, char dle ) {
+
+    // these are needed for the internal state of the function
+    // they are also the reaseon, why this function can only be used in exactly one location
+    // i.e. the interrupt routine for receiving characters from the RS232
+    static int state = 0;
+    static int dle_state = 0;
+
+    switch (state) {
+        case 0:
+            if (*c == header) {
+                message_led=!message_led;
+                state = 1;
+            }
+            return;
+
+        case 1:
+            if (*c== header && dle_state==0) {
+                // new header that is not escaped will set e new message start
+                buffer->clear();
+                return;
+            }
+            if (*c == footer && dle_state==0 ) {
+                // a frame end is only a frame end, if the footer is not escaped
+                messages->push_back( *buffer );
+                buffer->clear();
+                state = 0;
+                message_led=!message_led;
+                return;
+            }
+
+            // check length of buffer; clear, if too large; restart search for header!
+            if (buffer->length() > max_message_size) {
+                // prevent buffer overflows if someone is flooding us with characters
+                buffer->clear();
+                state=0;
+                return;
+            }
+
+            if (*c == dle && dle_state==0) {
+                // the next character is "escaped" and is part of the message
+                dle_state = 1;
+                return;
+            }
+
+            // probably the easiest and quickest way of resetting the dle_state
+            dle_state = 0;
+
+            // in all other cases, we found a new character and append it to the buffer
+            *buffer += *c;
+    }
+}
+
+
+