14 KiB
source_files, generated_at, model, schema_version, sha256
| source_files | generated_at | model | schema_version | sha256 | |||
|---|---|---|---|---|---|---|---|
|
2026-04-16T02:09:52.794052+00:00 | Qwen/Qwen3-Coder-Next-FP8 | 1 | 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 (CDC–Communication 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 returnsfalse. 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()
Returns0.0. Upload rate is not tracked. -
public double GetCurrentDownloadRate()
Returns0.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_devicePathnamepassed toCreate. Used as a device identifier. -
public bool Connected { get; }
Returns_Connected, indicating whether the underlyingSerialPortis 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)
ParsesconnectStringto match a registry key inRegKeys, then reads the"PortName"value from the device’s registry"Device Parameters"subkey and assigns it toPortName. Sets_devicePathname = connectString. -
public IAsyncResult BeginConnect(AsyncCallback cb, object state)
Returns anIAsyncResult(UsbRecAsyncResult) and queues a callback viaThreadPool.QueueUserWorkItem. Does not perform the actual connection. -
public void EndConnect(IAsyncResult ar)
Opens theSerialPortusing configured_baudRate,_parity,_stopBits,DATA_BITS, andPortName. Sets_Connected = trueon success. -
public IAsyncResult BeginSend(byte[] buffer, int offset, int size, AsyncCallback cb, object state)
ReturnsUsbRecAsyncResultwith buffer metadata. Actual write occurs inEndSend. -
public int EndSend(IAsyncResult ar)
Writesbuffer(usingsizeandoffsetfromUsbRecAsyncResult) to_comPort.Write(...). Returnssize. -
public Task<int> SendAsync(...)
WrapsBeginSend/EndSendin aTask<int>. -
public IAsyncResult BeginReceive(byte[] buffer, int offset, int size, AsyncCallback cb, object state)
ReturnsUsbRecAsyncResultwith 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(...)
ReturnsUsbRecAsyncResult. Actual disconnect occurs inEndDisconnect. -
public void EndDisconnect(IAsyncResult ar)
Closes and disposes_comPort, sets_Connected = false. -
public void Dispose()/protected virtual void Dispose(bool)
ImplementsIDisposable. Closes_comPortif open, setsDisposed = true. -
public void Bind(int port)/public void Listen(int backlog)/public IAsyncResult BeginAccept(...)/public IConnection EndAccept(...)
All throwNotSupportedException.
WINUSBConnection
-
public bool IsSoftDisconnected { get; }
Always returnsfalse. Soft disconnect is not supported. -
public void SoftConnect()/public void SoftDisconnect()
No-op. -
public double GetCurrentUploadRate()/public double GetCurrentDownloadRate()
Return0.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 toCreate. -
public event EventHandler OnDisconnected
Event for disconnection notifications (currently unused). -
public void Create(string connectString, string hostIPAddress)
StoresconnectStringinConnectString. -
public IAsyncResult BeginConnect(AsyncCallback cb, object state)
Validates_sliceDev == null && !Connected. ReturnsWinUSBRecAsyncResult, waits synchronously onAsyncWaitHandlebefore returning. -
public void EndConnect(IAsyncResult ar)
Instantiates_sliceDev = new WinUsbDevice(), calls_sliceDev.GetDeviceHandle(ConnectString)and_sliceDev.InitializeDevice(). SetsConnected = trueon success. Logs and throwsNotConnectedExceptionon failure. -
public IAsyncResult BeginSend(byte[] buffer, int offset, int size, AsyncCallback cb, object state)
Validates connection and buffer parameters. ReturnsWinUSBRecAsyncResult. -
public int EndSend(IAsyncResult ar)
Copies buffer data, then calls_sliceDev.SendViaInterruptTransfer(...)or_sliceDev.SendViaBulkTransfer(...)depending onMyDevInfo.UseHybridBulkIntMode. Throws on failure. -
public Task<int> SendAsync(...)
WrapsBeginSend/EndSend. -
public IAsyncResult BeginReceive(byte[] buffer, int offset, int size, AsyncCallback cb, object state)
Validates connection and buffer parameters. ReturnsWinUSBRecAsyncResult. -
public int EndReceive(IAsyncResult ar)
Calls_sliceDev.ReadViaBulkTransfer(...)in a loop untilbytesRead > 0or failure. Copies data intorar.Buffer. Returns bytes read. -
public IAsyncResult BeginDisconnect(...)
Validates_sliceDev != null. SetsConnected = false, returnsWinUSBRecAsyncResult. -
public void EndDisconnect(IAsyncResult ar)
CallsDisposeSliceDev()to release WinUSB handle. -
public void Dispose()/protected virtual void Dispose(bool)
ImplementsIDisposable. Disposes_wusbDeviceManagementand callsDisposeSliceDev(). UsesMutex _usbConnectionMutexfor thread safety. -
public void Bind(int port)/public void Listen(int backlog)/public IAsyncResult BeginAccept(...)/public IConnection EndAccept(...)
All throwNotSupportedException.
WinUsbDevice (internal)
-
internal const uint DEVICE_SPEED = 1
Used withWinUsb_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) usingDEVICE_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_SetPipePolicy1forPIPE_TRANSFER_TIMEOUT(usesuintvalue).
3. Invariants
-
ConnectedstateCDCUSBConnection:_Connectedistrueonly when_comPort.IsOpen == true.WINUSBConnection:Connectedistrueonly after_sliceDev.GetDeviceHandle(...)and_sliceDev.InitializeDevice()both succeed.
-
ConnectStringusageCDCUSBConnection: Used to match registry keys for COM port lookup.WINUSBConnection: Passed to_sliceDev.GetDeviceHandle(...)to locate device.
-
Thread safety
WINUSBConnectionuses_usbConnectionMutexaroundWinUsbDevicedisposal.CDCUSBConnection.RegKeysusesKEY_LOCKfor lazy initialization.
-
Asynchronous pattern
Begin*methods queue work toThreadPoolviaNetCallbackFix, which invokes the callback.End*methods perform actual I/O and signalAsyncWaitHandle.Set().
-
No soft disconnect
BothCDCUSBConnectionandWINUSBConnectionhave no-opSoftConnect/SoftDisconnect. -
No socket operations
Bind,Listen,BeginAccept,EndAcceptthrowNotSupportedExceptionin both classes.
4. Dependencies
Imports / External Dependencies
- Windows API:
winusb.dll(forWINUSBConnectionvia P/Invoke inWinUsbDevice). - .NET Framework:
System.IO.Ports.SerialPort(forCDCUSBConnection).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(IConnectioninterface).DTS.Common.Utilities.Logging(APILogger).DTS.Common.USBFramework(likely containsDeviceManagement).DTS.Common.Classes.Connection(likely containsNotConnectedException).
Dependencies on Other Modules
WINUSBConnectiondepends onDeviceManagementandWinUsbDevice(defined in same namespace).CDCUSBConnectiondepends onDASResource.Stringsfor exception messages.
Dependencies by This Module
IConnectioninterface (consumed by higher layers).DeviceManagement(used byWINUSBConnectionfor device lifecycle management).
5. Gotchas
-
Createrecursion
BothCDCUSBConnection.Create(string)andWINUSBConnection.Create(string)contain commented-out recursive calls (//Create(connectString); - this is recursive!). This suggests a historical bug or incomplete refactoring. -
BeginConnectblocking inWINUSBConnection
WINUSBConnection.BeginConnectcallsrar.AsyncWaitHandle.WaitOne()before returning, making it effectively synchronous despite being an "Async" pattern. This violates the expected non-blocking behavior ofBegin*methods. -
EndConnectinWINUSBConnectionthrows if already connected
EndConnectchecksif (_sliceDev != null || Connected)and throwsNotConnectedException, butBeginConnectalready setsConnected = falsebefore the async work. This is inconsistent and may cause confusion. -
EndReceivebusy-waits
CDCUSBConnection.EndReceiveandWINUSBConnection.EndReceiveboth use tight loops withThread.Sleep(1)when no data is available. This can cause high CPU usage. -
WinUSB_SetPipePolicyvsWinUsb_SetPipePolicy1
Two separate P/Invoke declarations exist forWinUsb_SetPipePolicy, withWinUsb_SetPipePolicy1used only forPIPE_TRANSFER_TIMEOUT(which requires auintinstead ofbyte). This is error-prone and not enforced by the API. -
RegKeysis static and lazily initialized
CDCUSBConnection.RegKeysis a static property. If the registry changes after first access, the list will be stale until app restart. -
No error propagation in
NetCallbackFix
Exceptions inNetCallbackFixare caught and logged, but the callback is still invoked. This may leave callers expecting an exception to be thrown inEnd*. -
IsSoftDisconnectedalways false
Both classes reportIsSoftDisconnected = 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. -
Flagsproperty unused
System.Net.Sockets.SocketFlags Flags { get; set; }is exposed but never used in either class. -
USB_ENDPOINT_DIRECTION_MASKis internal
While defined, it is not used in the provided source. May be used elsewhere in the codebase.