Files
DP44/DataPRO/SLICECommands/MulticastCommands/MulticastAutoDiscover.cs
2026-04-17 14:55:32 -04:00

226 lines
8.6 KiB
C#

using System;
using System.Collections.Generic;
using System.Net;
using System.Text;
using DTS.DASLib.Command.Classes;
using DTS.Common.Utilities.Logging;
using DTS.Common.Enums.DASFactory;
using DTS.Common.Interface.DASFactory;
namespace DTS.DASLib.Command.SLICE.MulticastCommands
{
public class MulticastAutoDiscover : MulticastCommandBase
{
#region constants and enums
private const int COMMAND_PAYLOAD_SIZE = 63;
private const int RESPONSE_PAYLOAD_SIZE = 278;
#endregion
#region private/protected properties
protected override Commands Command => Commands.AutoDiscover;
protected override bool StopAfterFirstMessage => false;
private uint _deviceClass;
private byte _responseOption;
private IPAddress _address;
private int _port = (int)Ports.Response;
private byte _dhcpEnabled;
private string _ip;
private string _subnet;
private string _gateway;
private string _dns;
private byte _isConnected;
private string _connectedIp;
private ushort _id;
private string _serialNumber;
private string _location;
private string _version;
private string _buildId;
#endregion
#region public properties
public List<IDiscoveredDevice> DiscoveredDevices { get; } = new List<IDiscoveredDevice>();
public TextLogger Logger { get; set; }
public DFConstantsAndEnums.MultiCastDeviceClasses DeviceClass { set { _deviceClass = (uint)value; command.SetParameter(36, (int)_deviceClass); } }
public ResponseOptions ResponseOption { set { _responseOption = (byte)value; command.SetParameter(40, _responseOption); } }
public IPAddress Address { set { _address = value; SetMulticastConfig(); } }
#endregion
#region methods
private void SetMulticastConfig()
{
IPAddress.TryParse(MulticastReceiveAddress, out _address);
var config = $"{_address}:{ResponsePort}";
command.SetParameter(41, config);
}
protected override CommandReceiveAction WholePackage()
{
if (response.Status != DFConstantsAndEnums.CommandStatus.StatusNoError)
return CommandReceiveAction.StopReceiving;
response.GetParameter(HOST_MAC_ADDRESS_OFFSET, out ResponseHostMac);
//we want to accept the response - even if it was sent on a
//a different mac address ...
if (response.ParameterLength < RESPONSE_PAYLOAD_SIZE)
{
response.Status = DFConstantsAndEnums.CommandStatus.StatusAttributeInvalidLength;
return CommandReceiveAction.StopReceiving;
}
response.GetParameter(CLIENT_MAC_ADDRESS_OFFSET, out ResponseClientMac);
response.GetParameter(36, out _deviceClass);
response.GetParameter(40, out _dhcpEnabled);
response.GetParameter(41, out _ip);
response.GetParameter(57, out _subnet);
response.GetParameter(73, out _gateway);
response.GetParameter(89, out _dns);
response.GetParameter(105, out _id);
response.GetParameter(107, out _isConnected);
response.GetParameter(108, out _serialNumber);
response.GetParameter(118, out _location);
response.GetParameter(198, out _version);
response.GetParameter(230, out _buildId);
response.GetParameter(262, out _connectedIp);
var sb = new StringBuilder();
//String.Format("{0,-27}", s);
sb.AppendFormat("SerialNumber {0}\r\n", _serialNumber);
sb.AppendFormat("ResponseClientMac {0}\r\n", ResponseClientMac);
sb.AppendFormat("IP {0}\r\n", _ip);
sb.AppendFormat("Location {0}\r\n", _location);
sb.AppendFormat("Id {0}\r\n", _id);
sb.AppendFormat("Version {0}\r\n", _version);
sb.AppendFormat("BuildId {0}\r\n", _buildId);
Log(sb.ToString());
var slice = new DiscoveredDevice
{
Mac = ResponseClientMac.Replace('-', ':'),
DevClass = (DFConstantsAndEnums.MultiCastDeviceClasses)_deviceClass,
Dhcp = Convert.ToBoolean(_dhcpEnabled),
Ip = _ip,
Subnet = _subnet,
Gateway = _gateway,
Dns = _dns,
SystemId = _id,
Connected = Convert.ToBoolean(_isConnected)
};
try
{
if (slice.DevClass == DFConstantsAndEnums.MultiCastDeviceClasses.S6DB ||
slice.DevClass == DFConstantsAndEnums.MultiCastDeviceClasses.Slice6)
{
}
}
catch (Exception ex)
{
APILogger.Log(ex);
}
slice.ConnectedIp = _connectedIp;
if (string.Empty != _connectedIp)
{
try
{
IPAddress connectedAddress;
IPAddress.TryParse(_connectedIp, out connectedAddress);
var hostName = Dns.GetHostEntry(connectedAddress);
slice.ConnectedHost = hostName.HostName;
}
catch (Exception ex)
{
APILogger.Log(ex);
}
}
slice.Serial = _serialNumber;
slice.Location = _location;
slice.FirmwareVersion = _version;
slice.BuildId = _buildId;
DiscoveredDevices.Add(slice);
return CommandReceiveAction.StopReceiving;
}
// ReSharper disable once InconsistentNaming
private static ConnectedEthernetDevice[] ParseSSIData(string data, DFConstantsAndEnums.MultiCastDeviceClasses type)
{
var connections = new List<ConnectedEthernetDevice>();
var lines = data.Replace("\r", "").Split('\n');
foreach (var line in lines)
{
var columns = line.Split(',');
if (columns.Length < 4) { continue; }
if (!char.IsNumber(columns[0][0])) { continue; }
var port = int.Parse(columns[1]);
switch (type)
{
case DFConstantsAndEnums.MultiCastDeviceClasses.Slice6:
if (2 != port) { continue; }
break;
case DFConstantsAndEnums.MultiCastDeviceClasses.S6DB:
if (port > 4) { continue; }
break;
}
var macAddress = columns[3];
connections.Add(new ConnectedEthernetDevice(macAddress, port));
}
return connections.ToArray();
}
private void Log(string msg)
{
if (null == Logger) { return; }
Logger.LogMessage($"====={DateTime.Now.ToShortDateString()} {DateTime.Now.ToShortTimeString()}=====\r\n");
Logger.LogMessage(msg);
}
public override void CommandToString(ref List<List<string>> lines)
{
base.CommandToString(ref lines);
lines.Add(new List<string> { $"AutoDiscover: [{HostMac}] {_address} : {_port}" });
}
#endregion
#region constructors and initializers
public MulticastAutoDiscover()
: base(null)
{
Init();
}
public MulticastAutoDiscover(string macAddress)
: base(null)
{
Init(macAddress);
}
public MulticastAutoDiscover(int timeoutMillisec)
: base(null, timeoutMillisec)
{
Init();
}
public MulticastAutoDiscover(string macAddress, int timeoutMillisec)
: base(null, timeoutMillisec)
{
Init(macAddress);
}
public void Init(string macAddress = "")
{
command.Parameter = new byte[COMMAND_PAYLOAD_SIZE];
HostMac = string.IsNullOrEmpty(macAddress) ? GetMacAddress() : macAddress;
command.SetParameter(HOST_MAC_ADDRESS_OFFSET, HostMac);
DeviceClass = DFConstantsAndEnums.MultiCastDeviceClasses.Any;
ResponseOption = ResponseOptions.AlwaysRespond;
SetMulticastConfig();
}
#endregion
}
}