12 KiB
source_files, generated_at, model, schema_version, sha256
| source_files | generated_at | model | schema_version | sha256 | |||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
|
2026-04-16T03:50:36.719547+00:00 | Qwen/Qwen3-Coder-Next-FP8 | 1 | 440f548bb3fa7458 |
DASFactory
Documentation Page: DASFactory Device Discovery and Handling Module
1. Purpose
This module implements device discovery and lifecycle management for multiple hardware interface types (UDP multicast, HID, WinUSB, CDCUSB, and Ethernet-based Ribeye) within the DAS (Data Acquisition System) factory framework. It enables background scanning for UDP-based devices via multicast, real-time detection of USB/HID device insertion/removal via Windows notifications, and structured connection/disconnection workflows for each device type. The module serves as the core infrastructure for dynamically managing connected DAS devices in the system, ensuring devices are correctly identified, validated, and integrated into the broader DAS ecosystem.
2. Public Interface
The module contains no public classes—all classes (AutoDiscovery, WinUSBHandling, CDCUSBHandling, RibeyeHandling, HIDHandling, WindowsNotification, DistributorSocket) are declared internal. Therefore, there is no public surface area exposed by this module.
However, the following internal classes and methods constitute the functional interface used by other internal modules (e.g., DASFactory):
AutoDiscovery
void StartMulticastAutoDiscovery()
Starts a background task that periodically polls for UDP devices via_dasFactory.AutoDiscoverMulticast(...). Uses aCancellationTokenfor cancellation. Ensures only one scan task runs at a time via_multicastLock.void StopMulticastAutoDiscovery()
Cancels the active scan task and waits for it to complete. Disposes and recreates theCancellationTokenSourceif previously cancelled.IDiscoveredDevice[] GetDiscoveredDevices()
Returns a snapshot (copy) of all discovered devices since the lastStartMulticastAutoDiscovery()call. Thread-safe via_multicastLock.
WinUSBHandling
- Inherits from
WindowsNotification. - Overrides
NotificationDeviceArrived,NotificationDeviceRemoved. public override void UpdateConnectedDevices()
Enumerates connected WinUSB devices, checks for duplicates, and connects new ones.public override void UpdateDisconnectedDevices()
Detects and disconnects devices that are no longer present.public override void UpdateDeviceSetups()
Setsthisas the handler for the associatedIDeviceSetup.
CDCUSBHandling
- Inherits from
WindowsNotification. - Overrides
NotificationDeviceArrived,NotificationDeviceRemoved. public override void UpdateConnectedDevices()
Enumerates CDCUSB devices (filtered by registry keys inGetListOfConnectedDevices()), checks for duplicates, and connects new ones.public override void UpdateDisconnectedDevices()
Detects and disconnects removed CDCUSB devices.public override void UpdateDeviceSetups()
Setsthisas the handler for the associatedIDeviceSetup.
RibeyeHandling
- Implements
IDeviceSetup. bool QueryInformation(ConnectedDevice dev)
Queries device metadata (serial number, LED count, firmware, supported modes/rates) via protocol commands (QueryArmAndTriggerStatus,QuerySerialNumber,QueryNumberOfLEDs). On failure, setsdev.InUpdateMode = true.ICommunication GetICommunication()/GetICommunication(ConnectedDevice dev)
ReturnsEthernetRibeyeinstances.IConnectedDevice GetIConnectedDevice(ICommunication comm)
WrapsEthernetRibeyeinConnectedEthernetRibeye.bool IsCorrectType(ConnectedDevice dev)
Returnstrueifdev.Dev is ConnectedEthernetRibeye.DASType GetDASType()→ETHERNET_RIBEYEGuid GetGuid()→Guid.Emptyint GetProductId()/string GetProductIdString()→0/string.Emptyvoid SetHandler(DeviceHandling handler)→ no-op.
WindowsNotification
- Abstract base class for device notification handlers.
- Constructor registers for Windows device notifications via
DeviceManagement.RegisterForDeviceNotifications(...). protected abstract void NotificationDeviceArrived(ref Message m)
Called on device arrival (viaNotificationWndProc).protected abstract void NotificationDeviceRemoved(ref Message m)
Called on device removal.protected virtual void NotificationWndProc(ref Message m)
FiltersWM_DEVICECHANGEmessages forDBT_DEVICEARRIVAL/DBT_DEVICEREMOVECOMPLETE, dispatching to abstract handlers.
DistributorSocket
public bool IsConnected()
Returnstrueif_sockis non-null and connected.public void Disconnect()
Shuts down and closes the socket, disposes resources.public bool ReadLine(ref string target, ref bool stopFlag)
Reads a line from_readerwith retry logic (up toMAX_CONSECUTIVE_READ_ERRORS = 2). Logs each message.public void SendAck()/SendNak()
Sends"ACK"or"NAK"over_writer, with logging and error handling.public bool KeepAliveEnabled()
Sends a keep-alive configuration string (<...>) to the remote endpoint and waits for a response. Sets_keepAliveEnabled = trueon success.public void Dispose()
Closes and disposes the socket.
3. Invariants
-
AutoDiscovery_scanTaskisnullor completed only when no scan is running._scanTaskis never started if already running (lock+ null/completed check)._discoveredDeviceslist is append-only: existing entries are never updated or removed during discovery; only new devices (by uniqueSerial) are added.ClearDiscoveredDevices()is called at the start of eachDiscoveryWorkiteration.- Cancellation token is not reusable; once cancelled, a new
CancellationTokenSourceis created.
-
WinUSBHandling,CDCUSBHandling,HIDHandling- Device path lists are deduplicated (case-insensitive) before use.
CheckForConnectedWinUSBDups()/CheckForConnectedCDCUSBDups()throw if duplicate device paths are detected.GetListOfConnectedDevices()returns a list of device paths; for CDCUSB, paths must contain at least one registry key fromCDCUSBConnection.RegKeys(case-insensitive substring match).ConnectWinUSBTimeout/ConnectCDCUSBTimeout/ConnectHIDTimeoutare set to60000,60000, and1000ms respectively.
-
RibeyeHandlingSamplerate2AAFilterDictis immutable and pre-populated with 9 sample rates (500–100000 Hz), each mapped tosampleRate / 5.0F.QueryInformationmay silently retryQueryArmAndTriggerStatuson first boot (CRC initialization issue).- Module serial numbers are derived as
<DAS serial>-<Index>; firmware versions default to"0000".
-
WindowsNotification- A hidden
NotificationFormis created and shown (then hidden) to receive Windows messages. - Device notification registration is mandatory; failure throws an exception.
RecipientHandleandDeviceNotifyHandleare initialized in the constructor.
- A hidden
-
DistributorSocket- TCP keep-alive is enabled and configured via
IOControlCode.KeepAliveValues. - Connection retry loop respects
slicedbCanConnect,whKillMe, and_bShutDownByNowflags. ReadLinefails ifstopFlagis true orMAX_CONSECUTIVE_READ_ERRORSis exceeded.
- TCP keep-alive is enabled and configured via
4. Dependencies
Internal Dependencies (from source):
DTS.Common.*namespaces:DTS.Common.Enums.DASFactory(DFConstantsAndEnums,MultiCastDeviceClasses)DTS.Common.Interface.DASFactory(IDASFactory,IDiscoveredDevice,IDeviceSetup)DTS.Common.DASResource,DTS.Common.DAS.Concepts,DTS.Common.ICommunication,DTS.Common.Utilities.Logging,DTS.Common.WINUSBConnection,DTS.Common.USBFramework
DTS.DASLib.*namespaces:DTS.DASLib.Command.*(e.g.,Ribeyecommands:QueryArmAndTriggerStatus,QuerySerialNumber,QueryNumberOfLEDs)DTS.DASLib.Connection.*,DTS.DASLib.Communication,DTS.DASLib.Service
- System namespaces:
System.Collections.Concurrent,System.Threading,System.Windows.Forms,System.Net.Sockets,System.Runtime.InteropServices
External Dependencies:
- Windows API (via
DeviceManagement,FileIODeclarations,HIDeclarations) for device enumeration and HID access. MyDeviceManagement.FindDeviceFromGuid(...)(fromDTS.Common.USBFramework) for device path enumeration.CDCUSBConnection.RegKeys(fromDTS.Common.WINUSBConnection) for CDCUSB path filtering.
Inferred Usage:
AutoDiscoveryis used byDASFactory(via_dasFactoryfield) to enable multicast discovery.WinUSBHandling,CDCUSBHandling,HIDHandling,RibeyeHandlingare instantiated and wired intoDASFactoryfor their respective device types.DistributorSocketis used for remote communication (e.g., with a "slice db" server), likely in distributed acquisition scenarios.
5. Gotchas
-
AutoDiscovery- Cancellation is not idempotent: once
tokenSource.Cancel()is called,tokenSourceis disposed and a new one is created. Reusing the same instance after cancellation is impossible. DiscoveryWorkalways clears_discoveredDevicesat the start of each loop iteration, meaning only devices discovered in the current scan cycle are retained (unlessStartMulticastAutoDiscoveryis called again).GetDiscoveredDevices()returns a copy (ToArray()), but the internal list is not versioned—concurrentUpdateDevicescalls may overwrite each other’s additions if not for the lock.
- Cancellation is not idempotent: once
-
WinUSBHandling,CDCUSBHandling,HIDHandling- Device path deduplication uses
string.IsNullOrEmpty(t)and case-insensitiveEquals, butGetAllHIDDevices()andGetListOfConnectedDevices()may returnnullon failure (not an empty list), which downstream code must handle. HIDHandling.ReadRegKeys()silently clearsRegKeyson exception; if registry access fails, no devices will match inNotificationDeviceArrived.- In
HIDHandling.NotificationDeviceArrived, ifRegKeysis empty (e.g., due to registry error), the device is ignored—even if it’s valid—untilReadRegKeys()is called again (e.g., on next arrival). WinUSBHandlingandCDCUSBHandlingboth callCheckForConnected...Dups()and throw if duplicates are found—this is a hard failure, not a warning.
- Device path deduplication uses
-
RibeyeHandlingQueryInformationmay fail silently on first boot (CRC issue), but only retries once. If the second attempt fails,QueryInformationreturnsfalseand setsdev.InUpdateMode = true.Samplerate2AAFilterDictis shared across all instances (static), but only 9 sample rates are supported. Using unsupported rates will cause aKeyNotFoundExceptionif accessed.GetGuid()returnsGuid.Empty, implying this device type may not use GUID-based enumeration (unlike WinUSB/CDCUSB/HID).
-
WindowsNotificationNotificationFormis created on the main thread; accessing it from other threads (e.g., inDispose) is unsafe and commented-out code warns about cross-thread violations.- Device notification registration failure throws immediately in the constructor—no fallback.
-
DistributorSocketKeepAliveEnabled()sends a configuration string but does not verify the remote response beyond reading a non-empty line. It does not parse<ACK>(commented out).ReadLinemay return an empty string ifstopFlagis set or errors exceed threshold—callers must check the return value.SLICE_DB_PORT = 8200is hardcoded; no configuration support.
-
General
- All timeout values (
ConnectWinUSBTimeout, etc.) are hardcoded in constructors and not configurable at runtime. - Logging uses
APILogger.LogString(...)andAPILogger.Log(...), but no structured error codes—debugging relies on log parsing. - No unit tests or validation for
IDeviceSetupimplementations beyond type checks (IsCorrectType).
- All timeout values (