--- /dev/null
+diff U3 IntByRef.java IntByRef.java
+--- IntByRef.java Thu Mar 23 15:34:52 2017
++++ IntByRef.java Tue Aug 08 18:53:37 2017
+@@ -1,40 +1,40 @@
+-/*=============================================================================|
+-| PROJECT Moka7 1.0.2 |
+-|==============================================================================|
+-| Copyright (C) 2013, 2016 Davide Nardella |
+-| All rights reserved. |
+-|==============================================================================|
+-| SNAP7 is free software: you can redistribute it and/or modify |
+-| it under the terms of the Lesser GNU General Public License as published by |
+-| the Free Software Foundation, either version 3 of the License, or under |
+-| EPL Eclipse Public License 1.0. |
+-| |
+-| This means that you have to chose in advance which take before you import |
+-| the library into your project. |
+-| |
+-| SNAP7 is distributed in the hope that it will be useful, |
+-| but WITHOUT ANY WARRANTY; without even the implied warranty of |
+-| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you |
+-| decide to adopt. |
+-| |
+-|=============================================================================*/
+-
+-package Moka7;
+-
+-/**
+- * Quick class to pass an integer by reference
+- * @author Davide
+- */
+-
+-public class IntByRef {
+-
+- public IntByRef(int Val)
+- {
+- this.Value=Val;
+- }
+- public IntByRef()
+- {
+- this.Value=0;
+- }
+- public int Value;
+-}
++/*=============================================================================|
++| PROJECT Moka7 1.0.2 |
++|==============================================================================|
++| Copyright (C) 2013, 2016 Davide Nardella |
++| All rights reserved. |
++|==============================================================================|
++| SNAP7 is free software: you can redistribute it and/or modify |
++| it under the terms of the Lesser GNU General Public License as published by |
++| the Free Software Foundation, either version 3 of the License, or under |
++| EPL Eclipse Public License 1.0. |
++| |
++| This means that you have to chose in advance which take before you import |
++| the library into your project. |
++| |
++| SNAP7 is distributed in the hope that it will be useful, |
++| but WITHOUT ANY WARRANTY; without even the implied warranty of |
++| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you |
++| decide to adopt. |
++| |
++|=============================================================================*/
++
++package Moka7;
++
++/**
++ * Quick class to pass an integer by reference
++ * @author Davide Nardella
++ */
++
++public class IntByRef {
++
++ public IntByRef(int Val)
++ {
++ this.Value=Val;
++ }
++ public IntByRef()
++ {
++ this.Value=0;
++ }
++ public int Value;
++}
+diff U3 S7.java S7.java
+--- S7.java Thu Mar 23 15:34:52 2017
++++ S7.java Tue Aug 08 18:53:37 2017
+@@ -1,287 +1,287 @@
+-/*=============================================================================|
+-| PROJECT Moka7 1.0.2 |
+-|==============================================================================|
+-| Copyright (C) 2013, 2016 Davide Nardella |
+-| All rights reserved. |
+-|==============================================================================|
+-| SNAP7 is free software: you can redistribute it and/or modify |
+-| it under the terms of the Lesser GNU General Public License as published by |
+-| the Free Software Foundation, either version 3 of the License, or under |
+-| EPL Eclipse Public License 1.0. |
+-| |
+-| This means that you have to chose in advance which take before you import |
+-| the library into your project. |
+-| |
+-| SNAP7 is distributed in the hope that it will be useful, |
+-| but WITHOUT ANY WARRANTY; without even the implied warranty of |
+-| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you |
+-| decide to adopt. |
+-| |
+-|=============================================================================*/
+-package Moka7;
+-
+-import java.io.UnsupportedEncodingException;
+-import java.util.Date;
+-import java.util.Calendar;
+-
+-/**
+- *
+- * @author Davide
+- */
+-
+-
+-// Step 7 Constants and Conversion helper class
+-public class S7 {
+- // S7 ID Area (Area that we want to read/write)
+- public static final int S7AreaPE = 0x81;
+- public static final int S7AreaPA = 0x82;
+- public static final int S7AreaMK = 0x83;
+- public static final int S7AreaDB = 0x84;
+- public static final int S7AreaCT = 0x1C;
+- public static final int S7AreaTM = 0x1D;
+- // Connection types
+- public static final byte PG = 0x01;
+- public static final byte OP = 0x02;
+- public static final byte S7_BASIC = 0x03;
+- // Block type
+- public static final int Block_OB = 0x38;
+- public static final int Block_DB = 0x41;
+- public static final int Block_SDB = 0x42;
+- public static final int Block_FC = 0x43;
+- public static final int Block_SFC = 0x44;
+- public static final int Block_FB = 0x45;
+- public static final int Block_SFB = 0x46;
+- // Sub Block Type
+- public static final int SubBlk_OB = 0x08;
+- public static final int SubBlk_DB = 0x0A;
+- public static final int SubBlk_SDB = 0x0B;
+- public static final int SubBlk_FC = 0x0C;
+- public static final int SubBlk_SFC = 0x0D;
+- public static final int SubBlk_FB = 0x0E;
+- public static final int SubBlk_SFB = 0x0F;
+- // Block languages
+- public static final int BlockLangAWL = 0x01;
+- public static final int BlockLangKOP = 0x02;
+- public static final int BlockLangFUP = 0x03;
+- public static final int BlockLangSCL = 0x04;
+- public static final int BlockLangDB = 0x05;
+- public static final int BlockLangGRAPH = 0x06;
+- // PLC Status
+- public static final int S7CpuStatusUnknown = 0x00;
+- public static final int S7CpuStatusRun = 0x08;
+- public static final int S7CpuStatusStop = 0x04;
+- // Type Var
+- public static final int S7TypeBool = 1;
+- public static final int S7TypeInt = 1;
+-
+- // Returns the bit at Pos.Bit
+- public static boolean GetBitAt(byte[] Buffer, int Pos, int Bit)
+- {
+- int Value = Buffer[Pos] & 0x0FF;
+- byte[] Mask = {
+- (byte)0x01,(byte)0x02,(byte)0x04,(byte)0x08,
+- (byte)0x10,(byte)0x20,(byte)0x40,(byte)0x80
+- };
+- if (Bit<0) Bit=0;
+- if (Bit>7) Bit=7;
+-
+- return (Value & Mask[Bit])!=0;
+- }
+- /**
+- * Returns a 16 bit unsigned value : from 0 to 65535 (2^16-1)
+- * @param Buffer
+- * @param Pos start position
+- * @return
+- */
+- public static int GetWordAt(byte[] Buffer, int Pos)
+- {
+- int hi = (Buffer[Pos] & 0x00FF);
+- int lo = (Buffer[Pos+1] & 0x00FF);
+- return (hi<<8)+lo;
+- }
+-
+- // Returns a 16 bit signed value : from -32768 to 32767
+- public static int GetShortAt(byte[] Buffer, int Pos)
+- {
+- int hi = (Buffer[Pos]);
+- int lo = (Buffer[Pos+1] & 0x00FF);
+- return ((hi<<8)+lo);
+- }
+-
+- // Returns a 32 bit unsigned value : from 0 to 4294967295 (2^32-1)
+- public static long GetDWordAt(byte[] Buffer, int Pos)
+- {
+- long Result;
+- Result=(long)(Buffer[Pos] & 0x0FF);
+- Result<<=8;
+- Result+=(long)(Buffer[Pos+1] & 0x0FF);
+- Result<<=8;
+- Result+=(long)(Buffer[Pos+2] & 0x0FF);
+- Result<<=8;
+- Result+=(long)(Buffer[Pos+3] & 0x0FF);
+- return Result;
+- }
+-
+- // Returns a 32 bit signed value : from 0 to 4294967295 (2^32-1)
+- public static int GetDIntAt(byte[] Buffer, int Pos)
+- {
+- int Result;
+- Result= Buffer[Pos];
+- Result<<=8;
+- Result+=(Buffer[Pos+1] & 0x0FF);
+- Result<<=8;
+- Result+=(Buffer[Pos+2] & 0x0FF);
+- Result<<=8;
+- Result+=(Buffer[Pos+3] & 0x0FF);
+- return Result;
+- }
+-
+- // Returns a 32 bit floating point
+- public static float GetFloatAt(byte[] Buffer, int Pos)
+- {
+- int IntFloat = GetDIntAt(Buffer, Pos);
+- return Float.intBitsToFloat(IntFloat);
+- }
+-
+- // Returns an ASCII string
+- public static String GetStringAt(byte[] Buffer, int Pos, int MaxLen)
+- {
+- byte[] StrBuffer = new byte[MaxLen];
+- System.arraycopy(Buffer, Pos, StrBuffer, 0, MaxLen);
+- String S;
+- try {
+- S = new String(StrBuffer, "UTF-8"); // the charset is UTF-8
+- } catch (UnsupportedEncodingException ex) {
+- S = "";
+- }
+- return S;
+- }
+-
+- public static String GetPrintableStringAt(byte[] Buffer, int Pos, int MaxLen)
+- {
+- byte[] StrBuffer = new byte[MaxLen];
+- System.arraycopy(Buffer, Pos, StrBuffer, 0, MaxLen);
+- for (int c = 0; c < MaxLen; c++)
+- {
+- if ((StrBuffer[c]<31) || (StrBuffer[c]>126))
+- StrBuffer[c]=46; // '.'
+- }
+- String S;
+- try {
+- S = new String(StrBuffer, "UTF-8"); // the charset is UTF-8
+- } catch (UnsupportedEncodingException ex) {
+- S = "";
+- }
+- return S;
+- }
+-
+- public static Date GetDateAt(byte[] Buffer, int Pos)
+- {
+- int Year, Month, Day, Hour, Min, Sec;
+- Calendar S7Date = Calendar.getInstance();
+-
+- 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]);
+-
+- S7Date.set(Year, Month, Day, Hour, Min, Sec);
+-
+- return S7Date.getTime();
+- }
+-
+- public static void SetBitAt(byte[] Buffer, int Pos, int Bit, boolean Value)
+- {
+- byte[] Mask = {
+- (byte)0x01,(byte)0x02,(byte)0x04,(byte)0x08,
+- (byte)0x10,(byte)0x20,(byte)0x40,(byte)0x80
+- };
+- if (Bit<0) Bit=0;
+- if (Bit>7) Bit=7;
+-
+- if (Value)
+- Buffer[Pos]= (byte) (Buffer[Pos] | Mask[Bit]);
+- else
+- Buffer[Pos]= (byte) (Buffer[Pos] & ~Mask[Bit]);
+- }
+-
+- public static void SetWordAt(byte[] Buffer, int Pos, int Value)
+- {
+- int Word = Value & 0x0FFFF;
+- Buffer[Pos] = (byte) (Word >> 8);
+- Buffer[Pos+1] = (byte) (Word & 0x00FF);
+- }
+-
+- public static void SetShortAt(byte[] Buffer, int Pos, int Value)
+- {
+- Buffer[Pos] = (byte) (Value >> 8);
+- Buffer[Pos+1] = (byte) (Value & 0x00FF);
+- }
+- public static void SetDWordAt(byte[] Buffer, int Pos, long Value)
+- {
+- long DWord = Value &0x0FFFFFFFF;
+- Buffer[Pos+3] = (byte) (DWord &0xFF);
+- Buffer[Pos+2] = (byte) ((DWord >> 8) &0xFF);
+- Buffer[Pos+1] = (byte) ((DWord >> 16) &0xFF);
+- Buffer[Pos] = (byte) ((DWord >> 24) &0xFF);
+- }
+-
+- public static void SetDIntAt(byte[] Buffer, int Pos, int Value)
+- {
+- Buffer[Pos+3] = (byte) (Value &0xFF);
+- Buffer[Pos+2] = (byte) ((Value >> 8) &0xFF);
+- Buffer[Pos+1] = (byte) ((Value >> 16) &0xFF);
+- Buffer[Pos] = (byte) ((Value >> 24) &0xFF);
+- }
+-
+- public static void SetFloatAt(byte[] Buffer, int Pos, float Value)
+- {
+- int DInt = Float.floatToIntBits(Value);
+- SetDIntAt(Buffer, Pos, DInt);
+- }
+-
+- public static void SetDateAt(byte[] Buffer, int Pos, Date DateTime)
+- {
+- int Year, Month, Day, Hour, Min, Sec, Dow;
+- Calendar S7Date = Calendar.getInstance();
+- S7Date.setTime(DateTime);
+-
+- Year = S7Date.get(Calendar.YEAR);
+- Month = S7Date.get(Calendar.MONTH)+1;
+- Day = S7Date.get(Calendar.DAY_OF_MONTH);
+- Hour = S7Date.get(Calendar.HOUR_OF_DAY);
+- Min = S7Date.get(Calendar.MINUTE);
+- Sec = S7Date.get(Calendar.SECOND);
+- Dow = S7Date.get(Calendar.DAY_OF_WEEK);
+-
+- if (Year>1999)
+- Year-=2000;
+-
+- Buffer[Pos] =ByteToBCD(Year);
+- Buffer[Pos+1]=ByteToBCD(Month);
+- Buffer[Pos+2]=ByteToBCD(Day);
+- Buffer[Pos+3]=ByteToBCD(Hour);
+- Buffer[Pos+4]=ByteToBCD(Min);
+- Buffer[Pos+5]=ByteToBCD(Sec);
+- Buffer[Pos+6]=0;
+- Buffer[Pos+7]=ByteToBCD(Dow);
+- }
+-
+- public static int BCDtoByte(byte B)
+- {
+- return ((B >> 4) * 10) + (B & 0x0F);
+- }
+-
+- public static byte ByteToBCD(int Value)
+- {
+- return (byte) (((Value / 10) << 4) | (Value % 10));
+- }
+-
+-}
++/*=============================================================================|
++| PROJECT Moka7 1.0.2 |
++|==============================================================================|
++| Copyright (C) 2013, 2016 Davide Nardella |
++| All rights reserved. |
++|==============================================================================|
++| SNAP7 is free software: you can redistribute it and/or modify |
++| it under the terms of the Lesser GNU General Public License as published by |
++| the Free Software Foundation, either version 3 of the License, or under |
++| EPL Eclipse Public License 1.0. |
++| |
++| This means that you have to chose in advance which take before you import |
++| the library into your project. |
++| |
++| SNAP7 is distributed in the hope that it will be useful, |
++| but WITHOUT ANY WARRANTY; without even the implied warranty of |
++| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you |
++| decide to adopt. |
++| |
++|=============================================================================*/
++package Moka7;
++
++import java.io.UnsupportedEncodingException;
++import java.util.Date;
++import java.util.Calendar;
++
++/**
++ *
++ * @author Davide Nardella
++ */
++
++
++// Step 7 Constants and Conversion helper class
++public class S7 {
++ // S7 ID Area (Area that we want to read/write)
++ public static final int S7AreaPE = 0x81;
++ public static final int S7AreaPA = 0x82;
++ public static final int S7AreaMK = 0x83;
++ public static final int S7AreaDB = 0x84;
++ public static final int S7AreaCT = 0x1C;
++ public static final int S7AreaTM = 0x1D;
++ // Connection types
++ public static final byte PG = 0x01;
++ public static final byte OP = 0x02;
++ public static final byte S7_BASIC = 0x03;
++ // Block type
++ public static final int Block_OB = 0x38;
++ public static final int Block_DB = 0x41;
++ public static final int Block_SDB = 0x42;
++ public static final int Block_FC = 0x43;
++ public static final int Block_SFC = 0x44;
++ public static final int Block_FB = 0x45;
++ public static final int Block_SFB = 0x46;
++ // Sub Block Type
++ public static final int SubBlk_OB = 0x08;
++ public static final int SubBlk_DB = 0x0A;
++ public static final int SubBlk_SDB = 0x0B;
++ public static final int SubBlk_FC = 0x0C;
++ public static final int SubBlk_SFC = 0x0D;
++ public static final int SubBlk_FB = 0x0E;
++ public static final int SubBlk_SFB = 0x0F;
++ // Block languages
++ public static final int BlockLangAWL = 0x01;
++ public static final int BlockLangKOP = 0x02;
++ public static final int BlockLangFUP = 0x03;
++ public static final int BlockLangSCL = 0x04;
++ public static final int BlockLangDB = 0x05;
++ public static final int BlockLangGRAPH = 0x06;
++ // PLC Status
++ public static final int S7CpuStatusUnknown = 0x00;
++ public static final int S7CpuStatusRun = 0x08;
++ public static final int S7CpuStatusStop = 0x04;
++ // Type Var
++ public static final int S7TypeBool = 1;
++ public static final int S7TypeInt = 1;
++
++ // Returns the bit at Pos.Bit
++ public static boolean GetBitAt(byte[] Buffer, int Pos, int Bit)
++ {
++ int Value = Buffer[Pos] & 0x0FF;
++ byte[] Mask = {
++ (byte)0x01,(byte)0x02,(byte)0x04,(byte)0x08,
++ (byte)0x10,(byte)0x20,(byte)0x40,(byte)0x80
++ };
++ if (Bit<0) Bit=0;
++ if (Bit>7) Bit=7;
++
++ return (Value & Mask[Bit])!=0;
++ }
++ /**
++ * Returns a 16 bit unsigned value : from 0 to 65535 (2^16-1)
++ * @param Buffer
++ * @param Pos start position
++ * @return
++ */
++ public static int GetWordAt(byte[] Buffer, int Pos)
++ {
++ int hi = (Buffer[Pos] & 0x00FF);
++ int lo = (Buffer[Pos+1] & 0x00FF);
++ return (hi<<8)+lo;
++ }
++
++ // Returns a 16 bit signed value : from -32768 to 32767
++ public static int GetShortAt(byte[] Buffer, int Pos)
++ {
++ int hi = (Buffer[Pos]);
++ int lo = (Buffer[Pos+1] & 0x00FF);
++ return ((hi<<8)+lo);
++ }
++
++ // Returns a 32 bit unsigned value : from 0 to 4294967295 (2^32-1)
++ public static long GetDWordAt(byte[] Buffer, int Pos)
++ {
++ long Result;
++ Result=(long)(Buffer[Pos] & 0x0FF);
++ Result<<=8;
++ Result+=(long)(Buffer[Pos+1] & 0x0FF);
++ Result<<=8;
++ Result+=(long)(Buffer[Pos+2] & 0x0FF);
++ Result<<=8;
++ Result+=(long)(Buffer[Pos+3] & 0x0FF);
++ return Result;
++ }
++
++ // Returns a 32 bit signed value : from 0 to 4294967295 (2^32-1)
++ public static int GetDIntAt(byte[] Buffer, int Pos)
++ {
++ int Result;
++ Result= Buffer[Pos];
++ Result<<=8;
++ Result+=(Buffer[Pos+1] & 0x0FF);
++ Result<<=8;
++ Result+=(Buffer[Pos+2] & 0x0FF);
++ Result<<=8;
++ Result+=(Buffer[Pos+3] & 0x0FF);
++ return Result;
++ }
++
++ // Returns a 32 bit floating point
++ public static float GetFloatAt(byte[] Buffer, int Pos)
++ {
++ int IntFloat = GetDIntAt(Buffer, Pos);
++ return Float.intBitsToFloat(IntFloat);
++ }
++
++ // Returns an ASCII string
++ public static String GetStringAt(byte[] Buffer, int Pos, int MaxLen)
++ {
++ byte[] StrBuffer = new byte[MaxLen];
++ System.arraycopy(Buffer, Pos, StrBuffer, 0, MaxLen);
++ String S;
++ try {
++ S = new String(StrBuffer, "UTF-8"); // the charset is UTF-8
++ } catch (UnsupportedEncodingException ex) {
++ S = "";
++ }
++ return S;
++ }
++
++ public static String GetPrintableStringAt(byte[] Buffer, int Pos, int MaxLen)
++ {
++ byte[] StrBuffer = new byte[MaxLen];
++ System.arraycopy(Buffer, Pos, StrBuffer, 0, MaxLen);
++ for (int c = 0; c < MaxLen; c++)
++ {
++ if ((StrBuffer[c]<31) || (StrBuffer[c]>126))
++ StrBuffer[c]=46; // '.'
++ }
++ String S;
++ try {
++ S = new String(StrBuffer, "UTF-8"); // the charset is UTF-8
++ } catch (UnsupportedEncodingException ex) {
++ S = "";
++ }
++ return S;
++ }
++
++ public static Date GetDateAt(byte[] Buffer, int Pos)
++ {
++ int Year, Month, Day, Hour, Min, Sec;
++ Calendar S7Date = Calendar.getInstance();
++
++ 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]);
++
++ S7Date.set(Year, Month, Day, Hour, Min, Sec);
++
++ return S7Date.getTime();
++ }
++
++ public static void SetBitAt(byte[] Buffer, int Pos, int Bit, boolean Value)
++ {
++ byte[] Mask = {
++ (byte)0x01,(byte)0x02,(byte)0x04,(byte)0x08,
++ (byte)0x10,(byte)0x20,(byte)0x40,(byte)0x80
++ };
++ if (Bit<0) Bit=0;
++ if (Bit>7) Bit=7;
++
++ if (Value)
++ Buffer[Pos]= (byte) (Buffer[Pos] | Mask[Bit]);
++ else
++ Buffer[Pos]= (byte) (Buffer[Pos] & ~Mask[Bit]);
++ }
++
++ public static void SetWordAt(byte[] Buffer, int Pos, int Value)
++ {
++ int Word = Value & 0x0FFFF;
++ Buffer[Pos] = (byte) (Word >> 8);
++ Buffer[Pos+1] = (byte) (Word & 0x00FF);
++ }
++
++ public static void SetShortAt(byte[] Buffer, int Pos, int Value)
++ {
++ Buffer[Pos] = (byte) (Value >> 8);
++ Buffer[Pos+1] = (byte) (Value & 0x00FF);
++ }
++ public static void SetDWordAt(byte[] Buffer, int Pos, long Value)
++ {
++ long DWord = Value &0x0FFFFFFFF;
++ Buffer[Pos+3] = (byte) (DWord &0xFF);
++ Buffer[Pos+2] = (byte) ((DWord >> 8) &0xFF);
++ Buffer[Pos+1] = (byte) ((DWord >> 16) &0xFF);
++ Buffer[Pos] = (byte) ((DWord >> 24) &0xFF);
++ }
++
++ public static void SetDIntAt(byte[] Buffer, int Pos, int Value)
++ {
++ Buffer[Pos+3] = (byte) (Value &0xFF);
++ Buffer[Pos+2] = (byte) ((Value >> 8) &0xFF);
++ Buffer[Pos+1] = (byte) ((Value >> 16) &0xFF);
++ Buffer[Pos] = (byte) ((Value >> 24) &0xFF);
++ }
++
++ public static void SetFloatAt(byte[] Buffer, int Pos, float Value)
++ {
++ int DInt = Float.floatToIntBits(Value);
++ SetDIntAt(Buffer, Pos, DInt);
++ }
++
++ public static void SetDateAt(byte[] Buffer, int Pos, Date DateTime)
++ {
++ int Year, Month, Day, Hour, Min, Sec, Dow;
++ Calendar S7Date = Calendar.getInstance();
++ S7Date.setTime(DateTime);
++
++ Year = S7Date.get(Calendar.YEAR);
++ Month = S7Date.get(Calendar.MONTH)+1;
++ Day = S7Date.get(Calendar.DAY_OF_MONTH);
++ Hour = S7Date.get(Calendar.HOUR_OF_DAY);
++ Min = S7Date.get(Calendar.MINUTE);
++ Sec = S7Date.get(Calendar.SECOND);
++ Dow = S7Date.get(Calendar.DAY_OF_WEEK);
++
++ if (Year>1999)
++ Year-=2000;
++
++ Buffer[Pos] =ByteToBCD(Year);
++ Buffer[Pos+1]=ByteToBCD(Month);
++ Buffer[Pos+2]=ByteToBCD(Day);
++ Buffer[Pos+3]=ByteToBCD(Hour);
++ Buffer[Pos+4]=ByteToBCD(Min);
++ Buffer[Pos+5]=ByteToBCD(Sec);
++ Buffer[Pos+6]=0;
++ Buffer[Pos+7]=ByteToBCD(Dow);
++ }
++
++ public static int BCDtoByte(byte B)
++ {
++ return ((B >> 4) * 10) + (B & 0x0F);
++ }
++
++ public static byte ByteToBCD(int Value)
++ {
++ return (byte) (((Value / 10) << 4) | (Value % 10));
++ }
++
++}
+diff U3 S7BlockInfo.java S7BlockInfo.java
+--- S7BlockInfo.java Thu Mar 23 15:34:52 2017
++++ S7BlockInfo.java Tue Aug 08 18:53:37 2017
+@@ -1,101 +1,101 @@
+-/*=============================================================================|
+-| PROJECT Moka7 1.0.2 |
+-|==============================================================================|
+-| Copyright (C) 2013, 2016 Davide Nardella |
+-| All rights reserved. |
+-|==============================================================================|
+-| SNAP7 is free software: you can redistribute it and/or modify |
+-| it under the terms of the Lesser GNU General Public License as published by |
+-| the Free Software Foundation, either version 3 of the License, or under |
+-| EPL Eclipse Public License 1.0. |
+-| |
+-| This means that you have to chose in advance which take before you import |
+-| the library into your project. |
+-| |
+-| SNAP7 is distributed in the hope that it will be useful, |
+-| but WITHOUT ANY WARRANTY; without even the implied warranty of |
+-| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you |
+-| decide to adopt. |
+-| |
+-|=============================================================================*/
+-package Moka7;
+-import java.util.Date;
+-/**
+- *
+- * @author Davide
+- */
+-public class S7BlockInfo {
+-
+- private final int BufSize = 96;
+- // MilliSeconds between 1970/1/1 (Java time base) and 1984/1/1 (Siemens base)
+- private final long DeltaMilliSecs = 441763200000L;
+- protected byte[] Buffer = new byte[BufSize];
+-
+- protected void Update(byte[] Src, int Pos)
+- {
+- System.arraycopy(Src, Pos, Buffer, 0, BufSize);
+- }
+- public int BlkType()
+- {
+- return Buffer[2];
+- }
+- public int BlkNumber()
+- {
+- return S7.GetWordAt(Buffer, 3);
+- }
+- public int BlkLang()
+- {
+- return Buffer[1];
+- }
+- public int BlkFlags()
+- {
+- return Buffer[0];
+- }
+- public int MC7Size() // The real size in bytes
+- {
+- return S7.GetWordAt(Buffer, 31);
+- }
+- public int LoadSize()
+- {
+- return S7.GetDIntAt(Buffer, 5);
+- }
+- public int LocalData()
+- {
+- return S7.GetWordAt(Buffer, 29);
+- }
+- public int SBBLength()
+- {
+- return S7.GetWordAt(Buffer, 25);
+- }
+- public int Checksum()
+- {
+- return S7.GetWordAt(Buffer, 59);
+- }
+- public int Version()
+- {
+- return Buffer[57];
+- }
+- public Date CodeDate()
+- {
+- long BlockDate = ((long)S7.GetWordAt(Buffer, 17))*86400000L+DeltaMilliSecs;
+- return new Date(BlockDate);
+- }
+- public Date IntfDate()
+- {
+- long BlockDate = ((long)S7.GetWordAt(Buffer, 23))*86400000L+DeltaMilliSecs;
+- return new Date(BlockDate);
+- }
+- public String Author()
+- {
+- return S7.GetStringAt(Buffer,33,8);
+- }
+- public String Family()
+- {
+- return S7.GetStringAt(Buffer,41,8);
+- }
+- public String Header()
+- {
+- return S7.GetStringAt(Buffer,49,8);
+- }
+-
+-}
++/*=============================================================================|
++| PROJECT Moka7 1.0.2 |
++|==============================================================================|
++| Copyright (C) 2013, 2016 Davide Nardella |
++| All rights reserved. |
++|==============================================================================|
++| SNAP7 is free software: you can redistribute it and/or modify |
++| it under the terms of the Lesser GNU General Public License as published by |
++| the Free Software Foundation, either version 3 of the License, or under |
++| EPL Eclipse Public License 1.0. |
++| |
++| This means that you have to chose in advance which take before you import |
++| the library into your project. |
++| |
++| SNAP7 is distributed in the hope that it will be useful, |
++| but WITHOUT ANY WARRANTY; without even the implied warranty of |
++| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you |
++| decide to adopt. |
++| |
++|=============================================================================*/
++package Moka7;
++import java.util.Date;
++/**
++ *
++ * @author Davide Nardella
++ */
++public class S7BlockInfo {
++
++ private final int BufSize = 96;
++ // MilliSeconds between 1970/1/1 (Java time base) and 1984/1/1 (Siemens base)
++ private final long DeltaMilliSecs = 441763200000L;
++ protected byte[] Buffer = new byte[BufSize];
++
++ protected void Update(byte[] Src, int Pos)
++ {
++ System.arraycopy(Src, Pos, Buffer, 0, BufSize);
++ }
++ public int BlkType()
++ {
++ return Buffer[2];
++ }
++ public int BlkNumber()
++ {
++ return S7.GetWordAt(Buffer, 3);
++ }
++ public int BlkLang()
++ {
++ return Buffer[1];
++ }
++ public int BlkFlags()
++ {
++ return Buffer[0];
++ }
++ public int MC7Size() // The real size in bytes
++ {
++ return S7.GetWordAt(Buffer, 31);
++ }
++ public int LoadSize()
++ {
++ return S7.GetDIntAt(Buffer, 5);
++ }
++ public int LocalData()
++ {
++ return S7.GetWordAt(Buffer, 29);
++ }
++ public int SBBLength()
++ {
++ return S7.GetWordAt(Buffer, 25);
++ }
++ public int Checksum()
++ {
++ return S7.GetWordAt(Buffer, 59);
++ }
++ public int Version()
++ {
++ return Buffer[57];
++ }
++ public Date CodeDate()
++ {
++ long BlockDate = ((long)S7.GetWordAt(Buffer, 17))*86400000L+DeltaMilliSecs;
++ return new Date(BlockDate);
++ }
++ public Date IntfDate()
++ {
++ long BlockDate = ((long)S7.GetWordAt(Buffer, 23))*86400000L+DeltaMilliSecs;
++ return new Date(BlockDate);
++ }
++ public String Author()
++ {
++ return S7.GetStringAt(Buffer,33,8);
++ }
++ public String Family()
++ {
++ return S7.GetStringAt(Buffer,41,8);
++ }
++ public String Header()
++ {
++ return S7.GetStringAt(Buffer,49,8);
++ }
++
++}
+diff U3 S7Client.java S7Client.java
+--- S7Client.java Thu Mar 23 15:34:52 2017
++++ S7Client.java Tue Aug 08 18:53:37 2017
+@@ -1,1214 +1,1233 @@
+-/*=============================================================================|
+-| PROJECT Moka7 1.0.2 |
+-|==============================================================================|
+-| Copyright (C) 2013, 2016 Davide Nardella |
+-| All rights reserved. |
+-|==============================================================================|
+-| SNAP7 is free software: you can redistribute it and/or modify |
+-| it under the terms of the Lesser GNU General Public License as published by |
+-| the Free Software Foundation, either version 3 of the License, or under |
+-| EPL Eclipse Public License 1.0. |
+-| |
+-| This means that you have to chose in advance which take before you import |
+-| the library into your project. |
+-| |
+-| SNAP7 is distributed in the hope that it will be useful, |
+-| but WITHOUT ANY WARRANTY; without even the implied warranty of |
+-| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you |
+-| decide to adopt. |
+-| |
+-|=============================================================================*/
+-package Moka7;
+-
+-import java.io.DataInputStream;
+-import java.io.DataOutputStream;
+-import java.io.IOException;
+-import java.io.UnsupportedEncodingException;
+-import java.net.InetSocketAddress;
+-import java.net.Socket;
+-import java.net.SocketAddress;
+-import java.util.Date;
+-
+-
+-/**
+- *
+- * @author Dave Nardella
+- */
+-public class S7Client
+-{
+- // WordLength
+- private static final byte S7WLByte =0x02;
+- private static final byte S7WLCounter =0x1C;
+- private static final byte S7WLTimer =0x1D;
+- // Error Codes
+- public static final int errTCPConnectionFailed = 0x0001;
+- public static final int errTCPDataSend = 0x0002;
+- public static final int errTCPDataRecv = 0x0003;
+- public static final int errTCPDataRecvTout = 0x0004;
+- public static final int errTCPConnectionReset = 0x0005;
+- public static final int errISOInvalidPDU = 0x0006;
+- public static final int errISOConnectionFailed = 0x0007;
+- public static final int errISONegotiatingPDU = 0x0008;
+- public static final int errS7InvalidPDU = 0x0009;
+- public static final int errS7DataRead = 0x000A;
+- public static final int errS7DataWrite = 0x000B;
+- public static final int errS7BufferTooSmall = 0x000C;
+- public static final int errS7FunctionError = 0x000D;
+- public static final int errS7InvalidParams = 0x000E;
+-
+- // Public fields
+- public boolean Connected = false;
+- public int LastError = 0;
+- public int RecvTimeout = 2000;
+-
+- // Privates
+- private static final int ISOTCP = 102; // ISOTCP Port
+- private static final int MinPduSize = 16;
+- private static final int DefaultPduSizeRequested = 480;
+- private static final int IsoHSize = 7; // TPKT+COTP Header Size
+- private static final int MaxPduSize = DefaultPduSizeRequested+IsoHSize;
+-
+-
+- private Socket TCPSocket;
+- private final byte[] PDU = new byte[2048];
+-
+- private DataInputStream InStream = null;
+- private DataOutputStream OutStream = null;
+-
+- private String IPAddress;
+-
+- private byte LocalTSAP_HI;
+- private byte LocalTSAP_LO;
+- private byte RemoteTSAP_HI;
+- private byte RemoteTSAP_LO;
+- private byte LastPDUType;
+-
+- private short ConnType = S7.PG;
+- private int _PDULength = 0;
+-
+- // Telegrams
+- // ISO Connection Request telegram (contains also ISO Header and COTP Header)
+- private static final byte ISO_CR[] = {
+- // TPKT (RFC1006 Header)
+- (byte)0x03, // RFC 1006 ID (3)
+- (byte)0x00, // Reserved, always 0
+- (byte)0x00, // High part of packet lenght (entire frame, payload and TPDU included)
+- (byte)0x16, // Low part of packet lenght (entire frame, payload and TPDU included)
+- // COTP (ISO 8073 Header)
+- (byte)0x11, // PDU Size Length
+- (byte)0xE0, // CR - Connection Request ID
+- (byte)0x00, // Dst Reference HI
+- (byte)0x00, // Dst Reference LO
+- (byte)0x00, // Src Reference HI
+- (byte)0x01, // Src Reference LO
+- (byte)0x00, // Class + Options Flags
+- (byte)0xC0, // PDU Max Length ID
+- (byte)0x01, // PDU Max Length HI
+- (byte)0x0A, // PDU Max Length LO
+- (byte)0xC1, // Src TSAP Identifier
+- (byte)0x02, // Src TSAP Length (2 bytes)
+- (byte)0x01, // Src TSAP HI (will be overwritten)
+- (byte)0x00, // Src TSAP LO (will be overwritten)
+- (byte)0xC2, // Dst TSAP Identifier
+- (byte)0x02, // Dst TSAP Length (2 bytes)
+- (byte)0x01, // Dst TSAP HI (will be overwritten)
+- (byte)0x02 // Dst TSAP LO (will be overwritten)
+- };
+-
+- // S7 PDU Negotiation Telegram (contains also ISO Header and COTP Header)
+- private static final byte S7_PN[] = {
+- (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x19,
+- (byte)0x02, (byte)0xf0, (byte)0x80, // TPKT + COTP (see above for info)
+- (byte)0x32, (byte)0x01, (byte)0x00, (byte)0x00,
+- (byte)0x04, (byte)0x00, (byte)0x00, (byte)0x08,
+- (byte)0x00, (byte)0x00, (byte)0xf0, (byte)0x00,
+- (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x01,
+- (byte)0x00, (byte)0x1e // PDU Length Requested = HI-LO 480 bytes
+- };
+-
+- // S7 Read/Write Request Header (contains also ISO Header and COTP Header)
+- private static final byte S7_RW[] = { // 31-35 bytes
+- (byte)0x03,(byte)0x00,
+- (byte)0x00,(byte)0x1f, // Telegram Length (Data Size + 31 or 35)
+- (byte)0x02,(byte)0xf0, (byte)0x80, // COTP (see above for info)
+- (byte)0x32, // S7 Protocol ID
+- (byte)0x01, // Job Type
+- (byte)0x00,(byte)0x00, // Redundancy identification
+- (byte)0x05,(byte)0x00, // PDU Reference
+- (byte)0x00,(byte)0x0e, // Parameters Length
+- (byte)0x00,(byte)0x00, // Data Length = Size(bytes) + 4
+- (byte)0x04, // Function 4 Read Var, 5 Write Var
+- (byte)0x01, // Items count
+- (byte)0x12, // Var spec.
+- (byte)0x0a, // Length of remaining bytes
+- (byte)0x10, // Syntax ID
+- S7WLByte, // Transport Size
+- (byte)0x00,(byte)0x00, // Num Elements
+- (byte)0x00,(byte)0x00, // DB Number (if any, else 0)
+- (byte)0x84, // Area Type
+- (byte)0x00,(byte)0x00,(byte)0x00, // Area Offset
+- // WR area
+- (byte)0x00, // Reserved
+- (byte)0x04, // Transport size
+- (byte)0x00,(byte)0x00, // Data Length * 8 (if not timer or counter)
+- };
+- private static final int Size_RD = 31;
+- private static final int Size_WR = 35;
+-
+- // S7 Get Block Info Request Header (contains also ISO Header and COTP Header)
+- private static final byte S7_BI[] = {
+- (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x25,
+- (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
+- (byte)0x07, (byte)0x00, (byte)0x00, (byte)0x05,
+- (byte)0x00, (byte)0x00, (byte)0x08, (byte)0x00,
+- (byte)0x0c, (byte)0x00, (byte)0x01, (byte)0x12,
+- (byte)0x04, (byte)0x11, (byte)0x43, (byte)0x03,
+- (byte)0x00, (byte)0xff, (byte)0x09, (byte)0x00,
+- (byte)0x08, (byte)0x30,
+- (byte)0x41, // Block Type
+- (byte)0x30, (byte)0x30, (byte)0x30, (byte)0x30, (byte)0x30, // ASCII Block Number
+- (byte)0x41
+- };
+-
+- // SZL First telegram request
+- private static final byte S7_SZL_FIRST[] = {
+- (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x21,
+- (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
+- (byte)0x07, (byte)0x00, (byte)0x00,
+- (byte)0x05, (byte)0x00, // Sequence out
+- (byte)0x00, (byte)0x08, (byte)0x00,
+- (byte)0x08, (byte)0x00, (byte)0x01, (byte)0x12,
+- (byte)0x04, (byte)0x11, (byte)0x44, (byte)0x01,
+- (byte)0x00, (byte)0xff, (byte)0x09, (byte)0x00,
+- (byte)0x04,
+- (byte)0x00, (byte)0x00, // ID (29)
+- (byte)0x00, (byte)0x00 // Index (31)
+- };
+-
+- // SZL Next telegram request
+- private static final byte S7_SZL_NEXT[] = {
+- (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x21,
+- (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
+- (byte)0x07, (byte)0x00, (byte)0x00, (byte)0x06,
+- (byte)0x00, (byte)0x00, (byte)0x0c, (byte)0x00,
+- (byte)0x04, (byte)0x00, (byte)0x01, (byte)0x12,
+- (byte)0x08, (byte)0x12, (byte)0x44, (byte)0x01,
+- (byte)0x01, // Sequence
+- (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+- (byte)0x0a, (byte)0x00, (byte)0x00, (byte)0x00
+- };
+-
+- // Get Date/Time request
+- private static final byte S7_GET_DT[] = {
+- (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x1d,
+- (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
+- (byte)0x07, (byte)0x00, (byte)0x00, (byte)0x38,
+- (byte)0x00, (byte)0x00, (byte)0x08, (byte)0x00,
+- (byte)0x04, (byte)0x00, (byte)0x01, (byte)0x12,
+- (byte)0x04, (byte)0x11, (byte)0x47, (byte)0x01,
+- (byte)0x00, (byte)0x0a, (byte)0x00, (byte)0x00,
+- (byte)0x00
+- };
+-
+- // Set Date/Time command
+- private static final byte S7_SET_DT[] = {
+- (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x27,
+- (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
+- (byte)0x07, (byte)0x00, (byte)0x00, (byte)0x89,
+- (byte)0x03, (byte)0x00, (byte)0x08, (byte)0x00,
+- (byte)0x0e, (byte)0x00, (byte)0x01, (byte)0x12,
+- (byte)0x04, (byte)0x11, (byte)0x47, (byte)0x02,
+- (byte)0x00, (byte)0xff, (byte)0x09, (byte)0x00,
+- (byte)0x0a, (byte)0x00, (byte)0x19, // Hi part of Year
+- (byte)0x13, // Lo part of Year
+- (byte)0x12, // Month
+- (byte)0x06, // Day
+- (byte)0x17, // Hour
+- (byte)0x37, // Min
+- (byte)0x13, // Sec
+- (byte)0x00, (byte)0x01 // ms + Day of week
+- };
+-
+- // S7 STOP request
+- private static final byte S7_STOP[] = {
+- (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x21,
+- (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
+- (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x0e,
+- (byte)0x00, (byte)0x00, (byte)0x10, (byte)0x00,
+- (byte)0x00, (byte)0x29, (byte)0x00, (byte)0x00,
+- (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x09,
+- (byte)0x50, (byte)0x5f, (byte)0x50, (byte)0x52,
+- (byte)0x4f, (byte)0x47, (byte)0x52, (byte)0x41,
+- (byte)0x4d
+- };
+-
+- // S7 HOT Start request
+- private static final byte S7_HOT_START[] = {
+- (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x25,
+- (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
+- (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x0c,
+- (byte)0x00, (byte)0x00, (byte)0x14, (byte)0x00,
+- (byte)0x00, (byte)0x28, (byte)0x00, (byte)0x00,
+- (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+- (byte)0xfd, (byte)0x00, (byte)0x00, (byte)0x09,
+- (byte)0x50, (byte)0x5f, (byte)0x50, (byte)0x52,
+- (byte)0x4f, (byte)0x47, (byte)0x52, (byte)0x41,
+- (byte)0x4d
+- };
+-
+- // S7 COLD Start request
+- private static final byte S7_COLD_START[] = {
+- (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x27,
+- (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
+- (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x0f,
+- (byte)0x00, (byte)0x00, (byte)0x16, (byte)0x00,
+- (byte)0x00, (byte)0x28, (byte)0x00, (byte)0x00,
+- (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+- (byte)0xfd, (byte)0x00, (byte)0x02, (byte)0x43,
+- (byte)0x20, (byte)0x09, (byte)0x50, (byte)0x5f,
+- (byte)0x50, (byte)0x52, (byte)0x4f, (byte)0x47,
+- (byte)0x52, (byte)0x41, (byte)0x4d
+- };
+-
+- // S7 Get PLC Status
+- private static final byte S7_GET_STAT[] = {
+- (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x21,
+- (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
+- (byte)0x07, (byte)0x00, (byte)0x00, (byte)0x2c,
+- (byte)0x00, (byte)0x00, (byte)0x08, (byte)0x00,
+- (byte)0x08, (byte)0x00, (byte)0x01, (byte)0x12,
+- (byte)0x04, (byte)0x11, (byte)0x44, (byte)0x01,
+- (byte)0x00, (byte)0xff, (byte)0x09, (byte)0x00,
+- (byte)0x04, (byte)0x04, (byte)0x24, (byte)0x00,
+- (byte)0x00
+- };
+-
+- // S7 Set Session Password
+- private static final byte S7_SET_PWD[] = {
+- (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x25,
+- (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
+- (byte)0x07, (byte)0x00, (byte)0x00, (byte)0x27,
+- (byte)0x00, (byte)0x00, (byte)0x08, (byte)0x00,
+- (byte)0x0c, (byte)0x00, (byte)0x01, (byte)0x12,
+- (byte)0x04, (byte)0x11, (byte)0x45, (byte)0x01,
+- (byte)0x00, (byte)0xff, (byte)0x09, (byte)0x00,
+- (byte)0x08,
+- // 8 Char Encoded Password
+- (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+- (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00
+- };
+-
+- // S7 Clear Session Password
+- private static final byte S7_CLR_PWD[] = {
+- (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x1d,
+- (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
+- (byte)0x07, (byte)0x00, (byte)0x00, (byte)0x29,
+- (byte)0x00, (byte)0x00, (byte)0x08, (byte)0x00,
+- (byte)0x04, (byte)0x00, (byte)0x01, (byte)0x12,
+- (byte)0x04, (byte)0x11, (byte)0x45, (byte)0x02,
+- (byte)0x00, (byte)0x0a, (byte)0x00, (byte)0x00,
+- (byte)0x00
+- };
+-
+- public S7Client()
+- {
+- // Placeholder for future implementations
+- }
+-
+- public static String ErrorText(int Error)
+- {
+- switch (Error)
+- {
+- case errTCPConnectionFailed :
+- return "TCP Connection failed.";
+- case errTCPDataSend :
+- return "TCP Sending error.";
+- case errTCPDataRecv :
+- return "TCP Receiving error.";
+- case errTCPDataRecvTout :
+- return "Data Receiving timeout.";
+- case errTCPConnectionReset :
+- return "Connection reset by the peer.";
+- case errISOInvalidPDU :
+- return "Invalid ISO PDU received.";
+- case errISOConnectionFailed :
+- return "ISO connection refused by the CPU.";
+- case errISONegotiatingPDU :
+- return "ISO error negotiating the PDU length.";
+- case errS7InvalidPDU :
+- return "Invalid S7 PDU received.";
+- case errS7DataRead :
+- return "S7 Error reading data from the CPU.";
+- case errS7DataWrite :
+- return "S7 Error writing data to the CPU.";
+- case errS7BufferTooSmall :
+- return "The Buffer supplied to the function is too small.";
+- case errS7FunctionError :
+- return "S7 function refused by the CPU.";
+- case errS7InvalidParams :
+- return "Invalid parameters supplied to the function.";
+- default :
+- return "Unknown error : 0x"+Integer.toHexString(Error);
+- }
+- }
+-
+- private int TCPConnect()
+- {
+- SocketAddress sockaddr = new InetSocketAddress(IPAddress, ISOTCP);
+- LastError=0;
+- try {
+- TCPSocket = new Socket();
+- TCPSocket.connect(sockaddr ,5000);
+- TCPSocket.setTcpNoDelay(true);
+- InStream = new DataInputStream(TCPSocket.getInputStream());
+- OutStream = new DataOutputStream(TCPSocket.getOutputStream());
+- }
+- catch (IOException e) {
+- LastError=errTCPConnectionFailed;
+- }
+- return LastError;
+- }
+-
+- private int WaitForData(int Size, int Timeout)
+- {
+- int cnt = 0;
+- LastError=0;
+- int SizeAvail;
+- boolean Expired = false;
+- try
+- {
+- SizeAvail=InStream.available();
+- while ((SizeAvail<Size) && (!Expired) && (LastError==0))
+- {
+-
+- cnt++;
+- try {
+- Thread.sleep(1);
+- }
+- catch (InterruptedException ex) {
+- LastError=errTCPDataRecvTout;
+- }
+- SizeAvail=InStream.available();
+- Expired=cnt>Timeout;
+- // If timeout we clean the buffer
+- if (Expired && (SizeAvail>0) && (LastError==0))
+- InStream.read(PDU, 0, SizeAvail);
+- }
+- }
+- catch (IOException ex)
+- {
+- LastError=errTCPDataRecvTout;
+- }
+- if (cnt>=Timeout)
+- {
+- LastError=errTCPDataRecvTout;
+- }
+- return LastError;
+- }
+-
+- private int RecvPacket(byte[] Buffer, int Start, int Size)
+- {
+- int BytesRead=0;
+- LastError=WaitForData(Size,RecvTimeout);
+- if (LastError==0)
+- {
+- try {
+- BytesRead = InStream.read(Buffer, Start, Size);
+- } catch (IOException ex) {
+- LastError=errTCPDataRecv;
+- }
+- if (BytesRead==0)
+- LastError=errTCPConnectionReset;
+- }
+- return LastError;
+- }
+-
+- private void SendPacket(byte[] Buffer, int Len)
+- {
+- LastError = 0;
+- try {
+- OutStream.write(Buffer,0,Len);
+- OutStream.flush();
+- } catch (IOException ex) {
+- LastError = errTCPDataSend;
+- }
+- }
+- private void SendPacket(byte[] Buffer)
+- {
+- SendPacket(Buffer,Buffer.length);
+- }
+-
+- 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;
+- }
+-
+- private int ISOConnect()
+- {
+- int Size;
+- ISO_CR[16]=LocalTSAP_HI;
+- ISO_CR[17]=LocalTSAP_LO;
+- ISO_CR[20]=RemoteTSAP_HI;
+- ISO_CR[21]=RemoteTSAP_LO;
+-
+- // Sends the connection request telegram
+- SendPacket(ISO_CR);
+- if (LastError==0)
+- {
+- // Gets the reply (if any)
+- Size=RecvIsoPacket();
+- if (LastError==0)
+- {
+- if (Size==22)
+- {
+- if (LastPDUType!=(byte)0xD0) // 0xD0 = CC Connection confirm
+- LastError=errISOConnectionFailed;
+- }
+- else
+- LastError=errISOInvalidPDU;
+- }
+- }
+- return LastError;
+- }
+-
+- 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 void SetConnectionType(short ConnectionType)
+- {
+- ConnType=ConnectionType;
+- }
+-
+- public int Connect()
+- {
+- LastError=0;
+- if (!Connected)
+- {
+- TCPConnect();
+- if (LastError==0) // First stage : TCP Connection
+- {
+- ISOConnect();
+- if (LastError==0) // Second stage : ISOTCP (ISO 8073) Connection
+- {
+- LastError=NegotiatePduLength(); // Third stage : S7 PDU negotiation
+- }
+- }
+- }
+- Connected=LastError==0;
+-
+- // In case the connection is not completely established (TCP connection + ISO connection + PDU negotiation)
+- // we close the socket and its IO streams to revert the object back to pre-Connect() state
+- if (!Connected)
+- {
+- if (TCPSocket != null) {
+- try {
+- TCPSocket.close();
+- } catch (IOException ex) {
+- }
+- }
+- if (InStream != null) {
+- try {
+- InStream.close();
+- } catch (IOException ex) {
+- }
+- }
+- if (OutStream != null) {
+- try {
+- OutStream.close();
+- } catch (IOException ex) {
+- }
+- }
+- _PDULength = 0;
+- }
+-
+- return LastError;
+- }
+-
+- public void Disconnect()
+- {
+- if (Connected)
+- {
+- try {
+- OutStream.close();
+- InStream.close();
+- TCPSocket.close();
+- _PDULength=0;
+- } catch (IOException ex) {
+- }
+- Connected=false;
+- }
+- }
+-
+- public int ConnectTo(String Address, int Rack, int Slot)
+- {
+- int RemoteTSAP=(ConnType<<8)+ (Rack * 0x20) + Slot;
+- SetConnectionParams(Address, 0x0100, RemoteTSAP);
+- return Connect();
+- }
+-
+- public int PDULength()
+- {
+- return _PDULength;
+- }
+-
+- public void SetConnectionParams(String Address, int LocalTSAP, int RemoteTSAP)
+- {
+- int LocTSAP = LocalTSAP & 0x0000FFFF;
+- int RemTSAP = RemoteTSAP & 0x0000FFFF;
+- IPAddress = Address;
+- LocalTSAP_HI = (byte) (LocTSAP>>8);
+- LocalTSAP_LO = (byte) (LocTSAP & 0x00FF);
+- RemoteTSAP_HI= (byte) (RemTSAP>>8);
+- RemoteTSAP_LO= (byte) (RemTSAP & 0x00FF);
+- }
+-
+- 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
+- System.arraycopy(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))
+- {
+- System.arraycopy(PDU, 25, Data, Offset, SizeRequested);
+- Offset+=SizeRequested;
+- }
+- else
+- LastError = errS7DataRead;
+- }
+- else
+- LastError = errS7InvalidPDU;
+- }
+- }
+-
+- TotElements -= NumElements;
+- Start += NumElements*WordSize;
+- }
+- 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
+- System.arraycopy(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
+- System.arraycopy(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 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;
+- }
+- /**
+- *
+- * @param DBNumber DB Number
+- * @param Buffer Destination buffer
+- * @param SizeRead How many bytes were read
+- * @return
+- */
+- public int DBGet(int DBNumber, byte[] Buffer, IntByRef SizeRead)
+- {
+- S7BlockInfo Block = new S7BlockInfo();
+- // Query the DB Length
+- LastError = GetAgBlockInfo(S7.Block_DB, DBNumber, Block);
+- if (LastError==0)
+- {
+- int SizeToRead = Block.MC7Size();
+- // Checks the room
+- if (SizeToRead<=Buffer.length)
+- {
+- LastError=ReadArea(S7.S7AreaDB, DBNumber, 0, SizeToRead, Buffer);
+- if (LastError==0)
+- SizeRead.Value=SizeToRead;
+- }
+- else
+- LastError=errS7BufferTooSmall;
+- }
+- 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 GetCpuInfo(S7CpuInfo Info)
+- {
+- S7Szl SZL = new S7Szl(1024);
+-
+- LastError = ReadSZL(0x001C, 0x0000, SZL);
+- if (LastError==0)
+- {
+- Info.Update(SZL.Data, 0);
+- }
+- return LastError;
+- }
+-
+- public int GetCpInfo(S7CpInfo Info)
+- {
+- S7Szl SZL = new S7Szl(1024);
+-
+- LastError = ReadSZL(0x0131, 0x0001, SZL);
+- if (LastError==0)
+- {
+- Info.Update(SZL.Data, 0);
+- }
+- return LastError;
+- }
+-
+- public int GetOrderCode(S7OrderCode Code)
+- {
+- S7Szl SZL = new S7Szl(1024);
+-
+- LastError = ReadSZL(0x0011, 0x0000, SZL);
+- if (LastError==0)
+- {
+- Code.Update(SZL.Data, 0, SZL.DataSize);
+- }
+- return LastError;
+- }
+-
+- public int GetPlcDateTime(Date 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 SetPlcDateTime(Date 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;
+- }
+-
+- public int SetPlcSystemDateTime()
+- {
+- return SetPlcDateTime(new Date());
+- }
+-
+- public int PlcStop()
+- {
+- int Length;
+-
+- LastError = 0;
+- SendPacket(S7_STOP);
+- if (LastError==0)
+- {
+- Length=RecvIsoPacket();
+- if (Length > 18) // 18 is the minimum expected
+- {
+- if (S7.GetWordAt(PDU,17)!=0)
+- LastError = errS7FunctionError;
+- }
+- else
+- LastError = errS7InvalidPDU;
+- }
+- return LastError;
+- }
+-
+- public int PlcHotStart()
+- {
+- int Length;
+-
+- LastError = 0;
+- SendPacket(S7_HOT_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 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 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;
+- }
+- }
+- 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("UTF-8");
+- } catch (UnsupportedEncodingException ex) {
+- 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]);
+- }
+- System.arraycopy(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 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 int GetProtection(S7Protection Protection)
+- {
+- S7Szl SZL = new S7Szl(256);
+-
+- LastError = ReadSZL(0x0232, 0x0004, SZL);
+- if (LastError==0)
+- {
+- Protection.Update(SZL.Data);
+- }
+- return LastError;
+- }
+-
+-}
++/*=============================================================================|
++| PROJECT Moka7 1.0.2 |
++|==============================================================================|
++| Copyright (C) 2013, 2016 Davide Nardella |
++| All rights reserved. |
++|==============================================================================|
++| SNAP7 is free software: you can redistribute it and/or modify |
++| it under the terms of the Lesser GNU General Public License as published by |
++| the Free Software Foundation, either version 3 of the License, or under |
++| EPL Eclipse Public License 1.0. |
++| |
++| This means that you have to chose in advance which take before you import |
++| the library into your project. |
++| |
++| SNAP7 is distributed in the hope that it will be useful, |
++| but WITHOUT ANY WARRANTY; without even the implied warranty of |
++| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you |
++| decide to adopt. |
++| |
++|=============================================================================*/
++package Moka7;
++
++import java.io.DataInputStream;
++import java.io.DataOutputStream;
++import java.io.IOException;
++import java.io.UnsupportedEncodingException;
++import java.net.InetSocketAddress;
++import java.net.Socket;
++import java.net.SocketAddress;
++import java.util.Date;
++
++
++/**
++ *
++ * @author Davide Nardella
++ */
++public class S7Client
++{
++ // WordLength
++ public static final int S7WLBit = 0x01;
++ public static final int S7WLByte = 0x02;
++ public static final int S7WLCounter = 0x1C;
++ public static final int S7WLTimer = 0x1D;
++
++ // Error Codes
++ public static final int errTCPConnectionFailed = 0x0001;
++ public static final int errTCPDataSend = 0x0002;
++ public static final int errTCPDataRecv = 0x0003;
++ public static final int errTCPDataRecvTout = 0x0004;
++ public static final int errTCPConnectionReset = 0x0005;
++ public static final int errISOInvalidPDU = 0x0006;
++ public static final int errISOConnectionFailed = 0x0007;
++ public static final int errISONegotiatingPDU = 0x0008;
++ public static final int errS7InvalidPDU = 0x0009;
++ public static final int errS7DataRead = 0x000A;
++ public static final int errS7DataWrite = 0x000B;
++ public static final int errS7BufferTooSmall = 0x000C;
++ public static final int errS7FunctionError = 0x000D;
++ public static final int errS7InvalidParams = 0x000E;
++
++ // Public fields
++ public boolean Connected = false;
++ public int LastError = 0;
++ public int RecvTimeout = 2000;
++
++ // Privates
++ private static final int ISOTCP = 102; // ISOTCP Port
++ private static final int MinPduSize = 16;
++ private static final int DefaultPduSizeRequested = 480;
++ private static final int IsoHSize = 7; // TPKT+COTP Header Size
++ private static final int MaxPduSize = DefaultPduSizeRequested+IsoHSize;
++
++ private Socket TCPSocket;
++ private final byte[] PDU = new byte[2048];
++
++ private DataInputStream InStream = null;
++ private DataOutputStream OutStream = null;
++
++ private String IPAddress;
++
++ private byte LocalTSAP_HI;
++ private byte LocalTSAP_LO;
++ private byte RemoteTSAP_HI;
++ private byte RemoteTSAP_LO;
++ private byte LastPDUType;
++
++ private short ConnType = S7.PG;
++ private int _PDULength = 0;
++
++ // Telegrams
++ // ISO Connection Request telegram (contains also ISO Header and COTP Header)
++ private static final byte ISO_CR[] = {
++ // TPKT (RFC1006 Header)
++ (byte)0x03, // RFC 1006 ID (3)
++ (byte)0x00, // Reserved, always 0
++ (byte)0x00, // High part of packet lenght (entire frame, payload and TPDU included)
++ (byte)0x16, // Low part of packet lenght (entire frame, payload and TPDU included)
++ // COTP (ISO 8073 Header)
++ (byte)0x11, // PDU Size Length
++ (byte)0xE0, // CR - Connection Request ID
++ (byte)0x00, // Dst Reference HI
++ (byte)0x00, // Dst Reference LO
++ (byte)0x00, // Src Reference HI
++ (byte)0x01, // Src Reference LO
++ (byte)0x00, // Class + Options Flags
++ (byte)0xC0, // PDU Max Length ID
++ (byte)0x01, // PDU Max Length HI
++ (byte)0x0A, // PDU Max Length LO
++ (byte)0xC1, // Src TSAP Identifier
++ (byte)0x02, // Src TSAP Length (2 bytes)
++ (byte)0x01, // Src TSAP HI (will be overwritten)
++ (byte)0x00, // Src TSAP LO (will be overwritten)
++ (byte)0xC2, // Dst TSAP Identifier
++ (byte)0x02, // Dst TSAP Length (2 bytes)
++ (byte)0x01, // Dst TSAP HI (will be overwritten)
++ (byte)0x02 // Dst TSAP LO (will be overwritten)
++ };
++
++ // S7 PDU Negotiation Telegram (contains also ISO Header and COTP Header)
++ private static final byte S7_PN[] = {
++ (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x19,
++ (byte)0x02, (byte)0xf0, (byte)0x80, // TPKT + COTP (see above for info)
++ (byte)0x32, (byte)0x01, (byte)0x00, (byte)0x00,
++ (byte)0x04, (byte)0x00, (byte)0x00, (byte)0x08,
++ (byte)0x00, (byte)0x00, (byte)0xf0, (byte)0x00,
++ (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x01,
++ (byte)0x00, (byte)0x1e // PDU Length Requested = HI-LO 480 bytes
++ };
++
++ // S7 Read/Write Request Header (contains also ISO Header and COTP Header)
++ private static final byte S7_RW[] = { // 31-35 bytes
++ (byte)0x03,(byte)0x00,
++ (byte)0x00,(byte)0x1f, // Telegram Length (Data Size + 31 or 35)
++ (byte)0x02,(byte)0xf0, (byte)0x80, // COTP (see above for info)
++ (byte)0x32, // S7 Protocol ID
++ (byte)0x01, // Job Type
++ (byte)0x00,(byte)0x00, // Redundancy identification
++ (byte)0x05,(byte)0x00, // PDU Reference
++ (byte)0x00,(byte)0x0e, // Parameters Length
++ (byte)0x00,(byte)0x00, // Data Length = Size(bytes) + 4
++ (byte)0x04, // Function 4 Read Var, 5 Write Var
++ (byte)0x01, // Items count
++ (byte)0x12, // Var spec.
++ (byte)0x0a, // Length of remaining bytes
++ (byte)0x10, // Syntax ID
++ S7WLByte, // Transport Size
++ (byte)0x00,(byte)0x00, // Num Elements
++ (byte)0x00,(byte)0x00, // DB Number (if any, else 0)
++ (byte)0x84, // Area Type
++ (byte)0x00,(byte)0x00,(byte)0x00, // Area Offset
++ // WR area
++ (byte)0x00, // Reserved
++ (byte)0x04, // Transport size
++ (byte)0x00,(byte)0x00, // Data Length * 8 (if not timer or counter)
++ };
++ private static final int Size_RD = 31;
++ private static final int Size_WR = 35;
++
++ // S7 Get Block Info Request Header (contains also ISO Header and COTP Header)
++ private static final byte S7_BI[] = {
++ (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x25,
++ (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
++ (byte)0x07, (byte)0x00, (byte)0x00, (byte)0x05,
++ (byte)0x00, (byte)0x00, (byte)0x08, (byte)0x00,
++ (byte)0x0c, (byte)0x00, (byte)0x01, (byte)0x12,
++ (byte)0x04, (byte)0x11, (byte)0x43, (byte)0x03,
++ (byte)0x00, (byte)0xff, (byte)0x09, (byte)0x00,
++ (byte)0x08, (byte)0x30,
++ (byte)0x41, // Block Type
++ (byte)0x30, (byte)0x30, (byte)0x30, (byte)0x30, (byte)0x30, // ASCII Block Number
++ (byte)0x41
++ };
++
++ // SZL First telegram request
++ private static final byte S7_SZL_FIRST[] = {
++ (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x21,
++ (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
++ (byte)0x07, (byte)0x00, (byte)0x00,
++ (byte)0x05, (byte)0x00, // Sequence out
++ (byte)0x00, (byte)0x08, (byte)0x00,
++ (byte)0x08, (byte)0x00, (byte)0x01, (byte)0x12,
++ (byte)0x04, (byte)0x11, (byte)0x44, (byte)0x01,
++ (byte)0x00, (byte)0xff, (byte)0x09, (byte)0x00,
++ (byte)0x04,
++ (byte)0x00, (byte)0x00, // ID (29)
++ (byte)0x00, (byte)0x00 // Index (31)
++ };
++
++ // SZL Next telegram request
++ private static final byte S7_SZL_NEXT[] = {
++ (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x21,
++ (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
++ (byte)0x07, (byte)0x00, (byte)0x00, (byte)0x06,
++ (byte)0x00, (byte)0x00, (byte)0x0c, (byte)0x00,
++ (byte)0x04, (byte)0x00, (byte)0x01, (byte)0x12,
++ (byte)0x08, (byte)0x12, (byte)0x44, (byte)0x01,
++ (byte)0x01, // Sequence
++ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
++ (byte)0x0a, (byte)0x00, (byte)0x00, (byte)0x00
++ };
++
++ // Get Date/Time request
++ private static final byte S7_GET_DT[] = {
++ (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x1d,
++ (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
++ (byte)0x07, (byte)0x00, (byte)0x00, (byte)0x38,
++ (byte)0x00, (byte)0x00, (byte)0x08, (byte)0x00,
++ (byte)0x04, (byte)0x00, (byte)0x01, (byte)0x12,
++ (byte)0x04, (byte)0x11, (byte)0x47, (byte)0x01,
++ (byte)0x00, (byte)0x0a, (byte)0x00, (byte)0x00,
++ (byte)0x00
++ };
++
++ // Set Date/Time command
++ private static final byte S7_SET_DT[] = {
++ (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x27,
++ (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
++ (byte)0x07, (byte)0x00, (byte)0x00, (byte)0x89,
++ (byte)0x03, (byte)0x00, (byte)0x08, (byte)0x00,
++ (byte)0x0e, (byte)0x00, (byte)0x01, (byte)0x12,
++ (byte)0x04, (byte)0x11, (byte)0x47, (byte)0x02,
++ (byte)0x00, (byte)0xff, (byte)0x09, (byte)0x00,
++ (byte)0x0a, (byte)0x00, (byte)0x19, // Hi part of Year
++ (byte)0x13, // Lo part of Year
++ (byte)0x12, // Month
++ (byte)0x06, // Day
++ (byte)0x17, // Hour
++ (byte)0x37, // Min
++ (byte)0x13, // Sec
++ (byte)0x00, (byte)0x01 // ms + Day of week
++ };
++
++ // S7 STOP request
++ private static final byte S7_STOP[] = {
++ (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x21,
++ (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
++ (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x0e,
++ (byte)0x00, (byte)0x00, (byte)0x10, (byte)0x00,
++ (byte)0x00, (byte)0x29, (byte)0x00, (byte)0x00,
++ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x09,
++ (byte)0x50, (byte)0x5f, (byte)0x50, (byte)0x52,
++ (byte)0x4f, (byte)0x47, (byte)0x52, (byte)0x41,
++ (byte)0x4d
++ };
++
++ // S7 HOT Start request
++ private static final byte S7_HOT_START[] = {
++ (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x25,
++ (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
++ (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x0c,
++ (byte)0x00, (byte)0x00, (byte)0x14, (byte)0x00,
++ (byte)0x00, (byte)0x28, (byte)0x00, (byte)0x00,
++ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
++ (byte)0xfd, (byte)0x00, (byte)0x00, (byte)0x09,
++ (byte)0x50, (byte)0x5f, (byte)0x50, (byte)0x52,
++ (byte)0x4f, (byte)0x47, (byte)0x52, (byte)0x41,
++ (byte)0x4d
++ };
++
++ // S7 COLD Start request
++ private static final byte S7_COLD_START[] = {
++ (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x27,
++ (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
++ (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x0f,
++ (byte)0x00, (byte)0x00, (byte)0x16, (byte)0x00,
++ (byte)0x00, (byte)0x28, (byte)0x00, (byte)0x00,
++ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
++ (byte)0xfd, (byte)0x00, (byte)0x02, (byte)0x43,
++ (byte)0x20, (byte)0x09, (byte)0x50, (byte)0x5f,
++ (byte)0x50, (byte)0x52, (byte)0x4f, (byte)0x47,
++ (byte)0x52, (byte)0x41, (byte)0x4d
++ };
++
++ // S7 Get PLC Status
++ private static final byte S7_GET_STAT[] = {
++ (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x21,
++ (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
++ (byte)0x07, (byte)0x00, (byte)0x00, (byte)0x2c,
++ (byte)0x00, (byte)0x00, (byte)0x08, (byte)0x00,
++ (byte)0x08, (byte)0x00, (byte)0x01, (byte)0x12,
++ (byte)0x04, (byte)0x11, (byte)0x44, (byte)0x01,
++ (byte)0x00, (byte)0xff, (byte)0x09, (byte)0x00,
++ (byte)0x04, (byte)0x04, (byte)0x24, (byte)0x00,
++ (byte)0x00
++ };
++
++ // S7 Set Session Password
++ private static final byte S7_SET_PWD[] = {
++ (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x25,
++ (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
++ (byte)0x07, (byte)0x00, (byte)0x00, (byte)0x27,
++ (byte)0x00, (byte)0x00, (byte)0x08, (byte)0x00,
++ (byte)0x0c, (byte)0x00, (byte)0x01, (byte)0x12,
++ (byte)0x04, (byte)0x11, (byte)0x45, (byte)0x01,
++ (byte)0x00, (byte)0xff, (byte)0x09, (byte)0x00,
++ (byte)0x08,
++ // 8 Char Encoded Password
++ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
++ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00
++ };
++
++ // S7 Clear Session Password
++ private static final byte S7_CLR_PWD[] = {
++ (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x1d,
++ (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
++ (byte)0x07, (byte)0x00, (byte)0x00, (byte)0x29,
++ (byte)0x00, (byte)0x00, (byte)0x08, (byte)0x00,
++ (byte)0x04, (byte)0x00, (byte)0x01, (byte)0x12,
++ (byte)0x04, (byte)0x11, (byte)0x45, (byte)0x02,
++ (byte)0x00, (byte)0x0a, (byte)0x00, (byte)0x00,
++ (byte)0x00
++ };
++
++ public S7Client()
++ {
++ // Placeholder for future implementations
++ }
++
++ public static String ErrorText(int Error)
++ {
++ switch (Error)
++ {
++ case errTCPConnectionFailed :
++ return "TCP Connection failed.";
++ case errTCPDataSend :
++ return "TCP Sending error.";
++ case errTCPDataRecv :
++ return "TCP Receiving error.";
++ case errTCPDataRecvTout :
++ return "Data Receiving timeout.";
++ case errTCPConnectionReset :
++ return "Connection reset by the peer.";
++ case errISOInvalidPDU :
++ return "Invalid ISO PDU received.";
++ case errISOConnectionFailed :
++ return "ISO connection refused by the CPU.";
++ case errISONegotiatingPDU :
++ return "ISO error negotiating the PDU length.";
++ case errS7InvalidPDU :
++ return "Invalid S7 PDU received.";
++ case errS7DataRead :
++ return "S7 Error reading data from the CPU.";
++ case errS7DataWrite :
++ return "S7 Error writing data to the CPU.";
++ case errS7BufferTooSmall :
++ return "The Buffer supplied to the function is too small.";
++ case errS7FunctionError :
++ return "S7 function refused by the CPU.";
++ case errS7InvalidParams :
++ return "Invalid parameters supplied to the function.";
++ default :
++ return "Unknown error : 0x"+Integer.toHexString(Error);
++ }
++ }
++
++ private int TCPConnect()
++ {
++ SocketAddress sockaddr = new InetSocketAddress(IPAddress, ISOTCP);
++ LastError=0;
++ try {
++ TCPSocket = new Socket();
++ TCPSocket.connect(sockaddr ,5000);
++ TCPSocket.setTcpNoDelay(true);
++ InStream = new DataInputStream(TCPSocket.getInputStream());
++ OutStream = new DataOutputStream(TCPSocket.getOutputStream());
++ }
++ catch (IOException e) {
++ LastError=errTCPConnectionFailed;
++ }
++ return LastError;
++ }
++
++ private int WaitForData(int Size, int Timeout)
++ {
++ int cnt = 0;
++ LastError=0;
++ int SizeAvail;
++ boolean Expired = false;
++ try
++ {
++ SizeAvail=InStream.available();
++ while ((SizeAvail<Size) && (!Expired) && (LastError==0))
++ {
++ cnt++;
++ try {
++ Thread.sleep(1);
++ }
++ catch (InterruptedException ex) {
++ LastError=errTCPDataRecvTout;
++ }
++ SizeAvail=InStream.available();
++ Expired=cnt>Timeout;
++ // If timeout we clean the buffer
++ if (Expired && (SizeAvail>0) && (LastError==0))
++ InStream.read(PDU, 0, SizeAvail);
++ }
++ }
++ catch (IOException ex)
++ {
++ LastError=errTCPDataRecvTout;
++ }
++ if (cnt>=Timeout)
++ {
++ LastError=errTCPDataRecvTout;
++ }
++ return LastError;
++ }
++
++ private int RecvPacket(byte[] Buffer, int Start, int Size)
++ {
++ int BytesRead=0;
++ LastError=WaitForData(Size,RecvTimeout);
++ if (LastError==0)
++ {
++ try {
++ BytesRead = InStream.read(Buffer, Start, Size);
++ } catch (IOException ex) {
++ LastError=errTCPDataRecv;
++ }
++ if (BytesRead==0)
++ LastError=errTCPConnectionReset;
++ }
++ return LastError;
++ }
++
++ private void SendPacket(byte[] Buffer, int Len)
++ {
++ LastError = 0;
++ try {
++ OutStream.write(Buffer,0,Len);
++ OutStream.flush();
++ } catch (IOException ex) {
++ LastError = errTCPDataSend;
++ }
++ }
++ private void SendPacket(byte[] Buffer)
++ {
++ SendPacket(Buffer,Buffer.length);
++ }
++
++ 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;
++ }
++
++ private int ISOConnect()
++ {
++ int Size;
++ ISO_CR[16]=LocalTSAP_HI;
++ ISO_CR[17]=LocalTSAP_LO;
++ ISO_CR[20]=RemoteTSAP_HI;
++ ISO_CR[21]=RemoteTSAP_LO;
++
++ // Sends the connection request telegram
++ SendPacket(ISO_CR);
++ if (LastError==0)
++ {
++ // Gets the reply (if any)
++ Size=RecvIsoPacket();
++ if (LastError==0)
++ {
++ if (Size==22)
++ {
++ if (LastPDUType!=(byte)0xD0) // 0xD0 = CC Connection confirm
++ LastError=errISOConnectionFailed;
++ }
++ else
++ LastError=errISOInvalidPDU;
++ }
++ }
++ return LastError;
++ }
++
++ 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 void SetConnectionType(short ConnectionType)
++ {
++ ConnType=ConnectionType;
++ }
++
++ public int Connect()
++ {
++ LastError=0;
++ if (!Connected)
++ {
++ TCPConnect();
++ if (LastError==0) // First stage : TCP Connection
++ {
++ ISOConnect();
++ if (LastError==0) // Second stage : ISOTCP (ISO 8073) Connection
++ {
++ LastError=NegotiatePduLength(); // Third stage : S7 PDU negotiation
++ }
++ }
++ }
++ Connected=LastError==0;
++
++ // In case the connection is not completely established (TCP connection + ISO connection + PDU negotiation)
++ // we close the socket and its IO streams to revert the object back to pre-Connect() state
++ if (!Connected)
++ {
++ if (TCPSocket != null) {
++ try {
++ TCPSocket.close();
++ } catch (IOException ex) {
++ }
++ }
++ if (InStream != null) {
++ try {
++ InStream.close();
++ } catch (IOException ex) {
++ }
++ }
++ if (OutStream != null) {
++ try {
++ OutStream.close();
++ } catch (IOException ex) {
++ }
++ }
++ _PDULength = 0;
++ }
++
++ return LastError;
++ }
++
++ public void Disconnect()
++ {
++ if (Connected)
++ {
++ try {
++ OutStream.close();
++ InStream.close();
++ TCPSocket.close();
++ _PDULength=0;
++ } catch (IOException ex) {
++ }
++ Connected=false;
++ }
++ }
++
++ public int ConnectTo(String Address, int Rack, int Slot)
++ {
++ int RemoteTSAP=(ConnType<<8)+ (Rack * 0x20) + Slot;
++ SetConnectionParams(Address, 0x0100, RemoteTSAP);
++ return Connect();
++ }
++
++ public int PDULength()
++ {
++ return _PDULength;
++ }
++
++ public void SetConnectionParams(String Address, int LocalTSAP, int RemoteTSAP)
++ {
++ int LocTSAP = LocalTSAP & 0x0000FFFF;
++ int RemTSAP = RemoteTSAP & 0x0000FFFF;
++ IPAddress = Address;
++ LocalTSAP_HI = (byte) (LocTSAP>>8);
++ LocalTSAP_LO = (byte) (LocTSAP & 0x00FF);
++ RemoteTSAP_HI= (byte) (RemTSAP>>8);
++ RemoteTSAP_LO= (byte) (RemTSAP & 0x00FF);
++ }
++
++ public int ReadArea(int Area, int DBNumber, int Start, int Amount, int WordLength, byte[] Data)
++ {
++ int Address;
++ int NumElements;
++ int MaxElements;
++ int TotElements;
++ int SizeRequested;
++ int Length;
++ int Offset = 0;
++ byte 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
++ System.arraycopy(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);
++
++ PDU[22] = (byte) WordLength;
++ // Adjusts Start and word length
++ if ((WordLength==S7WLBit) || (WordLength==S7WLTimer) || (WordLength==S7WLCounter))
++ {
++ Address = Start;
++ }
++ 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);
++
++ // Transport Size
++ PDU[32] = 0x04;
++ if (WordLength==S7WLBit)
++ {
++ PDU[32] = 0x03;
++ }
++ else if ((WordLength==S7WLTimer) || (WordLength==S7WLCounter))
++ {
++ PDU[32] = 0x09;
++ }
++
++ SendPacket(PDU, Size_RD);
++ if (LastError==0)
++ {
++ Length=RecvIsoPacket();
++ if (LastError==0)
++ {
++ if (Length>=25)
++ {
++ if ((Length-25==SizeRequested) && (PDU[21]==(byte)0xFF))
++ {
++ System.arraycopy(PDU, 25, Data, Offset, SizeRequested);
++ Offset+=SizeRequested;
++ }
++ else
++ LastError = errS7DataRead;
++ }
++ else
++ LastError = errS7InvalidPDU;
++ }
++ }
++
++ TotElements -= NumElements;
++ Start += NumElements*WordSize;
++ }
++ return LastError;
++ }
++
++ public int WriteArea(int Area, int DBNumber, int Start, int Amount, int WordLength, byte[] Data)
++ {
++ int Address;
++ int NumElements;
++ int MaxElements;
++ int TotElements;
++ int DataSize;
++ int IsoSize;
++ int Length;
++ int Offset = 0;
++ byte 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; // 35 = 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
++ System.arraycopy(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);
++
++ PDU[22] = (byte) WordLength;
++ // Adjusts Start and word length
++ if ((WordLength==S7WLBit) || (WordLength==S7WLTimer) || (WordLength==S7WLCounter))
++ {
++ Address = Start;
++ Length = DataSize;
++ }
++ 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);
++
++ // Transport Size
++ PDU[32] = 0x04;
++ if (WordLength==S7WLBit)
++ {
++ PDU[32] = 0x03;
++ }
++ else if ((WordLength==S7WLTimer) || (WordLength==S7WLCounter))
++ {
++ PDU[32] = 0x09;
++ }
++
++ // Length
++ S7.SetWordAt(PDU,33,Length);
++
++ // Copies the Data
++ System.arraycopy(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 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;
++ }
++ /**
++ *
++ * @param DBNumber DB Number
++ * @param Buffer Destination buffer
++ * @param SizeRead How many bytes were read
++ * @return
++ */
++ public int DBGet(int DBNumber, byte[] Buffer, IntByRef SizeRead)
++ {
++ S7BlockInfo Block = new S7BlockInfo();
++ // Query the DB Length
++ LastError = GetAgBlockInfo(S7.Block_DB, DBNumber, Block);
++ if (LastError==0)
++ {
++ int SizeToRead = Block.MC7Size();
++ // Checks the room
++ if (SizeToRead<=Buffer.length)
++ {
++ LastError=ReadArea(S7.S7AreaDB, DBNumber, 0, SizeToRead, S7WLByte, Buffer);
++ if (LastError==0)
++ SizeRead.Value=SizeToRead;
++ }
++ else
++ LastError=errS7BufferTooSmall;
++ }
++ 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 GetCpuInfo(S7CpuInfo Info)
++ {
++ S7Szl SZL = new S7Szl(1024);
++
++ LastError = ReadSZL(0x001C, 0x0000, SZL);
++ if (LastError==0)
++ {
++ Info.Update(SZL.Data, 0);
++ }
++ return LastError;
++ }
++
++ public int GetCpInfo(S7CpInfo Info)
++ {
++ S7Szl SZL = new S7Szl(1024);
++
++ LastError = ReadSZL(0x0131, 0x0001, SZL);
++ if (LastError==0)
++ {
++ Info.Update(SZL.Data, 0);
++ }
++ return LastError;
++ }
++
++ public int GetOrderCode(S7OrderCode Code)
++ {
++ S7Szl SZL = new S7Szl(1024);
++
++ LastError = ReadSZL(0x0011, 0x0000, SZL);
++ if (LastError==0)
++ {
++ Code.Update(SZL.Data, 0, SZL.DataSize);
++ }
++ return LastError;
++ }
++
++ public int GetPlcDateTime(Date 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 SetPlcDateTime(Date 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;
++ }
++
++ public int SetPlcSystemDateTime()
++ {
++ return SetPlcDateTime(new Date());
++ }
++
++ public int PlcStop()
++ {
++ int Length;
++
++ LastError = 0;
++ SendPacket(S7_STOP);
++ if (LastError==0)
++ {
++ Length=RecvIsoPacket();
++ if (Length > 18) // 18 is the minimum expected
++ {
++ if (S7.GetWordAt(PDU,17)!=0)
++ LastError = errS7FunctionError;
++ }
++ else
++ LastError = errS7InvalidPDU;
++ }
++ return LastError;
++ }
++
++ public int PlcHotStart()
++ {
++ int Length;
++
++ LastError = 0;
++ SendPacket(S7_HOT_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 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 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;
++ }
++ }
++ 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("UTF-8");
++ } catch (UnsupportedEncodingException ex) {
++ 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]);
++ }
++ System.arraycopy(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 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 int GetProtection(S7Protection Protection)
++ {
++ S7Szl SZL = new S7Szl(256);
++
++ LastError = ReadSZL(0x0232, 0x0004, SZL);
++ if (LastError==0)
++ {
++ Protection.Update(SZL.Data);
++ }
++ return LastError;
++ }
++
++}
+diff U3 S7CpInfo.java S7CpInfo.java
+--- S7CpInfo.java Thu Mar 23 15:34:52 2017
++++ S7CpInfo.java Tue Aug 08 18:53:37 2017
+@@ -1,41 +1,41 @@
+-/*=============================================================================|
+-| PROJECT Moka7 1.0.2 |
+-|==============================================================================|
+-| Copyright (C) 2013, 2016 Davide Nardella |
+-| All rights reserved. |
+-|==============================================================================|
+-| SNAP7 is free software: you can redistribute it and/or modify |
+-| it under the terms of the Lesser GNU General Public License as published by |
+-| the Free Software Foundation, either version 3 of the License, or under |
+-| EPL Eclipse Public License 1.0. |
+-| |
+-| This means that you have to chose in advance which take before you import |
+-| the library into your project. |
+-| |
+-| SNAP7 is distributed in the hope that it will be useful, |
+-| but WITHOUT ANY WARRANTY; without even the implied warranty of |
+-| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you |
+-| decide to adopt. |
+-| |
+-|=============================================================================*/
+-package Moka7;
+-
+-/**
+- *
+- * @author Davide
+- */
+-public class S7CpInfo {
+-
+- public int MaxPduLength;
+- public int MaxConnections;
+- public int MaxMpiRate;
+- public int MaxBusRate;
+-
+- protected void Update(byte[] Src, int Pos)
+- {
+- MaxPduLength = S7.GetShortAt(Src, 2);
+- MaxConnections = S7.GetShortAt(Src, 4);
+- MaxMpiRate = S7.GetDIntAt(Src, 6);
+- MaxBusRate = S7.GetDIntAt(Src, 10);
+- }
+-}
++/*=============================================================================|
++| PROJECT Moka7 1.0.2 |
++|==============================================================================|
++| Copyright (C) 2013, 2016 Davide Nardella |
++| All rights reserved. |
++|==============================================================================|
++| SNAP7 is free software: you can redistribute it and/or modify |
++| it under the terms of the Lesser GNU General Public License as published by |
++| the Free Software Foundation, either version 3 of the License, or under |
++| EPL Eclipse Public License 1.0. |
++| |
++| This means that you have to chose in advance which take before you import |
++| the library into your project. |
++| |
++| SNAP7 is distributed in the hope that it will be useful, |
++| but WITHOUT ANY WARRANTY; without even the implied warranty of |
++| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you |
++| decide to adopt. |
++| |
++|=============================================================================*/
++package Moka7;
++
++/**
++ *
++ * @author Davide Nardella
++ */
++public class S7CpInfo {
++
++ public int MaxPduLength;
++ public int MaxConnections;
++ public int MaxMpiRate;
++ public int MaxBusRate;
++
++ protected void Update(byte[] Src, int Pos)
++ {
++ MaxPduLength = S7.GetShortAt(Src, 2);
++ MaxConnections = S7.GetShortAt(Src, 4);
++ MaxMpiRate = S7.GetDIntAt(Src, 6);
++ MaxBusRate = S7.GetDIntAt(Src, 10);
++ }
++}
+diff U3 S7CpuInfo.java S7CpuInfo.java
+--- S7CpuInfo.java Thu Mar 23 15:34:52 2017
++++ S7CpuInfo.java Tue Aug 08 18:53:37 2017
+@@ -1,57 +1,57 @@
+-/*=============================================================================|
+-| PROJECT Moka7 1.0.2 |
+-|==============================================================================|
+-| Copyright (C) 2013, 2016 Davide Nardella |
+-| All rights reserved. |
+-|==============================================================================|
+-| SNAP7 is free software: you can redistribute it and/or modify |
+-| it under the terms of the Lesser GNU General Public License as published by |
+-| the Free Software Foundation, either version 3 of the License, or under |
+-| EPL Eclipse Public License 1.0. |
+-| |
+-| This means that you have to chose in advance which take before you import |
+-| the library into your project. |
+-| |
+-| SNAP7 is distributed in the hope that it will be useful, |
+-| but WITHOUT ANY WARRANTY; without even the implied warranty of |
+-| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you |
+-| decide to adopt. |
+-| |
+-|=============================================================================*/
+-package Moka7;
+-
+-/**
+- *
+- * @author Davide
+- */
+-public class S7CpuInfo {
+-
+- private final int BufSize = 256;
+- protected byte[] Buffer = new byte[BufSize];
+-
+- protected void Update(byte[] Src, int Pos)
+- {
+- System.arraycopy(Src, Pos, Buffer, 0, BufSize);
+- }
+-
+- public String ModuleTypeName()
+- {
+- return S7.GetStringAt(Buffer,172,32);
+- }
+- public String SerialNumber()
+- {
+- return S7.GetStringAt(Buffer,138,24);
+- }
+- public String ASName()
+- {
+- return S7.GetStringAt(Buffer,2,24);
+- }
+- public String Copyright()
+- {
+- return S7.GetStringAt(Buffer,104,26);
+- }
+- public String ModuleName()
+- {
+- return S7.GetStringAt(Buffer,36,24);
+- }
+-}
++/*=============================================================================|
++| PROJECT Moka7 1.0.2 |
++|==============================================================================|
++| Copyright (C) 2013, 2016 Davide Nardella |
++| All rights reserved. |
++|==============================================================================|
++| SNAP7 is free software: you can redistribute it and/or modify |
++| it under the terms of the Lesser GNU General Public License as published by |
++| the Free Software Foundation, either version 3 of the License, or under |
++| EPL Eclipse Public License 1.0. |
++| |
++| This means that you have to chose in advance which take before you import |
++| the library into your project. |
++| |
++| SNAP7 is distributed in the hope that it will be useful, |
++| but WITHOUT ANY WARRANTY; without even the implied warranty of |
++| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you |
++| decide to adopt. |
++| |
++|=============================================================================*/
++package Moka7;
++
++/**
++ *
++ * @author Davide Nardella
++ */
++public class S7CpuInfo {
++
++ private final int BufSize = 256;
++ protected byte[] Buffer = new byte[BufSize];
++
++ protected void Update(byte[] Src, int Pos)
++ {
++ System.arraycopy(Src, Pos, Buffer, 0, BufSize);
++ }
++
++ public String ModuleTypeName()
++ {
++ return S7.GetStringAt(Buffer,172,32);
++ }
++ public String SerialNumber()
++ {
++ return S7.GetStringAt(Buffer,138,24);
++ }
++ public String ASName()
++ {
++ return S7.GetStringAt(Buffer,2,24);
++ }
++ public String Copyright()
++ {
++ return S7.GetStringAt(Buffer,104,26);
++ }
++ public String ModuleName()
++ {
++ return S7.GetStringAt(Buffer,36,24);
++ }
++}
+diff U3 S7OrderCode.java S7OrderCode.java
+--- S7OrderCode.java Thu Mar 23 15:34:52 2017
++++ S7OrderCode.java Tue Aug 08 18:53:37 2017
+@@ -1,46 +1,46 @@
+-/*=============================================================================|
+-| PROJECT Moka7 1.0.2 |
+-|==============================================================================|
+-| Copyright (C) 2013, 2016 Davide Nardella |
+-| All rights reserved. |
+-|==============================================================================|
+-| SNAP7 is free software: you can redistribute it and/or modify |
+-| it under the terms of the Lesser GNU General Public License as published by |
+-| the Free Software Foundation, either version 3 of the License, or under |
+-| EPL Eclipse Public License 1.0. |
+-| |
+-| This means that you have to chose in advance which take before you import |
+-| the library into your project. |
+-| |
+-| SNAP7 is distributed in the hope that it will be useful, |
+-| but WITHOUT ANY WARRANTY; without even the implied warranty of |
+-| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you |
+-| decide to adopt. |
+-| |
+-|=============================================================================*/
+-package Moka7;
+-
+-/**
+- *
+- * @author Davide
+- */
+-public class S7OrderCode {
+-
+- public int V1;
+- public int V2;
+- public int V3;
+- protected byte[] Buffer = new byte[1024];
+-
+- protected void Update(byte[] Src, int Pos, int Size)
+- {
+- System.arraycopy(Src, Pos, Buffer, 0, Size);
+- V1 = (byte) Src[Size-3];
+- V2 = (byte) Src[Size-2];
+- V3 = (byte) Src[Size-1];
+- }
+-
+- public String Code()
+- {
+- return S7.GetStringAt(Buffer, 2, 20);
+- }
+-}
++/*=============================================================================|
++| PROJECT Moka7 1.0.2 |
++|==============================================================================|
++| Copyright (C) 2013, 2016 Davide Nardella |
++| All rights reserved. |
++|==============================================================================|
++| SNAP7 is free software: you can redistribute it and/or modify |
++| it under the terms of the Lesser GNU General Public License as published by |
++| the Free Software Foundation, either version 3 of the License, or under |
++| EPL Eclipse Public License 1.0. |
++| |
++| This means that you have to chose in advance which take before you import |
++| the library into your project. |
++| |
++| SNAP7 is distributed in the hope that it will be useful, |
++| but WITHOUT ANY WARRANTY; without even the implied warranty of |
++| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you |
++| decide to adopt. |
++| |
++|=============================================================================*/
++package Moka7;
++
++/**
++ *
++ * @author Davide Nardella
++ */
++public class S7OrderCode {
++
++ public int V1;
++ public int V2;
++ public int V3;
++ protected byte[] Buffer = new byte[1024];
++
++ protected void Update(byte[] Src, int Pos, int Size)
++ {
++ System.arraycopy(Src, Pos, Buffer, 0, Size);
++ V1 = (byte) Src[Size-3];
++ V2 = (byte) Src[Size-2];
++ V3 = (byte) Src[Size-1];
++ }
++
++ public String Code()
++ {
++ return S7.GetStringAt(Buffer, 2, 20);
++ }
++}
+diff U3 S7Protection.java S7Protection.java
+--- S7Protection.java Thu Mar 23 15:34:52 2017
++++ S7Protection.java Tue Aug 08 18:53:37 2017
+@@ -1,38 +1,43 @@
+-/*=============================================================================|
+-| PROJECT Moka7 1.0.2 |
+-|==============================================================================|
+-| Copyright (C) 2013, 2016 Davide Nardella |
+-| All rights reserved. |
+-|==============================================================================|
+-| SNAP7 is free software: you can redistribute it and/or modify |
+-| it under the terms of the Lesser GNU General Public License as published by |
+-| the Free Software Foundation, either version 3 of the License, or under |
+-| EPL Eclipse Public License 1.0. |
+-| |
+-| This means that you have to chose in advance which take before you import |
+-| the library into your project. |
+-| |
+-| SNAP7 is distributed in the hope that it will be useful, |
+-| but WITHOUT ANY WARRANTY; without even the implied warranty of |
+-| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you |
+-| decide to adopt. |
+-| |
+-|=============================================================================*/
+-package Moka7;
+-
+-// See §33.19 of "System Software for S7-300/400 System and Standard Functions"
+-public class S7Protection {
+- public int sch_schal;
+- public int sch_par;
+- public int sch_rel;
+- public int bart_sch;
+- public int anl_sch;
+- protected void Update(byte[] Src)
+- {
+- sch_schal = S7.GetWordAt(Src,2);
+- sch_par = S7.GetWordAt(Src,4);
+- sch_rel = S7.GetWordAt(Src,6);
+- bart_sch = S7.GetWordAt(Src,8);
+- anl_sch = S7.GetWordAt(Src,10);
+- }
+-}
++/*=============================================================================|
++| PROJECT Moka7 1.0.2 |
++|==============================================================================|
++| Copyright (C) 2013, 2016 Davide Nardella |
++| All rights reserved. |
++|==============================================================================|
++| SNAP7 is free software: you can redistribute it and/or modify |
++| it under the terms of the Lesser GNU General Public License as published by |
++| the Free Software Foundation, either version 3 of the License, or under |
++| EPL Eclipse Public License 1.0. |
++| |
++| This means that you have to chose in advance which take before you import |
++| the library into your project. |
++| |
++| SNAP7 is distributed in the hope that it will be useful, |
++| but WITHOUT ANY WARRANTY; without even the implied warranty of |
++| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you |
++| decide to adopt. |
++| |
++|=============================================================================*/
++package Moka7;
++
++/**
++ *
++ * @author Davide Nardella
++ */
++
++// See §33.19 of "System Software for S7-300/400 System and Standard Functions"
++public class S7Protection {
++ public int sch_schal;
++ public int sch_par;
++ public int sch_rel;
++ public int bart_sch;
++ public int anl_sch;
++ protected void Update(byte[] Src)
++ {
++ sch_schal = S7.GetWordAt(Src,2);
++ sch_par = S7.GetWordAt(Src,4);
++ sch_rel = S7.GetWordAt(Src,6);
++ bart_sch = S7.GetWordAt(Src,8);
++ anl_sch = S7.GetWordAt(Src,10);
++ }
++}
+diff U3 S7Szl.java S7Szl.java
+--- S7Szl.java Thu Mar 23 15:34:52 2017
++++ S7Szl.java Tue Aug 08 18:53:37 2017
+@@ -1,42 +1,42 @@
+-/*=============================================================================|
+-| PROJECT Moka7 1.0.2 |
+-|==============================================================================|
+-| Copyright (C) 2013, 2016 Davide Nardella |
+-| All rights reserved. |
+-|==============================================================================|
+-| SNAP7 is free software: you can redistribute it and/or modify |
+-| it under the terms of the Lesser GNU General Public License as published by |
+-| the Free Software Foundation, either version 3 of the License, or under |
+-| EPL Eclipse Public License 1.0. |
+-| |
+-| This means that you have to chose in advance which take before you import |
+-| the library into your project. |
+-| |
+-| SNAP7 is distributed in the hope that it will be useful, |
+-| but WITHOUT ANY WARRANTY; without even the implied warranty of |
+-| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you |
+-| decide to adopt. |
+-| |
+-|=============================================================================*/
+-package Moka7;
+-
+-/**
+- *
+- * @author Davide
+- */
+-public class S7Szl {
+-
+- public int LENTHDR;
+- public int N_DR;
+- public int DataSize;
+- public byte Data[];
+-
+- public S7Szl(int BufferSize)
+- {
+- Data = new byte[BufferSize];
+- }
+- protected void Copy(byte[] Src, int SrcPos, int DestPos, int Size)
+- {
+- System.arraycopy(Src, SrcPos, Data, DestPos, Size);
+- }
+-}
++/*=============================================================================|
++| PROJECT Moka7 1.0.2 |
++|==============================================================================|
++| Copyright (C) 2013, 2016 Davide Nardella |
++| All rights reserved. |
++|==============================================================================|
++| SNAP7 is free software: you can redistribute it and/or modify |
++| it under the terms of the Lesser GNU General Public License as published by |
++| the Free Software Foundation, either version 3 of the License, or under |
++| EPL Eclipse Public License 1.0. |
++| |
++| This means that you have to chose in advance which take before you import |
++| the library into your project. |
++| |
++| SNAP7 is distributed in the hope that it will be useful, |
++| but WITHOUT ANY WARRANTY; without even the implied warranty of |
++| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you |
++| decide to adopt. |
++| |
++|=============================================================================*/
++package Moka7;
++
++/**
++ *
++ * @author Davide Nardella
++ */
++public class S7Szl {
++
++ public int LENTHDR;
++ public int N_DR;
++ public int DataSize;
++ public byte Data[];
++
++ public S7Szl(int BufferSize)
++ {
++ Data = new byte[BufferSize];
++ }
++ protected void Copy(byte[] Src, int SrcPos, int DestPos, int Size)
++ {
++ System.arraycopy(Src, SrcPos, Data, DestPos, Size);
++ }
++}
+++ /dev/null
-diff U3 IntByRef.java IntByRef.java
---- IntByRef.java Thu Mar 23 15:34:52 2017
-+++ IntByRef.java Tue Aug 08 18:53:37 2017
-@@ -1,40 +1,40 @@
--/*=============================================================================|
--| PROJECT Moka7 1.0.2 |
--|==============================================================================|
--| Copyright (C) 2013, 2016 Davide Nardella |
--| All rights reserved. |
--|==============================================================================|
--| SNAP7 is free software: you can redistribute it and/or modify |
--| it under the terms of the Lesser GNU General Public License as published by |
--| the Free Software Foundation, either version 3 of the License, or under |
--| EPL Eclipse Public License 1.0. |
--| |
--| This means that you have to chose in advance which take before you import |
--| the library into your project. |
--| |
--| SNAP7 is distributed in the hope that it will be useful, |
--| but WITHOUT ANY WARRANTY; without even the implied warranty of |
--| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you |
--| decide to adopt. |
--| |
--|=============================================================================*/
--
--package Moka7;
--
--/**
-- * Quick class to pass an integer by reference
-- * @author Davide
-- */
--
--public class IntByRef {
--
-- public IntByRef(int Val)
-- {
-- this.Value=Val;
-- }
-- public IntByRef()
-- {
-- this.Value=0;
-- }
-- public int Value;
--}
-+/*=============================================================================|
-+| PROJECT Moka7 1.0.2 |
-+|==============================================================================|
-+| Copyright (C) 2013, 2016 Davide Nardella |
-+| All rights reserved. |
-+|==============================================================================|
-+| SNAP7 is free software: you can redistribute it and/or modify |
-+| it under the terms of the Lesser GNU General Public License as published by |
-+| the Free Software Foundation, either version 3 of the License, or under |
-+| EPL Eclipse Public License 1.0. |
-+| |
-+| This means that you have to chose in advance which take before you import |
-+| the library into your project. |
-+| |
-+| SNAP7 is distributed in the hope that it will be useful, |
-+| but WITHOUT ANY WARRANTY; without even the implied warranty of |
-+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you |
-+| decide to adopt. |
-+| |
-+|=============================================================================*/
-+
-+package Moka7;
-+
-+/**
-+ * Quick class to pass an integer by reference
-+ * @author Davide Nardella
-+ */
-+
-+public class IntByRef {
-+
-+ public IntByRef(int Val)
-+ {
-+ this.Value=Val;
-+ }
-+ public IntByRef()
-+ {
-+ this.Value=0;
-+ }
-+ public int Value;
-+}
-diff U3 S7.java S7.java
---- S7.java Thu Mar 23 15:34:52 2017
-+++ S7.java Tue Aug 08 18:53:37 2017
-@@ -1,287 +1,287 @@
--/*=============================================================================|
--| PROJECT Moka7 1.0.2 |
--|==============================================================================|
--| Copyright (C) 2013, 2016 Davide Nardella |
--| All rights reserved. |
--|==============================================================================|
--| SNAP7 is free software: you can redistribute it and/or modify |
--| it under the terms of the Lesser GNU General Public License as published by |
--| the Free Software Foundation, either version 3 of the License, or under |
--| EPL Eclipse Public License 1.0. |
--| |
--| This means that you have to chose in advance which take before you import |
--| the library into your project. |
--| |
--| SNAP7 is distributed in the hope that it will be useful, |
--| but WITHOUT ANY WARRANTY; without even the implied warranty of |
--| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you |
--| decide to adopt. |
--| |
--|=============================================================================*/
--package Moka7;
--
--import java.io.UnsupportedEncodingException;
--import java.util.Date;
--import java.util.Calendar;
--
--/**
-- *
-- * @author Davide
-- */
--
--
--// Step 7 Constants and Conversion helper class
--public class S7 {
-- // S7 ID Area (Area that we want to read/write)
-- public static final int S7AreaPE = 0x81;
-- public static final int S7AreaPA = 0x82;
-- public static final int S7AreaMK = 0x83;
-- public static final int S7AreaDB = 0x84;
-- public static final int S7AreaCT = 0x1C;
-- public static final int S7AreaTM = 0x1D;
-- // Connection types
-- public static final byte PG = 0x01;
-- public static final byte OP = 0x02;
-- public static final byte S7_BASIC = 0x03;
-- // Block type
-- public static final int Block_OB = 0x38;
-- public static final int Block_DB = 0x41;
-- public static final int Block_SDB = 0x42;
-- public static final int Block_FC = 0x43;
-- public static final int Block_SFC = 0x44;
-- public static final int Block_FB = 0x45;
-- public static final int Block_SFB = 0x46;
-- // Sub Block Type
-- public static final int SubBlk_OB = 0x08;
-- public static final int SubBlk_DB = 0x0A;
-- public static final int SubBlk_SDB = 0x0B;
-- public static final int SubBlk_FC = 0x0C;
-- public static final int SubBlk_SFC = 0x0D;
-- public static final int SubBlk_FB = 0x0E;
-- public static final int SubBlk_SFB = 0x0F;
-- // Block languages
-- public static final int BlockLangAWL = 0x01;
-- public static final int BlockLangKOP = 0x02;
-- public static final int BlockLangFUP = 0x03;
-- public static final int BlockLangSCL = 0x04;
-- public static final int BlockLangDB = 0x05;
-- public static final int BlockLangGRAPH = 0x06;
-- // PLC Status
-- public static final int S7CpuStatusUnknown = 0x00;
-- public static final int S7CpuStatusRun = 0x08;
-- public static final int S7CpuStatusStop = 0x04;
-- // Type Var
-- public static final int S7TypeBool = 1;
-- public static final int S7TypeInt = 1;
--
-- // Returns the bit at Pos.Bit
-- public static boolean GetBitAt(byte[] Buffer, int Pos, int Bit)
-- {
-- int Value = Buffer[Pos] & 0x0FF;
-- byte[] Mask = {
-- (byte)0x01,(byte)0x02,(byte)0x04,(byte)0x08,
-- (byte)0x10,(byte)0x20,(byte)0x40,(byte)0x80
-- };
-- if (Bit<0) Bit=0;
-- if (Bit>7) Bit=7;
--
-- return (Value & Mask[Bit])!=0;
-- }
-- /**
-- * Returns a 16 bit unsigned value : from 0 to 65535 (2^16-1)
-- * @param Buffer
-- * @param Pos start position
-- * @return
-- */
-- public static int GetWordAt(byte[] Buffer, int Pos)
-- {
-- int hi = (Buffer[Pos] & 0x00FF);
-- int lo = (Buffer[Pos+1] & 0x00FF);
-- return (hi<<8)+lo;
-- }
--
-- // Returns a 16 bit signed value : from -32768 to 32767
-- public static int GetShortAt(byte[] Buffer, int Pos)
-- {
-- int hi = (Buffer[Pos]);
-- int lo = (Buffer[Pos+1] & 0x00FF);
-- return ((hi<<8)+lo);
-- }
--
-- // Returns a 32 bit unsigned value : from 0 to 4294967295 (2^32-1)
-- public static long GetDWordAt(byte[] Buffer, int Pos)
-- {
-- long Result;
-- Result=(long)(Buffer[Pos] & 0x0FF);
-- Result<<=8;
-- Result+=(long)(Buffer[Pos+1] & 0x0FF);
-- Result<<=8;
-- Result+=(long)(Buffer[Pos+2] & 0x0FF);
-- Result<<=8;
-- Result+=(long)(Buffer[Pos+3] & 0x0FF);
-- return Result;
-- }
--
-- // Returns a 32 bit signed value : from 0 to 4294967295 (2^32-1)
-- public static int GetDIntAt(byte[] Buffer, int Pos)
-- {
-- int Result;
-- Result= Buffer[Pos];
-- Result<<=8;
-- Result+=(Buffer[Pos+1] & 0x0FF);
-- Result<<=8;
-- Result+=(Buffer[Pos+2] & 0x0FF);
-- Result<<=8;
-- Result+=(Buffer[Pos+3] & 0x0FF);
-- return Result;
-- }
--
-- // Returns a 32 bit floating point
-- public static float GetFloatAt(byte[] Buffer, int Pos)
-- {
-- int IntFloat = GetDIntAt(Buffer, Pos);
-- return Float.intBitsToFloat(IntFloat);
-- }
--
-- // Returns an ASCII string
-- public static String GetStringAt(byte[] Buffer, int Pos, int MaxLen)
-- {
-- byte[] StrBuffer = new byte[MaxLen];
-- System.arraycopy(Buffer, Pos, StrBuffer, 0, MaxLen);
-- String S;
-- try {
-- S = new String(StrBuffer, "UTF-8"); // the charset is UTF-8
-- } catch (UnsupportedEncodingException ex) {
-- S = "";
-- }
-- return S;
-- }
--
-- public static String GetPrintableStringAt(byte[] Buffer, int Pos, int MaxLen)
-- {
-- byte[] StrBuffer = new byte[MaxLen];
-- System.arraycopy(Buffer, Pos, StrBuffer, 0, MaxLen);
-- for (int c = 0; c < MaxLen; c++)
-- {
-- if ((StrBuffer[c]<31) || (StrBuffer[c]>126))
-- StrBuffer[c]=46; // '.'
-- }
-- String S;
-- try {
-- S = new String(StrBuffer, "UTF-8"); // the charset is UTF-8
-- } catch (UnsupportedEncodingException ex) {
-- S = "";
-- }
-- return S;
-- }
--
-- public static Date GetDateAt(byte[] Buffer, int Pos)
-- {
-- int Year, Month, Day, Hour, Min, Sec;
-- Calendar S7Date = Calendar.getInstance();
--
-- 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]);
--
-- S7Date.set(Year, Month, Day, Hour, Min, Sec);
--
-- return S7Date.getTime();
-- }
--
-- public static void SetBitAt(byte[] Buffer, int Pos, int Bit, boolean Value)
-- {
-- byte[] Mask = {
-- (byte)0x01,(byte)0x02,(byte)0x04,(byte)0x08,
-- (byte)0x10,(byte)0x20,(byte)0x40,(byte)0x80
-- };
-- if (Bit<0) Bit=0;
-- if (Bit>7) Bit=7;
--
-- if (Value)
-- Buffer[Pos]= (byte) (Buffer[Pos] | Mask[Bit]);
-- else
-- Buffer[Pos]= (byte) (Buffer[Pos] & ~Mask[Bit]);
-- }
--
-- public static void SetWordAt(byte[] Buffer, int Pos, int Value)
-- {
-- int Word = Value & 0x0FFFF;
-- Buffer[Pos] = (byte) (Word >> 8);
-- Buffer[Pos+1] = (byte) (Word & 0x00FF);
-- }
--
-- public static void SetShortAt(byte[] Buffer, int Pos, int Value)
-- {
-- Buffer[Pos] = (byte) (Value >> 8);
-- Buffer[Pos+1] = (byte) (Value & 0x00FF);
-- }
-- public static void SetDWordAt(byte[] Buffer, int Pos, long Value)
-- {
-- long DWord = Value &0x0FFFFFFFF;
-- Buffer[Pos+3] = (byte) (DWord &0xFF);
-- Buffer[Pos+2] = (byte) ((DWord >> 8) &0xFF);
-- Buffer[Pos+1] = (byte) ((DWord >> 16) &0xFF);
-- Buffer[Pos] = (byte) ((DWord >> 24) &0xFF);
-- }
--
-- public static void SetDIntAt(byte[] Buffer, int Pos, int Value)
-- {
-- Buffer[Pos+3] = (byte) (Value &0xFF);
-- Buffer[Pos+2] = (byte) ((Value >> 8) &0xFF);
-- Buffer[Pos+1] = (byte) ((Value >> 16) &0xFF);
-- Buffer[Pos] = (byte) ((Value >> 24) &0xFF);
-- }
--
-- public static void SetFloatAt(byte[] Buffer, int Pos, float Value)
-- {
-- int DInt = Float.floatToIntBits(Value);
-- SetDIntAt(Buffer, Pos, DInt);
-- }
--
-- public static void SetDateAt(byte[] Buffer, int Pos, Date DateTime)
-- {
-- int Year, Month, Day, Hour, Min, Sec, Dow;
-- Calendar S7Date = Calendar.getInstance();
-- S7Date.setTime(DateTime);
--
-- Year = S7Date.get(Calendar.YEAR);
-- Month = S7Date.get(Calendar.MONTH)+1;
-- Day = S7Date.get(Calendar.DAY_OF_MONTH);
-- Hour = S7Date.get(Calendar.HOUR_OF_DAY);
-- Min = S7Date.get(Calendar.MINUTE);
-- Sec = S7Date.get(Calendar.SECOND);
-- Dow = S7Date.get(Calendar.DAY_OF_WEEK);
--
-- if (Year>1999)
-- Year-=2000;
--
-- Buffer[Pos] =ByteToBCD(Year);
-- Buffer[Pos+1]=ByteToBCD(Month);
-- Buffer[Pos+2]=ByteToBCD(Day);
-- Buffer[Pos+3]=ByteToBCD(Hour);
-- Buffer[Pos+4]=ByteToBCD(Min);
-- Buffer[Pos+5]=ByteToBCD(Sec);
-- Buffer[Pos+6]=0;
-- Buffer[Pos+7]=ByteToBCD(Dow);
-- }
--
-- public static int BCDtoByte(byte B)
-- {
-- return ((B >> 4) * 10) + (B & 0x0F);
-- }
--
-- public static byte ByteToBCD(int Value)
-- {
-- return (byte) (((Value / 10) << 4) | (Value % 10));
-- }
--
--}
-+/*=============================================================================|
-+| PROJECT Moka7 1.0.2 |
-+|==============================================================================|
-+| Copyright (C) 2013, 2016 Davide Nardella |
-+| All rights reserved. |
-+|==============================================================================|
-+| SNAP7 is free software: you can redistribute it and/or modify |
-+| it under the terms of the Lesser GNU General Public License as published by |
-+| the Free Software Foundation, either version 3 of the License, or under |
-+| EPL Eclipse Public License 1.0. |
-+| |
-+| This means that you have to chose in advance which take before you import |
-+| the library into your project. |
-+| |
-+| SNAP7 is distributed in the hope that it will be useful, |
-+| but WITHOUT ANY WARRANTY; without even the implied warranty of |
-+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you |
-+| decide to adopt. |
-+| |
-+|=============================================================================*/
-+package Moka7;
-+
-+import java.io.UnsupportedEncodingException;
-+import java.util.Date;
-+import java.util.Calendar;
-+
-+/**
-+ *
-+ * @author Davide Nardella
-+ */
-+
-+
-+// Step 7 Constants and Conversion helper class
-+public class S7 {
-+ // S7 ID Area (Area that we want to read/write)
-+ public static final int S7AreaPE = 0x81;
-+ public static final int S7AreaPA = 0x82;
-+ public static final int S7AreaMK = 0x83;
-+ public static final int S7AreaDB = 0x84;
-+ public static final int S7AreaCT = 0x1C;
-+ public static final int S7AreaTM = 0x1D;
-+ // Connection types
-+ public static final byte PG = 0x01;
-+ public static final byte OP = 0x02;
-+ public static final byte S7_BASIC = 0x03;
-+ // Block type
-+ public static final int Block_OB = 0x38;
-+ public static final int Block_DB = 0x41;
-+ public static final int Block_SDB = 0x42;
-+ public static final int Block_FC = 0x43;
-+ public static final int Block_SFC = 0x44;
-+ public static final int Block_FB = 0x45;
-+ public static final int Block_SFB = 0x46;
-+ // Sub Block Type
-+ public static final int SubBlk_OB = 0x08;
-+ public static final int SubBlk_DB = 0x0A;
-+ public static final int SubBlk_SDB = 0x0B;
-+ public static final int SubBlk_FC = 0x0C;
-+ public static final int SubBlk_SFC = 0x0D;
-+ public static final int SubBlk_FB = 0x0E;
-+ public static final int SubBlk_SFB = 0x0F;
-+ // Block languages
-+ public static final int BlockLangAWL = 0x01;
-+ public static final int BlockLangKOP = 0x02;
-+ public static final int BlockLangFUP = 0x03;
-+ public static final int BlockLangSCL = 0x04;
-+ public static final int BlockLangDB = 0x05;
-+ public static final int BlockLangGRAPH = 0x06;
-+ // PLC Status
-+ public static final int S7CpuStatusUnknown = 0x00;
-+ public static final int S7CpuStatusRun = 0x08;
-+ public static final int S7CpuStatusStop = 0x04;
-+ // Type Var
-+ public static final int S7TypeBool = 1;
-+ public static final int S7TypeInt = 1;
-+
-+ // Returns the bit at Pos.Bit
-+ public static boolean GetBitAt(byte[] Buffer, int Pos, int Bit)
-+ {
-+ int Value = Buffer[Pos] & 0x0FF;
-+ byte[] Mask = {
-+ (byte)0x01,(byte)0x02,(byte)0x04,(byte)0x08,
-+ (byte)0x10,(byte)0x20,(byte)0x40,(byte)0x80
-+ };
-+ if (Bit<0) Bit=0;
-+ if (Bit>7) Bit=7;
-+
-+ return (Value & Mask[Bit])!=0;
-+ }
-+ /**
-+ * Returns a 16 bit unsigned value : from 0 to 65535 (2^16-1)
-+ * @param Buffer
-+ * @param Pos start position
-+ * @return
-+ */
-+ public static int GetWordAt(byte[] Buffer, int Pos)
-+ {
-+ int hi = (Buffer[Pos] & 0x00FF);
-+ int lo = (Buffer[Pos+1] & 0x00FF);
-+ return (hi<<8)+lo;
-+ }
-+
-+ // Returns a 16 bit signed value : from -32768 to 32767
-+ public static int GetShortAt(byte[] Buffer, int Pos)
-+ {
-+ int hi = (Buffer[Pos]);
-+ int lo = (Buffer[Pos+1] & 0x00FF);
-+ return ((hi<<8)+lo);
-+ }
-+
-+ // Returns a 32 bit unsigned value : from 0 to 4294967295 (2^32-1)
-+ public static long GetDWordAt(byte[] Buffer, int Pos)
-+ {
-+ long Result;
-+ Result=(long)(Buffer[Pos] & 0x0FF);
-+ Result<<=8;
-+ Result+=(long)(Buffer[Pos+1] & 0x0FF);
-+ Result<<=8;
-+ Result+=(long)(Buffer[Pos+2] & 0x0FF);
-+ Result<<=8;
-+ Result+=(long)(Buffer[Pos+3] & 0x0FF);
-+ return Result;
-+ }
-+
-+ // Returns a 32 bit signed value : from 0 to 4294967295 (2^32-1)
-+ public static int GetDIntAt(byte[] Buffer, int Pos)
-+ {
-+ int Result;
-+ Result= Buffer[Pos];
-+ Result<<=8;
-+ Result+=(Buffer[Pos+1] & 0x0FF);
-+ Result<<=8;
-+ Result+=(Buffer[Pos+2] & 0x0FF);
-+ Result<<=8;
-+ Result+=(Buffer[Pos+3] & 0x0FF);
-+ return Result;
-+ }
-+
-+ // Returns a 32 bit floating point
-+ public static float GetFloatAt(byte[] Buffer, int Pos)
-+ {
-+ int IntFloat = GetDIntAt(Buffer, Pos);
-+ return Float.intBitsToFloat(IntFloat);
-+ }
-+
-+ // Returns an ASCII string
-+ public static String GetStringAt(byte[] Buffer, int Pos, int MaxLen)
-+ {
-+ byte[] StrBuffer = new byte[MaxLen];
-+ System.arraycopy(Buffer, Pos, StrBuffer, 0, MaxLen);
-+ String S;
-+ try {
-+ S = new String(StrBuffer, "UTF-8"); // the charset is UTF-8
-+ } catch (UnsupportedEncodingException ex) {
-+ S = "";
-+ }
-+ return S;
-+ }
-+
-+ public static String GetPrintableStringAt(byte[] Buffer, int Pos, int MaxLen)
-+ {
-+ byte[] StrBuffer = new byte[MaxLen];
-+ System.arraycopy(Buffer, Pos, StrBuffer, 0, MaxLen);
-+ for (int c = 0; c < MaxLen; c++)
-+ {
-+ if ((StrBuffer[c]<31) || (StrBuffer[c]>126))
-+ StrBuffer[c]=46; // '.'
-+ }
-+ String S;
-+ try {
-+ S = new String(StrBuffer, "UTF-8"); // the charset is UTF-8
-+ } catch (UnsupportedEncodingException ex) {
-+ S = "";
-+ }
-+ return S;
-+ }
-+
-+ public static Date GetDateAt(byte[] Buffer, int Pos)
-+ {
-+ int Year, Month, Day, Hour, Min, Sec;
-+ Calendar S7Date = Calendar.getInstance();
-+
-+ 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]);
-+
-+ S7Date.set(Year, Month, Day, Hour, Min, Sec);
-+
-+ return S7Date.getTime();
-+ }
-+
-+ public static void SetBitAt(byte[] Buffer, int Pos, int Bit, boolean Value)
-+ {
-+ byte[] Mask = {
-+ (byte)0x01,(byte)0x02,(byte)0x04,(byte)0x08,
-+ (byte)0x10,(byte)0x20,(byte)0x40,(byte)0x80
-+ };
-+ if (Bit<0) Bit=0;
-+ if (Bit>7) Bit=7;
-+
-+ if (Value)
-+ Buffer[Pos]= (byte) (Buffer[Pos] | Mask[Bit]);
-+ else
-+ Buffer[Pos]= (byte) (Buffer[Pos] & ~Mask[Bit]);
-+ }
-+
-+ public static void SetWordAt(byte[] Buffer, int Pos, int Value)
-+ {
-+ int Word = Value & 0x0FFFF;
-+ Buffer[Pos] = (byte) (Word >> 8);
-+ Buffer[Pos+1] = (byte) (Word & 0x00FF);
-+ }
-+
-+ public static void SetShortAt(byte[] Buffer, int Pos, int Value)
-+ {
-+ Buffer[Pos] = (byte) (Value >> 8);
-+ Buffer[Pos+1] = (byte) (Value & 0x00FF);
-+ }
-+ public static void SetDWordAt(byte[] Buffer, int Pos, long Value)
-+ {
-+ long DWord = Value &0x0FFFFFFFF;
-+ Buffer[Pos+3] = (byte) (DWord &0xFF);
-+ Buffer[Pos+2] = (byte) ((DWord >> 8) &0xFF);
-+ Buffer[Pos+1] = (byte) ((DWord >> 16) &0xFF);
-+ Buffer[Pos] = (byte) ((DWord >> 24) &0xFF);
-+ }
-+
-+ public static void SetDIntAt(byte[] Buffer, int Pos, int Value)
-+ {
-+ Buffer[Pos+3] = (byte) (Value &0xFF);
-+ Buffer[Pos+2] = (byte) ((Value >> 8) &0xFF);
-+ Buffer[Pos+1] = (byte) ((Value >> 16) &0xFF);
-+ Buffer[Pos] = (byte) ((Value >> 24) &0xFF);
-+ }
-+
-+ public static void SetFloatAt(byte[] Buffer, int Pos, float Value)
-+ {
-+ int DInt = Float.floatToIntBits(Value);
-+ SetDIntAt(Buffer, Pos, DInt);
-+ }
-+
-+ public static void SetDateAt(byte[] Buffer, int Pos, Date DateTime)
-+ {
-+ int Year, Month, Day, Hour, Min, Sec, Dow;
-+ Calendar S7Date = Calendar.getInstance();
-+ S7Date.setTime(DateTime);
-+
-+ Year = S7Date.get(Calendar.YEAR);
-+ Month = S7Date.get(Calendar.MONTH)+1;
-+ Day = S7Date.get(Calendar.DAY_OF_MONTH);
-+ Hour = S7Date.get(Calendar.HOUR_OF_DAY);
-+ Min = S7Date.get(Calendar.MINUTE);
-+ Sec = S7Date.get(Calendar.SECOND);
-+ Dow = S7Date.get(Calendar.DAY_OF_WEEK);
-+
-+ if (Year>1999)
-+ Year-=2000;
-+
-+ Buffer[Pos] =ByteToBCD(Year);
-+ Buffer[Pos+1]=ByteToBCD(Month);
-+ Buffer[Pos+2]=ByteToBCD(Day);
-+ Buffer[Pos+3]=ByteToBCD(Hour);
-+ Buffer[Pos+4]=ByteToBCD(Min);
-+ Buffer[Pos+5]=ByteToBCD(Sec);
-+ Buffer[Pos+6]=0;
-+ Buffer[Pos+7]=ByteToBCD(Dow);
-+ }
-+
-+ public static int BCDtoByte(byte B)
-+ {
-+ return ((B >> 4) * 10) + (B & 0x0F);
-+ }
-+
-+ public static byte ByteToBCD(int Value)
-+ {
-+ return (byte) (((Value / 10) << 4) | (Value % 10));
-+ }
-+
-+}
-diff U3 S7BlockInfo.java S7BlockInfo.java
---- S7BlockInfo.java Thu Mar 23 15:34:52 2017
-+++ S7BlockInfo.java Tue Aug 08 18:53:37 2017
-@@ -1,101 +1,101 @@
--/*=============================================================================|
--| PROJECT Moka7 1.0.2 |
--|==============================================================================|
--| Copyright (C) 2013, 2016 Davide Nardella |
--| All rights reserved. |
--|==============================================================================|
--| SNAP7 is free software: you can redistribute it and/or modify |
--| it under the terms of the Lesser GNU General Public License as published by |
--| the Free Software Foundation, either version 3 of the License, or under |
--| EPL Eclipse Public License 1.0. |
--| |
--| This means that you have to chose in advance which take before you import |
--| the library into your project. |
--| |
--| SNAP7 is distributed in the hope that it will be useful, |
--| but WITHOUT ANY WARRANTY; without even the implied warranty of |
--| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you |
--| decide to adopt. |
--| |
--|=============================================================================*/
--package Moka7;
--import java.util.Date;
--/**
-- *
-- * @author Davide
-- */
--public class S7BlockInfo {
--
-- private final int BufSize = 96;
-- // MilliSeconds between 1970/1/1 (Java time base) and 1984/1/1 (Siemens base)
-- private final long DeltaMilliSecs = 441763200000L;
-- protected byte[] Buffer = new byte[BufSize];
--
-- protected void Update(byte[] Src, int Pos)
-- {
-- System.arraycopy(Src, Pos, Buffer, 0, BufSize);
-- }
-- public int BlkType()
-- {
-- return Buffer[2];
-- }
-- public int BlkNumber()
-- {
-- return S7.GetWordAt(Buffer, 3);
-- }
-- public int BlkLang()
-- {
-- return Buffer[1];
-- }
-- public int BlkFlags()
-- {
-- return Buffer[0];
-- }
-- public int MC7Size() // The real size in bytes
-- {
-- return S7.GetWordAt(Buffer, 31);
-- }
-- public int LoadSize()
-- {
-- return S7.GetDIntAt(Buffer, 5);
-- }
-- public int LocalData()
-- {
-- return S7.GetWordAt(Buffer, 29);
-- }
-- public int SBBLength()
-- {
-- return S7.GetWordAt(Buffer, 25);
-- }
-- public int Checksum()
-- {
-- return S7.GetWordAt(Buffer, 59);
-- }
-- public int Version()
-- {
-- return Buffer[57];
-- }
-- public Date CodeDate()
-- {
-- long BlockDate = ((long)S7.GetWordAt(Buffer, 17))*86400000L+DeltaMilliSecs;
-- return new Date(BlockDate);
-- }
-- public Date IntfDate()
-- {
-- long BlockDate = ((long)S7.GetWordAt(Buffer, 23))*86400000L+DeltaMilliSecs;
-- return new Date(BlockDate);
-- }
-- public String Author()
-- {
-- return S7.GetStringAt(Buffer,33,8);
-- }
-- public String Family()
-- {
-- return S7.GetStringAt(Buffer,41,8);
-- }
-- public String Header()
-- {
-- return S7.GetStringAt(Buffer,49,8);
-- }
--
--}
-+/*=============================================================================|
-+| PROJECT Moka7 1.0.2 |
-+|==============================================================================|
-+| Copyright (C) 2013, 2016 Davide Nardella |
-+| All rights reserved. |
-+|==============================================================================|
-+| SNAP7 is free software: you can redistribute it and/or modify |
-+| it under the terms of the Lesser GNU General Public License as published by |
-+| the Free Software Foundation, either version 3 of the License, or under |
-+| EPL Eclipse Public License 1.0. |
-+| |
-+| This means that you have to chose in advance which take before you import |
-+| the library into your project. |
-+| |
-+| SNAP7 is distributed in the hope that it will be useful, |
-+| but WITHOUT ANY WARRANTY; without even the implied warranty of |
-+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you |
-+| decide to adopt. |
-+| |
-+|=============================================================================*/
-+package Moka7;
-+import java.util.Date;
-+/**
-+ *
-+ * @author Davide Nardella
-+ */
-+public class S7BlockInfo {
-+
-+ private final int BufSize = 96;
-+ // MilliSeconds between 1970/1/1 (Java time base) and 1984/1/1 (Siemens base)
-+ private final long DeltaMilliSecs = 441763200000L;
-+ protected byte[] Buffer = new byte[BufSize];
-+
-+ protected void Update(byte[] Src, int Pos)
-+ {
-+ System.arraycopy(Src, Pos, Buffer, 0, BufSize);
-+ }
-+ public int BlkType()
-+ {
-+ return Buffer[2];
-+ }
-+ public int BlkNumber()
-+ {
-+ return S7.GetWordAt(Buffer, 3);
-+ }
-+ public int BlkLang()
-+ {
-+ return Buffer[1];
-+ }
-+ public int BlkFlags()
-+ {
-+ return Buffer[0];
-+ }
-+ public int MC7Size() // The real size in bytes
-+ {
-+ return S7.GetWordAt(Buffer, 31);
-+ }
-+ public int LoadSize()
-+ {
-+ return S7.GetDIntAt(Buffer, 5);
-+ }
-+ public int LocalData()
-+ {
-+ return S7.GetWordAt(Buffer, 29);
-+ }
-+ public int SBBLength()
-+ {
-+ return S7.GetWordAt(Buffer, 25);
-+ }
-+ public int Checksum()
-+ {
-+ return S7.GetWordAt(Buffer, 59);
-+ }
-+ public int Version()
-+ {
-+ return Buffer[57];
-+ }
-+ public Date CodeDate()
-+ {
-+ long BlockDate = ((long)S7.GetWordAt(Buffer, 17))*86400000L+DeltaMilliSecs;
-+ return new Date(BlockDate);
-+ }
-+ public Date IntfDate()
-+ {
-+ long BlockDate = ((long)S7.GetWordAt(Buffer, 23))*86400000L+DeltaMilliSecs;
-+ return new Date(BlockDate);
-+ }
-+ public String Author()
-+ {
-+ return S7.GetStringAt(Buffer,33,8);
-+ }
-+ public String Family()
-+ {
-+ return S7.GetStringAt(Buffer,41,8);
-+ }
-+ public String Header()
-+ {
-+ return S7.GetStringAt(Buffer,49,8);
-+ }
-+
-+}
-diff U3 S7Client.java S7Client.java
---- S7Client.java Thu Mar 23 15:34:52 2017
-+++ S7Client.java Tue Aug 08 18:53:37 2017
-@@ -1,1214 +1,1233 @@
--/*=============================================================================|
--| PROJECT Moka7 1.0.2 |
--|==============================================================================|
--| Copyright (C) 2013, 2016 Davide Nardella |
--| All rights reserved. |
--|==============================================================================|
--| SNAP7 is free software: you can redistribute it and/or modify |
--| it under the terms of the Lesser GNU General Public License as published by |
--| the Free Software Foundation, either version 3 of the License, or under |
--| EPL Eclipse Public License 1.0. |
--| |
--| This means that you have to chose in advance which take before you import |
--| the library into your project. |
--| |
--| SNAP7 is distributed in the hope that it will be useful, |
--| but WITHOUT ANY WARRANTY; without even the implied warranty of |
--| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you |
--| decide to adopt. |
--| |
--|=============================================================================*/
--package Moka7;
--
--import java.io.DataInputStream;
--import java.io.DataOutputStream;
--import java.io.IOException;
--import java.io.UnsupportedEncodingException;
--import java.net.InetSocketAddress;
--import java.net.Socket;
--import java.net.SocketAddress;
--import java.util.Date;
--
--
--/**
-- *
-- * @author Dave Nardella
-- */
--public class S7Client
--{
-- // WordLength
-- private static final byte S7WLByte =0x02;
-- private static final byte S7WLCounter =0x1C;
-- private static final byte S7WLTimer =0x1D;
-- // Error Codes
-- public static final int errTCPConnectionFailed = 0x0001;
-- public static final int errTCPDataSend = 0x0002;
-- public static final int errTCPDataRecv = 0x0003;
-- public static final int errTCPDataRecvTout = 0x0004;
-- public static final int errTCPConnectionReset = 0x0005;
-- public static final int errISOInvalidPDU = 0x0006;
-- public static final int errISOConnectionFailed = 0x0007;
-- public static final int errISONegotiatingPDU = 0x0008;
-- public static final int errS7InvalidPDU = 0x0009;
-- public static final int errS7DataRead = 0x000A;
-- public static final int errS7DataWrite = 0x000B;
-- public static final int errS7BufferTooSmall = 0x000C;
-- public static final int errS7FunctionError = 0x000D;
-- public static final int errS7InvalidParams = 0x000E;
--
-- // Public fields
-- public boolean Connected = false;
-- public int LastError = 0;
-- public int RecvTimeout = 2000;
--
-- // Privates
-- private static final int ISOTCP = 102; // ISOTCP Port
-- private static final int MinPduSize = 16;
-- private static final int DefaultPduSizeRequested = 480;
-- private static final int IsoHSize = 7; // TPKT+COTP Header Size
-- private static final int MaxPduSize = DefaultPduSizeRequested+IsoHSize;
--
--
-- private Socket TCPSocket;
-- private final byte[] PDU = new byte[2048];
--
-- private DataInputStream InStream = null;
-- private DataOutputStream OutStream = null;
--
-- private String IPAddress;
--
-- private byte LocalTSAP_HI;
-- private byte LocalTSAP_LO;
-- private byte RemoteTSAP_HI;
-- private byte RemoteTSAP_LO;
-- private byte LastPDUType;
--
-- private short ConnType = S7.PG;
-- private int _PDULength = 0;
--
-- // Telegrams
-- // ISO Connection Request telegram (contains also ISO Header and COTP Header)
-- private static final byte ISO_CR[] = {
-- // TPKT (RFC1006 Header)
-- (byte)0x03, // RFC 1006 ID (3)
-- (byte)0x00, // Reserved, always 0
-- (byte)0x00, // High part of packet lenght (entire frame, payload and TPDU included)
-- (byte)0x16, // Low part of packet lenght (entire frame, payload and TPDU included)
-- // COTP (ISO 8073 Header)
-- (byte)0x11, // PDU Size Length
-- (byte)0xE0, // CR - Connection Request ID
-- (byte)0x00, // Dst Reference HI
-- (byte)0x00, // Dst Reference LO
-- (byte)0x00, // Src Reference HI
-- (byte)0x01, // Src Reference LO
-- (byte)0x00, // Class + Options Flags
-- (byte)0xC0, // PDU Max Length ID
-- (byte)0x01, // PDU Max Length HI
-- (byte)0x0A, // PDU Max Length LO
-- (byte)0xC1, // Src TSAP Identifier
-- (byte)0x02, // Src TSAP Length (2 bytes)
-- (byte)0x01, // Src TSAP HI (will be overwritten)
-- (byte)0x00, // Src TSAP LO (will be overwritten)
-- (byte)0xC2, // Dst TSAP Identifier
-- (byte)0x02, // Dst TSAP Length (2 bytes)
-- (byte)0x01, // Dst TSAP HI (will be overwritten)
-- (byte)0x02 // Dst TSAP LO (will be overwritten)
-- };
--
-- // S7 PDU Negotiation Telegram (contains also ISO Header and COTP Header)
-- private static final byte S7_PN[] = {
-- (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x19,
-- (byte)0x02, (byte)0xf0, (byte)0x80, // TPKT + COTP (see above for info)
-- (byte)0x32, (byte)0x01, (byte)0x00, (byte)0x00,
-- (byte)0x04, (byte)0x00, (byte)0x00, (byte)0x08,
-- (byte)0x00, (byte)0x00, (byte)0xf0, (byte)0x00,
-- (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x01,
-- (byte)0x00, (byte)0x1e // PDU Length Requested = HI-LO 480 bytes
-- };
--
-- // S7 Read/Write Request Header (contains also ISO Header and COTP Header)
-- private static final byte S7_RW[] = { // 31-35 bytes
-- (byte)0x03,(byte)0x00,
-- (byte)0x00,(byte)0x1f, // Telegram Length (Data Size + 31 or 35)
-- (byte)0x02,(byte)0xf0, (byte)0x80, // COTP (see above for info)
-- (byte)0x32, // S7 Protocol ID
-- (byte)0x01, // Job Type
-- (byte)0x00,(byte)0x00, // Redundancy identification
-- (byte)0x05,(byte)0x00, // PDU Reference
-- (byte)0x00,(byte)0x0e, // Parameters Length
-- (byte)0x00,(byte)0x00, // Data Length = Size(bytes) + 4
-- (byte)0x04, // Function 4 Read Var, 5 Write Var
-- (byte)0x01, // Items count
-- (byte)0x12, // Var spec.
-- (byte)0x0a, // Length of remaining bytes
-- (byte)0x10, // Syntax ID
-- S7WLByte, // Transport Size
-- (byte)0x00,(byte)0x00, // Num Elements
-- (byte)0x00,(byte)0x00, // DB Number (if any, else 0)
-- (byte)0x84, // Area Type
-- (byte)0x00,(byte)0x00,(byte)0x00, // Area Offset
-- // WR area
-- (byte)0x00, // Reserved
-- (byte)0x04, // Transport size
-- (byte)0x00,(byte)0x00, // Data Length * 8 (if not timer or counter)
-- };
-- private static final int Size_RD = 31;
-- private static final int Size_WR = 35;
--
-- // S7 Get Block Info Request Header (contains also ISO Header and COTP Header)
-- private static final byte S7_BI[] = {
-- (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x25,
-- (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
-- (byte)0x07, (byte)0x00, (byte)0x00, (byte)0x05,
-- (byte)0x00, (byte)0x00, (byte)0x08, (byte)0x00,
-- (byte)0x0c, (byte)0x00, (byte)0x01, (byte)0x12,
-- (byte)0x04, (byte)0x11, (byte)0x43, (byte)0x03,
-- (byte)0x00, (byte)0xff, (byte)0x09, (byte)0x00,
-- (byte)0x08, (byte)0x30,
-- (byte)0x41, // Block Type
-- (byte)0x30, (byte)0x30, (byte)0x30, (byte)0x30, (byte)0x30, // ASCII Block Number
-- (byte)0x41
-- };
--
-- // SZL First telegram request
-- private static final byte S7_SZL_FIRST[] = {
-- (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x21,
-- (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
-- (byte)0x07, (byte)0x00, (byte)0x00,
-- (byte)0x05, (byte)0x00, // Sequence out
-- (byte)0x00, (byte)0x08, (byte)0x00,
-- (byte)0x08, (byte)0x00, (byte)0x01, (byte)0x12,
-- (byte)0x04, (byte)0x11, (byte)0x44, (byte)0x01,
-- (byte)0x00, (byte)0xff, (byte)0x09, (byte)0x00,
-- (byte)0x04,
-- (byte)0x00, (byte)0x00, // ID (29)
-- (byte)0x00, (byte)0x00 // Index (31)
-- };
--
-- // SZL Next telegram request
-- private static final byte S7_SZL_NEXT[] = {
-- (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x21,
-- (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
-- (byte)0x07, (byte)0x00, (byte)0x00, (byte)0x06,
-- (byte)0x00, (byte)0x00, (byte)0x0c, (byte)0x00,
-- (byte)0x04, (byte)0x00, (byte)0x01, (byte)0x12,
-- (byte)0x08, (byte)0x12, (byte)0x44, (byte)0x01,
-- (byte)0x01, // Sequence
-- (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-- (byte)0x0a, (byte)0x00, (byte)0x00, (byte)0x00
-- };
--
-- // Get Date/Time request
-- private static final byte S7_GET_DT[] = {
-- (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x1d,
-- (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
-- (byte)0x07, (byte)0x00, (byte)0x00, (byte)0x38,
-- (byte)0x00, (byte)0x00, (byte)0x08, (byte)0x00,
-- (byte)0x04, (byte)0x00, (byte)0x01, (byte)0x12,
-- (byte)0x04, (byte)0x11, (byte)0x47, (byte)0x01,
-- (byte)0x00, (byte)0x0a, (byte)0x00, (byte)0x00,
-- (byte)0x00
-- };
--
-- // Set Date/Time command
-- private static final byte S7_SET_DT[] = {
-- (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x27,
-- (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
-- (byte)0x07, (byte)0x00, (byte)0x00, (byte)0x89,
-- (byte)0x03, (byte)0x00, (byte)0x08, (byte)0x00,
-- (byte)0x0e, (byte)0x00, (byte)0x01, (byte)0x12,
-- (byte)0x04, (byte)0x11, (byte)0x47, (byte)0x02,
-- (byte)0x00, (byte)0xff, (byte)0x09, (byte)0x00,
-- (byte)0x0a, (byte)0x00, (byte)0x19, // Hi part of Year
-- (byte)0x13, // Lo part of Year
-- (byte)0x12, // Month
-- (byte)0x06, // Day
-- (byte)0x17, // Hour
-- (byte)0x37, // Min
-- (byte)0x13, // Sec
-- (byte)0x00, (byte)0x01 // ms + Day of week
-- };
--
-- // S7 STOP request
-- private static final byte S7_STOP[] = {
-- (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x21,
-- (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
-- (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x0e,
-- (byte)0x00, (byte)0x00, (byte)0x10, (byte)0x00,
-- (byte)0x00, (byte)0x29, (byte)0x00, (byte)0x00,
-- (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x09,
-- (byte)0x50, (byte)0x5f, (byte)0x50, (byte)0x52,
-- (byte)0x4f, (byte)0x47, (byte)0x52, (byte)0x41,
-- (byte)0x4d
-- };
--
-- // S7 HOT Start request
-- private static final byte S7_HOT_START[] = {
-- (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x25,
-- (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
-- (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x0c,
-- (byte)0x00, (byte)0x00, (byte)0x14, (byte)0x00,
-- (byte)0x00, (byte)0x28, (byte)0x00, (byte)0x00,
-- (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-- (byte)0xfd, (byte)0x00, (byte)0x00, (byte)0x09,
-- (byte)0x50, (byte)0x5f, (byte)0x50, (byte)0x52,
-- (byte)0x4f, (byte)0x47, (byte)0x52, (byte)0x41,
-- (byte)0x4d
-- };
--
-- // S7 COLD Start request
-- private static final byte S7_COLD_START[] = {
-- (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x27,
-- (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
-- (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x0f,
-- (byte)0x00, (byte)0x00, (byte)0x16, (byte)0x00,
-- (byte)0x00, (byte)0x28, (byte)0x00, (byte)0x00,
-- (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-- (byte)0xfd, (byte)0x00, (byte)0x02, (byte)0x43,
-- (byte)0x20, (byte)0x09, (byte)0x50, (byte)0x5f,
-- (byte)0x50, (byte)0x52, (byte)0x4f, (byte)0x47,
-- (byte)0x52, (byte)0x41, (byte)0x4d
-- };
--
-- // S7 Get PLC Status
-- private static final byte S7_GET_STAT[] = {
-- (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x21,
-- (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
-- (byte)0x07, (byte)0x00, (byte)0x00, (byte)0x2c,
-- (byte)0x00, (byte)0x00, (byte)0x08, (byte)0x00,
-- (byte)0x08, (byte)0x00, (byte)0x01, (byte)0x12,
-- (byte)0x04, (byte)0x11, (byte)0x44, (byte)0x01,
-- (byte)0x00, (byte)0xff, (byte)0x09, (byte)0x00,
-- (byte)0x04, (byte)0x04, (byte)0x24, (byte)0x00,
-- (byte)0x00
-- };
--
-- // S7 Set Session Password
-- private static final byte S7_SET_PWD[] = {
-- (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x25,
-- (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
-- (byte)0x07, (byte)0x00, (byte)0x00, (byte)0x27,
-- (byte)0x00, (byte)0x00, (byte)0x08, (byte)0x00,
-- (byte)0x0c, (byte)0x00, (byte)0x01, (byte)0x12,
-- (byte)0x04, (byte)0x11, (byte)0x45, (byte)0x01,
-- (byte)0x00, (byte)0xff, (byte)0x09, (byte)0x00,
-- (byte)0x08,
-- // 8 Char Encoded Password
-- (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-- (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00
-- };
--
-- // S7 Clear Session Password
-- private static final byte S7_CLR_PWD[] = {
-- (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x1d,
-- (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
-- (byte)0x07, (byte)0x00, (byte)0x00, (byte)0x29,
-- (byte)0x00, (byte)0x00, (byte)0x08, (byte)0x00,
-- (byte)0x04, (byte)0x00, (byte)0x01, (byte)0x12,
-- (byte)0x04, (byte)0x11, (byte)0x45, (byte)0x02,
-- (byte)0x00, (byte)0x0a, (byte)0x00, (byte)0x00,
-- (byte)0x00
-- };
--
-- public S7Client()
-- {
-- // Placeholder for future implementations
-- }
--
-- public static String ErrorText(int Error)
-- {
-- switch (Error)
-- {
-- case errTCPConnectionFailed :
-- return "TCP Connection failed.";
-- case errTCPDataSend :
-- return "TCP Sending error.";
-- case errTCPDataRecv :
-- return "TCP Receiving error.";
-- case errTCPDataRecvTout :
-- return "Data Receiving timeout.";
-- case errTCPConnectionReset :
-- return "Connection reset by the peer.";
-- case errISOInvalidPDU :
-- return "Invalid ISO PDU received.";
-- case errISOConnectionFailed :
-- return "ISO connection refused by the CPU.";
-- case errISONegotiatingPDU :
-- return "ISO error negotiating the PDU length.";
-- case errS7InvalidPDU :
-- return "Invalid S7 PDU received.";
-- case errS7DataRead :
-- return "S7 Error reading data from the CPU.";
-- case errS7DataWrite :
-- return "S7 Error writing data to the CPU.";
-- case errS7BufferTooSmall :
-- return "The Buffer supplied to the function is too small.";
-- case errS7FunctionError :
-- return "S7 function refused by the CPU.";
-- case errS7InvalidParams :
-- return "Invalid parameters supplied to the function.";
-- default :
-- return "Unknown error : 0x"+Integer.toHexString(Error);
-- }
-- }
--
-- private int TCPConnect()
-- {
-- SocketAddress sockaddr = new InetSocketAddress(IPAddress, ISOTCP);
-- LastError=0;
-- try {
-- TCPSocket = new Socket();
-- TCPSocket.connect(sockaddr ,5000);
-- TCPSocket.setTcpNoDelay(true);
-- InStream = new DataInputStream(TCPSocket.getInputStream());
-- OutStream = new DataOutputStream(TCPSocket.getOutputStream());
-- }
-- catch (IOException e) {
-- LastError=errTCPConnectionFailed;
-- }
-- return LastError;
-- }
--
-- private int WaitForData(int Size, int Timeout)
-- {
-- int cnt = 0;
-- LastError=0;
-- int SizeAvail;
-- boolean Expired = false;
-- try
-- {
-- SizeAvail=InStream.available();
-- while ((SizeAvail<Size) && (!Expired) && (LastError==0))
-- {
--
-- cnt++;
-- try {
-- Thread.sleep(1);
-- }
-- catch (InterruptedException ex) {
-- LastError=errTCPDataRecvTout;
-- }
-- SizeAvail=InStream.available();
-- Expired=cnt>Timeout;
-- // If timeout we clean the buffer
-- if (Expired && (SizeAvail>0) && (LastError==0))
-- InStream.read(PDU, 0, SizeAvail);
-- }
-- }
-- catch (IOException ex)
-- {
-- LastError=errTCPDataRecvTout;
-- }
-- if (cnt>=Timeout)
-- {
-- LastError=errTCPDataRecvTout;
-- }
-- return LastError;
-- }
--
-- private int RecvPacket(byte[] Buffer, int Start, int Size)
-- {
-- int BytesRead=0;
-- LastError=WaitForData(Size,RecvTimeout);
-- if (LastError==0)
-- {
-- try {
-- BytesRead = InStream.read(Buffer, Start, Size);
-- } catch (IOException ex) {
-- LastError=errTCPDataRecv;
-- }
-- if (BytesRead==0)
-- LastError=errTCPConnectionReset;
-- }
-- return LastError;
-- }
--
-- private void SendPacket(byte[] Buffer, int Len)
-- {
-- LastError = 0;
-- try {
-- OutStream.write(Buffer,0,Len);
-- OutStream.flush();
-- } catch (IOException ex) {
-- LastError = errTCPDataSend;
-- }
-- }
-- private void SendPacket(byte[] Buffer)
-- {
-- SendPacket(Buffer,Buffer.length);
-- }
--
-- 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;
-- }
--
-- private int ISOConnect()
-- {
-- int Size;
-- ISO_CR[16]=LocalTSAP_HI;
-- ISO_CR[17]=LocalTSAP_LO;
-- ISO_CR[20]=RemoteTSAP_HI;
-- ISO_CR[21]=RemoteTSAP_LO;
--
-- // Sends the connection request telegram
-- SendPacket(ISO_CR);
-- if (LastError==0)
-- {
-- // Gets the reply (if any)
-- Size=RecvIsoPacket();
-- if (LastError==0)
-- {
-- if (Size==22)
-- {
-- if (LastPDUType!=(byte)0xD0) // 0xD0 = CC Connection confirm
-- LastError=errISOConnectionFailed;
-- }
-- else
-- LastError=errISOInvalidPDU;
-- }
-- }
-- return LastError;
-- }
--
-- 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 void SetConnectionType(short ConnectionType)
-- {
-- ConnType=ConnectionType;
-- }
--
-- public int Connect()
-- {
-- LastError=0;
-- if (!Connected)
-- {
-- TCPConnect();
-- if (LastError==0) // First stage : TCP Connection
-- {
-- ISOConnect();
-- if (LastError==0) // Second stage : ISOTCP (ISO 8073) Connection
-- {
-- LastError=NegotiatePduLength(); // Third stage : S7 PDU negotiation
-- }
-- }
-- }
-- Connected=LastError==0;
--
-- // In case the connection is not completely established (TCP connection + ISO connection + PDU negotiation)
-- // we close the socket and its IO streams to revert the object back to pre-Connect() state
-- if (!Connected)
-- {
-- if (TCPSocket != null) {
-- try {
-- TCPSocket.close();
-- } catch (IOException ex) {
-- }
-- }
-- if (InStream != null) {
-- try {
-- InStream.close();
-- } catch (IOException ex) {
-- }
-- }
-- if (OutStream != null) {
-- try {
-- OutStream.close();
-- } catch (IOException ex) {
-- }
-- }
-- _PDULength = 0;
-- }
--
-- return LastError;
-- }
--
-- public void Disconnect()
-- {
-- if (Connected)
-- {
-- try {
-- OutStream.close();
-- InStream.close();
-- TCPSocket.close();
-- _PDULength=0;
-- } catch (IOException ex) {
-- }
-- Connected=false;
-- }
-- }
--
-- public int ConnectTo(String Address, int Rack, int Slot)
-- {
-- int RemoteTSAP=(ConnType<<8)+ (Rack * 0x20) + Slot;
-- SetConnectionParams(Address, 0x0100, RemoteTSAP);
-- return Connect();
-- }
--
-- public int PDULength()
-- {
-- return _PDULength;
-- }
--
-- public void SetConnectionParams(String Address, int LocalTSAP, int RemoteTSAP)
-- {
-- int LocTSAP = LocalTSAP & 0x0000FFFF;
-- int RemTSAP = RemoteTSAP & 0x0000FFFF;
-- IPAddress = Address;
-- LocalTSAP_HI = (byte) (LocTSAP>>8);
-- LocalTSAP_LO = (byte) (LocTSAP & 0x00FF);
-- RemoteTSAP_HI= (byte) (RemTSAP>>8);
-- RemoteTSAP_LO= (byte) (RemTSAP & 0x00FF);
-- }
--
-- 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
-- System.arraycopy(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))
-- {
-- System.arraycopy(PDU, 25, Data, Offset, SizeRequested);
-- Offset+=SizeRequested;
-- }
-- else
-- LastError = errS7DataRead;
-- }
-- else
-- LastError = errS7InvalidPDU;
-- }
-- }
--
-- TotElements -= NumElements;
-- Start += NumElements*WordSize;
-- }
-- 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
-- System.arraycopy(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
-- System.arraycopy(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 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;
-- }
-- /**
-- *
-- * @param DBNumber DB Number
-- * @param Buffer Destination buffer
-- * @param SizeRead How many bytes were read
-- * @return
-- */
-- public int DBGet(int DBNumber, byte[] Buffer, IntByRef SizeRead)
-- {
-- S7BlockInfo Block = new S7BlockInfo();
-- // Query the DB Length
-- LastError = GetAgBlockInfo(S7.Block_DB, DBNumber, Block);
-- if (LastError==0)
-- {
-- int SizeToRead = Block.MC7Size();
-- // Checks the room
-- if (SizeToRead<=Buffer.length)
-- {
-- LastError=ReadArea(S7.S7AreaDB, DBNumber, 0, SizeToRead, Buffer);
-- if (LastError==0)
-- SizeRead.Value=SizeToRead;
-- }
-- else
-- LastError=errS7BufferTooSmall;
-- }
-- 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 GetCpuInfo(S7CpuInfo Info)
-- {
-- S7Szl SZL = new S7Szl(1024);
--
-- LastError = ReadSZL(0x001C, 0x0000, SZL);
-- if (LastError==0)
-- {
-- Info.Update(SZL.Data, 0);
-- }
-- return LastError;
-- }
--
-- public int GetCpInfo(S7CpInfo Info)
-- {
-- S7Szl SZL = new S7Szl(1024);
--
-- LastError = ReadSZL(0x0131, 0x0001, SZL);
-- if (LastError==0)
-- {
-- Info.Update(SZL.Data, 0);
-- }
-- return LastError;
-- }
--
-- public int GetOrderCode(S7OrderCode Code)
-- {
-- S7Szl SZL = new S7Szl(1024);
--
-- LastError = ReadSZL(0x0011, 0x0000, SZL);
-- if (LastError==0)
-- {
-- Code.Update(SZL.Data, 0, SZL.DataSize);
-- }
-- return LastError;
-- }
--
-- public int GetPlcDateTime(Date 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 SetPlcDateTime(Date 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;
-- }
--
-- public int SetPlcSystemDateTime()
-- {
-- return SetPlcDateTime(new Date());
-- }
--
-- public int PlcStop()
-- {
-- int Length;
--
-- LastError = 0;
-- SendPacket(S7_STOP);
-- if (LastError==0)
-- {
-- Length=RecvIsoPacket();
-- if (Length > 18) // 18 is the minimum expected
-- {
-- if (S7.GetWordAt(PDU,17)!=0)
-- LastError = errS7FunctionError;
-- }
-- else
-- LastError = errS7InvalidPDU;
-- }
-- return LastError;
-- }
--
-- public int PlcHotStart()
-- {
-- int Length;
--
-- LastError = 0;
-- SendPacket(S7_HOT_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 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 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;
-- }
-- }
-- 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("UTF-8");
-- } catch (UnsupportedEncodingException ex) {
-- 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]);
-- }
-- System.arraycopy(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 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 int GetProtection(S7Protection Protection)
-- {
-- S7Szl SZL = new S7Szl(256);
--
-- LastError = ReadSZL(0x0232, 0x0004, SZL);
-- if (LastError==0)
-- {
-- Protection.Update(SZL.Data);
-- }
-- return LastError;
-- }
--
--}
-+/*=============================================================================|
-+| PROJECT Moka7 1.0.2 |
-+|==============================================================================|
-+| Copyright (C) 2013, 2016 Davide Nardella |
-+| All rights reserved. |
-+|==============================================================================|
-+| SNAP7 is free software: you can redistribute it and/or modify |
-+| it under the terms of the Lesser GNU General Public License as published by |
-+| the Free Software Foundation, either version 3 of the License, or under |
-+| EPL Eclipse Public License 1.0. |
-+| |
-+| This means that you have to chose in advance which take before you import |
-+| the library into your project. |
-+| |
-+| SNAP7 is distributed in the hope that it will be useful, |
-+| but WITHOUT ANY WARRANTY; without even the implied warranty of |
-+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you |
-+| decide to adopt. |
-+| |
-+|=============================================================================*/
-+package Moka7;
-+
-+import java.io.DataInputStream;
-+import java.io.DataOutputStream;
-+import java.io.IOException;
-+import java.io.UnsupportedEncodingException;
-+import java.net.InetSocketAddress;
-+import java.net.Socket;
-+import java.net.SocketAddress;
-+import java.util.Date;
-+
-+
-+/**
-+ *
-+ * @author Davide Nardella
-+ */
-+public class S7Client
-+{
-+ // WordLength
-+ public static final int S7WLBit = 0x01;
-+ public static final int S7WLByte = 0x02;
-+ public static final int S7WLCounter = 0x1C;
-+ public static final int S7WLTimer = 0x1D;
-+
-+ // Error Codes
-+ public static final int errTCPConnectionFailed = 0x0001;
-+ public static final int errTCPDataSend = 0x0002;
-+ public static final int errTCPDataRecv = 0x0003;
-+ public static final int errTCPDataRecvTout = 0x0004;
-+ public static final int errTCPConnectionReset = 0x0005;
-+ public static final int errISOInvalidPDU = 0x0006;
-+ public static final int errISOConnectionFailed = 0x0007;
-+ public static final int errISONegotiatingPDU = 0x0008;
-+ public static final int errS7InvalidPDU = 0x0009;
-+ public static final int errS7DataRead = 0x000A;
-+ public static final int errS7DataWrite = 0x000B;
-+ public static final int errS7BufferTooSmall = 0x000C;
-+ public static final int errS7FunctionError = 0x000D;
-+ public static final int errS7InvalidParams = 0x000E;
-+
-+ // Public fields
-+ public boolean Connected = false;
-+ public int LastError = 0;
-+ public int RecvTimeout = 2000;
-+
-+ // Privates
-+ private static final int ISOTCP = 102; // ISOTCP Port
-+ private static final int MinPduSize = 16;
-+ private static final int DefaultPduSizeRequested = 480;
-+ private static final int IsoHSize = 7; // TPKT+COTP Header Size
-+ private static final int MaxPduSize = DefaultPduSizeRequested+IsoHSize;
-+
-+ private Socket TCPSocket;
-+ private final byte[] PDU = new byte[2048];
-+
-+ private DataInputStream InStream = null;
-+ private DataOutputStream OutStream = null;
-+
-+ private String IPAddress;
-+
-+ private byte LocalTSAP_HI;
-+ private byte LocalTSAP_LO;
-+ private byte RemoteTSAP_HI;
-+ private byte RemoteTSAP_LO;
-+ private byte LastPDUType;
-+
-+ private short ConnType = S7.PG;
-+ private int _PDULength = 0;
-+
-+ // Telegrams
-+ // ISO Connection Request telegram (contains also ISO Header and COTP Header)
-+ private static final byte ISO_CR[] = {
-+ // TPKT (RFC1006 Header)
-+ (byte)0x03, // RFC 1006 ID (3)
-+ (byte)0x00, // Reserved, always 0
-+ (byte)0x00, // High part of packet lenght (entire frame, payload and TPDU included)
-+ (byte)0x16, // Low part of packet lenght (entire frame, payload and TPDU included)
-+ // COTP (ISO 8073 Header)
-+ (byte)0x11, // PDU Size Length
-+ (byte)0xE0, // CR - Connection Request ID
-+ (byte)0x00, // Dst Reference HI
-+ (byte)0x00, // Dst Reference LO
-+ (byte)0x00, // Src Reference HI
-+ (byte)0x01, // Src Reference LO
-+ (byte)0x00, // Class + Options Flags
-+ (byte)0xC0, // PDU Max Length ID
-+ (byte)0x01, // PDU Max Length HI
-+ (byte)0x0A, // PDU Max Length LO
-+ (byte)0xC1, // Src TSAP Identifier
-+ (byte)0x02, // Src TSAP Length (2 bytes)
-+ (byte)0x01, // Src TSAP HI (will be overwritten)
-+ (byte)0x00, // Src TSAP LO (will be overwritten)
-+ (byte)0xC2, // Dst TSAP Identifier
-+ (byte)0x02, // Dst TSAP Length (2 bytes)
-+ (byte)0x01, // Dst TSAP HI (will be overwritten)
-+ (byte)0x02 // Dst TSAP LO (will be overwritten)
-+ };
-+
-+ // S7 PDU Negotiation Telegram (contains also ISO Header and COTP Header)
-+ private static final byte S7_PN[] = {
-+ (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x19,
-+ (byte)0x02, (byte)0xf0, (byte)0x80, // TPKT + COTP (see above for info)
-+ (byte)0x32, (byte)0x01, (byte)0x00, (byte)0x00,
-+ (byte)0x04, (byte)0x00, (byte)0x00, (byte)0x08,
-+ (byte)0x00, (byte)0x00, (byte)0xf0, (byte)0x00,
-+ (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x01,
-+ (byte)0x00, (byte)0x1e // PDU Length Requested = HI-LO 480 bytes
-+ };
-+
-+ // S7 Read/Write Request Header (contains also ISO Header and COTP Header)
-+ private static final byte S7_RW[] = { // 31-35 bytes
-+ (byte)0x03,(byte)0x00,
-+ (byte)0x00,(byte)0x1f, // Telegram Length (Data Size + 31 or 35)
-+ (byte)0x02,(byte)0xf0, (byte)0x80, // COTP (see above for info)
-+ (byte)0x32, // S7 Protocol ID
-+ (byte)0x01, // Job Type
-+ (byte)0x00,(byte)0x00, // Redundancy identification
-+ (byte)0x05,(byte)0x00, // PDU Reference
-+ (byte)0x00,(byte)0x0e, // Parameters Length
-+ (byte)0x00,(byte)0x00, // Data Length = Size(bytes) + 4
-+ (byte)0x04, // Function 4 Read Var, 5 Write Var
-+ (byte)0x01, // Items count
-+ (byte)0x12, // Var spec.
-+ (byte)0x0a, // Length of remaining bytes
-+ (byte)0x10, // Syntax ID
-+ S7WLByte, // Transport Size
-+ (byte)0x00,(byte)0x00, // Num Elements
-+ (byte)0x00,(byte)0x00, // DB Number (if any, else 0)
-+ (byte)0x84, // Area Type
-+ (byte)0x00,(byte)0x00,(byte)0x00, // Area Offset
-+ // WR area
-+ (byte)0x00, // Reserved
-+ (byte)0x04, // Transport size
-+ (byte)0x00,(byte)0x00, // Data Length * 8 (if not timer or counter)
-+ };
-+ private static final int Size_RD = 31;
-+ private static final int Size_WR = 35;
-+
-+ // S7 Get Block Info Request Header (contains also ISO Header and COTP Header)
-+ private static final byte S7_BI[] = {
-+ (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x25,
-+ (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
-+ (byte)0x07, (byte)0x00, (byte)0x00, (byte)0x05,
-+ (byte)0x00, (byte)0x00, (byte)0x08, (byte)0x00,
-+ (byte)0x0c, (byte)0x00, (byte)0x01, (byte)0x12,
-+ (byte)0x04, (byte)0x11, (byte)0x43, (byte)0x03,
-+ (byte)0x00, (byte)0xff, (byte)0x09, (byte)0x00,
-+ (byte)0x08, (byte)0x30,
-+ (byte)0x41, // Block Type
-+ (byte)0x30, (byte)0x30, (byte)0x30, (byte)0x30, (byte)0x30, // ASCII Block Number
-+ (byte)0x41
-+ };
-+
-+ // SZL First telegram request
-+ private static final byte S7_SZL_FIRST[] = {
-+ (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x21,
-+ (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
-+ (byte)0x07, (byte)0x00, (byte)0x00,
-+ (byte)0x05, (byte)0x00, // Sequence out
-+ (byte)0x00, (byte)0x08, (byte)0x00,
-+ (byte)0x08, (byte)0x00, (byte)0x01, (byte)0x12,
-+ (byte)0x04, (byte)0x11, (byte)0x44, (byte)0x01,
-+ (byte)0x00, (byte)0xff, (byte)0x09, (byte)0x00,
-+ (byte)0x04,
-+ (byte)0x00, (byte)0x00, // ID (29)
-+ (byte)0x00, (byte)0x00 // Index (31)
-+ };
-+
-+ // SZL Next telegram request
-+ private static final byte S7_SZL_NEXT[] = {
-+ (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x21,
-+ (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
-+ (byte)0x07, (byte)0x00, (byte)0x00, (byte)0x06,
-+ (byte)0x00, (byte)0x00, (byte)0x0c, (byte)0x00,
-+ (byte)0x04, (byte)0x00, (byte)0x01, (byte)0x12,
-+ (byte)0x08, (byte)0x12, (byte)0x44, (byte)0x01,
-+ (byte)0x01, // Sequence
-+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-+ (byte)0x0a, (byte)0x00, (byte)0x00, (byte)0x00
-+ };
-+
-+ // Get Date/Time request
-+ private static final byte S7_GET_DT[] = {
-+ (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x1d,
-+ (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
-+ (byte)0x07, (byte)0x00, (byte)0x00, (byte)0x38,
-+ (byte)0x00, (byte)0x00, (byte)0x08, (byte)0x00,
-+ (byte)0x04, (byte)0x00, (byte)0x01, (byte)0x12,
-+ (byte)0x04, (byte)0x11, (byte)0x47, (byte)0x01,
-+ (byte)0x00, (byte)0x0a, (byte)0x00, (byte)0x00,
-+ (byte)0x00
-+ };
-+
-+ // Set Date/Time command
-+ private static final byte S7_SET_DT[] = {
-+ (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x27,
-+ (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
-+ (byte)0x07, (byte)0x00, (byte)0x00, (byte)0x89,
-+ (byte)0x03, (byte)0x00, (byte)0x08, (byte)0x00,
-+ (byte)0x0e, (byte)0x00, (byte)0x01, (byte)0x12,
-+ (byte)0x04, (byte)0x11, (byte)0x47, (byte)0x02,
-+ (byte)0x00, (byte)0xff, (byte)0x09, (byte)0x00,
-+ (byte)0x0a, (byte)0x00, (byte)0x19, // Hi part of Year
-+ (byte)0x13, // Lo part of Year
-+ (byte)0x12, // Month
-+ (byte)0x06, // Day
-+ (byte)0x17, // Hour
-+ (byte)0x37, // Min
-+ (byte)0x13, // Sec
-+ (byte)0x00, (byte)0x01 // ms + Day of week
-+ };
-+
-+ // S7 STOP request
-+ private static final byte S7_STOP[] = {
-+ (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x21,
-+ (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
-+ (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x0e,
-+ (byte)0x00, (byte)0x00, (byte)0x10, (byte)0x00,
-+ (byte)0x00, (byte)0x29, (byte)0x00, (byte)0x00,
-+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x09,
-+ (byte)0x50, (byte)0x5f, (byte)0x50, (byte)0x52,
-+ (byte)0x4f, (byte)0x47, (byte)0x52, (byte)0x41,
-+ (byte)0x4d
-+ };
-+
-+ // S7 HOT Start request
-+ private static final byte S7_HOT_START[] = {
-+ (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x25,
-+ (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
-+ (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x0c,
-+ (byte)0x00, (byte)0x00, (byte)0x14, (byte)0x00,
-+ (byte)0x00, (byte)0x28, (byte)0x00, (byte)0x00,
-+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-+ (byte)0xfd, (byte)0x00, (byte)0x00, (byte)0x09,
-+ (byte)0x50, (byte)0x5f, (byte)0x50, (byte)0x52,
-+ (byte)0x4f, (byte)0x47, (byte)0x52, (byte)0x41,
-+ (byte)0x4d
-+ };
-+
-+ // S7 COLD Start request
-+ private static final byte S7_COLD_START[] = {
-+ (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x27,
-+ (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
-+ (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x0f,
-+ (byte)0x00, (byte)0x00, (byte)0x16, (byte)0x00,
-+ (byte)0x00, (byte)0x28, (byte)0x00, (byte)0x00,
-+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-+ (byte)0xfd, (byte)0x00, (byte)0x02, (byte)0x43,
-+ (byte)0x20, (byte)0x09, (byte)0x50, (byte)0x5f,
-+ (byte)0x50, (byte)0x52, (byte)0x4f, (byte)0x47,
-+ (byte)0x52, (byte)0x41, (byte)0x4d
-+ };
-+
-+ // S7 Get PLC Status
-+ private static final byte S7_GET_STAT[] = {
-+ (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x21,
-+ (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
-+ (byte)0x07, (byte)0x00, (byte)0x00, (byte)0x2c,
-+ (byte)0x00, (byte)0x00, (byte)0x08, (byte)0x00,
-+ (byte)0x08, (byte)0x00, (byte)0x01, (byte)0x12,
-+ (byte)0x04, (byte)0x11, (byte)0x44, (byte)0x01,
-+ (byte)0x00, (byte)0xff, (byte)0x09, (byte)0x00,
-+ (byte)0x04, (byte)0x04, (byte)0x24, (byte)0x00,
-+ (byte)0x00
-+ };
-+
-+ // S7 Set Session Password
-+ private static final byte S7_SET_PWD[] = {
-+ (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x25,
-+ (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
-+ (byte)0x07, (byte)0x00, (byte)0x00, (byte)0x27,
-+ (byte)0x00, (byte)0x00, (byte)0x08, (byte)0x00,
-+ (byte)0x0c, (byte)0x00, (byte)0x01, (byte)0x12,
-+ (byte)0x04, (byte)0x11, (byte)0x45, (byte)0x01,
-+ (byte)0x00, (byte)0xff, (byte)0x09, (byte)0x00,
-+ (byte)0x08,
-+ // 8 Char Encoded Password
-+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00
-+ };
-+
-+ // S7 Clear Session Password
-+ private static final byte S7_CLR_PWD[] = {
-+ (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x1d,
-+ (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
-+ (byte)0x07, (byte)0x00, (byte)0x00, (byte)0x29,
-+ (byte)0x00, (byte)0x00, (byte)0x08, (byte)0x00,
-+ (byte)0x04, (byte)0x00, (byte)0x01, (byte)0x12,
-+ (byte)0x04, (byte)0x11, (byte)0x45, (byte)0x02,
-+ (byte)0x00, (byte)0x0a, (byte)0x00, (byte)0x00,
-+ (byte)0x00
-+ };
-+
-+ public S7Client()
-+ {
-+ // Placeholder for future implementations
-+ }
-+
-+ public static String ErrorText(int Error)
-+ {
-+ switch (Error)
-+ {
-+ case errTCPConnectionFailed :
-+ return "TCP Connection failed.";
-+ case errTCPDataSend :
-+ return "TCP Sending error.";
-+ case errTCPDataRecv :
-+ return "TCP Receiving error.";
-+ case errTCPDataRecvTout :
-+ return "Data Receiving timeout.";
-+ case errTCPConnectionReset :
-+ return "Connection reset by the peer.";
-+ case errISOInvalidPDU :
-+ return "Invalid ISO PDU received.";
-+ case errISOConnectionFailed :
-+ return "ISO connection refused by the CPU.";
-+ case errISONegotiatingPDU :
-+ return "ISO error negotiating the PDU length.";
-+ case errS7InvalidPDU :
-+ return "Invalid S7 PDU received.";
-+ case errS7DataRead :
-+ return "S7 Error reading data from the CPU.";
-+ case errS7DataWrite :
-+ return "S7 Error writing data to the CPU.";
-+ case errS7BufferTooSmall :
-+ return "The Buffer supplied to the function is too small.";
-+ case errS7FunctionError :
-+ return "S7 function refused by the CPU.";
-+ case errS7InvalidParams :
-+ return "Invalid parameters supplied to the function.";
-+ default :
-+ return "Unknown error : 0x"+Integer.toHexString(Error);
-+ }
-+ }
-+
-+ private int TCPConnect()
-+ {
-+ SocketAddress sockaddr = new InetSocketAddress(IPAddress, ISOTCP);
-+ LastError=0;
-+ try {
-+ TCPSocket = new Socket();
-+ TCPSocket.connect(sockaddr ,5000);
-+ TCPSocket.setTcpNoDelay(true);
-+ InStream = new DataInputStream(TCPSocket.getInputStream());
-+ OutStream = new DataOutputStream(TCPSocket.getOutputStream());
-+ }
-+ catch (IOException e) {
-+ LastError=errTCPConnectionFailed;
-+ }
-+ return LastError;
-+ }
-+
-+ private int WaitForData(int Size, int Timeout)
-+ {
-+ int cnt = 0;
-+ LastError=0;
-+ int SizeAvail;
-+ boolean Expired = false;
-+ try
-+ {
-+ SizeAvail=InStream.available();
-+ while ((SizeAvail<Size) && (!Expired) && (LastError==0))
-+ {
-+ cnt++;
-+ try {
-+ Thread.sleep(1);
-+ }
-+ catch (InterruptedException ex) {
-+ LastError=errTCPDataRecvTout;
-+ }
-+ SizeAvail=InStream.available();
-+ Expired=cnt>Timeout;
-+ // If timeout we clean the buffer
-+ if (Expired && (SizeAvail>0) && (LastError==0))
-+ InStream.read(PDU, 0, SizeAvail);
-+ }
-+ }
-+ catch (IOException ex)
-+ {
-+ LastError=errTCPDataRecvTout;
-+ }
-+ if (cnt>=Timeout)
-+ {
-+ LastError=errTCPDataRecvTout;
-+ }
-+ return LastError;
-+ }
-+
-+ private int RecvPacket(byte[] Buffer, int Start, int Size)
-+ {
-+ int BytesRead=0;
-+ LastError=WaitForData(Size,RecvTimeout);
-+ if (LastError==0)
-+ {
-+ try {
-+ BytesRead = InStream.read(Buffer, Start, Size);
-+ } catch (IOException ex) {
-+ LastError=errTCPDataRecv;
-+ }
-+ if (BytesRead==0)
-+ LastError=errTCPConnectionReset;
-+ }
-+ return LastError;
-+ }
-+
-+ private void SendPacket(byte[] Buffer, int Len)
-+ {
-+ LastError = 0;
-+ try {
-+ OutStream.write(Buffer,0,Len);
-+ OutStream.flush();
-+ } catch (IOException ex) {
-+ LastError = errTCPDataSend;
-+ }
-+ }
-+ private void SendPacket(byte[] Buffer)
-+ {
-+ SendPacket(Buffer,Buffer.length);
-+ }
-+
-+ 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;
-+ }
-+
-+ private int ISOConnect()
-+ {
-+ int Size;
-+ ISO_CR[16]=LocalTSAP_HI;
-+ ISO_CR[17]=LocalTSAP_LO;
-+ ISO_CR[20]=RemoteTSAP_HI;
-+ ISO_CR[21]=RemoteTSAP_LO;
-+
-+ // Sends the connection request telegram
-+ SendPacket(ISO_CR);
-+ if (LastError==0)
-+ {
-+ // Gets the reply (if any)
-+ Size=RecvIsoPacket();
-+ if (LastError==0)
-+ {
-+ if (Size==22)
-+ {
-+ if (LastPDUType!=(byte)0xD0) // 0xD0 = CC Connection confirm
-+ LastError=errISOConnectionFailed;
-+ }
-+ else
-+ LastError=errISOInvalidPDU;
-+ }
-+ }
-+ return LastError;
-+ }
-+
-+ 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 void SetConnectionType(short ConnectionType)
-+ {
-+ ConnType=ConnectionType;
-+ }
-+
-+ public int Connect()
-+ {
-+ LastError=0;
-+ if (!Connected)
-+ {
-+ TCPConnect();
-+ if (LastError==0) // First stage : TCP Connection
-+ {
-+ ISOConnect();
-+ if (LastError==0) // Second stage : ISOTCP (ISO 8073) Connection
-+ {
-+ LastError=NegotiatePduLength(); // Third stage : S7 PDU negotiation
-+ }
-+ }
-+ }
-+ Connected=LastError==0;
-+
-+ // In case the connection is not completely established (TCP connection + ISO connection + PDU negotiation)
-+ // we close the socket and its IO streams to revert the object back to pre-Connect() state
-+ if (!Connected)
-+ {
-+ if (TCPSocket != null) {
-+ try {
-+ TCPSocket.close();
-+ } catch (IOException ex) {
-+ }
-+ }
-+ if (InStream != null) {
-+ try {
-+ InStream.close();
-+ } catch (IOException ex) {
-+ }
-+ }
-+ if (OutStream != null) {
-+ try {
-+ OutStream.close();
-+ } catch (IOException ex) {
-+ }
-+ }
-+ _PDULength = 0;
-+ }
-+
-+ return LastError;
-+ }
-+
-+ public void Disconnect()
-+ {
-+ if (Connected)
-+ {
-+ try {
-+ OutStream.close();
-+ InStream.close();
-+ TCPSocket.close();
-+ _PDULength=0;
-+ } catch (IOException ex) {
-+ }
-+ Connected=false;
-+ }
-+ }
-+
-+ public int ConnectTo(String Address, int Rack, int Slot)
-+ {
-+ int RemoteTSAP=(ConnType<<8)+ (Rack * 0x20) + Slot;
-+ SetConnectionParams(Address, 0x0100, RemoteTSAP);
-+ return Connect();
-+ }
-+
-+ public int PDULength()
-+ {
-+ return _PDULength;
-+ }
-+
-+ public void SetConnectionParams(String Address, int LocalTSAP, int RemoteTSAP)
-+ {
-+ int LocTSAP = LocalTSAP & 0x0000FFFF;
-+ int RemTSAP = RemoteTSAP & 0x0000FFFF;
-+ IPAddress = Address;
-+ LocalTSAP_HI = (byte) (LocTSAP>>8);
-+ LocalTSAP_LO = (byte) (LocTSAP & 0x00FF);
-+ RemoteTSAP_HI= (byte) (RemTSAP>>8);
-+ RemoteTSAP_LO= (byte) (RemTSAP & 0x00FF);
-+ }
-+
-+ public int ReadArea(int Area, int DBNumber, int Start, int Amount, int WordLength, byte[] Data)
-+ {
-+ int Address;
-+ int NumElements;
-+ int MaxElements;
-+ int TotElements;
-+ int SizeRequested;
-+ int Length;
-+ int Offset = 0;
-+ byte 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
-+ System.arraycopy(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);
-+
-+ PDU[22] = (byte) WordLength;
-+ // Adjusts Start and word length
-+ if ((WordLength==S7WLBit) || (WordLength==S7WLTimer) || (WordLength==S7WLCounter))
-+ {
-+ Address = Start;
-+ }
-+ 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);
-+
-+ // Transport Size
-+ PDU[32] = 0x04;
-+ if (WordLength==S7WLBit)
-+ {
-+ PDU[32] = 0x03;
-+ }
-+ else if ((WordLength==S7WLTimer) || (WordLength==S7WLCounter))
-+ {
-+ PDU[32] = 0x09;
-+ }
-+
-+ SendPacket(PDU, Size_RD);
-+ if (LastError==0)
-+ {
-+ Length=RecvIsoPacket();
-+ if (LastError==0)
-+ {
-+ if (Length>=25)
-+ {
-+ if ((Length-25==SizeRequested) && (PDU[21]==(byte)0xFF))
-+ {
-+ System.arraycopy(PDU, 25, Data, Offset, SizeRequested);
-+ Offset+=SizeRequested;
-+ }
-+ else
-+ LastError = errS7DataRead;
-+ }
-+ else
-+ LastError = errS7InvalidPDU;
-+ }
-+ }
-+
-+ TotElements -= NumElements;
-+ Start += NumElements*WordSize;
-+ }
-+ return LastError;
-+ }
-+
-+ public int WriteArea(int Area, int DBNumber, int Start, int Amount, int WordLength, byte[] Data)
-+ {
-+ int Address;
-+ int NumElements;
-+ int MaxElements;
-+ int TotElements;
-+ int DataSize;
-+ int IsoSize;
-+ int Length;
-+ int Offset = 0;
-+ byte 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; // 35 = 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
-+ System.arraycopy(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);
-+
-+ PDU[22] = (byte) WordLength;
-+ // Adjusts Start and word length
-+ if ((WordLength==S7WLBit) || (WordLength==S7WLTimer) || (WordLength==S7WLCounter))
-+ {
-+ Address = Start;
-+ Length = DataSize;
-+ }
-+ 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);
-+
-+ // Transport Size
-+ PDU[32] = 0x04;
-+ if (WordLength==S7WLBit)
-+ {
-+ PDU[32] = 0x03;
-+ }
-+ else if ((WordLength==S7WLTimer) || (WordLength==S7WLCounter))
-+ {
-+ PDU[32] = 0x09;
-+ }
-+
-+ // Length
-+ S7.SetWordAt(PDU,33,Length);
-+
-+ // Copies the Data
-+ System.arraycopy(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 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;
-+ }
-+ /**
-+ *
-+ * @param DBNumber DB Number
-+ * @param Buffer Destination buffer
-+ * @param SizeRead How many bytes were read
-+ * @return
-+ */
-+ public int DBGet(int DBNumber, byte[] Buffer, IntByRef SizeRead)
-+ {
-+ S7BlockInfo Block = new S7BlockInfo();
-+ // Query the DB Length
-+ LastError = GetAgBlockInfo(S7.Block_DB, DBNumber, Block);
-+ if (LastError==0)
-+ {
-+ int SizeToRead = Block.MC7Size();
-+ // Checks the room
-+ if (SizeToRead<=Buffer.length)
-+ {
-+ LastError=ReadArea(S7.S7AreaDB, DBNumber, 0, SizeToRead, S7WLByte, Buffer);
-+ if (LastError==0)
-+ SizeRead.Value=SizeToRead;
-+ }
-+ else
-+ LastError=errS7BufferTooSmall;
-+ }
-+ 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 GetCpuInfo(S7CpuInfo Info)
-+ {
-+ S7Szl SZL = new S7Szl(1024);
-+
-+ LastError = ReadSZL(0x001C, 0x0000, SZL);
-+ if (LastError==0)
-+ {
-+ Info.Update(SZL.Data, 0);
-+ }
-+ return LastError;
-+ }
-+
-+ public int GetCpInfo(S7CpInfo Info)
-+ {
-+ S7Szl SZL = new S7Szl(1024);
-+
-+ LastError = ReadSZL(0x0131, 0x0001, SZL);
-+ if (LastError==0)
-+ {
-+ Info.Update(SZL.Data, 0);
-+ }
-+ return LastError;
-+ }
-+
-+ public int GetOrderCode(S7OrderCode Code)
-+ {
-+ S7Szl SZL = new S7Szl(1024);
-+
-+ LastError = ReadSZL(0x0011, 0x0000, SZL);
-+ if (LastError==0)
-+ {
-+ Code.Update(SZL.Data, 0, SZL.DataSize);
-+ }
-+ return LastError;
-+ }
-+
-+ public int GetPlcDateTime(Date 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 SetPlcDateTime(Date 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;
-+ }
-+
-+ public int SetPlcSystemDateTime()
-+ {
-+ return SetPlcDateTime(new Date());
-+ }
-+
-+ public int PlcStop()
-+ {
-+ int Length;
-+
-+ LastError = 0;
-+ SendPacket(S7_STOP);
-+ if (LastError==0)
-+ {
-+ Length=RecvIsoPacket();
-+ if (Length > 18) // 18 is the minimum expected
-+ {
-+ if (S7.GetWordAt(PDU,17)!=0)
-+ LastError = errS7FunctionError;
-+ }
-+ else
-+ LastError = errS7InvalidPDU;
-+ }
-+ return LastError;
-+ }
-+
-+ public int PlcHotStart()
-+ {
-+ int Length;
-+
-+ LastError = 0;
-+ SendPacket(S7_HOT_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 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 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;
-+ }
-+ }
-+ 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("UTF-8");
-+ } catch (UnsupportedEncodingException ex) {
-+ 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]);
-+ }
-+ System.arraycopy(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 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 int GetProtection(S7Protection Protection)
-+ {
-+ S7Szl SZL = new S7Szl(256);
-+
-+ LastError = ReadSZL(0x0232, 0x0004, SZL);
-+ if (LastError==0)
-+ {
-+ Protection.Update(SZL.Data);
-+ }
-+ return LastError;
-+ }
-+
-+}
-diff U3 S7CpInfo.java S7CpInfo.java
---- S7CpInfo.java Thu Mar 23 15:34:52 2017
-+++ S7CpInfo.java Tue Aug 08 18:53:37 2017
-@@ -1,41 +1,41 @@
--/*=============================================================================|
--| PROJECT Moka7 1.0.2 |
--|==============================================================================|
--| Copyright (C) 2013, 2016 Davide Nardella |
--| All rights reserved. |
--|==============================================================================|
--| SNAP7 is free software: you can redistribute it and/or modify |
--| it under the terms of the Lesser GNU General Public License as published by |
--| the Free Software Foundation, either version 3 of the License, or under |
--| EPL Eclipse Public License 1.0. |
--| |
--| This means that you have to chose in advance which take before you import |
--| the library into your project. |
--| |
--| SNAP7 is distributed in the hope that it will be useful, |
--| but WITHOUT ANY WARRANTY; without even the implied warranty of |
--| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you |
--| decide to adopt. |
--| |
--|=============================================================================*/
--package Moka7;
--
--/**
-- *
-- * @author Davide
-- */
--public class S7CpInfo {
--
-- public int MaxPduLength;
-- public int MaxConnections;
-- public int MaxMpiRate;
-- public int MaxBusRate;
--
-- protected void Update(byte[] Src, int Pos)
-- {
-- MaxPduLength = S7.GetShortAt(Src, 2);
-- MaxConnections = S7.GetShortAt(Src, 4);
-- MaxMpiRate = S7.GetDIntAt(Src, 6);
-- MaxBusRate = S7.GetDIntAt(Src, 10);
-- }
--}
-+/*=============================================================================|
-+| PROJECT Moka7 1.0.2 |
-+|==============================================================================|
-+| Copyright (C) 2013, 2016 Davide Nardella |
-+| All rights reserved. |
-+|==============================================================================|
-+| SNAP7 is free software: you can redistribute it and/or modify |
-+| it under the terms of the Lesser GNU General Public License as published by |
-+| the Free Software Foundation, either version 3 of the License, or under |
-+| EPL Eclipse Public License 1.0. |
-+| |
-+| This means that you have to chose in advance which take before you import |
-+| the library into your project. |
-+| |
-+| SNAP7 is distributed in the hope that it will be useful, |
-+| but WITHOUT ANY WARRANTY; without even the implied warranty of |
-+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you |
-+| decide to adopt. |
-+| |
-+|=============================================================================*/
-+package Moka7;
-+
-+/**
-+ *
-+ * @author Davide Nardella
-+ */
-+public class S7CpInfo {
-+
-+ public int MaxPduLength;
-+ public int MaxConnections;
-+ public int MaxMpiRate;
-+ public int MaxBusRate;
-+
-+ protected void Update(byte[] Src, int Pos)
-+ {
-+ MaxPduLength = S7.GetShortAt(Src, 2);
-+ MaxConnections = S7.GetShortAt(Src, 4);
-+ MaxMpiRate = S7.GetDIntAt(Src, 6);
-+ MaxBusRate = S7.GetDIntAt(Src, 10);
-+ }
-+}
-diff U3 S7CpuInfo.java S7CpuInfo.java
---- S7CpuInfo.java Thu Mar 23 15:34:52 2017
-+++ S7CpuInfo.java Tue Aug 08 18:53:37 2017
-@@ -1,57 +1,57 @@
--/*=============================================================================|
--| PROJECT Moka7 1.0.2 |
--|==============================================================================|
--| Copyright (C) 2013, 2016 Davide Nardella |
--| All rights reserved. |
--|==============================================================================|
--| SNAP7 is free software: you can redistribute it and/or modify |
--| it under the terms of the Lesser GNU General Public License as published by |
--| the Free Software Foundation, either version 3 of the License, or under |
--| EPL Eclipse Public License 1.0. |
--| |
--| This means that you have to chose in advance which take before you import |
--| the library into your project. |
--| |
--| SNAP7 is distributed in the hope that it will be useful, |
--| but WITHOUT ANY WARRANTY; without even the implied warranty of |
--| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you |
--| decide to adopt. |
--| |
--|=============================================================================*/
--package Moka7;
--
--/**
-- *
-- * @author Davide
-- */
--public class S7CpuInfo {
--
-- private final int BufSize = 256;
-- protected byte[] Buffer = new byte[BufSize];
--
-- protected void Update(byte[] Src, int Pos)
-- {
-- System.arraycopy(Src, Pos, Buffer, 0, BufSize);
-- }
--
-- public String ModuleTypeName()
-- {
-- return S7.GetStringAt(Buffer,172,32);
-- }
-- public String SerialNumber()
-- {
-- return S7.GetStringAt(Buffer,138,24);
-- }
-- public String ASName()
-- {
-- return S7.GetStringAt(Buffer,2,24);
-- }
-- public String Copyright()
-- {
-- return S7.GetStringAt(Buffer,104,26);
-- }
-- public String ModuleName()
-- {
-- return S7.GetStringAt(Buffer,36,24);
-- }
--}
-+/*=============================================================================|
-+| PROJECT Moka7 1.0.2 |
-+|==============================================================================|
-+| Copyright (C) 2013, 2016 Davide Nardella |
-+| All rights reserved. |
-+|==============================================================================|
-+| SNAP7 is free software: you can redistribute it and/or modify |
-+| it under the terms of the Lesser GNU General Public License as published by |
-+| the Free Software Foundation, either version 3 of the License, or under |
-+| EPL Eclipse Public License 1.0. |
-+| |
-+| This means that you have to chose in advance which take before you import |
-+| the library into your project. |
-+| |
-+| SNAP7 is distributed in the hope that it will be useful, |
-+| but WITHOUT ANY WARRANTY; without even the implied warranty of |
-+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you |
-+| decide to adopt. |
-+| |
-+|=============================================================================*/
-+package Moka7;
-+
-+/**
-+ *
-+ * @author Davide Nardella
-+ */
-+public class S7CpuInfo {
-+
-+ private final int BufSize = 256;
-+ protected byte[] Buffer = new byte[BufSize];
-+
-+ protected void Update(byte[] Src, int Pos)
-+ {
-+ System.arraycopy(Src, Pos, Buffer, 0, BufSize);
-+ }
-+
-+ public String ModuleTypeName()
-+ {
-+ return S7.GetStringAt(Buffer,172,32);
-+ }
-+ public String SerialNumber()
-+ {
-+ return S7.GetStringAt(Buffer,138,24);
-+ }
-+ public String ASName()
-+ {
-+ return S7.GetStringAt(Buffer,2,24);
-+ }
-+ public String Copyright()
-+ {
-+ return S7.GetStringAt(Buffer,104,26);
-+ }
-+ public String ModuleName()
-+ {
-+ return S7.GetStringAt(Buffer,36,24);
-+ }
-+}
-diff U3 S7OrderCode.java S7OrderCode.java
---- S7OrderCode.java Thu Mar 23 15:34:52 2017
-+++ S7OrderCode.java Tue Aug 08 18:53:37 2017
-@@ -1,46 +1,46 @@
--/*=============================================================================|
--| PROJECT Moka7 1.0.2 |
--|==============================================================================|
--| Copyright (C) 2013, 2016 Davide Nardella |
--| All rights reserved. |
--|==============================================================================|
--| SNAP7 is free software: you can redistribute it and/or modify |
--| it under the terms of the Lesser GNU General Public License as published by |
--| the Free Software Foundation, either version 3 of the License, or under |
--| EPL Eclipse Public License 1.0. |
--| |
--| This means that you have to chose in advance which take before you import |
--| the library into your project. |
--| |
--| SNAP7 is distributed in the hope that it will be useful, |
--| but WITHOUT ANY WARRANTY; without even the implied warranty of |
--| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you |
--| decide to adopt. |
--| |
--|=============================================================================*/
--package Moka7;
--
--/**
-- *
-- * @author Davide
-- */
--public class S7OrderCode {
--
-- public int V1;
-- public int V2;
-- public int V3;
-- protected byte[] Buffer = new byte[1024];
--
-- protected void Update(byte[] Src, int Pos, int Size)
-- {
-- System.arraycopy(Src, Pos, Buffer, 0, Size);
-- V1 = (byte) Src[Size-3];
-- V2 = (byte) Src[Size-2];
-- V3 = (byte) Src[Size-1];
-- }
--
-- public String Code()
-- {
-- return S7.GetStringAt(Buffer, 2, 20);
-- }
--}
-+/*=============================================================================|
-+| PROJECT Moka7 1.0.2 |
-+|==============================================================================|
-+| Copyright (C) 2013, 2016 Davide Nardella |
-+| All rights reserved. |
-+|==============================================================================|
-+| SNAP7 is free software: you can redistribute it and/or modify |
-+| it under the terms of the Lesser GNU General Public License as published by |
-+| the Free Software Foundation, either version 3 of the License, or under |
-+| EPL Eclipse Public License 1.0. |
-+| |
-+| This means that you have to chose in advance which take before you import |
-+| the library into your project. |
-+| |
-+| SNAP7 is distributed in the hope that it will be useful, |
-+| but WITHOUT ANY WARRANTY; without even the implied warranty of |
-+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you |
-+| decide to adopt. |
-+| |
-+|=============================================================================*/
-+package Moka7;
-+
-+/**
-+ *
-+ * @author Davide Nardella
-+ */
-+public class S7OrderCode {
-+
-+ public int V1;
-+ public int V2;
-+ public int V3;
-+ protected byte[] Buffer = new byte[1024];
-+
-+ protected void Update(byte[] Src, int Pos, int Size)
-+ {
-+ System.arraycopy(Src, Pos, Buffer, 0, Size);
-+ V1 = (byte) Src[Size-3];
-+ V2 = (byte) Src[Size-2];
-+ V3 = (byte) Src[Size-1];
-+ }
-+
-+ public String Code()
-+ {
-+ return S7.GetStringAt(Buffer, 2, 20);
-+ }
-+}
-diff U3 S7Protection.java S7Protection.java
---- S7Protection.java Thu Mar 23 15:34:52 2017
-+++ S7Protection.java Tue Aug 08 18:53:37 2017
-@@ -1,38 +1,43 @@
--/*=============================================================================|
--| PROJECT Moka7 1.0.2 |
--|==============================================================================|
--| Copyright (C) 2013, 2016 Davide Nardella |
--| All rights reserved. |
--|==============================================================================|
--| SNAP7 is free software: you can redistribute it and/or modify |
--| it under the terms of the Lesser GNU General Public License as published by |
--| the Free Software Foundation, either version 3 of the License, or under |
--| EPL Eclipse Public License 1.0. |
--| |
--| This means that you have to chose in advance which take before you import |
--| the library into your project. |
--| |
--| SNAP7 is distributed in the hope that it will be useful, |
--| but WITHOUT ANY WARRANTY; without even the implied warranty of |
--| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you |
--| decide to adopt. |
--| |
--|=============================================================================*/
--package Moka7;
--
--// See §33.19 of "System Software for S7-300/400 System and Standard Functions"
--public class S7Protection {
-- public int sch_schal;
-- public int sch_par;
-- public int sch_rel;
-- public int bart_sch;
-- public int anl_sch;
-- protected void Update(byte[] Src)
-- {
-- sch_schal = S7.GetWordAt(Src,2);
-- sch_par = S7.GetWordAt(Src,4);
-- sch_rel = S7.GetWordAt(Src,6);
-- bart_sch = S7.GetWordAt(Src,8);
-- anl_sch = S7.GetWordAt(Src,10);
-- }
--}
-+/*=============================================================================|
-+| PROJECT Moka7 1.0.2 |
-+|==============================================================================|
-+| Copyright (C) 2013, 2016 Davide Nardella |
-+| All rights reserved. |
-+|==============================================================================|
-+| SNAP7 is free software: you can redistribute it and/or modify |
-+| it under the terms of the Lesser GNU General Public License as published by |
-+| the Free Software Foundation, either version 3 of the License, or under |
-+| EPL Eclipse Public License 1.0. |
-+| |
-+| This means that you have to chose in advance which take before you import |
-+| the library into your project. |
-+| |
-+| SNAP7 is distributed in the hope that it will be useful, |
-+| but WITHOUT ANY WARRANTY; without even the implied warranty of |
-+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you |
-+| decide to adopt. |
-+| |
-+|=============================================================================*/
-+package Moka7;
-+
-+/**
-+ *
-+ * @author Davide Nardella
-+ */
-+
-+// See §33.19 of "System Software for S7-300/400 System and Standard Functions"
-+public class S7Protection {
-+ public int sch_schal;
-+ public int sch_par;
-+ public int sch_rel;
-+ public int bart_sch;
-+ public int anl_sch;
-+ protected void Update(byte[] Src)
-+ {
-+ sch_schal = S7.GetWordAt(Src,2);
-+ sch_par = S7.GetWordAt(Src,4);
-+ sch_rel = S7.GetWordAt(Src,6);
-+ bart_sch = S7.GetWordAt(Src,8);
-+ anl_sch = S7.GetWordAt(Src,10);
-+ }
-+}
-diff U3 S7Szl.java S7Szl.java
---- S7Szl.java Thu Mar 23 15:34:52 2017
-+++ S7Szl.java Tue Aug 08 18:53:37 2017
-@@ -1,42 +1,42 @@
--/*=============================================================================|
--| PROJECT Moka7 1.0.2 |
--|==============================================================================|
--| Copyright (C) 2013, 2016 Davide Nardella |
--| All rights reserved. |
--|==============================================================================|
--| SNAP7 is free software: you can redistribute it and/or modify |
--| it under the terms of the Lesser GNU General Public License as published by |
--| the Free Software Foundation, either version 3 of the License, or under |
--| EPL Eclipse Public License 1.0. |
--| |
--| This means that you have to chose in advance which take before you import |
--| the library into your project. |
--| |
--| SNAP7 is distributed in the hope that it will be useful, |
--| but WITHOUT ANY WARRANTY; without even the implied warranty of |
--| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you |
--| decide to adopt. |
--| |
--|=============================================================================*/
--package Moka7;
--
--/**
-- *
-- * @author Davide
-- */
--public class S7Szl {
--
-- public int LENTHDR;
-- public int N_DR;
-- public int DataSize;
-- public byte Data[];
--
-- public S7Szl(int BufferSize)
-- {
-- Data = new byte[BufferSize];
-- }
-- protected void Copy(byte[] Src, int SrcPos, int DestPos, int Size)
-- {
-- System.arraycopy(Src, SrcPos, Data, DestPos, Size);
-- }
--}
-+/*=============================================================================|
-+| PROJECT Moka7 1.0.2 |
-+|==============================================================================|
-+| Copyright (C) 2013, 2016 Davide Nardella |
-+| All rights reserved. |
-+|==============================================================================|
-+| SNAP7 is free software: you can redistribute it and/or modify |
-+| it under the terms of the Lesser GNU General Public License as published by |
-+| the Free Software Foundation, either version 3 of the License, or under |
-+| EPL Eclipse Public License 1.0. |
-+| |
-+| This means that you have to chose in advance which take before you import |
-+| the library into your project. |
-+| |
-+| SNAP7 is distributed in the hope that it will be useful, |
-+| but WITHOUT ANY WARRANTY; without even the implied warranty of |
-+| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you |
-+| decide to adopt. |
-+| |
-+|=============================================================================*/
-+package Moka7;
-+
-+/**
-+ *
-+ * @author Davide Nardella
-+ */
-+public class S7Szl {
-+
-+ public int LENTHDR;
-+ public int N_DR;
-+ public int DataSize;
-+ public byte Data[];
-+
-+ public S7Szl(int BufferSize)
-+ {
-+ Data = new byte[BufferSize];
-+ }
-+ protected void Copy(byte[] Src, int SrcPos, int DestPos, int Size)
-+ {
-+ System.arraycopy(Src, SrcPos, Data, DestPos, Size);
-+ }
-+}
<name>openHAB Add-ons :: Bundles :: PLCLogo Binding</name>
+ <dependencies>
+ <dependency>
+ <groupId>org.openhab.binding.plclogo</groupId>
+ <artifactId>Moka7</artifactId>
+ <version>1.0.2-iopatch</version>
+ </dependency>
+ </dependencies>
+
</project>