93 lines
3.8 KiB
C#
93 lines
3.8 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|