MessageCutter.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. using Edge.Core.Parser.BinaryParser.Util;
  2. using Edge.Core.Processor.Communicator;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Diagnostics;
  6. using System.Text;
  7. using System.Linq;
  8. namespace SuZhouSuAnXin_BatteryEMS
  9. {
  10. public class MessageCutter : IMessageCutter<byte[]>, IDisposable
  11. {
  12. public byte[] Message { get; set; }
  13. public event EventHandler OnMessageCut;
  14. public event EventHandler<MessageCutterInvalidMessageReadEventArg> OnInvalidMessageRead;
  15. private List<byte> buffer = new List<byte>();
  16. public MessageCutter()
  17. {
  18. //this.timer = new System.Timers.Timer();
  19. //this.timer.Interval = this.timeWindowTimedoutValue;
  20. //this.timer.Elapsed += (s, a) =>
  21. //{
  22. // this.timer.Stop();
  23. // this.Message = buffer.ToArray();
  24. // if (this.Message.Length <= 6) OnInvalidMessageRead?.Invoke(this, new MessageCutterInvalidMessageReadEventArg()
  25. // {
  26. // Message = $"Raw msg: 0x{this.Message.ToHexLogString()} does not meet the min length(valid Len must >6) requirment"
  27. // });
  28. // this.OnMessageCut?.Invoke(this, new EventArgs());
  29. // this.buffer.Clear();
  30. //};
  31. }
  32. /// <summary>
  33. /// 数据段格式定义如下:
  34. /// 2 字节 2 字节 2 字节 1 字节 1 字节 1 字节 N 字节
  35. /// 事务处理标识符(byte0,byte1)—为 0
  36. /// 协议标识符(byte2,byte3)—为 0
  37. /// 长度字段(byte4 为高字节,byte5 为低字节)—表示后面字节的总长度(地址+功能码+数据)
  38. /// 地址(byte6)—表示被寻址的从机地址,本协议中规定从机地址为 20 H
  39. /// 事务处理标识符 协议标识符 长度字段 地址 功能码 字节数 数据
  40. /// </summary>
  41. /// <param name="data"></param>
  42. public void Feed(byte[] data)
  43. {
  44. for (int i = 0; i < data.Length; i++)
  45. {
  46. this.buffer.Add(data[i]);
  47. if (this.buffer.Count >= 1 && this.buffer[0] != 0x00)
  48. {
  49. this.OnInvalidMessageRead?.Invoke(this,
  50. new MessageCutterInvalidMessageReadEventArg()
  51. {
  52. Message = $"invalid byte[0]: 0x{this.buffer[0].ToString("x2") }, " +
  53. $"must be 0x00, clear buf and continue reading..."
  54. });
  55. this.buffer.Clear();
  56. continue;
  57. }
  58. if (this.buffer.Count >= 4 &&
  59. (this.buffer[0] != 0 || this.buffer[1] != 0 || this.buffer[2] != 0 || this.buffer[3] != 0))
  60. {
  61. this.OnInvalidMessageRead?.Invoke(this,
  62. new MessageCutterInvalidMessageReadEventArg()
  63. {
  64. Message = $"invalid value in byte[0] or byte[1] or byte[2] or byte[3], actual are: 0x{this.buffer.Take(4).ToHexLogString() }, " +
  65. $"expect all 0x00, clear buf and continue reading..."
  66. });
  67. this.buffer.Clear();
  68. continue;
  69. }
  70. if (this.buffer.Count >= 7 && this.buffer[6] != 0x20)
  71. {
  72. this.OnInvalidMessageRead?.Invoke(this,
  73. new MessageCutterInvalidMessageReadEventArg()
  74. {
  75. Message = $"invalid byte[6]: 0x{this.buffer[6].ToString("x2") }, " +
  76. $"must be 0x20, clear buf and continue reading..."
  77. });
  78. this.buffer.Clear();
  79. continue;
  80. }
  81. if (this.buffer.Count >= 9 && this.buffer.Count == (4 + 2 + this.buffer[4] * 256 + this.buffer[5]))
  82. {
  83. this.Message = this.buffer.ToArray();
  84. var safe = this.OnMessageCut;
  85. safe?.Invoke(this, null);
  86. this.buffer.Clear();
  87. }
  88. if (this.buffer.Count >= 200)
  89. {
  90. this.OnInvalidMessageRead?.Invoke(this,
  91. new MessageCutterInvalidMessageReadEventArg()
  92. {
  93. Message = $"Long length(len: {this.buffer.Count } message is still constructing in MsgCutter: 0x{ this.buffer.ToHexLogString()}, clear buf and continue reading..."
  94. });
  95. this.buffer.Clear();
  96. continue;
  97. }
  98. }
  99. }
  100. public void Dispose()
  101. {
  102. }
  103. }
  104. }