Bladeren bron

feat(HengshanPaymentTerminal):fcc向油机授权、取消授权

Zhenghanjv 5 maanden geleden
bovenliggende
commit
1fbbb75128

+ 1 - 1
Edge.Core/Processor/GenericDeviceProcessor.cs

@@ -108,7 +108,7 @@ namespace Edge.Core.Processor
                 {
                     IClinet clinet = (IClinet)communicator;
                     handler.SetTcpClient(clinet?.GetTcpClient());
-                    handler.SendQRCode();
+                    handler.SendQRCodeAsync();
                 }
             };
             this.Communicator.OnDataReceived += (s, a) =>

+ 1 - 1
Edge.Core/Processor/IDeviceHandler.cs

@@ -36,7 +36,7 @@ namespace Edge.Core.Processor
         /// <summary>
         /// 发送二维码信息
         /// </summary>
-        void SendQRCode() { }
+        void SendQRCodeAsync() { }
 
         /// <summary>
         /// 发送实付金额给油机

+ 220 - 25
HengshanPaymentTerminal/HengshanPayTermHandler.cs

@@ -22,6 +22,7 @@ using Edge.Core.Domain.FccOrderInfo;
 using Microsoft.EntityFrameworkCore;
 using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities;
 using static Microsoft.AspNetCore.Hosting.Internal.HostingApplication;
+using HengshanPaymentTerminal.Mqtt.Request;
 
 namespace HengshanPaymentTerminal
 {
@@ -72,6 +73,11 @@ namespace HengshanPaymentTerminal
         public List<DetailsNozzleInfoOutput> nozzleInfoList { get; private set; }
 
         public TcpClient? client { get; set; }
+
+        private readonly ConcurrentDictionary<string,TaskCompletionSource<CommonMessage>> _tcsDictionary = new ConcurrentDictionary<string, TaskCompletionSource<CommonMessage>>();
+
+        private byte frame = 0x00;
+        private object lockFrame = new object();
         #endregion
 
         #region Logger
@@ -422,11 +428,66 @@ namespace HengshanPaymentTerminal
             {
                 //订单
                 case 0x18:
-                    //添加或修改数据库订单
-                    OrderFromMachine message = (OrderFromMachine)context.Incoming.Message;
-                    int row = UpLoadOrder(message);
-                    logger.Info($"receive order from machine,database had ${row} count change");
-                    break;
+                    {
+                        //添加或修改数据库订单
+                        OrderFromMachine orderFromMachine = (OrderFromMachine)context.Incoming.Message;
+                        int row = UpLoadOrder(orderFromMachine);
+                        logger.Info($"receive order from machine,database had ${row} count change");
+                        break;
+                    }
+                //普通应答
+                case 0x55:
+                    {
+                        CommonAnswerBack commonAnswerBack = (CommonAnswerBack)context.Incoming.Message;
+                        if (commonAnswerBack.Command == 0x63) //二维码回复
+                        {
+                            byte[] keyBytes = { commonAnswerBack.Command, (byte)commonAnswerBack.NozzleNum };
+                            var key = BitConverter.ToString(keyBytes).Replace("-", "");
+                            if (_tcsDictionary.TryGetValue(key, out var value))
+                            {
+                                value.SetResult(commonAnswerBack);
+                            }
+                            else
+                            {
+                                logger.Info($"qrcode response:can not get tcs for dictionary");
+                            }
+                        }
+
+                        break;
+                    }
+                // 授权回复
+                case 0x65:
+                    {
+                        AuthorizationResponse authorizationResponse = (AuthorizationResponse)context.Incoming.Message;
+                        byte[] keyBytes = { authorizationResponse.Handle, (byte)authorizationResponse.NozzleNum };
+                        var key = BitConverter.ToString(keyBytes).Replace("-", "");
+                        if (_tcsDictionary.TryGetValue(key, out var value))
+                        {
+                            value.SetResult(authorizationResponse);
+                        }
+                        else
+                        {
+                            logger.Info($"authorization response:can not get tcs for dictionary");
+                        }
+                        break;
+                    }
+                // 取消授权回复
+                case 0x66:
+                    {
+                        UnAhorizationResponse unauthorizationResponse = (UnAhorizationResponse)context.Incoming.Message;
+                        byte[] keyBytes = { unauthorizationResponse.Handle, (byte)unauthorizationResponse.NozzleNum };
+                        var key = BitConverter.ToString(keyBytes).Replace("-", "");
+                        if (_tcsDictionary.TryGetValue(key, out var value))
+                        {
+                            value.SetResult(unauthorizationResponse);
+                        }
+                        else
+                        {
+                            logger.Info($"unauthorization response:can not get tcs for dictionary");
+                        }
+                        break;
+                    }
+
             }
             
             context.Outgoing.Write(context.Incoming.Message);
@@ -616,7 +677,7 @@ namespace HengshanPaymentTerminal
         /// 发送二维码信息给油机
         /// </summary>
         /// <param name="tcpClient"></param>
-        public void SendQRCode()
+        public async void SendQRCodeAsync()
         {
             string? smallProgram = stationInfo?.SmallProgram;
             if (smallProgram == null)
@@ -643,8 +704,9 @@ namespace HengshanPaymentTerminal
                 list.AddRange(commandAndNozzle);
                 list.Add((byte)qrCodeBytes.Length);
                 list.AddRange(qrCodeBytes);
-                byte[] sendBytes = content2data(list.ToArray());
-                this.client?.Client.Send(sendBytes);
+                byte[] sendBytes = content2data(list.ToArray(),null);
+
+                await SendRequestToMachine("发送二维码", BitConverter.ToString(commandAndNozzle).Replace("-", ""), sendBytes);
             }
         }
 
