--- source_files: - DataPRO/DASFactory/DASFactory.AutoDiscovery.cs - DataPRO/DASFactory/DASFactory.WinUSB.cs - DataPRO/DASFactory/DASFactory.CDCUSB.cs - DataPRO/DASFactory/DASFactory.Ribeye.cs - DataPRO/DASFactory/DASFactory.WindowsNotification.cs - DataPRO/DASFactory/DistributorSocket.cs - DataPRO/DASFactory/DASFactory.HID.cs generated_at: "2026-04-17T15:46:31.124490+00:00" model: "zai-org/GLM-5-FP8" schema_version: 1 sha256: "292a1a9fc11d724e" --- # DASFactory Module Documentation ## 1. Purpose The DASFactory module provides device discovery, connection management, and communication handling for Data Acquisition System (DAS) hardware. It implements multiple transport protocols (HID, WinUSB, CDC USB, Ethernet, Multicast/UDP) to detect, connect to, and manage various DAS devices. The module serves as the hardware abstraction layer between the application and physical devices, handling Windows device notifications, background discovery tasks, and socket-based communication for remote distributors. --- ## 2. Public Interface ### AutoDiscovery (internal class) **Constructor:** - `AutoDiscovery(IDASFactory dasFactory)` — Initializes with a factory instance for device discovery. **Methods:** - `void StartMulticastAutoDiscovery()` — Starts a background task that periodically discovers UDP/multicast devices. Idempotent; no-op if already scanning. - `void StopMulticastAutoDiscovery()` — Stops the background discovery task via cancellation token and waits for task completion. - `IDiscoveredDevice[] GetDiscoveredDevices()` — Returns a snapshot of all discovered devices since discovery started. --- ### WinUSBHandling (internal class, extends WindowsNotification) **Constructor:** - `WinUSBHandling(DASFactory _factory, UpdateFinishedEventHandler _SerialUpdateFinished, IDeviceSetup _deviceHandler, BlockingCollection> queueActionPerDevice)` **Properties:** - `int ConnectWinUSBTimeout { get; set; }` — Timeout in milliseconds for WinUSB device connections. Default: 60000. **Methods:** - `override void UpdateConnectedDevices()` — Scans for and connects to new WinUSB devices. - `override void UpdateDisconnectedDevices()` — Handles disconnection of removed WinUSB devices. - `override void UpdateDeviceSetups()` — Sets the handler on the device handler. --- ### CDCUSBHandling (internal class, extends WindowsNotification) **Constructor:** - `CDCUSBHandling(DASFactory _factory, UpdateFinishedEventHandler _SerialUpdateFinished, IDeviceSetup _deviceHandler, BlockingCollection> queueActionPerDevice)` **Properties:** - `int ConnectCDCUSBTimeout { get; set; }` — Timeout in milliseconds for CDC USB device connections. Default: 60000. **Methods:** - `override void UpdateConnectedDevices()` — Scans for and connects to new CDC USB devices. - `override void UpdateDisconnectedDevices()` — Handles disconnection of removed CDC USB devices. - `override void UpdateDeviceSetups()` — Sets the handler on the device handler. --- ### RibeyeHandling (internal class, implements IDeviceSetup) **Constructor:** - `RibeyeHandling(bool _utilMode)` **Methods:** - `bool QueryInformation(ConnectedDevice dev)` — Queries a Ribeye device for serial number, LED count, module configuration, and DAS info. Returns `true` on success. - `ICommunication GetICommunication()` — Returns a new `EthernetRibeye` communication instance. - `ICommunication GetICommunication(ConnectedDevice dev)` — Extracts communication interface from a `ConnectedEthernetRibeye`. - `IConnectedDevice GetIConnectedDevice(ICommunication comm)` — Creates a `ConnectedEthernetRibeye` from an `EthernetRibeye` communication object. - `bool IsCorrectType(ConnectedDevice dev)` — Returns `true` if device is a `ConnectedEthernetRibeye`. - `DFConstantsAndEnums.DASType GetDASType()` — Returns `DFConstantsAndEnums.DASType.ETHERNET_RIBEYE`. - `Guid GetGuid()` — Returns `Guid.Empty`. - `int GetProductId()` — Returns 0. - `string GetProductIdString()` — Returns empty string. - `void SetHandler(DeviceHandling handler)` — No-op implementation. --- ### WindowsNotification (internal abstract class, extends DeviceHandling) **Constructor:** - `WindowsNotification(DASFactory _factory, UpdateFinishedEventHandler _SerialUpdateFinished, Guid _guid, BlockingCollection> queueActionPerDevice)` — Registers for Windows device notifications via a hidden form. **Methods:** - `void Dispose()` — Stops device notifications and cleans up resources. - `virtual void NotificationWndProc(ref Message m)` — Processes Windows messages for device arrival/removal. - `abstract void NotificationDeviceArrived(ref Message m)` — Must be implemented to handle device connection events. - `abstract void NotificationDeviceRemoved(ref Message m)` — Must be implemented to handle device disconnection events. --- ### DistributorSocket (public class, implements IDisposable) **Constructors:** - `DistributorSocket(string hostName, string hostIPAddress, ref bool slicedbCanConnect, ref ManualResetEvent slicedbCanConnectEvent, string logFolder, ManualResetEvent whKillMe)` — Creates and connects a socket to a remote distributor. - `DistributorSocket(Socket sock, string hostName, string logFolder)` — Wraps an existing connected socket. **Methods:** - `bool IsConnected()` — Returns `true` if socket exists and is connected. - `void Disconnect()` — Shuts down and closes the socket. - `bool ReadLine(ref string target, ref bool stopFlag)` — Reads a line from the socket with retry logic. Returns `false` on stop or max consecutive errors. - `void SendAck()` — Sends "ACK" acknowledgment over the socket. - `void SendNak()` — Sends "NAK" negative acknowledgment over the socket. - `bool KeepAliveEnabled()` — Negotiates keep-alive parameters with remote endpoint. Returns `true` on success. - `void Dispose()` — Cleans up socket resources. --- ### HIDHandling (internal class, extends WindowsNotification) **Constructor:** - `HIDHandling(DASFactory _factory, UpdateFinishedEventHandler _SerialUpdateFinished, IDeviceSetup _deviceHandler)` **Properties:** - `int ConnectHIDTimeout { get; set; }` — Timeout in milliseconds for HID device connections. Default: 1000. **Methods:** - `override void UpdateConnectedDevices()` — Handles disconnection of removed HID devices. - `override void UpdateDisconnectedDevices()` — Scans for and connects to new HID devices. --- ## 3. Invariants ### AutoDiscovery - `_scanTask` is either `null`, completed, or actively running—never in an indeterminate state. - `_multicastLock` must be held for any access to `_discoveredDevices`, `_scanTask`, or `tokenSource`. - `tokenSource` is replaced with a new instance after cancellation (no reset mechanism). - `DiscoveryWork` clears the device list at start and runs until cancellation is requested. ### WinUSBHandling / CDCUSBHandling - `ConnectWinUSBTimeout` / `ConnectCDCUSBTimeout` defaults to 60000ms. - `CheckForConnectedWinUSBDups()` / `CheckForConnectedCDCUSBDups()` throw if duplicate device paths are detected. - Device list filtering excludes null/empty paths and duplicates (case-insensitive). ### CDCUSBHandling - Only device paths containing a key from `CDCUSBConnection.RegKeys` (case-insensitive) are considered valid. ### RibeyeHandling - `QueryInformation` sets protocol version to 1 before querying. - First `QueryArmAndTriggerStatus` call may fail on boot; it is silently retried once. - If device is armed, serial number defaults to "Ribeye" and LED count to 18. - `Samplerate2AAFilterDict` maps specific sample rates to anti-aliasing filter frequencies (rate / 5.0). ### WindowsNotification - `NotificationWindow` is a hidden form used solely for receiving Windows messages. - `DeviceNotifyHandle` is non-zero after successful registration. - `NotificationWndProc` only processes `WM_DEVICECHANGE` messages with `DBT_DEVICEARRIVAL` or `DBT_DEVICEREMOVECOMPLETE` and `DBT_DEVTYP_DEVICEINTERFACE`. ### DistributorSocket - Port is always `SLICE_DB_PORT` (8200). - Maximum consecutive read errors before failure: `MAX_CONSECUTIVE_READ_ERRORS` (2). - Maximum log size: `MAX_LOG_SIZE_BYTES` (1024000). - Read/write timeout: 9000ms. - Keep-alive parameters use `DFConstantsAndEnums.LocalKeepAliveTimeOutMS` and `DFConstantsAndEnums.LocalKeepAliveRetryIntervalMS`. ### HIDHandling - Vendor ID is `DTS_VENDOR_ID` (value not shown in source). - Device filtering matches both VID and PID from `deviceHandler.GetProductID()`. - Registry keys are read from `SYSTEM\CurrentControlSet\Enum\HID\{VID}&{PID}`. --- ## 4. Dependencies ### External Dependencies (inferred from imports) - `DTS.Common.Enums.DASFactory` — Enumeration types including `DFConstantsAndEnums.MultiCastDeviceClasses`, `DFConstantsAndEnums.DASType`, `DFConstantsAndEnums.RecordingMode`, `DFConstantsAndEnums.ModuleType`. - `DTS.Common.Interface.DASFactory` — Interfaces including `IDASFactory`, `IDiscoveredDevice`, `IConnectedDevice`, `IDeviceSetup`, `ICommunication`, `IConnectedDAS`. - `DTS.Common.DASResource` — `Strings` resource class. - `DTS.Common.Utilities.Logging` — `APILogger` for logging. - `DTS.Common.WINUSBConnection` — `CDCUSBConnection.RegKeys`. - `DTS.Common.USBFramework` — `DeviceManagement`, `FileIODeclarations`, `DeviceManagementDeclarations`. - `DTS.DASLib.Command.Ribeye` — `QueryArmAndTriggerStatus`, `QuerySerialNumber`, `QueryNumberOfLEDs`. - `DTS.DASLib.Service` — `EthernetRibeye`, `ConnectedEthernetRibeye`. - `DTS.DASLib.Connection` — Connection-related types. - `DTS.DASLib.Communication` — Communication interfaces. - `System.Windows.Forms` — Windows message handling and forms. - `System.Net.Sockets` — Socket communication. - `System.Collections.Concurrent` — `BlockingCollection`. ### Internal Dependencies - `WinUSBHandling` and `CDCUSBHandling` depend on `WindowsNotification` (inheritance). - `HIDHandling` depends on `WindowsNotification` (inheritance). - `AutoDiscovery` depends on `IDASFactory.AutoDiscoverMulticast()`. - `RibeyeHandling` depends on `InfoResult`, `Communication_DASInfo` types (from `DTS.Common.DAS.Concepts` and `DTS.Common.ICommunication`). --- ## 5. Gotchas ### AutoDiscovery - **Blocking Wait on Stop**: `StopMulticastAutoDiscovery()` calls `_scanTask.Wait()` outside the lock, which could deadlock if the discovery work is blocked on the same lock. However, `DiscoveryWork` only holds the lock briefly during `UpdateDevices` and `ClearDiscoveredDevices`. - **No Device Removal**: Discovered devices are only added, never removed. The list grows until `ClearDiscoveredDevices()` is called at the start of a new discovery cycle. ### WinUSBHandling / CDCUSBHandling - **Duplicate Device Paths**: Windows may report the same device path multiple times. The code filters duplicates, but `CheckForConnectedWinUSBDups()` / `CheckForConnectedCDCUSBDups()` will throw an exception if duplicates persist after filtering. ### RibeyeHandling - **Silent Retry on Failure**: `QueryArmAndTriggerStatus` is retried once silently on failure. This is documented as a workaround for CRC initialization issues on first boot. - **Fallback Values When Armed**: If the device reports as armed, serial number and LED count are hardcoded to "Ribeye" and 18 respectively, which may be inaccurate. - **Empty GUID**: `GetGuid()` returns `Guid.Empty`, which may affect device notification registration if used elsewhere. ### WindowsNotification - **Commented-Out Dispose Code**: The `Dispose()` method contains commented-out code for closing `NotificationWindow` that was removed due to cross-thread access issues. The form may not be properly disposed. - **Hidden Form Required**: The implementation relies on a hidden Windows Form to receive device change messages. This requires a message pump (typically on the UI thread). ### DistributorSocket - **Blocking Constructor**: The constructor loops until connection succeeds or `whKillMe` is signaled, potentially blocking indefinitely. - **Keep-Alive Negotiation**: `KeepAliveEnabled()` blocks waiting for a response; if the remote end doesn't respond, this will hang. - **Logger Disabled**: Logger initialization is commented out in both constructors; `_logger` is null and logging is skipped. ### HIDHandling - **Registry Dependency**: Device detection depends on Windows registry keys under `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\HID\`. If registry access fails, the device list is empty. - **Large Commented-Out Block**: A significant portion of HID update logic is commented out (approximately 100 lines), suggesting incomplete refactoring or deprecated code paths.