The TDAS<T> class is a core service implementation for the TDAS (Time-Domain Acquisition System) hardware family, providing a unified interface across multiple connection types (Ethernet, Serial) and hardware variants (G5, Rack, SIM, TOM, LabRack). It implements multiple interface contracts (IDASCommunication, IConfigurationActions, IDiagnosticsActions, ITriggerCheckActions, IRealTimeActions, IArmActions, IDownloadActions) to manage configuration, diagnostics, arming, triggering, real-time data streaming, and event downloading. The class acts as a bridge between high-level application logic and low-level hardware commands, encapsulating device-specific behavior (e.g., G5 vs. non-G5 modules) and maintaining runtime state (e.g., arming status, recording flags, diagnostic results). It inherits from Communication<T> and uses asynchronous workers via ThreadPool.QueueUserWorkItem for long-running operations, with callback-based progress and result reporting.
2. Public Interface
Core Properties
bool IsEthernetDistributor()
Returns false. Indicates this instance is not an Ethernet distributor.
bool IsSlice6Distributor()
Returns false. Indicates this instance is not a Slice6 distributor.
bool IsBattery()
Returns false. Indicates this instance is not a battery-powered device.
bool IsTSRAIR()
Returns false. Indicates this instance is not a TSRAIR device.
bool IsSlice6Air()
Returns false. Indicates this instance is not a Slice6 Air device.
bool IsSlice6AirTc()
Returns false. Indicates this instance is not a Slice6 Air TC device.
bool IsScheduleEventCountSupported()
Returns false. Schedule event counting is not supported.
HardwareTypes GetHardwareType()
Determines hardware type based on SerialNumber prefix:
"5M" → G5INDUMMY or G5VDS (depending on G5Mode)
"DR" → TDAS_Pro_Rack
"SM" → SIM
"TOM" → TOM
"LR" → TDAS_LabRack
Otherwise → TDAS_Pro_Rack (fallback)
string SerialNumber(inherited from ICommunication, overridden)
Device serial number used for identification and equality comparison.
bool StartRecord
Gets/sets whether recording has been started (protected setter).
float InputLowVoltage, InputMediumVoltage, InputHighVoltage
Input voltage thresholds.
float BatteryLowVoltage, BatteryMediumVoltage, BatteryHighVoltage
Battery voltage thresholds.
double MinimumValidInputVoltage, MaximumValidInputVoltage
Valid input voltage range.
double MinimumValidBatteryVoltage, MaximumValidBatteryVoltage
Valid battery voltage range.
bool CheckAAF(float rate)
Returns true. Anti-aliasing filter validation is not implemented for TDAS.
ulong GetPhaseShiftSamples(uint ModuleIndex, double ActualSampleRate, uint HardwareAAF, ulong originalT0)
Returns 0. Phase shift is not known for TDAS modules.
Configuration
IConfigurationData ConfigData { get; set; }
Holds configuration data for the device.
Diagnostics
IDiagnosticActions[] ChannelDiagnostics { get; set; }
Diagnostic actions per channel.
class EthernetTDAS : TDAS<EthernetConnection>
TDAS using Ethernet connection.
class SerialTDAS : TDAS<SerialConnection>
TDAS using serial connection.
3. Invariants
Connection Requirement: All async operations (StartTriggerCheck, DoTriggerCheck, etc.) require Connected == true; otherwise, NotConnectedException is thrown.
Hardware Type Determination: GetHardwareType() relies solely on SerialNumber prefix; invalid prefixes default to TDAS_Pro_Rack.
Arming State: DASArmStatus must be initialized before use in arming/triggering methods; if null, a new ArmStatus is created and initialized.
Module Iteration: Trigger check operations iterate over DASInfo.Modules, skipping EMPTYBANK modules and applying G5-specific logic when IsG5() is true.
G5 Module Handling: For G5 devices (SerialNumber.StartsWith("5M")), only module index 0 is processed in trigger checks (other modules skipped).
Phase Shift: GetPhaseShiftSamples always returns 0; no phase shift is applied.
Equality: Two TDAS<T> instances are equal if their SerialNumber values are equal (null/empty handled).
Async Callback Safety: All TDASServiceAsyncInfo callback methods (Error, Success, etc.) wrap callback invocations in try/catch to prevent unhandled exceptions from propagating.
4. Dependencies
Internal Dependencies (from source):
Communication<T>: Base class providing core communication functionality.
DTS.Common.ICommunication: Defines ICommunication<T>, IInfoResult, IDownload, etc.
DTS.Common.Interface.Connection: Defines IConnection (generic type constraint T : IConnection, new()).
DoTriggerCheckSync Not Implemented: The method ITriggerCheckActions.DoTriggerCheckSync() throws NotImplementedException with a comment indicating it was intentionally left unimplemented for TDAS due to minimal impact of the original issue (ECM event line check). Using this method will crash at runtime.
IsG5() Not Defined: The method IsG5() is used in TriggerCheck.cs but is not defined in the provided source. It must be defined elsewhere (e.g., in Communication<T> or a partial class).
G5Mode Property: Used in GetHardwareType() but not defined in the provided source. Must be defined elsewhere.
Connected Property: Used in LaunchAsyncWorker and CallSyncMethod but not defined in the provided source. Must be defined in Communication<T>.
ServiceCallback and ServiceCallbackData: Types used for async callbacks but not defined in the provided source. Their structure (e.g., CallbackStatus enum, AddSampleData overloads) is inferred from usage.
TDASServiceSetupInfo Type: Referenced in TDASDownloadServiceAsyncInfo but not defined in the provided source.
IsG5() Assumption: The trigger check logic assumes IsG5() returns true for "5M" serials, but this is not explicitly stated.
G5 Module Indexing: In AsyncStartTriggerCheck and AsyncCancelTriggerCheck, G5 devices only process module index 0 (break after first non-empty module), but this is not documented in comments.
GetIsStreaming() Always Returns false: Despite the comment, it does not track streaming state dynamically.
SetInRealtime Ignores ExitRealtimeIfPossible: The parameter ExitRealtimeIfPossible is unused in the implementation.
SetEventArmAttemps Typo: Method name has typo (SetEventArmAttemps instead of SetEventArmAttempts).
TDASServiceAsyncInfo.NewData Overloads: Multiple overloads exist for NewData, but the IList<short[][]> overload hardcodes sequenceNumber = 0 for all samples.
Equals/GetHashCode on Null SerialNumber: Two devices with null/empty SerialNumber are considered equal, which may be unintended.
No-Op Trigger Check Pre/Post: PreStartTriggerCheck and PostStartTriggerCheck do nothing—consumers may expect actual logic here.
StartRecord Protected Setter: Only settable internally; external code must use SetInArm/SetInRealtime to influence state.