Files
DP44/enriched-qwen3-coder-next/Common/DTS.Common.Serialization/IRIGCH10/Packets.md
2026-04-17 14:55:32 -04:00

221 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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-16T03:43:44.837011+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "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
- **`ITransportStreamHeader`**
- `int MessageFormat { get; }` — 4-bit field identifying the message format (must be `1` per spec).
- `int MessageType { get; }` — 4-bit field identifying the message type (must be `0` per spec).
- `int SequenceNumber { get; }` — 24-bit UDP sequence number, incremented per packet.
- **`ISecondaryTimeFormatHeader`**
- `int NanoSeconds { get; }` — Nanosecond component of the time stamp.
- `int Seconds { get; }` — Seconds since Unix epoch (1970-01-01).
- `ushort Reserved { get; }` — Reserved field (always `0` in current implementation).
- `ushort CheckSum { get; }` — 8-bit checksum over preceding fields (stored as `ushort`).
- `DateTime LocalTime { get; }` — Computed local time from `Seconds` and `NanoSeconds`.
- **`IDataPacket`**
- `IPacketHeader 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`** (implements `ITransportStreamHeader`)
- `TransportStreamHeader()` — Default constructor (fields uninitialized).
- `TransportStreamHeader(byte[] input)` — Parses 4-byte header; validates length (`TRANSPORT_HEADER_LENGTH = 4`), extracts `MessageFormat`, `MessageType`, and `SequenceNumber` via bit manipulation.
- `const int TRANSPORT_HEADER_LENGTH = 4` — Header size in bytes.
- **`SecondaryTimeFormatHeader`** (implements `ISecondaryTimeFormatHeader`)
- `SecondaryTimeFormatHeader(byte[] input)` — Parses 12-byte header; validates checksum via `Utils.Utils.GetCheckSum8`; logs mismatch via `Trace.WriteLine`.
- `static byte[] GetBytes(int nanoseconds, int seconds)` — Serializes header with `Reserved=0`, computes checksum.
- `const int SECONDARY_TIME_HEADER_LENGTH = 12` — Header size in bytes.
- **`TimeDataPacket`** (implements `IDataPacket`, extends `AbstractDataPacket`)
- `TimeDataPacket()` — Initializes with `DataFileDataTypes.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 (03) in `_dataBytes[0]`.
- `void SetTimeSource(TimeSource src)` — Sets time source using `PacketHeaderValueAttribute.GetPacketHeaderValue(src)`; bit-reverses order (per CH10 spec).
- `void SetTimeFormat(TimeFormats fmt)` — Sets time format bits (47) similarly.
- **`TMATSPacket`** (implements `IDataPacket`, extends `AbstractDataPacket`)
- `TMATSPacket(int nanoseconds, int seconds, string tmatsDoc, bool secondaryHeaderPresent)` — Constructs TMATS packet with ASCII/XML doc; sets data version (`0x01` or `0x09`).
- `TMATSPacket(byte[] bytes)` — Deserializes from byte array.
- `bool XMLFormat { get; }` — Extracted from bit 9 of `ChannelSpecificDataWord`.
- `bool SetupRecordConfigurationChange { get; }` — Extracted from bit 8.
- `RCCChapter10Versions Chapter10Version { get; }` — Extracted from bits 07; maps to enum (`RESERVED`, `RCC_106_07`, ..., `RCC_106_15`).
- `string TMATSDocument { get; }` — Extracts TMATS string from `_dataBytes` after skipping CSDW and optional secondary header.
- **`RootRecorderIndexPacket`** (implements `IDataPacket`, extends `AbstractDataPacket`)
- `RootRecorderIndexPacket(DateTime dt)` — Initializes with `DataFileDataTypes.ComputerGeneratedDataFormat3`.
- `void SetRootPacketAddress(long address)` — Stores 8-byte address.
- `void AddRecordingIndex(RecordingIndexIndex index)` — Adds to `_indices` list.
- `override byte[] GetBytes()` — Appends a self-referencing index entry before serializing.
- **`RecordingIndexIndex`**
- `const 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`** (implements `IDataPacket`, extends `AbstractDataPacket`)
- `RecorderIndexPacket()` — Initializes with `DataFileDataTypes.ComputerGeneratedDataFormat3`.
- `DateTime GetDateTime()` — Returns `GetDateTime()` of first `RecordingIndex`.
- `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.
- **`RecordingIndex`**
- `const 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`** (implements `IDataPacket`, extends `AbstractDataPacket`)
- `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 74 of CSDW.
- `enum TimeStatuses` — Values: `TimeNotValid`, `TimeValid`, `RESERVED`.
- `TimeStatuses TimeStatus { get; set; }` — Bits 30 of CSDW.
- `uint UnsignedSeconds { get; }` — Parsed from data section.
- `uint UnsignedNanoSeconds { get; }` — Parsed from data section.
- `string PTPTime { get; }` — Formatted via `PTP1588Timestamps.ToDateTimeString(...)`.
- **`TimePacketFormat1`** (implements `IDataPacket`, extends `AbstractDataPacket`)
- `TimePacketFormat1(byte sequenceNumber, DateTime packetTime, long rtc, int nanoseconds, int seconds)` — Constructor.
- `enum IRIGTimeSource` — Values: `IRIG_TCG_freewheeling`, ..., `RESERVED`.
- `IRIGTimeSource ITS { get; set; }` — Bits 1512 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 74 of CSDW.
- `enum TimeSources` — Values: `Internal`, `External`, `InternalFromRMM`, `Reserved`, `None`.
- `TimeSources TimeSource { get; set; }` — Bits 30 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`** (implements `IDataPacket`, extends `AbstractDataPacket`)
- `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 2724 of CSDW.
- `int TotChan { get; set; }` — Bits 2316 of CSDW.
- `long Subchan { get; set; }` — Bits 158 of CSDW.
- `long Length { get; set; }` — Bits 72 of CSDW.
- `enum Modes` — Values: `DataIsPacked`, `DataIsUnpackedLSBPadded`, `Reserved`, `DataIsUnpackedMSBPadded`.
- `Modes Mode { get; set; }` — Bits 10 of CSDW.
- `SampleData[] Samples { get; }` — Array of sample records; each contains `short[] 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 via `Utils.Utils.GetCheckSum32`.
- `void SetRTC(long rtc)` / `long GetRTC()` — Manages `_rtc` and 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**:
- `MessageFormat` must be `1`.
- `MessageType` must be `0`.
- `SequenceNumber` is a 24-bit integer (range `0x000000``0xFFFFFF`).
- Input byte array must be exactly 4 bytes.
- **SecondaryTimeFormatHeader**:
- Input byte array must be exactly 12 bytes.
- `CheckSum` is validated against `Utils.Utils.GetCheckSum8`; mismatch triggers a trace warning but does not throw.
- `LocalTime` is computed as `new DateTime(1970, 1, 1).AddSeconds(Seconds).AddTicks(NanoSeconds / 100).ToLocalTime()`.
- **Data Packets**:
- All packets must have a valid `IPacketHeader` with correct `DataFileDataTypes`.
- `PacketHeader.PacketLength` is padded to a multiple of 4 bytes.
- `ChannelSpecificDataWord` is always 4 bytes and written into `_dataBytes` after optional secondary header.
- `ComputeCheckSum()` operates over `_dataBytes` only (not header).
- `SetSequenceNumber(ushort seq)` writes only the least significant byte of `seq` to `PacketHeader.SequenceNum`.
- **TimeDataPacket**:
- `_dataBytes` is fixed at 12 bytes.
- Time fields are encoded in BCD format.
- **TMATSPacket**:
- `TMATSDocument` extraction assumes ASCII encoding and skips 4-byte CSDW and optional secondary header.
- **AnalogDataFormat1Packet**:
- Data is stored as big-endian `ushort` (MSB first), converted to signed `short` with offset `+0x8000`.
- `Mode` defaults to `DataIsUnpackedMSBPadded`; `Length` defaults to `16`.
## 4. Dependencies
### Internal Dependencies
- **`DTS.Serialization.IRIGCH10.Enums`** — Defines `DataFileDataTypes`, `DataTypeVersion`, `TimeSource`, `TimeFormats`, etc.
- **`DTS.Serialization.IRIGCH10.Attributes`** — Used by `TimeDataPacket` for `PacketHeaderValueAttribute.GetPacketHeaderValue`.
- **`DTS.Serialization.IRIGCH10.Packets`** — Contains `PacketHeader`, `IPacketHeader`, `ITransportStreamHeader`, `ISecondaryTimeFormatHeader`, and related classes.
- **`DTS.Common.Utilities`** — Provides `Utils` class 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`** — For `MemoryStream`, `BinaryWriter`.
### Inferred Usage
- `AbstractDataPacket` and `IDataPacket` are used by higher-level file writers/readers (e.g., `Chapter10File`).
- `TransportStreamHeader` is likely used in UDP packet serialization/deserialization.
- `SecondaryTimeFormatHeader` is used in `TimePacketFormat2`, `AnalogDataFormat1Packet`, and `TMATSPacket` when `secondaryHeaderPresent=true`.
- `PTP1588Timestamps.ToDateTimeString(...)` is referenced but not defined in source—assumed external.
## 5. Gotchas
- **`TimeDataPacket.SetSequenceNumber`** writes only the LSB of the input `ushort`, ignoring the high byte.
- **`TransportStreamHeader`** performs bit extraction in reverse order (LSB-first) via `BitArrayToInt32(bits, start, end)`, where `end` is inclusive and higher than `start`.
- **`SecondaryTimeFormatHeader.CheckSum`** is stored as `ushort` but computed as 8-bit; only the low byte is meaningful.
- **`TimePacketFormat1.ITS`** is documented as *not serialized* to CSDW due to validation tool incompatibility (commented as of 2023-10-27).
- **`AnalogDataFormat1Packet`** uses two different data versions: `0x06` (DASSAULT) for secondary headers, `0x01` (CH10 v105) otherwise.
- **`RecordingIndexIndex` and `RecordingIndex`** store `DateTime` in BCD format (e.g., `0x12` for month=12), not binary.
- **`TimeDataPacket.SetTime`** encodes `dt.Millisecond / 10` (tens of milliseconds), not full milliseconds.
- **`AbstractDataPacket.SetRTC`** updates both `_rtc` and `PacketHeader.SetRTC(rtc)`; `GetRTC()` returns `_rtc`.
- **`TMATSPacket.TMATSDocument`** extraction assumes ASCII encoding; no validation of XML/ASCII format beyond `XMLFormat` bit.
- **`TransportStreamHeader`** constructor throws `NullReferenceException` for null input (should be `ArgumentNullException` per .NET conventions).
- **`TimePacketFormat2.TimeStatus`** and **`NetworkTimeFormat`** enums include `RESERVED` as a valid return value, but deserialization does not throw on unknown values—defaults to `RESERVED`.
- **`AnalogDataFormat1Packet`** samples are stored as `short[]` in `SampleData`, but the underlying data is big-endian `ushort`; conversion is handled in `GetChannels`.