Multiprocotol Terminalprogram (BAT)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
MultiTerm/MultiTerm.Protocols/Serial/SerialProtocol.cs

112 lines
3.7 KiB

using Common.Logging;
using CommunityToolkit.Mvvm.Messaging;
using MultiTerm.Protocols.Model;
using MultiTerm.Protocols.Types;
using RJCP.IO.Ports;
using System.Text;
namespace MultiTerm.Protocols.Serial;
public class SerialProtocol : CommunicationProtocol
{
public override ProtocolType ProtocolType => ProtocolType.Serial;
public override string InstanceIdentifier { get; protected set; } = string.Empty;
private ISerialProtocolSettings? serialSettings;
private SerialPortStream serialPort = new();
public SerialProtocol(ILogger logger, IMessenger messenger) : base(logger, messenger) { }
protected override bool InternalConnect(IProtocolSettings protocolSettings)
{
// check if settings are of correct type
if (protocolSettings is not ISerialProtocolSettings serialProtocolSettings)
{
this.serialSettings = null;
throw new ArgumentException($"Cannot connect due to wrong type of Protocol Settings. " +
$"Check parameter {nameof(protocolSettings)}' of '{nameof(InternalConnect)}()' in {nameof(SerialProtocol)}.");
}
// store locally
this.serialSettings = serialProtocolSettings;
// update identifier
this.InstanceIdentifier = this.serialSettings.PortName;
// create new serial port
this.serialPort = new()
{
// apply user settings, where needed converters are used
PortName = this.serialSettings.PortName,
BaudRate = this.serialSettings.BaudRate,
DataBits = this.serialSettings.DataBits,
Parity = new ParityLibraryEquivalentConverter().ConvertToLibraryType(this.serialSettings.Parity),
StopBits = new StopBitsLibraryEquivalentConverter().ConvertToLibraryType(this.serialSettings.StopBits),
Handshake = new HandshakeLibraryEquivalentConverter().ConvertToLibraryType(this.serialSettings.Handshake),
// define static settings
Encoding = Encoding.ASCII,
ReadTimeout = 500,
WriteTimeout = 500
};
// try opening serial port
try
{
serialPort.Open();
}
catch (Exception ex)
{
this.logger.LogException(ex, $"'{nameof(InternalConnect)}()'Opening serial port failed:", nameof(SerialProtocol));
return false;
}
return true;
}
protected override void InternalDisconnect()
{
serialPort.Close();
this.serialSettings = null;
}
protected override void InternalRead(CancellationToken ct)
{
while(ct.IsCancellationRequested == false)
{
// reads character based on configured encoding (here ASCII)
int readCharacter = serialPort.ReadChar();
if (readCharacter != -1) // -1 = timeout
{
// create extended char type
var character = new ExtendedChar((char)readCharacter);
// report new data with event
this.OnReceivedData(new ReceivedDataEventArgs(new ExtendedChar[] { character }));
}
}
}
protected override bool InternalSendBytes(byte[] bytes)
{
foreach (byte b in bytes)
{
try
{
serialPort.WriteByte(b);
}
// When the Serial Port is closed and InvalidOperationException is thrown
catch(InvalidOperationException)
{
this.OnUnintentionallyDisconnected();
}
}
return true;
}
public static IEnumerable<string> GetPortNames()
{
return SerialPortStream.GetPortNames();
}
}