This commit is contained in:
2026-04-17 14:55:32 -04:00
commit bc3ac1d4c9
18017 changed files with 4371742 additions and 0 deletions

View File

@@ -0,0 +1,224 @@
---
source_files:
- Common/DTS.Common.IConnection/EthernetConnection/RESTConnection.cs
- Common/DTS.Common.IConnection/EthernetConnection/EthernetConnection.cs
generated_at: "2026-04-16T02:09:04.702798+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "21dfcca726b35e5d"
---
# Documentation: `RESTConnection` and `EthernetConnection` Classes
## 1. Purpose
This module provides two concrete implementations of the `IConnection` interface for network communication: `RESTConnection`, a stub implementation that simulates connection operations without actual network activity (intended for REST-based or mock scenarios), and `EthernetConnection`, a full-featured implementation using `System.Net.Sockets.Socket` for real-time Ethernet communication with hardware devices. `RESTConnection` exists to satisfy interface contracts in environments where actual socket communication is unnecessary or undesirable (e.g., testing, REST API interactions), while `EthernetConnection` handles real socket operations including connection establishment, data transfer, keep-alive configuration, and soft disconnect/reconnect workflows for embedded hardware.
## 2. Public Interface
### `RESTConnection` (namespace `DTS.DASLib.Connection`)
- **`bool IConnection.IsSoftDisconnected => false`**
Always returns `false`; does not support soft disconnect semantics.
- **`SocketFlags IConnection.Flags { get; set; }`**
Gets/sets socket flags (unused; always `SocketFlags.None`).
- **`string IConnection.ConnectString => _ConnectString`**
Returns the stored connection string (e.g., `"host:port"`), set via `Create`.
- **`bool IConnection.Connected => _bConnected`**
Returns internal `_bConnected` state (set to `true` on `BeginConnect`, `false` on `BeginDisconnect`).
- **`event EventHandler OnDisconnected`**
Declared but never raised (no invocation in source).
- **`void IConnection.Create(string connectString)`**
Stores `connectString` in `_ConnectString`.
- **`void IConnection.Create(string connectString, string hostIPAddress)`**
Stores `connectString` and `hostIPAddress` in respective fields.
- **`IAsyncResult IConnection.BeginConnect(AsyncCallback callback, object callbackObject)`**
Sets `_bConnected = true` and returns a *synchronously completed* `IAsyncResult` via `GetAlreadyCompleted`.
- **`IAsyncResult IConnection.BeginDisconnect(bool reuseSocket, AsyncCallback callback, object state)`**
Sets `_bConnected = false` and returns a *synchronously completed* `IAsyncResult`.
- **`IAsyncResult IConnection.BeginSend(...)` / `BeginReceive(...)` / `BeginAccept(...)`**
All return *synchronously completed* `IAsyncResult` instances; no actual I/O.
- **`void IConnection.EndConnect(...)` / `EndDisconnect(...)` / `EndSend(...)` / `EndReceive(...)` / `EndAccept(...)`**
No-op implementations. `EndSend`/`EndReceive` return `0`. `EndAccept` returns `this`.
- **`void IConnection.Bind(int port)`**
Stub; no-op.
- **`void IConnection.Listen(int backlog)`**
Stub; no-op.
- **`void IConnection.KeepAliveErrorReceived()`**
Stub; no-op.
- **`string IConnection.GetConnectionData()`**
Returns `"{_ConnectString} - {_hostIPAddress}"`.
- **`Task<int> IConnection.SendAsync(...)`**
Wraps `BeginSend`/`EndSend` using `Task.Factory.FromAsync`; returns a completed task with result `0`.
- **`void IConnection.SoftConnect()` / `SoftDisconnect()`**
Stubs; no-op.
- **`void Dispose()` / `~RESTConnection()`**
Implements `IDisposable`; marks `_disposed = true` but performs no socket cleanup.
### `EthernetConnection` (namespace `DTS.Common`)
- **`bool IsSoftDisconnected { get; private set; }`**
Tracks soft-disconnect state; `true` after successful `SoftDisconnect()`.
- **`bool Connected => Sock != null && Sock.Connected`**
Reflects underlying socket state.
- **`string ConnectString => Connect_String`**
Returns stored connection string.
- **`SocketFlags Flags { get; set; }`**
Gets/sets socket flags used in `BeginSend`/`BeginReceive`.
- **`Socket Sock`**
Public field holding the underlying `Socket` instance.
- **`event EventHandler OnDisconnected`**
Raised in `KeepAliveErrorReceived()`.
- **`void Create(string connectString, string hostIPAddress)`**
Stores `connectString` and `hostIPAddress`, then calls `CreateSock` to initialize `Sock`.
- **`Socket CreateSock(string connectString, string hostIPAddress)`**
Creates and configures a `Socket` with:
- `NoDelay = true` (Nagle disabled)
- `KeepAlive = true`
- Buffer sizes from `DFConstantsAndEnums.SendBufferSizeBytes` / `ReceiveBufferSizeBytes`
- Custom keep-alive parameters from `DFConstantsAndEnums.LocalKeepAliveTimeOutMS` / `LocalKeepAliveRetryIntervalMS`
- Optional binding to `hostIPAddress` if provided.
- **`void SoftDisconnect()`**
If `HardwareConstants.AllowSoftDisconnects` is `true` and socket is connected:
- Disconnects and disposes `Sock`
- Sets `IsSoftDisconnected = true`
- Logs action.
- **`void SoftConnect()`**
If `AllowSoftDisconnects` is `true` and socket is not connected:
- Parses `Connect_String` as `"host:port"`.
- If `RequiresKeepAliveReset` is `true`, connects to port `8200`, sends `<60,5,4>`, receives response, then disconnects.
- Retries up to 3 times to connect to `host:port` (1s delay between attempts).
- Sets `IsSoftDisconnected = false`, logs success.
- **`void KeepAliveErrorReceived()`**
Shuts down, closes, and disposes `Sock`, sets `Sock = null`, and raises `OnDisconnected`.
- **`string GetConnectionData()`**
Returns `"local: {LocalEndPoint}, Remote: {RemoteEndPoint}"` or `""` on error.
- **`IAsyncResult BeginConnect(AsyncCallback, object)`**
Validates `Sock`, `Connect_String`, and port format; delegates to `Sock.BeginConnect`.
- **`void EndConnect(IAsyncResult)`**
Calls `Sock.EndConnect`, logs connection details.
- **`IAsyncResult BeginDisconnect(bool, AsyncCallback, object)`**
Validates `Sock`; throws if socket is `null` or *not* connected (`SocketException WSAEISCONN`); delegates to `Sock.BeginDisconnect`.
- **`void EndDisconnect(IAsyncResult)`**
Calls `Sock.EndDisconnect`.
- **`IAsyncResult BeginAccept(AsyncCallback, object)`**
Validates `Sock`; delegates to `Sock.BeginAccept`.
- **`IConnection EndAccept(IAsyncResult)`**
Calls `Sock.EndAccept`, wraps result in a *new* `EthernetConnection` instance.
- **`void Bind(int port)`**
Validates `Sock`; binds to first DNS-resolved IP address on `port`.
- **`void Listen(int backlog)`**
Validates `Sock`; calls `Sock.Listen`.
- **`IAsyncResult BeginSend(byte[], int, int, AsyncCallback, object)`**
Validates `Sock`, callback, and connection state; throws if not connected; delegates to `Sock.BeginSend`.
- **`int EndSend(IAsyncResult)`**
Calls `Sock.EndSend`; sets `Sock = null` on exception.
- **`Task<int> SendAsync(...)`**
Wraps `BeginSend`/`EndSend` via `Task.Factory.FromAsync`.
- **`IAsyncResult BeginReceive(byte[], int, int, AsyncCallback, object)`**
Validates `Sock` and callback; delegates to `Sock.BeginReceive`.
- **`int EndReceive(IAsyncResult)`**
Calls `Sock.EndReceive`.
- **`void Dispose()` / `~EthernetConnection()`**
Implements `IDisposable`; safely shuts down/disposes `Sock` in `Dispose(bool)`.
## 3. Invariants
- **`RESTConnection`**:
- `_bConnected` is the sole source of truth for connection state; never updated by external I/O.
- All `Begin*`/`End*` operations are synchronous and return immediately; no async state is maintained.
- `IsSoftDisconnected` is always `false`; soft disconnect logic is absent.
- `Connected` reflects `_bConnected`, which is manually toggled by `BeginConnect`/`BeginDisconnect`.
- **`EthernetConnection`**:
- `Connected` depends on `Sock != null && Sock.Connected`; `Sock` may be `null` after errors or disposal.
- `SoftDisconnect()` and `SoftConnect()` only execute if `HardwareConstants.AllowSoftDisconnects` is `true`.
- `SoftConnect()` requires `Connect_String` to be in `"host:port"` format; port must be parseable as `int`.
- `BeginDisconnect` throws `SocketException` if socket is not connected (per `WSAEISCONN`).
- `BeginSend`/`BeginReceive` throw if socket is not connected or callback is `null`.
- `KeepAliveErrorReceived()` guarantees `Sock` is `null` after execution (disposal path).
## 4. Dependencies
### `RESTConnection`:
- **Imports**:
- `DTS.Common.Interface.Connection` (for `IConnection`)
- `DTS.Common.Utilities.Logging` (for `APILogger`, but *not used* in this file)
- Standard .NET libraries (`System.Net.Sockets`, `System.Threading`, etc.)
- **Depended on by**: Any code requiring an `IConnection` instance where network activity is unnecessary (e.g., unit tests, REST-based workflows).
### `EthernetConnection`:
- **Imports**:
- `DTS.Common.Interface.Connection` (`IConnection`)
- `DTS.Common.DASResource` (for `Strings.EthernetConnection_*_Err*` exception messages)
- `DTS.Common.Enums.DASFactory` (for `HardwareConstants.AllowSoftDisconnects`)
- `DTS.Common.Utilities.Logging` (for `APILogger`)
- `DFConstantsAndEnums` (for buffer sizes, keep-alive timeouts, `WSAEISCONN`)
- **Depended on by**: Higher-level connection management logic (e.g., device initialization, data acquisition pipelines) requiring real Ethernet communication.
## 5. Gotchas
- **`RESTConnection`**:
- `IsSoftDisconnected` is hardcoded to `false`; callers expecting soft-disconnect behavior will be misled.
- `OnDisconnected` is declared but never raised; event subscriptions have no effect.
- `Begin*`/`End*` methods are *synchronous stubs*; using them in async contexts may cause deadlocks or incorrect assumptions about I/O latency.
- `EndSend`/`EndReceive` always return `0`—no actual bytes sent/received.
- `SoftConnect`/`SoftDisconnect` are no-ops despite being part of `IConnection`.
- **`EthernetConnection`**:
- `SoftConnect()` uses `Thread.Sleep` (50ms/100ms/1000ms) for timing; this is blocking and may cause issues in high-throughput or UI contexts.
- `SoftConnect()` sends `<60,5,4>` to port `8200` for keep-alive setup; this is a hardcoded protocol-specific command (device-dependent).
- `BeginDisconnect` throws `SocketException` if socket is not connected—*not* an error condition per se, but callers must handle this exception to avoid crashes.
- `EndSend` sets `Sock = null` on exception; this may cause subsequent operations to fail unexpectedly.
- `Bind` uses the *first* DNS-resolved IP address (`AddressList[0]`), which may be non-deterministic or IPv6 in some environments.
- `CreateSock` uses `IOControlCode.KeepAliveValues` with hardcoded `KeepAliveOn = 1`; this may conflict with system-wide settings.
- `IsSoftDisconnected` is not reset to `false` in `SoftConnect` if `AllowSoftDisconnects` is `false`—only if soft disconnect logic runs.
- **Both**:
- Neither class validates `connectString` format in `Create(string)` alone (only in `Create(string, string)` or `BeginConnect`).
- `RESTConnection` and `EthernetConnection` share the same `IConnection` interface but have wildly different semantics; callers must know which implementation they hold.
- `RESTConnection`s `GetConnectionData()` returns a string with `_hostIPAddress`, but `_hostIPAddress` is never used in `RESTConnection` beyond storage—no binding or resolution occurs.
None identified beyond those above.

