From 4db2df7f2058d58a88d141f20c7451200d577682 Mon Sep 17 00:00:00 2001 From: Benedikt Schenkel Date: Wed, 29 Nov 2023 10:49:46 +0100 Subject: [PATCH 01/11] add tmp B4R2 definitions --- .../InterfaceSpecificationSciCc.cs | 6 + .../InterfaceSpecificationSciGeneric.cs | 2572 +++++++++++++++++ .../InterfaceSpecificationSciIls.cs | 872 ++++++ .../InterfaceSpecificationSciIo.cs | 6 + .../InterfaceSpecificationSciLc.cs | 31 + .../InterfaceSpecificationSciLs.cs | 71 + .../InterfaceSpecificationSciLx.cs | 31 + .../Baseline4R2/InterfaceSpecificationSciP.cs | 139 + .../InterfaceSpecificationSciRbc.cs | 6 + .../InterfaceSpecificationSciTds.cs | 311 ++ src/Messages/Baseline4R2/Message.cs | 178 ++ src/Messages/ProtocolTypes.cs | 1 + 12 files changed, 4224 insertions(+) create mode 100644 src/Messages/Baseline4R2/InterfaceSpecificationSciCc.cs create mode 100644 src/Messages/Baseline4R2/InterfaceSpecificationSciGeneric.cs create mode 100644 src/Messages/Baseline4R2/InterfaceSpecificationSciIls.cs create mode 100644 src/Messages/Baseline4R2/InterfaceSpecificationSciIo.cs create mode 100644 src/Messages/Baseline4R2/InterfaceSpecificationSciLc.cs create mode 100644 src/Messages/Baseline4R2/InterfaceSpecificationSciLs.cs create mode 100644 src/Messages/Baseline4R2/InterfaceSpecificationSciLx.cs create mode 100644 src/Messages/Baseline4R2/InterfaceSpecificationSciP.cs create mode 100644 src/Messages/Baseline4R2/InterfaceSpecificationSciRbc.cs create mode 100644 src/Messages/Baseline4R2/InterfaceSpecificationSciTds.cs create mode 100644 src/Messages/Baseline4R2/Message.cs diff --git a/src/Messages/Baseline4R2/InterfaceSpecificationSciCc.cs b/src/Messages/Baseline4R2/InterfaceSpecificationSciCc.cs new file mode 100644 index 0000000..088e721 --- /dev/null +++ b/src/Messages/Baseline4R2/InterfaceSpecificationSciCc.cs @@ -0,0 +1,6 @@ +using System; +using System.Text; +using System.Linq; + +namespace EulynxLive.Messages.Baseline4R2; + diff --git a/src/Messages/Baseline4R2/InterfaceSpecificationSciGeneric.cs b/src/Messages/Baseline4R2/InterfaceSpecificationSciGeneric.cs new file mode 100644 index 0000000..39a7680 --- /dev/null +++ b/src/Messages/Baseline4R2/InterfaceSpecificationSciGeneric.cs @@ -0,0 +1,2572 @@ +using System; +using System.Text; +using System.Linq; + +namespace EulynxLive.Messages.Baseline4R2; + +public record AdjacentInterlockingSystemPdiVersionCheckCommand (string SenderIdentifier, string ReceiverIdentifier, byte PdiVersionOfSender) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int PdiVersionOfSenderOffset = 43; + public static readonly ushort MessageType = 0x0024; + + public new static AdjacentInterlockingSystemPdiVersionCheckCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var PdiVersionOfSender = (byte)message[PdiVersionOfSenderOffset]; + return new AdjacentInterlockingSystemPdiVersionCheckCommand(SenderIdentifier, ReceiverIdentifier, PdiVersionOfSender); + } + + public override byte[] ToByteArray() { + var result = new byte[44]; + result[0] = (byte)ProtocolType.AdjacentInterlockingSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + result[PdiVersionOfSenderOffset] = (byte)PdiVersionOfSender; + return result; + } +} + + + +public record TrainDetectionSystemPdiVersionCheckCommand (string SenderIdentifier, string ReceiverIdentifier, byte PdiVersionOfSender) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int PdiVersionOfSenderOffset = 43; + public static readonly ushort MessageType = 0x0024; + + public new static TrainDetectionSystemPdiVersionCheckCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var PdiVersionOfSender = (byte)message[PdiVersionOfSenderOffset]; + return new TrainDetectionSystemPdiVersionCheckCommand(SenderIdentifier, ReceiverIdentifier, PdiVersionOfSender); + } + + public override byte[] ToByteArray() { + var result = new byte[44]; + result[0] = (byte)ProtocolType.TrainDetectionSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + result[PdiVersionOfSenderOffset] = (byte)PdiVersionOfSender; + return result; + } +} + + + +public record LightSignalPdiVersionCheckCommand (string SenderIdentifier, string ReceiverIdentifier, byte PdiVersionOfSender) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int PdiVersionOfSenderOffset = 43; + public static readonly ushort MessageType = 0x0024; + + public new static LightSignalPdiVersionCheckCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var PdiVersionOfSender = (byte)message[PdiVersionOfSenderOffset]; + return new LightSignalPdiVersionCheckCommand(SenderIdentifier, ReceiverIdentifier, PdiVersionOfSender); + } + + public override byte[] ToByteArray() { + var result = new byte[44]; + result[0] = (byte)ProtocolType.LightSignal; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + result[PdiVersionOfSenderOffset] = (byte)PdiVersionOfSender; + return result; + } +} + + + +public record PointPdiVersionCheckCommand (string SenderIdentifier, string ReceiverIdentifier, byte PdiVersionOfSender) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int PdiVersionOfSenderOffset = 43; + public static readonly ushort MessageType = 0x0024; + + public new static PointPdiVersionCheckCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var PdiVersionOfSender = (byte)message[PdiVersionOfSenderOffset]; + return new PointPdiVersionCheckCommand(SenderIdentifier, ReceiverIdentifier, PdiVersionOfSender); + } + + public override byte[] ToByteArray() { + var result = new byte[44]; + result[0] = (byte)ProtocolType.Point; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + result[PdiVersionOfSenderOffset] = (byte)PdiVersionOfSender; + return result; + } +} + + +public record PointPdiVersionCheckMessage (string SenderIdentifier, string ReceiverIdentifier, PointPdiVersionCheckMessageResultPdiVersionCheck ResultPdiVersionCheck, byte SenderPdiVersion, byte ChecksumLength, byte[] Checksum) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int ResultPdiVersionCheckOffset = 43; + private const int SenderPdiVersionOffset = 44; + private const int ChecksumLengthOffset = 45; + private const int ChecksumOffset = 46; + + public new static PointPdiVersionCheckMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var ResultPdiVersionCheck = (PointPdiVersionCheckMessageResultPdiVersionCheck)message[ResultPdiVersionCheckOffset]; + var SenderPdiVersion = (byte)message[SenderPdiVersionOffset]; + var ChecksumLength = (byte)message[ChecksumLengthOffset]; + var Checksum = message.Skip(ChecksumOffset).Take(ChecksumLength).ToArray(); + return new PointPdiVersionCheckMessage(SenderIdentifier, ReceiverIdentifier, ResultPdiVersionCheck, SenderPdiVersion, ChecksumLength, Checksum); + } + + public override byte[] ToByteArray() { + var result = new byte[46 + ChecksumLength]; + result[0] = (byte)ProtocolType.Point; + BitConverter.GetBytes(0x0025).Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + result[ResultPdiVersionCheckOffset] = (byte)ResultPdiVersionCheck; + result[SenderPdiVersionOffset] = (byte)SenderPdiVersion; + result[ChecksumLengthOffset] = (byte)ChecksumLength; + Checksum.CopyTo(result, ChecksumOffset); + return result; + } +} + +public enum PointPdiVersionCheckMessageResultPdiVersionCheck : byte { + PDIVersionsFromReceiverAndSenderDoNotMatch = 0x01, + PDIVersionsFromReceiverAndSenderDoMatch = 0x02, +} + +public record RadioBlockCenterPdiVersionCheckCommand (string SenderIdentifier, string ReceiverIdentifier, byte PdiVersionOfSender) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int PdiVersionOfSenderOffset = 43; + public static readonly ushort MessageType = 0x0024; + + public new static RadioBlockCenterPdiVersionCheckCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var PdiVersionOfSender = (byte)message[PdiVersionOfSenderOffset]; + return new RadioBlockCenterPdiVersionCheckCommand(SenderIdentifier, ReceiverIdentifier, PdiVersionOfSender); + } + + public override byte[] ToByteArray() { + var result = new byte[44]; + result[0] = (byte)ProtocolType.RadioBlockCenter; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + result[PdiVersionOfSenderOffset] = (byte)PdiVersionOfSender; + return result; + } +} + + + +public record LevelCrossingPdiVersionCheckCommand (string SenderIdentifier, string ReceiverIdentifier, byte PdiVersionOfSender) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int PdiVersionOfSenderOffset = 43; + public static readonly ushort MessageType = 0x0024; + + public new static LevelCrossingPdiVersionCheckCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var PdiVersionOfSender = (byte)message[PdiVersionOfSenderOffset]; + return new LevelCrossingPdiVersionCheckCommand(SenderIdentifier, ReceiverIdentifier, PdiVersionOfSender); + } + + public override byte[] ToByteArray() { + var result = new byte[44]; + result[0] = (byte)ProtocolType.LevelCrossing; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + result[PdiVersionOfSenderOffset] = (byte)PdiVersionOfSender; + return result; + } +} + + + +public record CCPdiVersionCheckCommand (string SenderIdentifier, string ReceiverIdentifier, byte PdiVersionOfSender) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int PdiVersionOfSenderOffset = 43; + public static readonly ushort MessageType = 0x0024; + + public new static CCPdiVersionCheckCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var PdiVersionOfSender = (byte)message[PdiVersionOfSenderOffset]; + return new CCPdiVersionCheckCommand(SenderIdentifier, ReceiverIdentifier, PdiVersionOfSender); + } + + public override byte[] ToByteArray() { + var result = new byte[44]; + result[0] = (byte)ProtocolType.CC; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + result[PdiVersionOfSenderOffset] = (byte)PdiVersionOfSender; + return result; + } +} + + + +public record GenericIOPdiVersionCheckCommand (string SenderIdentifier, string ReceiverIdentifier, byte PdiVersionOfSender) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int PdiVersionOfSenderOffset = 43; + public static readonly ushort MessageType = 0x0024; + + public new static GenericIOPdiVersionCheckCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var PdiVersionOfSender = (byte)message[PdiVersionOfSenderOffset]; + return new GenericIOPdiVersionCheckCommand(SenderIdentifier, ReceiverIdentifier, PdiVersionOfSender); + } + + public override byte[] ToByteArray() { + var result = new byte[44]; + result[0] = (byte)ProtocolType.GenericIO; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + result[PdiVersionOfSenderOffset] = (byte)PdiVersionOfSender; + return result; + } +} + + + +public record ExternalLevelCrossingSystemPdiVersionCheckCommand (string SenderIdentifier, string ReceiverIdentifier, byte PdiVersionOfSender) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int PdiVersionOfSenderOffset = 43; + public static readonly ushort MessageType = 0x0024; + + public new static ExternalLevelCrossingSystemPdiVersionCheckCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var PdiVersionOfSender = (byte)message[PdiVersionOfSenderOffset]; + return new ExternalLevelCrossingSystemPdiVersionCheckCommand(SenderIdentifier, ReceiverIdentifier, PdiVersionOfSender); + } + + public override byte[] ToByteArray() { + var result = new byte[44]; + result[0] = (byte)ProtocolType.ExternalLevelCrossingSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + result[PdiVersionOfSenderOffset] = (byte)PdiVersionOfSender; + return result; + } +} + + + + +public record AdjacentInterlockingSystemInitialisationRequestCommand (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0021; + + public new static AdjacentInterlockingSystemInitialisationRequestCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new AdjacentInterlockingSystemInitialisationRequestCommand(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.AdjacentInterlockingSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record TrainDetectionSystemInitialisationRequestCommand (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0021; + + public new static TrainDetectionSystemInitialisationRequestCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new TrainDetectionSystemInitialisationRequestCommand(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.TrainDetectionSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record LightSignalInitialisationRequestCommand (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0021; + + public new static LightSignalInitialisationRequestCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new LightSignalInitialisationRequestCommand(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.LightSignal; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record PointInitialisationRequestCommand (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0021; + + public new static PointInitialisationRequestCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new PointInitialisationRequestCommand(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.Point; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record RadioBlockCenterInitialisationRequestCommand (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0021; + + public new static RadioBlockCenterInitialisationRequestCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new RadioBlockCenterInitialisationRequestCommand(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.RadioBlockCenter; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record LevelCrossingInitialisationRequestCommand (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0021; + + public new static LevelCrossingInitialisationRequestCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new LevelCrossingInitialisationRequestCommand(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.LevelCrossing; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record CCInitialisationRequestCommand (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0021; + + public new static CCInitialisationRequestCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new CCInitialisationRequestCommand(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.CC; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record GenericIOInitialisationRequestCommand (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0021; + + public new static GenericIOInitialisationRequestCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new GenericIOInitialisationRequestCommand(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.GenericIO; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record ExternalLevelCrossingSystemInitialisationRequestCommand (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0021; + + public new static ExternalLevelCrossingSystemInitialisationRequestCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new ExternalLevelCrossingSystemInitialisationRequestCommand(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.ExternalLevelCrossingSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record AdjacentInterlockingSystemStartInitialisationMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0022; + + public new static AdjacentInterlockingSystemStartInitialisationMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new AdjacentInterlockingSystemStartInitialisationMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.AdjacentInterlockingSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record TrainDetectionSystemStartInitialisationMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0022; + + public new static TrainDetectionSystemStartInitialisationMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new TrainDetectionSystemStartInitialisationMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.TrainDetectionSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record LightSignalStartInitialisationMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0022; + + public new static LightSignalStartInitialisationMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new LightSignalStartInitialisationMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.LightSignal; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record PointStartInitialisationMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0022; + + public new static PointStartInitialisationMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new PointStartInitialisationMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.Point; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record RadioBlockCenterStartInitialisationMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0022; + + public new static RadioBlockCenterStartInitialisationMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new RadioBlockCenterStartInitialisationMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.RadioBlockCenter; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record LevelCrossingStartInitialisationMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0022; + + public new static LevelCrossingStartInitialisationMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new LevelCrossingStartInitialisationMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.LevelCrossing; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record CCStartInitialisationMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0022; + + public new static CCStartInitialisationMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new CCStartInitialisationMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.CC; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record GenericIOStartInitialisationMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0022; + + public new static GenericIOStartInitialisationMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new GenericIOStartInitialisationMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.GenericIO; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record ExternalLevelCrossingSystemStartInitialisationMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0022; + + public new static ExternalLevelCrossingSystemStartInitialisationMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new ExternalLevelCrossingSystemStartInitialisationMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.ExternalLevelCrossingSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record AdjacentInterlockingSystemStatusReportCompletedMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0026; + + public new static AdjacentInterlockingSystemStatusReportCompletedMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new AdjacentInterlockingSystemStatusReportCompletedMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.AdjacentInterlockingSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record TrainDetectionSystemStatusReportCompletedMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0026; + + public new static TrainDetectionSystemStatusReportCompletedMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new TrainDetectionSystemStatusReportCompletedMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.TrainDetectionSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record LightSignalStatusReportCompletedMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0026; + + public new static LightSignalStatusReportCompletedMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new LightSignalStatusReportCompletedMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.LightSignal; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record PointStatusReportCompletedMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0026; + + public new static PointStatusReportCompletedMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new PointStatusReportCompletedMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.Point; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record RadioBlockCenterStatusReportCompletedMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0026; + + public new static RadioBlockCenterStatusReportCompletedMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new RadioBlockCenterStatusReportCompletedMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.RadioBlockCenter; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record LevelCrossingStatusReportCompletedMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0026; + + public new static LevelCrossingStatusReportCompletedMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new LevelCrossingStatusReportCompletedMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.LevelCrossing; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record CCStatusReportCompletedMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0026; + + public new static CCStatusReportCompletedMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new CCStatusReportCompletedMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.CC; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record GenericIOStatusReportCompletedMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0026; + + public new static GenericIOStatusReportCompletedMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new GenericIOStatusReportCompletedMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.GenericIO; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record ExternalLevelCrossingSystemStatusReportCompletedMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0026; + + public new static ExternalLevelCrossingSystemStatusReportCompletedMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new ExternalLevelCrossingSystemStatusReportCompletedMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.ExternalLevelCrossingSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record AdjacentInterlockingSystemInitialisationCompletedMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0023; + + public new static AdjacentInterlockingSystemInitialisationCompletedMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new AdjacentInterlockingSystemInitialisationCompletedMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.AdjacentInterlockingSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record TrainDetectionSystemInitialisationCompletedMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0023; + + public new static TrainDetectionSystemInitialisationCompletedMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new TrainDetectionSystemInitialisationCompletedMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.TrainDetectionSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record LightSignalInitialisationCompletedMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0023; + + public new static LightSignalInitialisationCompletedMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new LightSignalInitialisationCompletedMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.LightSignal; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record PointInitialisationCompletedMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0023; + + public new static PointInitialisationCompletedMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new PointInitialisationCompletedMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.Point; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record RadioBlockCenterInitialisationCompletedMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0023; + + public new static RadioBlockCenterInitialisationCompletedMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new RadioBlockCenterInitialisationCompletedMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.RadioBlockCenter; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record LevelCrossingInitialisationCompletedMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0023; + + public new static LevelCrossingInitialisationCompletedMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new LevelCrossingInitialisationCompletedMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.LevelCrossing; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record CCInitialisationCompletedMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0023; + + public new static CCInitialisationCompletedMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new CCInitialisationCompletedMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.CC; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record GenericIOInitialisationCompletedMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0023; + + public new static GenericIOInitialisationCompletedMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new GenericIOInitialisationCompletedMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.GenericIO; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record ExternalLevelCrossingSystemInitialisationCompletedMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0023; + + public new static ExternalLevelCrossingSystemInitialisationCompletedMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new ExternalLevelCrossingSystemInitialisationCompletedMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.ExternalLevelCrossingSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record AdjacentInterlockingSystemClosePdiCommand (string SenderIdentifier, string ReceiverIdentifier, AdjacentInterlockingSystemClosePdiCommandCloseReason CloseReason) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int CloseReasonOffset = 43; + public static readonly ushort MessageType = 0x0027; + + public new static AdjacentInterlockingSystemClosePdiCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var CloseReason = (AdjacentInterlockingSystemClosePdiCommandCloseReason)message[CloseReasonOffset]; + return new AdjacentInterlockingSystemClosePdiCommand(SenderIdentifier, ReceiverIdentifier, CloseReason); + } + + public override byte[] ToByteArray() { + var result = new byte[44]; + result[0] = (byte)ProtocolType.AdjacentInterlockingSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + result[CloseReasonOffset] = (byte)CloseReason; + return result; + } +} + +public enum AdjacentInterlockingSystemClosePdiCommandCloseReason : byte { + ProtocolError = 0x01, + FormalTelegramError = 0x02, + ContentTelegramError = 0x03, + NormalClose = 0x04, + OtherVersionRequired = 0x05, + Timeout = 0x06, + ChecksumMismatch = 0x07 +} + +public record TrainDetectionSystemClosePdiCommand (string SenderIdentifier, string ReceiverIdentifier, TrainDetectionSystemClosePdiCommandCloseReason CloseReason) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int CloseReasonOffset = 43; + public static readonly ushort MessageType = 0x0027; + + public new static TrainDetectionSystemClosePdiCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var CloseReason = (TrainDetectionSystemClosePdiCommandCloseReason)message[CloseReasonOffset]; + return new TrainDetectionSystemClosePdiCommand(SenderIdentifier, ReceiverIdentifier, CloseReason); + } + + public override byte[] ToByteArray() { + var result = new byte[44]; + result[0] = (byte)ProtocolType.TrainDetectionSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + result[CloseReasonOffset] = (byte)CloseReason; + return result; + } +} + +public enum TrainDetectionSystemClosePdiCommandCloseReason : byte { + ProtocolError = 0x01, + FormalTelegramError = 0x02, + ContentTelegramError = 0x03, + NormalClose = 0x04, + OtherVersionRequired = 0x05, + Timeout = 0x06, + ChecksumMismatch = 0x07 +} + +public record LightSignalClosePdiCommand (string SenderIdentifier, string ReceiverIdentifier, LightSignalClosePdiCommandCloseReason CloseReason) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int CloseReasonOffset = 43; + public static readonly ushort MessageType = 0x0027; + + public new static LightSignalClosePdiCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var CloseReason = (LightSignalClosePdiCommandCloseReason)message[CloseReasonOffset]; + return new LightSignalClosePdiCommand(SenderIdentifier, ReceiverIdentifier, CloseReason); + } + + public override byte[] ToByteArray() { + var result = new byte[44]; + result[0] = (byte)ProtocolType.LightSignal; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + result[CloseReasonOffset] = (byte)CloseReason; + return result; + } +} + +public enum LightSignalClosePdiCommandCloseReason : byte { + ProtocolError = 0x01, + FormalTelegramError = 0x02, + ContentTelegramError = 0x03, + NormalClose = 0x04, + OtherVersionRequired = 0x05, + Timeout = 0x06, + ChecksumMismatch = 0x07 +} + +public record PointClosePdiCommand (string SenderIdentifier, string ReceiverIdentifier, PointClosePdiCommandCloseReason CloseReason) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int CloseReasonOffset = 43; + public static readonly ushort MessageType = 0x0027; + + public new static PointClosePdiCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var CloseReason = (PointClosePdiCommandCloseReason)message[CloseReasonOffset]; + return new PointClosePdiCommand(SenderIdentifier, ReceiverIdentifier, CloseReason); + } + + public override byte[] ToByteArray() { + var result = new byte[44]; + result[0] = (byte)ProtocolType.Point; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + result[CloseReasonOffset] = (byte)CloseReason; + return result; + } +} + +public enum PointClosePdiCommandCloseReason : byte { + ProtocolError = 0x01, + FormalTelegramError = 0x02, + ContentTelegramError = 0x03, + NormalClose = 0x04, + OtherVersionRequired = 0x05, + Timeout = 0x06, + ChecksumMismatch = 0x07 +} + +public record RadioBlockCenterClosePdiCommand (string SenderIdentifier, string ReceiverIdentifier, RadioBlockCenterClosePdiCommandCloseReason CloseReason) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int CloseReasonOffset = 43; + public static readonly ushort MessageType = 0x0027; + + public new static RadioBlockCenterClosePdiCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var CloseReason = (RadioBlockCenterClosePdiCommandCloseReason)message[CloseReasonOffset]; + return new RadioBlockCenterClosePdiCommand(SenderIdentifier, ReceiverIdentifier, CloseReason); + } + + public override byte[] ToByteArray() { + var result = new byte[44]; + result[0] = (byte)ProtocolType.RadioBlockCenter; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + result[CloseReasonOffset] = (byte)CloseReason; + return result; + } +} + +public enum RadioBlockCenterClosePdiCommandCloseReason : byte { + ProtocolError = 0x01, + FormalTelegramError = 0x02, + ContentTelegramError = 0x03, + NormalClose = 0x04, + OtherVersionRequired = 0x05, + Timeout = 0x06, + ChecksumMismatch = 0x07 +} + +public record LevelCrossingClosePdiCommand (string SenderIdentifier, string ReceiverIdentifier, LevelCrossingClosePdiCommandCloseReason CloseReason) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int CloseReasonOffset = 43; + public static readonly ushort MessageType = 0x0027; + + public new static LevelCrossingClosePdiCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var CloseReason = (LevelCrossingClosePdiCommandCloseReason)message[CloseReasonOffset]; + return new LevelCrossingClosePdiCommand(SenderIdentifier, ReceiverIdentifier, CloseReason); + } + + public override byte[] ToByteArray() { + var result = new byte[44]; + result[0] = (byte)ProtocolType.LevelCrossing; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + result[CloseReasonOffset] = (byte)CloseReason; + return result; + } +} + +public enum LevelCrossingClosePdiCommandCloseReason : byte { + ProtocolError = 0x01, + FormalTelegramError = 0x02, + ContentTelegramError = 0x03, + NormalClose = 0x04, + OtherVersionRequired = 0x05, + Timeout = 0x06, + ChecksumMismatch = 0x07 +} + +public record CCClosePdiCommand (string SenderIdentifier, string ReceiverIdentifier, CCClosePdiCommandCloseReason CloseReason) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int CloseReasonOffset = 43; + public static readonly ushort MessageType = 0x0027; + + public new static CCClosePdiCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var CloseReason = (CCClosePdiCommandCloseReason)message[CloseReasonOffset]; + return new CCClosePdiCommand(SenderIdentifier, ReceiverIdentifier, CloseReason); + } + + public override byte[] ToByteArray() { + var result = new byte[44]; + result[0] = (byte)ProtocolType.CC; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + result[CloseReasonOffset] = (byte)CloseReason; + return result; + } +} + +public enum CCClosePdiCommandCloseReason : byte { + ProtocolError = 0x01, + FormalTelegramError = 0x02, + ContentTelegramError = 0x03, + NormalClose = 0x04, + OtherVersionRequired = 0x05, + Timeout = 0x06, + ChecksumMismatch = 0x07 +} + +public record GenericIOClosePdiCommand (string SenderIdentifier, string ReceiverIdentifier, GenericIOClosePdiCommandCloseReason CloseReason) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int CloseReasonOffset = 43; + public static readonly ushort MessageType = 0x0027; + + public new static GenericIOClosePdiCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var CloseReason = (GenericIOClosePdiCommandCloseReason)message[CloseReasonOffset]; + return new GenericIOClosePdiCommand(SenderIdentifier, ReceiverIdentifier, CloseReason); + } + + public override byte[] ToByteArray() { + var result = new byte[44]; + result[0] = (byte)ProtocolType.GenericIO; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + result[CloseReasonOffset] = (byte)CloseReason; + return result; + } +} + +public enum GenericIOClosePdiCommandCloseReason : byte { + ProtocolError = 0x01, + FormalTelegramError = 0x02, + ContentTelegramError = 0x03, + NormalClose = 0x04, + OtherVersionRequired = 0x05, + Timeout = 0x06, + ChecksumMismatch = 0x07 +} + +public record ExternalLevelCrossingSystemClosePdiCommand (string SenderIdentifier, string ReceiverIdentifier, ExternalLevelCrossingSystemClosePdiCommandCloseReason CloseReason) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int CloseReasonOffset = 43; + public static readonly ushort MessageType = 0x0027; + + public new static ExternalLevelCrossingSystemClosePdiCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var CloseReason = (ExternalLevelCrossingSystemClosePdiCommandCloseReason)message[CloseReasonOffset]; + return new ExternalLevelCrossingSystemClosePdiCommand(SenderIdentifier, ReceiverIdentifier, CloseReason); + } + + public override byte[] ToByteArray() { + var result = new byte[44]; + result[0] = (byte)ProtocolType.ExternalLevelCrossingSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + result[CloseReasonOffset] = (byte)CloseReason; + return result; + } +} + +public enum ExternalLevelCrossingSystemClosePdiCommandCloseReason : byte { + ProtocolError = 0x01, + FormalTelegramError = 0x02, + ContentTelegramError = 0x03, + NormalClose = 0x04, + OtherVersionRequired = 0x05, + Timeout = 0x06, + ChecksumMismatch = 0x07 +} + +public record AdjacentInterlockingSystemReleasePdiForMaintenanceCommand (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0028; + + public new static AdjacentInterlockingSystemReleasePdiForMaintenanceCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new AdjacentInterlockingSystemReleasePdiForMaintenanceCommand(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.AdjacentInterlockingSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record TrainDetectionSystemReleasePdiForMaintenanceCommand (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0028; + + public new static TrainDetectionSystemReleasePdiForMaintenanceCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new TrainDetectionSystemReleasePdiForMaintenanceCommand(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.TrainDetectionSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record LightSignalReleasePdiForMaintenanceCommand (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0028; + + public new static LightSignalReleasePdiForMaintenanceCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new LightSignalReleasePdiForMaintenanceCommand(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.LightSignal; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record PointReleasePdiForMaintenanceCommand (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0028; + + public new static PointReleasePdiForMaintenanceCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new PointReleasePdiForMaintenanceCommand(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.Point; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record RadioBlockCenterReleasePdiForMaintenanceCommand (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0028; + + public new static RadioBlockCenterReleasePdiForMaintenanceCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new RadioBlockCenterReleasePdiForMaintenanceCommand(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.RadioBlockCenter; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record LevelCrossingReleasePdiForMaintenanceCommand (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0028; + + public new static LevelCrossingReleasePdiForMaintenanceCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new LevelCrossingReleasePdiForMaintenanceCommand(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.LevelCrossing; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record CCReleasePdiForMaintenanceCommand (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0028; + + public new static CCReleasePdiForMaintenanceCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new CCReleasePdiForMaintenanceCommand(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.CC; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record GenericIOReleasePdiForMaintenanceCommand (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0028; + + public new static GenericIOReleasePdiForMaintenanceCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new GenericIOReleasePdiForMaintenanceCommand(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.GenericIO; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record ExternalLevelCrossingSystemReleasePdiForMaintenanceCommand (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0028; + + public new static ExternalLevelCrossingSystemReleasePdiForMaintenanceCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new ExternalLevelCrossingSystemReleasePdiForMaintenanceCommand(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.ExternalLevelCrossingSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record AdjacentInterlockingSystemPdiAvailableMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0029; + + public new static AdjacentInterlockingSystemPdiAvailableMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new AdjacentInterlockingSystemPdiAvailableMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.AdjacentInterlockingSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record TrainDetectionSystemPdiAvailableMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0029; + + public new static TrainDetectionSystemPdiAvailableMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new TrainDetectionSystemPdiAvailableMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.TrainDetectionSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record LightSignalPdiAvailableMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0029; + + public new static LightSignalPdiAvailableMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new LightSignalPdiAvailableMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.LightSignal; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record PointPdiAvailableMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0029; + + public new static PointPdiAvailableMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new PointPdiAvailableMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.Point; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record RadioBlockCenterPdiAvailableMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0029; + + public new static RadioBlockCenterPdiAvailableMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new RadioBlockCenterPdiAvailableMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.RadioBlockCenter; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record LevelCrossingPdiAvailableMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0029; + + public new static LevelCrossingPdiAvailableMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new LevelCrossingPdiAvailableMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.LevelCrossing; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record CCPdiAvailableMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0029; + + public new static CCPdiAvailableMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new CCPdiAvailableMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.CC; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record GenericIOPdiAvailableMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0029; + + public new static GenericIOPdiAvailableMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new GenericIOPdiAvailableMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.GenericIO; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record ExternalLevelCrossingSystemPdiAvailableMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0029; + + public new static ExternalLevelCrossingSystemPdiAvailableMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new ExternalLevelCrossingSystemPdiAvailableMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.ExternalLevelCrossingSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record AdjacentInterlockingSystemPdiNotAvailableMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x002A; + + public new static AdjacentInterlockingSystemPdiNotAvailableMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new AdjacentInterlockingSystemPdiNotAvailableMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.AdjacentInterlockingSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record TrainDetectionSystemPdiNotAvailableMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x002A; + + public new static TrainDetectionSystemPdiNotAvailableMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new TrainDetectionSystemPdiNotAvailableMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.TrainDetectionSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record LightSignalPdiNotAvailableMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x002A; + + public new static LightSignalPdiNotAvailableMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new LightSignalPdiNotAvailableMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.LightSignal; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record PointPdiNotAvailableMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x002A; + + public new static PointPdiNotAvailableMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new PointPdiNotAvailableMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.Point; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record RadioBlockCenterPdiNotAvailableMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x002A; + + public new static RadioBlockCenterPdiNotAvailableMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new RadioBlockCenterPdiNotAvailableMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.RadioBlockCenter; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record LevelCrossingPdiNotAvailableMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x002A; + + public new static LevelCrossingPdiNotAvailableMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new LevelCrossingPdiNotAvailableMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.LevelCrossing; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record CCPdiNotAvailableMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x002A; + + public new static CCPdiNotAvailableMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new CCPdiNotAvailableMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.CC; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record GenericIOPdiNotAvailableMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x002A; + + public new static GenericIOPdiNotAvailableMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new GenericIOPdiNotAvailableMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.GenericIO; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record ExternalLevelCrossingSystemPdiNotAvailableMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x002A; + + public new static ExternalLevelCrossingSystemPdiNotAvailableMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new ExternalLevelCrossingSystemPdiNotAvailableMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.ExternalLevelCrossingSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record AdjacentInterlockingSystemResetPdiMessage (string SenderIdentifier, string ReceiverIdentifier, AdjacentInterlockingSystemResetPdiMessageResetReason ResetReason) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int ResetReasonOffset = 43; + public static readonly ushort MessageType = 0x002B; + + public new static AdjacentInterlockingSystemResetPdiMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var ResetReason = (AdjacentInterlockingSystemResetPdiMessageResetReason)message[ResetReasonOffset]; + return new AdjacentInterlockingSystemResetPdiMessage(SenderIdentifier, ReceiverIdentifier, ResetReason); + } + + public override byte[] ToByteArray() { + var result = new byte[44]; + result[0] = (byte)ProtocolType.AdjacentInterlockingSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + result[ResetReasonOffset] = (byte)ResetReason; + return result; + } +} + +public enum AdjacentInterlockingSystemResetPdiMessageResetReason : byte { + ProtocolError = 0x01, + FormalTelegramError = 0x02, + ContentTelegramError = 0x03 +} + +public record TrainDetectionSystemResetPdiMessage (string SenderIdentifier, string ReceiverIdentifier, TrainDetectionSystemResetPdiMessageResetReason ResetReason) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int ResetReasonOffset = 43; + public static readonly ushort MessageType = 0x002B; + + public new static TrainDetectionSystemResetPdiMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var ResetReason = (TrainDetectionSystemResetPdiMessageResetReason)message[ResetReasonOffset]; + return new TrainDetectionSystemResetPdiMessage(SenderIdentifier, ReceiverIdentifier, ResetReason); + } + + public override byte[] ToByteArray() { + var result = new byte[44]; + result[0] = (byte)ProtocolType.TrainDetectionSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + result[ResetReasonOffset] = (byte)ResetReason; + return result; + } +} + +public enum TrainDetectionSystemResetPdiMessageResetReason : byte { + ProtocolError = 0x01, + FormalTelegramError = 0x02, + ContentTelegramError = 0x03 +} + +public record LightSignalResetPdiMessage (string SenderIdentifier, string ReceiverIdentifier, LightSignalResetPdiMessageResetReason ResetReason) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int ResetReasonOffset = 43; + public static readonly ushort MessageType = 0x002B; + + public new static LightSignalResetPdiMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var ResetReason = (LightSignalResetPdiMessageResetReason)message[ResetReasonOffset]; + return new LightSignalResetPdiMessage(SenderIdentifier, ReceiverIdentifier, ResetReason); + } + + public override byte[] ToByteArray() { + var result = new byte[44]; + result[0] = (byte)ProtocolType.LightSignal; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + result[ResetReasonOffset] = (byte)ResetReason; + return result; + } +} + +public enum LightSignalResetPdiMessageResetReason : byte { + ProtocolError = 0x01, + FormalTelegramError = 0x02, + ContentTelegramError = 0x03 +} + +public record PointResetPdiMessage (string SenderIdentifier, string ReceiverIdentifier, PointResetPdiMessageResetReason ResetReason) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int ResetReasonOffset = 43; + public static readonly ushort MessageType = 0x002B; + + public new static PointResetPdiMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var ResetReason = (PointResetPdiMessageResetReason)message[ResetReasonOffset]; + return new PointResetPdiMessage(SenderIdentifier, ReceiverIdentifier, ResetReason); + } + + public override byte[] ToByteArray() { + var result = new byte[44]; + result[0] = (byte)ProtocolType.Point; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + result[ResetReasonOffset] = (byte)ResetReason; + return result; + } +} + +public enum PointResetPdiMessageResetReason : byte { + ProtocolError = 0x01, + FormalTelegramError = 0x02, + ContentTelegramError = 0x03 +} + +public record RadioBlockCenterResetPdiMessage (string SenderIdentifier, string ReceiverIdentifier, RadioBlockCenterResetPdiMessageResetReason ResetReason) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int ResetReasonOffset = 43; + public static readonly ushort MessageType = 0x002B; + + public new static RadioBlockCenterResetPdiMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var ResetReason = (RadioBlockCenterResetPdiMessageResetReason)message[ResetReasonOffset]; + return new RadioBlockCenterResetPdiMessage(SenderIdentifier, ReceiverIdentifier, ResetReason); + } + + public override byte[] ToByteArray() { + var result = new byte[44]; + result[0] = (byte)ProtocolType.RadioBlockCenter; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + result[ResetReasonOffset] = (byte)ResetReason; + return result; + } +} + +public enum RadioBlockCenterResetPdiMessageResetReason : byte { + ProtocolError = 0x01, + FormalTelegramError = 0x02, + ContentTelegramError = 0x03 +} + +public record LevelCrossingResetPdiMessage (string SenderIdentifier, string ReceiverIdentifier, LevelCrossingResetPdiMessageResetReason ResetReason) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int ResetReasonOffset = 43; + public static readonly ushort MessageType = 0x002B; + + public new static LevelCrossingResetPdiMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var ResetReason = (LevelCrossingResetPdiMessageResetReason)message[ResetReasonOffset]; + return new LevelCrossingResetPdiMessage(SenderIdentifier, ReceiverIdentifier, ResetReason); + } + + public override byte[] ToByteArray() { + var result = new byte[44]; + result[0] = (byte)ProtocolType.LevelCrossing; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + result[ResetReasonOffset] = (byte)ResetReason; + return result; + } +} + +public enum LevelCrossingResetPdiMessageResetReason : byte { + ProtocolError = 0x01, + FormalTelegramError = 0x02, + ContentTelegramError = 0x03 +} + +public record CCResetPdiMessage (string SenderIdentifier, string ReceiverIdentifier, CCResetPdiMessageResetReason ResetReason) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int ResetReasonOffset = 43; + public static readonly ushort MessageType = 0x002B; + + public new static CCResetPdiMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var ResetReason = (CCResetPdiMessageResetReason)message[ResetReasonOffset]; + return new CCResetPdiMessage(SenderIdentifier, ReceiverIdentifier, ResetReason); + } + + public override byte[] ToByteArray() { + var result = new byte[44]; + result[0] = (byte)ProtocolType.CC; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + result[ResetReasonOffset] = (byte)ResetReason; + return result; + } +} + +public enum CCResetPdiMessageResetReason : byte { + ProtocolError = 0x01, + FormalTelegramError = 0x02, + ContentTelegramError = 0x03 +} + +public record GenericIOResetPdiMessage (string SenderIdentifier, string ReceiverIdentifier, GenericIOResetPdiMessageResetReason ResetReason) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int ResetReasonOffset = 43; + public static readonly ushort MessageType = 0x002B; + + public new static GenericIOResetPdiMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var ResetReason = (GenericIOResetPdiMessageResetReason)message[ResetReasonOffset]; + return new GenericIOResetPdiMessage(SenderIdentifier, ReceiverIdentifier, ResetReason); + } + + public override byte[] ToByteArray() { + var result = new byte[44]; + result[0] = (byte)ProtocolType.GenericIO; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + result[ResetReasonOffset] = (byte)ResetReason; + return result; + } +} + +public enum GenericIOResetPdiMessageResetReason : byte { + ProtocolError = 0x01, + FormalTelegramError = 0x02, + ContentTelegramError = 0x03 +} + +public record ExternalLevelCrossingSystemResetPdiMessage (string SenderIdentifier, string ReceiverIdentifier, ExternalLevelCrossingSystemResetPdiMessageResetReason ResetReason) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int ResetReasonOffset = 43; + public static readonly ushort MessageType = 0x002B; + + public new static ExternalLevelCrossingSystemResetPdiMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var ResetReason = (ExternalLevelCrossingSystemResetPdiMessageResetReason)message[ResetReasonOffset]; + return new ExternalLevelCrossingSystemResetPdiMessage(SenderIdentifier, ReceiverIdentifier, ResetReason); + } + + public override byte[] ToByteArray() { + var result = new byte[44]; + result[0] = (byte)ProtocolType.ExternalLevelCrossingSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + result[ResetReasonOffset] = (byte)ResetReason; + return result; + } +} + +public enum ExternalLevelCrossingSystemResetPdiMessageResetReason : byte { + ProtocolError = 0x01, + FormalTelegramError = 0x02, + ContentTelegramError = 0x03 +} diff --git a/src/Messages/Baseline4R2/InterfaceSpecificationSciIls.cs b/src/Messages/Baseline4R2/InterfaceSpecificationSciIls.cs new file mode 100644 index 0000000..af08c20 --- /dev/null +++ b/src/Messages/Baseline4R2/InterfaceSpecificationSciIls.cs @@ -0,0 +1,872 @@ +using System; +using System.Text; +using System.Linq; + +namespace EulynxLive.Messages.Baseline4R2; + +public record AdjacentInterlockingSystemActivationZoneStatusMessage (string SenderIdentifier, string ReceiverIdentifier, string BoundaryId, string ActivationZoneId, AdjacentInterlockingSystemActivationZoneStatusMessageActivationZoneStatus ActivationZoneStatus) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int BoundaryIdOffset = 43; + private const int ActivationZoneIdOffset = 63; + private const int ActivationZoneStatusOffset = 83; + public static readonly ushort MessageType = 0x0001; + + public new static AdjacentInterlockingSystemActivationZoneStatusMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var BoundaryId = Encoding.Latin1.GetString(message, BoundaryIdOffset, 20); + var ActivationZoneId = Encoding.Latin1.GetString(message, ActivationZoneIdOffset, 20); + var ActivationZoneStatus = (AdjacentInterlockingSystemActivationZoneStatusMessageActivationZoneStatus)message[ActivationZoneStatusOffset]; + return new AdjacentInterlockingSystemActivationZoneStatusMessage(SenderIdentifier, ReceiverIdentifier, BoundaryId, ActivationZoneId, ActivationZoneStatus); + } + + public override byte[] ToByteArray() { + var result = new byte[84]; + result[0] = (byte)ProtocolType.AdjacentInterlockingSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + Encoding.Latin1.GetBytes(BoundaryId.PadRight(20, '_')).CopyTo(result, BoundaryIdOffset); + Encoding.Latin1.GetBytes(ActivationZoneId.PadRight(20, '_')).CopyTo(result, ActivationZoneIdOffset); + result[ActivationZoneStatusOffset] = (byte)ActivationZoneStatus; + return result; + } +} + +public enum AdjacentInterlockingSystemActivationZoneStatusMessageActivationZoneStatus : byte { + Active = 0x01, + NotActive = 0x02 +} + +public record AdjacentInterlockingSystemApproachZoneStatusMessage (string SenderIdentifier, string ReceiverIdentifier, string BoundaryId, string ApproachZoneId, AdjacentInterlockingSystemApproachZoneStatusMessageApproachZoneStatus ApproachZoneStatus) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int BoundaryIdOffset = 43; + private const int ApproachZoneIdOffset = 63; + private const int ApproachZoneStatusOffset = 83; + public static readonly ushort MessageType = 0x0002; + + public new static AdjacentInterlockingSystemApproachZoneStatusMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var BoundaryId = Encoding.Latin1.GetString(message, BoundaryIdOffset, 20); + var ApproachZoneId = Encoding.Latin1.GetString(message, ApproachZoneIdOffset, 20); + var ApproachZoneStatus = (AdjacentInterlockingSystemApproachZoneStatusMessageApproachZoneStatus)message[ApproachZoneStatusOffset]; + return new AdjacentInterlockingSystemApproachZoneStatusMessage(SenderIdentifier, ReceiverIdentifier, BoundaryId, ApproachZoneId, ApproachZoneStatus); + } + + public override byte[] ToByteArray() { + var result = new byte[84]; + result[0] = (byte)ProtocolType.AdjacentInterlockingSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + Encoding.Latin1.GetBytes(BoundaryId.PadRight(20, '_')).CopyTo(result, BoundaryIdOffset); + Encoding.Latin1.GetBytes(ApproachZoneId.PadRight(20, '_')).CopyTo(result, ApproachZoneIdOffset); + result[ApproachZoneStatusOffset] = (byte)ApproachZoneStatus; + return result; + } +} + +public enum AdjacentInterlockingSystemApproachZoneStatusMessageApproachZoneStatus : byte { + Active = 0x01, + NotActive = 0x02 +} + +public record AdjacentInterlockingSystemAccessRestrictionRequestCommand (string SenderIdentifier, string ReceiverIdentifier, string BoundaryId, AdjacentInterlockingSystemAccessRestrictionRequestCommandAccessRestrictionType AccessRestrictionType) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int BoundaryIdOffset = 43; + private const int AccessRestrictionTypeOffset = 63; + public static readonly ushort MessageType = 0x0003; + + public new static AdjacentInterlockingSystemAccessRestrictionRequestCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var BoundaryId = Encoding.Latin1.GetString(message, BoundaryIdOffset, 20); + var AccessRestrictionType = (AdjacentInterlockingSystemAccessRestrictionRequestCommandAccessRestrictionType)message[AccessRestrictionTypeOffset]; + return new AdjacentInterlockingSystemAccessRestrictionRequestCommand(SenderIdentifier, ReceiverIdentifier, BoundaryId, AccessRestrictionType); + } + + public override byte[] ToByteArray() { + var result = new byte[64]; + result[0] = (byte)ProtocolType.AdjacentInterlockingSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + Encoding.Latin1.GetBytes(BoundaryId.PadRight(20, '_')).CopyTo(result, BoundaryIdOffset); + result[AccessRestrictionTypeOffset] = (byte)AccessRestrictionType; + return result; + } +} + +public enum AdjacentInterlockingSystemAccessRestrictionRequestCommandAccessRestrictionType : byte { + NoAccess = 0x01, + WorkTrack = 0x02, + TrackOutOfService = 0x03, + EmergencyTrain = 0x04, + SecondaryVehicle = 0x05, + WorkTeam = 0x06, + LevelCrossingInDegradedOperation = 0x07, + ClearanceCheckRequired = 0x08, + SectionCheckRequired = 0x09, + NoElectricTrains = 0x10, + ExtraordinaryTransport = 0x11, + CatenaryOffPantographDown = 0x12, + WrittenOrderRequired = 0x13, + AccessRestrictionTypeNotApplicable = 0xFF +} + +public record AdjacentInterlockingSystemAccessRestrictionStatusMessage (string SenderIdentifier, string ReceiverIdentifier, string BoundaryId, AdjacentInterlockingSystemAccessRestrictionStatusMessageAccessRestrictionActivationStatus AccessRestrictionActivationStatus, AdjacentInterlockingSystemAccessRestrictionStatusMessageAccessRestrictionType AccessRestrictionType) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int BoundaryIdOffset = 43; + private const int AccessRestrictionActivationStatusOffset = 63; + private const int AccessRestrictionTypeOffset = 64; + public static readonly ushort MessageType = 0x0012; + + public new static AdjacentInterlockingSystemAccessRestrictionStatusMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var BoundaryId = Encoding.Latin1.GetString(message, BoundaryIdOffset, 20); + var AccessRestrictionActivationStatus = (AdjacentInterlockingSystemAccessRestrictionStatusMessageAccessRestrictionActivationStatus)message[AccessRestrictionActivationStatusOffset]; + var AccessRestrictionType = (AdjacentInterlockingSystemAccessRestrictionStatusMessageAccessRestrictionType)message[AccessRestrictionTypeOffset]; + return new AdjacentInterlockingSystemAccessRestrictionStatusMessage(SenderIdentifier, ReceiverIdentifier, BoundaryId, AccessRestrictionActivationStatus, AccessRestrictionType); + } + + public override byte[] ToByteArray() { + var result = new byte[65]; + result[0] = (byte)ProtocolType.AdjacentInterlockingSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + Encoding.Latin1.GetBytes(BoundaryId.PadRight(20, '_')).CopyTo(result, BoundaryIdOffset); + result[AccessRestrictionActivationStatusOffset] = (byte)AccessRestrictionActivationStatus; + result[AccessRestrictionTypeOffset] = (byte)AccessRestrictionType; + return result; + } +} + +public enum AdjacentInterlockingSystemAccessRestrictionStatusMessageAccessRestrictionActivationStatus : byte { + Active = 0x01, + NotActive = 0x02 +} + +public enum AdjacentInterlockingSystemAccessRestrictionStatusMessageAccessRestrictionType : byte { + NoAccess = 0x01, + WorkTrack = 0x02, + TrackOutOfService = 0x03, + EmergencyTrain = 0x04, + SecondaryVehicle = 0x05, + WorkTeam = 0x06, + LevelCrossingInDegradedOperation = 0x07, + ClearanceCheckRequired = 0x08, + SectionCheckRequired = 0x09, + NoElectricTrains = 0x10, + ExtraordinaryTransport = 0x11, + CatenaryOffPantographDown = 0x12, + WrittenOrderRequired = 0x13, + ManualRouteCondition = 0x14, + DoNotUseOppositeDirection = 0x15, + UseOppositeDirection = 0x16, + NoLxRemoteSupervision = 0x17, + LxRemoteSupervisionTimeout = 0x18, + AccessRestrictionTypeNotApplicable = 0xFF +} + +public record AdjacentInterlockingSystemLineStatusMessage (string SenderIdentifier, string ReceiverIdentifier, string BoundaryId, AdjacentInterlockingSystemLineStatusMessageLineStatus LineStatus) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int BoundaryIdOffset = 43; + private const int LineStatusOffset = 63; + public static readonly ushort MessageType = 0x0004; + + public new static AdjacentInterlockingSystemLineStatusMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var BoundaryId = Encoding.Latin1.GetString(message, BoundaryIdOffset, 20); + var LineStatus = (AdjacentInterlockingSystemLineStatusMessageLineStatus)message[LineStatusOffset]; + return new AdjacentInterlockingSystemLineStatusMessage(SenderIdentifier, ReceiverIdentifier, BoundaryId, LineStatus); + } + + public override byte[] ToByteArray() { + var result = new byte[64]; + result[0] = (byte)ProtocolType.AdjacentInterlockingSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + Encoding.Latin1.GetBytes(BoundaryId.PadRight(20, '_')).CopyTo(result, BoundaryIdOffset); + result[LineStatusOffset] = (byte)LineStatus; + return result; + } +} + +public enum AdjacentInterlockingSystemLineStatusMessageLineStatus : byte { + Vacant = 0x01, + Occupied = 0x02, + RequestForLineBlockReset = 0x03 +} + +public record AdjacentInterlockingSystemFlankProtectionRequestCommand (string SenderIdentifier, string ReceiverIdentifier, string BoundaryId, AdjacentInterlockingSystemFlankProtectionRequestCommandFlankProtectionRequestType FlankProtectionRequestType) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int BoundaryIdOffset = 43; + private const int FlankProtectionRequestTypeOffset = 63; + public static readonly ushort MessageType = 0x0005; + + public new static AdjacentInterlockingSystemFlankProtectionRequestCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var BoundaryId = Encoding.Latin1.GetString(message, BoundaryIdOffset, 20); + var FlankProtectionRequestType = (AdjacentInterlockingSystemFlankProtectionRequestCommandFlankProtectionRequestType)message[FlankProtectionRequestTypeOffset]; + return new AdjacentInterlockingSystemFlankProtectionRequestCommand(SenderIdentifier, ReceiverIdentifier, BoundaryId, FlankProtectionRequestType); + } + + public override byte[] ToByteArray() { + var result = new byte[64]; + result[0] = (byte)ProtocolType.AdjacentInterlockingSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + Encoding.Latin1.GetBytes(BoundaryId.PadRight(20, '_')).CopyTo(result, BoundaryIdOffset); + result[FlankProtectionRequestTypeOffset] = (byte)FlankProtectionRequestType; + return result; + } +} + +public enum AdjacentInterlockingSystemFlankProtectionRequestCommandFlankProtectionRequestType : byte { + Provision = 0x01, + Cancellation = 0x02 +} + +public record AdjacentInterlockingSystemFlankProtectionStatusMessage (string SenderIdentifier, string ReceiverIdentifier, string BoundaryId, AdjacentInterlockingSystemFlankProtectionStatusMessageFlankProtectionStatus FlankProtectionStatus) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int BoundaryIdOffset = 43; + private const int FlankProtectionStatusOffset = 63; + public static readonly ushort MessageType = 0x0013; + + public new static AdjacentInterlockingSystemFlankProtectionStatusMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var BoundaryId = Encoding.Latin1.GetString(message, BoundaryIdOffset, 20); + var FlankProtectionStatus = (AdjacentInterlockingSystemFlankProtectionStatusMessageFlankProtectionStatus)message[FlankProtectionStatusOffset]; + return new AdjacentInterlockingSystemFlankProtectionStatusMessage(SenderIdentifier, ReceiverIdentifier, BoundaryId, FlankProtectionStatus); + } + + public override byte[] ToByteArray() { + var result = new byte[64]; + result[0] = (byte)ProtocolType.AdjacentInterlockingSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + Encoding.Latin1.GetBytes(BoundaryId.PadRight(20, '_')).CopyTo(result, BoundaryIdOffset); + result[FlankProtectionStatusOffset] = (byte)FlankProtectionStatus; + return result; + } +} + +public enum AdjacentInterlockingSystemFlankProtectionStatusMessageFlankProtectionStatus : byte { + Provided = 0x01, + NotProvided = 0x02 +} + +public record AdjacentInterlockingSystemRouteRequestCommand (string SenderIdentifier, string ReceiverIdentifier, string BoundaryId, string RouteId, AdjacentInterlockingSystemRouteRequestCommandRouteType RouteType) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int BoundaryIdOffset = 43; + private const int RouteIdOffset = 63; + private const int RouteTypeOffset = 83; + public static readonly ushort MessageType = 0x0007; + + public new static AdjacentInterlockingSystemRouteRequestCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var BoundaryId = Encoding.Latin1.GetString(message, BoundaryIdOffset, 20); + var RouteId = Encoding.Latin1.GetString(message, RouteIdOffset, 20); + var RouteType = (AdjacentInterlockingSystemRouteRequestCommandRouteType)message[RouteTypeOffset]; + return new AdjacentInterlockingSystemRouteRequestCommand(SenderIdentifier, ReceiverIdentifier, BoundaryId, RouteId, RouteType); + } + + public override byte[] ToByteArray() { + var result = new byte[84]; + result[0] = (byte)ProtocolType.AdjacentInterlockingSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + Encoding.Latin1.GetBytes(BoundaryId.PadRight(20, '_')).CopyTo(result, BoundaryIdOffset); + Encoding.Latin1.GetBytes(RouteId.PadRight(20, '_')).CopyTo(result, RouteIdOffset); + result[RouteTypeOffset] = (byte)RouteType; + return result; + } +} + +public enum AdjacentInterlockingSystemRouteRequestCommandRouteType : byte { + MainRoute = 0x01, + ShuntingRoute = 0x02, + OnSightRoute = 0x03, + SrTrainRoute = 0x04, + SpecialTrainRoute = 0x05, + TemporaryShuntingArea = 0x06 +} + +public record AdjacentInterlockingSystemRouteStatusMessage (string SenderIdentifier, string ReceiverIdentifier, string BoundaryId, string RouteId, AdjacentInterlockingSystemRouteStatusMessageRouteType RouteType, AdjacentInterlockingSystemRouteStatusMessageRouteStatus RouteStatus) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int BoundaryIdOffset = 43; + private const int RouteIdOffset = 63; + private const int RouteTypeOffset = 83; + private const int RouteStatusOffset = 84; + public static readonly ushort MessageType = 0x0008; + + public new static AdjacentInterlockingSystemRouteStatusMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var BoundaryId = Encoding.Latin1.GetString(message, BoundaryIdOffset, 20); + var RouteId = Encoding.Latin1.GetString(message, RouteIdOffset, 20); + var RouteType = (AdjacentInterlockingSystemRouteStatusMessageRouteType)message[RouteTypeOffset]; + var RouteStatus = (AdjacentInterlockingSystemRouteStatusMessageRouteStatus)message[RouteStatusOffset]; + return new AdjacentInterlockingSystemRouteStatusMessage(SenderIdentifier, ReceiverIdentifier, BoundaryId, RouteId, RouteType, RouteStatus); + } + + public override byte[] ToByteArray() { + var result = new byte[85]; + result[0] = (byte)ProtocolType.AdjacentInterlockingSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + Encoding.Latin1.GetBytes(BoundaryId.PadRight(20, '_')).CopyTo(result, BoundaryIdOffset); + Encoding.Latin1.GetBytes(RouteId.PadRight(20, '_')).CopyTo(result, RouteIdOffset); + result[RouteTypeOffset] = (byte)RouteType; + result[RouteStatusOffset] = (byte)RouteStatus; + return result; + } +} + +public enum AdjacentInterlockingSystemRouteStatusMessageRouteType : byte { + MainRoute = 0x01, + ShuntingRoute = 0x02, + OnSightRoute = 0x03, + SrTrainRoute = 0x04, + SpecialTrainRoute = 0x05, + TemporaryShuntingArea = 0x06 +} + +public enum AdjacentInterlockingSystemRouteStatusMessageRouteStatus : byte { + Initiated = 0x01, + Locked = 0x02, + NoRoute = 0x03, + Cancelling = 0x04 +} + +public record AdjacentInterlockingSystemRouteMonitoringStatusMessage (string SenderIdentifier, string ReceiverIdentifier, string BoundaryId, string RouteId, AdjacentInterlockingSystemRouteMonitoringStatusMessageRouteType RouteType, string OverlapId, AdjacentInterlockingSystemRouteMonitoringStatusMessageRouteMonitoring RouteMonitoring, AdjacentInterlockingSystemRouteMonitoringStatusMessageOccupancyMonitoring OccupancyMonitoring, AdjacentInterlockingSystemRouteMonitoringStatusMessageLevelCrossingMonitoring LevelCrossingMonitoring, byte EntranceSpeed, byte TargetSpeed, AdjacentInterlockingSystemRouteMonitoringStatusMessageDynamicOrStaticTargetSpeed DynamicOrStaticTargetSpeed) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int BoundaryIdOffset = 43; + private const int RouteIdOffset = 63; + private const int RouteTypeOffset = 83; + private const int OverlapIdOffset = 84; + private const int RouteMonitoringOffset = 104; + private const int OccupancyMonitoringOffset = 105; + private const int LevelCrossingMonitoringOffset = 106; + private const int EntranceSpeedOffset = 107; + private const int TargetSpeedOffset = 108; + private const int DynamicOrStaticTargetSpeedOffset = 109; + public static readonly ushort MessageType = 0x0009; + + public new static AdjacentInterlockingSystemRouteMonitoringStatusMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var BoundaryId = Encoding.Latin1.GetString(message, BoundaryIdOffset, 20); + var RouteId = Encoding.Latin1.GetString(message, RouteIdOffset, 20); + var RouteType = (AdjacentInterlockingSystemRouteMonitoringStatusMessageRouteType)message[RouteTypeOffset]; + var OverlapId = Encoding.Latin1.GetString(message, OverlapIdOffset, 20); + var RouteMonitoring = (AdjacentInterlockingSystemRouteMonitoringStatusMessageRouteMonitoring)message[RouteMonitoringOffset]; + var OccupancyMonitoring = (AdjacentInterlockingSystemRouteMonitoringStatusMessageOccupancyMonitoring)message[OccupancyMonitoringOffset]; + var LevelCrossingMonitoring = (AdjacentInterlockingSystemRouteMonitoringStatusMessageLevelCrossingMonitoring)message[LevelCrossingMonitoringOffset]; + var EntranceSpeed = (byte)message[EntranceSpeedOffset]; + var TargetSpeed = (byte)message[TargetSpeedOffset]; + var DynamicOrStaticTargetSpeed = (AdjacentInterlockingSystemRouteMonitoringStatusMessageDynamicOrStaticTargetSpeed)message[DynamicOrStaticTargetSpeedOffset]; + return new AdjacentInterlockingSystemRouteMonitoringStatusMessage(SenderIdentifier, ReceiverIdentifier, BoundaryId, RouteId, RouteType, OverlapId, RouteMonitoring, OccupancyMonitoring, LevelCrossingMonitoring, EntranceSpeed, TargetSpeed, DynamicOrStaticTargetSpeed); + } + + public override byte[] ToByteArray() { + var result = new byte[110]; + result[0] = (byte)ProtocolType.AdjacentInterlockingSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + Encoding.Latin1.GetBytes(BoundaryId.PadRight(20, '_')).CopyTo(result, BoundaryIdOffset); + Encoding.Latin1.GetBytes(RouteId.PadRight(20, '_')).CopyTo(result, RouteIdOffset); + result[RouteTypeOffset] = (byte)RouteType; + Encoding.Latin1.GetBytes(OverlapId.PadRight(20, '_')).CopyTo(result, OverlapIdOffset); + result[RouteMonitoringOffset] = (byte)RouteMonitoring; + result[OccupancyMonitoringOffset] = (byte)OccupancyMonitoring; + result[LevelCrossingMonitoringOffset] = (byte)LevelCrossingMonitoring; + result[EntranceSpeedOffset] = (byte)EntranceSpeed; + result[TargetSpeedOffset] = (byte)TargetSpeed; + result[DynamicOrStaticTargetSpeedOffset] = (byte)DynamicOrStaticTargetSpeed; + return result; + } +} + +public enum AdjacentInterlockingSystemRouteMonitoringStatusMessageRouteType : byte { + MainRoute = 0x01, + ShuntingRoute = 0x02, + OnSightRoute = 0x03, + SrTrainRoute = 0x04, + SpecialTrainRoute = 0x05, + TemporaryShuntingArea = 0x06 +} + +public enum AdjacentInterlockingSystemRouteMonitoringStatusMessageRouteMonitoring : byte { + RouteMonitoringConditionsOfSecondaryRoutePresent = 0x01, + RouteMonitoringConditionsOfSecondaryRouteNotPresent = 0x02, + RouteMonitoringConditionsOfSecondaryRoutePresentUpToNextBlockIndicator = 0x03, + ShuntingRouteMonitoringConditionsOfSecondaryRoutePresent = 0x04 +} + +public enum AdjacentInterlockingSystemRouteMonitoringStatusMessageOccupancyMonitoring : byte { + Occupation = 0x01, + NoOccupation = 0x02, + OccupancyMonitoringNotApplicable = 0xFF +} + +public enum AdjacentInterlockingSystemRouteMonitoringStatusMessageLevelCrossingMonitoring : byte { + LevelCrossingMonitoringConditionsOfSecondaryRoutePresent = 0x01, + LevelCrossingMonitoringConditionsOfSecondaryRouteNotPresent = 0x02, + LevelCrossingMonitoringConditionsPresentUpToNextBlockIndicator = 0x03, + LevelCrossingMonitoringNotApplicable = 0xFF +} + +public enum AdjacentInterlockingSystemRouteMonitoringStatusMessageDynamicOrStaticTargetSpeed : byte { + Dynamic = 0x01, + Static = 0x02, + DynamicOrStaticTargetSpeedNotApplicable = 0xFF +} + +public record AdjacentInterlockingSystemRouteCancellationRequestCommand (string SenderIdentifier, string ReceiverIdentifier, string BoundaryId, string RouteId) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int BoundaryIdOffset = 43; + private const int RouteIdOffset = 63; + public static readonly ushort MessageType = 0x000A; + + public new static AdjacentInterlockingSystemRouteCancellationRequestCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var BoundaryId = Encoding.Latin1.GetString(message, BoundaryIdOffset, 20); + var RouteId = Encoding.Latin1.GetString(message, RouteIdOffset, 20); + return new AdjacentInterlockingSystemRouteCancellationRequestCommand(SenderIdentifier, ReceiverIdentifier, BoundaryId, RouteId); + } + + public override byte[] ToByteArray() { + var result = new byte[83]; + result[0] = (byte)ProtocolType.AdjacentInterlockingSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + Encoding.Latin1.GetBytes(BoundaryId.PadRight(20, '_')).CopyTo(result, BoundaryIdOffset); + Encoding.Latin1.GetBytes(RouteId.PadRight(20, '_')).CopyTo(result, RouteIdOffset); + return result; + } +} + + + +public record AdjacentInterlockingSystemTrainOperatedRouteReleaseStatusMessage (string SenderIdentifier, string ReceiverIdentifier, string BoundaryId, AdjacentInterlockingSystemTrainOperatedRouteReleaseStatusMessageTrainOperatedRouteReleaseStatus TrainOperatedRouteReleaseStatus) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int BoundaryIdOffset = 43; + private const int TrainOperatedRouteReleaseStatusOffset = 63; + public static readonly ushort MessageType = 0x000B; + + public new static AdjacentInterlockingSystemTrainOperatedRouteReleaseStatusMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var BoundaryId = Encoding.Latin1.GetString(message, BoundaryIdOffset, 20); + var TrainOperatedRouteReleaseStatus = (AdjacentInterlockingSystemTrainOperatedRouteReleaseStatusMessageTrainOperatedRouteReleaseStatus)message[TrainOperatedRouteReleaseStatusOffset]; + return new AdjacentInterlockingSystemTrainOperatedRouteReleaseStatusMessage(SenderIdentifier, ReceiverIdentifier, BoundaryId, TrainOperatedRouteReleaseStatus); + } + + public override byte[] ToByteArray() { + var result = new byte[64]; + result[0] = (byte)ProtocolType.AdjacentInterlockingSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + Encoding.Latin1.GetBytes(BoundaryId.PadRight(20, '_')).CopyTo(result, BoundaryIdOffset); + result[TrainOperatedRouteReleaseStatusOffset] = (byte)TrainOperatedRouteReleaseStatus; + return result; + } +} + +public enum AdjacentInterlockingSystemTrainOperatedRouteReleaseStatusMessageTrainOperatedRouteReleaseStatus : byte { + TvpsAdjacentToTheBoundaryIsInACorrectOccupancySequence = 0x01, + TvpsAdjacentToTheBoundaryIsReleasedByTrain = 0x02, + TvpsAdjacentToTheBoundaryIsNotInACorrectOccupancySequenceAndNotReleasedByTrain = 0x03 +} + +public record AdjacentInterlockingSystemSignalStatusMessage (string SenderIdentifier, string ReceiverIdentifier, string BoundaryId, byte AspectLampCombinations, byte AspectExtensionLampCombinations, byte SpeedIndicator, byte SpeedIndicatorAnnouncement, byte DirectionIndicator, byte DirectionIndicatorAnnouncement, AdjacentInterlockingSystemSignalStatusMessageIntentionallyDark IntentionallyDark) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int BoundaryIdOffset = 43; + private const int AspectLampCombinationsOffset = 63; + private const int AspectExtensionLampCombinationsOffset = 64; + private const int SpeedIndicatorOffset = 65; + private const int SpeedIndicatorAnnouncementOffset = 66; + private const int DirectionIndicatorOffset = 67; + private const int DirectionIndicatorAnnouncementOffset = 68; + private const int IntentionallyDarkOffset = 69; + public static readonly ushort MessageType = 0x000C; + + public new static AdjacentInterlockingSystemSignalStatusMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var BoundaryId = Encoding.Latin1.GetString(message, BoundaryIdOffset, 20); + var AspectLampCombinations = (byte)message[AspectLampCombinationsOffset]; + var AspectExtensionLampCombinations = (byte)message[AspectExtensionLampCombinationsOffset]; + var SpeedIndicator = (byte)message[SpeedIndicatorOffset]; + var SpeedIndicatorAnnouncement = (byte)message[SpeedIndicatorAnnouncementOffset]; + var DirectionIndicator = (byte)message[DirectionIndicatorOffset]; + var DirectionIndicatorAnnouncement = (byte)message[DirectionIndicatorAnnouncementOffset]; + var IntentionallyDark = (AdjacentInterlockingSystemSignalStatusMessageIntentionallyDark)message[IntentionallyDarkOffset]; + return new AdjacentInterlockingSystemSignalStatusMessage(SenderIdentifier, ReceiverIdentifier, BoundaryId, AspectLampCombinations, AspectExtensionLampCombinations, SpeedIndicator, SpeedIndicatorAnnouncement, DirectionIndicator, DirectionIndicatorAnnouncement, IntentionallyDark); + } + + public override byte[] ToByteArray() { + var result = new byte[70]; + result[0] = (byte)ProtocolType.AdjacentInterlockingSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + Encoding.Latin1.GetBytes(BoundaryId.PadRight(20, '_')).CopyTo(result, BoundaryIdOffset); + result[AspectLampCombinationsOffset] = (byte)AspectLampCombinations; + result[AspectExtensionLampCombinationsOffset] = (byte)AspectExtensionLampCombinations; + result[SpeedIndicatorOffset] = (byte)SpeedIndicator; + result[SpeedIndicatorAnnouncementOffset] = (byte)SpeedIndicatorAnnouncement; + result[DirectionIndicatorOffset] = (byte)DirectionIndicator; + result[DirectionIndicatorAnnouncementOffset] = (byte)DirectionIndicatorAnnouncement; + result[IntentionallyDarkOffset] = (byte)IntentionallyDark; + return result; + } +} + +public enum AdjacentInterlockingSystemSignalStatusMessageIntentionallyDark : byte { + TheCommandedSignalAspectIsIndicatedInTheSetLuminosity = 0x01, + TheCommandedSignalAspectIsIndicatedDark = 0x0F, + IntentionallyDarkNotApplicable = 0xFF +} + +public record AdjacentInterlockingSystemTvpsStatusMessage (string SenderIdentifier, string ReceiverIdentifier, string BoundaryId, AdjacentInterlockingSystemTvpsStatusMessageOccupancyStatus OccupancyStatus, AdjacentInterlockingSystemTvpsStatusMessageFoulingStatus FoulingStatus) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int BoundaryIdOffset = 43; + private const int OccupancyStatusOffset = 63; + private const int FoulingStatusOffset = 64; + public static readonly ushort MessageType = 0x000D; + + public new static AdjacentInterlockingSystemTvpsStatusMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var BoundaryId = Encoding.Latin1.GetString(message, BoundaryIdOffset, 20); + var OccupancyStatus = (AdjacentInterlockingSystemTvpsStatusMessageOccupancyStatus)message[OccupancyStatusOffset]; + var FoulingStatus = (AdjacentInterlockingSystemTvpsStatusMessageFoulingStatus)message[FoulingStatusOffset]; + return new AdjacentInterlockingSystemTvpsStatusMessage(SenderIdentifier, ReceiverIdentifier, BoundaryId, OccupancyStatus, FoulingStatus); + } + + public override byte[] ToByteArray() { + var result = new byte[65]; + result[0] = (byte)ProtocolType.AdjacentInterlockingSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + Encoding.Latin1.GetBytes(BoundaryId.PadRight(20, '_')).CopyTo(result, BoundaryIdOffset); + result[OccupancyStatusOffset] = (byte)OccupancyStatus; + result[FoulingStatusOffset] = (byte)FoulingStatus; + return result; + } +} + +public enum AdjacentInterlockingSystemTvpsStatusMessageOccupancyStatus : byte { + Vacant = 0x01, + Occupied = 0x02, + Disturbed = 0x03 +} + +public enum AdjacentInterlockingSystemTvpsStatusMessageFoulingStatus : byte { + Fouling = 0x01, + NotFouling = 0x02, + FoulingStatusNotApplicable = 0xFF +} + +public record AdjacentInterlockingSystemOppositeMainSignalStatusMessage (string SenderIdentifier, string ReceiverIdentifier, string BoundaryId) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int BoundaryIdOffset = 43; + public static readonly ushort MessageType = 0x000E; + + public new static AdjacentInterlockingSystemOppositeMainSignalStatusMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var BoundaryId = Encoding.Latin1.GetString(message, BoundaryIdOffset, 20); + return new AdjacentInterlockingSystemOppositeMainSignalStatusMessage(SenderIdentifier, ReceiverIdentifier, BoundaryId); + } + + public override byte[] ToByteArray() { + var result = new byte[63]; + result[0] = (byte)ProtocolType.AdjacentInterlockingSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + Encoding.Latin1.GetBytes(BoundaryId.PadRight(20, '_')).CopyTo(result, BoundaryIdOffset); + return result; + } +} + + + +public record AdjacentInterlockingSystemRoutePretestRequestCommand (string SenderIdentifier, string ReceiverIdentifier, string BoundaryId, string RouteId, AdjacentInterlockingSystemRoutePretestRequestCommandRouteType RouteType) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int BoundaryIdOffset = 43; + private const int RouteIdOffset = 63; + private const int RouteTypeOffset = 83; + public static readonly ushort MessageType = 0x000F; + + public new static AdjacentInterlockingSystemRoutePretestRequestCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var BoundaryId = Encoding.Latin1.GetString(message, BoundaryIdOffset, 20); + var RouteId = Encoding.Latin1.GetString(message, RouteIdOffset, 20); + var RouteType = (AdjacentInterlockingSystemRoutePretestRequestCommandRouteType)message[RouteTypeOffset]; + return new AdjacentInterlockingSystemRoutePretestRequestCommand(SenderIdentifier, ReceiverIdentifier, BoundaryId, RouteId, RouteType); + } + + public override byte[] ToByteArray() { + var result = new byte[84]; + result[0] = (byte)ProtocolType.AdjacentInterlockingSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + Encoding.Latin1.GetBytes(BoundaryId.PadRight(20, '_')).CopyTo(result, BoundaryIdOffset); + Encoding.Latin1.GetBytes(RouteId.PadRight(20, '_')).CopyTo(result, RouteIdOffset); + result[RouteTypeOffset] = (byte)RouteType; + return result; + } +} + +public enum AdjacentInterlockingSystemRoutePretestRequestCommandRouteType : byte { + MainRoute = 0x01, + ShuntingRoute = 0x02, + OnSightRoute = 0x03, + SrTrainRoute = 0x04, + SpecialTrainRoute = 0x05, + TemporaryShuntingArea = 0x06 +} + +public record AdjacentInterlockingSystemRoutePretestStatusMessage (string SenderIdentifier, string ReceiverIdentifier, string BoundaryId, string RouteId, AdjacentInterlockingSystemRoutePretestStatusMessageRouteType RouteType, AdjacentInterlockingSystemRoutePretestStatusMessageRouteStatus RouteStatus, AdjacentInterlockingSystemRoutePretestStatusMessagePretestResponse PretestResponse) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int BoundaryIdOffset = 43; + private const int RouteIdOffset = 63; + private const int RouteTypeOffset = 83; + private const int RouteStatusOffset = 84; + private const int PretestResponseOffset = 85; + public static readonly ushort MessageType = 0x0010; + + public new static AdjacentInterlockingSystemRoutePretestStatusMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var BoundaryId = Encoding.Latin1.GetString(message, BoundaryIdOffset, 20); + var RouteId = Encoding.Latin1.GetString(message, RouteIdOffset, 20); + var RouteType = (AdjacentInterlockingSystemRoutePretestStatusMessageRouteType)message[RouteTypeOffset]; + var RouteStatus = (AdjacentInterlockingSystemRoutePretestStatusMessageRouteStatus)message[RouteStatusOffset]; + var PretestResponse = (AdjacentInterlockingSystemRoutePretestStatusMessagePretestResponse)message[PretestResponseOffset]; + return new AdjacentInterlockingSystemRoutePretestStatusMessage(SenderIdentifier, ReceiverIdentifier, BoundaryId, RouteId, RouteType, RouteStatus, PretestResponse); + } + + public override byte[] ToByteArray() { + var result = new byte[86]; + result[0] = (byte)ProtocolType.AdjacentInterlockingSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + Encoding.Latin1.GetBytes(BoundaryId.PadRight(20, '_')).CopyTo(result, BoundaryIdOffset); + Encoding.Latin1.GetBytes(RouteId.PadRight(20, '_')).CopyTo(result, RouteIdOffset); + result[RouteTypeOffset] = (byte)RouteType; + result[RouteStatusOffset] = (byte)RouteStatus; + result[PretestResponseOffset] = (byte)PretestResponse; + return result; + } +} + +public enum AdjacentInterlockingSystemRoutePretestStatusMessageRouteType : byte { + MainRoute = 0x01, + ShuntingRoute = 0x02, + OnSightRoute = 0x03, + SrTrainRoute = 0x04, + SpecialTrainRoute = 0x05, + TemporaryShuntingArea = 0x06 +} + +public enum AdjacentInterlockingSystemRoutePretestStatusMessageRouteStatus : byte { + Initiated = 0x01, + Locked = 0x02, + NoRoute = 0x03 +} + +public enum AdjacentInterlockingSystemRoutePretestStatusMessagePretestResponse : byte { + PossibleAndVacant = 0x01, + PossibleAndOccupied = 0x02, + Queue = 0x03, + Rejected = 0x04 +} + +public record AdjacentInterlockingSystemRouteReleaseInhibitionActivationRequestCommand (string SenderIdentifier, string ReceiverIdentifier, string BoundaryId) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int BoundaryIdOffset = 43; + public static readonly ushort MessageType = 0x0011; + + public new static AdjacentInterlockingSystemRouteReleaseInhibitionActivationRequestCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var BoundaryId = Encoding.Latin1.GetString(message, BoundaryIdOffset, 20); + return new AdjacentInterlockingSystemRouteReleaseInhibitionActivationRequestCommand(SenderIdentifier, ReceiverIdentifier, BoundaryId); + } + + public override byte[] ToByteArray() { + var result = new byte[63]; + result[0] = (byte)ProtocolType.AdjacentInterlockingSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + Encoding.Latin1.GetBytes(BoundaryId.PadRight(20, '_')).CopyTo(result, BoundaryIdOffset); + return result; + } +} + + + +public record AdjacentInterlockingSystemRouteReleaseInhibitionStatusMessage (string SenderIdentifier, string ReceiverIdentifier, string BoundaryId, AdjacentInterlockingSystemRouteReleaseInhibitionStatusMessageRouteReleaseInhibitionStatus RouteReleaseInhibitionStatus) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int BoundaryIdOffset = 43; + private const int RouteReleaseInhibitionStatusOffset = 63; + public static readonly ushort MessageType = 0x0014; + + public new static AdjacentInterlockingSystemRouteReleaseInhibitionStatusMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var BoundaryId = Encoding.Latin1.GetString(message, BoundaryIdOffset, 20); + var RouteReleaseInhibitionStatus = (AdjacentInterlockingSystemRouteReleaseInhibitionStatusMessageRouteReleaseInhibitionStatus)message[RouteReleaseInhibitionStatusOffset]; + return new AdjacentInterlockingSystemRouteReleaseInhibitionStatusMessage(SenderIdentifier, ReceiverIdentifier, BoundaryId, RouteReleaseInhibitionStatus); + } + + public override byte[] ToByteArray() { + var result = new byte[64]; + result[0] = (byte)ProtocolType.AdjacentInterlockingSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + Encoding.Latin1.GetBytes(BoundaryId.PadRight(20, '_')).CopyTo(result, BoundaryIdOffset); + result[RouteReleaseInhibitionStatusOffset] = (byte)RouteReleaseInhibitionStatus; + return result; + } +} + +public enum AdjacentInterlockingSystemRouteReleaseInhibitionStatusMessageRouteReleaseInhibitionStatus : byte { + Activated = 0x01, + Deactivated = 0x02 +} + +public record AdjacentInterlockingSystemAbortRouteCancellationRequestCommand (string SenderIdentifier, string ReceiverIdentifier, string BoundaryId, string RouteId) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int BoundaryIdOffset = 43; + private const int RouteIdOffset = 63; + public static readonly ushort MessageType = 0x0016; + + public new static AdjacentInterlockingSystemAbortRouteCancellationRequestCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var BoundaryId = Encoding.Latin1.GetString(message, BoundaryIdOffset, 20); + var RouteId = Encoding.Latin1.GetString(message, RouteIdOffset, 20); + return new AdjacentInterlockingSystemAbortRouteCancellationRequestCommand(SenderIdentifier, ReceiverIdentifier, BoundaryId, RouteId); + } + + public override byte[] ToByteArray() { + var result = new byte[83]; + result[0] = (byte)ProtocolType.AdjacentInterlockingSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + Encoding.Latin1.GetBytes(BoundaryId.PadRight(20, '_')).CopyTo(result, BoundaryIdOffset); + Encoding.Latin1.GetBytes(RouteId.PadRight(20, '_')).CopyTo(result, RouteIdOffset); + return result; + } +} + + diff --git a/src/Messages/Baseline4R2/InterfaceSpecificationSciIo.cs b/src/Messages/Baseline4R2/InterfaceSpecificationSciIo.cs new file mode 100644 index 0000000..088e721 --- /dev/null +++ b/src/Messages/Baseline4R2/InterfaceSpecificationSciIo.cs @@ -0,0 +1,6 @@ +using System; +using System.Text; +using System.Linq; + +namespace EulynxLive.Messages.Baseline4R2; + diff --git a/src/Messages/Baseline4R2/InterfaceSpecificationSciLc.cs b/src/Messages/Baseline4R2/InterfaceSpecificationSciLc.cs new file mode 100644 index 0000000..2aa1490 --- /dev/null +++ b/src/Messages/Baseline4R2/InterfaceSpecificationSciLc.cs @@ -0,0 +1,31 @@ +using System; +using System.Text; +using System.Linq; + +namespace EulynxLive.Messages.Baseline4R2; + +public record LevelCrossingDeactivationCommand (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0002; + + public new static LevelCrossingDeactivationCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new LevelCrossingDeactivationCommand(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.LevelCrossing; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + diff --git a/src/Messages/Baseline4R2/InterfaceSpecificationSciLs.cs b/src/Messages/Baseline4R2/InterfaceSpecificationSciLs.cs new file mode 100644 index 0000000..b6cf328 --- /dev/null +++ b/src/Messages/Baseline4R2/InterfaceSpecificationSciLs.cs @@ -0,0 +1,71 @@ +using System; +using System.Text; +using System.Linq; + +namespace EulynxLive.Messages.Baseline4R2; + +public record LightSignalSetLuminosityCommand (string SenderIdentifier, string ReceiverIdentifier, LightSignalSetLuminosityCommandLuminosity Luminosity) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int LuminosityOffset = 43; + public static readonly ushort MessageType = 0x0002; + + public new static LightSignalSetLuminosityCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var Luminosity = (LightSignalSetLuminosityCommandLuminosity)message[LuminosityOffset]; + return new LightSignalSetLuminosityCommand(SenderIdentifier, ReceiverIdentifier, Luminosity); + } + + public override byte[] ToByteArray() { + var result = new byte[44]; + result[0] = (byte)ProtocolType.LightSignal; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + result[LuminosityOffset] = (byte)Luminosity; + return result; + } +} + +public enum LightSignalSetLuminosityCommandLuminosity : byte { + LuminosityForDay = 0x01, + LuminosityForNight = 0x02, + IntentionallyDeleted = 0xFE +} + +public record LightSignalSetLuminosityMessage (string SenderIdentifier, string ReceiverIdentifier, LightSignalSetLuminosityMessageLuminosity Luminosity) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int LuminosityOffset = 43; + public static readonly ushort MessageType = 0x0004; + + public new static LightSignalSetLuminosityMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var Luminosity = (LightSignalSetLuminosityMessageLuminosity)message[LuminosityOffset]; + return new LightSignalSetLuminosityMessage(SenderIdentifier, ReceiverIdentifier, Luminosity); + } + + public override byte[] ToByteArray() { + var result = new byte[44]; + result[0] = (byte)ProtocolType.LightSignal; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + result[LuminosityOffset] = (byte)Luminosity; + return result; + } +} + +public enum LightSignalSetLuminosityMessageLuminosity : byte { + LuminosityForDay = 0x01, + LuminosityForNight = 0x02, + IntentionallyDeleted = 0xFE +} diff --git a/src/Messages/Baseline4R2/InterfaceSpecificationSciLx.cs b/src/Messages/Baseline4R2/InterfaceSpecificationSciLx.cs new file mode 100644 index 0000000..e012594 --- /dev/null +++ b/src/Messages/Baseline4R2/InterfaceSpecificationSciLx.cs @@ -0,0 +1,31 @@ +using System; +using System.Text; +using System.Linq; + +namespace EulynxLive.Messages.Baseline4R2; + +public record ExternalLevelCrossingSystemCrossingClearCommand (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0007; + + public new static ExternalLevelCrossingSystemCrossingClearCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new ExternalLevelCrossingSystemCrossingClearCommand(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.ExternalLevelCrossingSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + diff --git a/src/Messages/Baseline4R2/InterfaceSpecificationSciP.cs b/src/Messages/Baseline4R2/InterfaceSpecificationSciP.cs new file mode 100644 index 0000000..9196806 --- /dev/null +++ b/src/Messages/Baseline4R2/InterfaceSpecificationSciP.cs @@ -0,0 +1,139 @@ +using System; +using System.Text; +using System.Linq; + +namespace EulynxLive.Messages.Baseline4R2; + +public record PointMovePointCommand (string SenderIdentifier, string ReceiverIdentifier, PointMovePointCommandCommandedPointPosition CommandedPointPosition) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int CommandedPointPositionOffset = 43; + public static readonly ushort MessageType = 0x0001; + + public new static PointMovePointCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var CommandedPointPosition = (PointMovePointCommandCommandedPointPosition)message[CommandedPointPositionOffset]; + return new PointMovePointCommand(SenderIdentifier, ReceiverIdentifier, CommandedPointPosition); + } + + public override byte[] ToByteArray() { + var result = new byte[44]; + result[0] = (byte)ProtocolType.Point; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + result[CommandedPointPositionOffset] = (byte)CommandedPointPosition; + return result; + } +} + +public enum PointMovePointCommandCommandedPointPosition : byte { + SubsystemElectronicInterlockingRequestsARightHandPointMoving = 0x01, + SubsystemElectronicInterlockingRequestsALeftHandPointMoving = 0x02 +} + +public record PointPointPositionMessage (string SenderIdentifier, string ReceiverIdentifier, PointPointPositionMessageReportedPointPosition ReportedPointPosition, PointPointPositionMessageReportedDegradedPointPosition ReportedDegradedPointPosition) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int ReportedPointPositionOffset = 43; + private const int ReportedDegradedPointPositionOffset = 44; + public static readonly ushort MessageType = 0x000B; + + public new static PointPointPositionMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var ReportedPointPosition = (PointPointPositionMessageReportedPointPosition)message[ReportedPointPositionOffset]; + var ReportedDegradedPointPosition = (PointPointPositionMessageReportedDegradedPointPosition)message[ReportedDegradedPointPositionOffset]; + return new PointPointPositionMessage(SenderIdentifier, ReceiverIdentifier, ReportedPointPosition, ReportedDegradedPointPosition); + } + + public override byte[] ToByteArray() { + var result = new byte[45]; + result[0] = (byte)ProtocolType.Point; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + result[ReportedPointPositionOffset] = (byte)ReportedPointPosition; + result[ReportedDegradedPointPositionOffset] = (byte)ReportedDegradedPointPosition; + return result; + } +} + +public enum PointPointPositionMessageReportedPointPosition : byte { + PointIsInARightHandPositionDefinedEndPosition = 0x01, + PointIsInALeftHandPositionDefinedEndPosition = 0x02, + PointIsInNoEndPosition = 0x03, + PointIsInUnintendedPosition = 0x04 +} + +public enum PointPointPositionMessageReportedDegradedPointPosition : byte { + PointIsInADegradedRightHandPosition = 0x01, + PointIsInADegradedLeftHandPosition = 0x02, + PointIsNotInADegradedPosition = 0x03, + DegradedPointPositionIsNotApplicable = 0xFF +} + +public record PointMovementFailedMessage (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x000C; + + public new static PointMovementFailedMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new PointMovementFailedMessage(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.Point; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record PointAbilityToMovePointMessage (string SenderIdentifier, string ReceiverIdentifier, PointAbilityToMovePointMessageReportedAbilityToMovePointStatus ReportedAbilityToMovePointStatus) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int ReportedAbilityToMovePointStatusOffset = 43; + public static readonly ushort MessageType = 0x000D; + + public new static PointAbilityToMovePointMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var ReportedAbilityToMovePointStatus = (PointAbilityToMovePointMessageReportedAbilityToMovePointStatus)message[ReportedAbilityToMovePointStatusOffset]; + return new PointAbilityToMovePointMessage(SenderIdentifier, ReceiverIdentifier, ReportedAbilityToMovePointStatus); + } + + public override byte[] ToByteArray() { + var result = new byte[44]; + result[0] = (byte)ProtocolType.Point; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + result[ReportedAbilityToMovePointStatusOffset] = (byte)ReportedAbilityToMovePointStatus; + return result; + } +} + +public enum PointAbilityToMovePointMessageReportedAbilityToMovePointStatus : byte { + PointIsAbleToMove = 0x01, + PointIsUnableToMove = 0x02 +} diff --git a/src/Messages/Baseline4R2/InterfaceSpecificationSciRbc.cs b/src/Messages/Baseline4R2/InterfaceSpecificationSciRbc.cs new file mode 100644 index 0000000..088e721 --- /dev/null +++ b/src/Messages/Baseline4R2/InterfaceSpecificationSciRbc.cs @@ -0,0 +1,6 @@ +using System; +using System.Text; +using System.Linq; + +namespace EulynxLive.Messages.Baseline4R2; + diff --git a/src/Messages/Baseline4R2/InterfaceSpecificationSciTds.cs b/src/Messages/Baseline4R2/InterfaceSpecificationSciTds.cs new file mode 100644 index 0000000..f80550b --- /dev/null +++ b/src/Messages/Baseline4R2/InterfaceSpecificationSciTds.cs @@ -0,0 +1,311 @@ +using System; +using System.Text; +using System.Linq; + +namespace EulynxLive.Messages.Baseline4R2; + +public record TrainDetectionSystemUpdateFillingLevelCommand (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0002; + + public new static TrainDetectionSystemUpdateFillingLevelCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new TrainDetectionSystemUpdateFillingLevelCommand(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.TrainDetectionSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record TrainDetectionSystemCancelCommand (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0008; + + public new static TrainDetectionSystemCancelCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new TrainDetectionSystemCancelCommand(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.TrainDetectionSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record TrainDetectionSystemDisableTheRestrictionToForceSectionStatusToClearCommand (string SenderIdentifier, string ReceiverIdentifier) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + public static readonly ushort MessageType = 0x0003; + + public new static TrainDetectionSystemDisableTheRestrictionToForceSectionStatusToClearCommand FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + return new TrainDetectionSystemDisableTheRestrictionToForceSectionStatusToClearCommand(SenderIdentifier, ReceiverIdentifier); + } + + public override byte[] ToByteArray() { + var result = new byte[43]; + result[0] = (byte)ProtocolType.TrainDetectionSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + return result; + } +} + + + +public record TrainDetectionSystemTvpsOccupancyStatusMessage (string SenderIdentifier, string ReceiverIdentifier, TrainDetectionSystemTvpsOccupancyStatusMessageOccupancyStatus OccupancyStatus, TrainDetectionSystemTvpsOccupancyStatusMessageAbilityToBeForcedToClear AbilityToBeForcedToClear, ushort FillingLevel, TrainDetectionSystemTvpsOccupancyStatusMessagePomStatus PomStatus, TrainDetectionSystemTvpsOccupancyStatusMessageDisturbanceStatus DisturbanceStatus, TrainDetectionSystemTvpsOccupancyStatusMessageChangeTrigger ChangeTrigger) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int OccupancyStatusOffset = 43; + private const int AbilityToBeForcedToClearOffset = 44; + private const int FillingLevelOffset = 45; + private const int PomStatusOffset = 47; + private const int DisturbanceStatusOffset = 48; + private const int ChangeTriggerOffset = 49; + public static readonly ushort MessageType = 0x0007; + + public new static TrainDetectionSystemTvpsOccupancyStatusMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var OccupancyStatus = (TrainDetectionSystemTvpsOccupancyStatusMessageOccupancyStatus)message[OccupancyStatusOffset]; + var AbilityToBeForcedToClear = (TrainDetectionSystemTvpsOccupancyStatusMessageAbilityToBeForcedToClear)message[AbilityToBeForcedToClearOffset]; + var FillingLevelBytes = new byte[] { message[FillingLevelOffset], message[FillingLevelOffset + 1] }; + if (!BitConverter.IsLittleEndian) Array.Reverse(FillingLevelBytes); + var FillingLevel = BitConverter.ToUInt16(FillingLevelBytes); + var PomStatus = (TrainDetectionSystemTvpsOccupancyStatusMessagePomStatus)message[PomStatusOffset]; + var DisturbanceStatus = (TrainDetectionSystemTvpsOccupancyStatusMessageDisturbanceStatus)message[DisturbanceStatusOffset]; + var ChangeTrigger = (TrainDetectionSystemTvpsOccupancyStatusMessageChangeTrigger)message[ChangeTriggerOffset]; + return new TrainDetectionSystemTvpsOccupancyStatusMessage(SenderIdentifier, ReceiverIdentifier, OccupancyStatus, AbilityToBeForcedToClear, FillingLevel, PomStatus, DisturbanceStatus, ChangeTrigger); + } + + public override byte[] ToByteArray() { + var result = new byte[50]; + result[0] = (byte)ProtocolType.TrainDetectionSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + result[OccupancyStatusOffset] = (byte)OccupancyStatus; + result[AbilityToBeForcedToClearOffset] = (byte)AbilityToBeForcedToClear; + var FillingLevelBytes = BitConverter.GetBytes(FillingLevel); + if (!BitConverter.IsLittleEndian) Array.Reverse(FillingLevelBytes); + FillingLevelBytes.Take(2).ToArray().CopyTo(result, FillingLevelOffset); + result[PomStatusOffset] = (byte)PomStatus; + result[DisturbanceStatusOffset] = (byte)DisturbanceStatus; + result[ChangeTriggerOffset] = (byte)ChangeTrigger; + return result; + } +} + +public enum TrainDetectionSystemTvpsOccupancyStatusMessageOccupancyStatus : byte { + TvpsIsInStateVacant = 0x01, + TvpsIsInStateOccupied = 0x02, + TvpsIsInStateDisturbed = 0x03, + TvpsIsInStateWaitingForASweepingTrainAfterFcPAOrFcPCommand = 0x04, + TvpsIsInStateWaitingForAnAcknowledgmentAfterFcPACommand = 0x05, + TvpsIsInStateSweepingTrainDetected = 0x06 +} + +public enum TrainDetectionSystemTvpsOccupancyStatusMessageAbilityToBeForcedToClear : byte { + TvpsIsNotAbleToBeForcedToClear = 0x01, + TvpsIsAbleToBeForcedToClear = 0x02 +} + +public enum TrainDetectionSystemTvpsOccupancyStatusMessagePomStatus : byte { + PowerSupplyOk = 0x01, + PowerSupplyNok = 0x02, + PomStatusIsNotApplicable = 0xFF +} + +public enum TrainDetectionSystemTvpsOccupancyStatusMessageDisturbanceStatus : byte { + DisturbanceIsOperational = 0x01, + DisturbanceIsTechnical = 0x02, + DisturbanceStatusIsNotApplicable = 0xFF +} + +public enum TrainDetectionSystemTvpsOccupancyStatusMessageChangeTrigger : byte { + PassingDetected = 0x01, + CommandFromEilAccepted = 0x02, + CommandFromMaintainerAccepted = 0x03, + TechnicalFailure = 0x04, + InitialSectionState = 0x05, + InternalTrigger = 0x06, + ChangeTriggerIsNotApplicable = 0xFF +} + +public record TrainDetectionSystemCommandRejectedMessage (string SenderIdentifier, string ReceiverIdentifier, TrainDetectionSystemCommandRejectedMessageReasonForRejection ReasonForRejection) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int ReasonForRejectionOffset = 43; + public static readonly ushort MessageType = 0x0006; + + public new static TrainDetectionSystemCommandRejectedMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var ReasonForRejection = (TrainDetectionSystemCommandRejectedMessageReasonForRejection)message[ReasonForRejectionOffset]; + return new TrainDetectionSystemCommandRejectedMessage(SenderIdentifier, ReceiverIdentifier, ReasonForRejection); + } + + public override byte[] ToByteArray() { + var result = new byte[44]; + result[0] = (byte)ProtocolType.TrainDetectionSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + result[ReasonForRejectionOffset] = (byte)ReasonForRejection; + return result; + } +} + +public enum TrainDetectionSystemCommandRejectedMessageReasonForRejection : byte { + OperationalRejected = 0x01, + TechnicalRejected = 0x02 +} + +public record TrainDetectionSystemTvpsFcPFailedMessage (string SenderIdentifier, string ReceiverIdentifier, TrainDetectionSystemTvpsFcPFailedMessageReasonForFailure ReasonForFailure) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int ReasonForFailureOffset = 43; + public static readonly ushort MessageType = 0x0010; + + public new static TrainDetectionSystemTvpsFcPFailedMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var ReasonForFailure = (TrainDetectionSystemTvpsFcPFailedMessageReasonForFailure)message[ReasonForFailureOffset]; + return new TrainDetectionSystemTvpsFcPFailedMessage(SenderIdentifier, ReceiverIdentifier, ReasonForFailure); + } + + public override byte[] ToByteArray() { + var result = new byte[44]; + result[0] = (byte)ProtocolType.TrainDetectionSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + result[ReasonForFailureOffset] = (byte)ReasonForFailure; + return result; + } +} + +public enum TrainDetectionSystemTvpsFcPFailedMessageReasonForFailure : byte { + IncorrectCountOfTheSweepingTrain = 0x01, + ExpirationOfTimerConTmaxResponseTimeFcP = 0x02, + BoundingDetectionPointIsConfiguredAsNotPermittedForFcP = 0x03, + IntentionallyDeleted = 0x04, + OutgoingAxleDetectedBeforeExpirationOfMinimumTimer = 0x05, + ProcessCancelled = 0x06 +} + +public record TrainDetectionSystemTvpsFcPAFailedMessage (string SenderIdentifier, string ReceiverIdentifier, TrainDetectionSystemTvpsFcPAFailedMessageReasonForFailure ReasonForFailure) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int ReasonForFailureOffset = 43; + public static readonly ushort MessageType = 0x0011; + + public new static TrainDetectionSystemTvpsFcPAFailedMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var ReasonForFailure = (TrainDetectionSystemTvpsFcPAFailedMessageReasonForFailure)message[ReasonForFailureOffset]; + return new TrainDetectionSystemTvpsFcPAFailedMessage(SenderIdentifier, ReceiverIdentifier, ReasonForFailure); + } + + public override byte[] ToByteArray() { + var result = new byte[44]; + result[0] = (byte)ProtocolType.TrainDetectionSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + result[ReasonForFailureOffset] = (byte)ReasonForFailure; + return result; + } +} + +public enum TrainDetectionSystemTvpsFcPAFailedMessageReasonForFailure : byte { + IncorrectCountOfTheSweepingTrain = 0x01, + ExpirationOfTimerConTmaxResponseTimeFcPA = 0x02, + BoundingDetectionPointIsConfiguredAsNotPermittedForFcPA = 0x03, + IntentionallyDeleted = 0x04, + OutgoingAxleDetectedBeforeExpirationOfMinimumTimer = 0x05, + ProcessCancelled = 0x06 +} + +public record TrainDetectionSystemTdpStatusMessage (string SenderIdentifier, string ReceiverIdentifier, TrainDetectionSystemTdpStatusMessageStateOfPassing StateOfPassing, TrainDetectionSystemTdpStatusMessageDirectionOfPassing DirectionOfPassing) : Message(SenderIdentifier, ReceiverIdentifier) { + private const int MessageTypeOffset = 1; + private const int SenderIdentifierOffset = 3; + private const int ReceiverIdentifierOffset = 23; + private const int StateOfPassingOffset = 43; + private const int DirectionOfPassingOffset = 44; + public static readonly ushort MessageType = 0x000B; + + public new static TrainDetectionSystemTdpStatusMessage FromBytes(byte[] message) { + var SenderIdentifier = Encoding.Latin1.GetString(message, SenderIdentifierOffset, 20); + var ReceiverIdentifier = Encoding.Latin1.GetString(message, ReceiverIdentifierOffset, 20); + var StateOfPassing = (TrainDetectionSystemTdpStatusMessageStateOfPassing)message[StateOfPassingOffset]; + var DirectionOfPassing = (TrainDetectionSystemTdpStatusMessageDirectionOfPassing)message[DirectionOfPassingOffset]; + return new TrainDetectionSystemTdpStatusMessage(SenderIdentifier, ReceiverIdentifier, StateOfPassing, DirectionOfPassing); + } + + public override byte[] ToByteArray() { + var result = new byte[45]; + result[0] = (byte)ProtocolType.TrainDetectionSystem; + var MessageTypeBytes = BitConverter.GetBytes(MessageType); + if (!BitConverter.IsLittleEndian) Array.Reverse(MessageTypeBytes); + MessageTypeBytes.Take(2).ToArray().CopyTo(result, MessageTypeOffset); + Encoding.Latin1.GetBytes(SenderIdentifier.PadRight(20, '_')).CopyTo(result, SenderIdentifierOffset); + Encoding.Latin1.GetBytes(ReceiverIdentifier.PadRight(20, '_')).CopyTo(result, ReceiverIdentifierOffset); + result[StateOfPassingOffset] = (byte)StateOfPassing; + result[DirectionOfPassingOffset] = (byte)DirectionOfPassing; + return result; + } +} + +public enum TrainDetectionSystemTdpStatusMessageStateOfPassing : byte { + NotPassed = 0x01, + Passed = 0x02, + Disturbed = 0x03 +} + +public enum TrainDetectionSystemTdpStatusMessageDirectionOfPassing : byte { + ReferenceDirection = 0x01, + AgainstReferenceDirection = 0x02, + WithoutIndicatedDirection = 0x03 +} diff --git a/src/Messages/Baseline4R2/Message.cs b/src/Messages/Baseline4R2/Message.cs new file mode 100644 index 0000000..aa904a0 --- /dev/null +++ b/src/Messages/Baseline4R2/Message.cs @@ -0,0 +1,178 @@ +using System; + +namespace EulynxLive.Messages.Baseline4R2; + +public abstract record Message(string SenderIdentifier, string ReceiverIdentifier) { + + public abstract byte[] ToByteArray(); + + public static Message FromBytes(byte[] message) { + var protocolType = (ProtocolType)message[0]; + var messageType = BitConverter.ToUInt16(new byte[2] { message[1], message[2] }); + return protocolType switch { + ProtocolType.AdjacentInterlockingSystem => messageType switch { + 0x0001 => AdjacentInterlockingSystemActivationZoneStatusMessage.FromBytes(message), + 0x0002 => AdjacentInterlockingSystemApproachZoneStatusMessage.FromBytes(message), + 0x0003 => AdjacentInterlockingSystemAccessRestrictionRequestCommand.FromBytes(message), + 0x0012 => AdjacentInterlockingSystemAccessRestrictionStatusMessage.FromBytes(message), + 0x0004 => AdjacentInterlockingSystemLineStatusMessage.FromBytes(message), + 0x0005 => AdjacentInterlockingSystemFlankProtectionRequestCommand.FromBytes(message), + 0x0013 => AdjacentInterlockingSystemFlankProtectionStatusMessage.FromBytes(message), + 0x0007 => AdjacentInterlockingSystemRouteRequestCommand.FromBytes(message), + 0x0008 => AdjacentInterlockingSystemRouteStatusMessage.FromBytes(message), + 0x0009 => AdjacentInterlockingSystemRouteMonitoringStatusMessage.FromBytes(message), + 0x000A => AdjacentInterlockingSystemRouteCancellationRequestCommand.FromBytes(message), + 0x000B => AdjacentInterlockingSystemTrainOperatedRouteReleaseStatusMessage.FromBytes(message), + 0x000C => AdjacentInterlockingSystemSignalStatusMessage.FromBytes(message), + 0x000D => AdjacentInterlockingSystemTvpsStatusMessage.FromBytes(message), + 0x000E => AdjacentInterlockingSystemOppositeMainSignalStatusMessage.FromBytes(message), + 0x000F => AdjacentInterlockingSystemRoutePretestRequestCommand.FromBytes(message), + 0x0010 => AdjacentInterlockingSystemRoutePretestStatusMessage.FromBytes(message), + 0x0011 => AdjacentInterlockingSystemRouteReleaseInhibitionActivationRequestCommand.FromBytes(message), + 0x0014 => AdjacentInterlockingSystemRouteReleaseInhibitionStatusMessage.FromBytes(message), + 0x0016 => AdjacentInterlockingSystemAbortRouteCancellationRequestCommand.FromBytes(message), + 0x0024 => AdjacentInterlockingSystemPdiVersionCheckCommand.FromBytes(message), + // 0x0025 => AdjacentInterlockingSystemPdiVersionCheckMessage.FromBytes(message), + 0x0021 => AdjacentInterlockingSystemInitialisationRequestCommand.FromBytes(message), + 0x0022 => AdjacentInterlockingSystemStartInitialisationMessage.FromBytes(message), + 0x0026 => AdjacentInterlockingSystemStatusReportCompletedMessage.FromBytes(message), + 0x0023 => AdjacentInterlockingSystemInitialisationCompletedMessage.FromBytes(message), + 0x0027 => AdjacentInterlockingSystemClosePdiCommand.FromBytes(message), + 0x0028 => AdjacentInterlockingSystemReleasePdiForMaintenanceCommand.FromBytes(message), + 0x0029 => AdjacentInterlockingSystemPdiAvailableMessage.FromBytes(message), + 0x002A => AdjacentInterlockingSystemPdiNotAvailableMessage.FromBytes(message), + 0x002B => AdjacentInterlockingSystemResetPdiMessage.FromBytes(message), + _ => throw new Exception($"Unknown protocol and message type {protocolType} / {messageType}") + }, + ProtocolType.TrainDetectionSystem => messageType switch { + 0x0002 => TrainDetectionSystemUpdateFillingLevelCommand.FromBytes(message), + 0x0008 => TrainDetectionSystemCancelCommand.FromBytes(message), + 0x0003 => TrainDetectionSystemDisableTheRestrictionToForceSectionStatusToClearCommand.FromBytes(message), + 0x0007 => TrainDetectionSystemTvpsOccupancyStatusMessage.FromBytes(message), + 0x0006 => TrainDetectionSystemCommandRejectedMessage.FromBytes(message), + 0x0010 => TrainDetectionSystemTvpsFcPFailedMessage.FromBytes(message), + 0x0011 => TrainDetectionSystemTvpsFcPAFailedMessage.FromBytes(message), + 0x000B => TrainDetectionSystemTdpStatusMessage.FromBytes(message), + 0x0024 => TrainDetectionSystemPdiVersionCheckCommand.FromBytes(message), + // 0x0025 => TrainDetectionSystemPdiVersionCheckMessage.FromBytes(message), + 0x0021 => TrainDetectionSystemInitialisationRequestCommand.FromBytes(message), + 0x0022 => TrainDetectionSystemStartInitialisationMessage.FromBytes(message), + 0x0026 => TrainDetectionSystemStatusReportCompletedMessage.FromBytes(message), + 0x0023 => TrainDetectionSystemInitialisationCompletedMessage.FromBytes(message), + 0x0027 => TrainDetectionSystemClosePdiCommand.FromBytes(message), + 0x0028 => TrainDetectionSystemReleasePdiForMaintenanceCommand.FromBytes(message), + 0x0029 => TrainDetectionSystemPdiAvailableMessage.FromBytes(message), + 0x002A => TrainDetectionSystemPdiNotAvailableMessage.FromBytes(message), + 0x002B => TrainDetectionSystemResetPdiMessage.FromBytes(message), + _ => throw new Exception($"Unknown protocol and message type {protocolType} / {messageType}") + }, + ProtocolType.LightSignal => messageType switch { + 0x0002 => LightSignalSetLuminosityCommand.FromBytes(message), + 0x0004 => LightSignalSetLuminosityMessage.FromBytes(message), + 0x0024 => LightSignalPdiVersionCheckCommand.FromBytes(message), + // 0x0025 => LightSignalPdiVersionCheckMessage.FromBytes(message), + 0x0021 => LightSignalInitialisationRequestCommand.FromBytes(message), + 0x0022 => LightSignalStartInitialisationMessage.FromBytes(message), + 0x0026 => LightSignalStatusReportCompletedMessage.FromBytes(message), + 0x0023 => LightSignalInitialisationCompletedMessage.FromBytes(message), + 0x0027 => LightSignalClosePdiCommand.FromBytes(message), + 0x0028 => LightSignalReleasePdiForMaintenanceCommand.FromBytes(message), + 0x0029 => LightSignalPdiAvailableMessage.FromBytes(message), + 0x002A => LightSignalPdiNotAvailableMessage.FromBytes(message), + 0x002B => LightSignalResetPdiMessage.FromBytes(message), + _ => throw new Exception($"Unknown protocol and message type {protocolType} / {messageType}") + }, + ProtocolType.Point => messageType switch { + 0x0001 => PointMovePointCommand.FromBytes(message), + 0x000B => PointPointPositionMessage.FromBytes(message), + 0x000C => PointMovementFailedMessage.FromBytes(message), + 0x000D => PointAbilityToMovePointMessage.FromBytes(message), + 0x0024 => PointPdiVersionCheckCommand.FromBytes(message), + 0x0025 => PointPdiVersionCheckMessage.FromBytes(message), + 0x0021 => PointInitialisationRequestCommand.FromBytes(message), + 0x0022 => PointStartInitialisationMessage.FromBytes(message), + 0x0026 => PointStatusReportCompletedMessage.FromBytes(message), + 0x0023 => PointInitialisationCompletedMessage.FromBytes(message), + 0x0027 => PointClosePdiCommand.FromBytes(message), + 0x0028 => PointReleasePdiForMaintenanceCommand.FromBytes(message), + 0x0029 => PointPdiAvailableMessage.FromBytes(message), + 0x002A => PointPdiNotAvailableMessage.FromBytes(message), + 0x002B => PointResetPdiMessage.FromBytes(message), + _ => throw new Exception($"Unknown protocol and message type {protocolType} / {messageType}") + }, + ProtocolType.RadioBlockCenter => messageType switch { + 0x0024 => RadioBlockCenterPdiVersionCheckCommand.FromBytes(message), + // 0x0025 => RadioBlockCenterPdiVersionCheckMessage.FromBytes(message), + 0x0021 => RadioBlockCenterInitialisationRequestCommand.FromBytes(message), + 0x0022 => RadioBlockCenterStartInitialisationMessage.FromBytes(message), + 0x0026 => RadioBlockCenterStatusReportCompletedMessage.FromBytes(message), + 0x0023 => RadioBlockCenterInitialisationCompletedMessage.FromBytes(message), + 0x0027 => RadioBlockCenterClosePdiCommand.FromBytes(message), + 0x0028 => RadioBlockCenterReleasePdiForMaintenanceCommand.FromBytes(message), + 0x0029 => RadioBlockCenterPdiAvailableMessage.FromBytes(message), + 0x002A => RadioBlockCenterPdiNotAvailableMessage.FromBytes(message), + 0x002B => RadioBlockCenterResetPdiMessage.FromBytes(message), + _ => throw new Exception($"Unknown protocol and message type {protocolType} / {messageType}") + }, + ProtocolType.LevelCrossing => messageType switch { + 0x0002 => LevelCrossingDeactivationCommand.FromBytes(message), + 0x0024 => LevelCrossingPdiVersionCheckCommand.FromBytes(message), + // 0x0025 => LevelCrossingPdiVersionCheckMessage.FromBytes(message), + 0x0021 => LevelCrossingInitialisationRequestCommand.FromBytes(message), + 0x0022 => LevelCrossingStartInitialisationMessage.FromBytes(message), + 0x0026 => LevelCrossingStatusReportCompletedMessage.FromBytes(message), + 0x0023 => LevelCrossingInitialisationCompletedMessage.FromBytes(message), + 0x0027 => LevelCrossingClosePdiCommand.FromBytes(message), + 0x0028 => LevelCrossingReleasePdiForMaintenanceCommand.FromBytes(message), + 0x0029 => LevelCrossingPdiAvailableMessage.FromBytes(message), + 0x002A => LevelCrossingPdiNotAvailableMessage.FromBytes(message), + 0x002B => LevelCrossingResetPdiMessage.FromBytes(message), + _ => throw new Exception($"Unknown protocol and message type {protocolType} / {messageType}") + }, + ProtocolType.CC => messageType switch { + 0x0024 => CCPdiVersionCheckCommand.FromBytes(message), + // 0x0025 => CCPdiVersionCheckMessage.FromBytes(message), + 0x0021 => CCInitialisationRequestCommand.FromBytes(message), + 0x0022 => CCStartInitialisationMessage.FromBytes(message), + 0x0026 => CCStatusReportCompletedMessage.FromBytes(message), + 0x0023 => CCInitialisationCompletedMessage.FromBytes(message), + 0x0027 => CCClosePdiCommand.FromBytes(message), + 0x0028 => CCReleasePdiForMaintenanceCommand.FromBytes(message), + 0x0029 => CCPdiAvailableMessage.FromBytes(message), + 0x002A => CCPdiNotAvailableMessage.FromBytes(message), + 0x002B => CCResetPdiMessage.FromBytes(message), + _ => throw new Exception($"Unknown protocol and message type {protocolType} / {messageType}") + }, + ProtocolType.GenericIO => messageType switch { + 0x0024 => GenericIOPdiVersionCheckCommand.FromBytes(message), + // 0x0025 => GenericIOPdiVersionCheckMessage.FromBytes(message), + 0x0021 => GenericIOInitialisationRequestCommand.FromBytes(message), + 0x0022 => GenericIOStartInitialisationMessage.FromBytes(message), + 0x0026 => GenericIOStatusReportCompletedMessage.FromBytes(message), + 0x0023 => GenericIOInitialisationCompletedMessage.FromBytes(message), + 0x0027 => GenericIOClosePdiCommand.FromBytes(message), + 0x0028 => GenericIOReleasePdiForMaintenanceCommand.FromBytes(message), + 0x0029 => GenericIOPdiAvailableMessage.FromBytes(message), + 0x002A => GenericIOPdiNotAvailableMessage.FromBytes(message), + 0x002B => GenericIOResetPdiMessage.FromBytes(message), + _ => throw new Exception($"Unknown protocol and message type {protocolType} / {messageType}") + }, + ProtocolType.ExternalLevelCrossingSystem => messageType switch { + 0x0007 => ExternalLevelCrossingSystemCrossingClearCommand.FromBytes(message), + 0x0024 => ExternalLevelCrossingSystemPdiVersionCheckCommand.FromBytes(message), + // 0x0025 => ExternalLevelCrossingSystemPdiVersionCheckMessage.FromBytes(message), + 0x0021 => ExternalLevelCrossingSystemInitialisationRequestCommand.FromBytes(message), + 0x0022 => ExternalLevelCrossingSystemStartInitialisationMessage.FromBytes(message), + 0x0026 => ExternalLevelCrossingSystemStatusReportCompletedMessage.FromBytes(message), + 0x0023 => ExternalLevelCrossingSystemInitialisationCompletedMessage.FromBytes(message), + 0x0027 => ExternalLevelCrossingSystemClosePdiCommand.FromBytes(message), + 0x0028 => ExternalLevelCrossingSystemReleasePdiForMaintenanceCommand.FromBytes(message), + 0x0029 => ExternalLevelCrossingSystemPdiAvailableMessage.FromBytes(message), + 0x002A => ExternalLevelCrossingSystemPdiNotAvailableMessage.FromBytes(message), + 0x002B => ExternalLevelCrossingSystemResetPdiMessage.FromBytes(message), + _ => throw new Exception($"Unknown protocol and message type {protocolType} / {messageType}") + }, + _ => throw new Exception($"Unknown protocol and message type {protocolType} / {messageType}") + }; + } +} diff --git a/src/Messages/ProtocolTypes.cs b/src/Messages/ProtocolTypes.cs index fcf58a7..19b5c40 100644 --- a/src/Messages/ProtocolTypes.cs +++ b/src/Messages/ProtocolTypes.cs @@ -2,6 +2,7 @@ namespace EulynxLive.Messages { public enum ProtocolType: byte { // From: EU.SCI-XX.PDI.53 + CC = 0xD0, AdjacentInterlockingSystem = 0x01, TrainDetectionSystem = 0x20, LightSignal = 0x30, From 8652b6641130641206da0aa13727d2c01dded226 Mon Sep 17 00:00:00 2001 From: Benedikt Schenkel Date: Wed, 29 Nov 2023 14:32:11 +0100 Subject: [PATCH 02/11] add ConnectionFactory --- .../Baseline4R1/PointState.cs} | 15 +- .../PointToInterlockingConnection.cs | 8 +- .../Eulynx/Baseline4R2/PointState.cs | 33 +++++ .../PointToInterlockingConnection.cs | 134 ++++++++++++++++++ .../Connections/Eulynx/ConnectionFactory.cs | 21 +++ src/Point/Connections/Eulynx/PointState.cs | 21 +++ src/Point/Startup.cs | 6 +- 7 files changed, 220 insertions(+), 18 deletions(-) rename src/Point/Connections/{PointStateBaseline4R1.cs => Eulynx/Baseline4R1/PointState.cs} (67%) rename src/Point/Connections/{ => Eulynx}/Baseline4R1/PointToInterlockingConnection.cs (94%) create mode 100644 src/Point/Connections/Eulynx/Baseline4R2/PointState.cs create mode 100644 src/Point/Connections/Eulynx/Baseline4R2/PointToInterlockingConnection.cs create mode 100644 src/Point/Connections/Eulynx/ConnectionFactory.cs create mode 100644 src/Point/Connections/Eulynx/PointState.cs diff --git a/src/Point/Connections/PointStateBaseline4R1.cs b/src/Point/Connections/Eulynx/Baseline4R1/PointState.cs similarity index 67% rename from src/Point/Connections/PointStateBaseline4R1.cs rename to src/Point/Connections/Eulynx/Baseline4R1/PointState.cs index 3a69877..e9e38fe 100644 --- a/src/Point/Connections/PointStateBaseline4R1.cs +++ b/src/Point/Connections/Eulynx/Baseline4R1/PointState.cs @@ -1,22 +1,17 @@ using EulynxLive.Messages.Baseline4R1; using IPointToInterlockingConnection = EulynxLive.Point.Interfaces.IPointToInterlockingConnection; -using PointState = EulynxLive.Point.Interfaces.IPointToInterlockingConnection.PointState; using PointPosition = EulynxLive.Point.Interfaces.IPointToInterlockingConnection.PointPosition; using DegradedPointPosition = EulynxLive.Point.Interfaces.IPointToInterlockingConnection.DegradedPointPosition; -public record PointStateBaseline4R1 +namespace EulynxLive.Point.EulynxBaseline4R1; +public record PointState : Eulynx.PointState { - private PointState _state; - public PointPointPositionMessageReportedPointPosition PointPosition { get => MapInterfacePointPositionToConcrete(_state.PointPosition); } - public PointPointPositionMessageReportedDegradedPointPosition DegradedPointPosition { get => MapInterfaceDegradedPointPositionToConcrete(_state.DegradedPointPosition); } - - public PointStateBaseline4R1(PointState state) + public PointState(IPointToInterlockingConnection.PointState state) : base(state) { - _state = state; } - private PointPointPositionMessageReportedPointPosition MapInterfacePointPositionToConcrete(PointPosition value) => value switch + public override PointPointPositionMessageReportedPointPosition MapInterfacePointPositionToConcrete(PointPosition value) => value switch { IPointToInterlockingConnection.PointPosition.Left => PointPointPositionMessageReportedPointPosition.PointIsInALeftHandPositionDefinedEndPosition, IPointToInterlockingConnection.PointPosition.Right => PointPointPositionMessageReportedPointPosition.PointIsInARightHandPositionDefinedEndPosition, @@ -25,7 +20,7 @@ public PointStateBaseline4R1(PointState state) _ => throw new NotImplementedException(), }; - private PointPointPositionMessageReportedDegradedPointPosition MapInterfaceDegradedPointPositionToConcrete(DegradedPointPosition value) => value switch + public override PointPointPositionMessageReportedDegradedPointPosition MapInterfaceDegradedPointPositionToConcrete(DegradedPointPosition value) => value switch { IPointToInterlockingConnection.DegradedPointPosition.DegradedLeft => PointPointPositionMessageReportedDegradedPointPosition.PointIsInADegradedLeftHandPosition, IPointToInterlockingConnection.DegradedPointPosition.DegradedRight => PointPointPositionMessageReportedDegradedPointPosition.PointIsInADegradedRightHandPosition, diff --git a/src/Point/Connections/Baseline4R1/PointToInterlockingConnection.cs b/src/Point/Connections/Eulynx/Baseline4R1/PointToInterlockingConnection.cs similarity index 94% rename from src/Point/Connections/Baseline4R1/PointToInterlockingConnection.cs rename to src/Point/Connections/Eulynx/Baseline4R1/PointToInterlockingConnection.cs index 5d11b0e..30e6701 100644 --- a/src/Point/Connections/Baseline4R1/PointToInterlockingConnection.cs +++ b/src/Point/Connections/Eulynx/Baseline4R1/PointToInterlockingConnection.cs @@ -46,7 +46,7 @@ public void Connect() _currentConnection = new GrpcConnection(metadata, _remoteEndpoint, _timeout.Token); } - public async Task InitializeConnection(PointState state, CancellationToken cancellationToken) + public async Task InitializeConnection(IPointToInterlockingConnection.PointState state, CancellationToken cancellationToken) { _logger.LogTrace("Connected. Waiting for request..."); if (await ReceiveMessage(cancellationToken) == null) @@ -67,7 +67,7 @@ public async Task InitializeConnection(PointState state, CancellationToken var startInitialization = new PointStartInitialisationMessage(_localId, _remoteId); await SendMessage(startInitialization); - var pointState = new PointStateBaseline4R1(state); + var pointState = new PointState(state); var initialPosition = new PointPointPositionMessage(_localId, _remoteId, pointState.PointPosition, pointState.DegradedPointPosition); await SendMessage(initialPosition); @@ -76,9 +76,9 @@ public async Task InitializeConnection(PointState state, CancellationToken return true; } - public async Task SendPointPosition(PointState state) + public async Task SendPointPosition(IPointToInterlockingConnection.PointState state) { - var pointState = new PointStateBaseline4R1(state); + var pointState = new PointState(state); var response = new PointPointPositionMessage(_localId, _remoteId, pointState.PointPosition, pointState.DegradedPointPosition); await SendMessage(response); } diff --git a/src/Point/Connections/Eulynx/Baseline4R2/PointState.cs b/src/Point/Connections/Eulynx/Baseline4R2/PointState.cs new file mode 100644 index 0000000..55c22bf --- /dev/null +++ b/src/Point/Connections/Eulynx/Baseline4R2/PointState.cs @@ -0,0 +1,33 @@ + +using EulynxLive.Messages.Baseline4R2; +using IPointToInterlockingConnection = EulynxLive.Point.Interfaces.IPointToInterlockingConnection; +using PointPosition = EulynxLive.Point.Interfaces.IPointToInterlockingConnection.PointPosition; +using DegradedPointPosition = EulynxLive.Point.Interfaces.IPointToInterlockingConnection.DegradedPointPosition; +using EulynxLive.Point.Eulynx; + +namespace EulynxLive.Point.EulynxBaseline4R2; + +public record PointState : Eulynx.PointState +{ + public PointState(IPointToInterlockingConnection.PointState state) : base(state) + { + } + + public override PointPointPositionMessageReportedPointPosition MapInterfacePointPositionToConcrete(PointPosition value) => value switch + { + IPointToInterlockingConnection.PointPosition.Left => PointPointPositionMessageReportedPointPosition.PointIsInALeftHandPositionDefinedEndPosition, + IPointToInterlockingConnection.PointPosition.Right => PointPointPositionMessageReportedPointPosition.PointIsInARightHandPositionDefinedEndPosition, + IPointToInterlockingConnection.PointPosition.UnintendetPosition => PointPointPositionMessageReportedPointPosition.PointIsInUnintendedPosition, + IPointToInterlockingConnection.PointPosition.NoEndposition => PointPointPositionMessageReportedPointPosition.PointIsInNoEndPosition, + _ => throw new NotImplementedException(), + }; + + public override PointPointPositionMessageReportedDegradedPointPosition MapInterfaceDegradedPointPositionToConcrete(DegradedPointPosition value) => value switch + { + IPointToInterlockingConnection.DegradedPointPosition.DegradedLeft => PointPointPositionMessageReportedDegradedPointPosition.PointIsInADegradedLeftHandPosition, + IPointToInterlockingConnection.DegradedPointPosition.DegradedRight => PointPointPositionMessageReportedDegradedPointPosition.PointIsInADegradedRightHandPosition, + IPointToInterlockingConnection.DegradedPointPosition.NotDegraded => PointPointPositionMessageReportedDegradedPointPosition.PointIsNotInADegradedPosition, + IPointToInterlockingConnection.DegradedPointPosition.NotApplicable => PointPointPositionMessageReportedDegradedPointPosition.DegradedPointPositionIsNotApplicable, + _ => throw new NotImplementedException(), + }; +} diff --git a/src/Point/Connections/Eulynx/Baseline4R2/PointToInterlockingConnection.cs b/src/Point/Connections/Eulynx/Baseline4R2/PointToInterlockingConnection.cs new file mode 100644 index 0000000..b8191dd --- /dev/null +++ b/src/Point/Connections/Eulynx/Baseline4R2/PointToInterlockingConnection.cs @@ -0,0 +1,134 @@ +using EulynxLive.Messages.Baseline4R2; +using Grpc.Core; +using IPointToInterlockingConnection = EulynxLive.Point.Interfaces.IPointToInterlockingConnection; +using PointState = EulynxLive.Point.Interfaces.IPointToInterlockingConnection.PointState; +using PointPosition = EulynxLive.Point.Interfaces.IPointToInterlockingConnection.PointPosition; +using EulynxLive.Point.Interfaces; + + +namespace EulynxLive.Point.EulynxBaseline4R2; + +public class PointToInterlockingConnection : IPointToInterlockingConnection +{ + private readonly ILogger _logger; + private readonly string _localId; + private readonly string _localRastaId; + private readonly string _remoteId; + private readonly string _remoteEndpoint; + IConnection? _currentConnection; + private CancellationTokenSource _timeout; + private int _timeoutDuration; + private CancellationToken _stoppingToken; + + public PointToInterlockingConnection( + ILogger logger, + IConfiguration configuration, + CancellationToken stoppingToken, int timeoutDuration = 10000) + { + _timeoutDuration = timeoutDuration; + _stoppingToken = stoppingToken; + _timeout = new CancellationTokenSource(); + _logger = logger; + _currentConnection = null; + + var config = configuration.GetSection("PointSettings").Get() ?? throw new Exception("No configuration provided"); + _localId = config.LocalId; + _localRastaId = config.LocalRastaId.ToString(); + _remoteId = config.RemoteId; + _remoteEndpoint = config.RemoteEndpoint; + } + + public void Connect() + { + ResetTimeout(); + _logger.LogTrace("Connecting..."); + var metadata = new Metadata { { "rasta-id", _localRastaId } }; + _currentConnection = new GrpcConnection(metadata, _remoteEndpoint, _timeout.Token); + } + + public async Task InitializeConnection(IPointToInterlockingConnection.PointState state, CancellationToken cancellationToken) + { + _logger.LogTrace("Connected. Waiting for request..."); + if (await ReceiveMessage(cancellationToken) == null) + { + _logger.LogError("Unexpected message."); + return false; + } + + var versionCheckResponse = new PointPdiVersionCheckMessage(_localId, _remoteId, PointPdiVersionCheckMessageResultPdiVersionCheck.PDIVersionsFromReceiverAndSenderDoMatch, /* TODO */ 0, 0, new byte[] { }); + await SendMessage(versionCheckResponse); + + if (await ReceiveMessage(cancellationToken) == null) + { + _logger.LogError("Unexpected message."); + return false; + } + + var startInitialization = new PointStartInitialisationMessage(_localId, _remoteId); + await SendMessage(startInitialization); + + var pointState = new PointState(state); + var initialPosition = new PointPointPositionMessage(_localId, _remoteId, pointState.PointPosition, pointState.DegradedPointPosition); + await SendMessage(initialPosition); + + var completeInitialization = new PointInitialisationCompletedMessage(_localId, _remoteId); + await SendMessage(completeInitialization); + return true; + } + + public async Task SendPointPosition(IPointToInterlockingConnection.PointState state) + { + var pointState = new PointState(state); + var response = new PointPointPositionMessage(_localId, _remoteId, pointState.PointPosition, pointState.DegradedPointPosition); + await SendMessage(response); + } + + async public Task SendTimeoutMessage() + { + var response = new PointAbilityToMovePointMessage(_localId, _remoteId, PointAbilityToMovePointMessageReportedAbilityToMovePointStatus.PointIsUnableToMove); + await SendMessage(response); + } + + public async Task ReceivePointPosition(CancellationToken cancellationToken) + { + var message = await ReceiveMessage(cancellationToken); + + return (message != null)? message.CommandedPointPosition switch + { + PointMovePointCommandCommandedPointPosition.SubsystemElectronicInterlockingRequestsARightHandPointMoving => PointPosition.Right, + PointMovePointCommandCommandedPointPosition.SubsystemElectronicInterlockingRequestsALeftHandPointMoving => PointPosition.Left, + _ => throw new global::System.NotImplementedException(), + } : null; + } + + public void Dispose() + { + _currentConnection?.Dispose(); + } + + private async Task SendMessage(Message message) + { + if (_currentConnection == null) throw new InvalidOperationException("Connection is null. Did you call Connect()?"); + await _currentConnection.SendAsync(message.ToByteArray()); + } + + private async Task ReceiveMessage(CancellationToken cancellationToken) where T : Message + { + if (_currentConnection == null) throw new InvalidOperationException("Connection is null. Did you call Connect()?"); + ResetTimeout(); + + var message = Message.FromBytes(await _currentConnection.ReceiveAsync(_timeout.Token)); + if (message is not T) + { + _logger.LogError("Unexpected message: {}", message); + return null; + } + return message as T; + } + + private void ResetTimeout() + { + _timeout = CancellationTokenSource.CreateLinkedTokenSource(_stoppingToken); + _timeout.CancelAfter(_timeoutDuration); + } +} diff --git a/src/Point/Connections/Eulynx/ConnectionFactory.cs b/src/Point/Connections/Eulynx/ConnectionFactory.cs new file mode 100644 index 0000000..98c2c22 --- /dev/null +++ b/src/Point/Connections/Eulynx/ConnectionFactory.cs @@ -0,0 +1,21 @@ + +using EulynxLive.Point.Interfaces; + +namespace EulynxLive.Point.Eulynx; + +public static class ConnectionFactory{ + public static IPointToInterlockingConnection CreateConnection (IServiceProvider x) where T: IPointToInterlockingConnection { + + if (typeof(T).IsAssignableFrom(typeof(EulynxBaseline4R1.PointToInterlockingConnection))) + { + return new EulynxBaseline4R1.PointToInterlockingConnection(x.GetRequiredService>(), x.GetRequiredService(), CancellationToken.None); + } + + if (typeof(T).IsAssignableFrom(typeof(EulynxBaseline4R2.PointToInterlockingConnection))) + { + return new EulynxBaseline4R2.PointToInterlockingConnection(x.GetRequiredService>(), x.GetRequiredService(), CancellationToken.None); + } + + throw new NotImplementedException("Trying to create unknown connection."); + } +} diff --git a/src/Point/Connections/Eulynx/PointState.cs b/src/Point/Connections/Eulynx/PointState.cs new file mode 100644 index 0000000..a0bada6 --- /dev/null +++ b/src/Point/Connections/Eulynx/PointState.cs @@ -0,0 +1,21 @@ + +using IPointToInterlockingConnection = EulynxLive.Point.Interfaces.IPointToInterlockingConnection; +using PointPosition = EulynxLive.Point.Interfaces.IPointToInterlockingConnection.PointPosition; +using DegradedPointPosition = EulynxLive.Point.Interfaces.IPointToInterlockingConnection.DegradedPointPosition; + +namespace EulynxLive.Point.Eulynx; +public abstract record PointState +{ + private IPointToInterlockingConnection.PointState _state; + public PP PointPosition { get => MapInterfacePointPositionToConcrete(_state.PointPosition); } + public DP DegradedPointPosition { get => MapInterfaceDegradedPointPositionToConcrete(_state.DegradedPointPosition); } + + public PointState(IPointToInterlockingConnection.PointState state) + { + _state = state; + } + + public abstract PP MapInterfacePointPositionToConcrete(PointPosition value); + + public abstract DP MapInterfaceDegradedPointPositionToConcrete(DegradedPointPosition value); +} diff --git a/src/Point/Startup.cs b/src/Point/Startup.cs index d37e9dc..1a01dc4 100644 --- a/src/Point/Startup.cs +++ b/src/Point/Startup.cs @@ -2,6 +2,7 @@ using EulynxLive.Point.Services; using IPointToInterlockingConnection =EulynxLive.Point.Interfaces.IPointToInterlockingConnection; using EulynxLive.Point.EulynxBaseline4R1; +using EulynxLive.Point.Eulynx; namespace EulynxLive.Point { @@ -21,10 +22,7 @@ public void ConfigureServices(IServiceCollection services) services.AddGrpc(); services.AddGrpcReflection(); - services.AddSingleton(x => - { - return new PointToInterlockingConnection(x.GetRequiredService>(), x.GetRequiredService(), CancellationToken.None); - }); + services.AddSingleton(ConnectionFactory.CreateConnection); // In production, the React files will be served from this directory services.AddSpaStaticFiles(configuration => From ceba410d4c8027cc865a5b879abb2a1970bfc149 Mon Sep 17 00:00:00 2001 From: Robert Schmid Date: Sun, 3 Dec 2023 13:30:32 +0100 Subject: [PATCH 03/11] FIx merge --- .../Eulynx/Baseline4R2/PointState.cs | 66 +++++++++---------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/src/Point/Connections/Eulynx/Baseline4R2/PointState.cs b/src/Point/Connections/Eulynx/Baseline4R2/PointState.cs index 55c22bf..50763b0 100644 --- a/src/Point/Connections/Eulynx/Baseline4R2/PointState.cs +++ b/src/Point/Connections/Eulynx/Baseline4R2/PointState.cs @@ -1,33 +1,33 @@ - -using EulynxLive.Messages.Baseline4R2; -using IPointToInterlockingConnection = EulynxLive.Point.Interfaces.IPointToInterlockingConnection; -using PointPosition = EulynxLive.Point.Interfaces.IPointToInterlockingConnection.PointPosition; -using DegradedPointPosition = EulynxLive.Point.Interfaces.IPointToInterlockingConnection.DegradedPointPosition; -using EulynxLive.Point.Eulynx; - -namespace EulynxLive.Point.EulynxBaseline4R2; - -public record PointState : Eulynx.PointState -{ - public PointState(IPointToInterlockingConnection.PointState state) : base(state) - { - } - - public override PointPointPositionMessageReportedPointPosition MapInterfacePointPositionToConcrete(PointPosition value) => value switch - { - IPointToInterlockingConnection.PointPosition.Left => PointPointPositionMessageReportedPointPosition.PointIsInALeftHandPositionDefinedEndPosition, - IPointToInterlockingConnection.PointPosition.Right => PointPointPositionMessageReportedPointPosition.PointIsInARightHandPositionDefinedEndPosition, - IPointToInterlockingConnection.PointPosition.UnintendetPosition => PointPointPositionMessageReportedPointPosition.PointIsInUnintendedPosition, - IPointToInterlockingConnection.PointPosition.NoEndposition => PointPointPositionMessageReportedPointPosition.PointIsInNoEndPosition, - _ => throw new NotImplementedException(), - }; - - public override PointPointPositionMessageReportedDegradedPointPosition MapInterfaceDegradedPointPositionToConcrete(DegradedPointPosition value) => value switch - { - IPointToInterlockingConnection.DegradedPointPosition.DegradedLeft => PointPointPositionMessageReportedDegradedPointPosition.PointIsInADegradedLeftHandPosition, - IPointToInterlockingConnection.DegradedPointPosition.DegradedRight => PointPointPositionMessageReportedDegradedPointPosition.PointIsInADegradedRightHandPosition, - IPointToInterlockingConnection.DegradedPointPosition.NotDegraded => PointPointPositionMessageReportedDegradedPointPosition.PointIsNotInADegradedPosition, - IPointToInterlockingConnection.DegradedPointPosition.NotApplicable => PointPointPositionMessageReportedDegradedPointPosition.DegradedPointPositionIsNotApplicable, - _ => throw new NotImplementedException(), - }; -} + +using EulynxLive.Messages.Baseline4R2; +using IPointToInterlockingConnection = EulynxLive.Point.Interfaces.IPointToInterlockingConnection; +using PointPosition = EulynxLive.Point.Interfaces.IPointToInterlockingConnection.PointPosition; +using DegradedPointPosition = EulynxLive.Point.Interfaces.IPointToInterlockingConnection.DegradedPointPosition; +using EulynxLive.Point.Eulynx; + +namespace EulynxLive.Point.EulynxBaseline4R2; + +public record PointState : Eulynx.PointState +{ + public PointState(IPointToInterlockingConnection.PointState state) : base(state) + { + } + + public override PointPointPositionMessageReportedPointPosition MapInterfacePointPositionToConcrete(PointPosition value) => value switch + { + IPointToInterlockingConnection.PointPosition.Left => PointPointPositionMessageReportedPointPosition.PointIsInALeftHandPositionDefinedEndPosition, + IPointToInterlockingConnection.PointPosition.Right => PointPointPositionMessageReportedPointPosition.PointIsInARightHandPositionDefinedEndPosition, + IPointToInterlockingConnection.PointPosition.UnintendedPosition => PointPointPositionMessageReportedPointPosition.PointIsInUnintendedPosition, + IPointToInterlockingConnection.PointPosition.NoEndPosition => PointPointPositionMessageReportedPointPosition.PointIsInNoEndPosition, + _ => throw new NotImplementedException(), + }; + + public override PointPointPositionMessageReportedDegradedPointPosition MapInterfaceDegradedPointPositionToConcrete(DegradedPointPosition value) => value switch + { + IPointToInterlockingConnection.DegradedPointPosition.DegradedLeft => PointPointPositionMessageReportedDegradedPointPosition.PointIsInADegradedLeftHandPosition, + IPointToInterlockingConnection.DegradedPointPosition.DegradedRight => PointPointPositionMessageReportedDegradedPointPosition.PointIsInADegradedRightHandPosition, + IPointToInterlockingConnection.DegradedPointPosition.NotDegraded => PointPointPositionMessageReportedDegradedPointPosition.PointIsNotInADegradedPosition, + IPointToInterlockingConnection.DegradedPointPosition.NotApplicable => PointPointPositionMessageReportedDegradedPointPosition.DegradedPointPositionIsNotApplicable, + _ => throw new NotImplementedException(), + }; +} From 4fa5b0291f400a8384e9a30c1f18e675da868210 Mon Sep 17 00:00:00 2001 From: Robert Schmid Date: Sun, 3 Dec 2023 13:33:38 +0100 Subject: [PATCH 04/11] Move old message definitions to deprecated ns --- src/LevelCrossing/LevelCrossing.cs | 3 +- src/LightSignal/DistantLightSignal.cs | 50 +- src/LightSignal/EulynxLightSignal.cs | 1 + src/LightSignal/LightSignalFactory.cs | 132 +- src/LightSignal/LightSignalHostedService.cs | 456 +++--- src/LightSignal/MultiSectionLightSignal.cs | 51 +- .../Services/LightSignalService.cs | 70 +- src/Messages/Baseline4R2/ProtocolType.cs | 16 + .../{ => Deprecated}/EulynxMessage.cs | 490 +++---- .../ExternalLevelCrossingSystemMessage.cs | 1220 ++++++++--------- src/Messages/{ => Deprecated}/Generic.cs | 14 +- .../{ => Deprecated}/LightSignalMessage.cs | 1144 ++++++++-------- .../NeuPro/LevelCrossingMessage.cs | 546 ++++---- .../{ => Deprecated}/NeuPro/NeuProMessage.cs | 42 +- src/Messages/{ => Deprecated}/PointMessage.cs | 526 +++---- .../{ => Deprecated}/ProtocolTypes.cs | 33 +- .../TrainDetectionSystemMessage.cs | 986 ++++++------- 17 files changed, 2900 insertions(+), 2880 deletions(-) create mode 100644 src/Messages/Baseline4R2/ProtocolType.cs rename src/Messages/{ => Deprecated}/EulynxMessage.cs (98%) rename src/Messages/{ => Deprecated}/ExternalLevelCrossingSystemMessage.cs (97%) rename src/Messages/{ => Deprecated}/Generic.cs (67%) rename src/Messages/{ => Deprecated}/LightSignalMessage.cs (97%) rename src/Messages/{ => Deprecated}/NeuPro/LevelCrossingMessage.cs (97%) rename src/Messages/{ => Deprecated}/NeuPro/NeuProMessage.cs (89%) rename src/Messages/{ => Deprecated}/PointMessage.cs (96%) rename src/Messages/{ => Deprecated}/ProtocolTypes.cs (88%) rename src/Messages/{ => Deprecated}/TrainDetectionSystemMessage.cs (97%) diff --git a/src/LevelCrossing/LevelCrossing.cs b/src/LevelCrossing/LevelCrossing.cs index 7742577..6684700 100644 --- a/src/LevelCrossing/LevelCrossing.cs +++ b/src/LevelCrossing/LevelCrossing.cs @@ -12,10 +12,11 @@ using Microsoft.Extensions.Logging; using Sci; using EulynxLive.Messages; -using NeuPro = EulynxLive.Messages.NeuPro; +using NeuPro = EulynxLive.Messages.Deprecated.NeuPro; using static Sci.Rasta; using System.Text; using Grpc.Net.Client; +using EulynxLive.Messages.Deprecated; namespace EulynxLive.LevelCrossing { diff --git a/src/LightSignal/DistantLightSignal.cs b/src/LightSignal/DistantLightSignal.cs index da5f36b..e39f1b6 100644 --- a/src/LightSignal/DistantLightSignal.cs +++ b/src/LightSignal/DistantLightSignal.cs @@ -1,25 +1,25 @@ -using System.Threading.Tasks; -using Microsoft.Extensions.Logging; -using EulynxLive.Messages; -using System.Threading.Channels; - -namespace EulynxLive.LightSignal -{ - public class DistantLightSignal : EulynxLightSignal - { - public DistantLightSignal(ILogger logger, string id, string remoteId, Channel outgoingMessages) : base(logger, id, remoteId, outgoingMessages) { } - - public override async Task Reset() - { - Initialized = false; - BasicAspectType1 = BasicAspectType.ExpectStop; - BasicAspectTypeExtension = BasicAspectTypeExtension.IntendedDark; - SpeedIndicators = SpeedIndicators.IndicationDark; - SpeedIndicatorsAnnouncements = SpeedIndicatorsAnnouncements.AnnouncementDark; - DirectionIndicators = DirectionIndicators.IndicationDark; - DirectionIndicatorsAnnouncements = DirectionIndicatorsAnnouncements.AnnouncementDark; - Luminosity = Luminosity.Day; - TriggerUpdate(); - } - } -} +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using System.Threading.Channels; +using EulynxLive.Messages.Deprecated; + +namespace EulynxLive.LightSignal +{ + public class DistantLightSignal : EulynxLightSignal + { + public DistantLightSignal(ILogger logger, string id, string remoteId, Channel outgoingMessages) : base(logger, id, remoteId, outgoingMessages) { } + + public override async Task Reset() + { + Initialized = false; + BasicAspectType1 = BasicAspectType.ExpectStop; + BasicAspectTypeExtension = BasicAspectTypeExtension.IntendedDark; + SpeedIndicators = SpeedIndicators.IndicationDark; + SpeedIndicatorsAnnouncements = SpeedIndicatorsAnnouncements.AnnouncementDark; + DirectionIndicators = DirectionIndicators.IndicationDark; + DirectionIndicatorsAnnouncements = DirectionIndicatorsAnnouncements.AnnouncementDark; + Luminosity = Luminosity.Day; + TriggerUpdate(); + } + } +} diff --git a/src/LightSignal/EulynxLightSignal.cs b/src/LightSignal/EulynxLightSignal.cs index 4f7ab1a..94a71c4 100644 --- a/src/LightSignal/EulynxLightSignal.cs +++ b/src/LightSignal/EulynxLightSignal.cs @@ -4,6 +4,7 @@ using Microsoft.Extensions.Logging; using EulynxLive.Messages; using System.Threading.Channels; +using EulynxLive.Messages.Deprecated; namespace EulynxLive.LightSignal { diff --git a/src/LightSignal/LightSignalFactory.cs b/src/LightSignal/LightSignalFactory.cs index a18931a..5e28f59 100644 --- a/src/LightSignal/LightSignalFactory.cs +++ b/src/LightSignal/LightSignalFactory.cs @@ -1,65 +1,67 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using EulynxLive.Messages; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Logging; - -namespace EulynxLive.LightSignal -{ - public enum SignalTypeTypes - { - Main, - MainShunting, - MultiSection, - MultiSectionShunting, - Shunting, - Distant, - Repeater, - TrainProtection - } - - public class LightSignalFactory - { - private readonly IConfiguration _configuration; - private readonly ILogger _logger; - - public LightSignalFactory(ILogger logger, IConfiguration configuration) - { - _logger = logger; - _configuration = configuration; - } - - public class LightSignalConfig - { - public string Id { get; set; } - public SignalTypeTypes Type { get; set; } - } - - public List Create(System.Threading.Channels.Channel outgoingMessages) - { - - var signalType = _configuration.GetSection("LightSignals").Get>(); - if (signalType == null) - { - throw new Exception("Missing light signals configuration."); - } - - - // Command line argument parsing. - - var remoteId = _configuration["remote-id"]; - if (remoteId == null) - { - throw new Exception("Missing --remote-id command line parameter."); - } - - return signalType.Select(x => x.Type switch - { - SignalTypeTypes.MultiSection => new MultiSectionLightSignal(_logger, x.Id, remoteId, outgoingMessages), - SignalTypeTypes.Distant => new DistantLightSignal(_logger, x.Id, remoteId, outgoingMessages), - _ => new MultiSectionLightSignal(_logger, x.Id, remoteId, outgoingMessages), - }).ToList(); - } - } -} +using System; +using System.Collections.Generic; +using System.Linq; +using EulynxLive.Messages; +using EulynxLive.Messages.Deprecated; + +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; + +namespace EulynxLive.LightSignal +{ + public enum SignalTypeTypes + { + Main, + MainShunting, + MultiSection, + MultiSectionShunting, + Shunting, + Distant, + Repeater, + TrainProtection + } + + public class LightSignalFactory + { + private readonly IConfiguration _configuration; + private readonly ILogger _logger; + + public LightSignalFactory(ILogger logger, IConfiguration configuration) + { + _logger = logger; + _configuration = configuration; + } + + public class LightSignalConfig + { + public string Id { get; set; } + public SignalTypeTypes Type { get; set; } + } + + public List Create(System.Threading.Channels.Channel outgoingMessages) + { + + var signalType = _configuration.GetSection("LightSignals").Get>(); + if (signalType == null) + { + throw new Exception("Missing light signals configuration."); + } + + + // Command line argument parsing. + + var remoteId = _configuration["remote-id"]; + if (remoteId == null) + { + throw new Exception("Missing --remote-id command line parameter."); + } + + return signalType.Select(x => x.Type switch + { + SignalTypeTypes.MultiSection => new MultiSectionLightSignal(_logger, x.Id, remoteId, outgoingMessages), + SignalTypeTypes.Distant => new DistantLightSignal(_logger, x.Id, remoteId, outgoingMessages), + _ => new MultiSectionLightSignal(_logger, x.Id, remoteId, outgoingMessages), + }).ToList(); + } + } +} diff --git a/src/LightSignal/LightSignalHostedService.cs b/src/LightSignal/LightSignalHostedService.cs index c895ca2..40cb3c9 100644 --- a/src/LightSignal/LightSignalHostedService.cs +++ b/src/LightSignal/LightSignalHostedService.cs @@ -1,228 +1,228 @@ -using System; -using System.Linq; -using System.Collections.Generic; -using System.Net.WebSockets; -using System.Text.Json; -using System.Threading; -using System.Threading.Tasks; -using Google.Protobuf; -using Grpc.Core; -using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; -using Sci; -using EulynxLive.Messages; -using static Sci.Rasta; -using System.Text; -using Grpc.Net.Client; -using Microsoft.Extensions.Configuration; -using System.Threading.Channels; - -namespace EulynxLive.LightSignal -{ - public class LightSignalHostedService : BackgroundService - { - private readonly List _webSockets; - private string _remoteEndpoint; - private readonly LightSignalFactory _factory; - private string _rastaId; - private List _lightSignals; - private readonly ILogger _logger; - - public LightSignalHostedService(LightSignalFactory factory, ILogger logger, IConfiguration configuration) - { - _factory = factory; - - _rastaId = configuration["local-rasta-id"]; - if (_rastaId == null) - { - throw new Exception("Missing --local-rasta-id command line parameter."); - } - - _remoteEndpoint = configuration["remote-endpoint"]; - if (_remoteEndpoint == null) - { - throw new Exception("Missing --remote-endpoint command line parameter."); - } - - _webSockets = new List(); - _logger = logger; - } - - private async void LightSignal_OnUpdate(object sender, EventArgs e) - { - await UpdateConnectedWebClients(); - } - - public async Task HandleWebSocket(WebSocket webSocket) - { - _webSockets.Add(webSocket); - try - { - await UpdateWebClient(webSocket); - - while (true) - { - byte[] messageBuffer = new byte[1024]; - var buffer = new ArraySegment(messageBuffer); - var result = await webSocket.ReceiveAsync(buffer, CancellationToken.None); - if (result.CloseStatus.HasValue) - { - break; - } - } - } - catch (WebSocketException) - { - // Do nothing, the WebSocket has died. - } - _webSockets.Remove(webSocket); - } - - protected async Task UpdateConnectedWebClients() - { - try - { - var tasks = _webSockets.Select(UpdateWebClient); - await Task.WhenAll(tasks); - } - catch (Exception) - { - // Some client likely has an issue, ignore - } - } - - private async Task UpdateWebClient(WebSocket webSocket) - { - if (_lightSignals != null) { - var options = new JsonSerializerOptions { WriteIndented = true }; - var serializedState = JsonSerializer.Serialize(_lightSignals.Select(x => new LightSignalState{ - id = x.Id, - suspended = x.CtsSuspend.IsCancellationRequested, - setup = x.Initialized, - mainAspect = (MainAspect)x.BasicAspectType, - secondaryAspect = (SecondaryAspect)x.BasicAspectTypeExtension, - zs3 = (Zs3v)x.SpeedIndicators, - zs3v = (Zs3v)x.SpeedIndicatorsAnnouncements, - zs2 = (Zs2v)x.DirectionIndicators, - zs2v = (Zs2v)x.DirectionIndicatorsAnnouncements, - luminosity = (LuminosityNeuPro)x.IntentionallyDark - }), options); - var serializedStateBytes = Encoding.UTF8.GetBytes(serializedState); - await webSocket.SendAsync(serializedStateBytes, WebSocketMessageType.Text, true, CancellationToken.None); - } - } - - protected override async Task ExecuteAsync(CancellationToken stoppingToken) - { - while (true) - { - var _outgoingMessages = System.Threading.Channels.Channel.CreateUnbounded(); - _lightSignals = _factory.Create(_outgoingMessages); - - foreach (var lightSignal in _lightSignals) - { - lightSignal.OnUpdate += LightSignal_OnUpdate; - } - - await Task.WhenAll(_lightSignals.Select(x => x.Reset())); - - try - { - var channel = GrpcChannel.ForAddress(_remoteEndpoint); - var client = new RastaClient(channel); - _logger.LogTrace("Connecting..."); - var metadata = new Metadata { { "rasta-id", _rastaId } }; - - using var stream = client.Stream(metadata); - - // Mux - var mux = async () => { - await foreach (var message in _outgoingMessages.Reader.ReadAllAsync()) - { - var packet = new SciPacket - { - Message = ByteString.CopyFrom(message.ToByteArray()), - }; - _logger.LogTrace("Writing bytes to connection: {bytes}", packet.Message.ToByteArray()); - await stream.RequestStream.WriteAsync(packet); - } - }; - - // Demux - var demux = async () => { - await foreach (var message in stream.ResponseStream.ReadAllAsync()) - { - var bytes = message.Message.ToByteArray(); - _logger.LogTrace("Received bytes from connection: {bytes}", bytes); - EulynxMessage eulynxMessage; - try - { - eulynxMessage = EulynxMessage.FromBytes(bytes); - } - catch (Exception ex) - { - _logger.LogWarning(ex, "Couldn't parse EULYNX message"); - throw; - } - - var ls = _lightSignals.SingleOrDefault(x => x.Id == eulynxMessage.ReceiverId.TrimEnd('_')); - if (ls != null) - { - await ls.HandleMessage(eulynxMessage); - } - } - }; - - await Task.WhenAny(_lightSignals.Select(async x => { - while (true) - { - try - { - await x.Run(); - } - catch (Exception) - { - await x.Reset(); - await Task.Delay(1000); - } - } - }).Concat(new[] { mux(), demux() })); - } - catch (Exception ex) - { - _logger.LogWarning(ex, "Exception occurred in signal state machine: Reverting to safe state."); - } - - foreach (var lightSignal in _lightSignals) - { - lightSignal.CtsSuspend.Cancel(); - } - - await Task.WhenAll(_lightSignals.Select(x => x.Reset())); - - foreach (var lightSignal in _lightSignals) - { - lightSignal.OnUpdate -= LightSignal_OnUpdate; - } - } - } - - internal void Suspend(string lightSignal) - { - var ls = _lightSignals.SingleOrDefault(x => x.Id == lightSignal); - if (ls != null) - { - ls.Suspend(); - } - } - - internal async Task Unsuspend(string lightSignal) - { - var ls = _lightSignals.SingleOrDefault(x => x.Id == lightSignal); - if (ls != null) - { - await ls.Unsuspend(); - } - } - } -} +using System; +using System.Linq; +using System.Collections.Generic; +using System.Net.WebSockets; +using System.Text.Json; +using System.Threading; +using System.Threading.Tasks; +using Google.Protobuf; +using Grpc.Core; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using Sci; +using EulynxLive.Messages; +using static Sci.Rasta; +using System.Text; +using Grpc.Net.Client; +using Microsoft.Extensions.Configuration; +using EulynxLive.Messages.Deprecated; + +namespace EulynxLive.LightSignal +{ + public class LightSignalHostedService : BackgroundService + { + private readonly List _webSockets; + private string _remoteEndpoint; + private readonly LightSignalFactory _factory; + private string _rastaId; + private List _lightSignals; + private readonly ILogger _logger; + + public LightSignalHostedService(LightSignalFactory factory, ILogger logger, IConfiguration configuration) + { + _factory = factory; + + _rastaId = configuration["local-rasta-id"]; + if (_rastaId == null) + { + throw new Exception("Missing --local-rasta-id command line parameter."); + } + + _remoteEndpoint = configuration["remote-endpoint"]; + if (_remoteEndpoint == null) + { + throw new Exception("Missing --remote-endpoint command line parameter."); + } + + _webSockets = new List(); + _logger = logger; + } + + private async void LightSignal_OnUpdate(object sender, EventArgs e) + { + await UpdateConnectedWebClients(); + } + + public async Task HandleWebSocket(WebSocket webSocket) + { + _webSockets.Add(webSocket); + try + { + await UpdateWebClient(webSocket); + + while (true) + { + byte[] messageBuffer = new byte[1024]; + var buffer = new ArraySegment(messageBuffer); + var result = await webSocket.ReceiveAsync(buffer, CancellationToken.None); + if (result.CloseStatus.HasValue) + { + break; + } + } + } + catch (WebSocketException) + { + // Do nothing, the WebSocket has died. + } + _webSockets.Remove(webSocket); + } + + protected async Task UpdateConnectedWebClients() + { + try + { + var tasks = _webSockets.Select(UpdateWebClient); + await Task.WhenAll(tasks); + } + catch (Exception) + { + // Some client likely has an issue, ignore + } + } + + private async Task UpdateWebClient(WebSocket webSocket) + { + if (_lightSignals != null) { + var options = new JsonSerializerOptions { WriteIndented = true }; + var serializedState = JsonSerializer.Serialize(_lightSignals.Select(x => new LightSignalState{ + id = x.Id, + suspended = x.CtsSuspend.IsCancellationRequested, + setup = x.Initialized, + mainAspect = (MainAspect)x.BasicAspectType, + secondaryAspect = (SecondaryAspect)x.BasicAspectTypeExtension, + zs3 = (Zs3v)x.SpeedIndicators, + zs3v = (Zs3v)x.SpeedIndicatorsAnnouncements, + zs2 = (Zs2v)x.DirectionIndicators, + zs2v = (Zs2v)x.DirectionIndicatorsAnnouncements, + luminosity = (LuminosityNeuPro)x.IntentionallyDark + }), options); + var serializedStateBytes = Encoding.UTF8.GetBytes(serializedState); + await webSocket.SendAsync(serializedStateBytes, WebSocketMessageType.Text, true, CancellationToken.None); + } + } + + protected override async Task ExecuteAsync(CancellationToken stoppingToken) + { + while (true) + { + var _outgoingMessages = System.Threading.Channels.Channel.CreateUnbounded(); + _lightSignals = _factory.Create(_outgoingMessages); + + foreach (var lightSignal in _lightSignals) + { + lightSignal.OnUpdate += LightSignal_OnUpdate; + } + + await Task.WhenAll(_lightSignals.Select(x => x.Reset())); + + try + { + var channel = GrpcChannel.ForAddress(_remoteEndpoint); + var client = new RastaClient(channel); + _logger.LogTrace("Connecting..."); + var metadata = new Metadata { { "rasta-id", _rastaId } }; + + using var stream = client.Stream(metadata); + + // Mux + var mux = async () => { + await foreach (var message in _outgoingMessages.Reader.ReadAllAsync()) + { + var packet = new SciPacket + { + Message = ByteString.CopyFrom(message.ToByteArray()), + }; + _logger.LogTrace("Writing bytes to connection: {bytes}", packet.Message.ToByteArray()); + await stream.RequestStream.WriteAsync(packet); + } + }; + + // Demux + var demux = async () => { + await foreach (var message in stream.ResponseStream.ReadAllAsync()) + { + var bytes = message.Message.ToByteArray(); + _logger.LogTrace("Received bytes from connection: {bytes}", bytes); + EulynxMessage eulynxMessage; + try + { + eulynxMessage = EulynxMessage.FromBytes(bytes); + } + catch (Exception ex) + { + _logger.LogWarning(ex, "Couldn't parse EULYNX message"); + throw; + } + + var ls = _lightSignals.SingleOrDefault(x => x.Id == eulynxMessage.ReceiverId.TrimEnd('_')); + if (ls != null) + { + await ls.HandleMessage(eulynxMessage); + } + } + }; + + await Task.WhenAny(_lightSignals.Select(async x => { + while (true) + { + try + { + await x.Run(); + } + catch (Exception) + { + await x.Reset(); + await Task.Delay(1000); + } + } + }).Concat(new[] { mux(), demux() })); + } + catch (Exception ex) + { + _logger.LogWarning(ex, "Exception occurred in signal state machine: Reverting to safe state."); + } + + foreach (var lightSignal in _lightSignals) + { + lightSignal.CtsSuspend.Cancel(); + } + + await Task.WhenAll(_lightSignals.Select(x => x.Reset())); + + foreach (var lightSignal in _lightSignals) + { + lightSignal.OnUpdate -= LightSignal_OnUpdate; + } + } + } + + internal void Suspend(string lightSignal) + { + var ls = _lightSignals.SingleOrDefault(x => x.Id == lightSignal); + if (ls != null) + { + ls.Suspend(); + } + } + + internal async Task Unsuspend(string lightSignal) + { + var ls = _lightSignals.SingleOrDefault(x => x.Id == lightSignal); + if (ls != null) + { + await ls.Unsuspend(); + } + } + } +} diff --git a/src/LightSignal/MultiSectionLightSignal.cs b/src/LightSignal/MultiSectionLightSignal.cs index 955ca82..2943635 100644 --- a/src/LightSignal/MultiSectionLightSignal.cs +++ b/src/LightSignal/MultiSectionLightSignal.cs @@ -1,25 +1,26 @@ -using System.Threading.Tasks; -using Microsoft.Extensions.Logging; -using EulynxLive.Messages; -using System.Threading.Channels; - -namespace EulynxLive.LightSignal -{ - public class MultiSectionLightSignal : EulynxLightSignal - { - public MultiSectionLightSignal(ILogger logger, string id, string remoteId, Channel outgoingMessages) : base(logger, id, remoteId, outgoingMessages) { } - - public override async Task Reset() - { - Initialized = false; - BasicAspectType1 = BasicAspectType.Stop_Danger_1; - BasicAspectTypeExtension = BasicAspectTypeExtension.IntendedDark; - SpeedIndicators = SpeedIndicators.IndicationDark; - SpeedIndicatorsAnnouncements = SpeedIndicatorsAnnouncements.AnnouncementDark; - DirectionIndicators = DirectionIndicators.IndicationDark; - DirectionIndicatorsAnnouncements = DirectionIndicatorsAnnouncements.AnnouncementDark; - Luminosity = Luminosity.Day; - TriggerUpdate(); - } - } -} +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using EulynxLive.Messages; +using System.Threading.Channels; +using EulynxLive.Messages.Deprecated; + +namespace EulynxLive.LightSignal +{ + public class MultiSectionLightSignal : EulynxLightSignal + { + public MultiSectionLightSignal(ILogger logger, string id, string remoteId, Channel outgoingMessages) : base(logger, id, remoteId, outgoingMessages) { } + + public override async Task Reset() + { + Initialized = false; + BasicAspectType1 = BasicAspectType.Stop_Danger_1; + BasicAspectTypeExtension = BasicAspectTypeExtension.IntendedDark; + SpeedIndicators = SpeedIndicators.IndicationDark; + SpeedIndicatorsAnnouncements = SpeedIndicatorsAnnouncements.AnnouncementDark; + DirectionIndicators = DirectionIndicators.IndicationDark; + DirectionIndicatorsAnnouncements = DirectionIndicatorsAnnouncements.AnnouncementDark; + Luminosity = Luminosity.Day; + TriggerUpdate(); + } + } +} diff --git a/src/LightSignal/Services/LightSignalService.cs b/src/LightSignal/Services/LightSignalService.cs index 24d1ef2..a642ff3 100644 --- a/src/LightSignal/Services/LightSignalService.cs +++ b/src/LightSignal/Services/LightSignalService.cs @@ -1,35 +1,35 @@ -using System.Threading.Tasks; -using Grpc.Core; -using EulynxLive.Messages; -using static EulynxLive.LightSignal.Proto.LightSignal; -using EulynxLive.LightSignal.Proto; - -namespace EulynxLive.LightSignal.Services { - public class LightSignalService : LightSignalBase { - private readonly EulynxLightSignal _lightSignal; - - public LightSignalService(EulynxLightSignal LightSignal) - { - _lightSignal = LightSignal; - } - - public override Task GetSignalAspect(Nothing request, Grpc.Core.ServerCallContext context) - { - var response = new SignalAspectMessage(); - response.Aspect = SignalAspect.StopDanger1; - switch (_lightSignal.BasicAspectType) { - case BasicAspectType.Stop_Danger_1: - response.Aspect = SignalAspect.StopDanger1; - break; - case BasicAspectType.Proceed_Clear_1: - response.Aspect = SignalAspect.ProceedClear1; - break; - case BasicAspectType.ExpectStop: - response.Aspect = SignalAspect.ExpectStop; - break; - } - - return Task.FromResult(response); - } - } -} +using System.Threading.Tasks; +using static EulynxLive.LightSignal.Proto.LightSignal; +using EulynxLive.LightSignal.Proto; +using EulynxLive.Messages.Deprecated; + +namespace EulynxLive.LightSignal.Services +{ + public class LightSignalService : LightSignalBase { + private readonly EulynxLightSignal _lightSignal; + + public LightSignalService(EulynxLightSignal LightSignal) + { + _lightSignal = LightSignal; + } + + public override Task GetSignalAspect(Nothing request, Grpc.Core.ServerCallContext context) + { + var response = new SignalAspectMessage(); + response.Aspect = SignalAspect.StopDanger1; + switch (_lightSignal.BasicAspectType) { + case BasicAspectType.Stop_Danger_1: + response.Aspect = SignalAspect.StopDanger1; + break; + case BasicAspectType.Proceed_Clear_1: + response.Aspect = SignalAspect.ProceedClear1; + break; + case BasicAspectType.ExpectStop: + response.Aspect = SignalAspect.ExpectStop; + break; + } + + return Task.FromResult(response); + } + } +} diff --git a/src/Messages/Baseline4R2/ProtocolType.cs b/src/Messages/Baseline4R2/ProtocolType.cs new file mode 100644 index 0000000..5a55ab3 --- /dev/null +++ b/src/Messages/Baseline4R2/ProtocolType.cs @@ -0,0 +1,16 @@ +namespace EulynxLive.Messages.Baseline4R2; + +public enum ProtocolType : byte +{ + // From: EU.SCI-XX.PDI.53 + AdjacentInterlockingSystem = 0x01, + TrainDetectionSystem = 0x20, + LightSignal = 0x30, + Point = 0x40, + RadioBlockCenter = 0x50, + LevelCrossing = 0x60, + CC = 0x70, + TrackworkerSafetySystem = 0x80, + GenericIO = 0x90, + ExternalLevelCrossingSystem = 0xC0, +} diff --git a/src/Messages/EulynxMessage.cs b/src/Messages/Deprecated/EulynxMessage.cs similarity index 98% rename from src/Messages/EulynxMessage.cs rename to src/Messages/Deprecated/EulynxMessage.cs index b2ed3f2..9e690b1 100644 --- a/src/Messages/EulynxMessage.cs +++ b/src/Messages/Deprecated/EulynxMessage.cs @@ -1,245 +1,245 @@ -using System; -using System.Text; - -namespace EulynxLive.Messages -{ - public abstract class EulynxMessage - { - protected const int PROTOCOL_TYPE_OFFSET = 0; - protected const int MESSAGE_TYPE_OFFSET = 1; - protected const int SENDER_IDENTIFIER_OFFSET = 3; - protected const int RECEIVER_IDENTIFIER_OFFSET = 23; - - public virtual ProtocolType ProtocolType { get; } - public abstract ushort MessageTypeRaw { get; } - public string SenderId { get; } - public string ReceiverId { get; } - public abstract int Size { get; } - - public EulynxMessage(string senderId, string receiverId) - { - SenderId = senderId; - ReceiverId = receiverId; - } - - public static EulynxMessage FromBytes(byte[] message) - { - var protocolType = (ProtocolType)message[PROTOCOL_TYPE_OFFSET]; - var messageType = BitConverter.ToUInt16( - new byte[2] { message[MESSAGE_TYPE_OFFSET], message[MESSAGE_TYPE_OFFSET + 1] }); - var senderId = Encoding.UTF8.GetString(message, SENDER_IDENTIFIER_OFFSET, 20); - var receiverId = Encoding.UTF8.GetString(message, RECEIVER_IDENTIFIER_OFFSET, 20); - - switch (protocolType) - { - case ProtocolType.TrainDetectionSystem: - switch ((TrainDetectionSystemMessageType)messageType) - { - case TrainDetectionSystemMessageType.VersionCheckCommand: - return TrainDetectionSystemVersionCheckCommand.Parse(senderId, receiverId, message); - case TrainDetectionSystemMessageType.VersionCheckMessage: - return TrainDetectionSystemVersionCheckMessage.Parse(senderId, receiverId, message); - case TrainDetectionSystemMessageType.PDIAvailable: - return TrainDetectionSystemPDIAvailableMessage.Parse(senderId, receiverId, message); - case TrainDetectionSystemMessageType.PDINotAvailable: - return TrainDetectionSystemPDINotAvailableMessage.Parse(senderId, receiverId, message); - case TrainDetectionSystemMessageType.InitializationRequest: - return TrainDetectionSystemInitializationRequestMessage.Parse(senderId, receiverId, message); - case TrainDetectionSystemMessageType.StartInitialization: - return TrainDetectionSystemStartInitializationMessage.Parse(senderId, receiverId, message); - case TrainDetectionSystemMessageType.InitializationCompleted: - return TrainDetectionSystemInitializationCompletedMessage.Parse(senderId, receiverId, message); - case TrainDetectionSystemMessageType.ForceClearCommand: - return TrainDetectionSystemForceClearCommand.Parse(senderId, receiverId, message); - case TrainDetectionSystemMessageType.UpdateFillingLevelCommand: - return TrainDetectionSystemUpdateFillingLevelCommand.Parse(senderId, receiverId, message); - case TrainDetectionSystemMessageType.DRFCCommand: - return TrainDetectionSystemDRFCCommand.Parse(senderId, receiverId, message); - case TrainDetectionSystemMessageType.TDPActivationCommand: - return TrainDetectionSystemTDPActivationCommand.Parse(senderId, receiverId, message); - case TrainDetectionSystemMessageType.TvpsOccupancyStatusMessage: - if (message.Length == 45) { - return TrainDetectionSystemTvpsOccupancyStatusMessageNeuPro.Parse(senderId, receiverId, message); - } else if (message.Length == 47) { - return TrainDetectionSystemTvpsOccupancyStatusMessageNeuProThales.Parse(senderId, receiverId, message); - } else if (message.Length == 48) { - return TrainDetectionSystemTvpsOccupancyStatusMessage.Parse(senderId, receiverId, message); - } - break; - case TrainDetectionSystemMessageType.CommandRejectedMessage: - return TrainDetectionSystemCommandRejectedMessage.Parse(senderId, receiverId, message); - case TrainDetectionSystemMessageType.DRFCReceiptMessage: - return TrainDetectionSystemDRFCReceiptMessage.Parse(senderId, receiverId, message); - case TrainDetectionSystemMessageType.TvpsFCPFailedMessage: - return TrainDetectionSystemTvpsFCPFailedMessage.Parse(senderId, receiverId, message); - case TrainDetectionSystemMessageType.TvpsFCPAFailedMessage: - return TrainDetectionSystemTvpsFCPAFailedMessage.Parse(senderId, receiverId, message); - case TrainDetectionSystemMessageType.AdditionalInformationMessage: - return TrainDetectionSystemAdditionalInformationMessage.Parse(senderId, receiverId, message); - case TrainDetectionSystemMessageType.TDPStatusMessage: - return TrainDetectionSystemTDPStatusMessage.Parse(senderId, receiverId, message); - } - break; - case ProtocolType.LightSignal: - switch ((LightSignalMessageType)messageType) - { - case LightSignalMessageType.IndicateSignalAspect: - return LightSignalIndicateSignalAspectCommand.Parse(senderId, receiverId, message); - case LightSignalMessageType.IndicatedSignalAspect: - return LightSignalIndicatedSignalAspectMessage.Parse(senderId, receiverId, message); - case LightSignalMessageType.VersionCheckCommand: - return LightSignalVersionCheckCommand.Parse(senderId, receiverId, message); - case LightSignalMessageType.VersionCheckMessage: - return LightSignalVersionCheckMessage.Parse(senderId, receiverId, message); - case LightSignalMessageType.PDIAvailable: - return LightSignalPDIAvailableMessage.Parse(senderId, receiverId, message); - case LightSignalMessageType.PDINotAvailable: - return LightSignalPDINotAvailableMessage.Parse(senderId, receiverId, message); - case LightSignalMessageType.InitializationRequest: - return LightSignalInitializationRequestMessage.Parse(senderId, receiverId, message); - case LightSignalMessageType.StartInitialization: - return LightSignalStartInitializationMessage.Parse(senderId, receiverId, message); - case LightSignalMessageType.InitializationCompleted: - return LightSignalInitializationCompletedMessage.Parse(senderId, receiverId, message); - case LightSignalMessageType.SetLuminosityMessage: - return LightSignalSetLuminosityMessage.Parse(senderId, receiverId, message); - // Work in progress: - case LightSignalMessageType.SetLuminosityCommand: - throw new NotImplementedException(); - // return LightSignalSetLuminosityCommand.Parse(senderId, receiverId, message); - } - break; - case ProtocolType.Point: - switch ((PointMessageType)messageType) - { - case PointMessageType.MovePointCommand: - return PointMovePointCommand.Parse(senderId, receiverId, message); - case PointMessageType.PointPositionMessage: - return PointPositionMessage.Parse(senderId, receiverId, message); - case PointMessageType.TimeoutMessage: - return PointTimeoutMessage.Parse(senderId, receiverId, message); - case PointMessageType.VersionCheckCommand: - return PointVersionCheckCommand.Parse(senderId, receiverId, message); - case PointMessageType.VersionCheckMessage: - return PointVersionCheckMessage.Parse(senderId, receiverId, message); - case PointMessageType.PDIAvailable: - return PointPDIAvailableMessage.Parse(senderId, receiverId, message); - case PointMessageType.PDINotAvailable: - return PointPDINotAvailableMessage.Parse(senderId, receiverId, message); - case PointMessageType.InitializationRequest: - return PointInitializationRequestMessage.Parse(senderId, receiverId, message); - case PointMessageType.StartInitialization: - return PointStartInitializationMessage.Parse(senderId, receiverId, message); - case PointMessageType.InitializationCompleted: - return PointInitializationCompletedMessage.Parse(senderId, receiverId, message); - } - break; - case ProtocolType.LevelCrossing: - // NeuPro - switch ((NeuPro.LevelCrossingMessageType)messageType) { - case NeuPro.LevelCrossingMessageType.AnFsüCommand: - return NeuPro.AnFsüCommand.Parse(senderId, receiverId, message); - case NeuPro.LevelCrossingMessageType.AusFsüCommand: - return NeuPro.AusFsüCommand.Parse(senderId, receiverId, message); - case NeuPro.LevelCrossingMessageType.MeldungZustandGleisbezogenMessage: - return NeuPro.MeldungZustandGleisbezogenMessage.Parse(senderId, receiverId, message); - case NeuPro.LevelCrossingMessageType.MeldungZustandBüBezogenMessage: - return NeuPro.MeldungZustandBüBezogenMessage.Parse(senderId, receiverId, message); - - case NeuPro.LevelCrossingMessageType.InitializationRequest: - return NeuPro.LevelCrossingInitializationRequestMessage.Parse(senderId, receiverId, message); - case NeuPro.LevelCrossingMessageType.StartInitialization: - return NeuPro.LevelCrossingStartInitializationMessage.Parse(senderId, receiverId, message); - case NeuPro.LevelCrossingMessageType.InitializationCompleted: - return NeuPro.LevelCrossingInitializationCompletedMessage.Parse(senderId, receiverId, message); - case NeuPro.LevelCrossingMessageType.VersionCheckCommand: - return NeuPro.LevelCrossingVersionCheckCommand.Parse(senderId, receiverId, message); - case NeuPro.LevelCrossingMessageType.VersionCheckMessage: - return NeuPro.LevelCrossingVersionCheckMessage.Parse(senderId, receiverId, message); - // Not sure if these exist: - case NeuPro.LevelCrossingMessageType.PDIAvailable: - return NeuPro.LevelCrossingPDIAvailableMessage.Parse(senderId, receiverId, message); - case NeuPro.LevelCrossingMessageType.PDINotAvailable: - return NeuPro.LevelCrossingPDINotAvailableMessage.Parse(senderId, receiverId, message); - } - break; - case ProtocolType.ExternalLevelCrossingSystem: - switch ((ExternalLevelCrossingSystemMessageType)messageType) { - case ExternalLevelCrossingSystemMessageType.LxActivationCommand: - return ExternalLevelCrossingSystemLxActivationCommand.Parse(senderId, receiverId, message); - case ExternalLevelCrossingSystemMessageType.TrActivationCommand: - return ExternalLevelCrossingSystemTrActivationCommand.Parse(senderId, receiverId, message); - case ExternalLevelCrossingSystemMessageType.LxDeactivationCommand: - return ExternalLevelCrossingSystemLxDeactivationCommand.Parse(senderId, receiverId, message); - case ExternalLevelCrossingSystemMessageType.TrDeactivationCommand: - return ExternalLevelCrossingSystemTrDeactivationCommand.Parse(senderId, receiverId, message); - case ExternalLevelCrossingSystemMessageType.ControlActivationPointCommand: - return ExternalLevelCrossingSystemControlActivationPointCommand.Parse(senderId, receiverId, message); - case ExternalLevelCrossingSystemMessageType.TrackRelatedProlongActivationCommand: - return ExternalLevelCrossingSystemTrackRelatedProlongActivationCommand.Parse(senderId, receiverId, message); - case ExternalLevelCrossingSystemMessageType.CrossingClearCommand: - return ExternalLevelCrossingSystemCrossingClearCommand.Parse(senderId, receiverId, message); - case ExternalLevelCrossingSystemMessageType.BlockLxCommand: - return ExternalLevelCrossingSystemBlockLxCommand.Parse(senderId, receiverId, message); - case ExternalLevelCrossingSystemMessageType.TrackRelatedIsolationCommand: - return ExternalLevelCrossingSystemTrackRelatedIsolationCommand.Parse(senderId, receiverId, message); - case ExternalLevelCrossingSystemMessageType.LxFunctionalStatusMessage: - return ExternalLevelCrossingSystemLxFunctionalStatusMessage.Parse(senderId, receiverId, message); - case ExternalLevelCrossingSystemMessageType.TrFunctionalStatusMessage: - return ExternalLevelCrossingSystemTrFunctionalStatusMessage.Parse(senderId, receiverId, message); - case ExternalLevelCrossingSystemMessageType.ObstacleDetectionStatusMessage: - return ExternalLevelCrossingSystemObstacleDetectionStatusMessage.Parse(senderId, receiverId, message); - case ExternalLevelCrossingSystemMessageType.DetectionElementStatusMessage: - return ExternalLevelCrossingSystemDetectionElementStatusMessage.Parse(senderId, receiverId, message); - case ExternalLevelCrossingSystemMessageType.LxMonitoringStatusMessage: - return ExternalLevelCrossingSystemLxMonitoringStatusMessage.Parse(senderId, receiverId, message); - case ExternalLevelCrossingSystemMessageType.TrMonitoringStatusMessage: - return ExternalLevelCrossingSystemTrMonitoringStatusMessage.Parse(senderId, receiverId, message); - case ExternalLevelCrossingSystemMessageType.LxFailureStatusMessage: - return ExternalLevelCrossingSystemLxFailureStatusMessage.Parse(senderId, receiverId, message); - case ExternalLevelCrossingSystemMessageType.TrFailureStatusMessage: - return ExternalLevelCrossingSystemTrFailureStatusMessage.Parse(senderId, receiverId, message); - case ExternalLevelCrossingSystemMessageType.TrackRelatedCommandAdmissabilityMessage: - return ExternalLevelCrossingSystemTrackRelatedCommandAdmissabilityMessage.Parse(senderId, receiverId, message); - case ExternalLevelCrossingSystemMessageType.LxCommandAdmissibilityMessage: - return ExternalLevelCrossingSystemLxCommandAdmissibilityMessage.Parse(senderId, receiverId, message); - case ExternalLevelCrossingSystemMessageType.StatusOfActivationPointMessage: - return ExternalLevelCrossingSystemStatusOfActivationPointMessage.Parse(senderId, receiverId, message); - case ExternalLevelCrossingSystemMessageType.InitializationRequest: - return ExternalLevelCrossingSystemInitializationRequestMessage.Parse(senderId, receiverId, message); - case ExternalLevelCrossingSystemMessageType.StartInitialization: - return ExternalLevelCrossingSystemStartInitializationMessage.Parse(senderId, receiverId, message); - case ExternalLevelCrossingSystemMessageType.InitializationCompleted: - return ExternalLevelCrossingSystemInitializationCompletedMessage.Parse(senderId, receiverId, message); - case ExternalLevelCrossingSystemMessageType.VersionCheckCommand: - return ExternalLevelCrossingSystemVersionCheckCommand.Parse(senderId, receiverId, message); - case ExternalLevelCrossingSystemMessageType.VersionCheckMessage: - return ExternalLevelCrossingSystemVersionCheckMessage.Parse(senderId, receiverId, message); - case ExternalLevelCrossingSystemMessageType.PDIAvailable: - return ExternalLevelCrossingSystemPDIAvailableMessage.Parse(senderId, receiverId, message); - case ExternalLevelCrossingSystemMessageType.PDINotAvailable: - return ExternalLevelCrossingSystemPDINotAvailableMessage.Parse(senderId, receiverId, message); - } - break; - } - - throw new ArgumentException("Invalid EULYNX message: " + BitConverter.ToString(message)); - } - - public byte[] ToByteArray() - { - var bytes = new byte[Size]; - bytes[PROTOCOL_TYPE_OFFSET] = (byte)ProtocolType; - bytes[MESSAGE_TYPE_OFFSET] = (byte)MessageTypeRaw; - bytes[MESSAGE_TYPE_OFFSET + 1] = (byte)(MessageTypeRaw >> 8); - Encoding.UTF8.GetBytes(SenderId.PadRight(20, '_')).CopyTo(bytes, SENDER_IDENTIFIER_OFFSET); - Encoding.UTF8.GetBytes(ReceiverId.PadRight(20, '_')).CopyTo(bytes, RECEIVER_IDENTIFIER_OFFSET); - - WritePayloadToByteArray(bytes); - - return bytes; - } - - protected abstract void WritePayloadToByteArray(byte[] bytes); - } -} +using System; +using System.Text; + +namespace EulynxLive.Messages.Deprecated +{ + public abstract class EulynxMessage + { + protected const int PROTOCOL_TYPE_OFFSET = 0; + protected const int MESSAGE_TYPE_OFFSET = 1; + protected const int SENDER_IDENTIFIER_OFFSET = 3; + protected const int RECEIVER_IDENTIFIER_OFFSET = 23; + + public virtual ProtocolType ProtocolType { get; } + public abstract ushort MessageTypeRaw { get; } + public string SenderId { get; } + public string ReceiverId { get; } + public abstract int Size { get; } + + public EulynxMessage(string senderId, string receiverId) + { + SenderId = senderId; + ReceiverId = receiverId; + } + + public static EulynxMessage FromBytes(byte[] message) + { + var protocolType = (ProtocolType)message[PROTOCOL_TYPE_OFFSET]; + var messageType = BitConverter.ToUInt16( + new byte[2] { message[MESSAGE_TYPE_OFFSET], message[MESSAGE_TYPE_OFFSET + 1] }); + var senderId = Encoding.UTF8.GetString(message, SENDER_IDENTIFIER_OFFSET, 20); + var receiverId = Encoding.UTF8.GetString(message, RECEIVER_IDENTIFIER_OFFSET, 20); + + switch (protocolType) + { + case ProtocolType.TrainDetectionSystem: + switch ((TrainDetectionSystemMessageType)messageType) + { + case TrainDetectionSystemMessageType.VersionCheckCommand: + return TrainDetectionSystemVersionCheckCommand.Parse(senderId, receiverId, message); + case TrainDetectionSystemMessageType.VersionCheckMessage: + return TrainDetectionSystemVersionCheckMessage.Parse(senderId, receiverId, message); + case TrainDetectionSystemMessageType.PDIAvailable: + return TrainDetectionSystemPDIAvailableMessage.Parse(senderId, receiverId, message); + case TrainDetectionSystemMessageType.PDINotAvailable: + return TrainDetectionSystemPDINotAvailableMessage.Parse(senderId, receiverId, message); + case TrainDetectionSystemMessageType.InitializationRequest: + return TrainDetectionSystemInitializationRequestMessage.Parse(senderId, receiverId, message); + case TrainDetectionSystemMessageType.StartInitialization: + return TrainDetectionSystemStartInitializationMessage.Parse(senderId, receiverId, message); + case TrainDetectionSystemMessageType.InitializationCompleted: + return TrainDetectionSystemInitializationCompletedMessage.Parse(senderId, receiverId, message); + case TrainDetectionSystemMessageType.ForceClearCommand: + return TrainDetectionSystemForceClearCommand.Parse(senderId, receiverId, message); + case TrainDetectionSystemMessageType.UpdateFillingLevelCommand: + return TrainDetectionSystemUpdateFillingLevelCommand.Parse(senderId, receiverId, message); + case TrainDetectionSystemMessageType.DRFCCommand: + return TrainDetectionSystemDRFCCommand.Parse(senderId, receiverId, message); + case TrainDetectionSystemMessageType.TDPActivationCommand: + return TrainDetectionSystemTDPActivationCommand.Parse(senderId, receiverId, message); + case TrainDetectionSystemMessageType.TvpsOccupancyStatusMessage: + if (message.Length == 45) { + return TrainDetectionSystemTvpsOccupancyStatusMessageNeuPro.Parse(senderId, receiverId, message); + } else if (message.Length == 47) { + return TrainDetectionSystemTvpsOccupancyStatusMessageNeuProThales.Parse(senderId, receiverId, message); + } else if (message.Length == 48) { + return TrainDetectionSystemTvpsOccupancyStatusMessage.Parse(senderId, receiverId, message); + } + break; + case TrainDetectionSystemMessageType.CommandRejectedMessage: + return TrainDetectionSystemCommandRejectedMessage.Parse(senderId, receiverId, message); + case TrainDetectionSystemMessageType.DRFCReceiptMessage: + return TrainDetectionSystemDRFCReceiptMessage.Parse(senderId, receiverId, message); + case TrainDetectionSystemMessageType.TvpsFCPFailedMessage: + return TrainDetectionSystemTvpsFCPFailedMessage.Parse(senderId, receiverId, message); + case TrainDetectionSystemMessageType.TvpsFCPAFailedMessage: + return TrainDetectionSystemTvpsFCPAFailedMessage.Parse(senderId, receiverId, message); + case TrainDetectionSystemMessageType.AdditionalInformationMessage: + return TrainDetectionSystemAdditionalInformationMessage.Parse(senderId, receiverId, message); + case TrainDetectionSystemMessageType.TDPStatusMessage: + return TrainDetectionSystemTDPStatusMessage.Parse(senderId, receiverId, message); + } + break; + case ProtocolType.LightSignal: + switch ((LightSignalMessageType)messageType) + { + case LightSignalMessageType.IndicateSignalAspect: + return LightSignalIndicateSignalAspectCommand.Parse(senderId, receiverId, message); + case LightSignalMessageType.IndicatedSignalAspect: + return LightSignalIndicatedSignalAspectMessage.Parse(senderId, receiverId, message); + case LightSignalMessageType.VersionCheckCommand: + return LightSignalVersionCheckCommand.Parse(senderId, receiverId, message); + case LightSignalMessageType.VersionCheckMessage: + return LightSignalVersionCheckMessage.Parse(senderId, receiverId, message); + case LightSignalMessageType.PDIAvailable: + return LightSignalPDIAvailableMessage.Parse(senderId, receiverId, message); + case LightSignalMessageType.PDINotAvailable: + return LightSignalPDINotAvailableMessage.Parse(senderId, receiverId, message); + case LightSignalMessageType.InitializationRequest: + return LightSignalInitializationRequestMessage.Parse(senderId, receiverId, message); + case LightSignalMessageType.StartInitialization: + return LightSignalStartInitializationMessage.Parse(senderId, receiverId, message); + case LightSignalMessageType.InitializationCompleted: + return LightSignalInitializationCompletedMessage.Parse(senderId, receiverId, message); + case LightSignalMessageType.SetLuminosityMessage: + return LightSignalSetLuminosityMessage.Parse(senderId, receiverId, message); + // Work in progress: + case LightSignalMessageType.SetLuminosityCommand: + throw new NotImplementedException(); + // return LightSignalSetLuminosityCommand.Parse(senderId, receiverId, message); + } + break; + case ProtocolType.Point: + switch ((PointMessageType)messageType) + { + case PointMessageType.MovePointCommand: + return PointMovePointCommand.Parse(senderId, receiverId, message); + case PointMessageType.PointPositionMessage: + return PointPositionMessage.Parse(senderId, receiverId, message); + case PointMessageType.TimeoutMessage: + return PointTimeoutMessage.Parse(senderId, receiverId, message); + case PointMessageType.VersionCheckCommand: + return PointVersionCheckCommand.Parse(senderId, receiverId, message); + case PointMessageType.VersionCheckMessage: + return PointVersionCheckMessage.Parse(senderId, receiverId, message); + case PointMessageType.PDIAvailable: + return PointPDIAvailableMessage.Parse(senderId, receiverId, message); + case PointMessageType.PDINotAvailable: + return PointPDINotAvailableMessage.Parse(senderId, receiverId, message); + case PointMessageType.InitializationRequest: + return PointInitializationRequestMessage.Parse(senderId, receiverId, message); + case PointMessageType.StartInitialization: + return PointStartInitializationMessage.Parse(senderId, receiverId, message); + case PointMessageType.InitializationCompleted: + return PointInitializationCompletedMessage.Parse(senderId, receiverId, message); + } + break; + case ProtocolType.LevelCrossing: + // NeuPro + switch ((NeuPro.LevelCrossingMessageType)messageType) { + case NeuPro.LevelCrossingMessageType.AnFsüCommand: + return NeuPro.AnFsüCommand.Parse(senderId, receiverId, message); + case NeuPro.LevelCrossingMessageType.AusFsüCommand: + return NeuPro.AusFsüCommand.Parse(senderId, receiverId, message); + case NeuPro.LevelCrossingMessageType.MeldungZustandGleisbezogenMessage: + return NeuPro.MeldungZustandGleisbezogenMessage.Parse(senderId, receiverId, message); + case NeuPro.LevelCrossingMessageType.MeldungZustandBüBezogenMessage: + return NeuPro.MeldungZustandBüBezogenMessage.Parse(senderId, receiverId, message); + + case NeuPro.LevelCrossingMessageType.InitializationRequest: + return NeuPro.LevelCrossingInitializationRequestMessage.Parse(senderId, receiverId, message); + case NeuPro.LevelCrossingMessageType.StartInitialization: + return NeuPro.LevelCrossingStartInitializationMessage.Parse(senderId, receiverId, message); + case NeuPro.LevelCrossingMessageType.InitializationCompleted: + return NeuPro.LevelCrossingInitializationCompletedMessage.Parse(senderId, receiverId, message); + case NeuPro.LevelCrossingMessageType.VersionCheckCommand: + return NeuPro.LevelCrossingVersionCheckCommand.Parse(senderId, receiverId, message); + case NeuPro.LevelCrossingMessageType.VersionCheckMessage: + return NeuPro.LevelCrossingVersionCheckMessage.Parse(senderId, receiverId, message); + // Not sure if these exist: + case NeuPro.LevelCrossingMessageType.PDIAvailable: + return NeuPro.LevelCrossingPDIAvailableMessage.Parse(senderId, receiverId, message); + case NeuPro.LevelCrossingMessageType.PDINotAvailable: + return NeuPro.LevelCrossingPDINotAvailableMessage.Parse(senderId, receiverId, message); + } + break; + case ProtocolType.ExternalLevelCrossingSystem: + switch ((ExternalLevelCrossingSystemMessageType)messageType) { + case ExternalLevelCrossingSystemMessageType.LxActivationCommand: + return ExternalLevelCrossingSystemLxActivationCommand.Parse(senderId, receiverId, message); + case ExternalLevelCrossingSystemMessageType.TrActivationCommand: + return ExternalLevelCrossingSystemTrActivationCommand.Parse(senderId, receiverId, message); + case ExternalLevelCrossingSystemMessageType.LxDeactivationCommand: + return ExternalLevelCrossingSystemLxDeactivationCommand.Parse(senderId, receiverId, message); + case ExternalLevelCrossingSystemMessageType.TrDeactivationCommand: + return ExternalLevelCrossingSystemTrDeactivationCommand.Parse(senderId, receiverId, message); + case ExternalLevelCrossingSystemMessageType.ControlActivationPointCommand: + return ExternalLevelCrossingSystemControlActivationPointCommand.Parse(senderId, receiverId, message); + case ExternalLevelCrossingSystemMessageType.TrackRelatedProlongActivationCommand: + return ExternalLevelCrossingSystemTrackRelatedProlongActivationCommand.Parse(senderId, receiverId, message); + case ExternalLevelCrossingSystemMessageType.CrossingClearCommand: + return ExternalLevelCrossingSystemCrossingClearCommand.Parse(senderId, receiverId, message); + case ExternalLevelCrossingSystemMessageType.BlockLxCommand: + return ExternalLevelCrossingSystemBlockLxCommand.Parse(senderId, receiverId, message); + case ExternalLevelCrossingSystemMessageType.TrackRelatedIsolationCommand: + return ExternalLevelCrossingSystemTrackRelatedIsolationCommand.Parse(senderId, receiverId, message); + case ExternalLevelCrossingSystemMessageType.LxFunctionalStatusMessage: + return ExternalLevelCrossingSystemLxFunctionalStatusMessage.Parse(senderId, receiverId, message); + case ExternalLevelCrossingSystemMessageType.TrFunctionalStatusMessage: + return ExternalLevelCrossingSystemTrFunctionalStatusMessage.Parse(senderId, receiverId, message); + case ExternalLevelCrossingSystemMessageType.ObstacleDetectionStatusMessage: + return ExternalLevelCrossingSystemObstacleDetectionStatusMessage.Parse(senderId, receiverId, message); + case ExternalLevelCrossingSystemMessageType.DetectionElementStatusMessage: + return ExternalLevelCrossingSystemDetectionElementStatusMessage.Parse(senderId, receiverId, message); + case ExternalLevelCrossingSystemMessageType.LxMonitoringStatusMessage: + return ExternalLevelCrossingSystemLxMonitoringStatusMessage.Parse(senderId, receiverId, message); + case ExternalLevelCrossingSystemMessageType.TrMonitoringStatusMessage: + return ExternalLevelCrossingSystemTrMonitoringStatusMessage.Parse(senderId, receiverId, message); + case ExternalLevelCrossingSystemMessageType.LxFailureStatusMessage: + return ExternalLevelCrossingSystemLxFailureStatusMessage.Parse(senderId, receiverId, message); + case ExternalLevelCrossingSystemMessageType.TrFailureStatusMessage: + return ExternalLevelCrossingSystemTrFailureStatusMessage.Parse(senderId, receiverId, message); + case ExternalLevelCrossingSystemMessageType.TrackRelatedCommandAdmissabilityMessage: + return ExternalLevelCrossingSystemTrackRelatedCommandAdmissabilityMessage.Parse(senderId, receiverId, message); + case ExternalLevelCrossingSystemMessageType.LxCommandAdmissibilityMessage: + return ExternalLevelCrossingSystemLxCommandAdmissibilityMessage.Parse(senderId, receiverId, message); + case ExternalLevelCrossingSystemMessageType.StatusOfActivationPointMessage: + return ExternalLevelCrossingSystemStatusOfActivationPointMessage.Parse(senderId, receiverId, message); + case ExternalLevelCrossingSystemMessageType.InitializationRequest: + return ExternalLevelCrossingSystemInitializationRequestMessage.Parse(senderId, receiverId, message); + case ExternalLevelCrossingSystemMessageType.StartInitialization: + return ExternalLevelCrossingSystemStartInitializationMessage.Parse(senderId, receiverId, message); + case ExternalLevelCrossingSystemMessageType.InitializationCompleted: + return ExternalLevelCrossingSystemInitializationCompletedMessage.Parse(senderId, receiverId, message); + case ExternalLevelCrossingSystemMessageType.VersionCheckCommand: + return ExternalLevelCrossingSystemVersionCheckCommand.Parse(senderId, receiverId, message); + case ExternalLevelCrossingSystemMessageType.VersionCheckMessage: + return ExternalLevelCrossingSystemVersionCheckMessage.Parse(senderId, receiverId, message); + case ExternalLevelCrossingSystemMessageType.PDIAvailable: + return ExternalLevelCrossingSystemPDIAvailableMessage.Parse(senderId, receiverId, message); + case ExternalLevelCrossingSystemMessageType.PDINotAvailable: + return ExternalLevelCrossingSystemPDINotAvailableMessage.Parse(senderId, receiverId, message); + } + break; + } + + throw new ArgumentException("Invalid EULYNX message: " + BitConverter.ToString(message)); + } + + public byte[] ToByteArray() + { + var bytes = new byte[Size]; + bytes[PROTOCOL_TYPE_OFFSET] = (byte)ProtocolType; + bytes[MESSAGE_TYPE_OFFSET] = (byte)MessageTypeRaw; + bytes[MESSAGE_TYPE_OFFSET + 1] = (byte)(MessageTypeRaw >> 8); + Encoding.UTF8.GetBytes(SenderId.PadRight(20, '_')).CopyTo(bytes, SENDER_IDENTIFIER_OFFSET); + Encoding.UTF8.GetBytes(ReceiverId.PadRight(20, '_')).CopyTo(bytes, RECEIVER_IDENTIFIER_OFFSET); + + WritePayloadToByteArray(bytes); + + return bytes; + } + + protected abstract void WritePayloadToByteArray(byte[] bytes); + } +} diff --git a/src/Messages/ExternalLevelCrossingSystemMessage.cs b/src/Messages/Deprecated/ExternalLevelCrossingSystemMessage.cs similarity index 97% rename from src/Messages/ExternalLevelCrossingSystemMessage.cs rename to src/Messages/Deprecated/ExternalLevelCrossingSystemMessage.cs index 309b60f..a119b3d 100644 --- a/src/Messages/ExternalLevelCrossingSystemMessage.cs +++ b/src/Messages/Deprecated/ExternalLevelCrossingSystemMessage.cs @@ -1,610 +1,610 @@ -namespace EulynxLive.Messages -{ - public enum ExternalLevelCrossingSystemMessageType: ushort { - // Commands - LxActivationCommand = 0x0001, - TrActivationCommand = 0x0002, - LxDeactivationCommand = 0x0003, - TrDeactivationCommand = 0x0004, - ControlActivationPointCommand = 0x0005, - TrackRelatedProlongActivationCommand = 0x0006, - CrossingClearCommand = 0x0007, - BlockLxCommand = 0x0008, - TrackRelatedIsolationCommand = 0x0009, - - // Messages - LxFunctionalStatusMessage = 0x0010, - TrFunctionalStatusMessage = 0x0011, - ObstacleDetectionStatusMessage = 0x0012, - DetectionElementStatusMessage = 0x0013, - LxMonitoringStatusMessage = 0x0014, - TrMonitoringStatusMessage = 0x0015, - LxFailureStatusMessage = 0x0016, - TrFailureStatusMessage = 0x0017, - TrackRelatedCommandAdmissabilityMessage = 0x0018, - LxCommandAdmissibilityMessage = 0x0019, - StatusOfActivationPointMessage = 0x0020, - - // Generic - InitializationRequest = 0x0021, - StartInitialization = 0x0022, - InitializationCompleted = 0x0023, - VersionCheckCommand = 0x0024, - VersionCheckMessage = 0x0025, - PDIAvailable = 0x0029, - PDINotAvailable = 0x002A, - } - - public abstract class ExternalLevelCrossingSystemMessage : EulynxMessage - { - public ExternalLevelCrossingSystemMessage(string senderId, string receiverId) : base(senderId, receiverId) - {} - - public override ProtocolType ProtocolType => ProtocolType.ExternalLevelCrossingSystem; - public override ushort MessageTypeRaw => (ushort) MessageType; - public abstract ExternalLevelCrossingSystemMessageType MessageType { get; } - } - - public class ExternalLevelCrossingSystemLxActivationCommand : ExternalLevelCrossingSystemMessage - { - public ExternalLevelCrossingSystemLxActivationCommand(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.LxActivationCommand; - - public override int Size => 44; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new ExternalLevelCrossingSystemLxActivationCommand(senderId, receiverId); - - protected override void WritePayloadToByteArray(byte[] bytes) - { - } - } - - public class ExternalLevelCrossingSystemTrActivationCommand : ExternalLevelCrossingSystemMessage - { - public ExternalLevelCrossingSystemTrActivationCommand(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.TrActivationCommand; - - public override int Size => 45; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new ExternalLevelCrossingSystemTrActivationCommand(senderId, receiverId); - - protected override void WritePayloadToByteArray(byte[] bytes) - { - } - } - - public class ExternalLevelCrossingSystemLxDeactivationCommand : ExternalLevelCrossingSystemMessage - { - public ExternalLevelCrossingSystemLxDeactivationCommand(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.LxDeactivationCommand; - - public override int Size => 44; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new ExternalLevelCrossingSystemLxDeactivationCommand(senderId, receiverId); - - protected override void WritePayloadToByteArray(byte[] bytes) - { - } - } - - public class ExternalLevelCrossingSystemTrDeactivationCommand : ExternalLevelCrossingSystemMessage - { - public ExternalLevelCrossingSystemTrDeactivationCommand(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.TrDeactivationCommand; - - public override int Size => 45; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new ExternalLevelCrossingSystemTrDeactivationCommand(senderId, receiverId); - - protected override void WritePayloadToByteArray(byte[] bytes) - { - } - } - - public class ExternalLevelCrossingSystemControlActivationPointCommand : ExternalLevelCrossingSystemMessage - { - public ExternalLevelCrossingSystemControlActivationPointCommand(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.ControlActivationPointCommand; - - public override int Size => 46; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new ExternalLevelCrossingSystemControlActivationPointCommand(senderId, receiverId); - - protected override void WritePayloadToByteArray(byte[] bytes) - { - } - } - - public class ExternalLevelCrossingSystemTrackRelatedProlongActivationCommand : ExternalLevelCrossingSystemMessage - { - public ExternalLevelCrossingSystemTrackRelatedProlongActivationCommand(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.TrackRelatedProlongActivationCommand; - - public override int Size => 45; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new ExternalLevelCrossingSystemTrackRelatedProlongActivationCommand(senderId, receiverId); - - protected override void WritePayloadToByteArray(byte[] bytes) - { - } - } - - public class ExternalLevelCrossingSystemCrossingClearCommand : ExternalLevelCrossingSystemMessage - { - public ExternalLevelCrossingSystemCrossingClearCommand(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.CrossingClearCommand; - - public override int Size => 43; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new ExternalLevelCrossingSystemCrossingClearCommand(senderId, receiverId); - - protected override void WritePayloadToByteArray(byte[] bytes) - { - } - } - - public class ExternalLevelCrossingSystemBlockLxCommand : ExternalLevelCrossingSystemMessage - { - public ExternalLevelCrossingSystemBlockLxCommand(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.BlockLxCommand; - - public override int Size => 44; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new ExternalLevelCrossingSystemBlockLxCommand(senderId, receiverId); - - protected override void WritePayloadToByteArray(byte[] bytes) - { - } - } - - public class ExternalLevelCrossingSystemTrackRelatedIsolationCommand : ExternalLevelCrossingSystemMessage - { - public ExternalLevelCrossingSystemTrackRelatedIsolationCommand(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.TrackRelatedIsolationCommand; - - public override int Size => 44; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new ExternalLevelCrossingSystemTrackRelatedIsolationCommand(senderId, receiverId); - - protected override void WritePayloadToByteArray(byte[] bytes) - { - } - } - - public enum LxActivationStatus : byte { - DeactivatedAndUnprotected = 0x1, - ActivatedAndUnprotected = 0x2, - ActivatedAndProtected = 0x3 - } - - public enum LxActivationType : byte { - UnconditionalActivation = 0x1, - LocalActivationForShunting = 0x2, - } - - public enum LxBlockedForActivation : byte { - BlockedForActivation = 0x1, - NotBlockedForActivation = 0x2, - NotApplicable = 0x3, - } - - public enum LxBlockedForDeactivation : byte { - NotBlockedForDeactivation = 0x1, - BlockedForDeactivation = 0x2, - NotApplicable = 0x3, - } - - public enum LxMinimumOpenTimer : byte { - TimerNotRunning = 0x1, - TimerRunning = 0x2, - NotApplicable = 0x3, - } - - public class ExternalLevelCrossingSystemLxFunctionalStatusMessage : ExternalLevelCrossingSystemMessage - { - private const int ACTIVATION_STATUS_OFFSET = 43; - private const int ACTIVATION_TYPE_OFFSET = 44; - private const int BLOCKED_FOR_ACTIVATION_OFFSET = 45; - private const int BLOCKED_FOR_DEACTIVATION_OFFSET = 46; - private const int MINIMUM_OPEN_TIMER_OFFSET = 47; - - public ExternalLevelCrossingSystemLxFunctionalStatusMessage(string senderId, string receiverId, LxActivationStatus activationStatus, LxActivationType activationType, LxBlockedForActivation blockedForActivation, LxBlockedForDeactivation blockedForDeactivation, LxMinimumOpenTimer minimumOpenTimer) : base(senderId, receiverId) - { - ActivationStatus = activationStatus; - ActivationType = activationType; - BlockedForActivation = blockedForActivation; - BlockedForDeactivation = blockedForDeactivation; - MinimumOpenTimer = minimumOpenTimer; - } - - public LxActivationStatus ActivationStatus { get; } - - public LxActivationType ActivationType { get; } - - public LxBlockedForActivation BlockedForActivation { get; } - - public LxBlockedForDeactivation BlockedForDeactivation { get; } - - public LxMinimumOpenTimer MinimumOpenTimer { get; } - - public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.LxFunctionalStatusMessage; - - public override int Size => 48; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) - { - var activationStatus = (LxActivationStatus) message[ACTIVATION_STATUS_OFFSET]; - var activationType = (LxActivationType) message[ACTIVATION_TYPE_OFFSET]; - var blockedForActivation = (LxBlockedForActivation) message[BLOCKED_FOR_ACTIVATION_OFFSET]; - var blockedForDeactivation = (LxBlockedForDeactivation) message[BLOCKED_FOR_DEACTIVATION_OFFSET]; - var minimumOpenTimer = (LxMinimumOpenTimer) message[MINIMUM_OPEN_TIMER_OFFSET]; - - return new ExternalLevelCrossingSystemLxFunctionalStatusMessage(senderId, receiverId, activationStatus, activationType, blockedForActivation, blockedForDeactivation, minimumOpenTimer); - } - - protected override void WritePayloadToByteArray(byte[] bytes) - { - bytes[ACTIVATION_STATUS_OFFSET] = (byte)ActivationStatus; - bytes[ACTIVATION_TYPE_OFFSET] = (byte)ActivationType; - bytes[BLOCKED_FOR_ACTIVATION_OFFSET] = (byte)BlockedForActivation; - bytes[BLOCKED_FOR_DEACTIVATION_OFFSET] = (byte)BlockedForDeactivation; - bytes[MINIMUM_OPEN_TIMER_OFFSET] = (byte)MinimumOpenTimer; - } - } - - public class ExternalLevelCrossingSystemTrFunctionalStatusMessage : ExternalLevelCrossingSystemMessage - { - public ExternalLevelCrossingSystemTrFunctionalStatusMessage(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.TrFunctionalStatusMessage; - - public override int Size => 51; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new ExternalLevelCrossingSystemTrFunctionalStatusMessage(senderId, receiverId); - - protected override void WritePayloadToByteArray(byte[] bytes) - { - } - } - - public class ExternalLevelCrossingSystemObstacleDetectionStatusMessage : ExternalLevelCrossingSystemMessage - { - public ExternalLevelCrossingSystemObstacleDetectionStatusMessage(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.ObstacleDetectionStatusMessage; - - public override int Size => 44; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new ExternalLevelCrossingSystemObstacleDetectionStatusMessage(senderId, receiverId); - - protected override void WritePayloadToByteArray(byte[] bytes) - { - } - } - - public class ExternalLevelCrossingSystemDetectionElementStatusMessage : ExternalLevelCrossingSystemMessage - { - public ExternalLevelCrossingSystemDetectionElementStatusMessage(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.DetectionElementStatusMessage; - - // TODO: Dynamic size based on number of detection elements, here: k=0 - public override int Size => 44; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new ExternalLevelCrossingSystemDetectionElementStatusMessage(senderId, receiverId); - - protected override void WritePayloadToByteArray(byte[] bytes) - { - } - } - - public class ExternalLevelCrossingSystemLxMonitoringStatusMessage : ExternalLevelCrossingSystemMessage - { - public ExternalLevelCrossingSystemLxMonitoringStatusMessage(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.LxMonitoringStatusMessage; - - public override int Size => 49; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new ExternalLevelCrossingSystemLxMonitoringStatusMessage(senderId, receiverId); - - protected override void WritePayloadToByteArray(byte[] bytes) - { - } - } - - public class ExternalLevelCrossingSystemTrMonitoringStatusMessage : ExternalLevelCrossingSystemMessage - { - public ExternalLevelCrossingSystemTrMonitoringStatusMessage(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.TrMonitoringStatusMessage; - - public override int Size => 46; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new ExternalLevelCrossingSystemTrMonitoringStatusMessage(senderId, receiverId); - - protected override void WritePayloadToByteArray(byte[] bytes) - { - } - } - - public class ExternalLevelCrossingSystemLxFailureStatusMessage : ExternalLevelCrossingSystemMessage - { - public ExternalLevelCrossingSystemLxFailureStatusMessage(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.LxFailureStatusMessage; - - public override int Size => 45; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new ExternalLevelCrossingSystemLxFailureStatusMessage(senderId, receiverId); - - protected override void WritePayloadToByteArray(byte[] bytes) - { - } - } - - public class ExternalLevelCrossingSystemTrFailureStatusMessage : ExternalLevelCrossingSystemMessage - { - public ExternalLevelCrossingSystemTrFailureStatusMessage(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.TrFailureStatusMessage; - - public override int Size => 45; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new ExternalLevelCrossingSystemTrFailureStatusMessage(senderId, receiverId); - - protected override void WritePayloadToByteArray(byte[] bytes) - { - } - } - - public class ExternalLevelCrossingSystemTrackRelatedCommandAdmissabilityMessage : ExternalLevelCrossingSystemMessage - { - public ExternalLevelCrossingSystemTrackRelatedCommandAdmissabilityMessage(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.TrackRelatedCommandAdmissabilityMessage; - - public override int Size => 49; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new ExternalLevelCrossingSystemTrackRelatedCommandAdmissabilityMessage(senderId, receiverId); - - protected override void WritePayloadToByteArray(byte[] bytes) - { - } - } - - public class ExternalLevelCrossingSystemLxCommandAdmissibilityMessage : ExternalLevelCrossingSystemMessage - { - public ExternalLevelCrossingSystemLxCommandAdmissibilityMessage(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.LxCommandAdmissibilityMessage; - - public override int Size => 47; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new ExternalLevelCrossingSystemLxCommandAdmissibilityMessage(senderId, receiverId); - - protected override void WritePayloadToByteArray(byte[] bytes) - { - } - } - - public class ExternalLevelCrossingSystemStatusOfActivationPointMessage : ExternalLevelCrossingSystemMessage - { - public ExternalLevelCrossingSystemStatusOfActivationPointMessage(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.StatusOfActivationPointMessage; - - // TODO: dynamic size based on number k of activation points, here k=0 - public override int Size => 44; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new ExternalLevelCrossingSystemStatusOfActivationPointMessage(senderId, receiverId); - - protected override void WritePayloadToByteArray(byte[] bytes) - { - } - } - - public class ExternalLevelCrossingSystemVersionCheckCommand : ExternalLevelCrossingSystemMessage - { - private const int SENDER_PDI_VERSION_OFFSET = 43; - public ExternalLevelCrossingSystemVersionCheckCommand(string senderId, string receiverId, byte senderPdiVersion) : base(senderId, receiverId) - { - SenderPdiVersion = senderPdiVersion; - } - - public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.VersionCheckCommand; - - public byte SenderPdiVersion { get; } - - public override int Size => 44; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new ExternalLevelCrossingSystemVersionCheckCommand(senderId, receiverId, message[SENDER_PDI_VERSION_OFFSET]); - - protected override void WritePayloadToByteArray(byte[] bytes) - { - bytes[SENDER_PDI_VERSION_OFFSET] = SenderPdiVersion; - } - } - - public class ExternalLevelCrossingSystemVersionCheckMessage : ExternalLevelCrossingSystemMessage - { - private const int RESULT_PDI_VERSION_CHECK_OFFSET = 43; - private const int SENDER_PDI_VERSION_OFFSET = 44; - private const int CHECKSUM_LENGTH_OFFSET = 45; - private const int CHECKSUM_DATA_OFFSET = 46; - public ExternalLevelCrossingSystemVersionCheckMessage(string senderId, string receiverId, PdiVersionCheckResult resultPdiVersionCheck, byte senderPdiVersion, byte checksumLength) : base(senderId, receiverId) - { - ResultPdiVersionCheck = resultPdiVersionCheck; - SenderPdiVersion = senderPdiVersion; - ChecksumLength = checksumLength; - } - - public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.VersionCheckMessage; - - public PdiVersionCheckResult ResultPdiVersionCheck { get; } - public byte SenderPdiVersion { get; } - public byte ChecksumLength { get; } - - public override int Size => 46 + ChecksumLength; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) { - var resultPdiVersionCheck = (PdiVersionCheckResult) message[RESULT_PDI_VERSION_CHECK_OFFSET]; - var senderPdiVersion = message[SENDER_PDI_VERSION_OFFSET]; - var checksumLength = message[CHECKSUM_LENGTH_OFFSET]; - // var CHECKSUM_DATA_OFFSET = message[CHECKSUM_DATA_OFFSET]; - return new ExternalLevelCrossingSystemVersionCheckMessage(senderId, receiverId, resultPdiVersionCheck, senderPdiVersion, checksumLength); - } - - protected override void WritePayloadToByteArray(byte[] bytes) - { - bytes[RESULT_PDI_VERSION_CHECK_OFFSET] = (byte)ResultPdiVersionCheck; - bytes[SENDER_PDI_VERSION_OFFSET] = SenderPdiVersion; - bytes[CHECKSUM_LENGTH_OFFSET] = ChecksumLength; - } - } - - public class ExternalLevelCrossingSystemPDIAvailableMessage : ExternalLevelCrossingSystemMessage - { - public ExternalLevelCrossingSystemPDIAvailableMessage(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.PDIAvailable; - - public byte SenderPdiVersion { get; } - - public override int Size => 43; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new ExternalLevelCrossingSystemPDIAvailableMessage(senderId, receiverId); - - protected override void WritePayloadToByteArray(byte[] bytes) - { - } - } - - public class ExternalLevelCrossingSystemPDINotAvailableMessage : ExternalLevelCrossingSystemMessage - { - public ExternalLevelCrossingSystemPDINotAvailableMessage(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.PDINotAvailable; - - public byte SenderPdiVersion { get; } - - public override int Size => 43; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new ExternalLevelCrossingSystemPDINotAvailableMessage(senderId, receiverId); - - protected override void WritePayloadToByteArray(byte[] bytes) - { - } - } - - public class ExternalLevelCrossingSystemInitializationRequestMessage : ExternalLevelCrossingSystemMessage - { - public ExternalLevelCrossingSystemInitializationRequestMessage(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.InitializationRequest; - - public override int Size => 43; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) - { - return new ExternalLevelCrossingSystemInitializationRequestMessage(senderId, receiverId); - } - - protected override void WritePayloadToByteArray(byte[] bytes) - { - } - } - - public class ExternalLevelCrossingSystemStartInitializationMessage : ExternalLevelCrossingSystemMessage - { - public ExternalLevelCrossingSystemStartInitializationMessage(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.StartInitialization; - - public override int Size => 43; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) - { - return new ExternalLevelCrossingSystemStartInitializationMessage(senderId, receiverId); - } - - protected override void WritePayloadToByteArray(byte[] bytes) - { - } - } - - public class ExternalLevelCrossingSystemInitializationCompletedMessage : ExternalLevelCrossingSystemMessage - { - public ExternalLevelCrossingSystemInitializationCompletedMessage(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.InitializationCompleted; - - public override int Size => 43; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) - { - return new ExternalLevelCrossingSystemInitializationCompletedMessage(senderId, receiverId); - } - - protected override void WritePayloadToByteArray(byte[] bytes) - { - } - } -} +namespace EulynxLive.Messages.Deprecated +{ + public enum ExternalLevelCrossingSystemMessageType: ushort { + // Commands + LxActivationCommand = 0x0001, + TrActivationCommand = 0x0002, + LxDeactivationCommand = 0x0003, + TrDeactivationCommand = 0x0004, + ControlActivationPointCommand = 0x0005, + TrackRelatedProlongActivationCommand = 0x0006, + CrossingClearCommand = 0x0007, + BlockLxCommand = 0x0008, + TrackRelatedIsolationCommand = 0x0009, + + // Messages + LxFunctionalStatusMessage = 0x0010, + TrFunctionalStatusMessage = 0x0011, + ObstacleDetectionStatusMessage = 0x0012, + DetectionElementStatusMessage = 0x0013, + LxMonitoringStatusMessage = 0x0014, + TrMonitoringStatusMessage = 0x0015, + LxFailureStatusMessage = 0x0016, + TrFailureStatusMessage = 0x0017, + TrackRelatedCommandAdmissabilityMessage = 0x0018, + LxCommandAdmissibilityMessage = 0x0019, + StatusOfActivationPointMessage = 0x0020, + + // Generic + InitializationRequest = 0x0021, + StartInitialization = 0x0022, + InitializationCompleted = 0x0023, + VersionCheckCommand = 0x0024, + VersionCheckMessage = 0x0025, + PDIAvailable = 0x0029, + PDINotAvailable = 0x002A, + } + + public abstract class ExternalLevelCrossingSystemMessage : EulynxMessage + { + public ExternalLevelCrossingSystemMessage(string senderId, string receiverId) : base(senderId, receiverId) + {} + + public override ProtocolType ProtocolType => ProtocolType.ExternalLevelCrossingSystem; + public override ushort MessageTypeRaw => (ushort) MessageType; + public abstract ExternalLevelCrossingSystemMessageType MessageType { get; } + } + + public class ExternalLevelCrossingSystemLxActivationCommand : ExternalLevelCrossingSystemMessage + { + public ExternalLevelCrossingSystemLxActivationCommand(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.LxActivationCommand; + + public override int Size => 44; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new ExternalLevelCrossingSystemLxActivationCommand(senderId, receiverId); + + protected override void WritePayloadToByteArray(byte[] bytes) + { + } + } + + public class ExternalLevelCrossingSystemTrActivationCommand : ExternalLevelCrossingSystemMessage + { + public ExternalLevelCrossingSystemTrActivationCommand(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.TrActivationCommand; + + public override int Size => 45; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new ExternalLevelCrossingSystemTrActivationCommand(senderId, receiverId); + + protected override void WritePayloadToByteArray(byte[] bytes) + { + } + } + + public class ExternalLevelCrossingSystemLxDeactivationCommand : ExternalLevelCrossingSystemMessage + { + public ExternalLevelCrossingSystemLxDeactivationCommand(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.LxDeactivationCommand; + + public override int Size => 44; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new ExternalLevelCrossingSystemLxDeactivationCommand(senderId, receiverId); + + protected override void WritePayloadToByteArray(byte[] bytes) + { + } + } + + public class ExternalLevelCrossingSystemTrDeactivationCommand : ExternalLevelCrossingSystemMessage + { + public ExternalLevelCrossingSystemTrDeactivationCommand(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.TrDeactivationCommand; + + public override int Size => 45; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new ExternalLevelCrossingSystemTrDeactivationCommand(senderId, receiverId); + + protected override void WritePayloadToByteArray(byte[] bytes) + { + } + } + + public class ExternalLevelCrossingSystemControlActivationPointCommand : ExternalLevelCrossingSystemMessage + { + public ExternalLevelCrossingSystemControlActivationPointCommand(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.ControlActivationPointCommand; + + public override int Size => 46; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new ExternalLevelCrossingSystemControlActivationPointCommand(senderId, receiverId); + + protected override void WritePayloadToByteArray(byte[] bytes) + { + } + } + + public class ExternalLevelCrossingSystemTrackRelatedProlongActivationCommand : ExternalLevelCrossingSystemMessage + { + public ExternalLevelCrossingSystemTrackRelatedProlongActivationCommand(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.TrackRelatedProlongActivationCommand; + + public override int Size => 45; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new ExternalLevelCrossingSystemTrackRelatedProlongActivationCommand(senderId, receiverId); + + protected override void WritePayloadToByteArray(byte[] bytes) + { + } + } + + public class ExternalLevelCrossingSystemCrossingClearCommand : ExternalLevelCrossingSystemMessage + { + public ExternalLevelCrossingSystemCrossingClearCommand(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.CrossingClearCommand; + + public override int Size => 43; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new ExternalLevelCrossingSystemCrossingClearCommand(senderId, receiverId); + + protected override void WritePayloadToByteArray(byte[] bytes) + { + } + } + + public class ExternalLevelCrossingSystemBlockLxCommand : ExternalLevelCrossingSystemMessage + { + public ExternalLevelCrossingSystemBlockLxCommand(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.BlockLxCommand; + + public override int Size => 44; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new ExternalLevelCrossingSystemBlockLxCommand(senderId, receiverId); + + protected override void WritePayloadToByteArray(byte[] bytes) + { + } + } + + public class ExternalLevelCrossingSystemTrackRelatedIsolationCommand : ExternalLevelCrossingSystemMessage + { + public ExternalLevelCrossingSystemTrackRelatedIsolationCommand(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.TrackRelatedIsolationCommand; + + public override int Size => 44; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new ExternalLevelCrossingSystemTrackRelatedIsolationCommand(senderId, receiverId); + + protected override void WritePayloadToByteArray(byte[] bytes) + { + } + } + + public enum LxActivationStatus : byte { + DeactivatedAndUnprotected = 0x1, + ActivatedAndUnprotected = 0x2, + ActivatedAndProtected = 0x3 + } + + public enum LxActivationType : byte { + UnconditionalActivation = 0x1, + LocalActivationForShunting = 0x2, + } + + public enum LxBlockedForActivation : byte { + BlockedForActivation = 0x1, + NotBlockedForActivation = 0x2, + NotApplicable = 0x3, + } + + public enum LxBlockedForDeactivation : byte { + NotBlockedForDeactivation = 0x1, + BlockedForDeactivation = 0x2, + NotApplicable = 0x3, + } + + public enum LxMinimumOpenTimer : byte { + TimerNotRunning = 0x1, + TimerRunning = 0x2, + NotApplicable = 0x3, + } + + public class ExternalLevelCrossingSystemLxFunctionalStatusMessage : ExternalLevelCrossingSystemMessage + { + private const int ACTIVATION_STATUS_OFFSET = 43; + private const int ACTIVATION_TYPE_OFFSET = 44; + private const int BLOCKED_FOR_ACTIVATION_OFFSET = 45; + private const int BLOCKED_FOR_DEACTIVATION_OFFSET = 46; + private const int MINIMUM_OPEN_TIMER_OFFSET = 47; + + public ExternalLevelCrossingSystemLxFunctionalStatusMessage(string senderId, string receiverId, LxActivationStatus activationStatus, LxActivationType activationType, LxBlockedForActivation blockedForActivation, LxBlockedForDeactivation blockedForDeactivation, LxMinimumOpenTimer minimumOpenTimer) : base(senderId, receiverId) + { + ActivationStatus = activationStatus; + ActivationType = activationType; + BlockedForActivation = blockedForActivation; + BlockedForDeactivation = blockedForDeactivation; + MinimumOpenTimer = minimumOpenTimer; + } + + public LxActivationStatus ActivationStatus { get; } + + public LxActivationType ActivationType { get; } + + public LxBlockedForActivation BlockedForActivation { get; } + + public LxBlockedForDeactivation BlockedForDeactivation { get; } + + public LxMinimumOpenTimer MinimumOpenTimer { get; } + + public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.LxFunctionalStatusMessage; + + public override int Size => 48; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) + { + var activationStatus = (LxActivationStatus) message[ACTIVATION_STATUS_OFFSET]; + var activationType = (LxActivationType) message[ACTIVATION_TYPE_OFFSET]; + var blockedForActivation = (LxBlockedForActivation) message[BLOCKED_FOR_ACTIVATION_OFFSET]; + var blockedForDeactivation = (LxBlockedForDeactivation) message[BLOCKED_FOR_DEACTIVATION_OFFSET]; + var minimumOpenTimer = (LxMinimumOpenTimer) message[MINIMUM_OPEN_TIMER_OFFSET]; + + return new ExternalLevelCrossingSystemLxFunctionalStatusMessage(senderId, receiverId, activationStatus, activationType, blockedForActivation, blockedForDeactivation, minimumOpenTimer); + } + + protected override void WritePayloadToByteArray(byte[] bytes) + { + bytes[ACTIVATION_STATUS_OFFSET] = (byte)ActivationStatus; + bytes[ACTIVATION_TYPE_OFFSET] = (byte)ActivationType; + bytes[BLOCKED_FOR_ACTIVATION_OFFSET] = (byte)BlockedForActivation; + bytes[BLOCKED_FOR_DEACTIVATION_OFFSET] = (byte)BlockedForDeactivation; + bytes[MINIMUM_OPEN_TIMER_OFFSET] = (byte)MinimumOpenTimer; + } + } + + public class ExternalLevelCrossingSystemTrFunctionalStatusMessage : ExternalLevelCrossingSystemMessage + { + public ExternalLevelCrossingSystemTrFunctionalStatusMessage(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.TrFunctionalStatusMessage; + + public override int Size => 51; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new ExternalLevelCrossingSystemTrFunctionalStatusMessage(senderId, receiverId); + + protected override void WritePayloadToByteArray(byte[] bytes) + { + } + } + + public class ExternalLevelCrossingSystemObstacleDetectionStatusMessage : ExternalLevelCrossingSystemMessage + { + public ExternalLevelCrossingSystemObstacleDetectionStatusMessage(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.ObstacleDetectionStatusMessage; + + public override int Size => 44; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new ExternalLevelCrossingSystemObstacleDetectionStatusMessage(senderId, receiverId); + + protected override void WritePayloadToByteArray(byte[] bytes) + { + } + } + + public class ExternalLevelCrossingSystemDetectionElementStatusMessage : ExternalLevelCrossingSystemMessage + { + public ExternalLevelCrossingSystemDetectionElementStatusMessage(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.DetectionElementStatusMessage; + + // TODO: Dynamic size based on number of detection elements, here: k=0 + public override int Size => 44; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new ExternalLevelCrossingSystemDetectionElementStatusMessage(senderId, receiverId); + + protected override void WritePayloadToByteArray(byte[] bytes) + { + } + } + + public class ExternalLevelCrossingSystemLxMonitoringStatusMessage : ExternalLevelCrossingSystemMessage + { + public ExternalLevelCrossingSystemLxMonitoringStatusMessage(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.LxMonitoringStatusMessage; + + public override int Size => 49; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new ExternalLevelCrossingSystemLxMonitoringStatusMessage(senderId, receiverId); + + protected override void WritePayloadToByteArray(byte[] bytes) + { + } + } + + public class ExternalLevelCrossingSystemTrMonitoringStatusMessage : ExternalLevelCrossingSystemMessage + { + public ExternalLevelCrossingSystemTrMonitoringStatusMessage(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.TrMonitoringStatusMessage; + + public override int Size => 46; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new ExternalLevelCrossingSystemTrMonitoringStatusMessage(senderId, receiverId); + + protected override void WritePayloadToByteArray(byte[] bytes) + { + } + } + + public class ExternalLevelCrossingSystemLxFailureStatusMessage : ExternalLevelCrossingSystemMessage + { + public ExternalLevelCrossingSystemLxFailureStatusMessage(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.LxFailureStatusMessage; + + public override int Size => 45; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new ExternalLevelCrossingSystemLxFailureStatusMessage(senderId, receiverId); + + protected override void WritePayloadToByteArray(byte[] bytes) + { + } + } + + public class ExternalLevelCrossingSystemTrFailureStatusMessage : ExternalLevelCrossingSystemMessage + { + public ExternalLevelCrossingSystemTrFailureStatusMessage(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.TrFailureStatusMessage; + + public override int Size => 45; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new ExternalLevelCrossingSystemTrFailureStatusMessage(senderId, receiverId); + + protected override void WritePayloadToByteArray(byte[] bytes) + { + } + } + + public class ExternalLevelCrossingSystemTrackRelatedCommandAdmissabilityMessage : ExternalLevelCrossingSystemMessage + { + public ExternalLevelCrossingSystemTrackRelatedCommandAdmissabilityMessage(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.TrackRelatedCommandAdmissabilityMessage; + + public override int Size => 49; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new ExternalLevelCrossingSystemTrackRelatedCommandAdmissabilityMessage(senderId, receiverId); + + protected override void WritePayloadToByteArray(byte[] bytes) + { + } + } + + public class ExternalLevelCrossingSystemLxCommandAdmissibilityMessage : ExternalLevelCrossingSystemMessage + { + public ExternalLevelCrossingSystemLxCommandAdmissibilityMessage(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.LxCommandAdmissibilityMessage; + + public override int Size => 47; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new ExternalLevelCrossingSystemLxCommandAdmissibilityMessage(senderId, receiverId); + + protected override void WritePayloadToByteArray(byte[] bytes) + { + } + } + + public class ExternalLevelCrossingSystemStatusOfActivationPointMessage : ExternalLevelCrossingSystemMessage + { + public ExternalLevelCrossingSystemStatusOfActivationPointMessage(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.StatusOfActivationPointMessage; + + // TODO: dynamic size based on number k of activation points, here k=0 + public override int Size => 44; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new ExternalLevelCrossingSystemStatusOfActivationPointMessage(senderId, receiverId); + + protected override void WritePayloadToByteArray(byte[] bytes) + { + } + } + + public class ExternalLevelCrossingSystemVersionCheckCommand : ExternalLevelCrossingSystemMessage + { + private const int SENDER_PDI_VERSION_OFFSET = 43; + public ExternalLevelCrossingSystemVersionCheckCommand(string senderId, string receiverId, byte senderPdiVersion) : base(senderId, receiverId) + { + SenderPdiVersion = senderPdiVersion; + } + + public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.VersionCheckCommand; + + public byte SenderPdiVersion { get; } + + public override int Size => 44; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new ExternalLevelCrossingSystemVersionCheckCommand(senderId, receiverId, message[SENDER_PDI_VERSION_OFFSET]); + + protected override void WritePayloadToByteArray(byte[] bytes) + { + bytes[SENDER_PDI_VERSION_OFFSET] = SenderPdiVersion; + } + } + + public class ExternalLevelCrossingSystemVersionCheckMessage : ExternalLevelCrossingSystemMessage + { + private const int RESULT_PDI_VERSION_CHECK_OFFSET = 43; + private const int SENDER_PDI_VERSION_OFFSET = 44; + private const int CHECKSUM_LENGTH_OFFSET = 45; + private const int CHECKSUM_DATA_OFFSET = 46; + public ExternalLevelCrossingSystemVersionCheckMessage(string senderId, string receiverId, PdiVersionCheckResult resultPdiVersionCheck, byte senderPdiVersion, byte checksumLength) : base(senderId, receiverId) + { + ResultPdiVersionCheck = resultPdiVersionCheck; + SenderPdiVersion = senderPdiVersion; + ChecksumLength = checksumLength; + } + + public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.VersionCheckMessage; + + public PdiVersionCheckResult ResultPdiVersionCheck { get; } + public byte SenderPdiVersion { get; } + public byte ChecksumLength { get; } + + public override int Size => 46 + ChecksumLength; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) { + var resultPdiVersionCheck = (PdiVersionCheckResult) message[RESULT_PDI_VERSION_CHECK_OFFSET]; + var senderPdiVersion = message[SENDER_PDI_VERSION_OFFSET]; + var checksumLength = message[CHECKSUM_LENGTH_OFFSET]; + // var CHECKSUM_DATA_OFFSET = message[CHECKSUM_DATA_OFFSET]; + return new ExternalLevelCrossingSystemVersionCheckMessage(senderId, receiverId, resultPdiVersionCheck, senderPdiVersion, checksumLength); + } + + protected override void WritePayloadToByteArray(byte[] bytes) + { + bytes[RESULT_PDI_VERSION_CHECK_OFFSET] = (byte)ResultPdiVersionCheck; + bytes[SENDER_PDI_VERSION_OFFSET] = SenderPdiVersion; + bytes[CHECKSUM_LENGTH_OFFSET] = ChecksumLength; + } + } + + public class ExternalLevelCrossingSystemPDIAvailableMessage : ExternalLevelCrossingSystemMessage + { + public ExternalLevelCrossingSystemPDIAvailableMessage(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.PDIAvailable; + + public byte SenderPdiVersion { get; } + + public override int Size => 43; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new ExternalLevelCrossingSystemPDIAvailableMessage(senderId, receiverId); + + protected override void WritePayloadToByteArray(byte[] bytes) + { + } + } + + public class ExternalLevelCrossingSystemPDINotAvailableMessage : ExternalLevelCrossingSystemMessage + { + public ExternalLevelCrossingSystemPDINotAvailableMessage(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.PDINotAvailable; + + public byte SenderPdiVersion { get; } + + public override int Size => 43; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new ExternalLevelCrossingSystemPDINotAvailableMessage(senderId, receiverId); + + protected override void WritePayloadToByteArray(byte[] bytes) + { + } + } + + public class ExternalLevelCrossingSystemInitializationRequestMessage : ExternalLevelCrossingSystemMessage + { + public ExternalLevelCrossingSystemInitializationRequestMessage(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.InitializationRequest; + + public override int Size => 43; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) + { + return new ExternalLevelCrossingSystemInitializationRequestMessage(senderId, receiverId); + } + + protected override void WritePayloadToByteArray(byte[] bytes) + { + } + } + + public class ExternalLevelCrossingSystemStartInitializationMessage : ExternalLevelCrossingSystemMessage + { + public ExternalLevelCrossingSystemStartInitializationMessage(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.StartInitialization; + + public override int Size => 43; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) + { + return new ExternalLevelCrossingSystemStartInitializationMessage(senderId, receiverId); + } + + protected override void WritePayloadToByteArray(byte[] bytes) + { + } + } + + public class ExternalLevelCrossingSystemInitializationCompletedMessage : ExternalLevelCrossingSystemMessage + { + public ExternalLevelCrossingSystemInitializationCompletedMessage(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override ExternalLevelCrossingSystemMessageType MessageType => ExternalLevelCrossingSystemMessageType.InitializationCompleted; + + public override int Size => 43; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) + { + return new ExternalLevelCrossingSystemInitializationCompletedMessage(senderId, receiverId); + } + + protected override void WritePayloadToByteArray(byte[] bytes) + { + } + } +} diff --git a/src/Messages/Generic.cs b/src/Messages/Deprecated/Generic.cs similarity index 67% rename from src/Messages/Generic.cs rename to src/Messages/Deprecated/Generic.cs index 7df9733..8f310ad 100644 --- a/src/Messages/Generic.cs +++ b/src/Messages/Deprecated/Generic.cs @@ -1,7 +1,7 @@ -namespace EulynxLive.Messages -{ - public enum PdiVersionCheckResult : byte { - NoMatch = 0x1, - Match = 0x2 - } -} +namespace EulynxLive.Messages.Deprecated +{ + public enum PdiVersionCheckResult : byte { + NoMatch = 0x1, + Match = 0x2 + } +} diff --git a/src/Messages/LightSignalMessage.cs b/src/Messages/Deprecated/LightSignalMessage.cs similarity index 97% rename from src/Messages/LightSignalMessage.cs rename to src/Messages/Deprecated/LightSignalMessage.cs index 975fa37..cafb66d 100644 --- a/src/Messages/LightSignalMessage.cs +++ b/src/Messages/Deprecated/LightSignalMessage.cs @@ -1,572 +1,572 @@ -namespace EulynxLive.Messages -{ - public enum LightSignalMessageType: ushort { - InitializationRequest = 0x0021, - StartInitialization = 0x0022, - InitializationCompleted = 0x0023, - VersionCheckCommand = 0x0024, - VersionCheckMessage = 0x0025, - PDIAvailable = 0x0029, - PDINotAvailable = 0x002A, - IndicateSignalAspect = 0x0001, - IndicatedSignalAspect = 0x0003, - SetLuminosityCommand = 0x0002, - SetLuminosityMessage = 0x0004, - } - - public abstract class LightSignalMessage : EulynxMessage - { - public LightSignalMessage(string senderId, string receiverId) : base(senderId, receiverId) - {} - - public override ProtocolType ProtocolType => ProtocolType.LightSignal; - public override ushort MessageTypeRaw => (ushort) MessageType; - public abstract LightSignalMessageType MessageType { get; } - } - - public class LightSignalVersionCheckCommand : LightSignalMessage - { - private const int SENDER_PDI_VERSION_OFFSET = 43; - public LightSignalVersionCheckCommand(string senderId, string receiverId, byte senderPdiVersion) : base(senderId, receiverId) - { - SenderPdiVersion = senderPdiVersion; - } - - public override LightSignalMessageType MessageType => LightSignalMessageType.VersionCheckCommand; - - public byte SenderPdiVersion { get; } - - public override int Size => 44; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new LightSignalVersionCheckCommand(senderId, receiverId, message[SENDER_PDI_VERSION_OFFSET]); - - protected override void WritePayloadToByteArray(byte[] bytes) - { - bytes[SENDER_PDI_VERSION_OFFSET] = SenderPdiVersion; - } - } - - public class LightSignalVersionCheckMessage : LightSignalMessage - { - private const int RESULT_PDI_VERSION_CHECK_OFFSET = 43; - private const int SENDER_PDI_VERSION_OFFSET = 44; - private const int CHECKSUM_LENGTH_OFFSET = 45; - private const int CHECKSUM_DATA_OFFSET = 46; - public LightSignalVersionCheckMessage(string senderId, string receiverId, PdiVersionCheckResult resultPdiVersionCheck, byte senderPdiVersion, byte checksumLength) : base(senderId, receiverId) - { - ResultPdiVersionCheck = resultPdiVersionCheck; - SenderPdiVersion = senderPdiVersion; - ChecksumLength = checksumLength; - } - - public override LightSignalMessageType MessageType => LightSignalMessageType.VersionCheckMessage; - - public PdiVersionCheckResult ResultPdiVersionCheck { get; } - public byte SenderPdiVersion { get; } - public byte ChecksumLength { get; } - - public override int Size => 46 + ChecksumLength; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) { - var resultPdiVersionCheck = (PdiVersionCheckResult) message[RESULT_PDI_VERSION_CHECK_OFFSET]; - var senderPdiVersion = message[SENDER_PDI_VERSION_OFFSET]; - var checksumLength = message[CHECKSUM_LENGTH_OFFSET]; - // var CHECKSUM_DATA_OFFSET = message[CHECKSUM_DATA_OFFSET]; - return new LightSignalVersionCheckMessage(senderId, receiverId, resultPdiVersionCheck, senderPdiVersion, checksumLength); - } - - protected override void WritePayloadToByteArray(byte[] bytes) - { - bytes[RESULT_PDI_VERSION_CHECK_OFFSET] = (byte)ResultPdiVersionCheck; - bytes[SENDER_PDI_VERSION_OFFSET] = SenderPdiVersion; - bytes[CHECKSUM_LENGTH_OFFSET] = ChecksumLength; - } - } - - public class LightSignalPDIAvailableMessage : LightSignalMessage - { - public LightSignalPDIAvailableMessage(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override LightSignalMessageType MessageType => LightSignalMessageType.PDIAvailable; - - public byte SenderPdiVersion { get; } - - public override int Size => 43; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new LightSignalPDIAvailableMessage(senderId, receiverId); - - protected override void WritePayloadToByteArray(byte[] bytes) - { - } - } - - public class LightSignalPDINotAvailableMessage : LightSignalMessage - { - public LightSignalPDINotAvailableMessage(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override LightSignalMessageType MessageType => LightSignalMessageType.PDINotAvailable; - - public byte SenderPdiVersion { get; } - - public override int Size => 43; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new LightSignalPDINotAvailableMessage(senderId, receiverId); - - protected override void WritePayloadToByteArray(byte[] bytes) - { - } - } - - public class LightSignalInitializationRequestMessage : LightSignalMessage - { - public LightSignalInitializationRequestMessage(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override LightSignalMessageType MessageType => LightSignalMessageType.InitializationRequest; - - public override int Size => 43; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) - { - return new LightSignalInitializationRequestMessage(senderId, receiverId); - } - - protected override void WritePayloadToByteArray(byte[] bytes) - { - } - } - - public class LightSignalStartInitializationMessage : LightSignalMessage - { - public LightSignalStartInitializationMessage(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override LightSignalMessageType MessageType => LightSignalMessageType.StartInitialization; - - public override int Size => 43; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) - { - return new LightSignalStartInitializationMessage(senderId, receiverId); - } - - protected override void WritePayloadToByteArray(byte[] bytes) - { - } - } - - public class LightSignalInitializationCompletedMessage : LightSignalMessage - { - public LightSignalInitializationCompletedMessage(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override LightSignalMessageType MessageType => LightSignalMessageType.InitializationCompleted; - - public override int Size => 43; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) - { - return new LightSignalInitializationCompletedMessage(senderId, receiverId); - } - - protected override void WritePayloadToByteArray(byte[] bytes) - { - } - } - - /// Eu.SCI-LS.PDI.276 - public enum Luminosity : byte { - /// Eu.SCI-LS.PDI.360 - Day = 0x01, - /// Eu.SCI-LS.PDI.361 - Night = 0x02, - /// Eu.SCI-LS.PDI.372 - Undefined = 0xFE, - } - - public class LightSignalSetLuminosityMessage : LightSignalMessage - { - private const int RESULT_SET_LUMINOSITY_OFFSET = 43; - public LightSignalSetLuminosityMessage(string senderId, string receiverId, Luminosity luminosity) : base(senderId, receiverId) - { - Luminosity = luminosity; - } - - public override LightSignalMessageType MessageType => LightSignalMessageType.SetLuminosityMessage; - - public Luminosity Luminosity { get; } - - public override int Size => 44; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) { - var luminosity = (Luminosity) message[RESULT_SET_LUMINOSITY_OFFSET]; - return new LightSignalSetLuminosityMessage(senderId, receiverId, luminosity); - } - - protected override void WritePayloadToByteArray(byte[] bytes) - { - bytes[RESULT_SET_LUMINOSITY_OFFSET] = (byte)Luminosity; - } - } - - // Work in progress: - // public class LightSignalSetLuminosityCommand : LightSignalSetLuminosityMessage - // { - // public LightSignalSetLuminosityCommand(string senderId, string receiverId, Luminosity luminosity) : base(senderId, receiverId, luminosity) { } - // } - - public enum BasicAspectType : byte - { - /// Eu.SAT.209 - /// FTIA: Po0 - /// NR: Red/Stop/On - /// SZ: SZ1 - /// DB: Hp0 - /// CFL: SFA 1 - /// PR: HS01 - /// SNCF: Carré / Carré violet / Guidon d'arrêt fermé - Stop_Danger_1 = 0x1, - - /// Eu.SAT.210 - Stop_Danger_2 = 0x21, - - /// Eu.SAT.211 - Proceed_Clear_1 = 0x4, - - /// Eu.SAT.213 - Flashing_Clear_1 = 0x5, - - /// Eu.SAT.214 - Flashing_Clear_2 = 0x6, - - /// Eu.SAT.215 - Approach_Caution = 0x7, - - /// Eu.SAT.316 - StaffResponsible = 0x17, - - /// Eu.SAT.216 - FlashingYellow = 0x18, - - /// Eu.SAT.217 - PreliminaryCaution = 0x28, - - /// Eu.SAT.218 - FlashingDoubleYellow = 0x47, - - /// Eu.SAT.219 - ExpectStop = 0x08, - - /// Eu.SAT.340 - ExpectLimitedSpeed = 0x0B, - - /// Eu.SAT.220 - ShuntingAllowed = 0x02, - /// Eu.SAT.222 - IgnoreSignal = 0x0A, - /// Eu.SAT.320 - /// Eu.SAT.223 - /// Eu.SAT.226 - /// Eu.SAT.227 - /// Eu.SAT.228 - /// Eu.SAT.375 - /// Eu.SAT.235 - IntendedDark = 0xFF, - /// Eu.SAT.237 - /// Eu.SAT.238 - /// Eu.SAT.239 - /// Eu.SAT.240 - /// Eu.SAT.242 - /// Eu.SAT.365 - } - - public enum BasicAspectTypeExtension : byte - { - - /// Eu.SAT.229 - SubstitutionSignal = 0x01, - - /// Eu.SAT.230 - DriveOnSight = 0x02, - - /// Eu.SAT.231 - PassSignalAtStopToOppositeTrack = 0x03, - - /// Eu.SAT.232 - RouteToOppositeTrack = 0x04, - - /// Eu.SAT.233 - ExpectEarlyStop = 0x05, - - /// Eu.SAT.346 - IntendedDark = 0xFF, - } - - /// Eu.SAT.354 - public enum SpeedIndicators : byte { - /// Eu.SAT.355 - Indication10 = 0x01, - Indication20 = 0x02, - Indication30 = 0x03, - Indication40 = 0x04, - Indication50 = 0x05, - Indication60 = 0x06, - Indication70 = 0x07, - Indication80 = 0x08, - Indication90 = 0x09, - Indication100 = 0x0A, - Indication110 = 0x0B, - Indication120 = 0x0C, - Indication130 = 0x0D, - Indication140 = 0x0E, - /// Eu.SAT.356 - - Indication150 = 0x0F, - /// Eu.SAT.369 - Indication160 = 0x10, - /// Eu.SAT.357 - /// Eu.SAT.358 - IndicationDark = 0xFF, - } - - public enum SpeedIndicatorsAnnouncements : byte { - Announcement10 = 0x01, - Announcement20 = 0x02, - Announcement30 = 0x03, - Announcement40 = 0x04, - Announcement50 = 0x05, - Announcement60 = 0x06, - Announcement70 = 0x07, - Announcement80 = 0x08, - Announcement90 = 0x09, - Announcement100 = 0x0A, - Announcement110 = 0x0B, - Announcement120 = 0x0C, - Announcement130 = 0x0D, - Announcement140 = 0x0E, - Announcement150 = 0x0F, - Announcement160 = 0x10, - AnnouncementDark = 0xFF, - } - - /// Eu.SAT.251 - public enum DirectionIndicators : byte { - /// Eu.SAT.252 - IndicationA = 0x01, - IndicationB = 0x02, - IndicationC = 0x03, - IndicationD = 0x04, - IndicationE = 0x05, - IndicationF = 0x06, - IndicationG = 0x07, - IndicationH = 0x08, - IndicationI = 0x09, - IndicationJ = 0x0A, - IndicationK = 0x0B, - IndicationL = 0x0C, - IndicationM = 0x0D, - IndicationN = 0x0E, - IndicationO = 0x0F, - IndicationP = 0x10, - IndicationQ = 0x11, - IndicationR = 0x12, - IndicationS = 0x13, - IndicationT = 0x14, - IndicationU = 0x15, - IndicationV = 0x16, - IndicationW = 0x17, - IndicationX = 0x18, - IndicationY = 0x19, - /// Eu.SAT.254 - IndicationZ = 0x1A, - - // Missing additional indicators here (Eu.SAT.306, Eu.SAT.304, Eu.SAT.256) - - /// Eu.SAT.255 - /// Eu.SAT.353 - IndicationDark = 0xFF, - } - - public enum DirectionIndicatorsAnnouncements : byte { - AnnouncementDark = 0xFF, - } - - public enum DowngradeInformation : byte { - NotApplicable = 0xFF, - } - - public enum RouteInformation : byte { - NotApplicable = 0xFF, - } - - public enum IntentionallyDark : byte { - NotApplicable = 0xFF, - } - - - public class LightSignalIndicateSignalAspectCommand : LightSignalMessage - { - private const int BASIC_ASPECT_TYPE_OFFSET = 43; - private const int BASIC_ASPECT_TYPE_EXTENSION_OFFSET = 44; - private const int SPEED_INDICATORS_OFFSET = 45; - private const int SPEED_INDICATORS_ANNOUNCEMENTS_OFFSET = 46; - private const int DIRECTION_INDICATORS_OFFSET = 47; - private const int DIRECTION_INDICATORS_ANNOUNCEMENTS_OFFSET = 48; - private const int DOWNGRADE_INFORMATION_OFFSET = 49; - private const int ROUTE_INFORMATION_OFFSET = 50; - private const int INTENTIONALLY_DARK_OFFSET = 51; - private const int NATIONAL_SPECIFIED_OFFSET = 52; - public override LightSignalMessageType MessageType => LightSignalMessageType.IndicateSignalAspect; - - public LightSignalIndicateSignalAspectCommand(string senderId, string receiverId, BasicAspectType basicAspectType, BasicAspectTypeExtension basicAspectTypeExtension, SpeedIndicators speedIndicators, SpeedIndicatorsAnnouncements speedIndicatorsAnnouncements, DirectionIndicators directionIndicators, DirectionIndicatorsAnnouncements directionIndicatorsAnnouncements, DowngradeInformation downgradeInformation, RouteInformation routeInformation, IntentionallyDark intentionallyDark) : base(senderId, receiverId) - { - BasicAspectType = basicAspectType; - BasicAspectTypeExtension = basicAspectTypeExtension; - SpeedIndicators = speedIndicators; - SpeedIndicatorsAnnouncements = speedIndicatorsAnnouncements; - DirectionIndicators = directionIndicators; - DirectionIndicatorsAnnouncements = directionIndicatorsAnnouncements; - DowngradeInformation = downgradeInformation; - RouteInformation = routeInformation; - IntentionallyDark = intentionallyDark; - } - - public BasicAspectType BasicAspectType { get; } - public BasicAspectTypeExtension BasicAspectTypeExtension { get; } - public SpeedIndicators SpeedIndicators { get; } - public SpeedIndicatorsAnnouncements SpeedIndicatorsAnnouncements { get; } - public DirectionIndicators DirectionIndicators { get; } - public DirectionIndicatorsAnnouncements DirectionIndicatorsAnnouncements { get; } - public DowngradeInformation DowngradeInformation { get; } - public RouteInformation RouteInformation { get; } - public IntentionallyDark IntentionallyDark { get; } - - public override int Size => 61; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) - { - var basicAspectType = (BasicAspectType) message[BASIC_ASPECT_TYPE_OFFSET]; - var basicAspectTypeExtension = (BasicAspectTypeExtension) message[BASIC_ASPECT_TYPE_EXTENSION_OFFSET]; - var speedIndicators = (SpeedIndicators) message[SPEED_INDICATORS_OFFSET]; - var speedIndicatorsAnnouncements = (SpeedIndicatorsAnnouncements) message[SPEED_INDICATORS_ANNOUNCEMENTS_OFFSET]; - var directionIndicators = (DirectionIndicators) message[DIRECTION_INDICATORS_OFFSET]; - var directionIndicatorsAnnouncements = (DirectionIndicatorsAnnouncements) message[DIRECTION_INDICATORS_ANNOUNCEMENTS_OFFSET]; - var downgradeInformation = (DowngradeInformation) message[DOWNGRADE_INFORMATION_OFFSET]; - var routeInformation = (RouteInformation) message[ROUTE_INFORMATION_OFFSET]; - var intentionallyDark = (IntentionallyDark) message[INTENTIONALLY_DARK_OFFSET]; - - return new LightSignalIndicateSignalAspectCommand( - senderId, receiverId, - basicAspectType, - basicAspectTypeExtension, - speedIndicators, - speedIndicatorsAnnouncements, - directionIndicators, - directionIndicatorsAnnouncements, - downgradeInformation, - routeInformation, - intentionallyDark - ); - } - - protected override void WritePayloadToByteArray(byte[] bytes) - { - bytes[BASIC_ASPECT_TYPE_OFFSET] = (byte)BasicAspectType; - bytes[BASIC_ASPECT_TYPE_EXTENSION_OFFSET] = (byte)BasicAspectTypeExtension; - bytes[SPEED_INDICATORS_OFFSET] = (byte)SpeedIndicators; - bytes[SPEED_INDICATORS_ANNOUNCEMENTS_OFFSET] = (byte)SpeedIndicatorsAnnouncements; - bytes[DIRECTION_INDICATORS_OFFSET] = (byte)DirectionIndicators; - bytes[DIRECTION_INDICATORS_ANNOUNCEMENTS_OFFSET] = (byte)DirectionIndicatorsAnnouncements; - bytes[DOWNGRADE_INFORMATION_OFFSET] = (byte)DowngradeInformation; - bytes[ROUTE_INFORMATION_OFFSET] = (byte)RouteInformation; - bytes[INTENTIONALLY_DARK_OFFSET] = (byte)IntentionallyDark; - } - } - - public class LightSignalIndicatedSignalAspectMessage : LightSignalMessage - { - private const int BASIC_ASPECT_TYPE_OFFSET = 43; - private const int BASIC_ASPECT_TYPE_EXTENSION_OFFSET = 44; - private const int SPEED_INDICATORS_OFFSET = 45; - private const int SPEED_INDICATORS_ANNOUNCEMENTS_OFFSET = 46; - private const int DIRECTION_INDICATORS_OFFSET = 47; - private const int DIRECTION_INDICATORS_ANNOUNCEMENTS_OFFSET = 48; - private const int DOWNGRADE_INFORMATION_OFFSET = 49; - private const int ROUTE_INFORMATION_OFFSET = 50; - private const int INTENTIONALLY_DARK_OFFSET = 51; - private const int NATIONAL_SPECIFIED_OFFSET = 52; - - public LightSignalIndicatedSignalAspectMessage(string senderId, string receiverId, BasicAspectType basicAspectType, BasicAspectTypeExtension basicAspectTypeExtension, SpeedIndicators speedIndicators, SpeedIndicatorsAnnouncements speedIndicatorsAnnouncements, DirectionIndicators directionIndicators, DirectionIndicatorsAnnouncements directionIndicatorsAnnouncements, DowngradeInformation downgradeInformation, RouteInformation routeInformation, IntentionallyDark intentionallyDark) : base(senderId, receiverId) - { - BasicAspectType = basicAspectType; - BasicAspectTypeExtension = basicAspectTypeExtension; - SpeedIndicators = speedIndicators; - SpeedIndicatorsAnnouncements = speedIndicatorsAnnouncements; - DirectionIndicators = directionIndicators; - DirectionIndicatorsAnnouncements = directionIndicatorsAnnouncements; - DowngradeInformation = downgradeInformation; - RouteInformation = routeInformation; - IntentionallyDark = intentionallyDark; - } - - public override LightSignalMessageType MessageType => LightSignalMessageType.IndicatedSignalAspect; - - public override int Size => 61; - - public BasicAspectType BasicAspectType { get; } - public BasicAspectTypeExtension BasicAspectTypeExtension { get; } - public SpeedIndicators SpeedIndicators { get; } - public SpeedIndicatorsAnnouncements SpeedIndicatorsAnnouncements { get; } - public DirectionIndicators DirectionIndicators { get; } - public DirectionIndicatorsAnnouncements DirectionIndicatorsAnnouncements { get; } - public DowngradeInformation DowngradeInformation { get; } - public RouteInformation RouteInformation { get; } - public IntentionallyDark IntentionallyDark { get; } - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) - { - var basicAspectType = (BasicAspectType) message[BASIC_ASPECT_TYPE_OFFSET]; - var basicAspectTypeExtension = (BasicAspectTypeExtension) message[BASIC_ASPECT_TYPE_EXTENSION_OFFSET]; - var speedIndicators = (SpeedIndicators) message[SPEED_INDICATORS_OFFSET]; - var speedIndicatorsAnnouncements = (SpeedIndicatorsAnnouncements) message[SPEED_INDICATORS_ANNOUNCEMENTS_OFFSET]; - var directionIndicators = (DirectionIndicators) message[DIRECTION_INDICATORS_OFFSET]; - var directionIndicatorsAnnouncements = (DirectionIndicatorsAnnouncements) message[DIRECTION_INDICATORS_ANNOUNCEMENTS_OFFSET]; - var downgradeInformation = (DowngradeInformation) message[DOWNGRADE_INFORMATION_OFFSET]; - var routeInformation = (RouteInformation) message[ROUTE_INFORMATION_OFFSET]; - var intentionallyDark = (IntentionallyDark) message[INTENTIONALLY_DARK_OFFSET]; - - return new LightSignalIndicatedSignalAspectMessage( - senderId, receiverId, - basicAspectType, - basicAspectTypeExtension, - speedIndicators, - speedIndicatorsAnnouncements, - directionIndicators, - directionIndicatorsAnnouncements, - downgradeInformation, - routeInformation, - intentionallyDark - ); - } - - protected override void WritePayloadToByteArray(byte[] bytes) - { - bytes[BASIC_ASPECT_TYPE_OFFSET] = (byte)BasicAspectType; - bytes[BASIC_ASPECT_TYPE_EXTENSION_OFFSET] = (byte)BasicAspectTypeExtension; - bytes[SPEED_INDICATORS_OFFSET] = (byte)SpeedIndicators; - bytes[SPEED_INDICATORS_ANNOUNCEMENTS_OFFSET] = (byte)SpeedIndicatorsAnnouncements; - bytes[DIRECTION_INDICATORS_OFFSET] = (byte)DirectionIndicators; - bytes[DIRECTION_INDICATORS_ANNOUNCEMENTS_OFFSET] = (byte)DirectionIndicatorsAnnouncements; - bytes[DOWNGRADE_INFORMATION_OFFSET] = (byte)DowngradeInformation; - bytes[ROUTE_INFORMATION_OFFSET] = (byte)RouteInformation; - bytes[INTENTIONALLY_DARK_OFFSET] = (byte)IntentionallyDark; - } - } -} +namespace EulynxLive.Messages.Deprecated +{ + public enum LightSignalMessageType: ushort { + InitializationRequest = 0x0021, + StartInitialization = 0x0022, + InitializationCompleted = 0x0023, + VersionCheckCommand = 0x0024, + VersionCheckMessage = 0x0025, + PDIAvailable = 0x0029, + PDINotAvailable = 0x002A, + IndicateSignalAspect = 0x0001, + IndicatedSignalAspect = 0x0003, + SetLuminosityCommand = 0x0002, + SetLuminosityMessage = 0x0004, + } + + public abstract class LightSignalMessage : EulynxMessage + { + public LightSignalMessage(string senderId, string receiverId) : base(senderId, receiverId) + {} + + public override ProtocolType ProtocolType => ProtocolType.LightSignal; + public override ushort MessageTypeRaw => (ushort) MessageType; + public abstract LightSignalMessageType MessageType { get; } + } + + public class LightSignalVersionCheckCommand : LightSignalMessage + { + private const int SENDER_PDI_VERSION_OFFSET = 43; + public LightSignalVersionCheckCommand(string senderId, string receiverId, byte senderPdiVersion) : base(senderId, receiverId) + { + SenderPdiVersion = senderPdiVersion; + } + + public override LightSignalMessageType MessageType => LightSignalMessageType.VersionCheckCommand; + + public byte SenderPdiVersion { get; } + + public override int Size => 44; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new LightSignalVersionCheckCommand(senderId, receiverId, message[SENDER_PDI_VERSION_OFFSET]); + + protected override void WritePayloadToByteArray(byte[] bytes) + { + bytes[SENDER_PDI_VERSION_OFFSET] = SenderPdiVersion; + } + } + + public class LightSignalVersionCheckMessage : LightSignalMessage + { + private const int RESULT_PDI_VERSION_CHECK_OFFSET = 43; + private const int SENDER_PDI_VERSION_OFFSET = 44; + private const int CHECKSUM_LENGTH_OFFSET = 45; + private const int CHECKSUM_DATA_OFFSET = 46; + public LightSignalVersionCheckMessage(string senderId, string receiverId, PdiVersionCheckResult resultPdiVersionCheck, byte senderPdiVersion, byte checksumLength) : base(senderId, receiverId) + { + ResultPdiVersionCheck = resultPdiVersionCheck; + SenderPdiVersion = senderPdiVersion; + ChecksumLength = checksumLength; + } + + public override LightSignalMessageType MessageType => LightSignalMessageType.VersionCheckMessage; + + public PdiVersionCheckResult ResultPdiVersionCheck { get; } + public byte SenderPdiVersion { get; } + public byte ChecksumLength { get; } + + public override int Size => 46 + ChecksumLength; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) { + var resultPdiVersionCheck = (PdiVersionCheckResult) message[RESULT_PDI_VERSION_CHECK_OFFSET]; + var senderPdiVersion = message[SENDER_PDI_VERSION_OFFSET]; + var checksumLength = message[CHECKSUM_LENGTH_OFFSET]; + // var CHECKSUM_DATA_OFFSET = message[CHECKSUM_DATA_OFFSET]; + return new LightSignalVersionCheckMessage(senderId, receiverId, resultPdiVersionCheck, senderPdiVersion, checksumLength); + } + + protected override void WritePayloadToByteArray(byte[] bytes) + { + bytes[RESULT_PDI_VERSION_CHECK_OFFSET] = (byte)ResultPdiVersionCheck; + bytes[SENDER_PDI_VERSION_OFFSET] = SenderPdiVersion; + bytes[CHECKSUM_LENGTH_OFFSET] = ChecksumLength; + } + } + + public class LightSignalPDIAvailableMessage : LightSignalMessage + { + public LightSignalPDIAvailableMessage(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override LightSignalMessageType MessageType => LightSignalMessageType.PDIAvailable; + + public byte SenderPdiVersion { get; } + + public override int Size => 43; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new LightSignalPDIAvailableMessage(senderId, receiverId); + + protected override void WritePayloadToByteArray(byte[] bytes) + { + } + } + + public class LightSignalPDINotAvailableMessage : LightSignalMessage + { + public LightSignalPDINotAvailableMessage(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override LightSignalMessageType MessageType => LightSignalMessageType.PDINotAvailable; + + public byte SenderPdiVersion { get; } + + public override int Size => 43; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new LightSignalPDINotAvailableMessage(senderId, receiverId); + + protected override void WritePayloadToByteArray(byte[] bytes) + { + } + } + + public class LightSignalInitializationRequestMessage : LightSignalMessage + { + public LightSignalInitializationRequestMessage(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override LightSignalMessageType MessageType => LightSignalMessageType.InitializationRequest; + + public override int Size => 43; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) + { + return new LightSignalInitializationRequestMessage(senderId, receiverId); + } + + protected override void WritePayloadToByteArray(byte[] bytes) + { + } + } + + public class LightSignalStartInitializationMessage : LightSignalMessage + { + public LightSignalStartInitializationMessage(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override LightSignalMessageType MessageType => LightSignalMessageType.StartInitialization; + + public override int Size => 43; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) + { + return new LightSignalStartInitializationMessage(senderId, receiverId); + } + + protected override void WritePayloadToByteArray(byte[] bytes) + { + } + } + + public class LightSignalInitializationCompletedMessage : LightSignalMessage + { + public LightSignalInitializationCompletedMessage(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override LightSignalMessageType MessageType => LightSignalMessageType.InitializationCompleted; + + public override int Size => 43; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) + { + return new LightSignalInitializationCompletedMessage(senderId, receiverId); + } + + protected override void WritePayloadToByteArray(byte[] bytes) + { + } + } + + /// Eu.SCI-LS.PDI.276 + public enum Luminosity : byte { + /// Eu.SCI-LS.PDI.360 + Day = 0x01, + /// Eu.SCI-LS.PDI.361 + Night = 0x02, + /// Eu.SCI-LS.PDI.372 + Undefined = 0xFE, + } + + public class LightSignalSetLuminosityMessage : LightSignalMessage + { + private const int RESULT_SET_LUMINOSITY_OFFSET = 43; + public LightSignalSetLuminosityMessage(string senderId, string receiverId, Luminosity luminosity) : base(senderId, receiverId) + { + Luminosity = luminosity; + } + + public override LightSignalMessageType MessageType => LightSignalMessageType.SetLuminosityMessage; + + public Luminosity Luminosity { get; } + + public override int Size => 44; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) { + var luminosity = (Luminosity) message[RESULT_SET_LUMINOSITY_OFFSET]; + return new LightSignalSetLuminosityMessage(senderId, receiverId, luminosity); + } + + protected override void WritePayloadToByteArray(byte[] bytes) + { + bytes[RESULT_SET_LUMINOSITY_OFFSET] = (byte)Luminosity; + } + } + + // Work in progress: + // public class LightSignalSetLuminosityCommand : LightSignalSetLuminosityMessage + // { + // public LightSignalSetLuminosityCommand(string senderId, string receiverId, Luminosity luminosity) : base(senderId, receiverId, luminosity) { } + // } + + public enum BasicAspectType : byte + { + /// Eu.SAT.209 + /// FTIA: Po0 + /// NR: Red/Stop/On + /// SZ: SZ1 + /// DB: Hp0 + /// CFL: SFA 1 + /// PR: HS01 + /// SNCF: Carré / Carré violet / Guidon d'arrêt fermé + Stop_Danger_1 = 0x1, + + /// Eu.SAT.210 + Stop_Danger_2 = 0x21, + + /// Eu.SAT.211 + Proceed_Clear_1 = 0x4, + + /// Eu.SAT.213 + Flashing_Clear_1 = 0x5, + + /// Eu.SAT.214 + Flashing_Clear_2 = 0x6, + + /// Eu.SAT.215 + Approach_Caution = 0x7, + + /// Eu.SAT.316 + StaffResponsible = 0x17, + + /// Eu.SAT.216 + FlashingYellow = 0x18, + + /// Eu.SAT.217 + PreliminaryCaution = 0x28, + + /// Eu.SAT.218 + FlashingDoubleYellow = 0x47, + + /// Eu.SAT.219 + ExpectStop = 0x08, + + /// Eu.SAT.340 + ExpectLimitedSpeed = 0x0B, + + /// Eu.SAT.220 + ShuntingAllowed = 0x02, + /// Eu.SAT.222 + IgnoreSignal = 0x0A, + /// Eu.SAT.320 + /// Eu.SAT.223 + /// Eu.SAT.226 + /// Eu.SAT.227 + /// Eu.SAT.228 + /// Eu.SAT.375 + /// Eu.SAT.235 + IntendedDark = 0xFF, + /// Eu.SAT.237 + /// Eu.SAT.238 + /// Eu.SAT.239 + /// Eu.SAT.240 + /// Eu.SAT.242 + /// Eu.SAT.365 + } + + public enum BasicAspectTypeExtension : byte + { + + /// Eu.SAT.229 + SubstitutionSignal = 0x01, + + /// Eu.SAT.230 + DriveOnSight = 0x02, + + /// Eu.SAT.231 + PassSignalAtStopToOppositeTrack = 0x03, + + /// Eu.SAT.232 + RouteToOppositeTrack = 0x04, + + /// Eu.SAT.233 + ExpectEarlyStop = 0x05, + + /// Eu.SAT.346 + IntendedDark = 0xFF, + } + + /// Eu.SAT.354 + public enum SpeedIndicators : byte { + /// Eu.SAT.355 + Indication10 = 0x01, + Indication20 = 0x02, + Indication30 = 0x03, + Indication40 = 0x04, + Indication50 = 0x05, + Indication60 = 0x06, + Indication70 = 0x07, + Indication80 = 0x08, + Indication90 = 0x09, + Indication100 = 0x0A, + Indication110 = 0x0B, + Indication120 = 0x0C, + Indication130 = 0x0D, + Indication140 = 0x0E, + /// Eu.SAT.356 + + Indication150 = 0x0F, + /// Eu.SAT.369 + Indication160 = 0x10, + /// Eu.SAT.357 + /// Eu.SAT.358 + IndicationDark = 0xFF, + } + + public enum SpeedIndicatorsAnnouncements : byte { + Announcement10 = 0x01, + Announcement20 = 0x02, + Announcement30 = 0x03, + Announcement40 = 0x04, + Announcement50 = 0x05, + Announcement60 = 0x06, + Announcement70 = 0x07, + Announcement80 = 0x08, + Announcement90 = 0x09, + Announcement100 = 0x0A, + Announcement110 = 0x0B, + Announcement120 = 0x0C, + Announcement130 = 0x0D, + Announcement140 = 0x0E, + Announcement150 = 0x0F, + Announcement160 = 0x10, + AnnouncementDark = 0xFF, + } + + /// Eu.SAT.251 + public enum DirectionIndicators : byte { + /// Eu.SAT.252 + IndicationA = 0x01, + IndicationB = 0x02, + IndicationC = 0x03, + IndicationD = 0x04, + IndicationE = 0x05, + IndicationF = 0x06, + IndicationG = 0x07, + IndicationH = 0x08, + IndicationI = 0x09, + IndicationJ = 0x0A, + IndicationK = 0x0B, + IndicationL = 0x0C, + IndicationM = 0x0D, + IndicationN = 0x0E, + IndicationO = 0x0F, + IndicationP = 0x10, + IndicationQ = 0x11, + IndicationR = 0x12, + IndicationS = 0x13, + IndicationT = 0x14, + IndicationU = 0x15, + IndicationV = 0x16, + IndicationW = 0x17, + IndicationX = 0x18, + IndicationY = 0x19, + /// Eu.SAT.254 + IndicationZ = 0x1A, + + // Missing additional indicators here (Eu.SAT.306, Eu.SAT.304, Eu.SAT.256) + + /// Eu.SAT.255 + /// Eu.SAT.353 + IndicationDark = 0xFF, + } + + public enum DirectionIndicatorsAnnouncements : byte { + AnnouncementDark = 0xFF, + } + + public enum DowngradeInformation : byte { + NotApplicable = 0xFF, + } + + public enum RouteInformation : byte { + NotApplicable = 0xFF, + } + + public enum IntentionallyDark : byte { + NotApplicable = 0xFF, + } + + + public class LightSignalIndicateSignalAspectCommand : LightSignalMessage + { + private const int BASIC_ASPECT_TYPE_OFFSET = 43; + private const int BASIC_ASPECT_TYPE_EXTENSION_OFFSET = 44; + private const int SPEED_INDICATORS_OFFSET = 45; + private const int SPEED_INDICATORS_ANNOUNCEMENTS_OFFSET = 46; + private const int DIRECTION_INDICATORS_OFFSET = 47; + private const int DIRECTION_INDICATORS_ANNOUNCEMENTS_OFFSET = 48; + private const int DOWNGRADE_INFORMATION_OFFSET = 49; + private const int ROUTE_INFORMATION_OFFSET = 50; + private const int INTENTIONALLY_DARK_OFFSET = 51; + private const int NATIONAL_SPECIFIED_OFFSET = 52; + public override LightSignalMessageType MessageType => LightSignalMessageType.IndicateSignalAspect; + + public LightSignalIndicateSignalAspectCommand(string senderId, string receiverId, BasicAspectType basicAspectType, BasicAspectTypeExtension basicAspectTypeExtension, SpeedIndicators speedIndicators, SpeedIndicatorsAnnouncements speedIndicatorsAnnouncements, DirectionIndicators directionIndicators, DirectionIndicatorsAnnouncements directionIndicatorsAnnouncements, DowngradeInformation downgradeInformation, RouteInformation routeInformation, IntentionallyDark intentionallyDark) : base(senderId, receiverId) + { + BasicAspectType = basicAspectType; + BasicAspectTypeExtension = basicAspectTypeExtension; + SpeedIndicators = speedIndicators; + SpeedIndicatorsAnnouncements = speedIndicatorsAnnouncements; + DirectionIndicators = directionIndicators; + DirectionIndicatorsAnnouncements = directionIndicatorsAnnouncements; + DowngradeInformation = downgradeInformation; + RouteInformation = routeInformation; + IntentionallyDark = intentionallyDark; + } + + public BasicAspectType BasicAspectType { get; } + public BasicAspectTypeExtension BasicAspectTypeExtension { get; } + public SpeedIndicators SpeedIndicators { get; } + public SpeedIndicatorsAnnouncements SpeedIndicatorsAnnouncements { get; } + public DirectionIndicators DirectionIndicators { get; } + public DirectionIndicatorsAnnouncements DirectionIndicatorsAnnouncements { get; } + public DowngradeInformation DowngradeInformation { get; } + public RouteInformation RouteInformation { get; } + public IntentionallyDark IntentionallyDark { get; } + + public override int Size => 61; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) + { + var basicAspectType = (BasicAspectType) message[BASIC_ASPECT_TYPE_OFFSET]; + var basicAspectTypeExtension = (BasicAspectTypeExtension) message[BASIC_ASPECT_TYPE_EXTENSION_OFFSET]; + var speedIndicators = (SpeedIndicators) message[SPEED_INDICATORS_OFFSET]; + var speedIndicatorsAnnouncements = (SpeedIndicatorsAnnouncements) message[SPEED_INDICATORS_ANNOUNCEMENTS_OFFSET]; + var directionIndicators = (DirectionIndicators) message[DIRECTION_INDICATORS_OFFSET]; + var directionIndicatorsAnnouncements = (DirectionIndicatorsAnnouncements) message[DIRECTION_INDICATORS_ANNOUNCEMENTS_OFFSET]; + var downgradeInformation = (DowngradeInformation) message[DOWNGRADE_INFORMATION_OFFSET]; + var routeInformation = (RouteInformation) message[ROUTE_INFORMATION_OFFSET]; + var intentionallyDark = (IntentionallyDark) message[INTENTIONALLY_DARK_OFFSET]; + + return new LightSignalIndicateSignalAspectCommand( + senderId, receiverId, + basicAspectType, + basicAspectTypeExtension, + speedIndicators, + speedIndicatorsAnnouncements, + directionIndicators, + directionIndicatorsAnnouncements, + downgradeInformation, + routeInformation, + intentionallyDark + ); + } + + protected override void WritePayloadToByteArray(byte[] bytes) + { + bytes[BASIC_ASPECT_TYPE_OFFSET] = (byte)BasicAspectType; + bytes[BASIC_ASPECT_TYPE_EXTENSION_OFFSET] = (byte)BasicAspectTypeExtension; + bytes[SPEED_INDICATORS_OFFSET] = (byte)SpeedIndicators; + bytes[SPEED_INDICATORS_ANNOUNCEMENTS_OFFSET] = (byte)SpeedIndicatorsAnnouncements; + bytes[DIRECTION_INDICATORS_OFFSET] = (byte)DirectionIndicators; + bytes[DIRECTION_INDICATORS_ANNOUNCEMENTS_OFFSET] = (byte)DirectionIndicatorsAnnouncements; + bytes[DOWNGRADE_INFORMATION_OFFSET] = (byte)DowngradeInformation; + bytes[ROUTE_INFORMATION_OFFSET] = (byte)RouteInformation; + bytes[INTENTIONALLY_DARK_OFFSET] = (byte)IntentionallyDark; + } + } + + public class LightSignalIndicatedSignalAspectMessage : LightSignalMessage + { + private const int BASIC_ASPECT_TYPE_OFFSET = 43; + private const int BASIC_ASPECT_TYPE_EXTENSION_OFFSET = 44; + private const int SPEED_INDICATORS_OFFSET = 45; + private const int SPEED_INDICATORS_ANNOUNCEMENTS_OFFSET = 46; + private const int DIRECTION_INDICATORS_OFFSET = 47; + private const int DIRECTION_INDICATORS_ANNOUNCEMENTS_OFFSET = 48; + private const int DOWNGRADE_INFORMATION_OFFSET = 49; + private const int ROUTE_INFORMATION_OFFSET = 50; + private const int INTENTIONALLY_DARK_OFFSET = 51; + private const int NATIONAL_SPECIFIED_OFFSET = 52; + + public LightSignalIndicatedSignalAspectMessage(string senderId, string receiverId, BasicAspectType basicAspectType, BasicAspectTypeExtension basicAspectTypeExtension, SpeedIndicators speedIndicators, SpeedIndicatorsAnnouncements speedIndicatorsAnnouncements, DirectionIndicators directionIndicators, DirectionIndicatorsAnnouncements directionIndicatorsAnnouncements, DowngradeInformation downgradeInformation, RouteInformation routeInformation, IntentionallyDark intentionallyDark) : base(senderId, receiverId) + { + BasicAspectType = basicAspectType; + BasicAspectTypeExtension = basicAspectTypeExtension; + SpeedIndicators = speedIndicators; + SpeedIndicatorsAnnouncements = speedIndicatorsAnnouncements; + DirectionIndicators = directionIndicators; + DirectionIndicatorsAnnouncements = directionIndicatorsAnnouncements; + DowngradeInformation = downgradeInformation; + RouteInformation = routeInformation; + IntentionallyDark = intentionallyDark; + } + + public override LightSignalMessageType MessageType => LightSignalMessageType.IndicatedSignalAspect; + + public override int Size => 61; + + public BasicAspectType BasicAspectType { get; } + public BasicAspectTypeExtension BasicAspectTypeExtension { get; } + public SpeedIndicators SpeedIndicators { get; } + public SpeedIndicatorsAnnouncements SpeedIndicatorsAnnouncements { get; } + public DirectionIndicators DirectionIndicators { get; } + public DirectionIndicatorsAnnouncements DirectionIndicatorsAnnouncements { get; } + public DowngradeInformation DowngradeInformation { get; } + public RouteInformation RouteInformation { get; } + public IntentionallyDark IntentionallyDark { get; } + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) + { + var basicAspectType = (BasicAspectType) message[BASIC_ASPECT_TYPE_OFFSET]; + var basicAspectTypeExtension = (BasicAspectTypeExtension) message[BASIC_ASPECT_TYPE_EXTENSION_OFFSET]; + var speedIndicators = (SpeedIndicators) message[SPEED_INDICATORS_OFFSET]; + var speedIndicatorsAnnouncements = (SpeedIndicatorsAnnouncements) message[SPEED_INDICATORS_ANNOUNCEMENTS_OFFSET]; + var directionIndicators = (DirectionIndicators) message[DIRECTION_INDICATORS_OFFSET]; + var directionIndicatorsAnnouncements = (DirectionIndicatorsAnnouncements) message[DIRECTION_INDICATORS_ANNOUNCEMENTS_OFFSET]; + var downgradeInformation = (DowngradeInformation) message[DOWNGRADE_INFORMATION_OFFSET]; + var routeInformation = (RouteInformation) message[ROUTE_INFORMATION_OFFSET]; + var intentionallyDark = (IntentionallyDark) message[INTENTIONALLY_DARK_OFFSET]; + + return new LightSignalIndicatedSignalAspectMessage( + senderId, receiverId, + basicAspectType, + basicAspectTypeExtension, + speedIndicators, + speedIndicatorsAnnouncements, + directionIndicators, + directionIndicatorsAnnouncements, + downgradeInformation, + routeInformation, + intentionallyDark + ); + } + + protected override void WritePayloadToByteArray(byte[] bytes) + { + bytes[BASIC_ASPECT_TYPE_OFFSET] = (byte)BasicAspectType; + bytes[BASIC_ASPECT_TYPE_EXTENSION_OFFSET] = (byte)BasicAspectTypeExtension; + bytes[SPEED_INDICATORS_OFFSET] = (byte)SpeedIndicators; + bytes[SPEED_INDICATORS_ANNOUNCEMENTS_OFFSET] = (byte)SpeedIndicatorsAnnouncements; + bytes[DIRECTION_INDICATORS_OFFSET] = (byte)DirectionIndicators; + bytes[DIRECTION_INDICATORS_ANNOUNCEMENTS_OFFSET] = (byte)DirectionIndicatorsAnnouncements; + bytes[DOWNGRADE_INFORMATION_OFFSET] = (byte)DowngradeInformation; + bytes[ROUTE_INFORMATION_OFFSET] = (byte)RouteInformation; + bytes[INTENTIONALLY_DARK_OFFSET] = (byte)IntentionallyDark; + } + } +} diff --git a/src/Messages/NeuPro/LevelCrossingMessage.cs b/src/Messages/Deprecated/NeuPro/LevelCrossingMessage.cs similarity index 97% rename from src/Messages/NeuPro/LevelCrossingMessage.cs rename to src/Messages/Deprecated/NeuPro/LevelCrossingMessage.cs index b7770b4..50fd797 100644 --- a/src/Messages/NeuPro/LevelCrossingMessage.cs +++ b/src/Messages/Deprecated/NeuPro/LevelCrossingMessage.cs @@ -1,273 +1,273 @@ -namespace EulynxLive.Messages.NeuPro -{ - public enum LevelCrossingMessageType: ushort { - AnFsüCommand = 0x0055, - AusFsüCommand = 0x0057, - MeldungZustandGleisbezogenMessage = 0x0060, - MeldungZustandBüBezogenMessage = 0x0040, - - // Generic - InitializationRequest = 0x0011, - StartInitialization = 0x0021, - InitializationCompleted = 0x0022, - VersionCheckCommand = 0x0010, - VersionCheckMessage = 0x0020, - // Not sure if these exist: - PDIAvailable = 0x0029, - PDINotAvailable = 0x002A, - } - - public abstract class LevelCrossingMessage : NeuProMessage - { - public LevelCrossingMessage(string senderId, string receiverId) : base(senderId, receiverId) - {} - - public override ProtocolType ProtocolType => ProtocolType.LevelCrossing; - public override ushort MessageTypeRaw => (ushort) MessageType; - public abstract LevelCrossingMessageType MessageType { get; } - } - - public class AnFsüCommand : LevelCrossingMessage - { - private const int PLANUNGSPARAMETER_J_OFFSET = 43; - private const int EP_OFFSET = 44; - - public AnFsüCommand(string senderId, string receiverId, byte planungsparameterJ, byte ep) : base(senderId, receiverId) - { - PlanungsparameterJ = planungsparameterJ; - EP = ep; - } - - public byte PlanungsparameterJ { get; } - public byte EP { get; } - - public override LevelCrossingMessageType MessageType => LevelCrossingMessageType.AnFsüCommand; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) { - var planungsparameterJ = message[PLANUNGSPARAMETER_J_OFFSET]; - var ep = message[EP_OFFSET]; - return new AnFsüCommand(senderId, receiverId, planungsparameterJ, ep); - } - - protected override void NeuProWritePayloadToByteArray(byte[] bytes) - { - bytes[PLANUNGSPARAMETER_J_OFFSET] = PlanungsparameterJ; - bytes[EP_OFFSET] = EP; - bytes[45] = 0; - bytes[46] = 0; - } - } - - public class AusFsüCommand : LevelCrossingMessage - { - private const int PLANUNGSPARAMETER_J_OFFSET = 43; - public AusFsüCommand(string senderId, string receiverId, byte planungsparameterJ) : base(senderId, receiverId) - { - PlanungsparameterJ = planungsparameterJ; - } - - public byte PlanungsparameterJ { get; } - - public override LevelCrossingMessageType MessageType => LevelCrossingMessageType.AusFsüCommand; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) { - var planungsparameterJ = message[PLANUNGSPARAMETER_J_OFFSET]; - return new AusFsüCommand(senderId, receiverId, planungsparameterJ); - } - - protected override void NeuProWritePayloadToByteArray(byte[] bytes) - { - bytes[PLANUNGSPARAMETER_J_OFFSET] = PlanungsparameterJ; - bytes[44] = 0; - bytes[45] = 0; - bytes[46] = 0; - } - } - - public class MeldungZustandBüBezogenMessage : LevelCrossingMessage - { - public MeldungZustandBüBezogenMessage(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override LevelCrossingMessageType MessageType => LevelCrossingMessageType.MeldungZustandBüBezogenMessage; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) { - return new MeldungZustandBüBezogenMessage(senderId, receiverId); - } - - protected override void NeuProWritePayloadToByteArray(byte[] bytes) - { - } - } - - public class MeldungZustandGleisbezogenMessage : LevelCrossingMessage - { - private const int GLEISBEZOGENE_STÖRUNGSZUSTÄNDE_OFFSET = 50; - public MeldungZustandGleisbezogenMessage(string senderId, string receiverId, byte gleisbezogeneStörungszustände) : base(senderId, receiverId) - { - GleisbezogeneStörungszustände = gleisbezogeneStörungszustände; - } - - public byte GleisbezogeneStörungszustände { get; } - - public override LevelCrossingMessageType MessageType => LevelCrossingMessageType.MeldungZustandGleisbezogenMessage; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) { - var gleisbezogeneStörungszustände = message[GLEISBEZOGENE_STÖRUNGSZUSTÄNDE_OFFSET]; - return new MeldungZustandGleisbezogenMessage(senderId, receiverId, gleisbezogeneStörungszustände); - } - - protected override void NeuProWritePayloadToByteArray(byte[] bytes) - { - bytes[GLEISBEZOGENE_STÖRUNGSZUSTÄNDE_OFFSET] = GleisbezogeneStörungszustände; - } - } - - public class LevelCrossingInitializationRequestMessage : LevelCrossingMessage - { - public LevelCrossingInitializationRequestMessage(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override LevelCrossingMessageType MessageType => LevelCrossingMessageType.InitializationRequest; - - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) - { - return new LevelCrossingInitializationRequestMessage(senderId, receiverId); - } - - protected override void NeuProWritePayloadToByteArray(byte[] bytes) - { - - } - } - - public class LevelCrossingStartInitializationMessage : LevelCrossingMessage - { - public LevelCrossingStartInitializationMessage(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override LevelCrossingMessageType MessageType => LevelCrossingMessageType.StartInitialization; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) - { - return new LevelCrossingStartInitializationMessage(senderId, receiverId); - } - - protected override void NeuProWritePayloadToByteArray(byte[] bytes) - { - } - } - - public class LevelCrossingInitializationCompletedMessage : LevelCrossingMessage - { - public LevelCrossingInitializationCompletedMessage(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override LevelCrossingMessageType MessageType => LevelCrossingMessageType.InitializationCompleted; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) - { - return new LevelCrossingInitializationCompletedMessage(senderId, receiverId); - } - - protected override void NeuProWritePayloadToByteArray(byte[] bytes) - { - } - } - - public class LevelCrossingVersionCheckCommand : LevelCrossingMessage - { - private const int SENDER_PDI_VERSION_OFFSET = 43; - public LevelCrossingVersionCheckCommand(string senderId, string receiverId, byte senderPdiVersion) : base(senderId, receiverId) - { - SenderPdiVersion = senderPdiVersion; - } - - public override LevelCrossingMessageType MessageType => LevelCrossingMessageType.VersionCheckCommand; - - public byte SenderPdiVersion { get; } - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new LevelCrossingVersionCheckCommand(senderId, receiverId, message[SENDER_PDI_VERSION_OFFSET]); - - protected override void NeuProWritePayloadToByteArray(byte[] bytes) - { - bytes[SENDER_PDI_VERSION_OFFSET] = SenderPdiVersion; - } - } - - public class LevelCrossingVersionCheckMessage : LevelCrossingMessage - { - private const int RESULT_PDI_VERSION_CHECK_OFFSET = 43; - private const int SENDER_PDI_VERSION_OFFSET = 44; - private const int CHECKSUM_LENGTH_OFFSET = 45; - private const int CHECKSUM_DATA_OFFSET = 46; - public LevelCrossingVersionCheckMessage(string senderId, string receiverId, PdiVersionCheckResult resultPdiVersionCheck, byte senderPdiVersion, byte checksumLength) : base(senderId, receiverId) - { - ResultPdiVersionCheck = resultPdiVersionCheck; - SenderPdiVersion = senderPdiVersion; - ChecksumLength = checksumLength; - } - - public override LevelCrossingMessageType MessageType => LevelCrossingMessageType.VersionCheckMessage; - - public PdiVersionCheckResult ResultPdiVersionCheck { get; } - public byte SenderPdiVersion { get; } - public byte ChecksumLength { get; } - - // public override int Size => 46 + ChecksumLength; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) { - var resultPdiVersionCheck = (PdiVersionCheckResult) message[RESULT_PDI_VERSION_CHECK_OFFSET]; - var senderPdiVersion = message[SENDER_PDI_VERSION_OFFSET]; - var checksumLength = message[CHECKSUM_LENGTH_OFFSET]; - // var CHECKSUM_DATA_OFFSET = message[CHECKSUM_DATA_OFFSET]; - return new LevelCrossingVersionCheckMessage(senderId, receiverId, resultPdiVersionCheck, senderPdiVersion, checksumLength); - } - - protected override void NeuProWritePayloadToByteArray(byte[] bytes) - { - bytes[RESULT_PDI_VERSION_CHECK_OFFSET] = (byte)ResultPdiVersionCheck; - bytes[SENDER_PDI_VERSION_OFFSET] = SenderPdiVersion; - bytes[CHECKSUM_LENGTH_OFFSET] = ChecksumLength; - } - } - - public class LevelCrossingPDIAvailableMessage : LevelCrossingMessage - { - public LevelCrossingPDIAvailableMessage(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override LevelCrossingMessageType MessageType => LevelCrossingMessageType.PDIAvailable; - - public byte SenderPdiVersion { get; } - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new LevelCrossingPDIAvailableMessage(senderId, receiverId); - - protected override void NeuProWritePayloadToByteArray(byte[] bytes) - { - } - } - - public class LevelCrossingPDINotAvailableMessage : LevelCrossingMessage - { - public LevelCrossingPDINotAvailableMessage(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override LevelCrossingMessageType MessageType => LevelCrossingMessageType.PDINotAvailable; - - public byte SenderPdiVersion { get; } - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new LevelCrossingPDINotAvailableMessage(senderId, receiverId); - - protected override void NeuProWritePayloadToByteArray(byte[] bytes) - { - } - } -} +namespace EulynxLive.Messages.Deprecated.NeuPro +{ + public enum LevelCrossingMessageType: ushort { + AnFsüCommand = 0x0055, + AusFsüCommand = 0x0057, + MeldungZustandGleisbezogenMessage = 0x0060, + MeldungZustandBüBezogenMessage = 0x0040, + + // Generic + InitializationRequest = 0x0011, + StartInitialization = 0x0021, + InitializationCompleted = 0x0022, + VersionCheckCommand = 0x0010, + VersionCheckMessage = 0x0020, + // Not sure if these exist: + PDIAvailable = 0x0029, + PDINotAvailable = 0x002A, + } + + public abstract class LevelCrossingMessage : NeuProMessage + { + public LevelCrossingMessage(string senderId, string receiverId) : base(senderId, receiverId) + {} + + public override ProtocolType ProtocolType => ProtocolType.LevelCrossing; + public override ushort MessageTypeRaw => (ushort) MessageType; + public abstract LevelCrossingMessageType MessageType { get; } + } + + public class AnFsüCommand : LevelCrossingMessage + { + private const int PLANUNGSPARAMETER_J_OFFSET = 43; + private const int EP_OFFSET = 44; + + public AnFsüCommand(string senderId, string receiverId, byte planungsparameterJ, byte ep) : base(senderId, receiverId) + { + PlanungsparameterJ = planungsparameterJ; + EP = ep; + } + + public byte PlanungsparameterJ { get; } + public byte EP { get; } + + public override LevelCrossingMessageType MessageType => LevelCrossingMessageType.AnFsüCommand; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) { + var planungsparameterJ = message[PLANUNGSPARAMETER_J_OFFSET]; + var ep = message[EP_OFFSET]; + return new AnFsüCommand(senderId, receiverId, planungsparameterJ, ep); + } + + protected override void NeuProWritePayloadToByteArray(byte[] bytes) + { + bytes[PLANUNGSPARAMETER_J_OFFSET] = PlanungsparameterJ; + bytes[EP_OFFSET] = EP; + bytes[45] = 0; + bytes[46] = 0; + } + } + + public class AusFsüCommand : LevelCrossingMessage + { + private const int PLANUNGSPARAMETER_J_OFFSET = 43; + public AusFsüCommand(string senderId, string receiverId, byte planungsparameterJ) : base(senderId, receiverId) + { + PlanungsparameterJ = planungsparameterJ; + } + + public byte PlanungsparameterJ { get; } + + public override LevelCrossingMessageType MessageType => LevelCrossingMessageType.AusFsüCommand; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) { + var planungsparameterJ = message[PLANUNGSPARAMETER_J_OFFSET]; + return new AusFsüCommand(senderId, receiverId, planungsparameterJ); + } + + protected override void NeuProWritePayloadToByteArray(byte[] bytes) + { + bytes[PLANUNGSPARAMETER_J_OFFSET] = PlanungsparameterJ; + bytes[44] = 0; + bytes[45] = 0; + bytes[46] = 0; + } + } + + public class MeldungZustandBüBezogenMessage : LevelCrossingMessage + { + public MeldungZustandBüBezogenMessage(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override LevelCrossingMessageType MessageType => LevelCrossingMessageType.MeldungZustandBüBezogenMessage; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) { + return new MeldungZustandBüBezogenMessage(senderId, receiverId); + } + + protected override void NeuProWritePayloadToByteArray(byte[] bytes) + { + } + } + + public class MeldungZustandGleisbezogenMessage : LevelCrossingMessage + { + private const int GLEISBEZOGENE_STÖRUNGSZUSTÄNDE_OFFSET = 50; + public MeldungZustandGleisbezogenMessage(string senderId, string receiverId, byte gleisbezogeneStörungszustände) : base(senderId, receiverId) + { + GleisbezogeneStörungszustände = gleisbezogeneStörungszustände; + } + + public byte GleisbezogeneStörungszustände { get; } + + public override LevelCrossingMessageType MessageType => LevelCrossingMessageType.MeldungZustandGleisbezogenMessage; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) { + var gleisbezogeneStörungszustände = message[GLEISBEZOGENE_STÖRUNGSZUSTÄNDE_OFFSET]; + return new MeldungZustandGleisbezogenMessage(senderId, receiverId, gleisbezogeneStörungszustände); + } + + protected override void NeuProWritePayloadToByteArray(byte[] bytes) + { + bytes[GLEISBEZOGENE_STÖRUNGSZUSTÄNDE_OFFSET] = GleisbezogeneStörungszustände; + } + } + + public class LevelCrossingInitializationRequestMessage : LevelCrossingMessage + { + public LevelCrossingInitializationRequestMessage(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override LevelCrossingMessageType MessageType => LevelCrossingMessageType.InitializationRequest; + + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) + { + return new LevelCrossingInitializationRequestMessage(senderId, receiverId); + } + + protected override void NeuProWritePayloadToByteArray(byte[] bytes) + { + + } + } + + public class LevelCrossingStartInitializationMessage : LevelCrossingMessage + { + public LevelCrossingStartInitializationMessage(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override LevelCrossingMessageType MessageType => LevelCrossingMessageType.StartInitialization; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) + { + return new LevelCrossingStartInitializationMessage(senderId, receiverId); + } + + protected override void NeuProWritePayloadToByteArray(byte[] bytes) + { + } + } + + public class LevelCrossingInitializationCompletedMessage : LevelCrossingMessage + { + public LevelCrossingInitializationCompletedMessage(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override LevelCrossingMessageType MessageType => LevelCrossingMessageType.InitializationCompleted; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) + { + return new LevelCrossingInitializationCompletedMessage(senderId, receiverId); + } + + protected override void NeuProWritePayloadToByteArray(byte[] bytes) + { + } + } + + public class LevelCrossingVersionCheckCommand : LevelCrossingMessage + { + private const int SENDER_PDI_VERSION_OFFSET = 43; + public LevelCrossingVersionCheckCommand(string senderId, string receiverId, byte senderPdiVersion) : base(senderId, receiverId) + { + SenderPdiVersion = senderPdiVersion; + } + + public override LevelCrossingMessageType MessageType => LevelCrossingMessageType.VersionCheckCommand; + + public byte SenderPdiVersion { get; } + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new LevelCrossingVersionCheckCommand(senderId, receiverId, message[SENDER_PDI_VERSION_OFFSET]); + + protected override void NeuProWritePayloadToByteArray(byte[] bytes) + { + bytes[SENDER_PDI_VERSION_OFFSET] = SenderPdiVersion; + } + } + + public class LevelCrossingVersionCheckMessage : LevelCrossingMessage + { + private const int RESULT_PDI_VERSION_CHECK_OFFSET = 43; + private const int SENDER_PDI_VERSION_OFFSET = 44; + private const int CHECKSUM_LENGTH_OFFSET = 45; + private const int CHECKSUM_DATA_OFFSET = 46; + public LevelCrossingVersionCheckMessage(string senderId, string receiverId, PdiVersionCheckResult resultPdiVersionCheck, byte senderPdiVersion, byte checksumLength) : base(senderId, receiverId) + { + ResultPdiVersionCheck = resultPdiVersionCheck; + SenderPdiVersion = senderPdiVersion; + ChecksumLength = checksumLength; + } + + public override LevelCrossingMessageType MessageType => LevelCrossingMessageType.VersionCheckMessage; + + public PdiVersionCheckResult ResultPdiVersionCheck { get; } + public byte SenderPdiVersion { get; } + public byte ChecksumLength { get; } + + // public override int Size => 46 + ChecksumLength; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) { + var resultPdiVersionCheck = (PdiVersionCheckResult) message[RESULT_PDI_VERSION_CHECK_OFFSET]; + var senderPdiVersion = message[SENDER_PDI_VERSION_OFFSET]; + var checksumLength = message[CHECKSUM_LENGTH_OFFSET]; + // var CHECKSUM_DATA_OFFSET = message[CHECKSUM_DATA_OFFSET]; + return new LevelCrossingVersionCheckMessage(senderId, receiverId, resultPdiVersionCheck, senderPdiVersion, checksumLength); + } + + protected override void NeuProWritePayloadToByteArray(byte[] bytes) + { + bytes[RESULT_PDI_VERSION_CHECK_OFFSET] = (byte)ResultPdiVersionCheck; + bytes[SENDER_PDI_VERSION_OFFSET] = SenderPdiVersion; + bytes[CHECKSUM_LENGTH_OFFSET] = ChecksumLength; + } + } + + public class LevelCrossingPDIAvailableMessage : LevelCrossingMessage + { + public LevelCrossingPDIAvailableMessage(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override LevelCrossingMessageType MessageType => LevelCrossingMessageType.PDIAvailable; + + public byte SenderPdiVersion { get; } + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new LevelCrossingPDIAvailableMessage(senderId, receiverId); + + protected override void NeuProWritePayloadToByteArray(byte[] bytes) + { + } + } + + public class LevelCrossingPDINotAvailableMessage : LevelCrossingMessage + { + public LevelCrossingPDINotAvailableMessage(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override LevelCrossingMessageType MessageType => LevelCrossingMessageType.PDINotAvailable; + + public byte SenderPdiVersion { get; } + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new LevelCrossingPDINotAvailableMessage(senderId, receiverId); + + protected override void NeuProWritePayloadToByteArray(byte[] bytes) + { + } + } +} diff --git a/src/Messages/NeuPro/NeuProMessage.cs b/src/Messages/Deprecated/NeuPro/NeuProMessage.cs similarity index 89% rename from src/Messages/NeuPro/NeuProMessage.cs rename to src/Messages/Deprecated/NeuPro/NeuProMessage.cs index 343d936..6887f32 100644 --- a/src/Messages/NeuPro/NeuProMessage.cs +++ b/src/Messages/Deprecated/NeuPro/NeuProMessage.cs @@ -1,21 +1,21 @@ -namespace EulynxLive.Messages.NeuPro { - public abstract class NeuProMessage : EulynxMessage { - protected NeuProMessage(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override sealed int Size => 128; - - protected sealed override void WritePayloadToByteArray(byte[] bytes) - { - // Zero-initialize message buffer - for (var i = 43; i < Size; i++) { - bytes[i] = 0; - } - - NeuProWritePayloadToByteArray(bytes); - } - - protected abstract void NeuProWritePayloadToByteArray(byte[] bytes); - } -} +namespace EulynxLive.Messages.Deprecated.NeuPro { + public abstract class NeuProMessage : EulynxMessage { + protected NeuProMessage(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override sealed int Size => 128; + + protected sealed override void WritePayloadToByteArray(byte[] bytes) + { + // Zero-initialize message buffer + for (var i = 43; i < Size; i++) { + bytes[i] = 0; + } + + NeuProWritePayloadToByteArray(bytes); + } + + protected abstract void NeuProWritePayloadToByteArray(byte[] bytes); + } +} diff --git a/src/Messages/PointMessage.cs b/src/Messages/Deprecated/PointMessage.cs similarity index 96% rename from src/Messages/PointMessage.cs rename to src/Messages/Deprecated/PointMessage.cs index 11d855a..c4e2c22 100644 --- a/src/Messages/PointMessage.cs +++ b/src/Messages/Deprecated/PointMessage.cs @@ -1,263 +1,263 @@ -namespace EulynxLive.Messages -{ - public enum PointMessageType: ushort { - InitializationRequest = 0x0021, - StartInitialization = 0x0022, - InitializationCompleted = 0x0023, - VersionCheckCommand = 0x0024, - VersionCheckMessage = 0x0025, - PDIAvailable = 0x0029, - PDINotAvailable = 0x002A, - MovePointCommand = 0x0001, - PointPositionMessage = 0x000B, - TimeoutMessage = 0x000C, - } - - public abstract class PointMessage : EulynxMessage - { - public PointMessage(string senderId, string receiverId) : base(senderId, receiverId) - {} - - public override ProtocolType ProtocolType => ProtocolType.Point; - public override ushort MessageTypeRaw => (ushort) MessageType; - public abstract PointMessageType MessageType { get; } - } - public class PointVersionCheckCommand : PointMessage - { - private const int SENDER_PDI_VERSION_OFFSET = 43; - public PointVersionCheckCommand(string senderId, string receiverId, byte senderPdiVersion) : base(senderId, receiverId) - { - SenderPdiVersion = senderPdiVersion; - } - - public override PointMessageType MessageType => PointMessageType.VersionCheckCommand; - - public byte SenderPdiVersion { get; } - - public override int Size => 44; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new PointVersionCheckCommand(senderId, receiverId, message[SENDER_PDI_VERSION_OFFSET]); - - protected override void WritePayloadToByteArray(byte[] bytes) - { - bytes[SENDER_PDI_VERSION_OFFSET] = SenderPdiVersion; - } - } - - public class PointVersionCheckMessage : PointMessage - { - private const int RESULT_PDI_VERSION_CHECK_OFFSET = 43; - private const int SENDER_PDI_VERSION_OFFSET = 44; - private const int CHECKSUM_LENGTH_OFFSET = 45; - private const int CHECKSUM_DATA_OFFSET = 46; - public PointVersionCheckMessage(string senderId, string receiverId, PdiVersionCheckResult resultPdiVersionCheck, byte senderPdiVersion, byte checksumLength) : base(senderId, receiverId) - { - ResultPdiVersionCheck = resultPdiVersionCheck; - SenderPdiVersion = senderPdiVersion; - ChecksumLength = checksumLength; - } - - public override PointMessageType MessageType => PointMessageType.VersionCheckMessage; - - public PdiVersionCheckResult ResultPdiVersionCheck { get; } - public byte SenderPdiVersion { get; } - public byte ChecksumLength { get; } - - public override int Size => 46 + ChecksumLength; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) { - var resultPdiVersionCheck = (PdiVersionCheckResult) message[RESULT_PDI_VERSION_CHECK_OFFSET]; - var senderPdiVersion = message[SENDER_PDI_VERSION_OFFSET]; - var checksumLength = message[CHECKSUM_LENGTH_OFFSET]; - // var CHECKSUM_DATA_OFFSET = message[CHECKSUM_DATA_OFFSET]; - return new PointVersionCheckMessage(senderId, receiverId, resultPdiVersionCheck, senderPdiVersion, checksumLength); - } - - protected override void WritePayloadToByteArray(byte[] bytes) - { - bytes[RESULT_PDI_VERSION_CHECK_OFFSET] = (byte)ResultPdiVersionCheck; - bytes[SENDER_PDI_VERSION_OFFSET] = SenderPdiVersion; - bytes[CHECKSUM_LENGTH_OFFSET] = ChecksumLength; - } - } - - public class PointPDIAvailableMessage : PointMessage - { - public PointPDIAvailableMessage(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override PointMessageType MessageType => PointMessageType.PDIAvailable; - - public byte SenderPdiVersion { get; } - - public override int Size => 43; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new PointPDIAvailableMessage(senderId, receiverId); - - protected override void WritePayloadToByteArray(byte[] bytes) - { - } - } - - public class PointPDINotAvailableMessage : PointMessage - { - public PointPDINotAvailableMessage(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override PointMessageType MessageType => PointMessageType.PDINotAvailable; - - public byte SenderPdiVersion { get; } - - public override int Size => 43; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new PointPDINotAvailableMessage(senderId, receiverId); - - protected override void WritePayloadToByteArray(byte[] bytes) - { - } - } - - public class PointInitializationRequestMessage : PointMessage - { - public PointInitializationRequestMessage(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override PointMessageType MessageType => PointMessageType.InitializationRequest; - - public override int Size => 43; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) - { - return new PointInitializationRequestMessage(senderId, receiverId); - } - - protected override void WritePayloadToByteArray(byte[] bytes) - { - } - } - - public class PointStartInitializationMessage : PointMessage - { - public PointStartInitializationMessage(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override PointMessageType MessageType => PointMessageType.StartInitialization; - - public override int Size => 43; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) - { - return new PointStartInitializationMessage(senderId, receiverId); - } - - protected override void WritePayloadToByteArray(byte[] bytes) - { - } - } - - public class PointInitializationCompletedMessage : PointMessage - { - public PointInitializationCompletedMessage(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override PointMessageType MessageType => PointMessageType.InitializationCompleted; - - public override int Size => 43; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) - { - return new PointInitializationCompletedMessage(senderId, receiverId); - } - - protected override void WritePayloadToByteArray(byte[] bytes) - { - } - } - - public enum CommandedPointPosition : byte { - Right = 0x01, - Left = 0x02, - } - - public class PointMovePointCommand : PointMessage - { - private const int COMMANDED_POINT_POSITION_OFFSET = 43; - public override PointMessageType MessageType => PointMessageType.MovePointCommand; - public override int Size => 44; - public PointMovePointCommand(string senderId, string receiverId, CommandedPointPosition commandedPointPosition) : base(senderId, receiverId) - { - CommandedPointPosition = commandedPointPosition; - } - - public CommandedPointPosition CommandedPointPosition { get; } - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) - { - var commandedPointPosition = (CommandedPointPosition) message[COMMANDED_POINT_POSITION_OFFSET]; - - return new PointMovePointCommand(senderId, receiverId, commandedPointPosition); - } - - protected override void WritePayloadToByteArray(byte[] bytes) - { - bytes[COMMANDED_POINT_POSITION_OFFSET] = (byte)CommandedPointPosition; - } - } - - public enum ReportedPointPosition : byte { - Right = 0x01, - Left = 0x02, - NoEndPosition = 0x03, - Trailed = 0x04, - } - - public class PointPositionMessage : PointMessage - { - private const int REPORTED_POINT_POSITION_OFFSET = 43; - public override PointMessageType MessageType => PointMessageType.PointPositionMessage; - public override int Size => 44; - public PointPositionMessage(string senderId, string receiverId, ReportedPointPosition reportedPointPosition) : base(senderId, receiverId) - { - ReportedPointPosition = reportedPointPosition; - } - - public ReportedPointPosition ReportedPointPosition { get; } - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) - { - var reportedPointPosition = (ReportedPointPosition) message[REPORTED_POINT_POSITION_OFFSET]; - - return new PointPositionMessage(senderId, receiverId, reportedPointPosition); - } - - protected override void WritePayloadToByteArray(byte[] bytes) - { - bytes[REPORTED_POINT_POSITION_OFFSET] = (byte)ReportedPointPosition; - } - } - - public class PointTimeoutMessage : PointMessage - { - public override PointMessageType MessageType => PointMessageType.TimeoutMessage; - public override int Size => 43; - public PointTimeoutMessage(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public ReportedPointPosition ReportedPointPosition { get; } - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) - { - return new PointTimeoutMessage(senderId, receiverId); - } - - protected override void WritePayloadToByteArray(byte[] bytes) - { - } - } -} +namespace EulynxLive.Messages.Deprecated +{ + public enum PointMessageType: ushort { + InitializationRequest = 0x0021, + StartInitialization = 0x0022, + InitializationCompleted = 0x0023, + VersionCheckCommand = 0x0024, + VersionCheckMessage = 0x0025, + PDIAvailable = 0x0029, + PDINotAvailable = 0x002A, + MovePointCommand = 0x0001, + PointPositionMessage = 0x000B, + TimeoutMessage = 0x000C, + } + + public abstract class PointMessage : EulynxMessage + { + public PointMessage(string senderId, string receiverId) : base(senderId, receiverId) + {} + + public override ProtocolType ProtocolType => ProtocolType.Point; + public override ushort MessageTypeRaw => (ushort) MessageType; + public abstract PointMessageType MessageType { get; } + } + public class PointVersionCheckCommand : PointMessage + { + private const int SENDER_PDI_VERSION_OFFSET = 43; + public PointVersionCheckCommand(string senderId, string receiverId, byte senderPdiVersion) : base(senderId, receiverId) + { + SenderPdiVersion = senderPdiVersion; + } + + public override PointMessageType MessageType => PointMessageType.VersionCheckCommand; + + public byte SenderPdiVersion { get; } + + public override int Size => 44; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new PointVersionCheckCommand(senderId, receiverId, message[SENDER_PDI_VERSION_OFFSET]); + + protected override void WritePayloadToByteArray(byte[] bytes) + { + bytes[SENDER_PDI_VERSION_OFFSET] = SenderPdiVersion; + } + } + + public class PointVersionCheckMessage : PointMessage + { + private const int RESULT_PDI_VERSION_CHECK_OFFSET = 43; + private const int SENDER_PDI_VERSION_OFFSET = 44; + private const int CHECKSUM_LENGTH_OFFSET = 45; + private const int CHECKSUM_DATA_OFFSET = 46; + public PointVersionCheckMessage(string senderId, string receiverId, PdiVersionCheckResult resultPdiVersionCheck, byte senderPdiVersion, byte checksumLength) : base(senderId, receiverId) + { + ResultPdiVersionCheck = resultPdiVersionCheck; + SenderPdiVersion = senderPdiVersion; + ChecksumLength = checksumLength; + } + + public override PointMessageType MessageType => PointMessageType.VersionCheckMessage; + + public PdiVersionCheckResult ResultPdiVersionCheck { get; } + public byte SenderPdiVersion { get; } + public byte ChecksumLength { get; } + + public override int Size => 46 + ChecksumLength; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) { + var resultPdiVersionCheck = (PdiVersionCheckResult) message[RESULT_PDI_VERSION_CHECK_OFFSET]; + var senderPdiVersion = message[SENDER_PDI_VERSION_OFFSET]; + var checksumLength = message[CHECKSUM_LENGTH_OFFSET]; + // var CHECKSUM_DATA_OFFSET = message[CHECKSUM_DATA_OFFSET]; + return new PointVersionCheckMessage(senderId, receiverId, resultPdiVersionCheck, senderPdiVersion, checksumLength); + } + + protected override void WritePayloadToByteArray(byte[] bytes) + { + bytes[RESULT_PDI_VERSION_CHECK_OFFSET] = (byte)ResultPdiVersionCheck; + bytes[SENDER_PDI_VERSION_OFFSET] = SenderPdiVersion; + bytes[CHECKSUM_LENGTH_OFFSET] = ChecksumLength; + } + } + + public class PointPDIAvailableMessage : PointMessage + { + public PointPDIAvailableMessage(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override PointMessageType MessageType => PointMessageType.PDIAvailable; + + public byte SenderPdiVersion { get; } + + public override int Size => 43; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new PointPDIAvailableMessage(senderId, receiverId); + + protected override void WritePayloadToByteArray(byte[] bytes) + { + } + } + + public class PointPDINotAvailableMessage : PointMessage + { + public PointPDINotAvailableMessage(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override PointMessageType MessageType => PointMessageType.PDINotAvailable; + + public byte SenderPdiVersion { get; } + + public override int Size => 43; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new PointPDINotAvailableMessage(senderId, receiverId); + + protected override void WritePayloadToByteArray(byte[] bytes) + { + } + } + + public class PointInitializationRequestMessage : PointMessage + { + public PointInitializationRequestMessage(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override PointMessageType MessageType => PointMessageType.InitializationRequest; + + public override int Size => 43; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) + { + return new PointInitializationRequestMessage(senderId, receiverId); + } + + protected override void WritePayloadToByteArray(byte[] bytes) + { + } + } + + public class PointStartInitializationMessage : PointMessage + { + public PointStartInitializationMessage(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override PointMessageType MessageType => PointMessageType.StartInitialization; + + public override int Size => 43; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) + { + return new PointStartInitializationMessage(senderId, receiverId); + } + + protected override void WritePayloadToByteArray(byte[] bytes) + { + } + } + + public class PointInitializationCompletedMessage : PointMessage + { + public PointInitializationCompletedMessage(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override PointMessageType MessageType => PointMessageType.InitializationCompleted; + + public override int Size => 43; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) + { + return new PointInitializationCompletedMessage(senderId, receiverId); + } + + protected override void WritePayloadToByteArray(byte[] bytes) + { + } + } + + public enum CommandedPointPosition : byte { + Right = 0x01, + Left = 0x02, + } + + public class PointMovePointCommand : PointMessage + { + private const int COMMANDED_POINT_POSITION_OFFSET = 43; + public override PointMessageType MessageType => PointMessageType.MovePointCommand; + public override int Size => 44; + public PointMovePointCommand(string senderId, string receiverId, CommandedPointPosition commandedPointPosition) : base(senderId, receiverId) + { + CommandedPointPosition = commandedPointPosition; + } + + public CommandedPointPosition CommandedPointPosition { get; } + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) + { + var commandedPointPosition = (CommandedPointPosition) message[COMMANDED_POINT_POSITION_OFFSET]; + + return new PointMovePointCommand(senderId, receiverId, commandedPointPosition); + } + + protected override void WritePayloadToByteArray(byte[] bytes) + { + bytes[COMMANDED_POINT_POSITION_OFFSET] = (byte)CommandedPointPosition; + } + } + + public enum ReportedPointPosition : byte { + Right = 0x01, + Left = 0x02, + NoEndPosition = 0x03, + Trailed = 0x04, + } + + public class PointPositionMessage : PointMessage + { + private const int REPORTED_POINT_POSITION_OFFSET = 43; + public override PointMessageType MessageType => PointMessageType.PointPositionMessage; + public override int Size => 44; + public PointPositionMessage(string senderId, string receiverId, ReportedPointPosition reportedPointPosition) : base(senderId, receiverId) + { + ReportedPointPosition = reportedPointPosition; + } + + public ReportedPointPosition ReportedPointPosition { get; } + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) + { + var reportedPointPosition = (ReportedPointPosition) message[REPORTED_POINT_POSITION_OFFSET]; + + return new PointPositionMessage(senderId, receiverId, reportedPointPosition); + } + + protected override void WritePayloadToByteArray(byte[] bytes) + { + bytes[REPORTED_POINT_POSITION_OFFSET] = (byte)ReportedPointPosition; + } + } + + public class PointTimeoutMessage : PointMessage + { + public override PointMessageType MessageType => PointMessageType.TimeoutMessage; + public override int Size => 43; + public PointTimeoutMessage(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public ReportedPointPosition ReportedPointPosition { get; } + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) + { + return new PointTimeoutMessage(senderId, receiverId); + } + + protected override void WritePayloadToByteArray(byte[] bytes) + { + } + } +} diff --git a/src/Messages/ProtocolTypes.cs b/src/Messages/Deprecated/ProtocolTypes.cs similarity index 88% rename from src/Messages/ProtocolTypes.cs rename to src/Messages/Deprecated/ProtocolTypes.cs index 19b5c40..7d10611 100644 --- a/src/Messages/ProtocolTypes.cs +++ b/src/Messages/Deprecated/ProtocolTypes.cs @@ -1,17 +1,16 @@ -namespace EulynxLive.Messages -{ - public enum ProtocolType: byte { - // From: EU.SCI-XX.PDI.53 - CC = 0xD0, - AdjacentInterlockingSystem = 0x01, - TrainDetectionSystem = 0x20, - LightSignal = 0x30, - Point = 0x40, - RadioBlockCenter = 0x50, - LevelCrossing = 0x60, - SubsystemLevelCrossing = 0x70, - TrackworkerSafetySystem = 0x80, - GenericIO = 0x90, - ExternalLevelCrossingSystem = 0xC0, - } -} +namespace EulynxLive.Messages.Deprecated +{ + public enum ProtocolType: byte { + // From: EU.SCI-XX.PDI.53 + AdjacentInterlockingSystem = 0x01, + TrainDetectionSystem = 0x20, + LightSignal = 0x30, + Point = 0x40, + RadioBlockCenter = 0x50, + LevelCrossing = 0x60, + SubsystemLevelCrossing = 0x70, + TrackworkerSafetySystem = 0x80, + GenericIO = 0x90, + ExternalLevelCrossingSystem = 0xC0, + } +} diff --git a/src/Messages/TrainDetectionSystemMessage.cs b/src/Messages/Deprecated/TrainDetectionSystemMessage.cs similarity index 97% rename from src/Messages/TrainDetectionSystemMessage.cs rename to src/Messages/Deprecated/TrainDetectionSystemMessage.cs index 6424dbf..7f9699b 100644 --- a/src/Messages/TrainDetectionSystemMessage.cs +++ b/src/Messages/Deprecated/TrainDetectionSystemMessage.cs @@ -1,493 +1,493 @@ -using System; - -namespace EulynxLive.Messages -{ - public enum TrainDetectionSystemMessageType: ushort { - InitializationRequest = 0x0021, - StartInitialization = 0x0022, - InitializationCompleted = 0x0023, - VersionCheckCommand = 0x0024, - VersionCheckMessage = 0x0025, - PDIAvailable = 0x0029, - PDINotAvailable = 0x002A, - ForceClearCommand = 0x0001, - UpdateFillingLevelCommand = 0x0002, - DRFCCommand = 0x0003, - TDPActivationCommand = 0x0004, - TvpsOccupancyStatusMessage = 0x0007, - CommandRejectedMessage = 0x0006, - DRFCReceiptMessage = 0x0009, - TvpsFCPFailedMessage = 0x0010, - TvpsFCPAFailedMessage = 0x0011, - AdditionalInformationMessage = 0x0012, - TDPStatusMessage = 0x000B, - } - - public abstract class TrainDetectionSystemMessage : EulynxMessage - { - public TrainDetectionSystemMessage(string senderId, string receiverId) : base(senderId, receiverId) - {} - - public override ProtocolType ProtocolType => ProtocolType.TrainDetectionSystem; - public override ushort MessageTypeRaw => (ushort) MessageType; - public abstract TrainDetectionSystemMessageType MessageType { get; } - } - public class TrainDetectionSystemVersionCheckCommand : TrainDetectionSystemMessage - { - private const int SENDER_PDI_VERSION_OFFSET = 43; - public TrainDetectionSystemVersionCheckCommand(string senderId, string receiverId, byte senderPdiVersion) : base(senderId, receiverId) - { - SenderPdiVersion = senderPdiVersion; - } - - public override TrainDetectionSystemMessageType MessageType => TrainDetectionSystemMessageType.VersionCheckCommand; - - public byte SenderPdiVersion { get; } - - public override int Size => 44; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new TrainDetectionSystemVersionCheckCommand(senderId, receiverId, message[SENDER_PDI_VERSION_OFFSET]); - - protected override void WritePayloadToByteArray(byte[] bytes) - { - bytes[SENDER_PDI_VERSION_OFFSET] = SenderPdiVersion; - } - } - - public class TrainDetectionSystemVersionCheckMessage : TrainDetectionSystemMessage - { - private const int RESULT_PDI_VERSION_CHECK_OFFSET = 43; - private const int SENDER_PDI_VERSION_OFFSET = 44; - private const int CHECKSUM_LENGTH_OFFSET = 45; - private const int CHECKSUM_DATA_OFFSET = 46; - public TrainDetectionSystemVersionCheckMessage(string senderId, string receiverId, PdiVersionCheckResult resultPdiVersionCheck, byte senderPdiVersion, byte checksumLength) : base(senderId, receiverId) - { - ResultPdiVersionCheck = resultPdiVersionCheck; - SenderPdiVersion = senderPdiVersion; - ChecksumLength = checksumLength; - } - - public override TrainDetectionSystemMessageType MessageType => TrainDetectionSystemMessageType.VersionCheckMessage; - - public PdiVersionCheckResult ResultPdiVersionCheck { get; } - public byte SenderPdiVersion { get; } - public byte ChecksumLength { get; } - - public override int Size => 46 + ChecksumLength; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) { - var resultPdiVersionCheck = (PdiVersionCheckResult) message[RESULT_PDI_VERSION_CHECK_OFFSET]; - var senderPdiVersion = message[SENDER_PDI_VERSION_OFFSET]; - var checksumLength = message[CHECKSUM_LENGTH_OFFSET]; - // var CHECKSUM_DATA_OFFSET = message[CHECKSUM_DATA_OFFSET]; - return new TrainDetectionSystemVersionCheckMessage(senderId, receiverId, resultPdiVersionCheck, senderPdiVersion, checksumLength); - } - - protected override void WritePayloadToByteArray(byte[] bytes) - { - bytes[RESULT_PDI_VERSION_CHECK_OFFSET] = (byte)ResultPdiVersionCheck; - bytes[SENDER_PDI_VERSION_OFFSET] = SenderPdiVersion; - bytes[CHECKSUM_LENGTH_OFFSET] = ChecksumLength; - } - } - public class TrainDetectionSystemPDIAvailableMessage : TrainDetectionSystemMessage - { - public TrainDetectionSystemPDIAvailableMessage(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override TrainDetectionSystemMessageType MessageType => TrainDetectionSystemMessageType.PDIAvailable; - - public byte SenderPdiVersion { get; } - - public override int Size => 43; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new TrainDetectionSystemPDIAvailableMessage(senderId, receiverId); - - protected override void WritePayloadToByteArray(byte[] bytes) - { - } - } - - public class TrainDetectionSystemPDINotAvailableMessage : TrainDetectionSystemMessage - { - public TrainDetectionSystemPDINotAvailableMessage(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override TrainDetectionSystemMessageType MessageType => TrainDetectionSystemMessageType.PDINotAvailable; - - public byte SenderPdiVersion { get; } - - public override int Size => 43; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new TrainDetectionSystemPDINotAvailableMessage(senderId, receiverId); - - protected override void WritePayloadToByteArray(byte[] bytes) - { - } - } - - public class TrainDetectionSystemInitializationRequestMessage : TrainDetectionSystemMessage - { - public TrainDetectionSystemInitializationRequestMessage(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override TrainDetectionSystemMessageType MessageType => TrainDetectionSystemMessageType.InitializationRequest; - - public override int Size => 43; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) - { - return new TrainDetectionSystemInitializationRequestMessage(senderId, receiverId); - } - - protected override void WritePayloadToByteArray(byte[] bytes) - { - } - } - - public class TrainDetectionSystemStartInitializationMessage : TrainDetectionSystemMessage - { - public TrainDetectionSystemStartInitializationMessage(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override TrainDetectionSystemMessageType MessageType => TrainDetectionSystemMessageType.StartInitialization; - - public override int Size => 43; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) - { - return new TrainDetectionSystemStartInitializationMessage(senderId, receiverId); - } - - protected override void WritePayloadToByteArray(byte[] bytes) - { - } - } - - public class TrainDetectionSystemInitializationCompletedMessage : TrainDetectionSystemMessage - { - public TrainDetectionSystemInitializationCompletedMessage(string senderId, string receiverId) : base(senderId, receiverId) - { - } - - public override TrainDetectionSystemMessageType MessageType => TrainDetectionSystemMessageType.InitializationCompleted; - - public override int Size => 43; - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) - { - return new TrainDetectionSystemInitializationCompletedMessage(senderId, receiverId); - } - - protected override void WritePayloadToByteArray(byte[] bytes) - { - } - } - - public enum ForceClearMode : byte { - ForceClearU = 0x01, - ForceClearC = 0x02, - ForceClearPA = 0x03, - ForceClearP = 0x04, - AcknowledgementAfterForceClearPACommand = 0x05, - } - - public class TrainDetectionSystemForceClearCommand : TrainDetectionSystemMessage - { - - private const int FORCE_CLEAR_MODE_OFFSET = 43; - public override TrainDetectionSystemMessageType MessageType => TrainDetectionSystemMessageType.ForceClearCommand; - public override int Size => 44; - public TrainDetectionSystemForceClearCommand(string senderId, string receiverId, ForceClearMode forceClearMode) : base(senderId, receiverId) - { - ForceClearMode = forceClearMode; - } - - public ForceClearMode ForceClearMode { get; set; } - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) - { - var forceClearMode = (ForceClearMode) message[FORCE_CLEAR_MODE_OFFSET]; - return new TrainDetectionSystemForceClearCommand(senderId, receiverId, forceClearMode); - } - - protected override void WritePayloadToByteArray(byte[] bytes) - { - bytes[FORCE_CLEAR_MODE_OFFSET] = (byte)ForceClearMode; - } - } - - public class TrainDetectionSystemUpdateFillingLevelCommand : TrainDetectionSystemMessage - { - public override TrainDetectionSystemMessageType MessageType => TrainDetectionSystemMessageType.UpdateFillingLevelCommand; - public override int Size => 43; - public TrainDetectionSystemUpdateFillingLevelCommand(string senderId, string receiverId) : base(senderId, receiverId) - { - } - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) - { - return new TrainDetectionSystemUpdateFillingLevelCommand(senderId, receiverId); - } - - protected override void WritePayloadToByteArray(byte[] bytes) - { - } - } - - public class TrainDetectionSystemDRFCCommand : TrainDetectionSystemMessage - { - public override TrainDetectionSystemMessageType MessageType => TrainDetectionSystemMessageType.DRFCCommand; - public override int Size => 43; - public TrainDetectionSystemDRFCCommand(string senderId, string receiverId) : base(senderId, receiverId) - { - } - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) - { - return new TrainDetectionSystemDRFCCommand(senderId, receiverId); - } - - protected override void WritePayloadToByteArray(byte[] bytes) - { - } - } - - public enum DirectionOfPassing : byte { - ReferenceDirection = 0x01, - AgainstReferenceDirection = 0x02, - WithoutIndicatedDirection = 0x03, - } - - public class TrainDetectionSystemTDPActivationCommand : TrainDetectionSystemMessage - { - private const int DIRECTION_OF_PASSING_OFFSET = 43; - public override TrainDetectionSystemMessageType MessageType => TrainDetectionSystemMessageType.TDPActivationCommand; - public override int Size => 44; - public TrainDetectionSystemTDPActivationCommand(string senderId, string receiverId, DirectionOfPassing directionOfPassing) : base(senderId, receiverId) - { - DirectionOfPassing = directionOfPassing; - } - DirectionOfPassing DirectionOfPassing { get; set; } - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) - { - var directionOfPassing = (DirectionOfPassing) message[DIRECTION_OF_PASSING_OFFSET]; - return new TrainDetectionSystemTDPActivationCommand(senderId, receiverId, directionOfPassing); - } - - protected override void WritePayloadToByteArray(byte[] bytes) - { - bytes[DIRECTION_OF_PASSING_OFFSET] = (byte)DirectionOfPassing; - } - } - - public enum TvpsOccupancyStatus : byte { - Vacant = 0x01, - Occupied = 0x02, - Disturbed = 0x03, - WaitingForSweepingTrainAfterFcPAOrFcP = 0x04, - WaitingForAcknowledgementAfterFcPA = 0x05, - } - - public enum TvpsAbilityToBeForcedToClear : byte { - NotAbleToBeForcedToClear = 0x01, - AbleToBeForcedToClear = 0x02, - } - public enum TvpsPomStatus : byte { - PowerSupplyOk = 0x01, - PowerSupplyNok = 0x02, - NotApplicable = 0xff, - } - - public class TrainDetectionSystemTvpsOccupancyStatusMessage : TrainDetectionSystemMessage - { - private const int OCCUPANCY_STATUS_OFFSET = 43; - private const int ABILITY_TO_BE_FORCED_TO_CLEAR_OFFSET = 44; - private const int FILLING_LEVEL_OFFSET = 45; - - private const int POM_STATUS_OFFSET = 47; - public override TrainDetectionSystemMessageType MessageType => TrainDetectionSystemMessageType.TvpsOccupancyStatusMessage; - public override int Size => 48; - public TrainDetectionSystemTvpsOccupancyStatusMessage(string senderId, string receiverId, TvpsOccupancyStatus occupancyStatus, TvpsAbilityToBeForcedToClear abilityToBeForcedToClear, ushort fillingLevel, TvpsPomStatus pomStatus) : base(senderId, receiverId) - { - OccupancyStatus = occupancyStatus; - AbilityToBeForcedToClear = abilityToBeForcedToClear; - FillingLevel = fillingLevel; - PomStatus = pomStatus; - } - - public TvpsOccupancyStatus OccupancyStatus { get; set; } - public TvpsAbilityToBeForcedToClear AbilityToBeForcedToClear { get; set; } - public ushort FillingLevel { get; set; } - public TvpsPomStatus PomStatus { get; set; } - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) - { - var occupancyStatus = (TvpsOccupancyStatus) message[OCCUPANCY_STATUS_OFFSET]; - var abilityToBeForcedToClear = (TvpsAbilityToBeForcedToClear) message[ABILITY_TO_BE_FORCED_TO_CLEAR_OFFSET]; - var fillingLevel = BitConverter.ToUInt16( - new byte[2] { message[FILLING_LEVEL_OFFSET], message[FILLING_LEVEL_OFFSET + 1] }); - var pomStatus = (TvpsPomStatus) message[POM_STATUS_OFFSET]; - return new TrainDetectionSystemTvpsOccupancyStatusMessage(senderId, receiverId, occupancyStatus, abilityToBeForcedToClear, fillingLevel, pomStatus); - } - protected override void WritePayloadToByteArray(byte[] bytes) - { - bytes[OCCUPANCY_STATUS_OFFSET] = (byte)OccupancyStatus; - bytes[ABILITY_TO_BE_FORCED_TO_CLEAR_OFFSET] = (byte)AbilityToBeForcedToClear; - bytes[FILLING_LEVEL_OFFSET] = (byte)FillingLevel; - bytes[FILLING_LEVEL_OFFSET + 1] = (byte)(FillingLevel >> 8); - bytes[POM_STATUS_OFFSET] = (byte)PomStatus; - } - } - - public class TrainDetectionSystemTvpsOccupancyStatusMessageNeuPro : TrainDetectionSystemMessage - { - private const int OCCUPANCY_STATUS_OFFSET = 43; - public override TrainDetectionSystemMessageType MessageType => TrainDetectionSystemMessageType.TvpsOccupancyStatusMessage; - public override int Size => 45; - public TrainDetectionSystemTvpsOccupancyStatusMessageNeuPro(string senderId, string receiverId, TvpsOccupancyStatus occupancyStatus) : base(senderId, receiverId) - { - OccupancyStatus = occupancyStatus; - } - - public TvpsOccupancyStatus OccupancyStatus { get; set; } - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) - { - var occupancyStatus = (TvpsOccupancyStatus) message[OCCUPANCY_STATUS_OFFSET]; - return new TrainDetectionSystemTvpsOccupancyStatusMessageNeuPro(senderId, receiverId, occupancyStatus); - } - protected override void WritePayloadToByteArray(byte[] bytes) - { - bytes[OCCUPANCY_STATUS_OFFSET] = (byte)OccupancyStatus; - } - } - - public class TrainDetectionSystemTvpsOccupancyStatusMessageNeuProThales : TrainDetectionSystemMessage - { - private const int OCCUPANCY_STATUS_OFFSET = 43; - public override TrainDetectionSystemMessageType MessageType => TrainDetectionSystemMessageType.TvpsOccupancyStatusMessage; - public override int Size => 47; - public TrainDetectionSystemTvpsOccupancyStatusMessageNeuProThales(string senderId, string receiverId, TvpsOccupancyStatus occupancyStatus) : base(senderId, receiverId) - { - OccupancyStatus = occupancyStatus; - } - - public TvpsOccupancyStatus OccupancyStatus { get; set; } - - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) - { - var occupancyStatus = (TvpsOccupancyStatus) message[OCCUPANCY_STATUS_OFFSET]; - return new TrainDetectionSystemTvpsOccupancyStatusMessageNeuProThales(senderId, receiverId, occupancyStatus); - } - protected override void WritePayloadToByteArray(byte[] bytes) - { - bytes[OCCUPANCY_STATUS_OFFSET] = (byte)OccupancyStatus; - } - } - - public class TrainDetectionSystemCommandRejectedMessage : TrainDetectionSystemMessage - { - public override TrainDetectionSystemMessageType MessageType => TrainDetectionSystemMessageType.CommandRejectedMessage; - public override int Size => 43; - public TrainDetectionSystemCommandRejectedMessage(string senderId, string receiverId) : base(senderId, receiverId) - { - - } - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) - { - return new TrainDetectionSystemCommandRejectedMessage(senderId, receiverId); - } - protected override void WritePayloadToByteArray(byte[] bytes) - { - - } - } - public class TrainDetectionSystemDRFCReceiptMessage : TrainDetectionSystemMessage - { - public override TrainDetectionSystemMessageType MessageType => TrainDetectionSystemMessageType.DRFCReceiptMessage; - public override int Size => 43; - public TrainDetectionSystemDRFCReceiptMessage(string senderId, string receiverId) : base(senderId, receiverId) - { - - } - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) - { - return new TrainDetectionSystemDRFCReceiptMessage(senderId, receiverId); - } - protected override void WritePayloadToByteArray(byte[] bytes) - { - - } - } - public class TrainDetectionSystemTvpsFCPFailedMessage : TrainDetectionSystemMessage - { - public override TrainDetectionSystemMessageType MessageType => TrainDetectionSystemMessageType.TvpsFCPFailedMessage; - public override int Size => 43; - public TrainDetectionSystemTvpsFCPFailedMessage(string senderId, string receiverId) : base(senderId, receiverId) - { - - } - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) - { - return new TrainDetectionSystemTvpsFCPFailedMessage(senderId, receiverId); - } - protected override void WritePayloadToByteArray(byte[] bytes) - { - - } - } - public class TrainDetectionSystemTvpsFCPAFailedMessage : TrainDetectionSystemMessage - { - public override TrainDetectionSystemMessageType MessageType => TrainDetectionSystemMessageType.TvpsFCPAFailedMessage; - public override int Size => 43; - public TrainDetectionSystemTvpsFCPAFailedMessage(string senderId, string receiverId) : base(senderId, receiverId) - { - - } - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) - { - return new TrainDetectionSystemTvpsFCPAFailedMessage(senderId, receiverId); - } - protected override void WritePayloadToByteArray(byte[] bytes) - { - - } - } - public class TrainDetectionSystemAdditionalInformationMessage : TrainDetectionSystemMessage - { - public override TrainDetectionSystemMessageType MessageType => TrainDetectionSystemMessageType.AdditionalInformationMessage; - public override int Size => 43; - public TrainDetectionSystemAdditionalInformationMessage(string senderId, string receiverId) : base(senderId, receiverId) - { - - } - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) - { - return new TrainDetectionSystemAdditionalInformationMessage(senderId, receiverId); - } - protected override void WritePayloadToByteArray(byte[] bytes) - { - - } - } - public class TrainDetectionSystemTDPStatusMessage : TrainDetectionSystemMessage - { - public override TrainDetectionSystemMessageType MessageType => TrainDetectionSystemMessageType.TDPStatusMessage; - public override int Size => 43; - public TrainDetectionSystemTDPStatusMessage(string senderId, string receiverId) : base(senderId, receiverId) - { - - } - internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) - { - return new TrainDetectionSystemTDPStatusMessage(senderId, receiverId); - } - protected override void WritePayloadToByteArray(byte[] bytes) - { - - } - } -} +using System; + +namespace EulynxLive.Messages.Deprecated +{ + public enum TrainDetectionSystemMessageType: ushort { + InitializationRequest = 0x0021, + StartInitialization = 0x0022, + InitializationCompleted = 0x0023, + VersionCheckCommand = 0x0024, + VersionCheckMessage = 0x0025, + PDIAvailable = 0x0029, + PDINotAvailable = 0x002A, + ForceClearCommand = 0x0001, + UpdateFillingLevelCommand = 0x0002, + DRFCCommand = 0x0003, + TDPActivationCommand = 0x0004, + TvpsOccupancyStatusMessage = 0x0007, + CommandRejectedMessage = 0x0006, + DRFCReceiptMessage = 0x0009, + TvpsFCPFailedMessage = 0x0010, + TvpsFCPAFailedMessage = 0x0011, + AdditionalInformationMessage = 0x0012, + TDPStatusMessage = 0x000B, + } + + public abstract class TrainDetectionSystemMessage : EulynxMessage + { + public TrainDetectionSystemMessage(string senderId, string receiverId) : base(senderId, receiverId) + {} + + public override ProtocolType ProtocolType => ProtocolType.TrainDetectionSystem; + public override ushort MessageTypeRaw => (ushort) MessageType; + public abstract TrainDetectionSystemMessageType MessageType { get; } + } + public class TrainDetectionSystemVersionCheckCommand : TrainDetectionSystemMessage + { + private const int SENDER_PDI_VERSION_OFFSET = 43; + public TrainDetectionSystemVersionCheckCommand(string senderId, string receiverId, byte senderPdiVersion) : base(senderId, receiverId) + { + SenderPdiVersion = senderPdiVersion; + } + + public override TrainDetectionSystemMessageType MessageType => TrainDetectionSystemMessageType.VersionCheckCommand; + + public byte SenderPdiVersion { get; } + + public override int Size => 44; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new TrainDetectionSystemVersionCheckCommand(senderId, receiverId, message[SENDER_PDI_VERSION_OFFSET]); + + protected override void WritePayloadToByteArray(byte[] bytes) + { + bytes[SENDER_PDI_VERSION_OFFSET] = SenderPdiVersion; + } + } + + public class TrainDetectionSystemVersionCheckMessage : TrainDetectionSystemMessage + { + private const int RESULT_PDI_VERSION_CHECK_OFFSET = 43; + private const int SENDER_PDI_VERSION_OFFSET = 44; + private const int CHECKSUM_LENGTH_OFFSET = 45; + private const int CHECKSUM_DATA_OFFSET = 46; + public TrainDetectionSystemVersionCheckMessage(string senderId, string receiverId, PdiVersionCheckResult resultPdiVersionCheck, byte senderPdiVersion, byte checksumLength) : base(senderId, receiverId) + { + ResultPdiVersionCheck = resultPdiVersionCheck; + SenderPdiVersion = senderPdiVersion; + ChecksumLength = checksumLength; + } + + public override TrainDetectionSystemMessageType MessageType => TrainDetectionSystemMessageType.VersionCheckMessage; + + public PdiVersionCheckResult ResultPdiVersionCheck { get; } + public byte SenderPdiVersion { get; } + public byte ChecksumLength { get; } + + public override int Size => 46 + ChecksumLength; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) { + var resultPdiVersionCheck = (PdiVersionCheckResult) message[RESULT_PDI_VERSION_CHECK_OFFSET]; + var senderPdiVersion = message[SENDER_PDI_VERSION_OFFSET]; + var checksumLength = message[CHECKSUM_LENGTH_OFFSET]; + // var CHECKSUM_DATA_OFFSET = message[CHECKSUM_DATA_OFFSET]; + return new TrainDetectionSystemVersionCheckMessage(senderId, receiverId, resultPdiVersionCheck, senderPdiVersion, checksumLength); + } + + protected override void WritePayloadToByteArray(byte[] bytes) + { + bytes[RESULT_PDI_VERSION_CHECK_OFFSET] = (byte)ResultPdiVersionCheck; + bytes[SENDER_PDI_VERSION_OFFSET] = SenderPdiVersion; + bytes[CHECKSUM_LENGTH_OFFSET] = ChecksumLength; + } + } + public class TrainDetectionSystemPDIAvailableMessage : TrainDetectionSystemMessage + { + public TrainDetectionSystemPDIAvailableMessage(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override TrainDetectionSystemMessageType MessageType => TrainDetectionSystemMessageType.PDIAvailable; + + public byte SenderPdiVersion { get; } + + public override int Size => 43; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new TrainDetectionSystemPDIAvailableMessage(senderId, receiverId); + + protected override void WritePayloadToByteArray(byte[] bytes) + { + } + } + + public class TrainDetectionSystemPDINotAvailableMessage : TrainDetectionSystemMessage + { + public TrainDetectionSystemPDINotAvailableMessage(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override TrainDetectionSystemMessageType MessageType => TrainDetectionSystemMessageType.PDINotAvailable; + + public byte SenderPdiVersion { get; } + + public override int Size => 43; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) => new TrainDetectionSystemPDINotAvailableMessage(senderId, receiverId); + + protected override void WritePayloadToByteArray(byte[] bytes) + { + } + } + + public class TrainDetectionSystemInitializationRequestMessage : TrainDetectionSystemMessage + { + public TrainDetectionSystemInitializationRequestMessage(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override TrainDetectionSystemMessageType MessageType => TrainDetectionSystemMessageType.InitializationRequest; + + public override int Size => 43; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) + { + return new TrainDetectionSystemInitializationRequestMessage(senderId, receiverId); + } + + protected override void WritePayloadToByteArray(byte[] bytes) + { + } + } + + public class TrainDetectionSystemStartInitializationMessage : TrainDetectionSystemMessage + { + public TrainDetectionSystemStartInitializationMessage(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override TrainDetectionSystemMessageType MessageType => TrainDetectionSystemMessageType.StartInitialization; + + public override int Size => 43; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) + { + return new TrainDetectionSystemStartInitializationMessage(senderId, receiverId); + } + + protected override void WritePayloadToByteArray(byte[] bytes) + { + } + } + + public class TrainDetectionSystemInitializationCompletedMessage : TrainDetectionSystemMessage + { + public TrainDetectionSystemInitializationCompletedMessage(string senderId, string receiverId) : base(senderId, receiverId) + { + } + + public override TrainDetectionSystemMessageType MessageType => TrainDetectionSystemMessageType.InitializationCompleted; + + public override int Size => 43; + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) + { + return new TrainDetectionSystemInitializationCompletedMessage(senderId, receiverId); + } + + protected override void WritePayloadToByteArray(byte[] bytes) + { + } + } + + public enum ForceClearMode : byte { + ForceClearU = 0x01, + ForceClearC = 0x02, + ForceClearPA = 0x03, + ForceClearP = 0x04, + AcknowledgementAfterForceClearPACommand = 0x05, + } + + public class TrainDetectionSystemForceClearCommand : TrainDetectionSystemMessage + { + + private const int FORCE_CLEAR_MODE_OFFSET = 43; + public override TrainDetectionSystemMessageType MessageType => TrainDetectionSystemMessageType.ForceClearCommand; + public override int Size => 44; + public TrainDetectionSystemForceClearCommand(string senderId, string receiverId, ForceClearMode forceClearMode) : base(senderId, receiverId) + { + ForceClearMode = forceClearMode; + } + + public ForceClearMode ForceClearMode { get; set; } + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) + { + var forceClearMode = (ForceClearMode) message[FORCE_CLEAR_MODE_OFFSET]; + return new TrainDetectionSystemForceClearCommand(senderId, receiverId, forceClearMode); + } + + protected override void WritePayloadToByteArray(byte[] bytes) + { + bytes[FORCE_CLEAR_MODE_OFFSET] = (byte)ForceClearMode; + } + } + + public class TrainDetectionSystemUpdateFillingLevelCommand : TrainDetectionSystemMessage + { + public override TrainDetectionSystemMessageType MessageType => TrainDetectionSystemMessageType.UpdateFillingLevelCommand; + public override int Size => 43; + public TrainDetectionSystemUpdateFillingLevelCommand(string senderId, string receiverId) : base(senderId, receiverId) + { + } + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) + { + return new TrainDetectionSystemUpdateFillingLevelCommand(senderId, receiverId); + } + + protected override void WritePayloadToByteArray(byte[] bytes) + { + } + } + + public class TrainDetectionSystemDRFCCommand : TrainDetectionSystemMessage + { + public override TrainDetectionSystemMessageType MessageType => TrainDetectionSystemMessageType.DRFCCommand; + public override int Size => 43; + public TrainDetectionSystemDRFCCommand(string senderId, string receiverId) : base(senderId, receiverId) + { + } + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) + { + return new TrainDetectionSystemDRFCCommand(senderId, receiverId); + } + + protected override void WritePayloadToByteArray(byte[] bytes) + { + } + } + + public enum DirectionOfPassing : byte { + ReferenceDirection = 0x01, + AgainstReferenceDirection = 0x02, + WithoutIndicatedDirection = 0x03, + } + + public class TrainDetectionSystemTDPActivationCommand : TrainDetectionSystemMessage + { + private const int DIRECTION_OF_PASSING_OFFSET = 43; + public override TrainDetectionSystemMessageType MessageType => TrainDetectionSystemMessageType.TDPActivationCommand; + public override int Size => 44; + public TrainDetectionSystemTDPActivationCommand(string senderId, string receiverId, DirectionOfPassing directionOfPassing) : base(senderId, receiverId) + { + DirectionOfPassing = directionOfPassing; + } + DirectionOfPassing DirectionOfPassing { get; set; } + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) + { + var directionOfPassing = (DirectionOfPassing) message[DIRECTION_OF_PASSING_OFFSET]; + return new TrainDetectionSystemTDPActivationCommand(senderId, receiverId, directionOfPassing); + } + + protected override void WritePayloadToByteArray(byte[] bytes) + { + bytes[DIRECTION_OF_PASSING_OFFSET] = (byte)DirectionOfPassing; + } + } + + public enum TvpsOccupancyStatus : byte { + Vacant = 0x01, + Occupied = 0x02, + Disturbed = 0x03, + WaitingForSweepingTrainAfterFcPAOrFcP = 0x04, + WaitingForAcknowledgementAfterFcPA = 0x05, + } + + public enum TvpsAbilityToBeForcedToClear : byte { + NotAbleToBeForcedToClear = 0x01, + AbleToBeForcedToClear = 0x02, + } + public enum TvpsPomStatus : byte { + PowerSupplyOk = 0x01, + PowerSupplyNok = 0x02, + NotApplicable = 0xff, + } + + public class TrainDetectionSystemTvpsOccupancyStatusMessage : TrainDetectionSystemMessage + { + private const int OCCUPANCY_STATUS_OFFSET = 43; + private const int ABILITY_TO_BE_FORCED_TO_CLEAR_OFFSET = 44; + private const int FILLING_LEVEL_OFFSET = 45; + + private const int POM_STATUS_OFFSET = 47; + public override TrainDetectionSystemMessageType MessageType => TrainDetectionSystemMessageType.TvpsOccupancyStatusMessage; + public override int Size => 48; + public TrainDetectionSystemTvpsOccupancyStatusMessage(string senderId, string receiverId, TvpsOccupancyStatus occupancyStatus, TvpsAbilityToBeForcedToClear abilityToBeForcedToClear, ushort fillingLevel, TvpsPomStatus pomStatus) : base(senderId, receiverId) + { + OccupancyStatus = occupancyStatus; + AbilityToBeForcedToClear = abilityToBeForcedToClear; + FillingLevel = fillingLevel; + PomStatus = pomStatus; + } + + public TvpsOccupancyStatus OccupancyStatus { get; set; } + public TvpsAbilityToBeForcedToClear AbilityToBeForcedToClear { get; set; } + public ushort FillingLevel { get; set; } + public TvpsPomStatus PomStatus { get; set; } + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) + { + var occupancyStatus = (TvpsOccupancyStatus) message[OCCUPANCY_STATUS_OFFSET]; + var abilityToBeForcedToClear = (TvpsAbilityToBeForcedToClear) message[ABILITY_TO_BE_FORCED_TO_CLEAR_OFFSET]; + var fillingLevel = BitConverter.ToUInt16( + new byte[2] { message[FILLING_LEVEL_OFFSET], message[FILLING_LEVEL_OFFSET + 1] }); + var pomStatus = (TvpsPomStatus) message[POM_STATUS_OFFSET]; + return new TrainDetectionSystemTvpsOccupancyStatusMessage(senderId, receiverId, occupancyStatus, abilityToBeForcedToClear, fillingLevel, pomStatus); + } + protected override void WritePayloadToByteArray(byte[] bytes) + { + bytes[OCCUPANCY_STATUS_OFFSET] = (byte)OccupancyStatus; + bytes[ABILITY_TO_BE_FORCED_TO_CLEAR_OFFSET] = (byte)AbilityToBeForcedToClear; + bytes[FILLING_LEVEL_OFFSET] = (byte)FillingLevel; + bytes[FILLING_LEVEL_OFFSET + 1] = (byte)(FillingLevel >> 8); + bytes[POM_STATUS_OFFSET] = (byte)PomStatus; + } + } + + public class TrainDetectionSystemTvpsOccupancyStatusMessageNeuPro : TrainDetectionSystemMessage + { + private const int OCCUPANCY_STATUS_OFFSET = 43; + public override TrainDetectionSystemMessageType MessageType => TrainDetectionSystemMessageType.TvpsOccupancyStatusMessage; + public override int Size => 45; + public TrainDetectionSystemTvpsOccupancyStatusMessageNeuPro(string senderId, string receiverId, TvpsOccupancyStatus occupancyStatus) : base(senderId, receiverId) + { + OccupancyStatus = occupancyStatus; + } + + public TvpsOccupancyStatus OccupancyStatus { get; set; } + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) + { + var occupancyStatus = (TvpsOccupancyStatus) message[OCCUPANCY_STATUS_OFFSET]; + return new TrainDetectionSystemTvpsOccupancyStatusMessageNeuPro(senderId, receiverId, occupancyStatus); + } + protected override void WritePayloadToByteArray(byte[] bytes) + { + bytes[OCCUPANCY_STATUS_OFFSET] = (byte)OccupancyStatus; + } + } + + public class TrainDetectionSystemTvpsOccupancyStatusMessageNeuProThales : TrainDetectionSystemMessage + { + private const int OCCUPANCY_STATUS_OFFSET = 43; + public override TrainDetectionSystemMessageType MessageType => TrainDetectionSystemMessageType.TvpsOccupancyStatusMessage; + public override int Size => 47; + public TrainDetectionSystemTvpsOccupancyStatusMessageNeuProThales(string senderId, string receiverId, TvpsOccupancyStatus occupancyStatus) : base(senderId, receiverId) + { + OccupancyStatus = occupancyStatus; + } + + public TvpsOccupancyStatus OccupancyStatus { get; set; } + + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) + { + var occupancyStatus = (TvpsOccupancyStatus) message[OCCUPANCY_STATUS_OFFSET]; + return new TrainDetectionSystemTvpsOccupancyStatusMessageNeuProThales(senderId, receiverId, occupancyStatus); + } + protected override void WritePayloadToByteArray(byte[] bytes) + { + bytes[OCCUPANCY_STATUS_OFFSET] = (byte)OccupancyStatus; + } + } + + public class TrainDetectionSystemCommandRejectedMessage : TrainDetectionSystemMessage + { + public override TrainDetectionSystemMessageType MessageType => TrainDetectionSystemMessageType.CommandRejectedMessage; + public override int Size => 43; + public TrainDetectionSystemCommandRejectedMessage(string senderId, string receiverId) : base(senderId, receiverId) + { + + } + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) + { + return new TrainDetectionSystemCommandRejectedMessage(senderId, receiverId); + } + protected override void WritePayloadToByteArray(byte[] bytes) + { + + } + } + public class TrainDetectionSystemDRFCReceiptMessage : TrainDetectionSystemMessage + { + public override TrainDetectionSystemMessageType MessageType => TrainDetectionSystemMessageType.DRFCReceiptMessage; + public override int Size => 43; + public TrainDetectionSystemDRFCReceiptMessage(string senderId, string receiverId) : base(senderId, receiverId) + { + + } + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) + { + return new TrainDetectionSystemDRFCReceiptMessage(senderId, receiverId); + } + protected override void WritePayloadToByteArray(byte[] bytes) + { + + } + } + public class TrainDetectionSystemTvpsFCPFailedMessage : TrainDetectionSystemMessage + { + public override TrainDetectionSystemMessageType MessageType => TrainDetectionSystemMessageType.TvpsFCPFailedMessage; + public override int Size => 43; + public TrainDetectionSystemTvpsFCPFailedMessage(string senderId, string receiverId) : base(senderId, receiverId) + { + + } + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) + { + return new TrainDetectionSystemTvpsFCPFailedMessage(senderId, receiverId); + } + protected override void WritePayloadToByteArray(byte[] bytes) + { + + } + } + public class TrainDetectionSystemTvpsFCPAFailedMessage : TrainDetectionSystemMessage + { + public override TrainDetectionSystemMessageType MessageType => TrainDetectionSystemMessageType.TvpsFCPAFailedMessage; + public override int Size => 43; + public TrainDetectionSystemTvpsFCPAFailedMessage(string senderId, string receiverId) : base(senderId, receiverId) + { + + } + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) + { + return new TrainDetectionSystemTvpsFCPAFailedMessage(senderId, receiverId); + } + protected override void WritePayloadToByteArray(byte[] bytes) + { + + } + } + public class TrainDetectionSystemAdditionalInformationMessage : TrainDetectionSystemMessage + { + public override TrainDetectionSystemMessageType MessageType => TrainDetectionSystemMessageType.AdditionalInformationMessage; + public override int Size => 43; + public TrainDetectionSystemAdditionalInformationMessage(string senderId, string receiverId) : base(senderId, receiverId) + { + + } + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) + { + return new TrainDetectionSystemAdditionalInformationMessage(senderId, receiverId); + } + protected override void WritePayloadToByteArray(byte[] bytes) + { + + } + } + public class TrainDetectionSystemTDPStatusMessage : TrainDetectionSystemMessage + { + public override TrainDetectionSystemMessageType MessageType => TrainDetectionSystemMessageType.TDPStatusMessage; + public override int Size => 43; + public TrainDetectionSystemTDPStatusMessage(string senderId, string receiverId) : base(senderId, receiverId) + { + + } + internal static EulynxMessage Parse(string senderId, string receiverId, byte[] message) + { + return new TrainDetectionSystemTDPStatusMessage(senderId, receiverId); + } + protected override void WritePayloadToByteArray(byte[] bytes) + { + + } + } +} From 60528f7381cf8ce4b8874154b187fa855ad95717 Mon Sep 17 00:00:00 2001 From: Robert Schmid Date: Sun, 3 Dec 2023 13:40:13 +0100 Subject: [PATCH 05/11] Style --- .../Point/PointTest.cs | 2 +- src/Point/Connections/Eulynx/PointState.cs | 36 ++++++++----------- 2 files changed, 16 insertions(+), 22 deletions(-) diff --git a/src/FieldElementSubsystems.Test/Point/PointTest.cs b/src/FieldElementSubsystems.Test/Point/PointTest.cs index 6bc4cda..8b62816 100644 --- a/src/FieldElementSubsystems.Test/Point/PointTest.cs +++ b/src/FieldElementSubsystems.Test/Point/PointTest.cs @@ -9,7 +9,7 @@ public class PointTest private EulynxLive.Point.Point CreateDefaultPoint(IPointToInterlockingConnection? connection = null) => new(_logger, _configuration, connection ?? Mock.Of(), () => Task.CompletedTask); - private Mock CreateDefaultMockConnection() { + private static Mock CreateDefaultMockConnection() { var mockConnection = new Mock(); mockConnection .Setup(m => m.SendPointPosition( diff --git a/src/Point/Connections/Eulynx/PointState.cs b/src/Point/Connections/Eulynx/PointState.cs index a0bada6..c74e1f5 100644 --- a/src/Point/Connections/Eulynx/PointState.cs +++ b/src/Point/Connections/Eulynx/PointState.cs @@ -1,21 +1,15 @@ - -using IPointToInterlockingConnection = EulynxLive.Point.Interfaces.IPointToInterlockingConnection; -using PointPosition = EulynxLive.Point.Interfaces.IPointToInterlockingConnection.PointPosition; -using DegradedPointPosition = EulynxLive.Point.Interfaces.IPointToInterlockingConnection.DegradedPointPosition; - -namespace EulynxLive.Point.Eulynx; -public abstract record PointState -{ - private IPointToInterlockingConnection.PointState _state; - public PP PointPosition { get => MapInterfacePointPositionToConcrete(_state.PointPosition); } - public DP DegradedPointPosition { get => MapInterfaceDegradedPointPositionToConcrete(_state.DegradedPointPosition); } - - public PointState(IPointToInterlockingConnection.PointState state) - { - _state = state; - } - - public abstract PP MapInterfacePointPositionToConcrete(PointPosition value); - - public abstract DP MapInterfaceDegradedPointPositionToConcrete(DegradedPointPosition value); -} + +using IPointToInterlockingConnection = EulynxLive.Point.Interfaces.IPointToInterlockingConnection; +using PointPosition = EulynxLive.Point.Interfaces.IPointToInterlockingConnection.PointPosition; +using DegradedPointPosition = EulynxLive.Point.Interfaces.IPointToInterlockingConnection.DegradedPointPosition; + +namespace EulynxLive.Point.Eulynx; +public abstract record PointState(IPointToInterlockingConnection.PointState State) +{ + public TPointPosition PointPosition => MapInterfacePointPositionToConcrete(State.PointPosition); + public TDegradedPointPosition DegradedPointPosition => MapInterfaceDegradedPointPositionToConcrete(State.DegradedPointPosition); + + public abstract TPointPosition MapInterfacePointPositionToConcrete(PointPosition value); + + public abstract TDegradedPointPosition MapInterfaceDegradedPointPositionToConcrete(DegradedPointPosition value); +} From c84330ed988d7923ee3d042778f3a2fd704bf401 Mon Sep 17 00:00:00 2001 From: Robert Schmid Date: Sun, 3 Dec 2023 13:45:39 +0100 Subject: [PATCH 06/11] Add editorconfig, add readonly modifiers --- .editorconfig | 364 ++++++++++++++++++ .../PointToInterlockingConnection.cs | 267 +++++++------ .../Eulynx/Baseline4R2/PointState.cs | 1 - .../PointToInterlockingConnection.cs | 267 +++++++------ .../Connections/Eulynx/ConnectionFactory.cs | 41 +- 5 files changed, 650 insertions(+), 290 deletions(-) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..4a9952c --- /dev/null +++ b/.editorconfig @@ -0,0 +1,364 @@ +root = true + +# All files +[*] +indent_style = space + +# Xml files +[*.xml] +indent_size = 2 + +# C# files +[*.cs] + +#### Core EditorConfig Options #### + +# Indentation and spacing +indent_size = 4 +tab_width = 4 + +# New line preferences +end_of_line = crlf +insert_final_newline = false + +#### .NET Coding Conventions #### +[*.{cs,vb}] + +# Organize usings +dotnet_separate_import_directive_groups = true +dotnet_sort_system_directives_first = true +file_header_template = unset + +# this. and Me. preferences +dotnet_style_qualification_for_event = false:silent +dotnet_style_qualification_for_field = false:silent +dotnet_style_qualification_for_method = false:silent +dotnet_style_qualification_for_property = false:silent + +# Language keywords vs BCL types preferences +dotnet_style_predefined_type_for_locals_parameters_members = true:silent +dotnet_style_predefined_type_for_member_access = true:silent + +# Parentheses preferences +dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent +dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent +dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent +dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent + +# Modifier preferences +dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent + +# Expression-level preferences +dotnet_style_coalesce_expression = true:suggestion +dotnet_style_collection_initializer = true:suggestion +dotnet_style_explicit_tuple_names = true:suggestion +dotnet_style_null_propagation = true:suggestion +dotnet_style_object_initializer = true:suggestion +dotnet_style_operator_placement_when_wrapping = beginning_of_line +dotnet_style_prefer_auto_properties = true:suggestion +dotnet_style_prefer_compound_assignment = true:suggestion +dotnet_style_prefer_conditional_expression_over_assignment = true:suggestion +dotnet_style_prefer_conditional_expression_over_return = true:suggestion +dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion +dotnet_style_prefer_inferred_tuple_names = true:suggestion +dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion +dotnet_style_prefer_simplified_boolean_expressions = true:suggestion +dotnet_style_prefer_simplified_interpolation = true:suggestion + +# Field preferences +dotnet_style_readonly_field = true:warning + +# Parameter preferences +dotnet_code_quality_unused_parameters = all:suggestion + +# Suppression preferences +dotnet_remove_unnecessary_suppression_exclusions = none + +#### C# Coding Conventions #### +[*.cs] + +# var preferences +csharp_style_var_elsewhere = false:silent +csharp_style_var_for_built_in_types = false:silent +csharp_style_var_when_type_is_apparent = false:silent + +# Expression-bodied members +csharp_style_expression_bodied_accessors = true:silent +csharp_style_expression_bodied_constructors = false:silent +csharp_style_expression_bodied_indexers = true:silent +csharp_style_expression_bodied_lambdas = true:suggestion +csharp_style_expression_bodied_local_functions = false:silent +csharp_style_expression_bodied_methods = false:silent +csharp_style_expression_bodied_operators = false:silent +csharp_style_expression_bodied_properties = true:silent + +# Pattern matching preferences +csharp_style_pattern_matching_over_as_with_null_check = true:suggestion +csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion +csharp_style_prefer_not_pattern = true:suggestion +csharp_style_prefer_pattern_matching = true:silent +csharp_style_prefer_switch_expression = true:suggestion + +# Null-checking preferences +csharp_style_conditional_delegate_call = true:suggestion + +# Modifier preferences +csharp_prefer_static_local_function = true:warning +csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:silent + +# Code-block preferences +csharp_prefer_braces = true:silent +csharp_prefer_simple_using_statement = true:suggestion + +# Expression-level preferences +csharp_prefer_simple_default_expression = true:suggestion +csharp_style_deconstructed_variable_declaration = true:suggestion +csharp_style_inlined_variable_declaration = true:suggestion +csharp_style_pattern_local_over_anonymous_function = true:suggestion +csharp_style_prefer_index_operator = true:suggestion +csharp_style_prefer_range_operator = true:suggestion +csharp_style_throw_expression = true:suggestion +csharp_style_unused_value_assignment_preference = discard_variable:suggestion +csharp_style_unused_value_expression_statement_preference = discard_variable:silent + +# 'using' directive preferences +csharp_using_directive_placement = outside_namespace:silent + +#### C# Formatting Rules #### + +# New line preferences +csharp_new_line_before_catch = true +csharp_new_line_before_else = true +csharp_new_line_before_finally = true +csharp_new_line_before_members_in_anonymous_types = true +csharp_new_line_before_members_in_object_initializers = true +csharp_new_line_before_open_brace = all +csharp_new_line_between_query_expression_clauses = true + +# Indentation preferences +csharp_indent_block_contents = true +csharp_indent_braces = false +csharp_indent_case_contents = true +csharp_indent_case_contents_when_block = true +csharp_indent_labels = one_less_than_current +csharp_indent_switch_labels = true + +# Space preferences +csharp_space_after_cast = false +csharp_space_after_colon_in_inheritance_clause = true +csharp_space_after_comma = true +csharp_space_after_dot = false +csharp_space_after_keywords_in_control_flow_statements = true +csharp_space_after_semicolon_in_for_statement = true +csharp_space_around_binary_operators = before_and_after +csharp_space_around_declaration_statements = false +csharp_space_before_colon_in_inheritance_clause = true +csharp_space_before_comma = false +csharp_space_before_dot = false +csharp_space_before_open_square_brackets = false +csharp_space_before_semicolon_in_for_statement = false +csharp_space_between_empty_square_brackets = false +csharp_space_between_method_call_empty_parameter_list_parentheses = false +csharp_space_between_method_call_name_and_opening_parenthesis = false +csharp_space_between_method_call_parameter_list_parentheses = false +csharp_space_between_method_declaration_empty_parameter_list_parentheses = false +csharp_space_between_method_declaration_name_and_open_parenthesis = false +csharp_space_between_method_declaration_parameter_list_parentheses = false +csharp_space_between_parentheses = false +csharp_space_between_square_brackets = false + +# Wrapping preferences +csharp_preserve_single_line_blocks = true +csharp_preserve_single_line_statements = true + +#### Naming styles #### +[*.{cs,vb}] + +# Naming rules + +dotnet_naming_rule.types_and_namespaces_should_be_pascalcase.severity = suggestion +dotnet_naming_rule.types_and_namespaces_should_be_pascalcase.symbols = types_and_namespaces +dotnet_naming_rule.types_and_namespaces_should_be_pascalcase.style = pascalcase + +dotnet_naming_rule.interfaces_should_be_ipascalcase.severity = suggestion +dotnet_naming_rule.interfaces_should_be_ipascalcase.symbols = interfaces +dotnet_naming_rule.interfaces_should_be_ipascalcase.style = ipascalcase + +dotnet_naming_rule.type_parameters_should_be_tpascalcase.severity = suggestion +dotnet_naming_rule.type_parameters_should_be_tpascalcase.symbols = type_parameters +dotnet_naming_rule.type_parameters_should_be_tpascalcase.style = tpascalcase + +dotnet_naming_rule.methods_should_be_pascalcase.severity = suggestion +dotnet_naming_rule.methods_should_be_pascalcase.symbols = methods +dotnet_naming_rule.methods_should_be_pascalcase.style = pascalcase + +dotnet_naming_rule.properties_should_be_pascalcase.severity = suggestion +dotnet_naming_rule.properties_should_be_pascalcase.symbols = properties +dotnet_naming_rule.properties_should_be_pascalcase.style = pascalcase + +dotnet_naming_rule.events_should_be_pascalcase.severity = suggestion +dotnet_naming_rule.events_should_be_pascalcase.symbols = events +dotnet_naming_rule.events_should_be_pascalcase.style = pascalcase + +dotnet_naming_rule.local_variables_should_be_camelcase.severity = suggestion +dotnet_naming_rule.local_variables_should_be_camelcase.symbols = local_variables +dotnet_naming_rule.local_variables_should_be_camelcase.style = camelcase + +dotnet_naming_rule.local_constants_should_be_camelcase.severity = suggestion +dotnet_naming_rule.local_constants_should_be_camelcase.symbols = local_constants +dotnet_naming_rule.local_constants_should_be_camelcase.style = camelcase + +dotnet_naming_rule.parameters_should_be_camelcase.severity = suggestion +dotnet_naming_rule.parameters_should_be_camelcase.symbols = parameters +dotnet_naming_rule.parameters_should_be_camelcase.style = camelcase + +dotnet_naming_rule.public_fields_should_be_pascalcase.severity = suggestion +dotnet_naming_rule.public_fields_should_be_pascalcase.symbols = public_fields +dotnet_naming_rule.public_fields_should_be_pascalcase.style = pascalcase + +dotnet_naming_rule.private_fields_should_be__camelcase.severity = suggestion +dotnet_naming_rule.private_fields_should_be__camelcase.symbols = private_fields +dotnet_naming_rule.private_fields_should_be__camelcase.style = _camelcase + +dotnet_naming_rule.private_static_fields_should_be_s_camelcase.severity = suggestion +dotnet_naming_rule.private_static_fields_should_be_s_camelcase.symbols = private_static_fields +dotnet_naming_rule.private_static_fields_should_be_s_camelcase.style = s_camelcase + +dotnet_naming_rule.public_constant_fields_should_be_pascalcase.severity = suggestion +dotnet_naming_rule.public_constant_fields_should_be_pascalcase.symbols = public_constant_fields +dotnet_naming_rule.public_constant_fields_should_be_pascalcase.style = pascalcase + +dotnet_naming_rule.private_constant_fields_should_be_pascalcase.severity = suggestion +dotnet_naming_rule.private_constant_fields_should_be_pascalcase.symbols = private_constant_fields +dotnet_naming_rule.private_constant_fields_should_be_pascalcase.style = pascalcase + +dotnet_naming_rule.public_static_readonly_fields_should_be_pascalcase.severity = suggestion +dotnet_naming_rule.public_static_readonly_fields_should_be_pascalcase.symbols = public_static_readonly_fields +dotnet_naming_rule.public_static_readonly_fields_should_be_pascalcase.style = pascalcase + +dotnet_naming_rule.private_static_readonly_fields_should_be_pascalcase.severity = suggestion +dotnet_naming_rule.private_static_readonly_fields_should_be_pascalcase.symbols = private_static_readonly_fields +dotnet_naming_rule.private_static_readonly_fields_should_be_pascalcase.style = pascalcase + +dotnet_naming_rule.enums_should_be_pascalcase.severity = suggestion +dotnet_naming_rule.enums_should_be_pascalcase.symbols = enums +dotnet_naming_rule.enums_should_be_pascalcase.style = pascalcase + +dotnet_naming_rule.local_functions_should_be_pascalcase.severity = suggestion +dotnet_naming_rule.local_functions_should_be_pascalcase.symbols = local_functions +dotnet_naming_rule.local_functions_should_be_pascalcase.style = pascalcase + +dotnet_naming_rule.non_field_members_should_be_pascalcase.severity = suggestion +dotnet_naming_rule.non_field_members_should_be_pascalcase.symbols = non_field_members +dotnet_naming_rule.non_field_members_should_be_pascalcase.style = pascalcase + +# Symbol specifications + +dotnet_naming_symbols.interfaces.applicable_kinds = interface +dotnet_naming_symbols.interfaces.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.interfaces.required_modifiers = + +dotnet_naming_symbols.enums.applicable_kinds = enum +dotnet_naming_symbols.enums.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.enums.required_modifiers = + +dotnet_naming_symbols.events.applicable_kinds = event +dotnet_naming_symbols.events.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.events.required_modifiers = + +dotnet_naming_symbols.methods.applicable_kinds = method +dotnet_naming_symbols.methods.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.methods.required_modifiers = + +dotnet_naming_symbols.properties.applicable_kinds = property +dotnet_naming_symbols.properties.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.properties.required_modifiers = + +dotnet_naming_symbols.public_fields.applicable_kinds = field +dotnet_naming_symbols.public_fields.applicable_accessibilities = public, internal +dotnet_naming_symbols.public_fields.required_modifiers = + +dotnet_naming_symbols.private_fields.applicable_kinds = field +dotnet_naming_symbols.private_fields.applicable_accessibilities = private, protected, protected_internal, private_protected +dotnet_naming_symbols.private_fields.required_modifiers = + +dotnet_naming_symbols.private_static_fields.applicable_kinds = field +dotnet_naming_symbols.private_static_fields.applicable_accessibilities = private, protected, protected_internal, private_protected +dotnet_naming_symbols.private_static_fields.required_modifiers = static + +dotnet_naming_symbols.types_and_namespaces.applicable_kinds = namespace, class, struct, interface, enum +dotnet_naming_symbols.types_and_namespaces.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.types_and_namespaces.required_modifiers = + +dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method +dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.non_field_members.required_modifiers = + +dotnet_naming_symbols.type_parameters.applicable_kinds = namespace +dotnet_naming_symbols.type_parameters.applicable_accessibilities = * +dotnet_naming_symbols.type_parameters.required_modifiers = + +dotnet_naming_symbols.private_constant_fields.applicable_kinds = field +dotnet_naming_symbols.private_constant_fields.applicable_accessibilities = private, protected, protected_internal, private_protected +dotnet_naming_symbols.private_constant_fields.required_modifiers = const + +dotnet_naming_symbols.local_variables.applicable_kinds = local +dotnet_naming_symbols.local_variables.applicable_accessibilities = local +dotnet_naming_symbols.local_variables.required_modifiers = + +dotnet_naming_symbols.local_constants.applicable_kinds = local +dotnet_naming_symbols.local_constants.applicable_accessibilities = local +dotnet_naming_symbols.local_constants.required_modifiers = const + +dotnet_naming_symbols.parameters.applicable_kinds = parameter +dotnet_naming_symbols.parameters.applicable_accessibilities = * +dotnet_naming_symbols.parameters.required_modifiers = + +dotnet_naming_symbols.public_constant_fields.applicable_kinds = field +dotnet_naming_symbols.public_constant_fields.applicable_accessibilities = public, internal +dotnet_naming_symbols.public_constant_fields.required_modifiers = const + +dotnet_naming_symbols.public_static_readonly_fields.applicable_kinds = field +dotnet_naming_symbols.public_static_readonly_fields.applicable_accessibilities = public, internal +dotnet_naming_symbols.public_static_readonly_fields.required_modifiers = readonly, static + +dotnet_naming_symbols.private_static_readonly_fields.applicable_kinds = field +dotnet_naming_symbols.private_static_readonly_fields.applicable_accessibilities = private, protected, protected_internal, private_protected +dotnet_naming_symbols.private_static_readonly_fields.required_modifiers = readonly, static + +dotnet_naming_symbols.local_functions.applicable_kinds = local_function +dotnet_naming_symbols.local_functions.applicable_accessibilities = * +dotnet_naming_symbols.local_functions.required_modifiers = + +# Naming styles + +dotnet_naming_style.pascalcase.required_prefix = +dotnet_naming_style.pascalcase.required_suffix = +dotnet_naming_style.pascalcase.word_separator = +dotnet_naming_style.pascalcase.capitalization = pascal_case + +dotnet_naming_style.ipascalcase.required_prefix = I +dotnet_naming_style.ipascalcase.required_suffix = +dotnet_naming_style.ipascalcase.word_separator = +dotnet_naming_style.ipascalcase.capitalization = pascal_case + +dotnet_naming_style.tpascalcase.required_prefix = T +dotnet_naming_style.tpascalcase.required_suffix = +dotnet_naming_style.tpascalcase.word_separator = +dotnet_naming_style.tpascalcase.capitalization = pascal_case + +dotnet_naming_style._camelcase.required_prefix = _ +dotnet_naming_style._camelcase.required_suffix = +dotnet_naming_style._camelcase.word_separator = +dotnet_naming_style._camelcase.capitalization = camel_case + +dotnet_naming_style.camelcase.required_prefix = +dotnet_naming_style.camelcase.required_suffix = +dotnet_naming_style.camelcase.word_separator = +dotnet_naming_style.camelcase.capitalization = camel_case + +dotnet_naming_style.s_camelcase.required_prefix = s_ +dotnet_naming_style.s_camelcase.required_suffix = +dotnet_naming_style.s_camelcase.word_separator = +dotnet_naming_style.s_camelcase.capitalization = camel_case + diff --git a/src/Point/Connections/Eulynx/Baseline4R1/PointToInterlockingConnection.cs b/src/Point/Connections/Eulynx/Baseline4R1/PointToInterlockingConnection.cs index 30e6701..bde3802 100644 --- a/src/Point/Connections/Eulynx/Baseline4R1/PointToInterlockingConnection.cs +++ b/src/Point/Connections/Eulynx/Baseline4R1/PointToInterlockingConnection.cs @@ -1,134 +1,133 @@ -using EulynxLive.Messages.Baseline4R1; -using Grpc.Core; -using IPointToInterlockingConnection = EulynxLive.Point.Interfaces.IPointToInterlockingConnection; -using PointState = EulynxLive.Point.Interfaces.IPointToInterlockingConnection.PointState; -using PointPosition = EulynxLive.Point.Interfaces.IPointToInterlockingConnection.PointPosition; -using EulynxLive.Point.Interfaces; - - -namespace EulynxLive.Point.EulynxBaseline4R1; - -public class PointToInterlockingConnection : IPointToInterlockingConnection -{ - private readonly ILogger _logger; - private readonly string _localId; - private readonly string _localRastaId; - private readonly string _remoteId; - private readonly string _remoteEndpoint; - IConnection? _currentConnection; - private CancellationTokenSource _timeout; - private int _timeoutDuration; - private CancellationToken _stoppingToken; - - public PointToInterlockingConnection( - ILogger logger, - IConfiguration configuration, - CancellationToken stoppingToken, int timeoutDuration = 10000) - { - _timeoutDuration = timeoutDuration; - _stoppingToken = stoppingToken; - _timeout = new CancellationTokenSource(); - _logger = logger; - _currentConnection = null; - - var config = configuration.GetSection("PointSettings").Get() ?? throw new Exception("No configuration provided"); - _localId = config.LocalId; - _localRastaId = config.LocalRastaId.ToString(); - _remoteId = config.RemoteId; - _remoteEndpoint = config.RemoteEndpoint; - } - - public void Connect() - { - ResetTimeout(); - _logger.LogTrace("Connecting..."); - var metadata = new Metadata { { "rasta-id", _localRastaId } }; - _currentConnection = new GrpcConnection(metadata, _remoteEndpoint, _timeout.Token); - } - - public async Task InitializeConnection(IPointToInterlockingConnection.PointState state, CancellationToken cancellationToken) - { - _logger.LogTrace("Connected. Waiting for request..."); - if (await ReceiveMessage(cancellationToken) == null) - { - _logger.LogError("Unexpected message."); - return false; - } - - var versionCheckResponse = new PointPdiVersionCheckMessage(_localId, _remoteId, PointPdiVersionCheckMessageResultPdiVersionCheck.PDIVersionsFromReceiverAndSenderDoMatch, /* TODO */ 0, 0, new byte[] { }); - await SendMessage(versionCheckResponse); - - if (await ReceiveMessage(cancellationToken) == null) - { - _logger.LogError("Unexpected message."); - return false; - } - - var startInitialization = new PointStartInitialisationMessage(_localId, _remoteId); - await SendMessage(startInitialization); - - var pointState = new PointState(state); - var initialPosition = new PointPointPositionMessage(_localId, _remoteId, pointState.PointPosition, pointState.DegradedPointPosition); - await SendMessage(initialPosition); - - var completeInitialization = new PointInitialisationCompletedMessage(_localId, _remoteId); - await SendMessage(completeInitialization); - return true; - } - - public async Task SendPointPosition(IPointToInterlockingConnection.PointState state) - { - var pointState = new PointState(state); - var response = new PointPointPositionMessage(_localId, _remoteId, pointState.PointPosition, pointState.DegradedPointPosition); - await SendMessage(response); - } - - async public Task SendTimeoutMessage() - { - var response = new PointTimeoutMessage(_localId, _remoteId); - await SendMessage(response); - } - - public async Task ReceivePointPosition(CancellationToken cancellationToken) - { - var message = await ReceiveMessage(cancellationToken); - - return (message != null)? message.CommandedPointPosition switch - { - PointMovePointCommandCommandedPointPosition.SubsystemElectronicInterlockingRequestsARightHandPointMoving => PointPosition.Right, - PointMovePointCommandCommandedPointPosition.SubsystemElectronicInterlockingRequestsALeftHandPointMoving => PointPosition.Left, - _ => throw new global::System.NotImplementedException(), - } : null; - } - - public void Dispose() - { - _currentConnection?.Dispose(); - } - - private async Task SendMessage(Message message) - { - if (_currentConnection == null) throw new InvalidOperationException("Connection is null. Did you call Connect()?"); - await _currentConnection.SendAsync(message.ToByteArray()); - } - - private async Task ReceiveMessage(CancellationToken cancellationToken) where T : Message - { - if (_currentConnection == null) throw new InvalidOperationException("Connection is null. Did you call Connect()?"); - ResetTimeout(); - - var message = Message.FromBytes(await _currentConnection.ReceiveAsync(_timeout.Token)); - if (message is not T) - { - _logger.LogError("Unexpected message: {}", message); - return null; - } - return message as T; - } - - private void ResetTimeout() - { - _timeout = CancellationTokenSource.CreateLinkedTokenSource(_stoppingToken); - _timeout.CancelAfter(_timeoutDuration); - } -} +using EulynxLive.Messages.Baseline4R1; +using Grpc.Core; +using IPointToInterlockingConnection = EulynxLive.Point.Interfaces.IPointToInterlockingConnection; +using PointPosition = EulynxLive.Point.Interfaces.IPointToInterlockingConnection.PointPosition; +using EulynxLive.Point.Interfaces; + + +namespace EulynxLive.Point.EulynxBaseline4R1; + +public class PointToInterlockingConnection : IPointToInterlockingConnection +{ + private readonly ILogger _logger; + private readonly string _localId; + private readonly string _localRastaId; + private readonly string _remoteId; + private readonly string _remoteEndpoint; + IConnection? _currentConnection; + private CancellationTokenSource _timeout; + private readonly int _timeoutDuration; + private readonly CancellationToken _stoppingToken; + + public PointToInterlockingConnection( + ILogger logger, + IConfiguration configuration, + CancellationToken stoppingToken, int timeoutDuration = 10000) + { + _timeoutDuration = timeoutDuration; + _stoppingToken = stoppingToken; + _timeout = new CancellationTokenSource(); + _logger = logger; + _currentConnection = null; + + var config = configuration.GetSection("PointSettings").Get() ?? throw new Exception("No configuration provided"); + _localId = config.LocalId; + _localRastaId = config.LocalRastaId.ToString(); + _remoteId = config.RemoteId; + _remoteEndpoint = config.RemoteEndpoint; + } + + public void Connect() + { + ResetTimeout(); + _logger.LogTrace("Connecting..."); + var metadata = new Metadata { { "rasta-id", _localRastaId } }; + _currentConnection = new GrpcConnection(metadata, _remoteEndpoint, _timeout.Token); + } + + public async Task InitializeConnection(IPointToInterlockingConnection.PointState state, CancellationToken cancellationToken) + { + _logger.LogTrace("Connected. Waiting for request..."); + if (await ReceiveMessage(cancellationToken) == null) + { + _logger.LogError("Unexpected message."); + return false; + } + + var versionCheckResponse = new PointPdiVersionCheckMessage(_localId, _remoteId, PointPdiVersionCheckMessageResultPdiVersionCheck.PDIVersionsFromReceiverAndSenderDoMatch, /* TODO */ 0, 0, new byte[] { }); + await SendMessage(versionCheckResponse); + + if (await ReceiveMessage(cancellationToken) == null) + { + _logger.LogError("Unexpected message."); + return false; + } + + var startInitialization = new PointStartInitialisationMessage(_localId, _remoteId); + await SendMessage(startInitialization); + + var pointState = new PointState(state); + var initialPosition = new PointPointPositionMessage(_localId, _remoteId, pointState.PointPosition, pointState.DegradedPointPosition); + await SendMessage(initialPosition); + + var completeInitialization = new PointInitialisationCompletedMessage(_localId, _remoteId); + await SendMessage(completeInitialization); + return true; + } + + public async Task SendPointPosition(IPointToInterlockingConnection.PointState state) + { + var pointState = new PointState(state); + var response = new PointPointPositionMessage(_localId, _remoteId, pointState.PointPosition, pointState.DegradedPointPosition); + await SendMessage(response); + } + + async public Task SendTimeoutMessage() + { + var response = new PointTimeoutMessage(_localId, _remoteId); + await SendMessage(response); + } + + public async Task ReceivePointPosition(CancellationToken cancellationToken) + { + var message = await ReceiveMessage(cancellationToken); + + return (message != null)? message.CommandedPointPosition switch + { + PointMovePointCommandCommandedPointPosition.SubsystemElectronicInterlockingRequestsARightHandPointMoving => PointPosition.Right, + PointMovePointCommandCommandedPointPosition.SubsystemElectronicInterlockingRequestsALeftHandPointMoving => PointPosition.Left, + _ => throw new global::System.NotImplementedException(), + } : null; + } + + public void Dispose() + { + _currentConnection?.Dispose(); + } + + private async Task SendMessage(Message message) + { + if (_currentConnection == null) throw new InvalidOperationException("Connection is null. Did you call Connect()?"); + await _currentConnection.SendAsync(message.ToByteArray()); + } + + private async Task ReceiveMessage(CancellationToken cancellationToken) where T : Message + { + if (_currentConnection == null) throw new InvalidOperationException("Connection is null. Did you call Connect()?"); + ResetTimeout(); + + var message = Message.FromBytes(await _currentConnection.ReceiveAsync(_timeout.Token)); + if (message is not T) + { + _logger.LogError("Unexpected message: {}", message); + return null; + } + return message as T; + } + + private void ResetTimeout() + { + _timeout = CancellationTokenSource.CreateLinkedTokenSource(_stoppingToken); + _timeout.CancelAfter(_timeoutDuration); + } +} diff --git a/src/Point/Connections/Eulynx/Baseline4R2/PointState.cs b/src/Point/Connections/Eulynx/Baseline4R2/PointState.cs index 50763b0..abbce53 100644 --- a/src/Point/Connections/Eulynx/Baseline4R2/PointState.cs +++ b/src/Point/Connections/Eulynx/Baseline4R2/PointState.cs @@ -3,7 +3,6 @@ using IPointToInterlockingConnection = EulynxLive.Point.Interfaces.IPointToInterlockingConnection; using PointPosition = EulynxLive.Point.Interfaces.IPointToInterlockingConnection.PointPosition; using DegradedPointPosition = EulynxLive.Point.Interfaces.IPointToInterlockingConnection.DegradedPointPosition; -using EulynxLive.Point.Eulynx; namespace EulynxLive.Point.EulynxBaseline4R2; diff --git a/src/Point/Connections/Eulynx/Baseline4R2/PointToInterlockingConnection.cs b/src/Point/Connections/Eulynx/Baseline4R2/PointToInterlockingConnection.cs index b8191dd..110010c 100644 --- a/src/Point/Connections/Eulynx/Baseline4R2/PointToInterlockingConnection.cs +++ b/src/Point/Connections/Eulynx/Baseline4R2/PointToInterlockingConnection.cs @@ -1,134 +1,133 @@ -using EulynxLive.Messages.Baseline4R2; -using Grpc.Core; -using IPointToInterlockingConnection = EulynxLive.Point.Interfaces.IPointToInterlockingConnection; -using PointState = EulynxLive.Point.Interfaces.IPointToInterlockingConnection.PointState; -using PointPosition = EulynxLive.Point.Interfaces.IPointToInterlockingConnection.PointPosition; -using EulynxLive.Point.Interfaces; - - -namespace EulynxLive.Point.EulynxBaseline4R2; - -public class PointToInterlockingConnection : IPointToInterlockingConnection -{ - private readonly ILogger _logger; - private readonly string _localId; - private readonly string _localRastaId; - private readonly string _remoteId; - private readonly string _remoteEndpoint; - IConnection? _currentConnection; - private CancellationTokenSource _timeout; - private int _timeoutDuration; - private CancellationToken _stoppingToken; - - public PointToInterlockingConnection( - ILogger logger, - IConfiguration configuration, - CancellationToken stoppingToken, int timeoutDuration = 10000) - { - _timeoutDuration = timeoutDuration; - _stoppingToken = stoppingToken; - _timeout = new CancellationTokenSource(); - _logger = logger; - _currentConnection = null; - - var config = configuration.GetSection("PointSettings").Get() ?? throw new Exception("No configuration provided"); - _localId = config.LocalId; - _localRastaId = config.LocalRastaId.ToString(); - _remoteId = config.RemoteId; - _remoteEndpoint = config.RemoteEndpoint; - } - - public void Connect() - { - ResetTimeout(); - _logger.LogTrace("Connecting..."); - var metadata = new Metadata { { "rasta-id", _localRastaId } }; - _currentConnection = new GrpcConnection(metadata, _remoteEndpoint, _timeout.Token); - } - - public async Task InitializeConnection(IPointToInterlockingConnection.PointState state, CancellationToken cancellationToken) - { - _logger.LogTrace("Connected. Waiting for request..."); - if (await ReceiveMessage(cancellationToken) == null) - { - _logger.LogError("Unexpected message."); - return false; - } - - var versionCheckResponse = new PointPdiVersionCheckMessage(_localId, _remoteId, PointPdiVersionCheckMessageResultPdiVersionCheck.PDIVersionsFromReceiverAndSenderDoMatch, /* TODO */ 0, 0, new byte[] { }); - await SendMessage(versionCheckResponse); - - if (await ReceiveMessage(cancellationToken) == null) - { - _logger.LogError("Unexpected message."); - return false; - } - - var startInitialization = new PointStartInitialisationMessage(_localId, _remoteId); - await SendMessage(startInitialization); - - var pointState = new PointState(state); - var initialPosition = new PointPointPositionMessage(_localId, _remoteId, pointState.PointPosition, pointState.DegradedPointPosition); - await SendMessage(initialPosition); - - var completeInitialization = new PointInitialisationCompletedMessage(_localId, _remoteId); - await SendMessage(completeInitialization); - return true; - } - - public async Task SendPointPosition(IPointToInterlockingConnection.PointState state) - { - var pointState = new PointState(state); - var response = new PointPointPositionMessage(_localId, _remoteId, pointState.PointPosition, pointState.DegradedPointPosition); - await SendMessage(response); - } - - async public Task SendTimeoutMessage() - { - var response = new PointAbilityToMovePointMessage(_localId, _remoteId, PointAbilityToMovePointMessageReportedAbilityToMovePointStatus.PointIsUnableToMove); - await SendMessage(response); - } - - public async Task ReceivePointPosition(CancellationToken cancellationToken) - { - var message = await ReceiveMessage(cancellationToken); - - return (message != null)? message.CommandedPointPosition switch - { - PointMovePointCommandCommandedPointPosition.SubsystemElectronicInterlockingRequestsARightHandPointMoving => PointPosition.Right, - PointMovePointCommandCommandedPointPosition.SubsystemElectronicInterlockingRequestsALeftHandPointMoving => PointPosition.Left, - _ => throw new global::System.NotImplementedException(), - } : null; - } - - public void Dispose() - { - _currentConnection?.Dispose(); - } - - private async Task SendMessage(Message message) - { - if (_currentConnection == null) throw new InvalidOperationException("Connection is null. Did you call Connect()?"); - await _currentConnection.SendAsync(message.ToByteArray()); - } - - private async Task ReceiveMessage(CancellationToken cancellationToken) where T : Message - { - if (_currentConnection == null) throw new InvalidOperationException("Connection is null. Did you call Connect()?"); - ResetTimeout(); - - var message = Message.FromBytes(await _currentConnection.ReceiveAsync(_timeout.Token)); - if (message is not T) - { - _logger.LogError("Unexpected message: {}", message); - return null; - } - return message as T; - } - - private void ResetTimeout() - { - _timeout = CancellationTokenSource.CreateLinkedTokenSource(_stoppingToken); - _timeout.CancelAfter(_timeoutDuration); - } -} +using EulynxLive.Messages.Baseline4R2; +using Grpc.Core; +using IPointToInterlockingConnection = EulynxLive.Point.Interfaces.IPointToInterlockingConnection; +using PointPosition = EulynxLive.Point.Interfaces.IPointToInterlockingConnection.PointPosition; +using EulynxLive.Point.Interfaces; + + +namespace EulynxLive.Point.EulynxBaseline4R2; + +public class PointToInterlockingConnection : IPointToInterlockingConnection +{ + private readonly ILogger _logger; + private readonly string _localId; + private readonly string _localRastaId; + private readonly string _remoteId; + private readonly string _remoteEndpoint; + IConnection? _currentConnection; + private CancellationTokenSource _timeout; + private readonly int _timeoutDuration; + private readonly CancellationToken _stoppingToken; + + public PointToInterlockingConnection( + ILogger logger, + IConfiguration configuration, + CancellationToken stoppingToken, int timeoutDuration = 10000) + { + _timeoutDuration = timeoutDuration; + _stoppingToken = stoppingToken; + _timeout = new CancellationTokenSource(); + _logger = logger; + _currentConnection = null; + + var config = configuration.GetSection("PointSettings").Get() ?? throw new Exception("No configuration provided"); + _localId = config.LocalId; + _localRastaId = config.LocalRastaId.ToString(); + _remoteId = config.RemoteId; + _remoteEndpoint = config.RemoteEndpoint; + } + + public void Connect() + { + ResetTimeout(); + _logger.LogTrace("Connecting..."); + var metadata = new Metadata { { "rasta-id", _localRastaId } }; + _currentConnection = new GrpcConnection(metadata, _remoteEndpoint, _timeout.Token); + } + + public async Task InitializeConnection(IPointToInterlockingConnection.PointState state, CancellationToken cancellationToken) + { + _logger.LogTrace("Connected. Waiting for request..."); + if (await ReceiveMessage(cancellationToken) == null) + { + _logger.LogError("Unexpected message."); + return false; + } + + var versionCheckResponse = new PointPdiVersionCheckMessage(_localId, _remoteId, PointPdiVersionCheckMessageResultPdiVersionCheck.PDIVersionsFromReceiverAndSenderDoMatch, /* TODO */ 0, 0, new byte[] { }); + await SendMessage(versionCheckResponse); + + if (await ReceiveMessage(cancellationToken) == null) + { + _logger.LogError("Unexpected message."); + return false; + } + + var startInitialization = new PointStartInitialisationMessage(_localId, _remoteId); + await SendMessage(startInitialization); + + var pointState = new PointState(state); + var initialPosition = new PointPointPositionMessage(_localId, _remoteId, pointState.PointPosition, pointState.DegradedPointPosition); + await SendMessage(initialPosition); + + var completeInitialization = new PointInitialisationCompletedMessage(_localId, _remoteId); + await SendMessage(completeInitialization); + return true; + } + + public async Task SendPointPosition(IPointToInterlockingConnection.PointState state) + { + var pointState = new PointState(state); + var response = new PointPointPositionMessage(_localId, _remoteId, pointState.PointPosition, pointState.DegradedPointPosition); + await SendMessage(response); + } + + async public Task SendTimeoutMessage() + { + var response = new PointAbilityToMovePointMessage(_localId, _remoteId, PointAbilityToMovePointMessageReportedAbilityToMovePointStatus.PointIsUnableToMove); + await SendMessage(response); + } + + public async Task ReceivePointPosition(CancellationToken cancellationToken) + { + var message = await ReceiveMessage(cancellationToken); + + return (message != null)? message.CommandedPointPosition switch + { + PointMovePointCommandCommandedPointPosition.SubsystemElectronicInterlockingRequestsARightHandPointMoving => PointPosition.Right, + PointMovePointCommandCommandedPointPosition.SubsystemElectronicInterlockingRequestsALeftHandPointMoving => PointPosition.Left, + _ => throw new global::System.NotImplementedException(), + } : null; + } + + public void Dispose() + { + _currentConnection?.Dispose(); + } + + private async Task SendMessage(Message message) + { + if (_currentConnection == null) throw new InvalidOperationException("Connection is null. Did you call Connect()?"); + await _currentConnection.SendAsync(message.ToByteArray()); + } + + private async Task ReceiveMessage(CancellationToken cancellationToken) where T : Message + { + if (_currentConnection == null) throw new InvalidOperationException("Connection is null. Did you call Connect()?"); + ResetTimeout(); + + var message = Message.FromBytes(await _currentConnection.ReceiveAsync(_timeout.Token)); + if (message is not T) + { + _logger.LogError("Unexpected message: {}", message); + return null; + } + return message as T; + } + + private void ResetTimeout() + { + _timeout = CancellationTokenSource.CreateLinkedTokenSource(_stoppingToken); + _timeout.CancelAfter(_timeoutDuration); + } +} diff --git a/src/Point/Connections/Eulynx/ConnectionFactory.cs b/src/Point/Connections/Eulynx/ConnectionFactory.cs index 98c2c22..54ab951 100644 --- a/src/Point/Connections/Eulynx/ConnectionFactory.cs +++ b/src/Point/Connections/Eulynx/ConnectionFactory.cs @@ -1,21 +1,20 @@ - -using EulynxLive.Point.Interfaces; - -namespace EulynxLive.Point.Eulynx; - -public static class ConnectionFactory{ - public static IPointToInterlockingConnection CreateConnection (IServiceProvider x) where T: IPointToInterlockingConnection { - - if (typeof(T).IsAssignableFrom(typeof(EulynxBaseline4R1.PointToInterlockingConnection))) - { - return new EulynxBaseline4R1.PointToInterlockingConnection(x.GetRequiredService>(), x.GetRequiredService(), CancellationToken.None); - } - - if (typeof(T).IsAssignableFrom(typeof(EulynxBaseline4R2.PointToInterlockingConnection))) - { - return new EulynxBaseline4R2.PointToInterlockingConnection(x.GetRequiredService>(), x.GetRequiredService(), CancellationToken.None); - } - - throw new NotImplementedException("Trying to create unknown connection."); - } -} +using EulynxLive.Point.Interfaces; + +namespace EulynxLive.Point.Eulynx; + +public static class ConnectionFactory{ + public static IPointToInterlockingConnection CreateConnection (IServiceProvider x) where T : IPointToInterlockingConnection { + + if (typeof(T).IsAssignableFrom(typeof(EulynxBaseline4R1.PointToInterlockingConnection))) + { + return new EulynxBaseline4R1.PointToInterlockingConnection(x.GetRequiredService>(), x.GetRequiredService(), CancellationToken.None); + } + + if (typeof(T).IsAssignableFrom(typeof(EulynxBaseline4R2.PointToInterlockingConnection))) + { + return new EulynxBaseline4R2.PointToInterlockingConnection(x.GetRequiredService>(), x.GetRequiredService(), CancellationToken.None); + } + + throw new NotImplementedException("Trying to create unknown connection."); + } +} From 5036fde98f5f477ff793d5faae645fff0315c663 Mon Sep 17 00:00:00 2001 From: Benedikt Schenkel Date: Mon, 11 Dec 2023 15:19:59 +0100 Subject: [PATCH 07/11] add tests --- .../Connection/Baseline4R2Test.cs | 138 ++++++++++++++++++ .../PointToInterlockingConnection.cs | 3 +- 2 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 src/FieldElementSubsystems.Test/Connection/Baseline4R2Test.cs diff --git a/src/FieldElementSubsystems.Test/Connection/Baseline4R2Test.cs b/src/FieldElementSubsystems.Test/Connection/Baseline4R2Test.cs new file mode 100644 index 0000000..6ce5a16 --- /dev/null +++ b/src/FieldElementSubsystems.Test/Connection/Baseline4R2Test.cs @@ -0,0 +1,138 @@ +using EulynxLive.FieldElementSubsystems.Connections.EulynxBaseline4R2; +using EulynxLive.FieldElementSubsystems.Interfaces; +using EulynxLive.Messages.Baseline4R2; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using Moq; +using PointMovePointCommand = EulynxLive.Messages.Baseline4R2.PointMovePointCommand; + +public class Baseline4R1Test{ + + private static readonly IDictionary TestSettings = new Dictionary { + {"PointSettings:LocalId", "99W1" }, + {"PointSettings:LocalRastaId", "100" }, + {"PointSettings:RemoteId", "INTERLOCKING" }, + {"PointSettings:RemoteEndpoint", "http://localhost:50051" }, + {"PointSettings:AllPointMachinesCrucial", "false" }, + {"PointSettings:SimulateRandomTimeouts", "false" }, + }; + + private readonly IConfiguration _configuration = new ConfigurationBuilder() + .AddInMemoryCollection(TestSettings) + .Build(); + + [Fact] + public void Test_Connect(){ + // Arrange + var mockConnection = new Mock(); + var connection = new PointToInterlockingConnection(Mock.Of>(), _configuration, CancellationToken.None); + + // Act + connection.Connect(mockConnection.Object); + + // Assert + Assert.Equal(connection.CurrentConnection, mockConnection.Object); + } + + [Fact] + public async Task Test_Initialization(){ + // Arrange + var mockConnection = new Mock(); + mockConnection.SetupSequence(x => x.ReceiveAsync(It.IsAny())) + .ReturnsAsync(new PointPdiVersionCheckCommand("99W1","100", 0x01).ToByteArray()) + .ReturnsAsync(new PointInitialisationRequestCommand("99W1","100").ToByteArray()); + var args = new List(); + mockConnection.Setup(x => x.SendAsync(Capture.In(args))) + .Returns(Task.FromResult(0)); + + var connection = new PointToInterlockingConnection(Mock.Of>(), _configuration, CancellationToken.None); + + // Act + connection.Connect(mockConnection.Object); + await connection.InitializeConnection(new GenericPointState(){PointPosition = GenericPointPosition.Left, DegradedPointPosition = GenericDegradedPointPosition.NotDegraded}, CancellationToken.None); + + // Assert + mockConnection.Verify(v => v.ReceiveAsync(It.IsAny()), Times.Exactly(2)); + mockConnection.Verify(v => v.SendAsync(It.IsAny()), Times.Exactly(4)); + Assert.Equal(new PointPdiVersionCheckMessage("99W1________________", "INTERLOCKING________", PointPdiVersionCheckMessageResultPdiVersionCheck.PDIVersionsFromReceiverAndSenderDoMatch, /* TODO */ 0, 0, new byte[] { }).ToByteArray(), args[0]); + Assert.Equal(new PointStartInitialisationMessage("99W1________________", "INTERLOCKING________").ToByteArray(), args[1]); + Assert.Equal(new PointPointPositionMessage("99W1________________", "INTERLOCKING________", PointPointPositionMessageReportedPointPosition.PointIsInALeftHandPositionDefinedEndPosition, PointPointPositionMessageReportedDegradedPointPosition.PointIsNotInADegradedPosition).ToByteArray(), args[2]); + Assert.Equal(new PointInitialisationCompletedMessage("99W1________________", "INTERLOCKING________").ToByteArray(), args[3]); + } + + [Fact] + public async Task Test_Send_Position(){ + // Arrange + var mockConnection = new Mock(); + mockConnection.SetupSequence(x => x.ReceiveAsync(It.IsAny())) + .ReturnsAsync(new PointPdiVersionCheckCommand("99W1","100", 0x01).ToByteArray()) + .ReturnsAsync(new PointInitialisationRequestCommand("99W1","100").ToByteArray()); + var args = new List(); + mockConnection.Setup(x => x.SendAsync(Capture.In(args))) + .Returns(Task.FromResult(0)); + + var connection = new PointToInterlockingConnection(Mock.Of>(), _configuration, CancellationToken.None); + + // Act + connection.Connect(mockConnection.Object); + await connection.InitializeConnection(new GenericPointState(){PointPosition = GenericPointPosition.Left, DegradedPointPosition = GenericDegradedPointPosition.NotDegraded}, CancellationToken.None); + await connection.SendPointPosition(new GenericPointState(){PointPosition = GenericPointPosition.Right, DegradedPointPosition = GenericDegradedPointPosition.NotDegraded}); + await connection.SendPointPosition(new GenericPointState(){PointPosition = GenericPointPosition.Left, DegradedPointPosition = GenericDegradedPointPosition.NotDegraded}); + await connection.SendPointPosition(new GenericPointState(){PointPosition = GenericPointPosition.UnintendedPosition, DegradedPointPosition = GenericDegradedPointPosition.NotDegraded}); + await connection.SendPointPosition(new GenericPointState(){PointPosition = GenericPointPosition.NoEndPosition, DegradedPointPosition = GenericDegradedPointPosition.NotDegraded}); + + // Assert + mockConnection.Verify(v => v.SendAsync(It.IsAny()), Times.Exactly(8)); + Assert.Equal(new PointPointPositionMessage("99W1________________", "INTERLOCKING________", PointPointPositionMessageReportedPointPosition.PointIsInARightHandPositionDefinedEndPosition, PointPointPositionMessageReportedDegradedPointPosition.PointIsNotInADegradedPosition).ToByteArray(), args[4]); + Assert.Equal(new PointPointPositionMessage("99W1________________", "INTERLOCKING________", PointPointPositionMessageReportedPointPosition.PointIsInALeftHandPositionDefinedEndPosition, PointPointPositionMessageReportedDegradedPointPosition.PointIsNotInADegradedPosition).ToByteArray(), args[5]); + Assert.Equal(new PointPointPositionMessage("99W1________________", "INTERLOCKING________", PointPointPositionMessageReportedPointPosition.PointIsInUnintendedPosition, PointPointPositionMessageReportedDegradedPointPosition.PointIsNotInADegradedPosition).ToByteArray(), args[6]); + Assert.Equal(new PointPointPositionMessage("99W1________________", "INTERLOCKING________", PointPointPositionMessageReportedPointPosition.PointIsInNoEndPosition, PointPointPositionMessageReportedDegradedPointPosition.PointIsNotInADegradedPosition).ToByteArray(), args[7]); + } + + [Fact] + public async Task Test_Receive_Position(){ + // Arrange + var mockConnection = new Mock(); + mockConnection.SetupSequence(x => x.ReceiveAsync(It.IsAny())) + .ReturnsAsync(new PointPdiVersionCheckCommand("99W1","100", 0x01).ToByteArray()) + .ReturnsAsync(new PointInitialisationRequestCommand("99W1","100").ToByteArray()) + .ReturnsAsync(new PointMovePointCommand("99W1", "100", PointMovePointCommandCommandedPointPosition.SubsystemElectronicInterlockingRequestsALeftHandPointMoving).ToByteArray()) + .ReturnsAsync(new PointMovePointCommand("99W1", "100", PointMovePointCommandCommandedPointPosition.SubsystemElectronicInterlockingRequestsARightHandPointMoving).ToByteArray()); + + var connection = new PointToInterlockingConnection(Mock.Of>(), _configuration, CancellationToken.None); + + // Act + connection.Connect(mockConnection.Object); + await connection.InitializeConnection(new GenericPointState(){PointPosition = GenericPointPosition.Left, DegradedPointPosition = GenericDegradedPointPosition.NotDegraded}, CancellationToken.None); + var position1 = await connection.ReceivePointPosition(CancellationToken.None); + var position2 = await connection.ReceivePointPosition(CancellationToken.None); + + // Assert + mockConnection.Verify(v => v.ReceiveAsync(It.IsAny()), Times.Exactly(4)); + Assert.Equal(GenericPointPosition.Left, position1); + Assert.Equal(GenericPointPosition.Right, position2); + } + + [Fact] + public async Task Test_TimeoutMessage(){ + // Arrange + var mockConnection = new Mock(); + mockConnection.SetupSequence(x => x.ReceiveAsync(It.IsAny())) + .ReturnsAsync(new PointPdiVersionCheckCommand("99W1","100", 0x01).ToByteArray()) + .ReturnsAsync(new PointInitialisationRequestCommand("99W1","100").ToByteArray()); + var args = new List(); + mockConnection.Setup(x => x.SendAsync(Capture.In(args))) + .Returns(Task.FromResult(0)); + + var connection = new PointToInterlockingConnection(Mock.Of>(), _configuration, CancellationToken.None); + + // Act + connection.Connect(mockConnection.Object); + await connection.InitializeConnection(new GenericPointState(){PointPosition = GenericPointPosition.Left, DegradedPointPosition = GenericDegradedPointPosition.NotDegraded}, CancellationToken.None); + await connection.SendTimeoutMessage(); + + // Assert + mockConnection.Verify(v => v.SendAsync(It.IsAny()), Times.Exactly(5)); + Assert.Equal(new PointMovementFailedMessage("99W1________________", "INTERLOCKING________").ToByteArray(), args[4]); + } +} diff --git a/src/FieldElementSubsystems/Connections/EulynxBaseline4R2/PointToInterlockingConnection.cs b/src/FieldElementSubsystems/Connections/EulynxBaseline4R2/PointToInterlockingConnection.cs index 856f729..1413581 100644 --- a/src/FieldElementSubsystems/Connections/EulynxBaseline4R2/PointToInterlockingConnection.cs +++ b/src/FieldElementSubsystems/Connections/EulynxBaseline4R2/PointToInterlockingConnection.cs @@ -14,7 +14,8 @@ public class PointToInterlockingConnection : IPointToInterlockingConnection private readonly string _remoteId; public PointConfiguration Configuration { get; } public CancellationToken TimeoutToken => _timeout.Token; - IConnection? _currentConnection; + private IConnection? _currentConnection; + public IConnection? CurrentConnection { get => _currentConnection; } private CancellationTokenSource _timeout; private readonly int _timeoutDuration; private readonly CancellationToken _stoppingToken; From 1277b738ebb898dcaf7dd89c48871cf0700cdf6f Mon Sep 17 00:00:00 2001 From: Benedikt Schenkel Date: Tue, 12 Dec 2023 16:16:16 +0100 Subject: [PATCH 08/11] fix name --- src/FieldElementSubsystems.Test/Connection/Baseline4R2Test.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FieldElementSubsystems.Test/Connection/Baseline4R2Test.cs b/src/FieldElementSubsystems.Test/Connection/Baseline4R2Test.cs index 6ce5a16..28ad9ee 100644 --- a/src/FieldElementSubsystems.Test/Connection/Baseline4R2Test.cs +++ b/src/FieldElementSubsystems.Test/Connection/Baseline4R2Test.cs @@ -6,7 +6,7 @@ using Moq; using PointMovePointCommand = EulynxLive.Messages.Baseline4R2.PointMovePointCommand; -public class Baseline4R1Test{ +public class Baseline4R2Test{ private static readonly IDictionary TestSettings = new Dictionary { {"PointSettings:LocalId", "99W1" }, From f2ae0b8a218544cf0ccdb2838389a70740b90542 Mon Sep 17 00:00:00 2001 From: Benedikt Schenkel Date: Tue, 12 Dec 2023 16:18:53 +0100 Subject: [PATCH 09/11] rename test file --- .../Connection/{Baseline4R2Test.cs => Baseline4R1Test.cs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/FieldElementSubsystems.Test/Connection/{Baseline4R2Test.cs => Baseline4R1Test.cs} (100%) diff --git a/src/FieldElementSubsystems.Test/Connection/Baseline4R2Test.cs b/src/FieldElementSubsystems.Test/Connection/Baseline4R1Test.cs similarity index 100% rename from src/FieldElementSubsystems.Test/Connection/Baseline4R2Test.cs rename to src/FieldElementSubsystems.Test/Connection/Baseline4R1Test.cs From 3ca285507e88c1c022eeabdab0c7e87de1a445fa Mon Sep 17 00:00:00 2001 From: Benedikt Schenkel Date: Tue, 12 Dec 2023 17:06:04 +0100 Subject: [PATCH 10/11] fix grpc receive --- .../PointToInterlockingConnection.cs | 24 +++++++++++++++---- .../FieldElementSubsystems.csproj | 1 + 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/FieldElementSubsystems/Connections/EulynxBaseline4R2/PointToInterlockingConnection.cs b/src/FieldElementSubsystems/Connections/EulynxBaseline4R2/PointToInterlockingConnection.cs index 1413581..0edc021 100644 --- a/src/FieldElementSubsystems/Connections/EulynxBaseline4R2/PointToInterlockingConnection.cs +++ b/src/FieldElementSubsystems/Connections/EulynxBaseline4R2/PointToInterlockingConnection.cs @@ -3,6 +3,7 @@ using Microsoft.Extensions.Logging; using EulynxLive.FieldElementSubsystems.Interfaces; using EulynxLive.FieldElementSubsystems.Configuration; +using Grpc.Core; namespace EulynxLive.FieldElementSubsystems.Connections.EulynxBaseline4R2; @@ -109,14 +110,27 @@ private async Task SendMessage(Message message) { if (_currentConnection == null) throw new InvalidOperationException("Connection is null. Did you call Connect()?"); ResetTimeout(); - - var message = Message.FromBytes(await _currentConnection.ReceiveAsync(_timeout.Token)); - if (message is not T) + try + { + var message = Message.FromBytes(await _currentConnection.ReceiveAsync(_timeout.Token)); + if (message is not T) + { + _logger.LogError("Unexpected message: {}", message); + return null; + } + return message as T; + } + catch (RpcException) + { + if (_timeout.IsCancellationRequested) + { + _logger.LogError("Timeout"); + } + return null; + } catch (TaskCanceledException) { - _logger.LogError("Unexpected message: {}", message); return null; } - return message as T; } private void ResetTimeout() diff --git a/src/FieldElementSubsystems/FieldElementSubsystems.csproj b/src/FieldElementSubsystems/FieldElementSubsystems.csproj index 6bca8d3..602b5b4 100644 --- a/src/FieldElementSubsystems/FieldElementSubsystems.csproj +++ b/src/FieldElementSubsystems/FieldElementSubsystems.csproj @@ -5,6 +5,7 @@ + From ed571b5fb28b63eb4403b64d42db614143a35eff Mon Sep 17 00:00:00 2001 From: Benedikt Schenkel Date: Wed, 13 Dec 2023 11:47:51 +0100 Subject: [PATCH 11/11] update factory and readme --- .../Point/PointTest.cs | 3 +- .../Configuration/ConnectionProtocol.cs | 6 ++++ .../Configuration/PointConfiguration.cs | 3 +- src/Point/Connections/ConnectionFactory.cs | 29 +++++++++++++++++-- src/Point/README.md | 23 ++++++++++++++- src/Point/Startup.cs | 4 +-- 6 files changed, 59 insertions(+), 9 deletions(-) create mode 100644 src/FieldElementSubsystems/Configuration/ConnectionProtocol.cs diff --git a/src/FieldElementSubsystems.Test/Point/PointTest.cs b/src/FieldElementSubsystems.Test/Point/PointTest.cs index b26cdf7..37af51b 100644 --- a/src/FieldElementSubsystems.Test/Point/PointTest.cs +++ b/src/FieldElementSubsystems.Test/Point/PointTest.cs @@ -20,7 +20,8 @@ private static Mock CreateDefaultMockConnection( "INTERLOCKING", "http://localhost:50051", true, - false + false, + ConnectionProtocol.EulynxBaseline4R1 )); mockConnection.Setup(x => x.TimeoutToken).Returns(() => CancellationToken.None); mockConnection diff --git a/src/FieldElementSubsystems/Configuration/ConnectionProtocol.cs b/src/FieldElementSubsystems/Configuration/ConnectionProtocol.cs new file mode 100644 index 0000000..6bf38fa --- /dev/null +++ b/src/FieldElementSubsystems/Configuration/ConnectionProtocol.cs @@ -0,0 +1,6 @@ +namespace EulynxLive.FieldElementSubsystems.Configuration; + +public enum ConnectionProtocol { + EulynxBaseline4R1, + EulynxBaseline4R2 +} diff --git a/src/FieldElementSubsystems/Configuration/PointConfiguration.cs b/src/FieldElementSubsystems/Configuration/PointConfiguration.cs index 17a073c..4118a8e 100644 --- a/src/FieldElementSubsystems/Configuration/PointConfiguration.cs +++ b/src/FieldElementSubsystems/Configuration/PointConfiguration.cs @@ -6,5 +6,6 @@ public record PointConfiguration( string RemoteId, string RemoteEndpoint, bool? AllPointMachinesCrucial = null, - bool? SimulateRandomTimeouts = null + bool? SimulateRandomTimeouts = null, + ConnectionProtocol? ConnectionProtocol = null ); diff --git a/src/Point/Connections/ConnectionFactory.cs b/src/Point/Connections/ConnectionFactory.cs index 9bdd9f1..23da160 100644 --- a/src/Point/Connections/ConnectionFactory.cs +++ b/src/Point/Connections/ConnectionFactory.cs @@ -1,10 +1,33 @@ +using EulynxLive.FieldElementSubsystems.Configuration; using EulynxLive.FieldElementSubsystems.Interfaces; +using EulynxBaseline4R1 = EulynxLive.FieldElementSubsystems.Connections.EulynxBaseline4R1; +using EulynxBaseline4R2 = EulynxLive.FieldElementSubsystems.Connections.EulynxBaseline4R2; + namespace EulynxLive.Point.Connections; -public static class ConnectionFactory{ - public static IPointToInterlockingConnection CreateConnection (IServiceProvider x) where T : IPointToInterlockingConnection { +public class ConnectionFactory{ + private IConfiguration _configuration { get; } + private ILogger _logger { get; } + + public ConnectionFactory(ILogger logger, IConfiguration configuration){ + _logger = logger; + _configuration = configuration; + } - return ActivatorUtilities.CreateInstance(x, CancellationToken.None); + public IPointToInterlockingConnection CreateConnection(IServiceProvider x) { + var connectionProtocol = _configuration.GetSection("ConnectionSettings").Get()?.ConnectionProtocol; + switch (connectionProtocol){ + case ConnectionProtocol.EulynxBaseline4R1: + return new EulynxBaseline4R1.PointToInterlockingConnection(x.GetRequiredService>(), _configuration, CancellationToken.None); + case ConnectionProtocol.EulynxBaseline4R2: + return new EulynxBaseline4R2.PointToInterlockingConnection(x.GetRequiredService>(), _configuration, CancellationToken.None); + default: + if (connectionProtocol != null) + _logger.LogWarning($"Unknown connection protocol {connectionProtocol}. Using EulynxBaseline4R2."); + else + _logger.LogWarning($"No connection protocol specified. Using EulynxBaseline4R2."); + return new EulynxBaseline4R2.PointToInterlockingConnection(x.GetRequiredService>(), _configuration, CancellationToken.None); + } } } diff --git a/src/Point/README.md b/src/Point/README.md index bd20a0e..b22eda3 100644 --- a/src/Point/README.md +++ b/src/Point/README.md @@ -6,4 +6,25 @@ EULYNX Point Simulator - https://dotnet.microsoft.com/ - https://nodejs.org/en/ -Then, execute `dotnet run` in this directory and open http://localhost:5000 in the browser. +Then, execute `dotnet run` in this directory and open http://localhost:5101 in the browser. + +## Arguments + +The `PointSettings` command-line arguments are used to configure the point simulator. + +| Argument | Description | +|---|---| +| `--PointSettings:LocalId` | The local point ID. | +| `--PointSettings:LocalRastaId` | The local Rasta ID. | +| `--PointSettings:RemoteId` | The remote point ID. | +| `--PointSettings:RemoteEndpoint` | The remote endpoint URL. | +| `--PointSettings:ConnectionProtocol` | The protocol to use when connecting to an endpoint. | + +For example, to set the local point ID to `W1`, the local Rasta ID to `96`, the remote point ID to `INTERLOCKING`, and the remote endpoint URL to `http://localhost:5100` using `EulynxBaseline4R1`, you would use the following command: +``` +dotnet run --PointSettings:LocalId W1 --PointSettings:LocalRastaId 96 --PointSettings:RemoteId INTERLOCKING --PointSettings:RemoteEndpoint http://localhost:5100 --PointSettings:ConnectionProtocol EulynxBaseline4R1 +``` + +### Available Connection Protocols: +- EulynxBaseline4R1 +- EulynxBaseline4R2 diff --git a/src/Point/Startup.cs b/src/Point/Startup.cs index 9905df9..378bc3e 100644 --- a/src/Point/Startup.cs +++ b/src/Point/Startup.cs @@ -1,8 +1,6 @@ using Microsoft.AspNetCore.SpaServices.ReactDevelopmentServer; using EulynxLive.Point.Services; using EulynxLive.FieldElementSubsystems.Interfaces; -using EulynxBaseline4R1 = EulynxLive.FieldElementSubsystems.Connections.EulynxBaseline4R1; -using EulynxBaseline4R2 = EulynxLive.FieldElementSubsystems.Connections.EulynxBaseline4R2; using EulynxLive.Point.Connections; namespace EulynxLive.Point @@ -23,7 +21,7 @@ public void ConfigureServices(IServiceCollection services) services.AddGrpc(); services.AddGrpcReflection(); - services.AddSingleton(ConnectionFactory.CreateConnection); + services.AddSingleton(x => new ConnectionFactory(x.GetRequiredService>(), x.GetRequiredService()).CreateConnection(x)); // In production, the React files will be served from this directory services.AddSpaStaticFiles(configuration =>