206 lines
5.7 KiB
C#
206 lines
5.7 KiB
C#
namespace Common.Hardware.SIRT
|
|
{
|
|
using Common.Hardware.SIRT.Parameters;
|
|
|
|
using System;
|
|
using System.Collections.Concurrent;
|
|
using System.Timers;
|
|
|
|
public class SIRTTask
|
|
{
|
|
protected readonly Timer timer;
|
|
protected readonly SIRTMessage request;
|
|
protected readonly ConcurrentStack<SIRTMessage> responses;
|
|
|
|
/// <param name="timeout">The tiemout in milliseconds, after the task will be cancelled.</param>
|
|
public SIRTTask(int timeout = 5_000)
|
|
{
|
|
this.Timeout = timeout;
|
|
this.State = SIRTTaskState.Pending;
|
|
|
|
this.timer = new Timer();
|
|
this.request = new SIRTMessage();
|
|
this.responses = new ConcurrentStack<SIRTMessage>();
|
|
|
|
// Cancel after 10 seconds
|
|
this.timer.AutoReset = false;
|
|
this.timer.Enabled = false;
|
|
this.timer.Interval = this.Timeout;
|
|
this.timer.Elapsed += this.Timer_Elapsed;
|
|
}
|
|
|
|
public event Action<SIRTTask> Completed;
|
|
public event Action<SIRTTask> Cancelled;
|
|
public event Action<SIRTTask> Timeouted;
|
|
public event Action<SIRTTask> Updated;
|
|
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// The tiemout in milliseconds, after the task will be cancelled.
|
|
/// </summary>
|
|
public int Timeout { get; }
|
|
|
|
public int Frequency { get; set; }
|
|
|
|
public int Index { get; internal set; }
|
|
|
|
public SIRTTaskState State { get; protected set; }
|
|
|
|
public virtual void BeginReceiveMessage(SIRTMessage response)
|
|
{
|
|
this.responses.Push(response);
|
|
|
|
if (this.State == SIRTTaskState.Running)
|
|
{
|
|
if (response.Cmd == SIRTMessage.FROMAIR && response?.Data?[0] == SIRTMessage.SEMI)
|
|
{
|
|
this.State = SIRTTaskState.Completed;
|
|
}
|
|
else if (response.Cmd == SIRTMessage.ACKNANSW)
|
|
{
|
|
this.State = SIRTTaskState.Completed;
|
|
}
|
|
}
|
|
|
|
this.EndReceiveMessage(response);
|
|
}
|
|
|
|
public virtual void SetRunning()
|
|
{
|
|
this.State = SIRTTaskState.Running;
|
|
|
|
this.timer.Start();
|
|
}
|
|
|
|
public virtual byte[] ToByteArray()
|
|
=> this.request.ToByteArray();
|
|
|
|
public override string ToString()
|
|
=> BitConverter.ToString(this.ToByteArray());
|
|
|
|
protected void Cancel()
|
|
{
|
|
this.State = SIRTTaskState.Cancelled;
|
|
|
|
this.Cancelled?.Invoke(this);
|
|
}
|
|
|
|
protected virtual void EndReceiveMessage(SIRTMessage _)
|
|
{
|
|
if (this.State == SIRTTaskState.Completed)
|
|
{
|
|
this.timer.Stop();
|
|
this.Completed?.Invoke(this);
|
|
}
|
|
else if (this.State == SIRTTaskState.Cancelled)
|
|
{
|
|
this.timer.Stop();
|
|
this.Cancelled?.Invoke(this);
|
|
}
|
|
}
|
|
|
|
protected void NotifyUpdated()
|
|
=> this.Updated?.Invoke(this);
|
|
|
|
protected virtual void Timer_Elapsed(object sender, ElapsedEventArgs e)
|
|
{
|
|
this.State = SIRTTaskState.Pending;
|
|
|
|
this.Timeouted?.Invoke(this);
|
|
}
|
|
|
|
public static implicit operator byte[](SIRTTask task)
|
|
=> task.ToByteArray();
|
|
|
|
public static implicit operator SIRTMessage(SIRTTask task)
|
|
=> task.request;
|
|
|
|
internal static readonly AnswerTask ActivateSIRT = new AnswerTask
|
|
{
|
|
Cmd = SIRTMessage.W_REG,
|
|
RequestAddress = 0x20000000,
|
|
P2 = 0x05,
|
|
Data = new byte[]
|
|
{
|
|
new SirtOperating { /* default */ },
|
|
new BluetoothOperating { BtOff = true },
|
|
new RFModuleOperating { RfOff = true },
|
|
new RFModuleOperating { OpMode = OperatingModes.ReceiveF1TransmitSensusRFF3 },
|
|
new PamTimeout { Minutes = 1 }
|
|
}
|
|
};
|
|
|
|
internal static readonly AnswerTask IdentifySIRT = new AnswerTask
|
|
{
|
|
Cmd = SIRTMessage.R_REG,
|
|
RequestAddress = 0x11001820,
|
|
P2 = 0x08
|
|
};
|
|
|
|
internal static readonly AnswerTask ReadPamPool = new AnswerTask
|
|
{
|
|
Cmd = SIRTMessage.R_PAM,
|
|
RequestAddress = 0xFFFFFFFF
|
|
};
|
|
|
|
internal static AnswerTask DeleteFromPamPool(uint address) => new AnswerTask
|
|
{
|
|
Cmd = SIRTMessage.W_PAM,
|
|
P1 = new P811 { DelPamAdr = true },
|
|
RequestAddress = address
|
|
};
|
|
}
|
|
|
|
public class AnswerTask : SIRTTask
|
|
{
|
|
public AnswerTask(int timeout = 3000) : base(timeout)
|
|
{
|
|
|
|
}
|
|
|
|
public byte[] Last { get; private set; }
|
|
|
|
public override void BeginReceiveMessage(SIRTMessage response)
|
|
{
|
|
base.BeginReceiveMessage(response);
|
|
|
|
this.Last = response.Data ?? new byte[] { };
|
|
}
|
|
}
|
|
}
|