2021-12-15 16:16:22 +00:00
|
|
|
|
namespace Modbus.IO
|
|
|
|
|
{
|
|
|
|
|
using System.Diagnostics;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Text;
|
|
|
|
|
|
|
|
|
|
using Message;
|
|
|
|
|
using Utility;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Refined Abstraction - http://en.wikipedia.org/wiki/Bridge_Pattern
|
|
|
|
|
/// </summary>
|
|
|
|
|
internal class ModbusAsciiTransport : ModbusSerialTransport
|
|
|
|
|
{
|
|
|
|
|
internal ModbusAsciiTransport(IStreamResource streamResource)
|
|
|
|
|
: base(streamResource)
|
|
|
|
|
{
|
|
|
|
|
Debug.Assert(streamResource != null, "Argument streamResource cannot be null.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal override byte[] BuildMessageFrame(IModbusMessage message)
|
|
|
|
|
{
|
|
|
|
|
var msgFrame = message.MessageFrame;
|
|
|
|
|
|
|
|
|
|
var msgFrameAscii = ModbusUtility.GetAsciiBytes(msgFrame);
|
|
|
|
|
var lrcAscii = ModbusUtility.GetAsciiBytes(ModbusUtility.CalculateLrc(msgFrame));
|
|
|
|
|
var nlAscii = Encoding.UTF8.GetBytes(Modbus.NewLine.ToCharArray());
|
|
|
|
|
|
|
|
|
|
var frame = new MemoryStream(1 + msgFrameAscii.Length + lrcAscii.Length + nlAscii.Length);
|
|
|
|
|
frame.WriteByte((byte)':');
|
|
|
|
|
frame.Write(msgFrameAscii, 0, msgFrameAscii.Length);
|
|
|
|
|
frame.Write(lrcAscii, 0, lrcAscii.Length);
|
|
|
|
|
frame.Write(nlAscii, 0, nlAscii.Length);
|
|
|
|
|
|
|
|
|
|
return frame.ToArray();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal override bool ChecksumsMatch(IModbusMessage message, byte[] messageFrame)
|
|
|
|
|
{
|
|
|
|
|
return ModbusUtility.CalculateLrc(message.MessageFrame) == messageFrame[messageFrame.Length - 1];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal override byte[] ReadRequest()
|
|
|
|
|
{
|
|
|
|
|
return ReadRequestResponse();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal override IModbusMessage ReadResponse<T>()
|
|
|
|
|
{
|
|
|
|
|
return CreateResponse<T>(ReadRequestResponse());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal byte[] ReadRequestResponse()
|
|
|
|
|
{
|
|
|
|
|
// read message frame, removing frame start ':'
|
|
|
|
|
string frameHex = StreamResourceUtility.ReadLine(StreamResource).Substring(1);
|
|
|
|
|
|
|
|
|
|
// convert hex to bytes
|
|
|
|
|
byte[] frame = ModbusUtility.HexToBytes(frameHex);
|
2022-09-14 12:47:12 +00:00
|
|
|
|
//Debug.WriteLine($"RX: {string.Join(", ", frame)}");
|
2021-12-15 16:16:22 +00:00
|
|
|
|
|
|
|
|
|
if (frame.Length < 3)
|
|
|
|
|
{
|
|
|
|
|
throw new IOException("Premature end of stream, message truncated.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return frame;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|