예제 #1
0
        private void SendData(S7OexchangeBlock data)
        {
            if (!Disposed)
            {
                int    len    = Marshal.SizeOf(data);
                byte[] buffer = new byte[len];

                data.headerlength = 80; //Length of the Header (always 80)  (but the 4 first unkown bytes are not count)
                data.rb_type      = 2;  //rb_type is always 2
                data.offset_1     = 80; //Offset of the Begin of userdata (but the 4 first unkown bytes are not count)

                IntPtr ptr = Marshal.AllocHGlobal(len);
                Marshal.StructureToPtr(data, ptr, true);
                Marshal.Copy(ptr, buffer, 0, len);
                Marshal.FreeHGlobal(ptr);

                int ret = SCP_send(_connectionHandle, (ushort)(data.seg_length_1 + data.headerlength), buffer);
                if (ret < 0)
                {
                    throw new S7OnlineException(SCP_get_errno());
                }
            }
            else
            {
                throw new ObjectDisposedException(this.ToString());
            }
        }
        private void DisconnectPlcsimStatemachine()
        {
            switch (m_PlcsimConnectionState)
            {
            case PlcsimConnectionState.DisconnectState1:
                S7OexchangeBlock fdr = new S7OexchangeBlock();
                fdr = GetNewS7OexchangeBlock(user: 0, rb_type: 2, subsystem: 0x40, opcode: 12, response: 0xffff);
                fdr.fill_length_1               = 0;
                fdr.seg_length_1                = 0;
                fdr.offset_1                    = 80;
                fdr.application_block_opcode    = m_application_block_opcode;
                fdr.application_block_subsystem = m_application_block_subsystem;

                SendS7OExchangeBlockToPlcsim(fdr);
                // Simatic applications use a two-step disconnect, but this sometimes makes problems.
                // So don't use it anymore, works also without this.
                //
                //m_PlcsimConnectionState = PlcsimConnectionState.DisconnectState2;
                //break;
                //case PlcsimConnectionState.DisconnectState2:
                //rec = ReceiveFromPlcsimDirect();
                //if (rec.opcode == 0x0c && rec.response == 0x0001)
                //{
                //    m_PlcsimConnectionState = PlcsimConnectionState.NotConnected;
                //    ExitThisThread();
                //}
                m_PlcsimConnectionState = PlcsimConnectionState.NotConnected;
                ExitThisThread();
                break;
            }
        }
예제 #3
0
        public S7OnlineInterface(string EntryPoint)
        {
            _entryPoint = EntryPoint;

            _connectionHandle = SCP_open(_entryPoint);

            if (_connectionHandle < 0)
            {
                this.Dispose();
                throw new S7OnlineException(SCP_get_errno());
            }

            S7OexchangeBlock fdr = new S7OexchangeBlock();


            formBackgroundThread = new Thread(new ThreadStart(createFormInOtherThread));
            formBackgroundThread.IsBackground = true;
            formBackgroundThread.Start();

            //_myForm = new _intForm(_connectionHandle, Marshal.SizeOf(fdr), this);
            //SetSinecHWndMsg(_connectionHandle, _myForm.Handle, WM_SINEC);
            while (!WndProcReady)
            {
            }
        }
예제 #4
0
        public void DisconnectPlc(Connection conn)
        {
            conn.ConnectionEstablished = false;
            S7OexchangeBlock fdr;

            if (conn.ConnectionConfig.ConnectionToEthernet)
            {
                fdr           = new S7OexchangeBlock();
                fdr.user      = (ushort)conn.ConnectionNumber;
                fdr.subsystem = 64;
                fdr.opcode    = 8;
                fdr.response  = 255;
                fdr.application_block_opcode = conn.application_block_opcode;
                SendData(fdr);
                RecieveData((ushort)conn.ConnectionNumber);
            }

            fdr           = new S7OexchangeBlock();
            fdr.user      = (ushort)conn.ConnectionNumber;
            fdr.subsystem = 64;
            fdr.opcode    = 0xC;
            fdr.response  = 255;
            fdr.application_block_service   = 0x8000;
            fdr.application_block_opcode    = conn.application_block_opcode;
            fdr.application_block_subsystem = conn.application_block_subsystem;
            SendData(fdr);
            RecieveData((ushort)conn.ConnectionNumber);

            ConnectionsList.Remove(conn.ConnectionNumber);
        }
예제 #5
0
            protected override void WndProc(ref Message m)
            {
                if (m.Msg == WM_SINEC) //WM_SINEC Message recieved, recieve Data
                {
                    int[]  rec_len = new int[1];
                    byte[] buffer  = new byte[fdrlen];
                    SCP_receive(_connectionHandle, 0, rec_len, (ushort)fdrlen, buffer);

                    GCHandle         handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
                    S7OexchangeBlock rec    = (S7OexchangeBlock)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(S7OexchangeBlock));
                    handle.Free();

                    if (Interface.ConnectionsList[rec.user].ConnectionEstablished)
                    {
                        Interface.ConnectionsList[rec.user].SetRecievedPdu(new Pdu(rec.user_data_1));
                    }
                    else
                    {
                        Interface.ConnectionsList[rec.user].RecievedData = rec;
                    }
                }
                else
                {
                    base.WndProc(ref m);
                }
            }
