123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 |
- using Edge.Core.Processor.Communicator;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- namespace HengshanPaymentTerminal
- {
- public class StateMachineMessageCutter : IMessageCutter<byte[]>
- {
- #region Internal State enum
- private enum State
- {
- Uninitialized,
- LengthReady,
- BodyReady,
- EtxReady,
- CrcReady
- }
- #endregion
- #region Fields
- public byte[] Message { get; private set; }
- public event EventHandler OnMessageCut;
- public event EventHandler<MessageCutterInvalidMessageReadEventArg> OnInvalidMessageRead;
- private string loggerAppendix = "HengshanPay Terminal";
- private readonly SizableWindow<byte> window;
- private State nextState = State.Uninitialized;
- private const int STX = 0xFA;
- #endregion
- #region Logger
- static NLog.Logger innerLogger = NLog.LogManager.LoadConfiguration("nlog.config").GetLogger("Communicator");
- #endregion
- public StateMachineMessageCutter()
- {
- window = new SizableWindow<byte>();
- window.OnWindowFull += (data) =>
- {
- Message = window.ToArray();
- var safe = OnMessageCut;
- safe?.Invoke(this, null);
- nextState = State.Uninitialized;
- window.Clear();
- //switch (nextState)
- //{
- // case State.Uninitialized:
- // if (data.First() == STX)
- // {
- // window.NewSize = 6;
- // nextState = State.LengthReady;
- // }
- // else
- // {
- // OnInvalidMessageRead?.Invoke(this, new MessageCutterInvalidMessageReadEventArg()
- // {
- // Message = "invalid byte[0]: 0x" + data.First().ToString("x2") + ", will skip"
- // });
- // window.Clear();
- // }
- // break;
- // case State.LengthReady:
- // var countSTX = window.Count(b => b == STX);
- // if (countSTX > 1)
- // {
- // //Console.WriteLine($"0xFA count: {countSTX}");
- // innerLogger.Info($"0xFA count: {countSTX}");
- // int index = window.ToList().LastIndexOf(STX);
- // var tempArray = window.Skip(index).ToArray();
- // window.Clear();
- // nextState = State.Uninitialized;
- // Feed(tempArray);
- // return;
- // }
- // int bodyLen = window[4] * 10 + window[5];
- // if (bodyLen > 256 || bodyLen < 2)
- // {
- // var safe8 = this.OnInvalidMessageRead;
- // safe8?.Invoke(this, new MessageCutterInvalidMessageReadEventArg()
- // {
- // Message = "Message body length is not valid, len is: " + bodyLen
- // });
- // nextState = State.Uninitialized;
- // window.Clear();
- // window.NewSize = 1;
- // return;
- // }
- // window.NewSize += bodyLen;
- // nextState = State.BodyReady;
- // break;
- // case State.BodyReady:
- // window.NewSize = window.Skip(4).Take(2).ToArray().ToInt32() + 6 + 3;
- // nextState = State.CrcReady;
- // break;
- // case State.CrcReady:
- // var stxCount = window.Count(b => b == STX);
- // if (stxCount > 1)
- // {
- // //Console.WriteLine($"0xFA count: {stxCount}");
- // innerLogger.Info($"0xFA count: {stxCount}");
- // int length = window.Count;
- // if (window[length - 3] == 0xFF)
- // {
- // //Console.WriteLine("ETX exists, consider it a complete message");
- // innerLogger.Info("ETX exists, consider it a complete message");
- // }
- // else
- // {
- // int index = window.ToList().LastIndexOf(STX);
- // if (index + 2 <= window.Count - 1)
- // {
- // byte trailingByte1 = window[index + 1];
- // byte trailingByte2 = window[index + 2];
- // if (trailingByte1 == trailingByte2 && trailingByte1 <= 6 && trailingByte1 > 0)
- // {
- // //Console.WriteLine("Possible mix of incompleted messages");
- // innerLogger.Info("Possible mix of incompleted messages");
- // var tempArray = window.Skip(index).ToArray();
- // window.Clear();
- // nextState = State.Uninitialized;
- // Feed(tempArray);
- // return;
- // }
- // }
- // }
- // }
- // Message = window.ToArray();
- // var safe = OnMessageCut;
- // safe?.Invoke(this, null);
- // nextState = State.Uninitialized;
- // window.Clear();
- // break;
- // default:
- // throw new ArgumentOutOfRangeException();
- //}
- };
- }
- public void Feed(byte[] data)
- {
- for (int i = 0; i < data.Length; i++)
- {
- window.Add(data[i]);
- }
- }
- private int Get0xFAPairCountInWindow(IEnumerable<byte> data)
- {
- return (int)Math.Round(((double)(data.Count(w => w == 0xFA)) / 2), MidpointRounding.AwayFromZero);
- }
- public int Reduce0xFAPair(IList<byte> target, int startIndex)
- {
- int reducedCount = 0;
- var faAppearedPositions = new List<int>();
- for (int i = startIndex; i < target.Count; i++)
- {
- if (target[i] == 0xFA)
- {
- if (i <= (target.Count - 2))
- {
- if (target[i + 1] == 0xFA)
- {
- faAppearedPositions.Add(i);
- i++;
- }
- }
- }
- }
- for (int i = 0; i < faAppearedPositions.Count; i++)
- {
- target.RemoveAt(faAppearedPositions[i] - i);
- reducedCount++;
- }
- return reducedCount;
- }
- }
- }
|