using System.IO.Ports; using CliWrap; using InnovEnergy.Lib.Protocols.Modbus.Protocol; namespace InnovEnergy.Lib.Protocols.Modbus.Channels; public class SerialPortChannel : ConnectionChannel { private readonly Func _Open; public SerialPortChannel(String portName, Int32 baudRate, Parity parity, Int32 dataBits, Int32 stopBits, Boolean closeAfterSuccessfulRead = false, Boolean closeAfterSuccessfulWrite = false) : base( closeAfterSuccessfulRead, closeAfterSuccessfulWrite ) { var sb = stopBits switch { 0 => StopBits.None, 1 => StopBits.One, 2 => StopBits.Two, _ => StopBits.OnePointFive }; _Open = () => { var serialPort = new SerialPort(portName, baudRate, parity, dataBits, sb); serialPort.Open(); return serialPort; }; } protected override SerialPort Open() => _Open(); protected override void Close(SerialPort serialPort) => serialPort.Dispose(); protected override IReadOnlyList Read(SerialPort serialPort, Int32 nBytes) { var buffer = new Byte[nBytes]; var bytesReceived = 0; do { var received = serialPort.Read(buffer, bytesReceived, nBytes - bytesReceived); if (received < 0) throw new NotConnectedException("Serial Connection has been closed"); bytesReceived += received; } while (bytesReceived < nBytes); return buffer; } protected override void Write(SerialPort serialPort, IReadOnlyList data) { var array = data.ToArray(); serialPort.Write(array, 0, array.Length); } }