laatzen/Common/Hardware/Common.Hardware.SIRT/Tasks/WritePamTask.cs
2026-01-23 11:16:38 +01:00

321 lines
9.1 KiB
C#

namespace Common.Hardware.SIRT.Tasks
{
using Common.Hardware.SIRT.Parameters;
using System;
using System.Collections.Generic;
public class WritePamTask : SIRTTask
{
private event Action<SIRTMessage> AKNReceived;
private event Action<SIRTMessage> BUPReceived;
private event Action<SIRTMessage> LATReceived;
private event Action<SIRTMessage> DEBUGReceived;
private event Action<SIRTMessage> SEMIReceived;
private event Action<SIRTMessage> UnknownReceived;
protected P811 p811;
protected bool latReceived;
protected bool debugReceived;
public WritePamTask()
{
this.p811 = this.request.P1;
this.request.Command = SIRTConstants.W_PAM;
this.MessageSent += this.OnMessageSent;
this.AKNReceived += this.OnAKNReceived;
this.BUPReceived += this.OnBUPReceived;
this.LATReceived += this.OnLATReceived;
this.DEBUGReceived += this.OnDEBUGReceived;
this.SEMIReceived += this.OnSEMIReceived;
this.UnknownReceived += this.OnUnknownReceived;
this.RequireLAT = true;
this.PamStatusIX = 11;
this.DebugLength = 52;
this.SemiLength = 91;
}
public event Action<SIRTMessage> MessageSent;
public event Action<SIRTMessage> MessageReceived;
public bool RequireLAT { get; set; }
public bool RequireDEBUG { get; set; }
public bool IsEncrypted { get; set; }
public byte[] EncryptionKeyI { get; set; }
private byte[] encryptionKeyII;
public byte[] EncryptionKeyII
{
get => this.encryptionKeyII;
set
{
this.encryptionKeyII = value;
this.IsEncrypted = true;
}
}
public bool WakeUpModul
{
get => this.p811.WakeUpModul;
set => this.SetP811(x => x.WakeUpModul = value);
}
public bool WakeUpCmd
{
get => this.p811.WakeUpCmd;
set => this.SetP811(x => x.WakeUpCmd = value);
}
public bool IgnoreTimeout
{
get => this.p811.IgnoreTimeout;
set => this.SetP811(x => x.IgnoreTimeout = value);
}
public bool DelPamSemi
{
get => this.p811.DelPamSemi;
set => this.SetP811(x => x.DelPamSemi = value);
}
public bool DelPamTx
{
get => this.p811.DelPamTx;
set => this.SetP811(x => x.DelPamTx = value);
}
public bool DelPamAdr
{
get => this.p811.DelPamAdr;
set => this.SetP811(x => x.DelPamAdr = value);
}
public bool DelPamAll
{
get => this.p811.DelPamAll;
set => this.SetP811(x => x.DelPamAll = value);
}
public byte[] Data
{
get => this.request.Payload;
set => this.request.Payload = value;
}
public byte DebugLength { get; set; }
public byte SemiLength { get; set; }
public byte PamStatusIX { get; set; }
public bool AnyTelegramReceived { get; set; }
public Queue<SIRTMessage> MessageQueue { get; set; } = new Queue<SIRTMessage>();
public override void Receive(SIRTMessage response)
{
if (this.UseEncryption(response))
{
this.DecriptResponse(response);
}
this.MessageQueue.Enqueue(response);
if (response.Command == SIRTConstants.ACKN_ANSW)
{
this.AKNReceived?.Invoke(response);
}
else if (response.Command == SIRTConstants.FROM_AIR)
{
var payload = response?.Payload;
if (payload != null && payload.Length > 0)
{
var type = payload[0];
if (type == SIRTConstants.BUP)
{
this.AnyTelegramReceived = true;
this.BUPReceived?.Invoke(response);
}
else if (type == SIRTConstants.LAT)
{
this.latReceived = true;
this.AnyTelegramReceived = true;
this.LATReceived?.Invoke(response);
}
else if (type == SIRTConstants.DEBUG)
{
this.debugReceived = true;
this.AnyTelegramReceived = true;
this.DEBUGReceived?.Invoke(response);
}
else if (type == SIRTConstants.SEMI)
{
this.AnyTelegramReceived = true;
this.SEMIReceived?.Invoke(response);
}
else
{
this.UnknownReceived?.Invoke(response);
}
}
else
{
this.UnknownReceived?.Invoke(response);
}
}
else
{
this.UnknownReceived?.Invoke(response);
}
this.MessageReceived?.Invoke(response);
}
public override byte[] Start()
{
this.latReceived = false;
this.debugReceived = false;
var message = new SIRTMessage
{
Direction = this.request.Direction,
Command = this.request.Command,
P1 = this.request.P1,
P2 = this.request.P2,
Address = this.request.Address,
Payload = this.EncryptRequest(),
Frequency = this.Frequency,
SirtId = this.SirtId,
};
this.MessageSent?.Invoke(this.request);
this.SetRunning();
return message.GetBytes();
}
protected virtual void OnMessageSent(SIRTMessage request)
{
}
protected virtual void OnAKNReceived(SIRTMessage akn)
{
}
protected virtual void OnBUPReceived(SIRTMessage bup)
{
}
protected virtual void OnLATReceived(SIRTMessage lat)
{
this.latReceived = true;
}
protected virtual void OnDEBUGReceived(SIRTMessage debug)
{
this.debugReceived = true;
if (this.RequireLAT && !this.latReceived)
{
this.SetPending();
}
}
protected virtual void OnSEMIReceived(SIRTMessage semi)
{
if ((this.RequireLAT && !this.latReceived) || (this.RequireDEBUG && !this.debugReceived) || semi.Payload[this.PamStatusIX] != 0)
{
this.SetPending();
}
else
{
this.SetCompleted();
}
}
protected virtual void OnUnknownReceived(SIRTMessage unknown)
{
}
protected virtual bool UseEncryption(SIRTMessage response)
{
if (response is null || this.EncryptionKeyI is null)
{
return false;
}
var payload = response.Payload;
if (payload is null)
{
return false;
}
var payloadLength = payload.Length;
if (payloadLength == 0 || payloadLength == this.DebugLength || payloadLength == this.SemiLength)
{
return false;
}
this.IsEncrypted = payload.GetCrc() != 0;
return this.IsEncrypted;
}
private byte[] EncryptRequest()
{
var requestPayload = this.request.Payload;
var payloadLength = requestPayload.Length;
var payload = new byte[payloadLength];
if (payloadLength > 0)
{
Array.Copy(requestPayload, 0, payload, 0, payloadLength);
if (this.IsEncrypted)
{
payload = payload.EncryptRequest(this.EncryptionKeyI, this.RequestAddress);
}
}
return payload;
}
private void DecriptResponse(SIRTMessage response)
{
var payload = new byte[response.Length];
Array.Copy(response.Payload, 0, payload, 0, payload.Length);
response.Payload = payload.DecryptResponse(this.EncryptionKeyI);
if (response.Payload[this.PamStatusIX] != 0 && this.EncryptionKeyII != null)
{
response.Payload = payload.DecryptResponse(this.EncryptionKeyII);
if (response.Payload[this.PamStatusIX] == 0)
{
var oldEncryptionKey = this.EncryptionKeyI;
this.EncryptionKeyI = this.EncryptionKeyII;
this.EncryptionKeyII = oldEncryptionKey;
}
}
}
private void SetP811(Action<P811> p811Setter)
{
p811Setter.Invoke(this.p811);
this.request.P1 = this.p811;
}
}
}