64 lines
1.9 KiB
C#
64 lines
1.9 KiB
C#
using InnovEnergy.Lib.Protocols.Modbus.Protocol.Frames;
|
|
|
|
namespace InnovEnergy.Lib.Protocols.Modbus.Tcp;
|
|
|
|
internal static class ModbusTcpFrameExtensions
|
|
{
|
|
internal static ModbusTcpFrame ToModbusTcpFrame(this ModbusFrame frame, UInt16 transactionId)
|
|
{
|
|
var hdr = new MbapHeader(transactionId, frame.Data.Count);
|
|
return new ModbusTcpFrame(hdr, frame);
|
|
}
|
|
}
|
|
|
|
internal readonly struct ModbusTcpFrame
|
|
{
|
|
public MbapHeader Header => new MbapHeader(new ArraySegment<Byte>(_Data, 0, MbapHeader.Size));
|
|
public ModbusFrame Frame => new ModbusFrame(new ArraySegment<Byte>(_Data, MbapHeader.Size, _Data.Length - MbapHeader.Size));
|
|
|
|
public IReadOnlyList<Byte> Data => _Data;
|
|
|
|
private readonly Byte[] _Data;
|
|
|
|
public ModbusTcpFrame(MbapHeader header, ModbusFrame frame)
|
|
{
|
|
if (frame.Data.Count != header.FrameLength /* - 1*/) // TODO
|
|
throw new ArgumentException(nameof(header.FrameLength));
|
|
|
|
_Data = CreateData(header, frame);
|
|
}
|
|
|
|
public ModbusTcpFrame(Byte[] data)
|
|
{
|
|
_Data = data;
|
|
|
|
if (Frame.Data.Count != Header.FrameLength - 1)
|
|
throw new ArgumentException(nameof(Header.FrameLength));
|
|
}
|
|
|
|
|
|
private static Byte[] CreateData(MbapHeader header, ModbusFrame frame)
|
|
{
|
|
var hdl = header.Data.Count;
|
|
var fdl = frame.Data.Count;
|
|
|
|
var data = new Byte[hdl + fdl];
|
|
|
|
|
|
// TODO: avoid Array copy using ArraySegments?
|
|
|
|
Array.Copy(sourceArray: header.Data.Array!,
|
|
sourceIndex: header.Data.Offset,
|
|
destinationArray: data,
|
|
destinationIndex: 0,
|
|
length: hdl);
|
|
|
|
Array.Copy(sourceArray: frame.Data.Array!,
|
|
sourceIndex: frame.Data.Offset,
|
|
destinationArray: data,
|
|
destinationIndex: hdl,
|
|
length: fdl);
|
|
|
|
return data;
|
|
}
|
|
} |