internal override ModbusResponse DeserializeResponse(ResponseBuffer buffer, ModbusRequest request, int timeout) { ModbusResponse result = null; while (result == null || result is ModbusCommErrorResponse responseCommErrorMessage && responseCommErrorMessage.ErrorCode != ModbusCommErrorCode.ResponseTimeout) { if (buffer.Count > 0) { errorBuffer.Add(buffer[0]); buffer.RemoveAt(0); } buffer.Read(timeout); try { while (buffer[0] != 0x3a) { errorBuffer.Add(buffer[0]); buffer.RemoveAt(0); buffer.Read(timeout); } } catch { return(new ModbusCommErrorResponse(ModbusCommErrorCode.ResponseAsciiStartError, errorBuffer.Concat(buffer), request)); } result = base.DeserializeResponse(buffer, request, timeout); } if (result is ModbusCommErrorResponse responseCommError) { result = new ModbusCommErrorResponse(responseCommError.ErrorCode, errorBuffer.Concat(responseCommError.ReceivedBytes), request); } else { var asciiEnd = buffer.Read(2, timeout); if (!asciiEnd.SequenceEqual(new byte[] { 13, 10 })) { return(new ModbusCommErrorResponse(ModbusCommErrorCode.ResponseAsciiEndError, buffer, request)); } if (errorBuffer.Count > 0) { RaiseUnrecognized(buffer.Channel, errorBuffer.ToArray()); errorBuffer.Clear(); } } return(result); }
internal virtual IEnumerable <byte> Read(ResponseBuffer buffer, int index, int count, int timeout) { if (index + count > buffer.Count) { buffer.Read((uint)(index + count - buffer.Count), timeout); } return(buffer.Skip(index).Take(count)); }
internal virtual byte Read(ResponseBuffer buffer, int index, int timeout) { if (index >= buffer.Count) { buffer.Read((uint)(index - buffer.Count + 1), timeout); } return(buffer[index]); }
internal override byte Read(ResponseBuffer buffer, int index, int timeout) { if (index * 2 >= buffer.Count - 2) { buffer.Read((uint)(index * 2 - buffer.Count + 3), timeout); } return(byte.Parse(Encoding.ASCII.GetString(buffer.Skip(index * 2 + 1).Take(2).ToArray()), System.Globalization.NumberStyles.HexNumber, null)); }
internal override IEnumerable <byte> Read(ResponseBuffer buffer, int index, int count, int timeout) { if ((index + count) * 2 > buffer.Count - 1) { buffer.Read((uint)((index + count) * 2 - buffer.Count + 1), timeout); } var bytes = buffer.Skip(index * 2 + 1).Take(count * 2).ToArray(); for (int i = 0; i < count; i++) { yield return(byte.Parse(Encoding.ASCII.GetString(bytes, i * 2, 2), System.Globalization.NumberStyles.HexNumber, null)); } }
private void RunReceive(ModbusChannel channel) { lock (responseWaitHandles) { if (!isReceiving) { isReceiving = true; try { var readBuffer = new ResponseBuffer(channel); while (responseWaitHandles.Count > 0) { if (errorBuffer.Count >= 256) { RaiseUnrecognized(channel, errorBuffer.ToArray()); errorBuffer.Clear(); } readBuffer.Read(2, 0); ushort transactionID = (ushort)((readBuffer[0] << 8) | readBuffer[1]); if (!responseWaitHandles.TryGetValue(transactionID, out var responseWaitHandle)) { errorBuffer.AddRange(readBuffer); readBuffer.Clear(); continue; } readBuffer.Read(2, responseWaitHandle.Timeout); if (readBuffer[2] != 0 || readBuffer[3] != 0) { errorBuffer.AddRange(readBuffer); readBuffer.Clear(); responseWaitHandle.Response = new ModbusCommErrorResponse(ModbusCommErrorCode.ModbusTcpSymbolError, errorBuffer, responseWaitHandle.Request); continue; } var result = base.DeserializeResponse(readBuffer, responseWaitHandle.Request, responseWaitHandle.Timeout); if (result is ModbusCommErrorResponse responseCommErrorMessage) { errorBuffer.AddRange(readBuffer.Take(4)); readBuffer.RemoveRange(0, 4); responseWaitHandle.Response = result; continue; } if (readBuffer.Count - 6 != (ushort)((readBuffer[4] << 8) | readBuffer[5])) { errorBuffer.AddRange(readBuffer.Take(4)); readBuffer.RemoveRange(0, 4); responseWaitHandle.Response = new ModbusCommErrorResponse(ModbusCommErrorCode.ResponseTcpLengthDoNotMatch, readBuffer, responseWaitHandle.Request); continue; } if (errorBuffer.Count > 0) { RaiseUnrecognized(channel, errorBuffer.ToArray()); errorBuffer.Clear(); } responseWaitHandle.ResponseBuffer.AddRange(readBuffer); readBuffer.Clear(); responseWaitHandle.Response = result; responseWaitHandle.Set(); this.responseWaitHandles.Remove(transactionID); } } catch { } isReceiving = false; } } }