This commit is contained in:
2026-04-17 14:55:32 -04:00
commit bc3ac1d4c9
18017 changed files with 4371742 additions and 0 deletions

View 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;
}
}
}

View 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
}
}

View 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;
}
}
}

View File

@@ -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
}
}

View 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}" });
}
}
}

View File

@@ -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}" });
}
}
}

View File

@@ -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}" });
}
}
}

View File

@@ -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}" });
}
}
}

View File

@@ -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}" });
}
}
}

View 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}" });
}
}
}

View 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}" });
}
}
}

View 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} " });
}
}
}

View File

@@ -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}" });
}
}
}

View File

@@ -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}" });
}
}
}

View File

@@ -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}" });
}
}
}

View File

@@ -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}" });
}
}
}

View 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) });
}
}
}