--- source_files: - Common/DTS.Common.ICommunication/IDASConnectedDevice.cs - Common/DTS.Common.ICommunication/ICommunication.cs - Common/DTS.Common.ICommunication/Communication.cs generated_at: "2026-04-16T14:07:22.447976+00:00" model: "zai-org/GLM-5-FP8" schema_version: 1 sha256: "b573bb7d2f5d27d0" --- # Documentation: DTS.Common.ICommunication ## 1. Purpose This module provides the core communication infrastructure for interacting with DAS (Data Acquisition System) hardware devices. It defines the contract for connected devices via `IDASConnectedDevice`, encapsulates device metadata through `Communication_DASInfo`, and implements an asynchronous, callback-driven communication layer via the abstract `Communication` class. The module handles connection lifecycle management, command execution with timeout handling, cancellation support, and protocol version negotiation for hardware commands. --- ## 2. Public Interface ### IDASConnectedDevice (Interface) **Namespace:** `DTS.DASLib.Communication` Describes a device connected to a DAS (e.g., S6 connected to S6DB). | Property | Type | Description | |----------|------|-------------| | `DeviceType` | `HardwareTypes` | The device type of the connected device | | `Port` | `int` | The port on the DAS which the device is on (0-based) | | `SpotOnPort` | `int` | The spot on the chain or port the device is on (0-based) | | `PhysicalAddress` | `PhysicalAddress` | MAC Address or physical address | | `IPAddress` | `string` | The IP address of the device | | `SerialNumber` | `string` | The serial number of the device | | `Location` | `string` | The location of the device | | `Version` | `string` | The version of the device | --- ### CanceledException (Class) **Namespace:** `DTS.Common.ICommunication` A marker exception class extending `ApplicationException` to signal operation cancellation. --- ### Communication_DASInfo (Class) **Namespace:** `DTS.Common.ICommunication` **Implements:** `ICommunication_DASInfo` Encapsulates metadata about a DAS device. **Properties:** | Property | Type | Default | Description | |----------|------|---------|-------------| | `FirstUseDate` | `DateTime?` | `null` | Date of first use; `null` indicates hardware not used since calibration. Only valid when `IsFirstUseDateSupported` is `true` | | `IsFirstUseDateSupported` | `bool` | `false` | Indicates hardware supports first use dates | | `IsStreamingSupported` | `bool` | `false` | Indicates whether streaming is supported | | `ConnectedDevices` | `IDASConnectedDevice[]` | empty array | Devices connected to the DAS (currently only used by SLICE6DB) | | `SerialNumbers` | `string[]` | - | Array of serial numbers | | `FirmwareVersions` | `string[]` | - | Array of firmware versions | **Methods:** - `void SetConnectedDevices(IDASConnectedDevice[] devices)` — Sets the `ConnectedDevices` array - `string StackSerialNumber(int devid)` — Returns a stacked serial number string. Returns "N/A" if `SerialNumbers` is null/empty; returns `SerialNumbers[0]::SerialNumbers[devid]` if `devid` is non-zero and valid; otherwise returns `SerialNumbers[0]` **Constructors:** - `Communication_DASInfo()` — Default constructor - `Communication_DASInfo(string[] serials, string[] fwnums)` — Constructs with cloned copies of serial and firmware arrays --- ### Communication\ (Abstract Class) **Namespace:** `DTS.Common.ICommunication` **Implements:** `Interface.DASFactory.ICommunication`, `IDisposable` **Constraint:** `where T : IConnection, new()` Abstract base class for hardware communication, providing connection management, command execution, and cancellation support. **Properties:** | Property | Type | Description | |----------|------|-------------| | `ErrorInSetup` | `bool` | Indicates an error occurred during setup | | `ConnectString` | `string` | Connection string from underlying socket | | `Connected` | `bool` | Whether the socket is connected | | `DASInfo` | `ICommunication_DASInfo` | DAS device information | | `Transport` | `IConnection` | Underlying connection transport (setter throws `NotSupportedException`) | | `ReceiveBufferSize` | `int` | Receive buffer size; default is 65536 (2^16) | | `SerialNumber` | `string` | Device serial number | | `FirmwareVersion` | `string` | Device firmware version; setter triggers `FirmwareVersionUpdated()` | | `ProtocolVersion` | `byte` | Protocol version for command support checks | | `MinimumProtocols` | `Dictionary` | Maps commands to minimum required protocol versions | | `FlushTimeoutMilliSec` | `int` | Timeout for flush operations; default is 5ms | | `ExecuteIsBusy` | `bool` | Thread-safe flag indicating execution lock state | | `CancelEvent` | `ManualResetEvent` | Event signaling cancellation has occurred | **Events:** - `EventHandler OnDisconnected` — Raised when the underlying socket disconnects **Public Methods:** - `int CompareTo(Interface.DASFactory.ICommunication dev)` — Compares connection strings (case-insensitive, ordinal) - `int CompareTo(string conStr)` — Compares connection string to provided string - `abstract void InitMinProto()` — Must be implemented to populate `MinimumProtocols` - `bool IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands command)` — Returns `true` if `ProtocolVersion >= GetMinProto(command)` - `byte GetMinProto(DFConstantsAndEnums.ProtocolLimitedCommands command)` — Returns minimum protocol version for command; returns `0xFF` if not found; throws `NotSupportedException` if `MinimumProtocols` is null - `void Flush(int timeoutMs)` — Flushes the socket data buffer until empty or timeout - `byte[] SyncExecute(byte[] byteData, int cbTimeout)` — **Throws `NotSupportedException`** (not implemented) - `void Connect(string connectString, CommunicationCallback callback, object callbackObject, int callbackTimeout, string hostIPAddress)` — Initiates asynchronous connection - `void Disconnect(bool reuseSocket, CommunicationCallback callback, object callbackObject, int callbackTimeout)` — Initiates asynchronous disconnect - `void Cancel()` — Sets cancel state with 500ms sleep delay on clear - `void ForceCancel()` — Sets cancel state with 250ms sleep delay on clear - `bool IsCanceled()` — Returns current cancel state - `void ClearCancel()` — Clears cancel state after sleeping - `void Execute(byte[] byteData, CommunicationCallback cb, object cbObject, int cbTimeout)` — Sends data and processes responses asynchronously - `void PseudoExecute(byte[] byteData, CommunicationCallback cb, object cbObject, int cbTimeout)` — For commands that only receive data (no send); does not clear buffer - `void SetupReader()` — Initializes the asynchronous receive loop - `void Close(int timeout)` — Empty implementation (no-op) - `void Dispose()` — Implements `IDisposable` **Protected Methods:** - `void Lock()` — Empty implementation - `void Release()` — Empty implementation - `virtual void FirmwareVersionUpdated()` — Called when `FirmwareVersion` is set --- ### CommunicationReport (Class) **Namespace:** `DTS.Common.ICommunication` **Implements:** `ICommunicationReport` Carries the result of an asynchronous communication operation. | Property | Type | Description | |----------|------|-------------| | `UserState` | `object` | User-provided state object | | `Result` | `CommunicationResult` | Result enum value | | `Data` | `byte[]` | Received data (for read operations) | **Constructor:** `CommunicationReport(object state, CommunicationResult res)` --- ### Communication\.ActionData (Abstract Nested Class) Base class for tracking asynchronous operations with timeout handling. | Property | Description | |----------|-------------| | `UserCallback` | `CommunicationCallback` delegate | | `UserCallbackObject` | User-provided state object | | `UserTimeout` | Timeout in milliseconds | | `TimerExpired` | Whether the timeout timer fired | **Methods:** - `void StartTimer()` — Starts the timeout timer - `void KillTimer()` — Stops and disposes the timer - `bool ReportCanceled()` — Invokes callback with `CommunicationResult.Canceled` - `abstract bool ReportFailure()` — Must implement failure reporting - `abstract bool ReportSuccess()` — Must implement success reporting - `abstract CommunicationResult GetTimeoutResult()` — Must return the timeout-specific result --- ### Communication\.ExecuteActionData (Nested Class) Extends `ActionData` for execute operations. **Additional Methods:** - `bool ReportReadSuccess(byte[] data)` — Reports successful read with data - `bool ReportReadTimeout()` — Reports read timeout - `bool ReportReadDisconnected()` — Reports disconnection during read --- ### Communication\.PseudoAsyncResult (Nested Class) Implements `IAsyncResult` for `PseudoExecute` operations. | Property | Value | |----------|-------| | `IsCompleted` | Always `true` | | `AsyncState` | The `ExecuteActionData` instance | | `CompletedSynchronously` | Always `true` | | `AsyncWaitHandle` | Throws `NotImplementedException` | --- ## 3. Invariants 1. **Connection State Consistency**: `sock` is instantiated in the constructor and cannot be replaced via `Transport` setter (throws `NotSupportedException`). 2. **Execute Locking**: `ExecuteIsBusy` must be `false` before setting to `true`, and `true` before setting to `false`. Debug assertions enforce this—violations indicate re-entry or extra unlock bugs. 3. **Port/Spot Indexing**: `Port` and `SpotOnPort` on `IDASConnectedDevice` are 0-based indices. 4. **FirstUseDate Validity**: `FirstUseDate` is only meaningful when `IsFirstUseDateSupported` is `true`. 5. **MinimumProtocols Initialization**: `MinimumProtocols` must be populated by `InitMinProto()` before calling `GetMinProto()` or `IsCommandSupported()`, otherwise `NotSupportedException` is thrown. 6. **Callback Non-Null Assertion**: `ActionData` constructor asserts that the callback parameter is non-null. 7. **Thread ID Consistency**: In `ProcessReceivedData` and `SRRecvCallback`, if the thread ID changes during `WaitWithCondition.Wait`, the method exits early without processing. --- ## 4. Dependencies ### This module depends on: - `DTS.Common.Enums.Hardware` — `HardwareTypes` enum - `DTS.Common.Enums.Communication` — `CommunicationResult`, `CommunicationConstantsAndEnums` - `DTS.Common.Enums.DASFactory` — `DFConstantsAndEnums` - `DTS.Common.Interface.Communication` — `ICommunication_DASInfo`, `CommunicationCallback` delegate - `DTS.Common.Interface.Connection` — `IConnection` - `DTS.Common.Classes.Connection` — (referenced but contents not in source) - `DTS.Common.Utilities.Logging` — `APILogger` - `DTS.Common.Utilities` — `SecureQueue` - `DTS.Common.Utils` — `WaitWithCondition` - `System.Net.NetworkInformation` — `PhysicalAddress` - `System.Net.Sockets` — `SocketException` - `System.Threading` — `ManualResetEvent`, `Timer`, `Timeout` - `System.Threading.Tasks` — `Task` ### What depends on this module: - Implementations of `IConnection` (generic constraint `T`) - Concrete DAS communication implementations that extend `Communication` - Consumers of `IDASConnectedDevice` for device enumeration - Consumers of `ICommunication_DASInfo` for device metadata --- ## 5. Gotchas 1. **SyncExecute Not Implemented**: Calling `SyncExecute()` throws `NotSupportedException`. Use `Execute()` with callbacks instead. 2. **Lock/Release Are No-ops**: `Lock()` and `Release()` methods have empty implementations. Any synchronization relying on these is not actually protected. 3. **Close() Does Nothing**: `Close(int timeout)` has an empty body and performs no cleanup. 4. **Cancel Sleep Delays**: `ClearCancel()` sleeps for either 500ms (after `Cancel()`) or 250ms (after `ForceCancel()`) before clearing the cancel state. This can introduce unexpected latency. 5. **Transport Setter Always Throws**: Setting `Transport` throws `NotSupportedException`—the socket cannot be replaced after construction. 6. **PseudoExecute Buffer Behavior**: Unlike `Execute()`, `PseudoExecute()` does not flush the buffer before operation and picks up from wherever the previous `PseudoExecute` left off. 7. **StackSerialNumber Edge Cases**: Returns "N/A" for empty/null `SerialNumbers`, but returns `SerialNumbers[0]` for `devid` values outside valid range (except 0). This may mask indexing errors. 8. **ActionData Timer Race**: The timer callback and `KillTimer()` both check `_timerFired` under a lock, but if the timer fires just before disposal, the callback will still execute. 9. **ReceiveCallback Disconnection Handling**: When `sock.EndReceive` returns 0 bytes, `_receiveCallbackRunning` is set to `false` and `OnDisconnected` is invoked, but the socket state is not explicitly cleaned up. 10. **Extra Communication Logging**: Conditional logging via `DFConstantsAndEnums.ExtraCommunicationLogging` may impact performance if enabled in production.