コード例 #1
0
ファイル: S7ClientAsync.cs プロジェクト: robinson/DataLink
        private int NegotiatePduLength()
        {
            int Length;

            // Set PDU Size Requested
            S7.SetWordAt(S7_PN, 23, DefaultPduSizeRequested);
            // Sends the connection request telegram
            SendPacket(S7_PN);
            if (LastError == 0)
            {
                Length = RecvIsoPacket();
                if (LastError == 0)
                {
                    // check S7 Error
                    if ((Length == 27) && (PDU[17] == 0) && (PDU[18] == 0))  // 20 = size of Negotiate Answer
                    {
                        // Get PDU Size Negotiated
                        _PDULength = S7.GetWordAt(PDU, 25);
                        if (_PDULength > 0)
                        {
                            return(0);
                        }
                        else
                        {
                            LastError = errISONegotiatingPDU;
                        }
                    }
                    else
                    {
                        LastError = errISONegotiatingPDU;
                    }
                }
            }
            return(LastError);
        }
コード例 #2
0
ファイル: S7ClientAsync.cs プロジェクト: robinson/DataLink
        public int ReadSZL(int ID, int Index, S7Szl SZL)
        {
            int     Length;
            int     DataSZL;
            int     Offset  = 0;
            Boolean Done    = false;
            Boolean First   = true;
            byte    Seq_in  = 0x00;
            int     Seq_out = 0x0000;

            LastError    = 0;
            SZL.DataSize = 0;
            do
            {
                if (First)
                {
                    S7.SetWordAt(S7_SZL_FIRST, 11, ++Seq_out);
                    S7.SetWordAt(S7_SZL_FIRST, 29, ID);
                    S7.SetWordAt(S7_SZL_FIRST, 31, Index);
                    SendPacket(S7_SZL_FIRST);
                }
                else
                {
                    S7.SetWordAt(S7_SZL_NEXT, 11, ++Seq_out);
                    PDU[24] = (byte)Seq_in;
                    SendPacket(S7_SZL_NEXT);
                }
                if (LastError != 0)
                {
                    return(LastError);
                }

                Length = RecvIsoPacket();
                if (LastError == 0)
                {
                    if (First)
                    {
                        if (Length > 32) // the minimum expected
                        {
                            if ((S7.GetWordAt(PDU, 27) == 0) && (PDU[29] == (byte)0xFF))
                            {
                                // Gets Amount of this slice
                                DataSZL = S7.GetWordAt(PDU, 31) - 8; // Skips extra params (ID, Index ...)
                                Done    = PDU[26] == 0x00;
                                Seq_in  = (byte)PDU[24];             // Slice sequence

                                SZL.LENTHDR = S7.GetWordAt(PDU, 37);
                                SZL.N_DR    = S7.GetWordAt(PDU, 39);
                                SZL.Copy(PDU, 41, Offset, DataSZL);
                                Offset       += DataSZL;
                                SZL.DataSize += DataSZL;
                            }
                            else
                            {
                                LastError = errS7FunctionError;
                            }
                        }
                        else
                        {
                            LastError = errS7InvalidPDU;
                        }
                    }
                    else
                    {
                        if (Length > 32) // the minimum expected
                        {
                            if ((S7.GetWordAt(PDU, 27) == 0) && (PDU[29] == (byte)0xFF))
                            {
                                // Gets Amount of this slice
                                DataSZL = S7.GetWordAt(PDU, 31);
                                Done    = PDU[26] == 0x00;
                                Seq_in  = (byte)PDU[24]; // Slice sequence
                                SZL.Copy(PDU, 37, Offset, DataSZL);
                                Offset       += DataSZL;
                                SZL.DataSize += DataSZL;
                            }
                            else
                            {
                                LastError = errS7FunctionError;
                            }
                        }
                        else
                        {
                            LastError = errS7InvalidPDU;
                        }
                    }
                }
                First = false;
            }while (!Done && (LastError == 0));

            return(LastError);
        }
