using Edge.Core.Parser.BinaryParser.Util; using Edge.Core.Processor.Communicator; using System; using System.Collections.Generic; using System.Diagnostics; using System.Text; using System.Linq; namespace SuZhouSuAnXin_BatteryEMS { public class MessageCutter : IMessageCutter, IDisposable { public byte[] Message { get; set; } public event EventHandler OnMessageCut; public event EventHandler OnInvalidMessageRead; private List buffer = new List(); public MessageCutter() { //this.timer = new System.Timers.Timer(); //this.timer.Interval = this.timeWindowTimedoutValue; //this.timer.Elapsed += (s, a) => //{ // this.timer.Stop(); // this.Message = buffer.ToArray(); // if (this.Message.Length <= 6) OnInvalidMessageRead?.Invoke(this, new MessageCutterInvalidMessageReadEventArg() // { // Message = $"Raw msg: 0x{this.Message.ToHexLogString()} does not meet the min length(valid Len must >6) requirment" // }); // this.OnMessageCut?.Invoke(this, new EventArgs()); // this.buffer.Clear(); //}; } /// /// 数据段格式定义如下: /// 2 字节 2 字节 2 字节 1 字节 1 字节 1 字节 N 字节 /// 事务处理标识符(byte0,byte1)—为 0 /// 协议标识符(byte2,byte3)—为 0 /// 长度字段(byte4 为高字节,byte5 为低字节)—表示后面字节的总长度(地址+功能码+数据) /// 地址(byte6)—表示被寻址的从机地址,本协议中规定从机地址为 20 H /// 事务处理标识符 协议标识符 长度字段 地址 功能码 字节数 数据 /// /// public void Feed(byte[] data) { for (int i = 0; i < data.Length; i++) { this.buffer.Add(data[i]); if (this.buffer.Count >= 1 && this.buffer[0] != 0x00) { this.OnInvalidMessageRead?.Invoke(this, new MessageCutterInvalidMessageReadEventArg() { Message = $"invalid byte[0]: 0x{this.buffer[0].ToString("x2") }, " + $"must be 0x00, clear buf and continue reading..." }); this.buffer.Clear(); continue; } if (this.buffer.Count >= 4 && (this.buffer[0] != 0 || this.buffer[1] != 0 || this.buffer[2] != 0 || this.buffer[3] != 0)) { this.OnInvalidMessageRead?.Invoke(this, new MessageCutterInvalidMessageReadEventArg() { Message = $"invalid value in byte[0] or byte[1] or byte[2] or byte[3], actual are: 0x{this.buffer.Take(4).ToHexLogString() }, " + $"expect all 0x00, clear buf and continue reading..." }); this.buffer.Clear(); continue; } if (this.buffer.Count >= 7 && this.buffer[6] != 0x20) { this.OnInvalidMessageRead?.Invoke(this, new MessageCutterInvalidMessageReadEventArg() { Message = $"invalid byte[6]: 0x{this.buffer[6].ToString("x2") }, " + $"must be 0x20, clear buf and continue reading..." }); this.buffer.Clear(); continue; } if (this.buffer.Count >= 9 && this.buffer.Count == (4 + 2 + this.buffer[4] * 256 + this.buffer[5])) { this.Message = this.buffer.ToArray(); var safe = this.OnMessageCut; safe?.Invoke(this, null); this.buffer.Clear(); } if (this.buffer.Count >= 200) { this.OnInvalidMessageRead?.Invoke(this, new MessageCutterInvalidMessageReadEventArg() { Message = $"Long length(len: {this.buffer.Count } message is still constructing in MsgCutter: 0x{ this.buffer.ToHexLogString()}, clear buf and continue reading..." }); this.buffer.Clear(); continue; } } } public void Dispose() { } } }