using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Net.Sockets;

namespace BEMSDataGateway
{
    [StructLayout(LayoutKind.Sequential)]
    public struct SYSTEMTIME
    {
        [MarshalAs(UnmanagedType.U2)]
        public short Year;
        [MarshalAs(UnmanagedType.U2)]
        public short Month;
        [MarshalAs(UnmanagedType.U2)]
        public short DayOfWeek;
        [MarshalAs(UnmanagedType.U2)]
        public short Day;
        [MarshalAs(UnmanagedType.U2)]
        public short Hour;
        [MarshalAs(UnmanagedType.U2)]
        public short Minute;
        [MarshalAs(UnmanagedType.U2)]
        public short Second;
        [MarshalAs(UnmanagedType.U2)]
        public short Milliseconds;

        public SYSTEMTIME(DateTime dt)
        {
            dt = dt.ToUniversalTime();  // SetSystemTime expects the SYSTEMTIME in UTC
            Year = (short)dt.Year;
            Month = (short)dt.Month;
            DayOfWeek = (short)dt.DayOfWeek;
            Day = (short)dt.Day;
            Hour = (short)dt.Hour;
            Minute = (short)dt.Minute;
            Second = (short)dt.Second;
            Milliseconds = (short)dt.Millisecond;
        }
    }

