using EasyTemplate.Tool.Entity; using System.Collections.Concurrent; using System.Globalization; using System.Net.Sockets; using System.Runtime.InteropServices; using System.Text; using System.IO.Ports; namespace EasyTemplate.Service { public class GlobalTool { public const int NozzleState_Offline = 0; public const int NozzleState_Idle = 1; public const int NozzleState_Filling = 2; public const int WarningState_Normal = 0; public const int WarningState_Prewarning = 1; public const int WarningState_Warning = 2; public static Dictionary g_mNozzleState = new Dictionary(); public static ConcurrentQueue g_dataQueue = new ConcurrentQueue(); const int DIT_BUFSIZE = 1024; // 计算单个字节的CRC public static ushort calccrc(byte crcbuf, ushort crc) { byte i; crc = (ushort)(crc ^ crcbuf); for (i = 0; i < 8; i++) { byte chk; chk = (byte)(crc & 1); crc = (ushort)(crc >> 1); crc = (ushort)(crc & 0x7fff); if (chk == 1) crc = (ushort)(crc ^ 0xa001); /* CRC polynom=0xa001 */ crc = (ushort)(crc & 0xffff); } return crc; } // 带自定义多项式的CRC计算 public static ushort calccrc(byte crcbuf, ushort crc, ushort polynom) { byte i; crc = (ushort)(crc ^ crcbuf); for (i = 0; i < 8; i++) { byte chk; chk = (byte)(crc & 1); crc = (ushort)(crc >> 1); crc = (ushort)(crc & 0x7fff); if (chk == 1) crc = (ushort)(crc ^ polynom); crc = (ushort)(crc & 0xffff); } return crc; } // 标准CRC校验 public static ushort chkcrc(byte[] buf, ushort len) { ushort i; ushort crc; crc = 0x0000; /* Initial crc value=0x0000 */ for (i = 0; i < len; i++) { crc = calccrc(buf[i], crc); } return crc; } // 带多项式的CRC校验 public static ushort chkcrc(byte[] buf, ushort len, ushort polynom) { ushort i; ushort crc; crc = 0x0000; for (i = 0; i < len; i++) { crc = calccrc(buf[i], crc, polynom); } return crc; } // Modbus CRC校验 public static ushort chkcrc_modbus(byte[] buf, ushort len, ushort polynom) { ushort i; ushort crc; crc = 0xffff; for (i = 0; i < len; i++) { crc = calccrc(buf[i], crc, polynom); } return crc; } public static void crc_calc_sinopec(byte[] ptr_buffer, ushort length) { ushort crc_result; /* calculate CRC */ crc_result = chkcrc(ptr_buffer, length); /* ... and store it */ ptr_buffer[length] = (byte)(crc_result >> 8); ptr_buffer[length + 1] = (byte)crc_result; } public static string BytesToBcd(byte[] Bytes) { if (Bytes == null || Bytes.Length == 0) return string.Empty; StringBuilder result = new StringBuilder(); foreach (byte b in Bytes) { // 提取高4位和低4位 byte highNibble = (byte)((b >> 4) & 0x0F); byte lowNibble = (byte)(b & 0x0F); // 转换为字符 result.Append((char)('0' + highNibble)); result.Append((char)('0' + lowNibble)); } return result.ToString(); } public static T ByteToStructure(Byte[] dataBuffer) { object structure = null; int size = Marshal.SizeOf(typeof(T)); IntPtr allocIntPtr = Marshal.AllocHGlobal(size); try { Marshal.Copy(dataBuffer, 0, allocIntPtr, size); structure = Marshal.PtrToStructure(allocIntPtr, typeof(T)); } catch (Exception e) { } finally { Marshal.FreeHGlobal(allocIntPtr); } return (T)structure; } public static byte[] StructToBytes(object structObj) { //得到结构体的大小 int size = Marshal.SizeOf(structObj); //创建byte数组 byte[] bytes = new byte[size]; //分配结构体大小的内存空间 IntPtr structPtr = Marshal.AllocHGlobal(size); //将结构体拷到分配好的内存空间 Marshal.StructureToPtr(structObj, structPtr, false); //从内存空间拷到byte数组 Marshal.Copy(structPtr, bytes, 0, size); //释放内存空间 Marshal.FreeHGlobal(structPtr); //返回byte数组 return bytes; } /// /// 将字节数组按大端序转换为整数 /// /// 字节数组 /// 转换后的整数 public static int BytesToInt(byte[] bytes) { if (bytes == null) throw new ArgumentNullException(nameof(bytes)); if (bytes.Length == 0) return 0; if (bytes.Length > 4) throw new ArgumentException("字节数组长度不能超过4个字节"); int result = 0; for (int i = 0; i < bytes.Length; i++) { result = (result << 8) | bytes[i]; } return result; } public static bool checkEscapeCharacter(ref byte[] buf, ref int len, byte ch) { bool ischeck = false; byte[] tmpData = new byte[DIT_BUFSIZE]; int j = 0; for (int i = 0; i < len && j < DIT_BUFSIZE; i++) { if (i < len - 1 && buf[i] == ch && buf[i + 1] == ch) { tmpData[j] = ch; i += 1; // 跳过下一个字符 ischeck = true; j++; } else { tmpData[j] = buf[i]; j++; } } // 更新长度和缓冲区内容 len = j; Array.Copy(tmpData, buf, len); return ischeck; } public static bool calcEscapeLength(byte[] buf, ref int len, byte ch) { bool ischeck = false; // 确保数组足够大,如果不够大则调整循环次数 int loopCount = Math.Min(DIT_BUFSIZE, buf.Length); for (int i = 0; i < loopCount; i++) { if (i < loopCount - 1 && buf[i] == ch && buf[i + 1] == ch) { i += 1; // 跳过下一个字符 len--; // 长度减1 ischeck = true; } } return ischeck; } public static int BCDtoDec(byte[] data, int length) { // BCD转十进制实现 int result = 0; for (int i = 0; i < length; i++) { result = result * 100 + ((data[i] >> 4) * 10 + (data[i] & 0x0F)); } return result; } /// /// 将BCD码转换回十进制数值 /// /// BCD码值 /// 对应的十进制数值 public static int ConvertBCDToDecimalSingle(byte bcdValue) { // 提取高四位(十位数字) byte tens = (byte)((bcdValue >> 4) & 0x0F); // 提取低四位(个位数字) byte units = (byte)(bcdValue & 0x0F); // 组合得到十进制数值 return tens * 10 + units; } /// /// 将多个BCD码转换为可变长度的十进制数值 如0x1234转成1234 /// /// BCD码字节数组 /// 对应的十进制数值 public static long ConvertBCDToDecimal(byte[] bcdBytes) { long result = 0; foreach (byte bcd in bcdBytes) { byte tens = (byte)((bcd >> 4) & 0x0F); byte units = (byte)(bcd & 0x0F); result = result * 100 + tens * 10 + units; } return result; } public static filling_nozzleup extractFillingNozzleUP(byte[] Buffer, int startIndex) { filling_nozzleup data = new filling_nozzleup(); BufferHandler handler = new BufferHandler(Buffer, startIndex); data.board = handler.getData(1); data.noz = handler.getData(1); data.fip = data.board; data.time = handler.getDataString_BCD(7); return data; } public static filling_nozzledown extractFillingNozzleDown(byte[] Buffer, int startIndex) { filling_nozzledown data = new filling_nozzledown(); BufferHandler handler = new BufferHandler(Buffer, startIndex); data.board = handler.getData(1); data.noz = handler.getData(1); data.fip = data.board; data.time = handler.getDataString_BCD(7); return data; } public static filling_process extractFillingProcess(byte[] Buffer, int startIndex) { filling_process data = new filling_process(); BufferHandler handler = new BufferHandler(Buffer, startIndex); data.board = handler.getData(1); data.noz = handler.getData(1); data.fip = data.board; data.liquidVL = handler.getData(3); data.vaporVL = handler.getData(3); data.vaporFR = handler.getData(2); data.VLR = handler.getData(2); data.vaporPA = handler.getData(2); data.errornum = handler.getData(2); data.liquidFR = handler.getData(2); data.pwm = handler.getData(2); data.current = handler.getData(2); return data; } public static filling_record extractFillingRecord(byte[] Buffer, int startIndex) { int bufferlen = Buffer.Length; filling_record data = new filling_record(); BufferHandler handler = new BufferHandler(Buffer, startIndex); data.board = handler.getData(1); data.noz = handler.getData(1); data.fip = data.board; if (bufferlen != 22)//兼容旧协议,解析顺序改变 { data.ttc = handler.getData(4); } data.liquidVL = handler.getData(3); data.liquidFR = handler.getData(2); data.vaporVL = handler.getData(3); data.vaporFR = handler.getData(2); data.VLR = handler.getData(2); data.tmBegin = handler.getDataString_BCD(7); data.tmEnd = handler.getDataString_BCD(7); data.errornum = handler.getData(2); data.vaporPA = handler.getData(2); data.pwm = handler.getData(2); return data; } public static void vr_log(string log) { } public static void vr_log_error(string log) { } } public class BufferHandler { public byte[] buffer = Array.Empty(); public int startIndex = 0; public int length = 0; public BufferHandler(byte[] buf, int startindex = 0) { buffer = buf; startIndex = startindex; length = buf.Length; } public string getDataString_BCD(int len) { if (startIndex + len > length) { return ""; } byte[] segment = new byte[len]; Array.Copy(buffer, startIndex, segment, 0, len); string result = GlobalTool.BytesToBcd(segment); startIndex += len; return result; } public int getData(int len) { if (startIndex + len > length) { return 0; } byte[] segment = new byte[len]; Array.Copy(buffer, startIndex, segment, 0, len); int val = GlobalTool.BytesToInt(segment); startIndex += len; return val; } } public class NozzleState { public int noz = 0; public string VLR = "0"; public string oil = string.Empty; public int nozzlestate = GlobalTool.NozzleState_Offline; public int warnstate = GlobalTool.WarningState_Normal; } public struct filling_nozzleup { public int fip; public int board; public int noz; public string time; /* byte cmd; byte fip; byte noz; byte time[7]; byte product[4];*/ /* auto& cmd = src->data.CMD1; dst.target = cmd.noz; _ubcd_to_str (dst.time, sizeof dst.time, cmd.time, sizeof cmd.time); _ubcd_to_str (dst.product, sizeof dst.product, cmd.product, sizeof cmd.product);*/ } public struct filling_nozzledown { public int fip; public int board; public int noz; public string time; } public struct filling_record { public int fip; public int board; public int noz; public int liquidVL; public int vaporVL; public int liquidFR; public int vaporFR; public int VLR; public int vaporPA; public int ttc; public int VLR_BEFORE; public int VLR_OFFSET; public int pwm; public string tmBegin; public string tmEnd; public int overproof; public int uploadflag; public int uploadflag2; public int uploadflag3; public int downloadflag1; public int yz; public int tankpressure; public int refuelingseconds; public int errorcontrolvalue; public int errornum; public int callbackflag; public string vccerrorinfo; } public struct filling_process { public int fip; public int board; public int noz; public int liquidVL; public int vaporVL; public int liquidFR; public int vaporFR; public int VLR; public int vaporPA; public int ttc; public int VLR_BEFORE; public int VLR_OFFSET; public int errornum; public int pwm; public int current; } public class BufferData { public int type = 0; public byte[] buffer = Array.Empty(); public System.Net.IPEndPoint endpoint; public UdpClient udpClient; public SerialPort serialPort; } }