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

8.7 KiB

source_files, generated_at, model, schema_version, sha256
source_files generated_at model schema_version sha256
Common/DTS.Common.IConnection/USBConnection/WINUSBConnection/WINUSBDeviceApi.cs
Common/DTS.Common.IConnection/USBConnection/WINUSBConnection/CDCUSBConnection.cs
Common/DTS.Common.IConnection/USBConnection/WINUSBConnection/WINUSBConnection.cs
2026-04-16T11:50:38.580755+00:00 zai-org/GLM-5-FP8 1 2043cd8e3c0f04ef

Documentation: DTS.Common.WINUSBConnection

1. Purpose

This module provides USB connectivity abstractions within the DTS.Common.WINUSBConnection namespace. It contains two concrete implementations of the IConnection interface: CDCUSBConnection, which wraps a standard System.IO.Ports.SerialPort for CDC (Communications Device Class) USB devices, and WINUSBConnection, which provides low-level communication via the native winusb.dll API for custom WinUSB devices. Additionally, it defines the internal P/Invoke signatures and data structures required to interact with the Windows WinUSB driver stack.

2. Public Interface

Class: CDCUSBConnection

Implements IConnection. Represents a USB device connection via a virtual COM port (CDC).

  • void Create(string connectString, string hostIPAddress)
    • Parses the connectString to match against registry keys in RegKeys. If a match is found, it retrieves the PortName from the registry (Device Parameters subkey) and configures the internal SerialPort instance.
  • IAsyncResult BeginConnect(AsyncCallback cb, object state)
    • Initiates an asynchronous connection. Queues the connection logic to the thread pool.
  • void EndConnect(IAsyncResult ar)
    • Completes the asynchronous connection. Configures the serial port (BaudRate, DataBits, etc.) and calls _comPort.Open(). Sets Connected to true.
  • IAsyncResult BeginSend(byte[] buffer, int offset, int size, AsyncCallback cb, object state)
    • Initiates an asynchronous send operation.
  • int EndSend(IAsyncResult ar)
    • Completes the send operation. Writes data to the internal _comPort using _comPort.Write.
  • Task<int> SendAsync(byte[] sendBuffer, int bufferStartOffset, int bufferSizeToSend)
    • Task-based asynchronous wrapper for BeginSend/EndSend.
  • IAsyncResult BeginReceive(byte[] buffer, int offset, int size, AsyncCallback cb, object state)
    • Initiates an asynchronous receive operation.
  • int EndReceive(IAsyncResult ar)
    • Completes the receive operation. Reads data from _comPort. Note: This method blocks in a loop (Thread.Sleep(1)) until at least one byte is read.
  • IAsyncResult BeginDisconnect(bool reuseSocket, AsyncCallback cb, Object state)
    • Initiates an asynchronous disconnect.
  • void EndDisconnect(IAsyncResult ar)
    • Completes the disconnect. Closes and disposes the internal _comPort.
  • Properties
    • bool Connected: Gets the current connection state.
    • string ConnectString: Returns the device pathname.
    • IList<string> RegKeys: Static property that lazily loads registry keys for the device from SYSTEM\CurrentControlSet\Enum\USB\.

Class: WINUSBConnection

Implements IConnection. Represents a USB device connection using the native WinUSB driver.

  • void Create(string connectString, string hostIPAddress)
    • Stores the connectString in the ConnectString property.
  • IAsyncResult BeginConnect(AsyncCallback cb, object state)
    • Initiates an asynchronous connection. Throws NotConnectedException if already connected.
  • void EndConnect(IAsyncResult ar)
    • Completes the connection. Instantiates a new WinUsbDevice, retrieves a device handle via GetDeviceHandle, and initializes the device via InitializeDevice. Uses a mutex (_usbConnectionMutex) to synchronize access.
  • IAsyncResult BeginSend(byte[] buffer, int offset, int size, AsyncCallback cb, object state)
    • Initiates an asynchronous send. Validates buffer parameters.
  • int EndSend(IAsyncResult ar)
    • Completes the send. Checks MyDevInfo.UseHybridBulkIntMode. If true, calls SendViaInterruptTransfer; otherwise, calls SendViaBulkTransfer.
  • Task<int> SendAsync(byte[] sendBuffer, int bufferStartOffset, int bufferSizeToSend)
    • Task-based asynchronous wrapper for BeginSend/EndSend.
  • IAsyncResult BeginReceive(byte[] buffer, int offset, int size, AsyncCallback cb, object state)
    • Initiates an asynchronous receive.
  • int EndReceive(IAsyncResult ar)
    • Completes the receive. Reads data via ReadViaBulkTransfer. Blocks in a loop (Thread.Sleep(1)) until bytes are read. Returns 0 if the connection fails or closes.
  • IAsyncResult BeginDisconnect(bool reuseSocket, AsyncCallback cb, Object state)
    • Initiates an asynchronous disconnect.
  • void EndDisconnect(IAsyncResult ar)
    • Completes the disconnect. Calls DisposeSliceDev to release the WinUSB handle.
  • Properties
    • bool Connected: Gets the current connection state.
    • string ConnectString: Gets the device pathname.