View File

@@ -0,0 +1,50 @@
---
source_files:
- Common/DTS.Common.IConnection/EthernetConnection/Properties/AssemblyInfo.cs
generated_at: "2026-04-16T02:07:20.010068+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "21f98ce79850642b"
---
# Properties
### 1. **Purpose**
This module is an assembly metadata configuration file (`AssemblyInfo.cs`) for the `EthernetConnection` .NET assembly, part of the `DTS.Common.IConnection` namespace. Its purpose is to define assembly-level attributes—such as title, version, and COM visibility—used for identification, versioning, and interoperability. It does not contain executable logic or types; rather, it provides metadata consumed by the .NET runtime and tools (e.g., reflection, deployment, COM interop).
---
### 2. **Public Interface**
**No public types, functions, or classes are defined in this file.**
This file exclusively contains assembly-level attributes via `Assembly*` attributes (e.g., `AssemblyTitle`, `AssemblyVersion`). It does not declare any public APIs.
---
### 3. **Invariants**
- The assembly is **not visible to COM** by default (`ComVisible(false)`).
- The assembly version is strictly `1.06.0081` (both `AssemblyVersion` and `AssemblyFileVersion` match).
- The `Guid` attribute is set to `"355ff6bb-d823-4853-93aa-4c12fd8c350e"` for COM type library identification.
- No culture-specific attributes are set (`AssemblyCulture("")` indicates a neutral/culture-agnostic assembly).
- Copyright notice is fixed to "Copyright © 2008".
---
### 4. **Dependencies**
- **Dependencies**:
- `System.Reflection`
- `System.Runtime.CompilerServices`
- `System.Runtime.InteropServices`
These are standard .NET namespaces, so the only external dependency is the .NET Framework (or compatible runtime).
- **Depended on by**:
- Other modules in the `DTS.Common.IConnection` project (or solution) that reference this `EthernetConnection` assembly.
- Tools or components that rely on assembly metadata (e.g., COM interop consumers, build/deployment scripts, reflection-based diagnostics).
---
### 5. **Gotchas**
- **Versioning**: The `AssemblyVersion` (`1.06.0081`) uses a non-standard format (likely `Major.Minor.Build` where `06` = minor, `0081` = build). This may cause confusion if consumers expect semantic versioning (e.g., `1.6.81`).
- **COM Interop**: Though `ComVisible(false)` is set, the explicit `Guid` suggests this assembly *may* have been designed for COM exposure at some point. If COM interop is needed, `ComVisible(true)` must be enabled on specific types—not the assembly—and the GUID must be preserved.
- **No functional logic**: This file has no runtime behavior; errors here (e.g., malformed GUID) only surface during build/compile time or COM registration.
- **Copyright year**: The hardcoded `2008` copyright may be outdated and could mislead auditors or legal reviews.
- **Empty fields**: `AssemblyDescription`, `AssemblyCompany`, and `AssemblyTrademark` are empty strings—no documentation or branding metadata is embedded.
- **None identified from source alone.** *(Note: While the above points are reasonable inferences, they are not explicit in the source and thus should be verified in context.)*

View File

@@ -0,0 +1,50 @@
---
source_files:
- Common/DTS.Common.IConnection/Properties/AssemblyInfo.cs
generated_at: "2026-04-16T02:09:10.860889+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "344d5d1b6c8a507c"
---
# Properties
### **1. Purpose**
This module defines the `IConnection` assembly, a foundational .NET component intended to encapsulate connection-related abstractions for the broader system. Based on the assembly title and GUID, it serves as a shared contract layer—likely providing interfaces and possibly base types—for database, network, or service connections used across dependent modules. Its existence suggests a design goal of decoupling connection logic from implementation details, enabling testability and interchangeability of connection providers.
---
### **2. Public Interface**
**No public types (classes, interfaces, structs, or enums) are defined in this file.**
The file `AssemblyInfo.cs` contains only assembly-level metadata attributes (e.g., version, GUID, COM visibility). It does not declare any public APIs, interfaces, or types. The actual `IConnection` interface (implied by the assembly name) must reside in other source files not provided here.
---
### **3. Invariants**
- **Assembly Identity**: The assembly is uniquely identified by GUID `c8394d57-92d3-4ee1-b2f3-f8fabce0d487`.
- **Versioning**: Version is strictly `1.06.0081` (both `AssemblyVersion` and `AssemblyFileVersion`).
- **COM Visibility**: Types in this assembly are **not** visible to COM (`ComVisible(false)`), unless explicitly overridden on individual types.
- **No Runtime Behavior**: This file contributes no executable logic or state; it only defines metadata.
---
### **4. Dependencies**
- **Dependencies**:
- `System.Reflection`
- `System.Runtime.CompilerServices`
- `System.Runtime.InteropServices`
These are standard .NET Framework namespaces; no external or proprietary dependencies are declared.
- **Dependents**:
- Any assembly referencing `IConnection` (e.g., database clients, service adapters) depends on this assembly for its contract types (e.g., `IConnection` interface), though those types are not defined here.
- The assemblys GUID and version suggest it may be consumed by COM-aware components or build systems expecting strong-named or versioned contracts, but no explicit references are visible in this file.
---
### **5. Gotchas**
- **Misleading Name**: The assembly is named `IConnection`, but this file contains no `IConnection` interface—developers may incorrectly assume the interface is defined here.
- **Version Format**: The version `1.06.0081` uses a non-standard format (likely `Major.Minor.BuildRevision`), which may cause confusion during version comparison or binding.
- **COM Interop**: While `ComVisible(false)` is set, if this assembly is referenced by COM clients, *any* types defined elsewhere in the assembly must explicitly opt in to COM visibility (e.g., via `[ComVisible(true)]`), or they will remain inaccessible.
- **No Public API Surface**: This file alone provides no actionable API documentation; developers must inspect other files in the `DTS.Common.IConnection` project to understand the actual contract.
None identified beyond the above.

View File

