using System; namespace SharpModbus { public class ModbusTCPWrapper : IModbusWrapper { private readonly IModbusCommand wrapped; private readonly ushort transactionId; public byte Code { get { return wrapped.Code; } } public byte Slave { get { return wrapped.Slave; } } public ushort Address { get { return wrapped.Address; } } public IModbusCommand Wrapped { get { return wrapped; } } public ushort TransactionId { get { return transactionId; } } public int RequestLength { get { return wrapped.RequestLength + 6; } } public int ResponseLength { get { return wrapped.ResponseLength + 6; } } public ModbusTCPWrapper(IModbusCommand wrapped, ushort transactionId) { this.wrapped = wrapped; this.transactionId = transactionId; } public void FillRequest(byte[] request, int offset) { request[offset + 0] = ModbusUtils.High(transactionId); request[offset + 1] = ModbusUtils.Low(transactionId); request[offset + 2] = 0; request[offset + 3] = 0; request[offset + 4] = ModbusUtils.High(wrapped.RequestLength); request[offset + 5] = ModbusUtils.Low(wrapped.RequestLength); wrapped.FillRequest(request, offset + 6); } public object ParseResponse(byte[] response, int offset) { Tools.AssertEqual(ModbusUtils.GetUShort(response, offset + 0), transactionId, "TransactionId mismatch got {0} expected {1}"); Tools.AssertEqual(ModbusUtils.GetUShort(response, offset + 2), 0, "Zero mismatch got {0} expected {1}"); Tools.AssertEqual(ModbusUtils.GetUShort(response, offset + 4), wrapped.ResponseLength, "Length mismatch got {0} expected {1}"); return wrapped.ParseResponse(response, offset + 6); } public object ApplyTo(IModbusModel model) { return wrapped.ApplyTo(model); } public void FillResponse(byte[] response, int offset, object value) { response[offset + 0] = ModbusUtils.High(transactionId); response[offset + 1] = ModbusUtils.Low(transactionId); response[offset + 2] = 0; response[offset + 3] = 0; response[offset + 4] = ModbusUtils.High(wrapped.ResponseLength); response[offset + 5] = ModbusUtils.Low(wrapped.ResponseLength); wrapped.FillResponse(response, offset + 6, value); } public byte[] GetException(byte code) { var exception = new byte[9]; exception[0] = ModbusUtils.High(transactionId); exception[1] = ModbusUtils.Low(transactionId); exception[2] = 0; exception[3] = 0; exception[4] = ModbusUtils.High(3); exception[5] = ModbusUtils.Low(3); exception[6 + 0] = wrapped.Slave; exception[6 + 1] = (byte)(wrapped.Code | 0x80); exception[6 + 2] = code; return exception; } public void CheckException(byte[] response, int count) { if (count < 9) Tools.Throw("Partial packet exception got {0} expected >= {1}", count, 9); var offset = 6; var code = response[offset + 1]; if ((code & 0x80) != 0) { Tools.AssertEqual(response[offset + 0], wrapped.Slave, "Slave mismatch got {0} expected {1}"); Tools.AssertEqual(code & 0x7F, wrapped.Code, "Code mismatch got {0} expected {1}"); throw new ModbusException(response[offset + 2]); } } public override string ToString() { return string.Format("[ModbusTCPWrapper Wrapped={0}, TransactionId={1}]", wrapped, transactionId); } } }