Internal Class: WinUsbDevice (Partial)

Defines P/Invoke signatures and structures for winusb.dll.

  • Structs: USBConfigurationDescriptor, USBInterfaceDescriptor, WinUSBPipeInformation, WinUSBSetupPacket.
  • Enums: PolicyType, USBDPipeTypes, USBDeviceSpeeds.
  • Methods: WinUsb_Initialize, WinUsb_Free, WinUsb_ControlTransfer, WinUsb_ReadPipe, WinUsb_WritePipe, WinUsb_QueryPipe, WinUsb_SetPipePolicy, etc.

3. Invariants

  • Registry Dependency (CDCUSBConnection): The CDCUSBConnection requires the device to be registered under SYSTEM\CurrentControlSet\Enum\USB\ with a Vendor ID of VID_1CB9 and Product ID of PID_001A. The Create method cannot resolve the port name if these registry keys are missing.
  • Thread Safety (WINUSBConnection): The WINUSBConnection.EndConnect and DisposeSliceDev methods rely on a named Mutex ("USBConnection") to prevent race conditions during device initialization and disposal.
  • Disposal State: Both connection classes track Disposed and Disposing flags. Methods generally do not proceed if Disposed is true.
  • APM Pattern: Both classes implement the Asynchronous Programming Model (APM) using internal IAsyncResult implementations (UsbRecAsyncResult and WinUSBRecAsyncResult). Callbacks are invoked via ThreadPool.QueueUserWorkItem.

4. Dependencies

Internal Dependencies

  • DTS.Common.Interface.Connection: Implements IConnection.
  • DTS.Common.DASResource: Uses localized strings for exception messages (e.g., Strings.CDCUSBConnection_BeginConnect_Err1).
  • DTS.Common.Utilities.Logging: Uses APILogger for logging exceptions and status messages.
  • DTS.Common.USBFramework: Uses DeviceManagement class (in WINUSBConnection).
  • DTS.Common.Classes.Connection: Uses NotConnectedException.

External Dependencies

  • System.IO.Ports: Used by CDCUSBConnection for SerialPort.
  • System.Runtime.InteropServices: Used for P/Invoke attributes.
  • Microsoft.Win32: Used for registry access (RegistryKey, SafeFileHandle).
  • winusb.dll: Native Windows DLL imported by WinUsbDevice.

5. Gotchas

  • Blocking Async Reads: The EndReceive methods in both CDCUSBConnection and WINUSBConnection contain while loops that sleep (Thread.Sleep(1)) if zero bytes are read. This effectively makes the "asynchronous" operation blocking and consumes a thread pool thread while waiting for data.
  • Recursive Comment: The Create(string connectString) method in both connection classes contains a commented-out line //Create(connectString); with a note "this is recursive!". This suggests a historical bug or confusion regarding method overloads.
  • Empty Soft Disconnect: SoftConnect and SoftDisconnect methods are implemented but empty. The comments explicitly state they do nothing because there is no soft disconnect option implemented.
  • Hardcoded Device IDs: CDCUSBConnection hardcodes DTS_VENDOR_ID (0x1CB9) and DTS_TSR2_CDCUSB_PRODUCT_ID_STR ("PID_001A"). It will not work with other USB devices.
  • Partial Class Source: WinUsbDevice is defined as internal sealed partial class. The logic for GetDeviceHandle, InitializeDevice, SendViaBulkTransfer, etc., is referenced in WINUSBConnection but is not present in the provided source files (likely in another file part of the partial class definition).
  • Hybrid Mode Logic: WINUSBConnection.EndSend switches between interrupt and bulk transfers based on a boolean UseHybridBulkIntMode located on a MyDevInfo object. The definition of MyDevInfo is not visible in the provided source.