@@ -652,7 +714,7 @@ namespace HengshanPaymentTerminal
         /// 发送实付金额给油机
         /// </summary>
         /// <param name="orderInfo"></param>
-        public void SendActuallyPaid(FccOrderInfo orderInfo) 
+        public async void SendActuallyPaid(FccOrderInfo orderInfo) 
         {
             List<Byte> list = new List<Byte>();
             byte[] commandAndNozzle = { 0x19, (byte)orderInfo.NozzleNum };
@@ -665,8 +727,39 @@ namespace HengshanPaymentTerminal
             list.AddRange(amountPayableBytes);  //添加实付金额
             //添加3位交易金额1,3位交易金额2,2位优惠规则代码,10位卡应用号,4位消息鉴别码
             list.AddRange(new byte[] { 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00 });
-            byte[] sendBytes = content2data(list.ToArray());
-            this.client?.Client.Send(sendBytes);
+            byte[] sendBytes = content2data(list.ToArray(), null);
+
+            await SendRequestToMachine("发送实付金额", BitConverter.ToString(commandAndNozzle).Replace("-", ""), sendBytes);
+        }
+
+        public async Task<CommonMessage> SendAuthorization(MqttAuthorizationRequest request)
+        {
+            List<Byte> list = new List<Byte>();
+            byte[] commandAndNozzle = { 0x65, (byte)request.NozzleNum };
+            byte[] authorizationTimeBytes = ConvertDateTimeToByteArray(request.AuthorizationTime);
+            //将小数点后移两位,因为油机只支持两位小数点,这边传过去的3位字节转为int后取后两位为十分位和百分位
+            int value = (int)request.Value * 100;
+            byte[] valueBytes = NumberToByteArrayWithPadding(value, 3);
+            list.AddRange(commandAndNozzle);
+            list.AddRange(authorizationTimeBytes);
+            list.Add((byte)request.AuthorizationType);
+            list.AddRange(valueBytes);
+            byte[] sendBytes = content2data(list.ToArray(), null);
+            return await SendRequestToMachine("发送授权请求", BitConverter.ToString(commandAndNozzle).Replace("-", ""), sendBytes);
+        }
+
+        public async Task<CommonMessage> SendUnAuthorizartion(MqttUnAhorizationRequest request)
+        {
+            List<Byte> list = new List<Byte>();
+            byte[] commandAndNozzle = { 0x66, (byte)request.NozzleNum };
+            byte[] authorizationTimeBytes = ConvertDateTimeToByteArray(request.AuthorizationTime);
+            
+            byte[] ttcBytes = NumberToByteArrayWithPadding(request.Ttc, 4);
+            list.AddRange(commandAndNozzle);
+            list.AddRange(authorizationTimeBytes);
+            list.AddRange(ttcBytes);
+            byte[] sendBytes = content2data(list.ToArray(), null);
+            return await SendRequestToMachine("发送取消授权请求", BitConverter.ToString(commandAndNozzle).Replace("-", ""), sendBytes);
         }
 
         public void SetTcpClinet(TcpClient? tcpClient)
