Files
DP44/enriched-partialglm/Common/DTS.Common.ICommunication.md
2026-04-17 14:55:32 -04:00

214 lines
11 KiB
Markdown

---
source_files:
- Common/DTS.Common.ICommunication/IDASConnectedDevice.cs
- Common/DTS.Common.ICommunication/ICommunication.cs
- Common/DTS.Common.ICommunication/Communication.cs
generated_at: "2026-04-16T11:28:10.843855+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. It defines the contract for DAS-connected devices via `IDASConnectedDevice`, encapsulates device metadata through `Communication_DASInfo`, and implements an asynchronous, callback-driven communication layer via the abstract `Communication<T>` class. The module handles connection lifecycle management, command execution with timeout handling, cancellation support, and receive buffering for networked hardware devices.
---
## 2. Public Interface
### IDASConnectedDevice (Interface)
**Namespace:** `DTS.DASLib.Communication`
Describes a device connected to a DAS (e.g., an S6 connected to an 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`
Marker exception class extending `ApplicationException`. Used to signal operation cancellation.
---
### Communication_DASInfo (Class)
**Namespace:** `DTS.Common.ICommunication`
Implements `ICommunication_DASInfo`. Holds metadata about a DAS device.
**Properties:**
- `FirstUseDate` (`DateTime?`) — Date of first use; `null` indicates hardware has not been used since calibration. Only valid when `IsFirstUseDateSupported` is `true`.
- `IsFirstUseDateSupported` (`bool`) — Indicates hardware supports first use dates.
- `IsStreamingSupported` (`bool`) — Indicates whether streaming is supported.
- `ConnectedDevices` (`IDASConnectedDevice[]`) — Devices connected to the DAS (currently only used by SLICE6DB).
**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 serial and firmware version arrays.
---
### Communication\<T\> (Abstract Class)
**Namespace:** `DTS.Common.ICommunication`
Generic abstract base class for DAS communication. Type parameter `T` must implement `IConnection` and have a parameterless constructor.
**Properties:**
- `ErrorInSetup` (`bool`) — Indicates an error occurred during setup.
- `ConnectString` (`string`) — Returns `sock.ConnectString`.
- `Connected` (`bool`) — Returns `sock.Connected`.
- `DASInfo` (`ICommunication_DASInfo`) — DAS information object.
- `Transport` (`IConnection`) — Gets the underlying connection; setter throws `NotSupportedException`.
- `ReceiveBufferSize` (`int`) — Receive buffer size; default is 65536 (2^16).
- `SerialNumber` (`string`) — Device serial number.
- `FirmwareVersion` (`string`) — Firmware version; setter triggers `FirmwareVersionUpdated()`.
- `ProtocolVersion` (`byte`) — Protocol version.
- `MinimumProtocols` (`Dictionary<DFConstantsAndEnums.ProtocolLimitedCommands, byte>`) — Minimum protocol versions for commands.
- `FlushTimeoutMilliSec` (`int`) — Flush timeout; default is 5ms.
- `ExecuteIsBusy` (`bool`) — Thread-safe flag indicating execution lock state.
- `CancelEvent` (`ManualResetEvent`) — Event signaling cancellation.
**Methods:**
- `int CompareTo(ICommunication dev)` — Compares connect strings (case-insensitive ordinal).
- `int CompareTo(string conStr)` — Compares connect string to given string.
- `abstract void InitMinProto()` — Must be implemented to initialize `MinimumProtocols`.
- `bool IsCommandSupported(ProtocolLimitedCommands command)` — Returns `true` if `ProtocolVersion >= GetMinProto(command)`.
- `byte GetMinProto(ProtocolLimitedCommands command)` — Returns minimum protocol version for command; returns `0xFF` if not found; throws if `MinimumProtocols` is null.
- `void Flush(int timeoutMs)` — Flushes `SockDataBuffer` until empty or timeout.
- `byte[] SyncExecute(byte[] byteData, int cbTimeout)` — Throws `NotSupportedException`.
- `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 ForceCancel()` — Sets cancel state with 250ms sleep on clear.
- `void Cancel()` — Sets cancel state with 500ms sleep on clear.
- `bool IsCanceled()` — Returns current cancel state.
- `void ClearCancel()` — Clears cancel state after sleeping.
- `void PseudoExecute(byte[] byteData, CommunicationCallback cb, object cbObject, int cbTimeout)` — For commands that only receive data (no send). Throws `CanceledException` if canceled, `NotConnectedException` if not connected.
- `void Execute(byte[] byteData, CommunicationCallback cb, object cbObject, int cbTimeout)` — Sends data and processes response. Throws `CanceledException` if canceled, `NotConnectedException` if not connected.
- `void SetupReader()` — Initializes asynchronous receive loop.
- `void Close(int timeout)` — Empty implementation.
**Events:**
- `OnDisconnected` (`EventHandler`) — Raised when the underlying connection disconnects.
**Protected Methods:**
- `void Lock()` — Empty implementation.
- `void Release()` — Empty implementation.
- `virtual void FirmwareVersionUpdated()` — Called when `FirmwareVersion` is set.
---
### Communication.ActionData (Nested Abstract Class)
Base class for async operation tracking with timeout support.
**Constructor:** `ActionData(CommunicationCallback cb, object obj, int to)`
**Methods:**
- `void StartTimer()` — Starts timeout timer.
- `void KillTimer()` — Stops and disposes 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 result for timeout.
**Properties:**
- `TimerExpired` (`bool`) — Returns whether timer has fired.
---
### 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.
---
### CommunicationReport (Class)
**Namespace:** `DTS.Common.ICommunication`
Implements `ICommunicationReport`.
**Properties:**
- `UserState` (`object`) — User-provided state object.
- `Result` (`CommunicationResult`) — Result of the operation.
- `Data` (`byte[]`) — Received data (for read operations).
**Constructor:** `CommunicationReport(object state, CommunicationResult res)`
---
### Communication.PseudoAsyncResult (Nested Class)
Implements `IAsyncResult` for `PseudoExecute`. `IsCompleted` and `CompletedSynchronously` return `true`. `AsyncWaitHandle` throws `NotImplementedException`.
---
## 3. Invariants
1. **Connection State Checks:** `Connect()` throws if `sock` is null or already connected. `Disconnect()` throws if `sock` is null.
2. **Execute Pre-conditions:** Both `Execute()` and `PseudoExecute()` throw `CanceledException` if `IsCanceled()` returns `true`, and `NotConnectedException` if `Connected` is `false`.
3. **ExecuteIsBusy Thread Safety:** The `ExecuteIsBusy` property uses locking (`_executeBusyMtLock`) and asserts on re-entry or extra unlock attempts.
4. **Transport Immutability:** The `Transport` property setter always throws `NotSupportedException`.
5. **MinimumProtocols Requirement:** `GetMinProto()` throws `NotSupportedException` if `MinimumProtocols` is null.
6. **SyncExecute Unavailable:** `SyncExecute()` always throws `NotSupportedException`.
7. **Clone Behavior:** `Communication_DASInfo` constructor clones input arrays for `SerialNumbers` and `FirmwareVersions`.
8. **Port/Spot Indexing:** `Port` and `SpotOnPort` in `IDASConnectedDevice` are explicitly 0-based.
---
## 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 implementation not shown)
- `DTS.Common.Utilities.Logging``APILogger`
- `DTS.Common.Utilities``SecureQueue<T>`
- `DTS.Common.Utils``WaitWithCondition`
- `System.Net.NetworkInformation``PhysicalAddress`
- `System.Net.Sockets``SocketException`
- `System.Threading`, `System.Threading.Tasks` — Async primitives
### What depends on this module:
- Cannot be definitively determined from source alone, but `Communication_DASInfo.ConnectedDevices` references `IDASConnectedDevice`, suggesting SLICE6DB implementations depend on this interface.
---
## 5. Gotchas
1. **Empty Lock/Release Methods:** `Lock()` and `Release()` are defined but have empty implementations. Their intended purpose is unclear from source alone.
2. **Close() is a No-Op:** The `Close(int timeout)` method has an empty body. Callers should not rely on it for cleanup.
3. **Cancel Sleep Behavior:** `ClearCancel()` sleeps for either 250ms (after `ForceCancel()`) or 500ms (after `Cancel()`) before clearing the cancel state. This blocking delay may be unexpected in time-sensitive contexts.
4. **Thread ID Check in Receive Callbacks:** Both `ProcessReceivedData` and `SRRecvCallback` check if `Thread.CurrentThread.ManagedThreadId` changes during `WaitWithCondition.Wait()`, logging and returning early if it does. This suggests a historical threading issue.
5. **Transport Setter Always Throws:** Attempting to set `Transport` throws `NotSupportedException` with message "Communication::Transport Can't replace socket".
6. **PseudoAsyncResult.AsyncWaitHandle Throws:** Accessing `AsyncWaitHandle` on `PseudoAsyncResult` throws `NotImplementedException`.
7. **ConnectedDevices Default is Empty Array:** `Communication_DASInfo.ConnectedDevices` initializes to an empty array, not null. Code checking for null will not behave as expected.
8. **StackSerialNumber Index Logic:** `StackSerialNumber(int devid)` returns the stacked format only when `devid != 0 && devid < SerialNumbers.Length`. A `devid` of 0 returns just `SerialNumbers[0]`, not a stacked string.