using Sick.SafetyScanners.DataStructures; using Sick.SafetyScanners.Helpers; namespace Sick.SafetyScanners.DataProcessing; /// /// Parser for the data header from UDP packets /// Thread-safe implementation /// public sealed class ParseDataHeader { /// /// Parses the data header from a UDP sequence /// public DataHeader ParseUdpSequence(PacketBuffer buffer) { if (buffer == null) throw new ArgumentNullException(nameof(buffer)); var bufferData = buffer.GetBuffer(); if (bufferData.Length < 52) // Minimum header size throw new ArgumentException($"Buffer too small (got {bufferData.Length}, expected at least 52)", nameof(buffer)); var span = bufferData.Span; return new DataHeader { VersionIndicator = ReadWriteHelper.ReadUint8LittleEndian(span, 0), VersionMajor = ReadWriteHelper.ReadUint8LittleEndian(span, 1), VersionMinor = ReadWriteHelper.ReadUint8LittleEndian(span, 2), VersionRelease = ReadWriteHelper.ReadUint8LittleEndian(span, 3), SerialNumberOfDevice = ReadWriteHelper.ReadUint32LittleEndian(span, 4), SerialNumberOfSystemPlug = ReadWriteHelper.ReadUint32LittleEndian(span, 8), ChannelNumber = ReadWriteHelper.ReadUint8LittleEndian(span, 12), // Offset 13-15 reserved SequenceNumber = ReadWriteHelper.ReadUint32LittleEndian(span, 16), ScanNumber = ReadWriteHelper.ReadUint32LittleEndian(span, 20), TimestampDate = ReadWriteHelper.ReadUint16LittleEndian(span, 24), TimestampTime = ReadWriteHelper.ReadUint32LittleEndian(span, 28), GeneralSystemStateBlockOffset = ReadWriteHelper.ReadUint16LittleEndian(span, 32), GeneralSystemStateBlockSize = ReadWriteHelper.ReadUint16LittleEndian(span, 34), DerivedValuesBlockOffset = ReadWriteHelper.ReadUint16LittleEndian(span, 36), DerivedValuesBlockSize = ReadWriteHelper.ReadUint16LittleEndian(span, 38), MeasurementDataBlockOffset = ReadWriteHelper.ReadUint16LittleEndian(span, 40), MeasurementDataBlockSize = ReadWriteHelper.ReadUint16LittleEndian(span, 42), IntrusionDataBlockOffset = ReadWriteHelper.ReadUint16LittleEndian(span, 44), IntrusionDataBlockSize = ReadWriteHelper.ReadUint16LittleEndian(span, 46), ApplicationDataBlockOffset = ReadWriteHelper.ReadUint16LittleEndian(span, 48), ApplicationDataBlockSize = ReadWriteHelper.ReadUint16LittleEndian(span, 50), IsEmpty = false }; } }