using Edge.Core.Processor; using Edge.Core.IndustryStandardInterface.Pump; using Edge.Core.Parser.BinaryParser.Util; using System; using System.Collections.Generic; using System.Linq; using System.Text; using Edge.Core.Processor.Communicator; namespace Censtar_31064V105OrV106_Pump { public class MessageCutterV105 : IMessageCutter { private readonly SizableWindow window; private State nextState = State.Uninitialized; private readonly List buffer = new List(); /// /// cmd:bodyLength /// private static Dictionary CmdCharAndBodyLengthMappers = new Dictionary() { {0,0 }, {2,1 }, {3,0 }, {4,0}, {5,0}, {6,0 }, {7,0 }, {8,12 }, {9,1 }, {0x0E,3 }, {0x10,1 }, {0x12,0 }, {0x13,0 }, {0x14,0 }, {0x15,3 }, {0x17,0 }, {0x31,0 }, {0x32,0 }, {0x33,0 }, {0x34,4 }, {0x35,4 }, {0x36,20 }, {0x38,22 }, }; public byte[] Message { get; private set; } public event EventHandler OnMessageCut; public event EventHandler OnInvalidMessageRead; private enum State { Uninitialized, SyncHeader_Cmd_NozzleNumber_Ready, BodyAndCrcReady, } public MessageCutterV105() { this.window = new SizableWindow(3); this.window.OnWindowFull += (data) => { switch (nextState) { case State.Uninitialized: if (data[0] == data[1] && data[0] == data[2] && data[0] == 0xFC) { this.window.NewSize = 5; this.nextState = State.SyncHeader_Cmd_NozzleNumber_Ready; } else { this.window.Clear(); this.OnInvalidMessageRead?.Invoke(this, new MessageCutterInvalidMessageReadEventArg() { Message = "First 3 bytes: 0x" + this.window.ToHexLogString() + " are not the expecting 0xFC, will clear window and start over" }); } break; case State.SyncHeader_Cmd_NozzleNumber_Ready: var cmd = this.window[3]; if (!CmdCharAndBodyLengthMappers.TryGetValue(cmd, out byte bodyLength)) { this.nextState = State.Uninitialized; this.OnInvalidMessageRead?.Invoke(this, new MessageCutterInvalidMessageReadEventArg() { Message = "Cmd byte: 0x" + cmd.ToString("X2") + " is not defined, will clear window and start over" }); } else { this.window.NewSize = 3 + 1 + 1 + bodyLength + 1; this.nextState = State.BodyAndCrcReady; } break; case State.BodyAndCrcReady: //innerLogger.Debug(this.loggerAppendix + " Fire OnMessageConstructed with innerQueue: " + this.buffer.ToHexLogString()); this.Message = this.window.ToArray(); var safe = this.OnMessageCut; safe?.Invoke(this, null); this.nextState = State.Uninitialized; this.window.Clear(); //this.window.NewSize = this.initWindowSize; break; default: throw new ArgumentOutOfRangeException(); } }; } public void Feed(byte[] data) { for (int i = 0; i < data.Length; i++) this.window.Add(data[i]); } } }