@@ -0,0 +1,136 @@
---
source_files:
- Common/DTS.Common.IConnection/SerialConnection/SerialConnection.cs
generated_at: "2026-04-16T02:09:02.781823+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "4992256eaf51da73"
---
# SerialConnection
## Documentation: `SerialConnection` Class
---
### 1. Purpose
The `SerialConnection` class provides a serial portbased implementation of the `IConnection` interface, enabling asynchronous I/O operations over a system serial port (`System.IO.Ports.SerialPort`). It wraps the .NET `SerialPort` class to expose standard connection semantics (connect, disconnect, send, receive) using the asynchronous programming model (APM) and Task-based wrappers. Despite implementing methods like `SoftConnect`, `SoftDisconnect`, `Bind`, `Listen`, and `Accept`, the class does **not** support soft disconnection or server-side listening—those methods are stubs or throw exceptions when misused. Its primary role is to allow serial communication to be used interchangeably with other connection types (e.g., TCP) via the `IConnection` abstraction.
---
### 2. Public Interface
All methods and properties are part of the public API unless explicitly marked `protected`.
| Member | Signature | Description |
|--------|-----------|-------------|
| **`IsSoftDisconnected`** | `public bool IsSoftDisconnected { get; private set; }` | Always `false`. Not used for serial connections. |
| **`SoftConnect()`** | `public void SoftConnect()` | No-op. Comment notes: *"does nothing for serial as we don't have a soft disconnect option yet."* |
| **`SoftDisconnect()`** | `public void SoftDisconnect()` | No-op. Comment notes: *"does nothing for serial as we don't have a soft disconnect option yet."* |
| **`KeepAliveErrorReceived()`** | `void IConnection.KeepAliveErrorReceived()` | Explicit interface implementation; no-op. |
| **`Create(string connectString, string hostIPAddress)`** | `public void Create(string connectString, string hostIPAddress)` | No-op. Does not assign `connectString`. |
| **`GetConnectionData()`** | `public string GetConnectionData()` | Returns `""`. |
| **`GetCurrentDownloadRate()`** | `public double GetCurrentDownloadRate()` | Returns `0D`. |
| **`GetCurrentUploadRate()`** | `public double GetCurrentUploadRate()` | Returns `0D`. |
| **`OnDisconnected`** | `public event EventHandler OnDisconnected` | Event declared but never raised. |
| **`Connected`** | `public bool Connected { get; }` | Always `false`. Not updated on connect. |
| **`ConnectString`** | `public string ConnectString => _PortName` | Returns the last-assigned port name (e.g., `"COM3"`). |
| **`Flags`** | `public System.Net.Sockets.SocketFlags Flags { get; set; }` | Property inherited from `IConnection`; unused (no socket semantics). |
| **`Create(string PortName)`** | `public void Create(string PortName)` | Initializes `Port` with `_PortName` (note: bug—see *Gotchas*). Sets `_PortName = PortName`. |
| **`BeginConnect(...)`** | `public IAsyncResult BeginConnect(AsyncCallback cb, object state)` | Opens the `SerialPort`. Throws if `Port == null` or `_PortName` is null/empty. Returns `null`. |
| **`EndConnect(...)`** | `public void EndConnect(IAsyncResult ar)` | No-op. Throws if `Port == null`. |
| **`BeginDisconnect(...)`** | `public IAsyncResult BeginDisconnect(bool reuseSocket, AsyncCallback cb, object state)` | No-op. Throws if `Port == null`. Returns `null`. |
| **`EndDisconnect(...)`** | `public void EndDisconnect(IAsyncResult asyncResult)` | No-op. Throws if `Port == null`. |
| **`BeginAccept(...)`** | `public IAsyncResult BeginAccept(AsyncCallback callback, Object state)` | Throws if `Port == null`. Returns `null`. |
| **`EndAccept(...)`** | `public IConnection EndAccept(IAsyncResult asyncResult)` | Returns a **new** `SerialConnection` instance (uninitialized—no `Port` created). Throws if `Port == null`. |
| **`Bind(int port)`** | `public void Bind(int port)` | No-op. Throws if `Port == null`. |
| **`Listen(int backlog)`** | `public void Listen(int backlog)` | No-op. Throws if `Port == null`. |
| **`BeginSend(...)`** | `public IAsyncResult BeginSend(byte[] buffer, int offset, int size, AsyncCallback cb, object state)` | Delegates to `SerialPort.BaseStream.BeginWrite(...)`. Throws if `Port == null` or `cb == null`. |
| **`EndSend(...)`** | `public int EndSend(IAsyncResult ar)` | Calls `SerialPort.BaseStream.EndWrite(ar)`. Returns `Port.BytesToWrite`. Throws if `Port == null`. |
| **`SendAsync(...)`** | `public Task<int> SendAsync(byte[] sendBuffer, int bufferStartOffset, int bufferSizeToSend)` | Wraps `BeginSend`/`EndSend` using `Task.Factory.FromAsync`. |
| **`BeginReceive(...)`** | `public IAsyncResult BeginReceive(byte[] buffer, int offset, int size, AsyncCallback cb, object state)` | Delegates to `SerialPort.BaseStream.BeginRead(...)`. Throws if `Port == null` or `cb == null`. |
| **`EndReceive(...)`** | `public int EndReceive(IAsyncResult ar)` | Calls `SerialPort.BaseStream.EndRead(ar)`. Throws if `Port == null`. |
| **`Dispose()`** | `public void Dispose()` | Calls `Dispose(true)` and suppresses finalization. |
| **`~SerialConnection()`** | `~SerialConnection()` | Finalizer calls `Dispose(false)`. |
| **`Dispose(bool)`** | `protected virtual void Dispose(bool disposing)` | Closes and nulls `Port` if `disposing` is `true`. Sets `disposed = true`. |
> **Note**: The class implements `IDisposable`. `Connected` is never set to `true`, and `OnDisconnected` is never invoked.
---
### 3. Invariants
- `Connected` is **always** `false`. It is a read-only property initialized to `false` and never modified.
- `_PortName` is set only via `Create(string PortName)`. `ConnectString` returns `_PortName`.
- `Port` is only initialized in `Create(string PortName)` and `EndAccept(...)`. In the latter case, the new `SerialConnection` instance has `Port == null`.
- `BeginConnect` is the only method that actually opens the serial port (`Port.Open()`). No other method affects port state.
- `EndSend` returns `Port.BytesToWrite`, which reflects the number of bytes *still pending in the transmit buffer*—not bytes sent.
- `SoftConnect`, `SoftDisconnect`, `Bind`, `Listen`, and `BeginAccept`/`EndAccept` are **not functional** for serial connections and may throw if `Port == null`.
- `IsSoftDisconnected` is always `false` and unused.
---
### 4. Dependencies
- **Depends on**:
- `DTS.Common.Interface.Connection` (via `IConnection` interface).
- `System.IO.Ports` (for `SerialPort`).
- `System.Threading.Tasks` (for `Task<int>`).
- `System` (for `EventHandler`, `AsyncCallback`, `IAsyncResult`, `Exception`).
- **Depended on by**:
- Unknown from source alone. Presumably used by higher-level connection-handling logic that consumes `IConnection`.
---
### 5. Gotchas
- **Critical Bug in `Create(string PortName)`**:
```csharp
Port = new SerialPort(_PortName); // ❌ Uses uninitialized _PortName
_PortName = PortName; // ✅ Sets _PortName *after* use
```
The `SerialPort` constructor is called with `_PortName`, which is `null` at that point. Should be `new SerialPort(PortName)`.
- **`Connected` is never updated**:
Even after `BeginConnect` succeeds, `Connected` remains `false`. Consumers cannot rely on this property.
- **`OnDisconnected` is never raised**:
The event is declared but never invoked—even during `Dispose` or `Port.Close()`.
- **`EndAccept` returns an uninitialized `SerialConnection`**:
The new instance has `Port == null`, so calling `BeginConnect`/`Send`/`Receive` on it will throw.
- **`SoftConnect`/`SoftDisconnect` are no-ops**:
Despite being part of `IConnection`, they do nothing. Do not expect disconnection behavior from them.
- **`BeginDisconnect`/`EndDisconnect` do not close the port**:
Only `Dispose` closes the `SerialPort`. `EndDisconnect` is a no-op.
- **`GetCurrentDownloadRate()` / `GetCurrentUploadRate()` always return `0D`**:
No actual rate tracking is implemented.
- **`Flags` property is unused**:
It is a `SocketFlags` property (from `IConnection`) but serial ports do not use socket flags.
- **`BeginSend`/`BeginReceive` use `SerialPort.BaseStream`**:
This is correct for async I/O, but note that `SerialPort.BaseStream` is synchronous under the hood—performance may be suboptimal for high-throughput scenarios.
- **No validation of `PortName` in `Create`**:
Invalid port names (e.g., `"COM999"`) will only fail at `Port.Open()` in `BeginConnect`.
- **`ConnectString` is misleading**:
It holds only the port name (e.g., `"COM3"`), not a full connection string. Also, the overload `Create(string connectString, string hostIPAddress)` ignores `connectString`.
- **`disposed` flag prevents double-dispose**:
Safe, but `Port` may be `null` after first dispose—subsequent `Dispose` calls are no-ops.
- **No exception handling in `BeginConnect`/`EndConnect`**:
Exceptions from `Port.Open()` (e.g., `UnauthorizedAccessException`, `IOException`) propagate directly.
- **No cancellation support**:
All async methods lack `CancellationToken` support.
- **`EndSend` returns `BytesToWrite`**:
This is the number of bytes *remaining* in the output buffer—not bytes sent. Likely a mistake; should be bytes *written* (which is implicit in `EndWrite`s return value, but `EndSend` discards it and returns `BytesToWrite` instead).

View File

@@ -0,0 +1,38 @@
---
source_files:
- Common/DTS.Common.IConnection/SerialConnection/Properties/AssemblyInfo.cs
generated_at: "2026-04-16T02:09:13.932338+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "387f9fdb03f26ec5"
---
# Properties
## Documentation: DTS.Common.IConnection.SerialConnection Assembly
### 1. Purpose
This assembly (`DTS.Common.IConnection.SerialConnection`) defines metadata and versioning information for a .NET assembly containing serial connection functionality. Based solely on the provided source file, the assembly itself does not contain implementation logic—it is an *assembly-level metadata file* (`AssemblyInfo.cs`) used to configure assembly attributes such as title, version, and COM visibility. Its role is to identify and version the `SerialConnection.cs` component within the broader `DTS.Common.IConnection` module, enabling proper deployment, referencing, and version management in the system.
### 2. Public Interface
**No public types (classes, interfaces, structs, enums, or delegates) are defined in this file.**
The file contains only assembly-level attributes (via `Assembly*` attributes). No executable code, types, or public APIs are declared here.
### 3. Invariants
- The assembly version is fixed at `1.06.0081` (both `AssemblyVersion` and `AssemblyFileVersion`).
- The assembly is **not** COM-visible (`ComVisible(false)`), meaning its types cannot be consumed by COM clients unless explicitly exposed via other mechanisms (e.g., `ComVisible(true)` on individual types).
- The `Guid` attribute (`8d3a85de-321a-48fb-8f9e-f1d9594ee423`) uniquely identifies the typelib for COM interop scenarios (though COM visibility is disabled, this GUID is still present for potential future use or legacy compatibility).
- The assembly title is `"SerialConnection.cs"` (note: likely a misnomer, as this is an assembly title, not a file title).
### 4. Dependencies
- **No runtime dependencies** are declared in this file.
- The file uses standard .NET namespaces: `System.Reflection`, `System.Runtime.CompilerServices`, and `System.Runtime.InteropServices`.
- This assembly is part of the `DTS.Common.IConnection` module (inferred from the assembly title and directory path), implying it is consumed by other modules in the `DTS.Common` hierarchy. However, no direct references or dependents are specified in this file.
### 5. Gotchas
- **Misleading assembly title**: The `AssemblyTitle` is set to `"SerialConnection.cs"`, which suggests a single file, but assembly titles conventionally describe the *assembly* (e.g., `"DTS Serial Connection Library"`), not a source file. This may cause confusion during debugging or deployment.
- **COM interop ambiguity**: While `ComVisible(false)` is set, the presence of a `Guid` attribute implies potential COM exposure intent. If COM interop is required, this setting may need revisiting (e.g., enabling `ComVisible(true)` on specific types).
- **No public surface area**: Developers expecting to find serial connection logic (e.g., `Open()`, `Write()`, `Read()`) in this file will be misled—this file is purely metadata. Actual implementation resides in other files (e.g., `SerialConnection.cs` in the same directory, not provided here).
- **Versioning**: The version `1.06.0081` uses a non-standard format (likely `major.minor.build` where `06` = minor version 6, `0081` = build 81). Ensure build/deployment tooling interprets this correctly.
None identified beyond the above.

