From: J-N-K Date: Wed, 7 Oct 2020 19:44:42 +0000 (+0200) Subject: move lib to remote (#8687) X-Git-Url: https://git.basschouten.com/?a=commitdiff_plain;h=3cc162bf7ec637512f2d0cddcff3d43043ddf31f;p=openhab-addons.git move lib to remote (#8687) Signed-off-by: Jan N. Klug --- diff --git a/bundles/org.openhab.binding.plclogo/3rdparty/bit_io.patch b/bundles/org.openhab.binding.plclogo/3rdparty/bit_io.patch new file mode 100644 index 0000000000..8b1a218da2 --- /dev/null +++ b/bundles/org.openhab.binding.plclogo/3rdparty/bit_io.patch @@ -0,0 +1,3792 @@ +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 ((SizeAvailTimeout; +- // 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) || (Size16 && <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 ((SizeAvailTimeout; ++ // 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) || (Size16 && <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); ++ } ++} diff --git a/bundles/org.openhab.binding.plclogo/lib/Moka7-1.0.2_io_patch.jar b/bundles/org.openhab.binding.plclogo/lib/Moka7-1.0.2_io_patch.jar deleted file mode 100644 index 3c8ecc045c..0000000000 Binary files a/bundles/org.openhab.binding.plclogo/lib/Moka7-1.0.2_io_patch.jar and /dev/null differ diff --git a/bundles/org.openhab.binding.plclogo/lib/bit_io.patch b/bundles/org.openhab.binding.plclogo/lib/bit_io.patch deleted file mode 100644 index 8b1a218da2..0000000000 --- a/bundles/org.openhab.binding.plclogo/lib/bit_io.patch +++ /dev/null @@ -1,3792 +0,0 @@ -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 ((SizeAvailTimeout; -- // 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) || (Size16 && <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 ((SizeAvailTimeout; -+ // 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) || (Size16 && <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); -+ } -+} diff --git a/bundles/org.openhab.binding.plclogo/pom.xml b/bundles/org.openhab.binding.plclogo/pom.xml index d36322c7b7..9dc84172b4 100644 --- a/bundles/org.openhab.binding.plclogo/pom.xml +++ b/bundles/org.openhab.binding.plclogo/pom.xml @@ -14,4 +14,12 @@ openHAB Add-ons :: Bundles :: PLCLogo Binding + + + org.openhab.binding.plclogo + Moka7 + 1.0.2-iopatch + + +