Files
DP44/enriched-qwen3-coder-next/DataPRO/SLICECommands/MulticastCommands.md
2026-04-17 14:55:32 -04:00

18 KiB
Raw Blame History

source_files, generated_at, model, schema_version, sha256
source_files generated_at model schema_version sha256
DataPRO/SLICECommands/MulticastCommands/MulticastIdentify.cs
DataPRO/SLICECommands/MulticastCommands/MulticastResetMcu.cs
DataPRO/SLICECommands/MulticastCommands/MACTableEntry.cs
DataPRO/SLICECommands/MulticastCommands/MulticastSetIPAddress.cs
DataPRO/SLICECommands/MulticastCommands/MulticastSetSubnetAddress.cs
DataPRO/SLICECommands/MulticastCommands/MulticastSetGatewayAddress.cs
DataPRO/SLICECommands/MulticastCommands/MulticastSetDhcp.cs
DataPRO/SLICECommands/MulticastCommands/MulticastSetDnsAddress.cs
DataPRO/SLICECommands/MulticastCommands/MulticastGetIpAddress.cs
DataPRO/SLICECommands/MulticastCommands/MulticastGetDnsAddress.cs
DataPRO/SLICECommands/MulticastCommands/MulticastGetSubnetAddress.cs
DataPRO/SLICECommands/MulticastCommands/MulticastGetDhcp.cs
DataPRO/SLICECommands/MulticastCommands/MulticastGetGatewayAddress.cs
DataPRO/SLICECommands/MulticastCommands/MulticastAutoDiscover.cs
DataPRO/SLICECommands/MulticastCommands/MulticastDiscoverSlice6.cs
DataPRO/SLICECommands/MulticastCommands/MulticastUDPQueryQATS.cs
DataPRO/SLICECommands/MulticastCommands/MulticastCommandBase.cs
2026-04-16T03:55:01.601441+00:00 Qwen/Qwen3-Coder-Next-FP8 1 0d6bca66954e7e76

Documentation: Multicast Command Module (DTS.DASLib.Command.SLICE.MulticastCommands)


1. Purpose

This module provides a set of multicast-based communication commands for interacting with SLICE-series hardware devices (e.g., Slice6, S6DB) over UDP. It enables discovery, configuration (IP, subnet, gateway, DNS, DHCP), diagnostics (MAC table retrieval), and status querying (e.g., QATS sensor data) via multicast messaging. All commands inherit from MulticastCommandBase, which abstracts low-level UDP multicast send/receive logic, packet parsing, and MAC address handling. The module serves as the primary interface for networked device management in the DAS (Data Acquisition System) framework.


2. Public Interface

Classes

MulticastCommandBase

Abstract base class for all multicast commands.

  • Constructors

    • MulticastCommandBase(ICommunication sock)
      Initializes base with a communication socket.
    • MulticastCommandBase(ICommunication sock, int timeoutMillisec)
      Initializes with socket and custom receive timeout.
  • Properties

    • protected abstract Commands Command { get; }
      Returns the command enum value (e.g., Commands.Identify).
    • public string HostMac { get; set; }
      MAC address of the sending host (used in command/response validation).
    • public string ClientMac { set; }
      MAC address of the target client device.
    • public int ReceiveTimeoutMs { get; set; } = 3000
      Timeout for receiving responses.
    • public IPAddress BindToAdapterIPAddress { get; set; } = IPAddress.Any
      Network adapter to bind to for sending/receiving.
  • Methods

    • public void BuildPacket()
      Computes CRCs on the command packet.
    • public void SendCommand()
      Sends the multicast command packet without waiting for responses.
    • public void StartListening()
      Starts a background thread to listen for multicast responses.
    • public void StopListening()
      Signals the listening thread to terminate.
    • public void MulticastExecute(CancellationToken ct, bool waitForResponse = true)
      Sends command and optionally waits for responses (uses StartListening internally if waitForResponse=true).
    • protected virtual bool StopAfterFirstMessage => true
      Controls whether to stop after first response (overridden in MulticastAutoDiscover, MulticastDiscoverSlice6, MulticastUdpQueryQATS).
    • protected virtual CommandReceiveAction WholePackage()
      Parses incoming response packet (overridden in derived classes).
    • public static string GetMacAddress()
      Returns first multicast-capable, active network interfaces MAC address.

MulticastIdentify

Command to trigger device identification (e.g., LED blink).

  • Constructors

    • MulticastIdentify(ICommunication sock)
    • MulticastIdentify(ICommunication sock, int timeoutMillisec)
  • Overrides

    • protected override Commands Command => Commands.Identify
    • public override void CommandToString(ref List<List<string>> lines)
      Appends "MAC: {CommandClientMac}" to output.

