public EnIPNetworkStatus ForwardOpen(EnIPAttribut Config, EnIPAttribut O2T, EnIPAttribut T2O, out ForwardClose_Packet ClosePacket, ForwardOpen_Config conf, bool WriteConfig = false)
        {
            ClosePacket = null;

            byte[] DataPath = GetForwardOpenPath(Config, O2T, T2O);

            if ((WriteConfig == true) && (Config != null)) // Add data segment
            {
                DataPath = EnIPPath.AddDataSegment(DataPath, Config.RawData);

                /*
                 * byte[] FinaleFrame = new byte[DataPath.Length + 2 + Config.RawData.Length];
                 * Array.Copy(DataPath, FinaleFrame, DataPath.Length);
                 * FinaleFrame[DataPath.Length] = 0x80;
                 * FinaleFrame[DataPath.Length + 1] = (byte)(Config.RawData.Length / 2); // Certainly the lenght is always even !!!
                 * Array.Copy(Config.RawData, 0, FinaleFrame, DataPath.Length + 2, Config.RawData.Length);
                 * DataPath = FinaleFrame;
                 */
            }

            ForwardOpen_Packet FwPkt = new ForwardOpen_Packet(DataPath, conf);

            int Offset = 0;
            int Lenght = 0;

            byte[] packet;

            EnIPNetworkStatus Status;

            if (FwPkt.IsLargeForwardOpen)
            {
                Status = SendUCMM_RR_Packet(EnIPPath.GetPath(6, 1), CIPServiceCodes.LargeForwardOpen, FwPkt.toByteArray(), ref Offset, ref Lenght, out packet);
            }
            else
            {
                Status = SendUCMM_RR_Packet(EnIPPath.GetPath(6, 1), CIPServiceCodes.ForwardOpen, FwPkt.toByteArray(), ref Offset, ref Lenght, out packet);
            }

            if (Status == EnIPNetworkStatus.OnLine)
            {
                if (O2T != null)
                {
                    O2T.O2T_ConnectionId = BitConverter.ToUInt32(packet, Offset);                          // badly made
                    O2T.SequenceItem     = new SequencedAddressItem(O2T.O2T_ConnectionId, 0, O2T.RawData); // ready to send
                }

                if (T2O != null)
                {
                    T2O.Class1Enrolment();
                    T2O.T2O_ConnectionId = BitConverter.ToUInt32(packet, Offset + 4);
                }
                ClosePacket = new ForwardClose_Packet(FwPkt, T2O);
            }

            return(Status);
        }
示例#2
0
        // Only use for request up to now
        // O2T & T2O could be use at the same time
        // using a Connection_Path with more than 1 reference
        // 1 Path : path is for Consumption & Production
        // 2 Path : First path is for Consumption, second path is for Production.
        public ForwardOpen_Packet(byte[] Connection_Path, ForwardOpen_Config conf, uint?ConnectionId = null)
        {
            ConnectionSerialNumber = GlobalConnectionSerialNumber++;

            if ((conf.O2T_datasize > 511 - 2) || (conf.T2O_datasize > 511 - 6))
            {
                IsLargeForwardOpen = true;
            }

            this.Connection_Path = Connection_Path;

            if (ConnectionId == null)
            {
                // volume 2 : 3-3.7.1.3 Pseudo-Random Connection ID Per Connection
                _ConnectionId += 2;
                _ConnectionId  = _ConnectionId | (uint)(new Random().Next(65535) << 16);
            }
            else
            {
                _ConnectionId = ConnectionId.Value;
            }

            if (conf.IsO2T)
            {
                O2T_ConnectionId = _ConnectionId;
            }
            if (conf.IsT2O)
            {
                T2O_ConnectionId = _ConnectionId + 1;
            }

            /*
             * // Volume 1:  chapter 3-5.5.1.1
             * T->O Network Connection Parameters: 0x463b
             * 0... .... .... .... = Owner: Exclusive (0)
             * .10. .... .... .... = Connection Type: Point to Point (2)
             * .... 01.. .... .... = Priority: High Priority (1)
             * .... ..1. .... .... = Connection Size Type: Variable (1)
             * .... ...0 0011 1011 = Connection Size: 59
             */
            if (conf.IsT2O)
            {
                T2O_ConnectionParameters = 0x0000; // Fixed Datasize, Variable data size is 0x0200
                T2O_ConnectionParameters = (uint)(T2O_ConnectionParameters + (conf.T2O_Priority & 0x03) << 10);
                if (conf.T2O_P2P)
                {
                    T2O_ConnectionParameters = T2O_ConnectionParameters | 0x4000;
                }
                else
                {
                    T2O_ConnectionParameters = T2O_ConnectionParameters | 0x2000;
                }

                if (conf.O2T_Exculsive)
                {
                    T2O_ConnectionParameters = T2O_ConnectionParameters | 0x8000;
                }

                if (IsLargeForwardOpen)
                {
                    T2O_ConnectionParameters = (T2O_ConnectionParameters << 16) + conf.T2O_datasize + 2;
                }
                else
                {
                    T2O_ConnectionParameters += (ushort)(conf.T2O_datasize + 2);
                }

                T2O_RPI = conf.T2O_RPI;
            }
            if (conf.IsO2T)
            {
                O2T_ConnectionParameters = 0x0000; // Fixed Datasize, Variable data size is 0x0200
                O2T_ConnectionParameters = (uint)(O2T_ConnectionParameters + (conf.O2T_Priority & 0x03) << 10);
                if (conf.O2T_P2P)
                {
                    O2T_ConnectionParameters = O2T_ConnectionParameters | 0x4000;
                }
                else
                {
                    O2T_ConnectionParameters = O2T_ConnectionParameters | 0x2000;
                }

                if (conf.O2T_Exculsive)
                {
                    O2T_ConnectionParameters = O2T_ConnectionParameters | 0x8000;
                }


                // 2 bytes CIP class 1 sequence count + 4 bytes 32-bit real time header + datasize bytes application data
                if (conf.O2T_P2P)
                {
                    O2T_ConnectionParameters = 0x4600;
                }
                else
                {
                    O2T_ConnectionParameters = 0x2600;
                }

                if (IsLargeForwardOpen)
                {
                    if (conf.O2T_datasize != 0)
                    {
                        O2T_ConnectionParameters = (O2T_ConnectionParameters << 16) + conf.O2T_datasize + 2 + 4;
                    }
                    else
                    {
                        O2T_ConnectionParameters = (O2T_ConnectionParameters << 16) + 2;
                    }
                }
                else
                {
                    if (conf.O2T_datasize != 0)
                    {
                        O2T_ConnectionParameters += (ushort)(conf.O2T_datasize + 2 + 4);
                    }
                    else
                    {
                        O2T_ConnectionParameters += (ushort)(2);
                    }
                }

                O2T_RPI = conf.O2T_RPI;
            }
        }
        public EnIPNetworkStatus ForwardOpen(EnIPAttribut Config, EnIPAttribut O2T, EnIPAttribut T2O, out ForwardClose_Packet ClosePacket, uint CycleTime, bool P2P = false, bool WriteConfig = false)
        {
            ForwardOpen_Config conf = new ForwardOpen_Config(O2T, T2O, P2P, CycleTime);

            return(ForwardOpen(Config, O2T, T2O, out ClosePacket, conf, WriteConfig));
        }