tbf/TestBenchFramework/Telegram.cs

165 lines
4.7 KiB
C#

using System;
using System.Collections.Generic;
using System.Text;
namespace TBF
{
public class Telegram
{
const UInt16 crcSeed = 0xFFFF; // Initial crc value
const UInt16 crcGP = 0xA001; // Generating polynomial
/// <summary>
/// For standard CRC16 (remainder of division)
/// to start a new crc, set CRC16 = SEED
/// then for each byte call UpdateCRC(byte, &CRC16);
/// CRC16 will contain the result
/// (if you calculate all of the incoming data
/// INCLUDING the crc, the result should be 0x0000
/// and if you are sending the crc be sure to
/// send the bytes in the correct order)
/// <summary>
static void UpdateCRC(byte b, ref UInt16 crc)
{
crc ^= (UInt16)b;
for (int i = 0; i < 8; i++)
{
bool carry = (crc & 0x0001) != 0;
crc >>= 1;
if (carry) crc ^= crcGP;
}
}
/// <summary>
/// Calculates the CRC from a data telegram (an array of bytes).
/// A complete telegram including two bytes reserved for the CRC
/// must be supplied as an argument.
/// </summary>
/// <param name="data">Data telegram</param>
/// <returns>Calculated CRC</returns>
public static UInt16 ClaculateTelegramCRC(byte[] data)
{
UInt16 crc = crcSeed;
for (int i = 0; i < data.Length - 2; i++) UpdateCRC(data[i], ref crc);
return crc;
}
/// <summary>
/// This function modifies the last 2 bytes in the message buffer
/// by the CRC calculated from the remaining first (Lenght - 2) bytes.
/// A complete telegram including two bytes reserved for the CRC
/// must be supplied as an argument.
/// </summary>
/// <param name="data">Data telegram</param>
public static void UpdateTelegramCRC(byte[] data)
{
int len = data.Length;
if (len < 2) return;
UInt16 crc = ClaculateTelegramCRC(data);
data[len - 2] = (byte)(crc & 0xFF);
data[len - 1] = (byte)(crc >> 8);
}
/// <summary>
/// This function compares the last 2 bytes in the message buffer
/// with the CRC calculated from the remaining first (Lenght - 2) bytes.
/// A complete telegram including two bytes reserved for the CRC
/// must be supplied as an argument.
/// </summary>
/// <param name="data">Data telegram</param>
/// <returns>true if the CRC in the telegram is correct</returns>
public static bool VerifyTelegramCRC(byte[] data)
{
int len = data.Length;
if (len < 2) return false;
UInt16 crc = ClaculateTelegramCRC(data);
return (data[len - 2] == (byte)(crc & 0xFF)) && (data[len - 1] == (byte)(crc >> 8));
}
/// <summary>
/// Calculates the checksum from a data telegram (an array of bytes).
/// A complete telegram including one bytes reserved for the checksum
/// must be supplied as an argument.
/// </summary>
/// <param name="data">Data telegram</param>
/// <returns>Calculated CRC</returns>
public static byte ClaculateTelegramChecksum(byte[] data)
{
byte checksum = 0;
for (int i = 0; i < data.Length - 1; i++) checksum = (byte)(checksum ^ data[i]);
return checksum;
}
/// <summary>
/// This function modifies the last byte in the message buffer
/// by the checksum calculated from the remaining first (Lenght - 1) bytes.
/// A complete telegram including one bytes reserved for the checksum
/// must be supplied as an argument.
/// </summary>
/// <param name="data">Data telegram</param>
public static void UpdateTelegramChecksum(byte[] data)
{
int len = data.Length;
if (len < 1) return;
data[len - 1] = ClaculateTelegramChecksum(data);
}
/// <summary>
/// This function compares the last byte in the message buffer
/// with the checksum calculated from the remaining first (Lenght - 1) bytes.
/// A complete telegram including two bytes reserved for the checksum
/// must be supplied as an argument.
/// </summary>
/// <param name="data">Data telegram</param>
/// <returns>true if the CRC in the telegram is correct</returns>
public static bool VerifyTelegramChecksum(byte[] data)
{
int len = data.Length;
if (len < 1) return false;
return (data[len - 1] == ClaculateTelegramChecksum(data));
}
public static string LogTelegram(string intro, byte[] data)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder(80);
sb.Append(intro);
sb.Append(data.Length.ToString());
sb.Append(" bytes:");
foreach (var d in data)
{
sb.Append(" ");
sb.Append(((int)d).ToString("X2"));
}
return sb.ToString();
}
public static string LogTelegram(string intro, string data)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder(80);
sb.Append(intro);
sb.Append(data.Length.ToString());
sb.Append(" bytes:");
foreach (var d in data)
{
sb.Append(" ");
sb.Append(((int)d).ToString("X2"));
}
return sb.ToString();
}
}
}