| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934 | using System;using System.Collections.Generic;using System.Text;using System.Threading;using PLC.Siemens.Communication;using PLC.Siemens.Protocol.Common;using PLC.Siemens.Protocol.Iso;using PLC.Siemens.Protocol.Negotiate;using PLC.Siemens.Protocol.ReadData;using PLC.Siemens.Protocol.Szl;using PLC.Siemens.ProtocolHandle;using PLC.Siemens.O;using System.Linq;namespace PLC.Siemens.O   {    public class SimenssPlc    {        public ConnectionType ConnectionType { get; private set; }        public ushort SrcRef { get; set; }        public ushort DstRef { get; set; }        public ushort SrcTSap { get; private set; }        public ushort DstTSap { get; private set; }        public ushort PduRequest { get; set; }        public int RecvTimeout { get; set; }        public int RemotePort { get; set; }        public int IsoPduSize { get; set; }        // ReSharper disable once InconsistentNaming        public string IP { get; private set; }        public bool Connected        {            get            {                if (_socket == null)                    return false;                return _socket.Connected;            }        }        private Action<PLC.Siemens.O.MessageEvent> _onMessageEvent;        private readonly IsoSocket _socket;        public SimenssPlc()        {            _socket = new IsoSocket();            PduRequest = 480;            IsoPduSize = 1024;            RecvTimeout = 3000;            RemotePort = 102;            SrcRef = 0x0001; // RFC0983 states that SrcRef and DetRef should be 0                             // and, in any case, they are ignored.                             // S7 instead requires a number != 0                             // Libnodave uses 0x0100                             // S7Manager uses 0x0D00                             // TIA Portal V12 uses 0x1D00                             // WinCC     uses 0x0300                             // Seems that every non zero value is good enough...            DstRef = 0x0000;            SrcTSap = 0x0100;            DstTSap = 0x0000; // It's filled by connection functions            ConnectionType = ConnectionType.PG;         }        public SimenssPlc(string ip, int rack, int slot)        {            _socket = new IsoSocket();            PduRequest = 480*2;            IsoPduSize = 1024;            RecvTimeout = 3000;            RemotePort = 102;            SrcRef = 0x0001; // RFC0983 states that SrcRef and DetRef should be 0                             // and, in any case, they are ignored.                             // S7 instead requires a number != 0                             // Libnodave uses 0x0100                             // S7Manager uses 0x0D00                             // TIA Portal V12 uses 0x1D00                             // WinCC     uses 0x0300                             // Seems that every non zero value is good enough...            DstRef = 0x0000;            SrcTSap = 0x0100;            DstTSap = 0x0000; // It's filled by connection functions            ConnectionType = ConnectionType.PG;            var remoteTsap = (ushort)(((ushort)ConnectionType << 8) + (rack * 0x20) + slot);            SetConnectionParams(ip, SrcTSap, remoteTsap);         }        #region 连接        public void RegisterMessageEvent(Action<MessageEvent> messageAction)        {            if (messageAction == null) throw new ArgumentNullException("messageAction");            _onMessageEvent = messageAction;        }        private void OnMessage(string method, string message)        {            if(_onMessageEvent!=null)                _onMessageEvent.Invoke(new MessageEvent(method, message));        }        public void SetConnectionType(ConnectionType connectionType)        {            ConnectionType = connectionType;        }        public void SetConnectionParams(string ip, ushort localTsap, ushort remoteTsap)        {            SrcTSap = localTsap;            DstTSap = remoteTsap;            IP = ip;        }        public bool ConnectTo(string ip, int rack, int slot)        {            var remoteTsap = (ushort)(((ushort)ConnectionType << 8) + (rack * 0x20) + slot);            SetConnectionParams(ip, SrcTSap, remoteTsap);            return Connect();        }        //暂时用系统SOCKET测试        private int _connecting;//连接中        private int _processing;//处理中        private string _processMehtod;        public bool Connect()        {            try            {                if (Interlocked.CompareExchange(ref _connecting, 1, 0) != 0)                    return false;                OnMessage("Connect", "正在连接");                if (!_socket.Connect(IP, 102))                    return false;                                 IsoControlPduHandle pduHandle = new IsoControlPduHandle()                {                    IsoPduSize = IsoPduSize,                    DstRef = DstRef,                    DstTSap = DstTSap,                    SrcRef = SrcRef,                    SrcTSap = SrcTSap                };                pduHandle.Handle(_socket);                if (pduHandle.ResultCode == ResultCode.OK)                {                    NegotiateHandle negotiateHandle = new NegotiateHandle() { PduRequest = PduRequest };                    negotiateHandle.Handle(_socket);                    if (negotiateHandle.ResultCode == ResultCode.OK)                    {                        PduRequest = negotiateHandle.Responses[0].Params.PduLength;                        return true;                    }                    else                    {                        OnMessage("Connect", "PDU握手失败");                    }                }                else                {                    OnMessage("Connect", "PDU握手失败");                }            }            catch (Exception ex)            {                OnMessage("Connect", ex.Message);            }            finally            {                Interlocked.CompareExchange(ref _connecting, 0, 1);            }            return false;        }        #endregion                public bool GetLock(string method)        {            if (Interlocked.CompareExchange(ref _processing, 1, 0) != 0)            {                OnMessage(method, "执行失败,{_processMehtod}处理正在执行中");                return false;            }            _processMehtod = method;            return true;        }        public bool ReleaseLock()        {            _processMehtod = "";            return Interlocked.CompareExchange(ref _processing, 0, 1) == 0;        }        #region [System Info functions]        private SzlResponse ReadSzlHelper(SzlCmd szlcmd)        {            SzlHandle handle = new SzlHandle { SzlCmd = szlcmd };            handle.Handle(_socket);            return handle.SzlResponseFirst;        }                public SzlResponse ReadSzl(SzlCmd szlcmd)        {            if (!GetLock("ReadSzl"))            {                return null;            }            try            {                SzlHandle handle = new SzlHandle { SzlCmd = szlcmd };                handle.Handle(_socket);                OnMessage("ReadSzl", "{handle.ResultCode}");                return handle.SzlResponseFirst;            }            catch (Exception ex)            {                OnMessage("ReadSzl", ex.Message);            }            finally            {                ReleaseLock();            }            return null;        }        public OrderInfo GetOrderCode()        {            OrderInfo orderCode = new OrderInfo();            if (!GetLock("GetOrderCode"))            {                return orderCode;            }            try            {                var aaaa = ReadSzlHelper(SzlInfo.OrderCode);                OnMessage("GetOrderCode", aaaa.Params.Err.ToString());                if (aaaa.Params.Err != ResultCode.OK)                    return orderCode;                orderCode.Code = Encoding.UTF8.GetString(aaaa.Data.Data, 2, 20);                orderCode.V1 = aaaa.Data.Data[aaaa.Data.Data.Length - 3];                orderCode.V2 = aaaa.Data.Data[aaaa.Data.Data.Length - 2];                orderCode.V3 = aaaa.Data.Data[aaaa.Data.Data.Length - 1];                return orderCode;            }            catch (Exception ex)            {                OnMessage("GetOrderCode", ex.Message);                return orderCode;            }            finally            {                ReleaseLock();            }        }        public CpuInfo GetCpuInfo()        {            CpuInfo cpuInfo = new CpuInfo();            if (!GetLock("GetCpuInfo"))                return cpuInfo;            try            {                var aaaa = ReadSzlHelper(SzlInfo.CpuInfo);                OnMessage("GetCpuInfo", aaaa.Params.Err.ToString());                if (aaaa.Params.Err != ResultCode.OK)                    return cpuInfo;                cpuInfo.ModuleTypeName = Encoding.UTF8.GetString(aaaa.Data.Data, 172, 32).TrimEnd('\0');                cpuInfo.SerialNumber = Encoding.UTF8.GetString(aaaa.Data.Data, 138, 24).TrimEnd('\0');                cpuInfo.AsName = Encoding.UTF8.GetString(aaaa.Data.Data, 2, 24).TrimEnd('\0');                cpuInfo.Copyright = Encoding.UTF8.GetString(aaaa.Data.Data, 104, 26).TrimEnd('\0');                cpuInfo.ModuleName = Encoding.UTF8.GetString(aaaa.Data.Data, 36, 24).TrimEnd('\0');            }            catch (Exception ex)            {                OnMessage("GetCpuInfo", ex.Message);            }            finally            {                ReleaseLock();            }            return cpuInfo;        }        public CpInfo GetCpInfo()        {            CpInfo info = new CpInfo();            if (!GetLock("GetCpuInfo"))                return info;            try            {                var aaaa = ReadSzlHelper(SzlInfo.CpInfo);                OnMessage("GetCpInfo", aaaa.Params.Err.ToString());                if (aaaa.Params.Err != ResultCode.OK)                    return info;                info.MaxPduLengt = DWordAt(aaaa.Data.Data, 2, 2);                //aaaa.ResDataFirst.Data[2] * 256 + aaaa.ResDataFirst.Data[3];                info.MaxConnections = DWordAt(aaaa.Data.Data, 4, 2);                // aaaa.ResDataFirst.Data[4] * 256 + aaaa.ResDataFirst.Data[5];                info.MaxMpiRate = DWordAt(aaaa.Data.Data, 6, 4);                //aaaa.ResDataFirst.Data[6] * 256 + aaaa.ResDataFirst.Data[7];                info.MaxBusRate = DWordAt(aaaa.Data.Data, 10, 4);                //aaaa.ResDataFirst.Data[10] * 256 + aaaa.ResDataFirst.Data[7];            }            catch (Exception ex)            {                OnMessage("GetCpInfo", ex.Message);            }            finally            {                ReleaseLock();            }            return info;        }        #endregion        private int DWordAt(byte[] buffer, int index, int length)        {            int value = 0;            for (int i = 0; i < length; i++)            {                value = (value << 8) + buffer[index + i];            }            return value;        }        #region [Date/Time functions]        public DateTime GetS7DateTime()        {            if (!GetLock("GetS7DateTime"))                return DateTime.MinValue;            try            {                GetDateTimeHandle handle = new GetDateTimeHandle();                handle.Handle(_socket);                OnMessage("GetS7DateTime", handle.ResultCode.ToString());                if (handle.ResultCode == ResultCode.OK)                {                    return handle.Response.GetDateTime();                }                else                {                    return DateTime.MinValue;                }            }            catch (Exception ex)            {                OnMessage("GetS7DateTime", ex.Message);                return DateTime.MinValue;            }            finally            {                ReleaseLock();            }        }        public bool SetS7DateTime(DateTime curDateTime)        {            if (!GetLock("SetS7DateTime"))                return false;            try            {                SetDateTimeHandle handle = new SetDateTimeHandle { DateTime = curDateTime };                handle.Handle(_socket);                OnMessage("SetS7DateTime", handle.ResultCode.ToString());                return handle.ResultCode == ResultCode.OKFF;            }            catch (Exception ex)            {                OnMessage("SetS7DateTime", ex.Message);                return false;            }            finally            {                ReleaseLock();            }        }        #endregion        #region [Control functions]        public S7CpuStatus GetPlcStatus()        {            S7CpuStatus status = S7CpuStatus.Unknown;            if (!GetLock("GetPlcStatus"))            {                return status;            }            try            {                SzlResponse first = ReadSzlHelper(SzlInfo.PlcStatus);                OnMessage("GetPlcStatus", first.Params.Err.ToString());                if (first.Params.Err == ResultCode.OK)                {                    status = (S7CpuStatus)first.Data.Data[3];                    if (status != S7CpuStatus.Run)                        status = S7CpuStatus.Stop;                }                return status;            }            catch (Exception ex)            {                OnMessage("GetPlcStatus", ex.Message);                return status;            }            finally            {                ReleaseLock();            }        }        public bool PlcStop()        {            if (!GetLock("PlcStop"))                return false;            try            {                var handle = new PlcStopHandle();                handle.Handle(_socket);                OnMessage("PlcStop", handle.ResultCode.ToString());                return handle.ResultCode == ResultCode.OK;            }            catch (Exception ex)            {                OnMessage("PlcStop", ex.Message);                return false;            }            finally            {                ReleaseLock();            }        }        public bool PlcHotStart()        {            if (!GetLock("PlcHotStart"))                return false;            try            {                var handle = new PlcHotStartHandle();                handle.Handle(_socket);                OnMessage("PlcHotStart", handle.ResultCode.ToString());                return handle.ResultCode == ResultCode.OK;            }            catch (Exception ex)            {                OnMessage("PlcHotStart", ex.Message);                return false;            }            finally            {                ReleaseLock();            }        }        public bool PlcColdStart()        {            if (!GetLock("PlcColdStart"))                return false;            try            {                var handle = new PlcColdStartHandle();                handle.Handle(_socket);                OnMessage("PlcColdStart", handle.ResultCode.ToString());                return handle.ResultCode == ResultCode.OK;            }            catch (Exception ex)            {                OnMessage("PlcColdStart", ex.Message);                return false;            }            finally            {                ReleaseLock();            }        }        public bool CopyRamToRom()        {            if (!GetLock("CopyRamToRom"))                return false;            try            {                var handle = new CopyRamToRomHandle();                handle.Handle(_socket);                OnMessage("CopyRamToRom", handle.ResultCode.ToString());                return handle.ResultCode == ResultCode.OK;            }            catch (Exception ex)            {                OnMessage("CopyRamToRom", ex.Message);                return false;            }            finally            {                ReleaseLock();            }        }        public bool Compress()        {            if (!GetLock("Compress"))                return false;            try            {                var handle = new CompressHandle();                handle.Handle(_socket);                OnMessage("Compress", handle.Response.Header.Error.ToString());                return handle.ResultCode == ResultCode.OK;            }            catch (Exception ex)            {                OnMessage("Compress", ex.Message);                return false;            }            finally            {                ReleaseLock();            }        }        #endregion        #region [Security functions]        public ProtectionInfo GetProtection()        {            ProtectionInfo info = new ProtectionInfo();            if (!GetLock("GetProtection"))            {                return info;            }            try            {                var sss = ReadSzlHelper(SzlInfo.Protection);                OnMessage("GetProtection", sss.Data.Ret.ToString());                if (sss.Params.Err != ResultCode.OK) return info;                info.SchSchal = (RWLevel)DWordAt(sss.Data.Data, 2, 2);                info.SchPar = (ProtectionLevel)DWordAt(sss.Data.Data, 4, 2);                info.SchRel = (CpuLevel)DWordAt(sss.Data.Data, 6, 2);                info.BartSch = (RunStatus)DWordAt(sss.Data.Data, 8, 2);                info.AnlSch = (StartupSwitch)DWordAt(sss.Data.Data, 10, 2);                return info;            }            catch (Exception ex)            {                OnMessage("GetProtection", ex.Message);                return info;            }            finally            {                ReleaseLock();            }        }        public bool SetPwd(string password)        {            if (!GetLock("SetPwd")) return false;            try            {                var handle = new SetPasswordHandle { Password = password };                handle.Handle(_socket);                OnMessage("SetPwd", handle.Response.Params.Err.ToString());                return handle.ResultCode == ResultCode.OK;            }            catch (Exception ex)            {                OnMessage("SetPwd", ex.Message);                return false;            }            finally            {                ReleaseLock();            }        }        public bool ClearPwd()        {            if (!GetLock("ClearPwd")) return false;            try            {                var handle = new SetPasswordHandle();                handle.Handle(_socket);                OnMessage("ClearPwd", handle.ResultCode.ToString());                return handle.ResultCode == ResultCode.OK;            }            catch (Exception ex)            {                OnMessage("ClearPwd", ex.Message);                return false;            }            finally            {                ReleaseLock();            }        }        #endregion        #region [Blocks]        public ListBlocksHandle ListBlocks()        {            if (!GetLock("ListBlocks")) return null;            try            {                var handle = new ListBlocksHandle();                handle.Handle(_socket);                OnMessage("ListBlocks", handle.ResultCode.ToString());                return handle;            }            catch (Exception ex)            {                OnMessage("ListBlocks", ex.Message);                return null;            }            finally            {                ReleaseLock();            }        }        public DataBlockOfTypeHandle ListBlocksOfType(BlockType blockType)        {            if (!GetLock("ListBlocksOfType")) return null;            try            {                var handle = new DataBlockOfTypeHandle();                handle.BlockType = blockType;                handle.Handle(_socket);                OnMessage("ListBlocksOfType", handle.ResultCode.ToString());                return handle;            }            catch (Exception ex)            {                OnMessage("ListBlocksOfType", ex.Message);                return null;            }            finally            {                ReleaseLock();            }        }        public DataBlockInfoHandle BlockInfoGet(ushort db, BlockType blockType)        {            if (!GetLock("BlockInfoHandle")) return null;            try            {                var handle = new DataBlockInfoHandle();                handle.BlockType = blockType;                handle.DB = db;                handle.Handle(_socket);                OnMessage("BlockInfoHandle", handle.ResultCode.ToString());                return handle;            }            catch (Exception ex)            {                OnMessage("BlockInfoHandle", ex.Message);                return null;            }            finally            {                ReleaseLock();            }        }        #endregion        object readlock = new object();        public DataItem ReadArea(AreaType area, ushort db, ushort start, ushort amount, DataType dataType)        {            lock (readlock)            {                if (!GetLock("ReadArea"))                {                    return null;                }                else                {                }                try                {                    var handle = new ReadHandle                    {                        PduLength = PduRequest,                        DataItem = new DataItem()                        {                            AreaType = area,                            Db = db,                            Start = start,                            Length = amount,                            DataType = dataType                        }                    };                    handle.Handle(_socket);                    OnMessage("ReadArea", handle.ResultCode.ToString());                    if (handle.ResultCode != ResultCode.OK)                    {                        throw new Exception(handle.ResultCode.ToString());                    }                    return handle.DataItem;                }                catch (Exception ex)                {                    OnMessage("ReadArea", ex.Message);                }                finally                {                    ReleaseLock();                }                return null;            }        }        public ReadMultiHandle ReadMulti(List<DataItem> items)        {            if (!GetLock("ReadMulti")) return null;            try            {                var handle = new ReadMultiHandle { DataItem = items };                handle.Handle(_socket);                OnMessage("ReadMulti", handle.ResultCode.ToString());                return handle;            }            catch (Exception ex)            {                OnMessage("ReadMulti", ex.Message);                return null;            }            finally            {                ReleaseLock();            }        }        public bool WriteArea(AreaType area, ushort db, ushort start, ushort amount, DataType dataType, byte[] writeData)        {            if (IP == "192.168.0.120" && db == 520)            {                if (start % 36 == 16)                {                    if (writeData.Max() == 0)                    {                    }                }                else if (start % 36 == 0)                {                    if (writeData.Length > 16)                    {                        if (writeData.Skip(16).Take(2).Max() == 0)                        {                        }                    }                    else                     {                                         }                }            }            if (!GetLock("WriteArea"))                return false;            try            {                var handle = new WriteHandle()                {                    PduLength = PduRequest,                    DataItem = new DataItem()                    {                        AreaType = area,                        Db = db,                        Start = start,                        Length = amount,                        DataType = dataType,                        Data = writeData                    }                };                OnMessage("WriteArea", handle.ResultCode.ToString());                handle.Handle(_socket);                return handle.ResultCode == ResultCode.OK|| handle.ResultCode == ResultCode.OKFF;            }            catch (Exception ex)            {                OnMessage("WriteArea", ex.Message);                return false;            }            finally            {                ReleaseLock();            }        }        public WriteMultiHandle WriteMulti(List<DataItem> items)        {            if (!GetLock("WriteMulti")) return null;            try            {                var handle = new WriteMultiHandle { DataItem = items };                handle.Handle(_socket);                OnMessage("WriteMulti", handle.ResultCode.ToString());                return handle;            }            catch (Exception ex)            {                OnMessage("WriteMulti", ex.Message);                return null;            }            finally            {                ReleaseLock();            }        }                // ReSharper disable once InconsistentNaming        public DataItem DBGet(ushort db)        {            //if (!GetLock("DBGet")) return null;            try            {                var handle = new DataBlockInfoHandle();                handle.BlockType = BlockType.DB;                handle.DB = db;                handle.Handle(_socket);                if (handle.ResultCode == ResultCode.OK)                {                    var res = ReadArea(AreaType.DB, handle.DB, 0, handle.Response.Data.Mc7Len, DataType.Byte);                    if (res.Err == ResultCode.OKFF)                    {                        return res;                    }                    OnMessage("DBGet", "ReadArea:{handle.ResultCode}");                }                else                    OnMessage("DBGet", "RequestBlock:{handle.ResultCode}");            }            catch (Exception ex)            {                OnMessage("DBGet", ex.Message);            }            //finally            //{            //    ReleaseLock();            //}            return null;        }        // ReSharper disable once InconsistentNaming        public bool DBFill(ushort db, byte value)        {            try            {                var handle = new DataBlockInfoHandle();                handle.BlockType = BlockType.DB;                handle.DB = db;                handle.Handle(_socket);                if (handle.ResultCode == ResultCode.OK)                {                    byte[] datas = new byte[handle.Response.Data.Mc7Len];                    for (int i = 0; i < handle.Response.Data.Mc7Len; i++)                    {                        datas[i] = value;                    }                    return WriteArea(AreaType.DB, handle.DB, 0, handle.Response.Data.Mc7Len, DataType.Byte, datas);                }                else                    OnMessage("DBFill", "RequestBlock:{handle.ResultCode}");                return false;            }            catch (Exception ex)            {                OnMessage("DBFill", ex.Message);                return false;            }            //finally            //{            //    ReleaseLock();            //}        }        public bool UpLoad(BlockType blockType, ushort db, bool isFull)        {            UploadStartHandle handle = new UploadStartHandle();            handle.BlockType = blockType;            handle.BlockNum = db;            handle.Handle(_socket);            if (handle.ResultCode != ResultCode.OK)                return false;            UploadHandle handle1 = new UploadHandle();            handle1.UploadID = handle.Response.Params.UploadID;            handle1.Handle(_socket);            return false;        }    }}
 |