View File

@@ -0,0 +1,147 @@
---
source_files:
- Common/DTS.Common.IConnection/USBConnection/HIDUSBConnection/HIDUSBConnection.cs
generated_at: "2026-04-16T02:10:22.619594+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "4a9eeb7b8043999a"
---
# Documentation: `HIDUSBConnection` Class
## 1. Purpose
`HIDUSBConnection` is a concrete implementation of the `IConnection` interface that enables communication with a specific HID-class USB device (identified by Vendor ID `0x1CB9` and Product ID `0x0003`, named *HIDSLICE*) using Windows file I/O APIs (`CreateFile`, `ReadFile`, `WriteFile` via overlapped I/O). It abstracts low-level HID report handling (input/output reports) over USB, providing asynchronous send/receive semantics consistent with .NETs `IAsyncResult` pattern. This module exists to support direct, low-latency data transfer to/from embedded hardware (e.g., a data acquisition recorder) where standard socket-based communication is not applicable.
---
## 2. Public Interface
### Constructors & Finalizer
- **`HIDUSBConnection()`**
Initializes the instance, sets up `SECURITY_ATTRIBUTES` for `CreateFile`, and initializes `_Connected = false`.
- **`~HIDUSBConnection()`**
Finalizer that invokes `Dispose(false)` to release unmanaged resources.
### Disposal
- **`void Dispose()`**
Performs deterministic cleanup: calls `Dispose(true)` and suppresses finalization.
- **`protected virtual void Dispose(bool disposing)`**
Releases all handles (`_HIDHandle`, `_ReadHandle`, `_WriteHandle`) via `FileIODeclarations.CloseHandle`, disposes `_MyHID`, and sets `_Connected = false`. Idempotent (`disposed` flag prevents double-disposal).
### Connection Management
- **`void Create(string ConnectString)`**
Stores the device path (`ConnectString`) for later use in `EndConnect`. Does *not* open the device.
- **`IAsyncResult BeginConnect(AsyncCallback cb, object state)`**
Initiates asynchronous connection. Enqueues a work item to invoke `NetCallbackFix`, which in turn invokes the callback on the thread pool. *Actual device opening occurs in `EndConnect`*.
- **`void EndConnect(IAsyncResult ar)`**
Opens the device using `ConnectString` (set via `Create`) via three `CreateFile` calls:
- `_HIDHandle`: for attribute queries (no access rights)
- `_ReadHandle`: for reading input reports (`GENERIC_READ`)
- `_WriteHandle`: for writing output reports (`GENERIC_WRITE`)
Retrieves device attributes (`HidD_GetAttributes`), capabilities (`GetDeviceCapabilities`), and input report buffer size (`GetInputReportBufferSize`). Flushes the input queue. Sets `_Connected = true`. Throws on handle failure or attribute retrieval failure.
- **`IAsyncResult BeginDisconnect(bool reuseSocket, AsyncCallback cb, object state)`**
Asynchronous disconnect. Enqueues a work item to invoke the callback. *Actual cleanup is deferred to `EndDisconnect`*.
- **`void EndDisconnect(IAsyncResult asyncResult)`**
Closes all three handles (`_HIDHandle`, `_ReadHandle`, `_WriteHandle`) and sets `_Connected = false`.
### Properties
- **`bool Connected { get; }`**
Returns `_Connected`.
- **`string ConnectString { get; }`**
Returns `Device_Name` (set via `Create`).
- **`System.Net.Sockets.SocketFlags Flags { get; set; }`**
Property required by `IConnection` interface; unused in this implementation.
- **`string GetConnectionData()`**
Returns `""` (empty string). No meaningful data exposed.
- **`double GetCurrentDownloadRate()`**
Returns `0D`. Rate tracking not implemented.
- **`double GetCurrentUploadRate()`**
Returns `0D`. Rate tracking not implemented.
### Static Utility
- **`static string GetFirstConnectString()`**
Scans all HID devices on the system to find the first device matching `DTS_VID` (`0x1CB9`) and `HIDSLICE_PID` (`0x0003`). Returns the devices path string (e.g., `\\?\hid#vid_1cb9&pid_0003#...`) or `string.Empty` if not found. Uses `HIDDeclarations.HidD_GetHidGuid`, `DeviceManagement.FindDeviceFromGuid`, and `HIDDeclarations.HidD_GetAttributes`.
### I/O Operations
- **`IAsyncResult BeginSend(byte[] buffer, int offset, int size, AsyncCallback cb, object state)`**
Initiates asynchronous send. Validates `_ReadHandle` and `_WriteHandle` are valid. Enqueues callback via `ThreadPool.QueueUserWorkItem`. *Actual transmission occurs in `EndSend`*.
- **`int EndSend(IAsyncResult ar)`**
Writes `buffer[offset..offset+size)` to the device in chunks, respecting `OutputReportByteLength`.
- Prepends each chunk with report ID `0x00` at index `0`.
- Uses `HIDevice.OutputReport.Write` for each chunk.
Returns `size` (number of bytes sent). Throws on invalid handles or write failure.
- **`IAsyncResult BeginReceive(byte[] buffer, int offset, int size, AsyncCallback cb, object state)`**
Initiates asynchronous receive. Validates handles. Enqueues callback. *Actual read occurs in `EndReceive`*.
- **`int EndReceive(IAsyncResult ar)`**
Reads one input report into `InputReportBuffer` via `HIDevice.InputReport.Read`. Copies data (skipping report ID at index `0`) into `buffer[offset..]`. Returns `size` if successful, `0` otherwise. Sets `IsCompleted = true` and signals `AsyncWaitHandle`.
### Unsupported Operations (Throw `NotSupportedException`)
- `BeginAccept`, `EndAccept`, `Bind(int)`, `Listen(int)`
These methods are implemented only to satisfy `IConnection` but are not applicable to HID device communication.
---
## 3. Invariants
- **Device Identity**: Only devices with `VendorID == 0x1CB9` and `ProductID == 0x0003` are accepted.
- **Handle State**: `_HIDHandle`, `_ReadHandle`, and `_WriteHandle` must be valid (non-`INVALID_HANDLE_VALUE`) before `BeginSend`/`BeginReceive` succeeds.
- **Connection State**: `_Connected` is `true` only after successful completion of `EndConnect`, and `false` otherwise (including after `EndDisconnect` or disposal).
- **Report Structure**:
- Input reports: Data starts at index `1`; index `0` is the report ID (ignored).
- Output reports: Data starts at index `1`; index `0` is report ID (set to `0`).
- **Buffer Size**: `InputReportBuffer` is sized to `_MyHID.Capabilities.InputReportByteLength` during `EndConnect`.
- **Disposal Safety**: `Dispose` is idempotent (`disposed` flag prevents re-entry).
- **Asynchronous Pattern**: All async operations (`BeginConnect`, `BeginSend`, etc.) use `HIDUSBRecAsyncResult` and delegate callback invocation to `NetCallbackFix`, which runs on a thread pool thread.
---
## 4. Dependencies
### External Dependencies
- **Windows API (via interop)**:
- `FileIODeclarations.CreateFile`, `CloseHandle`, `FILE_SHARE_*`, `GENERIC_*`, `INVALID_HANDLE_VALUE`, `OPEN_EXISTING`
- `HIDDeclarations.HidD_GetHidGuid`, `HidD_GetAttributes`
- **`DTS.DASLib.Connection.USBFramework`**:
- `HIDevice` class (used for device attributes, capabilities, input/output report handling)
- `DeviceManagement` class (used in `GetFirstConnectString`)
- **`DTS.DASLib.DASResource`**:
- `Strings` resource class (for localized error messages, e.g., `Strings.HIDUSBConnection_EndConnect_Err1`)
- **.NET Framework Core**:
- `System.Runtime.InteropServices` (for `Marshal.SizeOf`, `SECURITY_ATTRIBUTES`)
- `System.Threading` (for `ThreadPool`, `ManualResetEvent`)
- `System.Windows.Forms.MessageBox` (used in `NetCallbackFix` for exception reporting—*potential runtime dependency on WinForms*).
### Implemented Interfaces
- `IConnection` (interface defining the contract; not shown in source but referenced).
### Inferred Consumers
- Any code requiring `IConnection` to communicate with the *HIDSLICE* device (e.g., data acquisition logic, device enumeration UI).
- `GetFirstConnectString` is likely called by device discovery components.
---
## 5. Gotchas
- **Misleading Async Pattern**: `BeginConnect`/`BeginSend`/`BeginReceive` do *not* perform actual I/O; they only enqueue a callback. All work happens in `End*` methods. This deviates from typical .NET async patterns where `Begin*` initiates the operation.
- **No Overlapped I/O**: Despite using `CreateFile` with overlapped semantics (implied by `_ReadHandle`/`_WriteHandle`), the code does *not* use `OVERLAPPED` structures or `ReadFile`/`WriteFile` with completion callbacks. Instead, it relies on synchronous `HIDevice.InputReport.Read`/`Write`, which may block the thread pool thread.
- **Hardcoded Report ID**: Output reports always use `0x00` as the report ID. This assumes the device expects report ID `0`; mismatched IDs will cause silent failures or device errors.
- **WinForms Dependency in Error Handling**: `NetCallbackFix` shows a `MessageBox` on exceptions—a severe anti-pattern for non-UI threads or server environments.
- **`GetFirstConnectString` Hack**: The method scans *all* HID devices and stops at the first match. If multiple *HIDSLICE* devices are connected, behavior is undefined (first found wins).
- **Buffer Size Mismatch in `EndReceive`**: `EndReceive` copies `InputReportBuffer.Length - 1` bytes into the user buffer, but returns `rar.size` regardless. If `rar.size < InputReportBuffer.Length - 1`, the caller may read uninitialized buffer data beyond the actual received payload.
- **No Timeout Handling**: No mechanism for read/write timeouts; operations may block indefinitely.
- **`Flags` Property Unused**: The `SocketFlags` property is implemented but never used.
- **`BeginAccept`/`EndAccept` Misuse**: Throwing `NotSupportedException` for connection-oriented methods suggests this class was adapted from a socket-based `IConnection` implementation without full refactoring.

