TerminalManager.cs 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. using Dfs.WayneChina.GilbarcoDispenserPayTerminal;
  2. using Dfs.WayneChina.GilbarcoDispenserPayTerminal.MessageEntities;
  3. using Dfs.WayneChina.GilbarcoDispenserPayTerminal.MessageEntities.Incoming;
  4. using Dfs.WayneChina.GilbarcoDispenserPayTerminal.MessageEntities.Outgoing;
  5. using Edge.Core.IndustryStandardInterface.Pump;
  6. using System;
  7. using System.Collections.Concurrent;
  8. using System.Collections.Generic;
  9. using System.Linq;
  10. using System.Text;
  11. using System.Timers;
  12. using Wayne.FDCPOSLibrary;
  13. namespace Dfs.WayneChina.GilbarcoPos
  14. {
  15. public class TerminalManager
  16. {
  17. private class SeqNoGenerator
  18. {
  19. private List<byte> seqNoList;
  20. private int i = 0;
  21. public SeqNoGenerator()
  22. {
  23. seqNoList = new List<byte>();
  24. for (byte i = 0x5F; i >= 0x40; i--)
  25. {
  26. seqNoList.Add(i);
  27. }
  28. }
  29. public byte GetNextSeqNo()
  30. {
  31. i++;
  32. return seqNoList[i % 32];
  33. }
  34. }
  35. public byte PumpId { get; }
  36. private GilbarcoPosApp PosApp { get; }
  37. private GilbarcoPayTerminalHandler terminal;
  38. private Timer timer;
  39. private int _interval;
  40. private byte seqNo;
  41. private SeqNoGenerator Sqg { get; }
  42. private Queue<FdcTransaction> fillings = new Queue<FdcTransaction>(10);
  43. private NLog.Logger logger = NLog.LogManager.LoadConfiguration("NLog.config").GetLogger("IPosPlusApp");
  44. public TerminalManager(GilbarcoPosApp posApp, GilbarcoPayTerminalHandler terminalHandler, int interval)
  45. {
  46. PosApp = posApp;
  47. terminal = terminalHandler;
  48. _interval = interval;
  49. PumpId = terminalHandler.PumpId;
  50. Sqg = new SeqNoGenerator();
  51. }
  52. public void Start()
  53. {
  54. timer = new Timer();
  55. timer.Interval = _interval;
  56. timer.Elapsed += Timer_Elapsed;
  57. timer.Start();
  58. }
  59. private void Timer_Elapsed(object sender, ElapsedEventArgs e)
  60. {
  61. SendCheckCommand();
  62. }
  63. private byte GetNextSeqNo()
  64. {
  65. return (byte)(seqNo++ % 0x7F);
  66. }
  67. private void SendCheckCommand()
  68. {
  69. logger.Debug($"Checking pump {PumpId}");
  70. CheckCommand checkCommand = new CheckCommand();
  71. checkCommand.DestinationAddress = terminal.TerminalAddress;
  72. checkCommand.SourceAddress = terminal.Address;
  73. checkCommand.FrameSqNoByte = Sqg.GetNextSeqNo();
  74. checkCommand.Time = long.Parse(DateTime.Now.ToString("yyyyMMddHHmmss"));
  75. checkCommand.BaseBlacklistVersion = PosApp.CurrentVersionInfo.BaseBlacklistVersion;
  76. checkCommand.AddBlacklistVersion = PosApp.CurrentVersionInfo.AddBlacklistVersion;
  77. checkCommand.DeleteBlacklistVersion = PosApp.CurrentVersionInfo.DeleteBlacklistVersion;
  78. checkCommand.WhitelistVersion = PosApp.CurrentVersionInfo.WhitelistVersion;
  79. checkCommand.PriceVersion = PosApp.CurrentVersionInfo.PriceVersion;
  80. checkCommand.StationGeneralInfoVersion = PosApp.CurrentVersionInfo.StationGeneralInfoVersion;
  81. checkCommand.PrivateDataDownloadFlag = PosApp.CurrentVersionInfo.PrivateDataDownloadFlag;
  82. checkCommand.SoftwareDownloadFlag = PosApp.CurrentVersionInfo.SoftwareDownloadFlag;
  83. terminal.Write(checkCommand);
  84. }
  85. public void HandleInfoCommand(InfoCommand command)
  86. {
  87. logger.Debug("Handling INFO command");
  88. if (command.Count > 0)
  89. {
  90. if (command.CardInsertedStates != null)
  91. {
  92. }
  93. else if (command.NozzleOperatingStates != null)
  94. {
  95. var nozzleOperationState = command.NozzleOperatingStates[0];
  96. if (nozzleOperationState.State == NozzleOperatingState.PumpStateChangeCode.NozzleLiftOrFueling)
  97. {
  98. if (nozzleOperationState.PRC == 0)
  99. {
  100. //Assume this is nozzle lift => FDC_CALLING
  101. terminal.UpdatePumpState(LogicalDeviceState.FDC_CALLING);
  102. }
  103. else if (nozzleOperationState.PRC > 0 && nozzleOperationState.VOL == 0)
  104. {
  105. //Assume this is FDC_AUTHORIZED
  106. terminal.UpdatePumpState(LogicalDeviceState.FDC_AUTHORISED);
  107. }
  108. else if (nozzleOperationState.VOL > 0)
  109. {
  110. //Assume this is FDC_FUELLING
  111. terminal.UpdatePumpState(LogicalDeviceState.FDC_FUELLING);
  112. terminal.UpdateFuelingStatus(new FdcTransaction
  113. {
  114. Finished = false,
  115. Nozzle = new LogicalNozzle(PumpId, 1, 1, null),
  116. Amount = nozzleOperationState.AMN,
  117. Price = nozzleOperationState.PRC,
  118. Volumn = nozzleOperationState.VOL
  119. });
  120. }
  121. }
  122. }
  123. }
  124. else
  125. {
  126. //Terminal is running fine for now.
  127. }
  128. }
  129. public void HandleTransactionData(TransactionData transactionData)
  130. {
  131. logger.Info("Handling TransactionData");
  132. //First trigger pump state change, idle again => FDC_READY
  133. terminal.UpdatePumpState(Wayne.FDCPOSLibrary.LogicalDeviceState.FDC_READY);
  134. // Handle possible duplicate
  135. var filling = fillings.FirstOrDefault(f => f.Nozzle.PumpId == transactionData.NozzleNo
  136. && f.SequenceNumberGeneratedOnPhysicalPump == transactionData.PosTtc);
  137. if (filling == null)
  138. {
  139. //Fuelling is done now, trigger as well the fueling status change
  140. var trans = new FdcTransaction
  141. {
  142. Finished = true,
  143. Nozzle = new LogicalNozzle(PumpId, 1, 1, null),
  144. Amount = transactionData.Amount,
  145. Price = transactionData.Price,
  146. Volumn = transactionData.Volume,
  147. VolumeTotalizer = Convert.ToInt32(transactionData.VolumeTotalizer),
  148. SequenceNumberGeneratedOnPhysicalPump = transactionData.PosTtc
  149. };
  150. terminal.UpdateFuelingStatus(trans);
  151. if (fillings.Count >= 10)
  152. {
  153. fillings.Dequeue();
  154. }
  155. fillings.Enqueue(trans);
  156. }
  157. var ack = CreateTransactionDataAck(0);
  158. terminal.Write(ack);
  159. }
  160. private TransactionDataAck CreateTransactionDataAck(byte result)
  161. {
  162. TransactionDataAck ack = new TransactionDataAck();
  163. ack.DestinationAddress = terminal.TerminalAddress;
  164. ack.SourceAddress = terminal.Address;
  165. ack.FrameSqNoByte = Sqg.GetNextSeqNo();
  166. ack.Result = result;
  167. return ack;
  168. }
  169. }
  170. }