--- source_files: - Common/DTS.Common.Serialization/IRIGCH10/Packets/ITransportStreamHeader.cs - Common/DTS.Common.Serialization/IRIGCH10/Packets/ISecondaryTimeFormatHeader.cs - Common/DTS.Common.Serialization/IRIGCH10/Packets/TransportStreamHeader.cs - Common/DTS.Common.Serialization/IRIGCH10/Packets/SecondaryTimeFormatHeader.cs - Common/DTS.Common.Serialization/IRIGCH10/Packets/TimeDataPacket.cs - Common/DTS.Common.Serialization/IRIGCH10/Packets/TMATSPacket.cs - Common/DTS.Common.Serialization/IRIGCH10/Packets/RootRecorderIndexPacket.cs - Common/DTS.Common.Serialization/IRIGCH10/Packets/RecorderIndexPacket.cs - Common/DTS.Common.Serialization/IRIGCH10/Packets/TimePacketFormat2.cs - Common/DTS.Common.Serialization/IRIGCH10/Packets/IDataPacket.cs - Common/DTS.Common.Serialization/IRIGCH10/Packets/TimePacketFormat1.cs - Common/DTS.Common.Serialization/IRIGCH10/Packets/AnalogDataFormat1Packet.cs generated_at: "2026-04-17T15:30:22.882503+00:00" model: "zai-org/GLM-5-FP8" schema_version: 1 sha256: "ea68d7597278f2c1" --- # IRIG Chapter 10 Packet Serialization Module Documentation ## 1. Purpose This module provides serialization and deserialization support for IRIG 106 Chapter 10 data packets. It implements the packet structures defined in the Chapter 10 standard for recording and playback of telemetry data, including time data packets (Format 1 and Format 2), TMATS configuration packets, analog data packets, and recorder index packets. The module serves as the foundational layer for reading and writing Chapter 10 format files, handling binary encoding, checksums, and time format conversions. --- ## 2. Public Interface ### Interfaces #### `ITransportStreamHeader` ```csharp public interface ITransportStreamHeader { int MessageFormat { get; } int MessageType { get; } int SequenceNumber { get; } } ``` Defines read-only access to transport stream header fields. #### `ISecondaryTimeFormatHeader` ```csharp public interface ISecondaryTimeFormatHeader { int NanoSeconds { get; } int Seconds { get; } ushort Reserved { get; } ushort CheckSum { get; } DateTime LocalTime { get; } } ``` Defines read-only access to secondary time format header fields. #### `IDataPacket` ```csharp public interface IDataPacket { IPacketHeader PacketHeader { get; } uint ComputeCheckSum(); byte[] GetBytes(); void SetRTC(long rtc); void SetDataVersion(DataTypeVersion version); void SetChannelID(ushort channelID); void SetSequenceNumber(ushort seq); } ``` Defines the contract for all Chapter 10 data packets. --- ### Abstract Base Class #### `AbstractDataPacket` Base class for all packet types. Provides common functionality: | Member | Signature | Description | |--------|-----------|-------------| | `ChannelSpecificDataWord` | `uint` property | Gets/sets the Channel Specific Data Word (CSDW). | | `PacketHeader` | `IPacketHeader` property | Gets the packet header. | | `ComputeCheckSum` | `uint ComputeCheckSum()` | Computes 32-bit checksum of packet data. | | `GetRTC` | `long GetRTC()` | Returns the 10MHz Realtime Counter value. | | `SetRTC` | `void SetRTC(long rtc)` | Sets the RTC value in both the packet and header. | | `SetSequenceNumber` | `void SetSequenceNumber(ushort seq)` | Sets the packet sequence number. | | `SetDataVersion` | `void SetDataVersion(DataTypeVersion version)` | Sets the data version in the header. | | `SetChannelID` | `void SetChannelID(ushort channelID)` | Sets the channel ID in the header. | | `GetBytes` | `virtual byte[] GetBytes()` | Serializes the packet to a byte array. | | `BASE_RTC` | `const long = 141989612500056L` | Base RTC value constant. | --- ### Concrete Packet Classes #### `TransportStreamHeader` ```csharp public TransportStreamHeader(byte[] input) public const int TRANSPORT_HEADER_LENGTH = 4; ``` Parses a 4-byte transport stream header. Extracts `MessageFormat` (bits 0-3), `MessageType` (bits 4-7), and `SequenceNumber` (bits 8-31) from the input bytes. #### `SecondaryTimeFormatHeader` ```csharp public SecondaryTimeFormatHeader(byte[] input) public static byte[] GetBytes(int nanoseconds, int seconds) public const int SECONDARY_TIME_HEADER_LENGTH = 12; ``` Parses or constructs a 12-byte secondary time header. `LocalTime` is computed as Unix epoch (1970-01-01) plus `Seconds` and `NanoSeconds` converted to ticks, then converted to local time. Constructor validates checksum and writes to `Trace` on mismatch. #### `TimeDataPacket` ```csharp public TimeDataPacket() public DateTime GetDateTime() public void SetTime(DateTime dt) public void SetTimeSource(byte b) public void SetTimeSource(TimeSource src) public void SetTimeFormat(TimeFormats fmt) ``` Implements Time Data Format 1 packet. `SetTime` encodes a `DateTime` into BCD format in a 12-byte payload at positions 4-11. #### `TimePacketFormat1` ```csharp public TimePacketFormat1(byte sequenceNumber, DateTime packetTime, long rtc, int nanoseconds, int seconds) ``` Implements Time Data Format 1 with full IRIG time encoding. Properties include: - `ITS` (`IRIGTimeSource` enum) - IRIG time source (bits 15-12, not serialized per comment) - `TimeFormat` (`TimeFormats` enum) - bits 7-4 - `TimeSource` (`TimeSources` enum) - bits 3-0 - `DateFormat` (`DateFormats` enum) - bit 9 - `IsLeapYear` (`bool`) - bit 8 - `TimePacketTime` (`DateTime`) - the time represented by this packet #### `TimePacketFormat2` ```csharp public TimePacketFormat2(byte sequenceNumber, bool rtcSyncError, int nanoseconds, int seconds, long rtc, bool includeSecondaryHeader) public TimePacketFormat2(byte[] bytes) ``` Implements Time Data Format 2 for network time protocols. Properties include: - `LocalTimeOfFirstSample` (`DateTime`) - `NetworkTimeFormat` (`NetworkTimeFormats` enum) - bits 7-4 - `TimeStatus` (`TimeStatuses` enum) - bits 3-0 - `UnsignedSeconds` (`uint`) - `UnsignedNanoSeconds` (`uint`) - `PTPTime` (`string`) - formatted PTP timestamp #### `TMATSPacket` ```csharp public TMATSPacket(int nanoseconds, int seconds, string tmatsDoc, bool secondaryHeaderPresent) public TMATSPacket(byte[] bytes) public string TMATSDocument { get; } public bool XMLFormat { get; } public bool SetupRecordConfigurationChange { get; } public RCCChapter10Versions Chapter10Version { get; } ``` Implements TMATS (Telemetry Attributes Transfer Standard) packet. `TMATSDocument` returns ASCII-decoded content. `RCCChapter10Versions` enum maps values 0x07-0x0B to versions RCC_106_07 through RCC_106_15. #### `AnalogDataFormat1Packet` ```csharp public AnalogDataFormat1Packet(int nanoseconds, int seconds, Chapter10File.GetNextSampleDelegate getNextSample, int totalChannels, long channelLength, long rtc, long numSamples, long currentSample, byte sequenceNumber, ushort channelId, bool includeSecondaryHeader) public AnalogDataFormat1Packet(byte[] bytes) public SampleData[] Samples { get; } ``` Implements Analog Data Format 1 packet. CSDW properties: - `Same` (bit 28) - `Factor` (bits 27-24) - `TotChan` (bits 23-16) - `Subchan` (bits 15-8) - `Length` (bits 7-2) - `Mode` (`Modes` enum, bits 1-0) `SampleData` inner class holds `ChannelData` as `short[]`. #### `RecorderIndexPacket` ```csharp public RecorderIndexPacket() public void SetRootPacketAddress(long address) public void AddRecordingIndex(RecordingIndex index) public int NumberOfEntries { get; } public DateTime GetDateTime() public override byte[] GetBytes() ``` Implements recorder index packet. Uses hardcoded `ChannelSpecificDataWord = {0x8D, 0x02, 0x00, 0xE0}`. #### `RootRecorderIndexPacket` ```csharp public RootRecorderIndexPacket(DateTime dt) public void SetRootPacketAddress(long address) public void AddRecordingIndex(RecordingIndexIndex index) public override byte[] GetBytes() ``` Implements root recorder index packet (last packet in file). Uses hardcoded `ChannelSpecificDataWord = {0x8D, 0x00, 0x00, 0x60}`. #### `RecordingIndex` ```csharp public RecordingIndex(long rtc, long offset, DateTime dt) public const int SIZE = 28; public byte[] GetBytes() public DateTime GetDateTime() ``` Helper structure for recorder index entries. Fixed size of 28 bytes. #### `RecordingIndexIndex` ```csharp public RecordingIndexIndex(long rtc, long offset, DateTime dt) public const int SIZE = 24; public byte[] GetBytes() ``` Helper structure for root index entries. Fixed size of 24 bytes. --- ## 3. Invariants - **TransportStreamHeader**: Input must be exactly `TRANSPORT_HEADER_LENGTH` (4) bytes; null input throws `NullReferenceException`. - **SecondaryTimeFormatHeader**: Input must be exactly `SECONDARY_TIME_HEADER_LENGTH` (12) bytes. - **Packet alignment**: `PacketHeader.PacketLength` is always padded to a multiple of 4 bytes. - **RTC consistency**: Setting RTC via `SetRTC(long)` updates both the internal `_rtc` field and `PacketHeader`. - **Sequence numbers**: Should be monotonically increasing and wrap to 0 after maximum value (caller responsibility). - **TimeDataPacket**: `_dataBytes` is initialized to 12 bytes; time data is written at positions 4-11. - **TMATSDocument encoding**: Always decoded as ASCII. - **AnalogDataFormat1Packet sample data**: Samples are byte-swapped and offset by 0x8000 for signed/unsigned conversion. --- ## 4. Dependencies ### This module depends on: - `DTS.Serialization.IRIGCH10.Enums` - Data type enumerations (`DataFileDataTypes`, `DataTypeVersion`) - `DTS.Serialization.IRIGCh10.Attributes` - `PacketHeaderValueAttribute` - `DTS.Serialization.IRIGCH10.Packets` - `PacketHeader`, `IPacketHeader` - `DTS.Common.Utilities` - `PTP1588Timestamps` (referenced in `TimePacketFormat2`) - `Utils.Utils` (external utility class) - Static methods: `BitArrayToInt32`, `SetBits`, `GetCheckSum8`, `GetCheckSum32`, `GetBCDBytes` - `System.IO` - `MemoryStream`, `BinaryWriter` - `System.Collections` - `BitArray` ### What depends on this module: - `Chapter10File` (referenced in `AnalogDataFormat1Packet` constructor delegate type `GetNextSampleDelegate`) --- ## 5. Gotchas 1. **SecondaryTimeFormatHeader checksum validation is non-blocking**: When checksum mismatch occurs, the constructor only writes to `System.Diagnostics.Trace.WriteLine` rather than throwing an exception. Callers must not assume valid checksums. 2. **TimePacketFormat1 ITS field not serialized**: The `ITS` property (IRIGTimeSource) is explicitly not serialized to the CSDW due to EMC validation tool compatibility issues (comment dated 2023-10-27). 3. **Hardcoded ChannelSpecificDataWord values**: `RecorderIndexPacket` and `RootRecorderIndexPacket` use hardcoded byte arrays for `ChannelSpecificDataWord` with comments indicating uncertainty about individual field breakdown. 4. **AnalogDataFormat1Packet data version selection**: Uses `DATA_VERSION_DASSAULT` (0x06) when secondary header is present, otherwise `DATA_VERSION_V105` (0x01). Comment indicates EMC validation tool only supports CH10 106v5. 5. **TimeDataPacket SetTimeSource overloads behave differently**: The `byte` overload sets bits 0-3 directly, while the `TimeSource` enum overload reverses bit order (bit 0←3, bit 1←2, etc.) per Chapter 10 reference 10-47. 6. **LocalTime calculation in SecondaryTimeFormatHeader**: Uses `AddTicks(NanoSeconds / 100)` which truncates nanoseconds to 100-nanosecond tick precision. 7. **RecordingIndexIndex added automatically in RootRecorderIndexPacket.GetBytes()**: The last index entry pointing back to the current packet is appended internally during `GetBytes()` call, modifying `_indices` list state.