// State machine for decoding a message private void DecodeRxByte(byte Data) { switch (_State) { // Check to see if first header matches case FramerState.SearchHeader1: if (Data == MESSAGE_HEADER1) { _State = FramerState.SearchHeader2; } break; // Check to see if second header matches case FramerState.SearchHeader2: if (Data == MESSAGE_HEADER2) { _State = FramerState.SearchLength; } break; // Record the length case FramerState.SearchLength: _Length = Data; _Data = new List <byte>(); _State = FramerState.SearchData; break; // Collect Data for payload case FramerState.SearchData: if (_Length > 0) { _Data.Add(Data); _Length--; // If there is data left, stay in SearchData // If all data has been collected, next byte will be the checksum _State = (_Length > 0) ? FramerState.SearchData : FramerState.SearchChecksum; } break; // Calculate checksum case FramerState.SearchChecksum: { byte checksum = 0; // Add headers and length checksum += MESSAGE_HEADER1; checksum += MESSAGE_HEADER2; checksum += (byte)(_Data.Count & 0xFF); // Add the command and payload for (int index = 0; index < _Data.Count; index++) { checksum += _Data[index]; } // Negate checksum checksum = (byte)((~checksum) & (0xFF)); // Does the checksum match if (checksum == Data) { // Notify upper layer that a full message // has been received OnSerialMessageReceived(_Data); } } break; } }
// Constructor public SerialFramer() { // Set initial state of decode machine _State = FramerState.SearchHeader1; }