15 KiB
source_files, generated_at, model, schema_version, sha256
| source_files | generated_at | model | schema_version | sha256 | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
2026-04-16T03:43:44.837011+00:00 | Qwen/Qwen3-Coder-Next-FP8 | 1 | a37b40770bf1428d |
IRIG CH10 Packet Serialization Module Documentation
1. Purpose
This module provides serialization and deserialization support for IRIG CH10 data packets, implementing core packet types required for recording and playback of time-synchronized embedded system data streams. It defines interfaces and concrete classes for transport headers, secondary time headers, and various data packet formats—including time data (Formats 1 and 2), analog data (Format 1), TMATS metadata, and recorder indexing structures—enabling interoperability with IRIG CH10-compliant systems. The module is designed for use in data acquisition and post-processing pipelines where precise time-stamping and structured binary packet formatting are required.
2. Public Interface
Interfaces
-
ITransportStreamHeaderint MessageFormat { get; }— 4-bit field identifying the message format (must be1per spec).int MessageType { get; }— 4-bit field identifying the message type (must be0per spec).int SequenceNumber { get; }— 24-bit UDP sequence number, incremented per packet.
-
ISecondaryTimeFormatHeaderint NanoSeconds { get; }— Nanosecond component of the time stamp.int Seconds { get; }— Seconds since Unix epoch (1970-01-01).ushort Reserved { get; }— Reserved field (always0in current implementation).ushort CheckSum { get; }— 8-bit checksum over preceding fields (stored asushort).DateTime LocalTime { get; }— Computed local time fromSecondsandNanoSeconds.
-
IDataPacketIPacketHeader PacketHeader { get; }— Access to the packet header metadata.uint ComputeCheckSum()— Computes CRC32 checksum over data bytes.byte[] GetBytes()— Serializes the entire packet to a byte array.void SetRTC(long rtc)— Sets the Real-Time Counter (10 MHz) value.void SetDataVersion(DataTypeVersion version)— Sets the data version field in the header.void SetChannelID(ushort channelID)— Sets the channel ID.void SetSequenceNumber(ushort seq)— Sets the packet sequence number.
Concrete Classes
-
TransportStreamHeader(implementsITransportStreamHeader)TransportStreamHeader()— Default constructor (fields uninitialized).TransportStreamHeader(byte[] input)— Parses 4-byte header; validates length (TRANSPORT_HEADER_LENGTH = 4), extractsMessageFormat,MessageType, andSequenceNumbervia bit manipulation.const int TRANSPORT_HEADER_LENGTH = 4— Header size in bytes.
-
SecondaryTimeFormatHeader(implementsISecondaryTimeFormatHeader)SecondaryTimeFormatHeader(byte[] input)— Parses 12-byte header; validates checksum viaUtils.Utils.GetCheckSum8; logs mismatch viaTrace.WriteLine.static byte[] GetBytes(int nanoseconds, int seconds)— Serializes header withReserved=0, computes checksum.const int SECONDARY_TIME_HEADER_LENGTH = 12— Header size in bytes.
-
TimeDataPacket(implementsIDataPacket, extendsAbstractDataPacket)TimeDataPacket()— Initializes withDataFileDataTypes.TimeDataFormat1, 12-byte_dataBytes.DateTime GetDateTime()— Returns internal_dt.void SetTime(DateTime dt)— Encodes time fields (ms/10, sec, min, hour, day, month, year) as BCD into_dataBytes[4..11].void SetTimeSource(byte b)— Sets time source bits (0–3) in_dataBytes[0].void SetTimeSource(TimeSource src)— Sets time source usingPacketHeaderValueAttribute.GetPacketHeaderValue(src); bit-reverses order (per CH10 spec).void SetTimeFormat(TimeFormats fmt)— Sets time format bits (4–7) similarly.
-
TMATSPacket(implementsIDataPacket, extendsAbstractDataPacket)TMATSPacket(int nanoseconds, int seconds, string tmatsDoc, bool secondaryHeaderPresent)— Constructs TMATS packet with ASCII/XML doc; sets data version (0x01or0x09).TMATSPacket(byte[] bytes)— Deserializes from byte array.bool XMLFormat { get; }— Extracted from bit 9 ofChannelSpecificDataWord.bool SetupRecordConfigurationChange { get; }— Extracted from bit 8.RCCChapter10Versions Chapter10Version { get; }— Extracted from bits 0–7; maps to enum (RESERVED,RCC_106_07, ...,RCC_106_15).string TMATSDocument { get; }— Extracts TMATS string from_dataBytesafter skipping CSDW and optional secondary header.
-
RootRecorderIndexPacket(implementsIDataPacket, extendsAbstractDataPacket)RootRecorderIndexPacket(DateTime dt)— Initializes withDataFileDataTypes.ComputerGeneratedDataFormat3.void SetRootPacketAddress(long address)— Stores 8-byte address.void AddRecordingIndex(RecordingIndexIndex index)— Adds to_indiceslist.override byte[] GetBytes()— Appends a self-referencing index entry before serializing.
-
RecordingIndexIndexconst int SIZE = 24— 8 bytes (RTC) + 8 bytes (DateTime BCD) + 8 bytes (data packet offset).RecordingIndexIndex(long rtc, long offset, DateTime dt)— Constructor.byte[] GetBytes()— Serializes fields in order: RTC, DateTime (BCD), offset.
-
RecorderIndexPacket(implementsIDataPacket, extendsAbstractDataPacket)RecorderIndexPacket()— Initializes withDataFileDataTypes.ComputerGeneratedDataFormat3.DateTime GetDateTime()— ReturnsGetDateTime()of firstRecordingIndex.int NumberOfEntries { get; }— Count of_indices.void AddRecordingIndex(RecordingIndex index)— Adds to_indices.override byte[] GetBytes()— Serializes channel-specific data word, root address, and indices.
-
RecordingIndexconst int SIZE = 35— 8 (RTC) + 8 (DateTime BCD) + 2 (ChannelId) + 1 (DataType) + 1 (Reserved) + 8 (offset).DateTime GetDateTime()— Returns stored_dt.RecordingIndex(long rtc, long offset, DateTime dt)— Constructor.byte[] GetBytes()— Serializes fields.
-
TimePacketFormat2(implementsIDataPacket, extendsAbstractDataPacket)TimePacketFormat2(byte sequenceNumber, bool rtcSyncError, int nanoseconds, int seconds, long rtc, bool includeSecondaryHeader)— Constructor.TimePacketFormat2(byte[] bytes)— Deserializes from byte array.DateTime LocalTimeOfFirstSample { get; }— Populated if secondary header present.enum NetworkTimeFormats— Values:NetworkTimeProtocolVersion3,IEEE1588_2002,IEEE1588_2008,RESERVED.NetworkTimeFormats NetworkTimeFormat { get; set; }— Bits 7–4 of CSDW.enum TimeStatuses— Values:TimeNotValid,TimeValid,RESERVED.TimeStatuses TimeStatus { get; set; }— Bits 3–0 of CSDW.uint UnsignedSeconds { get; }— Parsed from data section.uint UnsignedNanoSeconds { get; }— Parsed from data section.string PTPTime { get; }— Formatted viaPTP1588Timestamps.ToDateTimeString(...).
-
TimePacketFormat1(implementsIDataPacket, extendsAbstractDataPacket)TimePacketFormat1(byte sequenceNumber, DateTime packetTime, long rtc, int nanoseconds, int seconds)— Constructor.enum IRIGTimeSource— Values:IRIG_TCG_freewheeling, ...,RESERVED.IRIGTimeSource ITS { get; set; }— Bits 15–12 of CSDW (not serialized per comment).enum TimeFormats— Values:IRIG_B,IRIG_A,IRIG_G,RTC,UTC,NativeGPS,RESERVED,NONE.TimeFormats TimeFormat { get; set; }— Bits 7–4 of CSDW.enum TimeSources— Values:Internal,External,InternalFromRMM,Reserved,None.TimeSources TimeSource { get; set; }— Bits 3–0 of CSDW.enum DateFormats— Values:IRIGDayAvailable,MonthAndYearAvailable.DateFormats DateFormat { get; set; }— Bit 9 of CSDW.DateTime TimePacketTime { get; set; }— Stored time.bool IsLeapYear { get; set; }— Bit 8 of CSDW.
-
AnalogDataFormat1Packet(implementsIDataPacket, extendsAbstractDataPacket)AnalogDataFormat1Packet(int nanoseconds, int seconds, Chapter10File.GetNextSampleDelegate getNextSample, int totalChannels, long channelLength, long rtc, long numSamples, long currentSample, byte sequenceNumber, ushort channelId, bool includeSecondaryHeader)— Constructor.AnalogDataFormat1Packet(byte[] bytes)— Deserializes from byte array.DateTime LocalTimeOfFirstSample { get; }— Populated if secondary header present.bool Same { get; set; }— Bit 28 of CSDW.int Factor { get; set; }— Bits 27–24 of CSDW.int TotChan { get; set; }— Bits 23–16 of CSDW.long Subchan { get; set; }— Bits 15–8 of CSDW.long Length { get; set; }— Bits 7–2 of CSDW.enum Modes— Values:DataIsPacked,DataIsUnpackedLSBPadded,Reserved,DataIsUnpackedMSBPadded.Modes Mode { get; set; }— Bits 1–0 of CSDW.SampleData[] Samples { get; }— Array of sample records; each containsshort[] ChannelData.
-
AbstractDataPacket(abstract base class)protected uint ChannelSpecificDataWord { get; protected set; }— CSDW field.IPacketHeader PacketHeader { get; protected set; }— Header reference.void SetCSDWBit(int bit, bool value)— Sets/clears a single bit in CSDW.bool GetCSDWBit(int bit)— Reads a bit from CSDW.protected int CommonHeaderWork(...)— Initializes header fields, computes packet length, handles padding, and writes secondary header/CSDW into_dataBytes.uint ComputeCheckSum()— Returns CRC32 viaUtils.Utils.GetCheckSum32.void SetRTC(long rtc)/long GetRTC()— Manages_rtcand header RTC.const long BASE_RTC = 141989612500056L— Reference RTC value.virtual byte[] GetBytes()— Serializes header +_dataBytes.- Protected constructors for initialization and deserialization.
3. Invariants
-
TransportStreamHeader:
MessageFormatmust be1.MessageTypemust be0.SequenceNumberis a 24-bit integer (range0x000000–0xFFFFFF).- Input byte array must be exactly 4 bytes.
-
SecondaryTimeFormatHeader:
- Input byte array must be exactly 12 bytes.
CheckSumis validated againstUtils.Utils.GetCheckSum8; mismatch triggers a trace warning but does not throw.LocalTimeis computed asnew DateTime(1970, 1, 1).AddSeconds(Seconds).AddTicks(NanoSeconds / 100).ToLocalTime().
-
Data Packets:
- All packets must have a valid
IPacketHeaderwith correctDataFileDataTypes. PacketHeader.PacketLengthis padded to a multiple of 4 bytes.ChannelSpecificDataWordis always 4 bytes and written into_dataBytesafter optional secondary header.ComputeCheckSum()operates over_dataBytesonly (not header).SetSequenceNumber(ushort seq)writes only the least significant byte ofseqtoPacketHeader.SequenceNum.
- All packets must have a valid
-
TimeDataPacket:
_dataBytesis fixed at 12 bytes.- Time fields are encoded in BCD format.
-
TMATSPacket:
TMATSDocumentextraction assumes ASCII encoding and skips 4-byte CSDW and optional secondary header.
-
AnalogDataFormat1Packet:
- Data is stored as big-endian
ushort(MSB first), converted to signedshortwith offset+0x8000. Modedefaults toDataIsUnpackedMSBPadded;Lengthdefaults to16.
- Data is stored as big-endian
4. Dependencies
Internal Dependencies
DTS.Serialization.IRIGCH10.Enums— DefinesDataFileDataTypes,DataTypeVersion,TimeSource,TimeFormats, etc.DTS.Serialization.IRIGCH10.Attributes— Used byTimeDataPacketforPacketHeaderValueAttribute.GetPacketHeaderValue.DTS.Serialization.IRIGCH10.Packets— ContainsPacketHeader,IPacketHeader,ITransportStreamHeader,ISecondaryTimeFormatHeader, and related classes.DTS.Common.Utilities— ProvidesUtilsclass with methods:BitArrayToInt32(BitArray, int, int)SetBits(BitArray, uint, int, int)GetCheckSum8(byte[])GetCheckSum32(byte[])GetBCDBytes(int)
External Dependencies
System— Core types (BitConverter,BitArray,DateTime,Encoding,Array,Buffer,MemoryStream,BinaryWriter).System.IO— ForMemoryStream,BinaryWriter.
Inferred Usage
AbstractDataPacketandIDataPacketare used by higher-level file writers/readers (e.g.,Chapter10File).TransportStreamHeaderis likely used in UDP packet serialization/deserialization.SecondaryTimeFormatHeaderis used inTimePacketFormat2,AnalogDataFormat1Packet, andTMATSPacketwhensecondaryHeaderPresent=true.PTP1588Timestamps.ToDateTimeString(...)is referenced but not defined in source—assumed external.
5. Gotchas
TimeDataPacket.SetSequenceNumberwrites only the LSB of the inputushort, ignoring the high byte.TransportStreamHeaderperforms bit extraction in reverse order (LSB-first) viaBitArrayToInt32(bits, start, end), whereendis inclusive and higher thanstart.SecondaryTimeFormatHeader.CheckSumis stored asushortbut computed as 8-bit; only the low byte is meaningful.TimePacketFormat1.ITSis documented as not serialized to CSDW due to validation tool incompatibility (commented as of 2023-10-27).AnalogDataFormat1Packetuses two different data versions:0x06(DASSAULT) for secondary headers,0x01(CH10 v105) otherwise.RecordingIndexIndexandRecordingIndexstoreDateTimein BCD format (e.g.,0x12for month=12), not binary.TimeDataPacket.SetTimeencodesdt.Millisecond / 10(tens of milliseconds), not full milliseconds.AbstractDataPacket.SetRTCupdates both_rtcandPacketHeader.SetRTC(rtc);GetRTC()returns_rtc.TMATSPacket.TMATSDocumentextraction assumes ASCII encoding; no validation of XML/ASCII format beyondXMLFormatbit.TransportStreamHeaderconstructor throwsNullReferenceExceptionfor null input (should beArgumentNullExceptionper .NET conventions).TimePacketFormat2.TimeStatusandNetworkTimeFormatenums includeRESERVEDas a valid return value, but deserialization does not throw on unknown values—defaults toRESERVED.AnalogDataFormat1Packetsamples are stored asshort[]inSampleData, but the underlying data is big-endianushort; conversion is handled inGetChannels.