180 lines
5.1 KiB
C#
180 lines
5.1 KiB
C#
namespace Common.Hardware.Ports
|
|
{
|
|
using System;
|
|
using System.Collections.Concurrent;
|
|
using System.IO.Ports;
|
|
using System.Threading;
|
|
|
|
public abstract class SerialPortBase
|
|
{
|
|
private static readonly ConcurrentDictionary<String, System.IO.Ports.SerialPort> serialPorts
|
|
= new ConcurrentDictionary<String, System.IO.Ports.SerialPort>();
|
|
|
|
private readonly SerialPortSettings settings;
|
|
|
|
public SerialPortBase(SerialPortSettings settings)
|
|
{
|
|
this.settings = settings;
|
|
this.PortName = settings.PortName;
|
|
}
|
|
|
|
public event Action<String> Logging;
|
|
|
|
public String PortName { get; }
|
|
|
|
public Int32 ReadSize { get; private set; }
|
|
|
|
public virtual void Close()
|
|
{
|
|
try
|
|
{
|
|
this.ReadSize = default(Int32);
|
|
|
|
if (serialPorts.TryRemove(this.PortName, out var serialPort))
|
|
{
|
|
if (serialPort != null)
|
|
{
|
|
serialPort.Close();
|
|
serialPort.Dispose();
|
|
serialPort = null;
|
|
|
|
|
|
this.LogMessage($"Disconnected: {this}");
|
|
}
|
|
else
|
|
{
|
|
this.LogMessage($"{this.PortName} is null!");
|
|
}
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
this.LogMessage(e.ToString());
|
|
}
|
|
}
|
|
|
|
public virtual void EnsureConnected()
|
|
{
|
|
if (!this.TryGetSerialPort(out var serialPort))
|
|
{
|
|
this.Open();
|
|
}
|
|
}
|
|
|
|
public virtual void Open()
|
|
{
|
|
this.Close();
|
|
|
|
try
|
|
{
|
|
this.ReadSize = default(Int32);
|
|
|
|
var serialPort = new System.IO.Ports.SerialPort
|
|
{
|
|
BaudRate = this.settings.BaudRate,
|
|
DataBits = this.settings.DataBits,
|
|
Parity = this.settings.Parity,
|
|
PortName = this.settings.PortName,
|
|
StopBits = this.settings.StopBits
|
|
};
|
|
|
|
if (serialPorts.TryAdd(serialPort.PortName, serialPort))
|
|
{
|
|
serialPort.Open();
|
|
|
|
if (serialPort.IsOpen)
|
|
{
|
|
this.ReadSize = serialPort.ReadBufferSize;
|
|
}
|
|
|
|
this.LogMessage($"Connected: {this}");
|
|
}
|
|
else
|
|
{
|
|
this.LogMessage($"{this.PortName} can not be addedd!");
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
this.LogMessage(e.ToString());
|
|
}
|
|
}
|
|
|
|
public override String ToString()
|
|
=> serialPorts.TryGetValue(this.PortName, out var serialPort)
|
|
? $"{serialPort.PortName}, "
|
|
+ $"{serialPort.BaudRate}, "
|
|
+ $"{serialPort.DataBits}, "
|
|
+ $"{serialPort.Parity}, "
|
|
+ $"{serialPort.StopBits}"
|
|
: $"{this.settings.PortName}, "
|
|
+ $"{this.settings.BaudRate}, "
|
|
+ $"{this.settings.DataBits}, "
|
|
+ $"{this.settings.Parity}, "
|
|
+ $"{this.settings.StopBits}";
|
|
|
|
public virtual Byte[] Write(params Byte[] data)
|
|
{
|
|
this.Write(data, 0, data.Length);
|
|
|
|
return data;
|
|
}
|
|
|
|
protected void LogMessage(String message) => this.Logging?.Invoke(message);
|
|
|
|
protected Byte[] Read(Int32 sleep = 1)
|
|
{
|
|
Thread.Sleep(sleep);
|
|
|
|
var bytes = new Byte[0];
|
|
|
|
if (this.TryGetSerialPort(out var serialPort))
|
|
{
|
|
try
|
|
{
|
|
var buffer = new Byte[this.ReadSize];
|
|
var length = serialPort.Read(buffer, 0, this.ReadSize);
|
|
|
|
Array.Resize(ref bytes, length);
|
|
Array.Copy(buffer, 0, bytes, 0, length);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
this.LogMessage(e.ToString());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
this.LogMessage($"{this.PortName} dose not exists!");
|
|
}
|
|
|
|
return bytes;
|
|
}
|
|
|
|
protected void Write(Byte[] bytes, Int32 start, Int32 length, Int32 sleep = 1)
|
|
{
|
|
if (this.TryGetSerialPort(out var serialPort))
|
|
{
|
|
try
|
|
{
|
|
serialPort.Write(bytes, start, length);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
this.LogMessage(e.ToString());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
this.LogMessage($"{this.PortName} dose not exists!");
|
|
}
|
|
|
|
Thread.Sleep(sleep);
|
|
}
|
|
|
|
private Boolean TryGetSerialPort(out System.IO.Ports.SerialPort serialPort)
|
|
=> serialPorts.TryGetValue(this.PortName, out serialPort)
|
|
&& serialPort?.IsOpen == true;
|
|
}
|
|
}
|