View File

@@ -0,0 +1,33 @@
---
source_files:
- Common/DTS.Common.IConnection/USBConnection/HIDUSBConnection/Properties/AssemblyInfo.cs
generated_at: "2026-04-16T02:10:22.587640+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "1fcf58774b015c19"
---
# Properties
## 1. Purpose
This file is an assembly-level metadata configuration file (`AssemblyInfo.cs`) for the `DTS.Common.IConnection.USBConnection.HIDUSBConnection` .NET assembly. Its purpose is to define assembly-wide attributes such as title, version, COM visibility, and GUID—used for identification, versioning, and interoperability—but it does *not* contain any executable logic, interfaces, or types. It serves as infrastructure metadata required by the .NET build system and COM interop layer, with no runtime behavior or public API surface.
## 2. Public Interface
**None.**
This file contains only assembly-level attributes and no public types (classes, structs, interfaces, enums), methods, properties, or fields. All content is metadata declarations via `Assembly*` attributes.
## 3. Invariants
- The assembly is **not visible to COM** (`ComVisible(false)`), meaning its types cannot be accessed via COM unless explicitly exposed elsewhere.
- The assemblys version is fixed at **1.06.0081** for both `AssemblyVersion` and `AssemblyFileVersion`.
- The assemblys GUID is **`9127ae79-928b-4187-a425-97f49034c5ad`**, used for COM type library identification (though irrelevant here due to `ComVisible(false)`).
- No runtime invariants apply, as this file contributes no executable code.
## 4. Dependencies
- **Dependencies**: None (this file has no external dependencies beyond the .NET Frameworks `System.Reflection`, `System.Runtime.CompilerServices`, and `System.Runtime.InteropServices` namespaces, which are implicitly available).
- **Depended upon**: None directly—this file is consumed by the build system and runtime metadata infrastructure, not by application code. Other modules in the `DTS.Common.IConnection` hierarchy may reference this assembly, but they do not depend on its metadata content.
## 5. Gotchas
- **Versioning nuance**: `AssemblyVersion` (`1.06.0081`) controls binding redirects and assembly identity at runtime, while `AssemblyFileVersion` is informational (used for file properties in Windows). Changing only `AssemblyFileVersion` does *not* affect runtime binding.
- **COM irrelevance**: Despite the explicit `Guid` attribute, `ComVisible(false)` renders the GUID unused for COM registration. If COM interop is needed, `ComVisible(true)` must be set *and* types must be explicitly marked with `ComVisible(true)`.
- **No functional impact**: Modifying or deleting this file will not break runtime logic but may cause build warnings or break COM registration tooling (e.g., `regasm`) if used.
- **Historical date**: Copyright year is set to 2008; verify if this reflects current ownership or is legacy.

View File

