2023-02-16 12:57:06 +00:00
|
|
|
using InnovEnergy.Lib.Protocols.Modbus.Protocol.Frames.Accessors;
|
|
|
|
|
|
|
|
namespace InnovEnergy.Lib.Protocols.Modbus.Protocol.Frames;
|
|
|
|
|
|
|
|
using Fc = FunctionCode;
|
|
|
|
|
|
|
|
|
|
|
|
public class ModbusFrame
|
|
|
|
{
|
|
|
|
internal const Int32 MinSize = 2;
|
|
|
|
|
|
|
|
public ArraySegment<Byte> Data { get; }
|
|
|
|
|
|
|
|
public MbByte SlaveAddress => Data.ByteAt(0);
|
|
|
|
public MbByte<FunctionCode> FunctionCode => Data.ByteAt<FunctionCode>(1);
|
|
|
|
|
|
|
|
|
|
|
|
internal ModbusFrame(Int32 size)
|
|
|
|
{
|
2023-03-10 12:46:46 +00:00
|
|
|
Data = new Byte[size];
|
2023-02-16 12:57:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
internal ModbusFrame(ArraySegment<Byte> data)
|
|
|
|
{
|
|
|
|
if (data.Count < MinSize) throw new ArgumentException(nameof(data));
|
|
|
|
|
|
|
|
Data = data;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
protected void AssertFunctionCode(FunctionCode expectedFc)
|
|
|
|
{
|
|
|
|
var actualFc = FunctionCode.Get();
|
|
|
|
|
|
|
|
if (actualFc == (expectedFc | Fc.Error))
|
|
|
|
throw new ErrorResponseException(ExceptionCode.IllegalDataValue, actualFc); // TODO parse exception code
|
|
|
|
|
|
|
|
if (actualFc != expectedFc)
|
|
|
|
throw new UnexpectedResponseFieldException(field: nameof(FunctionCode),
|
|
|
|
expected: expectedFc.ToString(),
|
|
|
|
actual: Enum.GetName(typeof(FunctionCode), actualFc)!);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void AssertSlaveAddress(Byte expectedSlaveAddress)
|
|
|
|
{
|
|
|
|
var actualSlaveAddress = SlaveAddress.Get();
|
|
|
|
|
|
|
|
if (actualSlaveAddress != expectedSlaveAddress)
|
|
|
|
throw new UnexpectedResponseFieldException(field: nameof(SlaveAddress),
|
|
|
|
expected: expectedSlaveAddress,
|
|
|
|
actual: actualSlaveAddress);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|