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(); } } }