예제 #6
0
        protected void DumpS7OexchangeBlock(S7OexchangeBlock fd)
        {
            string dump;

            dump  = ("******************** S7OexchangeBlock **********************************" + Environment.NewLine);
            dump += ("** Header Start **" + Environment.NewLine);
            //dump += ("unknown      : 0x" + String.Format("{0:X02}", fd.unknown[0] + fd.unknown[1] + Environment.NewLine);
            dump += ("headerlength : " + fd.headerlength + Environment.NewLine);
            dump += ("user         : 0x" + String.Format("{0:X02}", fd.user) + Environment.NewLine);
            dump += ("rb_type      : 0x" + String.Format("{0:X02}", fd.rb_type) + Environment.NewLine);
            dump += ("priority     : 0x" + String.Format("{0:X02}", fd.priority) + Environment.NewLine);
            dump += ("reserved_1   : 0x" + String.Format("{0:X02}", fd.reserved_1) + Environment.NewLine);
            dump += ("reserved_2   : 0x" + String.Format("{0:X02}", fd.reserved_2) + Environment.NewLine);
            dump += ("subsystem    : 0x" + String.Format("{0:X02}", fd.subsystem) + Environment.NewLine);
            dump += ("opcode       : 0x" + String.Format("{0:X02}", fd.opcode) + Environment.NewLine);
            dump += ("response     : 0x" + String.Format("{0:X02}", fd.response) + Environment.NewLine);
            dump += ("fill_length_1: 0x" + String.Format("{0:X02}", fd.fill_length_1) + Environment.NewLine);
            dump += ("reserved_3   : 0x" + String.Format("{0:X02}", fd.reserved_3) + Environment.NewLine);
            dump += ("seg_length_1 : 0x" + String.Format("{0:X02}", fd.seg_length_1) + Environment.NewLine);
            dump += ("offset_1     : 0x" + String.Format("{0:X02}", fd.offset_1) + Environment.NewLine);
            dump += ("reserved_4   : 0x" + String.Format("{0:X02}", fd.reserved_4) + Environment.NewLine);
            dump += ("fill_length_2: 0x" + String.Format("{0:X02}", fd.fill_length_2) + Environment.NewLine);
            dump += ("reserved_5   : 0x" + String.Format("{0:X02}", fd.reserved_5) + Environment.NewLine);
            dump += ("seg_length_2 : 0x" + String.Format("{0:X02}", fd.seg_length_2) + Environment.NewLine);
            dump += ("offset_2     : 0x" + String.Format("{0:X02}", fd.offset_2) + Environment.NewLine);
            dump += ("reserved_6   : 0x" + String.Format("{0:X02}", fd.reserved_6) + Environment.NewLine);
            dump += ("** End of Header **" + Environment.NewLine);

            dump += ("** Start of application Block **" + Environment.NewLine);
            dump += ("application_block_opcode                 : 0x" + String.Format("{0:X02}", fd.application_block_opcode) + Environment.NewLine);
            dump += ("application_block_subsystem              : 0x" + String.Format("{0:X02}", fd.application_block_subsystem) + Environment.NewLine);
            dump += ("application_block_id                     : 0x" + String.Format("{0:X02}", fd.application_block_id) + Environment.NewLine);
            dump += ("application_block_service                : 0x" + String.Format("{0:X02}", fd.application_block_service) + Environment.NewLine);
            dump += ("application_block_local_address_station  : 0x" + String.Format("{0:X02}", fd.application_block_local_address_station) + Environment.NewLine);
            dump += ("application_block_local_address_segment  : 0x" + String.Format("{0:X02}", fd.application_block_local_address_segment) + Environment.NewLine);
            dump += ("application_block_ssap                   : 0x" + String.Format("{0:X02}", fd.application_block_ssap) + Environment.NewLine);
            dump += ("application_block_dsap                   : 0x" + String.Format("{0:X02}", fd.application_block_dsap) + Environment.NewLine);
            dump += ("application_block_remote_address_station : 0x" + String.Format("{0:X02}", fd.application_block_remote_address_station) + Environment.NewLine);
            dump += ("application_block_remote_address_segment : 0x" + String.Format("{0:X02}", fd.application_block_remote_address_segment) + Environment.NewLine);
            dump += ("application_block_service_class          : 0x" + String.Format("{0:X02}", fd.application_block_service_class) + Environment.NewLine);
            dump += ("application_block_receive_l_sdu_length   : 0x" + String.Format("{0:X02}", fd.application_block_receive_l_sdu_length) + Environment.NewLine);
            dump += ("application_block_reserved_1             : 0x" + String.Format("{0:X02}", fd.application_block_reserved_1) + Environment.NewLine);
            dump += ("application_block_reserved               : 0x" + String.Format("{0:X02}", fd.application_block_reserved) + Environment.NewLine);
            dump += ("application_block_send_l_sdu_length      : 0x" + String.Format("{0:X02}", fd.application_block_send_l_sdu_length) + Environment.NewLine);
            dump += ("application_block_l_status               : 0x" + String.Format("{0:X02}", fd.application_block_l_status) + Environment.NewLine);
            dump += ("** End of application Block **" + Environment.NewLine);
            dump += ("** Start user_data_1 **" + Environment.NewLine);
            if (fd.user_data_1 != null)
            {
                dump += HexDumping.Utils.HexDump(fd.user_data_1, fd.user_data_1.Length);
            }
            dump += ("** End user_data_1 **" + Environment.NewLine);
            dump += ("**************************************************************");

            DoTrace(dump, false);
        }
