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); }
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); }
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); }
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); }