239 lines
8.9 KiB
C#
239 lines
8.9 KiB
C#
|
|
using DTS.Common.Interface.DASFactory;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using static DTS.Common.Enums.DASFactory.DFConstantsAndEnums;
|
|
|
|
namespace DTS.DASLib.Command.Classes
|
|
{
|
|
/// <summary>
|
|
/// DiscoveredDevice class is used by the multicast autodiscovery mechanism to describe response payload from devices
|
|
/// </summary>
|
|
public class DiscoveredDevice : IDiscoveredDevice, IComparable<DiscoveredDevice>
|
|
{
|
|
//Addresses are strings so SortableBindingList can be used unmodified
|
|
|
|
#region UDP payload properties
|
|
/// <summary>
|
|
/// Device Serial Number
|
|
/// </summary>
|
|
public string Serial { get; set; }
|
|
|
|
/// <summary>
|
|
/// Device type
|
|
/// </summary>
|
|
public MultiCastDeviceClasses DevClass { get; set; }
|
|
|
|
/// <summary>
|
|
/// Device Mac
|
|
/// </summary>
|
|
public string Mac { get; set; }
|
|
|
|
public IDiscoveredDevice Parent { get; set; }
|
|
|
|
public bool IsParent(IDiscoveredDevice possibleChild)
|
|
{
|
|
if (null == Connections)
|
|
{
|
|
return false;
|
|
}
|
|
var matches = from connection in Connections where connection.MACAddress == possibleChild.Mac select connection;
|
|
var connectedEthernetDevices = matches as ConnectedEthernetDevice[] ?? matches.ToArray();
|
|
if (!connectedEthernetDevices.Any()) { return false; }
|
|
//if it matches it's our DIRECT uplink/parent if it contains all of our children and no other children ON THIS PORT.
|
|
var port = connectedEthernetDevices[0].Port;
|
|
|
|
var childrenOnPort = from connection in Connections where connection.Port == port select connection;
|
|
|
|
return childrenOnPort.Count() == 1 + possibleChild.Connections.Length;
|
|
}
|
|
public int GetPort(IDiscoveredDevice device)
|
|
{
|
|
var matches = from connection in Connections where connection.MACAddress == device.Mac select connection;
|
|
var connectedEthernetDevices = matches as ConnectedEthernetDevice[] ?? matches.ToArray();
|
|
if (!connectedEthernetDevices.Any()) { return -1; }
|
|
return connectedEthernetDevices[0].Port;
|
|
}
|
|
private List<IDiscoveredDevice> _orderedList = null;
|
|
public int GetSlot(IDiscoveredDevice child, Dictionary<string, IDiscoveredDevice> lookup)
|
|
{
|
|
if (null == _orderedList)
|
|
{
|
|
_orderedList = new List<IDiscoveredDevice>();
|
|
foreach (var macAddress in Connections.Select(x => x.MACAddress))
|
|
{
|
|
if (!lookup.ContainsKey(macAddress)) continue;
|
|
var device = lookup[macAddress];
|
|
if (null == device) continue;
|
|
_orderedList.Add(device);
|
|
_orderedList.Sort(new DiscoveredChildrenSorter());
|
|
}
|
|
}
|
|
var slot = _orderedList.IndexOf(child);
|
|
return slot <= 0 ? 1 : 1 + slot;
|
|
}
|
|
public int GetSlotOnPort(IDiscoveredDevice child, Dictionary<string, IDiscoveredDevice> lookup)
|
|
{
|
|
var matches = from device in _orderedList where device.Port == child.Port select device;
|
|
var slotOnPort = matches.ToList().IndexOf(child);
|
|
return slotOnPort <= 0 ? 1 : 1 + slotOnPort;
|
|
}
|
|
/// <summary>
|
|
/// so what we want here is first alphabetic by ultimate parent, then
|
|
/// by slot within each parent
|
|
/// </summary>
|
|
/// <param name="other"></param>
|
|
/// <returns></returns>
|
|
public int CompareTo(DiscoveredDevice other)
|
|
{
|
|
var myUltimateParent = GetParent(this);
|
|
var otherUltimateParent = GetParent(other);
|
|
if (null == myUltimateParent && null == otherUltimateParent)
|
|
{
|
|
//both SLICE6dbs or both without a chain...
|
|
return String.Compare(Serial, other.Serial, StringComparison.Ordinal);
|
|
}
|
|
if (null == myUltimateParent)
|
|
{
|
|
if (otherUltimateParent == this)
|
|
{
|
|
return -1;
|
|
}
|
|
return string.Compare(Serial, otherUltimateParent.Serial, StringComparison.Ordinal);
|
|
}
|
|
if (null == otherUltimateParent)
|
|
{
|
|
if (myUltimateParent == other)
|
|
{
|
|
return 1;
|
|
}
|
|
return string.Compare(myUltimateParent.Serial, other.Serial, StringComparison.Ordinal);
|
|
}
|
|
//we both have parents, if they aren't the same, then use their serial numbers
|
|
if (myUltimateParent != otherUltimateParent)
|
|
{
|
|
return string.Compare(myUltimateParent.Serial, otherUltimateParent.Serial, StringComparison.Ordinal);
|
|
}
|
|
//same parent, first compare port
|
|
if (Port != other.Port) { return Port.CompareTo(other.Port); }
|
|
//on same port, then use slot
|
|
return PositionOnDistributor.CompareTo(other.PositionOnDistributor);
|
|
}
|
|
public static IDiscoveredDevice GetParent(IDiscoveredDevice device)
|
|
{
|
|
var target = device;
|
|
while (null != target.Parent) { target = target.Parent; }
|
|
|
|
return target != device ? target : null;
|
|
}
|
|
public class DiscoveredChildrenSorter : IComparer<IDiscoveredDevice>
|
|
{
|
|
int IComparer<IDiscoveredDevice>.Compare(IDiscoveredDevice x, IDiscoveredDevice y)
|
|
{
|
|
if (x == y) { return 0; }
|
|
if (null == x) { return -1; }
|
|
if (null == y) { return 1; }
|
|
return x.Port != y.Port ? x.Port.CompareTo(y.Port) : y.Connections.Length.CompareTo(x.Connections.Length);
|
|
}
|
|
}
|
|
public bool IsModule { get; set; }
|
|
|
|
/// <summary>
|
|
/// if I'm on a SLICE6DB, what port am I on
|
|
/// </summary>
|
|
public int Port { get; set; }
|
|
/// <summary>
|
|
/// starting at the first device in the chain on the first point, up until the last device on the last chain/port, where is this device
|
|
/// this is used to as we don't show SLICE6 devices when on a SLICE6Db, but we still need to know which devices is where for showing
|
|
/// the channels in the UI
|
|
/// </summary>
|
|
public int PositionOnDistributor { get; set; }
|
|
/// <summary>
|
|
/// where is this device in a chain of devices, only used for SLICE6 on a SLICE6Db right now
|
|
/// </summary>
|
|
public int PositionOnChain { get; set; }
|
|
/// <summary>
|
|
/// Is DHCP enabled
|
|
/// </summary>
|
|
public bool Dhcp { get; set; }
|
|
|
|
/// <summary>
|
|
/// Device IP
|
|
/// </summary>
|
|
public string Ip { get; set; }
|
|
|
|
/// <summary>
|
|
/// Device Subnet
|
|
/// </summary>
|
|
public string Subnet { get; set; }
|
|
|
|
/// <summary>
|
|
/// Device Gateway
|
|
/// </summary>
|
|
public string Gateway { get; set; }
|
|
|
|
/// <summary>
|
|
/// Device DNS Sever
|
|
/// </summary>
|
|
public string Dns { get; set; }
|
|
|
|
/// <summary>
|
|
/// Is Device connected to another host
|
|
/// </summary>
|
|
public bool Connected { get; set; }
|
|
|
|
/// <summary>
|
|
/// Host IP that device is connected to
|
|
/// </summary>
|
|
public string ConnectedIp { get; set; }
|
|
|
|
/// <summary>
|
|
/// Host Name Resolution that device is connected to
|
|
/// </summary>
|
|
public string ConnectedHost { get; set; }
|
|
|
|
/// <summary>
|
|
/// User entry for Distributor ID that device is connected to
|
|
/// </summary>
|
|
public ushort SystemId { get; set; }
|
|
|
|
/// <summary>
|
|
/// User entry for location of device
|
|
/// </summary>
|
|
public string Location { get; set; }
|
|
|
|
/// <summary>
|
|
/// Firmware version string
|
|
/// [Product Name]-[FW/BL]-[REL/DBG]-[Board #]-[FW Ver Name]
|
|
/// </summary>
|
|
public string FirmwareVersion { get; set; }
|
|
|
|
/// <summary>
|
|
/// Build Server number for the firmware
|
|
/// </summary>
|
|
public string BuildId { get; set; }
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
public IConnectedEthernetDevice[] Connections { get; set; }
|
|
|
|
public DiscoveredDevice()
|
|
{
|
|
Connections = new IConnectedEthernetDevice[0];
|
|
}
|
|
}
|
|
public class ConnectedEthernetDevice : IConnectedEthernetDevice
|
|
{
|
|
public string MACAddress { get; }
|
|
public int Port { get; }
|
|
|
|
public ConnectedEthernetDevice(string macAddress, int port) { MACAddress = macAddress; Port = port; }
|
|
|
|
public string SerialNumber { get; set; }
|
|
}
|
|
|
|
}
|