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
}
}