예제 #7
0
        private S7OexchangeBlock RecieveData(ushort myConnNr)
        {
            while (ConnectionsList[myConnNr].RecievedData == null)
            {
            }

            S7OexchangeBlock rec = (S7OexchangeBlock)ConnectionsList[myConnNr].RecievedData;

            ConnectionsList[myConnNr].RecievedData = null;

            return(rec);
        }
예제 #8
0
        protected S7OexchangeBlock GetNewS7OexchangeBlock(ushort user, byte rb_type, byte subsystem, byte opcode, ushort response)
        {
            S7OexchangeBlock block = new S7OexchangeBlock();

            block.headerlength = 80;
            block.user         = user;
            block.rb_type      = rb_type;
            block.subsystem    = subsystem;
            block.opcode       = opcode;
            block.response     = response;

            return(block);
        }
예제 #9
0
 private void createFormInOtherThread()
 {
     try
     {
         S7OexchangeBlock fdr = new S7OexchangeBlock();
         _myForm = new _intForm(_connectionHandle, Marshal.SizeOf(fdr), this);
         SetSinecHWndMsg(_connectionHandle, _myForm.Handle, WM_SINEC);
         WndProcReady = true;
         Application.Run();
     }
     catch (ThreadAbortException)
     { }
 }
        private void ReceiveFromPlcsimAndSendBack()
        {
            int[]  rec_len = new int[1];
            byte[] buffer  = new byte[m_FdrLen];

            if (SCP_receive(m_connectionHandle, 0, rec_len, (ushort)m_FdrLen, buffer) == -1)
            {
                if (m_connectionHandle > 0)
                {
                    if (m_PlcsimConnectionState == PlcsimConnectionState.ConnectState1 ||
                        m_PlcsimConnectionState == PlcsimConnectionState.ConnectState2 ||
                        m_PlcsimConnectionState == PlcsimConnectionState.ConnectState3)
                    {
                        SendConnectErrorMessage("ERROR: Connect failed in SCP_receive at " + m_PlcsimConnectionState.ToString());
                    }
                    else
                    {
                        int    errno  = SCP_get_errno();
                        string errtxt = GetErrTxt(errno);
                        SendErrorMessage("ERROR: SCP_receive() failed. m_connectionHandle = " + m_connectionHandle + " SCP_get_errno=" + errno + " (" + errtxt + ")");
                    }
                }
                ExitThisThread();
                return;
            }

            GCHandle         handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
            S7OexchangeBlock rec    = (S7OexchangeBlock)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(S7OexchangeBlock));

            handle.Free();

            if (rec.opcode == 6 && rec.response == 1)
            {
                // don't care
            }
            else if (rec.opcode == 7 && rec.response == 3)
            {
                byte[] recbytes = new byte[rec.fill_length_1];
                Array.Copy(rec.user_data_1, recbytes, rec.fill_length_1);
                SendPduMessage(recbytes);

                S7OexchangeBlock snd = GetNewS7OexchangeBlock(user: 0, rb_type: 2, subsystem: 0x40, opcode: 7, response: 0xffff);
                snd.offset_1                    = 80;
                snd.fill_length_1               = 0;
                snd.seg_length_1                = SEG_LENGTH_1;
                snd.application_block_opcode    = rec.application_block_opcode;
                snd.application_block_subsystem = rec.application_block_subsystem;

                SendS7OExchangeBlockToPlcsim(snd);
            }
        }
예제 #11
0
        protected S7OexchangeBlock ReceiveFromPlcsimDirect()
        {
            S7OexchangeBlock rec = new S7OexchangeBlock();

            int[] rec_len = new int[1];
            int   len     = Marshal.SizeOf(rec);

            byte[] buffer = new byte[len];

            if (SCP_receive(m_connectionHandle, 0, rec_len, (ushort)len, buffer) == 0)
            {
                GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
                rec = (S7OexchangeBlock)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(S7OexchangeBlock));
                handle.Free();
            }
            return(rec);
        }
