init
This commit is contained in:
1
DataPRO/SLICECommands/.svn/entries
Normal file
1
DataPRO/SLICECommands/.svn/entries
Normal file
@@ -0,0 +1 @@
|
||||
12
|
||||
1
DataPRO/SLICECommands/.svn/format
Normal file
1
DataPRO/SLICECommands/.svn/format
Normal file
@@ -0,0 +1 @@
|
||||
12
|
||||
@@ -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
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
using System.Collections.Generic;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.DownloadCommands
|
||||
{
|
||||
/// <summary>
|
||||
/// Retrieves parameters of Ethernet data recorder by EthernetRecorder
|
||||
/// </summary>
|
||||
public class QueryEthernetEventInfo : EventDataCommands
|
||||
{
|
||||
protected override Commands Command => Commands.QueryEthernetEventInfo;
|
||||
|
||||
private ushort _eventID = 0;
|
||||
public ushort EventID
|
||||
{
|
||||
get { return _eventID; }
|
||||
set { _eventID = value; command.SetParameter(0, _eventID); }
|
||||
}
|
||||
|
||||
private ushort _dataDownloaded = 0;
|
||||
public ushort DataDownloaded => _dataDownloaded;
|
||||
|
||||
private ulong _totalByteCount = 0UL;
|
||||
public ulong TotalByteCount => _totalByteCount;
|
||||
|
||||
private ulong _triggerByteCount = 0UL;
|
||||
public ulong TriggerByteCount => _triggerByteCount;
|
||||
|
||||
private ulong _faultByteCount;
|
||||
public ulong FaultByteCount => _faultByteCount;
|
||||
|
||||
private uint[] _DataStartTimeStamp = new uint[] { 0, 0 };
|
||||
public uint[] DataStartTimeStamp => _DataStartTimeStamp;
|
||||
public QueryEthernetEventInfo(ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
//Command Parameters: 4 bytes.
|
||||
//Byte[1:0] U16 Event ID.
|
||||
//Byte[3:2]: Reserved.
|
||||
command.Parameter = new byte[4];
|
||||
}
|
||||
|
||||
public QueryEthernetEventInfo(ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
//Command Parameters: 4 bytes.
|
||||
//Byte[1:0] U16 Event ID.
|
||||
//Byte[3:2]: Reserved.
|
||||
command.Parameter = new byte[4];
|
||||
}
|
||||
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
if (response.Status == DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
if (response.ParameterLength > 0)
|
||||
{
|
||||
/*
|
||||
Response: 36 bytes.
|
||||
Byte [1:0] U16 Event ID.
|
||||
Byte [3:2] U16 Data Downloaded Flag.
|
||||
Byte [11:4] U64 Total ByteCount.
|
||||
Byte [19:12] U64 Trigger ByteCount.
|
||||
Byte [27:20] U64 Fault ByteCount.
|
||||
Byte [35:28] U32[2] Data Start Timestamp. U32[0] = Second. U32[1] = Nano-Second
|
||||
*/
|
||||
response.GetParameter(0, out _eventID);
|
||||
response.GetParameter(2, out _dataDownloaded);
|
||||
response.GetParameter(4, out _totalByteCount);
|
||||
response.GetParameter(12, out _triggerByteCount);
|
||||
response.GetParameter(20, out _faultByteCount);
|
||||
response.GetParameter(28, out uint temp);
|
||||
_DataStartTimeStamp[0] = temp;
|
||||
response.GetParameter(32, out temp);
|
||||
_DataStartTimeStamp[1] = temp;
|
||||
}
|
||||
else { _eventID = 0; }
|
||||
}
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
public override void ResponseToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.ResponseToString(ref lines);
|
||||
lines.Add(new List<string>()
|
||||
{
|
||||
$"EventId: {EventID}",
|
||||
$"DataDownloaded: {DataDownloaded}",
|
||||
$"TotalByteCount: {TotalByteCount}",
|
||||
$"TriggerByteCount: {TriggerByteCount}",
|
||||
$"FaultByteCount: {FaultByteCount}",
|
||||
$"DataStartTimeStamp: {DataStartTimeStamp[0]}, {DataStartTimeStamp[1]}"
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using DTS.Common.ICommunication;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.RealtimeCommands
|
||||
{
|
||||
public abstract class RealtimeCommandBase : CommandBase
|
||||
{
|
||||
protected enum Commands
|
||||
{
|
||||
Reserved = 0x00,
|
||||
StartRealtimeMode = 0x01,
|
||||
EndRealtimeMode = 0x02,
|
||||
GetRealtimeSamples = 0x03,
|
||||
RetrieveSingleSample = 0x04,
|
||||
RetrieveSampleAverage = 0x05,
|
||||
RetrieveInternalOffsetSampleAvg = 0x06,
|
||||
StartRealtimeStreamingMode = 0x07,
|
||||
GetRealtimeStreamSamples = 0x08,
|
||||
StartTimeStampStreamMode = 0x09, // CMDRT_START_TIMESTAMPED_STREAM_MODE = 0x09: Start IRIG realtime stream with destination IP address from system attribute
|
||||
GetTimeStampStreamSamples = 0x0A, // CMDRT_TIMESTAMPED_STREAM_SAMPLES = 0x0A: streaming data from cmd 0x09
|
||||
ChannelTappedTest = 0x0B,
|
||||
I106StreamConfigSet = 0x0C, // FB15313 add streaming config options
|
||||
I106StreamConfigGet = 0x0D,
|
||||
};
|
||||
|
||||
protected abstract Commands _Command { get; }
|
||||
|
||||
protected RealtimeCommandBase(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
command.Type = CommandPacket.CommandType.Realtime;
|
||||
command.SetCommand((byte)_Command, _Command.ToString());
|
||||
}
|
||||
|
||||
protected RealtimeCommandBase(DTS.Common.Interface.DASFactory.ICommunication sock, int timeoutMillisec)
|
||||
: base(sock, timeoutMillisec)
|
||||
{
|
||||
command.Type = CommandPacket.CommandType.Realtime;
|
||||
command.SetCommand((byte)_Command, _Command.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using DTS.Common.ICommunication;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.DownloadCommands
|
||||
{
|
||||
public abstract class EventDataCommands : CommandBase
|
||||
{
|
||||
protected enum Commands
|
||||
{
|
||||
Reserved = 0x00,
|
||||
ResetEventList = 0x01,
|
||||
QueryTotalEventCount = 0x02,
|
||||
QueryMatchingEvents = 0x03,
|
||||
QueryEventData = 0x04,
|
||||
SetEventData = 0x05,
|
||||
StartDownloadStreamData = 0x06, // CMDEVD_STREAM_EVENT_DATA_START
|
||||
GetNextDownloadStreamDataSamples = 0x07, // stream packet of data out to receiver.
|
||||
QueryUartEventInfo = 0x09, // saved UART info
|
||||
QueryUartEventData = 0x0A,
|
||||
SetUartEventData = 0x0B,
|
||||
GenerateEvent = 0x0C,
|
||||
QueryEthernetEventInfo = 0x0D,
|
||||
QueryEthernetEventData = 0x0E,
|
||||
SetEthernetEventData = 0x0F
|
||||
};
|
||||
|
||||
protected abstract Commands Command { get; }
|
||||
|
||||
protected EventDataCommands(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
command.Type = CommandPacket.CommandType.EventData;
|
||||
command.SetCommand((byte)Command, Command.ToString());
|
||||
}
|
||||
|
||||
protected EventDataCommands(DTS.Common.Interface.DASFactory.ICommunication sock, int timeoutMillisec)
|
||||
: base(sock, timeoutMillisec)
|
||||
{
|
||||
command.Type = CommandPacket.CommandType.EventData;
|
||||
command.SetCommand((byte)Command, Command.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.RealtimeCommands
|
||||
{
|
||||
/// <summary>
|
||||
/// this class handles decoding a SPS realtime stream packet.
|
||||
/// </summary>
|
||||
public class RealtimeStreamDecoder
|
||||
{
|
||||
/* per lp,
|
||||
* Byte index:
|
||||
0 Sync = CMD_SYNC_BYTE = 0xFA
|
||||
1 type = CMD_TYPE_REALTIME = 0x08
|
||||
2 command = CMDRT_REALTIME_STREAM_SAMPLE_PUSH = 0x08
|
||||
3 status = STATUS_ERROR_NONE = 0x00
|
||||
4 group = 0x00;
|
||||
5 id = 0x00;
|
||||
6-7 datalength
|
||||
8-9 sequence number
|
||||
10-11 headerCRC16
|
||||
12-13 dataCRC16 (currently not used)
|
||||
… payload
|
||||
8-byte uint64_t Timestamp (for first sample in payload.)
|
||||
4-byte uint32_t Channel list (bit set = channel present. Bit clear = channel not present.
|
||||
8-byte uint64_t Sample Number (starting with first ADC scan in payload)
|
||||
Number of ADC-Scan sample = (datalength – 20) / (channellist*2)
|
||||
*/
|
||||
/// <summary>
|
||||
/// this is the order of information in the packet
|
||||
/// the enum value is the offset in bytes from the start of the packet
|
||||
/// </summary>
|
||||
public enum ByteIndex
|
||||
{
|
||||
Sync = 0,
|
||||
Type = 1,
|
||||
Command = 2,
|
||||
Status = 3,
|
||||
Group = 4,
|
||||
Id = 5,
|
||||
DataLength = 6,
|
||||
SequenceNumber = 8,
|
||||
HeaderCRC = 10,
|
||||
DataCRC = 12,
|
||||
TimeStamp = 14,
|
||||
ChannelList = 22,
|
||||
SampleNumber = 26,
|
||||
DataStart = 34
|
||||
}
|
||||
|
||||
public ushort SequenceNumber { get; }
|
||||
public ulong TimeStamp { get; }
|
||||
public ulong SampleNumber { get; }
|
||||
public int[] Channels { get; }
|
||||
|
||||
/// <summary>
|
||||
/// this is all data, not transformed into (short) yet, which requires 2's compliment
|
||||
/// it is also for all channels in the realtime stream
|
||||
/// </summary>
|
||||
public ushort[] RtData { get; }
|
||||
|
||||
/// <summary>
|
||||
/// constructors and decodes byte stream
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="bytes"></param>
|
||||
public RealtimeStreamDecoder(IReadOnlyList<byte> bytes)
|
||||
{
|
||||
if (bytes.Count > (int)ByteIndex.DataStart)
|
||||
{
|
||||
TimeStamp = GetULong(bytes, (int)ByteIndex.TimeStamp);
|
||||
SequenceNumber = GetUShort(bytes, (int)ByteIndex.SequenceNumber);
|
||||
SampleNumber = GetULong(bytes, (int)ByteIndex.SampleNumber);
|
||||
RtData = new ushort[(bytes.Count - (int)ByteIndex.DataStart) / 2];
|
||||
var uintChannelList = GetUINT(bytes, (int)ByteIndex.ChannelList);
|
||||
var channels = new List<int>();
|
||||
var ba = new BitArray(BitConverter.GetBytes(uintChannelList));
|
||||
for (var i = 0; i < ba.Length; i++)
|
||||
{
|
||||
if (ba.Get(i))
|
||||
{
|
||||
channels.Add(i);
|
||||
}
|
||||
}
|
||||
|
||||
Channels = channels.ToArray();
|
||||
for (var idx = 0; idx < RtData.Length; idx++)
|
||||
{
|
||||
//all the data is stored as uint16 with channel order so
|
||||
// AABBCCDDEEFF, so split out the ushorts
|
||||
RtData[idx] = GetRTUShort(bytes, (int)(ByteIndex.DataStart + idx * 2));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RtData = new ushort[0];
|
||||
SampleNumber = 0;
|
||||
Channels = new int[0];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns a ulong given a sequence of bytes and a starting offset in bytes
|
||||
/// that the ulong starts at
|
||||
/// SLICE header bytes are sent in reverse order so we have to fix them first
|
||||
/// </summary>
|
||||
/// <param name="bytes"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <returns></returns>
|
||||
private static ulong GetULong(IReadOnlyList<byte> bytes, int offset)
|
||||
{
|
||||
return (ulong)bytes[offset + 7] << 0 |
|
||||
(ulong)bytes[offset + 6] << 8 |
|
||||
(ulong)bytes[offset + 5] << 16 |
|
||||
(ulong)bytes[offset + 4] << 24 |
|
||||
(ulong)bytes[offset + 3] << 32 |
|
||||
(ulong)bytes[offset + 2] << 40 |
|
||||
(ulong)bytes[offset + 1] << 48 |
|
||||
(ulong)bytes[offset + 0] << 56;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// gets a ushort from the response parameters
|
||||
/// SLICE header bytes are sent in reverse order, so we have to fix
|
||||
/// them first
|
||||
/// </summary>
|
||||
/// <param name="bytes"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <returns></returns>
|
||||
private static uint GetUINT(IReadOnlyList<byte> bytes, int offset)
|
||||
{
|
||||
return (uint)bytes[offset + 3] << 0 |
|
||||
(uint)bytes[offset + 2] << 8 |
|
||||
(uint)bytes[offset + 1] << 16 |
|
||||
(uint)bytes[offset + 0] << 32;
|
||||
}
|
||||
/// <summary>
|
||||
/// returns a ushort given a sequence of bytes and a starting offset in bytes
|
||||
/// SLICE header bytes are sent in reverse order, so we have to fix the byte
|
||||
/// order first
|
||||
/// </summary>
|
||||
/// <param name="bytes"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <returns></returns>
|
||||
private static ushort GetUShort(IReadOnlyList<byte> bytes, int offset)
|
||||
{
|
||||
return (ushort)(bytes[offset + 1] |
|
||||
bytes[offset + 0] << 8);
|
||||
}
|
||||
/// <summary>
|
||||
/// returns a ushort given a sequence of bytes and a starting offset in bytes
|
||||
/// note that DATA is not in reverse order unlike the header, so we
|
||||
/// DON'T need to fix the order
|
||||
/// </summary>
|
||||
/// <param name="bytes"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <returns></returns>
|
||||
private static ushort GetRTUShort(IReadOnlyList<byte> bytes, int offset)
|
||||
{
|
||||
return (ushort)(bytes[offset + 0] |
|
||||
bytes[offset + 1] << 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 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}" });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
using System.Collections.Generic;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.DownloadCommands
|
||||
{
|
||||
/// <summary>
|
||||
/// retrieves Ethernet data from an EthernetRecorder
|
||||
/// </summary>
|
||||
public class QueryEthernetEventData : EventDataCommands
|
||||
{
|
||||
private ushort _eventID = 0;
|
||||
public ushort EventID
|
||||
{
|
||||
get => _eventID;
|
||||
set { _eventID = value; command.SetParameter(0, _eventID); }
|
||||
}
|
||||
|
||||
protected override Commands Command => Commands.QueryEthernetEventData;
|
||||
|
||||
private uint _requestByteCount = 0;
|
||||
public uint RequestByteCount
|
||||
{
|
||||
get => _requestByteCount;
|
||||
set { _requestByteCount = value; command.SetParameter(2, _requestByteCount); }
|
||||
}
|
||||
|
||||
private ulong _StartDataOffsetBytes = 0UL;
|
||||
public ulong StartDataOffsetBytes
|
||||
{
|
||||
get => _StartDataOffsetBytes;
|
||||
set { _StartDataOffsetBytes = value; command.SetParameter(6, _StartDataOffsetBytes); }
|
||||
}
|
||||
|
||||
private byte[] _data;
|
||||
public byte[] Data
|
||||
{
|
||||
get => _data;
|
||||
set
|
||||
{
|
||||
if (null == value) { return; }
|
||||
_data = value;
|
||||
}
|
||||
}
|
||||
|
||||
private const int PARAMETER_BYTE_COUNT = 14;
|
||||
public QueryEthernetEventData(ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
command.Parameter = new byte[PARAMETER_BYTE_COUNT];
|
||||
/*
|
||||
Byte [1:0] U16 Event ID
|
||||
Byte [5:2] U32 Request byte count.
|
||||
Byte [13:6] U64 Start data offset in byte counter.
|
||||
*/
|
||||
}
|
||||
|
||||
public QueryEthernetEventData(ICommunication sock, int timeoutMS)
|
||||
: base(sock, timeoutMS)
|
||||
{
|
||||
command.Parameter = new byte[PARAMETER_BYTE_COUNT];
|
||||
/*
|
||||
Byte [1:0] U16 Event ID
|
||||
Byte [5:2] U32 Request byte count.
|
||||
Byte [13:6] U64 Start data offset in byte counter.
|
||||
*/
|
||||
}
|
||||
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
/*
|
||||
Byte [1:0]: U16 Event ID
|
||||
Byte [5:2]: U32 Payload length in byte count.
|
||||
Byte [13:6]: U64 data offset start.
|
||||
Byte [payloadLength]: Data byte stream with payload length firmware can fit to a response payload size or that of request whichever less.
|
||||
*/
|
||||
if (response.Status == DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
if (response.ParameterLength > 0)
|
||||
{
|
||||
response.GetParameter(0, out _eventID);
|
||||
response.GetParameter(2, out uint payloadLength);
|
||||
response.GetParameter(6, out _StartDataOffsetBytes);
|
||||
_data = new byte[payloadLength];
|
||||
|
||||
for (var i = 0; i < payloadLength; i++)
|
||||
{
|
||||
response.GetParameter(PARAMETER_BYTE_COUNT + i, out _data[i]);
|
||||
}
|
||||
}
|
||||
else { _eventID = 0; }
|
||||
}
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
|
||||
public override void CommandToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.CommandToString(ref lines);
|
||||
lines.Add(new List<string>()
|
||||
{
|
||||
$"Event ID: {EventID}",
|
||||
$"StartDataOffset: {StartDataOffsetBytes}",
|
||||
$"RequestByteCount: {RequestByteCount}"
|
||||
});
|
||||
}
|
||||
public override void ResponseToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.ResponseToString(ref lines);
|
||||
lines.Add(new List<string>()
|
||||
{
|
||||
$"Event ID: {EventID}",
|
||||
$"Payload(bytes): {_data.Length}",
|
||||
$"StartDataOffsetBytes: {StartDataOffsetBytes}"
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using System;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.RealtimeCommands
|
||||
{
|
||||
/// <summary>
|
||||
/// ported from FWTU, appears almost verbatim to there
|
||||
/// </summary>
|
||||
public class UDPStreamPacket
|
||||
{
|
||||
/// <summary>
|
||||
/// first array channels, second array sample index
|
||||
/// </summary>
|
||||
public short[][] ChannelData { get; set; }
|
||||
|
||||
public long TimeStamp { get; set; }
|
||||
public ulong SampleNumber { get; set; }
|
||||
public ulong SequenceNumber { get; set; }
|
||||
|
||||
public uint PTPTimesec { get; set; }
|
||||
public uint PTPTimeNsec { get; set; }
|
||||
|
||||
public bool PTPSyncStatusError { get; set; }
|
||||
public bool ADCOverflowStatus { get; set; }
|
||||
|
||||
public string PTPTimeString => string.Concat(PTPTimesec, ":", PTPTimeNsec.ToString("000000000"));
|
||||
|
||||
public UDPStreamPacket()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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,61 @@
|
||||
using System.Collections.Generic;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.ICommunication;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.RealtimeCommands
|
||||
{
|
||||
public class GetRealtimeSamplesSLICE6 : GetRealtimeSamples
|
||||
{
|
||||
public GetRealtimeSamplesSLICE6(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock) { }
|
||||
|
||||
public GetRealtimeSamplesSLICE6(DTS.Common.Interface.DASFactory.ICommunication sock, int timeoutMillisec)
|
||||
: base(sock, timeoutMillisec) { }
|
||||
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (response.Status == DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
// Figure out the number of samples returned
|
||||
var samplesReturned = (response.ParameterLength - 8) / (_channels * 2);
|
||||
_samplesReturned = samplesReturned;
|
||||
_data = new List<short[]>(_channels);
|
||||
|
||||
// Grab the sample number
|
||||
if (response.ParameterLength > 0)
|
||||
{
|
||||
response.GetParameter(0, out _sampleNumber);
|
||||
}
|
||||
|
||||
// Create the data arrays by channel
|
||||
for (int i = 0; i < _channels; i++)
|
||||
{
|
||||
_data.Add(new short[samplesReturned]);
|
||||
}
|
||||
|
||||
// Grab the data
|
||||
var parameter = 8;
|
||||
for (var sample = 0; sample < samplesReturned; sample++)
|
||||
{
|
||||
for (var channel = 0; channel < _channels; channel++)
|
||||
{
|
||||
response.GetParameter(parameter, out ushort val);
|
||||
//Slice6 data is signed data. No need to convert.
|
||||
_data[channel][sample] = (short)((((val & 0x00FF) << 8) | ((val >> 8) & 0x00FF)));
|
||||
|
||||
parameter += 2;
|
||||
}
|
||||
}
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
_samplesReturned = 0;
|
||||
}
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
using DTS.Common.ICommunication;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.RealtimeCommands
|
||||
{
|
||||
public class StartRealtimeMode : RealtimeCommandBase
|
||||
{
|
||||
private bool _bSupportsMultipleSampleRealtime = true;
|
||||
public bool SupportsMultipleSampleRealtime
|
||||
{
|
||||
get => _bSupportsMultipleSampleRealtime;
|
||||
set
|
||||
{
|
||||
_bSupportsMultipleSampleRealtime = value;
|
||||
if (value) { command.Parameter = new byte[1]; }
|
||||
else { command.Parameter = new byte[0]; }
|
||||
}
|
||||
}
|
||||
protected override Commands _Command => Commands.StartRealtimeMode;
|
||||
|
||||
public StartRealtimeMode(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
// don't need to put anything in here ... its presense
|
||||
// tells the firmware that we support multiple-sample
|
||||
// realtime
|
||||
command.Parameter = new byte[1];
|
||||
}
|
||||
|
||||
public StartRealtimeMode(DTS.Common.Interface.DASFactory.ICommunication sock, int timeoutMillisec)
|
||||
: base(sock, timeoutMillisec)
|
||||
{
|
||||
// don't need to put anything in here ... its presense
|
||||
// tells the firmware that we support multiple-sample
|
||||
// realtime
|
||||
command.Parameter = new byte[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using DTS.DASLib.Communication;
|
||||
using DTS.DASLib.Utility;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE
|
||||
{
|
||||
public abstract class Commands_Stack_Utility: CommandBase
|
||||
{
|
||||
protected enum Commands
|
||||
{
|
||||
ArbitraryFlashWrite = 0x01,
|
||||
ArbitraryFlashRead,
|
||||
FlashSelfTest,
|
||||
BusPowerControl,
|
||||
ForceEnumeration,
|
||||
GainSet,
|
||||
GainQuery,
|
||||
DACSet,
|
||||
DACQuery,
|
||||
SwitchSet,
|
||||
SwitchQuery,
|
||||
FilterSet,
|
||||
FilterQuery,
|
||||
};
|
||||
|
||||
protected Commands_Stack_Utility(ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
this.command.Type = CommandPacket.CommandType.StackUtility;
|
||||
}
|
||||
|
||||
protected Commands_Stack_Utility(ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
this.command.Type = CommandPacket.CommandType.StackUtility;
|
||||
}
|
||||
}
|
||||
|
||||
public class BusPowerControl: Commands_Stack_Utility
|
||||
{
|
||||
private bool _on;
|
||||
|
||||
public bool PowerOn
|
||||
{
|
||||
get { return _on; }
|
||||
set
|
||||
{
|
||||
_on = value;
|
||||
if(_on)
|
||||
this.command.SetParameter(0, (byte)1);
|
||||
else
|
||||
this.command.SetParameter(0, (byte)0);
|
||||
}
|
||||
}
|
||||
|
||||
public BusPowerControl(ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
this.command.Command = (byte)Commands.BusPowerControl;
|
||||
this.command.Parameter = new byte[1];
|
||||
PowerOn = false;
|
||||
}
|
||||
|
||||
public BusPowerControl(ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
this.command.Command = (byte)Commands.BusPowerControl;
|
||||
this.command.Parameter = new byte[1];
|
||||
PowerOn = false;
|
||||
}
|
||||
|
||||
public override string CommandToString()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine("Sending command BusPowerControl");
|
||||
sb.AppendFormat("PowerOn: {0}", PowerOn);
|
||||
sb.AppendLine();
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public override string ResponseToString()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendFormat("Response for command BusPowerControl: {0}", ResponseStatus);
|
||||
sb.AppendLine();
|
||||
sb.AppendFormat("PowerOn: {0}", PowerOn);
|
||||
sb.AppendLine();
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public class ForceEnumeration: Commands_Stack_Utility
|
||||
{
|
||||
int _SLICECount;
|
||||
|
||||
public int SLICECount { get { return _SLICECount; } }
|
||||
|
||||
public ForceEnumeration(ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
this.command.Command = (byte)Commands.ForceEnumeration;
|
||||
this.command.Parameter = new byte[0];
|
||||
_SLICECount = 0;
|
||||
}
|
||||
|
||||
public ForceEnumeration(ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
this.command.Command = (byte)Commands.ForceEnumeration;
|
||||
this.command.Parameter = new byte[0];
|
||||
_SLICECount = 0;
|
||||
}
|
||||
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
if(response.Status == CommandPacket.CommandStatus.StatusNoError)
|
||||
{
|
||||
byte b;
|
||||
response.GetParameter(0, out b);
|
||||
_SLICECount = (int)b;
|
||||
}
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
|
||||
public override string CommandToString()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine("Sending command ForceEnumeration");
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public override string ResponseToString()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendFormat("Response for command ForceEnumeration: {0}", ResponseStatus);
|
||||
sb.AppendLine();
|
||||
sb.AppendFormat("SLICECount: {0}", SLICECount);
|
||||
sb.AppendLine();
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.RealtimeCommands
|
||||
{
|
||||
public class GetRealtimeSamplesTSRAIR : GetRealtimeSamples
|
||||
{
|
||||
public GetRealtimeSamplesTSRAIR(ICommunication sock)
|
||||
: base(sock) { }
|
||||
|
||||
public GetRealtimeSamplesTSRAIR(ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec) { }
|
||||
|
||||
protected List<UInt64> _timestamps;
|
||||
public List<UInt64> Timestamps => _timestamps;
|
||||
|
||||
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (response.Status == DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
// Figure out the number of samples returned
|
||||
int samples_returned = (response.ParameterLength - 8) / (_channels * 2);
|
||||
_samplesReturned = samples_returned;
|
||||
int data_bytes_returned = samples_returned * _channels * 2;
|
||||
_data = new List<short[]>(_channels);
|
||||
|
||||
// Grab the sample number
|
||||
if (response.ParameterLength > 0)
|
||||
{
|
||||
response.GetParameter(0, out _sampleNumber);
|
||||
}
|
||||
|
||||
// Create the data arrays by channel
|
||||
for (int i = 0; i < _channels; i++)
|
||||
{
|
||||
_data.Add(new short[samples_returned]);
|
||||
}
|
||||
|
||||
// Grab the data
|
||||
int parameter = 8;
|
||||
for (int sample = 0; sample < samples_returned; sample++)
|
||||
{
|
||||
for (int channel = 0; channel < _channels; channel++)
|
||||
{
|
||||
response.GetParameter(parameter, out ushort uval);
|
||||
|
||||
//TSRAIR data is unsigned data. Convert sign, no need to normalize
|
||||
_data[channel][sample] = (short)((((uval & 0x00FF) << 8) | ((uval >> 8) & 0x00FF)));
|
||||
parameter += 2;
|
||||
}
|
||||
}
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
_samplesReturned = 0;
|
||||
}
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,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,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,104 @@
|
||||
namespace DTS.DASLib.Command.SLICE.DownloadCommands
|
||||
{
|
||||
/// <summary>
|
||||
/// this is ported from FirmwareTestUtility where it was written by Loc Pham. It is included for
|
||||
/// 10573 implement SW side of single command/streaming download
|
||||
/// </summary>
|
||||
public class DownloadByteConverter
|
||||
{
|
||||
public enum DlByteIndex
|
||||
{
|
||||
Sync = 0,
|
||||
Type = 1,
|
||||
Command = 2,
|
||||
Status = 3,
|
||||
Group = 4,
|
||||
Id = 5,
|
||||
Datalength = 6,
|
||||
SequenceNumber = 8,
|
||||
HeaderCRC = 10,
|
||||
DataCRC = 12,
|
||||
DataADCStartOffset = 14,
|
||||
DataADCEndOffset = 22,
|
||||
DataStart = 30
|
||||
}
|
||||
|
||||
public ushort SeqNumber { get; }
|
||||
public ushort SeqNumberPrev { get; }
|
||||
public ulong DlAdcStartOffset { get; }
|
||||
public ulong DlAdcEndOffset { get; }
|
||||
|
||||
public ulong DlStreamSampleNumber { get; }
|
||||
|
||||
public ushort[] DlData { get; }
|
||||
|
||||
public uint[] DlChannels { get; }
|
||||
|
||||
public DownloadByteConverter(byte[] bytes)
|
||||
{
|
||||
SeqNumber = GetUShort(bytes, (int)DlByteIndex.SequenceNumber);
|
||||
DlAdcStartOffset = GetUInt(bytes, (int)DlByteIndex.DataADCStartOffset);
|
||||
DlAdcStartOffset = GetULong(bytes, (int)DlByteIndex.DataADCEndOffset);
|
||||
DlData = new ushort[(bytes.Length - (int)DlByteIndex.DataStart) / 2];
|
||||
|
||||
if (SeqNumber == 0)
|
||||
{
|
||||
SeqNumberPrev = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (SeqNumberPrev != 0 &&
|
||||
SeqNumberPrev != SeqNumber - 1)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine("sequence out of order: ");
|
||||
System.Diagnostics.Debug.WriteLine(SeqNumberPrev.ToString());
|
||||
System.Diagnostics.Debug.WriteLine(SeqNumber.ToString());
|
||||
}
|
||||
}
|
||||
SeqNumberPrev = SeqNumber;
|
||||
|
||||
for (var idx = 0; idx < DlData.Length; idx++)
|
||||
{
|
||||
DlData[idx] = GetDownloadUShort(bytes, (int)(DlByteIndex.DataStart + idx * 2));
|
||||
}
|
||||
}
|
||||
|
||||
private static ulong GetULong(byte[] bytes, int offset)
|
||||
{
|
||||
return (ulong)bytes[offset + 7] << 0 |
|
||||
(ulong)bytes[offset + 6] << 8 |
|
||||
(ulong)bytes[offset + 5] << 16 |
|
||||
(ulong)bytes[offset + 4] << 24 |
|
||||
(ulong)bytes[offset + 3] << 32 |
|
||||
(ulong)bytes[offset + 2] << 40 |
|
||||
(ulong)bytes[offset + 1] << 48 |
|
||||
(ulong)bytes[offset + 0] << 56;
|
||||
}
|
||||
|
||||
private static ushort GetUShort(byte[] bytes, int offset)
|
||||
{
|
||||
return (ushort)(bytes[offset + 1] |
|
||||
bytes[offset + 0] << 8);
|
||||
}
|
||||
|
||||
private static uint GetUInt(byte[] bytes, int offset)
|
||||
{
|
||||
return (uint)bytes[offset + 3] << 0 |
|
||||
(uint)bytes[offset + 2] << 8 |
|
||||
(uint)bytes[offset + 1] << 16 |
|
||||
(uint)bytes[offset + 0] << 32;
|
||||
}
|
||||
/// <summary>
|
||||
/// data apparently has a different byte order than parameters, so we have to
|
||||
/// rearrange byte order for parameters but not data.
|
||||
/// </summary>
|
||||
/// <param name="bytes"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <returns></returns>
|
||||
private static ushort GetDownloadUShort(byte[] bytes, int offset)
|
||||
{
|
||||
return (ushort)(bytes[offset + 0] | bytes[offset + 1] << 8);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.DownloadCommands
|
||||
{
|
||||
public class QueryUARTEventData : EventDataCommands
|
||||
{
|
||||
public const int MAX_DATA_LENGTH = 2000;
|
||||
public const int PAYLOAD_HEADER_LENGTH = 14;
|
||||
protected override Commands Command => Commands.QueryUartEventData;
|
||||
|
||||
protected ushort _eventNumber;
|
||||
protected uint _requestByteCount;
|
||||
protected ulong _requestOffsetByteCount;
|
||||
protected uint _payloadByteCount;
|
||||
protected ulong _payloadOffsetByteCount;
|
||||
protected byte[] _data;
|
||||
|
||||
public ushort EventNumber
|
||||
{
|
||||
get => _eventNumber;
|
||||
set { _eventNumber = value; command.SetParameter(0, _eventNumber); }
|
||||
}
|
||||
|
||||
public uint RequestByteCount
|
||||
{
|
||||
get => _requestByteCount;
|
||||
set { _requestByteCount = value; command.SetParameter(2, _requestByteCount); }
|
||||
}
|
||||
|
||||
public ulong RequestOffsetByteCount
|
||||
{
|
||||
get => _requestOffsetByteCount;
|
||||
set { _requestOffsetByteCount = value; command.SetParameter(6, _requestOffsetByteCount); }
|
||||
}
|
||||
|
||||
public uint PayloadByteCount => _payloadByteCount;
|
||||
|
||||
public ulong PayloadOffsetByteCount => _payloadOffsetByteCount;
|
||||
|
||||
public byte[] PayloadData => _data;
|
||||
|
||||
public QueryUARTEventData(ICommunication sock) : base(sock)
|
||||
{
|
||||
command.Parameter = new byte[14];
|
||||
_data = null;
|
||||
|
||||
_eventNumber = 0;
|
||||
_requestByteCount = 0;
|
||||
_requestOffsetByteCount = 0;
|
||||
_payloadByteCount = 0;
|
||||
_payloadOffsetByteCount = 0;
|
||||
|
||||
command.ShouldLog = false;
|
||||
}
|
||||
|
||||
public QueryUARTEventData(ICommunication sock, int timeoutMillisec) : base(sock, timeoutMillisec)
|
||||
{
|
||||
command.Parameter = new byte[14];
|
||||
_data = null;
|
||||
|
||||
_eventNumber = 0;
|
||||
_requestByteCount = 0;
|
||||
_requestOffsetByteCount = 0;
|
||||
_payloadByteCount = 0;
|
||||
_payloadOffsetByteCount = 0;
|
||||
|
||||
command.ShouldLog = false;
|
||||
}
|
||||
|
||||
public override void Execute(CommandCallback cb, object cbData)
|
||||
{
|
||||
// Do a little parameter checking
|
||||
_data = null;
|
||||
base.Execute(cb, cbData);
|
||||
}
|
||||
|
||||
protected override CommandReceiveAction WholePackagePost()
|
||||
{
|
||||
// now send the data to the user
|
||||
var stat = CommandStatus.Success;
|
||||
if (response.Status != DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
var s = (int)response.Status;
|
||||
APILogger.LogString("QueryUARTEventData.WholePackagePost: reporting failure, status==" + CommandPacketBase.StatusLabels[s] + " (0x" + s.ToString("X") + ")");
|
||||
stat = CommandStatus.Failure;
|
||||
}
|
||||
var cbReport = new QueryEventDataReport(stat, UserCallbackData);
|
||||
//cbReport.Data = new short[_channelsDownloaded][];
|
||||
//for (var i = 0; i < _channelsDownloaded; i++)
|
||||
// GetChannelData(i, out cbReport.Data[i]);
|
||||
return UserCallback(cbReport);
|
||||
}
|
||||
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
if (response.Status != DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
response.GetParameter(0, out ushort responseEventNum);
|
||||
response.GetParameter(2, out _payloadByteCount);
|
||||
response.GetParameter(6, out _payloadOffsetByteCount);
|
||||
_data = new byte[_payloadByteCount];
|
||||
for (var i = 0; i < _payloadByteCount; i++)
|
||||
{
|
||||
response.GetParameter(PAYLOAD_HEADER_LENGTH + i, out _data[i]);
|
||||
}
|
||||
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
|
||||
public override void SyncExecute()
|
||||
{
|
||||
// Do a little parameter checking
|
||||
_data = null;
|
||||
base.SyncExecute();
|
||||
}
|
||||
|
||||
public override void CommandToString(ref List<List<string>> lines)
|
||||
{
|
||||
lines.Add(new List<string> { $"Event number: {EventNumber}, RequestByteCount: {RequestByteCount}, OffsetByteCount: {RequestOffsetByteCount}" });
|
||||
}
|
||||
|
||||
public override void ResponseToString(ref List<List<string>> lines)
|
||||
{
|
||||
lines.Add(new List<string>
|
||||
{
|
||||
$"PayloadByteCount: {PayloadByteCount}, OffsetByteCount: {PayloadOffsetByteCount}"
|
||||
});
|
||||
}
|
||||
|
||||
public void LogResponse()
|
||||
{
|
||||
LogCommand(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,290 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using DTS.Common.Constant;
|
||||
using DTS.Common.Enums.Communication;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.ICommunication;
|
||||
using DTS.Common.Utilities;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.RealtimeCommands
|
||||
{
|
||||
/// <summary>
|
||||
/// this "command" gets the next set of samples
|
||||
/// note that in streaming mode no actual command is sent, we just pick up whatever data is in the RECV buffer
|
||||
/// </summary>
|
||||
public class RealtimeStreamingNextSamples : CommandBase, IGetRealtimeSamples
|
||||
{
|
||||
public RealtimeStreamingNextSamples(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
baseCommand = new CommandPacket();
|
||||
}
|
||||
public RealtimeStreamingNextSamples(DTS.Common.Interface.DASFactory.ICommunication sock, int msTimeout)
|
||||
: base(sock, msTimeout)
|
||||
{
|
||||
baseCommand = new CommandPacket();
|
||||
}
|
||||
public bool DigitalInput { get; set; }
|
||||
public bool[] TransitionMode { get; set; }
|
||||
/// <summary>
|
||||
/// the realtime data sample data
|
||||
/// </summary>
|
||||
public RealtimeStreamDecoder RtData { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// these are both used in garbage packet detection
|
||||
/// sample numbers are always increasing, sequence numbers are increasing but wrap around at ushort.max
|
||||
/// we could just use only sample number and not sample number and sequence
|
||||
/// for the garbage packet detection, but the number of samples per packet can be variable
|
||||
/// (especially with different SPS and number of channels) while the sequence is always +1 increase
|
||||
/// </summary>
|
||||
private ulong _lastProcessedSampleNumber = ulong.MaxValue;
|
||||
private ushort _lastSequenceNumber = 0;
|
||||
/// <summary>
|
||||
/// this is a fairly arbitrary choice, this is just used for garbage packet detection
|
||||
/// in practical use we are unlikely to drop more than 50 sequence at 2k sps
|
||||
/// so if we have more than a 1k difference there's a good chance the packet is garbage
|
||||
/// </summary>
|
||||
private const int MAX_SEQUENCE_DELTA = 1000;
|
||||
public bool SignedData { get; set; } = false;
|
||||
public void ProcessData()
|
||||
{
|
||||
try
|
||||
{
|
||||
#if REALTIME_LOGGING
|
||||
var dt = DateTime.Now;
|
||||
System.Diagnostics.Trace.WriteLine($"{dt.Hour}:{dt.Minute}:{dt.Second}.{dt.Millisecond} ProcessData");
|
||||
#endif
|
||||
RtData = null;
|
||||
System.Threading.Thread.Sleep(20);
|
||||
var bytes = baseResponse.ToBytes();
|
||||
var headerCRC = response.HeaderCRC;
|
||||
response.ComputeCRCs();
|
||||
if (response.HeaderCRC != headerCRC)
|
||||
{
|
||||
//garbage packet, don't process
|
||||
return;
|
||||
}
|
||||
if (!bytes.Any()) return;
|
||||
RtData = new RealtimeStreamDecoder(bytes);
|
||||
var bFailsSequenceCheck = false;
|
||||
|
||||
var sequenceDelta = Math.Abs(RtData.SequenceNumber - _lastSequenceNumber);
|
||||
|
||||
if (RtData.SequenceNumber != 0 && sequenceDelta > MAX_SEQUENCE_DELTA)
|
||||
{
|
||||
#if REALTIME_LOGGING
|
||||
System.Diagnostics.Trace.WriteLine("garbage packet");
|
||||
#endif
|
||||
//crc matched, but we've still got a garbage packet, as determined by looking at the sequence #
|
||||
bFailsSequenceCheck = true;
|
||||
}
|
||||
|
||||
_lastSequenceNumber = RtData.SequenceNumber;
|
||||
|
||||
if (null == RtData || RtData.SampleNumber == _lastProcessedSampleNumber || bFailsSequenceCheck)
|
||||
{
|
||||
#if REALTIME_LOGGING
|
||||
if (RtData.SampleNumber == _lastProcessedSampleNumber)
|
||||
{
|
||||
System.Diagnostics.Trace.WriteLine("Same packet #");
|
||||
}
|
||||
#endif
|
||||
RtData = null;
|
||||
return;
|
||||
}
|
||||
|
||||
#if REALTIME_LOGGING
|
||||
System.Diagnostics.Trace.WriteLine($"Processed: {RtData.SampleNumber}");
|
||||
#endif
|
||||
_lastProcessedSampleNumber = RtData.SampleNumber;
|
||||
ChannelData = new short[Channels][];
|
||||
for (var idx = 0; idx < Channels; idx++)
|
||||
{
|
||||
ChannelData[idx] = new short[SamplesReturned];
|
||||
}
|
||||
int insertPt;
|
||||
short adc;
|
||||
|
||||
for (var i = 0; i < RtData.RtData.Length; i++)
|
||||
{
|
||||
//data is in the form of ABC where A is channel 0, and C is channel 2, so we can
|
||||
//figure out the channel idx using modulo
|
||||
var channelIdx = RtData.Channels[i % RtData.Channels.Length];
|
||||
//per other realtime functions, we transform the ushort to a short
|
||||
if (SignedData) { adc = (short)RtData.RtData[i]; }
|
||||
else { adc = (short)(RtData.RtData[i] - 0x8000); }
|
||||
//data is in the form of ABC, so what sample we are on from the first sample can be computed
|
||||
//by dividing by the number of channels in the response
|
||||
insertPt = Convert.ToInt32(Math.Floor((double)i / RtData.Channels.Length));
|
||||
|
||||
ChannelData[channelIdx][insertPt] = adc;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
#if REALTIME_LOGGING
|
||||
System.Diagnostics.Trace.WriteLine(ex.Message);
|
||||
#endif
|
||||
RtData = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// the sample number of the first sample in the data stream
|
||||
/// </summary>
|
||||
public ulong SampleNumber => RtData.SampleNumber;
|
||||
|
||||
public ulong TimeStamp => RtData.TimeStamp;
|
||||
|
||||
public ulong SequenceNumber => RtData.SequenceNumber;
|
||||
/// <summary>
|
||||
/// All channel data for the DAS, note that if a channel is not in realtime
|
||||
/// then it's short data values or not defined
|
||||
/// this is all channels.
|
||||
/// </summary>
|
||||
private short[][] ChannelData { get; set; }
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// gets the sample data for a given channel index
|
||||
/// </summary>
|
||||
/// <param name="zeroBasedChannel"></param>
|
||||
/// <returns></returns>
|
||||
public short[] GetChannelData(int zeroBasedChannel)
|
||||
{
|
||||
return ChannelData[zeroBasedChannel];
|
||||
}
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// this is the total number of channels on the DAS
|
||||
/// this is used to build ChannelData
|
||||
/// </summary>
|
||||
public ushort Channels { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// count of how many samples have been performed
|
||||
/// if data is ABCABCABC, then there are 3 samples returned
|
||||
/// </summary>
|
||||
public int SamplesReturned => RtData?.RtData.Length / RtData?.Channels.Length ?? 0;
|
||||
|
||||
/// <summary>
|
||||
/// We need to override SyncExecute because we don't want to send anything. Instead we just want to
|
||||
/// read whatever is out there. Otherwise this is mostly cut and paste of normal SyncExecute with some streamlining for our specific case.
|
||||
/// </summary>
|
||||
public override void SyncExecute()
|
||||
{
|
||||
// this is a try/finally to handle the ExecuteIsBusy
|
||||
try
|
||||
{
|
||||
// there can be only one!
|
||||
recorder.ExecuteIsBusy = true;
|
||||
|
||||
if (recorder.IsCanceled())
|
||||
{
|
||||
throw new CanceledException();
|
||||
}
|
||||
|
||||
UserCallback = null;
|
||||
UserCallbackData = null;
|
||||
IsSynchronous = true;
|
||||
SyncEvent.Reset();
|
||||
recorder.PseudoExecute(new byte[0], ExecuteCallback, null, IO_Timeout);
|
||||
|
||||
var syncExecTimeout = IO_Timeout;
|
||||
|
||||
try
|
||||
{
|
||||
if (!WaitWithCondition.Wait(SyncEvent, syncExecTimeout,
|
||||
recorder.CancelEvent))
|
||||
{
|
||||
//timeout
|
||||
LogString("SyncExecute: timeout");
|
||||
throw new TimeoutException(MakeLogString("SyncExecute: timeout"));
|
||||
}
|
||||
}
|
||||
catch (WaitWithCondition.ConditionMetException)
|
||||
{
|
||||
throw new CanceledException();
|
||||
}
|
||||
|
||||
// we didn't timeout, check the result
|
||||
switch (ComReport.Result)
|
||||
{
|
||||
case CommunicationConstantsAndEnums.CommunicationResult.Canceled:
|
||||
throw new CanceledException();
|
||||
|
||||
case CommunicationConstantsAndEnums.CommunicationResult.ReceiveOK:
|
||||
if (baseResponse == null)
|
||||
{
|
||||
LogString("SyncExecute: ReceiveOK but response==null!");
|
||||
LogCommand(false);
|
||||
}
|
||||
|
||||
if (baseResponse.Status != DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
// didn't go well
|
||||
var msg = MakeLogString("SyncExecute: response.Status = " + baseResponse.Status);
|
||||
LogCommand(false);
|
||||
if (baseResponse.Status == DFConstantsAndEnums.CommandStatus.StatusInvalidModeForCommand)
|
||||
{
|
||||
throw new CommandException(CommandErrorReason.InvalidMode, msg);
|
||||
}
|
||||
if (baseResponse.Status == DFConstantsAndEnums.CommandStatus.StatusUnimplemented ||
|
||||
baseResponse.Status == DFConstantsAndEnums.CommandStatus.StatusInvalidCommand ||
|
||||
baseResponse.Status == DFConstantsAndEnums.CommandStatus.StatusInvalidCommandType)
|
||||
{
|
||||
throw new NotImplementedException(msg);
|
||||
}
|
||||
var ex = new Exception(msg);
|
||||
ex.Data.Add("Status", baseResponse.Status);
|
||||
APILogger.Log(ex);
|
||||
}
|
||||
|
||||
// everything is fine, let it exit
|
||||
if (LogCommands)
|
||||
{
|
||||
LogCommand(false);
|
||||
}
|
||||
break;
|
||||
|
||||
case CommunicationConstantsAndEnums.CommunicationResult.ReceiveFailed:
|
||||
{
|
||||
var msg = MakeLogString("SyncExecute: ComReport.Result == " + ComReport.Result);
|
||||
LogCommand(false);
|
||||
|
||||
throw new CommandException(CommandErrorReason.ReceiveFailed, msg);
|
||||
}
|
||||
case CommunicationConstantsAndEnums.CommunicationResult.ReceiveTimeout:
|
||||
{
|
||||
var msg = MakeLogString("SyncExecute: ComReport.Result == " + ComReport.Result);
|
||||
LogCommand(false);
|
||||
throw new CommandException(CommandErrorReason.ReceiveFailed, msg);
|
||||
}
|
||||
|
||||
case CommunicationConstantsAndEnums.CommunicationResult.SendFailed:
|
||||
case CommunicationConstantsAndEnums.CommunicationResult.SendTimeout:
|
||||
{
|
||||
var msg = MakeLogString("SyncExecute: ComReport.Result == " + ComReport.Result);
|
||||
LogCommand(false);
|
||||
throw new CommandException(CommandErrorReason.SendFailed, msg);
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
var msg = MakeLogString("SyncExecute: Unknown ComReport.Result == " + ComReport.Result);
|
||||
LogCommand(false);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
recorder.ExecuteIsBusy = false;
|
||||
ProcessData();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.RealtimeCommands
|
||||
{
|
||||
/// <summary>
|
||||
/// this class was ported from FWTU RealtimeCommands, it appears almost verbatim to there
|
||||
/// </summary>
|
||||
public class UDPRealtimeByteConverter
|
||||
{
|
||||
public enum UDP_BYTE_INDEX
|
||||
{
|
||||
PKT_PATTERN = 0, // u16
|
||||
CHANNEL_ID = 2, // u16
|
||||
PKT_LEN = 4, // u32
|
||||
DATA_LEN = 8, // u32
|
||||
DATA_TYPE_VER = 12, // u8
|
||||
SEQ_NUMBER = 13, // u8
|
||||
PKT_FLAGS = 14, // u8
|
||||
DATA_TYPE = 15, // u8
|
||||
REL_TIME32 = 16, // u32 of 48
|
||||
REL_TIME16 = 20, // u16
|
||||
HDR_CRC16 = 22, // u16
|
||||
PTP_U32_LSW = 24, // u32
|
||||
PTP_U32_MSW = 28, // u32
|
||||
RSV_U16 = 32, // u32
|
||||
HDR2CRC16 = 34, // u16
|
||||
CSDW = 36, // u32
|
||||
DATA_START = 40, // data start address
|
||||
}
|
||||
|
||||
// This is list of data type for UDP to support
|
||||
public enum UDP_DATA_TYPE
|
||||
{
|
||||
// 0x21 for analog format 1. 0x01 = CGDP format 1 (setup record). 0x12 = Time Data, Format 2 (PTP time)
|
||||
CGDP_TYPE = 0x01, // Setup XML record. 1. Setup Record, periodic message sent out.
|
||||
TIME_DATA_PTP = 0x12, // Time data, format 2. Periodic message.
|
||||
ANALOG_DATA_FORMAT_1 = 0x21, // Analog data format 3. Periodic message.
|
||||
}
|
||||
public ushort PacketPattern { get; private set; }
|
||||
public ushort DataChannelID { get; private set; }
|
||||
public uint PacketLength { get; private set; }
|
||||
/// <summary>
|
||||
/// careful if you use this, it's not the same as
|
||||
/// RtData.Length ...
|
||||
/// </summary>
|
||||
public uint DataLength { get; private set; }
|
||||
public byte DataTypeVersion { get; private set; }
|
||||
public byte SequenceNumber { get; private set; }
|
||||
public byte PacketFlags { get; private set; }
|
||||
public byte DataType { get; private set; }
|
||||
public uint RelativeTime32 { get; private set; }
|
||||
public ushort RelativeTime16 { get; private set; }
|
||||
public ushort HdrCrc16 { get; private set; }
|
||||
public uint PtpTimeStampSec { get; private set; }
|
||||
public uint PtpTimeStampNsec { get; private set; }
|
||||
public uint Hdr2Crc16 { get; private set; }
|
||||
public uint ChannelMask { get; private set; }
|
||||
public ulong UdpSampleCount { get; private set; }
|
||||
|
||||
public ushort[] RtData { get; private set; }
|
||||
|
||||
public uint[] Channels { get; private set; }
|
||||
public byte SequenceNumberPrev { get; private set; }
|
||||
|
||||
public UDPRealtimeByteConverter(byte[] bytes)
|
||||
{
|
||||
// TBD: Currently expect 36byte header. If simplified version with 24Byte,
|
||||
// we have to account for the right offset. RTC will be used then.
|
||||
PacketPattern = GetUShort(bytes, (int)UDP_BYTE_INDEX.PKT_PATTERN);
|
||||
DataChannelID = GetUShort(bytes, (int)UDP_BYTE_INDEX.CHANNEL_ID);
|
||||
PacketLength = GetUInt(bytes, (int)UDP_BYTE_INDEX.PKT_LEN);
|
||||
DataLength = GetUInt(bytes, (int)UDP_BYTE_INDEX.DATA_LEN);
|
||||
DataTypeVersion = GetByte(bytes, (int)UDP_BYTE_INDEX.DATA_TYPE_VER);
|
||||
SequenceNumber = GetByte(bytes, (int)UDP_BYTE_INDEX.SEQ_NUMBER);
|
||||
PacketFlags = GetByte(bytes, (int)UDP_BYTE_INDEX.PKT_FLAGS);
|
||||
DataType = GetByte(bytes, (int)UDP_BYTE_INDEX.DATA_TYPE); // 0x21 for analog format 1. 0x01 = CGDP format 1 (setup record). 0x12 = Time Data, Format 2 (PTP time)
|
||||
RelativeTime32 = GetUInt(bytes, (int)UDP_BYTE_INDEX.REL_TIME32);
|
||||
RelativeTime16 = GetUShort(bytes, (int)UDP_BYTE_INDEX.REL_TIME16);
|
||||
HdrCrc16 = GetUShort(bytes, (int)UDP_BYTE_INDEX.HDR_CRC16);
|
||||
PtpTimeStampSec = GetUInt(bytes, (int)UDP_BYTE_INDEX.PTP_U32_MSW);
|
||||
PtpTimeStampNsec = GetUInt(bytes, (int)UDP_BYTE_INDEX.PTP_U32_LSW);
|
||||
Hdr2Crc16 = GetUShort(bytes, (int)UDP_BYTE_INDEX.HDR2CRC16);
|
||||
|
||||
if (DataType == (int)UDP_DATA_TYPE.ANALOG_DATA_FORMAT_1)
|
||||
{
|
||||
RtData = new ushort[(DataLength - 4) / 2]; // ushort[(bytes.Length - (int)UDP_BYTE_INDEX.DATA_START) / 2];
|
||||
|
||||
var mychannels = new List<uint>();
|
||||
|
||||
for (var i = 0; i < 6; i++) // var length = dataLength;
|
||||
{
|
||||
//if (ba.Get(i)) assume all 6 channels if UDP.
|
||||
{
|
||||
mychannels.Add(Convert.ToUInt32(i));
|
||||
}
|
||||
}
|
||||
Channels = mychannels.ToArray();
|
||||
UdpSampleCount = Convert.ToUInt64(RtData.Length / Channels.Length);
|
||||
|
||||
SequenceNumberPrev = SequenceNumber;
|
||||
|
||||
// TBD: check for pktFlag if the optional 2nd header is being used or not. If not,
|
||||
// we can start the data from UDP_BYTE_INDEX.PTP_U32_LSW
|
||||
for (var idx = 0; idx < RtData.Length; idx++)
|
||||
{
|
||||
RtData[idx] = GetRTUShort(bytes, (int)(UDP_BYTE_INDEX.DATA_START + idx * 2));
|
||||
RtData[idx] ^= 0x8000;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// TBD for other packet types.
|
||||
RtData = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static ulong GetULong(byte[] bytes, int offset)
|
||||
{
|
||||
return (ulong)bytes[offset + 7] << 0 |
|
||||
(ulong)bytes[offset + 6] << 8 |
|
||||
(ulong)bytes[offset + 5] << 16 |
|
||||
(ulong)bytes[offset + 4] << 24 |
|
||||
(ulong)bytes[offset + 3] << 32 |
|
||||
(ulong)bytes[offset + 2] << 40 |
|
||||
(ulong)bytes[offset + 1] << 48 |
|
||||
(ulong)bytes[offset + 0] << 56;
|
||||
}
|
||||
|
||||
private static ushort GetUShort(byte[] bytes, int offset)
|
||||
{
|
||||
return (ushort)(bytes[offset + 1] |
|
||||
bytes[offset + 0] << 8);
|
||||
}
|
||||
|
||||
private static byte GetByte(byte[] bytes, int offset)
|
||||
{
|
||||
return bytes[offset];
|
||||
}
|
||||
private static uint GetUInt(byte[] bytes, int offset)
|
||||
{
|
||||
return (uint)bytes[offset + 3] << 0 |
|
||||
(uint)bytes[offset + 2] << 8 |
|
||||
(uint)bytes[offset + 1] << 16 |
|
||||
(uint)bytes[offset + 0] << 24;
|
||||
}
|
||||
/// <summary>
|
||||
/// data apparently has a different byte order than parameters, so we have to
|
||||
/// rearrange byte order for parameters but not data.
|
||||
/// </summary>
|
||||
/// <param name="bytes"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <returns></returns>
|
||||
private static ushort GetRTUShort(byte[] bytes, int offset)
|
||||
{
|
||||
return (ushort)(bytes[offset + 0] |
|
||||
bytes[offset + 1] << 8);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Reflection;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using DTS.Common.ICommunication;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE
|
||||
{
|
||||
public abstract class CommandBase : SliceCommandBase
|
||||
{
|
||||
public CommandBase(DTS.Common.Interface.DASFactory.ICommunication sock) : base(sock)
|
||||
{
|
||||
command = new CommandPacket();
|
||||
}
|
||||
|
||||
public CommandBase(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec) : base(sock, TimeoutMillisec)
|
||||
{
|
||||
command = new CommandPacket();
|
||||
}
|
||||
|
||||
protected override CommandPacketBase GetCommandPacket()
|
||||
{
|
||||
return new CommandPacket();
|
||||
}
|
||||
protected override CommandPacketBase GetCommandPacket(byte[] buffer)
|
||||
{
|
||||
return new CommandPacket(buffer);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ClassDiagram MajorVersion="1" MinorVersion="1">
|
||||
<Class Name="DTS.DASLib.Command.SLICE.MulticastCommands.MACTableEntry" Collapsed="true">
|
||||
<Position X="8.25" Y="5.25" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAABAAAAAAAAAAAEAAAAAACBAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>MulticastCommands\MACTableEntry.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.MulticastCommands.DiscoveredConnectedSlice" Collapsed="true">
|
||||
<Position X="6.5" Y="5.25" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAACAAAAAAA=</HashCode>
|
||||
<FileName>MulticastCommands\MACTableEntry.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.MulticastCommands.MulticastAutoDiscover" Collapsed="true">
|
||||
<Position X="14" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>EAAACUEAAAIAIAgIAEBAFABACAgRgAACQCQACWAAABA=</HashCode>
|
||||
<FileName>MulticastCommands\MulticastAutoDiscover.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.MulticastCommands.MulticastCommandBase" Collapsed="true">
|
||||
<Position X="15.25" Y="0.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>IAACgAAJEABAAAAAIIAEBggQwAAAwCAAFAEIgsgQAAA=</HashCode>
|
||||
<FileName>MulticastCommands\MulticastCommandBase.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.MulticastCommands.MulticastDiscoverSlice6" Collapsed="true">
|
||||
<Position X="25.25" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>QAIACQAAACMKAAAAABAABARAAAgTiAAAQAAQIWAAQEA=</HashCode>
|
||||
<FileName>MulticastCommands\MulticastDiscoverSlice6.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.MulticastCommands.MulticastGetDhcp" Collapsed="true">
|
||||
<Position X="0.5" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAQAAAAABABAAAAAAAAAAAAAAEAAAEA=</HashCode>
|
||||
<FileName>MulticastCommands\MulticastGetDhcp.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.MulticastCommands.MulticastGetDnsAddress" Collapsed="true">
|
||||
<Position X="7.25" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAEAAAAAAAAAAAAAAEAABABAAAAAAAAAAAAAAEAAAEA=</HashCode>
|
||||
<FileName>MulticastCommands\MulticastGetDnsAddress.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.MulticastCommands.MulticastGetGatewayAddress" Collapsed="true">
|
||||
<Position X="16.25" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAACAAAAAAAAAAAAAAAJABAAAAAAAAAAAAAAEAAAEA=</HashCode>
|
||||
<FileName>MulticastCommands\MulticastGetGatewayAddress.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.MulticastCommands.MulticastGetIpAddress" Collapsed="true">
|
||||
<Position X="20.75" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAABABABAAAAAAAAAAAAAAEAAIEA=</HashCode>
|
||||
<FileName>MulticastCommands\MulticastGetIpAddress.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.MulticastCommands.MulticastGetSubnetAddress" Collapsed="true">
|
||||
<Position X="27.5" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAABABAAAAAAACAAAAAAEAAAFA=</HashCode>
|
||||
<FileName>MulticastCommands\MulticastGetSubnetAddress.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.MulticastCommands.MulticastIdentify" Collapsed="true">
|
||||
<Position X="2.75" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAABABAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>MulticastCommands\MulticastIdentify.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.MulticastCommands.MulticastResetMcu" Collapsed="true">
|
||||
<Position X="9.5" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAABABAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>MulticastCommands\MulticastResetMcu.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.MulticastCommands.MulticastSetDhcp" Collapsed="true">
|
||||
<Position X="18.5" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAQAAAAABABAAAAAAAAAQAAAAAAAAAA=</HashCode>
|
||||
<FileName>MulticastCommands\MulticastSetDhcp.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.MulticastCommands.MulticastSetDnsAddress" Collapsed="true">
|
||||
<Position X="23" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAEAAAAAAAAAAAAAAEAABABAAAAAAAAAQAAAAAAAAAA=</HashCode>
|
||||
<FileName>MulticastCommands\MulticastSetDnsAddress.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.MulticastCommands.MulticastSetGatewayAddress" Collapsed="true">
|
||||
<Position X="29.75" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAACAAAAAAAAAAAAAAAJABAAAAAAAAAQAAAAAAAAAA=</HashCode>
|
||||
<FileName>MulticastCommands\MulticastSetGatewayAddress.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.MulticastCommands.MulticastSetIpAddress" Collapsed="true">
|
||||
<Position X="5" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAABABABAAAAAAAAAQAAAAAAAIAA=</HashCode>
|
||||
<FileName>MulticastCommands\MulticastSetIPAddress.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.MulticastCommands.MulticastSetSubnetAddress" Collapsed="true">
|
||||
<Position X="11.75" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAABABAAAAAAACAQAAAAAAAABA=</HashCode>
|
||||
<FileName>MulticastCommands\MulticastSetSubnetAddress.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Font Name="Segoe UI" Size="9" />
|
||||
</ClassDiagram>
|
||||
@@ -0,0 +1,71 @@
|
||||
using System.Collections.Generic;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.ICommunication;
|
||||
using DTS.Common.Utilities;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.RealtimeCommands
|
||||
{
|
||||
public class RetrieveSingleSample : RealtimeCommandBase
|
||||
{
|
||||
protected override Commands _Command => Commands.RetrieveSingleSample;
|
||||
|
||||
public short[] _data;
|
||||
public short GetChannelData(int zeroBasedChannel)
|
||||
{
|
||||
return _data[zeroBasedChannel];
|
||||
}
|
||||
|
||||
public ushort Channels
|
||||
{
|
||||
get
|
||||
{
|
||||
if (null == _data) return 0;
|
||||
return (ushort)_data.Length;
|
||||
}
|
||||
}
|
||||
|
||||
public RetrieveSingleSample(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
}
|
||||
|
||||
public RetrieveSingleSample(DTS.Common.Interface.DASFactory.ICommunication sock, int timeoutMillisec)
|
||||
: base(sock, timeoutMillisec)
|
||||
{
|
||||
}
|
||||
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (response.Status == DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
// Figure out the number of samples returned
|
||||
var unsignedData = new ushort[response.Parameter.Length / 2];
|
||||
_data = new short[response.Parameter.Length / 2];
|
||||
for (var i = 0; i < response.Parameter.Length / 2; i++)
|
||||
{
|
||||
response.GetParameter(2 * i, out unsignedData[i]);
|
||||
if (unsignedData[i] > 32768)
|
||||
{
|
||||
_data[i] = (short)(unsignedData[i] - 65536);
|
||||
}
|
||||
else
|
||||
{
|
||||
_data[i] = (short)unsignedData[i];
|
||||
}
|
||||
}
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
|
||||
public override void ResponseToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.ResponseToString(ref lines);
|
||||
lines.Add(new List<string> { $"Channels: {Channels}, Data: {ArrayToString.ArrayObjectToString(_data)}" });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>9.0.21022</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{D015F93D-9507-4484-977B-4CF1BDC0B30E}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>DTS.DASLib.Command.SLICE</RootNamespace>
|
||||
<AssemblyName>SLICECommands</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<UpgradeBackupLocation>
|
||||
</UpgradeBackupLocation>
|
||||
<OldToolsVersion>3.5</OldToolsVersion>
|
||||
<TargetFrameworkProfile />
|
||||
<SccProjectName>
|
||||
</SccProjectName>
|
||||
<SccLocalPath>
|
||||
</SccLocalPath>
|
||||
<SccAuxPath>
|
||||
</SccAuxPath>
|
||||
<SccProvider>
|
||||
</SccProvider>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ArmCommands.cs" />
|
||||
<Compile Include="DownloadCommands\DownloadByteConverter.cs" />
|
||||
<Compile Include="DownloadCommands\EventDataCommands.cs" />
|
||||
<Compile Include="DownloadCommands\GetNextDownloadStreamDataSamples.cs" />
|
||||
<Compile Include="DownloadCommands\QueryEventDataBase.cs" />
|
||||
<Compile Include="DownloadCommands\QueryEventDataReport.cs" />
|
||||
<Compile Include="DownloadCommands\QueryTotalEventCount.cs" />
|
||||
<Compile Include="DownloadCommands\QueryEthernetEventData.cs" />
|
||||
<Compile Include="DownloadCommands\QueryUARTEventData.cs" />
|
||||
<Compile Include="DownloadCommands\QueryEthernetEventInfo.cs" />
|
||||
<Compile Include="DownloadCommands\QueryUARTEventInfo.cs" />
|
||||
<Compile Include="DownloadCommands\ResetEventList.cs" />
|
||||
<Compile Include="DownloadCommands\StartDownloadStreamData.cs" />
|
||||
<Compile Include="MulticastCommands\MACTableEntry.cs" />
|
||||
<Compile Include="MulticastCommands\MulticastAutoDiscover.cs" />
|
||||
<Compile Include="MulticastCommands\MulticastCommandBase.cs" />
|
||||
<Compile Include="MulticastCommands\MulticastDiscoverSlice6.cs" />
|
||||
<Compile Include="MulticastCommands\MulticastGetDhcp.cs" />
|
||||
<Compile Include="MulticastCommands\MulticastGetDnsAddress.cs" />
|
||||
<Compile Include="MulticastCommands\MulticastGetGatewayAddress.cs" />
|
||||
<Compile Include="MulticastCommands\MulticastGetIpAddress.cs" />
|
||||
<Compile Include="MulticastCommands\MulticastGetSubnetAddress.cs" />
|
||||
<Compile Include="MulticastCommands\MulticastIdentify.cs" />
|
||||
<Compile Include="MulticastCommands\MulticastResetMcu.cs" />
|
||||
<Compile Include="MulticastCommands\MulticastSetDhcp.cs" />
|
||||
<Compile Include="MulticastCommands\MulticastSetDnsAddress.cs" />
|
||||
<Compile Include="MulticastCommands\MulticastSetGatewayAddress.cs" />
|
||||
<Compile Include="MulticastCommands\MulticastSetIPAddress.cs" />
|
||||
<Compile Include="MulticastCommands\MulticastSetSubnetAddress.cs" />
|
||||
<Compile Include="MulticastCommands\MulticastUDPQueryQATS.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="AttributeCommands.cs" />
|
||||
<Compile Include="CalibrationCommands.cs" />
|
||||
<Compile Include="CommandBase.cs" />
|
||||
<Compile Include="CommandPacket.cs" />
|
||||
<Compile Include="FirmwareUpdateCommands.cs" />
|
||||
<Compile Include="InformationCommands.cs" />
|
||||
<Compile Include="Ptp1588Commands.cs" />
|
||||
<Compile Include="QAandUtilityCommands.cs" />
|
||||
<Compile Include="RealtimeCommands\EndRealtimeMode.cs" />
|
||||
<Compile Include="RealtimeCommands\GetRealtimeSamples.cs" />
|
||||
<Compile Include="RealtimeCommands\GetRealtimeSamplesSLICE2.cs" />
|
||||
<Compile Include="RealtimeCommands\GetRealtimeSamplesSLICE6.cs" />
|
||||
<Compile Include="RealtimeCommands\GetRealtimeSamplesTSRAIR.cs" />
|
||||
<Compile Include="RealtimeCommands\IGetRealtimeSamples.cs" />
|
||||
<Compile Include="RealtimeCommands\RealtimeCommandBase.cs" />
|
||||
<Compile Include="RealtimeCommands\RealtimeStreamDecoder.cs" />
|
||||
<Compile Include="RealtimeCommands\RealtimeStreamingNextSamples.cs" />
|
||||
<Compile Include="RealtimeCommands\RetrieveSampleAverage.cs" />
|
||||
<Compile Include="RealtimeCommands\RetrieveSingleSample.cs" />
|
||||
<Compile Include="RealtimeCommands\StartRealtimeMode.cs" />
|
||||
<Compile Include="RealtimeCommands\StartRealtimeStreamingMode.cs" />
|
||||
<Compile Include="RealtimeCommands\StreamConfigUDP.cs" />
|
||||
<Compile Include="RealtimeCommands\StreamReaderUDP.cs" />
|
||||
<Compile Include="RealtimeCommands\UDPRealtimeByteConverter.cs" />
|
||||
<Compile Include="RealtimeCommands\UDPStreamPacket.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Common\DTS.Common.DASResource\DTS.Common.DASResource.csproj">
|
||||
<Project>{f621ce48-bb4b-4cfc-a325-9410b721cc44}</Project>
|
||||
<Name>DTS.Common.DASResource</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\Common\DTS.Common.ICommunication\DTS.Common.ICommunication.csproj">
|
||||
<Project>{f57b954e-a49a-4110-b36c-b5abab3e230b}</Project>
|
||||
<Name>DTS.Common.ICommunication</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\Common\DTS.Common.Utilities\DTS.Common.Utilities.csproj">
|
||||
<Project>{d6da1b74-c711-43c2-91b1-1908a8d04dbf}</Project>
|
||||
<Name>DTS.Common.Utilities</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\Common\DTS.Common\DTS.Common.csproj">
|
||||
<Project>{f7a0804f-61a4-40ae-83d0-f1137622b592}</Project>
|
||||
<Name>DTS.Common</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\ICommand\ICommand.csproj">
|
||||
<Project>{58e70872-8acc-4957-bb8e-d3746bcc536d}</Project>
|
||||
<Name>ICommand</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Design\ClassDiagram_DownloadCommands.cd" />
|
||||
<None Include="Design\ClassDiagram_MulticastCommands.cd" />
|
||||
<None Include="Design\ClassDiagram_RealTimeCommands.cd" />
|
||||
<None Include="Design\ClassDiagram_SliceCommands.cd" />
|
||||
<None Include="Properties\DataSources\AttributeTypes.SystemAttributes_Bridge.datasource" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,289 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using DTS.Common.Constant;
|
||||
using DTS.Common.Enums.Communication;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.ICommunication;
|
||||
using DTS.Common.Utilities;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.RealtimeCommands
|
||||
{
|
||||
/// <summary>
|
||||
/// this "command" gets the next set of samples
|
||||
/// note that in streaming mode no actual command is sent, we just pick up whatever data is in the RECV buffer
|
||||
/// </summary>
|
||||
public class RealtimeStreamingNextSamples : CommandBase, IGetRealtimeSamples
|
||||
{
|
||||
public RealtimeStreamingNextSamples(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
baseCommand = new CommandPacket();
|
||||
}
|
||||
public RealtimeStreamingNextSamples(DTS.Common.Interface.DASFactory.ICommunication sock, int msTimeout)
|
||||
: base(sock, msTimeout)
|
||||
{
|
||||
baseCommand = new CommandPacket();
|
||||
}
|
||||
public bool DigitalInput { get; set; }
|
||||
public bool[] TransitionMode { get; set; }
|
||||
/// <summary>
|
||||
/// the realtime data sample data
|
||||
/// </summary>
|
||||
public RealtimeStreamDecoder RtData { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// these are both used in garbage packet detection
|
||||
/// sample numbers are always increasing, sequence numbers are increasing but wrap around at ushort.max
|
||||
/// we could just use only sample number and not sample number and sequence
|
||||
/// for the garbage packet detection, but the number of samples per packet can be variable
|
||||
/// (especially with different SPS and number of channels) while the sequence is always +1 increase
|
||||
/// </summary>
|
||||
private ulong _lastProcessedSampleNumber = ulong.MaxValue;
|
||||
private ushort _lastSequenceNumber = 0;
|
||||
/// <summary>
|
||||
/// this is a fairly arbitrary choice, this is just used for garbage packet detection
|
||||
/// in practical use we are unlikely to drop more than 50 sequence at 2k sps
|
||||
/// so if we have more than a 1k difference there's a good chance the packet is garbage
|
||||
/// </summary>
|
||||
private const int MAX_SEQUENCE_DELTA = 1000;
|
||||
|
||||
public void ProcessData()
|
||||
{
|
||||
try
|
||||
{
|
||||
#if REALTIME_LOGGING
|
||||
var dt = DateTime.Now;
|
||||
System.Diagnostics.Trace.WriteLine($"{dt.Hour}:{dt.Minute}:{dt.Second}.{dt.Millisecond} ProcessData");
|
||||
#endif
|
||||
RtData = null;
|
||||
System.Threading.Thread.Sleep(20);
|
||||
var bytes = baseResponse.ToBytes();
|
||||
var headerCRC = response.HeaderCRC;
|
||||
response.ComputeCRCs();
|
||||
if (response.HeaderCRC != headerCRC)
|
||||
{
|
||||
//garbage packet, don't process
|
||||
return;
|
||||
}
|
||||
if (!bytes.Any()) return;
|
||||
RtData = new RealtimeStreamDecoder(bytes);
|
||||
var bFailsSequenceCheck = false;
|
||||
|
||||
var sequenceDelta = Math.Abs(RtData.SequenceNumber - _lastSequenceNumber);
|
||||
|
||||
if (RtData.SequenceNumber != 0 && sequenceDelta > MAX_SEQUENCE_DELTA)
|
||||
{
|
||||
#if REALTIME_LOGGING
|
||||
System.Diagnostics.Trace.WriteLine("garbage packet");
|
||||
#endif
|
||||
//crc matched, but we've still got a garbage packet, as determined by looking at the sequence #
|
||||
bFailsSequenceCheck = true;
|
||||
}
|
||||
|
||||
_lastSequenceNumber = RtData.SequenceNumber;
|
||||
|
||||
if (null == RtData || RtData.SampleNumber == _lastProcessedSampleNumber || bFailsSequenceCheck)
|
||||
{
|
||||
#if REALTIME_LOGGING
|
||||
if (RtData.SampleNumber == _lastProcessedSampleNumber)
|
||||
{
|
||||
System.Diagnostics.Trace.WriteLine("Same packet #");
|
||||
}
|
||||
#endif
|
||||
RtData = null;
|
||||
return;
|
||||
}
|
||||
|
||||
#if REALTIME_LOGGING
|
||||
System.Diagnostics.Trace.WriteLine($"Processed: {RtData.SampleNumber}");
|
||||
#endif
|
||||
_lastProcessedSampleNumber = RtData.SampleNumber;
|
||||
ChannelData = new short[Channels][];
|
||||
for (var idx = 0; idx < Channels; idx++)
|
||||
{
|
||||
ChannelData[idx] = new short[SamplesReturned];
|
||||
}
|
||||
int insertPt;
|
||||
short adc;
|
||||
|
||||
for (var i = 0; i < RtData.RtData.Length; i++)
|
||||
{
|
||||
//data is in the form of ABC where A is channel 0, and C is channel 2, so we can
|
||||
//figure out the channel idx using modulo
|
||||
var channelIdx = RtData.Channels[i % RtData.Channels.Length];
|
||||
//per other realtime functions, we transform the ushort to a short
|
||||
adc = (short)(RtData.RtData[i] - 0x8000);
|
||||
//data is in the form of ABC, so what sample we are on from the first sample can be computed
|
||||
//by dividing by the number of channels in the response
|
||||
insertPt = Convert.ToInt32(Math.Floor((double)i / RtData.Channels.Length));
|
||||
|
||||
ChannelData[channelIdx][insertPt] = adc;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
#if REALTIME_LOGGING
|
||||
System.Diagnostics.Trace.WriteLine(ex.Message);
|
||||
#endif
|
||||
RtData = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// the sample number of the first sample in the data stream
|
||||
/// </summary>
|
||||
public ulong SampleNumber => RtData.SampleNumber;
|
||||
|
||||
public ulong TimeStamp => RtData.TimeStamp;
|
||||
|
||||
public ulong SequenceNumber => RtData.SequenceNumber;
|
||||
/// <summary>
|
||||
/// All channel data for the DAS, note that if a channel is not in realtime
|
||||
/// then it's short data values or not defined
|
||||
/// this is all channels.
|
||||
/// </summary>
|
||||
private short[][] ChannelData { get; set; }
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// gets the sample data for a given channel index
|
||||
/// </summary>
|
||||
/// <param name="zeroBasedChannel"></param>
|
||||
/// <returns></returns>
|
||||
public short[] GetChannelData(int zeroBasedChannel)
|
||||
{
|
||||
return ChannelData[zeroBasedChannel];
|
||||
}
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// this is the total number of channels on the DAS
|
||||
/// this is used to build ChannelData
|
||||
/// </summary>
|
||||
public ushort Channels { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// count of how many samples have been performed
|
||||
/// if data is ABCABCABC, then there are 3 samples returned
|
||||
/// </summary>
|
||||
public int SamplesReturned => RtData?.RtData.Length / RtData?.Channels.Length ?? 0;
|
||||
|
||||
/// <summary>
|
||||
/// We need to override SyncExecute because we don't want to send anything. Instead we just want to
|
||||
/// read whatever is out there. Otherwise this is mostly cut and paste of normal SyncExecute with some streamlining for our specific case.
|
||||
/// </summary>
|
||||
public override void SyncExecute()
|
||||
{
|
||||
// this is a try/finally to handle the ExecuteIsBusy
|
||||
try
|
||||
{
|
||||
// there can be only one!
|
||||
recorder.ExecuteIsBusy = true;
|
||||
|
||||
if (recorder.IsCanceled())
|
||||
{
|
||||
throw new CanceledException();
|
||||
}
|
||||
|
||||
UserCallback = null;
|
||||
UserCallbackData = null;
|
||||
IsSynchronous = true;
|
||||
SyncEvent.Reset();
|
||||
recorder.PseudoExecute(new byte[0], ExecuteCallback, null, IO_Timeout);
|
||||
|
||||
var syncExecTimeout = IO_Timeout;
|
||||
|
||||
try
|
||||
{
|
||||
if (!WaitWithCondition.Wait(SyncEvent, syncExecTimeout,
|
||||
recorder.CancelEvent))
|
||||
{
|
||||
//timeout
|
||||
LogString("SyncExecute: timeout");
|
||||
throw new TimeoutException(MakeLogString("SyncExecute: timeout"));
|
||||
}
|
||||
}
|
||||
catch (WaitWithCondition.ConditionMetException)
|
||||
{
|
||||
throw new CanceledException();
|
||||
}
|
||||
|
||||
// we didn't timeout, check the result
|
||||
switch (ComReport.Result)
|
||||
{
|
||||
case CommunicationConstantsAndEnums.CommunicationResult.Canceled:
|
||||
throw new CanceledException();
|
||||
|
||||
case CommunicationConstantsAndEnums.CommunicationResult.ReceiveOK:
|
||||
if (baseResponse == null)
|
||||
{
|
||||
LogString("SyncExecute: ReceiveOK but response==null!");
|
||||
LogCommand(false);
|
||||
}
|
||||
|
||||
if (baseResponse.Status != DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
// didn't go well
|
||||
var msg = MakeLogString("SyncExecute: response.Status = " + baseResponse.Status);
|
||||
LogCommand(false);
|
||||
if (baseResponse.Status == DFConstantsAndEnums.CommandStatus.StatusInvalidModeForCommand)
|
||||
{
|
||||
throw new CommandException(CommandErrorReason.InvalidMode, msg);
|
||||
}
|
||||
if (baseResponse.Status == DFConstantsAndEnums.CommandStatus.StatusUnimplemented ||
|
||||
baseResponse.Status == DFConstantsAndEnums.CommandStatus.StatusInvalidCommand ||
|
||||
baseResponse.Status == DFConstantsAndEnums.CommandStatus.StatusInvalidCommandType)
|
||||
{
|
||||
throw new NotImplementedException(msg);
|
||||
}
|
||||
var ex = new Exception(msg);
|
||||
ex.Data.Add("Status", baseResponse.Status);
|
||||
APILogger.Log(ex);
|
||||
}
|
||||
|
||||
// everything is fine, let it exit
|
||||
if (LogCommands)
|
||||
{
|
||||
LogCommand(false);
|
||||
}
|
||||
break;
|
||||
|
||||
case CommunicationConstantsAndEnums.CommunicationResult.ReceiveFailed:
|
||||
{
|
||||
var msg = MakeLogString("SyncExecute: ComReport.Result == " + ComReport.Result);
|
||||
LogCommand(false);
|
||||
|
||||
throw new CommandException(CommandErrorReason.ReceiveFailed, msg);
|
||||
}
|
||||
case CommunicationConstantsAndEnums.CommunicationResult.ReceiveTimeout:
|
||||
{
|
||||
var msg = MakeLogString("SyncExecute: ComReport.Result == " + ComReport.Result);
|
||||
LogCommand(false);
|
||||
throw new CommandException(CommandErrorReason.ReceiveFailed, msg);
|
||||
}
|
||||
|
||||
case CommunicationConstantsAndEnums.CommunicationResult.SendFailed:
|
||||
case CommunicationConstantsAndEnums.CommunicationResult.SendTimeout:
|
||||
{
|
||||
var msg = MakeLogString("SyncExecute: ComReport.Result == " + ComReport.Result);
|
||||
LogCommand(false);
|
||||
throw new CommandException(CommandErrorReason.SendFailed, msg);
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
var msg = MakeLogString("SyncExecute: Unknown ComReport.Result == " + ComReport.Result);
|
||||
LogCommand(false);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
recorder.ExecuteIsBusy = false;
|
||||
ProcessData();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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}" });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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}" });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
using System.Collections.Generic;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.ICommunication;
|
||||
using DTS.Common.Utilities;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.RealtimeCommands
|
||||
{
|
||||
public class RetrieveSampleAverage : RealtimeCommandBase
|
||||
{
|
||||
protected override Commands _Command => Commands.RetrieveSampleAverage;
|
||||
|
||||
const int SAMPLES_POSITION = 0;
|
||||
const int DATA_POSITION = 2;
|
||||
|
||||
private ushort _samples;
|
||||
public ushort Samples
|
||||
{
|
||||
set { _samples = value; command.SetParameter(SAMPLES_POSITION, _samples); }
|
||||
get => _samples;
|
||||
}
|
||||
|
||||
public short[] _data;
|
||||
public short GetChannelData(int zeroBasedChannel)
|
||||
{
|
||||
return _data[zeroBasedChannel];
|
||||
}
|
||||
|
||||
public ushort Channels
|
||||
{
|
||||
get
|
||||
{
|
||||
if (null == _data) return 0;
|
||||
return (ushort)_data.Length;
|
||||
}
|
||||
}
|
||||
|
||||
public RetrieveSampleAverage(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
command.Parameter = new byte[DATA_POSITION];
|
||||
}
|
||||
|
||||
public RetrieveSampleAverage(DTS.Common.Interface.DASFactory.ICommunication sock, int timeoutMillisec)
|
||||
: base(sock, timeoutMillisec)
|
||||
{
|
||||
command.Parameter = new byte[DATA_POSITION];
|
||||
}
|
||||
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
if (response.Status != DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
// Figure out how many samples were actually used to compute the means --
|
||||
// we may have requested more than the recorder has RAM to store
|
||||
response.GetParameter(SAMPLES_POSITION, out _samples);
|
||||
|
||||
// Figure out the number of channels returned and grab the means
|
||||
var numChannels = (response.Parameter.Length - 2) / 2;
|
||||
_data = new short[numChannels];
|
||||
for (var i = 0; i < numChannels; i++)
|
||||
{
|
||||
response.GetParameter(2 * i + DATA_POSITION, out _data[i]);
|
||||
}
|
||||
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
|
||||
public override void CommandToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.CommandToString(ref lines);
|
||||
lines.Add(new List<string> { $"Samples Requested: {Samples}" });
|
||||
}
|
||||
|
||||
public override void ResponseToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.ResponseToString(ref lines);
|
||||
lines.Add(new List<string>
|
||||
{
|
||||
$"Channels: {Channels}, Samples Used: {Samples}, Data: {ArrayToString.ArrayObjectToString(_data)}"
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,199 @@
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using DTS.Common.Enums;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.RealtimeCommands
|
||||
{
|
||||
/// <summary>
|
||||
/// this class was ported from FWTU
|
||||
/// </summary>
|
||||
public class StreamReaderUDP
|
||||
{
|
||||
public string StreamAddress { get; }
|
||||
|
||||
/// <summary>
|
||||
/// appears to be the parameters (line) sent to the start command
|
||||
/// </summary>
|
||||
public byte[] cmdline { get; set; }
|
||||
|
||||
private Socket _udpSocket { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// IP of our receive endpoint. Either 0.0.0.0 or a specified adapter's IP
|
||||
/// FB15531: Follow pattern for multicast AutoDiscovery in StreamReader
|
||||
/// </summary>
|
||||
public string HostIPAddress { get; set; } = IPAddress.Any.ToString();
|
||||
|
||||
public void CloseSocket()
|
||||
{
|
||||
try
|
||||
{
|
||||
_udpSocket.Close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
APILogger.LogException(e);
|
||||
}
|
||||
}
|
||||
public UDPStreamProfile UDPStreamType
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
private EndPoint _uDPEndpoint;
|
||||
public EndPoint UDPEndpoint
|
||||
{
|
||||
get => _uDPEndpoint;
|
||||
set => _uDPEndpoint = value;
|
||||
}
|
||||
|
||||
public ulong UDPSampleNumber { get; set; }
|
||||
|
||||
public StreamReaderUDP(string streamAddress, string hostAddress, UDPStreamProfile uDPStreamType, byte[] channels)
|
||||
{
|
||||
StreamAddress = streamAddress.TrimEnd('/');
|
||||
UDPSampleNumber = 0;
|
||||
UDPStreamType = uDPStreamType;
|
||||
Channels = channels;
|
||||
HostIPAddress = hostAddress;
|
||||
Configure();
|
||||
}
|
||||
|
||||
public byte[] Channels { get; set; } = new byte[0];
|
||||
|
||||
private void Configure()
|
||||
{
|
||||
// setup parameter for command
|
||||
var channelMaskAndReserved = 0; // default to all channels.
|
||||
//I'm not sure this is supported yet...
|
||||
//if (Channels.Any())
|
||||
//{
|
||||
// foreach (var ch in Channels)
|
||||
// {
|
||||
// channelMaskAndReserved |= 1 << ch;
|
||||
// }
|
||||
//}
|
||||
|
||||
var channelList = BitConverter.GetBytes(channelMaskAndReserved);
|
||||
|
||||
// create parameter for streaming command.
|
||||
cmdline = new byte[4 + StreamAddress.Length];
|
||||
var paramNetAddr = Encoding.ASCII.GetBytes(StreamAddress);
|
||||
Buffer.BlockCopy(channelList, 0, cmdline, 0, channelList.Length);
|
||||
Buffer.BlockCopy(paramNetAddr, 0, cmdline, channelList.Length,
|
||||
paramNetAddr
|
||||
.Length); // System.Buffer.BlockCopy(netAddr.ToArray(), 0, cmdline, channelList.Length, netAddr.Length);
|
||||
|
||||
|
||||
// get IP and port udp://239.1.2.10:portID
|
||||
var parts = StreamAddress.Split(':');
|
||||
if (parts.Length != 3)
|
||||
{
|
||||
throw new Exception($"Invalid UDP address:{StreamAddress}");
|
||||
}
|
||||
|
||||
// remove '//' or '/' from IP and port
|
||||
var udphost = parts[1].Trim('/');
|
||||
var udpport = parts[2].Trim('/');
|
||||
|
||||
_udpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
|
||||
var iep = IPAddress.TryParse(HostIPAddress, out var address) ? new IPEndPoint(address, Convert.ToUInt16(udpport)) : new IPEndPoint(IPAddress.Any, Convert.ToUInt16(udpport));
|
||||
UDPEndpoint = iep;
|
||||
try
|
||||
{
|
||||
_udpSocket.Bind(iep);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
APILogger.LogException(e);
|
||||
_udpSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 2000);
|
||||
_udpSocket.Bind(iep); // retry again.
|
||||
}
|
||||
|
||||
// check for udp broadcast
|
||||
var ipChecks = udphost.Split('.');
|
||||
var ipV4Check = Convert.ToInt32(ipChecks[0]);
|
||||
if ((ipV4Check >= 224) & (ipV4Check <= 239))
|
||||
{
|
||||
|
||||
var mcastOption = new MulticastOption(IPAddress.Parse(udphost));
|
||||
if (iep.Address != IPAddress.Any)
|
||||
{
|
||||
mcastOption = new MulticastOption(IPAddress.Parse(udphost), iep.Address);
|
||||
}
|
||||
|
||||
_udpSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, mcastOption); // "239.1.2.10")));
|
||||
}
|
||||
//set timer for recv_socket
|
||||
_udpSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 2000);
|
||||
}
|
||||
/// <summary>
|
||||
/// receives any packets waiting
|
||||
/// returns null if no information is ready, otherwise a structure filled with information
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public UDPStreamPacket Read()
|
||||
{
|
||||
//receive data
|
||||
var databuf = new byte[2000];
|
||||
var recv = _udpSocket.ReceiveFrom(databuf, ref _uDPEndpoint);
|
||||
if (recv <= 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var data = new byte[recv];
|
||||
Buffer.BlockCopy(databuf, 0, data, 0, recv);
|
||||
var udpData = new UDPRealtimeByteConverter(data);
|
||||
|
||||
var udpStreamPacket = new UDPStreamPacket();
|
||||
udpStreamPacket.ChannelData = new short[Channels.Length][];
|
||||
|
||||
//fun fact, sending all channels right now, so regardless of how many were configured to send, use this
|
||||
var numChannels = 6;
|
||||
//calculate how many samples are in the packet, but use the floor incase it's not complete
|
||||
var numSamples = Convert.ToUInt64(Math.Floor((double)udpData.RtData.Length / numChannels));
|
||||
for (var i = 0; i < Channels.Length; i++)
|
||||
{
|
||||
udpStreamPacket.ChannelData[i] = new short[numSamples];
|
||||
}
|
||||
|
||||
//forward declarations to reduce a little churn
|
||||
byte channel = 0;
|
||||
var list = Channels.ToList();
|
||||
var sampleIndex = 0UL;
|
||||
short adc = 0;
|
||||
|
||||
for (var i = 0; i < udpData.RtData.Length; i++)
|
||||
{
|
||||
//which channel this sample is for
|
||||
channel = Convert.ToByte(i % numChannels);
|
||||
//which channel in the list this is for
|
||||
var channelIdx = list.IndexOf(channel);
|
||||
//channel is not in list, don't care about this sample
|
||||
if (channelIdx < 0) { continue; }
|
||||
//which sample in a sequence of multiple samples this is
|
||||
sampleIndex = Convert.ToUInt64(Math.Floor((double)i / numChannels));
|
||||
//we should have all complete packets, but if there's an incomplete round
|
||||
//this will skip it
|
||||
if (sampleIndex >= numSamples) { continue; }
|
||||
//add the sample into the list of samples
|
||||
adc = (short)udpData.RtData[i];
|
||||
udpStreamPacket.ChannelData[channelIdx][sampleIndex] = adc;
|
||||
}
|
||||
udpStreamPacket.PTPTimesec = Convert.ToUInt32(udpData.PtpTimeStampSec);
|
||||
udpStreamPacket.PTPTimeNsec = Convert.ToUInt32(udpData.PtpTimeStampNsec);
|
||||
udpStreamPacket.PTPSyncStatusError = Convert.ToBoolean(udpData.PacketFlags & 0x20);
|
||||
udpStreamPacket.ADCOverflowStatus = Convert.ToBoolean(udpData.PacketFlags & 0x10);
|
||||
udpStreamPacket.TimeStamp = 0L;
|
||||
//packet does not contain a sample number, so we calculate it
|
||||
udpStreamPacket.SampleNumber = udpData.SequenceNumber * numSamples;
|
||||
return udpStreamPacket;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
using DTS.Common.ICommunication;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.DownloadCommands
|
||||
{
|
||||
/// <summary>
|
||||
/// this was ported almost directly from FirmwareTestUtility, where it was written by Loc Pham
|
||||
/// this was done for
|
||||
/// 10573 implement SW side of single command/streaming download
|
||||
/// this command should put SLICE2 firmware >= A1N4 into download streaming mode
|
||||
/// any command should be sufficient to stop this streaming early
|
||||
/// </summary>
|
||||
public class StartDownloadStreamData : EventDataCommands
|
||||
{
|
||||
protected override Commands Command => Commands.StartDownloadStreamData;
|
||||
|
||||
public StartDownloadStreamData(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
command.Parameter = new byte[18];
|
||||
}
|
||||
|
||||
public StartDownloadStreamData(DTS.Common.Interface.DASFactory.ICommunication sock, int timeoutMillisec)
|
||||
: base(sock, timeoutMillisec)
|
||||
{
|
||||
command.Parameter = new byte[18];
|
||||
}
|
||||
|
||||
public const byte AllChannels = 0xFF;
|
||||
|
||||
private ushort _eventNumber;
|
||||
private ulong _firstSample;
|
||||
private ulong _lastSample;
|
||||
|
||||
public ushort EventNumber
|
||||
{
|
||||
get => _eventNumber;
|
||||
set
|
||||
{
|
||||
_eventNumber = value;
|
||||
command.SetParameter(0, _eventNumber);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual ulong FirstSample
|
||||
{
|
||||
get => _firstSample;
|
||||
set
|
||||
{
|
||||
_firstSample = value;
|
||||
command.SetParameter(2, _firstSample);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual ulong LastSample
|
||||
{
|
||||
get => _lastSample;
|
||||
set
|
||||
{
|
||||
_lastSample = value;
|
||||
command.SetParameter(10, _lastSample);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using DTS.Common.ICommunication;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.RealtimeCommands
|
||||
{
|
||||
public class EndRealtimeMode : RealtimeCommandBase
|
||||
{
|
||||
protected override Commands _Command => Commands.EndRealtimeMode;
|
||||
|
||||
public EndRealtimeMode(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
}
|
||||
|
||||
public EndRealtimeMode(DTS.Common.Interface.DASFactory.ICommunication sock, int timeoutMillisec)
|
||||
: base(sock, timeoutMillisec)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,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}" });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
using System.Collections.Generic;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.ICommunication;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.RealtimeCommands
|
||||
{
|
||||
public class GetRealtimeSamplesSLICE2 : GetRealtimeSamples
|
||||
{
|
||||
public GetRealtimeSamplesSLICE2(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock) { LogCommands = false; }
|
||||
|
||||
public GetRealtimeSamplesSLICE2(DTS.Common.Interface.DASFactory.ICommunication sock, int timeoutMillisec)
|
||||
: base(sock, timeoutMillisec) { LogCommands = false; }
|
||||
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (response.Status == DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
// Figure out the number of samples returned
|
||||
var samplesReturned = (response.ParameterLength - 8) / (_channels * 2);
|
||||
_samplesReturned = samplesReturned;
|
||||
_data = new List<short[]>(_channels);
|
||||
|
||||
// Grab the sample number
|
||||
if (response.ParameterLength > 0)
|
||||
{
|
||||
response.GetParameter(0, out _sampleNumber);
|
||||
}
|
||||
|
||||
// Create the data arrays by channel
|
||||
for (var i = 0; i < _channels; i++)
|
||||
{
|
||||
_data.Add(new short[samplesReturned]);
|
||||
}
|
||||
|
||||
// Grab the data
|
||||
var parameter = 8;
|
||||
for (var sample = 0; sample < samplesReturned; sample++)
|
||||
{
|
||||
for (var channel = 0; channel < _channels; channel++)
|
||||
{
|
||||
response.GetParameter(parameter, out ushort val);
|
||||
//changed from unsigned to signed
|
||||
_data[channel][sample] = (short)((((val & 0x00FF) << 8) | ((val >> 8) & 0x00FF)) + 0x8000);
|
||||
|
||||
parameter += 2;
|
||||
}
|
||||
}
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
_samplesReturned = 0;
|
||||
}
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,43 @@
|
||||
namespace DTS.DASLib.Command.SLICE.RealtimeCommands
|
||||
{
|
||||
/// <summary>
|
||||
/// this interface describes objects that are able to get realtime samples from
|
||||
/// SLICE devices, the implementation differs based on whether it's using streaming
|
||||
/// or is a SLICE6 device, etc, but all still operate through the same interface
|
||||
/// </summary>
|
||||
public interface IGetRealtimeSamples
|
||||
{
|
||||
/// <summary>
|
||||
/// returns the sample number for the first sample, with all samples after that being consecutive
|
||||
/// </summary>
|
||||
ulong SampleNumber { get; }
|
||||
ulong TimeStamp { get; }
|
||||
|
||||
ulong SequenceNumber { get; }
|
||||
/// <summary>
|
||||
/// returns all samples for the given channel
|
||||
/// </summary>
|
||||
/// <param name="zeroBasedChannel"></param>
|
||||
/// <returns></returns>
|
||||
short[] GetChannelData(int zeroBasedChannel);
|
||||
/// <summary>
|
||||
/// right now this holds the total channel count for the unit
|
||||
/// </summary>
|
||||
ushort Channels { get; set; }
|
||||
/// <summary>
|
||||
/// the count of samples per channel that were returned
|
||||
/// if return value is 10 and there's 10 channels, there's 100 samples, or 10 samples per 10 channels
|
||||
/// </summary>
|
||||
int SamplesReturned { get; }
|
||||
/// <summary>
|
||||
/// whether to log the command or not
|
||||
/// (not applicable on streaming mode as no command is executed)
|
||||
/// default is normally false otherwise the log will be spammy
|
||||
/// </summary>
|
||||
bool LogCommands { get; set; }
|
||||
/// <summary>
|
||||
/// this is the execute that retrieves samples
|
||||
/// </summary>
|
||||
void SyncExecute();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("SLICECommands")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("SLICECommands")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2008")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("B97BAF22-3B93-4187-9438-848AC714A144")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
[assembly: AssemblyVersion("1.06.0081")]
|
||||
[assembly: AssemblyFileVersion("1.06.0081")]
|
||||
@@ -0,0 +1,307 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.RealtimeCommands
|
||||
{
|
||||
/// <summary>
|
||||
/// these classes was ported from FWTU
|
||||
/// </summary>
|
||||
public class StreamConfigUDPGet : RealtimeCommandBase
|
||||
{
|
||||
private const int COMMAND_PAYLOAD_SIZE = 65;
|
||||
|
||||
protected override Commands _Command => Commands.I106StreamConfigGet;
|
||||
|
||||
private byte _stream_profile_number;
|
||||
private byte[] _udpipport;
|
||||
private ushort _timechannelid;
|
||||
private ushort _datachannelid;
|
||||
private uint _tmnsPcmSubFrameId; // _tmns0;
|
||||
private uint _tmnsMsgId; // _tmns1;
|
||||
private uint _tmnsPcmMinorPerMajor; // _tmns2;
|
||||
private uint _tmnsTmatsPortNumber; // _tmns3;
|
||||
private uint _ienaUdpSrcPortNumber; // _tmns4;
|
||||
private uint _udpRsv1; // _tmns5;
|
||||
private uint _udpRsv2; // _tmns6;
|
||||
private uint _udpRsv3; // _tmns7;
|
||||
|
||||
public byte Stream_Profile_Number
|
||||
{
|
||||
get => _stream_profile_number;
|
||||
set { _stream_profile_number = value; command.SetParameter(0, _stream_profile_number); }
|
||||
}
|
||||
public byte[] UdpIpPort
|
||||
{
|
||||
get { return _udpipport; }
|
||||
set { _udpipport = value; command.SetParameter(1, _udpipport); }
|
||||
}
|
||||
public ushort TimeChannelID
|
||||
{
|
||||
get => _timechannelid;
|
||||
set { _timechannelid = value; command.SetParameter(29, _timechannelid); }
|
||||
}
|
||||
|
||||
public ushort DataChannelID
|
||||
{
|
||||
get => _datachannelid;
|
||||
set { _datachannelid = value; command.SetParameter(31, _datachannelid); }
|
||||
}
|
||||
|
||||
public uint TMNS_PCMSUBFRAMEID
|
||||
{
|
||||
get => _tmnsPcmSubFrameId;
|
||||
set
|
||||
{
|
||||
_tmnsPcmSubFrameId = value;
|
||||
command.SetParameter(33, _tmnsPcmSubFrameId);
|
||||
}
|
||||
}
|
||||
public uint TMNS_MSGID
|
||||
{
|
||||
get { return _tmnsMsgId; }
|
||||
set
|
||||
{
|
||||
_tmnsMsgId = value; command.SetParameter(37, _tmnsMsgId);
|
||||
}
|
||||
}
|
||||
public uint TMNS_PCMINORPERMAJOR
|
||||
{
|
||||
get => _tmnsPcmMinorPerMajor;
|
||||
set
|
||||
{
|
||||
_tmnsPcmMinorPerMajor = value; command.SetParameter(41, _tmnsPcmMinorPerMajor);
|
||||
}
|
||||
}
|
||||
public uint TMNS_TMATSPORTNUMBER
|
||||
{
|
||||
get => _tmnsTmatsPortNumber;
|
||||
set
|
||||
{
|
||||
_tmnsTmatsPortNumber = value; command.SetParameter(45, _tmnsTmatsPortNumber);
|
||||
}
|
||||
}
|
||||
public uint IENAUDP_PortNumber
|
||||
{
|
||||
get => _ienaUdpSrcPortNumber;
|
||||
set
|
||||
{
|
||||
_ienaUdpSrcPortNumber = value; command.SetParameter(49, _ienaUdpSrcPortNumber);
|
||||
}
|
||||
}
|
||||
public uint TMNS5
|
||||
{
|
||||
get => _udpRsv1;
|
||||
set
|
||||
{
|
||||
_udpRsv1 = value; command.SetParameter(53, _udpRsv1);
|
||||
}
|
||||
}
|
||||
public uint TMNS6
|
||||
{
|
||||
get => _udpRsv2;
|
||||
set
|
||||
{
|
||||
_udpRsv2 = value; command.SetParameter(57, _udpRsv2);
|
||||
}
|
||||
}
|
||||
public uint TMNS7
|
||||
{
|
||||
get => _udpRsv3;
|
||||
set
|
||||
{
|
||||
_udpRsv3 = value; command.SetParameter(61, _udpRsv3);
|
||||
}
|
||||
}
|
||||
public StreamConfigUDPGet(Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
command.Parameter = new byte[COMMAND_PAYLOAD_SIZE];
|
||||
}
|
||||
|
||||
public StreamConfigUDPGet(Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
command.Parameter = new byte[COMMAND_PAYLOAD_SIZE];
|
||||
}
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
if (response.Status == DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
if (response.ParameterLength > 0)
|
||||
{
|
||||
response.GetParameter(0, out _stream_profile_number);
|
||||
_udpipport = new byte[29];
|
||||
for (int i = 0; i < 28; i++)
|
||||
{
|
||||
response.GetParameter(1 + i, out _udpipport[i]);
|
||||
}
|
||||
response.GetParameter(29, out _timechannelid);
|
||||
response.GetParameter(31, out _datachannelid);
|
||||
response.GetParameter(33, out _tmnsPcmSubFrameId);
|
||||
response.GetParameter(37, out _tmnsMsgId);
|
||||
response.GetParameter(41, out _tmnsPcmMinorPerMajor);
|
||||
response.GetParameter(45, out _tmnsTmatsPortNumber);
|
||||
response.GetParameter(49, out _ienaUdpSrcPortNumber);
|
||||
response.GetParameter(53, out _udpRsv1);
|
||||
response.GetParameter(57, out _udpRsv2);
|
||||
response.GetParameter(61, out _udpRsv3);
|
||||
}
|
||||
else { _stream_profile_number = 0; }
|
||||
}
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
|
||||
public override void ResponseToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.ResponseToString(ref lines);
|
||||
lines.Add(new List<string>() { $"Stream Profile Number: {_stream_profile_number}" });
|
||||
lines.Add(new List<string>() { $"UDP IP PORT: {_udpipport}" });
|
||||
lines.Add(new List<string>() { $"Time Channel ID: {_timechannelid}" });
|
||||
lines.Add(new List<string>() { $"Data Channel ID: {_timechannelid}" });
|
||||
lines.Add(new List<string>() { $"TMNS: {_tmnsPcmSubFrameId}, {_tmnsMsgId}, {_tmnsPcmMinorPerMajor}, {_tmnsTmatsPortNumber}, {_ienaUdpSrcPortNumber}, {_udpRsv1}, {_udpRsv2}, {_udpRsv3}," });
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public class StreamConfigUDPSet : RealtimeCommandBase
|
||||
{
|
||||
const int COMMAND_PAYLOAD_SIZE = 74;
|
||||
|
||||
protected override RealtimeCommandBase.Commands _Command
|
||||
{
|
||||
get { return Commands.I106StreamConfigSet; }
|
||||
}
|
||||
|
||||
private byte _stream_profile_number;
|
||||
private byte[] _udpipport;
|
||||
private ushort _irig106config0;
|
||||
private ushort _irig106config1;
|
||||
private uint _tmnsPcmSubFrameId; // _tmns0;
|
||||
private uint _tmnsMsgId; // _tmns1;
|
||||
private uint _tmnsPcmMinorPerMajor; // _tmns2;
|
||||
private uint _tmnsTmatsPortNumber; // _tmns3;
|
||||
private uint _ienaUdpSrcPortNumber; // _tmns4;
|
||||
private uint _udpRsv1; // _tmns5;
|
||||
private uint _udpRsv2; // _tmns6;
|
||||
private uint _udpRsv3; // _tmns7;
|
||||
|
||||
public byte Stream_Profile_Number
|
||||
{
|
||||
get => _stream_profile_number;
|
||||
set { _stream_profile_number = value; command.SetParameter(0, _stream_profile_number); }
|
||||
}
|
||||
public byte[] UdpIpPort
|
||||
{
|
||||
get => _udpipport;
|
||||
set
|
||||
{
|
||||
_udpipport = value;
|
||||
command.SetParameter(1, _udpipport);
|
||||
}
|
||||
}
|
||||
|
||||
public ushort Irig106Config0
|
||||
{
|
||||
get => _irig106config0;
|
||||
set
|
||||
{
|
||||
_irig106config0 = value; command.SetParameter(29, _irig106config0);
|
||||
}
|
||||
}
|
||||
|
||||
public ushort Irig106Config1
|
||||
{
|
||||
get => _irig106config1;
|
||||
set
|
||||
{
|
||||
_irig106config1 = value; command.SetParameter(31, _irig106config1);
|
||||
}
|
||||
}
|
||||
public uint TMNS_PCMSubFrameId
|
||||
{
|
||||
get => _tmnsPcmSubFrameId;
|
||||
set
|
||||
{
|
||||
_tmnsPcmSubFrameId = value; command.SetParameter(33, _tmnsPcmSubFrameId);
|
||||
}
|
||||
}
|
||||
|
||||
public uint TMNS_MsgId
|
||||
{
|
||||
get => _tmnsMsgId;
|
||||
set
|
||||
{
|
||||
_tmnsMsgId = value; command.SetParameter(37, _tmnsMsgId);
|
||||
}
|
||||
}
|
||||
public uint TMNS_PCMMinorPerMajor
|
||||
{
|
||||
get => _tmnsPcmMinorPerMajor;
|
||||
set
|
||||
{
|
||||
_tmnsPcmMinorPerMajor = value; command.SetParameter(41, _tmnsPcmMinorPerMajor);
|
||||
}
|
||||
}
|
||||
public uint TMNS_TMATSPortNumber
|
||||
{
|
||||
get => _tmnsTmatsPortNumber;
|
||||
set
|
||||
{
|
||||
_tmnsTmatsPortNumber = value; command.SetParameter(45, _tmnsTmatsPortNumber);
|
||||
}
|
||||
}
|
||||
public uint IENAUDP_PortNumber
|
||||
{
|
||||
get => _ienaUdpSrcPortNumber;
|
||||
set
|
||||
{
|
||||
_ienaUdpSrcPortNumber = value; command.SetParameter(49, _ienaUdpSrcPortNumber);
|
||||
}
|
||||
}
|
||||
public uint TMNS5
|
||||
{
|
||||
get => _udpRsv1;
|
||||
set
|
||||
{
|
||||
_udpRsv1 = value; command.SetParameter(53, _udpRsv1);
|
||||
}
|
||||
}
|
||||
public uint TMNS6
|
||||
{
|
||||
get => _udpRsv2;
|
||||
set
|
||||
{
|
||||
_udpRsv2 = value; command.SetParameter(57, _udpRsv2);
|
||||
}
|
||||
}
|
||||
public uint TMNS7
|
||||
{
|
||||
get { return _udpRsv3; }
|
||||
set
|
||||
{
|
||||
_udpRsv3 = value; command.SetParameter(61, _udpRsv3);
|
||||
}
|
||||
}
|
||||
public StreamConfigUDPSet(Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
command.Parameter = new byte[COMMAND_PAYLOAD_SIZE];
|
||||
}
|
||||
|
||||
public StreamConfigUDPSet(Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
command.Parameter = new byte[COMMAND_PAYLOAD_SIZE];
|
||||
}
|
||||
|
||||
public override void ResponseToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.ResponseToString(ref lines);
|
||||
lines.Add(new List<string>() { $"Stream Profile Number: {_stream_profile_number}" });
|
||||
lines.Add(new List<string>() { $"UDP IP PORT: {_udpipport}" });
|
||||
lines.Add(new List<string>() { $"Irig Config: {_irig106config0}" });
|
||||
lines.Add(new List<string>() { $"TMNS: {_tmnsPcmSubFrameId}, {_tmnsMsgId}, {_tmnsPcmMinorPerMajor}, {_tmnsTmatsPortNumber}, {_ienaUdpSrcPortNumber}, {_udpRsv1}, {_udpRsv2}, {_udpRsv3}," });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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) });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using DTS.Common.Enums.Communication;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.ICommunication;
|
||||
using DTS.Common.Utilities;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.DownloadCommands
|
||||
{
|
||||
/// <summary>
|
||||
/// This was ported from FirmwareTestUtility where it was written by Loc Pham
|
||||
/// it is being included for
|
||||
/// 10573 implement SW side of single command/streaming download
|
||||
/// this command can be used to collect data that has been collecting in a buffer
|
||||
/// from download streaming
|
||||
/// </summary>
|
||||
public class GetNextDownloadStreamDataSamples : EventDataCommands
|
||||
{
|
||||
protected override Commands Command => Commands.GetNextDownloadStreamDataSamples;
|
||||
|
||||
public GetNextDownloadStreamDataSamples(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
baseCommand = new CommandPacket();
|
||||
LogCommands = false;
|
||||
baseCommand.SetCommand((byte)Commands.GetNextDownloadStreamDataSamples, "GetNextDownloadStreamDataSamples");
|
||||
}
|
||||
public GetNextDownloadStreamDataSamples(DTS.Common.Interface.DASFactory.ICommunication sock, int msTimeout)
|
||||
: base(sock, msTimeout)
|
||||
{
|
||||
baseCommand = new CommandPacket();
|
||||
LogCommands = false;
|
||||
baseCommand.SetCommand((byte)Commands.GetNextDownloadStreamDataSamples, "GetNextDownloadStreamDataSamples");
|
||||
}
|
||||
|
||||
public DownloadByteConverter DlData { get; private set; }
|
||||
|
||||
private ushort _lastSequenceProcessed = ushort.MaxValue;
|
||||
private const int MAX_SEQUENCE_DIFF = 1000;
|
||||
|
||||
public void ProcessData()
|
||||
{
|
||||
var bytes = baseResponse.ToBytes();
|
||||
var headerCrc = response.HeaderCRC;
|
||||
response.ComputeCRCs();
|
||||
if (headerCrc != response.HeaderCRC)
|
||||
{
|
||||
DlData = null;
|
||||
return;
|
||||
}
|
||||
|
||||
DlData = new DownloadByteConverter(bytes);
|
||||
|
||||
if (null == DlData) { return; }
|
||||
if (_lastSequenceProcessed == DlData.SeqNumber)
|
||||
{
|
||||
DlData = null;
|
||||
return;
|
||||
}
|
||||
var delta = Math.Abs(DlData.SeqNumber - _lastSequenceProcessed);
|
||||
if (delta > MAX_SEQUENCE_DIFF && ushort.MaxValue != _lastSequenceProcessed && 0 != DlData.SeqNumber)
|
||||
{
|
||||
//per loc we shouldn't get here, the old code in the FWTU would apparently unintentionally throw an exception
|
||||
//I've preserved that code in comments below
|
||||
throw new Exception("sequence number overflow");
|
||||
//DlData = null;
|
||||
//_lastSequenceProcessed = DlData.SeqNumber;
|
||||
//return;
|
||||
}
|
||||
_lastSequenceProcessed = DlData.SeqNumber;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// We need to override SyncExecute because we don't want to send anything (that would tell the G5 to stop sending). Instead we just want to
|
||||
/// read whatever is out there. Otherwise this is mostly cut and paste of normal SyncExecute with some streamlining for our specific case.
|
||||
/// </summary>
|
||||
public override void SyncExecute()
|
||||
{
|
||||
// this is a try/finally to handle the ExecuteIsBusy
|
||||
try
|
||||
{
|
||||
DlData = null;
|
||||
// there can be only one!
|
||||
recorder.ExecuteIsBusy = true;
|
||||
|
||||
if (recorder.IsCanceled())
|
||||
{
|
||||
throw new CanceledException();
|
||||
}
|
||||
|
||||
UserCallback = null;
|
||||
UserCallbackData = null;
|
||||
IsSynchronous = true;
|
||||
SyncEvent.Reset();
|
||||
recorder.PseudoExecute(new byte[0], ExecuteCallback, null, IO_Timeout);
|
||||
|
||||
var syncExecTimeout = IO_Timeout;
|
||||
|
||||
try
|
||||
{
|
||||
if (!WaitWithCondition.Wait(SyncEvent, syncExecTimeout,
|
||||
recorder.CancelEvent))
|
||||
{
|
||||
//timeout
|
||||
LogString("SyncExecute: timeout");
|
||||
throw new TimeoutException(MakeLogString("SyncExecute: timeout"));
|
||||
}
|
||||
}
|
||||
catch (WaitWithCondition.ConditionMetException)
|
||||
{
|
||||
throw new CanceledException();
|
||||
}
|
||||
|
||||
// we didn't timeout, check the result
|
||||
switch (ComReport.Result)
|
||||
{
|
||||
case CommunicationConstantsAndEnums.CommunicationResult.Canceled:
|
||||
throw new CanceledException();
|
||||
|
||||
case CommunicationConstantsAndEnums.CommunicationResult.ReceiveOK:
|
||||
if (baseResponse == null)
|
||||
{
|
||||
LogString("SyncExecute: ReceiveOK but response==null!");
|
||||
LogCommand(false);
|
||||
}
|
||||
else if (baseResponse.Status != DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
// didn't go well
|
||||
var msg = MakeLogString("SyncExecute: response.Status = " + baseResponse.Status);
|
||||
LogCommand(false);
|
||||
switch (baseResponse.Status)
|
||||
{
|
||||
case DFConstantsAndEnums.CommandStatus.StatusInvalidModeForCommand:
|
||||
throw new CommandException(CommandErrorReason.InvalidMode, msg);
|
||||
case DFConstantsAndEnums.CommandStatus.StatusUnimplemented:
|
||||
case DFConstantsAndEnums.CommandStatus.StatusInvalidCommand:
|
||||
case DFConstantsAndEnums.CommandStatus.StatusInvalidCommandType:
|
||||
throw new NotImplementedException(msg);
|
||||
}
|
||||
var ex = new Exception(msg);
|
||||
ex.Data.Add("Status", baseResponse.Status);
|
||||
throw ex;
|
||||
}
|
||||
|
||||
// everything is fine, let it exit
|
||||
if (LogCommands)
|
||||
{
|
||||
LogCommand(false);
|
||||
}
|
||||
break;
|
||||
|
||||
case CommunicationConstantsAndEnums.CommunicationResult.ReceiveFailed:
|
||||
{
|
||||
var msg = MakeLogString("SyncExecute: ComReport.Result == " + ComReport.Result);
|
||||
LogCommand(false);
|
||||
|
||||
throw new CommandException(CommandErrorReason.ReceiveFailed, msg);
|
||||
}
|
||||
case CommunicationConstantsAndEnums.CommunicationResult.ReceiveTimeout:
|
||||
{
|
||||
var msg = MakeLogString("SyncExecute: ComReport.Result == " + ComReport.Result);
|
||||
LogCommand(false);
|
||||
throw new CommandException(CommandErrorReason.ReceiveFailed, msg);
|
||||
}
|
||||
|
||||
case CommunicationConstantsAndEnums.CommunicationResult.SendFailed:
|
||||
case CommunicationConstantsAndEnums.CommunicationResult.SendTimeout:
|
||||
{
|
||||
var msg = MakeLogString("SyncExecute: ComReport.Result == " + ComReport.Result);
|
||||
LogCommand(false);
|
||||
throw new CommandException(CommandErrorReason.SendFailed, msg);
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
var msg = MakeLogString("SyncExecute: Unknown ComReport.Result == " + ComReport.Result);
|
||||
LogCommand(false);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
recorder.ExecuteIsBusy = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,559 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.ICommunication;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE
|
||||
{
|
||||
public abstract class FirmwareUpdateCommands : CommandBase
|
||||
{
|
||||
protected enum Commands
|
||||
{
|
||||
Reserved = 0x00,
|
||||
QueryFirmwareUpdateBlockSize = 0x01,
|
||||
QueryBootloaderVersion = 0x02,
|
||||
SwitchToFirmwareUpdateMode = 0x03,
|
||||
BeginFirmwareUpdate = 0x04,
|
||||
ProgramFirmwareUpdateBlock = 0x05,
|
||||
FinishFirmwareUpdate = 0x06,
|
||||
Reboot = 0x07,
|
||||
QueryInFirmwareUpdateMode = 0x08,
|
||||
|
||||
// added to support slice pro (Bridge/IEPE) firmware update via USB.
|
||||
Load_SliceProStackFirmwareImage = 0x09, // CMDFW_LOAD_STACK_FW, // = 0x09, loading (in 400-byte blocks) firmware image to base NAND.
|
||||
Query_SliceProStackFirmwareImage = 0x0A, // CMDFW_QUERY_STACK_FW, // = 0x0A, reading block (in 400-byte blocks) of firmware image from base NAND at a time.
|
||||
Query_SliceProStackFirmwareCRC = 0x0B, // CMDFW_QUERY_STACK_FW_CRC, // = 0x0B, read firmware CRC for validation purpose.
|
||||
Start_SliceProStackFirmwareUpdate = 0x0C, // CMDFW_START_STACK_FW_UPDADE, // = 0x0C, stack module to be upgraded with firmware.
|
||||
Stop_SliceProStackFirmwareUpdate = 0x0D, // CMDFW_STOP_STACK_FW_UPDADE, // = 0x0D, stop firmware upgrade for after completes the on-going one.
|
||||
Query_SliceProStackFirmwareUpdateMode = 0x0E, // CMDFW_QUERY_STACK_FW_UPDATE_MODE, // = 0x0E, polling updatae mode from stack
|
||||
Set_SliceProStackFirmwareUpdateMode = 0x0F, // CMDFW_SET_STACK_FW_UPDATE_MODE, // = 0x0F, Set stack module to update mode
|
||||
MAX_CMDFW_COMMAND // = 0x10
|
||||
};
|
||||
|
||||
public enum FirmwareMode
|
||||
{
|
||||
FW = 0,
|
||||
BL = 1,
|
||||
BLL = 2,
|
||||
};
|
||||
|
||||
//protected const int MIN_SLICE2_FILEDATA_PROTOCOL = 130; //SLICE 2 Protocol cmd
|
||||
protected const int MAX_FILE_ID = 30; // user = 10, firmware = 20, max internally = 65. 10;
|
||||
protected const int MAX_FILE_LENGTH = 400;
|
||||
|
||||
protected abstract Commands _Command { get; }
|
||||
protected FirmwareUpdateCommands(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
command.Type = CommandPacket.CommandType.FirmwareUpdate;
|
||||
command.SetCommand((byte)_Command, _Command.ToString());
|
||||
}
|
||||
|
||||
protected FirmwareUpdateCommands(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
command.Type = CommandPacket.CommandType.FirmwareUpdate;
|
||||
command.SetCommand((byte)_Command, _Command.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public class QueryFirmwareUpdateBlockSize : FirmwareUpdateCommands
|
||||
{
|
||||
protected override Commands _Command => Commands.QueryFirmwareUpdateBlockSize;
|
||||
|
||||
private ushort _size;
|
||||
public ushort BlockSize => _size;
|
||||
|
||||
public QueryFirmwareUpdateBlockSize(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
_size = 0;
|
||||
}
|
||||
|
||||
public QueryFirmwareUpdateBlockSize(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
_size = 0;
|
||||
}
|
||||
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
if (response.Status == DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
response.GetParameter(0, out _size);
|
||||
}
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
|
||||
public override void ResponseToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.CommandToString(ref lines);
|
||||
lines.Add(new List<string>()
|
||||
{
|
||||
$"BlockSize: {BlockSize}"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public class QueryBootloaderVersion : FirmwareUpdateCommands
|
||||
{
|
||||
protected override Commands _Command => Commands.QueryBootloaderVersion;
|
||||
|
||||
private string _version = string.Empty;
|
||||
public string Version => _version;
|
||||
|
||||
public QueryBootloaderVersion(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
}
|
||||
|
||||
public QueryBootloaderVersion(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
}
|
||||
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
if (response.Status == DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
response.GetParameter(0, out _version);
|
||||
}
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
|
||||
public override void ResponseToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.ResponseToString(ref lines);
|
||||
lines.Add(new List<string>()
|
||||
{
|
||||
$"Version: {Version}"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public class SwitchToFirmwareUpdateMode : FirmwareUpdateCommands
|
||||
{
|
||||
protected override Commands _Command => Commands.SwitchToFirmwareUpdateMode;
|
||||
|
||||
public SwitchToFirmwareUpdateMode(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
}
|
||||
|
||||
public SwitchToFirmwareUpdateMode(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class BeginFirmwareUpdate : FirmwareUpdateCommands
|
||||
{
|
||||
protected override Commands _Command => Commands.BeginFirmwareUpdate;
|
||||
|
||||
public BeginFirmwareUpdate(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
}
|
||||
|
||||
public BeginFirmwareUpdate(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class ProgramFirmwareUpdateBlock : FirmwareUpdateCommands
|
||||
{
|
||||
protected override Commands _Command => Commands.ProgramFirmwareUpdateBlock;
|
||||
|
||||
private uint _address;
|
||||
private ushort _blockcrc;
|
||||
private ushort _upperlower;
|
||||
private byte[] _data;
|
||||
|
||||
public uint BlockBaseAddress
|
||||
{
|
||||
get => _address;
|
||||
set
|
||||
{
|
||||
_address = value;
|
||||
command.SetParameter(0, _address);
|
||||
}
|
||||
}
|
||||
|
||||
public ushort BlockSize { get; private set; }
|
||||
|
||||
public ushort BlockCRC16
|
||||
{
|
||||
get => _blockcrc;
|
||||
set
|
||||
{
|
||||
_blockcrc = value;
|
||||
command.SetParameter(6, _blockcrc);
|
||||
}
|
||||
}
|
||||
|
||||
public bool Upper
|
||||
{
|
||||
get => _upperlower == 1 ? true : false;
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
_upperlower = 1;
|
||||
command.SetParameter(8, _upperlower);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] Data
|
||||
{
|
||||
get => _data;
|
||||
set
|
||||
{
|
||||
if (null == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_data = value;
|
||||
if (command.Parameter.Length < value.Length + 10)
|
||||
{
|
||||
var newparameter = new byte[value.Length + 10];
|
||||
BlockSize = (ushort)value.Length;
|
||||
command.SetParameter(4, BlockSize);
|
||||
Buffer.BlockCopy(command.Parameter, 0,
|
||||
newparameter, 0, 10);
|
||||
command.Parameter = newparameter;
|
||||
Buffer.BlockCopy(_data, 0, command.Parameter, 10, _data.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ProgramFirmwareUpdateBlock(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
command.Parameter = new byte[10];
|
||||
Upper = false;
|
||||
}
|
||||
|
||||
public ProgramFirmwareUpdateBlock(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
command.Parameter = new byte[10];
|
||||
Upper = false;
|
||||
}
|
||||
|
||||
public override void CommandToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.CommandToString(ref lines);
|
||||
lines.Add(new List<string>() { $"BlockBaseAddress: {BlockBaseAddress}, BlockSize: {BlockSize}, BlockCRC16: {BlockCRC16}, Upper: {Upper}" });
|
||||
}
|
||||
}
|
||||
|
||||
public class FinishFirmwareUpdate : FirmwareUpdateCommands
|
||||
{
|
||||
protected override Commands _Command => Commands.FinishFirmwareUpdate;
|
||||
|
||||
private ushort _imagecrc;
|
||||
|
||||
public ushort ImageCRC16
|
||||
{
|
||||
get => _imagecrc;
|
||||
set
|
||||
{
|
||||
_imagecrc = value;
|
||||
command.SetParameter(0, _imagecrc);
|
||||
}
|
||||
}
|
||||
|
||||
public FinishFirmwareUpdate(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
command.Parameter = new byte[2];
|
||||
}
|
||||
|
||||
public FinishFirmwareUpdate(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
command.Parameter = new byte[2];
|
||||
}
|
||||
|
||||
public override void CommandToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.CommandToString(ref lines);
|
||||
lines.Add(new List<string>() { $"ImageCRC16: {ImageCRC16}" });
|
||||
}
|
||||
|
||||
public override void ResponseToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.ResponseToString(ref lines);
|
||||
lines.Add(new List<string>()
|
||||
{
|
||||
$"ImageCRC16: {ImageCRC16}"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public class Reboot : FirmwareUpdateCommands
|
||||
{
|
||||
protected override Commands _Command => Commands.Reboot;
|
||||
public Reboot(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
}
|
||||
|
||||
public Reboot(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class QueryInFirmwareUpdateMode : FirmwareUpdateCommands
|
||||
{
|
||||
protected override Commands _Command => Commands.QueryInFirmwareUpdateMode;
|
||||
private byte _updateMode = (byte)FirmwareMode.FW;
|
||||
public bool InUpdateMode => FirmwareMode.FW != (FirmwareMode)_updateMode;
|
||||
|
||||
public bool IsFwMode => FirmwareMode.FW == (FirmwareMode)_updateMode;
|
||||
public bool IsBlMode => FirmwareMode.BL == (FirmwareMode)_updateMode;
|
||||
public bool IsBllMode => FirmwareMode.BLL == (FirmwareMode)_updateMode;
|
||||
|
||||
public FirmwareMode Mode => (FirmwareMode)_updateMode;
|
||||
|
||||
public QueryInFirmwareUpdateMode(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
}
|
||||
|
||||
public QueryInFirmwareUpdateMode(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
}
|
||||
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
if (response.Status == DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
response.GetParameter(0, out _updateMode);
|
||||
}
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
public override void ResponseToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.ResponseToString(ref lines);
|
||||
lines.Add(new List<string>()
|
||||
{
|
||||
string.Format($"UpdateMode: {(FirmwareMode)_updateMode}")
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
///These stack firmware command updates need at least protocol version 137
|
||||
///No parameter. All slice in bootloader mode will be updated with new firmware.
|
||||
/// </summary>
|
||||
///
|
||||
public class Load_SliceProStackFirmwareImage : FirmwareUpdateCommands
|
||||
{
|
||||
protected override Commands _Command => Commands.Load_SliceProStackFirmwareImage;
|
||||
|
||||
#region Private Variables
|
||||
private readonly ushort _fileID; //Byte 0-1: 16-bit file ID ranges from 1-10.
|
||||
private uint _startByteCount;
|
||||
private byte[] _data;
|
||||
private static byte PARAM_NUM = 6;
|
||||
#endregion
|
||||
|
||||
#region Command Parameters
|
||||
|
||||
public uint StartByteCount
|
||||
{
|
||||
get => _startByteCount;
|
||||
set { _startByteCount = value; command.SetParameter(2, _startByteCount); }
|
||||
}
|
||||
|
||||
public byte[] Data
|
||||
{
|
||||
get => _data;
|
||||
set
|
||||
{
|
||||
if (null == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (MAX_FILE_LENGTH < value.Length)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
_data = value;
|
||||
//if (this.command.Parameter.Length < value.Length+ PARAM_NUM)
|
||||
//{
|
||||
byte[] newparameter = new byte[value.Length + PARAM_NUM];
|
||||
Buffer.BlockCopy(command.Parameter, 0, newparameter, 0, PARAM_NUM);
|
||||
Size = value.Length;
|
||||
command.Parameter = newparameter;
|
||||
Buffer.BlockCopy(_data, 0, command.Parameter, PARAM_NUM, _data.Length);
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
public int Size { get; private set; }
|
||||
|
||||
public int MaximumFileStreamBytes => MAX_FILE_LENGTH;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Command Functions
|
||||
public Load_SliceProStackFirmwareImage(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
command.Parameter = new byte[PARAM_NUM];
|
||||
MinimumProtocolVersion = sock.GetMinProto(DFConstantsAndEnums.ProtocolLimitedCommands.StackFirmwareUpdate);
|
||||
_data = null;
|
||||
|
||||
_fileID = 20;
|
||||
command.SetParameter(0, _fileID);
|
||||
_startByteCount = 0;
|
||||
|
||||
command.ShouldLog = false;
|
||||
}
|
||||
|
||||
public Load_SliceProStackFirmwareImage(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
command.Parameter = new byte[PARAM_NUM];
|
||||
MinimumProtocolVersion = sock.GetMinProto(DFConstantsAndEnums.ProtocolLimitedCommands.StackFirmwareUpdate);
|
||||
_data = null;
|
||||
|
||||
_fileID = 20;
|
||||
command.SetParameter(0, _fileID);
|
||||
_startByteCount = 0;
|
||||
|
||||
command.ShouldLog = false;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Log Functions
|
||||
public override void CommandToString(ref List<List<string>> lines)
|
||||
{
|
||||
lines.Add(new List<string>() { $"Store ID: {_fileID}, Start Byte: {StartByteCount}, End Byte: {Size + StartByteCount}" });
|
||||
}
|
||||
|
||||
public void LogResponse()
|
||||
{
|
||||
LogCommand(false);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
public class Start_SliceProStackFirmwareUpdate : FirmwareUpdateCommands
|
||||
{
|
||||
protected override Commands _Command => Commands.Start_SliceProStackFirmwareUpdate;
|
||||
|
||||
public Start_SliceProStackFirmwareUpdate(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
MinimumProtocolVersion = sock.GetMinProto(DFConstantsAndEnums.ProtocolLimitedCommands.StackFirmwareUpdate);
|
||||
|
||||
command.Type = CommandPacket.CommandType.FirmwareUpdate;
|
||||
command.SetCommand((byte)_Command, _Command.ToString());
|
||||
}
|
||||
|
||||
public Start_SliceProStackFirmwareUpdate(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
MinimumProtocolVersion = sock.GetMinProto(DFConstantsAndEnums.ProtocolLimitedCommands.StackFirmwareUpdate);
|
||||
|
||||
command.Type = CommandPacket.CommandType.FirmwareUpdate;
|
||||
command.SetCommand((byte)_Command, _Command.ToString());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class Set_SliceProStackFirmwareUpdateMode : FirmwareUpdateCommands
|
||||
{
|
||||
protected override Commands _Command => Commands.Set_SliceProStackFirmwareUpdateMode;
|
||||
|
||||
private int _sliceCount = 0;
|
||||
private byte[] _sliceProUpdateMode;
|
||||
|
||||
public int SliceModuleCount
|
||||
{
|
||||
get => _sliceCount;
|
||||
set
|
||||
{
|
||||
_sliceCount = value;
|
||||
_sliceProUpdateMode = new byte[_sliceCount];
|
||||
}
|
||||
}
|
||||
public byte[] SliceModuledateMode
|
||||
{
|
||||
get => _sliceProUpdateMode;
|
||||
set
|
||||
{
|
||||
for (int i = 0; i < _sliceCount; i++)
|
||||
{
|
||||
_sliceProUpdateMode[i] = value[i];
|
||||
}
|
||||
command.Parameter = _sliceProUpdateMode;
|
||||
}
|
||||
}
|
||||
|
||||
public Set_SliceProStackFirmwareUpdateMode(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
MinimumProtocolVersion = sock.GetMinProto(DFConstantsAndEnums.ProtocolLimitedCommands.StackFirmwareUpdate);
|
||||
command.Type = CommandPacket.CommandType.FirmwareUpdate;
|
||||
command.SetCommand((byte)_Command, _Command.ToString());
|
||||
}
|
||||
|
||||
public Set_SliceProStackFirmwareUpdateMode(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
MinimumProtocolVersion = sock.GetMinProto(DFConstantsAndEnums.ProtocolLimitedCommands.StackFirmwareUpdate);
|
||||
command.Type = CommandPacket.CommandType.FirmwareUpdate;
|
||||
command.SetCommand((byte)_Command, _Command.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public class Get_SliceProStackFirmwareUpdateMode : FirmwareUpdateCommands
|
||||
{
|
||||
protected override Commands _Command => Commands.Query_SliceProStackFirmwareUpdateMode;
|
||||
|
||||
public int SliceModuleCount { get; private set; } = 0;
|
||||
public byte[] SliceModuledateMode { get; private set; }
|
||||
|
||||
public Get_SliceProStackFirmwareUpdateMode(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
MinimumProtocolVersion = sock.GetMinProto(DFConstantsAndEnums.ProtocolLimitedCommands.StackFirmwareUpdate);
|
||||
command.Type = CommandPacket.CommandType.FirmwareUpdate;
|
||||
command.SetCommand((byte)_Command, _Command.ToString());
|
||||
}
|
||||
|
||||
public Get_SliceProStackFirmwareUpdateMode(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
MinimumProtocolVersion = sock.GetMinProto(DFConstantsAndEnums.ProtocolLimitedCommands.StackFirmwareUpdate);
|
||||
command.Type = CommandPacket.CommandType.FirmwareUpdate;
|
||||
command.SetCommand((byte)_Command, _Command.ToString());
|
||||
}
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
if (response.Status == DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
SliceModuleCount = response.Parameter.Length;
|
||||
SliceModuledateMode = new byte[SliceModuleCount];
|
||||
|
||||
for (int i = 0; i < SliceModuleCount; i++)
|
||||
{
|
||||
response.GetParameter(i, out SliceModuledateMode[i]);
|
||||
}
|
||||
}
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,15 @@
|
||||
namespace DTS.DASLib.Command.SLICE.DownloadCommands
|
||||
{
|
||||
public class QueryEventDataReport : ICommandReport
|
||||
{
|
||||
public object CallbackObject { get; set; }
|
||||
public CommandStatus Status { get; set; }
|
||||
public short[][] Data { get; set; }
|
||||
|
||||
public QueryEventDataReport(CommandStatus status, object cbData)
|
||||
{
|
||||
Status = status;
|
||||
CallbackObject = cbData;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,619 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using DTS.Common;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.ICommunication;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE
|
||||
{
|
||||
public abstract class Ptp1588Commands : CommandBase
|
||||
{
|
||||
public enum PtpClockType
|
||||
{
|
||||
SlaveTransparentClock = 0,
|
||||
MasterTransparentClock = 1,
|
||||
BoundaryClock = 2,
|
||||
};
|
||||
|
||||
public enum PtpMode
|
||||
{
|
||||
Slave = 0,
|
||||
Master = 1,
|
||||
Auto = 2,
|
||||
};
|
||||
|
||||
public enum PtpDelayMechanism
|
||||
{
|
||||
Undefined = 0,
|
||||
E2E = 1,
|
||||
P2P = 2,
|
||||
};
|
||||
|
||||
public enum PtpSyncStatus
|
||||
{
|
||||
NotSynced = 0,
|
||||
Synced = 1,
|
||||
};
|
||||
|
||||
public enum PtpTimestampUnits
|
||||
{
|
||||
AutoTrigger = 1,
|
||||
Event = 3,
|
||||
AdcStart = 2,
|
||||
Pps = 5,
|
||||
};
|
||||
|
||||
protected enum Commands
|
||||
{
|
||||
Reserved = 0x00,
|
||||
SetMode = 0x01,
|
||||
GetMode = 0x02,
|
||||
SetOptions = 0x03,
|
||||
GetSyncStatus = 0x04,
|
||||
SetTime = 0x05,
|
||||
GetTime = 0x06,
|
||||
GetAutoTriggerTime = 0x07,
|
||||
SetAutoTriggerTime = 0x08,
|
||||
GetTimestamp = 0x09,
|
||||
SetTriggerTimestamping = 0x0A,
|
||||
SetAdcClockFrquency = 0x0B,
|
||||
RunClockAdjustmentCalibration = 0x0C,
|
||||
SetClockSyncConfig = 0x0d,
|
||||
GetClockSyncConfig = 0x0e,
|
||||
};
|
||||
|
||||
protected abstract Commands _Command { get; }
|
||||
|
||||
protected Ptp1588Commands(Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
command.Type = CommandPacket.CommandType.Ptp1588;
|
||||
command.SetCommand((byte)_Command, _Command.ToString());
|
||||
}
|
||||
|
||||
protected Ptp1588Commands(Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
command.Type = CommandPacket.CommandType.Ptp1588;
|
||||
command.SetCommand((byte)_Command, _Command.ToString());
|
||||
}
|
||||
|
||||
public static string ToTimestampString(uint s, uint ns)
|
||||
{
|
||||
return $"{s}.{ns,9:000000000}";
|
||||
}
|
||||
}
|
||||
|
||||
public class Ptp1588SetMode : Ptp1588Commands
|
||||
{
|
||||
const int COMMAND_PAYLOAD_SIZE = 4;
|
||||
|
||||
protected override Commands _Command => Commands.SetMode;
|
||||
|
||||
private ushort _clock_type = 0;
|
||||
private ushort _delay_mechanism = 0;
|
||||
|
||||
public void SetClockType(PtpClockType clockType)
|
||||
{
|
||||
_clock_type = (ushort)clockType;
|
||||
command.SetParameter(0, _clock_type);
|
||||
}
|
||||
public void SetDelayMechanism(PtpDelayMechanism delayMechanism)
|
||||
{
|
||||
_delay_mechanism = (ushort)delayMechanism;
|
||||
command.SetParameter(2, _delay_mechanism);
|
||||
}
|
||||
|
||||
public Ptp1588SetMode(Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
command.Parameter = new byte[COMMAND_PAYLOAD_SIZE];
|
||||
}
|
||||
|
||||
public Ptp1588SetMode(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>> list)
|
||||
{
|
||||
base.CommandToString(ref list);
|
||||
list.Add(new List<string>() { $"Mode: {_clock_type} DelayMechanism: {_delay_mechanism}" });
|
||||
}
|
||||
}
|
||||
|
||||
public class Ptp1588GetMode : Ptp1588Commands
|
||||
{
|
||||
private const int COMMAND_PAYLOAD_SIZE = 4;
|
||||
|
||||
protected override Commands _Command => Commands.GetMode;
|
||||
|
||||
private ushort _clock_type = 0;
|
||||
private ushort _delay_mechanism = 0;
|
||||
|
||||
public PtpClockType ClockType => (PtpClockType)_clock_type;
|
||||
public PtpDelayMechanism DelayMechanism => (PtpDelayMechanism)_delay_mechanism;
|
||||
|
||||
public Ptp1588GetMode(Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
command.Parameter = new byte[COMMAND_PAYLOAD_SIZE];
|
||||
}
|
||||
|
||||
public Ptp1588GetMode(Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
command.Parameter = new byte[COMMAND_PAYLOAD_SIZE];
|
||||
}
|
||||
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
if (response.Status == DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
response.GetParameter(0, out _clock_type);
|
||||
response.GetParameter(2, out _delay_mechanism);
|
||||
}
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
|
||||
public override void ResponseToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.ResponseToString(ref lines);
|
||||
lines.Add(new List<string>() { $"ClockType: {ClockType}" });
|
||||
}
|
||||
}
|
||||
|
||||
public class Ptp1588GetSyncStatus : Ptp1588Commands
|
||||
{
|
||||
protected override Commands _Command => Commands.GetSyncStatus;
|
||||
|
||||
private int _ofm;
|
||||
private int _adj;
|
||||
|
||||
public PtpSyncStatus SyncStatus { get; private set; }
|
||||
public int OFM => _ofm;
|
||||
public int FreqAdj => _adj;
|
||||
|
||||
public Ptp1588GetSyncStatus(Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
command.Parameter = new byte[5];
|
||||
}
|
||||
|
||||
public Ptp1588GetSyncStatus(Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
command.Parameter = new byte[5];
|
||||
}
|
||||
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
if (response.Status == DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
if (response.ParameterLength > 6)
|
||||
{
|
||||
response.GetParameter(0, out byte status);
|
||||
SyncStatus = (PtpSyncStatus)status;
|
||||
response.GetParameter(1, out _ofm);
|
||||
response.GetParameter(5, out _adj);
|
||||
}
|
||||
else { SyncStatus = PtpSyncStatus.NotSynced; }
|
||||
}
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
|
||||
public override void ResponseToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.ResponseToString(ref lines);
|
||||
lines.Add(new List<string>() { $"Status: {SyncStatus} OFM: {OFM} ns Adj: {FreqAdj}" });
|
||||
}
|
||||
}
|
||||
|
||||
public class Ptp1588SetTime : Ptp1588Commands
|
||||
{
|
||||
protected override Commands _Command => Commands.SetTime;
|
||||
|
||||
private uint _s;
|
||||
private uint _ns;
|
||||
|
||||
public void SetSeconds(uint seconds)
|
||||
{
|
||||
_s = seconds;
|
||||
command.SetParameter(0, _s);
|
||||
}
|
||||
public void SetNanoseconds(uint ns)
|
||||
{
|
||||
_ns = ns;
|
||||
command.SetParameter(4, _ns);
|
||||
}
|
||||
|
||||
public Ptp1588SetTime(Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
command.Parameter = new byte[8];
|
||||
}
|
||||
|
||||
public Ptp1588SetTime(Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
command.Parameter = new byte[8];
|
||||
}
|
||||
|
||||
public override void CommandToString(ref List<List<string>> list)
|
||||
{
|
||||
base.CommandToString(ref list);
|
||||
list.Add(new List<string>() { $"Time: {_s}.{_ns,9:000000000}" });
|
||||
}
|
||||
}
|
||||
|
||||
public class Ptp1588GetTime : Ptp1588Commands
|
||||
{
|
||||
protected override Commands _Command => Commands.GetTime;
|
||||
|
||||
private uint _s;
|
||||
private uint _ns;
|
||||
|
||||
public uint Seconds => _s;
|
||||
public uint Nanoseconds => _ns;
|
||||
public string Timestamp => ToTimestampString(_s, _ns);
|
||||
|
||||
public Ptp1588GetTime(Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
command.Parameter = new byte[8];
|
||||
}
|
||||
|
||||
public Ptp1588GetTime(Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
command.Parameter = new byte[8];
|
||||
}
|
||||
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
if (response.Status == DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
response.GetParameter(0, out _s);
|
||||
response.GetParameter(4, out _ns);
|
||||
}
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
|
||||
public override void ResponseToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.ResponseToString(ref lines);
|
||||
lines.Add(new List<string>() { Timestamp });
|
||||
}
|
||||
}
|
||||
|
||||
public class Ptp1588SetAutoTriggerTime : Ptp1588Commands
|
||||
{
|
||||
protected override Commands _Command => Commands.SetAutoTriggerTime;
|
||||
|
||||
private uint _s;
|
||||
private uint _ns;
|
||||
|
||||
public void SetSeconds(uint seconds)
|
||||
{
|
||||
_s = seconds;
|
||||
command.SetParameter(0, _s);
|
||||
}
|
||||
public void SetNanoseconds(uint ns)
|
||||
{
|
||||
_ns = ns;
|
||||
command.SetParameter(4, _ns);
|
||||
}
|
||||
|
||||
public Ptp1588SetAutoTriggerTime(Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
command.Parameter = new byte[8];
|
||||
}
|
||||
|
||||
public Ptp1588SetAutoTriggerTime(Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
command.Parameter = new byte[8];
|
||||
}
|
||||
|
||||
public override void CommandToString(ref List<List<string>> list)
|
||||
{
|
||||
base.CommandToString(ref list);
|
||||
list.Add(new List<string>() { $"Timestamp: {_s}.{_ns,9:000000000}" });
|
||||
}
|
||||
}
|
||||
|
||||
public class Ptp1588GetAutoTriggerTime : Ptp1588Commands
|
||||
{
|
||||
protected override Commands _Command => Commands.GetAutoTriggerTime;
|
||||
|
||||
private uint _s;
|
||||
private uint _ns;
|
||||
|
||||
public uint Seconds => _s;
|
||||
public uint Nanoseconds => _ns;
|
||||
public string Timestamp => ToTimestampString(_s, _ns);
|
||||
|
||||
public Ptp1588GetAutoTriggerTime(Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
command.Parameter = new byte[8];
|
||||
}
|
||||
|
||||
public Ptp1588GetAutoTriggerTime(Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
command.Parameter = new byte[8];
|
||||
}
|
||||
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
if (response.Status == DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
response.GetParameter(0, out _s);
|
||||
response.GetParameter(4, out _ns);
|
||||
}
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
|
||||
public override void ResponseToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.ResponseToString(ref lines);
|
||||
lines.Add(new List<string>() { Timestamp });
|
||||
}
|
||||
}
|
||||
|
||||
public class Ptp1588GetTimestamp : Ptp1588Commands
|
||||
{
|
||||
protected override Commands _Command => Commands.GetTimestamp;
|
||||
|
||||
private byte _timestamp_unit;
|
||||
private uint _s;
|
||||
private uint _ns;
|
||||
private byte _timestamp_valid;
|
||||
|
||||
public PtpTimestampUnits TimestampUnit { set { _timestamp_unit = (byte)value; command.SetParameter(0, _timestamp_unit); } }
|
||||
public uint Seconds => _s;
|
||||
public uint Nanoseconds => _ns;
|
||||
public bool IsValid => Convert.ToBoolean(_timestamp_valid);
|
||||
public string Timestamp => ToTimestampString(_s, _ns);
|
||||
|
||||
public Ptp1588GetTimestamp(Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
command.Parameter = new byte[1];
|
||||
}
|
||||
|
||||
public Ptp1588GetTimestamp(Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
command.Parameter = new byte[1];
|
||||
}
|
||||
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
if (response.Status == DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
response.GetParameter(0, out _timestamp_valid);
|
||||
response.GetParameter(1, out _s);
|
||||
response.GetParameter(5, out _ns);
|
||||
}
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
|
||||
public override void CommandToString(ref List<List<string>> list)
|
||||
{
|
||||
base.CommandToString(ref list);
|
||||
list.Add(new List<string>() { $"Timestamp Unit: {_timestamp_unit}" });
|
||||
}
|
||||
|
||||
public override void ResponseToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.ResponseToString(ref lines);
|
||||
lines.Add(new List<string>() { $"Timestamp: {Timestamp}" });
|
||||
}
|
||||
}
|
||||
|
||||
public class Ptp1588SetEnableTimestamping : Ptp1588Commands
|
||||
{
|
||||
protected override Commands _Command => Commands.SetTriggerTimestamping;
|
||||
|
||||
private byte _enable;
|
||||
|
||||
public void SetEnable(bool enable)
|
||||
{
|
||||
_enable = Convert.ToByte(enable);
|
||||
command.SetParameter(0, _enable);
|
||||
}
|
||||
|
||||
public Ptp1588SetEnableTimestamping(Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
command.Parameter = new byte[1];
|
||||
}
|
||||
|
||||
public Ptp1588SetEnableTimestamping(Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
command.Parameter = new byte[1];
|
||||
}
|
||||
|
||||
public override void CommandToString(ref List<List<string>> list)
|
||||
{
|
||||
base.CommandToString(ref list);
|
||||
list.Add(new List<string>() { $"Enable: {_enable}" });
|
||||
}
|
||||
}
|
||||
|
||||
public class Ptp1588SetAdcClockFrequency : Ptp1588Commands
|
||||
{
|
||||
private const int COMMAND_PAYLOAD_SIZE = 4;
|
||||
|
||||
protected override Commands _Command => Commands.SetAdcClockFrquency;
|
||||
|
||||
private uint _requestedFrequency;
|
||||
private uint _actualFrequency;
|
||||
|
||||
public uint RequestedFrequency { set { _requestedFrequency = value; command.SetParameter(0, _requestedFrequency); } }
|
||||
|
||||
public Ptp1588SetAdcClockFrequency(Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
command.Parameter = new byte[COMMAND_PAYLOAD_SIZE];
|
||||
}
|
||||
|
||||
public Ptp1588SetAdcClockFrequency(Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
command.Parameter = new byte[COMMAND_PAYLOAD_SIZE];
|
||||
}
|
||||
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
if (response.Status == DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
response.GetParameter(0, out _actualFrequency);
|
||||
}
|
||||
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
public override void CommandToString(ref List<List<string>> list)
|
||||
{
|
||||
base.CommandToString(ref list);
|
||||
list.Add(new List<string>() { $"Requested Frequency: {_requestedFrequency}" });
|
||||
}
|
||||
|
||||
public override void ResponseToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.ResponseToString(ref lines);
|
||||
lines.Add(new List<string>() { $"Actual Frequency: {_actualFrequency}" });
|
||||
}
|
||||
}
|
||||
|
||||
public class Ptp1588RunClockAdjustmentCalibration : Ptp1588Commands
|
||||
{
|
||||
private const int COMMAND_PAYLOAD_SIZE = 3;
|
||||
|
||||
protected override Commands _Command => Commands.RunClockAdjustmentCalibration;
|
||||
|
||||
private byte _saveAtribute = 0;
|
||||
private ushort _durationSeconds = 60;
|
||||
|
||||
public void SetDuration(ushort duration)
|
||||
{
|
||||
_durationSeconds = duration;
|
||||
command.SetParameter(0, _durationSeconds);
|
||||
}
|
||||
public void SetSaveAttribute(bool b)
|
||||
{
|
||||
_saveAtribute = Convert.ToByte(b);
|
||||
command.SetParameter(2, _saveAtribute);
|
||||
}
|
||||
|
||||
public Ptp1588RunClockAdjustmentCalibration(Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
command.Parameter = new byte[COMMAND_PAYLOAD_SIZE];
|
||||
}
|
||||
|
||||
public Ptp1588RunClockAdjustmentCalibration(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>> list)
|
||||
{
|
||||
base.CommandToString(ref list);
|
||||
list.Add(new List<string>() { $"Duration: {_durationSeconds} Save Attribute {_saveAtribute}" });
|
||||
}
|
||||
}
|
||||
|
||||
public class QueryClockSyncStatus : Ptp1588Commands
|
||||
{
|
||||
protected override Commands _Command
|
||||
{
|
||||
get { return Commands.GetClockSyncConfig; }
|
||||
}
|
||||
|
||||
private byte _inputstate;
|
||||
public byte InputState { get => _inputstate; }
|
||||
private byte _outputstate;
|
||||
public byte OutputState { get => _outputstate; }
|
||||
private byte _clockSyncProfile;
|
||||
private byte _syncstatus;
|
||||
public byte SyncStatus { get => _syncstatus; }
|
||||
|
||||
public ClockSyncProfile ClockSyncProfile => (ClockSyncProfile)_clockSyncProfile;
|
||||
|
||||
private readonly List<InputClockSource> _inputSources = new List<InputClockSource>();
|
||||
public List<InputClockSource> InputSources => _inputSources;
|
||||
|
||||
private readonly List<OutputClockSource> _outputSources = new List<OutputClockSource>();
|
||||
public List<OutputClockSource> OutputSources => _outputSources;
|
||||
public IDictionary<InputClockSource, bool> InputSyncStatus { get; } = new Dictionary<InputClockSource, bool>();
|
||||
|
||||
public QueryClockSyncStatus(Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
MinimumProtocolVersion = sock.GetMinProto(DFConstantsAndEnums.ProtocolLimitedCommands.QueryClockSyncStatus);
|
||||
}
|
||||
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
if (response.Status == DFConstantsAndEnums.CommandStatus.StatusNoError && response.ParameterLength > 1)
|
||||
{
|
||||
response.GetParameter(0, out _clockSyncProfile);
|
||||
response.GetParameter(1, out _inputstate);
|
||||
response.GetParameter(2, out _outputstate);
|
||||
response.GetParameter(3, out _syncstatus);
|
||||
|
||||
var sources = Enum.GetValues(typeof(InputClockSource)).Cast<InputClockSource>().ToList();
|
||||
|
||||
for (int i = 1; i < sources.Count; i++)
|
||||
{
|
||||
// use source as a mask on status to get the current state (same bit structure)
|
||||
InputSyncStatus.Add(sources[i], (_syncstatus & (byte)sources[i]) == (byte)sources[i]);
|
||||
}
|
||||
}
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
|
||||
public override void ResponseToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.ResponseToString(ref lines);
|
||||
|
||||
lines.Add(new List<string>() { string.Format("Input source(s): {0}", string.Join(", ", InputSources.Select(source => source.ToString()))) });
|
||||
lines.Add(new List<string>() { string.Format("Output source(s): {0}", string.Join(", ", OutputSources.Select(source => source.ToString()))) });
|
||||
lines.Add(new List<string>() { string.Format("Input source synced: {0}", string.Join(", ", InputSyncStatus.Select(statuspair => statuspair.Key.ToString() + "-" + statuspair.Value.ToString()))) });
|
||||
}
|
||||
}
|
||||
|
||||
public class SetClockSyncConfig : Ptp1588Commands
|
||||
{
|
||||
protected override Commands _Command
|
||||
{
|
||||
get { return Commands.SetClockSyncConfig; }
|
||||
}
|
||||
|
||||
public SetClockSyncConfig(Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
MinimumProtocolVersion = sock.GetMinProto(DFConstantsAndEnums.ProtocolLimitedCommands.SetClockSyncConfig);
|
||||
}
|
||||
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
|
||||
public override void ResponseToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.ResponseToString(ref lines);
|
||||
|
||||
lines.Add(new List<string>() { ResponseStatus == DFConstantsAndEnums.CommandStatus.StatusNoError ? "Set Clock Config Success" : "Set Clock Config Failure" });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ClassDiagram MajorVersion="1" MinorVersion="1">
|
||||
<Class Name="DTS.DASLib.Command.SLICE.RealtimeCommands.EndRealtimeMode" Collapsed="true">
|
||||
<Position X="0.5" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>RealtimeCommands\EndRealtimeMode.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.RealtimeCommands.GetRealtimeSamples" Collapsed="true">
|
||||
<Position X="6.25" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AEAAAAAABAAAEABAAAAABBAAAAAAAAAAAAAAgEIAEEA=</HashCode>
|
||||
<FileName>RealtimeCommands\GetRealtimeSamples.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
<Lollipop Position="0.2" />
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.RealtimeCommands.GetRealtimeSamplesSLICE2" Collapsed="true">
|
||||
<Position X="5" Y="3.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAA=</HashCode>
|
||||
<FileName>RealtimeCommands\GetRealtimeSamplesSLICE2.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.RealtimeCommands.GetRealtimeSamplesSLICE6" Collapsed="true">
|
||||
<Position X="7.25" Y="3.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAA=</HashCode>
|
||||
<FileName>RealtimeCommands\GetRealtimeSamplesSLICE6.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.RealtimeCommands.RealtimeCommandBase" Collapsed="true">
|
||||
<Position X="7.25" Y="0.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>RealtimeCommands\RealtimeCommandBase.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.RealtimeCommands.RealtimeStreamDecoder" Collapsed="true">
|
||||
<Position X="0.5" Y="3.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAABAACAAAAAAABAgAgAAAAAAQAAAAAAAAAAAAgAEAA=</HashCode>
|
||||
<FileName>RealtimeCommands\RealtimeStreamDecoder.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.RealtimeCommands.RealtimeStreamingNextSamples" Collapsed="true" BaseTypeListCollapsed="true">
|
||||
<Position X="2.25" Y="3.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>EgABAACAAAAAAABAAAAABABAAAIBAAAAQAAAgAABEAA=</HashCode>
|
||||
<FileName>RealtimeCommands\RealtimeStreamingNextSamples.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
<Lollipop Position="0.2" Collapsed="true" />
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.RealtimeCommands.RetrieveSampleAverage" Collapsed="true">
|
||||
<Position X="2.75" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAABAQAAAAIAAAABBBAAAAAAAAgAAAAgEAAEEA=</HashCode>
|
||||
<FileName>RealtimeCommands\RetrieveSampleAverage.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.RealtimeCommands.RetrieveSingleSample" Collapsed="true">
|
||||
<Position X="9.5" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAABAAAAAAAAAAABBAAAAAAAAAAAAAAAEAAEEA=</HashCode>
|
||||
<FileName>RealtimeCommands\RetrieveSingleSample.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.RealtimeCommands.StartRealtimeMode" Collapsed="true">
|
||||
<Position X="11.75" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAACAAAAAAABAAAAAAAAAAABAAAAAAAAA=</HashCode>
|
||||
<FileName>RealtimeCommands\StartRealtimeMode.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.RealtimeCommands.StartRealtimeStreamingMode" Collapsed="true">
|
||||
<Position X="14" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AABAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAQAAAAAA=</HashCode>
|
||||
<FileName>RealtimeCommands\StartRealtimeStreamingMode.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Interface Name="DTS.DASLib.Command.SLICE.RealtimeCommands.IGetRealtimeSamples" Collapsed="true">
|
||||
<Position X="0.5" Y="4.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AgAAAAAAAAAAAABAAAAABAAAAAAAAAAAAAQAgAAAEAA=</HashCode>
|
||||
<FileName>RealtimeCommands\IGetRealtimeSamples.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Interface>
|
||||
<Font Name="Segoe UI" Size="9" />
|
||||
</ClassDiagram>
|
||||
@@ -0,0 +1,134 @@
|
||||
using System.Collections.Generic;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.ICommunication;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.RealtimeCommands
|
||||
{
|
||||
public class GetRealtimeSamples : RealtimeCommandBase, IGetRealtimeSamples
|
||||
{
|
||||
protected override Commands _Command => Commands.GetRealtimeSamples;
|
||||
|
||||
protected ulong _sampleNumber;
|
||||
/// <summary>
|
||||
/// The first sample number of the samples being returned. The remaining samples in
|
||||
/// the response packet will be numbered sequentially and without gaps from this number.
|
||||
/// If 12 samples are returned, and SampleNumber is 83042, the first sample will be number
|
||||
/// 83042, the second 83043, etc.
|
||||
/// </summary>
|
||||
public ulong SampleNumber => _sampleNumber;
|
||||
|
||||
protected ulong _timeStamp;
|
||||
|
||||
public ulong TimeStamp => _timeStamp;
|
||||
|
||||
protected ulong _sequenceNumber;
|
||||
|
||||
public ulong SequenceNumber => _sequenceNumber;
|
||||
|
||||
protected List<short[]> _data;
|
||||
public short[] GetChannelData(int zeroBasedChannel)
|
||||
{
|
||||
return _data[zeroBasedChannel];
|
||||
}
|
||||
|
||||
protected ushort _channels;
|
||||
public ushort Channels
|
||||
{
|
||||
get
|
||||
{
|
||||
if (null == _data) return 0;
|
||||
return _channels;
|
||||
}
|
||||
set => _channels = value;
|
||||
}
|
||||
|
||||
protected int _samplesReturned;
|
||||
/// <summary>
|
||||
/// Contains the number of samples that were returned in this realtime packet. Can be 0!
|
||||
/// </summary>
|
||||
public int SamplesReturned => _samplesReturned;
|
||||
|
||||
public GetRealtimeSamples(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock, 2000)
|
||||
{
|
||||
// don't need to put anything in here ... its presense
|
||||
// tells the firmware that we support multiple-sample
|
||||
// realtime
|
||||
command.Parameter = new byte[1];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// constructor for GetRealtimeSamples, a class implementing IGetRealtimeSamples
|
||||
/// this class is capable of returning realtime samples
|
||||
/// </summary>
|
||||
/// <param name="sock"></param>
|
||||
/// <param name="TimeoutMillisec"></param>
|
||||
/// <param name="bPolling">whether realtime is using polling or not</param>
|
||||
public GetRealtimeSamples(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec, bool bPolling = false)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
// don't need to put anything in here ... its presense
|
||||
// tells the firmware that we support multiple-sample
|
||||
// realtime
|
||||
command.Parameter = new byte[1];
|
||||
}
|
||||
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (response.Status == DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
// Figure out the number of samples returned
|
||||
var samplesReturned = response.ParameterLength / (_channels * 2 + 8);
|
||||
_samplesReturned = samplesReturned;
|
||||
var unsignedData = new List<ushort[]>(_channels);
|
||||
_data = new List<short[]>(_channels);
|
||||
|
||||
// Grab the sample number
|
||||
if (response.ParameterLength > 0)
|
||||
{
|
||||
response.GetParameter(0, out _sampleNumber);
|
||||
}
|
||||
|
||||
// Create the data arrays by channel
|
||||
for (var i = 0; i < _channels; i++)
|
||||
{
|
||||
unsignedData.Add(new ushort[samplesReturned]);
|
||||
_data.Add(new short[samplesReturned]);
|
||||
}
|
||||
|
||||
// Grab the data
|
||||
for (var sample = 0; sample < samplesReturned; sample++)
|
||||
{
|
||||
// Data order for a 9 channel stack
|
||||
// 7 8 9 4 5 6 1 2 3 7 8 9 4 5 6 1 2 3 etc.
|
||||
for (var channel = 0; channel < _channels; channel++)
|
||||
{
|
||||
var sliceNumber = channel / 3;
|
||||
var sliceOffset = (_channels / 3 - sliceNumber - 1) * 3;
|
||||
var channelInSlice = channel % 3;
|
||||
var offset = sliceOffset + channelInSlice;
|
||||
|
||||
response.GetParameter(8 + sample * (8 + _channels * 2) + 2 * offset, out ushort val);
|
||||
unsignedData[channel][sample] = val;
|
||||
_data[channel][sample] = (short)(unsignedData[channel][sample] - 0x8000);
|
||||
}
|
||||
}
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
_samplesReturned = 0;
|
||||
}
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
|
||||
public override void ResponseToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.ResponseToString(ref lines);
|
||||
lines.Add(new List<string> { $"Sample number: {ResponseStatus}, Samples returned: {SampleNumber}, Time Stamp returned: {TimeStamp}, Sequence Number returned: {SequenceNumber}" });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
using DTS.Common.Strings;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.DownloadCommands
|
||||
{
|
||||
public class QueryUARTEventInfo : EventDataCommands
|
||||
{
|
||||
protected override Commands Command => Commands.QueryUartEventInfo;
|
||||
|
||||
protected ushort _eventNumber;
|
||||
protected ushort _dataPresent;
|
||||
protected ushort _dataDownloaded;
|
||||
protected ulong _totalByteCount;
|
||||
protected ulong _triggerByteCount;
|
||||
protected ulong _faultByteCount;
|
||||
protected uint _startTimestamp;
|
||||
protected uint _endTimestamp;
|
||||
protected uint _baudrate;
|
||||
|
||||
public ushort EventNumber
|
||||
{
|
||||
get => _eventNumber;
|
||||
set { _eventNumber = value; command.SetParameter(0, _eventNumber); }
|
||||
}
|
||||
|
||||
public QueryUARTEventInfo(ICommunication sock) : base(sock)
|
||||
{
|
||||
command.Parameter = new byte[2];
|
||||
|
||||
_eventNumber = 0;
|
||||
_dataPresent = 0;
|
||||
_dataDownloaded = 0;
|
||||
_totalByteCount = 0;
|
||||
_triggerByteCount = 0;
|
||||
_faultByteCount = 0;
|
||||
_startTimestamp = 0;
|
||||
_endTimestamp = 0;
|
||||
_baudrate = 0;
|
||||
|
||||
command.ShouldLog = false;
|
||||
}
|
||||
|
||||
public QueryUARTEventInfo(ICommunication sock, int timeoutMillisec) : base(sock, timeoutMillisec)
|
||||
{
|
||||
command.Parameter = new byte[2];
|
||||
|
||||
_eventNumber = 0;
|
||||
_dataPresent = 0;
|
||||
_dataDownloaded = 0;
|
||||
_totalByteCount = 0;
|
||||
_faultByteCount = 0;
|
||||
_triggerByteCount = 0;
|
||||
_startTimestamp = 0;
|
||||
_endTimestamp = 0;
|
||||
_baudrate = 0;
|
||||
|
||||
command.ShouldLog = false;
|
||||
}
|
||||
|
||||
public bool DataPresent => 1 == _dataPresent;
|
||||
|
||||
public bool DataDownloaded => 1 == _dataDownloaded;
|
||||
|
||||
public ulong TotalByteCount => _totalByteCount;
|
||||
|
||||
public ulong TriggerByteCount => _triggerByteCount;
|
||||
|
||||
public ulong FaultByteCount => _faultByteCount;
|
||||
|
||||
public uint StartTimestamp => _startTimestamp;
|
||||
|
||||
public uint EndTimestamp => _endTimestamp;
|
||||
|
||||
public uint BaudRate => _baudrate;
|
||||
|
||||
public override void Execute(CommandCallback cb, object cbData)
|
||||
{
|
||||
// Do a little parameter checking
|
||||
|
||||
base.Execute(cb, cbData);
|
||||
}
|
||||
|
||||
protected override CommandReceiveAction WholePackagePost()
|
||||
{
|
||||
// now send the data to the user
|
||||
var stat = CommandStatus.Success;
|
||||
if (response.Status != DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
var s = (int)response.Status;
|
||||
APILogger.LogString("QueryUARTEventInfo.WholePackagePost: reporting failure, status==" + CommandPacketBase.StatusLabels[s] + " (0x" + s.ToString("X") + ")");
|
||||
stat = CommandStatus.Failure;
|
||||
}
|
||||
var cbReport = new QueryEventDataReport(stat, UserCallbackData);
|
||||
//cbReport.Data = new short[_channelsDownloaded][];
|
||||
//for (var i = 0; i < _channelsDownloaded; i++)
|
||||
// GetChannelData(i, out cbReport.Data[i]);
|
||||
return UserCallback(cbReport);
|
||||
}
|
||||
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
if (response.Status != DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
response.GetParameter(0, out ushort responseEventNum);
|
||||
response.GetParameter(2, out _dataPresent);
|
||||
response.GetParameter(4, out _dataDownloaded);
|
||||
response.GetParameter(8, out _totalByteCount);
|
||||
response.GetParameter(16, out _triggerByteCount);
|
||||
response.GetParameter(24, out _faultByteCount);
|
||||
response.GetParameter(32, out _startTimestamp);
|
||||
response.GetParameter(36, out _endTimestamp);
|
||||
response.GetParameter(40, out _baudrate);
|
||||
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
|
||||
public override void SyncExecute()
|
||||
{
|
||||
// Do a little parameter checking
|
||||
|
||||
base.SyncExecute();
|
||||
}
|
||||
|
||||
public override void CommandToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.CommandToString(ref lines);
|
||||
lines.Add(new List<string> { $"Event number: {EventNumber}" });
|
||||
}
|
||||
|
||||
public override void ResponseToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.ResponseToString(ref lines);
|
||||
lines.Add(new List<string>
|
||||
{
|
||||
$"DataPresent: {DataPresent}, DataDownloaded: {DataDownloaded}, TotalByteCount: {TotalByteCount}, TriggerByteCount: {TriggerByteCount}, StartTimestamp: {StartTimestamp}, EndTimestamp: {EndTimestamp}"
|
||||
});
|
||||
}
|
||||
|
||||
public void LogResponse()
|
||||
{
|
||||
LogCommand(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ClassDiagram MajorVersion="1" MinorVersion="1">
|
||||
<Class Name="DTS.DASLib.Command.SLICE.DownloadCommands.DownloadByteConverter" Collapsed="true">
|
||||
<Position X="2.25" Y="4" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAQAAAAAAAIREAAAAAQAAgAAAQAgAAAgQAAA=</HashCode>
|
||||
<FileName>DownloadCommands\DownloadByteConverter.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.DownloadCommands.EventDataCommands" Collapsed="true">
|
||||
<Position X="5" Y="0.5" Width="2" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>DownloadCommands\EventDataCommands.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.DownloadCommands.GetNextDownloadStreamDataSamples" Collapsed="true">
|
||||
<Position X="7.25" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>EgAAAAAAAAAAAAAAAAAABAQAAAABgAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>DownloadCommands\GetNextDownloadStreamDataSamples.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.DownloadCommands.QueryEventDataBase" Collapsed="true">
|
||||
<Position X="0.5" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AkAAAAAghABIAAQBAIAABIRCAAAAAAgAAABAFFEgAEA=</HashCode>
|
||||
<FileName>DownloadCommands\QueryEventDataBase.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.DownloadCommands.QueryEventDataReport" Collapsed="true">
|
||||
<Position X="4" Y="4" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAEAAAAAAAAAAAAAAAAAAAAABAAAAAAAIAAAAA=</HashCode>
|
||||
<FileName>DownloadCommands\QueryEventDataReport.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
<Lollipop Position="0.2" />
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.DownloadCommands.QueryTotalEventCount" Collapsed="true">
|
||||
<Position X="9.5" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAABAQAAAAAAAAAAACAAEAAAEA=</HashCode>
|
||||
<FileName>DownloadCommands\QueryTotalEventCount.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.DownloadCommands.ResetEventList" Collapsed="true">
|
||||
<Position X="2.75" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>DownloadCommands\ResetEventList.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.DownloadCommands.StartDownloadStreamData" Collapsed="true">
|
||||
<Position X="5" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAgAAAAAABAAAABAAAAAAAAAoAAABAABAgAAA=</HashCode>
|
||||
<FileName>DownloadCommands\StartDownloadStreamData.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Font Name="Segoe UI" Size="9" />
|
||||
</ClassDiagram>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,643 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE
|
||||
{
|
||||
public abstract class ArmCommands : CommandBase
|
||||
{
|
||||
protected enum Commands
|
||||
{
|
||||
Reserved = 0x00,
|
||||
Arm = 0x01,
|
||||
Disarm = 0x02,
|
||||
EnableFaultChecking = 0x03,
|
||||
DisableFaultChecking = 0x04,
|
||||
QueryArmAndTriggerStatus = 0x05,
|
||||
PrepareForDiagnostics = 0x06,
|
||||
PrepareForDataCollection = 0x07,
|
||||
BeginFlashErase = 0x08,
|
||||
QueryFlashEraseStatus = 0x09,
|
||||
InitializeHardwareLines = 0x0a,
|
||||
};
|
||||
|
||||
protected abstract Commands _Command { get; }
|
||||
|
||||
protected ArmCommands(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
command.Type = CommandPacket.CommandType.Arm;
|
||||
command.SetCommand((byte)_Command, _Command.ToString());
|
||||
}
|
||||
|
||||
protected ArmCommands(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
command.Type = CommandPacket.CommandType.Arm;
|
||||
command.SetCommand((byte)_Command, _Command.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public class Arm : ArmCommands
|
||||
{
|
||||
protected override Commands _Command => Commands.Arm;
|
||||
|
||||
public Arm(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
}
|
||||
|
||||
public Arm(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
}
|
||||
public DFConstantsAndEnums.CommandStatus ArmStatus { get; private set; } = DFConstantsAndEnums.CommandStatus.StatusNoError;
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
switch (response.Status)
|
||||
{
|
||||
case DFConstantsAndEnums.CommandStatus.StatusNoError:
|
||||
break;
|
||||
default:
|
||||
ArmStatus = response.Status;
|
||||
break;
|
||||
}
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
}
|
||||
|
||||
public class EnableFaultChecking : ArmCommands
|
||||
{
|
||||
protected override Commands _Command => Commands.EnableFaultChecking;
|
||||
|
||||
public EnableFaultChecking(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
}
|
||||
|
||||
public EnableFaultChecking(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class DisableFaultChecking : ArmCommands
|
||||
{
|
||||
protected override Commands _Command => Commands.DisableFaultChecking;
|
||||
|
||||
public DisableFaultChecking(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
}
|
||||
|
||||
public DisableFaultChecking(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class QueryArmAndTriggerStatus : ArmCommands
|
||||
{
|
||||
protected override Commands _Command => Commands.QueryArmAndTriggerStatus;
|
||||
|
||||
public enum FaultFlags
|
||||
{
|
||||
IncomingStatusLineDropped = (1 << 0),
|
||||
ADCBufferOverrun = (1 << 1),
|
||||
FlashCRCError = (1 << 2),
|
||||
TriggerBeforeStart = (1 << 3),
|
||||
InputVoltageLow = (1 << 4),
|
||||
InputVoltageHigh = (1 << 5),
|
||||
BackupVoltageLow = (1 << 6),
|
||||
BackupVoltageHigh = (1 << 7),
|
||||
OutOfMemory = (1 << 8),
|
||||
SquibResistanceOutOfRange = (1 << 9),
|
||||
SafeSwitchUnplugged = (1 << 10),
|
||||
SquibPowerOutOfRange = (1 << 11),
|
||||
AutoSquibDisableActivated = (1 << 12)
|
||||
}
|
||||
private float _inputVoltage = 0;
|
||||
public float InputVoltage => _inputVoltage;
|
||||
|
||||
private float _backupVoltage = 0;
|
||||
public float BackupVoltage => _backupVoltage;
|
||||
|
||||
private byte _armstate;
|
||||
private byte _armmode;
|
||||
private byte _startrecordstatus;
|
||||
private byte _triggerstatus;
|
||||
private byte _faultstatus;
|
||||
private uint _eventsamplerate;
|
||||
private ulong _totalsamples;
|
||||
private ulong _currentsample;
|
||||
private ushort _currenteventnumber;
|
||||
private ulong _faultsamplenumber;
|
||||
private ushort _faultbits;
|
||||
|
||||
private float _batterySoc;
|
||||
private float _systemTempC;
|
||||
private ulong _actualCurrentSample;
|
||||
private ulong _maxSampleAvailable;
|
||||
|
||||
private short _tsChannel1;
|
||||
private short _tsChannel2;
|
||||
private short _tsChannel3;
|
||||
|
||||
private short _sensorChannelA;
|
||||
private short _sensorChannelB;
|
||||
private short _sensorChannelC;
|
||||
private short _sensorChannelD;
|
||||
private short _sensorChannelE;
|
||||
private short _sensorChannelF;
|
||||
|
||||
// for TOM
|
||||
private float _squib1;
|
||||
private float _squib2;
|
||||
private float _squib3;
|
||||
private float _squib4;
|
||||
private float _squibP17V;
|
||||
private float _squibP5V;
|
||||
private float _squibP3p3V;
|
||||
private float _squibN5V;
|
||||
private bool _ptpEnable;
|
||||
private bool _adcPtpClkEnable;
|
||||
private bool _ptpSyncStatus;
|
||||
private bool _adcClkSyncStatus;
|
||||
|
||||
private uint _extFaultId;
|
||||
|
||||
public ArmStates ArmState => (ArmStates)_armstate;
|
||||
|
||||
public enum ArmStates { Disarmed, Armed, Realtime, Diagnostics, FlashClear, Arming };
|
||||
|
||||
public byte ArmMode => _armmode;
|
||||
|
||||
public bool IsDiagnostics => (ArmStates)_armstate == ArmStates.Diagnostics;
|
||||
public bool IsFlashClear => (ArmStates)_armstate == ArmStates.FlashClear;
|
||||
public bool IsArming => (ArmStates)_armstate == ArmStates.Arming;
|
||||
public bool IsArmed => (ArmStates)_armstate == ArmStates.Armed;
|
||||
|
||||
public bool IsInRealtime => (ArmStates)_armstate == ArmStates.Realtime;
|
||||
|
||||
public bool IsRecording => _startrecordstatus == 0x01;
|
||||
|
||||
public bool IsTriggered => _triggerstatus == 0x01;
|
||||
|
||||
public bool IsFaulted => _faultstatus == 0x01;
|
||||
|
||||
public uint EventSampleRate => _eventsamplerate;
|
||||
|
||||
public ulong TotalSamples => _totalsamples;
|
||||
|
||||
public ulong CurrentSample => _currentsample;
|
||||
|
||||
public ushort EventNumber => _currenteventnumber;
|
||||
|
||||
public ulong FaultSampleNumber => _faultsamplenumber;
|
||||
|
||||
public List<FaultFlags> CurrentFaultFlags { get; } = new List<FaultFlags>();
|
||||
|
||||
public int BatterySoc => (int)_batterySoc;
|
||||
public float SystemTempC => _systemTempC;
|
||||
public ulong ActualCurrentSample => _actualCurrentSample;
|
||||
public ulong MaxSampleAvailable => _maxSampleAvailable;
|
||||
|
||||
public short TiltSensorChannel1 => _tsChannel1;
|
||||
public short TiltSensorChannel2 => _tsChannel2;
|
||||
public short TiltSensorChannel3 => _tsChannel3;
|
||||
|
||||
public short SensorChannelA => _sensorChannelA;
|
||||
public short SensorChannelB => _sensorChannelB;
|
||||
public short SensorChannelC => _sensorChannelC;
|
||||
public short SensorChannelD => _sensorChannelD;
|
||||
public short SensorChannelE => _sensorChannelE;
|
||||
public short SensorChannelF => _sensorChannelF;
|
||||
|
||||
|
||||
public float SquibResistance1 { get { return _squib1; } }
|
||||
public float SquibResistance2 { get { return _squib2; } }
|
||||
public float SquibResistance3 { get { return _squib3; } }
|
||||
public float SquibResistance4 { get { return _squib4; } }
|
||||
|
||||
public float SquibPowerP17V { get { return _squibP17V; } }
|
||||
public float SquibPowerP5V { get { return _squibP5V; } }
|
||||
public float SquibPowerP3p3V { get { return _squibP3p3V; } }
|
||||
public float SquibPowerN5V { get { return _squibN5V; } }
|
||||
|
||||
|
||||
public bool PtpFunctionEnable { get { return _ptpEnable; } }
|
||||
public bool AdcPtpClkEnable { get { return _adcPtpClkEnable; } }
|
||||
public bool PtpClkSyncStatus { get { return _ptpSyncStatus; } }
|
||||
public bool AdcClkSyncStatus { get { return _adcClkSyncStatus; } }
|
||||
private List<QATSExtendedFault> _extendedFaultFlags = new List<QATSExtendedFault>();
|
||||
public List<QATSExtendedFault> ExtendedFaultFlags { get { return _extendedFaultFlags; } }
|
||||
public uint ExtendedFaultId { get { return _extFaultId; } }
|
||||
public QueryArmAndTriggerStatus(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
}
|
||||
|
||||
public QueryArmAndTriggerStatus(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
private const int QUATS_MIN_LENGTH_INPUTVOLTAGE = 38;
|
||||
private const int QUATS_MIN_LENGTH_BACKUPVOLTAGE = 42;
|
||||
private const int QUATS_MIN_LENGTH_BATTERYSOC = 49;
|
||||
private const int QUATS_MIN_LENGTH_ACTUALCURRENTSAMPLE = 57;
|
||||
private const int QUATS_MIN_LENGTH_MAXSAMPLEAVAILABLE = 65;
|
||||
private const int QUATS_MIN_LENGTH_TILTCHANNELDATA = 71;
|
||||
private const int QUATS_MIN_LENGTH_SYSTEMTEMP = 75;
|
||||
private const int QUATS_MIN_LENGTH_CHANNELADC = 87;
|
||||
private const int QUATS_MIN_LENGTH_TOMSTATUS = 119;
|
||||
private const int QUATS_MIN_LENGTH_CLKSTATUS = 123;
|
||||
private const int QUATS_MIN_LENGTH_EXTFAULTID = 127;
|
||||
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
if (response.Status == DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
if (response.ParameterLength > 1)
|
||||
{
|
||||
|
||||
|
||||
response.GetParameter(0, out _armstate);
|
||||
response.GetParameter(1, out _armmode);
|
||||
response.GetParameter(2, out _startrecordstatus);
|
||||
response.GetParameter(3, out _triggerstatus);
|
||||
response.GetParameter(4, out _faultstatus);
|
||||
response.GetParameter(5, out _eventsamplerate);
|
||||
response.GetParameter(9, out _totalsamples);
|
||||
response.GetParameter(17, out _currentsample);
|
||||
response.GetParameter(25, out _currenteventnumber);
|
||||
response.GetParameter(27, out _faultsamplenumber);
|
||||
//this is only valid for > 00E7, but that's long retired, so I'm enforcing it now
|
||||
response.GetParameter(35, out _faultbits);
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
if (0 != (_faultbits & (1 << i)))
|
||||
{
|
||||
CurrentFaultFlags.Add((FaultFlags)(1 << i));
|
||||
}
|
||||
}
|
||||
|
||||
if (response.ParameterLength >= QUATS_MIN_LENGTH_INPUTVOLTAGE)
|
||||
{
|
||||
response.GetParameter(37, out _inputVoltage);
|
||||
}
|
||||
else
|
||||
{
|
||||
_inputVoltage = 0;
|
||||
}
|
||||
|
||||
if (response.ParameterLength >= QUATS_MIN_LENGTH_BACKUPVOLTAGE)
|
||||
{
|
||||
response.GetParameter(41, out _backupVoltage);
|
||||
}
|
||||
else
|
||||
{
|
||||
_backupVoltage = 0;
|
||||
}
|
||||
|
||||
|
||||
if (recorder.IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.QueryBatterySOC)
|
||||
&& response.ParameterLength >= QUATS_MIN_LENGTH_BATTERYSOC)
|
||||
{
|
||||
response.GetParameter(45, out _batterySoc);
|
||||
}
|
||||
else
|
||||
{
|
||||
_batterySoc = 0;
|
||||
}
|
||||
|
||||
if (response.ParameterLength >= QUATS_MIN_LENGTH_ACTUALCURRENTSAMPLE)
|
||||
{
|
||||
response.GetParameter(49, out _actualCurrentSample);
|
||||
}
|
||||
else
|
||||
{
|
||||
_actualCurrentSample = 0;
|
||||
}
|
||||
|
||||
if (response.ParameterLength >= QUATS_MIN_LENGTH_MAXSAMPLEAVAILABLE)
|
||||
{
|
||||
response.GetParameter(57, out _maxSampleAvailable);
|
||||
}
|
||||
else
|
||||
{
|
||||
_maxSampleAvailable = 0;
|
||||
}
|
||||
|
||||
if (response.ParameterLength >= QUATS_MIN_LENGTH_TILTCHANNELDATA)
|
||||
{
|
||||
response.GetParameter(65, out _tsChannel1);
|
||||
response.GetParameter(67, out _tsChannel2);
|
||||
response.GetParameter(69, out _tsChannel3);
|
||||
}
|
||||
else
|
||||
{
|
||||
_tsChannel1 = 0;
|
||||
_tsChannel2 = 0;
|
||||
_tsChannel3 = 0;
|
||||
}
|
||||
|
||||
if (response.ParameterLength >= QUATS_MIN_LENGTH_SYSTEMTEMP)
|
||||
{
|
||||
response.GetParameter(71, out _systemTempC);
|
||||
}
|
||||
else
|
||||
{
|
||||
_systemTempC = 0;
|
||||
}
|
||||
|
||||
if (response.ParameterLength >= QUATS_MIN_LENGTH_CHANNELADC)
|
||||
{
|
||||
response.GetParameter(75, out _sensorChannelA);
|
||||
response.GetParameter(77, out _sensorChannelB);
|
||||
response.GetParameter(79, out _sensorChannelC);
|
||||
response.GetParameter(81, out _sensorChannelD);
|
||||
response.GetParameter(83, out _sensorChannelE);
|
||||
response.GetParameter(85, out _sensorChannelF);
|
||||
}
|
||||
else
|
||||
{
|
||||
_sensorChannelA = 0;
|
||||
_sensorChannelB = 0;
|
||||
_sensorChannelC = 0;
|
||||
_sensorChannelD = 0;
|
||||
_sensorChannelE = 0;
|
||||
_sensorChannelF = 0;
|
||||
}
|
||||
|
||||
// hack for TOM
|
||||
if (response.ParameterLength >= QUATS_MIN_LENGTH_TOMSTATUS)
|
||||
{
|
||||
response.GetParameter(87, out _squib1);
|
||||
response.GetParameter(91, out _squib2);
|
||||
response.GetParameter(95, out _squib3);
|
||||
response.GetParameter(99, out _squib4);
|
||||
|
||||
response.GetParameter(103, out _squibP17V);
|
||||
response.GetParameter(107, out _squibP5V);
|
||||
response.GetParameter(111, out _squibP3p3V);
|
||||
response.GetParameter(115, out _squibN5V);
|
||||
}
|
||||
if (response.ParameterLength >= QUATS_MIN_LENGTH_CLKSTATUS)
|
||||
{
|
||||
response.GetParameter(119, out _ptpEnable);
|
||||
response.GetParameter(120, out _adcPtpClkEnable);
|
||||
response.GetParameter(121, out _ptpSyncStatus);
|
||||
response.GetParameter(122, out _adcClkSyncStatus);
|
||||
}
|
||||
if (response.ParameterLength >= QUATS_MIN_LENGTH_EXTFAULTID)
|
||||
{
|
||||
response.GetParameter(123, out _extFaultId);
|
||||
}
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
if (0 != (_extFaultId & (1 << i)))
|
||||
{
|
||||
_extendedFaultFlags.Add((QATSExtendedFault)(1 << i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
|
||||
public override void ResponseToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.ResponseToString(ref lines);
|
||||
|
||||
lines.Add(new List<string>() { $"Event number: {EventNumber}, Arm Mode: {ArmMode}" });
|
||||
lines.Add(new List<string>() { $"Armed: {IsArmed}, Started: {IsRecording}, Triggered: {IsTriggered}, Faulted: {IsFaulted}, Diagnostics: {IsDiagnostics}, FlashClear: {IsFlashClear}, Arming: {IsArming}, ArmState: {_armstate}" });
|
||||
lines.Add(new List<string>() { $"Samplerate: {EventSampleRate}, Current Sample: {CurrentSample}, Total Samples: {TotalSamples}, Fault Sample Number: {FaultSampleNumber}" });
|
||||
lines.Add(new List<string>() { $"Input Voltage: {InputVoltage.ToString("N3")}V, Backup Voltage: {BackupVoltage.ToString("N3")}V, Backup Percentage Remaining: {BatterySoc}%" });
|
||||
lines.Add(new List<string>() { $"System Temp: {SystemTempC}C, Actual Current Sample: {ActualCurrentSample}, Max Sample Available: {MaxSampleAvailable}" });
|
||||
lines.Add(new List<string>() { $"Tilt Ch1: {TiltSensorChannel1}, Tilt Ch2: {TiltSensorChannel2}, Tilt Ch3: {TiltSensorChannel3}" });
|
||||
lines.Add(new List<string>() { $"Squib Ch1: {SquibResistance1}, Squib Ch2: { SquibResistance2}, Squib Ch3: { SquibResistance3}, Squib Ch4: { SquibResistance4}" });
|
||||
lines.Add(new List<string>() { $"Squib P17V: {SquibPowerP17V}, Squib PV5: { SquibPowerP5V}, Squib P3p3V: { SquibPowerP3p3V}, Squib N5V: { SquibPowerN5V}" });
|
||||
lines.Add(new List<string>() { $"PTP Enabled: {PtpFunctionEnable}, PTP Clk Enable: {AdcPtpClkEnable}, PTP Clk Sync Status: {PtpClkSyncStatus}, ADC Clk Sync Status: {AdcClkSyncStatus}" });
|
||||
|
||||
|
||||
var sb = new StringBuilder(50);
|
||||
sb.AppendFormat("Fault Flags: ");
|
||||
if (null != CurrentFaultFlags && CurrentFaultFlags.Count > 0)
|
||||
{
|
||||
var addcomma = false;
|
||||
for (int i = 0; i < CurrentFaultFlags.Count; i++)
|
||||
{
|
||||
if (addcomma) sb.AppendFormat(", ");
|
||||
addcomma = true;
|
||||
sb.AppendFormat("{0}", CurrentFaultFlags[i].ToString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.AppendFormat("none");
|
||||
}
|
||||
lines.Add(new List<string>() { sb.ToString() });
|
||||
sb = new StringBuilder();
|
||||
sb.AppendFormat("Extended Fault Flags: ");
|
||||
if (null != ExtendedFaultFlags && ExtendedFaultFlags.Count > 0)
|
||||
{
|
||||
var addcomma = false;
|
||||
for (int i = 0; i < ExtendedFaultFlags.Count; i++)
|
||||
{
|
||||
if (addcomma) sb.AppendFormat(", ");
|
||||
addcomma = true;
|
||||
sb.AppendFormat("{0}", ExtendedFaultFlags[i].ToString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.AppendFormat("none");
|
||||
}
|
||||
lines.Add(new List<string>() { sb.ToString() });
|
||||
}
|
||||
}
|
||||
|
||||
public class Disarm : ArmCommands
|
||||
{
|
||||
protected override Commands _Command => Commands.Disarm;
|
||||
|
||||
public Disarm(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
}
|
||||
|
||||
public Disarm(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class PrepareForDiagnostics : ArmCommands
|
||||
{
|
||||
protected override Commands _Command => Commands.PrepareForDiagnostics;
|
||||
|
||||
public PrepareForDiagnostics(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
}
|
||||
|
||||
public PrepareForDiagnostics(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class PrepareForDataCollection : ArmCommands
|
||||
{
|
||||
protected override Commands _Command => Commands.PrepareForDataCollection;
|
||||
|
||||
public PrepareForDataCollection(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
}
|
||||
|
||||
public PrepareForDataCollection(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class BeginFlashErase : ArmCommands
|
||||
{
|
||||
protected override Commands _Command => Commands.BeginFlashErase;
|
||||
|
||||
public BeginFlashErase(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
}
|
||||
|
||||
public BeginFlashErase(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class QueryFlashEraseStatus : ArmCommands
|
||||
{
|
||||
protected override Commands _Command => Commands.QueryFlashEraseStatus;
|
||||
|
||||
public QueryFlashEraseStatus(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
}
|
||||
|
||||
public QueryFlashEraseStatus(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
}
|
||||
|
||||
private float _percentcomplete;
|
||||
public float PercentComplete => _percentcomplete;
|
||||
|
||||
private byte _lasterror;
|
||||
public DFConstantsAndEnums.CommandStatus LastError => (DFConstantsAndEnums.CommandStatus)_lasterror;
|
||||
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
const int LastErrorPosition = 0;
|
||||
const int PercentCompletePosition = 1;
|
||||
|
||||
if (response.Status == DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
response.GetParameter(LastErrorPosition, out _lasterror);
|
||||
response.GetParameter(PercentCompletePosition, out _percentcomplete);
|
||||
}
|
||||
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
|
||||
public override void ResponseToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.ResponseToString(ref lines);
|
||||
lines.Add(new List<string>() { $"Erase status: {LastError.ToString()}, Percent complete: {PercentComplete.ToString()}" });
|
||||
}
|
||||
|
||||
}
|
||||
public class InitializeHardwareLines : ArmCommands
|
||||
{
|
||||
protected override Commands _Command => Commands.InitializeHardwareLines;
|
||||
|
||||
public bool CheckTriggerForShort
|
||||
{
|
||||
get => Convert.ToBoolean(command.Parameter[0]);
|
||||
set => command.Parameter[0] = Convert.ToByte(value);
|
||||
}
|
||||
|
||||
public bool CheckStartForShort
|
||||
{
|
||||
get => Convert.ToBoolean(command.Parameter[1]);
|
||||
set => command.Parameter[1] = Convert.ToByte(value);
|
||||
}
|
||||
|
||||
public InitializeHardwareLines(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
command.Parameter = new byte[] { 0x01, 0x01 };
|
||||
LogCommands = false;
|
||||
}
|
||||
|
||||
public InitializeHardwareLines(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
command.Parameter = new byte[] { 0x01, 0x01 };
|
||||
LogCommands = false;
|
||||
}
|
||||
|
||||
public bool StartRecordShorted { get; private set; } = false;
|
||||
|
||||
public bool TriggerInputShorted { get; private set; } = false;
|
||||
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
switch (response.Status)
|
||||
{
|
||||
case DFConstantsAndEnums.CommandStatus.StatusNoError:
|
||||
break;
|
||||
case DFConstantsAndEnums.CommandStatus.StatusArmShortedStartRecordInput:
|
||||
StartRecordShorted = true;
|
||||
break;
|
||||
case DFConstantsAndEnums.CommandStatus.StatusArmShortedTriggerInput:
|
||||
TriggerInputShorted = true;
|
||||
break;
|
||||
case DFConstantsAndEnums.CommandStatus.StatusArmShortedStartAndTrigger:
|
||||
StartRecordShorted = true;
|
||||
TriggerInputShorted = true;
|
||||
break;
|
||||
default:
|
||||
APILogger.Log("Unexpected return from InitializeHardwareLines ", response.Status.ToString());
|
||||
break;
|
||||
}
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
|
||||
public override void ResponseToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.ResponseToString(ref lines);
|
||||
lines.Add(new List<string>(new[] { $"StartRecord: {StartRecordShorted}, Trigger: {TriggerInputShorted}" }));
|
||||
}
|
||||
|
||||
public static void Log(Exception exception, InitializeHardwareLines ihl)
|
||||
{
|
||||
var bShortStart = exception.Message.Contains(DFConstantsAndEnums.CommandStatus.StatusArmShortedStartRecordInput.ToString());
|
||||
var bShortTrig = exception.Message.Contains(DFConstantsAndEnums.CommandStatus.StatusArmShortedTriggerInput.ToString());
|
||||
|
||||
if (exception.Message.Contains(DFConstantsAndEnums.CommandStatus.StatusArmShortedStartAndTrigger.ToString()))
|
||||
{
|
||||
bShortStart = true;
|
||||
bShortTrig = true;
|
||||
}
|
||||
APILogger.Log($"InitializeHardwareLines: Start shorted: {bShortStart} Trigger shorted: {bShortTrig}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using DTS.Common.DASResource;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.ICommunication;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.DownloadCommands
|
||||
{
|
||||
public class QueryEventDataBase : EventDataCommands
|
||||
{
|
||||
protected override Commands Command => Commands.QueryEventData;
|
||||
private const ushort ADC_OFFSET = 0x8000;
|
||||
|
||||
public const byte ALL_CHANNELS = 0xFF;
|
||||
|
||||
protected UInt16 _eventNumber;
|
||||
protected UInt64 _firstSample;
|
||||
protected UInt64 _lastSample;
|
||||
protected UInt64 _samplesDownloaded;
|
||||
protected byte _channel;
|
||||
protected int _channelsDownloaded;
|
||||
protected ushort[] _data;
|
||||
|
||||
public UInt16 EventNumber
|
||||
{
|
||||
get => _eventNumber;
|
||||
set { _eventNumber = value; command.SetParameter(0, _eventNumber); }
|
||||
}
|
||||
|
||||
public virtual UInt64 FirstSample
|
||||
{
|
||||
get => _firstSample;
|
||||
set { _firstSample = value; command.SetParameter(2, _firstSample); }
|
||||
}
|
||||
|
||||
public virtual UInt64 LastSample
|
||||
{
|
||||
get => _lastSample;
|
||||
set { _lastSample = value; command.SetParameter(10, _lastSample); }
|
||||
}
|
||||
|
||||
public byte Channel
|
||||
{
|
||||
get => _channel;
|
||||
set
|
||||
{
|
||||
_channel = value; command.SetParameter(18, _channel);
|
||||
ChannelsDownloaded = 0xFF == _channel ? 3 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
public int ChannelsDownloaded
|
||||
{
|
||||
get => _channelsDownloaded;
|
||||
set => _channelsDownloaded = value;
|
||||
}
|
||||
|
||||
public int Count => (int)_samplesDownloaded;
|
||||
|
||||
public QueryEventDataBase(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
command.Parameter = new byte[19];
|
||||
_data = null;
|
||||
|
||||
_eventNumber = 0;
|
||||
_firstSample = 0;
|
||||
_lastSample = 0;
|
||||
_channel = 0;
|
||||
|
||||
command.ShouldLog = false;
|
||||
}
|
||||
|
||||
public QueryEventDataBase(DTS.Common.Interface.DASFactory.ICommunication sock, int timeoutMillisec)
|
||||
: base(sock, timeoutMillisec)
|
||||
{
|
||||
command.Parameter = new byte[19];
|
||||
_data = null;
|
||||
|
||||
_eventNumber = 0;
|
||||
_firstSample = 0;
|
||||
_lastSample = 0;
|
||||
_channel = 0;
|
||||
|
||||
command.ShouldLog = false;
|
||||
}
|
||||
|
||||
public override void Execute(CommandCallback cb, object cbData)
|
||||
{
|
||||
// Do a little parameter checking
|
||||
if (_firstSample > _lastSample)
|
||||
{
|
||||
// "QueryEventData.Execute: First Sample cannot be greater than Last Sample"
|
||||
throw new ApplicationException(Strings.QueryEventData_Execute_Err1);
|
||||
}
|
||||
base.Execute(cb, cbData);
|
||||
}
|
||||
|
||||
protected override CommandReceiveAction WholePackagePost()
|
||||
{
|
||||
// now send the data to the user
|
||||
var stat = CommandStatus.Success;
|
||||
if (response.Status != DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
var s = (int)response.Status;
|
||||
APILogger.LogString("QueryEventData.WholePackagePost: reporting failure, status==" + CommandPacketBase.StatusLabels[s] + " (0x" + s.ToString("X") + ")");
|
||||
stat = CommandStatus.Failure;
|
||||
}
|
||||
var cbReport = new QueryEventDataReport(stat, UserCallbackData);
|
||||
cbReport.Data = new short[_channelsDownloaded][];
|
||||
for (var i = 0; i < _channelsDownloaded; i++)
|
||||
GetChannelData(i, out cbReport.Data[i]);
|
||||
return UserCallback(cbReport);
|
||||
}
|
||||
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
if (response.Status != DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
_samplesDownloaded = (ulong)(response.Parameter.Length / 2) / (ulong)_channelsDownloaded;
|
||||
_data = new ushort[_samplesDownloaded * (ulong)_channelsDownloaded];
|
||||
for (var i = 0; (ulong)i < _samplesDownloaded * (ulong)_channelsDownloaded; i++)
|
||||
{
|
||||
response.GetParameter(2 * i, out _data[i]);
|
||||
}
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
|
||||
public override void SyncExecute()
|
||||
{
|
||||
// Do a little parameter checking
|
||||
if (_firstSample > _lastSample)
|
||||
{
|
||||
// "QueryEventData.SyncExecute: First Sample cannot be greater than Last Sample"
|
||||
throw new ApplicationException(Strings.QueryEventData_SyncExecute_Err1);
|
||||
}
|
||||
base.SyncExecute();
|
||||
}
|
||||
|
||||
public virtual void GetChannelData(int channel, out short[] signedADC)
|
||||
{
|
||||
if (channel < 0 || channel > _channelsDownloaded)
|
||||
{
|
||||
// "QueryEventData.GetChannelData: Data requested on a channel that wasn't downloaded."
|
||||
throw new ApplicationException(Strings.QueryEventData_GetChannelData_Err1);
|
||||
}
|
||||
|
||||
// Data order for a 9 channel stack
|
||||
// 7 8 9 4 5 6 1 2 3 7 8 9 4 5 6 1 2 3 etc.
|
||||
|
||||
var rv = new short[_samplesDownloaded];
|
||||
var sliceNumber = channel / 3;
|
||||
var sliceOffset = (_channelsDownloaded / 3 - sliceNumber - 1) * 3;
|
||||
if (sliceOffset < 0) sliceOffset = 0;
|
||||
var channelInSlice = channel % 3;
|
||||
for (var i = 0; i < rv.Length; i++)
|
||||
{
|
||||
rv[i] = (short)(_data[i * _channelsDownloaded + sliceOffset + channelInSlice] - ADC_OFFSET);
|
||||
}
|
||||
signedADC = rv;
|
||||
}
|
||||
|
||||
public virtual void GetRawIndexedData(int index, out ushort[] data)
|
||||
{
|
||||
data = new ushort[_samplesDownloaded];
|
||||
for (var i = 0; i < data.Length; i++)
|
||||
{
|
||||
data[i] = _data[i * _channelsDownloaded + index];
|
||||
}
|
||||
}
|
||||
|
||||
public override void CommandToString(ref List<List<string>> lines)
|
||||
{
|
||||
lines.Add(new List<string> { $"Event number: {EventNumber}, First sample: {FirstSample}, Last sample: {LastSample}" });
|
||||
}
|
||||
|
||||
public override void ResponseToString(ref List<List<string>> lines)
|
||||
{
|
||||
lines.Add(new List<string>
|
||||
{
|
||||
$"ChannelsDownloaded: {ChannelsDownloaded}, Count: {Count}"
|
||||
});
|
||||
}
|
||||
|
||||
public void LogResponse()
|
||||
{
|
||||
LogCommand(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using DTS.DASLib.Communication;
|
||||
using DTS.DASLib.Utility;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE
|
||||
{
|
||||
public abstract class Commands_Stack_Setup: CommandBase
|
||||
{
|
||||
protected enum Commands
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
protected Commands_Stack_Setup(ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
this.command.Type = CommandPacket.CommandType.StackSetup;
|
||||
}
|
||||
|
||||
protected Commands_Stack_Setup(ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
this.command.Type = CommandPacket.CommandType.StackSetup;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,91 @@
|
||||
using DTS.Common.ICommunication;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.RealtimeCommands
|
||||
{
|
||||
public class StartTimeStampStreamMode : RealtimeCommandBase
|
||||
{
|
||||
private bool _bSupportsIrigTimeStampSampleRealtime = true;
|
||||
public bool SupportsMultipleSampleRealtime
|
||||
{
|
||||
get { return _bSupportsIrigTimeStampSampleRealtime; }
|
||||
set
|
||||
{
|
||||
_bSupportsIrigTimeStampSampleRealtime = value;
|
||||
if (value) { command.Parameter = new byte[1]; }
|
||||
else { command.Parameter = new byte[0]; }
|
||||
}
|
||||
}
|
||||
protected override Commands _Command => Commands.StartTimeStampStreamMode;
|
||||
|
||||
public StartTimeStampStreamMode(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
MinimumProtocolVersion = sock.GetMinProto(Common.Enums.DASFactory.DFConstantsAndEnums.ProtocolLimitedCommands.UDPRealtimeStream);
|
||||
}
|
||||
|
||||
public StartTimeStampStreamMode(DTS.Common.Interface.DASFactory.ICommunication sock, int timeoutMillisec)
|
||||
: base(sock, timeoutMillisec)
|
||||
{
|
||||
MinimumProtocolVersion = sock.GetMinProto(Common.Enums.DASFactory.DFConstantsAndEnums.ProtocolLimitedCommands.UDPRealtimeStream);
|
||||
}
|
||||
private byte[] _paramsToSend;
|
||||
public byte[] ParamsToSend
|
||||
{
|
||||
get => _paramsToSend;
|
||||
set
|
||||
{
|
||||
_paramsToSend = value;
|
||||
command.Parameter = new byte[value.Length];
|
||||
for (var i = 0; i < value.Length; i++)
|
||||
{
|
||||
command.SetParameter(i, _paramsToSend[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
public override void CommandToString(ref List<List<string>> list)
|
||||
{
|
||||
base.CommandToString(ref list);
|
||||
list.Add(new List<string>(new[] { $"ParamsToSend: {System.Text.Encoding.UTF8.GetString(ParamsToSend)}" }));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// this puts the firmware into realtime streaming mode
|
||||
/// in this mode the firmware will constantly send out realtime data
|
||||
/// </summary>
|
||||
public class StartRealtimeStreamingMode : RealtimeCommandBase
|
||||
{
|
||||
protected override Commands _Command => Commands.StartRealtimeStreamingMode;
|
||||
|
||||
public StartRealtimeStreamingMode(DTS.Common.Interface.DASFactory.ICommunication sock, byte[] channelList)
|
||||
: base(sock)
|
||||
{
|
||||
ChannelList = channelList;
|
||||
}
|
||||
|
||||
public StartRealtimeStreamingMode(DTS.Common.Interface.DASFactory.ICommunication sock, int timeoutMillisec, byte[] channelList)
|
||||
: base(sock, timeoutMillisec)
|
||||
{
|
||||
ChannelList = channelList;
|
||||
}
|
||||
|
||||
private byte[] _channelList;
|
||||
/// <summary>
|
||||
/// channels to collect data on, each channel should be represented as a byte
|
||||
/// </summary>
|
||||
public byte[] ChannelList
|
||||
{
|
||||
get => _channelList;
|
||||
set
|
||||
{
|
||||
_channelList = value;
|
||||
command.Parameter = new byte[value.Length];
|
||||
for (var i = 0; i < value.Length; i++)
|
||||
{
|
||||
command.SetParameter(i, value[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,45 @@
|
||||
using System.Collections.Generic;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.ICommunication;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.DownloadCommands
|
||||
{
|
||||
public class QueryTotalEventCount : EventDataCommands
|
||||
{
|
||||
protected override Commands Command => Commands.QueryTotalEventCount;
|
||||
private ushort _count;
|
||||
|
||||
public ushort Count => _count;
|
||||
|
||||
public QueryTotalEventCount(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
}
|
||||
|
||||
public QueryTotalEventCount(DTS.Common.Interface.DASFactory.ICommunication sock, int timeoutMillisec)
|
||||
: base(sock, timeoutMillisec)
|
||||
{
|
||||
}
|
||||
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
if (response.Status != DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
if (response.ParameterLength > 0)
|
||||
{
|
||||
response.GetParameter(0, out _count);
|
||||
}
|
||||
else { _count = 0; }
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
|
||||
public override void ResponseToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.ResponseToString(ref lines);
|
||||
lines.Add(new List<string>
|
||||
{
|
||||
$"Count: {Count}"
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE
|
||||
{
|
||||
public class CommandPacket : SliceCommandPacketBase
|
||||
{
|
||||
public enum CommandType
|
||||
{
|
||||
Reserved = 0,
|
||||
Arm = 1,
|
||||
Attribute = 2,
|
||||
Diagnostics = 3,
|
||||
EventData = 4,
|
||||
FirmwareUpdate = 5,
|
||||
Information = 6,
|
||||
QAandUtility = 7,
|
||||
Realtime = 8,
|
||||
Bulk = 9,
|
||||
StackFirmwareUpdate = 10,
|
||||
Ptp1588 = 11,
|
||||
Multicast = 12,
|
||||
};
|
||||
|
||||
private static UInt16 GlobalSequenceNumber = 0;
|
||||
private static object GlobalSequenceNumberLock = new object();
|
||||
|
||||
public CommandPacket() : base() { }
|
||||
|
||||
public override void GetNextSequenceNumber()
|
||||
{
|
||||
lock (GlobalSequenceNumberLock)
|
||||
{
|
||||
SequenceNumber = GlobalSequenceNumber;
|
||||
GlobalSequenceNumber++;
|
||||
}
|
||||
}
|
||||
|
||||
public CommandPacket(byte[] Bytes) : base(Bytes) { }
|
||||
|
||||
public override object ConvertByteToCommandType(byte b)
|
||||
{
|
||||
return (CommandType)b;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,19 @@
|
||||
using DTS.Common.ICommunication;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.DownloadCommands
|
||||
{
|
||||
public class ResetEventList : EventDataCommands
|
||||
{
|
||||
protected override Commands Command => Commands.ResetEventList;
|
||||
|
||||
public ResetEventList(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
}
|
||||
|
||||
public ResetEventList(DTS.Common.Interface.DASFactory.ICommunication sock, int timeoutMillisec)
|
||||
: base(sock, timeoutMillisec)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
DataPRO/SLICECommands/.svn/wc.db
Normal file
BIN
DataPRO/SLICECommands/.svn/wc.db
Normal file
Binary file not shown.
0
DataPRO/SLICECommands/.svn/wc.db-journal
Normal file
0
DataPRO/SLICECommands/.svn/wc.db-journal
Normal file
643
DataPRO/SLICECommands/ArmCommands.cs
Normal file
643
DataPRO/SLICECommands/ArmCommands.cs
Normal file
@@ -0,0 +1,643 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE
|
||||
{
|
||||
public abstract class ArmCommands : CommandBase
|
||||
{
|
||||
protected enum Commands
|
||||
{
|
||||
Reserved = 0x00,
|
||||
Arm = 0x01,
|
||||
Disarm = 0x02,
|
||||
EnableFaultChecking = 0x03,
|
||||
DisableFaultChecking = 0x04,
|
||||
QueryArmAndTriggerStatus = 0x05,
|
||||
PrepareForDiagnostics = 0x06,
|
||||
PrepareForDataCollection = 0x07,
|
||||
BeginFlashErase = 0x08,
|
||||
QueryFlashEraseStatus = 0x09,
|
||||
InitializeHardwareLines = 0x0a,
|
||||
};
|
||||
|
||||
protected abstract Commands _Command { get; }
|
||||
|
||||
protected ArmCommands(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
command.Type = CommandPacket.CommandType.Arm;
|
||||
command.SetCommand((byte)_Command, _Command.ToString());
|
||||
}
|
||||
|
||||
protected ArmCommands(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
command.Type = CommandPacket.CommandType.Arm;
|
||||
command.SetCommand((byte)_Command, _Command.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public class Arm : ArmCommands
|
||||
{
|
||||
protected override Commands _Command => Commands.Arm;
|
||||
|
||||
public Arm(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
}
|
||||
|
||||
public Arm(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
}
|
||||
public DFConstantsAndEnums.CommandStatus ArmStatus { get; private set; } = DFConstantsAndEnums.CommandStatus.StatusNoError;
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
switch (response.Status)
|
||||
{
|
||||
case DFConstantsAndEnums.CommandStatus.StatusNoError:
|
||||
break;
|
||||
default:
|
||||
ArmStatus = response.Status;
|
||||
break;
|
||||
}
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
}
|
||||
|
||||
public class EnableFaultChecking : ArmCommands
|
||||
{
|
||||
protected override Commands _Command => Commands.EnableFaultChecking;
|
||||
|
||||
public EnableFaultChecking(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
}
|
||||
|
||||
public EnableFaultChecking(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class DisableFaultChecking : ArmCommands
|
||||
{
|
||||
protected override Commands _Command => Commands.DisableFaultChecking;
|
||||
|
||||
public DisableFaultChecking(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
}
|
||||
|
||||
public DisableFaultChecking(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class QueryArmAndTriggerStatus : ArmCommands
|
||||
{
|
||||
protected override Commands _Command => Commands.QueryArmAndTriggerStatus;
|
||||
|
||||
public enum FaultFlags
|
||||
{
|
||||
IncomingStatusLineDropped = (1 << 0),
|
||||
ADCBufferOverrun = (1 << 1),
|
||||
FlashCRCError = (1 << 2),
|
||||
TriggerBeforeStart = (1 << 3),
|
||||
InputVoltageLow = (1 << 4),
|
||||
InputVoltageHigh = (1 << 5),
|
||||
BackupVoltageLow = (1 << 6),
|
||||
BackupVoltageHigh = (1 << 7),
|
||||
OutOfMemory = (1 << 8),
|
||||
SquibResistanceOutOfRange = (1 << 9),
|
||||
SafeSwitchUnplugged = (1 << 10),
|
||||
SquibPowerOutOfRange = (1 << 11),
|
||||
AutoSquibDisableActivated = (1 << 12)
|
||||
}
|
||||
private float _inputVoltage = 0;
|
||||
public float InputVoltage => _inputVoltage;
|
||||
|
||||
private float _backupVoltage = 0;
|
||||
public float BackupVoltage => _backupVoltage;
|
||||
|
||||
private byte _armstate;
|
||||
private byte _armmode;
|
||||
private byte _startrecordstatus;
|
||||
private byte _triggerstatus;
|
||||
private byte _faultstatus;
|
||||
private uint _eventsamplerate;
|
||||
private ulong _totalsamples;
|
||||
private ulong _currentsample;
|
||||
private ushort _currenteventnumber;
|
||||
private ulong _faultsamplenumber;
|
||||
private ushort _faultbits;
|
||||
|
||||
private float _batterySoc;
|
||||
private float _systemTempC;
|
||||
private ulong _actualCurrentSample;
|
||||
private ulong _maxSampleAvailable;
|
||||
|
||||
private short _tsChannel1;
|
||||
private short _tsChannel2;
|
||||
private short _tsChannel3;
|
||||
|
||||
private short _sensorChannelA;
|
||||
private short _sensorChannelB;
|
||||
private short _sensorChannelC;
|
||||
private short _sensorChannelD;
|
||||
private short _sensorChannelE;
|
||||
private short _sensorChannelF;
|
||||
|
||||
// for TOM
|
||||
private float _squib1;
|
||||
private float _squib2;
|
||||
private float _squib3;
|
||||
private float _squib4;
|
||||
private float _squibP17V;
|
||||
private float _squibP5V;
|
||||
private float _squibP3p3V;
|
||||
private float _squibN5V;
|
||||
private bool _ptpEnable;
|
||||
private bool _adcPtpClkEnable;
|
||||
private bool _ptpSyncStatus;
|
||||
private bool _adcClkSyncStatus;
|
||||
|
||||
private uint _extFaultId;
|
||||
|
||||
public ArmStates ArmState => (ArmStates)_armstate;
|
||||
|
||||
public enum ArmStates { Disarmed, Armed, Realtime, Diagnostics, FlashClear, Arming };
|
||||
|
||||
public byte ArmMode => _armmode;
|
||||
|
||||
public bool IsDiagnostics => (ArmStates)_armstate == ArmStates.Diagnostics;
|
||||
public bool IsFlashClear => (ArmStates)_armstate == ArmStates.FlashClear;
|
||||
public bool IsArming => (ArmStates)_armstate == ArmStates.Arming;
|
||||
public bool IsArmed => (ArmStates)_armstate == ArmStates.Armed;
|
||||
|
||||
public bool IsInRealtime => (ArmStates)_armstate == ArmStates.Realtime;
|
||||
|
||||
public bool IsRecording => _startrecordstatus == 0x01;
|
||||
|
||||
public bool IsTriggered => _triggerstatus == 0x01;
|
||||
|
||||
public bool IsFaulted => _faultstatus == 0x01;
|
||||
|
||||
public uint EventSampleRate => _eventsamplerate;
|
||||
|
||||
public ulong TotalSamples => _totalsamples;
|
||||
|
||||
public ulong CurrentSample => _currentsample;
|
||||
|
||||
public ushort EventNumber => _currenteventnumber;
|
||||
|
||||
public ulong FaultSampleNumber => _faultsamplenumber;
|
||||
|
||||
public List<FaultFlags> CurrentFaultFlags { get; } = new List<FaultFlags>();
|
||||
|
||||
public int BatterySoc => (int)_batterySoc;
|
||||
public float SystemTempC => _systemTempC;
|
||||
public ulong ActualCurrentSample => _actualCurrentSample;
|
||||
public ulong MaxSampleAvailable => _maxSampleAvailable;
|
||||
|
||||
public short TiltSensorChannel1 => _tsChannel1;
|
||||
public short TiltSensorChannel2 => _tsChannel2;
|
||||
public short TiltSensorChannel3 => _tsChannel3;
|
||||
|
||||
public short SensorChannelA => _sensorChannelA;
|
||||
public short SensorChannelB => _sensorChannelB;
|
||||
public short SensorChannelC => _sensorChannelC;
|
||||
public short SensorChannelD => _sensorChannelD;
|
||||
public short SensorChannelE => _sensorChannelE;
|
||||
public short SensorChannelF => _sensorChannelF;
|
||||
|
||||
|
||||
public float SquibResistance1 { get { return _squib1; } }
|
||||
public float SquibResistance2 { get { return _squib2; } }
|
||||
public float SquibResistance3 { get { return _squib3; } }
|
||||
public float SquibResistance4 { get { return _squib4; } }
|
||||
|
||||
public float SquibPowerP17V { get { return _squibP17V; } }
|
||||
public float SquibPowerP5V { get { return _squibP5V; } }
|
||||
public float SquibPowerP3p3V { get { return _squibP3p3V; } }
|
||||
public float SquibPowerN5V { get { return _squibN5V; } }
|
||||
|
||||
|
||||
public bool PtpFunctionEnable { get { return _ptpEnable; } }
|
||||
public bool AdcPtpClkEnable { get { return _adcPtpClkEnable; } }
|
||||
public bool PtpClkSyncStatus { get { return _ptpSyncStatus; } }
|
||||
public bool AdcClkSyncStatus { get { return _adcClkSyncStatus; } }
|
||||
private List<QATSExtendedFault> _extendedFaultFlags = new List<QATSExtendedFault>();
|
||||
public List<QATSExtendedFault> ExtendedFaultFlags { get { return _extendedFaultFlags; } }
|
||||
public uint ExtendedFaultId { get { return _extFaultId; } }
|
||||
public QueryArmAndTriggerStatus(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
}
|
||||
|
||||
public QueryArmAndTriggerStatus(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
private const int QUATS_MIN_LENGTH_INPUTVOLTAGE = 38;
|
||||
private const int QUATS_MIN_LENGTH_BACKUPVOLTAGE = 42;
|
||||
private const int QUATS_MIN_LENGTH_BATTERYSOC = 49;
|
||||
private const int QUATS_MIN_LENGTH_ACTUALCURRENTSAMPLE = 57;
|
||||
private const int QUATS_MIN_LENGTH_MAXSAMPLEAVAILABLE = 65;
|
||||
private const int QUATS_MIN_LENGTH_TILTCHANNELDATA = 71;
|
||||
private const int QUATS_MIN_LENGTH_SYSTEMTEMP = 75;
|
||||
private const int QUATS_MIN_LENGTH_CHANNELADC = 87;
|
||||
private const int QUATS_MIN_LENGTH_TOMSTATUS = 119;
|
||||
private const int QUATS_MIN_LENGTH_CLKSTATUS = 123;
|
||||
private const int QUATS_MIN_LENGTH_EXTFAULTID = 127;
|
||||
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
if (response.Status == DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
if (response.ParameterLength > 1)
|
||||
{
|
||||
|
||||
|
||||
response.GetParameter(0, out _armstate);
|
||||
response.GetParameter(1, out _armmode);
|
||||
response.GetParameter(2, out _startrecordstatus);
|
||||
response.GetParameter(3, out _triggerstatus);
|
||||
response.GetParameter(4, out _faultstatus);
|
||||
response.GetParameter(5, out _eventsamplerate);
|
||||
response.GetParameter(9, out _totalsamples);
|
||||
response.GetParameter(17, out _currentsample);
|
||||
response.GetParameter(25, out _currenteventnumber);
|
||||
response.GetParameter(27, out _faultsamplenumber);
|
||||
//this is only valid for > 00E7, but that's long retired, so I'm enforcing it now
|
||||
response.GetParameter(35, out _faultbits);
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
if (0 != (_faultbits & (1 << i)))
|
||||
{
|
||||
CurrentFaultFlags.Add((FaultFlags)(1 << i));
|
||||
}
|
||||
}
|
||||
|
||||
if (response.ParameterLength >= QUATS_MIN_LENGTH_INPUTVOLTAGE)
|
||||
{
|
||||
response.GetParameter(37, out _inputVoltage);
|
||||
}
|
||||
else
|
||||
{
|
||||
_inputVoltage = 0;
|
||||
}
|
||||
|
||||
if (response.ParameterLength >= QUATS_MIN_LENGTH_BACKUPVOLTAGE)
|
||||
{
|
||||
response.GetParameter(41, out _backupVoltage);
|
||||
}
|
||||
else
|
||||
{
|
||||
_backupVoltage = 0;
|
||||
}
|
||||
|
||||
|
||||
if (recorder.IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.QueryBatterySOC)
|
||||
&& response.ParameterLength >= QUATS_MIN_LENGTH_BATTERYSOC)
|
||||
{
|
||||
response.GetParameter(45, out _batterySoc);
|
||||
}
|
||||
else
|
||||
{
|
||||
_batterySoc = 0;
|
||||
}
|
||||
|
||||
if (response.ParameterLength >= QUATS_MIN_LENGTH_ACTUALCURRENTSAMPLE)
|
||||
{
|
||||
response.GetParameter(49, out _actualCurrentSample);
|
||||
}
|
||||
else
|
||||
{
|
||||
_actualCurrentSample = 0;
|
||||
}
|
||||
|
||||
if (response.ParameterLength >= QUATS_MIN_LENGTH_MAXSAMPLEAVAILABLE)
|
||||
{
|
||||
response.GetParameter(57, out _maxSampleAvailable);
|
||||
}
|
||||
else
|
||||
{
|
||||
_maxSampleAvailable = 0;
|
||||
}
|
||||
|
||||
if (response.ParameterLength >= QUATS_MIN_LENGTH_TILTCHANNELDATA)
|
||||
{
|
||||
response.GetParameter(65, out _tsChannel1);
|
||||
response.GetParameter(67, out _tsChannel2);
|
||||
response.GetParameter(69, out _tsChannel3);
|
||||
}
|
||||
else
|
||||
{
|
||||
_tsChannel1 = 0;
|
||||
_tsChannel2 = 0;
|
||||
_tsChannel3 = 0;
|
||||
}
|
||||
|
||||
if (response.ParameterLength >= QUATS_MIN_LENGTH_SYSTEMTEMP)
|
||||
{
|
||||
response.GetParameter(71, out _systemTempC);
|
||||
}
|
||||
else
|
||||
{
|
||||
_systemTempC = 0;
|
||||
}
|
||||
|
||||
if (response.ParameterLength >= QUATS_MIN_LENGTH_CHANNELADC)
|
||||
{
|
||||
response.GetParameter(75, out _sensorChannelA);
|
||||
response.GetParameter(77, out _sensorChannelB);
|
||||
response.GetParameter(79, out _sensorChannelC);
|
||||
response.GetParameter(81, out _sensorChannelD);
|
||||
response.GetParameter(83, out _sensorChannelE);
|
||||
response.GetParameter(85, out _sensorChannelF);
|
||||
}
|
||||
else
|
||||
{
|
||||
_sensorChannelA = 0;
|
||||
_sensorChannelB = 0;
|
||||
_sensorChannelC = 0;
|
||||
_sensorChannelD = 0;
|
||||
_sensorChannelE = 0;
|
||||
_sensorChannelF = 0;
|
||||
}
|
||||
|
||||
// hack for TOM
|
||||
if (response.ParameterLength >= QUATS_MIN_LENGTH_TOMSTATUS)
|
||||
{
|
||||
response.GetParameter(87, out _squib1);
|
||||
response.GetParameter(91, out _squib2);
|
||||
response.GetParameter(95, out _squib3);
|
||||
response.GetParameter(99, out _squib4);
|
||||
|
||||
response.GetParameter(103, out _squibP17V);
|
||||
response.GetParameter(107, out _squibP5V);
|
||||
response.GetParameter(111, out _squibP3p3V);
|
||||
response.GetParameter(115, out _squibN5V);
|
||||
}
|
||||
if (response.ParameterLength >= QUATS_MIN_LENGTH_CLKSTATUS)
|
||||
{
|
||||
response.GetParameter(119, out _ptpEnable);
|
||||
response.GetParameter(120, out _adcPtpClkEnable);
|
||||
response.GetParameter(121, out _ptpSyncStatus);
|
||||
response.GetParameter(122, out _adcClkSyncStatus);
|
||||
}
|
||||
if (response.ParameterLength >= QUATS_MIN_LENGTH_EXTFAULTID)
|
||||
{
|
||||
response.GetParameter(123, out _extFaultId);
|
||||
}
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
if (0 != (_extFaultId & (1 << i)))
|
||||
{
|
||||
_extendedFaultFlags.Add((QATSExtendedFault)(1 << i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
|
||||
public override void ResponseToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.ResponseToString(ref lines);
|
||||
|
||||
lines.Add(new List<string>() { $"Event number: {EventNumber}, Arm Mode: {ArmMode}" });
|
||||
lines.Add(new List<string>() { $"Armed: {IsArmed}, Started: {IsRecording}, Triggered: {IsTriggered}, Faulted: {IsFaulted}, Diagnostics: {IsDiagnostics}, FlashClear: {IsFlashClear}, Arming: {IsArming}, ArmState: {_armstate}" });
|
||||
lines.Add(new List<string>() { $"Samplerate: {EventSampleRate}, Current Sample: {CurrentSample}, Total Samples: {TotalSamples}, Fault Sample Number: {FaultSampleNumber}" });
|
||||
lines.Add(new List<string>() { $"Input Voltage: {InputVoltage.ToString("N3")}V, Backup Voltage: {BackupVoltage.ToString("N3")}V, Backup Percentage Remaining: {BatterySoc}%" });
|
||||
lines.Add(new List<string>() { $"System Temp: {SystemTempC}C, Actual Current Sample: {ActualCurrentSample}, Max Sample Available: {MaxSampleAvailable}" });
|
||||
lines.Add(new List<string>() { $"Tilt Ch1: {TiltSensorChannel1}, Tilt Ch2: {TiltSensorChannel2}, Tilt Ch3: {TiltSensorChannel3}" });
|
||||
lines.Add(new List<string>() { $"Squib Ch1: {SquibResistance1}, Squib Ch2: { SquibResistance2}, Squib Ch3: { SquibResistance3}, Squib Ch4: { SquibResistance4}" });
|
||||
lines.Add(new List<string>() { $"Squib P17V: {SquibPowerP17V}, Squib PV5: { SquibPowerP5V}, Squib P3p3V: { SquibPowerP3p3V}, Squib N5V: { SquibPowerN5V}" });
|
||||
lines.Add(new List<string>() { $"PTP Enabled: {PtpFunctionEnable}, PTP Clk Enable: {AdcPtpClkEnable}, PTP Clk Sync Status: {PtpClkSyncStatus}, ADC Clk Sync Status: {AdcClkSyncStatus}" });
|
||||
|
||||
|
||||
var sb = new StringBuilder(50);
|
||||
sb.AppendFormat("Fault Flags: ");
|
||||
if (null != CurrentFaultFlags && CurrentFaultFlags.Count > 0)
|
||||
{
|
||||
var addcomma = false;
|
||||
for (int i = 0; i < CurrentFaultFlags.Count; i++)
|
||||
{
|
||||
if (addcomma) sb.AppendFormat(", ");
|
||||
addcomma = true;
|
||||
sb.AppendFormat("{0}", CurrentFaultFlags[i].ToString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.AppendFormat("none");
|
||||
}
|
||||
lines.Add(new List<string>() { sb.ToString() });
|
||||
sb = new StringBuilder();
|
||||
sb.AppendFormat("Extended Fault Flags: ");
|
||||
if (null != ExtendedFaultFlags && ExtendedFaultFlags.Count > 0)
|
||||
{
|
||||
var addcomma = false;
|
||||
for (int i = 0; i < ExtendedFaultFlags.Count; i++)
|
||||
{
|
||||
if (addcomma) sb.AppendFormat(", ");
|
||||
addcomma = true;
|
||||
sb.AppendFormat("{0}", ExtendedFaultFlags[i].ToString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.AppendFormat("none");
|
||||
}
|
||||
lines.Add(new List<string>() { sb.ToString() });
|
||||
}
|
||||
}
|
||||
|
||||
public class Disarm : ArmCommands
|
||||
{
|
||||
protected override Commands _Command => Commands.Disarm;
|
||||
|
||||
public Disarm(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
}
|
||||
|
||||
public Disarm(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class PrepareForDiagnostics : ArmCommands
|
||||
{
|
||||
protected override Commands _Command => Commands.PrepareForDiagnostics;
|
||||
|
||||
public PrepareForDiagnostics(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
}
|
||||
|
||||
public PrepareForDiagnostics(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class PrepareForDataCollection : ArmCommands
|
||||
{
|
||||
protected override Commands _Command => Commands.PrepareForDataCollection;
|
||||
|
||||
public PrepareForDataCollection(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
}
|
||||
|
||||
public PrepareForDataCollection(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class BeginFlashErase : ArmCommands
|
||||
{
|
||||
protected override Commands _Command => Commands.BeginFlashErase;
|
||||
|
||||
public BeginFlashErase(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
}
|
||||
|
||||
public BeginFlashErase(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class QueryFlashEraseStatus : ArmCommands
|
||||
{
|
||||
protected override Commands _Command => Commands.QueryFlashEraseStatus;
|
||||
|
||||
public QueryFlashEraseStatus(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
}
|
||||
|
||||
public QueryFlashEraseStatus(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
}
|
||||
|
||||
private float _percentcomplete;
|
||||
public float PercentComplete => _percentcomplete;
|
||||
|
||||
private byte _lasterror;
|
||||
public DFConstantsAndEnums.CommandStatus LastError => (DFConstantsAndEnums.CommandStatus)_lasterror;
|
||||
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
const int LastErrorPosition = 0;
|
||||
const int PercentCompletePosition = 1;
|
||||
|
||||
if (response.Status == DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
response.GetParameter(LastErrorPosition, out _lasterror);
|
||||
response.GetParameter(PercentCompletePosition, out _percentcomplete);
|
||||
}
|
||||
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
|
||||
public override void ResponseToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.ResponseToString(ref lines);
|
||||
lines.Add(new List<string>() { $"Erase status: {LastError.ToString()}, Percent complete: {PercentComplete.ToString()}" });
|
||||
}
|
||||
|
||||
}
|
||||
public class InitializeHardwareLines : ArmCommands
|
||||
{
|
||||
protected override Commands _Command => Commands.InitializeHardwareLines;
|
||||
|
||||
public bool CheckTriggerForShort
|
||||
{
|
||||
get => Convert.ToBoolean(command.Parameter[0]);
|
||||
set => command.Parameter[0] = Convert.ToByte(value);
|
||||
}
|
||||
|
||||
public bool CheckStartForShort
|
||||
{
|
||||
get => Convert.ToBoolean(command.Parameter[1]);
|
||||
set => command.Parameter[1] = Convert.ToByte(value);
|
||||
}
|
||||
|
||||
public InitializeHardwareLines(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
command.Parameter = new byte[] { 0x01, 0x01 };
|
||||
LogCommands = false;
|
||||
}
|
||||
|
||||
public InitializeHardwareLines(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
command.Parameter = new byte[] { 0x01, 0x01 };
|
||||
LogCommands = false;
|
||||
}
|
||||
|
||||
public bool StartRecordShorted { get; private set; } = false;
|
||||
|
||||
public bool TriggerInputShorted { get; private set; } = false;
|
||||
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
switch (response.Status)
|
||||
{
|
||||
case DFConstantsAndEnums.CommandStatus.StatusNoError:
|
||||
break;
|
||||
case DFConstantsAndEnums.CommandStatus.StatusArmShortedStartRecordInput:
|
||||
StartRecordShorted = true;
|
||||
break;
|
||||
case DFConstantsAndEnums.CommandStatus.StatusArmShortedTriggerInput:
|
||||
TriggerInputShorted = true;
|
||||
break;
|
||||
case DFConstantsAndEnums.CommandStatus.StatusArmShortedStartAndTrigger:
|
||||
StartRecordShorted = true;
|
||||
TriggerInputShorted = true;
|
||||
break;
|
||||
default:
|
||||
APILogger.Log("Unexpected return from InitializeHardwareLines ", response.Status.ToString());
|
||||
break;
|
||||
}
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
|
||||
public override void ResponseToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.ResponseToString(ref lines);
|
||||
lines.Add(new List<string>(new[] { $"StartRecord: {StartRecordShorted}, Trigger: {TriggerInputShorted}" }));
|
||||
}
|
||||
|
||||
public static void Log(Exception exception, InitializeHardwareLines ihl)
|
||||
{
|
||||
var bShortStart = exception.Message.Contains(DFConstantsAndEnums.CommandStatus.StatusArmShortedStartRecordInput.ToString());
|
||||
var bShortTrig = exception.Message.Contains(DFConstantsAndEnums.CommandStatus.StatusArmShortedTriggerInput.ToString());
|
||||
|
||||
if (exception.Message.Contains(DFConstantsAndEnums.CommandStatus.StatusArmShortedStartAndTrigger.ToString()))
|
||||
{
|
||||
bShortStart = true;
|
||||
bShortTrig = true;
|
||||
}
|
||||
APILogger.Log($"InitializeHardwareLines: Start shorted: {bShortStart} Trigger shorted: {bShortTrig}");
|
||||
}
|
||||
}
|
||||
}
|
||||
7152
DataPRO/SLICECommands/AttributeCommands.cs
Normal file
7152
DataPRO/SLICECommands/AttributeCommands.cs
Normal file
File diff suppressed because it is too large
Load Diff
2498
DataPRO/SLICECommands/CalibrationCommands.cs
Normal file
2498
DataPRO/SLICECommands/CalibrationCommands.cs
Normal file
File diff suppressed because it is too large
Load Diff
35
DataPRO/SLICECommands/CommandBase.cs
Normal file
35
DataPRO/SLICECommands/CommandBase.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Reflection;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using DTS.Common.ICommunication;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE
|
||||
{
|
||||
public abstract class CommandBase : SliceCommandBase
|
||||
{
|
||||
public CommandBase(DTS.Common.Interface.DASFactory.ICommunication sock) : base(sock)
|
||||
{
|
||||
command = new CommandPacket();
|
||||
}
|
||||
|
||||
public CommandBase(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec) : base(sock, TimeoutMillisec)
|
||||
{
|
||||
command = new CommandPacket();
|
||||
}
|
||||
|
||||
protected override CommandPacketBase GetCommandPacket()
|
||||
{
|
||||
return new CommandPacket();
|
||||
}
|
||||
protected override CommandPacketBase GetCommandPacket(byte[] buffer)
|
||||
{
|
||||
return new CommandPacket(buffer);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
47
DataPRO/SLICECommands/CommandPacket.cs
Normal file
47
DataPRO/SLICECommands/CommandPacket.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE
|
||||
{
|
||||
public class CommandPacket : SliceCommandPacketBase
|
||||
{
|
||||
public enum CommandType
|
||||
{
|
||||
Reserved = 0,
|
||||
Arm = 1,
|
||||
Attribute = 2,
|
||||
Diagnostics = 3,
|
||||
EventData = 4,
|
||||
FirmwareUpdate = 5,
|
||||
Information = 6,
|
||||
QAandUtility = 7,
|
||||
Realtime = 8,
|
||||
Bulk = 9,
|
||||
StackFirmwareUpdate = 10,
|
||||
Ptp1588 = 11,
|
||||
Multicast = 12,
|
||||
};
|
||||
|
||||
private static UInt16 GlobalSequenceNumber = 0;
|
||||
private static object GlobalSequenceNumberLock = new object();
|
||||
|
||||
public CommandPacket() : base() { }
|
||||
|
||||
public override void GetNextSequenceNumber()
|
||||
{
|
||||
lock (GlobalSequenceNumberLock)
|
||||
{
|
||||
SequenceNumber = GlobalSequenceNumber;
|
||||
GlobalSequenceNumber++;
|
||||
}
|
||||
}
|
||||
|
||||
public CommandPacket(byte[] Bytes) : base(Bytes) { }
|
||||
|
||||
public override object ConvertByteToCommandType(byte b)
|
||||
{
|
||||
return (CommandType)b;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ClassDiagram MajorVersion="1" MinorVersion="1">
|
||||
<Class Name="DTS.DASLib.Command.SLICE.DownloadCommands.DownloadByteConverter" Collapsed="true">
|
||||
<Position X="2.25" Y="4" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAQAAAAAAAIREAAAAAQAAgAAAQAgAAAgQAAA=</HashCode>
|
||||
<FileName>DownloadCommands\DownloadByteConverter.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.DownloadCommands.EventDataCommands" Collapsed="true">
|
||||
<Position X="5" Y="0.5" Width="2" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>DownloadCommands\EventDataCommands.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.DownloadCommands.GetNextDownloadStreamDataSamples" Collapsed="true">
|
||||
<Position X="7.25" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>EgAAAAAAAAAAAAAAAAAABAQAAAABgAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>DownloadCommands\GetNextDownloadStreamDataSamples.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.DownloadCommands.QueryEventDataBase" Collapsed="true">
|
||||
<Position X="0.5" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AkAAAAAghABIAAQBAIAABIRCAAAAAAgAAABAFFEgAEA=</HashCode>
|
||||
<FileName>DownloadCommands\QueryEventDataBase.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.DownloadCommands.QueryEventDataReport" Collapsed="true">
|
||||
<Position X="4" Y="4" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAEAAAAAAAAAAAAAAAAAAAAABAAAAAAAIAAAAA=</HashCode>
|
||||
<FileName>DownloadCommands\QueryEventDataReport.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
<Lollipop Position="0.2" />
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.DownloadCommands.QueryTotalEventCount" Collapsed="true">
|
||||
<Position X="9.5" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAABAQAAAAAAAAAAACAAEAAAEA=</HashCode>
|
||||
<FileName>DownloadCommands\QueryTotalEventCount.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.DownloadCommands.ResetEventList" Collapsed="true">
|
||||
<Position X="2.75" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>DownloadCommands\ResetEventList.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.DownloadCommands.StartDownloadStreamData" Collapsed="true">
|
||||
<Position X="5" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAgAAAAAABAAAABAAAAAAAAAoAAABAABAgAAA=</HashCode>
|
||||
<FileName>DownloadCommands\StartDownloadStreamData.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Font Name="Segoe UI" Size="9" />
|
||||
</ClassDiagram>
|
||||
123
DataPRO/SLICECommands/Design/ClassDiagram_MulticastCommands.cd
Normal file
123
DataPRO/SLICECommands/Design/ClassDiagram_MulticastCommands.cd
Normal file
@@ -0,0 +1,123 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ClassDiagram MajorVersion="1" MinorVersion="1">
|
||||
<Class Name="DTS.DASLib.Command.SLICE.MulticastCommands.MACTableEntry" Collapsed="true">
|
||||
<Position X="8.25" Y="5.25" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAABAAAAAAAAAAAEAAAAAACBAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>MulticastCommands\MACTableEntry.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.MulticastCommands.DiscoveredConnectedSlice" Collapsed="true">
|
||||
<Position X="6.5" Y="5.25" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAACAAAAAAA=</HashCode>
|
||||
<FileName>MulticastCommands\MACTableEntry.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.MulticastCommands.MulticastAutoDiscover" Collapsed="true">
|
||||
<Position X="14" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>EAAACUEAAAIAIAgIAEBAFABACAgRgAACQCQACWAAABA=</HashCode>
|
||||
<FileName>MulticastCommands\MulticastAutoDiscover.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.MulticastCommands.MulticastCommandBase" Collapsed="true">
|
||||
<Position X="15.25" Y="0.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>IAACgAAJEABAAAAAIIAEBggQwAAAwCAAFAEIgsgQAAA=</HashCode>
|
||||
<FileName>MulticastCommands\MulticastCommandBase.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.MulticastCommands.MulticastDiscoverSlice6" Collapsed="true">
|
||||
<Position X="25.25" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>QAIACQAAACMKAAAAABAABARAAAgTiAAAQAAQIWAAQEA=</HashCode>
|
||||
<FileName>MulticastCommands\MulticastDiscoverSlice6.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.MulticastCommands.MulticastGetDhcp" Collapsed="true">
|
||||
<Position X="0.5" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAQAAAAABABAAAAAAAAAAAAAAEAAAEA=</HashCode>
|
||||
<FileName>MulticastCommands\MulticastGetDhcp.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.MulticastCommands.MulticastGetDnsAddress" Collapsed="true">
|
||||
<Position X="7.25" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAEAAAAAAAAAAAAAAEAABABAAAAAAAAAAAAAAEAAAEA=</HashCode>
|
||||
<FileName>MulticastCommands\MulticastGetDnsAddress.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.MulticastCommands.MulticastGetGatewayAddress" Collapsed="true">
|
||||
<Position X="16.25" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAACAAAAAAAAAAAAAAAJABAAAAAAAAAAAAAAEAAAEA=</HashCode>
|
||||
<FileName>MulticastCommands\MulticastGetGatewayAddress.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.MulticastCommands.MulticastGetIpAddress" Collapsed="true">
|
||||
<Position X="20.75" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAABABABAAAAAAAAAAAAAAEAAIEA=</HashCode>
|
||||
<FileName>MulticastCommands\MulticastGetIpAddress.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.MulticastCommands.MulticastGetSubnetAddress" Collapsed="true">
|
||||
<Position X="27.5" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAABABAAAAAAACAAAAAAEAAAFA=</HashCode>
|
||||
<FileName>MulticastCommands\MulticastGetSubnetAddress.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.MulticastCommands.MulticastIdentify" Collapsed="true">
|
||||
<Position X="2.75" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAABABAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>MulticastCommands\MulticastIdentify.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.MulticastCommands.MulticastResetMcu" Collapsed="true">
|
||||
<Position X="9.5" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAABABAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>MulticastCommands\MulticastResetMcu.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.MulticastCommands.MulticastSetDhcp" Collapsed="true">
|
||||
<Position X="18.5" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAQAAAAABABAAAAAAAAAQAAAAAAAAAA=</HashCode>
|
||||
<FileName>MulticastCommands\MulticastSetDhcp.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.MulticastCommands.MulticastSetDnsAddress" Collapsed="true">
|
||||
<Position X="23" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAEAAAAAAAAAAAAAAEAABABAAAAAAAAAQAAAAAAAAAA=</HashCode>
|
||||
<FileName>MulticastCommands\MulticastSetDnsAddress.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.MulticastCommands.MulticastSetGatewayAddress" Collapsed="true">
|
||||
<Position X="29.75" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAACAAAAAAAAAAAAAAAJABAAAAAAAAAQAAAAAAAAAA=</HashCode>
|
||||
<FileName>MulticastCommands\MulticastSetGatewayAddress.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.MulticastCommands.MulticastSetIpAddress" Collapsed="true">
|
||||
<Position X="5" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAABABABAAAAAAAAAQAAAAAAAIAA=</HashCode>
|
||||
<FileName>MulticastCommands\MulticastSetIPAddress.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.MulticastCommands.MulticastSetSubnetAddress" Collapsed="true">
|
||||
<Position X="11.75" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAABABAAAAAAACAQAAAAAAAABA=</HashCode>
|
||||
<FileName>MulticastCommands\MulticastSetSubnetAddress.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Font Name="Segoe UI" Size="9" />
|
||||
</ClassDiagram>
|
||||
@@ -0,0 +1,90 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ClassDiagram MajorVersion="1" MinorVersion="1">
|
||||
<Class Name="DTS.DASLib.Command.SLICE.RealtimeCommands.EndRealtimeMode" Collapsed="true">
|
||||
<Position X="0.5" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>RealtimeCommands\EndRealtimeMode.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.RealtimeCommands.GetRealtimeSamples" Collapsed="true">
|
||||
<Position X="6.25" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AEAAAAAABAAAEABAAAAABBAAAAAAAAAAAAAAgEIAEEA=</HashCode>
|
||||
<FileName>RealtimeCommands\GetRealtimeSamples.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
<Lollipop Position="0.2" />
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.RealtimeCommands.GetRealtimeSamplesSLICE2" Collapsed="true">
|
||||
<Position X="5" Y="3.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAA=</HashCode>
|
||||
<FileName>RealtimeCommands\GetRealtimeSamplesSLICE2.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.RealtimeCommands.GetRealtimeSamplesSLICE6" Collapsed="true">
|
||||
<Position X="7.25" Y="3.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAA=</HashCode>
|
||||
<FileName>RealtimeCommands\GetRealtimeSamplesSLICE6.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.RealtimeCommands.RealtimeCommandBase" Collapsed="true">
|
||||
<Position X="7.25" Y="0.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAA=</HashCode>
|
||||
<FileName>RealtimeCommands\RealtimeCommandBase.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.RealtimeCommands.RealtimeStreamDecoder" Collapsed="true">
|
||||
<Position X="0.5" Y="3.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAABAACAAAAAAABAgAgAAAAAAQAAAAAAAAAAAAgAEAA=</HashCode>
|
||||
<FileName>RealtimeCommands\RealtimeStreamDecoder.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.RealtimeCommands.RealtimeStreamingNextSamples" Collapsed="true" BaseTypeListCollapsed="true">
|
||||
<Position X="2.25" Y="3.5" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>EgABAACAAAAAAABAAAAABABAAAIBAAAAQAAAgAABEAA=</HashCode>
|
||||
<FileName>RealtimeCommands\RealtimeStreamingNextSamples.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
<Lollipop Position="0.2" Collapsed="true" />
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.RealtimeCommands.RetrieveSampleAverage" Collapsed="true">
|
||||
<Position X="2.75" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAABAQAAAAIAAAABBBAAAAAAAAgAAAAgEAAEEA=</HashCode>
|
||||
<FileName>RealtimeCommands\RetrieveSampleAverage.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.RealtimeCommands.RetrieveSingleSample" Collapsed="true">
|
||||
<Position X="9.5" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAABAAAAAAAAAAABBAAAAAAAAAAAAAAAEAAEEA=</HashCode>
|
||||
<FileName>RealtimeCommands\RetrieveSingleSample.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.RealtimeCommands.StartRealtimeMode" Collapsed="true">
|
||||
<Position X="11.75" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AAAAAAAAAAAAACAAAAAAABAAAAAAAAAAABAAAAAAAAA=</HashCode>
|
||||
<FileName>RealtimeCommands\StartRealtimeMode.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Class Name="DTS.DASLib.Command.SLICE.RealtimeCommands.StartRealtimeStreamingMode" Collapsed="true">
|
||||
<Position X="14" Y="2" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AABAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAQAAAAAA=</HashCode>
|
||||
<FileName>RealtimeCommands\StartRealtimeStreamingMode.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Class>
|
||||
<Interface Name="DTS.DASLib.Command.SLICE.RealtimeCommands.IGetRealtimeSamples" Collapsed="true">
|
||||
<Position X="0.5" Y="4.75" Width="1.5" />
|
||||
<TypeIdentifier>
|
||||
<HashCode>AgAAAAAAAAAAAABAAAAABAAAAAAAAAAAAAQAgAAAEAA=</HashCode>
|
||||
<FileName>RealtimeCommands\IGetRealtimeSamples.cs</FileName>
|
||||
</TypeIdentifier>
|
||||
</Interface>
|
||||
<Font Name="Segoe UI" Size="9" />
|
||||
</ClassDiagram>
|
||||
1309
DataPRO/SLICECommands/Design/ClassDiagram_SliceCommands.cd
Normal file
1309
DataPRO/SLICECommands/Design/ClassDiagram_SliceCommands.cd
Normal file
File diff suppressed because it is too large
Load Diff
104
DataPRO/SLICECommands/DownloadCommands/DownloadByteConverter.cs
Normal file
104
DataPRO/SLICECommands/DownloadCommands/DownloadByteConverter.cs
Normal file
@@ -0,0 +1,104 @@
|
||||
namespace DTS.DASLib.Command.SLICE.DownloadCommands
|
||||
{
|
||||
/// <summary>
|
||||
/// this is ported from FirmwareTestUtility where it was written by Loc Pham. It is included for
|
||||
/// 10573 implement SW side of single command/streaming download
|
||||
/// </summary>
|
||||
public class DownloadByteConverter
|
||||
{
|
||||
public enum DlByteIndex
|
||||
{
|
||||
Sync = 0,
|
||||
Type = 1,
|
||||
Command = 2,
|
||||
Status = 3,
|
||||
Group = 4,
|
||||
Id = 5,
|
||||
Datalength = 6,
|
||||
SequenceNumber = 8,
|
||||
HeaderCRC = 10,
|
||||
DataCRC = 12,
|
||||
DataADCStartOffset = 14,
|
||||
DataADCEndOffset = 22,
|
||||
DataStart = 30
|
||||
}
|
||||
|
||||
public ushort SeqNumber { get; }
|
||||
public ushort SeqNumberPrev { get; }
|
||||
public ulong DlAdcStartOffset { get; }
|
||||
public ulong DlAdcEndOffset { get; }
|
||||
|
||||
public ulong DlStreamSampleNumber { get; }
|
||||
|
||||
public ushort[] DlData { get; }
|
||||
|
||||
public uint[] DlChannels { get; }
|
||||
|
||||
public DownloadByteConverter(byte[] bytes)
|
||||
{
|
||||
SeqNumber = GetUShort(bytes, (int)DlByteIndex.SequenceNumber);
|
||||
DlAdcStartOffset = GetUInt(bytes, (int)DlByteIndex.DataADCStartOffset);
|
||||
DlAdcStartOffset = GetULong(bytes, (int)DlByteIndex.DataADCEndOffset);
|
||||
DlData = new ushort[(bytes.Length - (int)DlByteIndex.DataStart) / 2];
|
||||
|
||||
if (SeqNumber == 0)
|
||||
{
|
||||
SeqNumberPrev = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (SeqNumberPrev != 0 &&
|
||||
SeqNumberPrev != SeqNumber - 1)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine("sequence out of order: ");
|
||||
System.Diagnostics.Debug.WriteLine(SeqNumberPrev.ToString());
|
||||
System.Diagnostics.Debug.WriteLine(SeqNumber.ToString());
|
||||
}
|
||||
}
|
||||
SeqNumberPrev = SeqNumber;
|
||||
|
||||
for (var idx = 0; idx < DlData.Length; idx++)
|
||||
{
|
||||
DlData[idx] = GetDownloadUShort(bytes, (int)(DlByteIndex.DataStart + idx * 2));
|
||||
}
|
||||
}
|
||||
|
||||
private static ulong GetULong(byte[] bytes, int offset)
|
||||
{
|
||||
return (ulong)bytes[offset + 7] << 0 |
|
||||
(ulong)bytes[offset + 6] << 8 |
|
||||
(ulong)bytes[offset + 5] << 16 |
|
||||
(ulong)bytes[offset + 4] << 24 |
|
||||
(ulong)bytes[offset + 3] << 32 |
|
||||
(ulong)bytes[offset + 2] << 40 |
|
||||
(ulong)bytes[offset + 1] << 48 |
|
||||
(ulong)bytes[offset + 0] << 56;
|
||||
}
|
||||
|
||||
private static ushort GetUShort(byte[] bytes, int offset)
|
||||
{
|
||||
return (ushort)(bytes[offset + 1] |
|
||||
bytes[offset + 0] << 8);
|
||||
}
|
||||
|
||||
private static uint GetUInt(byte[] bytes, int offset)
|
||||
{
|
||||
return (uint)bytes[offset + 3] << 0 |
|
||||
(uint)bytes[offset + 2] << 8 |
|
||||
(uint)bytes[offset + 1] << 16 |
|
||||
(uint)bytes[offset + 0] << 32;
|
||||
}
|
||||
/// <summary>
|
||||
/// data apparently has a different byte order than parameters, so we have to
|
||||
/// rearrange byte order for parameters but not data.
|
||||
/// </summary>
|
||||
/// <param name="bytes"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <returns></returns>
|
||||
private static ushort GetDownloadUShort(byte[] bytes, int offset)
|
||||
{
|
||||
return (ushort)(bytes[offset + 0] | bytes[offset + 1] << 8);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
42
DataPRO/SLICECommands/DownloadCommands/EventDataCommands.cs
Normal file
42
DataPRO/SLICECommands/DownloadCommands/EventDataCommands.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using DTS.Common.ICommunication;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.DownloadCommands
|
||||
{
|
||||
public abstract class EventDataCommands : CommandBase
|
||||
{
|
||||
protected enum Commands
|
||||
{
|
||||
Reserved = 0x00,
|
||||
ResetEventList = 0x01,
|
||||
QueryTotalEventCount = 0x02,
|
||||
QueryMatchingEvents = 0x03,
|
||||
QueryEventData = 0x04,
|
||||
SetEventData = 0x05,
|
||||
StartDownloadStreamData = 0x06, // CMDEVD_STREAM_EVENT_DATA_START
|
||||
GetNextDownloadStreamDataSamples = 0x07, // stream packet of data out to receiver.
|
||||
QueryUartEventInfo = 0x09, // saved UART info
|
||||
QueryUartEventData = 0x0A,
|
||||
SetUartEventData = 0x0B,
|
||||
GenerateEvent = 0x0C,
|
||||
QueryEthernetEventInfo = 0x0D,
|
||||
QueryEthernetEventData = 0x0E,
|
||||
SetEthernetEventData = 0x0F
|
||||
};
|
||||
|
||||
protected abstract Commands Command { get; }
|
||||
|
||||
protected EventDataCommands(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
command.Type = CommandPacket.CommandType.EventData;
|
||||
command.SetCommand((byte)Command, Command.ToString());
|
||||
}
|
||||
|
||||
protected EventDataCommands(DTS.Common.Interface.DASFactory.ICommunication sock, int timeoutMillisec)
|
||||
: base(sock, timeoutMillisec)
|
||||
{
|
||||
command.Type = CommandPacket.CommandType.EventData;
|
||||
command.SetCommand((byte)Command, Command.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using DTS.Common.Enums.Communication;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.ICommunication;
|
||||
using DTS.Common.Utilities;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.DownloadCommands
|
||||
{
|
||||
/// <summary>
|
||||
/// This was ported from FirmwareTestUtility where it was written by Loc Pham
|
||||
/// it is being included for
|
||||
/// 10573 implement SW side of single command/streaming download
|
||||
/// this command can be used to collect data that has been collecting in a buffer
|
||||
/// from download streaming
|
||||
/// </summary>
|
||||
public class GetNextDownloadStreamDataSamples : EventDataCommands
|
||||
{
|
||||
protected override Commands Command => Commands.GetNextDownloadStreamDataSamples;
|
||||
|
||||
public GetNextDownloadStreamDataSamples(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
baseCommand = new CommandPacket();
|
||||
LogCommands = false;
|
||||
baseCommand.SetCommand((byte)Commands.GetNextDownloadStreamDataSamples, "GetNextDownloadStreamDataSamples");
|
||||
}
|
||||
public GetNextDownloadStreamDataSamples(DTS.Common.Interface.DASFactory.ICommunication sock, int msTimeout)
|
||||
: base(sock, msTimeout)
|
||||
{
|
||||
baseCommand = new CommandPacket();
|
||||
LogCommands = false;
|
||||
baseCommand.SetCommand((byte)Commands.GetNextDownloadStreamDataSamples, "GetNextDownloadStreamDataSamples");
|
||||
}
|
||||
|
||||
public DownloadByteConverter DlData { get; private set; }
|
||||
|
||||
private ushort _lastSequenceProcessed = ushort.MaxValue;
|
||||
private const int MAX_SEQUENCE_DIFF = 1000;
|
||||
|
||||
public void ProcessData()
|
||||
{
|
||||
var bytes = baseResponse.ToBytes();
|
||||
var headerCrc = response.HeaderCRC;
|
||||
response.ComputeCRCs();
|
||||
if (headerCrc != response.HeaderCRC)
|
||||
{
|
||||
DlData = null;
|
||||
return;
|
||||
}
|
||||
|
||||
DlData = new DownloadByteConverter(bytes);
|
||||
|
||||
if (null == DlData) { return; }
|
||||
if (_lastSequenceProcessed == DlData.SeqNumber)
|
||||
{
|
||||
DlData = null;
|
||||
return;
|
||||
}
|
||||
var delta = Math.Abs(DlData.SeqNumber - _lastSequenceProcessed);
|
||||
if (delta > MAX_SEQUENCE_DIFF && ushort.MaxValue != _lastSequenceProcessed && 0 != DlData.SeqNumber)
|
||||
{
|
||||
//per loc we shouldn't get here, the old code in the FWTU would apparently unintentionally throw an exception
|
||||
//I've preserved that code in comments below
|
||||
throw new Exception("sequence number overflow");
|
||||
//DlData = null;
|
||||
//_lastSequenceProcessed = DlData.SeqNumber;
|
||||
//return;
|
||||
}
|
||||
_lastSequenceProcessed = DlData.SeqNumber;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// We need to override SyncExecute because we don't want to send anything (that would tell the G5 to stop sending). Instead we just want to
|
||||
/// read whatever is out there. Otherwise this is mostly cut and paste of normal SyncExecute with some streamlining for our specific case.
|
||||
/// </summary>
|
||||
public override void SyncExecute()
|
||||
{
|
||||
// this is a try/finally to handle the ExecuteIsBusy
|
||||
try
|
||||
{
|
||||
DlData = null;
|
||||
// there can be only one!
|
||||
recorder.ExecuteIsBusy = true;
|
||||
|
||||
if (recorder.IsCanceled())
|
||||
{
|
||||
throw new CanceledException();
|
||||
}
|
||||
|
||||
UserCallback = null;
|
||||
UserCallbackData = null;
|
||||
IsSynchronous = true;
|
||||
SyncEvent.Reset();
|
||||
recorder.PseudoExecute(new byte[0], ExecuteCallback, null, IO_Timeout);
|
||||
|
||||
var syncExecTimeout = IO_Timeout;
|
||||
|
||||
try
|
||||
{
|
||||
if (!WaitWithCondition.Wait(SyncEvent, syncExecTimeout,
|
||||
recorder.CancelEvent))
|
||||
{
|
||||
//timeout
|
||||
LogString("SyncExecute: timeout");
|
||||
throw new TimeoutException(MakeLogString("SyncExecute: timeout"));
|
||||
}
|
||||
}
|
||||
catch (WaitWithCondition.ConditionMetException)
|
||||
{
|
||||
throw new CanceledException();
|
||||
}
|
||||
|
||||
// we didn't timeout, check the result
|
||||
switch (ComReport.Result)
|
||||
{
|
||||
case CommunicationConstantsAndEnums.CommunicationResult.Canceled:
|
||||
throw new CanceledException();
|
||||
|
||||
case CommunicationConstantsAndEnums.CommunicationResult.ReceiveOK:
|
||||
if (baseResponse == null)
|
||||
{
|
||||
LogString("SyncExecute: ReceiveOK but response==null!");
|
||||
LogCommand(false);
|
||||
}
|
||||
else if (baseResponse.Status != DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
// didn't go well
|
||||
var msg = MakeLogString("SyncExecute: response.Status = " + baseResponse.Status);
|
||||
LogCommand(false);
|
||||
switch (baseResponse.Status)
|
||||
{
|
||||
case DFConstantsAndEnums.CommandStatus.StatusInvalidModeForCommand:
|
||||
throw new CommandException(CommandErrorReason.InvalidMode, msg);
|
||||
case DFConstantsAndEnums.CommandStatus.StatusUnimplemented:
|
||||
case DFConstantsAndEnums.CommandStatus.StatusInvalidCommand:
|
||||
case DFConstantsAndEnums.CommandStatus.StatusInvalidCommandType:
|
||||
throw new NotImplementedException(msg);
|
||||
}
|
||||
var ex = new Exception(msg);
|
||||
ex.Data.Add("Status", baseResponse.Status);
|
||||
throw ex;
|
||||
}
|
||||
|
||||
// everything is fine, let it exit
|
||||
if (LogCommands)
|
||||
{
|
||||
LogCommand(false);
|
||||
}
|
||||
break;
|
||||
|
||||
case CommunicationConstantsAndEnums.CommunicationResult.ReceiveFailed:
|
||||
{
|
||||
var msg = MakeLogString("SyncExecute: ComReport.Result == " + ComReport.Result);
|
||||
LogCommand(false);
|
||||
|
||||
throw new CommandException(CommandErrorReason.ReceiveFailed, msg);
|
||||
}
|
||||
case CommunicationConstantsAndEnums.CommunicationResult.ReceiveTimeout:
|
||||
{
|
||||
var msg = MakeLogString("SyncExecute: ComReport.Result == " + ComReport.Result);
|
||||
LogCommand(false);
|
||||
throw new CommandException(CommandErrorReason.ReceiveFailed, msg);
|
||||
}
|
||||
|
||||
case CommunicationConstantsAndEnums.CommunicationResult.SendFailed:
|
||||
case CommunicationConstantsAndEnums.CommunicationResult.SendTimeout:
|
||||
{
|
||||
var msg = MakeLogString("SyncExecute: ComReport.Result == " + ComReport.Result);
|
||||
LogCommand(false);
|
||||
throw new CommandException(CommandErrorReason.SendFailed, msg);
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
var msg = MakeLogString("SyncExecute: Unknown ComReport.Result == " + ComReport.Result);
|
||||
LogCommand(false);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
recorder.ExecuteIsBusy = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
117
DataPRO/SLICECommands/DownloadCommands/QueryEthernetEventData.cs
Normal file
117
DataPRO/SLICECommands/DownloadCommands/QueryEthernetEventData.cs
Normal file
@@ -0,0 +1,117 @@
|
||||
using System.Collections.Generic;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.DownloadCommands
|
||||
{
|
||||
/// <summary>
|
||||
/// retrieves Ethernet data from an EthernetRecorder
|
||||
/// </summary>
|
||||
public class QueryEthernetEventData : EventDataCommands
|
||||
{
|
||||
private ushort _eventID = 0;
|
||||
public ushort EventID
|
||||
{
|
||||
get => _eventID;
|
||||
set { _eventID = value; command.SetParameter(0, _eventID); }
|
||||
}
|
||||
|
||||
protected override Commands Command => Commands.QueryEthernetEventData;
|
||||
|
||||
private uint _requestByteCount = 0;
|
||||
public uint RequestByteCount
|
||||
{
|
||||
get => _requestByteCount;
|
||||
set { _requestByteCount = value; command.SetParameter(2, _requestByteCount); }
|
||||
}
|
||||
|
||||
private ulong _StartDataOffsetBytes = 0UL;
|
||||
public ulong StartDataOffsetBytes
|
||||
{
|
||||
get => _StartDataOffsetBytes;
|
||||
set { _StartDataOffsetBytes = value; command.SetParameter(6, _StartDataOffsetBytes); }
|
||||
}
|
||||
|
||||
private byte[] _data;
|
||||
public byte[] Data
|
||||
{
|
||||
get => _data;
|
||||
set
|
||||
{
|
||||
if (null == value) { return; }
|
||||
_data = value;
|
||||
}
|
||||
}
|
||||
|
||||
private const int PARAMETER_BYTE_COUNT = 14;
|
||||
public QueryEthernetEventData(ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
command.Parameter = new byte[PARAMETER_BYTE_COUNT];
|
||||
/*
|
||||
Byte [1:0] U16 Event ID
|
||||
Byte [5:2] U32 Request byte count.
|
||||
Byte [13:6] U64 Start data offset in byte counter.
|
||||
*/
|
||||
}
|
||||
|
||||
public QueryEthernetEventData(ICommunication sock, int timeoutMS)
|
||||
: base(sock, timeoutMS)
|
||||
{
|
||||
command.Parameter = new byte[PARAMETER_BYTE_COUNT];
|
||||
/*
|
||||
Byte [1:0] U16 Event ID
|
||||
Byte [5:2] U32 Request byte count.
|
||||
Byte [13:6] U64 Start data offset in byte counter.
|
||||
*/
|
||||
}
|
||||
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
/*
|
||||
Byte [1:0]: U16 Event ID
|
||||
Byte [5:2]: U32 Payload length in byte count.
|
||||
Byte [13:6]: U64 data offset start.
|
||||
Byte [payloadLength]: Data byte stream with payload length firmware can fit to a response payload size or that of request whichever less.
|
||||
*/
|
||||
if (response.Status == DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
if (response.ParameterLength > 0)
|
||||
{
|
||||
response.GetParameter(0, out _eventID);
|
||||
response.GetParameter(2, out uint payloadLength);
|
||||
response.GetParameter(6, out _StartDataOffsetBytes);
|
||||
_data = new byte[payloadLength];
|
||||
|
||||
for (var i = 0; i < payloadLength; i++)
|
||||
{
|
||||
response.GetParameter(PARAMETER_BYTE_COUNT + i, out _data[i]);
|
||||
}
|
||||
}
|
||||
else { _eventID = 0; }
|
||||
}
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
|
||||
public override void CommandToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.CommandToString(ref lines);
|
||||
lines.Add(new List<string>()
|
||||
{
|
||||
$"Event ID: {EventID}",
|
||||
$"StartDataOffset: {StartDataOffsetBytes}",
|
||||
$"RequestByteCount: {RequestByteCount}"
|
||||
});
|
||||
}
|
||||
public override void ResponseToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.ResponseToString(ref lines);
|
||||
lines.Add(new List<string>()
|
||||
{
|
||||
$"Event ID: {EventID}",
|
||||
$"Payload(bytes): {_data.Length}",
|
||||
$"StartDataOffsetBytes: {StartDataOffsetBytes}"
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
using System.Collections.Generic;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.DownloadCommands
|
||||
{
|
||||
/// <summary>
|
||||
/// Retrieves parameters of Ethernet data recorder by EthernetRecorder
|
||||
/// </summary>
|
||||
public class QueryEthernetEventInfo : EventDataCommands
|
||||
{
|
||||
protected override Commands Command => Commands.QueryEthernetEventInfo;
|
||||
|
||||
private ushort _eventID = 0;
|
||||
public ushort EventID
|
||||
{
|
||||
get { return _eventID; }
|
||||
set { _eventID = value; command.SetParameter(0, _eventID); }
|
||||
}
|
||||
|
||||
private ushort _dataDownloaded = 0;
|
||||
public ushort DataDownloaded => _dataDownloaded;
|
||||
|
||||
private ulong _totalByteCount = 0UL;
|
||||
public ulong TotalByteCount => _totalByteCount;
|
||||
|
||||
private ulong _triggerByteCount = 0UL;
|
||||
public ulong TriggerByteCount => _triggerByteCount;
|
||||
|
||||
private ulong _faultByteCount;
|
||||
public ulong FaultByteCount => _faultByteCount;
|
||||
|
||||
private uint[] _DataStartTimeStamp = new uint[] { 0, 0 };
|
||||
public uint[] DataStartTimeStamp => _DataStartTimeStamp;
|
||||
public QueryEthernetEventInfo(ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
//Command Parameters: 4 bytes.
|
||||
//Byte[1:0] U16 Event ID.
|
||||
//Byte[3:2]: Reserved.
|
||||
command.Parameter = new byte[4];
|
||||
}
|
||||
|
||||
public QueryEthernetEventInfo(ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
//Command Parameters: 4 bytes.
|
||||
//Byte[1:0] U16 Event ID.
|
||||
//Byte[3:2]: Reserved.
|
||||
command.Parameter = new byte[4];
|
||||
}
|
||||
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
if (response.Status == DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
if (response.ParameterLength > 0)
|
||||
{
|
||||
/*
|
||||
Response: 36 bytes.
|
||||
Byte [1:0] U16 Event ID.
|
||||
Byte [3:2] U16 Data Downloaded Flag.
|
||||
Byte [11:4] U64 Total ByteCount.
|
||||
Byte [19:12] U64 Trigger ByteCount.
|
||||
Byte [27:20] U64 Fault ByteCount.
|
||||
Byte [35:28] U32[2] Data Start Timestamp. U32[0] = Second. U32[1] = Nano-Second
|
||||
*/
|
||||
response.GetParameter(0, out _eventID);
|
||||
response.GetParameter(2, out _dataDownloaded);
|
||||
response.GetParameter(4, out _totalByteCount);
|
||||
response.GetParameter(12, out _triggerByteCount);
|
||||
response.GetParameter(20, out _faultByteCount);
|
||||
response.GetParameter(28, out uint temp);
|
||||
_DataStartTimeStamp[0] = temp;
|
||||
response.GetParameter(32, out temp);
|
||||
_DataStartTimeStamp[1] = temp;
|
||||
}
|
||||
else { _eventID = 0; }
|
||||
}
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
public override void ResponseToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.ResponseToString(ref lines);
|
||||
lines.Add(new List<string>()
|
||||
{
|
||||
$"EventId: {EventID}",
|
||||
$"DataDownloaded: {DataDownloaded}",
|
||||
$"TotalByteCount: {TotalByteCount}",
|
||||
$"TriggerByteCount: {TriggerByteCount}",
|
||||
$"FaultByteCount: {FaultByteCount}",
|
||||
$"DataStartTimeStamp: {DataStartTimeStamp[0]}, {DataStartTimeStamp[1]}"
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
193
DataPRO/SLICECommands/DownloadCommands/QueryEventDataBase.cs
Normal file
193
DataPRO/SLICECommands/DownloadCommands/QueryEventDataBase.cs
Normal file
@@ -0,0 +1,193 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using DTS.Common.DASResource;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.ICommunication;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.DownloadCommands
|
||||
{
|
||||
public class QueryEventDataBase : EventDataCommands
|
||||
{
|
||||
protected override Commands Command => Commands.QueryEventData;
|
||||
private const ushort ADC_OFFSET = 0x8000;
|
||||
|
||||
public const byte ALL_CHANNELS = 0xFF;
|
||||
|
||||
protected UInt16 _eventNumber;
|
||||
protected UInt64 _firstSample;
|
||||
protected UInt64 _lastSample;
|
||||
protected UInt64 _samplesDownloaded;
|
||||
protected byte _channel;
|
||||
protected int _channelsDownloaded;
|
||||
protected ushort[] _data;
|
||||
|
||||
public UInt16 EventNumber
|
||||
{
|
||||
get => _eventNumber;
|
||||
set { _eventNumber = value; command.SetParameter(0, _eventNumber); }
|
||||
}
|
||||
|
||||
public virtual UInt64 FirstSample
|
||||
{
|
||||
get => _firstSample;
|
||||
set { _firstSample = value; command.SetParameter(2, _firstSample); }
|
||||
}
|
||||
|
||||
public virtual UInt64 LastSample
|
||||
{
|
||||
get => _lastSample;
|
||||
set { _lastSample = value; command.SetParameter(10, _lastSample); }
|
||||
}
|
||||
|
||||
public byte Channel
|
||||
{
|
||||
get => _channel;
|
||||
set
|
||||
{
|
||||
_channel = value; command.SetParameter(18, _channel);
|
||||
ChannelsDownloaded = 0xFF == _channel ? 3 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
public int ChannelsDownloaded
|
||||
{
|
||||
get => _channelsDownloaded;
|
||||
set => _channelsDownloaded = value;
|
||||
}
|
||||
|
||||
public int Count => (int)_samplesDownloaded;
|
||||
|
||||
public QueryEventDataBase(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
command.Parameter = new byte[19];
|
||||
_data = null;
|
||||
|
||||
_eventNumber = 0;
|
||||
_firstSample = 0;
|
||||
_lastSample = 0;
|
||||
_channel = 0;
|
||||
|
||||
command.ShouldLog = false;
|
||||
}
|
||||
|
||||
public QueryEventDataBase(DTS.Common.Interface.DASFactory.ICommunication sock, int timeoutMillisec)
|
||||
: base(sock, timeoutMillisec)
|
||||
{
|
||||
command.Parameter = new byte[19];
|
||||
_data = null;
|
||||
|
||||
_eventNumber = 0;
|
||||
_firstSample = 0;
|
||||
_lastSample = 0;
|
||||
_channel = 0;
|
||||
|
||||
command.ShouldLog = false;
|
||||
}
|
||||
|
||||
public override void Execute(CommandCallback cb, object cbData)
|
||||
{
|
||||
// Do a little parameter checking
|
||||
if (_firstSample > _lastSample)
|
||||
{
|
||||
// "QueryEventData.Execute: First Sample cannot be greater than Last Sample"
|
||||
throw new ApplicationException(Strings.QueryEventData_Execute_Err1);
|
||||
}
|
||||
base.Execute(cb, cbData);
|
||||
}
|
||||
|
||||
protected override CommandReceiveAction WholePackagePost()
|
||||
{
|
||||
// now send the data to the user
|
||||
var stat = CommandStatus.Success;
|
||||
if (response.Status != DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
var s = (int)response.Status;
|
||||
APILogger.LogString("QueryEventData.WholePackagePost: reporting failure, status==" + CommandPacketBase.StatusLabels[s] + " (0x" + s.ToString("X") + ")");
|
||||
stat = CommandStatus.Failure;
|
||||
}
|
||||
var cbReport = new QueryEventDataReport(stat, UserCallbackData);
|
||||
cbReport.Data = new short[_channelsDownloaded][];
|
||||
for (var i = 0; i < _channelsDownloaded; i++)
|
||||
GetChannelData(i, out cbReport.Data[i]);
|
||||
return UserCallback(cbReport);
|
||||
}
|
||||
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
if (response.Status != DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
_samplesDownloaded = (ulong)(response.Parameter.Length / 2) / (ulong)_channelsDownloaded;
|
||||
_data = new ushort[_samplesDownloaded * (ulong)_channelsDownloaded];
|
||||
for (var i = 0; (ulong)i < _samplesDownloaded * (ulong)_channelsDownloaded; i++)
|
||||
{
|
||||
response.GetParameter(2 * i, out _data[i]);
|
||||
}
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
|
||||
public override void SyncExecute()
|
||||
{
|
||||
// Do a little parameter checking
|
||||
if (_firstSample > _lastSample)
|
||||
{
|
||||
// "QueryEventData.SyncExecute: First Sample cannot be greater than Last Sample"
|
||||
throw new ApplicationException(Strings.QueryEventData_SyncExecute_Err1);
|
||||
}
|
||||
base.SyncExecute();
|
||||
}
|
||||
|
||||
public virtual void GetChannelData(int channel, out short[] signedADC)
|
||||
{
|
||||
if (channel < 0 || channel > _channelsDownloaded)
|
||||
{
|
||||
// "QueryEventData.GetChannelData: Data requested on a channel that wasn't downloaded."
|
||||
throw new ApplicationException(Strings.QueryEventData_GetChannelData_Err1);
|
||||
}
|
||||
|
||||
// Data order for a 9 channel stack
|
||||
// 7 8 9 4 5 6 1 2 3 7 8 9 4 5 6 1 2 3 etc.
|
||||
|
||||
var rv = new short[_samplesDownloaded];
|
||||
var sliceNumber = channel / 3;
|
||||
var sliceOffset = (_channelsDownloaded / 3 - sliceNumber - 1) * 3;
|
||||
if (sliceOffset < 0) sliceOffset = 0;
|
||||
var channelInSlice = channel % 3;
|
||||
for (var i = 0; i < rv.Length; i++)
|
||||
{
|
||||
rv[i] = (short)(_data[i * _channelsDownloaded + sliceOffset + channelInSlice] - ADC_OFFSET);
|
||||
}
|
||||
signedADC = rv;
|
||||
}
|
||||
|
||||
public virtual void GetRawIndexedData(int index, out ushort[] data)
|
||||
{
|
||||
data = new ushort[_samplesDownloaded];
|
||||
for (var i = 0; i < data.Length; i++)
|
||||
{
|
||||
data[i] = _data[i * _channelsDownloaded + index];
|
||||
}
|
||||
}
|
||||
|
||||
public override void CommandToString(ref List<List<string>> lines)
|
||||
{
|
||||
lines.Add(new List<string> { $"Event number: {EventNumber}, First sample: {FirstSample}, Last sample: {LastSample}" });
|
||||
}
|
||||
|
||||
public override void ResponseToString(ref List<List<string>> lines)
|
||||
{
|
||||
lines.Add(new List<string>
|
||||
{
|
||||
$"ChannelsDownloaded: {ChannelsDownloaded}, Count: {Count}"
|
||||
});
|
||||
}
|
||||
|
||||
public void LogResponse()
|
||||
{
|
||||
LogCommand(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
namespace DTS.DASLib.Command.SLICE.DownloadCommands
|
||||
{
|
||||
public class QueryEventDataReport : ICommandReport
|
||||
{
|
||||
public object CallbackObject { get; set; }
|
||||
public CommandStatus Status { get; set; }
|
||||
public short[][] Data { get; set; }
|
||||
|
||||
public QueryEventDataReport(CommandStatus status, object cbData)
|
||||
{
|
||||
Status = status;
|
||||
CallbackObject = cbData;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using System.Collections.Generic;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.ICommunication;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.DownloadCommands
|
||||
{
|
||||
public class QueryTotalEventCount : EventDataCommands
|
||||
{
|
||||
protected override Commands Command => Commands.QueryTotalEventCount;
|
||||
private ushort _count;
|
||||
|
||||
public ushort Count => _count;
|
||||
|
||||
public QueryTotalEventCount(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
}
|
||||
|
||||
public QueryTotalEventCount(DTS.Common.Interface.DASFactory.ICommunication sock, int timeoutMillisec)
|
||||
: base(sock, timeoutMillisec)
|
||||
{
|
||||
}
|
||||
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
if (response.Status != DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
if (response.ParameterLength > 0)
|
||||
{
|
||||
response.GetParameter(0, out _count);
|
||||
}
|
||||
else { _count = 0; }
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
|
||||
public override void ResponseToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.ResponseToString(ref lines);
|
||||
lines.Add(new List<string>
|
||||
{
|
||||
$"Count: {Count}"
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
144
DataPRO/SLICECommands/DownloadCommands/QueryUARTEventData.cs
Normal file
144
DataPRO/SLICECommands/DownloadCommands/QueryUARTEventData.cs
Normal file
@@ -0,0 +1,144 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.DownloadCommands
|
||||
{
|
||||
public class QueryUARTEventData : EventDataCommands
|
||||
{
|
||||
public const int MAX_DATA_LENGTH = 2000;
|
||||
public const int PAYLOAD_HEADER_LENGTH = 14;
|
||||
protected override Commands Command => Commands.QueryUartEventData;
|
||||
|
||||
protected ushort _eventNumber;
|
||||
protected uint _requestByteCount;
|
||||
protected ulong _requestOffsetByteCount;
|
||||
protected uint _payloadByteCount;
|
||||
protected ulong _payloadOffsetByteCount;
|
||||
protected byte[] _data;
|
||||
|
||||
public ushort EventNumber
|
||||
{
|
||||
get => _eventNumber;
|
||||
set { _eventNumber = value; command.SetParameter(0, _eventNumber); }
|
||||
}
|
||||
|
||||
public uint RequestByteCount
|
||||
{
|
||||
get => _requestByteCount;
|
||||
set { _requestByteCount = value; command.SetParameter(2, _requestByteCount); }
|
||||
}
|
||||
|
||||
public ulong RequestOffsetByteCount
|
||||
{
|
||||
get => _requestOffsetByteCount;
|
||||
set { _requestOffsetByteCount = value; command.SetParameter(6, _requestOffsetByteCount); }
|
||||
}
|
||||
|
||||
public uint PayloadByteCount => _payloadByteCount;
|
||||
|
||||
public ulong PayloadOffsetByteCount => _payloadOffsetByteCount;
|
||||
|
||||
public byte[] PayloadData => _data;
|
||||
|
||||
public QueryUARTEventData(ICommunication sock) : base(sock)
|
||||
{
|
||||
command.Parameter = new byte[14];
|
||||
_data = null;
|
||||
|
||||
_eventNumber = 0;
|
||||
_requestByteCount = 0;
|
||||
_requestOffsetByteCount = 0;
|
||||
_payloadByteCount = 0;
|
||||
_payloadOffsetByteCount = 0;
|
||||
|
||||
command.ShouldLog = false;
|
||||
}
|
||||
|
||||
public QueryUARTEventData(ICommunication sock, int timeoutMillisec) : base(sock, timeoutMillisec)
|
||||
{
|
||||
command.Parameter = new byte[14];
|
||||
_data = null;
|
||||
|
||||
_eventNumber = 0;
|
||||
_requestByteCount = 0;
|
||||
_requestOffsetByteCount = 0;
|
||||
_payloadByteCount = 0;
|
||||
_payloadOffsetByteCount = 0;
|
||||
|
||||
command.ShouldLog = false;
|
||||
}
|
||||
|
||||
public override void Execute(CommandCallback cb, object cbData)
|
||||
{
|
||||
// Do a little parameter checking
|
||||
_data = null;
|
||||
base.Execute(cb, cbData);
|
||||
}
|
||||
|
||||
protected override CommandReceiveAction WholePackagePost()
|
||||
{
|
||||
// now send the data to the user
|
||||
var stat = CommandStatus.Success;
|
||||
if (response.Status != DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
var s = (int)response.Status;
|
||||
APILogger.LogString("QueryUARTEventData.WholePackagePost: reporting failure, status==" + CommandPacketBase.StatusLabels[s] + " (0x" + s.ToString("X") + ")");
|
||||
stat = CommandStatus.Failure;
|
||||
}
|
||||
var cbReport = new QueryEventDataReport(stat, UserCallbackData);
|
||||
//cbReport.Data = new short[_channelsDownloaded][];
|
||||
//for (var i = 0; i < _channelsDownloaded; i++)
|
||||
// GetChannelData(i, out cbReport.Data[i]);
|
||||
return UserCallback(cbReport);
|
||||
}
|
||||
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
if (response.Status != DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
response.GetParameter(0, out ushort responseEventNum);
|
||||
response.GetParameter(2, out _payloadByteCount);
|
||||
response.GetParameter(6, out _payloadOffsetByteCount);
|
||||
_data = new byte[_payloadByteCount];
|
||||
for (var i = 0; i < _payloadByteCount; i++)
|
||||
{
|
||||
response.GetParameter(PAYLOAD_HEADER_LENGTH + i, out _data[i]);
|
||||
}
|
||||
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
|
||||
public override void SyncExecute()
|
||||
{
|
||||
// Do a little parameter checking
|
||||
_data = null;
|
||||
base.SyncExecute();
|
||||
}
|
||||
|
||||
public override void CommandToString(ref List<List<string>> lines)
|
||||
{
|
||||
lines.Add(new List<string> { $"Event number: {EventNumber}, RequestByteCount: {RequestByteCount}, OffsetByteCount: {RequestOffsetByteCount}" });
|
||||
}
|
||||
|
||||
public override void ResponseToString(ref List<List<string>> lines)
|
||||
{
|
||||
lines.Add(new List<string>
|
||||
{
|
||||
$"PayloadByteCount: {PayloadByteCount}, OffsetByteCount: {PayloadOffsetByteCount}"
|
||||
});
|
||||
}
|
||||
|
||||
public void LogResponse()
|
||||
{
|
||||
LogCommand(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
153
DataPRO/SLICECommands/DownloadCommands/QueryUARTEventInfo.cs
Normal file
153
DataPRO/SLICECommands/DownloadCommands/QueryUARTEventInfo.cs
Normal file
@@ -0,0 +1,153 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.Interface.DASFactory;
|
||||
using DTS.Common.Strings;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.DownloadCommands
|
||||
{
|
||||
public class QueryUARTEventInfo : EventDataCommands
|
||||
{
|
||||
protected override Commands Command => Commands.QueryUartEventInfo;
|
||||
|
||||
protected ushort _eventNumber;
|
||||
protected ushort _dataPresent;
|
||||
protected ushort _dataDownloaded;
|
||||
protected ulong _totalByteCount;
|
||||
protected ulong _triggerByteCount;
|
||||
protected ulong _faultByteCount;
|
||||
protected uint _startTimestamp;
|
||||
protected uint _endTimestamp;
|
||||
protected uint _baudrate;
|
||||
|
||||
public ushort EventNumber
|
||||
{
|
||||
get => _eventNumber;
|
||||
set { _eventNumber = value; command.SetParameter(0, _eventNumber); }
|
||||
}
|
||||
|
||||
public QueryUARTEventInfo(ICommunication sock) : base(sock)
|
||||
{
|
||||
command.Parameter = new byte[2];
|
||||
|
||||
_eventNumber = 0;
|
||||
_dataPresent = 0;
|
||||
_dataDownloaded = 0;
|
||||
_totalByteCount = 0;
|
||||
_triggerByteCount = 0;
|
||||
_faultByteCount = 0;
|
||||
_startTimestamp = 0;
|
||||
_endTimestamp = 0;
|
||||
_baudrate = 0;
|
||||
|
||||
command.ShouldLog = false;
|
||||
}
|
||||
|
||||
public QueryUARTEventInfo(ICommunication sock, int timeoutMillisec) : base(sock, timeoutMillisec)
|
||||
{
|
||||
command.Parameter = new byte[2];
|
||||
|
||||
_eventNumber = 0;
|
||||
_dataPresent = 0;
|
||||
_dataDownloaded = 0;
|
||||
_totalByteCount = 0;
|
||||
_faultByteCount = 0;
|
||||
_triggerByteCount = 0;
|
||||
_startTimestamp = 0;
|
||||
_endTimestamp = 0;
|
||||
_baudrate = 0;
|
||||
|
||||
command.ShouldLog = false;
|
||||
}
|
||||
|
||||
public bool DataPresent => 1 == _dataPresent;
|
||||
|
||||
public bool DataDownloaded => 1 == _dataDownloaded;
|
||||
|
||||
public ulong TotalByteCount => _totalByteCount;
|
||||
|
||||
public ulong TriggerByteCount => _triggerByteCount;
|
||||
|
||||
public ulong FaultByteCount => _faultByteCount;
|
||||
|
||||
public uint StartTimestamp => _startTimestamp;
|
||||
|
||||
public uint EndTimestamp => _endTimestamp;
|
||||
|
||||
public uint BaudRate => _baudrate;
|
||||
|
||||
public override void Execute(CommandCallback cb, object cbData)
|
||||
{
|
||||
// Do a little parameter checking
|
||||
|
||||
base.Execute(cb, cbData);
|
||||
}
|
||||
|
||||
protected override CommandReceiveAction WholePackagePost()
|
||||
{
|
||||
// now send the data to the user
|
||||
var stat = CommandStatus.Success;
|
||||
if (response.Status != DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
var s = (int)response.Status;
|
||||
APILogger.LogString("QueryUARTEventInfo.WholePackagePost: reporting failure, status==" + CommandPacketBase.StatusLabels[s] + " (0x" + s.ToString("X") + ")");
|
||||
stat = CommandStatus.Failure;
|
||||
}
|
||||
var cbReport = new QueryEventDataReport(stat, UserCallbackData);
|
||||
//cbReport.Data = new short[_channelsDownloaded][];
|
||||
//for (var i = 0; i < _channelsDownloaded; i++)
|
||||
// GetChannelData(i, out cbReport.Data[i]);
|
||||
return UserCallback(cbReport);
|
||||
}
|
||||
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
if (response.Status != DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
response.GetParameter(0, out ushort responseEventNum);
|
||||
response.GetParameter(2, out _dataPresent);
|
||||
response.GetParameter(4, out _dataDownloaded);
|
||||
response.GetParameter(8, out _totalByteCount);
|
||||
response.GetParameter(16, out _triggerByteCount);
|
||||
response.GetParameter(24, out _faultByteCount);
|
||||
response.GetParameter(32, out _startTimestamp);
|
||||
response.GetParameter(36, out _endTimestamp);
|
||||
response.GetParameter(40, out _baudrate);
|
||||
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
|
||||
public override void SyncExecute()
|
||||
{
|
||||
// Do a little parameter checking
|
||||
|
||||
base.SyncExecute();
|
||||
}
|
||||
|
||||
public override void CommandToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.CommandToString(ref lines);
|
||||
lines.Add(new List<string> { $"Event number: {EventNumber}" });
|
||||
}
|
||||
|
||||
public override void ResponseToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.ResponseToString(ref lines);
|
||||
lines.Add(new List<string>
|
||||
{
|
||||
$"DataPresent: {DataPresent}, DataDownloaded: {DataDownloaded}, TotalByteCount: {TotalByteCount}, TriggerByteCount: {TriggerByteCount}, StartTimestamp: {StartTimestamp}, EndTimestamp: {EndTimestamp}"
|
||||
});
|
||||
}
|
||||
|
||||
public void LogResponse()
|
||||
{
|
||||
LogCommand(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
19
DataPRO/SLICECommands/DownloadCommands/ResetEventList.cs
Normal file
19
DataPRO/SLICECommands/DownloadCommands/ResetEventList.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using DTS.Common.ICommunication;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.DownloadCommands
|
||||
{
|
||||
public class ResetEventList : EventDataCommands
|
||||
{
|
||||
protected override Commands Command => Commands.ResetEventList;
|
||||
|
||||
public ResetEventList(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
}
|
||||
|
||||
public ResetEventList(DTS.Common.Interface.DASFactory.ICommunication sock, int timeoutMillisec)
|
||||
: base(sock, timeoutMillisec)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
using DTS.Common.ICommunication;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE.DownloadCommands
|
||||
{
|
||||
/// <summary>
|
||||
/// this was ported almost directly from FirmwareTestUtility, where it was written by Loc Pham
|
||||
/// this was done for
|
||||
/// 10573 implement SW side of single command/streaming download
|
||||
/// this command should put SLICE2 firmware >= A1N4 into download streaming mode
|
||||
/// any command should be sufficient to stop this streaming early
|
||||
/// </summary>
|
||||
public class StartDownloadStreamData : EventDataCommands
|
||||
{
|
||||
protected override Commands Command => Commands.StartDownloadStreamData;
|
||||
|
||||
public StartDownloadStreamData(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
command.Parameter = new byte[18];
|
||||
}
|
||||
|
||||
public StartDownloadStreamData(DTS.Common.Interface.DASFactory.ICommunication sock, int timeoutMillisec)
|
||||
: base(sock, timeoutMillisec)
|
||||
{
|
||||
command.Parameter = new byte[18];
|
||||
}
|
||||
|
||||
public const byte AllChannels = 0xFF;
|
||||
|
||||
private ushort _eventNumber;
|
||||
private ulong _firstSample;
|
||||
private ulong _lastSample;
|
||||
|
||||
public ushort EventNumber
|
||||
{
|
||||
get => _eventNumber;
|
||||
set
|
||||
{
|
||||
_eventNumber = value;
|
||||
command.SetParameter(0, _eventNumber);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual ulong FirstSample
|
||||
{
|
||||
get => _firstSample;
|
||||
set
|
||||
{
|
||||
_firstSample = value;
|
||||
command.SetParameter(2, _firstSample);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual ulong LastSample
|
||||
{
|
||||
get => _lastSample;
|
||||
set
|
||||
{
|
||||
_lastSample = value;
|
||||
command.SetParameter(10, _lastSample);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
559
DataPRO/SLICECommands/FirmwareUpdateCommands.cs
Normal file
559
DataPRO/SLICECommands/FirmwareUpdateCommands.cs
Normal file
@@ -0,0 +1,559 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using DTS.Common.Enums.DASFactory;
|
||||
using DTS.Common.ICommunication;
|
||||
|
||||
namespace DTS.DASLib.Command.SLICE
|
||||
{
|
||||
public abstract class FirmwareUpdateCommands : CommandBase
|
||||
{
|
||||
protected enum Commands
|
||||
{
|
||||
Reserved = 0x00,
|
||||
QueryFirmwareUpdateBlockSize = 0x01,
|
||||
QueryBootloaderVersion = 0x02,
|
||||
SwitchToFirmwareUpdateMode = 0x03,
|
||||
BeginFirmwareUpdate = 0x04,
|
||||
ProgramFirmwareUpdateBlock = 0x05,
|
||||
FinishFirmwareUpdate = 0x06,
|
||||
Reboot = 0x07,
|
||||
QueryInFirmwareUpdateMode = 0x08,
|
||||
|
||||
// added to support slice pro (Bridge/IEPE) firmware update via USB.
|
||||
Load_SliceProStackFirmwareImage = 0x09, // CMDFW_LOAD_STACK_FW, // = 0x09, loading (in 400-byte blocks) firmware image to base NAND.
|
||||
Query_SliceProStackFirmwareImage = 0x0A, // CMDFW_QUERY_STACK_FW, // = 0x0A, reading block (in 400-byte blocks) of firmware image from base NAND at a time.
|
||||
Query_SliceProStackFirmwareCRC = 0x0B, // CMDFW_QUERY_STACK_FW_CRC, // = 0x0B, read firmware CRC for validation purpose.
|
||||
Start_SliceProStackFirmwareUpdate = 0x0C, // CMDFW_START_STACK_FW_UPDADE, // = 0x0C, stack module to be upgraded with firmware.
|
||||
Stop_SliceProStackFirmwareUpdate = 0x0D, // CMDFW_STOP_STACK_FW_UPDADE, // = 0x0D, stop firmware upgrade for after completes the on-going one.
|
||||
Query_SliceProStackFirmwareUpdateMode = 0x0E, // CMDFW_QUERY_STACK_FW_UPDATE_MODE, // = 0x0E, polling updatae mode from stack
|
||||
Set_SliceProStackFirmwareUpdateMode = 0x0F, // CMDFW_SET_STACK_FW_UPDATE_MODE, // = 0x0F, Set stack module to update mode
|
||||
MAX_CMDFW_COMMAND // = 0x10
|
||||
};
|
||||
|
||||
public enum FirmwareMode
|
||||
{
|
||||
FW = 0,
|
||||
BL = 1,
|
||||
BLL = 2,
|
||||
};
|
||||
|
||||
//protected const int MIN_SLICE2_FILEDATA_PROTOCOL = 130; //SLICE 2 Protocol cmd
|
||||
protected const int MAX_FILE_ID = 30; // user = 10, firmware = 20, max internally = 65. 10;
|
||||
protected const int MAX_FILE_LENGTH = 400;
|
||||
|
||||
protected abstract Commands _Command { get; }
|
||||
protected FirmwareUpdateCommands(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
command.Type = CommandPacket.CommandType.FirmwareUpdate;
|
||||
command.SetCommand((byte)_Command, _Command.ToString());
|
||||
}
|
||||
|
||||
protected FirmwareUpdateCommands(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
command.Type = CommandPacket.CommandType.FirmwareUpdate;
|
||||
command.SetCommand((byte)_Command, _Command.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public class QueryFirmwareUpdateBlockSize : FirmwareUpdateCommands
|
||||
{
|
||||
protected override Commands _Command => Commands.QueryFirmwareUpdateBlockSize;
|
||||
|
||||
private ushort _size;
|
||||
public ushort BlockSize => _size;
|
||||
|
||||
public QueryFirmwareUpdateBlockSize(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
_size = 0;
|
||||
}
|
||||
|
||||
public QueryFirmwareUpdateBlockSize(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
_size = 0;
|
||||
}
|
||||
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
if (response.Status == DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
response.GetParameter(0, out _size);
|
||||
}
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
|
||||
public override void ResponseToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.CommandToString(ref lines);
|
||||
lines.Add(new List<string>()
|
||||
{
|
||||
$"BlockSize: {BlockSize}"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public class QueryBootloaderVersion : FirmwareUpdateCommands
|
||||
{
|
||||
protected override Commands _Command => Commands.QueryBootloaderVersion;
|
||||
|
||||
private string _version = string.Empty;
|
||||
public string Version => _version;
|
||||
|
||||
public QueryBootloaderVersion(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
}
|
||||
|
||||
public QueryBootloaderVersion(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
}
|
||||
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
if (response.Status == DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
response.GetParameter(0, out _version);
|
||||
}
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
|
||||
public override void ResponseToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.ResponseToString(ref lines);
|
||||
lines.Add(new List<string>()
|
||||
{
|
||||
$"Version: {Version}"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public class SwitchToFirmwareUpdateMode : FirmwareUpdateCommands
|
||||
{
|
||||
protected override Commands _Command => Commands.SwitchToFirmwareUpdateMode;
|
||||
|
||||
public SwitchToFirmwareUpdateMode(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
}
|
||||
|
||||
public SwitchToFirmwareUpdateMode(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class BeginFirmwareUpdate : FirmwareUpdateCommands
|
||||
{
|
||||
protected override Commands _Command => Commands.BeginFirmwareUpdate;
|
||||
|
||||
public BeginFirmwareUpdate(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
}
|
||||
|
||||
public BeginFirmwareUpdate(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class ProgramFirmwareUpdateBlock : FirmwareUpdateCommands
|
||||
{
|
||||
protected override Commands _Command => Commands.ProgramFirmwareUpdateBlock;
|
||||
|
||||
private uint _address;
|
||||
private ushort _blockcrc;
|
||||
private ushort _upperlower;
|
||||
private byte[] _data;
|
||||
|
||||
public uint BlockBaseAddress
|
||||
{
|
||||
get => _address;
|
||||
set
|
||||
{
|
||||
_address = value;
|
||||
command.SetParameter(0, _address);
|
||||
}
|
||||
}
|
||||
|
||||
public ushort BlockSize { get; private set; }
|
||||
|
||||
public ushort BlockCRC16
|
||||
{
|
||||
get => _blockcrc;
|
||||
set
|
||||
{
|
||||
_blockcrc = value;
|
||||
command.SetParameter(6, _blockcrc);
|
||||
}
|
||||
}
|
||||
|
||||
public bool Upper
|
||||
{
|
||||
get => _upperlower == 1 ? true : false;
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
_upperlower = 1;
|
||||
command.SetParameter(8, _upperlower);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] Data
|
||||
{
|
||||
get => _data;
|
||||
set
|
||||
{
|
||||
if (null == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_data = value;
|
||||
if (command.Parameter.Length < value.Length + 10)
|
||||
{
|
||||
var newparameter = new byte[value.Length + 10];
|
||||
BlockSize = (ushort)value.Length;
|
||||
command.SetParameter(4, BlockSize);
|
||||
Buffer.BlockCopy(command.Parameter, 0,
|
||||
newparameter, 0, 10);
|
||||
command.Parameter = newparameter;
|
||||
Buffer.BlockCopy(_data, 0, command.Parameter, 10, _data.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ProgramFirmwareUpdateBlock(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
command.Parameter = new byte[10];
|
||||
Upper = false;
|
||||
}
|
||||
|
||||
public ProgramFirmwareUpdateBlock(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
command.Parameter = new byte[10];
|
||||
Upper = false;
|
||||
}
|
||||
|
||||
public override void CommandToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.CommandToString(ref lines);
|
||||
lines.Add(new List<string>() { $"BlockBaseAddress: {BlockBaseAddress}, BlockSize: {BlockSize}, BlockCRC16: {BlockCRC16}, Upper: {Upper}" });
|
||||
}
|
||||
}
|
||||
|
||||
public class FinishFirmwareUpdate : FirmwareUpdateCommands
|
||||
{
|
||||
protected override Commands _Command => Commands.FinishFirmwareUpdate;
|
||||
|
||||
private ushort _imagecrc;
|
||||
|
||||
public ushort ImageCRC16
|
||||
{
|
||||
get => _imagecrc;
|
||||
set
|
||||
{
|
||||
_imagecrc = value;
|
||||
command.SetParameter(0, _imagecrc);
|
||||
}
|
||||
}
|
||||
|
||||
public FinishFirmwareUpdate(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
command.Parameter = new byte[2];
|
||||
}
|
||||
|
||||
public FinishFirmwareUpdate(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
command.Parameter = new byte[2];
|
||||
}
|
||||
|
||||
public override void CommandToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.CommandToString(ref lines);
|
||||
lines.Add(new List<string>() { $"ImageCRC16: {ImageCRC16}" });
|
||||
}
|
||||
|
||||
public override void ResponseToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.ResponseToString(ref lines);
|
||||
lines.Add(new List<string>()
|
||||
{
|
||||
$"ImageCRC16: {ImageCRC16}"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public class Reboot : FirmwareUpdateCommands
|
||||
{
|
||||
protected override Commands _Command => Commands.Reboot;
|
||||
public Reboot(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
}
|
||||
|
||||
public Reboot(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class QueryInFirmwareUpdateMode : FirmwareUpdateCommands
|
||||
{
|
||||
protected override Commands _Command => Commands.QueryInFirmwareUpdateMode;
|
||||
private byte _updateMode = (byte)FirmwareMode.FW;
|
||||
public bool InUpdateMode => FirmwareMode.FW != (FirmwareMode)_updateMode;
|
||||
|
||||
public bool IsFwMode => FirmwareMode.FW == (FirmwareMode)_updateMode;
|
||||
public bool IsBlMode => FirmwareMode.BL == (FirmwareMode)_updateMode;
|
||||
public bool IsBllMode => FirmwareMode.BLL == (FirmwareMode)_updateMode;
|
||||
|
||||
public FirmwareMode Mode => (FirmwareMode)_updateMode;
|
||||
|
||||
public QueryInFirmwareUpdateMode(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
}
|
||||
|
||||
public QueryInFirmwareUpdateMode(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
}
|
||||
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
if (response.Status == DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
response.GetParameter(0, out _updateMode);
|
||||
}
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
public override void ResponseToString(ref List<List<string>> lines)
|
||||
{
|
||||
base.ResponseToString(ref lines);
|
||||
lines.Add(new List<string>()
|
||||
{
|
||||
string.Format($"UpdateMode: {(FirmwareMode)_updateMode}")
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
///These stack firmware command updates need at least protocol version 137
|
||||
///No parameter. All slice in bootloader mode will be updated with new firmware.
|
||||
/// </summary>
|
||||
///
|
||||
public class Load_SliceProStackFirmwareImage : FirmwareUpdateCommands
|
||||
{
|
||||
protected override Commands _Command => Commands.Load_SliceProStackFirmwareImage;
|
||||
|
||||
#region Private Variables
|
||||
private readonly ushort _fileID; //Byte 0-1: 16-bit file ID ranges from 1-10.
|
||||
private uint _startByteCount;
|
||||
private byte[] _data;
|
||||
private static byte PARAM_NUM = 6;
|
||||
#endregion
|
||||
|
||||
#region Command Parameters
|
||||
|
||||
public uint StartByteCount
|
||||
{
|
||||
get => _startByteCount;
|
||||
set { _startByteCount = value; command.SetParameter(2, _startByteCount); }
|
||||
}
|
||||
|
||||
public byte[] Data
|
||||
{
|
||||
get => _data;
|
||||
set
|
||||
{
|
||||
if (null == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (MAX_FILE_LENGTH < value.Length)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
_data = value;
|
||||
//if (this.command.Parameter.Length < value.Length+ PARAM_NUM)
|
||||
//{
|
||||
byte[] newparameter = new byte[value.Length + PARAM_NUM];
|
||||
Buffer.BlockCopy(command.Parameter, 0, newparameter, 0, PARAM_NUM);
|
||||
Size = value.Length;
|
||||
command.Parameter = newparameter;
|
||||
Buffer.BlockCopy(_data, 0, command.Parameter, PARAM_NUM, _data.Length);
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
public int Size { get; private set; }
|
||||
|
||||
public int MaximumFileStreamBytes => MAX_FILE_LENGTH;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Command Functions
|
||||
public Load_SliceProStackFirmwareImage(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
command.Parameter = new byte[PARAM_NUM];
|
||||
MinimumProtocolVersion = sock.GetMinProto(DFConstantsAndEnums.ProtocolLimitedCommands.StackFirmwareUpdate);
|
||||
_data = null;
|
||||
|
||||
_fileID = 20;
|
||||
command.SetParameter(0, _fileID);
|
||||
_startByteCount = 0;
|
||||
|
||||
command.ShouldLog = false;
|
||||
}
|
||||
|
||||
public Load_SliceProStackFirmwareImage(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
command.Parameter = new byte[PARAM_NUM];
|
||||
MinimumProtocolVersion = sock.GetMinProto(DFConstantsAndEnums.ProtocolLimitedCommands.StackFirmwareUpdate);
|
||||
_data = null;
|
||||
|
||||
_fileID = 20;
|
||||
command.SetParameter(0, _fileID);
|
||||
_startByteCount = 0;
|
||||
|
||||
command.ShouldLog = false;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Log Functions
|
||||
public override void CommandToString(ref List<List<string>> lines)
|
||||
{
|
||||
lines.Add(new List<string>() { $"Store ID: {_fileID}, Start Byte: {StartByteCount}, End Byte: {Size + StartByteCount}" });
|
||||
}
|
||||
|
||||
public void LogResponse()
|
||||
{
|
||||
LogCommand(false);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
public class Start_SliceProStackFirmwareUpdate : FirmwareUpdateCommands
|
||||
{
|
||||
protected override Commands _Command => Commands.Start_SliceProStackFirmwareUpdate;
|
||||
|
||||
public Start_SliceProStackFirmwareUpdate(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
MinimumProtocolVersion = sock.GetMinProto(DFConstantsAndEnums.ProtocolLimitedCommands.StackFirmwareUpdate);
|
||||
|
||||
command.Type = CommandPacket.CommandType.FirmwareUpdate;
|
||||
command.SetCommand((byte)_Command, _Command.ToString());
|
||||
}
|
||||
|
||||
public Start_SliceProStackFirmwareUpdate(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
MinimumProtocolVersion = sock.GetMinProto(DFConstantsAndEnums.ProtocolLimitedCommands.StackFirmwareUpdate);
|
||||
|
||||
command.Type = CommandPacket.CommandType.FirmwareUpdate;
|
||||
command.SetCommand((byte)_Command, _Command.ToString());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class Set_SliceProStackFirmwareUpdateMode : FirmwareUpdateCommands
|
||||
{
|
||||
protected override Commands _Command => Commands.Set_SliceProStackFirmwareUpdateMode;
|
||||
|
||||
private int _sliceCount = 0;
|
||||
private byte[] _sliceProUpdateMode;
|
||||
|
||||
public int SliceModuleCount
|
||||
{
|
||||
get => _sliceCount;
|
||||
set
|
||||
{
|
||||
_sliceCount = value;
|
||||
_sliceProUpdateMode = new byte[_sliceCount];
|
||||
}
|
||||
}
|
||||
public byte[] SliceModuledateMode
|
||||
{
|
||||
get => _sliceProUpdateMode;
|
||||
set
|
||||
{
|
||||
for (int i = 0; i < _sliceCount; i++)
|
||||
{
|
||||
_sliceProUpdateMode[i] = value[i];
|
||||
}
|
||||
command.Parameter = _sliceProUpdateMode;
|
||||
}
|
||||
}
|
||||
|
||||
public Set_SliceProStackFirmwareUpdateMode(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
MinimumProtocolVersion = sock.GetMinProto(DFConstantsAndEnums.ProtocolLimitedCommands.StackFirmwareUpdate);
|
||||
command.Type = CommandPacket.CommandType.FirmwareUpdate;
|
||||
command.SetCommand((byte)_Command, _Command.ToString());
|
||||
}
|
||||
|
||||
public Set_SliceProStackFirmwareUpdateMode(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
MinimumProtocolVersion = sock.GetMinProto(DFConstantsAndEnums.ProtocolLimitedCommands.StackFirmwareUpdate);
|
||||
command.Type = CommandPacket.CommandType.FirmwareUpdate;
|
||||
command.SetCommand((byte)_Command, _Command.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public class Get_SliceProStackFirmwareUpdateMode : FirmwareUpdateCommands
|
||||
{
|
||||
protected override Commands _Command => Commands.Query_SliceProStackFirmwareUpdateMode;
|
||||
|
||||
public int SliceModuleCount { get; private set; } = 0;
|
||||
public byte[] SliceModuledateMode { get; private set; }
|
||||
|
||||
public Get_SliceProStackFirmwareUpdateMode(DTS.Common.Interface.DASFactory.ICommunication sock)
|
||||
: base(sock)
|
||||
{
|
||||
MinimumProtocolVersion = sock.GetMinProto(DFConstantsAndEnums.ProtocolLimitedCommands.StackFirmwareUpdate);
|
||||
command.Type = CommandPacket.CommandType.FirmwareUpdate;
|
||||
command.SetCommand((byte)_Command, _Command.ToString());
|
||||
}
|
||||
|
||||
public Get_SliceProStackFirmwareUpdateMode(DTS.Common.Interface.DASFactory.ICommunication sock, int TimeoutMillisec)
|
||||
: base(sock, TimeoutMillisec)
|
||||
{
|
||||
MinimumProtocolVersion = sock.GetMinProto(DFConstantsAndEnums.ProtocolLimitedCommands.StackFirmwareUpdate);
|
||||
command.Type = CommandPacket.CommandType.FirmwareUpdate;
|
||||
command.SetCommand((byte)_Command, _Command.ToString());
|
||||
}
|
||||
protected override CommandReceiveAction WholePackage()
|
||||
{
|
||||
if (response.Status == DFConstantsAndEnums.CommandStatus.StatusNoError)
|
||||
{
|
||||
SliceModuleCount = response.Parameter.Length;
|
||||
SliceModuledateMode = new byte[SliceModuleCount];
|
||||
|
||||
for (int i = 0; i < SliceModuleCount; i++)
|
||||
{
|
||||
response.GetParameter(i, out SliceModuledateMode[i]);
|
||||
}
|
||||
}
|
||||
return CommandReceiveAction.StopReceiving;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
1296
DataPRO/SLICECommands/InformationCommands.cs
Normal file
1296
DataPRO/SLICECommands/InformationCommands.cs
Normal file
File diff suppressed because it is too large
Load Diff
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}" });
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user