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;
        }
Ejemplo n.º 2
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);
        }