예제 #12
0
        public void SendPdu(Pdu pdu, Connection connection)
        {
            if (!Disposed)
            {
                byte[] pdubytes = pdu.ToBytes();

                S7OexchangeBlock fdr = new S7OexchangeBlock();

                fdr.user                     = (ushort)connection.ConnectionNumber;
                fdr.subsystem                = 64;
                fdr.opcode                   = 6;
                fdr.response                 = 255;
                fdr.fill_length_1            = (byte)pdubytes.Length;
                fdr.seg_length_1             = (byte)pdubytes.Length;
                fdr.application_block_opcode = connection.application_block_opcode;
                //if (!connection.ConnectionConfig.ConnectionToEthernet)
                fdr.application_block_subsystem = connection.application_block_subsystem;


                fdr.headerlength = 80; //Length of the Header (always 80)  (but the 4 first unkown bytes are not count)
                fdr.rb_type      = 2;  //rb_type is always 2
                fdr.offset_1     = 80; //Offset of the Begin of userdata (but the 4 first unkown bytes are not count)

                fdr.user_data_1 = new byte[260];
                Array.Copy(pdubytes, fdr.user_data_1, pdubytes.Length);

                int    len    = Marshal.SizeOf(fdr);
                byte[] buffer = new byte[len];
                IntPtr ptr    = Marshal.AllocHGlobal(len);
                Marshal.StructureToPtr(fdr, ptr, true);
                Marshal.Copy(ptr, buffer, 0, len);
                Marshal.FreeHGlobal(ptr);

                int ret = SCP_send(_connectionHandle, (ushort)(fdr.seg_length_1 + fdr.headerlength), buffer);
                if (ret < 0)
                {
                    throw new S7OnlineException(SCP_get_errno());
                }
            }
            else
            {
                throw new ObjectDisposedException(this.ToString());
            }
        }
예제 #13
0
        public PlcS7onlineMsgPump(IPAddress plc_ipaddress, int rack, int slot)
        {
            m_PlcIPAddress          = plc_ipaddress;
            m_PlcRack               = rack;
            m_PlcSlot               = slot;
            m_connectionHandle      = -1;
            m_user                  = 1;
            m_PlcsimConnectionState = PlcsimConnectionState.NotConnected;

            S7OexchangeBlock fdr = new S7OexchangeBlock();

            m_FdrLen = Marshal.SizeOf(fdr);

            m_TraceEnabled = false;
            if (m_TraceEnabled)
            {
                Trace.Listeners.Add(new TextWriterTraceListener("PlcsimS7online.log"));
                DoTrace("Start trace...");
            }
        }
예제 #14
0
        private void SendDataToPlcsim(WndProcMessage msg)
        {
            if (++m_user >= 32000)
            {
                m_user = 1;
            }
            S7OexchangeBlock snd = GetNewS7OexchangeBlock(user: m_user, rb_type: 2, subsystem: 0x40, opcode: 6, response: 0xff);

            snd.offset_1 = 80;

            snd.application_block_opcode    = m_application_block_opcode;
            snd.application_block_subsystem = m_application_block_subsystem;

            snd.fill_length_1 = (ushort)msg.pdu.Length;
            snd.seg_length_1  = (ushort)msg.pdu.Length;

            snd.user_data_1 = new byte[SIZE_OF_USER_DATA_1];
            Array.Copy(msg.pdu, snd.user_data_1, msg.pdu.Length);

            SendS7OExchangeBlockToPlcsim(snd);
        }
예제 #15
0
        private void GetResponsePdu(Connection connection)
        {
            if (!Disposed)
            {
                S7OexchangeBlock fdr = new S7OexchangeBlock();

                fdr.user      = (ushort)connection.ConnectionNumber;
                fdr.subsystem = 64;
                fdr.opcode    = 7;

                fdr.seg_length_1 = 480;
                fdr.response     = 16642;

                fdr.application_block_opcode    = connection.application_block_opcode;
                fdr.application_block_subsystem = connection.application_block_subsystem;

                fdr.headerlength = 80; //Length of the Header (always 80)  (but the 4 first unkown bytes are not count)
                fdr.rb_type      = 2;  //rb_type is always 2
                fdr.offset_1     = 80; //Offset of the Begin of userdata (but the 4 first unkown bytes are not count)

                fdr.user_data_1 = new byte[260];

                int    len    = Marshal.SizeOf(fdr);
                byte[] buffer = new byte[len];
                IntPtr ptr    = Marshal.AllocHGlobal(len);
                Marshal.StructureToPtr(fdr, ptr, true);
                Marshal.Copy(ptr, buffer, 0, len);
                Marshal.FreeHGlobal(ptr);

                int ret = SCP_send(_connectionHandle, (ushort)(fdr.seg_length_1 + fdr.headerlength), buffer);
                if (ret < 0)
                {
                    throw new S7OnlineException(SCP_get_errno());
                }
            }
            else
            {
                throw new ObjectDisposedException(this.ToString());
            }
        }
