init
This commit is contained in:
32
DataPRO/SLICECommands/MulticastCommands/MACTableEntry.cs
Normal file
32
DataPRO/SLICECommands/MulticastCommands/MACTableEntry.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
// ReSharper disable once InconsistentNaming
|
||||
namespace DTS.DASLib.Command.SLICE.MulticastCommands
|
||||
{
|
||||
public class MACTableEntry
|
||||
{
|
||||
public ushort Age { get; }
|
||||
public ushort Port { get; }
|
||||
public ushort Filter { get; }
|
||||
// ReSharper disable once InconsistentNaming
|
||||
public byte[] MAC { get; }
|
||||
|
||||
public MACTableEntry(ushort age, ushort port, ushort filter, byte[] mac)
|
||||
{
|
||||
Age = age;
|
||||
Port = port;
|
||||
Filter = filter;
|
||||
MAC = mac;
|
||||
}
|
||||
}
|
||||
|
||||
public class DiscoveredConnectedSlice
|
||||
{
|
||||
public string DeviceMAC { get; }
|
||||
public MACTableEntry[] ConnectedDevices { get; }
|
||||
|
||||
public DiscoveredConnectedSlice(string deviceMAC, MACTableEntry[] devices)
|
||||
{
|
||||
DeviceMAC = deviceMAC;
|
||||
ConnectedDevices = devices;
|
||||
}
|
||||
}
|
||||
}
|
||||
226
DataPRO/SLICECommands/MulticastCommands/MulticastAutoDiscover.cs
Normal file
226
DataPRO/SLICECommands/MulticastCommands/MulticastAutoDiscover.cs
Normal file
@@ -0,0 +1,226 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
328
DataPRO/SLICECommands/MulticastCommands/MulticastCommandBase.cs
Normal file
328
DataPRO/SLICECommands/MulticastCommands/MulticastCommandBase.cs
Normal file
@@ -0,0 +1,328 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using DTS.Common.Utils;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.MulticastCommands
|
||||
{
|
||||
public abstract class MulticastCommandBase : CommandBase
|
||||
{
|
||||
protected const int IP_ADDR_SIZE = 16;
|
||||
protected const int MAC_ADDR_SIZE = 18;
|
||||
protected const int DOUBLE_MAC_ADDR_SIZE = 2 * MAC_ADDR_SIZE;
|
||||
|
||||
protected const int HOST_MAC_ADDRESS_OFFSET = 0;
|
||||
protected const int CLIENT_MAC_ADDRESS_OFFSET = MAC_ADDR_SIZE;
|
||||
protected const int FIRST_PARAMETER_OFFSET = CLIENT_MAC_ADDRESS_OFFSET + MAC_ADDR_SIZE;
|
||||
protected const int DEFAULT_COMMAND_PAYLOAD_SIZE = DOUBLE_MAC_ADDR_SIZE;
|
||||
protected const int DEFAULT_RESPONSE_PAYLOAD_SIZE = DOUBLE_MAC_ADDR_SIZE;
|
||||
|
||||
protected enum Commands
|
||||
{
|
||||
Reserved = 0x00,
|
||||
AutoDiscover = 0x01,
|
||||
SetIpAddress = 0x02,
|
||||
GetIpAddress = 0x03,
|
||||
SetSubnetAddress = 0x04,
|
||||
GetSubnetAddress = 0x05,
|
||||
SetGatewayAddress = 0x06,
|
||||
GetGatewayAddress = 0x07,
|
||||
SetDnsAddress = 0x08,
|
||||
GetDnsAddress = 0x09,
|
||||
SetDhcp = 0x0A,
|
||||
GetDhcp = 0x0B,
|
||||
ResetMcu = 0x0C,
|
||||
WakeupBootloader = 0x0D,
|
||||
Identify = 0x0E,
|
||||
GetMACTable = 0x0F,
|
||||
GetMACTable_Reserved = 0x10, // created in FW but not being used. Just ignore this command for now.
|
||||
UdpQueryQTAS = 0x11, // query Arm-Trigger status via UDP multicast or unicast message via discovery route.
|
||||
UdpAutoQATS = 0x12, // message command ID for auto-arm self-start UDP multicast QATS
|
||||
UdpQATSInit = 0x13, // host command to send to DAS to start/stop UdpAutoQats message.
|
||||
UdpAutoTiltSensorData = 0x14, //Periodic UDP response when enabled by cmd ID 0x13
|
||||
UdpPrepareToShutdown = 0x15, //Command UUT to preserve auto-arm configuration and go to idle state ready for power down.
|
||||
}
|
||||
|
||||
public enum Ports
|
||||
{
|
||||
Command = 8501,
|
||||
Response = 8503,
|
||||
}
|
||||
|
||||
public enum DeviceClasses
|
||||
{
|
||||
Unknown = 0,
|
||||
Slice6 = 1 << 0,
|
||||
SDB = 1 << 1,
|
||||
ECM = 1 << 2,
|
||||
S6DB = 1 << 3,
|
||||
|
||||
Slice6Air = 1 << 4,
|
||||
PowerPro = 1 << 5,
|
||||
TsrAir = 1 << 6,
|
||||
S6DB3 = 1 << 7,
|
||||
Any = 0xFFFF,
|
||||
}
|
||||
|
||||
public enum ResponseOptions
|
||||
{
|
||||
AlwaysRespond = 0,
|
||||
RespondIfNotBusy = 1,
|
||||
RespondIfNotConnected = 2
|
||||
}
|
||||
|
||||
public static int DEFAULT_RECEIVE_TIMEOUT_MS = 3000;
|
||||
public const string DEFAULT_MULTICAST_ADDRESS = "239.1.2.3";
|
||||
public const string DEFAULT_RECEIVE_ADDRESS = "239.4.5.6";
|
||||
|
||||
public static string MulticastAddress = DEFAULT_MULTICAST_ADDRESS;
|
||||
public static string MulticastReceiveAddress = DEFAULT_RECEIVE_ADDRESS;
|
||||
|
||||
public static int CommandPort = (int)Ports.Command;
|
||||
public static int ResponsePort = (int)Ports.Response;
|
||||
|
||||
protected abstract Commands Command { get; }
|
||||
|
||||
protected MulticastCommandBase(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
command.Type = CommandPacket.CommandType.Multicast;
|
||||
command.SetCommand((byte)Command, Command.ToString());
|
||||
|
||||
command.Parameter = new byte[DEFAULT_COMMAND_PAYLOAD_SIZE];
|
||||
}
|
||||
|
||||
protected MulticastCommandBase(DTS.Common.Interface.DASFactory.ICommunication sock, int timeoutMillisec)
|
||||
: base(sock, timeoutMillisec)
|
||||
{
|
||||
command.Type = CommandPacket.CommandType.Multicast;
|
||||
command.SetCommand((byte)Command, Command.ToString());
|
||||
|
||||
command.Parameter = new byte[DEFAULT_COMMAND_PAYLOAD_SIZE];
|
||||
}
|
||||
|
||||
public void BuildPacket()
|
||||
{
|
||||
baseCommand.ComputeCRCs();
|
||||
}
|
||||
|
||||
protected virtual bool StopAfterFirstMessage => true;
|
||||
|
||||
public int ReceiveTimeoutMs { get; set; } = DEFAULT_RECEIVE_TIMEOUT_MS;
|
||||
|
||||
private string _commandHostMac;
|
||||
protected string CommandClientMac;
|
||||
protected string ResponseHostMac;
|
||||
protected string ResponseClientMac;
|
||||
|
||||
public string HostMac
|
||||
{
|
||||
get => _commandHostMac;
|
||||
set { _commandHostMac = value; command.SetParameter(HOST_MAC_ADDRESS_OFFSET, _commandHostMac); }
|
||||
}
|
||||
public string ClientMac { set { CommandClientMac = value; command.SetParameter(CLIENT_MAC_ADDRESS_OFFSET, CommandClientMac); } }
|
||||
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
if (response.Status != DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
response.GetParameter(HOST_MAC_ADDRESS_OFFSET, out ResponseHostMac);
|
||||
response.GetParameter(CLIENT_MAC_ADDRESS_OFFSET, out ResponseClientMac);
|
||||
|
||||
if (!CommandClientMac.Equals(ResponseClientMac) || !HostMac.Equals(ResponseHostMac))
|
||||
{
|
||||
response.Status = DFConstantsAndEnums.CommandStatus.StatusInvalidPacket;
|
||||
}
|
||||
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
public IPAddress BindToAdapterIPAddress { get; set; } = IPAddress.Any;
|
||||
private void SendRequest()
|
||||
{
|
||||
var txGroupAddress = IPAddress.Parse(MulticastAddress);
|
||||
var remoteEndPoint = new IPEndPoint(txGroupAddress, CommandPort);
|
||||
|
||||
UdpClient client = null;
|
||||
|
||||
if (BindToAdapterIPAddress == IPAddress.Any)
|
||||
{
|
||||
client = new UdpClient();
|
||||
}
|
||||
else
|
||||
{
|
||||
client = new UdpClient(new IPEndPoint(BindToAdapterIPAddress, CommandPort));
|
||||
}
|
||||
|
||||
client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
|
||||
client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.IpTimeToLive, 4);
|
||||
|
||||
command.SequenceNumber = 0;
|
||||
command.ComputeCRCs();
|
||||
var data = command.ToBytes();
|
||||
|
||||
client.Send(data, data.Length, remoteEndPoint);
|
||||
client.Close();
|
||||
}
|
||||
/// <summary>
|
||||
/// alternative to MulticastExecute,
|
||||
/// just sends the multicast request, relies on
|
||||
/// StartListening to have been called to process any incoming data
|
||||
/// </summary>
|
||||
public void SendCommand()
|
||||
{
|
||||
SendRequest();
|
||||
}
|
||||
/// <summary>
|
||||
/// used to signal Listen() function that it should terminate
|
||||
/// </summary>
|
||||
protected ManualResetEvent _stopListening = new ManualResetEvent(false);
|
||||
|
||||
/// <summary>
|
||||
/// starts a listening thread
|
||||
/// </summary>
|
||||
public void StartListening()
|
||||
{
|
||||
CancellationToken ct;
|
||||
Task.Run(() => ReceiveThread(null, true, ct)).ConfigureAwait(false);
|
||||
}
|
||||
/// <summary>
|
||||
/// stops any listening thread
|
||||
/// </summary>
|
||||
public void StopListening() => _stopListening.Set();
|
||||
public void MulticastExecute(CancellationToken ct, bool waitForResponse = true)
|
||||
{
|
||||
if (ct.IsCancellationRequested) { return; }
|
||||
//It's easier to kick off a worker thread to handle the receiver
|
||||
using (var signalComplete = new ManualResetEvent(true))
|
||||
{
|
||||
if (true == waitForResponse)
|
||||
{
|
||||
signalComplete.Reset();
|
||||
Task.Run(() => ReceiveThread(signalComplete, false, ct));
|
||||
|
||||
//Give it time to come up
|
||||
Thread.Sleep(100);
|
||||
}
|
||||
|
||||
//Send request once receive socket is set up
|
||||
SendRequest();
|
||||
WaitHandle.WaitAny(new[] { signalComplete, ct.WaitHandle });
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void ProcessResponse(byte[] data)
|
||||
{
|
||||
response = new CommandPacket(data);
|
||||
WholePackage();
|
||||
}
|
||||
private const int UDP_ASYNC_RESPONSETIME_MS = 1000;
|
||||
/// <summary>
|
||||
/// Listens for UDP responses. Can signal when complete and can listen until _stopListening MRE is set.
|
||||
/// </summary>
|
||||
/// <param name="signalComplete">This MRE is set when the process is complete</param>
|
||||
/// <param name="listenUntilStopped">This will cause the listening loop to continue untill stopped by the _stopListening MRE</param>
|
||||
private void ReceiveThread(ManualResetEvent signalComplete, bool listenUntilStopped, CancellationToken ct)
|
||||
{
|
||||
var rxGroupAddress = IPAddress.Parse(MulticastReceiveAddress);
|
||||
var endPoint = new IPEndPoint(BindToAdapterIPAddress, ResponsePort);
|
||||
var receiver = new UdpClient();
|
||||
|
||||
receiver.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
|
||||
receiver.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, ReceiveTimeoutMs);
|
||||
|
||||
_stopListening.Reset();
|
||||
|
||||
if (BindToAdapterIPAddress == IPAddress.Any) { receiver.ExclusiveAddressUse = false; }
|
||||
|
||||
try
|
||||
{
|
||||
receiver.Client.Bind(endPoint);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log(ex);
|
||||
if (!ct.IsCancellationRequested)
|
||||
{
|
||||
signalComplete?.Set();
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (ct.IsCancellationRequested) { return; }
|
||||
try
|
||||
{
|
||||
if (BindToAdapterIPAddress == IPAddress.Any)
|
||||
{
|
||||
receiver.JoinMulticastGroup(rxGroupAddress);
|
||||
}
|
||||
else
|
||||
{
|
||||
receiver.JoinMulticastGroup(rxGroupAddress, BindToAdapterIPAddress);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log(ex);
|
||||
}
|
||||
|
||||
var timeToWait = TimeSpan.FromMilliseconds(UDP_ASYNC_RESPONSETIME_MS);
|
||||
byte[] data = new byte[0];
|
||||
IAsyncResult asyncResult = null;
|
||||
do
|
||||
{
|
||||
if (BindToAdapterIPAddress != IPAddress.Any && !NetworkUtils.IsNetworkInterfaceUp(BindToAdapterIPAddress))
|
||||
{
|
||||
Thread.Sleep(100);
|
||||
continue;
|
||||
}
|
||||
asyncResult = receiver.BeginReceive(null, null);
|
||||
asyncResult.AsyncWaitHandle.WaitOne(timeToWait);
|
||||
|
||||
if (asyncResult.IsCompleted)
|
||||
{
|
||||
try
|
||||
{
|
||||
IPEndPoint remoteEP = null;
|
||||
|
||||
|
||||
data = receiver.EndReceive(asyncResult, ref remoteEP);
|
||||
// EndReceive worked and we have received data and remote endpoint
|
||||
System.Diagnostics.Debug.WriteLine("Got " + data.Length + " bytes from " + remoteEP);
|
||||
ProcessResponse(data);
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log(ex);
|
||||
}
|
||||
}
|
||||
} while (!_stopListening.WaitOne(0, false) && (asyncResult == null || asyncResult.IsCompleted) && !ct.IsCancellationRequested);
|
||||
receiver.Close();
|
||||
if (ct.IsCancellationRequested) { return; }
|
||||
if (null != signalComplete && !signalComplete.WaitOne(0))
|
||||
{
|
||||
signalComplete.Set();
|
||||
}
|
||||
}
|
||||
|
||||
//This is a little hokey. It returns the first interface that's multicast compatible AND 'up'. It may not actually be the interface
|
||||
//that we're interested in.
|
||||
public static string GetMacAddress()
|
||||
{
|
||||
var interfaces = NetworkInterface.GetAllNetworkInterfaces();
|
||||
foreach (var i in interfaces)
|
||||
{
|
||||
if (OperationalStatus.Up != i.OperationalStatus || !i.SupportsMulticast) continue;
|
||||
var address = BitConverter.ToString(i.GetPhysicalAddress().GetAddressBytes());
|
||||
address = address.Replace("-", ":");
|
||||
return address;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using DTS.DASLib.Command.Classes;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.MulticastCommands
|
||||
{
|
||||
/// <summary>
|
||||
/// 10558 Auto-discovery to add cmd/res support for MAC table
|
||||
/// </summary>
|
||||
public class MulticastDiscoverSlice6 : MulticastCommandBase
|
||||
{
|
||||
#region constants and enums
|
||||
private const int COMMAND_PAYLOAD_SIZE = 80;
|
||||
private const int DEVICE_CLASS_OFFSET = 36;
|
||||
private const int NUMBER_OF_RECORDS_OFFSET = 40;
|
||||
private const int RESERVED_OFFSET = 42;
|
||||
private const int START_OF_MAC_TABLE = 48;
|
||||
private const int SIZE_OF_MAC_RECORD = 12;//bytes
|
||||
private const int PORT_OFFSET = 2;
|
||||
private const int FILTER_OFFSET = 4;
|
||||
private const int MAC_OFFSET = 6;
|
||||
#endregion
|
||||
|
||||
#region private properties
|
||||
protected override Commands Command => Commands.GetMACTable;
|
||||
protected override bool StopAfterFirstMessage => false;
|
||||
|
||||
private uint _deviceClass;
|
||||
private byte _responseOption;
|
||||
private IPAddress _address;
|
||||
private const string RX_MULTICAST_ADDRESS = "239.4.5.6";
|
||||
private void SetMulticastConfig()
|
||||
{
|
||||
IPAddress.TryParse(RX_MULTICAST_ADDRESS, out _address);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region public properties
|
||||
|
||||
public DeviceClasses DeviceClass { set { _deviceClass = (uint)value; command.SetParameter(36, (int)_deviceClass); } }
|
||||
public ResponseOptions ResponseOption { set { _responseOption = (byte)value; command.SetParameter(40, _responseOption); } }
|
||||
|
||||
public uint DesiredPort
|
||||
{
|
||||
set => command.SetParameter(41, value);
|
||||
}
|
||||
|
||||
public byte[] MACFilter
|
||||
{
|
||||
set => command.SetParameter(45, value);
|
||||
}
|
||||
public TextLogger Logger { get; set; }
|
||||
public Dictionary<string, IDiscoveredDevice> MACAddressToDevice { get; set; }
|
||||
private readonly List<DiscoveredConnectedSlice> _connectedDevices = new List<DiscoveredConnectedSlice>();
|
||||
public DiscoveredConnectedSlice[] ConnectedDevices => _connectedDevices.ToArray();
|
||||
#endregion
|
||||
|
||||
#region constructors and initializers
|
||||
public MulticastDiscoverSlice6(DeviceClasses deviceClass, string hostMac)
|
||||
: base(null)
|
||||
{
|
||||
command.Parameter = new byte[COMMAND_PAYLOAD_SIZE];
|
||||
HostMac = hostMac;
|
||||
DeviceClass = deviceClass;
|
||||
ResponseOption = ResponseOptions.AlwaysRespond;
|
||||
SetMulticastConfig();
|
||||
DesiredPort = 1 << 0 | 1 << 1 | 1 << 2 | 1 << 3;
|
||||
|
||||
MACFilter = new[]
|
||||
{
|
||||
Convert.ToByte(0x00),
|
||||
Convert.ToByte(0x19),
|
||||
Convert.ToByte(0x9b),
|
||||
byte.MaxValue,
|
||||
byte.MaxValue,
|
||||
byte.MaxValue
|
||||
};
|
||||
}
|
||||
|
||||
public MulticastDiscoverSlice6(string hostMac, int timeoutMillisec)
|
||||
: base(null, timeoutMillisec)
|
||||
{
|
||||
command.Parameter = new byte[COMMAND_PAYLOAD_SIZE];
|
||||
HostMac = hostMac;
|
||||
DeviceClass = DeviceClasses.Any;
|
||||
ResponseOption = ResponseOptions.AlwaysRespond;
|
||||
SetMulticastConfig();
|
||||
DesiredPort = 1 << 0 | 1 << 1 | 1 << 2 | 1 << 3;//ports 1-4
|
||||
|
||||
MACFilter = new[]
|
||||
{
|
||||
Convert.ToByte(0x00),
|
||||
Convert.ToByte(0x19),
|
||||
Convert.ToByte(0x9b),
|
||||
byte.MaxValue,
|
||||
byte.MaxValue,
|
||||
byte.MaxValue
|
||||
};
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region methods
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
if (response.Status != DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
|
||||
response.GetParameter(HOST_MAC_ADDRESS_OFFSET, out ResponseHostMac);
|
||||
|
||||
if (null == ResponseHostMac || !HostMac.Equals(ResponseHostMac))
|
||||
{
|
||||
response.Status = DFConstantsAndEnums.CommandStatus.StatusInvalidPacket;
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
|
||||
response.GetParameter(CLIENT_MAC_ADDRESS_OFFSET, out ResponseClientMac);
|
||||
response.GetParameter(DEVICE_CLASS_OFFSET, out _deviceClass);
|
||||
ushort numberOfEntries;
|
||||
response.GetParameter(NUMBER_OF_RECORDS_OFFSET, out numberOfEntries);
|
||||
var list = new List<MACTableEntry>();
|
||||
for (var i = 0; i < numberOfEntries; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
response.GetParameter(START_OF_MAC_TABLE + i * SIZE_OF_MAC_RECORD, out ushort age);
|
||||
response.GetParameter(START_OF_MAC_TABLE + i * SIZE_OF_MAC_RECORD + PORT_OFFSET, out ushort port);
|
||||
response.GetParameter(START_OF_MAC_TABLE + i * SIZE_OF_MAC_RECORD + FILTER_OFFSET, out ushort filter);
|
||||
var mac = new byte[6];
|
||||
for (var b = 0; b < mac.Length; b++)
|
||||
{
|
||||
response.GetParameter(START_OF_MAC_TABLE + i * SIZE_OF_MAC_RECORD + MAC_OFFSET + b, out byte thisByte);
|
||||
mac[b] = thisByte;
|
||||
}
|
||||
list.Add(new MACTableEntry(age, port, filter, mac));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log($"MulticastDiscoverSlice6 failed to get entry - ignoring entry", ex.Message);
|
||||
}
|
||||
}
|
||||
_connectedDevices.Add(new DiscoveredConnectedSlice(ResponseClientMac, list.ToArray()));
|
||||
|
||||
var responseMac = ResponseClientMac.Replace('-', ':').ToUpper();
|
||||
|
||||
var serialNumber = "N/A";
|
||||
if (null != MACAddressToDevice && MACAddressToDevice.ContainsKey(responseMac))
|
||||
{
|
||||
serialNumber = MACAddressToDevice[responseMac].Serial;
|
||||
}
|
||||
Log(ResponseHostMac, ResponseClientMac, list.ToArray(), serialNumber);
|
||||
//Log(response.Parameter);
|
||||
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
|
||||
private static string ByteToHex(byte b)
|
||||
{
|
||||
return $"{b:x2}";
|
||||
}
|
||||
private void Log(IReadOnlyList<byte> parameter)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
|
||||
sb.Append("msg: ");
|
||||
foreach (var b in parameter)
|
||||
{
|
||||
sb.Append(ByteToHex(b));
|
||||
}
|
||||
sb.AppendLine();
|
||||
|
||||
//var bytes = new List<byte>(parameter);
|
||||
|
||||
sb.Append("header: ");
|
||||
for (var i = 0; i < START_OF_MAC_TABLE; i++)
|
||||
{
|
||||
sb.Append(ByteToHex(parameter[i]));
|
||||
}
|
||||
sb.AppendLine();
|
||||
|
||||
for (var i = START_OF_MAC_TABLE; i < parameter.Count; i += SIZE_OF_MAC_RECORD)
|
||||
{
|
||||
sb.Append("Record: ");
|
||||
for (var idx = 0; idx < SIZE_OF_MAC_RECORD; idx++)
|
||||
{
|
||||
sb.Append(ByteToHex(parameter[i + idx]));
|
||||
}
|
||||
sb.AppendLine();
|
||||
}
|
||||
|
||||
Log(sb.ToString());
|
||||
}
|
||||
private void Log(string responseHostMac, string responseClientMac, MACTableEntry[] entries, string serialNumber)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
|
||||
sb.AppendFormat("Host: {0}, Client: {1}, SerialNumber: {2}", responseHostMac, responseClientMac, serialNumber);
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("Age\tFilter\tMAC\t\t\tPort");
|
||||
foreach (var entry in entries)
|
||||
{
|
||||
sb.AppendFormat("{0}\t{1}\t{2}\t{3}", entry.Age, entry.Filter, MACAddressToString(entry.MAC), entry.Port);
|
||||
sb.AppendLine();
|
||||
}
|
||||
|
||||
Log(sb.ToString());
|
||||
}
|
||||
|
||||
public static string MACAddressToString(IEnumerable<byte> mac)
|
||||
{
|
||||
var list = mac.Select(b => $"{b:x2}").ToList();
|
||||
return string.Join(":", list.ToArray()).ToUpper();
|
||||
}
|
||||
public override void CommandToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.CommandToString(ref lines);
|
||||
lines.Add(new List<string> { $"AutoDiscover: [{HostMac}]" });
|
||||
}
|
||||
private void Log(string msg)
|
||||
{
|
||||
if (null == Logger) { return; }
|
||||
Logger.LogMessage($"====={DateTime.Now.ToShortDateString()} {DateTime.Now.ToShortTimeString()}=====\r\n");
|
||||
Logger.LogMessage(msg);
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
46
DataPRO/SLICECommands/MulticastCommands/MulticastGetDhcp.cs
Normal file
46
DataPRO/SLICECommands/MulticastCommands/MulticastGetDhcp.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.ICommunication;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.MulticastCommands
|
||||
{
|
||||
public class MulticastGetDhcp : MulticastCommandBase
|
||||
{
|
||||
protected override Commands Command => Commands.GetDhcp;
|
||||
|
||||
private byte _dhcp;
|
||||
public bool Dhcp => Convert.ToBoolean(_dhcp);
|
||||
|
||||
public MulticastGetDhcp(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
}
|
||||
|
||||
public MulticastGetDhcp(DTS.Common.Interface.DASFactory.ICommunication sock, int timeoutMillisec)
|
||||
: base(sock, timeoutMillisec)
|
||||
{
|
||||
}
|
||||
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
if (response.Status != DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
base.WholePackage();
|
||||
response.GetParameter(FIRST_PARAMETER_OFFSET, out _dhcp);
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
|
||||
public override void CommandToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.CommandToString(ref lines);
|
||||
lines.Add(new List<string> { $"MAC: {ResponseClientMac} " });
|
||||
}
|
||||
|
||||
public override void ResponseToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.ResponseToString(ref lines);
|
||||
lines.Add(new List<string> { $"MAC: {ResponseClientMac} Dhcp: {_dhcp}" });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using System.Collections.Generic;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.ICommunication;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.MulticastCommands
|
||||
{
|
||||
public class MulticastGetDnsAddress : MulticastCommandBase
|
||||
{
|
||||
protected override Commands Command => Commands.GetDnsAddress;
|
||||
|
||||
private string _dns;
|
||||
public string Dns => _dns;
|
||||
|
||||
public MulticastGetDnsAddress(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
}
|
||||
|
||||
public MulticastGetDnsAddress(DTS.Common.Interface.DASFactory.ICommunication sock, int timeoutMillisec)
|
||||
: base(sock, timeoutMillisec)
|
||||
{
|
||||
}
|
||||
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
if (response.Status == DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
base.WholePackage();
|
||||
response.GetParameter(FIRST_PARAMETER_OFFSET, out _dns);
|
||||
}
|
||||
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
|
||||
public override void CommandToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.CommandToString(ref lines);
|
||||
lines.Add(new List<string> { $"MAC: {CommandClientMac} " });
|
||||
}
|
||||
|
||||
public override void ResponseToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.ResponseToString(ref lines);
|
||||
lines.Add(new List<string> { $"MAC: {CommandClientMac} Dns: {_dns}" });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using System.Collections.Generic;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.ICommunication;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.MulticastCommands
|
||||
{
|
||||
public class MulticastGetGatewayAddress : MulticastCommandBase
|
||||
{
|
||||
protected override Commands Command => Commands.GetGatewayAddress;
|
||||
|
||||
private string _gateway;
|
||||
public string Gateway => _gateway;
|
||||
|
||||
public MulticastGetGatewayAddress(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
}
|
||||
|
||||
public MulticastGetGatewayAddress(DTS.Common.Interface.DASFactory.ICommunication sock, int timeoutMillisec)
|
||||
: base(sock, timeoutMillisec)
|
||||
{
|
||||
}
|
||||
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
if (response.Status == DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
base.WholePackage();
|
||||
response.GetParameter(FIRST_PARAMETER_OFFSET, out _gateway);
|
||||
}
|
||||
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
|
||||
public override void CommandToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.CommandToString(ref lines);
|
||||
lines.Add(new List<string> { $"MAC: {CommandClientMac} " });
|
||||
}
|
||||
|
||||
public override void ResponseToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.ResponseToString(ref lines);
|
||||
lines.Add(new List<string> { $"MAC: {CommandClientMac} Gateway: {_gateway}" });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using System.Collections.Generic;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.ICommunication;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.MulticastCommands
|
||||
{
|
||||
public class MulticastGetIpAddress : MulticastCommandBase
|
||||
{
|
||||
protected override Commands Command => Commands.GetIpAddress;
|
||||
|
||||
private string _ip;
|
||||
public string Ip => _ip;
|
||||
|
||||
public MulticastGetIpAddress(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
}
|
||||
|
||||
public MulticastGetIpAddress(DTS.Common.Interface.DASFactory.ICommunication sock, int timeoutMillisec)
|
||||
: base(sock, timeoutMillisec)
|
||||
{
|
||||
}
|
||||
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
if (response.Status == DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
base.WholePackage();
|
||||
response.GetParameter(DOUBLE_MAC_ADDR_SIZE, out _ip);
|
||||
}
|
||||
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
|
||||
public override void CommandToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.CommandToString(ref lines);
|
||||
lines.Add(new List<string> { $"MAC: {CommandClientMac} " });
|
||||
}
|
||||
|
||||
public override void ResponseToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.ResponseToString(ref lines);
|
||||
lines.Add(new List<string> { $"MAC: {CommandClientMac} IP: {_ip}" });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using System.Collections.Generic;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.ICommunication;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.MulticastCommands
|
||||
{
|
||||
public class MulticastGetSubnetAddress : MulticastCommandBase
|
||||
{
|
||||
protected override Commands Command => Commands.GetSubnetAddress;
|
||||
|
||||
private string _subnet;
|
||||
public string Subnet => _subnet;
|
||||
|
||||
public MulticastGetSubnetAddress(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
}
|
||||
|
||||
public MulticastGetSubnetAddress(DTS.Common.Interface.DASFactory.ICommunication sock, int timeoutMillisec)
|
||||
: base(sock, timeoutMillisec)
|
||||
{
|
||||
}
|
||||
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
if (response.Status == DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
base.WholePackage();
|
||||
response.GetParameter(FIRST_PARAMETER_OFFSET, out _subnet);
|
||||
}
|
||||
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
|
||||
public override void CommandToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.CommandToString(ref lines);
|
||||
lines.Add(new List<string> { $"MAC: {CommandClientMac} " });
|
||||
}
|
||||
|
||||
public override void ResponseToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.ResponseToString(ref lines);
|
||||
lines.Add(new List<string> { $"MAC: {CommandClientMac} Subnet: {_subnet}" });
|
||||
}
|
||||
}
|
||||
}
|
||||
26
DataPRO/SLICECommands/MulticastCommands/MulticastIdentify.cs
Normal file
26
DataPRO/SLICECommands/MulticastCommands/MulticastIdentify.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using System.Collections.Generic;
|
||||
using DTS.Common.ICommunication;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.MulticastCommands
|
||||
{
|
||||
public class MulticastIdentify : MulticastCommandBase
|
||||
{
|
||||
protected override Commands Command => Commands.Identify;
|
||||
|
||||
public MulticastIdentify(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
}
|
||||
|
||||
public MulticastIdentify(DTS.Common.Interface.DASFactory.ICommunication sock, int timeoutMillisec)
|
||||
: base(sock, timeoutMillisec)
|
||||
{
|
||||
}
|
||||
|
||||
public override void CommandToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.CommandToString(ref lines);
|
||||
lines.Add(new List<string> { $"MAC: {CommandClientMac}" });
|
||||
}
|
||||
}
|
||||
}
|
||||
26
DataPRO/SLICECommands/MulticastCommands/MulticastResetMcu.cs
Normal file
26
DataPRO/SLICECommands/MulticastCommands/MulticastResetMcu.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using System.Collections.Generic;
|
||||
using DTS.Common.ICommunication;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.MulticastCommands
|
||||
{
|
||||
public class MulticastResetMcu : MulticastCommandBase
|
||||
{
|
||||
protected override Commands Command => Commands.ResetMcu;
|
||||
|
||||
public MulticastResetMcu(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
}
|
||||
|
||||
public MulticastResetMcu(DTS.Common.Interface.DASFactory.ICommunication sock, int timeoutMillisec)
|
||||
: base(sock, timeoutMillisec)
|
||||
{
|
||||
}
|
||||
|
||||
public override void CommandToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.CommandToString(ref lines);
|
||||
lines.Add(new List<string> { $"MAC: {CommandClientMac}" });
|
||||
}
|
||||
}
|
||||
}
|
||||
42
DataPRO/SLICECommands/MulticastCommands/MulticastSetDhcp.cs
Normal file
42
DataPRO/SLICECommands/MulticastCommands/MulticastSetDhcp.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using DTS.Common.ICommunication;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.MulticastCommands
|
||||
{
|
||||
public class MulticastSetDhcp : MulticastCommandBase
|
||||
{
|
||||
const int COMMAND_PAYLOAD_SIZE = DOUBLE_MAC_ADDR_SIZE + 1;
|
||||
|
||||
protected override Commands Command => Commands.SetDhcp;
|
||||
|
||||
private byte _dhcp;
|
||||
|
||||
public bool Dhcp
|
||||
{
|
||||
set
|
||||
{
|
||||
_dhcp = Convert.ToByte(value);
|
||||
command.SetParameter(FIRST_PARAMETER_OFFSET, _dhcp);
|
||||
}
|
||||
}
|
||||
|
||||
public MulticastSetDhcp(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
command.Parameter = new byte[COMMAND_PAYLOAD_SIZE];
|
||||
}
|
||||
|
||||
public MulticastSetDhcp(DTS.Common.Interface.DASFactory.ICommunication sock, int timeoutMillisec)
|
||||
: base(sock, timeoutMillisec)
|
||||
{
|
||||
command.Parameter = new byte[COMMAND_PAYLOAD_SIZE];
|
||||
}
|
||||
|
||||
public override void CommandToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.CommandToString(ref lines);
|
||||
lines.Add(new List<string> { $"MAC: {CommandClientMac} DHCP: {_dhcp} " });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using System.Collections.Generic;
|
||||
using DTS.Common.ICommunication;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.MulticastCommands
|
||||
{
|
||||
public class MulticastSetDnsAddress : MulticastCommandBase
|
||||
{
|
||||
private const int COMMAND_PAYLOAD_SIZE = DOUBLE_MAC_ADDR_SIZE + IP_ADDR_SIZE;
|
||||
|
||||
protected override Commands Command => Commands.SetDnsAddress;
|
||||
|
||||
private string _dns;
|
||||
|
||||
public string Dns
|
||||
{
|
||||
set
|
||||
{
|
||||
_dns = value;
|
||||
command.SetParameter(FIRST_PARAMETER_OFFSET, _dns);
|
||||
}
|
||||
}
|
||||
|
||||
public MulticastSetDnsAddress(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
command.Parameter = new byte[COMMAND_PAYLOAD_SIZE];
|
||||
}
|
||||
|
||||
public MulticastSetDnsAddress(DTS.Common.Interface.DASFactory.ICommunication sock, int timeoutMillisec)
|
||||
: base(sock, timeoutMillisec)
|
||||
{
|
||||
command.Parameter = new byte[COMMAND_PAYLOAD_SIZE];
|
||||
}
|
||||
|
||||
public override void CommandToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.CommandToString(ref lines);
|
||||
lines.Add(new List<string> { $"MAC: {CommandClientMac} DNS: {_dns}" });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using System.Collections.Generic;
|
||||
using DTS.Common.ICommunication;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.MulticastCommands
|
||||
{
|
||||
public class MulticastSetGatewayAddress : MulticastCommandBase
|
||||
{
|
||||
const int COMMAND_PAYLOAD_SIZE = DOUBLE_MAC_ADDR_SIZE + IP_ADDR_SIZE;
|
||||
|
||||
protected override Commands Command => Commands.SetGatewayAddress;
|
||||
|
||||
private string _gateway;
|
||||
public string Gateway { set { _gateway = value; command.SetParameter(FIRST_PARAMETER_OFFSET, _gateway); } }
|
||||
|
||||
public MulticastSetGatewayAddress(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
command.Parameter = new byte[COMMAND_PAYLOAD_SIZE];
|
||||
}
|
||||
|
||||
public MulticastSetGatewayAddress(DTS.Common.Interface.DASFactory.ICommunication sock, int timeoutMillisec)
|
||||
: base(sock, timeoutMillisec)
|
||||
{
|
||||
command.Parameter = new byte[COMMAND_PAYLOAD_SIZE];
|
||||
}
|
||||
|
||||
public override void CommandToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.CommandToString(ref lines);
|
||||
lines.Add(new List<string> { $"MAC: {CommandClientMac} Gateway: {_gateway}" });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using System.Collections.Generic;
|
||||
using DTS.Common.ICommunication;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.MulticastCommands
|
||||
{
|
||||
public class MulticastSetIpAddress : MulticastCommandBase
|
||||
{
|
||||
const int COMMAND_PAYLOAD_SIZE = DOUBLE_MAC_ADDR_SIZE + IP_ADDR_SIZE;
|
||||
|
||||
protected override Commands Command => Commands.SetIpAddress;
|
||||
|
||||
private string _ip;
|
||||
public string Ip { set { _ip = value; command.SetParameter(FIRST_PARAMETER_OFFSET, _ip); } }
|
||||
|
||||
public MulticastSetIpAddress(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
command.Parameter = new byte[COMMAND_PAYLOAD_SIZE];
|
||||
}
|
||||
|
||||
public MulticastSetIpAddress(DTS.Common.Interface.DASFactory.ICommunication sock, int timeoutMillisec)
|
||||
: base(sock, timeoutMillisec)
|
||||
{
|
||||
command.Parameter = new byte[COMMAND_PAYLOAD_SIZE];
|
||||
}
|
||||
|
||||
public override void CommandToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.CommandToString(ref lines);
|
||||
lines.Add(new List<string> { $"MAC: {CommandClientMac} IP: {_ip}" });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using System.Collections.Generic;
|
||||
using DTS.Common.ICommunication;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.MulticastCommands
|
||||
{
|
||||
public class MulticastSetSubnetAddress : MulticastCommandBase
|
||||
{
|
||||
private const int COMMAND_PAYLOAD_SIZE = DOUBLE_MAC_ADDR_SIZE + IP_ADDR_SIZE;
|
||||
|
||||
protected override Commands Command => Commands.SetSubnetAddress;
|
||||
|
||||
private string _subnet;
|
||||
public string Subnet { set { _subnet = value; command.SetParameter(FIRST_PARAMETER_OFFSET, _subnet); } }
|
||||
|
||||
public MulticastSetSubnetAddress(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
command.Parameter = new byte[COMMAND_PAYLOAD_SIZE];
|
||||
}
|
||||
|
||||
public MulticastSetSubnetAddress(DTS.Common.Interface.DASFactory.ICommunication sock, int timeoutMillisec)
|
||||
: base(sock, timeoutMillisec)
|
||||
{
|
||||
command.Parameter = new byte[COMMAND_PAYLOAD_SIZE];
|
||||
}
|
||||
|
||||
public override void CommandToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.CommandToString(ref lines);
|
||||
lines.Add(new List<string> { $"MAC: {CommandClientMac} Subnet: {_subnet}" });
|
||||
}
|
||||
}
|
||||
}
|
||||
212
DataPRO/SLICECommands/MulticastCommands/MulticastUDPQueryQATS.cs
Normal file
212
DataPRO/SLICECommands/MulticastCommands/MulticastUDPQueryQATS.cs
Normal file
@@ -0,0 +1,212 @@
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
using DTS.Common.Utilities;
|
||||
using DTS.DASLib.Command.Classes;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.MulticastCommands
|
||||
{
|
||||
public class MulticastUdpQueryQATS : MulticastCommandBase
|
||||
{
|
||||
private const int COMMAND_PAYLOAD_SIZE = 63;
|
||||
private const int RESPONSE_PAYLOAD_SIZE = 215; // 278;
|
||||
|
||||
protected override Commands Command => Commands.UdpQueryQTAS;
|
||||
|
||||
protected override bool StopAfterFirstMessage { get { return false; } }
|
||||
|
||||
private uint _deviceClass;
|
||||
private byte _responseOption;
|
||||
private IPAddress _address;
|
||||
private int _port = (int)Ports.Response;
|
||||
|
||||
private void SetMulticastConfig()
|
||||
{
|
||||
IPAddress.TryParse(MulticastReceiveAddress, out _address);
|
||||
|
||||
string config = _address.ToString() + ":" + _port.ToString();
|
||||
command.SetParameter(41, config);
|
||||
}
|
||||
|
||||
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(); } }
|
||||
public int Port { set { _port = value; SetMulticastConfig(); } }
|
||||
private static object MyLock = new object();
|
||||
|
||||
public List<IUDPQATSEntry> QATSEntry { get; set; } = new List<IUDPQATSEntry>();
|
||||
public MulticastUdpQueryQATS(ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
public MulticastUdpQueryQATS(string macAddress)
|
||||
: base(null)
|
||||
{
|
||||
Init(macAddress);
|
||||
}
|
||||
public MulticastUdpQueryQATS(int timeoutMillisec)
|
||||
: base(null, timeoutMillisec)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
public MulticastUdpQueryQATS(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;
|
||||
ReceiveTimeoutMs = 5000;
|
||||
SetMulticastConfig();
|
||||
}
|
||||
public MulticastUdpQueryQATS(ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
protected const int QATS_OFFSET = 74;
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
|
||||
if (response.Status == DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
var responseHostMac = string.Empty;
|
||||
response.GetParameter(HOST_MAC_ADDRESS_OFFSET, out responseHostMac);
|
||||
|
||||
if ((null == responseHostMac) || !HostMac.Equals(responseHostMac))
|
||||
{
|
||||
response.Status = DFConstantsAndEnums.CommandStatus.StatusInvalidPacket;
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
|
||||
if (response.ParameterLength < RESPONSE_PAYLOAD_SIZE)
|
||||
{
|
||||
response.Status = DFConstantsAndEnums.CommandStatus.StatusAttributeInvalidLength;
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
|
||||
var responseClientMac = string.Empty;
|
||||
response.GetParameter(CLIENT_MAC_ADDRESS_OFFSET, out responseClientMac);
|
||||
var qatsSerialNumber = string.Empty;
|
||||
response.GetParameter(QATS_OFFSET, out qatsSerialNumber); /*! serial = 10B */
|
||||
var armState = (byte)0;
|
||||
response.GetParameter(QATS_OFFSET + 10, out armState); /*! 10 */
|
||||
var armMode = (byte)0;
|
||||
response.GetParameter(QATS_OFFSET + 11, out armMode); /*! 11 */
|
||||
var started = (byte)0;
|
||||
response.GetParameter(QATS_OFFSET + 12, out started); /*! 12 */
|
||||
var eventTrigger = (byte)0;
|
||||
response.GetParameter(QATS_OFFSET + 13, out eventTrigger); /*! 13 */
|
||||
var faultFlags = (byte)0;
|
||||
response.GetParameter(QATS_OFFSET + 14, out faultFlags); /*! 14 */
|
||||
var sampleRate = (uint)0;
|
||||
response.GetParameter(QATS_OFFSET + 15, out sampleRate); /*! 15 + 4 */
|
||||
var totalSamples = 0UL;
|
||||
response.GetParameter(QATS_OFFSET + 19, out totalSamples); /*! 19 + 8 */
|
||||
var currentSample = 0UL;
|
||||
response.GetParameter(QATS_OFFSET + 27, out currentSample); /*! 27 + 8 */
|
||||
var eventNumber = (ushort)0;
|
||||
response.GetParameter(QATS_OFFSET + 35, out eventNumber); /*! 35 + 2 */
|
||||
var faultSampleNumber = 0UL;
|
||||
response.GetParameter(QATS_OFFSET + 37, out faultSampleNumber); /*! 37 + 8 */
|
||||
var legacyFaultFlag = (ushort)0;
|
||||
response.GetParameter(QATS_OFFSET + 45, out legacyFaultFlag); /*! 45 + 2 */
|
||||
var inputVoltage = 0F;
|
||||
response.GetParameter(QATS_OFFSET + 47, out inputVoltage); /*! 47 + 4 */
|
||||
var backupVoltage = 0F;
|
||||
response.GetParameter(QATS_OFFSET + 51, out backupVoltage); /*! 51 + 4 */
|
||||
var batterySoC = 0F;
|
||||
response.GetParameter(QATS_OFFSET + 55, out batterySoC); /*! 55 + 4 */
|
||||
var actualCurrentSample = 0UL;
|
||||
response.GetParameter(QATS_OFFSET + 59, out actualCurrentSample); /*! 59 + 8 used by software to estimate remaining time in Circular mode */
|
||||
var estimateMaxSamples = 0UL;
|
||||
response.GetParameter(QATS_OFFSET + 67, out estimateMaxSamples); /*! 67 + 8 used by software to calculate current storage remaining */
|
||||
/*! ^^^^ SPS Legacy end here ^^^^^^^*/
|
||||
|
||||
/*! Added by S6/S6A product */
|
||||
var tiltSensorCh1 = (short)0;
|
||||
response.GetParameter(QATS_OFFSET + 75, out tiltSensorCh1); /*! 75 + 2 */
|
||||
var tiltSensorCh2 = (short)0;
|
||||
response.GetParameter(QATS_OFFSET + 77, out tiltSensorCh2); /*! 77 + 2 */
|
||||
var tiltSensorCh3 = (short)0;
|
||||
response.GetParameter(QATS_OFFSET + 79, out tiltSensorCh3); /*! 79 + 2 */
|
||||
|
||||
var sysTempC = 0F;
|
||||
response.GetParameter(QATS_OFFSET + 81, out sysTempC); /*! 71 + 4 */
|
||||
// response.GetParameter(DOUBLE_MAC_ADDR_SIZE + 75, out _sensorData); /*! 75 + 12 channel 1 - 6 for S6/S6A */
|
||||
|
||||
/*! added for synchronization status in S6/S6A/S6DB/TSR-AIR ... */
|
||||
var syncClockEnable = (byte)0;
|
||||
response.GetParameter(QATS_OFFSET + 129, out syncClockEnable); /*! 129 + 1 */
|
||||
var adcExtClockSyncEnable = (byte)0;
|
||||
response.GetParameter(QATS_OFFSET + 130, out adcExtClockSyncEnable); /*! 130 + 1 */
|
||||
var syncClockStatus = (byte)0;
|
||||
response.GetParameter(QATS_OFFSET + 131, out syncClockStatus); /*! 131 + 1 */
|
||||
var adcExtClockSyncStatus = (byte)0;
|
||||
response.GetParameter(QATS_OFFSET + 132, out adcExtClockSyncStatus); /*! 132 + 1 */
|
||||
var triggerSample = 0UL;
|
||||
response.GetParameter(QATS_OFFSET + 133, out triggerSample); /*! 133 + 8 */
|
||||
|
||||
var curOffset = QATS_OFFSET + 133 + 4;
|
||||
var stackChannelOffsetMV = new float[6];
|
||||
for (var i = 0; i < 6; i++)
|
||||
{
|
||||
response.GetParameter(curOffset, out stackChannelOffsetMV[i]);
|
||||
curOffset += 4;
|
||||
}
|
||||
|
||||
var shuntDeviationPercent = new float[6];
|
||||
for (var i = 0; i < 6; i++)
|
||||
{
|
||||
response.GetParameter(curOffset, out shuntDeviationPercent[i]);
|
||||
curOffset += 4;
|
||||
}
|
||||
|
||||
var timeStamp = DateTime.Now;
|
||||
lock (MyLock)
|
||||
{
|
||||
QATSEntry.Add(
|
||||
new UDPQATSEntry(responseHostMac, responseClientMac,
|
||||
qatsSerialNumber, armState, armMode, started, eventTrigger, faultFlags, sampleRate, totalSamples,
|
||||
currentSample, eventNumber, faultSampleNumber, legacyFaultFlag, inputVoltage,
|
||||
backupVoltage, batterySoC, estimateMaxSamples, tiltSensorCh1, tiltSensorCh2, tiltSensorCh3,
|
||||
sysTempC, syncClockEnable, adcExtClockSyncEnable, syncClockStatus, adcExtClockSyncStatus, triggerSample,
|
||||
stackChannelOffsetMV,
|
||||
shuntDeviationPercent,
|
||||
timeStamp));
|
||||
}
|
||||
}
|
||||
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
/// <summary>
|
||||
/// returns any waiting QATS, clear the list
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IUDPQATSEntry[] GetUDPQATs()
|
||||
{
|
||||
lock (MyLock)
|
||||
{
|
||||
var quats = QATSEntry.ToArray();
|
||||
QATSEntry.Clear();
|
||||
return quats;
|
||||
}
|
||||
}
|
||||
public override void CommandToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.CommandToString(ref lines);
|
||||
lines.Add(new List<string>() { string.Format("UdpQueryQATS: [{0}] {1} : {1}", HostMac, _address, _port) });
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user