Files
DP44/Common/DTS.Common.Serialization/.svn/pristine/55/556d1df43624278ef73e9954011ffd8cf2a8e8ed.svn-base

356 lines
12 KiB
Plaintext
Raw Permalink Normal View History

2026-04-17 14:55:32 -04:00
using DTS.Serialization.IRIGCh10.Attributes;
using DTS.Serialization.IRIGCH10.Enums;
using System;
using System.Collections;
using System.ComponentModel;
using System.IO;
using System.Linq;
namespace DTS.Serialization.IRIGCH10
{
/// <summary>
/// implements the packet header portion of a packet
/// </summary>
public class PacketHeader : IPacketHeader
{
/// <summary>
/// used to indicate the start of a packet, is defined to 0x25, 0xEB by chapter10.pdf
/// </summary>
public ushort PacketSyncPattern { get; set; } = BitConverter.ToUInt16(new byte[] { 0x25, 0xEB }, 0);
/// <summary>
/// this is just a shortcut to avoid calculating the ushort value for 0x25,0xEB
/// this is the ushort pattern expected for pattern sync
/// </summary>
public const ushort EXPECTED_SYNC_PATTERN = 60197;
/// <summary>
/// channel id, default to 0
/// </summary>
public ushort ChannelId { get; set; } = BitConverter.ToUInt16(new byte[] { 0x00, 0x00 }, 0);
/// <summary>
/// total length of the packet including header, data, and filler, and any checksums
/// </summary>
public uint PacketLength { get; set; } = 0;
/// <summary>
/// length of the data portion of the packet, so sans filler and checksums
/// </summary>
public uint DataLength { get; set; } = 0;
public byte DataVersion { get; set; } = 0;
public byte SequenceNum { get; set; } = 0;
[Browsable(false)]
public byte PacketFlags { get; private set; } = 0;
public bool SecondaryHeaderPresent
{
get
{
var b = new BitArray(new[] { PacketFlags });
return b.Get(7);
}
set
{
PacketFlags = SetBit(PacketFlags, 7, value);
}
}
public bool IPTSTimeSource
{
get
{
var b = new BitArray(new[] { PacketFlags });
return b.Get(6);
}
set
{
PacketFlags = SetBit(PacketFlags, 6, value);
}
}
public bool RTCSyncError
{
get
{
var b = new BitArray(new[] { PacketFlags });
return b.Get(5);
}
set
{
PacketFlags = SetBit(PacketFlags, 5, value);
}
}
public enum SecondaryHeaderTimeFormats
{
Chapter4 = 0,
IEEE1588 = 1,
ExtendedRelativeTimeCounter = 2,
Reserved = 3
}
public SecondaryHeaderTimeFormats SecondaryHeaderTimeFormat
{
get
{
var b = new BitArray(new[] { PacketFlags });
return (SecondaryHeaderTimeFormats)Utils.Utils.BitArrayToInt32(b, 2, 3);
}
set
{
var b = new BitArray(new[] { PacketFlags });
Utils.Utils.SetBits(b, (uint)value, 2, 3);
var ret = new byte[1];
b.CopyTo(ret, 0);
PacketFlags = ret[0];
}
}
public bool DataOverflowError
{
get
{
var b = new BitArray(new[] { PacketFlags });
return b.Get(4);
}
set
{
PacketFlags = SetBit(PacketFlags, 4, value);
}
}
private byte SetBit(byte input, int bit, bool bVal)
{
var b = new BitArray(new[] { input });
b.Set(bit, bVal);
var ret = new byte[1];
b.CopyTo(ret, 0);
return ret[0];
}
public enum DataCheckSumPresences
{
NotPresent = 0,
EightBit = 1,
SixteenBit = 2,
ThirtyTwoBit = 3
}
public DataCheckSumPresences CheckSumPresence
{
get
{
var b = new BitArray(new[] { PacketFlags });
return (DataCheckSumPresences)Utils.Utils.BitArrayToInt32(b, 0, 1);
}
set
{
var b = new BitArray(new[] { PacketFlags });
Utils.Utils.SetBits(b, (uint)value, 0, 1);
var ret = new byte[1];
b.CopyTo(ret, 0);
PacketFlags = ret[0];
}
}
[Browsable(false)]
public byte DataType { get; set; } = 0;
public DataFileDataTypes DataFileType
{
get
{
var all = Enum.GetValues(typeof(DataFileDataTypes)).Cast<DataFileDataTypes>().ToArray();
foreach (var datatype in all)
{
var b = PacketHeaderValueAttribute.GetPacketHeaderValue(datatype);
if (b == DataType) { return datatype; }
}
return DataFileDataTypes.ComputerGeneratedDataFormat0;
}
}
//10 MHz Relative Time Counter
[Browsable(false)]
public byte[] RTC { get; set; } = new byte[6];
public long RTCLong
{
get
{
var bytes = new byte[8];
Buffer.BlockCopy(RTC, 0, bytes, 0, 6);
return BitConverter.ToInt64(bytes, 0);
}
}
public ushort CheckSum { get; set; }
/// <summary>
/// the RealtimeCounter in the packet header is a 6 byte field
/// for convenience we'll use a long to interact with it
/// even though we are only using 6 bytes
/// </summary>
/// <param name="rtc"></param>
public void SetRTC(long rtc)
{
var bytes = GetRTCBytes(rtc);
Buffer.BlockCopy(bytes, 0, RTC, 0, RTC.Length);
}
private const int RTC_SIZE_BYTES = 6;
public static byte[] GetRTCBytes(long rtc)
{
var s = rtc.ToString("X");
var buffer = new byte[RTC_SIZE_BYTES];
for (int i = 0; i < RTC_SIZE_BYTES; i++)
{
string sVal = s.Substring(i * 2, 2);
var val = Convert.ToInt16(sVal, 16);
buffer[buffer.Length - 1 - i] = BitConverter.GetBytes(val)[0];
}
return buffer;
}
public PacketHeader(DataFileDataTypes dataType)
{
DataType = PacketHeaderValueAttribute.GetPacketHeaderValue(dataType);
}
public PacketHeader(byte[] bytes)
{
if (null == bytes) { throw new NullReferenceException("no bytes received"); }
if (PACKET_HEADER_LENGTH != bytes.Length) { throw new Exception($"Expected {PACKET_HEADER_LENGTH} bytes, received: {bytes.Length}"); }
PacketSyncPattern = BitConverter.ToUInt16(bytes, 0);
if (PacketSyncPattern != EXPECTED_SYNC_PATTERN)
{
System.Diagnostics.Trace.WriteLine("Expected sync pattern not found");
}
ChannelId = BitConverter.ToUInt16(bytes, 2);
PacketLength = BitConverter.ToUInt32(bytes, 4);
DataLength = BitConverter.ToUInt32(bytes, 8);
DataVersion = bytes[12];
SequenceNum = bytes[13];
PacketFlags = bytes[14];
DataType = bytes[15];
RTC = new byte[6];
Array.Copy(bytes, 16, RTC, 0, 6);
CheckSum = BitConverter.ToUInt16(bytes, 22);
var computedCRC = ComputeCheckSum();
if (CheckSum != computedCRC)
{
System.Diagnostics.Trace.WriteLine("Checksum doesn't match");
}
}
public byte[] GetBytes()
{
using (var sw = new MemoryStream())
{
using (var bw = new BinaryWriter(sw))
{
bw.Write(PacketSyncPattern);
bw.Write(ChannelId);
bw.Write(PacketLength);
bw.Write(DataLength);
bw.Write(DataVersion);
bw.Write(SequenceNum);
bw.Write(PacketFlags);
bw.Write(DataType);
bw.Write(RTC);
bw.Write(ComputeCheckSum());
}
return sw.ToArray();
}
}
public void SetDataVersion(DataTypeVersion version)
{
DataVersion = PacketHeaderValueAttribute.GetPacketHeaderValue(version);
}
public void SetPacketFlags(bool SecondaryHeaderPresent,
bool SecondaryHeaderTime,
bool RTCSyncerror,
bool DataOverflow,
SecondaryHeaderTimeFormat fmt,
DataCheckSumType checkSum
)
{
var bitArray = new BitArray(new[] { PacketFlags });
bitArray[7] = SecondaryHeaderPresent;
bitArray[6] = SecondaryHeaderTime;
bitArray[5] = RTCSyncerror;
bitArray[4] = DataOverflow;
var byteValue = new BitArray(new[] { PacketHeaderValueAttribute.GetPacketHeaderValue(fmt) });
bitArray[3] = byteValue[0];
bitArray[2] = byteValue[1];
byteValue = new BitArray(new[] { PacketHeaderValueAttribute.GetPacketHeaderValue(checkSum) });
bitArray[1] = byteValue[0];
bitArray[0] = byteValue[1];
var bytes = new byte[1];
bitArray.CopyTo(bytes, 0);
PacketFlags = bytes[0];
}
public ushort ComputeCheckSum()
{
byte[] bytesToCompute;
using (var ms = new MemoryStream())
{
using (var bw = new BinaryWriter(ms))
{
bw.Write(PacketSyncPattern);
bw.Write(ChannelId);
bw.Write(PacketLength);
bw.Write(DataLength);
bw.Write(DataVersion);
bw.Write(SequenceNum);
bw.Write(PacketFlags);
bw.Write(DataType);
bw.Write(RTC);
}
bytesToCompute = ms.ToArray();
}
return Utils.Utils.GetCheckSum16(bytesToCompute);
}
public const int PACKET_HEADER_LENGTH = 24;
}
public interface IPacketHeader
{
ushort PacketSyncPattern { get; set; }
ushort ChannelId { get; set; }
uint PacketLength { get; set; }
uint DataLength { get; set; }
byte DataVersion { get; set; }
byte SequenceNum { get; set; }
[Browsable(false)]
byte PacketFlags { get; }
bool SecondaryHeaderPresent { get; set; }
bool IPTSTimeSource { get; set; }
bool RTCSyncError { get; set; }
PacketHeader.SecondaryHeaderTimeFormats SecondaryHeaderTimeFormat { get; set; }
bool DataOverflowError { get; set; }
PacketHeader.DataCheckSumPresences CheckSumPresence { get; set; }
[Browsable(false)]
byte DataType { get; set; }
DataFileDataTypes DataFileType { get; }
[Browsable(false)]
byte[] RTC { get; set; }
long RTCLong { get; }
ushort CheckSum { get; set; }
void SetRTC(long rtc);
void SetDataVersion(DataTypeVersion version);
void SetPacketFlags(bool SecondaryHeaderPresent,
bool SecondaryHeaderTime,
bool RTCSyncerror,
bool DataOverflow,
SecondaryHeaderTimeFormat fmt,
DataCheckSumType checkSum
);
byte[] GetBytes();
ushort ComputeCheckSum();
}
}