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 SetPlcDateTime(DateTime DateTime) { int Length; LastError = 0; S7.SetDateAt(S7_SET_DT, 31, DateTime); SendPacket(S7_SET_DT); if (LastError == 0) { Length = RecvIsoPacket(); if (Length > 30) // the minimum expected { if (S7.GetWordAt(PDU, 27) != 0) { LastError = errS7FunctionError; } } else { LastError = errS7InvalidPDU; } } return(LastError); }
/// <summary> /// Returns a date /// </summary> /// <param name="Buffer"></param> /// <param name="Pos"></param> /// <returns></returns> public static DateTime GetDateAt(byte[] Buffer, int Pos) { int Year = S7.BCDtoByte(Buffer[Pos + 1]); if (Year < 90) { Year += 2000; } else { Year += 1900; } int Month = S7.BCDtoByte(Buffer[Pos + 2]); int Day = S7.BCDtoByte(Buffer[Pos + 3]); int Hour = S7.BCDtoByte(Buffer[Pos + 4]); int Min = S7.BCDtoByte(Buffer[Pos + 5]); int Sec = S7.BCDtoByte(Buffer[Pos + 6]); //lth: should be get by this position, it is bit moved now. //Year = S7.BCDtoByte(Buffer[Pos]); //if (Year < 90) // Year += 2000; //else // Year += 1900; //Month = S7.BCDtoByte(Buffer[Pos + 1]) - 1; //Day = S7.BCDtoByte(Buffer[Pos + 2]); //Hour = S7.BCDtoByte(Buffer[Pos + 3]); //Min = S7.BCDtoByte(Buffer[Pos + 4]); //Sec = S7.BCDtoByte(Buffer[Pos + 5]); var S7Date = new DateTime(Year, Month, Day, Hour, Min, Sec); return(S7Date); }
public int GetPlcDateTime(DateTime DateTime) { int Length; LastError = 0; SendPacket(S7_GET_DT); if (LastError == 0) { Length = RecvIsoPacket(); if (Length > 30) // the minimum expected { if ((S7.GetWordAt(PDU, 27) == 0) && (PDU[29] == (byte)0xFF)) { DateTime = S7.GetDateAt(PDU, 34); } else { LastError = errS7FunctionError; } } else { LastError = errS7InvalidPDU; } } return(LastError); }
public int SetSessionPassword(String Password) { byte[] pwd = { 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }; int Length; LastError = 0; // Adjusts the Password length to 8 if (Password.Length > 8) { Password = Password.Substring(0, 8); } else { while (Password.Length < 8) { Password = Password + " "; } } try { pwd = Password.GetBytes(); //.getBytes("UTF-8"); } catch (Exception ex) //UnsupportedEncodingException { LastError = errS7InvalidParams; } if (LastError == 0) { // Encodes the password pwd[0] = (byte)(pwd[0] ^ 0x55); pwd[1] = (byte)(pwd[1] ^ 0x55); for (int c = 2; c < 8; c++) { pwd[c] = (byte)(pwd[c] ^ 0x55 ^ pwd[c - 2]); } Array.Copy(pwd, 0, S7_SET_PWD, 29, 8); // Sends the telegrem SendPacket(S7_SET_PWD); if (LastError == 0) { Length = RecvIsoPacket(); if (Length > 32) // the minimum expected { if (S7.GetWordAt(PDU, 27) != 0) { LastError = errS7FunctionError; } } else { LastError = errS7InvalidPDU; } } } return(LastError); }
public static DateTime GetTODAt(byte[] Buffer, int Pos) { try { return(new DateTime(0).AddMilliseconds(S7.GetDIntAt(Buffer, Pos))); } catch (System.ArgumentOutOfRangeException) { return(new DateTime(0)); } }
private int RecvIsoPacket() { Boolean Done = false; int Size = 0; while ((LastError == 0) && !Done) { // Get TPKT (4 bytes) RecvPacket(PDU, 0, 4); if (LastError == 0) { Size = S7.GetWordAt(PDU, 2); // Check 0 bytes Data Packet (only TPKT+COTP = 7 bytes) if (Size == IsoHSize) { RecvPacket(PDU, 4, 3); // Skip remaining 3 bytes and Done is still false } else { if ((Size > MaxPduSize) || (Size < MinPduSize)) { LastError = errISOInvalidPDU; } else { Done = true; // a valid Length !=7 && >16 && <247 } } } } if (LastError == 0) { RecvPacket(PDU, 4, 3); // Skip remaining 3 COTP bytes LastPDUType = PDU[5]; // Stores PDU Type, we need it // Receives the S7 Payload RecvPacket(PDU, 7, Size - IsoHSize); } if (LastError == 0) { return(Size); } else { return(0); } }
public int GetAgBlockInfo(int BlockType, int BlockNumber, S7BlockInfo Block) { int Length; LastError = 0; // Block Type S7_BI[30] = (byte)BlockType; // Block Number S7_BI[31] = (byte)((BlockNumber / 10000) + 0x30); BlockNumber = BlockNumber % 10000; S7_BI[32] = (byte)((BlockNumber / 1000) + 0x30); BlockNumber = BlockNumber % 1000; S7_BI[33] = (byte)((BlockNumber / 100) + 0x30); BlockNumber = BlockNumber % 100; S7_BI[34] = (byte)((BlockNumber / 10) + 0x30); BlockNumber = BlockNumber % 10; S7_BI[35] = (byte)((BlockNumber / 1) + 0x30); SendPacket(S7_BI); if (LastError == 0) { Length = RecvIsoPacket(); if (Length > 32) // the minimum expected { if ((S7.GetWordAt(PDU, 27) == 0) && (PDU[29] == (byte)0xFF)) { Block.Update(PDU, 42); } else { LastError = errS7FunctionError; } } else { LastError = errS7InvalidPDU; } } return(LastError); }
public int GetPlcStatus(IntByRef Status) { int Length; LastError = 0; SendPacket(S7_GET_STAT); if (LastError == 0) { Length = RecvIsoPacket(); if (Length > 30) // the minimum expected { if (S7.GetWordAt(PDU, 27) == 0) { switch (PDU[44]) { case S7.S7CpuStatusUnknown: case S7.S7CpuStatusRun: case S7.S7CpuStatusStop: Status.Value = PDU[44]; break; default: // Since RUN status is always 0x08 for all CPUs and CPs, STOP status // sometime can be coded as 0x03 (especially for old cpu...) Status.Value = S7.S7CpuStatusStop; break; } } else { LastError = errS7FunctionError; } } else { LastError = errS7InvalidPDU; } } return(LastError); }
public int PlcColdStart() { int Length; LastError = 0; SendPacket(S7_COLD_START); if (LastError == 0) { Length = RecvIsoPacket(); if (Length > 18) // the minimum expected { if (S7.GetWordAt(PDU, 17) != 0) { LastError = errS7FunctionError; } } else { LastError = errS7InvalidPDU; } } return(LastError); }
public int ClearSessionPassword() { int Length; LastError = 0; SendPacket(S7_CLR_PWD); if (LastError == 0) { Length = RecvIsoPacket(); if (Length > 30) // the minimum expected { if (S7.GetWordAt(PDU, 27) != 0) { LastError = errS7FunctionError; } } else { LastError = errS7InvalidPDU; } } return(LastError); }
public String ModuleTypeName() { return(S7.GetStringAt(Buffer, 172, 32)); }
public int BlkNumber() { return(S7.GetWordAt(Buffer, 3)); }
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 MC7Size() // The real size in bytes { return(S7.GetWordAt(Buffer, 31)); }
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); }
public String Header() { return(S7.GetStringAt(Buffer, 49, 8)); }
public int LocalData() { return(S7.GetWordAt(Buffer, 29)); }
public int Checksum() { return(S7.GetWordAt(Buffer, 59)); }
public int SBBLength() { return(S7.GetWordAt(Buffer, 25)); }
public String Copyright() { return(S7.GetStringAt(Buffer, 104, 26)); }
public DateTime IntfDate() { long BlockDate = ((long)S7.GetWordAt(Buffer, 23)) * 86400000L + DeltaMilliSecs; return(new DateTime(BlockDate)); }
public String Author() { return(S7.GetStringAt(Buffer, 33, 8)); }
public String SerialNumber() { return(S7.GetStringAt(Buffer, 138, 24)); }
public int LoadSize() { return(S7.GetDIntAt(Buffer, 5)); }
public String ASName() { return(S7.GetStringAt(Buffer, 2, 24)); }
public String Family() { return(S7.GetStringAt(Buffer, 41, 8)); }
public String ModuleName() { return(S7.GetStringAt(Buffer, 36, 24)); }
public String Code() { return(S7.GetStringAt(Buffer, 2, 20)); }