laatzen/Common/CommonConsole/Program.cs
2023-12-14 16:18:51 +01:00

256 lines
6.8 KiB
C#

namespace CommonConsole
{
using OmniPlus;
using System;
using System.IO;
using System.IO.Ports;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
class Program
{
static void Main()
{
var connection = new IRDAPort();
var response = connection.Send(0x01);
Console.WriteLine(Encoding.ASCII.GetString(response));
response = connection.Send(0xFD, 0xC6);
Console.WriteLine(Encoding.ASCII.GetString(response));
connection.Dispose();
}
}
public abstract class Port : IDisposable
{
private readonly String name;
private readonly Int32 bauds;
private readonly Int32 data;
private readonly Parity parity;
private readonly StopBits stop;
private SerialPort port;
protected Port(String name, Int32 bauds, Int32 data, Parity parity, StopBits stop)
{
this.name = name;
this.bauds = bauds;
this.data = data;
this.parity = parity;
this.stop = stop;
}
protected bool IsOpen => this.port?.IsOpen ?? false;
protected Stream Stream => this.port.BaseStream;
public virtual void Dispose()
{
try
{
if (this.port != null)
{
this.port.Disposed -= this.Port_Disposed;
this.port.ErrorReceived -= this.Port_ErrorReceived;
this.port.Close();
this.port.Dispose();
this.port = null;
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
Console.WriteLine("... Port disposed");
}
protected virtual void Open()
{
this.Dispose();
try
{
this.port = new SerialPort
{
PortName = this.name,
BaudRate = this.bauds,
DataBits = this.data,
Parity = this.parity,
StopBits = this.stop,
};
this.port.Disposed += this.Port_Disposed;
this.port.ErrorReceived += this.Port_ErrorReceived;
this.port.Open();
}
catch (Exception e)
{
Console.WriteLine(e);
}
Console.WriteLine("... Port created");
}
private void Port_Disposed(Object sender, EventArgs args)
{
this.Dispose();
Console.WriteLine("... Port disposed internal");
}
private void Port_ErrorReceived(Object sender, SerialErrorReceivedEventArgs args)
{
Console.WriteLine("... Port error received");
Console.WriteLine($"... {args.EventType}");
if (!this.port.IsOpen)
{
this.Dispose();
}
}
}
public class IRDAPort : Port
{
public IRDAPort() : base("COM26", 115200, 8, Parity.None, StopBits.One)
{
}
public Byte[] Send(params Byte[] request)
{
Console.WriteLine(">>> " + BitConverter.ToString(request));
if (!this.IsOpen)
{
this.Open();
}
var response = new Byte[] { };
if (!this.IsOpen || !this.Stream.CanWrite || !this.Stream.CanRead)
{
return response;
}
Console.WriteLine(">>> 1-1-1-1");
this.Stream.Write(new byte[] { 1, 1, 1, 1 }, 0, 4);
request = request
.ToUI1236Message()
.ToIrdaMessage();
Console.WriteLine(">>> " + BitConverter.ToString(request));
var asyncState = new IRDAAsyncState
{
Request = request,
Stream = this.Stream
};
var lock_object = new object();
lock (lock_object)
{
Task.Factory.StartNew(asyncState.BeginReadAsync, asyncState.CancellationToken);
asyncState.BeginWriteAsync(request);
}
return asyncState.Response;
}
}
public class IRDAAsyncState
{
private readonly ManualResetEventSlim manualResetEventSlim;
private readonly CancellationTokenSource cancellationTokenSource;
public IRDAAsyncState()
{
this.manualResetEventSlim = new ManualResetEventSlim();
this.cancellationTokenSource = new CancellationTokenSource();
this.CancellationToken = this.cancellationTokenSource.Token;
this.Buffer = new Byte[256];
}
public Byte[] Buffer { get; private set; }
public Byte[] Request { get; set; }
public Byte[] Response { get; set; }
public Stream Stream { get; set; }
public CancellationToken CancellationToken { get; }
internal void BeginReadAsync()
{
this.Response = null;
var asyncResult = this.Stream.BeginRead(this.Buffer, 0, this.Buffer.Length, this.EndReadAsync, this);
asyncResult.AsyncWaitHandle.WaitOne();
if (this.Response is null)
{
this.BeginReadAsync();
}
else
{
this.manualResetEventSlim.Set();
}
}
private void EndReadAsync(IAsyncResult asyncResult)
{
if (asyncResult.AsyncState is IRDAAsyncState asyncState)
{
var bytesLength = asyncState.Stream.EndRead(asyncResult);
if (this.Response is null)
{
var response = new Byte[bytesLength];
Array.Copy(this.Buffer, 0, response, 0, bytesLength);
Console.WriteLine("<<< " + BitConverter.ToString(response));
response = response
.FromIrdaMessage()
.FromUI1236Message();
Console.WriteLine("<<< " + BitConverter.ToString(response));
if (response.Length != 0)
{
this.Response = response;
}
}
}
}
internal void BeginWriteAsync(Byte[] request)
{
var asyncResult = this.Stream.BeginWrite(request, 0, request.Length, this.EndWriteAsync, this);
asyncResult.AsyncWaitHandle.WaitOne();
this.manualResetEventSlim.Wait();
}
private void EndWriteAsync(IAsyncResult asyncResult)
{
if (asyncResult.AsyncState is IRDAAsyncState asyncState)
{
asyncState.Stream.EndWrite(asyncResult);
}
}
}
}