127 lines
3.5 KiB
C#
127 lines
3.5 KiB
C#
namespace Common.Hardware.SIRT
|
|
{
|
|
using System;
|
|
using System.Collections.Concurrent;
|
|
using System.Timers;
|
|
|
|
public partial class SIRTTask
|
|
{
|
|
public readonly ConcurrentStack<SIRTMessage> responses;
|
|
public readonly SIRTMessage request;
|
|
protected readonly Timer timeoutTimer;
|
|
|
|
public SIRTTask(int frequency, int timeout = 5_000)
|
|
{
|
|
this.Timeout = timeout;
|
|
this.Frequency = frequency;
|
|
this.responses = new ConcurrentStack<SIRTMessage>();
|
|
this.request = new SIRTMessage();
|
|
this.timeoutTimer = new Timer
|
|
{
|
|
AutoReset = false,
|
|
Enabled = false,
|
|
Interval = this.Timeout
|
|
};
|
|
this.timeoutTimer.Elapsed += this.OnTimeout;
|
|
}
|
|
|
|
public event Action<SIRTTask> Completed;
|
|
public event Action<SIRTTask> Cancelled;
|
|
public event Action<SIRTTask> Timeouted;
|
|
|
|
public byte Cmd
|
|
{
|
|
get => this.request.Cmd;
|
|
set => this.request.Cmd = value;
|
|
}
|
|
|
|
public byte P1
|
|
{
|
|
get => this.request.P1;
|
|
set => this.request.P1 = value;
|
|
}
|
|
|
|
public byte P2
|
|
{
|
|
get => this.request.P2;
|
|
set => this.request.P2 = value;
|
|
}
|
|
|
|
public uint RequestAddress
|
|
{
|
|
get => this.request.Address;
|
|
set
|
|
{
|
|
this.request.Address = value;
|
|
this.ResponseAddress = value;
|
|
}
|
|
}
|
|
|
|
public uint ResponseAddress { get; set; }
|
|
|
|
public byte[] Data
|
|
{
|
|
get => this.request.Data;
|
|
set => this.request.Data = value;
|
|
}
|
|
|
|
public int Timeout { get; }
|
|
|
|
public int Frequency { get; }
|
|
|
|
public SIRTTaskState State { get; protected set; }
|
|
|
|
public void PushResponse(SIRTMessage response)
|
|
{
|
|
if (this.State == SIRTTaskState.Cancelled)
|
|
{
|
|
this.NotifyCancelled();
|
|
}
|
|
else
|
|
{
|
|
this.responses.Push(response);
|
|
this.ProcessResponse(response);
|
|
}
|
|
}
|
|
|
|
public virtual byte[] ToByteArray() => this.request.ToByteArray();
|
|
|
|
public override string ToString() => BitConverter.ToString(this.ToByteArray());
|
|
|
|
protected void NotifyCancelled() => this.Cancelled?.Invoke(this);
|
|
|
|
protected void NotifyCompleted() => this.Completed?.Invoke(this);
|
|
|
|
protected void NotifyTimeouted() => this.Timeouted?.Invoke(this);
|
|
|
|
protected virtual void OnTimeout(object sender, ElapsedEventArgs e)
|
|
{
|
|
this.State = SIRTTaskState.Cancelled;
|
|
|
|
this.NotifyCancelled();
|
|
}
|
|
|
|
protected virtual void ProcessResponse(SIRTMessage response)
|
|
{
|
|
if (this.State == SIRTTaskState.Running)
|
|
{
|
|
if (response.Cmd == SIRTMessage.ACKNANSW || (response.Data.Length > 0 && response.Data[0] == SIRTMessage.SEMI))
|
|
{
|
|
this.State = SIRTTaskState.Completed;
|
|
}
|
|
}
|
|
|
|
if (this.State == SIRTTaskState.Completed)
|
|
{
|
|
this.timeoutTimer.Stop();
|
|
this.NotifyCompleted();
|
|
}
|
|
else if (this.State == SIRTTaskState.Cancelled)
|
|
{
|
|
this.timeoutTimer.Stop();
|
|
this.NotifyCancelled();
|
|
}
|
|
}
|
|
}
|
|
}
|