MulticastResetMcu

Command to reset the device MCU.

  • Constructors

    • MulticastResetMcu(ICommunication sock)
    • MulticastResetMcu(ICommunication sock, int timeoutMillisec)
  • Overrides

    • protected override Commands Command => Commands.ResetMcu
    • public override void CommandToString(ref List<List<string>> lines)
      Appends "MAC: {CommandClientMac}".

MulticastSetIpAddress

Command to set static IP address.

  • Constructors

    • MulticastSetIpAddress(ICommunication sock)
    • MulticastSetIpAddress(ICommunication sock, int timeoutMillisec)
  • Properties

    • public string Ip { set; }
      Sets IP address string (e.g., "192.168.1.100"); writes to parameter buffer.
  • Overrides

    • protected override Commands Command => Commands.SetIpAddress
    • public override void CommandToString(ref List<List<string>> lines)
      Appends "MAC: {CommandClientMac} IP: {_ip}".

MulticastSetSubnetAddress

Command to set subnet mask.

  • Constructors

    • MulticastSetSubnetAddress(ICommunication sock)
    • MulticastSetSubnetAddress(ICommunication sock, int timeoutMillisec)
  • Properties

    • public string Subnet { set; }
  • Overrides

    • protected override Commands Command => Commands.SetSubnetAddress
    • public override void CommandToString(ref List<List<string>> lines)
      Appends "MAC: {CommandClientMac} Subnet: {_subnet}".

MulticastSetGatewayAddress

Command to set gateway IP.

  • Constructors

    • MulticastSetGatewayAddress(ICommunication sock)
    • MulticastSetGatewayAddress(ICommunication sock, int timeoutMillisec)
  • Properties

    • public string Gateway { set; }
  • Overrides

    • protected override Commands Command => Commands.SetGatewayAddress
    • public override void CommandToString(ref List<List<string>> lines)
      Appends "MAC: {CommandClientMac} Gateway: {_gateway}".

MulticastSetDnsAddress

Command to set DNS server IP.

  • Constructors

    • MulticastSetDnsAddress(ICommunication sock)
    • MulticastSetDnsAddress(ICommunication sock, int timeoutMillisec)
  • Properties

    • public string Dns { set; }
  • Overrides

    • protected override Commands Command => Commands.SetDnsAddress
    • public override void CommandToString(ref List<List<string>> lines)
      Appends "MAC: {CommandClientMac} DNS: {_dns}".

MulticastSetDhcp

Command to enable/disable DHCP.

  • Constructors

    • MulticastSetDhcp(ICommunication sock)
    • MulticastSetDhcp(ICommunication sock, int timeoutMillisec)
  • Properties

    • public bool Dhcp { set; }
      Converts bool to byte (0/1) and writes to parameter buffer.
  • Overrides

    • protected override Commands Command => Commands.SetDhcp
    • public override void CommandToString(ref List<List<string>> lines)
      Appends "MAC: {CommandClientMac} DHCP: {_dhcp} ".

MulticastGetIpAddress

Command to retrieve device IP address.

  • Constructors

    • MulticastGetIpAddress(ICommunication sock)
    • MulticastGetIpAddress(ICommunication sock, int timeoutMillisec)
  • Properties

    • public string Ip => _ip
      Populated after WholePackage() processes response.
  • Overrides

    • protected override Commands Command => Commands.GetIpAddress
    • protected override CommandReceiveAction WholePackage()
      On success, extracts IP from response at offset DOUBLE_MAC_ADDR_SIZE.
    • public override void CommandToString(...) / ResponseToString(...)
      Appends MAC and (response) IP.

MulticastGetSubnetAddress

Command to retrieve subnet mask.

  • Constructors

    • MulticastGetSubnetAddress(ICommunication sock)
    • MulticastGetSubnetAddress(ICommunication sock, int timeoutMillisec)
  • Properties

    • public string Subnet => _subnet
  • Overrides

    • protected override Commands Command => Commands.GetSubnetAddress
    • protected override CommandReceiveAction WholePackage()
      Extracts subnet at offset FIRST_PARAMETER_OFFSET.

MulticastGetGatewayAddress

Command to retrieve gateway IP.

  • Constructors

    • MulticastGetGatewayAddress(ICommunication sock)
    • MulticastGetGatewayAddress(ICommunication sock, int timeoutMillisec)
  • Properties

    • public string Gateway => _gateway
  • Overrides

    • protected override Commands Command => Commands.GetGatewayAddress
    • protected override CommandReceiveAction WholePackage()
      Extracts gateway at offset FIRST_PARAMETER_OFFSET.

MulticastGetDnsAddress