@@ -0,0 +1,158 @@
---
source_files:
- Common/DTS.Common.IConnection/USBConnection/USBFramework/FileIODeclarations.cs
- Common/DTS.Common.IConnection/USBConnection/USBFramework/HIDDeclarations.cs
- Common/DTS.Common.IConnection/USBConnection/USBFramework/DeviceManagementDeclarations.cs
- Common/DTS.Common.IConnection/USBConnection/USBFramework/DeviceManagement.cs
generated_at: "2026-04-16T02:09:55.521694+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "8939bee008e13a9a"
---
# Documentation: USBFramework Module
## 1. Purpose
This module provides low-level Windows API interop declarations and high-level device management utilities for USB device communication, specifically targeting HID-class devices and generic file I/O operations. It serves as the foundational layer for USB device enumeration, notification handling, and raw communication in the DTS system. The module exposes P/Invoke signatures for Windows kernel32.dll, hid.dll, setupapi.dll, and advapi32.dll functions, alongside managed wrappers (e.g., `DeviceManagement`) that abstract device discovery, registration for plug-and-play events, and property retrieval. Its role is to enable reliable detection, connection, and interaction with USB devices without relying on higher-level .NET USB libraries.
## 2. Public Interface
### `FileIODeclarations` class (namespace `DTS.Common.USBFramework`)
- **`const uint GENERIC_READ = 0x80000000`**
Access mask for read operations in `CreateFile`.
- **`const uint GENERIC_WRITE = 0x40000000`**
Access mask for write operations in `CreateFile`.
- **`const uint FILE_SHARE_READ = 0x00000001`**
Share mode flag for read sharing.
- **`const uint FILE_SHARE_WRITE = 0x00000002`**
Share mode flag for write sharing.
- **`const uint FILE_FLAG_OVERLAPPED = 0x40000000`**
Flag for asynchronous I/O in `CreateFile`.
- **`const int INVALID_HANDLE_VALUE = -1`**
Sentinel value for invalid handle.
- **`const short OPEN_EXISTING = 3`**
Creation disposition for opening existing files/devices.
- **`const int WAIT_TIMEOUT = 0x102`**, **`WAIT_OBJECT_0 = 0`**, **`WAIT_FAILED = 0xFFFFFFFF`**, **`WAIT_ABANDONED = 0x00000080`**
Return codes for `WaitForSingleObject`.
- **`const int FSCTL_SET_COMPRESSION = 0x9C040`**
I/O control code for compression (unused in current context).
- **`struct OVERLAPPED`**
Unmanaged structure for asynchronous I/O (note: `hEvent` is `int`, not `IntPtr`).
- **`struct SECURITY_ATTRIBUTES`**
Unmanaged structure for security descriptor handling (note: `lpSecurityDescriptor` is `int`, not `IntPtr`).
- **`int CancelIo(int hFile)`**
Cancels pending I/O operations on the specified file handle.
- **`int CloseHandle(int hObject)`**
Closes an open object handle.
- **`int CreateEvent(ref SECURITY_ATTRIBUTES SecurityAttributes, int bManualReset, int bInitialState, string lpName)`**
Creates or opens a named or unnamed event object.
- **`int CreateFile(string lpFileName, uint dwDesiredAccess, uint dwShareMode, ref SECURITY_ATTRIBUTES lpSecurityAttributes, int dwCreationDisposition, uint dwFlagsAndAttributes, int hTemplateFile)`**
Creates or opens a file or I/O device (e.g., USB device).
- **`int GetLastError()`**
Retrieves the calling threads last-error code.
- **`int ReadFile(int hFile, ref byte lpBuffer, int nNumberOfBytesToRead, ref int lpNumberOfBytesRead, int lpOverlapped)`**
Reads from a file or device (note: `lpOverlapped` is `int`, not `ref OVERLAPPED`).
- **`uint WaitForSingleObject(int hHandle, int dwMilliseconds)`**
Waits until the specified object is in the signaled state or the time-out interval elapses.
- **`int WriteFile(int hFile, ref byte lpBuffer, int nNumberOfBytesToWrite, ref int lpNumberOfBytesWritten, int lpOverlapped)`**
Writes to a file or device.
- **`int DeviceIoControl(IntPtr hDevice, int dwIoControlCode, ref short lpInBuffer, int nInBufferSize, IntPtr lpOutBuffer, int nOutBufferSize, ref int lpBytesReturned, IntPtr lpOverlapped)`**
Sends a control code directly to a device driver.
### `FileIO` class (namespace `DTS.Common.USBFramework`)
- **`const short FILE_ATTRIBUTE_NORMAL = 0x80`**, **`FILE_FLAG_OVERLAPPED = 0x40000000`**, etc.
Duplicate constants (with different types) from `FileIODeclarations`.
- **`struct SECURITY_ATTRIBUTES`**
Alternate definition with `lpSecurityDescriptor` as `IntPtr` (inconsistent with `FileIODeclarations`).
- **`bool CloseHandle(SafeFileHandle hObject)`**
Managed wrapper for closing a `SafeFileHandle`.
- **`SafeFileHandle CreateFile(string lpFileName, uint dwDesiredAccess, int dwShareMode, ref SECURITY_ATTRIBUTES lpSecurityAttributes, int dwCreationDisposition, int dwFlagsAndAttributes, int hTemplateFile)`**
Managed wrapper returning `SafeFileHandle`.
### `HIDDeclarations` class (namespace `DTS.DASLib.Connection.USBFramework`)
- **`const short HidP_Input = 0`, `HidP_Output = 1`, `HidP_Feature = 2`**
Report types for HID operations.
- **`struct HIDD_ATTRIBUTES`**
Contains vendor ID, product ID, and version number.
- **`struct HIDP_CAPS`**
Contains HID device capabilities (report sizes, usage pages, etc.).
- **`struct HidP_Value_Caps`**
Describes value capabilities (e.g., range, usage, min/max).
- **`bool HidD_FlushQueue(int HidDeviceObject)`**
Flushes the input buffer of an HID device.
- **`bool HidD_FreePreparsedData(ref IntPtr PreparsedData)`**
Frees preparsed data allocated by `HidD_GetPreparsedData`.
- **`int HidD_GetAttributes(int HidDeviceObject, ref HIDD_ATTRIBUTES Attributes)`**
Retrieves device attributes (VID, PID, version).
- **`bool HidD_GetFeature(int HidDeviceObject, ref byte lpReportBuffer, int ReportBufferLength)`**
Retrieves a feature report from the device.
- **`bool HidD_GetInputReport(int HidDeviceObject, ref byte lpReportBuffer, int ReportBufferLength)`**
Retrieves an input report from the device.
- **`void HidD_GetHidGuid(ref Guid HidGuid)`**
Retrieves the system-defined GUID for HID devices.
- **`bool HidD_GetNumInputBuffers(int HidDeviceObject, ref int NumberBuffers)`**
Gets the number of input buffers allocated for the device.
- **`bool HidD_GetPreparsedData(int HidDeviceObject, ref IntPtr PreparsedData)`**
Retrieves preparsed data for HID device.
- **`bool HidD_SetFeature(int HidDeviceObject, ref byte lpReportBuffer, int ReportBufferLength)`**
Sends a feature report to the device.
- **`bool HidD_SetNumInputBuffers(int HidDeviceObject, int NumberBuffers)`**
Sets the number of input buffers.
- **`bool HidD_SetOutputReport(int HidDeviceObject, ref byte lpReportBuffer, int ReportBufferLength)`**
Sends an output report to the device.
- **`int HidP_GetCaps(IntPtr PreparsedData, ref HIDP_CAPS Capabilities)`**
Retrieves HID capabilities from preparsed data.
- **`int HidP_GetValueCaps(short ReportType, ref byte ValueCaps, ref short ValueCapsLength, IntPtr PreparsedData)`**
Retrieves value capability information.
### `DeviceManagement` class (namespace `DTS.Common.USBFramework`)
- **`bool DeviceNameMatch(Message m, string mydevicePathName)`**
Compares the device path in a `WM_DEVICECHANGE` message with `mydevicePathName`. Returns `true` if they match (case-insensitive). Uses `DEV_BROADCAST_DEVICEINTERFACE_1` to extract the device name from the messages `LParam`.
- **`bool FindDeviceFromGuid(Guid myGuid, ref string[] devicePathName)`**
Enumerates devices in the interface class specified by `myGuid` and populates `devicePathName` with their device paths. Returns `true` if at least one device is found. Uses `SetupDiGetClassDevs`, `SetupDiEnumDeviceInterfaces`, and `SetupDiGetDeviceInterfaceDetail`.
- **`bool RegisterForDeviceNotifications(IntPtr formHandle, Guid classGuid, ref IntPtr deviceNotificationHandle)`**
Registers a window (`formHandle`) to receive `WM_DEVICECHANGE` notifications for devices in `classGuid`. Returns `true` on success. Allocates unmanaged memory for `DEV_BROADCAST_DEVICEINTERFACE` and calls `RegisterDeviceNotification`.
- **`void StopReceivingDeviceNotifications(IntPtr deviceNotificationHandle)`**
Unregisters device notifications using `UnregisterDeviceNotification`. Ignores failures.
- **`bool GetDeviceRegistryProperty(Guid myGuid)`**
Enumerates devices in `myGuid`s class and retrieves the `SPDRP_DRIVER` registry property for each device. Logs results via `APILogger`. Returns `true` on success (even if no devices found).
## 3. Invariants
- **Handle Validity**: All handle-based APIs (`CreateFile`, `RegisterDeviceNotification`) return `INVALID_HANDLE_VALUE` (-1) or `IntPtr.Zero` on failure. Callers must check return values before use.
- **Memory Management**: Unmanaged memory allocated via `Marshal.AllocHGlobal` (e.g., in `FindDeviceFromGuid`, `RegisterForDeviceNotifications`) must be freed with `Marshal.FreeHGlobal`. The `DeviceManagement` class handles this in `try/finally` blocks.
- **Structure Size Consistency**: The `cbSize` field of `SP_DEVICE_INTERFACE_DETAIL_DATA` must be set to `Marshal.SizeOf()` *before* calling `SetupDiGetDeviceInterfaceDetail`. The implementation writes `cbSize` manually to the unmanaged buffer, with logic to handle 32/64-bit alignment.
- **64-bit Compatibility**: `IS64_BIT_PROCESS` (set via `IntPtr.Size == 8`) is used to adjust pointer arithmetic (e.g., `cbSize` offset, handle comparison). This is critical for `FindDeviceFromGuid` and `RegisterForDeviceNotifications`.
- **HID Report Buffer Size**: `HidD_GetFeature`, `HidD_SetFeature`, etc., require the report buffer to be exactly `InputReportByteLength`/`OutputReportByteLength`/`FeatureReportByteLength` bytes (from `HIDP_CAPS`), including the report ID byte.
- **GUID Consistency**: The `HidD_GetHidGuid` function populates a `Guid` by reference; callers must pass a valid `Guid` instance (not `Guid.Empty`).
## 4. Dependencies
### Imports/References:
- **System.Runtime.InteropServices**: Required for P/Invoke, `Marshal`, `StructLayout`.
- **Microsoft.Win32.SafeHandles**: Used in `FileIO.CloseHandle` (via `SafeFileHandle`).
- **System.Windows.Forms**: Required for `Message` type in `DeviceNameMatch`.
- **DTS.Common.Utilities.Logging**: Used for `APILogger.Log` in `GetDeviceRegistryProperty`.
- **hid.dll**, **setupapi.dll**, **kernel32.dll**, **advapi32.dll**: Native libraries for HID, device setup, and registry operations.
### Dependencies on Other Modules:
- **`DeviceManagement`** depends on `DeviceManagementDeclarations` for unmanaged API declarations.
- **`FileIO`** and **`FileIODeclarations`** provide overlapping declarations (likely legacy duplication).
- **`HIDDeclarations`** is in a different namespace (`DTS.DASLib.Connection.USBFramework`) and is used by HID-specific communication logic (not shown here).
### Used By:
- Higher-level USB connection classes (e.g., `USBConnection`, `HIDConnection`) that consume `DeviceManagement` for device discovery and `HIDDeclarations` for HID I/O.
## 5. Gotchas
- **Duplicate Constants**: `FileIO` and `FileIODeclarations` define identical constants (e.g., `GENERIC_READ`, `FILE_FLAG_OVERLAPPED`) with inconsistent types (`uint` vs `short`/`int`). This may cause confusion or errors if mixed.
- **Inconsistent Structure Definitions**: `SECURITY_ATTRIBUTES` is defined twice in `FileIODeclarations` and `FileIO` with different field types (`int` vs `IntPtr`). This is unsafe and may cause crashes on 64-bit systems.
- **`OVERLAPPED` Structure**: The `OVERLAPPED` struct uses `int` for `hEvent` instead of `IntPtr`, which is incorrect for 64-bit compatibility. This will fail on 64-bit processes.
- **`CreateFile` Overloads**: `FileIODeclarations.CreateFile` returns `int` (unmanaged handle), while `FileIO.CreateFile` returns `SafeFileHandle`. Using the wrong overload may lead to resource leaks or handle misuse.
- **`RegisterForDeviceNotifications` Memory Leak Risk**: The `buffer` allocated via `Marshal.AllocHGlobal` is freed *after* `RegisterDeviceNotification`, but if `RegisterDeviceNotification` fails, the handle is `IntPtr.Zero`, and the buffer is still freed. This is safe, but the comment `// Set fDeleteOld True to prevent memory leaks` is misleading—the `true` flag in `StructureToPtr` overwrites the old pointer, but `AllocHGlobal`/`FreeHGlobal` is still required.
- **`FindDeviceFromGuid` Buffer Size Calculation**: The `cbSize` offset calculation `(IntPtr.Size == 4) ? (4 + Marshal.SystemDefaultCharSize) : 8` assumes `cbSize` is 4 bytes on 32-bit and 8 on 64-bit, but `SP_DEVICE_INTERFACE_DETAIL_DATA.cbSize` is `int` (4 bytes) regardless of platform. This may cause misalignment on 64-bit.
- **`DeviceNameMatch` String Size Calculation**: Assumes `dbcc_name` is Unicode (2 bytes/char) and subtracts 28 bytes for fixed fields. This is correct for `DEV_BROADCAST_DEVICEINTERFACE_1` but may break if structure layout changes.
- **`GetDeviceRegistryProperty` Registry Key Access**: Uses `SetupDiOpenDevRegKey` but does not show its usage; the implementation only retrieves `SPDRP_DRIVER` via `SetupDiGetDeviceRegistryPropertyA`. Registry access may fail without elevated privileges.
- **`HIDP_*` Functions**: Return codes (e.g., `HidP_GetCaps`) are `int` but not documented. Callers must check for success (typically `0` for success, non-zero for error codes like `HIDP_STATUS_BUFFER_TOO_SMALL`).
- **No Async Support**: Despite `FILE_FLAG_OVERLAPPED` being defined, the `ReadFile`/`WriteFile` declarations use synchronous signatures (no `OVERLAPPED` pointer). Asynchronous I/O is not implemented.

View File