@@ -675,25 +768,83 @@ namespace HengshanPaymentTerminal
         }
 
         /// <summary>
-        /// 添加或修改订单
+        /// 发送消息到油机,3秒的超时,重试三次
         /// </summary>
-        /// <param name="order">接收到油机的订单信息</param>
+        /// <param name="sendTag">发送的消息类型,用于日志记录</param>
+        /// <param name="sendKey">发送的消息key,用于存储 TaskCompletionSource</param>
+        /// <param name="requestBytes">实际发送消息</param>
         /// <returns></returns>
-        public int UpLoadOrder(OrderFromMachine order)
+        /// <exception cref="TimeoutException"></exception>
+        private async Task<CommonMessage> SendRequestToMachine(string sendTag,string sendKey, byte[] requestBytes)
         {
-            FccOrderInfo orderByMessage = order.ToComponent();
-            FccOrderInfo? fccOrderInfo = MysqlDbContext.fccOrderInfos.FirstOrDefault(fccOrder => 
-                fccOrder.NozzleNum == order.nozzleNum && fccOrder.Ttc == order.ttc);
-            if (fccOrderInfo == null)
+            int retryCount = 0;
+            while(retryCount < 3)
             {
-                logger.Info($"receive order from machine,find order from database is null");
-                MysqlDbContext.fccOrderInfos.Add(orderByMessage);
+                var cts = new CancellationTokenSource(TimeSpan.FromSeconds(3));
+                bool isAdd = _tcsDictionary.TryAdd(sendKey, new TaskCompletionSource<CommonMessage>());
+                logger.Info($"{sendTag}: add request {sendKey} to dic is {isAdd}");
+
+                client?.Client.Send(requestBytes);
+
+                try
+                {
+                    TaskCompletionSource<CommonMessage>? value;
+                    TaskCompletionSource<CommonMessage> tcs;
+                    if(_tcsDictionary.TryGetValue(sendKey, out value))
+                    {
+                        tcs = value;
+                    } else
+                    {
+                        tcs = new TaskCompletionSource<CommonMessage>();
+                    }
+
+                    CommonMessage response = await tcs.Task.WaitAsync(cts.Token);
+                    return response;
+                } catch (OperationCanceledException)
+                {
+                    retryCount++;
+                    logger.Info($"{sendTag}: time out,retrying... ({retryCount} / 3)");
+                } finally
+                {
+                    if(retryCount >= 3)
+                    {
+                        logger.Info($"{sendTag}: is time out add retry 3 time");
+                        _tcsDictionary.TryRemove(sendKey,out _);
+                    }
+                }
             }
-            else
+            return new ErrorMessage()
             {
-                logger.Info($"receive order from machine,padding data right now");
-                order.PaddingAuthorizationOrderData(fccOrderInfo);
+                IsError = true,
+                ErrorMessage = $"{sendTag}: can not receive response after 3 retries"
+            };
+        }
+        /// <summary>
+        /// 添加或修改订单
+        /// </summary>
+        /// <param name="order">接收到油机的订单信息</param>
+        /// <returns></returns>
+        public int UpLoadOrder(CommonMessage order)
+        {
+            //接收到油机发送过来的订单信息
+            if(order is OrderFromMachine)
+            {
+                OrderFromMachine orderFromMachine = (OrderFromMachine)order;
+                FccOrderInfo orderByMessage = orderFromMachine.ToComponent();
+                FccOrderInfo? fccOrderInfo = MysqlDbContext.fccOrderInfos.FirstOrDefault(fccOrder =>
+                    fccOrder.NozzleNum == orderFromMachine.nozzleNum && fccOrder.Ttc == orderFromMachine.ttc);
+                if (fccOrderInfo == null)
+                {
+                    logger.Info($"receive order from machine,find order from database is null");
+                    MysqlDbContext.fccOrderInfos.Add(orderByMessage);
+                }
+                else
+                {
+                    logger.Info($"receive order from machine,padding data right now");
+                    orderFromMachine.PaddingAuthorizationOrderData(fccOrderInfo);
+                }
             }
+
             return MysqlDbContext.SaveChanges();
         }
 
