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