Command to retrieve DNS IP.

  • Constructors

    • MulticastGetDnsAddress(ICommunication sock)
    • MulticastGetDnsAddress(ICommunication sock, int timeoutMillisec)
  • Properties

    • public string Dns => _dns
  • Overrides

    • protected override Commands Command => Commands.GetDnsAddress
    • protected override CommandReceiveAction WholePackage()
      Extracts DNS at offset FIRST_PARAMETER_OFFSET.

MulticastGetDhcp

Command to retrieve DHCP status.

  • Constructors

    • MulticastGetDhcp(ICommunication sock)
    • MulticastGetDhcp(ICommunication sock, int timeoutMillisec)
  • Properties

    • public bool Dhcp => Convert.ToBoolean(_dhcp)
      _dhcp is a byte (0/1).
  • Overrides

    • protected override Commands Command => Commands.GetDhcp
    • protected override CommandReceiveAction WholePackage()
      Extracts DHCP byte at FIRST_PARAMETER_OFFSET; returns early on error.
    • public override void CommandToString(...) uses ResponseClientMac (unlike others using CommandClientMac).

MulticastAutoDiscover

Command to discover devices on network via multicast.

  • Constructors

    • MulticastAutoDiscover()
    • MulticastAutoDiscover(string macAddress)
    • MulticastAutoDiscover(int timeoutMillisec)
    • MulticastAutoDiscover(string macAddress, int timeoutMillisec)
  • Properties

    • public List<IDiscoveredDevice> DiscoveredDevices { get; }
      Populated with discovered devices after execution.
    • public TextLogger Logger { get; set; }
    • public DFConstantsAndEnums.MultiCastDeviceClasses DeviceClass { set; }
    • public ResponseOptions ResponseOption { set; }
    • public IPAddress Address { set; }
      Sets multicast receive address/config.
  • Overrides

    • protected override Commands Command => Commands.AutoDiscover
    • protected override bool StopAfterFirstMessage => false
    • protected override CommandReceiveAction WholePackage()
      Parses response payload (278 bytes) into device fields (IP, MAC, serial, etc.); appends to DiscoveredDevices.
    • public override void CommandToString(...)
      Appends "AutoDiscover: [{HostMac}] {_address} : {_port}".

MulticastDiscoverSlice6

Command to retrieve MAC table entries from Slice6/S6DB devices.

  • Constructors

    • MulticastDiscoverSlice6(DeviceClasses deviceClass, string hostMac)
    • MulticastDiscoverSlice6(string hostMac, int timeoutMillisec)
  • Properties

    • public DeviceClasses DeviceClass { set; }
    • public ResponseOptions ResponseOption { set; }
    • public uint DesiredPort { set; }
      Bitmask for ports (e.g., 0x0F for ports 14).
    • public byte[] MACFilter { set; }
      MAC address filter (e.g., 00:19:9B:*:*:*).
    • public TextLogger Logger { get; set; }
    • public Dictionary<string, IDiscoveredDevice> MACAddressToDevice { get; set; }
    • public DiscoveredConnectedSlice[] ConnectedDevices => _connectedDevices.ToArray()
      Populated with MAC table entries per device.
  • Overrides

    • protected override Commands Command => Commands.GetMACTable
    • protected override bool StopAfterFirstMessage => false
    • protected override CommandReceiveAction WholePackage()
      Parses MAC table entries (12-byte records) into MACTableEntry objects; adds to _connectedDevices.
    • public static string MACAddressToString(IEnumerable<byte> mac)
      Converts MAC byte array to "XX:XX:XX:XX:XX:XX" string.

MulticastUdpQueryQATS

Command to query QATS (Quasi-Adaptive Time Series) sensor data from devices.

  • Constructors

    • MulticastUdpQueryQATS(ICommunication sock)
    • MulticastUdpQueryQATS(string macAddress)
    • MulticastUdpQueryQATS(int timeoutMillisec)
    • MulticastUdpQueryQATS(string macAddress, int timeoutMillisec)
  • Properties

    • public List<IUDPQATSEntry> QATSEntry { get; set; } = new List<IUDPQATSEntry>()
      Accumulates QATS entries until GetUDPQATs() clears them.
    • public DFConstantsAndEnums.MultiCastDeviceClasses DeviceClass { set; }
    • public ResponseOptions ResponseOption { set; }
    • public IPAddress Address { set; }
    • public int Port { set; }
  • Overrides

    • protected override Commands Command => Commands.UdpQueryQTAS
    • protected override bool StopAfterFirstMessage => false
    • protected override CommandReceiveAction WholePackage()
      Parses 215-byte response payload at offset 74 (QATS_OFFSET) into QATS fields (arm state, sample rate, tilt sensors, etc.); adds to QATSEntry (thread-safe via lock).
    • public IUDPQATSEntry[] GetUDPQATs()
      Returns and clears QATSEntry list.