@@ -0,0 +1,36 @@
---
source_files:
- Common/DTS.Common.IConnection/USBConnection/USBFramework/Properties/AssemblyInfo.cs
generated_at: "2026-04-16T02:10:14.603636+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "f8e1fde835545ec4"
---
# Properties
## 1. Purpose
This module is the `DTS.Common.IConnection.USBConnection.USBFramework` assembly (internally titled *HIDFramework*), a .NET class library component responsible for providing USB communication capabilities—specifically targeting Human Interface Device (HID) protocols—within the DTS (presumably *Digital Training Systems* or similar domain) ecosystem. It serves as a foundational layer for establishing and managing connections to USB HID devices, likely abstracting low-level OS interactions (e.g., Windows HID API) into higher-level .NET interfaces used by other connection-handling modules (e.g., `IConnection` implementations). Its existence enables standardized, reusable USB device integration across the codebase.
## 2. Public Interface
**No public types (classes, interfaces, structs, or methods) are declared in this file.**
This file (`AssemblyInfo.cs`) contains only assembly-level metadata attributes (e.g., title, version, COM visibility) and does not define any executable code or public API surface. Therefore, there are **no public functions, classes, or methods** documented here. Public interfaces would reside in other source files within the `USBFramework` project (e.g., `HIDDevice.cs`, `USBConnection.cs`), which are not provided.
## 3. Invariants
- The assembly is **not COM-visible** (`ComVisible(false)`), meaning its types cannot be directly consumed by COM clients without explicit interop wrappers.
- The assembly version is fixed at `1.06.0081` (both `AssemblyVersion` and `AssemblyFileVersion`).
- The assembly GUID (`c655f31f-ca6c-4e9b-9480-934762d20a8c`) uniquely identifies the typelib for COM interop *if* `ComVisible` were enabled (though it is not).
- No runtime invariants (e.g., state constraints, validation rules) are expressible in this file, as it contains no logic.
## 4. Dependencies
- **Framework Dependencies**: Requires core .NET Framework assemblies (implicitly via `System.Reflection`, `System.Runtime.CompilerServices`, `System.Runtime.InteropServices`).
- **No explicit external dependencies** are declared in this file.
- **Inferred consumers**: Other modules in the `DTS.Common.IConnection` hierarchy (e.g., `USBConnection` implementations) likely depend on types defined in this assembly, but those types are not visible here.
- **Inferred producers**: This assembly is likely built as part of a larger solution where `USBFramework` is a referenced library for USB-specific connection logic.
## 5. Gotchas
- **Misleading assembly title**: The `AssemblyTitle` is `"HIDFramework"`, but the namespace/path is `USBFramework`. This may cause confusion during debugging, logging, or reflection-based discovery (e.g., `Assembly.GetExecutingAssembly().Title` returns `"HIDFramework"`).
- **No versioning strategy in source**: The version `1.06.0081` is hardcoded; no build-time auto-increment or CI integration is evident.
- **COM interop disabled**: While `ComVisible(false)` is appropriate for pure .NET usage, it precludes direct COM consumption without additional interop layers (e.g., `RegAsm` with `/tlb` and `/codebase`).
- **No documentation comments**: The file lacks XML documentation (`<summary>`, etc.), consistent with typical `AssemblyInfo.cs` but contributing to low discoverability of assembly-level intent.
- **None identified from source alone** regarding runtime behavior, logic, or usage patterns—these would require inspecting the actual implementation files (not provided).

View File

@@ -0,0 +1,284 @@
---
source_files:
- Common/DTS.Common.IConnection/USBConnection/WINUSBConnection/WINUSBDeviceApi.cs
- Common/DTS.Common.IConnection/USBConnection/WINUSBConnection/CDCUSBConnection.cs
- Common/DTS.Common.IConnection/USBConnection/WINUSBConnection/WINUSBConnection.cs
generated_at: "2026-04-16T02:09:52.794052+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "2043cd8e3c0f04ef"
---
# Documentation: USB Connection Modules
## 1. Purpose
This module provides two distinct USB-based connection implementations (`CDCUSBConnection` and `WINUSBConnection`) that implement the `IConnection` interface for communicating with DTS hardware devices. `CDCUSBConnection` emulates a serial port over USB using the Windows `SerialPort` class (CDCCommunication Device Class), while `WINUSBConnection` uses the native Windows WinUSB API (`winusb.dll`) for direct USB communication. Both modules support asynchronous I/O operations (`BeginConnect`, `EndConnect`, `BeginSend`, `EndSend`, etc.), resource disposal, and registry-based device enumeration for the DTS vendor ID `0x1CB9` and specific product IDs.
## 2. Public Interface
### `CDCUSBConnection`
- **`public bool IsSoftDisconnected { get; }`**
Always returns `false`. Soft disconnect is not supported for CDCUSB.
- **`public void SoftConnect()`**
No-op. Soft connect is not supported.
- **`public void SoftDisconnect()`**
No-op. Soft disconnect is not supported.
- **`public double GetCurrentUploadRate()`**
Returns `0.0`. Upload rate is not tracked.
- **`public double GetCurrentDownloadRate()`**
Returns `0.0`. Download rate is not tracked.
- **`public string PortName { get; set; }`**
Gets or sets the COM port name (e.g., `"COM3"`) used for serial communication.
- **`public string ConnectString { get; }`**
Returns the `_devicePathname` passed to `Create`. Used as a device identifier.
- **`public bool Connected { get; }`**
Returns `_Connected`, indicating whether the underlying `SerialPort` is open.
- **`public event EventHandler OnDisconnected`**
Event raised on disconnection (currently unused in this implementation).
- **`public static IList<string> RegKeys { get; }`**
Lazily-initialized list of registry subkey names under the DTS CDCUSB device path (`USB\VID_1CB9&PID_001A`). Used to locate device-specific COM port names.
- **`public CDCUSBConnection()`**
Constructor initializing internal state (`_Connected = false`, `Disposed = false`, `Disposing = false`).
- **`public void Create(string connectString, string hostIPAddress)`**
Parses `connectString` to match a registry key in `RegKeys`, then reads the `"PortName"` value from the devices registry `"Device Parameters"` subkey and assigns it to `PortName`. Sets `_devicePathname = connectString`.
- **`public IAsyncResult BeginConnect(AsyncCallback cb, object state)`**
Returns an `IAsyncResult` (`UsbRecAsyncResult`) and queues a callback via `ThreadPool.QueueUserWorkItem`. Does *not* perform the actual connection.
- **`public void EndConnect(IAsyncResult ar)`**
Opens the `SerialPort` using configured `_baudRate`, `_parity`, `_stopBits`, `DATA_BITS`, and `PortName`. Sets `_Connected = true` on success.
- **`public IAsyncResult BeginSend(byte[] buffer, int offset, int size, AsyncCallback cb, object state)`**
Returns `UsbRecAsyncResult` with buffer metadata. Actual write occurs in `EndSend`.
- **`public int EndSend(IAsyncResult ar)`**
Writes `buffer` (using `size` and `offset` from `UsbRecAsyncResult`) to `_comPort.Write(...)`. Returns `size`.
- **`public Task<int> SendAsync(...)`**
Wraps `BeginSend`/`EndSend` in a `Task<int>`.
- **`public IAsyncResult BeginReceive(byte[] buffer, int offset, int size, AsyncCallback cb, object state)`**
Returns `UsbRecAsyncResult` with buffer metadata.
- **`public int EndReceive(IAsyncResult ar)`**
Reads from `_comPort.Read(...)` in a loop until at least one byte is read (sleeps 1 ms between retries). Returns number of bytes read.
- **`public IAsyncResult BeginDisconnect(...)`**
Returns `UsbRecAsyncResult`. Actual disconnect occurs in `EndDisconnect`.
- **`public void EndDisconnect(IAsyncResult ar)`**
Closes and disposes `_comPort`, sets `_Connected = false`.
- **`public void Dispose()` / `protected virtual void Dispose(bool)`**
Implements `IDisposable`. Closes `_comPort` if open, sets `Disposed = true`.
- **`public void Bind(int port)` / `public void Listen(int backlog)` / `public IAsyncResult BeginAccept(...)` / `public IConnection EndAccept(...)`**
All throw `NotSupportedException`.
### `WINUSBConnection`
- **`public bool IsSoftDisconnected { get; }`**
Always returns `false`. Soft disconnect is not supported.
- **`public void SoftConnect()` / `public void SoftDisconnect()`**
No-op.
- **`public double GetCurrentUploadRate()` / `public double GetCurrentDownloadRate()`**
Return `0.0`.
- **`public bool Connected { get; private set; }`**
Indicates whether the device is connected via WinUSB.
- **`public string ConnectString { get; private set; }`**
Stores the device path passed to `Create`.
- **`public event EventHandler OnDisconnected`**
Event for disconnection notifications (currently unused).
- **`public void Create(string connectString, string hostIPAddress)`**
Stores `connectString` in `ConnectString`.
- **`public IAsyncResult BeginConnect(AsyncCallback cb, object state)`**
Validates `_sliceDev == null && !Connected`. Returns `WinUSBRecAsyncResult`, waits synchronously on `AsyncWaitHandle` before returning.
- **`public void EndConnect(IAsyncResult ar)`**
Instantiates `_sliceDev = new WinUsbDevice()`, calls `_sliceDev.GetDeviceHandle(ConnectString)` and `_sliceDev.InitializeDevice()`. Sets `Connected = true` on success. Logs and throws `NotConnectedException` on failure.
- **`public IAsyncResult BeginSend(byte[] buffer, int offset, int size, AsyncCallback cb, object state)`**
Validates connection and buffer parameters. Returns `WinUSBRecAsyncResult`.
- **`public int EndSend(IAsyncResult ar)`**
Copies buffer data, then calls `_sliceDev.SendViaInterruptTransfer(...)` or `_sliceDev.SendViaBulkTransfer(...)` depending on `MyDevInfo.UseHybridBulkIntMode`. Throws on failure.
- **`public Task<int> SendAsync(...)`**
Wraps `BeginSend`/`EndSend`.
- **`public IAsyncResult BeginReceive(byte[] buffer, int offset, int size, AsyncCallback cb, object state)`**
Validates connection and buffer parameters. Returns `WinUSBRecAsyncResult`.
- **`public int EndReceive(IAsyncResult ar)`**
Calls `_sliceDev.ReadViaBulkTransfer(...)` in a loop until `bytesRead > 0` or failure. Copies data into `rar.Buffer`. Returns bytes read.
- **`public IAsyncResult BeginDisconnect(...)`**
Validates `_sliceDev != null`. Sets `Connected = false`, returns `WinUSBRecAsyncResult`.
- **`public void EndDisconnect(IAsyncResult ar)`**
Calls `DisposeSliceDev()` to release WinUSB handle.
- **`public void Dispose()` / `protected virtual void Dispose(bool)`**
Implements `IDisposable`. Disposes `_wusbDeviceManagement` and calls `DisposeSliceDev()`. Uses `Mutex _usbConnectionMutex` for thread safety.
- **`public void Bind(int port)` / `public void Listen(int backlog)` / `public IAsyncResult BeginAccept(...)` / `public IConnection EndAccept(...)`**
All throw `NotSupportedException`.
### `WinUsbDevice` (internal)
- **`internal const uint DEVICE_SPEED = 1`**
Used with `WinUsb_QueryDeviceInformation`.
- **`internal const byte USB_ENDPOINT_DIRECTION_MASK = 0x80`**
Mask to determine endpoint direction (IN/OUT).
- **`internal enum PolicyType`**
Defines WinUSB pipe policies: `ShortPacketTerminate`, `AutoClearStall`, `PipeTransferTimeout`, etc.
- **`internal enum USBDPipeTypes`**
Pipe types: `UsbdPipeTypeControl`, `UsbdPipeTypeIsochronous`, `UsbdPipeTypeBulk`, `UsbdPipeTypeInterrupt`.
- **`internal enum USBDeviceSpeeds`**
Device speeds: `UsbLowSpeed`, `UsbFullSpeed`, `UsbHighSpeed`.
- **`internal struct USBConfigurationDescriptor`**
P/Invoke struct for USB configuration descriptor.
- **`internal struct USBInterfaceDescriptor`**
P/Invoke struct for USB interface descriptor.
- **`internal struct WinUSBPipeInformation`**
P/Invoke struct for pipe info: `PipeTypes`, `PipeId`, `MaximumPacketSize`, `Interval`.
- **`internal struct WinUSBSetupPacket`**
P/Invoke struct for control transfer setup packet.
- **`internal static extern bool WinUsb_ControlTransfer(...)`**
Sends control transfers.
- **`internal static extern bool WinUsb_Initialize(...)`**
Initializes WinUSB interface handle.
- **`internal static extern bool WinUsb_Free(...)`**
Frees WinUSB interface handle.
- **`internal static extern bool WinUsb_QueryDeviceInformation(...)`**
Retrieves device info (e.g., speed) using `DEVICE_SPEED`.
- **`internal static extern bool WinUsb_QueryInterfaceSettings(...)`**
Queries interface settings.
- **`internal static extern bool WinUsb_QueryPipe(...)`**
Queries pipe info.
- **`internal static extern bool WinUsb_ReadPipe(...)`**
Reads from a pipe.
- **`internal static extern bool WinUsb_WritePipe(...)`**
Writes to a pipe.
- **`internal static extern bool WinUsb_SetPipePolicy(...)`**
Sets pipe policy (byte value).
**Alias**: `WinUsb_SetPipePolicy1` for `PIPE_TRANSFER_TIMEOUT` (uses `uint` value).
## 3. Invariants
- **`Connected` state**
- `CDCUSBConnection`: `_Connected` is `true` only when `_comPort.IsOpen == true`.
- `WINUSBConnection`: `Connected` is `true` only after `_sliceDev.GetDeviceHandle(...)` and `_sliceDev.InitializeDevice()` both succeed.
- **`ConnectString` usage**
- `CDCUSBConnection`: Used to match registry keys for COM port lookup.
- `WINUSBConnection`: Passed to `_sliceDev.GetDeviceHandle(...)` to locate device.
- **Thread safety**
- `WINUSBConnection` uses `_usbConnectionMutex` around `WinUsbDevice` disposal.
- `CDCUSBConnection.RegKeys` uses `KEY_LOCK` for lazy initialization.
- **Asynchronous pattern**
- `Begin*` methods queue work to `ThreadPool` via `NetCallbackFix`, which invokes the callback.
- `End*` methods perform actual I/O and signal `AsyncWaitHandle.Set()`.
- **No soft disconnect**
Both `CDCUSBConnection` and `WINUSBConnection` have no-op `SoftConnect`/`SoftDisconnect`.
- **No socket operations**
`Bind`, `Listen`, `BeginAccept`, `EndAccept` throw `NotSupportedException` in both classes.
## 4. Dependencies
### Imports / External Dependencies
- **Windows API**: `winusb.dll` (for `WINUSBConnection` via P/Invoke in `WinUsbDevice`).
- **.NET Framework**:
- `System.IO.Ports.SerialPort` (for `CDCUSBConnection`).
- `System.Threading`, `System.Threading.Tasks`, `System.Runtime.InteropServices`.
- `Microsoft.Win32.Registry` (for registry enumeration).
- **Internal DTS modules** (from namespace imports):
- `DTS.Common.DASResource` (string resources, e.g., `DASResource.Strings.*`).
- `DTS.Common.Interface.Connection` (`IConnection` interface).
- `DTS.Common.Utilities.Logging` (`APILogger`).
- `DTS.Common.USBFramework` (likely contains `DeviceManagement`).
- `DTS.Common.Classes.Connection` (likely contains `NotConnectedException`).
### Dependencies on Other Modules
- `WINUSBConnection` depends on `DeviceManagement` and `WinUsbDevice` (defined in same namespace).
- `CDCUSBConnection` depends on `DASResource.Strings` for exception messages.
### Dependencies *by* This Module
- `IConnection` interface (consumed by higher layers).
- `DeviceManagement` (used by `WINUSBConnection` for device lifecycle management).
## 5. Gotchas
- **`Create` recursion**
Both `CDCUSBConnection.Create(string)` and `WINUSBConnection.Create(string)` contain commented-out recursive calls (`//Create(connectString); - this is recursive!`). This suggests a historical bug or incomplete refactoring.
- **`BeginConnect` blocking in `WINUSBConnection`**
`WINUSBConnection.BeginConnect` calls `rar.AsyncWaitHandle.WaitOne()` *before returning*, making it effectively synchronous despite being an "Async" pattern. This violates the expected non-blocking behavior of `Begin*` methods.
- **`EndConnect` in `WINUSBConnection` throws if already connected**
`EndConnect` checks `if (_sliceDev != null || Connected)` and throws `NotConnectedException`, but `BeginConnect` already sets `Connected = false` *before* the async work. This is inconsistent and may cause confusion.
- **`EndReceive` busy-waits**
`CDCUSBConnection.EndReceive` and `WINUSBConnection.EndReceive` both use tight loops with `Thread.Sleep(1)` when no data is available. This can cause high CPU usage.
- **`WinUSB_SetPipePolicy` vs `WinUsb_SetPipePolicy1`**
Two separate P/Invoke declarations exist for `WinUsb_SetPipePolicy`, with `WinUsb_SetPipePolicy1` used *only* for `PIPE_TRANSFER_TIMEOUT` (which requires a `uint` instead of `byte`). This is error-prone and not enforced by the API.
- **`RegKeys` is static and lazily initialized**
`CDCUSBConnection.RegKeys` is a static property. If the registry changes after first access, the list will be stale until app restart.
- **No error propagation in `NetCallbackFix`**
Exceptions in `NetCallbackFix` are caught and logged, but the callback is still invoked. This may leave callers expecting an exception to be thrown in `End*`.
- **`IsSoftDisconnected` always false**
Both classes report `IsSoftDisconnected = false`, but the interface contract may expect it to reflect a real state. This could mislead callers.
- **`GetConnectionData()` returns `""`**
Both classes return empty strings. This may indicate incomplete implementation.
- **`Flags` property unused**
`System.Net.Sockets.SocketFlags Flags { get; set; }` is exposed but never used in either class.
- **`USB_ENDPOINT_DIRECTION_MASK` is internal**
While defined, it is not used in the provided source. May be used elsewhere in the codebase.

