using SocketCommunication; using System; using System.Collections; using System.Globalization; using System.Runtime.InteropServices; using System.Text; using System.Threading; using log4net; using log4net.Appender; using log4net.Layout; using log4net.Repository.Hierarchy; using System.Collections.Generic; namespace SHARP_CLAS_UI { public class CIM_Server { #region Define [DllImport("kernel32.dll", SetLastError = true)] public static extern bool SetLocalTime(ref SYSTEMTIME st); [StructLayout(LayoutKind.Sequential)] public struct SYSTEMTIME { public short Year; public short Month; public short DayOfWeek; public short Day; public short Hour; public short Minute; public short Second; public short Milliseconds; } #endregion #region Logger /// /// Alarm Log /// private ILog Server_Log = LogManager.GetLogger("CIM_Server"); /// /// Alarm Log Write /// /// Method name of exception that occurred /// exception private void Write_Server_Log(string message) { if (Server_Log != null) Server_Log.Debug($"{message}"); } /// /// Create excepton logger /// private void Create_Server_logger() { Hierarchy hierarchy = (Hierarchy)LogManager.GetRepository(); RollingFileAppender rollingAppender = new RollingFileAppender(); PatternLayout layout = new PatternLayout(); hierarchy.Configured = true; rollingAppender.Name = "Server_RoolingFile"; rollingAppender.LockingModel = new RollingFileAppender.MinimalLock(); rollingAppender.File = $@"D:\Logger\Cim_Server\"; rollingAppender.AppendToFile = true; rollingAppender.DatePattern = "yyyy\\\\MM\\\\'Server'_dd'.csv'"; rollingAppender.RollingStyle = RollingFileAppender.RollingMode.Composite; rollingAppender.MaxSizeRollBackups = 10; rollingAppender.MaximumFileSize = "100MB"; rollingAppender.StaticLogFileName = false; rollingAppender.Encoding = Encoding.UTF8; rollingAppender.PreserveLogFileNameExtension = true; layout = new PatternLayout("%d{yyyy/MM/dd HH:mm:ss.fff},%m%n"); layout.ActivateOptions(); rollingAppender.Layout = layout; rollingAppender.ActivateOptions(); hierarchy.GetLogger("CIM_Server"); ILog log = LogManager.GetLogger("CIM_Server"); Logger l = (Logger)log.Logger; l.Level = log4net.Core.Level.Debug; l.AddAppender(rollingAppender); Server_Log = LogManager.GetLogger("CIM_Server"); } #endregion #region Property public bool isOpen { get { return server == null ? false : server.isOpen; } } public string Panel_ID { get; private set; } public string Tray_ID { get; private set; } #endregion #region Field Equipment _equip; private SocketServer server; private Queue commandlist; private StringBuilder received_data; private Thread communicationThread; public readonly int Port = 5571; private bool isclosed = false; public readonly string Servername = "CIM_Server"; private Dictionary Command_Acks = new Dictionary(); private Dictionary Command_Results = new Dictionary(); #endregion #region Construct public CIM_Server(Equipment _equip, int port = 5571) { this._equip = _equip; this.Port = port; server = new SocketServer(Servername, Port); commandlist = new Queue(); received_data = new StringBuilder(); received_data.Clear(); Create_Server_logger(); communicationThread = new Thread(Command_trigger); communicationThread.Start(); } #endregion #region Function public void Init_Server() { Close(); server = new SocketServer(Servername, Port); Open(); } public bool Open() { if (!server.Open()) { return false; } server.Add_received_event(Received); return true; } public void Close() { try { server.Close(); } catch(Exception) { } } public void Received(object sender, ReceiveEventArgs events) { received_data.Append(events.stateobject.Received_data.ToString()); Write_Server_Log($"[Receive Success] Client Handle : {events.stateobject.workSocket.Handle}, Client Connected : {events.stateobject.workSocket.Connected}, Data : {received_data.ToString().Replace("\r\n", "")}"); if (received_data.ToString().Contains("\r\n")) { string[] commands = received_data.ToString().Split(new string[] { "\r\n" }, StringSplitOptions.None); commandlist.Enqueue(new ReceivedCommand(events.stateobject.workSocket, commands[0])); received_data.Clear(); } } public void Command_trigger() { while (!_equip.IsDisposed) { try { Thread.Sleep(10); if (commandlist.Count > 0) { ReceivedCommand revceivedcommand = (ReceivedCommand)commandlist.Dequeue(); string command = revceivedcommand.command; string[] recv_data = command.Split(','); if (recv_data.Length < 3) { Write_Server_Log($"The server command format is different. command : {command}"); throw new Exception($"The server command format is different. command : {command}"); } string SequenceNo = recv_data[0]; string Command = recv_data[1]; string Control = recv_data[2]; string[] datas = new string[recv_data.Length - 3]; for (int i = 3; i < recv_data.Length; i++) { datas[i - 3] += recv_data[i]; } En_Cim_Command cim_command; if (!Enum.TryParse(Command, out cim_command)) { Write_Server_Log($"The Command({Command}) is not exist"); throw new Exception($"The Command({Command}) is not exist"); } switch (cim_command) { case En_Cim_Command.ONLCK: { if (datas[0] == "ONL") { Set_Command_Result(En_Cim_Command.ONLCK, true); SendCommand(revceivedcommand.Requester, $"{SequenceNo},{Command},ACK,0"); } else { Set_Command_Result(En_Cim_Command.ONLCK, false); SendCommand(revceivedcommand.Requester, $"{SequenceNo},{Command},ACK,1"); } Set_Command_Ack(En_Cim_Command.ONLCK, true); break; } case En_Cim_Command.TMSET: { DateTime dt = new DateTime(); if (DateTime.TryParseExact(datas[0], "yyyyMMddHHmmssff", CultureInfo.InvariantCulture, DateTimeStyles.None, out dt)) { SYSTEMTIME st = new SYSTEMTIME(); st.Year = (short)dt.Year; st.Month = (short)dt.Month; st.Day = (short)dt.Day; st.Hour = (short)dt.Hour; st.Minute = (short)dt.Minute; st.Second = (short)dt.Second; st.Milliseconds = (short)dt.Millisecond; if(SetLocalTime(ref st)) { _equip.cim_server.Set_Command_Result(En_Cim_Command.ONLCK, false); SendCommand(revceivedcommand.Requester, $"{SequenceNo},{Command},ACK,0"); } else { _equip.cim_server.Set_Command_Result(En_Cim_Command.ONLCK, true); SendCommand(revceivedcommand.Requester, $"{SequenceNo},{Command},ACK,1"); } } else { _equip.cim_server.Set_Command_Result(En_Cim_Command.ONLCK, true); SendCommand(revceivedcommand.Requester, $"{SequenceNo},{Command},ACK,1"); } _equip.cim_server.Set_Command_Ack(En_Cim_Command.ONLCK, true); break; } case En_Cim_Command.INCRT: { string panel_id = datas[0]; bool check = datas[1] == "0" ? true : false; string rank_code = datas[2]; Panel_ID = panel_id; _equip.cim_server.Set_Command_Result(En_Cim_Command.INCRT, check); SendCommand(revceivedcommand.Requester, $"{SequenceNo},{Command},ACK,0"); _equip.cim_server.Set_Command_Ack(En_Cim_Command.INCRT, true); break; } case En_Cim_Command.TINRT: { string tray_id = datas[0]; bool check = datas[1] == "0" ? true : false; int tray_count = int.Parse(datas[2]); int module_mismatch_count = int.Parse(datas[3]); int pre_process_ng_count = int.Parse(datas[4]); Tray_ID = tray_id; _equip.cim_server.Set_Command_Result(En_Cim_Command.TINRT, check); SendCommand(revceivedcommand.Requester, $"{SequenceNo},{Command},ACK,0"); _equip.cim_server.Set_Command_Ack(En_Cim_Command.TINRT, true); break; } case En_Cim_Command.ERTQK: { int stop_level = int.Parse(datas[0]); if(stop_level == 0) { Alarm_Manager.Instance.Occurred(En_Alarm_List.AL_0900_EARTHQUAKE_LEVEL_0); } else if(stop_level == 1) { Alarm_Manager.Instance.Occurred(En_Alarm_List.AL_0901_EARTHQUAKE_LEVEL_1); } else if(stop_level == 2) { Alarm_Manager.Instance.Occurred(En_Alarm_List.AL_0902_EARTHQUAKE_LEVEL_2); } _equip.cim_server.Set_Command_Result(En_Cim_Command.ERTQK, true); SendCommand(revceivedcommand.Requester, $"{SequenceNo},{Command},ACK,0"); _equip.cim_server.Set_Command_Ack(En_Cim_Command.ERTQK, true); _equip.cim_client.Send_Earthquake_Stop(SequenceNo); break; } default: { break; } } } } catch (Exception ex) { Write_Server_Log("[Send Fail]," + ex.Message); } } } public bool SendCommand(System.Net.Sockets.Socket client, string command) { try { if (server.SendData(client, $"{command}\r\n")) { Write_Server_Log($"[Send Success] Client Handle : {client.Handle}, Client Connected : {client.Connected}, Data : {command.ToString()}"); return true; } else { Write_Server_Log($"[Send Fail] Client Handle : {client.Handle}, Client Connected : {client.Connected}, Data : {command.ToString()}"); throw new Exception("Client socket send is fail."); } } catch (Exception ex) { return false; } } public bool SendCommand(string clientname, string command, string data = "") { try { if (server.Client_Exist(clientname)) { server.SendData(clientname, $"{command}"); return true; } else throw new Exception($"Client {clientname} does not exist."); } catch (Exception ex) { Write_Server_Log("[Send Fail]," + ex.Message); return false; } } public void Set_Command_Ack(En_Cim_Command command, bool value) { Command_Acks[command] = value; } public bool Get_Command_Ack(En_Cim_Command command) { return Command_Acks[command]; } public void Set_Command_Result(En_Cim_Command command, bool value) { Command_Results[command] = value; } public bool Get_Command_Result(En_Cim_Command command) { return Command_Results[command]; } #endregion } }