@@ -702,11 +853,30 @@ namespace HengshanPaymentTerminal
         /// </summary>
         /// <param name="content"></param>
         /// <returns></returns>
-        public byte[] content2data(byte[] content)
+        public byte[] content2data(byte[] content,byte? sendFrame)
         {
             List<byte> list = new List<byte>();
             //目标地址,源地址,帧号
-            byte[] head = new byte[] { 0xFF, 0xE0, 0x01 };
+            byte frameNo = 0x00;
+            if(sendFrame == null)
+            {
+                lock (lockFrame)
+                {
+                    if (frame == 0x3f)
+                    {
+                        frameNo = 0x00;
+                    }
+                    else
+                    {
+                        frameNo = (byte)(frame + 1);
+                    }
+                }
+            } else
+            {
+                frameNo = sendFrame.Value;
+            }
+            
+            byte[] head = new byte[] { 0xFF, 0xE0, frameNo };
             byte[] length = Int2BCD(content.Length);
             list.AddRange(head);
             list.AddRange(length);
@@ -806,6 +976,31 @@ namespace HengshanPaymentTerminal
             return NumberToByteArrayWithPadding(valueInt, 3); ;
         }
 
+        /// <summary>
+        /// 将时间转为 BCD 
+        /// </summary>
+        /// <param name="dateTime"></param>
+        /// <returns></returns>
+        public static byte[] ConvertDateTimeToByteArray(DateTime dateTime)
+        {
+            // 创建byte数组
+            byte[] result = new byte[7];
+
+            // 年份处理
+            int year = dateTime.Year;
+            result[0] = (byte)((year / 1000) * 16 + (year / 100) % 10); // 千年和百年
+            result[1] = (byte)((year / 10) % 10 * 16 + year % 10);      // 十年和个年
+
+            // 月、日、小时、分钟、秒直接转换为BCD
+            result[2] = (byte)(dateTime.Month / 10 * 16 + dateTime.Month % 10);
+            result[3] = (byte)(dateTime.Day / 10 * 16 + dateTime.Day % 10);
+            result[4] = (byte)(dateTime.Hour / 10 * 16 + dateTime.Hour % 10);
+            result[5] = (byte)(dateTime.Minute / 10 * 16 + dateTime.Minute % 10);
+            result[6] = (byte)(dateTime.Second / 10 * 16 + dateTime.Second % 10);
+
+            return result;
+        }
+
         // CRC16 constants  
         const ushort CRC_ORDER16 = 16;
         const ushort CRC_POLYNOM16 = 0x1021;

+ 4 - 0
HengshanPaymentTerminal/HengshanPaymentTerminal.csproj

@@ -20,4 +20,8 @@
     <ProjectReference Include="..\Edge.Core\Edge.Core.csproj" />
   </ItemGroup>
 
+  <ItemGroup>
+    <Folder Include="Mqtt\Response\" />
+  </ItemGroup>
+
 </Project>

+ 24 - 0
HengshanPaymentTerminal/MessageEntity/CommonMessage.cs

@@ -1,5 +1,6 @@
 using Edge.Core.Parser;
 using Edge.Core.Parser.BinaryParser.MessageEntity;
