using System;
using System.Collections.Generic;
using System.Text;
namespace IceCoffee.HJ212.Models
{
///
/// 通讯包
///
public class NetPackage
{
///
/// 默认头
///
public const string FixedHead = "##";
///
/// 默认尾
///
public const string FixedTail = "\r\n";
///
/// 包头
///
public string Head { get; set; }
///
/// 数据段长度
///
public int DataSegmentLength { get; set; }
///
/// 数据段
///
public DataSegment DataSegment { get; set; }
///
/// CRC校验码
///
public string CrcCode { get; set; }
///
/// 包尾
///
public string Tail { get; set; }
///
/// CRC16校验
///
/// 需要校验的字符串
/// CRC16 校验码
private static string CRC16(string arg)
{
char[] puchMsg = arg.ToCharArray();
uint i, j, crc_reg, check;
crc_reg = 0xFFFF;
for (i = 0; i < puchMsg.Length; i++)
{
crc_reg = (crc_reg >> 8) ^ puchMsg[i];
for (j = 0; j < 8; j++)
{
check = crc_reg & 0x0001;
crc_reg >>= 1;
if (check == 0x0001)
{
crc_reg ^= 0xA001;
}
}
}
return crc_reg.ToString("X2").PadLeft(4, '0');
}
///
/// 解析
///
///
///
///
public static NetPackage Parse(string line, Func unpackCacheFunc = null)
{
try
{
NetPackage netPackage = new NetPackage();
netPackage.Head = line.Substring(0, 2);
netPackage.DataSegmentLength = int.Parse(line.Substring(2, 4));
string dataSegment = line.Substring(6, netPackage.DataSegmentLength);
string crcCode = line.Substring(6 + netPackage.DataSegmentLength, 4);
string calcCrcCode = CRC16(dataSegment);
if (crcCode != calcCrcCode)
{
throw new Exception("CRC校验失败 " + line);
}
netPackage.DataSegment = DataSegment.Parse(dataSegment, unpackCacheFunc);
netPackage.CrcCode = crcCode;
netPackage.Tail = line.Substring(10 + netPackage.DataSegmentLength);
return netPackage;
}
catch (Exception ex)
{
throw new Exception("Error in NetPackage.Parse", ex);
}
}
///
/// 序列化
///
///
public string Serialize()
{
string dataSegment = DataSegment.Serialize();
DataSegmentLength = dataSegment.Length;
CrcCode = CRC16(dataSegment);
return $"{Head}{DataSegmentLength.ToString().PadLeft(4, '0')}{dataSegment}{CrcCode}{Tail}";
}
}
}