implemented abstract CommunicationProtocol and enhanced ICommunicationProtocol

master
Jonas Arnold 3 years ago
parent 867cc15529
commit b05f3ff137
  1. 96
      MultiTerm.Protocols/CommunicationProtocol.cs
  2. 43
      MultiTerm.Protocols/ICommunicationProtocol.cs
  3. 4
      MultiTerm.Protocols/MultiTerm.Protocols.csproj
  4. 13
      MultiTerm.Protocols/ReceivedDataEventArgs.cs
  5. 13
      MultiTerm.Protocols/SentDataEventArgs.cs

@ -0,0 +1,96 @@
using Common.Logging;
namespace MultiTerm.Protocols;
public abstract class CommunicationProtocol : ICommunicationProtocol
{
public string NewlineSequenceOnSend { get; set; }
public string NewlineOnReceivedSequence { get; set; }
protected ILogger logger;
private CancellationTokenSource cancellationTokenSource;
private Thread? readingThread;
public event EventHandler<ReceivedDataEventArgs>? ReceivedDataEvent;
public event EventHandler<SentDataEventArgs>? SentDataEvent;
public CommunicationProtocol(ILogger logger)
{
// initialize with empty string, must be correctly initalized by factory
this.NewlineSequenceOnSend = string.Empty;
this.NewlineOnReceivedSequence = string.Empty;
// initialize other
this.cancellationTokenSource = new CancellationTokenSource();
this.logger = logger;
}
/// <summary>
/// To be called when data was received from the connected device.
/// </summary>
/// <param name="e"><see cref="ReceivedDataEventArgs"/></param>
protected void OnReceivedData(ReceivedDataEventArgs e) { this.ReceivedDataEvent?.Invoke(this, e); }
/// <summary>
/// To be called when data was sent to the connected device.
/// </summary>
/// <param name="e"><see cref="SentDataEventArgs"/></param>
protected void OnSentData(SentDataEventArgs e) { this.SentDataEvent?.Invoke(this, e); }
/// <summary>
/// Allows to send bytes using the implemented protocol.
/// </summary>
/// <param name="bytes">data as bytes</param>
protected abstract void InternalSendBytes(byte[] bytes);
public void SendBytes(byte[] bytes)
{
this.InternalSendBytes(bytes);
}
/// <summary>
/// Allows to connect to the selected device using the implemented protocol.
/// </summary>
/// <returns>true on success</returns>
protected abstract bool InternalConnect();
/// <summary>
/// Reads from the connected device in an endless loop.
/// The endless loop must be ended when the <paramref name="ct"/> has <see cref="CancellationToken.IsCancellationRequested"/> set.
/// </summary>
/// <param name="ct">cancellation token</param>
protected abstract void InternalRead(CancellationToken ct);
public void Connect()
{
if (this.InternalConnect())
{
// renew token source
this.cancellationTokenSource = new CancellationTokenSource();
// start internal reading thread
this.readingThread = new Thread(() => this.InternalRead(this.cancellationTokenSource.Token));
this.readingThread.Start();
}
else
{
this.logger.LogWarn($"'{nameof(Connect)}()' failed to connect to protocol, did not start reading thread.", nameof(CommunicationProtocol));
}
}
/// <summary>
/// Allows to disconnect from the connected device.
/// </summary>
protected abstract void InternalDisconnect();
public void Disconnect()
{
// if reading thread exists and is running => cancel it and wait
if (this.readingThread != null && this.readingThread.IsAlive)
{
this.cancellationTokenSource.Cancel();
this.readingThread.Join();
}
this.InternalDisconnect();
}
}

@ -0,0 +1,43 @@
namespace MultiTerm.Protocols;
/// <summary>
/// Interface to interact with a Communication protocol.
/// </summary>
public interface ICommunicationProtocol
{
/// <summary>
/// Newline sequence to add on the end when sending a message using <see cref="SendBytes(byte[])"/>.
/// </summary>
string NewlineSequenceOnSend { get; }
/// <summary>
/// When this sequence is detected while reading, a new line is introduced.
/// </summary>
string NewlineOnReceivedSequence { get; }
/// <summary>
/// New data received from connected device.
/// </summary>
event EventHandler<ReceivedDataEventArgs>? ReceivedDataEvent;
/// <summary>
/// New data sent to the connected device.
/// </summary>
event EventHandler<SentDataEventArgs>? SentDataEvent;
/// <summary>
/// Connect to the device.
/// </summary>
void Connect();
/// <summary>
/// Disconnect from the device. Ends all internal activities.
/// </summary>
void Disconnect();
/// <summary>
/// Send data to the connected device.
/// </summary>
/// <param name="bytes">data to send, as an array of bytes</param>
void SendBytes(byte[] bytes);
}

@ -6,4 +6,8 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Common\Common.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,13 @@
using MultiTerm.Protocols.Model;
namespace MultiTerm.Protocols;
public class ReceivedDataEventArgs : EventArgs
{
public IEnumerable<ExtendedChar> ReceivedCharacters { get; private set; }
public ReceivedDataEventArgs(IEnumerable<ExtendedChar> receivedCharacters)
{
this.ReceivedCharacters = receivedCharacters;
}
}

@ -0,0 +1,13 @@
using MultiTerm.Protocols.Model;
namespace MultiTerm.Protocols;
public class SentDataEventArgs : EventArgs
{
public IEnumerable<ExtendedChar> SentCharacters { get; private set; }
public SentDataEventArgs(IEnumerable<ExtendedChar> sentCharacters)
{
this.SentCharacters = sentCharacters;
}
}
Loading…
Cancel
Save