init
This commit is contained in:
355
Common/DTS.Common.Serialization/IRIGCH10/Packets/PacketHeader.cs
Normal file
355
Common/DTS.Common.Serialization/IRIGCH10/Packets/PacketHeader.cs
Normal file
@@ -0,0 +1,355 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user