예제 #16
0
        protected void SendS7OExchangeBlockToPlcsim(S7OexchangeBlock data)
        {
            int len = Marshal.SizeOf(data);

            byte[] buffer = new byte[len];

            ushort send_len = (ushort)(data.seg_length_1 + data.headerlength);

            IntPtr ptr = Marshal.AllocHGlobal(len);

            Marshal.StructureToPtr(data, ptr, false);
            Marshal.Copy(ptr, buffer, 0, len);
            Marshal.DestroyStructure(ptr, typeof(S7OexchangeBlock));
            Marshal.FreeHGlobal(ptr);

            int ret = SCP_send(m_connectionHandle, send_len, buffer);

            if (ret < 0)
            {
                SendErrorMessage("ERROR: SCP_send failed");
                ExitThisThread();
            }
        }
        public S7OnlineInterface(string EntryPoint)
        {
            _entryPoint = EntryPoint;

            _connectionHandle = SCP_open(_entryPoint);

            if (_connectionHandle < 0)
            {
                this.Dispose();
                throw new S7OnlineException(SCP_get_errno());
            }

            S7OexchangeBlock fdr = new S7OexchangeBlock();

            formBackgroundThread = new Thread(new ThreadStart(createFormInOtherThread));
            formBackgroundThread.IsBackground = true;
            formBackgroundThread.Start();

            //_myForm = new _intForm(_connectionHandle, Marshal.SizeOf(fdr), this);
            //SetSinecHWndMsg(_connectionHandle, _myForm.Handle, WM_SINEC);
            while (!WndProcReady)
            { }
        }
        private void SendData(S7OexchangeBlock data)
        {
            if (!Disposed)
            {
                int len = Marshal.SizeOf(data);
                byte[] buffer = new byte[len];

                data.headerlength = 80; //Length of the Header (always 80)  (but the 4 first unkown bytes are not count)
                data.rb_type = 2; //rb_type is always 2
                data.offset_1 = 80; //Offset of the Begin of userdata (but the 4 first unkown bytes are not count)

                IntPtr ptr = Marshal.AllocHGlobal(len);
                Marshal.StructureToPtr(data, ptr, true);
                Marshal.Copy(ptr, buffer, 0, len);
                Marshal.FreeHGlobal(ptr);

                int ret = SCP_send(_connectionHandle, (ushort) (data.seg_length_1 + data.headerlength), buffer);
                if (ret < 0)
                    throw new S7OnlineException(SCP_get_errno());
            }
            else
            {
                throw new ObjectDisposedException(this.ToString());
            }
        }
        private void GetResponsePdu(Connection connection)
        {
            if (!Disposed)
            {
                S7OexchangeBlock fdr = new S7OexchangeBlock();

                fdr.user = (ushort)connection.ConnectionNumber;
                fdr.subsystem = 64;
                fdr.opcode = 7;

                fdr.seg_length_1 = 480;
                fdr.response = 16642;

                fdr.application_block_opcode = connection.application_block_opcode;
                fdr.application_block_subsystem = connection.application_block_subsystem;

                fdr.headerlength = 80; //Length of the Header (always 80)  (but the 4 first unkown bytes are not count)
                fdr.rb_type = 2;       //rb_type is always 2
                fdr.offset_1 = 80;     //Offset of the Begin of userdata (but the 4 first unkown bytes are not count)

                fdr.user_data_1 = new byte[260];

                int len = Marshal.SizeOf(fdr);
                byte[] buffer = new byte[len];
                IntPtr ptr = Marshal.AllocHGlobal(len);
                Marshal.StructureToPtr(fdr, ptr, true);
                Marshal.Copy(ptr, buffer, 0, len);
                Marshal.FreeHGlobal(ptr);

                int ret = SCP_send(_connectionHandle, (ushort)(fdr.seg_length_1 + fdr.headerlength), buffer);
                if (ret < 0)
                    throw new S7OnlineException(SCP_get_errno());
            }
            else
            {
                throw new ObjectDisposedException(this.ToString());
            }
        }
 private void createFormInOtherThread()
 {
     try
     {
         S7OexchangeBlock fdr = new S7OexchangeBlock();
         _myForm = new _intForm(_connectionHandle, Marshal.SizeOf(fdr), this);
         SetSinecHWndMsg(_connectionHandle, _myForm.Handle, WM_SINEC);
         WndProcReady = true;
         Application.Run();
     }
     catch (ThreadAbortException)
     { }
 }
        public void SendPdu(Pdu pdu, Connection connection)
        {
            if (!Disposed)
            {
                byte[] pdubytes = pdu.ToBytes();

                S7OexchangeBlock fdr = new S7OexchangeBlock();

                fdr.user = (ushort) connection.ConnectionNumber;
                fdr.subsystem = 64;
                fdr.opcode = 6;
                fdr.response = 255;
                fdr.fill_length_1 = (byte) pdubytes.Length;
                fdr.seg_length_1 = (byte) pdubytes.Length;
                fdr.application_block_opcode = connection.application_block_opcode;
                //if (!connection.ConnectionConfig.ConnectionToEthernet)
                fdr.application_block_subsystem = connection.application_block_subsystem;

                fdr.headerlength = 80; //Length of the Header (always 80)  (but the 4 first unkown bytes are not count)
                fdr.rb_type = 2; //rb_type is always 2
                fdr.offset_1 = 80; //Offset of the Begin of userdata (but the 4 first unkown bytes are not count)

                fdr.user_data_1 = new byte[260];
                Array.Copy(pdubytes, fdr.user_data_1, pdubytes.Length);

                int len = Marshal.SizeOf(fdr);
                byte[] buffer = new byte[len];
                IntPtr ptr = Marshal.AllocHGlobal(len);
                Marshal.StructureToPtr(fdr, ptr, true);
                Marshal.Copy(ptr, buffer, 0, len);
                Marshal.FreeHGlobal(ptr);

                int ret = SCP_send(_connectionHandle, (ushort)(fdr.seg_length_1 + fdr.headerlength), buffer);
                if (ret < 0)
                    throw new S7OnlineException(SCP_get_errno());
            }
            else
            {
                throw new ObjectDisposedException(this.ToString());
            }
        }
        public void DisconnectPlc(Connection conn)
        {
            conn.ConnectionEstablished = false;
            S7OexchangeBlock fdr;

            if (conn.ConnectionConfig.ConnectionToEthernet)
            {
                fdr = new S7OexchangeBlock();
                fdr.user = (ushort) conn.ConnectionNumber;
                fdr.subsystem = 64;
                fdr.opcode = 8;
                fdr.response = 255;
                fdr.application_block_opcode = conn.application_block_opcode;
                SendData(fdr);
                RecieveData((ushort) conn.ConnectionNumber);
            }

            fdr = new S7OexchangeBlock();
            fdr.user = (ushort)conn.ConnectionNumber;
            fdr.subsystem = 64;
            fdr.opcode = 0xC;
            fdr.response = 255;
            fdr.application_block_service = 0x8000;
            fdr.application_block_opcode = conn.application_block_opcode;
            fdr.application_block_subsystem = conn.application_block_subsystem;
            SendData(fdr);
            RecieveData((ushort)conn.ConnectionNumber);

            ConnectionsList.Remove(conn.ConnectionNumber);
        }
        public Connection ConnectPlc(ConnectionConfig config)
        {
            //eine eindeutige connection id erzeugen
            //in der connection eine liste der pdus pflegen, auf welche noch gewartet wird.
            //für die pdu welche asynchron kommt nummer 0 verwenden!

            S7OexchangeBlock fdr = new S7OexchangeBlock();
            S7OexchangeBlock rec = new S7OexchangeBlock();
            int len = Marshal.SizeOf(fdr);
            byte[] buffer = new byte[len];
            IntPtr ptr;
            GCHandle handle;

            Connection retVal;

            while (ConnectionsList.ContainsKey(connNr))
            {
                connNr++;
                if (connNr >= ushort.MaxValue)
                    connNr = 1;
            }
            retVal = new Connection(this, config, 0);
            retVal.ConnectionNumber = connNr;
            ConnectionsList.Add(connNr, retVal);

            //Todo:
            //Im Feld fdr.user für jede Connection einen eigenen Wert verwenden, so das bei empfangen Daten auch
            //Festgestellt werden kann für welche Connection die sind.
            //Dann muss eine Liste geführt werden, in der die IDs und die zugehörige Connection gespeichert ist.
            //Wenn dann auf der ID was empfangen wird, wird das an die Connection weitergeleitet!

            if (!config.ConnectionToEthernet)
            {
                #region Telegramm 1
                fdr.subsystem = 0x22;
                fdr.response = 0xFF;
                fdr.user = connNr;//0xFF;
                fdr.seg_length_1 = 0x80;
                fdr.priority = 1;
                fdr.application_block_service = (ushort)service_code.fdl_life_list_create_remote;

                SendData(fdr);
                rec = RecieveData(connNr);
                #endregion

                #region Telegramm 2
                fdr.seg_length_1 = 0xF2;
                fdr.application_block_service = (ushort) service_code.fdl_read_value;

                SendData(fdr);
                rec = RecieveData(connNr);
                #endregion
            }

            #region Telegramm 3 (Ethernet 1)

            fdr = new S7OexchangeBlock();
            fdr.user = connNr;
            fdr.response = 255;
            fdr.subsystem = 0x40;
            SendData(fdr);
            rec = RecieveData(connNr);

            retVal.application_block_opcode = rec.application_block_opcode;
            retVal.application_block_subsystem = rec.application_block_subsystem;
            #endregion

            #region Telegramm 4 (Ethernet 2)

            fdr = new S7OexchangeBlock();

            fdr.user = connNr;// 111;
            fdr.subsystem = 64;
            fdr.opcode = 1;
            fdr.response = 255;
            fdr.fill_length_1 = 126;
            fdr.seg_length_1 = 126;
            fdr.application_block_opcode = retVal.application_block_opcode;
            fdr.application_block_ssap = 2;
            fdr.application_block_remote_address_station = 114;
            fdr.application_block_subsystem = retVal.application_block_subsystem; //When this is One it is a MPI Connection, zero means TCP Connection!
            UserDataConnectionConfig ud_cfg = new UserDataConnectionConfig(true);
            ud_cfg.rack_slot = (byte) (config.Slot + config.Rack*32);
            ud_cfg.connection_type = (byte) config.ConnectionType;
            if (config.ConnectionToEthernet)
            {
                ud_cfg.destination_1 = config.IPAddress.GetAddressBytes()[0];
                ud_cfg.destination_2 = config.IPAddress.GetAddressBytes()[1];
                ud_cfg.destination_3 = config.IPAddress.GetAddressBytes()[2];
                ud_cfg.destination_4 = config.IPAddress.GetAddressBytes()[3];
            }
            else
                ud_cfg.destination_1 = (byte) config.MPIAddress;

            if (config.Routing)
            {
                ud_cfg.routing_enabled = 0x01;
                ud_cfg.rack_slot = (byte) (config.RoutingSlot + config.RoutingRack*32);
                ud_cfg.size_of_subnet = 0x06;
                ud_cfg.routing_destination_1 = (byte) ((config.RoutingSubnet1 >> 8) & 0xFF);
                ud_cfg.routing_destination_2 = (byte) ((config.RoutingSubnet1) & 0xFF);
                ud_cfg.routing_destination_3 = (byte) ((config.RoutingSubnet2 >> 8) & 0xFF);
                ud_cfg.routing_destination_4 = (byte) ((config.RoutingSubnet2) & 0xFF);

                if (!config.RoutingToEthernet)
                {
                    ud_cfg.size_of_routing_destination = 0x01;
                    ud_cfg.routing_destination_1 = (byte) config.RoutingMPIAddres;
                    ud_cfg.size_to_end = 0x09;
                }
                else
                {
                    ud_cfg.size_of_routing_destination = 0x04;
                    ud_cfg.routing_destination_1 = config.RoutingIPAddress.GetAddressBytes()[0];
                    ud_cfg.routing_destination_2 = config.RoutingIPAddress.GetAddressBytes()[1];
                    ud_cfg.routing_destination_3 = config.RoutingIPAddress.GetAddressBytes()[2];
                    ud_cfg.routing_destination_4 = config.RoutingIPAddress.GetAddressBytes()[3];
                    ud_cfg.size_to_end = 0x0C;
                }
            }
            ptr = Marshal.AllocHGlobal(Marshal.SizeOf(ud_cfg));
            Marshal.StructureToPtr(ud_cfg, ptr, true);
            fdr.user_data_1 = new byte[260];
            Marshal.Copy(ptr, fdr.user_data_1, 0, Marshal.SizeOf(ud_cfg));
            Marshal.FreeHGlobal(ptr);
            SendData(fdr);
            rec = RecieveData(connNr);
            if (rec.response != 0x01)
                throw new S7OnlineException("S7Online: Error Connection to PLC");

            #endregion

            #region Telegramm 5 (Ethernet 3) (this Telegramm sends a PDU)
            //5th Telegramm / TCP(3rd)
            Pdu pdu = new Pdu(1);
            pdu.Param.AddRange(new byte[] {0xF0, 0, 0, 1, 0, 1, 3, 0xc0});
            SendPdu(pdu, retVal);
            Pdu recPdu = RecievePdu(connNr);
            #endregion

            #region Telegramm 6 (Ethernet 4) (get PDU size)
            fdr = new S7OexchangeBlock();
            fdr.user = connNr;//0;
            fdr.subsystem = 64;
            fdr.opcode = 7;
            fdr.response = 16642;
            fdr.seg_length_1 = 480;
            fdr.application_block_opcode = retVal.application_block_opcode;
            fdr.application_block_subsystem = retVal.application_block_subsystem;
            SendData(fdr);
            recPdu = RecievePdu(connNr);
            retVal.PduSize = ByteFunctions.getU16from(recPdu.Param.ToArray(), 6);
            #endregion

            retVal.ConnectionEstablished = true;

            return retVal;
        }
