using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using log4net;
using Modbus.Message;
using Modbus.Utility;
namespace Modbus.IO
{
///
/// Refined Abstraction - http://en.wikipedia.org/wiki/Bridge_Pattern
///
internal class ModbusAsciiTransport : ModbusSerialTransport
{
private static readonly ILog _logger = LogManager.GetLogger(typeof(ModbusAsciiTransport));
internal ModbusAsciiTransport(IStreamResource streamResource)
: base(streamResource)
{
Debug.Assert(streamResource != null, "Argument streamResource cannot be null.");
}
internal override byte[] BuildMessageFrame(IModbusMessage message)
{
List frame = new List();
frame.Add((byte)':');
frame.AddRange(ModbusUtility.GetAsciiBytes(message.SlaveAddress));
frame.AddRange(ModbusUtility.GetAsciiBytes(message.ProtocolDataUnit));
frame.AddRange(ModbusUtility.GetAsciiBytes(ModbusUtility.CalculateLrc(message.MessageFrame)));
frame.AddRange(Encoding.ASCII.GetBytes(Modbus.NewLine.ToCharArray()));
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()
{
return CreateResponse(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);
_logger.InfoFormat("RX: {0}", StringUtility.Join(", ", frame));
if (frame.Length < 3)
throw new IOException("Premature end of stream, message truncated.");
return frame;
}
}
}