using Edge.Core.Parser;
using Edge.Core.Parser.BinaryParser.MessageEntity;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace HengshanPaymentTerminal.MessageEntity
{
///
/// 与油机通讯的基础数据包对象
///
public abstract class CommonMessage: MessageTemplateBase
{
public enum Command
{
///
/// 通用应答命令字
///
COMMON = 0x55,
///
/// 心跳命令字
///
HEART_BRET = 0x10,
///
/// 油枪信息命令字
///
NOZZLE_INFO = 0x61,
///
/// 油枪状态命令字
///
NOZZLE_STATE = 0x62,
///
/// 发送二维码给油机命令字
///
SEND_QR_CODE = 0x63,
///
/// 获取单价命令字
///
GET_PRICE = 0x64,
///
/// 授权命令字
///
ACCREDIT = 0x65,
///
/// 取消授权命令字
///
CANCEL_ACCREDIT = 0x66,
///
/// 接收油机订单命令字
///
RECIEVE_TRANX = 0x18,
///
/// 发送应付金额给油机命令字
///
SEND_NEED_AMOUNT = 0x19
}
///
/// 包头 0xFA
///
public Byte Head { get; set; }
///
/// 目标地址
///
public Byte DestinationAddr { get; set; }
///
/// 源地址
///
public Byte SourceAddr { get; set; }
///
/// 帧号
///
public int FrameNum { get; set; }
///
/// 有效数据长度,标识油机数据包中,有效数据的长度
///
public int DataLength { get; set; }
///
/// 命令字,用来标识数据包传递的数据
///
public Byte Handle { get; set; }
///
/// crc 校验值
///
public Byte[] CRC { get; set; }
///
/// 是否为错误响应(与油机通讯协议无关)
///
public bool IsError { get; set; } = false;
///
/// 错误信息(与油机协议无关)
///
public string ErrorMessage { get; set; }
public CommonMessage getBaseData(byte[] data)
{
this.Handle = data[0];
this.DestinationAddr = data[1];
this.SourceAddr = data[2];
this.FrameNum = data[3];
this.DataLength = Bcd2Int(data[4], data[5]);
this.Handle = data[6];
this.CRC = new byte[]{ data[data.Length - 2],data[data.Length - 1] };
return this;
}
///
/// 传入有效数据,拼接为要发送给油机包
///
///
///
public byte[] content2data(byte[] content)
{
List list = new List();
//目标地址,源地址,帧号
byte[] head = new byte[] { this.SourceAddr, this.DestinationAddr, (byte)this.FrameNum };
byte[] length = Int2BCD(content.Length);
list.AddRange(head);
list.AddRange(length);
list.AddRange(content);
byte[] crc = HengshanCRC16.ComputeChecksumToBytes(list.ToArray());
list.AddRange(crc);
List addFAList = addFA(list);
addFAList.Insert(0,0xFA);
return addFAList.ToArray();
}
public int Bcd2Int(byte byte1, byte byte2)
{
// 提取第一个字节的高四位和低四位
int digit1 = (byte1 >> 4) & 0x0F; // 高四位
int digit2 = byte1 & 0x0F; // 低四位
// 提取第二个字节的高四位和低四位
int digit3 = (byte2 >> 4) & 0x0F; // 高四位
int digit4 = byte2 & 0x0F; // 低四位
// 组合成一个整数
int result = digit1 * 1000 + digit2 * 100 + digit3 * 10 + digit4;
return result;
}
public byte[] Int2BCD(int number)
{
// 提取千位、百位、十位和个位
int thousands = number / 1000;
int hundreds = (number / 100) % 10;
int tens = (number / 10) % 10;
int units = number % 10;
// 将千位和百位组合成一个字节(千位在高四位,百位在低四位)
byte firstByte = (byte)((thousands * 16) + hundreds); // 乘以16相当于左移4位
// 将十位和个位组合成一个字节(十位在高四位,个位在低四位)
byte secondByte = (byte)((tens * 16) + units);
// 返回结果数组
return new byte[] { firstByte, secondByte };
}
///
/// 数组转数字
///
/// 数组
/// 开始的截取的下标
/// 截取长度
///
public T Bytes2Number(byte[] datas,int startIndex,int length) where T: unmanaged
{
int sizeOfT = Unsafe.SizeOf();
Span span = datas.AsSpan(startIndex, length);
// 如果 span 的长度不够,补足长度
if (span.Length < sizeOfT)
{
// 使用数组而不是 stackalloc,避免栈溢出
byte[] paddedArray = new byte[sizeOfT];
Span paddedSpan = paddedArray.AsSpan();
// 在前面补零
span.CopyTo(paddedSpan.Slice(sizeOfT - span.Length));
if (BitConverter.IsLittleEndian)
{
// 小端序:反转字节顺序
paddedSpan.Reverse();
}
return MemoryMarshal.Read(paddedSpan);
}
// 如果长度足够,直接读取
if (BitConverter.IsLittleEndian)
{
// 小端序:反转字节顺序
span.Reverse();
}
return MemoryMarshal.Read(span);
}
public List addFA(List list)
{
List result = new List();
foreach (byte b in list)
{
if (b == 0xFA)
{
result.Add(0xFA);
result.Add(0xFA);
}
else
{
result.Add(b);
}
}
return result;
}
public DateTime bytes2DateTime(byte[] timeBytes)
{
string formate = "yyyyMMddHHmmss";
string timeStr = BitConverter.ToString(timeBytes).Replace("-", "");
DateTime parsedDateTime;
bool success = DateTime.TryParseExact(timeStr, formate, null, System.Globalization.DateTimeStyles.None, out parsedDateTime);
return success ? parsedDateTime : DateTime.Now;
}
}
}