예제 #24
0
        public Connection ConnectPlc(ConnectionConfig config)
        {
            //eine eindeutige connection id erzeugen
            //in der connection eine liste der pdus pflegen, auf welche noch gewartet wird.
            //für die pdu welche asynchron kommt nummer 0 verwenden!

            S7OexchangeBlock fdr = new S7OexchangeBlock();
            S7OexchangeBlock rec = new S7OexchangeBlock();
            int len = Marshal.SizeOf(fdr);

            byte[]   buffer = new byte[len];
            IntPtr   ptr;
            GCHandle handle;

            Connection retVal;


            while (ConnectionsList.ContainsKey(connNr))
            {
                connNr++;
                if (connNr >= ushort.MaxValue)
                {
                    connNr = 1;
                }
            }
            retVal = new Connection(this, config, 0);
            retVal.ConnectionNumber = connNr;
            ConnectionsList.Add(connNr, retVal);

            //Todo:
            //Im Feld fdr.user für jede Connection einen eigenen Wert verwenden, so das bei empfangen Daten auch
            //Festgestellt werden kann für welche Connection die sind.
            //Dann muss eine Liste geführt werden, in der die IDs und die zugehörige Connection gespeichert ist.
            //Wenn dann auf der ID was empfangen wird, wird das an die Connection weitergeleitet!

            if (!config.ConnectionToEthernet)
            {
                #region Telegramm 1
                fdr.subsystem    = 0x22;
                fdr.response     = 0xFF;
                fdr.user         = connNr;//0xFF;
                fdr.seg_length_1 = 0x80;
                fdr.priority     = 1;
                fdr.application_block_service = (ushort)service_code.fdl_life_list_create_remote;

                SendData(fdr);
                rec = RecieveData(connNr);
                #endregion

                #region Telegramm 2
                fdr.seg_length_1 = 0xF2;
                fdr.application_block_service = (ushort)service_code.fdl_read_value;

                SendData(fdr);
                rec = RecieveData(connNr);
                #endregion
            }

            #region Telegramm 3 (Ethernet 1)

            fdr           = new S7OexchangeBlock();
            fdr.user      = connNr;
            fdr.response  = 255;
            fdr.subsystem = 0x40;
            SendData(fdr);
            rec = RecieveData(connNr);

            retVal.application_block_opcode    = rec.application_block_opcode;
            retVal.application_block_subsystem = rec.application_block_subsystem;
            #endregion

            #region Telegramm 4 (Ethernet 2)

            fdr = new S7OexchangeBlock();

            fdr.user                     = connNr;// 111;
            fdr.subsystem                = 64;
            fdr.opcode                   = 1;
            fdr.response                 = 255;
            fdr.fill_length_1            = 126;
            fdr.seg_length_1             = 126;
            fdr.application_block_opcode = retVal.application_block_opcode;
            fdr.application_block_ssap   = 2;
            fdr.application_block_remote_address_station = 114;
            fdr.application_block_subsystem = retVal.application_block_subsystem; //When this is One it is a MPI Connection, zero means TCP Connection!
            UserDataConnectionConfig ud_cfg = new UserDataConnectionConfig(true);
            ud_cfg.rack_slot       = (byte)(config.Slot + config.Rack * 32);
            ud_cfg.connection_type = (byte)config.ConnectionType;
            if (config.ConnectionToEthernet)
            {
                ud_cfg.destination_1 = config.IPAddress.GetAddressBytes()[0];
                ud_cfg.destination_2 = config.IPAddress.GetAddressBytes()[1];
                ud_cfg.destination_3 = config.IPAddress.GetAddressBytes()[2];
                ud_cfg.destination_4 = config.IPAddress.GetAddressBytes()[3];
            }
            else
            {
                ud_cfg.destination_1 = (byte)config.MPIAddress;
            }

            if (config.Routing)
            {
                ud_cfg.routing_enabled       = 0x01;
                ud_cfg.rack_slot             = (byte)(config.RoutingSlot + config.RoutingRack * 32);
                ud_cfg.size_of_subnet        = 0x06;
                ud_cfg.routing_destination_1 = (byte)((config.RoutingSubnet1 >> 8) & 0xFF);
                ud_cfg.routing_destination_2 = (byte)((config.RoutingSubnet1) & 0xFF);
                ud_cfg.routing_destination_3 = (byte)((config.RoutingSubnet2 >> 8) & 0xFF);
                ud_cfg.routing_destination_4 = (byte)((config.RoutingSubnet2) & 0xFF);

                if (!config.RoutingToEthernet)
                {
                    ud_cfg.size_of_routing_destination = 0x01;
                    ud_cfg.routing_destination_1       = (byte)config.RoutingMPIAddres;
                    ud_cfg.size_to_end = 0x09;
                }
                else
                {
                    ud_cfg.size_of_routing_destination = 0x04;
                    ud_cfg.routing_destination_1       = config.RoutingIPAddress.GetAddressBytes()[0];
                    ud_cfg.routing_destination_2       = config.RoutingIPAddress.GetAddressBytes()[1];
                    ud_cfg.routing_destination_3       = config.RoutingIPAddress.GetAddressBytes()[2];
                    ud_cfg.routing_destination_4       = config.RoutingIPAddress.GetAddressBytes()[3];
                    ud_cfg.size_to_end = 0x0C;
                }
            }
            ptr = Marshal.AllocHGlobal(Marshal.SizeOf(ud_cfg));
            Marshal.StructureToPtr(ud_cfg, ptr, true);
            fdr.user_data_1 = new byte[260];
            Marshal.Copy(ptr, fdr.user_data_1, 0, Marshal.SizeOf(ud_cfg));
            Marshal.FreeHGlobal(ptr);
            SendData(fdr);
            rec = RecieveData(connNr);
            if (rec.response != 0x01)
            {
                throw new S7OnlineException("S7Online: Error Connection to PLC");
            }

            #endregion

            #region Telegramm 5 (Ethernet 3) (this Telegramm sends a PDU)
            //5th Telegramm / TCP(3rd)
            Pdu pdu = new Pdu(1);
            pdu.Param.AddRange(new byte[] { 0xF0, 0, 0, 1, 0, 1, 3, 0xc0 });
            SendPdu(pdu, retVal);
            Pdu recPdu = RecievePdu(connNr);
            #endregion

            #region Telegramm 6 (Ethernet 4) (get PDU size)
            fdr                             = new S7OexchangeBlock();
            fdr.user                        = connNr;//0;
            fdr.subsystem                   = 64;
            fdr.opcode                      = 7;
            fdr.response                    = 16642;
            fdr.seg_length_1                = 480;
            fdr.application_block_opcode    = retVal.application_block_opcode;
            fdr.application_block_subsystem = retVal.application_block_subsystem;
            SendData(fdr);
            recPdu         = RecievePdu(connNr);
            retVal.PduSize = ByteFunctions.getU16from(recPdu.Param.ToArray(), 6);
            #endregion

            retVal.ConnectionEstablished = true;

            return(retVal);
        }
예제 #25
0
        private Pdu RecievePdu(ushort myConnNr)
        {
            S7OexchangeBlock rec = RecieveData(myConnNr);

            return(new Pdu(rec.user_data_1));
        }