Files
DP44/docs/ai/Common/DTS.Common.ICommunication.md

258 lines
12 KiB
Markdown
Raw Normal View History

2026-04-17 14:55:32 -04:00
---
source_files:
- Common/DTS.Common.ICommunication/IDASConnectedDevice.cs
- Common/DTS.Common.ICommunication/ICommunication.cs
- Common/DTS.Common.ICommunication/Communication.cs
generated_at: "2026-04-17T15:39:44.338256+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "f84cd76ebff4b497"
---
# Documentation: DTS.Common.ICommunication
## 1. Purpose
This module provides the core communication infrastructure for interacting with DAS (Data Acquisition System) hardware. It defines the abstract `Communication<T>` base class that implements asynchronous connect/disconnect operations, command execution with timeout handling, and a continuous receive loop for hardware communication. The module also defines `IDASConnectedDevice` for describing devices attached to a DAS (e.g., SLICE6 units on a SLICE6DB), and `Communication_DASInfo` for encapsulating DAS metadata such as serial numbers, firmware versions, and connected device information.
---
## 2. Public Interface
### `IDASConnectedDevice` (interface)
**Namespace:** `DTS.DASLib.Communication`
Describes a device connected to a DAS.
| 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`
**Base:** `ApplicationException`
Marker exception thrown when operations are canceled.
---
### `Communication_DASInfo` (class)
**Namespace:** `DTS.Common.ICommunication`
**Implements:** `ICommunication_DASInfo`
Encapsulates metadata about a DAS device.
| Property | Type | Description |
|----------|------|-------------|
| `FirstUseDate` | `DateTime?` | Date of first use; `null` indicates hardware not 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). |
| `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 or empty. Returns `SerialNumbers[0] + "::" + SerialNumbers[devid]` if `devid` is non-zero and within bounds; 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<T>` (abstract class)
**Namespace:** `DTS.Common.ICommunication`
**Implements:** `Interface.DASFactory.ICommunication`
**Generic constraint:** `where T : IConnection, new()`
Abstract base class for hardware communication.
**Properties:**
| Property | Type | Access | Description |
|----------|------|--------|-------------|
| `ErrorInSetup` | `bool` | get/set | Indicates an error occurred during setup. |
| `ConnectString` | `string` | get | Returns `sock.ConnectString`. |
| `Connected` | `bool` | get | Returns `sock.Connected`. |
| `DASInfo` | `ICommunication_DASInfo` | get/set | DAS metadata. |
| `Transport` | `IConnection` | get/set | Gets `sock`; setter throws `NotSupportedException`. |
| `ReceiveBufferSize` | `int` | get/set | Receive buffer size; defaults to 65536. |
| `SerialNumber` | `string` | get/set | Device serial number. |
| `FirmwareVersion` | `string` | get/set | Firmware version; setter invokes `FirmwareVersionUpdated()`. |
| `ProtocolVersion` | `byte` | get/set | Protocol version. |
| `MinimumProtocols` | `Dictionary<DFConstantsAndEnums.ProtocolLimitedCommands, byte>` | get/set | Minimum protocol versions for commands. |
| `FlushTimeoutMilliSec` | `int` | get/set | Flush timeout; defaults to 5. |
| `ExecuteIsBusy` | `bool` | get/set | Thread-safe execution lock indicator. |
| `CancelEvent` | `ManualResetEvent` | get | Event signaling cancel state. |
**Events:**
- `EventHandler OnDisconnected` — Raised when the connection is disconnected.
**Methods:**
- `int CompareTo(Interface.DASFactory.ICommunication dev)` — Compares `ConnectString` values (ordinal, case-insensitive).
- `int CompareTo(string conStr)` — Compares `ConnectString` to provided string (ordinal, case-insensitive).
- `abstract void InitMinProto()` — Must be implemented to initialize `MinimumProtocols`.
- `bool IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands command)` — Returns `true` if `ProtocolVersion >= GetMinProto(command)`.
- `byte GetMinProto(DFConstantsAndEnums.ProtocolLimitedCommands command)` — Returns minimum protocol for command, or `0xFF` if not found. Throws `NotSupportedException` if `MinimumProtocols` is null.
- `void Connect(string connectString, CommunicationCallback callback, object callbackObject, int callbackTimeout, string hostIPAddress)` — Initiates asynchronous connection. Throws if socket is null or already connected.
- `void Disconnect(bool reuseSocket, CommunicationCallback callback, object callbackObject, int callbackTimeout)` — Initiates asynchronous disconnect. Throws if socket is null.
- `void Cancel()` — Sets cancel state with 500ms sleep on clear.
- `void ForceCancel()` — Sets cancel state with 250ms sleep on clear.
- `bool IsCanceled()` — Returns current cancel state.
- `void ClearCancel()` — Clears cancel state after sleeping.
- `void Flush(int timeoutMs)` — Flushes `SockDataBuffer` until no data arrives within timeout.
- `byte[] SyncExecute(byte[] byteData, int cbTimeout)` — Throws `NotSupportedException`.
- `void Execute(byte[] byteData, CommunicationCallback cb, object cbObject, int cbTimeout)` — Sends data and processes responses asynchronously. Throws `CanceledException` if canceled; throws `NotConnectedException` if not connected.
- `void PseudoExecute(byte[] byteData, CommunicationCallback cb, object cbObject, int cbTimeout)` — For commands that only receive data without sending. Throws `CanceledException` if canceled; throws `NotConnectedException` if not connected.
- `void SetupReader()` — Initializes the asynchronous receive loop.
- `void Dispose()` — IDisposable implementation.
---
### `CommunicationReport` (class)
**Namespace:** `DTS.Common.ICommunication`
**Implements:** `ICommunicationReport`
Encapsulates the result of a communication operation.
| Property | Type | Description |
|----------|------|-------------|
| `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<T>.ActionData` (abstract class)
**Namespace:** `DTS.Common.ICommunication`
Base class for tracking asynchronous operations with timeout handling.
| Property | Type | Description |
|----------|------|-------------|
| `UserTimeout` | `int` | Timeout in milliseconds. |
| `TimerExpired` | `bool` | Indicates if the 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.
- `protected abstract CommunicationResult GetTimeoutResult()` — Must return the timeout-specific result.
---
### `Communication<T>.ExecuteActionData` (class)
**Namespace:** `DTS.Common.ICommunication`
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<T>.PseudoAsyncResult` (class)
**Namespace:** `DTS.Common.ICommunication`
**Implements:** `IAsyncResult`
Wraps `ExecuteActionData` for pseudo-execute operations.
| Property | Type | Description |
|----------|------|-------------|
| `IsCompleted` | `bool` | Always `true`. |
| `AsyncWaitHandle` | `WaitHandle` | Throws `NotImplementedException`. |
| `AsyncState` | `object` | Returns the wrapped `ExecuteActionData`. |
| `CompletedSynchronously` | `bool` | Always `true`. |
---
## 3. Invariants
1. **Connection State Guards**: `Connect()` throws if `sock` is null or already connected. `Disconnect()` throws if `sock` is null.
2. **ExecuteIsBusy Thread Safety**: The `ExecuteIsBusy` property uses a lock (`_executeBusyMtLock`) and asserts on re-entry or extra unlock attempts.
3. **MinimumProtocols Initialization**: `GetMinProto()` throws `NotSupportedException` if `MinimumProtocols` is null. Derived classes must implement `InitMinProto()` to populate this dictionary.
4. **Transport Immutability**: The `Transport` property setter always throws `NotSupportedException`; the transport cannot be replaced after construction.
5. **Buffer Flushing Before Execute**: `Execute()` calls `CheckAndFlushBuffer()` to ensure `SockDataBuffer` is empty before sending.
6. **Cancel State Consistency**: `ClearCancel()` only performs sleep and reset if `_commandsAreCanceled` is `true`.
7. **SerialNumbers Bounds Check**: `StackSerialNumber(int devid)` returns `"N/A"` for null/empty arrays and `SerialNumbers[0]` for out-of-bounds `devid` values.
---
## 4. Dependencies
**This module depends on:**
- `DTS.Common.Enums.Hardware``HardwareTypes` enum.
- `DTS.Common.Enums.Communication``CommunicationConstantsAndEnums`, `CommunicationResult`.
- `DTS.Common.Enums.DASFactory``DFConstantsAndEnums`.
- `DTS.Common.Interface.Communication``ICommunication_DASInfo`, `CommunicationCallback` (delegate type inferred).
- `DTS.Common.Interface.Connection``IConnection`.
- `DTS.Common.Classes.Connection` — (referenced but specific types not visible in source).
- `DTS.Common.Utilities.Logging``APILogger`.
- `DTS.Common.Utilities``SecureQueue<T>`.
- `DTS.Common.Utils``WaitWithCondition`.
- `System.Net.NetworkInformation``PhysicalAddress`.
- `System.Net.Sockets``SocketException`.
- `System.Threading``ManualResetEvent`, `Timer`, `Timeout`.
- `System.Threading.Tasks``Task`.
**Consumers of this module:**
- Not determinable from the provided source alone. The abstract `Communication<T>` class is designed to be extended by concrete implementations.
---
## 5. Gotchas
1. **SyncExecute Not Supported**: The `SyncExecute()` method throws `NotSupportedException` with a message referencing `DTS.DASLib.Communication.Communication`, suggesting a namespace mismatch or historical artifact.
2. **PseudoAsyncResult.AsyncWaitHandle Throws**: Accessing `AsyncWaitHandle` on `PseudoAsyncResult` throws `NotImplementedException`, which could surprise callers expecting a functional `IAsyncResult`.
3. **Thread ID Check in Receive Callbacks**: Both `ProcessReceivedData()` and `SRRecvCallback()` check that `Thread.CurrentThread.ManagedThreadId` remains consistent before and after `WaitWithCondition.Wait()`. If it changes, the method logs and returns without completing the operation