using System; using System.Collections.Generic; using System.Text; using System.IO; namespace csRepeat.FW6 { /// /// Packet layout looks like: /// [SYNC1][SYNC2][PID1][PID2][LEN1][LEN2][data bytes, length][CHECKSUM MSB][CHECKSUM LSB] /// /// Length is the number of 'Data bytes', and does not include the header or checksum bytes /// public abstract class FW6Packet { /// /// Offset from the start of the packet /// public const int PID1Offset = 2; /// /// Offset from the start of the packet /// public const int PID2Offset = 3; /// /// Bytes in the header of the packet /// public const int PacketHeaderLength = 2 + 2 + 2; // 2 sync bytes + 2 pid bytes + 2 length bytes /// /// Trailing checksum bytes /// public const int ChecksumLength = 2; public static UInt16 Calculate16bitChecksum(byte[] array, int length) { UInt16 sum = 0; for (int x = 0; x < length; x++) { sum += array[x]; } return (UInt16)(sum & 0xFFFF); } public abstract byte PID1 { get; } public abstract byte PID2 { get; } /// /// Payload data /// public abstract byte[] Data { get; } public byte SYNC1 { get { return 0xF5; } } public byte SYNC2 { get { return 0xFA; } } public byte[] EncodedPacket { get { // build the output packet MemoryStream outputMemoryStream = new MemoryStream(); BinaryWriter outputBinaryWriter = new BinaryWriter(outputMemoryStream); outputBinaryWriter.Write(SYNC1); outputBinaryWriter.Write(SYNC2); outputBinaryWriter.Write(PID1); outputBinaryWriter.Write(PID2); if (Data == null) { outputBinaryWriter.Write((byte)0x0); outputBinaryWriter.Write((byte)0x0); } else { outputBinaryWriter.Write((byte)(Data.Length >> 8)); // length msb outputBinaryWriter.Write((byte)(Data.Length & 0xFF)); // length lsb } if (Data != null) { outputBinaryWriter.Write(Data); } // calculate the checksum of the packet thus far byte[] packetArray = outputMemoryStream.ToArray(); ushort checksum = Calculate16bitChecksum(packetArray, packetArray.Length); // generate the output value checksum = (UInt16)((Int16)(-checksum)); // append the checksum outputBinaryWriter.Write((byte)(checksum >> 8)); outputBinaryWriter.Write((byte)(checksum & 0xFF)); return outputMemoryStream.ToArray(); } } public override string ToString() { return base.ToString() + string.Format(" PID1: {0}, PID2: {1}", PID1, PID2); } } }