Files
DP44/DataPRO/RibeyeCommands/CommandPacket.cs
2026-04-17 14:55:32 -04:00

385 lines
11 KiB
C#

using System;
using System.Collections.Generic;
using System.Text;
namespace DTS.DASLib.Command.Ribeye
{
public class CommandPacket : CommandPacketBase
{
public enum CommandType
{
Reserved = 0x00,
Arm,
Attribute,
Diagnostics,
EventData,
FirmwareUpdate,
Information,
QAandUtility,
Realtime,
};
const int HEADER_SIZE_BYTES = 4;
public string[] Parameter;
byte Checksum = 0;
//public byte[] OriginalBytes;
public CommandPacket()
{
Parameter = new string[0];
ShouldLog = true;
}
public CommandPacket(byte[] Bytes)
{
OriginalBytes = Bytes;
ShouldLog = true;
int ParameterCount = 0;
foreach (byte CurrentByte in Bytes)
{
if ('#' == CurrentByte)
{
ParameterCount++;
}
}
Parameter = new string[ParameterCount];
int CurrentParameter = 0;
StringBuilder sb = new StringBuilder();
foreach (byte CurrentByte in Bytes)
{
if ('#' == CurrentByte)
{
Parameter[CurrentParameter] = sb.ToString();
CurrentParameter++;
sb = new StringBuilder();
}
else if ((byte)'\r' != CurrentByte && (byte)'\n' != CurrentByte)
{
sb.Append((char)CurrentByte);
}
}
}
public override PacketState VerifyPacket(byte[] Bytes)
{
if (Bytes == null || '?' == Bytes[0]) // ? is the error indicator
return PacketState.Unknown;
if (Bytes.Length < HEADER_SIZE_BYTES)
return PacketState.TooShort;
// Need to check checksum
if (Bytes[Bytes.Length - 2] == '\r' && Bytes[Bytes.Length - 1] == '\n')
{
return PacketState.OK;
}
else
{
return PacketState.TooShort;
}
}
public override byte[] ToBytes()
{
uint Length;
byte[] CommandBytes;
Length = 0;
foreach (string CurrentParameter in Parameter)
{
if (null != CurrentParameter)
{
Length += (uint)(CurrentParameter.Length + 1);
}
}
Length += (uint)(Checksum.ToString().Length + 2);
CommandBytes = new byte[Length];
int CommandIndex = 0;
foreach (string CurrentParameter in Parameter)
{
foreach (char CurrentChar in CurrentParameter)
{
CommandBytes[CommandIndex] = (byte)CurrentChar;
CommandIndex++;
}
CommandBytes[CommandIndex] = (byte)'#';
CommandIndex++;
}
foreach (char CurrentChar in Checksum.ToString())
{
CommandBytes[CommandIndex] = (byte)CurrentChar;
CommandIndex++;
}
CommandBytes[CommandBytes.Length - 2] = (byte)'\r';
CommandBytes[CommandBytes.Length - 1] = (byte)'\n';
OriginalBytes = CommandBytes;
return CommandBytes;
}
private void ComputeChecksum()
{
Checksum = 0;
foreach (string CurrentParameter in Parameter)
{
foreach (char CurrentCharacter in CurrentParameter)
{
Checksum += (byte)CurrentCharacter;
}
Checksum += (byte)'#';
}
}
public override void ComputeCRCs()
{
ComputeChecksum();
}
private static System.Globalization.CultureInfo InvariantCulture = new System.Globalization.CultureInfo("");
public void GetParameter(int Position, out double Value)
{
Double.TryParse(Parameter[Position], System.Globalization.NumberStyles.Float, InvariantCulture, out Value);
}
public void GetParameter(int Position, out UInt64 Value)
{
UInt64.TryParse(Parameter[Position], out Value);
}
public void GetParameter(int Position, out Int64 Value)
{
Int64.TryParse(Parameter[Position], out Value);
}
public void GetParameter(int Position, out Int32 Value)
{
Int32.TryParse(Parameter[Position], out Value);
}
public void GetParameter(int Position, out UInt32 Value)
{
UInt32.TryParse(Parameter[Position], out Value);
}
public void GetParameter(int Position, out Int16 Value)
{
Int16.TryParse(Parameter[Position], out Value);
}
public void GetParameter(int Position, out UInt16 Value)
{
UInt16.TryParse(Parameter[Position], out Value);
}
public void GetParameter(int Position, out float Value)
{
float.TryParse(Parameter[Position], out Value);
}
public void GetParameter(int Position, out string Value)
{
Value = Parameter[Position];
}
public void SetParameter(int Position, double Value)
{
Parameter[Position] = Value.ToString();
}
public void SetParameter(int Position, Int64 Value)
{
Parameter[Position] = Value.ToString();
}
public void SetParameter(int Position, UInt64 Value)
{
Parameter[Position] = Value.ToString();
}
public void SetParameter(int Position, Int32 Value)
{
Parameter[Position] = Value.ToString();
}
public void SetParameter(int Position, UInt32 Value)
{
Parameter[Position] = Value.ToString();
}
public void SetParameter(int Position, Int16 Value)
{
Parameter[Position] = Value.ToString();
}
public void SetParameter(int Position, UInt16 Value)
{
Parameter[Position] = Value.ToString();
}
public void SetParameter(int Position, float Value)
{
Parameter[Position] = Value.ToString();
}
public void SetParameter(int Position, string Value)
{
Parameter[Position] = Value;
}
public override object ConvertByteToCommandType(byte b)
{
return (CommandType)b;
}
private static UInt16 GlobalSequenceNumber = 0;
private static object GlobalSequenceNumberLock = new object();
public override void GetNextSequenceNumber()
{
lock (GlobalSequenceNumberLock)
{
SequenceNumber = GlobalSequenceNumber;
GlobalSequenceNumber++;
}
}
}
public class DownloadPacket : CommandPacket
{
public byte[] Data;
public DownloadPacket(byte[] Bytes)
{
OriginalBytes = Bytes;
ShouldLog = true;
int ParameterCount = 0;
foreach (byte CurrentByte in Bytes)
{
if ('#' == CurrentByte)
{
ParameterCount++;
}
if ('\r' == CurrentByte)
{
break;
}
}
Parameter = new string[ParameterCount];
int CurrentParameter = 0;
StringBuilder sb = new StringBuilder();
uint ByteOffset = 0;
foreach (byte CurrentByte in Bytes)
{
if ('#' == CurrentByte)
{
Parameter[CurrentParameter] = sb.ToString();
CurrentParameter++;
sb = new StringBuilder();
}
else if ((byte)'\n' == CurrentByte)
{
break;
}
else
{
sb.Append((char)CurrentByte);
}
ByteOffset++;
}
ByteOffset++;
uint DataLength = (uint)(Bytes.Length - ByteOffset);
Data = new byte[DataLength];
Array.Copy(Bytes, ByteOffset, Data, 0, DataLength);
}
public static PacketState VerifyPacket(byte[] Bytes, ref uint BytesExpected)
{
if (Bytes == null)
return PacketState.Unknown;
if (0 == BytesExpected)
{
string[] Parameter = new string[3];
uint CurrentParameter = 0;
StringBuilder sb = new StringBuilder();
// Look for initial header
foreach (byte CurrentByte in Bytes)
{
try
{
if ('#' == CurrentByte)
{
Parameter[CurrentParameter] = sb.ToString();
CurrentParameter++;
sb = new StringBuilder();
}
else if ((byte)'\r' == CurrentByte || (byte)'\n' == CurrentByte)
{
break;
}
else
{
sb.Append((char)CurrentByte);
}
}
catch (Exception)
{
return PacketState.Unknown;
}
}
if (3 != CurrentParameter)
{
return PacketState.TooShort;
}
else
{
// Parameter 1 = number of channels
// Parameter 2 = number of samples
// + 1 is for checksum on each sample
// * 2 is for 2 bytes per sample
try
{
BytesExpected = (uint)((UInt16.Parse(Parameter[1]) * 2 + 1) * UInt16.Parse(Parameter[2]) + Bytes.Length);
}
catch (Exception)
{
return PacketState.Unknown;
}
if (Bytes.Length >= BytesExpected)
{
return PacketState.OK;
}
else
{
return PacketState.TooShort;
}
}
}
else
{
if (Bytes.Length >= BytesExpected)
{
return PacketState.OK;
}
else
{
return PacketState.TooShort;
}
}
}
}
}