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; } } }