using System;
using System.Collections;
using System.Collections.Generic;
namespace DTS.Serialization.IRIGCH10.Packets
{
///
/// added an analog time format 1 packet for validating exports with EMC
///
public class TimePacketFormat1 : AbstractDataPacket, IDataPacket
{
public enum IRIGTimeSource
{
IRIG_TCG_freewheeling,
IRIG_TCG_freewheeling_from_TIME,
IRIG_TCG_freewheeling_from_RMM,
IRIG_TCG_locked_to_external_IRIG,
IRIG_TCG_locked_to_external_GPS,
IRIG_TCG_locked_to_external_NetworkTimeProtocol,
IRIG_TCG_locked_to_external_Precision_Time_Protocol,
IRIG_TCG_locked_to_external_Embedded,
RESERVED
};
//bits 15-12
//this is currently not serialized to the CSDW as the EMC validation tool will return errors if the
//field is filled in.
//DTM 2023-10-27
public IRIGTimeSource ITS
{
get; set;
}
public enum TimeFormats
{
IRIG_B = 0x00,
IRIG_A = 0x01,
IRIG_G = 0x02,
RTC = 0x03,
UTC = 0x04,
NativeGPS = 0x05,
RESERVED = 0x06,
NONE = 0x0F
}
//bits 7-4
public TimeFormats TimeFormat
{
get
{
var channelSpecificDataWord = BitConverter.GetBytes(ChannelSpecificDataWord);
var bits = new BitArray(channelSpecificDataWord);
var ntf = Utils.Utils.BitArrayToInt32(bits, 4, 7);
return (TimeFormats)ntf;
}
set
{
var channelSpecificDataWord = BitConverter.GetBytes(ChannelSpecificDataWord);
var b = new BitArray(channelSpecificDataWord);
Utils.Utils.SetBits(b, (uint)value, 4, 7);
var ret = new byte[sizeof(uint)];
b.CopyTo(ret, 0);
ChannelSpecificDataWord = BitConverter.ToUInt32(ret, 0);
}
}
//bits 3-0
public enum TimeSources
{
Internal = 0x00,
External = 0x01,
InternalFromRMM = 0x02,
Reserved = 0x03,
None = 0x0F
}
public TimeSources TimeSource
{
get
{
var channelSpecificDataWord = BitConverter.GetBytes(ChannelSpecificDataWord);
var bits = new BitArray(channelSpecificDataWord);
var ntf = Utils.Utils.BitArrayToInt32(bits, 0, 3);
return (TimeSources)ntf;
}
set
{
var channelSpecificDataWord = BitConverter.GetBytes(ChannelSpecificDataWord);
var b = new BitArray(channelSpecificDataWord);
Utils.Utils.SetBits(b, (uint)value, 0, 3);
var ret = new byte[sizeof(uint)];
b.CopyTo(ret, 0);
ChannelSpecificDataWord = BitConverter.ToUInt32(ret, 0);
}
}
public enum DateFormats
{
IRIGDayAvailable = 0x00,
MonthAndYearAvailable = 0x01
}
//bit 9
public DateFormats DateFormat
{
get
{
var csdw = BitConverter.GetBytes(ChannelSpecificDataWord);
var bits = new BitArray(csdw);
return bits[9] ? DateFormats.MonthAndYearAvailable : DateFormats.IRIGDayAvailable;
}
set
{
var channelSpecificDataWord = BitConverter.GetBytes(ChannelSpecificDataWord);
var b = new BitArray(channelSpecificDataWord);
b.Set(9, value == DateFormats.MonthAndYearAvailable);
var ret = new byte[sizeof(uint)];
b.CopyTo(ret, 0);
ChannelSpecificDataWord = BitConverter.ToUInt32(ret, 0);
}
}
///
/// the time represented by this packet
///
public DateTime TimePacketTime { get; set; }
//bit 8
public bool IsLeapYear
{
get
{
var csdw = BitConverter.GetBytes(ChannelSpecificDataWord);
var bits = new BitArray(csdw);
return bits[8];
}
set
{
var channelSpecificDataWord = BitConverter.GetBytes(ChannelSpecificDataWord);
var b = new BitArray(channelSpecificDataWord);
b.Set(8, value);
var ret = new byte[sizeof(uint)];
b.CopyTo(ret, 0);
ChannelSpecificDataWord = BitConverter.ToUInt32(ret, 0);
}
}
public TimePacketFormat1(byte sequenceNumber, DateTime packetTime, long rtc, int nanoseconds, int seconds)
: base(Enums.DataFileDataTypes.TimeDataFormat1, false)
{
SetDataVersion(Enums.DataTypeVersion.TG78);
TimePacketTime = packetTime;
IsLeapYear = DateTime.IsLeapYear(packetTime.Year);
DateFormat = DateFormats.MonthAndYearAvailable;
TimeSource = TimeSources.External;
ITS = IRIGTimeSource.IRIG_TCG_locked_to_external_Embedded;
var dataLength = Convert.ToUInt32(4 + sizeof(ushort) + 4);
var offset = CommonHeaderWork(1, PacketHeader.DataVersion, sequenceNumber, rtc, dataLength, nanoseconds, seconds);
WriteMonthDayPayload(offset);
}
///
/// writes the month day payload portion of the timepacket
///
///
private void WriteMonthDayPayload(int offset)
{
var Line1 = new BitArray(16);
var digits = GetDigits(TimePacketTime.Second, 2);
//tens of seconds
var TSn = digits[0];
Utils.Utils.SetBits(Line1, (uint)TSn, 12, 14);
//units of seconds
var Sn = digits[1];
Utils.Utils.SetBits(Line1, (uint)Sn, 8, 11);
digits = GetDigits(TimePacketTime.Millisecond, 3);
//hundreds of ms
var Hmn = digits[0];
Utils.Utils.SetBits(Line1, (uint)Hmn, 4, 7);
//tens of ms
var Tmn = digits[1];
Utils.Utils.SetBits(Line1, (uint)Tmn, 0, 3);
var temp = new byte[sizeof(ushort)];
Line1.CopyTo(temp, 0);
Buffer.BlockCopy(temp, 0, _dataBytes, offset, 2);
offset += 2;
var Line2 = new BitArray(16);
digits = GetDigits(TimePacketTime.Hour, 2);
//tens of hours
var THn = digits[0];
Utils.Utils.SetBits(Line2, (uint)THn, 12, 13);
//Units of hours
var Hn = digits[1];
Utils.Utils.SetBits(Line2, (uint)Hn, 8, 11);
digits = GetDigits(TimePacketTime.Minute, 2);
//tens of minutes
var TMn = digits[0];
Utils.Utils.SetBits(Line2, (uint)TMn, 4, 6);
//units of minutes
var Mn = digits[1];
Utils.Utils.SetBits(Line2, (uint)Mn, 0, 3);
temp = new byte[sizeof(ushort)];
Line2.CopyTo(temp, 0);
Buffer.BlockCopy(temp, 0, _dataBytes, offset, 2);
offset += 2;
var Line3 = new BitArray(16);
digits = GetDigits(TimePacketTime.Month, 2);
//tens of months
var Ton = digits[0];
Utils.Utils.SetBits(Line3, (uint)Ton, 12, 13);
//units of months
var On = digits[1];
Utils.Utils.SetBits(Line3, (uint)On, 8, 11);
digits = GetDigits(TimePacketTime.Day, 2);
//Tens of days
var TDn = digits[0];
Utils.Utils.SetBits(Line3, (uint)TDn, 4, 7);
//units of days
var Dn = digits[1];
Utils.Utils.SetBits(Line3, (uint)Dn, 0, 3);
temp = new byte[sizeof(ushort)];
Line3.CopyTo(temp, 0);
Buffer.BlockCopy(temp, 0, _dataBytes, offset, 2);
offset += 2;
var line4 = new BitArray(16);
digits = GetDigits(TimePacketTime.Year, 4);
var OYn = digits[0];
//thousands of years
Utils.Utils.SetBits(line4, (uint)OYn, 12, 13);
var HYn = digits[1];
//hundreds of years
Utils.Utils.SetBits(line4, (uint)HYn, 8, 11);
var TYn = digits[2];
//tens of years
Utils.Utils.SetBits(line4, (uint)TYn, 4, 7);
var Yn = digits[3];
//units of years
Utils.Utils.SetBits(line4, (uint)Yn, 0, 3);
temp = new byte[sizeof(ushort)];
line4.CopyTo(temp, 0);
Buffer.BlockCopy(temp, 0, _dataBytes, offset, 2);
offset += 2;
}
private int[] GetDigits(int number, int expectedDigits)
{
var list = new List();
var res = number;
while (0 != res)
{
var digit = res % 10;
res /= 10;
list.Add(digit);
}
while (list.Count < expectedDigits)
{
list.Add(0);
}
list.Reverse();
return list.ToArray();
}
}
}