Files
2026-04-17 14:55:32 -04:00

158 lines
9.5 KiB
Markdown

---
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-17T15:37:40.541814+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "ead3f24c8ac15de2"
---
# USB Connection Module Documentation
## 1. Purpose
This module provides USB connectivity for DTS hardware devices through two distinct implementations: `CDCUSBConnection` for CDC (Communications Device Class) USB devices that present as virtual serial ports, and `WINUSBConnection` for devices using the WinUSB driver for direct bulk/interrupt transfers. Both classes implement the `IConnection` interface, providing a unified async communication pattern (Begin/End and Task-based async) for sending and receiving data. The module also includes `WinUsbDevice` (partial class in `WINUSBDeviceApi.cs`) which provides low-level P/Invoke bindings to the Windows WinUSB API.
---
## 2. Public Interface
### CDCUSBConnection (CDCUSBConnection.cs)
A connection class for CDC USB devices that uses `System.IO.Ports.SerialPort` for communication.
**Properties:**
- `bool IsSoftDisconnected { get; }` - Returns whether the device is soft-disconnected (always `false` for this implementation).
- `bool Connected { get; }` - Returns the current connection state.
- `string ConnectString { get; }` - Returns the device pathname.
- `string PortName { get; set; }` - The serial port name (e.g., "COM3").
- `System.Net.Sockets.SocketFlags Flags { get; set; }` - Socket flags (purpose unclear from source).
- `static IList<string> RegKeys { get; }` - Registry keys for device discovery.
**Constants:**
- `const int DTS_VENDOR_ID = 0x1CB9`
- `const string DTS_VENDOR_ID_STR = "VID_1CB9"`
- `const string DTS_TSR2_CDCUSB_PRODUCT_ID_STR = "PID_001A"`
**Methods:**
- `void Create(string connectString, string hostIPAddress)` - Parses the connect string to extract the port name from registry.
- `IAsyncResult BeginConnect(AsyncCallback cb, object state)` - Begins an async connection attempt.
- `void EndConnect(IAsyncResult ar)` - Completes the connection; configures and opens the serial port with default settings (9600 baud, 8 data bits, no parity, one stop bit).
- `IAsyncResult BeginDisconnect(bool reuseSocket, AsyncCallback cb, Object state)` - Begins an async disconnect.
- `void EndDisconnect(IAsyncResult ar)` - Closes and disposes the serial port.
- `IAsyncResult BeginSend(byte[] buffer, int offset, int size, AsyncCallback cb, object state)` - Begins an async send operation.
- `int EndSend(IAsyncResult ar)` - Completes the send; writes data to the serial port.
- `Task<int> SendAsync(byte[] sendBuffer, int bufferStartOffset, int bufferSizeToSend)` - Task-based async send wrapper.
- `IAsyncResult BeginReceive(byte[] buffer, int offset, int size, AsyncCallback cb, object state)` - Begins an async receive operation.
- `int EndReceive(IAsyncResult ar)` - Completes the receive; blocks until data is available.
- `void Dispose()` - Disposes the connection.
- `void SoftConnect()` - No-op (empty body).
- `void SoftDisconnect()` - No-op (empty body).
- `double GetCurrentUploadRate()` - Returns `0D`.
- `double GetCurrentDownloadRate()` - Returns `0D`.
- `string GetConnectionData()` - Returns empty string.
**Events:**
- `event EventHandler OnDisconnected` - Event for disconnection notification (never raised in source).
**Not Supported:**
- `BeginAccept`, `EndAccept`, `Listen`, `Bind` - Throw `NotSupportedException`.
---
### WINUSBConnection (WINUSBConnection.cs)
A connection class for WinUSB devices using direct USB transfers via the WinUSB API.
**Properties:**
- `bool IsSoftDisconnected { get; }` - Returns whether the device is soft-disconnected (always `false` for this implementation).
- `bool Connected { get; }` - Returns the current connection state.
- `string ConnectString { get; }` - Returns the device connection string.
- `System.Net.Sockets.SocketFlags Flags { get; set; }` - Socket flags (purpose unclear from source).
**Methods:**
- `void Create(string connectString, string hostIPAddress)` - Stores the connect string.
- `IAsyncResult BeginConnect(AsyncCallback cb, object state)` - Begins an async connection; validates not already connected.
- `void EndConnect(IAsyncResult ar)` - Completes the connection; creates `WinUsbDevice` instance, gets device handle, and initializes device.
- `IAsyncResult BeginDisconnect(bool reuseSocket, AsyncCallback cb, Object state)` - Begins an async disconnect.
- `void EndDisconnect(IAsyncResult ar)` - Disposes the `WinUsbDevice` via `DisposeSliceDev()`.
- `IAsyncResult BeginSend(byte[] buffer, int offset, int size, AsyncCallback cb, object state)` - Begins an async send; validates connection and parameters.
- `int EndSend(IAsyncResult ar)` - Completes the send; uses `SendViaInterruptTransfer` or `SendViaBulkTransfer` based on `MyDevInfo.UseHybridBulkIntMode`.
- `Task<int> SendAsync(byte[] sendBuffer, int bufferStartOffset, int bufferSizeToSend)` - Task-based async send wrapper.
- `IAsyncResult BeginReceive(byte[] buffer, int offset, int size, AsyncCallback cb, object state)` - Begins an async receive.
- `int EndReceive(IAsyncResult ar)` - Completes the receive; uses `ReadViaBulkTransfer` with a polling loop.
- `void Dispose()` - Disposes the connection and device management resources.
- `void SoftConnect()` - No-op (empty body).
- `void SoftDisconnect()` - No-op (empty body).
- `double GetCurrentUploadRate()` - Returns `0D`.
- `double GetCurrentDownloadRate()` - Returns `0D`.
- `string GetConnectionData()` - Returns empty string.
**Events:**
- `event EventHandler OnDisconnected` - Event for disconnection notification (never raised in source).
**Not Supported:**
- `BeginAccept`, `EndAccept`, `Listen`, `Bind` - Throw `NotSupportedException`.
**Nested Classes:**
- `WinUSBRecAsyncResult` - Implements `IAsyncResult` with additional `Buffer`, `Offset`, `Size` properties.
---
### WinUsbDevice (WINUSBDeviceApi.cs) - Internal Partial Class
Low-level P/Invoke bindings to `winusb.dll`.
**Constants:**
- `const uint DEVICE_SPEED = 1`
- `const byte USB_ENDPOINT_DIRECTION_MASK = 0x80`
**Enums:**
- `PolicyType` - Pipe policy types: `ShortPacketTerminate`, `AutoClearStall`, `PipeTransferTimeout`, `IgnoreShortPackets`, `AllowPartialReads`, `AutoFlush`, `RawIO`.
- `USBDPipeTypes` - Pipe types: `UsbdPipeTypeControl`, `UsbdPipeTypeIsochronous`, `UsbdPipeTypeBulk`, `UsbdPipeTypeInterrupt`.
- `USBDeviceSpeeds` - Device speeds: `UsbLowSpeed = 1`, `UsbFullSpeed`, `UsbHighSpeed`.
**Structs:**
- `USBConfigurationDescriptor` - USB configuration descriptor with fields: `bLength`, `bDescriptorType`, `wTotalLength`, `bNumInterfaces`, `bConfigurationValue`, `iConfiguration`, `bmAttributes`, `MaxPower`.
- `USBInterfaceDescriptor` - USB interface descriptor with fields: `bLength`, `bDescriptorType`, `bInterfaceNumber`, `bAlternateSetting`, `bNumEndpoints`, `bInterfaceClass`, `bInterfaceSubClass`, `bInterfaceProtocol`, `iInterface`.
- `WinUSBPipeInformation` - Pipe information with fields: `PipeTypes`, `PipeId`, `MaximumPacketSize`, `Interval`.
- `WinUSBSetupPacket` - Setup packet for control transfers with fields: `RequestType`, `Request`, `Value`, `Index`, `Length`.
**P/Invoke Functions (all from `winusb.dll`):**
- `WinUsb_ControlTransfer(IntPtr interfaceHandle, WinUSBSetupPacket setupPacket, byte[] buffer, uint bufferLength, ref uint lengthTransferred, IntPtr overlapped)`
- `WinUsb_Free(IntPtr interfaceHandle)`
- `WinUsb_Initialize(SafeFileHandle deviceHandle, ref IntPtr interfaceHandle)`
- `WinUsb_QueryDeviceInformation(IntPtr interfaceHandle, uint informationType, ref uint bufferLength, ref byte buffer)`
- `WinUsb_QueryInterfaceSettings(IntPtr interfaceHandle, byte alternateInterfaceNumber, ref USBInterfaceDescriptor usbAltInterfaceDescriptor)`
- `WinUsb_QueryPipe(IntPtr interfaceHandle, byte alternateInterfaceNumber, byte pipeIndex, ref WinUSBPipeInformation pipeInformation)`
- `WinUsb_ReadPipe(IntPtr interfaceHandle, byte pipeId, byte[] buffer, uint bufferLength, ref uint lengthTransferred, IntPtr overlapped)`
- `WinUsb_SetPipePolicy(IntPtr interfaceHandle, byte pipeId, uint policyType, uint valueLength, ref byte Value)` - For byte policy values.
- `WinUsb_SetPipePolicy1(IntPtr interfaceHandle, byte pipeId, uint policyType, uint valueLength, ref uint Value)` - For `uint` policy values (alias for `WinUsb_SetPipePolicy`).
- `WinUsb_WritePipe(IntPtr interfaceHandle, Byte pipeId, byte[] buffer, uint bufferLength, ref uint lengthTransferred, IntPtr overlapped)`
---
### UsbRecAsyncResult (CDCUSBConnection.cs)
Helper class implementing `IAsyncResult` for async operations.
**Properties:**
- `object AsyncState { get; set; }`
- `WaitHandle AsyncWaitHandle { get; set; }`
- `bool CompletedSynchronously { get; set; }`
- `bool IsCompleted { get; set; }`
- `byte[] buffer { get; set; }`
- `int Offset { get; set; }`
- `int Size { get; set; }`
---
## 3. Invariants
1. **Connection State Consistency**: `_Connected`/`Connected` must be `false` when `_sliceDev`/`_comPort` is `null` or disposed.
2. **Single Connection**: `WINUSBConnection.BeginConnect` throws `NotConnectedException` if already connected (`_sliceDev != null || Connected`).
3. **Thread Safety**: `WINUSBConnection` uses a `Mutex` named `"USBConnection"` to protect device initialization and disposal operations.
4. **Dispose Guard**: Both connection classes use `Disposed` and `Disposing` flags to prevent double-disposal.
5. **Parameter Validation**: `BeginSend` and `BeginReceive` validate that `buffer` is not null/empty