+using System.Runtime.InteropServices;
 
 namespace HengshanPaymentTerminal.MessageEntity
 {
@@ -97,6 +98,16 @@ namespace HengshanPaymentTerminal.MessageEntity
         /// </summary>
         public Byte[] CRC { get; set; }
 
+        /// <summary>
+        /// 是否为错误响应(与油机通讯协议无关)
+        /// </summary>
+        public bool IsError { get; set; } = false;
+
+        /// <summary>
+        /// 错误信息(与油机协议无关)
+        /// </summary>
+        public string ErrorMessage { get; set; }
+
         public CommonMessage getBaseData(byte[] data)
         {
             this.Handle = data[0];
@@ -164,6 +175,19 @@ namespace HengshanPaymentTerminal.MessageEntity
             return new byte[] { firstByte, secondByte };
         }
 
+        /// <summary>
+        /// 数组转数字
+        /// </summary>
+        /// <param name="datas">数组</param>
+        /// <param name="startIndex">开始的截取的下标</param>
+        /// <param name="length">截取长度</param>
+        /// <returns></returns>
+        public T Bytes2Number<T>(byte[] datas,int startIndex,int length) where T: unmanaged
+        {
+            Span<byte> span = datas.AsSpan(startIndex, length);
+            if (BitConverter.IsLittleEndian) span.Reverse();
+            return MemoryMarshal.Read<T>(span);
+        }
         public List<Byte> addFA(List<Byte> list)
         {
             List<byte> result = new List<byte>();

+ 13 - 0
HengshanPaymentTerminal/MessageEntity/ErrorMessage.cs

@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HengshanPaymentTerminal.MessageEntity
+{
+    public class ErrorMessage:CommonMessage
+    {
+        
+    }
+}

+ 54 - 0
HengshanPaymentTerminal/MessageEntity/Incoming/AuthorizationResponse.cs

@@ -0,0 +1,54 @@
+using Edge.Core.Parser.BinaryParser.MessageEntity;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HengshanPaymentTerminal.MessageEntity.Incoming
+{
+    /// <summary>
+    /// FCC发起授权请求,油机回复数据对象
+    /// </summary>
+    public class AuthorizationResponse:CommonMessage
+    {
+        /// <summary>
+        /// 枪号
+        /// </summary>
+        public int NozzleNum { get; set; }
+
+        /// <summary>
+        /// 发起授权时间
+        /// </summary>
+        public DateTime? AuthorizationTime { get; set; }
+
+        /// <summary>
+        /// 授权结果:00:失败;01:成功
+        /// </summary>
+        public int Result {  get; set; }
+
+        /// <summary>
+        /// 流水号
+        /// </summary>
+        public int Ttc {  get; set; }
+
+        public override byte[] ToCommonByteArray()
+        {
+            return base.ToCommonByteArray();
+        }
+
+        public override CommonMessage ToObject(byte[] datas)
+        {
+            getBaseData(datas);
+            this.NozzleNum = datas[7];
+
+            Span<byte> authorizationTimeSapn = datas.AsSpan(8, 7);
+            this.AuthorizationTime = bytes2DateTime(authorizationTimeSapn.ToArray());
+
+            this.Result = datas[15];
+
+            this.Ttc = Bytes2Number<int>(datas, 16, 4);
+            return this;
+        }
+    }
+}

+ 9 - 1
HengshanPaymentTerminal/MessageEntity/Incoming/CommonAnswerBack.cs

@@ -33,7 +33,15 @@ namespace HengshanPaymentTerminal.MessageEntity.Incoming
 
         public override CommonMessage ToObject(byte[] datas)
         {
-            throw new NotImplementedException();
+            getBaseData(datas);
+            this.Command = datas[7];
+            this.NozzleNum = datas[8];
+            if (Enum.IsDefined(typeof(RESULT), datas[9]))
+            {
+                this.Result = (RESULT)datas[9];
+            }
+            
+            return this;
         }
 
         public override byte[] ToCommonByteArray()

+ 7 - 18
HengshanPaymentTerminal/MessageEntity/Incoming/OrderFromMachine.cs

@@ -91,9 +91,8 @@ namespace HengshanPaymentTerminal.MessageEntity.Incoming
         {
             getBaseData(datas);
             this.nozzleNum = datas[7];
-            Span<byte> ttcSpan = datas.AsSpan(8, 4);
-            if (BitConverter.IsLittleEndian) ttcSpan.Reverse();
-            this.ttc = MemoryMarshal.Read<int>(ttcSpan);
+
+            this.ttc = Bytes2Number<int>(datas, 8, 4);
 
             Span<byte> dispenserSpan = datas.AsSpan(12, 7);
             this.dispenserTime = bytes2DateTime(dispenserSpan.ToArray());
@@ -106,28 +105,18 @@ namespace HengshanPaymentTerminal.MessageEntity.Incoming
 
             this.payType = datas[28];
 
-            Span<byte> priceSpan = datas.AsSpan(29, 2);
-            if (BitConverter.IsLittleEndian) priceSpan.Reverse();
-            ushort priceShort = MemoryMarshal.Read<ushort>(priceSpan);
+            ushort priceShort = Bytes2Number<ushort>(datas,29, 2);
             this.price = priceShort / 100;
 
-            Span<byte> ctcSpan = datas.AsSpan(31, 2);
-            if (BitConverter.IsLittleEndian) ctcSpan.Reverse();
-            this.ctc = MemoryMarshal.Read<ushort>(ctcSpan);
+            this.ctc = Bytes2Number<ushort>(datas, 31, 2);
 
-            Span<byte> volumeTotalSpan = datas.AsSpan(33, 4);
-            if (BitConverter.IsLittleEndian) volumeTotalSpan.Reverse();
-            uint volumeTotalInt = MemoryMarshal.Read<UInt32>(volumeTotalSpan);
+            uint volumeTotalInt = Bytes2Number<uint>(datas, 33, 4);
             this.volumeTotal = volumeTotalInt / 100;
 
-            Span<byte> amountSpan = datas.AsSpan(37, 3);
-            if (BitConverter.IsLittleEndian) amountSpan.Reverse();
-            uint amountInt = MemoryMarshal.Read<UInt32>(amountSpan);
+            uint amountInt = Bytes2Number<uint>(datas, 37, 4);
             this.amount = amountInt / 100;
 
-            Span<byte> volumeSpan = datas.AsSpan(40, 3);
-            if (BitConverter.IsLittleEndian) volumeSpan.Reverse();
-            uint volumeInt = MemoryMarshal.Read<UInt32>(volumeSpan);
+            uint volumeInt = Bytes2Number<uint>(datas, 40, 4);
             this.volume = volumeInt / 100;
 
             Span<byte> cardNumSpan = datas.AsSpan(43, 10);

+ 53 - 0
HengshanPaymentTerminal/MessageEntity/Incoming/UnAhorizationResponse.cs

@@ -0,0 +1,53 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HengshanPaymentTerminal.MessageEntity.Incoming
+{
+    /// <summary>
+    /// Fcc发起取消授权,油机回复信息数据对象
+    /// </summary>
+    public class UnAhorizationResponse:CommonAnswerBack
+    {
+        /// <summary>
+        /// 枪号
+        /// </summary>
+        public int NozzleNum { get; set; }
+
+        /// <summary>
+        /// 发起授权时间
+        /// </summary>
+        public DateTime? AuthorizationTime { get; set; }
+
+        /// <summary>
+        /// 授权结果:00:失败;01:成功
+        /// </summary>
+        public int Result { get; set; }
+
+        /// <summary>
+        /// 流水号
+        /// </summary>
+        public int Ttc { get; set; }
+
+        public override byte[] ToCommonByteArray()
+        {
+            return base.ToCommonByteArray();
+        }
+
+        public override CommonMessage ToObject(byte[] datas)
+        {
+            getBaseData(datas);
+            this.NozzleNum = datas[7];
+
+            Span<byte> authorizationTimeSapn = datas.AsSpan(8, 7);
+            this.AuthorizationTime = bytes2DateTime(authorizationTimeSapn.ToArray());
+
+            this.Result = datas[15];
+
+            this.Ttc = Bytes2Number<int>(datas, 16, 4);
+            return this;
+        }
+    }
+}

+ 53 - 0
HengshanPaymentTerminal/Mqtt/Request/MqttAuthorizationRequest.cs

@@ -0,0 +1,53 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HengshanPaymentTerminal.Mqtt.Request
+{
+    /// <summary>
+    /// 云端 Mqtt 发送授权请求数据对象
+    /// </summary>
+    public class MqttAuthorizationRequest
+    {
+        /// <summary>
+        /// 枪号
+        /// </summary>
+        public int NozzleNum { get; set; }
+
+        /// <summary>
+        /// 授权时间
+        /// </summary>
+        public DateTime AuthorizationTime { get; set; }
+
+        /// <summary>
+        /// 定量类型 01:定金额;02:定升数
+        /// </summary>
+        public int AuthorizationType { get; set; }
+
+        /// <summary>
+        /// 定量值
+        /// </summary>
+        public decimal Value { get; set; }
+    }
+
+    public class MqttUnAhorizationRequest
+    {
+        /// <summary>
+        /// 枪号
+        /// </summary>
+        public int NozzleNum { get; set; }
+
+        /// <summary>
+        /// 授权时间
+        /// </summary>
+        public DateTime AuthorizationTime { get; set; }
+
+        /// <summary>
+        /// 交易流水号
+        /// </summary>
+        public int Ttc {  get; set; }
+
+    }
+}

+ 6 - 0
HengshanPaymentTerminal/StateMachineMessageCutter.cs

@@ -51,6 +51,8 @@ namespace HengshanPaymentTerminal
             window.OnWindowFull += (data) =>
             {
                 byte[] tempBytes = window.ToArray();
+                string receiveStr = BitConverter.ToString(tempBytes).Replace("-", " ");
+                innerLogger.Info($"receive data : ${receiveStr}");
 
                 //查找包头位置
                 int findIndex = -1;
@@ -62,6 +64,7 @@ namespace HengshanPaymentTerminal
                         break;
                     }
                 }
+                innerLogger.Info($"find head index = ${findIndex}");
                 //若没有找到包头,证明目前缓存中都是垃圾数据,清掉
                 if (findIndex == -1)
                 {
@@ -78,6 +81,8 @@ namespace HengshanPaymentTerminal
                 //获取有效数据长度
                 int dataLen = Bcd2Int(tempBytes[4], tempBytes[5]);
                 byte[] reduceFAData = Reduce0xFAPair(tempBytes);
+                string reduceFADataStr = BitConverter.ToString(reduceFAData).Replace("-", " ");
+                innerLogger.Info($"data length is ${dataLen},reduceFAData len is ${reduceFAData.Length},value is ${reduceFADataStr}");
                 //去除多余FA后,实际数据不足有效数据长度,表示有粘包,仍非完整数据,等待下一轮接收数据再处理
                 if(reduceFAData.Length < dataLen + 2)
                 {
@@ -92,6 +97,7 @@ namespace HengshanPaymentTerminal
                 if (calculatorValue != crcValue)
                 {
                     innerLogger.Info($"crc value error,get value is {crcValue},calculator value is {calculatorValue}");
+                    window.RemoveRange(0, tempBytes.Length);
                     return;
                 }
 

+ 10 - 1
HengshanPaymentTerminal/Test/CalculatorTest.cs

@@ -16,7 +16,7 @@ namespace HengshanPaymentTerminal.Test
         [Fact]
         public void crc16()
         {
-            byte[] bytes = { 0x12,0x66,0xfb};
+            byte[] bytes = { 0x00, 0x00, 0x01, 0x00, 0x01, 0x30};
             ushort value = HengshanCRC16.ComputeChecksum(bytes);
             byte[] bytes1 = HengshanCRC16.ComputeChecksumToBytes(bytes);
             Console.WriteLine($"CRC TEST RESULT:{value}");
@@ -125,5 +125,14 @@ namespace HengshanPaymentTerminal.Test
 
            
         }
+
+        [Fact]
+        private void testConverDateTimeToBytes()
+        {
+            DateTime dateTime = DateTime.Now;
+            byte[] bytes = HengshanPayTermHandler.ConvertDateTimeToByteArray(dateTime);
+            string result = BitConverter.ToString(bytes).Replace("-", " ");
+            Console.WriteLine(result);
+        }
     }
 }