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 DiscoveredDevices { get; } = new List(); 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(); 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> lines) { base.CommandToString(ref lines); lines.Add(new List { $"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 } }