    [StructLayout(LayoutKind.Explicit, Size = 4)]
    public struct ArrayData
    {
        [FieldOffset(0)]
        public byte digital;
        [FieldOffset(0)]
        public double analog;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct PointValue
    {
        [MarshalAs(UnmanagedType.I4)]
        public int nChannel;
        [MarshalAs(UnmanagedType.I4)]
        public int nController;
        [MarshalAs(UnmanagedType.I4)]
        public int nDataType;
        [MarshalAs(UnmanagedType.I4)]
        public int nPoint;
        [MarshalAs(UnmanagedType.I4)]
        public int nState;
        [MarshalAs(UnmanagedType.Struct, SizeConst = 4)]
        public ArrayData Values;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct PointText
    {
        [MarshalAs(UnmanagedType.I4)]
        public int nChannel;
        [MarshalAs(UnmanagedType.I4)]
        public int nController;
        [MarshalAs(UnmanagedType.I4)]
        public int nDataType;
        [MarshalAs(UnmanagedType.I4)]
        public int nPoint;
        [MarshalAs(UnmanagedType.I4)]
        public int nState;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
        public string szTextValue;
    }

    [StructLayout(LayoutKind.Explicit, Size = 256)]
    public struct MonitorData
    {
        [FieldOffset(0)]
        public byte digital;
        [FieldOffset(0)]
        public double analog;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct TagAddr
    {
        [MarshalAs(UnmanagedType.I4)]
        public int nChannel;
        [MarshalAs(UnmanagedType.I4)]
        public int nController;
        [MarshalAs(UnmanagedType.I4)]
        public int nDataType;
        [MarshalAs(UnmanagedType.I4)]
        public int nPoint;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct iCosLogInRequest
    {
        [MarshalAs(UnmanagedType.I4)]
        public int nLength;

        [MarshalAs(UnmanagedType.I4)]
        public int nType;

        [MarshalAs(UnmanagedType.I4)]
        public int nSubType;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
        public string szId;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
        public string szPassword;

        public byte[] Serialize()
        {
            var buffer = new byte[Marshal.SizeOf(typeof(iCosLogInRequest))];
            var gch = GCHandle.Alloc(buffer, GCHandleType.Pinned);
            var pBuffer = gch.AddrOfPinnedObject();
            Marshal.StructureToPtr(this, pBuffer, false);
            if (this.nType == 6)
            {
                if (this.nSubType == 1)
                {
                    LogFileCreate LFC = new LogFileCreate(); //로그 기록 파일
                    string str = "";
                    for (var i = 0; i < 24; i++)
                    {
                        if (i != 23)
                        {
                            str += ((byte[])gch.Target)[i] + " ";
                        }
                        else
                        {
                            str += ((byte[])gch.Target)[i];
                        }
                    }
                    LFC.Log("IcosPacket send: " + str + Environment.NewLine);
                }
            }
            gch.Free();
            return buffer;
        }

        public void Deserialize(ref byte[] data)
        {
            var gch = GCHandle.Alloc(data, GCHandleType.Pinned);
            this = (iCosLogInRequest)Marshal.PtrToStructure(gch.AddrOfPinnedObject(), typeof(iCosLogInRequest));
            gch.Free();
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct iCosLogInResponse
    {
        [MarshalAs(UnmanagedType.I4)]
        public int nLength;

        [MarshalAs(UnmanagedType.I4)]
        public int nType;

        [MarshalAs(UnmanagedType.I4)]
        public int nSubType;

        [MarshalAs(UnmanagedType.I4)]
        public int nResult;

        [MarshalAs(UnmanagedType.U4)]
        public UInt32 dwLevel;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
        public string szInitPage;

        public byte[] Serialize()
        {
            var buffer = new byte[Marshal.SizeOf(typeof(iCosLogInResponse))];
            var gch = GCHandle.Alloc(buffer, GCHandleType.Pinned);
            var pBuffer = gch.AddrOfPinnedObject();
            Marshal.StructureToPtr(this, pBuffer, false);
            gch.Free();
            return buffer;
        }

        public void Deserialize(byte[] data)
        {
            var gch = GCHandle.Alloc(data, GCHandleType.Pinned);
            this = (iCosLogInResponse)Marshal.PtrToStructure(gch.AddrOfPinnedObject(), typeof(iCosLogInResponse));
            if (this.nType == 6)
            {
                if (this.nSubType == 2)
                {
                    if (this.nResult != 3)
                    {
                        LogFileCreate LFC = new LogFileCreate(); //로그 기록 파일
                        string str = "";
                        for (var i = 0; i < 24; i++)
                        {
                            if (i != 23)
                            {
                                str += data[i] + " ";
                            }
                            else
                            {
                                str += data[i];
                            }
                        }
                        LFC.Log("IcosPacket receive: " + str + Environment.NewLine);
                    }
                }
            }
            gch.Free();
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct iCosMonitorRegTag
    {
        [MarshalAs(UnmanagedType.I4)]
        public int nLength;

        [MarshalAs(UnmanagedType.I4)]
        public int nType;

        [MarshalAs(UnmanagedType.I4)]
        public int nSubType;

        [MarshalAs(UnmanagedType.I4)]
        public int nChannel;

        [MarshalAs(UnmanagedType.I4)]
        public int nController;

        [MarshalAs(UnmanagedType.I4)]
        public int nDataType;

        [MarshalAs(UnmanagedType.I4)]
        public int nPoint;

        public byte[] Serialize()
        {
            var buffer = new byte[Marshal.SizeOf(typeof(iCosMonitorRegTag))];
            var gch = GCHandle.Alloc(buffer, GCHandleType.Pinned);
            var pBuffer = gch.AddrOfPinnedObject();
            Marshal.StructureToPtr(this, pBuffer, false);
            gch.Free();
            return buffer;
        }

        public void Deserialize(ref byte[] data)
        {
            var gch = GCHandle.Alloc(data, GCHandleType.Pinned);
            this = (iCosMonitorRegTag)Marshal.PtrToStructure(gch.AddrOfPinnedObject(), typeof(iCosMonitorRegTag));
            gch.Free();
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct iCosMonitorRegTagArray
    {
        [MarshalAs(UnmanagedType.I4)]
        public int nLength;

        [MarshalAs(UnmanagedType.I4)]
        public int nType;

        [MarshalAs(UnmanagedType.I4)]
        public int nSubType;

        [MarshalAs(UnmanagedType.I4)]
        public int nPntCnt;

        [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 50)]
        public TagAddr[] Tags;

        public byte[] Serialize()
        {
            var buffer = new byte[Marshal.SizeOf(typeof(iCosMonitorRegTagArray))];
            var gch = GCHandle.Alloc(buffer, GCHandleType.Pinned);
            var pBuffer = gch.AddrOfPinnedObject();
            Marshal.StructureToPtr(this, pBuffer, false);
            gch.Free();
            return buffer;
        }

        public void Deserialize(ref byte[] data)
        {
            var gch = GCHandle.Alloc(data, GCHandleType.Pinned);
            this = (iCosMonitorRegTagArray)Marshal.PtrToStructure(gch.AddrOfPinnedObject(), typeof(iCosMonitorRegTagArray));
            gch.Free();
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct iCosMonitorValue
    {
        [MarshalAs(UnmanagedType.I4)]
        public int nLength;

        [MarshalAs(UnmanagedType.I4)]
        public int nType;

        [MarshalAs(UnmanagedType.I4)]
        public int nSubType;

        [MarshalAs(UnmanagedType.I4)]
        public int nChannel;

        [MarshalAs(UnmanagedType.I4)]
        public int nController;

        [MarshalAs(UnmanagedType.I4)]
        public int nDataType;

        [MarshalAs(UnmanagedType.I4)]
        public int nPoint;

        [MarshalAs(UnmanagedType.I4)]
        public int nState;

        [MarshalAs(UnmanagedType.I4)]
        public int nReserved1;

        [MarshalAs(UnmanagedType.I4)]
        public int nReserved2;

        [MarshalAs(UnmanagedType.Struct, SizeConst = 256)]
        public MonitorData Values;

        public byte[] Serialize()
        {
            var buffer = new byte[Marshal.SizeOf(typeof(iCosMonitorValue))];
            var gch = GCHandle.Alloc(buffer, GCHandleType.Pinned);
            var pBuffer = gch.AddrOfPinnedObject();
            Marshal.StructureToPtr(this, pBuffer, false);
            gch.Free();
            return buffer;
        }

        public void Deserialize(byte[] data)
        {
            var gch = GCHandle.Alloc(data, GCHandleType.Pinned);
            this = (iCosMonitorValue)Marshal.PtrToStructure(gch.AddrOfPinnedObject(), typeof(iCosMonitorValue));
            gch.Free();
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct iCosMonitorText
    {
        [MarshalAs(UnmanagedType.I4)]
        public int nLength;

        [MarshalAs(UnmanagedType.I4)]
        public int nType;

        [MarshalAs(UnmanagedType.I4)]
        public int nSubType;

        [MarshalAs(UnmanagedType.I4)]
        public int nChannel;

        [MarshalAs(UnmanagedType.I4)]
        public int nController;

        [MarshalAs(UnmanagedType.I4)]
        public int nDataType;

        [MarshalAs(UnmanagedType.I4)]
        public int nPoint;

        [MarshalAs(UnmanagedType.I4)]
        public int nState;

        [MarshalAs(UnmanagedType.I4)]
        public int nReserved1;

        [MarshalAs(UnmanagedType.I4)]
        public int nReserved2;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
        public string szTextValue;

        public byte[] Serialize()
        {
            var buffer = new byte[Marshal.SizeOf(typeof(iCosMonitorText))];
            var gch = GCHandle.Alloc(buffer, GCHandleType.Pinned);
            var pBuffer = gch.AddrOfPinnedObject();
            Marshal.StructureToPtr(this, pBuffer, false);
            gch.Free();
            return buffer;
        }

        public void Deserialize(byte[] data)
        {
            var gch = GCHandle.Alloc(data, GCHandleType.Pinned);
            this = (iCosMonitorText)Marshal.PtrToStructure(gch.AddrOfPinnedObject(), typeof(iCosMonitorText));
            gch.Free();
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct iCosMonitorValueArray
    {
        [MarshalAs(UnmanagedType.I4)]
        public int nLength;

        [MarshalAs(UnmanagedType.I4)]
        public int nType;

        [MarshalAs(UnmanagedType.I4)]
        public int nSubType;

        [MarshalAs(UnmanagedType.I4)]
        public int nPntCnt;

        [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 50)]
        public PointValue[] Values;

        public byte[] Serialize()
        {
            var buffer = new byte[Marshal.SizeOf(typeof(iCosMonitorValueArray))];
            var gch = GCHandle.Alloc(buffer, GCHandleType.Pinned);
            var pBuffer = gch.AddrOfPinnedObject();
            Marshal.StructureToPtr(this, pBuffer, false);
            gch.Free();
            return buffer;
        }

        public void Deserialize(byte[] data)
        {
            var gch = GCHandle.Alloc(data, GCHandleType.Pinned);
            this = (iCosMonitorValueArray)Marshal.PtrToStructure(gch.AddrOfPinnedObject(), typeof(iCosMonitorValueArray));
            gch.Free();
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct iCosMonitorTextArray
    {
        [MarshalAs(UnmanagedType.I4)]
        public int nLength;

        [MarshalAs(UnmanagedType.I4)]
        public int nType;

        [MarshalAs(UnmanagedType.I4)]
        public int nSubType;

        [MarshalAs(UnmanagedType.I4)]
        public int nPntCnt;

        [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 5)]
        public PointText[] Values;

        public byte[] Serialize()
        {
            var buffer = new byte[Marshal.SizeOf(typeof(iCosMonitorTextArray))];
            var gch = GCHandle.Alloc(buffer, GCHandleType.Pinned);
            var pBuffer = gch.AddrOfPinnedObject();
            Marshal.StructureToPtr(this, pBuffer, false);
            gch.Free();
            return buffer;
        }

        public void Deserialize(byte[] data)
        {
            var gch = GCHandle.Alloc(data, GCHandleType.Pinned);
            this = (iCosMonitorTextArray)Marshal.PtrToStructure(gch.AddrOfPinnedObject(), typeof(iCosMonitorTextArray));
            gch.Free();
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct iCosMonitorNetStatus
    {
        [MarshalAs(UnmanagedType.I4)]
        public int nLength;

        [MarshalAs(UnmanagedType.I4)]
        public int nType;

        [MarshalAs(UnmanagedType.I4)]
        public int nSubType;

        [MarshalAs(UnmanagedType.I4)]
        public int nTotalCount;

        [MarshalAs(UnmanagedType.I4)]
        public int nConnectionCount;

        [MarshalAs(UnmanagedType.I4)]
        public int nIconId;

        public byte[] Serialize()
        {
            var buffer = new byte[Marshal.SizeOf(typeof(iCosMonitorNetStatus))];
            var gch = GCHandle.Alloc(buffer, GCHandleType.Pinned);
            var pBuffer = gch.AddrOfPinnedObject();
            Marshal.StructureToPtr(this, pBuffer, false);
            gch.Free();
            return buffer;
        }

        public void Deserialize(byte[] data)
        {
            var gch = GCHandle.Alloc(data, GCHandleType.Pinned);
            this = (iCosMonitorNetStatus)Marshal.PtrToStructure(gch.AddrOfPinnedObject(), typeof(iCosMonitorNetStatus));
            gch.Free();
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct iCosMonitorTimeSync
    {
        [MarshalAs(UnmanagedType.I4)]
        public int nLength;

        [MarshalAs(UnmanagedType.I4)]
        public int nType;

        [MarshalAs(UnmanagedType.I4)]
        public int nSubType;

        [MarshalAs(UnmanagedType.Struct, SizeConst = 16)]
        public SYSTEMTIME tmAck;

        public byte[] Serialize()
        {
            var buffer = new byte[Marshal.SizeOf(typeof(iCosMonitorTimeSync))];
            var gch = GCHandle.Alloc(buffer, GCHandleType.Pinned);
            var pBuffer = gch.AddrOfPinnedObject();
            Marshal.StructureToPtr(this, pBuffer, false);
            gch.Free();
            return buffer;
        }

        public void Deserialize(byte[] data)
        {
            var gch = GCHandle.Alloc(data, GCHandleType.Pinned);
            this = (iCosMonitorTimeSync)Marshal.PtrToStructure(gch.AddrOfPinnedObject(), typeof(iCosMonitorTimeSync));
            gch.Free();
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct iCosAlarmPointValue
    {
        [MarshalAs(UnmanagedType.I4)]
        public int nLength;

        [MarshalAs(UnmanagedType.I4)]
        public int nType;

        [MarshalAs(UnmanagedType.I4)]
        public int nSubType;

        [MarshalAs(UnmanagedType.I8)]
        public Int64 tmDateTime;

        [MarshalAs(UnmanagedType.I4)]
        public int nChannel;

        [MarshalAs(UnmanagedType.I4)]
        public int nController;

        [MarshalAs(UnmanagedType.I4)]
        public int nDataType;

        [MarshalAs(UnmanagedType.I4)]
        public int nPoint;

        [MarshalAs(UnmanagedType.U1)]
        public byte byAlarmLevel;

        [MarshalAs(UnmanagedType.U1)]
        public byte byStatus;

        [MarshalAs(UnmanagedType.U1)]
        public byte bySound;

        [MarshalAs(UnmanagedType.U1)]
        public byte byIsAck;

        [MarshalAs(UnmanagedType.R8)]
        public double fAlarmValue;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
        public string szSoundFile;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
        public string szAlarmMessage;

        public byte[] Serialize()
        {
            var buffer = new byte[Marshal.SizeOf(typeof(iCosAlarmPointValue))];
            var gch = GCHandle.Alloc(buffer, GCHandleType.Pinned);
            var pBuffer = gch.AddrOfPinnedObject();
            Marshal.StructureToPtr(this, pBuffer, false);
            gch.Free();
            return buffer;
        }

        public void Deserialize(byte[] data)
        {
            var gch = GCHandle.Alloc(data, GCHandleType.Pinned);
            this = (iCosAlarmPointValue)Marshal.PtrToStructure(gch.AddrOfPinnedObject(), typeof(iCosAlarmPointValue));
            gch.Free();
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct iCosAlarmPointAck
    {
        [MarshalAs(UnmanagedType.I4)]
        public int nLength;

        [MarshalAs(UnmanagedType.I4)]
        public int nType;

        [MarshalAs(UnmanagedType.I4)]
        public int nSubType;

        [MarshalAs(UnmanagedType.I4)]
        public int nChannel;

        [MarshalAs(UnmanagedType.I4)]
        public int nController;

        [MarshalAs(UnmanagedType.I4)]
        public int nDataType;

        [MarshalAs(UnmanagedType.I4)]
        public int nPoint;

        public byte[] Serialize()
        {
            var buffer = new byte[Marshal.SizeOf(typeof(iCosAlarmPointAck))];
            var gch = GCHandle.Alloc(buffer, GCHandleType.Pinned);
            var pBuffer = gch.AddrOfPinnedObject();
            Marshal.StructureToPtr(this, pBuffer, false);
            gch.Free();
            return buffer;
        }

        public void Deserialize(byte[] data)
        {
            var gch = GCHandle.Alloc(data, GCHandleType.Pinned);
            this = (iCosAlarmPointAck)Marshal.PtrToStructure(gch.AddrOfPinnedObject(), typeof(iCosAlarmPointAck));
            gch.Free();
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct iCosAlarmAckFromServer
    {
        [MarshalAs(UnmanagedType.I4)]
        public int nLength;

        [MarshalAs(UnmanagedType.I4)]
        public int nType;

        [MarshalAs(UnmanagedType.I4)]
        public int nSubType;

        [MarshalAs(UnmanagedType.Struct, SizeConst = 16)]
        public SYSTEMTIME tmAlarm;

        [MarshalAs(UnmanagedType.I4)]
        public int nChannel;

        [MarshalAs(UnmanagedType.I4)]
        public int nController;

        [MarshalAs(UnmanagedType.I4)]
        public int nDataType;

        [MarshalAs(UnmanagedType.I4)]
        public int nPoint;

        [MarshalAs(UnmanagedType.Struct, SizeConst = 16)]
        public SYSTEMTIME tmAck;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
        public string szAckUser;

        public byte[] Serialize()
        {
            var buffer = new byte[Marshal.SizeOf(typeof(iCosAlarmAckFromServer))];
            var gch = GCHandle.Alloc(buffer, GCHandleType.Pinned);
            var pBuffer = gch.AddrOfPinnedObject();
            Marshal.StructureToPtr(this, pBuffer, false);
            gch.Free();
            return buffer;
        }

        public void Deserialize(byte[] data)
        {
            var gch = GCHandle.Alloc(data, GCHandleType.Pinned);
            this = (iCosAlarmAckFromServer)Marshal.PtrToStructure(gch.AddrOfPinnedObject(), typeof(iCosAlarmAckFromServer));
            gch.Free();
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct iCosAlarmNotify
    {
        [MarshalAs(UnmanagedType.I4)]
        public int nLength;

        [MarshalAs(UnmanagedType.I4)]
        public int nType;

        [MarshalAs(UnmanagedType.I4)]
        public int nSubType;

        [MarshalAs(UnmanagedType.Struct, SizeConst = 16)]
        public SYSTEMTIME tmAck;

        [MarshalAs(UnmanagedType.Struct, SizeConst = 16)]
        public SYSTEMTIME tmDateTime;

        [MarshalAs(UnmanagedType.I4)]
        public int nChannel;

        [MarshalAs(UnmanagedType.I4)]
        public int nController;

        [MarshalAs(UnmanagedType.I4)]
        public int nDataType;

        [MarshalAs(UnmanagedType.I4)]
        public int nPoint;

        [MarshalAs(UnmanagedType.U1)]
        public byte byAlarmType;

        [MarshalAs(UnmanagedType.U1)]
        public byte byAlarmLevel;

        [MarshalAs(UnmanagedType.U1)]
        public byte byStatus;

        [MarshalAs(UnmanagedType.U1)]
        public byte bySound;

        [MarshalAs(UnmanagedType.U1)]
        public byte byIsClear;

        //public double fAlarmValue;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
        public byte[] byTemp;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
        public byte[] byVal;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
        public string szAckUser;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
        public string szAlarmMessage;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
        public string szSoundFile;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
        public string szAlarmScript;

        public byte[] Serialize()
        {
            var buffer = new byte[Marshal.SizeOf(typeof(iCosAlarmNotify))];
            var gch = GCHandle.Alloc(buffer, GCHandleType.Pinned);
            var pBuffer = gch.AddrOfPinnedObject();
            Marshal.StructureToPtr(this, pBuffer, false);
            gch.Free();
            return buffer;
        }

        public void Deserialize(byte[] data)
        {
            var gch = GCHandle.Alloc(data, GCHandleType.Pinned);
            this = (iCosAlarmNotify)Marshal.PtrToStructure(gch.AddrOfPinnedObject(), typeof(iCosAlarmNotify));
            gch.Free();
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct iCosAlarmSet
    {
        [MarshalAs(UnmanagedType.I4)]
        public int nLength;

        [MarshalAs(UnmanagedType.I4)]
        public int nType;

        [MarshalAs(UnmanagedType.I4)]
        public int nSubType;

        [MarshalAs(UnmanagedType.I4)]
        public int nChannel;

        [MarshalAs(UnmanagedType.I4)]
        public int nController;

        [MarshalAs(UnmanagedType.I4)]
        public int nDataType;

        [MarshalAs(UnmanagedType.I4)]
        public int nPoint;

        [MarshalAs(UnmanagedType.U1)]
        public byte byAlarmType;

        [MarshalAs(UnmanagedType.R8)]
        public double fAlarmValue;

        public byte[] Serialize()
        {
            var buffer = new byte[Marshal.SizeOf(typeof(iCosAlarmSet))];
            var gch = GCHandle.Alloc(buffer, GCHandleType.Pinned);
            var pBuffer = gch.AddrOfPinnedObject();
            Marshal.StructureToPtr(this, pBuffer, false);
            gch.Free();
            return buffer;
        }

        public void Deserialize(byte[] data)
        {
            var gch = GCHandle.Alloc(data, GCHandleType.Pinned);
            this = (iCosAlarmSet)Marshal.PtrToStructure(gch.AddrOfPinnedObject(), typeof(iCosAlarmSet));
            gch.Free();
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct iCosAlarmAckNotify
    {
        [MarshalAs(UnmanagedType.I4)]
        public int nLength;

        [MarshalAs(UnmanagedType.I4)]
        public int nType;

        [MarshalAs(UnmanagedType.I4)]
        public int nSubType;

        [MarshalAs(UnmanagedType.Struct, SizeConst = 16)]
        public SYSTEMTIME tmAlarm;

        [MarshalAs(UnmanagedType.I4)]
        public int nChannel;

        [MarshalAs(UnmanagedType.I4)]
        public int nController;

        [MarshalAs(UnmanagedType.I4)]
        public int nDataType;

        [MarshalAs(UnmanagedType.I4)]
        public int nPoint;

        [MarshalAs(UnmanagedType.Struct, SizeConst = 16)]
        public SYSTEMTIME tmAck;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
        public string szName;

        public byte[] Serialize()
        {
            var buffer = new byte[Marshal.SizeOf(typeof(iCosAlarmAckNotify))];
            var gch = GCHandle.Alloc(buffer, GCHandleType.Pinned);
            var pBuffer = gch.AddrOfPinnedObject();
            Marshal.StructureToPtr(this, pBuffer, false);
            gch.Free();
            return buffer;
        }

        public void Deserialize(byte[] data)
        {
            var gch = GCHandle.Alloc(data, GCHandleType.Pinned);
            this = (iCosAlarmAckNotify)Marshal.PtrToStructure(gch.AddrOfPinnedObject(), typeof(iCosAlarmAckNotify));
            gch.Free();
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct iCosAlarmDelete
    {
        [MarshalAs(UnmanagedType.I4)]
        public int nLength;

        [MarshalAs(UnmanagedType.I4)]
        public int nType;

        [MarshalAs(UnmanagedType.I4)]
        public int nSubType;

        [MarshalAs(UnmanagedType.Struct, SizeConst = 16)]
        public SYSTEMTIME tmAlarm;

        [MarshalAs(UnmanagedType.I4)]
        public int nChannel;

        [MarshalAs(UnmanagedType.I4)]
        public int nController;

        [MarshalAs(UnmanagedType.I4)]
        public int nDataType;

        [MarshalAs(UnmanagedType.I4)]
        public int nPoint;

        public byte[] Serialize()
        {
            var buffer = new byte[Marshal.SizeOf(typeof(iCosAlarmDelete))];
            var gch = GCHandle.Alloc(buffer, GCHandleType.Pinned);
            var pBuffer = gch.AddrOfPinnedObject();
            Marshal.StructureToPtr(this, pBuffer, false);
            gch.Free();
            return buffer;
        }

        public void Deserialize(byte[] data)
        {
            var gch = GCHandle.Alloc(data, GCHandleType.Pinned);
            this = (iCosAlarmDelete)Marshal.PtrToStructure(gch.AddrOfPinnedObject(), typeof(iCosAlarmDelete));
            gch.Free();
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    public struct iCosAlarmAllAck
    {
        [MarshalAs(UnmanagedType.I4)]
        public int nLength;

        [MarshalAs(UnmanagedType.I4)]
        public int nType;

        [MarshalAs(UnmanagedType.I4)]
        public int nSubType;

        [MarshalAs(UnmanagedType.Struct, SizeConst = 16)]
        public SYSTEMTIME tmAck;

        [MarshalAs(UnmanagedType.I4)]
        public int nUserLevel;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
        public string szAckUser;

        public byte[] Serialize()
        {
            var buffer = new byte[Marshal.SizeOf(typeof(iCosAlarmAllAck))];
            var gch = GCHandle.Alloc(buffer, GCHandleType.Pinned);
            var pBuffer = gch.AddrOfPinnedObject();
            Marshal.StructureToPtr(this, pBuffer, false);
            gch.Free();
            return buffer;
        }

        public void Deserialize(byte[] data)
        {
            var gch = GCHandle.Alloc(data, GCHandleType.Pinned);
            this = (iCosAlarmAllAck)Marshal.PtrToStructure(gch.AddrOfPinnedObject(), typeof(iCosAlarmAllAck));
            gch.Free();
        }
    }

    public class iCosTag
    {
        public int nChannel;
        public int nController;
        public int nDataType;
        public int nPoint;
        public int nState;
        public byte digital;
        public double analog;
        public string szText;
    }

    public class iCosTagIndex
    {
        public string szTag;
        public int nChannel;
        public int nController;
        public int nDataType;
        public int nPoint;
    }

    public class ClientData
    {
        public Socket clientSocket;
        public NetworkStream readStream;
        public string ipAddress;
        public int nPort;
        public string icosId;
        public string icosPassword;
        public List<string> RegTag = new List<string>();
    }
}