256 lines
6.8 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|
|
}
|