View File

@@ -0,0 +1,35 @@
---
source_files:
- Common/DTS.Common.IConnection/USBConnection/WINUSBConnection/Properties/AssemblyInfo.cs
generated_at: "2026-04-16T02:10:04.213580+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "8875c5ea92f3aea7"
---
# Properties
## 1. Purpose
This module is an assembly metadata definition for the `WINUSBConnection` component, part of the `DTS.Common.IConnection` namespace. It does not contain executable logic or implementation code; its sole purpose is to declare assembly-level attributes—such as title, version, and COM visibility settings—that identify and configure the compiled .NET assembly for deployment and interoperation. It serves as a static configuration layer for the WINUSB-based USB communication module within the larger device connectivity framework.
## 2. Public Interface
**No public types, functions, classes, or methods are defined in this file.**
This file (`AssemblyInfo.cs`) contains only assembly-level attributes and does not declare any runtime-visible members. All public APIs (e.g., connection handling, USB I/O) reside in other source files (e.g., `WINUSBConnection.cs`, `IConnection.cs`) not included here.
## 3. Invariants
- The assembly is **not visible to COM** (`ComVisible(false)`), meaning external COM clients cannot directly instantiate types from this assembly unless explicitly exposed via other mechanisms (e.g., COM-visible wrapper assemblies).
- The assembly version is strictly `1.06.0081` (both `AssemblyVersion` and `AssemblyFileVersion`), enforcing version consistency for binding and deployment.
- The GUID `F3C369E6-BFFB-41bc-B8E8-A31094CED447` is reserved for the type library ID (if exposed to COM in the future), and must remain unchanged to preserve type identity across builds.
## 4. Dependencies
- **No runtime dependencies** are declared in this file.
- **Build-time dependency**: Requires the .NET Framework (or .NET Standard/Core with compatible attributes) to process `System.Reflection`, `System.Runtime.CompilerServices`, and `System.Runtime.InteropServices`.
- **Logical dependency**: This assembly (`WINUSBConnection`) is part of the `DTS.Common.IConnection` hierarchy, implying it implements or references interfaces defined in `DTS.Common.IConnection` (e.g., `IConnection`), though those interfaces are not defined here.
## 5. Gotchas
- **Misleading file location**: The path `Common/DTS.Common.IConnection/USBConnection/WINUSBConnection/Properties/AssemblyInfo.cs` suggests this assembly contains WINUSB-specific logic, but this file *only* defines metadata—no actual USB communication code resides here. Developers must look elsewhere (e.g., `WINUSBConnection.cs`) for implementation.
- **Hardcoded version**: Version `1.06.0081` is fixed in source; automated versioning (e.g., via CI) would require modifying this file or overriding via build scripts.
- **COM visibility**: `ComVisible(false)` prevents accidental COM exposure, but if COM interop is needed, additional attributes (e.g., `[ComVisible(true)]` on specific types) must be added in *other* files—this file alone does not enable COM support.
- **No functional behavior**: This file cannot be tested for correctness beyond verifying attribute values; runtime behavior is entirely absent here.
None identified beyond the above.