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@0:566fc5f530fe, 2012-05-02 (annotated)
- Committer:
- janwesterkamp
- Date:
- Wed May 02 06:01:00 2012 +0000
- Revision:
- 0:566fc5f530fe
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
janwesterkamp | 0:566fc5f530fe | 1 | /* |
janwesterkamp | 0:566fc5f530fe | 2 | * |
janwesterkamp | 0:566fc5f530fe | 3 | */ |
janwesterkamp | 0:566fc5f530fe | 4 | |
janwesterkamp | 0:566fc5f530fe | 5 | #include "mbed.h" |
janwesterkamp | 0:566fc5f530fe | 6 | #include "parser.h" |
janwesterkamp | 0:566fc5f530fe | 7 | |
janwesterkamp | 0:566fc5f530fe | 8 | int wrap_protocol(char *c, string *message, list<string> *messages, char header, char footer, char dle ) { |
janwesterkamp | 0:566fc5f530fe | 9 | |
janwesterkamp | 0:566fc5f530fe | 10 | static int state = 0; |
janwesterkamp | 0:566fc5f530fe | 11 | static int dle_state = 0; |
janwesterkamp | 0:566fc5f530fe | 12 | static int index; |
janwesterkamp | 0:566fc5f530fe | 13 | static int size; |
janwesterkamp | 0:566fc5f530fe | 14 | |
janwesterkamp | 0:566fc5f530fe | 15 | |
janwesterkamp | 0:566fc5f530fe | 16 | switch (state) { |
janwesterkamp | 0:566fc5f530fe | 17 | case 0: // start sending a header if there is a valid message available |
janwesterkamp | 0:566fc5f530fe | 18 | if (!messages->empty()) { |
janwesterkamp | 0:566fc5f530fe | 19 | *message = messages->front(); |
janwesterkamp | 0:566fc5f530fe | 20 | messages->pop_front(); // now that we have the message, delete it from the list |
janwesterkamp | 0:566fc5f530fe | 21 | index = 0; // initialize sending the actual message |
janwesterkamp | 0:566fc5f530fe | 22 | size = message->size(); |
janwesterkamp | 0:566fc5f530fe | 23 | state = 1; |
janwesterkamp | 0:566fc5f530fe | 24 | *c = header; |
janwesterkamp | 0:566fc5f530fe | 25 | return WRAP_SEND; |
janwesterkamp | 0:566fc5f530fe | 26 | } |
janwesterkamp | 0:566fc5f530fe | 27 | return WRAP_ABORT; |
janwesterkamp | 0:566fc5f530fe | 28 | |
janwesterkamp | 0:566fc5f530fe | 29 | case 1: |
janwesterkamp | 0:566fc5f530fe | 30 | if ((size == 0) || (index==size)) { |
janwesterkamp | 0:566fc5f530fe | 31 | *c = footer; |
janwesterkamp | 0:566fc5f530fe | 32 | state = 0; |
janwesterkamp | 0:566fc5f530fe | 33 | return WRAP_FINISHED; |
janwesterkamp | 0:566fc5f530fe | 34 | } |
janwesterkamp | 0:566fc5f530fe | 35 | |
janwesterkamp | 0:566fc5f530fe | 36 | *c = (*message)[index]; |
janwesterkamp | 0:566fc5f530fe | 37 | |
janwesterkamp | 0:566fc5f530fe | 38 | if ( dle_state == 1 ) { |
janwesterkamp | 0:566fc5f530fe | 39 | dle_state = 0; |
janwesterkamp | 0:566fc5f530fe | 40 | index++; |
janwesterkamp | 0:566fc5f530fe | 41 | return WRAP_SEND; |
janwesterkamp | 0:566fc5f530fe | 42 | } |
janwesterkamp | 0:566fc5f530fe | 43 | |
janwesterkamp | 0:566fc5f530fe | 44 | if ( (*c == header) || (*c == footer) || (*c == dle) ) { |
janwesterkamp | 0:566fc5f530fe | 45 | dle_state = 1; |
janwesterkamp | 0:566fc5f530fe | 46 | *c = dle; |
janwesterkamp | 0:566fc5f530fe | 47 | return WRAP_SEND; |
janwesterkamp | 0:566fc5f530fe | 48 | } |
janwesterkamp | 0:566fc5f530fe | 49 | |
janwesterkamp | 0:566fc5f530fe | 50 | index++; |
janwesterkamp | 0:566fc5f530fe | 51 | return WRAP_SEND; |
janwesterkamp | 0:566fc5f530fe | 52 | } |
janwesterkamp | 0:566fc5f530fe | 53 | |
janwesterkamp | 0:566fc5f530fe | 54 | // if we reach this point, something went wrong! |
janwesterkamp | 0:566fc5f530fe | 55 | return WRAP_ABORT; |
janwesterkamp | 0:566fc5f530fe | 56 | } |
janwesterkamp | 0:566fc5f530fe | 57 | |
janwesterkamp | 0:566fc5f530fe | 58 | void unwrap_protocol(char *c, string *buffer, list<string> *messages, unsigned int max_message_size, |
janwesterkamp | 0:566fc5f530fe | 59 | unsigned int max_messages, char header, char footer, char dle ) { |
janwesterkamp | 0:566fc5f530fe | 60 | |
janwesterkamp | 0:566fc5f530fe | 61 | // these are needed for the internal state of the function |
janwesterkamp | 0:566fc5f530fe | 62 | // they are also the reaseon, why this function can only be used in exactly one location |
janwesterkamp | 0:566fc5f530fe | 63 | // i.e. the interrupt routine for receiving characters from the RS232 |
janwesterkamp | 0:566fc5f530fe | 64 | static int state = 0; |
janwesterkamp | 0:566fc5f530fe | 65 | static int dle_state = 0; |
janwesterkamp | 0:566fc5f530fe | 66 | |
janwesterkamp | 0:566fc5f530fe | 67 | switch (state) { |
janwesterkamp | 0:566fc5f530fe | 68 | case 0: |
janwesterkamp | 0:566fc5f530fe | 69 | if (*c == header) { |
janwesterkamp | 0:566fc5f530fe | 70 | message_led=!message_led; |
janwesterkamp | 0:566fc5f530fe | 71 | state = 1; |
janwesterkamp | 0:566fc5f530fe | 72 | } |
janwesterkamp | 0:566fc5f530fe | 73 | return; |
janwesterkamp | 0:566fc5f530fe | 74 | |
janwesterkamp | 0:566fc5f530fe | 75 | case 1: |
janwesterkamp | 0:566fc5f530fe | 76 | if (*c== header && dle_state==0) { |
janwesterkamp | 0:566fc5f530fe | 77 | // new header that is not escaped will set e new message start |
janwesterkamp | 0:566fc5f530fe | 78 | buffer->clear(); |
janwesterkamp | 0:566fc5f530fe | 79 | return; |
janwesterkamp | 0:566fc5f530fe | 80 | } |
janwesterkamp | 0:566fc5f530fe | 81 | if (*c == footer && dle_state==0 ) { |
janwesterkamp | 0:566fc5f530fe | 82 | // a frame end is only a frame end, if the footer is not escaped |
janwesterkamp | 0:566fc5f530fe | 83 | messages->push_back( *buffer ); |
janwesterkamp | 0:566fc5f530fe | 84 | buffer->clear(); |
janwesterkamp | 0:566fc5f530fe | 85 | state = 0; |
janwesterkamp | 0:566fc5f530fe | 86 | message_led=!message_led; |
janwesterkamp | 0:566fc5f530fe | 87 | return; |
janwesterkamp | 0:566fc5f530fe | 88 | } |
janwesterkamp | 0:566fc5f530fe | 89 | |
janwesterkamp | 0:566fc5f530fe | 90 | // check length of buffer; clear, if too large; restart search for header! |
janwesterkamp | 0:566fc5f530fe | 91 | if (buffer->length() > max_message_size) { |
janwesterkamp | 0:566fc5f530fe | 92 | // prevent buffer overflows if someone is flooding us with characters |
janwesterkamp | 0:566fc5f530fe | 93 | buffer->clear(); |
janwesterkamp | 0:566fc5f530fe | 94 | state=0; |
janwesterkamp | 0:566fc5f530fe | 95 | return; |
janwesterkamp | 0:566fc5f530fe | 96 | } |
janwesterkamp | 0:566fc5f530fe | 97 | |
janwesterkamp | 0:566fc5f530fe | 98 | if (*c == dle && dle_state==0) { |
janwesterkamp | 0:566fc5f530fe | 99 | // the next character is "escaped" and is part of the message |
janwesterkamp | 0:566fc5f530fe | 100 | dle_state = 1; |
janwesterkamp | 0:566fc5f530fe | 101 | return; |
janwesterkamp | 0:566fc5f530fe | 102 | } |
janwesterkamp | 0:566fc5f530fe | 103 | |
janwesterkamp | 0:566fc5f530fe | 104 | // probably the easiest and quickest way of resetting the dle_state |
janwesterkamp | 0:566fc5f530fe | 105 | dle_state = 0; |
janwesterkamp | 0:566fc5f530fe | 106 | |
janwesterkamp | 0:566fc5f530fe | 107 | // in all other cases, we found a new character and append it to the buffer |
janwesterkamp | 0:566fc5f530fe | 108 | *buffer += *c; |
janwesterkamp | 0:566fc5f530fe | 109 | } |
janwesterkamp | 0:566fc5f530fe | 110 | } |
janwesterkamp | 0:566fc5f530fe | 111 | |
janwesterkamp | 0:566fc5f530fe | 112 | |
janwesterkamp | 0:566fc5f530fe | 113 |