using System; using System.Collections.Generic; using System.Text; namespace EPD.Data { public class EPDSocketClient { public Action OnConnect; public Action OnDisconnect; public Action OnSocketSend; public Action OnSocketReceive; public Action OnEPDReply; public Action OnError; private SocketClientWrapper socketWrapper; private object lockerReceive = new object(); private ByteReader dataReader; private ResponseHeader dataHeader; private string channel; public string Channel { get => channel; set { if (string.IsNullOrEmpty(value)) return; channel = value; if (byte.TryParse(value, out byte res)) _channel = res; else _channel = 0; } } private byte _channel; public EPDSocketClient() { socketWrapper = new SocketClientWrapper(); socketWrapper.OnDataChanged += Received; socketWrapper.OnConnected += Connected; socketWrapper.OnDisconnected += Disconnected; } private void Received(byte[] data, int offset, int size) { lock (lockerReceive) { dataHeader.token = 0; if (dataReader == null) { if (data[0] == 1 && data[1] == 1 && data[2] == 0 && data[3] == 0) { dataReader = new ByteReader(data, size); if (size >= ResponseHeader.Size) { var buf = new byte[ResponseHeader.Size]; dataReader.ReadBytes(buf, ResponseHeader.Size); dataHeader = ByteStructConverter.ToStruct(buf); } } else if (data[size - 3] == 0 && data[size - 2] == 0x0D && data[size - 1] == 0x0A) { var lst = CytAsciiData.ToList(data, 0, ref size); if (size > 0 && lst.Count >= 4) { var cmd = ProcessAsciiReceived(lst); OnSocketReceive?.Invoke(cmd, data, size); } } } else dataReader.Append(data, size); if (dataHeader.token != 0) { if (dataReader.Length >= dataHeader.length + 14) { var cmd = ProcessReceived(); OnSocketReceive?.Invoke(cmd, data, dataHeader.length + 14); } else OnSocketReceive?.Invoke("", data, data.Length); } } } private string ProcessAsciiReceived(List lst) { switch (lst[1].Trim()) { case "101": OnEPDReply?.Invoke(EPDCommand.GetSensorStatus, lst.GetRange(5, 2)); return "GetSensorStatus"; case "102": OnEPDReply?.Invoke(EPDCommand.StartMeasurement, lst.GetRange(5, lst.Count - 5)); return "StartMeasurement"; case "103": OnEPDReply?.Invoke(EPDCommand.GetRecipesList, lst.GetRange(5, lst.Count - 5)); return "GetRecipesList"; case "104": OnEPDReply?.Invoke(EPDCommand.StopMeasurement, lst.GetRange(5, lst.Count - 5)); return "StopMeasurement"; case "5": OnEPDReply?.Invoke(EPDCommand.AsciiEvent, lst[5]); return lst[5]; case "110": OnEPDReply?.Invoke(EPDCommand.QueryChannalNames, lst.GetRange(8, lst.Count-8)); return "AllChannelNames"; } return ""; } private string ProcessReceived() { if (dataHeader.errorcode != 0) OnError?.Invoke(dataHeader.command, dataHeader.errorcode); switch (dataHeader.command) { case (int)EPDCommand.QueryCfgList: if (dataReader.ReadInt(out int count)) { var cfgs = new List(); var tmp = new byte[256]; for (int i = 0; i < count; i++) { if (dataReader.ReadBytes(tmp, 256)) { var name = Encoding.UTF8.GetString(tmp); name = name.Substring(0, name.IndexOf('\0')); cfgs.Add(name); } } OnEPDReply?.Invoke(EPDCommand.QueryCfgList, cfgs); } break; case (int)EPDCommand.QueryState: if (dataReader.ReadUInt16(out ushort state)) OnEPDReply?.Invoke(EPDCommand.QueryState, state); break; case (int)EPDCommand.QueryOperateMode: if (dataReader.ReadUInt16(out ushort mode)) OnEPDReply?.Invoke(EPDCommand.QueryOperateMode, mode); break; case (int)EPDCommand.QueryRunStatus: if (dataReader.ReadUInt16(out ushort runStatus)) OnEPDReply?.Invoke(EPDCommand.QueryRunStatus, runStatus); break; case (int)EPDCommand.QueryVer: { var tmp = new byte[32]; if (dataReader.ReadBytes(tmp, 32)) { var ver = Encoding.UTF8.GetString(tmp); OnEPDReply?.Invoke(EPDCommand.QueryVer, ver.Substring(0, ver.IndexOf('\0'))); } } break; case (int)EPDCommand.Event: dataReader.ReadInt(out int type); dataReader.ReadInt64(out long ticket); var paras = new byte[16]; if (type == 17) Console.WriteLine(); dataReader.ReadBytes(paras, 16); dataReader.ReadString(out string desc, 256); var lst = new List { type, ticket, paras, desc}; OnEPDReply?.Invoke(EPDCommand.Event, lst); break; case (int)EPDCommand.Connect: OnEPDReply?.Invoke(EPDCommand.Connect, null); break; case (int)EPDCommand.Disconnect: OnEPDReply?.Invoke(EPDCommand.Disconnect, null); break; case (int)EPDCommand.QueryChannelCount: if (dataReader.ReadByte(out byte res)) OnEPDReply?.Invoke(EPDCommand.QueryChannelCount, res); break; case (int)EPDCommand.Start: OnEPDReply?.Invoke(EPDCommand.Start, null); break; case (int)EPDCommand.RecipeStart: OnEPDReply?.Invoke(EPDCommand.RecipeStart, null); break; case (int)EPDCommand.QueryCurrentConfig: if (dataReader.ReadString(out string cfg, dataHeader.length)) OnEPDReply?.Invoke(EPDCommand.QueryCurrentConfig, cfg); break; case (int)EPDCommand.HeartBeat: OnEPDReply?.Invoke(EPDCommand.HeartBeat,null); break; default: break; } dataReader = null; return ((EPDCommand)dataHeader.command).ToString(); } public void Connect(string ip, int port) { socketWrapper.Connect(ip, port); } public void Disconnect() { socketWrapper.Disconnect(); } private void Connected() { OnConnect?.Invoke(); } private void Disconnected() { OnDisconnect?.Invoke(); } public void ConnectEPD() { var header = new PacketHeader() { token = 0x0101, channel = _channel, command = (byte)EPDCommand.Connect, length = 0 }; var data = new byte[PacketHeader.Size]; Buffer.BlockCopy(ByteStructConverter.Struct2Bytes(header), 0, data, 0, PacketHeader.Size); socketWrapper.Send(data); OnSocketSend?.Invoke("Connect", data); } public void DisconnectEPD() { var header = new PacketHeader() { token = 0x0101, channel = _channel, command = (byte)EPDCommand.Disconnect, length = 0 }; var data = new byte[PacketHeader.Size]; Buffer.BlockCopy(ByteStructConverter.Struct2Bytes(header), 0, data, 0, PacketHeader.Size); socketWrapper.Send(data); OnSocketSend?.Invoke("Disconnect", data); } public void QueryState() { var header = new PacketHeader() { token = 0x0101, channel = _channel, command = (byte)EPDCommand.QueryState, length = 0 }; var data = new byte[PacketHeader.Size]; Buffer.BlockCopy(ByteStructConverter.Struct2Bytes(header), 0, data, 0, PacketHeader.Size); socketWrapper.Send(data); OnSocketSend?.Invoke("QueryState", data); } public void QueryVersion() { var header = new PacketHeader() { token = 0x0101, channel = _channel, command = (byte)EPDCommand.QueryVer, length = 0 }; var data = new byte[PacketHeader.Size]; Buffer.BlockCopy(ByteStructConverter.Struct2Bytes(header), 0, data, 0, PacketHeader.Size); socketWrapper.Send(data); OnSocketSend?.Invoke("QueryVer", data); } public void QueryMode() { var header = new PacketHeader() { token = 0x0101, channel = _channel, command = (byte)EPDCommand.QueryOperateMode, length = 0 }; var data = new byte[PacketHeader.Size]; Buffer.BlockCopy(ByteStructConverter.Struct2Bytes(header), 0, data, 0, PacketHeader.Size); socketWrapper.Send(data); OnSocketSend?.Invoke("QueryOperateMode", data); } public void ResetEPD() { var header = new PacketHeader() { token = 0x0101, channel = _channel, command = (byte)EPDCommand.Reset, length = 0 }; var data = new byte[PacketHeader.Size]; Buffer.BlockCopy(ByteStructConverter.Struct2Bytes(header), 0, data, 0, PacketHeader.Size); socketWrapper.Send(data); OnSocketSend?.Invoke("Reset", data); } public void SendHeartBeat() { var header = new PacketHeader() { token = 0x0101, channel = 0, command = (byte)EPDCommand.HeartBeat, length = 0 }; var data = new byte[PacketHeader.Size]; Buffer.BlockCopy(ByteStructConverter.Struct2Bytes(header), 0, data, 0, PacketHeader.Size); socketWrapper.Send(data); OnSocketSend?.Invoke("HeartBeat", data); } public void SetMode(byte mode) // 1 local; 2 remote { var header = new PacketHeader() { token = 0x0101, channel = _channel, command = (byte)EPDCommand.SetOperateMode, length = 4 }; var data = new byte[PacketHeader.Size + 4]; Buffer.BlockCopy(ByteStructConverter.Struct2Bytes(header), 0, data, 0, PacketHeader.Size); Buffer.BlockCopy(new byte[] { mode, 0, 0, 0 }, 0, data, PacketHeader.Size, 4); socketWrapper.Send(data); OnSocketSend?.Invoke("SetOperateMode", data); } public void QueryRunStatus() { var header = new PacketHeader() { token = 0x0101, channel = _channel, command = (byte)EPDCommand.QueryRunStatus, length = 0 }; var data = new byte[PacketHeader.Size]; Buffer.BlockCopy(ByteStructConverter.Struct2Bytes(header), 0, data, 0, PacketHeader.Size); socketWrapper.Send(data); OnSocketSend?.Invoke("QueryRunStatus", data); } public void SetRunStatus(byte sta) // 1 Monitor; 2 Save; 3:Capture; 4:Process { var header = new PacketHeader() { token = 0x0101, channel = _channel, command = (byte)EPDCommand.SetRunStatus, length = 4 }; var data = new byte[PacketHeader.Size + 4]; Buffer.BlockCopy(ByteStructConverter.Struct2Bytes(header), 0, data, 0, PacketHeader.Size); Buffer.BlockCopy(new byte[] { sta, 0, 0, 0 }, 0, data, PacketHeader.Size, 4); socketWrapper.Send(data); OnSocketSend?.Invoke("QueryOperateMode", data); } public void QueryConfigList() { var header = new PacketHeader() { token = 0x0101, channel = _channel, command = (byte)EPDCommand.QueryCfgList, length = 0 }; var data = new byte[PacketHeader.Size]; Buffer.BlockCopy(ByteStructConverter.Struct2Bytes(header), 0, data, 0, PacketHeader.Size); socketWrapper.Send(data); OnSocketSend?.Invoke("QueryCfgList", data); } public void RecipeStart(int channel, string name) { var header = new PacketHeader() { token = 0x0101, channel = _channel, command = (byte)EPDCommand.RecipeStart, length = 0 }; var data = new byte[PacketHeader.Size]; Buffer.BlockCopy(ByteStructConverter.Struct2Bytes(header), 0, data, 0, PacketHeader.Size); socketWrapper.Send(data); OnSocketSend?.Invoke("RecipeStart", data); } public void RecipeStop(int channel) { var header = new PacketHeader() { token = 0x0101, channel = _channel, command = (byte)EPDCommand.RecipeStop, length = 0 }; var data = new byte[PacketHeader.Size]; Buffer.BlockCopy(ByteStructConverter.Struct2Bytes(header), 0, data, 0, PacketHeader.Size); socketWrapper.Send(data); OnSocketSend?.Invoke("RecipeStop", data); } public void Start(byte channel, string name) { var header = new PacketHeader() { token = 0x0101, channel = _channel, command = (byte)EPDCommand.Start, length = 256 }; var data = new byte[PacketHeader.Size + 256]; Buffer.BlockCopy(ByteStructConverter.Struct2Bytes(header), 0, data, 0, PacketHeader.Size); char[] chars = name.ToCharArray(); Encoding.UTF8.GetBytes(chars, 0, chars.Length, data, PacketHeader.Size); socketWrapper.Send(data); OnSocketSend?.Invoke("Start", data); } public void Stop(byte channel) { var header = new PacketHeader() { token = 0x0101, channel = _channel, command = (byte)EPDCommand.Stop, length = 0 }; var data = new byte[PacketHeader.Size]; Buffer.BlockCopy(ByteStructConverter.Struct2Bytes(header), 0, data, 0, PacketHeader.Size); socketWrapper.Send(data); OnSocketSend?.Invoke("Stop", data); } public void SetWaferInfo(WaferData wafer) { var header = new PacketHeader() { token = 0x0101, channel = _channel, command = (byte)EPDCommand.SetWaferInfo, length = WaferData.Size }; var data = new byte[PacketHeader.Size + WaferData.Size]; Buffer.BlockCopy(ByteStructConverter.Struct2Bytes(header), 0, data, 0, PacketHeader.Size); var buffer = ByteStructConverter.Struct2Bytes(wafer); Buffer.BlockCopy(buffer, 0, data, PacketHeader.Size, WaferData.Size); socketWrapper.Send(data); OnSocketSend?.Invoke("SetWaferInfo", data); } public void QueryCurrentConfig() { var header = new PacketHeader() { token = 0x0101, channel = _channel, command = (byte)EPDCommand.QueryCurrentConfig, length = 0 }; var data = new byte[PacketHeader.Size]; Buffer.BlockCopy(ByteStructConverter.Struct2Bytes(header), 0, data, 0, PacketHeader.Size); socketWrapper.Send(data); OnSocketSend?.Invoke("QueryCurrentConfig", data); } public void SetCurrentConfig(string content) { var header = new PacketHeader() { token = 0x0101, channel = _channel, command = (byte)EPDCommand.SetCurrentConfig, length = 256 }; var data = new byte[PacketHeader.Size + header.length]; Buffer.BlockCopy(ByteStructConverter.Struct2Bytes(header), 0, data, 0, PacketHeader.Size); char[] chars = content.ToCharArray(); Encoding.UTF8.GetBytes(chars, 0, chars.Length, data, PacketHeader.Size); socketWrapper.Send(data); OnSocketSend?.Invoke("SetCurrentConfig", data); } #region ASCII private int messageID = 3845; public void GetSensorStatus() { var ascii = new CytAsciiData(messageID++, 1, "H", Channel); var data = ascii.ToBytes(); socketWrapper.Send(data); OnSocketSend?.Invoke("GetSensorStatus", data); } public void GetRecipeList() { var ascii = new CytAsciiData(messageID++, 3, "H", Channel); var data = ascii.ToBytes(); socketWrapper.Send(data); OnSocketSend?.Invoke("GetRecipesList", data); } public void StartMeasurement(string recipe) { var ascii = new CytAsciiData(messageID++, 2, "H", Channel); ascii.Params = new List { recipe, "5", "Lot ID", "Cassette ID", "Techno ID" }; var data = ascii.ToBytes(); socketWrapper.Send(data); OnSocketSend?.Invoke("StartMeasurement", data); } public void StopMeasurement() { var ascii = new CytAsciiData(messageID++, 4, "H", Channel); ascii.Params = new List { "STOP" }; var data = ascii.ToBytes(); socketWrapper.Send(data); OnSocketSend?.Invoke("StopMeasurement", data); } #endregion public void QueryChannels(bool isAscii) { byte[] data; if (isAscii) { var ascii = new CytAsciiData(messageID++, 10, "H", ""); data = ascii.ToBytes(); } else { var header = new PacketHeader() { token = 0x0101, channel = 0, command = (byte)EPDCommand.QueryChannelCount, length = 0 }; data = new byte[PacketHeader.Size]; Buffer.BlockCopy(ByteStructConverter.Struct2Bytes(header), 0, data, 0, PacketHeader.Size); } socketWrapper.Send(data); OnSocketSend?.Invoke("QueryChannels", data); } } }