StateMachineMessageCutter.cs 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. using Edge.Core.Processor;using Edge.Core.IndustryStandardInterface.Pump;
  2. using Edge.Core.Parser.BinaryParser.Util;
  3. using System;
  4. using System.Collections;
  5. using System.Collections.Generic;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. using Edge.Core.Processor.Communicator;
  10. namespace HengShan_Pump_TQC_IFSF
  11. {
  12. public class StateMachineMessageCutter : IMessageCutter<byte[]>
  13. {
  14. public byte[] Message { get; private set; }
  15. public event EventHandler OnMessageCut;
  16. public event EventHandler<MessageCutterInvalidMessageReadEventArg> OnInvalidMessageRead;
  17. //static ILog innerLogger = log4net.LogManager.GetLogger("StateMachineMessageCutter");
  18. static NLog.Logger innerLogger = NLog.LogManager.LoadConfiguration("nlog.config").GetLogger("StateMachineMessageCutter");
  19. private string loggerAppendix = "HengShan_Pump_TQC_IFSF msgCutter ";
  20. private readonly SizableWindow<byte> window;
  21. private State nextState = State.Uninitialized;
  22. /// <summary>
  23. ///
  24. /// </summary>
  25. public StateMachineMessageCutter()
  26. {
  27. //this.initWindowSize = initWindowSize;
  28. this.window = new SizableWindow<byte>(2);
  29. this.window.OnWindowFull += (data) =>
  30. {
  31. switch (nextState)
  32. {
  33. case State.Uninitialized:
  34. // minimal msg is heartbeat msg, which is 4 bytes
  35. var len = this.window.ToInt32();
  36. if (len < 4)
  37. {
  38. innerLogger.Error(this.loggerAppendix + "Unexpected ifsf 2 len bytes read(value must >=4): " + data.Take(2).ToHexLogString());
  39. this.window.Clear();
  40. return;
  41. }
  42. if (innerLogger.IsDebugEnabled)
  43. innerLogger.Debug(this.loggerAppendix + " Ifsf Msg len(2 bytes) read with: " + len);
  44. this.window.NewSize = len + 2;
  45. this.nextState = State.LengthReadWaitForBody;
  46. break;
  47. case State.LengthReadWaitForBody:
  48. if (innerLogger.IsDebugEnabled)
  49. innerLogger.Debug(this.loggerAppendix + " Ifsf Msg read with(2 bytes len at header): " + this.window.ToHexLogString());
  50. this.Message = this.window.Skip(2).ToArray();
  51. var safe = this.OnMessageCut;
  52. safe?.Invoke(this, null);
  53. this.nextState = State.Uninitialized;
  54. this.window.Clear();
  55. break;
  56. default:
  57. throw new ArgumentOutOfRangeException();
  58. }
  59. };
  60. }
  61. private enum State
  62. {
  63. Uninitialized,
  64. LengthReadWaitForBody,
  65. }
  66. public void Feed(byte[] next)
  67. {
  68. //innerLogger.Debug(this.loggerAppendix + " " + next.ToHexLogString() + " is feed in Window in state: " + nextState);
  69. for (int i = 0; i < next.Length; i++)
  70. this.window.Add(next[i]);
  71. }
  72. }
  73. }