private EchoStatus ProcessEcho(int echoLength) { if (port == null || messageProcessor == null) { throw new InvalidOperationException(); } var data = ReadData(echoLength, true); if (data.Length == 0) { logger.ErrorFormat("No data read from port"); return(EchoStatus.None); } // if the first byte is a NAK (15) then return a NAK and add whatever additional data was read to the buffer if (data[0] == (byte)EchoStatus.NAK) { logger.DebugFormat("RX: {0}", Utilities.ByteArrayToString(data)); if (data.Length > 1) { int remainingCount = data.Length - 1; var remainingData = new byte[remainingCount]; Array.Copy(data, 1, remainingData, 0, remainingCount); lock (buffer) buffer.AddRange(remainingData); ProcessData(); //process the rest of the data stream } return(EchoStatus.NAK); } // scan until a MESSAGE START byte (02) is detected, which should be the first byte int offset = 0; while (offset < data.Length) { if (data[offset++] == Constants.MessageStartByte) { break; } } // exit if no MESSAGE START byte detected if (offset >= data.Length) { logger.DebugFormat("RX: {0} ERROR - Failed to find MESSAGE START byte (02)", Utilities.ByteArrayToString(data)); return(EchoStatus.Unknown); } logger.DebugFormat("RX: {0}", Utilities.ByteArrayToString(data)); // warn about any skipped bytes if (offset > 1) { logger.WarnFormat("Skipping {0} bytes to '{1}', discarded '{2}'", offset - 1, Utilities.ByteArrayToString(data, offset - 1), Utilities.ByteArrayToString(data, 0, offset - 1)); } // process the echo and decode the trailing status byte int count; if (messageProcessor.ProcessEcho(data, offset, out count)) { int j = offset + count; byte result = j < data.Length ? data[j] : Byte.MinValue; j += 1; if (data.Length > j) // if there's data beyond the echo then add it to the buffer { int remainingCount = data.Length - j; var remainingData = new byte[remainingCount]; Array.Copy(data, j, remainingData, 0, remainingCount); lock (buffer) buffer.AddRange(remainingData); ProcessData(); //process the rest of the data stream } if (result == (byte)EchoStatus.ACK) { messageProcessor.SetEchoStatus(EchoStatus.ACK); logger.DebugFormat("PLM: {0} ACK", Utilities.ByteArrayToString(data, offset - 1, count + 2)); // +1 for MESSAGE START byte (02), +1 for ACK byte (06) return(EchoStatus.ACK); } if (result == (byte)EchoStatus.NAK) { logger.DebugFormat("PLM: {0} NAK", Utilities.ByteArrayToString(data, offset - 1, count + 2)); // +1 for MESSAGE START byte (02), +1 for NAK byte (15) messageProcessor.SetEchoStatus(EchoStatus.NAK); return(EchoStatus.NAK); } logger.DebugFormat("PLM: {0} Unknown trailing byte", Utilities.ByteArrayToString(data, offset - 1, count + 2)); // +1 for MESSAGE START byte (02), +1 for unknown byte messageProcessor.SetEchoStatus(EchoStatus.Unknown); return(EchoStatus.Unknown); } logger.DebugFormat("PLM: {0} Echo mismatch", Utilities.ByteArrayToString(data, offset - 1)); return(EchoStatus.Unknown); }