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/
parser.c
- Committer:
- janwesterkamp
- Date:
- 2012-05-02
- Revision:
- 0:566fc5f530fe
File content as of revision 0:566fc5f530fe:
/* * */ #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; } }