3. Invariants

  • MAC Address Format: All MAC addresses are stored and transmitted as colon-separated hex strings (e.g., "AA:BB:CC:DD:EE:FF"). Internal parsing uses hyphen-separated strings (e.g., "AA-BB-CC-DD-EE-FF") from the protocol, converted via Replace('-', ':').
  • Command/Response Validation: MulticastCommandBase.WholePackage() validates that:
    • ResponseClientMac == CommandClientMac
    • ResponseHostMac == HostMac
    • Response status is StatusNoError.
  • Payload Sizes:
    • Command payload size is fixed per command (e.g., DOUBLE_MAC_ADDR_SIZE + IP_ADDR_SIZE for IP/subnet/gateway/DNS/DHCP commands).
    • Response payload size is fixed per command (e.g., 278 bytes for AutoDiscover, 215 for UdpQueryQTAS).
  • Multicast Addresses:
    • Command multicast group: "239.1.2.3" (configurable via MulticastAddress).
    • Response multicast group: "239.4.5.6" (configurable via MulticastReceiveAddress).
  • Port Numbers:
    • Command port: 8501 (Ports.Command).
    • Response port: 8503 (Ports.Response).
  • Timeout Handling: Default receive timeout is 3000 ms (DEFAULT_RECEIVE_TIMEOUT_MS). MulticastUdpQueryQATS overrides to 5000 ms.

4. Dependencies

Dependencies of this module:

  • DTS.Common.Interface.DASFactory.ICommunication
    Used for socket abstraction (though most commands instantiate UdpClient directly).
  • DTS.Common.Enums.DASFactory
    Defines enums: Commands, MultiCastDeviceClasses, ResponseOptions, CommandStatus.
  • DTS.Common.Utilities.Logging
    TextLogger, APILogger.
  • DTS.DASLib.Command.Classes
    Defines IDiscoveredDevice, ConnectedEthernetDevice, UDPQATSEntry, IUDPQATSEntry.
  • System.Net, System.Net.NetworkInformation
    For UdpClient, IPAddress, NetworkInterface, MulticastOption.

Dependencies on this module:

  • High-level discovery/configuration workflows (e.g., device setup tools).
  • MulticastAutoDiscover and MulticastDiscoverSlice6 are used for device enumeration.
  • MulticastUdpQueryQATS is used for real-time sensor data acquisition.

5. Gotchas

  • MAC Address Parsing Inconsistency:
    MulticastGetDhcp.CommandToString uses ResponseClientMac, while other CommandToString overrides use CommandClientMac. This may cause mismatched MACs if ClientMac is set but ResponseClientMac is not yet populated.
  • MulticastCommandBase.WholePackage() Default Behavior:
    The base implementation strictly validates CommandClientMac == ResponseClientMac. Derived classes (MulticastAutoDiscover, MulticastDiscoverSlice6, MulticastUdpQueryQATS) override this to accept responses from any client MAC (or validate only HostMac), but this is not obvious from the base class.
  • MulticastDiscoverSlice6 Port Filtering:
    ParseSSIData (not used in current MulticastDiscoverSlice6) filters ports based on device class (Slice6: port 2 only; S6DB: ports ≤4). This logic is unused in WholePackage()—MAC table parsing uses raw port values from the response.
  • Thread Safety in MulticastUdpQueryQATS:
    QATSEntry is accessed via lock(MyLock) in WholePackage() and GetUDPQATs(), but MyLock is private static, meaning all instances share the same lock. This may cause contention if multiple MulticastUdpQueryQATS instances run concurrently.
  • MulticastAutoDiscover Payload Parsing:
    Hardcoded offsets (e.g., 36, 41, 57) assume fixed-layout binary protocol. Changes to firmware response structure will break parsing silently.
  • MulticastSetDhcp Parameter Size:
    COMMAND_PAYLOAD_SIZE = DOUBLE_MAC_ADDR_SIZE + 1 implies a 1-byte DHCP flag, but command.SetParameter(FIRST_PARAMETER_OFFSET, _dhcp) writes a byte. Ensure SetParameter handles byte correctly (likely via implicit conversion to int or padding).
  • MulticastCommandBase.BindToAdapterIPAddress:
    Setting BindToAdapterIPAddress to IPAddress.Any may cause issues on multi-homed systems if the wrong interface is used for multicast traffic. No validation ensures the adapter is active/multicast-capable.
  • GetMacAddress() Limitation:
    Returns the first multicast-capable, active interface—may not be the desired interface for communication.