212 lines
7.7 KiB
Plaintext
212 lines
7.7 KiB
Plaintext
using DTS.Serialization.IRIGCH10.Enums;
|
|
using DTS.Serialization.IRIGCH10.Packets;
|
|
using System;
|
|
using System.ComponentModel;
|
|
using System.IO;
|
|
|
|
namespace DTS.Serialization.IRIGCH10
|
|
{
|
|
/// <summary>
|
|
/// this is the interface that all datapackets implement, it defines how packets can be interacted with in general
|
|
/// </summary>
|
|
public interface IDataPacket
|
|
{
|
|
/// <summary>
|
|
/// all chapter 10 packets have a packet header
|
|
/// </summary>
|
|
IPacketHeader PacketHeader { get; }
|
|
/// <summary>
|
|
/// computes the checksum for the datapacket data
|
|
/// </summary>
|
|
uint ComputeCheckSum();
|
|
/// <summary>
|
|
/// returns all bytes for the packet
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
byte[] GetBytes();
|
|
/// <summary>
|
|
/// sets the Realtime Counter (10 MHZ) for the packet
|
|
/// </summary>
|
|
/// <param name="rtc"></param>
|
|
void SetRTC(long rtc);
|
|
/// <summary>
|
|
/// sets the DataVersion of the packet
|
|
/// (part of the packet header)
|
|
/// </summary>
|
|
/// <param name="version"></param>
|
|
void SetDataVersion(DataTypeVersion version);
|
|
|
|
/// <summary>
|
|
/// sets the channel id for the packet (part of packet header)
|
|
/// </summary>
|
|
/// <param name="channelID"></param>
|
|
void SetChannelID(ushort channelID);
|
|
/// <summary>
|
|
/// sets the sequence number for the packet,
|
|
/// in general should be increasing and flip back to 0
|
|
/// after max value
|
|
/// </summary>
|
|
/// <param name="seq"></param>
|
|
void SetSequenceNumber(ushort seq);
|
|
}
|
|
/// <summary>
|
|
/// this is the general base class all packets extend, it
|
|
/// has common features like computing the checksum, setting the
|
|
/// packet specific Channel Data Word, etc
|
|
/// </summary>
|
|
public abstract class AbstractDataPacket
|
|
{
|
|
protected void SetCSDWBit(int bit, bool value)
|
|
{
|
|
if (bit <0 || bit > 31)
|
|
{
|
|
return;
|
|
}
|
|
if (!value)
|
|
{
|
|
//and with all ones except for the bit in question
|
|
ChannelSpecificDataWord &= ~(1u << bit);
|
|
}
|
|
else
|
|
{
|
|
//or with all 0s except for bit in question
|
|
ChannelSpecificDataWord |= (1u << bit);
|
|
}
|
|
}
|
|
protected bool GetCSDWBit(int bit)
|
|
{
|
|
if (bit < 0 || bit > 31) { return false; }
|
|
return (ChannelSpecificDataWord & (1u << bit)) != 0;
|
|
}
|
|
protected int CommonHeaderWork(ushort channelId, byte dataVersion,
|
|
byte sequenceNumber, long rtc, uint dataLength, int nanoseconds, int seconds)
|
|
{
|
|
PacketHeader.ChannelId = channelId;
|
|
PacketHeader.DataVersion = dataVersion;
|
|
PacketHeader.SequenceNum = sequenceNumber;
|
|
PacketHeader.IPTSTimeSource = PacketHeader.SecondaryHeaderPresent;
|
|
PacketHeader.RTCSyncError = false;
|
|
PacketHeader.SecondaryHeaderTimeFormat = IRIGCH10.PacketHeader.SecondaryHeaderTimeFormats.IEEE1588;
|
|
PacketHeader.DataOverflowError = false;
|
|
PacketHeader.CheckSumPresence = IRIGCH10.PacketHeader.DataCheckSumPresences.NotPresent;
|
|
PacketHeader.SetRTC(rtc);
|
|
PacketHeader.DataLength = dataLength;
|
|
|
|
PacketHeader.PacketLength = PacketHeader.DataLength + IRIGCH10.PacketHeader.PACKET_HEADER_LENGTH;
|
|
if (PacketHeader.SecondaryHeaderPresent)
|
|
{
|
|
PacketHeader.PacketLength += SecondaryTimeFormatHeader.SECONDARY_TIME_HEADER_LENGTH;
|
|
}
|
|
if (0 != PacketHeader.PacketLength % 4)
|
|
{
|
|
var pad = 4 - PacketHeader.PacketLength % 4;
|
|
//pad out packet length to a multiple of 4 ...
|
|
PacketHeader.PacketLength += pad;
|
|
}
|
|
_dataBytes = new byte[PacketHeader.PacketLength - IRIGCH10.PacketHeader.PACKET_HEADER_LENGTH];
|
|
|
|
var offset = 0;
|
|
|
|
if (PacketHeader.SecondaryHeaderPresent)
|
|
{
|
|
var secondaryHeader = SecondaryTimeFormatHeader.GetBytes(nanoseconds, seconds);
|
|
|
|
Buffer.BlockCopy(secondaryHeader, 0, _dataBytes, offset, secondaryHeader.Length);
|
|
offset += secondaryHeader.Length;
|
|
}
|
|
|
|
var channelSpecificDataWord = BitConverter.GetBytes(ChannelSpecificDataWord);
|
|
Buffer.BlockCopy(channelSpecificDataWord, 0, _dataBytes, offset, channelSpecificDataWord.Length);
|
|
offset += channelSpecificDataWord.Length;
|
|
return offset;
|
|
}
|
|
private uint _ChannelSpecificDataWork = 0;
|
|
[Browsable(false)]
|
|
public uint ChannelSpecificDataWord
|
|
{
|
|
get => _ChannelSpecificDataWork;
|
|
protected set => _ChannelSpecificDataWork = value;
|
|
}
|
|
[Browsable(false)]
|
|
public IPacketHeader PacketHeader { get; protected set; }
|
|
public uint ComputeCheckSum()
|
|
{
|
|
return Utils.Utils.GetCheckSum32(_dataBytes);
|
|
}
|
|
|
|
/// <summary>
|
|
/// sets the sequence number for the packet
|
|
/// </summary>
|
|
/// <param name="seq"></param>
|
|
public void SetSequenceNumber(ushort seq)
|
|
{
|
|
PacketHeader.SequenceNum = BitConverter.GetBytes(seq)[0];
|
|
}
|
|
|
|
private long _rtc;
|
|
/// <summary>
|
|
/// returns the Realtime Counter (10Mhz) value for the packet
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public long GetRTC() { return _rtc; }
|
|
/// <summary>
|
|
/// sets the Realtime Counter (10Mhz) value for the packet
|
|
/// </summary>
|
|
/// <param name="rtc"></param>
|
|
public void SetRTC(long rtc)
|
|
{
|
|
_rtc = rtc;
|
|
PacketHeader.SetRTC(rtc);
|
|
|
|
}
|
|
|
|
public const long BASE_RTC = 141989612500056L;
|
|
/// <summary>
|
|
/// returns all bytes for the packet
|
|
/// is virtual so extending classes can define their own behavior as needed
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public virtual byte[] GetBytes()
|
|
{
|
|
using (var ms = new MemoryStream())
|
|
{
|
|
using (var bw = new BinaryWriter(ms))
|
|
{
|
|
bw.Write(PacketHeader.GetBytes());
|
|
bw.Write(_dataBytes);
|
|
}
|
|
return ms.ToArray();
|
|
}
|
|
}
|
|
|
|
protected AbstractDataPacket(DataFileDataTypes dataType, bool secondaryHeaderPresent)
|
|
{
|
|
PacketHeader = new PacketHeader(dataType);
|
|
PacketHeader.SecondaryHeaderPresent = secondaryHeaderPresent;
|
|
}
|
|
protected AbstractDataPacket(byte[] bytes)
|
|
{
|
|
var header = new byte[24];
|
|
Buffer.BlockCopy(bytes, 0, header, 0, 24);
|
|
PacketHeader = new PacketHeader(header);
|
|
_dataBytes = new byte[PacketHeader.DataLength];
|
|
var length = _dataBytes.Length;
|
|
var length2 = bytes.Length - 24;
|
|
if (length2 < length) { length = length2; }
|
|
Buffer.BlockCopy(bytes, 24, _dataBytes, 0, length);
|
|
ChannelSpecificDataWord = BitConverter.ToUInt32(_dataBytes, 0);
|
|
}
|
|
|
|
protected byte[] _dataBytes;
|
|
public void SetDataVersion(DataTypeVersion version)
|
|
{
|
|
PacketHeader.SetDataVersion(version);
|
|
}
|
|
|
|
public void SetChannelID(ushort channelID)
|
|
{
|
|
PacketHeader.ChannelId = channelID;
|
|
}
|
|
}
|
|
}
|