コード例 #3
0
ファイル: S7ClientAsync.cs プロジェクト: robinson/DataLink
        public int WriteArea(int Area, int DBNumber, int Start, int Amount, byte[] Data)
        {
            int Address;
            int NumElements;
            int MaxElements;
            int TotElements;
            int DataSize;
            int IsoSize;
            int Length;
            int Offset   = 0;
            int WordSize = 1;

            LastError = 0;

            // If we are addressing Timers or counters the element size is 2
            if ((Area == S7.S7AreaCT) || (Area == S7.S7AreaTM))
            {
                WordSize = 2;
            }

            MaxElements = (_PDULength - 35) / WordSize; // 18 = Reply telegram header
            TotElements = Amount;

            while ((TotElements > 0) && (LastError == 0))
            {
                NumElements = TotElements;
                if (NumElements > MaxElements)
                {
                    NumElements = MaxElements;
                }

                DataSize = NumElements * WordSize;
                IsoSize  = Size_WR + DataSize;

                // Setup the telegram
                Array.Copy(S7_RW, 0, PDU, 0, Size_WR);
                // Whole telegram Size
                S7.SetWordAt(PDU, 2, IsoSize);
                // Data Length
                Length = DataSize + 4;
                S7.SetWordAt(PDU, 15, Length);
                // Function
                PDU[17] = (byte)0x05;
                // Set DB Number
                PDU[27] = (byte)Area;
                if (Area == S7.S7AreaDB)
                {
                    S7.SetWordAt(PDU, 25, DBNumber);
                }

                // Adjusts Start and word length
                if ((Area == S7.S7AreaCT) || (Area == S7.S7AreaTM))
                {
                    Address = Start;
                    Length  = DataSize;
                    if (Area == S7.S7AreaCT)
                    {
                        PDU[22] = S7WLCounter;
                    }
                    else
                    {
                        PDU[22] = S7WLTimer;
                    }
                }
                else
                {
                    Address = Start << 3;
                    Length  = DataSize << 3;
                }
                // Num elements
                S7.SetWordAt(PDU, 23, NumElements);
                // Address into the PLC
                PDU[30] = (byte)(Address & 0x0FF);
                Address = Address >> 8;
                PDU[29] = (byte)(Address & 0x0FF);
                Address = Address >> 8;
                PDU[28] = (byte)(Address & 0x0FF);
                // Length
                S7.SetWordAt(PDU, 33, Length);

                // Copies the Data
                Array.Copy(Data, Offset, PDU, 35, DataSize);

                SendPacket(PDU, IsoSize);
                if (LastError == 0)
                {
                    Length = RecvIsoPacket();
                    if (LastError == 0)
                    {
                        if (Length == 22)
                        {
                            if ((S7.GetWordAt(PDU, 17) != 0) || (PDU[21] != (byte)0xFF))
                            {
                                LastError = errS7DataWrite;
                            }
                        }
                        else
                        {
                            LastError = errS7InvalidPDU;
                        }
                    }
                }

                Offset      += DataSize;
                TotElements -= NumElements;
                Start       += NumElements * WordSize;
            }
            return(LastError);
        }
コード例 #4
0
ファイル: S7ClientAsync.cs プロジェクト: robinson/DataLink
        public int ReadArea(int Area, int DBNumber, int Start, int Amount, byte[] Data)
        {
            int Address;
            int NumElements;
            int MaxElements;
            int TotElements;
            int SizeRequested;
            int Length;
            int Offset   = 0;
            int WordSize = 1;

            LastError = 0;

            // If we are addressing Timers or counters the element size is 2
            if ((Area == S7.S7AreaCT) || (Area == S7.S7AreaTM))
            {
                WordSize = 2;
            }

            MaxElements = (_PDULength - 18) / WordSize; // 18 = Reply telegram header
            TotElements = Amount;

            while ((TotElements > 0) && (LastError == 0))
            {
                NumElements = TotElements;
                if (NumElements > MaxElements)
                {
                    NumElements = MaxElements;
                }

                SizeRequested = NumElements * WordSize;

                // Setup the telegram
                Array.Copy(S7_RW, 0, PDU, 0, Size_RD);
                // Set DB Number
                PDU[27] = (byte)Area;
                // Set Area
                if (Area == S7.S7AreaDB)
                {
                    S7.SetWordAt(PDU, 25, DBNumber);
                }

                // Adjusts Start and word length
                if ((Area == S7.S7AreaCT) || (Area == S7.S7AreaTM))
                {
                    Address = Start;
                    if (Area == S7.S7AreaCT)
                    {
                        PDU[22] = S7WLCounter;
                    }
                    else
                    {
                        PDU[22] = S7WLTimer;
                    }
                }
                else
                {
                    Address = Start << 3;
                }

                // Num elements
                S7.SetWordAt(PDU, 23, NumElements);

                // Address into the PLC (only 3 bytes)
                PDU[30] = (byte)(Address & 0x0FF);
                Address = Address >> 8;
                PDU[29] = (byte)(Address & 0x0FF);
                Address = Address >> 8;
                PDU[28] = (byte)(Address & 0x0FF);

                SendPacket(PDU, Size_RD);
                if (LastError == 0)
                {
                    Length = RecvIsoPacket();
                    if (LastError == 0)
                    {
                        if (Length >= 25)
                        {
                            if ((Length - 25 == SizeRequested) && (PDU[21] == (byte)0xFF))
                            {
                                Array.Copy(PDU, 25, Data, Offset, SizeRequested);
                                Offset += SizeRequested;
                            }
                            else
                            {
                                LastError = errS7DataRead;
                            }
                        }
                        else
                        {
                            LastError = errS7InvalidPDU;
                        }
                    }
                }

                TotElements -= NumElements;
                Start       += NumElements * WordSize;
            }
            return(LastError);
        }