]> git.basschouten.com Git - openhab-addons.git/commitdiff
move lib to remote (#8687)
authorJ-N-K <J-N-K@users.noreply.github.com>
Wed, 7 Oct 2020 19:44:42 +0000 (21:44 +0200)
committerGitHub <noreply@github.com>
Wed, 7 Oct 2020 19:44:42 +0000 (21:44 +0200)
Signed-off-by: Jan N. Klug <jan.n.klug@rub.de>
bundles/org.openhab.binding.plclogo/3rdparty/bit_io.patch [new file with mode: 0644]
bundles/org.openhab.binding.plclogo/lib/Moka7-1.0.2_io_patch.jar [deleted file]
bundles/org.openhab.binding.plclogo/lib/bit_io.patch [deleted file]
bundles/org.openhab.binding.plclogo/pom.xml

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 (file)
index 0000000..8b1a218
--- /dev/null
@@ -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 ((SizeAvail<Size) && (!Expired) && (LastError==0))
+-            {
+-                
+-                cnt++;
+-                try {
+-                    Thread.sleep(1);
+-                } 
+-                catch (InterruptedException ex) {
+-                    LastError=errTCPDataRecvTout;
+-                }
+-                SizeAvail=InStream.available();              
+-                Expired=cnt>Timeout;
+-                // If timeout we clean the buffer
+-                if (Expired && (SizeAvail>0) && (LastError==0))
+-                  InStream.read(PDU, 0, SizeAvail);
+-            }
+-        } 
+-        catch (IOException ex) 
+-        {
+-            LastError=errTCPDataRecvTout;
+-        }
+-        if (cnt>=Timeout)
+-        {
+-            LastError=errTCPDataRecvTout;
+-        }        
+-        return LastError;
+-    }
+-    
+-    private int RecvPacket(byte[] Buffer, int Start, int Size)
+-    {
+-      int BytesRead=0;
+-        LastError=WaitForData(Size,RecvTimeout);
+-      if (LastError==0)
+-        {
+-            try {
+-                BytesRead = InStream.read(Buffer, Start, Size);
+-            } catch (IOException ex) {
+-                LastError=errTCPDataRecv;
+-            }
+-            if (BytesRead==0)
+-                LastError=errTCPConnectionReset;        
+-        }
+-        return LastError;
+-    }
+-
+-    private void SendPacket(byte[] Buffer, int Len)
+-    {
+-        LastError = 0;
+-        try {
+-            OutStream.write(Buffer,0,Len);
+-            OutStream.flush();
+-        } catch (IOException ex) {
+-            LastError = errTCPDataSend; 
+-        }
+-    }   
+-    private void SendPacket(byte[] Buffer)
+-    {
+-        SendPacket(Buffer,Buffer.length);
+-    }   
+-    
+-    private int RecvIsoPacket()
+-    {
+-        Boolean Done = false;
+-        int Size = 0;
+-      while ((LastError==0) && !Done)
+-      {
+-            // Get TPKT (4 bytes)
+-            RecvPacket(PDU, 0, 4); 
+-            if (LastError==0)
+-            {
+-                Size=S7.GetWordAt(PDU,2);
+-                // Check 0 bytes Data Packet (only TPKT+COTP = 7 bytes)
+-                if (Size==IsoHSize)
+-                    RecvPacket(PDU,4, 3); // Skip remaining 3 bytes and Done is still false
+-                else
+-                {
+-                    if ((Size>MaxPduSize) || (Size<MinPduSize))
+-                        LastError=errISOInvalidPDU;
+-                    else
+-                        Done = true; // a valid Length !=7 && >16 && <247
+-                }
+-            }               
+-        }
+-        if (LastError==0)
+-        {
+-            RecvPacket(PDU,4, 3); // Skip remaining 3 COTP bytes
+-            LastPDUType=PDU[5];   // Stores PDU Type, we need it 
+-            // Receives the S7 Payload          
+-            RecvPacket(PDU, 7, Size-IsoHSize);          
+-        }
+-        if (LastError==0)
+-            return Size;
+-        else
+-            return 0;
+-    }
+-    
+-    private int ISOConnect() 
+-    {
+-      int Size;
+-        ISO_CR[16]=LocalTSAP_HI;
+-        ISO_CR[17]=LocalTSAP_LO;
+-        ISO_CR[20]=RemoteTSAP_HI;
+-        ISO_CR[21]=RemoteTSAP_LO;
+-        
+-        // Sends the connection request telegram      
+-        SendPacket(ISO_CR);
+-        if (LastError==0)
+-        {            
+-            // Gets the reply (if any)
+-            Size=RecvIsoPacket();
+-            if (LastError==0) 
+-            {
+-                if (Size==22) 
+-                {
+-                    if (LastPDUType!=(byte)0xD0) // 0xD0 = CC Connection confirm
+-                        LastError=errISOConnectionFailed;
+-                }
+-                else
+-                    LastError=errISOInvalidPDU;
+-            }
+-        }        
+-        return LastError;
+-    }        
+-    
+-    private int NegotiatePduLength()
+-    {
+-        int Length;
+-        // Set PDU Size Requested
+-        S7.SetWordAt(S7_PN,23,DefaultPduSizeRequested);            
+-        // Sends the connection request telegram
+-        SendPacket(S7_PN);
+-        if (LastError==0)    
+-        {
+-            Length=RecvIsoPacket();
+-            if (LastError==0)                 
+-            {
+-                // check S7 Error
+-                if ((Length==27) && (PDU[17]==0) && (PDU[18]==0))  // 20 = size of Negotiate Answer
+-                {
+-                    // Get PDU Size Negotiated
+-                    _PDULength = S7.GetWordAt(PDU,25);
+-                    if (_PDULength>0)
+-                        return 0;
+-                    else
+-                        LastError=errISONegotiatingPDU;
+-                }
+-                else 
+-                    LastError=errISONegotiatingPDU;
+-            }
+-        }
+-        return LastError;
+-    }
+-      
+-    public void SetConnectionType(short ConnectionType)
+-    {
+-        ConnType=ConnectionType;
+-    }
+-      
+-    public int Connect() 
+-    {
+-        LastError=0;
+-        if (!Connected)
+-        {
+-            TCPConnect();
+-            if (LastError==0) // First stage : TCP Connection
+-            {
+-                ISOConnect();
+-                if (LastError==0) // Second stage : ISOTCP (ISO 8073) Connection
+-                {
+-                    LastError=NegotiatePduLength(); // Third stage : S7 PDU negotiation
+-                }
+-            }             
+-        }
+-        Connected=LastError==0;
+-        
+-        // In case the connection is not completely established (TCP connection + ISO connection + PDU negotiation)
+-        // we close the socket and its IO streams to revert the object back to pre-Connect() state
+-        if (!Connected)
+-        {
+-            if (TCPSocket != null) {
+-                try {
+-                    TCPSocket.close();
+-                } catch (IOException ex) {
+-                }
+-            }
+-            if (InStream != null) {
+-                try {
+-                    InStream.close();
+-                } catch (IOException ex) {
+-                }
+-            }
+-            if (OutStream != null) {
+-                try {
+-                    OutStream.close();
+-                } catch (IOException ex) {
+-                }
+-            }
+-            _PDULength = 0;
+-        }                
+-        
+-      return LastError;
+-    }
+-    
+-    public void Disconnect()
+-    {
+-        if (Connected)
+-        {
+-            try {
+-                OutStream.close();
+-                InStream.close();
+-                TCPSocket.close();
+-                _PDULength=0;
+-            } catch (IOException ex) {            
+-            }
+-            Connected=false;
+-        }
+-    }
+-    
+-    public int ConnectTo(String Address, int Rack, int Slot) 
+-    {       
+-        int RemoteTSAP=(ConnType<<8)+ (Rack * 0x20) + Slot;
+-        SetConnectionParams(Address, 0x0100, RemoteTSAP);
+-        return Connect();
+-    }
+-    
+-    public int PDULength()
+-    {
+-        return _PDULength;
+-    }
+-    
+-    public void SetConnectionParams(String Address, int LocalTSAP, int RemoteTSAP)
+-    {
+-        int LocTSAP = LocalTSAP & 0x0000FFFF;
+-        int RemTSAP = RemoteTSAP & 0x0000FFFF;        
+-        IPAddress    =  Address;
+-        LocalTSAP_HI = (byte) (LocTSAP>>8);
+-        LocalTSAP_LO = (byte) (LocTSAP & 0x00FF);
+-        RemoteTSAP_HI= (byte) (RemTSAP>>8);
+-        RemoteTSAP_LO= (byte) (RemTSAP & 0x00FF);      
+-    }
+- 
+-    public int ReadArea(int Area, int DBNumber, int Start, int Amount, byte[] Data)
+-    {
+-      int Address;
+-      int NumElements;
+-      int MaxElements;
+-      int TotElements;
+-      int SizeRequested;
+-      int Length;
+-      int Offset = 0;
+-      int WordSize = 1;
+-           
+-      LastError=0;
+-              
+-      // If we are addressing Timers or counters the element size is 2
+-      if ((Area==S7.S7AreaCT) || (Area==S7.S7AreaTM))
+-            WordSize = 2;
+-      
+-        MaxElements=(_PDULength-18) / WordSize; // 18 = Reply telegram header
+-            TotElements=Amount;
+-      
+-        while ((TotElements>0) && (LastError==0))
+-        {
+-            NumElements=TotElements;
+-            if (NumElements>MaxElements)
+-               NumElements=MaxElements;
+-
+-            SizeRequested = NumElements * WordSize;
+-
+-            // Setup the telegram
+-            System.arraycopy(S7_RW, 0, PDU, 0, Size_RD);
+-            // Set DB Number
+-            PDU[27] = (byte) Area;
+-            // Set Area
+-            if (Area==S7.S7AreaDB) 
+-                S7.SetWordAt(PDU,25,DBNumber);
+-
+-            // Adjusts Start and word length
+-            if ((Area==S7.S7AreaCT) || (Area==S7.S7AreaTM))
+-            {
+-                Address = Start;
+-                if (Area==S7.S7AreaCT)
+-                    PDU[22]=S7WLCounter;
+-                else
+-                    PDU[22]=S7WLTimer;
+-            }
+-            else
+-                Address = Start<<3;
+-
+-            // Num elements
+-            S7.SetWordAt(PDU,23,NumElements);
+-
+-            // Address into the PLC (only 3 bytes)           
+-            PDU[30] = (byte) (Address & 0x0FF);
+-            Address = Address >> 8;
+-            PDU[29] = (byte) (Address & 0x0FF);
+-            Address = Address >> 8;
+-            PDU[28] = (byte) (Address & 0x0FF);         
+-            
+-            SendPacket(PDU, Size_RD);
+-            if (LastError==0)
+-            {
+-                Length=RecvIsoPacket();
+-                if (LastError==0)
+-                {
+-                    if (Length>=25)
+-                    {
+-                        if ((Length-25==SizeRequested) && (PDU[21]==(byte)0xFF))
+-                        {
+-                            System.arraycopy(PDU, 25, Data, Offset, SizeRequested);
+-                            Offset+=SizeRequested;
+-                        }
+-                        else
+-                            LastError = errS7DataRead;
+-                    }
+-                    else
+-                        LastError = errS7InvalidPDU;
+-                }
+-            }
+-
+-            TotElements -= NumElements;
+-            Start += NumElements*WordSize;
+-        }
+-        return LastError;
+-    }
+-
+-    public int WriteArea(int Area, int DBNumber, int Start, int Amount, byte[] Data)
+-    {
+-      int Address;
+-      int NumElements;
+-      int MaxElements;
+-      int TotElements;
+-      int DataSize;
+-      int IsoSize;
+-      int Length;
+-      int Offset = 0;
+-      int WordSize = 1;
+-     
+-      LastError=0;
+-      
+-      // If we are addressing Timers or counters the element size is 2
+-      if ((Area==S7.S7AreaCT) || (Area==S7.S7AreaTM))
+-            WordSize = 2;
+-
+-        MaxElements=(_PDULength-35) / WordSize; // 18 = Reply telegram header
+-      TotElements=Amount;
+-      
+-        while ((TotElements>0) && (LastError==0))
+-        {
+-            NumElements=TotElements;
+-            if (NumElements>MaxElements)
+-               NumElements=MaxElements;
+-
+-            DataSize = NumElements * WordSize;
+-            IsoSize  = Size_WR + DataSize;
+-
+-            // Setup the telegram
+-            System.arraycopy(S7_RW, 0, PDU, 0, Size_WR);
+-            // Whole telegram Size
+-            S7.SetWordAt(PDU,2,IsoSize);
+-            // Data Length
+-            Length=DataSize+4;
+-            S7.SetWordAt(PDU,15,Length);
+-            // Function
+-            PDU[17]= (byte) 0x05;
+-            // Set DB Number
+-            PDU[27] = (byte) Area;
+-            if (Area==S7.S7AreaDB) 
+-                S7.SetWordAt(PDU,25,DBNumber);
+-
+-            // Adjusts Start and word length
+-            if ((Area==S7.S7AreaCT) || (Area==S7.S7AreaTM))
+-            {
+-                Address = Start;
+-                Length = DataSize;
+-                if (Area==S7.S7AreaCT)
+-                    PDU[22]=S7WLCounter;
+-                else
+-                    PDU[22]=S7WLTimer;
+-            }
+-            else
+-            {
+-                Address = Start<<3;
+-                Length  = DataSize<<3;
+-            }
+-            // Num elements
+-            S7.SetWordAt(PDU,23,NumElements);
+-            // Address into the PLC
+-            PDU[30] = (byte) (Address & 0x0FF);
+-            Address = Address >> 8;
+-            PDU[29] = (byte) (Address & 0x0FF);
+-            Address = Address >> 8;
+-            PDU[28] = (byte) (Address & 0x0FF);
+-            // Length
+-            S7.SetWordAt(PDU,33,Length);
+-            
+-            // Copies the Data
+-            System.arraycopy(Data, Offset, PDU, 35, DataSize);
+-                        
+-            SendPacket(PDU, IsoSize);
+-            if (LastError==0)
+-            {
+-                Length=RecvIsoPacket();
+-                if (LastError==0)
+-                {
+-                    if (Length==22)
+-                    {
+-                        if ((S7.GetWordAt(PDU,17)!=0) || (PDU[21]!=(byte)0xFF))
+-                            LastError = errS7DataWrite;
+-                    }
+-                    else
+-                        LastError = errS7InvalidPDU;
+-                }
+-            }
+-
+-            Offset+=DataSize;
+-            TotElements -= NumElements;
+-            Start += NumElements*WordSize;
+-        }
+-        return LastError;
+-    }
+-   
+-    public int GetAgBlockInfo(int BlockType, int BlockNumber, S7BlockInfo Block)
+-    {
+-      int Length;
+-        LastError=0;
+-        // Block Type
+-        S7_BI[30] = (byte) BlockType;
+-        // Block Number
+-        S7_BI[31]=(byte) ((BlockNumber / 10000)+0x30);
+-        BlockNumber=BlockNumber % 10000;
+-        S7_BI[32]=(byte) ((BlockNumber / 1000)+0x30);
+-        BlockNumber=BlockNumber % 1000;
+-        S7_BI[33]=(byte) ((BlockNumber / 100)+0x30);
+-        BlockNumber=BlockNumber % 100;
+-        S7_BI[34]=(byte) ((BlockNumber / 10)+0x30);
+-        BlockNumber=BlockNumber % 10;
+-        S7_BI[35]=(byte) ((BlockNumber / 1)+0x30);
+-        
+-        SendPacket(S7_BI);
+-        if (LastError==0)
+-        {
+-            Length=RecvIsoPacket();
+-            if (Length > 32) // the minimum expected
+-            {
+-                if ((S7.GetWordAt(PDU,27)==0) && (PDU[29]==(byte)0xFF))
+-                {
+-                    Block.Update(PDU, 42);
+-                }
+-                else
+-                    LastError = errS7FunctionError;
+-            }
+-            else
+-                LastError = errS7InvalidPDU;
+-        }
+-        
+-        return LastError;
+-    }      
+-    /**
+-     * 
+-     * @param DBNumber DB Number
+-     * @param Buffer   Destination buffer
+-     * @param SizeRead How many bytes were read
+-     * @return 
+-     */
+-    public int DBGet(int DBNumber, byte[] Buffer, IntByRef SizeRead)
+-    {
+-        S7BlockInfo Block = new S7BlockInfo();
+-        // Query the DB Length
+-        LastError = GetAgBlockInfo(S7.Block_DB, DBNumber, Block);
+-        if (LastError==0)
+-        {
+-            int SizeToRead = Block.MC7Size();
+-            // Checks the room
+-            if (SizeToRead<=Buffer.length)
+-            {
+-                LastError=ReadArea(S7.S7AreaDB, DBNumber, 0, SizeToRead, Buffer);
+-                if (LastError==0)
+-                    SizeRead.Value=SizeToRead;
+-            }
+-            else
+-                LastError=errS7BufferTooSmall;
+-        }
+-        return LastError;
+-    }  
+-    
+-    public int ReadSZL(int ID, int Index, S7Szl SZL)
+-    {
+-      int Length;
+-        int DataSZL;
+-        int Offset = 0;
+-        boolean Done = false;
+-        boolean First = true;
+-        byte Seq_in =0x00;
+-        int Seq_out =0x0000;
+-        
+-        LastError=0;
+-        SZL.DataSize=0;
+-        do
+-        {
+-            if (First)
+-            {
+-                S7.SetWordAt(S7_SZL_FIRST, 11, ++Seq_out);
+-                S7.SetWordAt(S7_SZL_FIRST, 29, ID);
+-                S7.SetWordAt(S7_SZL_FIRST, 31, Index);
+-                SendPacket(S7_SZL_FIRST);                
+-            }
+-            else
+-            {
+-                S7.SetWordAt(S7_SZL_NEXT, 11, ++Seq_out);
+-                PDU[24] = (byte)Seq_in;
+-                SendPacket(S7_SZL_NEXT);                
+-            }
+-            if (LastError!=0)
+-                return LastError;
+-            
+-            Length=RecvIsoPacket();
+-            if (LastError==0)
+-            {
+-                if (First)
+-                {
+-                    if (Length > 32) // the minimum expected
+-                    {
+-                        if ((S7.GetWordAt(PDU,27)==0) && (PDU[29]==(byte)0xFF))
+-                        {
+-                            // Gets Amount of this slice
+-                            DataSZL=S7.GetWordAt(PDU,31)-8; // Skips extra params (ID, Index ...)
+-                            Done=PDU[26]==0x00;
+-                            Seq_in=(byte)PDU[24]; // Slice sequence
+-                            
+-                            SZL.LENTHDR=S7.GetWordAt(PDU, 37);
+-                            SZL.N_DR=S7.GetWordAt(PDU, 39);
+-                            SZL.Copy(PDU, 41, Offset, DataSZL);                       
+-                            Offset+=DataSZL;
+-                            SZL.DataSize+=DataSZL;
+-                        }
+-                        else
+-                            LastError = errS7FunctionError;
+-                    }
+-                    else
+-                        LastError = errS7InvalidPDU;
+-                }
+-                else
+-                {
+-                    if (Length > 32) // the minimum expected
+-                    {
+-                        if ((S7.GetWordAt(PDU,27)==0) && (PDU[29]==(byte)0xFF))
+-                        {
+-                            // Gets Amount of this slice
+-                            DataSZL=S7.GetWordAt(PDU,31); 
+-                            Done=PDU[26]==0x00;
+-                            Seq_in=(byte)PDU[24]; // Slice sequence
+-                            SZL.Copy(PDU, 37, Offset, DataSZL);                       
+-                            Offset+=DataSZL;
+-                            SZL.DataSize+=DataSZL;
+-                        }
+-                        else
+-                            LastError = errS7FunctionError;
+-                    }
+-                    else
+-                        LastError = errS7InvalidPDU;
+-                }
+-            }            
+-            First=false;
+-        }            
+-        while(!Done && (LastError==0));
+-        
+-        return LastError;
+-    }
+-    
+-    
+-    public int GetCpuInfo(S7CpuInfo Info)
+-    {
+-        S7Szl SZL = new S7Szl(1024);
+-        
+-        LastError = ReadSZL(0x001C, 0x0000, SZL);
+-        if (LastError==0)
+-        {
+-            Info.Update(SZL.Data, 0);
+-        }
+-        return LastError;
+-    }
+-
+-    public int GetCpInfo(S7CpInfo Info)
+-    {
+-        S7Szl SZL = new S7Szl(1024);
+-        
+-        LastError = ReadSZL(0x0131, 0x0001, SZL);
+-        if (LastError==0)
+-        {
+-            Info.Update(SZL.Data, 0);
+-        }
+-        return LastError;
+-    }
+-    
+-    public int GetOrderCode(S7OrderCode Code)
+-    {
+-        S7Szl SZL = new S7Szl(1024);
+-        
+-        LastError = ReadSZL(0x0011, 0x0000, SZL);
+-        if (LastError==0)
+-        {
+-            Code.Update(SZL.Data, 0, SZL.DataSize);
+-        }
+-        return LastError;
+-    }
+-
+-    public int GetPlcDateTime(Date DateTime)
+-    {
+-        int Length;
+-
+-        LastError = 0;
+-        SendPacket(S7_GET_DT);
+-        if (LastError==0)
+-        {
+-            Length=RecvIsoPacket();
+-            if (Length > 30) // the minimum expected
+-            {
+-                if ((S7.GetWordAt(PDU,27)==0) && (PDU[29]==(byte)0xFF))
+-                {
+-                    DateTime=S7.GetDateAt(PDU, 34);
+-                }
+-                else
+-                    LastError = errS7FunctionError;
+-            }
+-            else
+-                LastError = errS7InvalidPDU;
+-        }
+-        
+-        return LastError;
+-    }
+-
+-    public int SetPlcDateTime(Date DateTime)
+-    {
+-        int Length;
+-       
+-        LastError = 0;
+-        S7.SetDateAt(S7_SET_DT, 31, DateTime);
+-        
+-        SendPacket(S7_SET_DT);
+-        if (LastError==0)
+-        {
+-            Length=RecvIsoPacket();
+-            if (Length > 30) // the minimum expected
+-            {
+-                if (S7.GetWordAt(PDU,27)!=0) 
+-                    LastError = errS7FunctionError;
+-            }
+-            else
+-                LastError = errS7InvalidPDU;
+-        }
+-        
+-        return LastError;
+-    }
+-
+-    public int SetPlcSystemDateTime()
+-    {
+-        return SetPlcDateTime(new Date());
+-    }
+-    
+-    public int PlcStop()
+-    {
+-        int Length;
+-       
+-        LastError = 0;
+-        SendPacket(S7_STOP);
+-        if (LastError==0)
+-        {
+-            Length=RecvIsoPacket();
+-            if (Length > 18) // 18 is the minimum expected
+-            {
+-                if (S7.GetWordAt(PDU,17)!=0) 
+-                    LastError = errS7FunctionError;
+-            }
+-            else
+-                LastError = errS7InvalidPDU;
+-        }
+-        return LastError;
+-    }
+-
+-    public int PlcHotStart()
+-    {
+-        int Length;
+-       
+-        LastError = 0;
+-        SendPacket(S7_HOT_START);
+-        if (LastError==0)
+-        {
+-            Length=RecvIsoPacket();
+-            if (Length > 18) // the minimum expected
+-            {
+-                if (S7.GetWordAt(PDU,17)!=0) 
+-                    LastError = errS7FunctionError;
+-            }
+-            else
+-                LastError = errS7InvalidPDU;
+-        }
+-        return LastError;
+-    }
+-
+-    public int PlcColdStart()
+-    {
+-        int Length;
+-       
+-        LastError = 0;
+-        SendPacket(S7_COLD_START);
+-        if (LastError==0)
+-        {
+-            Length=RecvIsoPacket();
+-            if (Length > 18) // the minimum expected
+-            {
+-                if (S7.GetWordAt(PDU,17)!=0) 
+-                    LastError = errS7FunctionError;
+-            }
+-            else
+-                LastError = errS7InvalidPDU;
+-        }
+-        return LastError;
+-    }
+-
+-    public int GetPlcStatus(IntByRef Status)
+-    {
+-        int Length;
+-       
+-        LastError = 0;
+-        SendPacket(S7_GET_STAT);
+-        if (LastError==0)
+-        {
+-            Length=RecvIsoPacket();
+-            if (Length > 30) // the minimum expected
+-            {
+-                if (S7.GetWordAt(PDU,27)==0) 
+-                {
+-                    switch (PDU[44])
+-                    {
+-                        case S7.S7CpuStatusUnknown :
+-                        case S7.S7CpuStatusRun     :
+-                        case S7.S7CpuStatusStop    : Status.Value=PDU[44];
+-                        break;
+-                        default :
+-                        // Since RUN status is always 0x08 for all CPUs and CPs, STOP status
+-                        // sometime can be coded as 0x03 (especially for old cpu...)
+-                            Status.Value=S7.S7CpuStatusStop;
+-                    }                    
+-                }
+-                else
+-                    LastError = errS7FunctionError;
+-            }
+-            else
+-                LastError = errS7InvalidPDU;
+-        }            
+-        return LastError;
+-    }
+-
+-    public int SetSessionPassword(String Password)
+-    {
+-        byte[] pwd = {0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20};
+-        int Length;
+-
+-        LastError = 0;
+-        // Adjusts the Password length to 8
+-        if (Password.length()>8) 
+-            Password=Password.substring(0, 8);
+-        else
+-        {
+-            while (Password.length()<8)
+-                Password=Password+" ";
+-        }
+-        
+-        try {
+-            pwd = Password.getBytes("UTF-8");
+-        } catch (UnsupportedEncodingException ex) {
+-            LastError = errS7InvalidParams;
+-        }
+-        if (LastError==0)
+-        {            
+-            // Encodes the password
+-            pwd[0]=(byte) (pwd[0] ^ 0x55);
+-            pwd[1]=(byte) (pwd[1] ^ 0x55);
+-            for (int c = 2; c < 8; c++)
+-            {
+-                pwd[c]=(byte) (pwd[c] ^ 0x55 ^ pwd[c-2]);            
+-            }
+-            System.arraycopy(pwd, 0, S7_SET_PWD, 29, 8);
+-            // Sends the telegrem
+-            SendPacket(S7_SET_PWD);
+-            if (LastError==0)
+-            {
+-                Length=RecvIsoPacket();
+-                if (Length > 32) // the minimum expected
+-                {
+-                    if (S7.GetWordAt(PDU,27)!=0) 
+-                        LastError = errS7FunctionError;                    
+-                }                
+-                else
+-                    LastError = errS7InvalidPDU;                
+-            }            
+-        }        
+-        return LastError;
+-    }
+-        
+-    public int ClearSessionPassword()
+-    {
+-        int Length;
+-       
+-        LastError = 0;       
+-        SendPacket(S7_CLR_PWD);
+-        if (LastError==0)
+-        {
+-            Length=RecvIsoPacket();
+-            if (Length > 30) // the minimum expected
+-            {
+-                if (S7.GetWordAt(PDU,27)!=0) 
+-                    LastError = errS7FunctionError;
+-            }
+-            else
+-                LastError = errS7InvalidPDU;
+-        }        
+-        return LastError;
+-    }
+-    
+-    public int GetProtection(S7Protection Protection)
+-    {
+-        S7Szl SZL = new S7Szl(256);
+-        
+-        LastError = ReadSZL(0x0232, 0x0004, SZL);
+-        if (LastError==0)
+-        {
+-            Protection.Update(SZL.Data);
+-        }
+-        return LastError;
+-    }
+-    
+-}
++/*=============================================================================|
++|  PROJECT Moka7                                                         1.0.2 |
++|==============================================================================|
++|  Copyright (C) 2013, 2016 Davide Nardella                                    |
++|  All rights reserved.                                                        |
++|==============================================================================|
++|  SNAP7 is free software: you can redistribute it and/or modify               |
++|  it under the terms of the Lesser GNU General Public License as published by |
++|  the Free Software Foundation, either version 3 of the License, or under     |
++|  EPL Eclipse Public License 1.0.                                             |
++|                                                                              |
++|  This means that you have to chose in advance which take before you import   |
++|  the library into your project.                                              |
++|                                                                              |
++|  SNAP7 is distributed in the hope that it will be useful,                    |
++|  but WITHOUT ANY WARRANTY; without even the implied warranty of              |
++|  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you    |
++|  decide to adopt.                                                            |
++|                                                                              |
++|=============================================================================*/
++package Moka7;
++
++import java.io.DataInputStream;
++import java.io.DataOutputStream;
++import java.io.IOException;
++import java.io.UnsupportedEncodingException;
++import java.net.InetSocketAddress;
++import java.net.Socket;
++import java.net.SocketAddress;
++import java.util.Date;
++
++
++/**
++ *
++ * @author Davide Nardella
++ */
++public class S7Client
++{
++    // WordLength
++    public static final int S7WLBit     = 0x01;
++    public static final int S7WLByte    = 0x02;
++    public static final int S7WLCounter = 0x1C;
++    public static final int S7WLTimer   = 0x1D;
++
++    // Error Codes
++    public static final int errTCPConnectionFailed = 0x0001;
++    public static final int errTCPDataSend         = 0x0002;
++    public static final int errTCPDataRecv         = 0x0003;
++    public static final int errTCPDataRecvTout     = 0x0004;
++    public static final int errTCPConnectionReset  = 0x0005;
++    public static final int errISOInvalidPDU       = 0x0006;
++    public static final int errISOConnectionFailed = 0x0007;
++    public static final int errISONegotiatingPDU   = 0x0008;
++    public static final int errS7InvalidPDU        = 0x0009;
++    public static final int errS7DataRead          = 0x000A;
++    public static final int errS7DataWrite         = 0x000B;
++    public static final int errS7BufferTooSmall    = 0x000C;
++    public static final int errS7FunctionError     = 0x000D;
++    public static final int errS7InvalidParams     = 0x000E;
++
++    // Public fields
++    public boolean Connected = false;
++    public int LastError = 0;
++    public int RecvTimeout = 2000;
++
++    // Privates
++    private static final int ISOTCP = 102; // ISOTCP Port
++    private static final int MinPduSize = 16;
++    private static final int DefaultPduSizeRequested = 480;
++    private static final int IsoHSize = 7; // TPKT+COTP Header Size
++    private static final int MaxPduSize = DefaultPduSizeRequested+IsoHSize;
++
++    private Socket TCPSocket;
++    private final byte[] PDU = new byte[2048];
++
++    private DataInputStream InStream = null;
++    private DataOutputStream OutStream = null;
++
++    private String IPAddress;
++
++    private byte LocalTSAP_HI;
++    private byte LocalTSAP_LO;
++    private byte RemoteTSAP_HI;
++    private byte RemoteTSAP_LO;
++    private byte LastPDUType;
++
++    private short ConnType = S7.PG;
++    private int _PDULength = 0;
++
++    // Telegrams
++    // ISO Connection Request telegram (contains also ISO Header and COTP Header)
++    private static final byte ISO_CR[] = {
++        // TPKT (RFC1006 Header)
++        (byte)0x03, // RFC 1006 ID (3)
++        (byte)0x00, // Reserved, always 0
++        (byte)0x00, // High part of packet lenght (entire frame, payload and TPDU included)
++        (byte)0x16, // Low part of packet lenght (entire frame, payload and TPDU included)
++        // COTP (ISO 8073 Header)
++        (byte)0x11, // PDU Size Length
++        (byte)0xE0, // CR - Connection Request ID
++        (byte)0x00, // Dst Reference HI
++        (byte)0x00, // Dst Reference LO
++        (byte)0x00, // Src Reference HI
++        (byte)0x01, // Src Reference LO
++        (byte)0x00, // Class + Options Flags
++        (byte)0xC0, // PDU Max Length ID
++        (byte)0x01, // PDU Max Length HI
++        (byte)0x0A, // PDU Max Length LO
++        (byte)0xC1, // Src TSAP Identifier
++        (byte)0x02, // Src TSAP Length (2 bytes)
++        (byte)0x01, // Src TSAP HI (will be overwritten)
++        (byte)0x00, // Src TSAP LO (will be overwritten)
++        (byte)0xC2, // Dst TSAP Identifier
++        (byte)0x02, // Dst TSAP Length (2 bytes)
++        (byte)0x01, // Dst TSAP HI (will be overwritten)
++        (byte)0x02  // Dst TSAP LO (will be overwritten)
++    };
++
++    // S7 PDU Negotiation Telegram (contains also ISO Header and COTP Header)
++    private static final byte S7_PN[] = {
++        (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x19,
++        (byte)0x02, (byte)0xf0, (byte)0x80, // TPKT + COTP (see above for info)
++        (byte)0x32, (byte)0x01, (byte)0x00, (byte)0x00,
++        (byte)0x04, (byte)0x00, (byte)0x00, (byte)0x08,
++        (byte)0x00, (byte)0x00, (byte)0xf0, (byte)0x00,
++        (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x01,
++        (byte)0x00, (byte)0x1e // PDU Length Requested = HI-LO 480 bytes
++    };
++
++    // S7 Read/Write Request Header (contains also ISO Header and COTP Header)
++    private static final byte S7_RW[] = { // 31-35 bytes
++        (byte)0x03,(byte)0x00,
++        (byte)0x00,(byte)0x1f,  // Telegram Length (Data Size + 31 or 35)
++        (byte)0x02,(byte)0xf0, (byte)0x80, // COTP (see above for info)
++        (byte)0x32,             // S7 Protocol ID
++        (byte)0x01,             // Job Type
++        (byte)0x00,(byte)0x00,  // Redundancy identification
++        (byte)0x05,(byte)0x00,  // PDU Reference
++        (byte)0x00,(byte)0x0e,  // Parameters Length
++        (byte)0x00,(byte)0x00,  // Data Length = Size(bytes) + 4
++        (byte)0x04,             // Function 4 Read Var, 5 Write Var
++        (byte)0x01,             // Items count
++        (byte)0x12,             // Var spec.
++        (byte)0x0a,             // Length of remaining bytes
++        (byte)0x10,             // Syntax ID
++        S7WLByte,               // Transport Size
++        (byte)0x00,(byte)0x00,  // Num Elements
++        (byte)0x00,(byte)0x00,  // DB Number (if any, else 0)
++        (byte)0x84,             // Area Type
++        (byte)0x00,(byte)0x00,(byte)0x00, // Area Offset
++        // WR area
++        (byte)0x00,             // Reserved
++        (byte)0x04,             // Transport size
++        (byte)0x00,(byte)0x00,  // Data Length * 8 (if not timer or counter)
++    };
++    private static final int Size_RD = 31;
++    private static final int Size_WR = 35;
++
++    // S7 Get Block Info Request Header (contains also ISO Header and COTP Header)
++    private static final byte S7_BI[] = {
++        (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x25,
++        (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
++        (byte)0x07, (byte)0x00, (byte)0x00, (byte)0x05,
++        (byte)0x00, (byte)0x00, (byte)0x08, (byte)0x00,
++        (byte)0x0c, (byte)0x00, (byte)0x01, (byte)0x12,
++        (byte)0x04, (byte)0x11, (byte)0x43, (byte)0x03,
++        (byte)0x00, (byte)0xff, (byte)0x09, (byte)0x00,
++        (byte)0x08, (byte)0x30,
++        (byte)0x41, // Block Type
++        (byte)0x30, (byte)0x30, (byte)0x30, (byte)0x30, (byte)0x30, // ASCII Block Number
++        (byte)0x41
++    };
++
++    // SZL First telegram request
++    private static final byte S7_SZL_FIRST[] = {
++        (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x21,
++        (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
++        (byte)0x07, (byte)0x00, (byte)0x00,
++        (byte)0x05, (byte)0x00, // Sequence out
++        (byte)0x00, (byte)0x08, (byte)0x00,
++        (byte)0x08, (byte)0x00, (byte)0x01, (byte)0x12,
++        (byte)0x04, (byte)0x11, (byte)0x44, (byte)0x01,
++        (byte)0x00, (byte)0xff, (byte)0x09, (byte)0x00,
++        (byte)0x04,
++        (byte)0x00, (byte)0x00, // ID (29)
++        (byte)0x00, (byte)0x00  // Index (31)
++    };
++
++    // SZL Next telegram request
++    private static final byte S7_SZL_NEXT[] = {
++        (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x21,
++        (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
++        (byte)0x07, (byte)0x00, (byte)0x00, (byte)0x06,
++        (byte)0x00, (byte)0x00, (byte)0x0c, (byte)0x00,
++        (byte)0x04, (byte)0x00, (byte)0x01, (byte)0x12,
++        (byte)0x08, (byte)0x12, (byte)0x44, (byte)0x01,
++        (byte)0x01, // Sequence
++        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
++        (byte)0x0a, (byte)0x00, (byte)0x00, (byte)0x00
++    };
++
++    // Get Date/Time request
++    private static final byte S7_GET_DT[] = {
++        (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x1d,
++        (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
++        (byte)0x07, (byte)0x00, (byte)0x00, (byte)0x38,
++        (byte)0x00, (byte)0x00, (byte)0x08, (byte)0x00,
++        (byte)0x04, (byte)0x00, (byte)0x01, (byte)0x12,
++        (byte)0x04, (byte)0x11, (byte)0x47, (byte)0x01,
++        (byte)0x00, (byte)0x0a, (byte)0x00, (byte)0x00,
++        (byte)0x00
++    };
++
++    // Set Date/Time command
++    private static final byte S7_SET_DT[] = {
++        (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x27,
++        (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
++        (byte)0x07, (byte)0x00, (byte)0x00, (byte)0x89,
++        (byte)0x03, (byte)0x00, (byte)0x08, (byte)0x00,
++        (byte)0x0e, (byte)0x00, (byte)0x01, (byte)0x12,
++        (byte)0x04, (byte)0x11, (byte)0x47, (byte)0x02,
++        (byte)0x00, (byte)0xff, (byte)0x09, (byte)0x00,
++        (byte)0x0a, (byte)0x00, (byte)0x19, // Hi part of Year
++        (byte)0x13, // Lo part of Year
++        (byte)0x12, // Month
++        (byte)0x06, // Day
++        (byte)0x17, // Hour
++        (byte)0x37, // Min
++        (byte)0x13, // Sec
++        (byte)0x00, (byte)0x01 // ms + Day of week
++    };
++
++    // S7 STOP request
++    private static final byte S7_STOP[] = {
++        (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x21,
++        (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
++        (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x0e,
++        (byte)0x00, (byte)0x00, (byte)0x10, (byte)0x00,
++        (byte)0x00, (byte)0x29, (byte)0x00, (byte)0x00,
++        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x09,
++        (byte)0x50, (byte)0x5f, (byte)0x50, (byte)0x52,
++        (byte)0x4f, (byte)0x47, (byte)0x52, (byte)0x41,
++        (byte)0x4d
++    };
++
++    // S7 HOT Start request
++    private static final byte S7_HOT_START[] = {
++        (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x25,
++        (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
++        (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x0c,
++        (byte)0x00, (byte)0x00, (byte)0x14, (byte)0x00,
++        (byte)0x00, (byte)0x28, (byte)0x00, (byte)0x00,
++        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
++        (byte)0xfd, (byte)0x00, (byte)0x00, (byte)0x09,
++        (byte)0x50, (byte)0x5f, (byte)0x50, (byte)0x52,
++        (byte)0x4f, (byte)0x47, (byte)0x52, (byte)0x41,
++        (byte)0x4d
++    };
++
++    // S7 COLD Start request
++    private static final byte S7_COLD_START[] = {
++        (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x27,
++        (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
++        (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x0f,
++        (byte)0x00, (byte)0x00, (byte)0x16, (byte)0x00,
++        (byte)0x00, (byte)0x28, (byte)0x00, (byte)0x00,
++        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
++        (byte)0xfd, (byte)0x00, (byte)0x02, (byte)0x43,
++        (byte)0x20, (byte)0x09, (byte)0x50, (byte)0x5f,
++        (byte)0x50, (byte)0x52, (byte)0x4f, (byte)0x47,
++        (byte)0x52, (byte)0x41, (byte)0x4d
++    };
++
++    // S7 Get PLC Status
++    private static final byte S7_GET_STAT[] = {
++        (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x21,
++        (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
++        (byte)0x07, (byte)0x00, (byte)0x00, (byte)0x2c,
++        (byte)0x00, (byte)0x00, (byte)0x08, (byte)0x00,
++        (byte)0x08, (byte)0x00, (byte)0x01, (byte)0x12,
++        (byte)0x04, (byte)0x11, (byte)0x44, (byte)0x01,
++        (byte)0x00, (byte)0xff, (byte)0x09, (byte)0x00,
++        (byte)0x04, (byte)0x04, (byte)0x24, (byte)0x00,
++        (byte)0x00
++    };
++
++    // S7 Set Session Password
++    private static final byte S7_SET_PWD[] = {
++        (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x25,
++        (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
++        (byte)0x07, (byte)0x00, (byte)0x00, (byte)0x27,
++        (byte)0x00, (byte)0x00, (byte)0x08, (byte)0x00,
++        (byte)0x0c, (byte)0x00, (byte)0x01, (byte)0x12,
++        (byte)0x04, (byte)0x11, (byte)0x45, (byte)0x01,
++        (byte)0x00, (byte)0xff, (byte)0x09, (byte)0x00,
++        (byte)0x08,
++        // 8 Char Encoded Password
++        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
++        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00
++    };
++
++    // S7 Clear Session Password
++    private static final byte S7_CLR_PWD[] = {
++        (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x1d,
++        (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
++        (byte)0x07, (byte)0x00, (byte)0x00, (byte)0x29,
++        (byte)0x00, (byte)0x00, (byte)0x08, (byte)0x00,
++        (byte)0x04, (byte)0x00, (byte)0x01, (byte)0x12,
++        (byte)0x04, (byte)0x11, (byte)0x45, (byte)0x02,
++        (byte)0x00, (byte)0x0a, (byte)0x00, (byte)0x00,
++        (byte)0x00
++    };
++
++    public S7Client()
++    {
++        // Placeholder for future implementations
++    }
++
++    public static String ErrorText(int Error)
++    {
++        switch (Error)
++        {
++            case errTCPConnectionFailed :
++                return "TCP Connection failed.";
++            case errTCPDataSend :
++                return "TCP Sending error.";
++            case errTCPDataRecv :
++                return "TCP Receiving error.";
++            case errTCPDataRecvTout :
++                return "Data Receiving timeout.";
++            case errTCPConnectionReset :
++                return "Connection reset by the peer.";
++            case errISOInvalidPDU :
++                return "Invalid ISO PDU received.";
++            case errISOConnectionFailed :
++                return "ISO connection refused by the CPU.";
++            case errISONegotiatingPDU :
++                return "ISO error negotiating the PDU length.";
++            case errS7InvalidPDU :
++                return "Invalid S7 PDU received.";
++            case errS7DataRead :
++                return "S7 Error reading data from the CPU.";
++            case errS7DataWrite :
++                return "S7 Error writing data to the CPU.";
++            case errS7BufferTooSmall :
++                return "The Buffer supplied to the function is too small.";
++            case errS7FunctionError :
++                return "S7 function refused by the CPU.";
++            case errS7InvalidParams :
++                return "Invalid parameters supplied to the function.";
++            default :
++                return "Unknown error : 0x"+Integer.toHexString(Error);
++        }
++    }
++
++    private int TCPConnect()
++    {
++        SocketAddress sockaddr = new InetSocketAddress(IPAddress, ISOTCP);
++        LastError=0;
++        try {
++            TCPSocket = new Socket();
++            TCPSocket.connect(sockaddr ,5000);
++            TCPSocket.setTcpNoDelay(true);
++            InStream = new DataInputStream(TCPSocket.getInputStream());
++            OutStream = new DataOutputStream(TCPSocket.getOutputStream());
++        }
++        catch (IOException e) {
++            LastError=errTCPConnectionFailed;
++        }
++        return LastError;
++    }
++
++    private int WaitForData(int Size, int Timeout)
++    {
++        int cnt = 0;
++        LastError=0;
++        int SizeAvail;
++        boolean Expired = false;
++        try
++        {
++            SizeAvail=InStream.available();
++            while ((SizeAvail<Size) && (!Expired) && (LastError==0))
++            {
++                cnt++;
++                try {
++                    Thread.sleep(1);
++                }
++                catch (InterruptedException ex) {
++                    LastError=errTCPDataRecvTout;
++                }
++                SizeAvail=InStream.available();
++                Expired=cnt>Timeout;
++                // If timeout we clean the buffer
++                if (Expired && (SizeAvail>0) && (LastError==0))
++                  InStream.read(PDU, 0, SizeAvail);
++            }
++        }
++        catch (IOException ex)
++        {
++            LastError=errTCPDataRecvTout;
++        }
++        if (cnt>=Timeout)
++        {
++            LastError=errTCPDataRecvTout;
++        }
++        return LastError;
++    }
++
++    private int RecvPacket(byte[] Buffer, int Start, int Size)
++    {
++        int BytesRead=0;
++        LastError=WaitForData(Size,RecvTimeout);
++        if (LastError==0)
++        {
++            try {
++                BytesRead = InStream.read(Buffer, Start, Size);
++            } catch (IOException ex) {
++                LastError=errTCPDataRecv;
++            }
++            if (BytesRead==0)
++                LastError=errTCPConnectionReset;
++        }
++        return LastError;
++    }
++
++    private void SendPacket(byte[] Buffer, int Len)
++    {
++        LastError = 0;
++        try {
++            OutStream.write(Buffer,0,Len);
++            OutStream.flush();
++        } catch (IOException ex) {
++            LastError = errTCPDataSend;
++        }
++    }
++    private void SendPacket(byte[] Buffer)
++    {
++        SendPacket(Buffer,Buffer.length);
++    }
++
++    private int RecvIsoPacket()
++    {
++        Boolean Done = false;
++        int Size = 0;
++        while ((LastError==0) && !Done)
++        {
++            // Get TPKT (4 bytes)
++            RecvPacket(PDU, 0, 4);
++            if (LastError==0)
++            {
++                Size=S7.GetWordAt(PDU,2);
++                // Check 0 bytes Data Packet (only TPKT+COTP = 7 bytes)
++                if (Size==IsoHSize)
++                    RecvPacket(PDU,4, 3); // Skip remaining 3 bytes and Done is still false
++                else
++                {
++                    if ((Size>MaxPduSize) || (Size<MinPduSize))
++                        LastError=errISOInvalidPDU;
++                    else
++                        Done = true; // a valid Length !=7 && >16 && <247
++                }
++            }
++        }
++        if (LastError==0)
++        {
++            RecvPacket(PDU,4, 3); // Skip remaining 3 COTP bytes
++            LastPDUType=PDU[5];   // Stores PDU Type, we need it
++            // Receives the S7 Payload
++            RecvPacket(PDU, 7, Size-IsoHSize);
++        }
++        if (LastError==0)
++            return Size;
++        else
++            return 0;
++    }
++
++    private int ISOConnect()
++    {
++        int Size;
++        ISO_CR[16]=LocalTSAP_HI;
++        ISO_CR[17]=LocalTSAP_LO;
++        ISO_CR[20]=RemoteTSAP_HI;
++        ISO_CR[21]=RemoteTSAP_LO;
++
++        // Sends the connection request telegram
++        SendPacket(ISO_CR);
++        if (LastError==0)
++        {
++            // Gets the reply (if any)
++            Size=RecvIsoPacket();
++            if (LastError==0)
++            {
++                if (Size==22)
++                {
++                    if (LastPDUType!=(byte)0xD0) // 0xD0 = CC Connection confirm
++                        LastError=errISOConnectionFailed;
++                }
++                else
++                    LastError=errISOInvalidPDU;
++            }
++        }
++        return LastError;
++    }
++
++    private int NegotiatePduLength()
++    {
++        int Length;
++        // Set PDU Size Requested
++        S7.SetWordAt(S7_PN,23,DefaultPduSizeRequested);
++        // Sends the connection request telegram
++        SendPacket(S7_PN);
++        if (LastError==0)
++        {
++            Length=RecvIsoPacket();
++            if (LastError==0)
++            {
++                // check S7 Error
++                if ((Length==27) && (PDU[17]==0) && (PDU[18]==0))  // 20 = size of Negotiate Answer
++                {
++                    // Get PDU Size Negotiated
++                    _PDULength = S7.GetWordAt(PDU,25);
++                    if (_PDULength>0)
++                        return 0;
++                    else
++                        LastError=errISONegotiatingPDU;
++                }
++                else
++                    LastError=errISONegotiatingPDU;
++            }
++        }
++        return LastError;
++    }
++
++    public void SetConnectionType(short ConnectionType)
++    {
++        ConnType=ConnectionType;
++    }
++
++    public int Connect()
++    {
++        LastError=0;
++        if (!Connected)
++        {
++            TCPConnect();
++            if (LastError==0) // First stage : TCP Connection
++            {
++                ISOConnect();
++                if (LastError==0) // Second stage : ISOTCP (ISO 8073) Connection
++                {
++                    LastError=NegotiatePduLength(); // Third stage : S7 PDU negotiation
++                }
++            }
++        }
++        Connected=LastError==0;
++
++        // In case the connection is not completely established (TCP connection + ISO connection + PDU negotiation)
++        // we close the socket and its IO streams to revert the object back to pre-Connect() state
++        if (!Connected)
++        {
++            if (TCPSocket != null) {
++                try {
++                    TCPSocket.close();
++                } catch (IOException ex) {
++                }
++            }
++            if (InStream != null) {
++                try {
++                    InStream.close();
++                } catch (IOException ex) {
++                }
++            }
++            if (OutStream != null) {
++                try {
++                    OutStream.close();
++                } catch (IOException ex) {
++                }
++            }
++            _PDULength = 0;
++        }
++
++        return LastError;
++    }
++
++    public void Disconnect()
++    {
++        if (Connected)
++        {
++            try {
++                OutStream.close();
++                InStream.close();
++                TCPSocket.close();
++                _PDULength=0;
++            } catch (IOException ex) {
++            }
++            Connected=false;
++        }
++    }
++
++    public int ConnectTo(String Address, int Rack, int Slot)
++    {
++        int RemoteTSAP=(ConnType<<8)+ (Rack * 0x20) + Slot;
++        SetConnectionParams(Address, 0x0100, RemoteTSAP);
++        return Connect();
++    }
++
++    public int PDULength()
++    {
++        return _PDULength;
++    }
++
++    public void SetConnectionParams(String Address, int LocalTSAP, int RemoteTSAP)
++    {
++        int LocTSAP = LocalTSAP & 0x0000FFFF;
++        int RemTSAP = RemoteTSAP & 0x0000FFFF;
++        IPAddress    =  Address;
++        LocalTSAP_HI = (byte) (LocTSAP>>8);
++        LocalTSAP_LO = (byte) (LocTSAP & 0x00FF);
++        RemoteTSAP_HI= (byte) (RemTSAP>>8);
++        RemoteTSAP_LO= (byte) (RemTSAP & 0x00FF);
++    }
++
++    public int ReadArea(int Area, int DBNumber, int Start, int Amount, int WordLength, byte[] Data)
++    {
++        int Address;
++        int NumElements;
++        int MaxElements;
++        int TotElements;
++        int SizeRequested;
++        int Length;
++        int Offset = 0;
++        byte WordSize = 1;
++
++        LastError=0;
++
++        // If we are addressing Timers or counters the element size is 2
++        if ((Area==S7.S7AreaCT) || (Area==S7.S7AreaTM))
++            WordSize = 2;
++
++        MaxElements=(_PDULength-18) / WordSize; // 18 = Reply telegram header
++            TotElements=Amount;
++
++        while ((TotElements>0) && (LastError==0))
++        {
++            NumElements=TotElements;
++            if (NumElements>MaxElements)
++               NumElements=MaxElements;
++
++            SizeRequested = NumElements * WordSize;
++
++            // Setup the telegram
++            System.arraycopy(S7_RW, 0, PDU, 0, Size_RD);
++            // Set DB Number
++            PDU[27] = (byte) Area;
++            // Set Area
++            if (Area==S7.S7AreaDB)
++                S7.SetWordAt(PDU,25,DBNumber);
++
++            PDU[22] = (byte) WordLength;
++            // Adjusts Start and word length
++            if ((WordLength==S7WLBit) || (WordLength==S7WLTimer) || (WordLength==S7WLCounter))
++            {
++                Address = Start;
++            }
++            else
++            {
++                Address = Start<<3;
++            }
++
++            // Num elements
++            S7.SetWordAt(PDU,23,NumElements);
++
++            // Address into the PLC (only 3 bytes)
++            PDU[30] = (byte) (Address & 0x0FF);
++            Address = Address >> 8;
++            PDU[29] = (byte) (Address & 0x0FF);
++            Address = Address >> 8;
++            PDU[28] = (byte) (Address & 0x0FF);
++
++            // Transport Size
++            PDU[32] = 0x04;
++            if (WordLength==S7WLBit)
++            {
++                PDU[32] = 0x03;
++            }
++            else if ((WordLength==S7WLTimer) || (WordLength==S7WLCounter))
++            {
++                PDU[32] = 0x09;
++            }
++
++            SendPacket(PDU, Size_RD);
++            if (LastError==0)
++            {
++                Length=RecvIsoPacket();
++                if (LastError==0)
++                {
++                    if (Length>=25)
++                    {
++                        if ((Length-25==SizeRequested) && (PDU[21]==(byte)0xFF))
++                        {
++                            System.arraycopy(PDU, 25, Data, Offset, SizeRequested);
++                            Offset+=SizeRequested;
++                        }
++                        else
++                            LastError = errS7DataRead;
++                    }
++                    else
++                        LastError = errS7InvalidPDU;
++                }
++            }
++
++            TotElements -= NumElements;
++            Start += NumElements*WordSize;
++        }
++        return LastError;
++    }
++
++    public int WriteArea(int Area, int DBNumber, int Start, int Amount, int WordLength, byte[] Data)
++    {
++        int Address;
++        int NumElements;
++        int MaxElements;
++        int TotElements;
++        int DataSize;
++        int IsoSize;
++        int Length;
++        int Offset = 0;
++        byte WordSize = 1;
++
++        LastError=0;
++
++        // If we are addressing Timers or counters the element size is 2
++        if ((Area==S7.S7AreaCT) || (Area==S7.S7AreaTM))
++            WordSize = 2;
++
++        MaxElements=(_PDULength-35) / WordSize; // 35 = Reply telegram header
++        TotElements=Amount;
++
++        while ((TotElements>0) && (LastError==0))
++        {
++            NumElements=TotElements;
++            if (NumElements>MaxElements)
++               NumElements=MaxElements;
++
++            DataSize = NumElements * WordSize;
++            IsoSize  = Size_WR + DataSize;
++
++            // Setup the telegram
++            System.arraycopy(S7_RW, 0, PDU, 0, Size_WR);
++            // Whole telegram Size
++            S7.SetWordAt(PDU,2,IsoSize);
++            // Data Length
++            Length=DataSize+4;
++            S7.SetWordAt(PDU,15,Length);
++            // Function
++            PDU[17]= (byte) 0x05;
++            // Set DB Number
++            PDU[27] = (byte) Area;
++            if (Area==S7.S7AreaDB)
++                S7.SetWordAt(PDU,25,DBNumber);
++
++            PDU[22] = (byte) WordLength;
++            // Adjusts Start and word length
++            if ((WordLength==S7WLBit) || (WordLength==S7WLTimer) || (WordLength==S7WLCounter))
++            {
++                Address = Start;
++                Length = DataSize;
++            }
++            else
++            {
++                Address = Start<<3;
++                Length = DataSize<<3;
++            }
++
++            // Num elements
++            S7.SetWordAt(PDU,23,NumElements);
++            // Address into the PLC
++            PDU[30] = (byte) (Address & 0x0FF);
++            Address = Address >> 8;
++            PDU[29] = (byte) (Address & 0x0FF);
++            Address = Address >> 8;
++            PDU[28] = (byte) (Address & 0x0FF);
++
++            // Transport Size
++            PDU[32] = 0x04;
++            if (WordLength==S7WLBit)
++            {
++                PDU[32] = 0x03;
++            }
++            else if ((WordLength==S7WLTimer) || (WordLength==S7WLCounter))
++            {
++                PDU[32] = 0x09;
++            }
++
++            // Length
++            S7.SetWordAt(PDU,33,Length);
++
++            // Copies the Data
++            System.arraycopy(Data, Offset, PDU, 35, DataSize);
++
++            SendPacket(PDU, IsoSize);
++            if (LastError==0)
++            {
++                Length=RecvIsoPacket();
++                if (LastError==0)
++                {
++                    if (Length==22)
++                    {
++                        if ((S7.GetWordAt(PDU,17)!=0) || (PDU[21]!=(byte)0xFF))
++                            LastError = errS7DataWrite;
++                    }
++                    else
++                        LastError = errS7InvalidPDU;
++                }
++            }
++
++            Offset+=DataSize;
++            TotElements -= NumElements;
++            Start += NumElements*WordSize;
++        }
++        return LastError;
++    }
++
++    public int GetAgBlockInfo(int BlockType, int BlockNumber, S7BlockInfo Block)
++    {
++        int Length;
++        LastError=0;
++        // Block Type
++        S7_BI[30] = (byte) BlockType;
++        // Block Number
++        S7_BI[31]=(byte) ((BlockNumber / 10000)+0x30);
++        BlockNumber=BlockNumber % 10000;
++        S7_BI[32]=(byte) ((BlockNumber / 1000)+0x30);
++        BlockNumber=BlockNumber % 1000;
++        S7_BI[33]=(byte) ((BlockNumber / 100)+0x30);
++        BlockNumber=BlockNumber % 100;
++        S7_BI[34]=(byte) ((BlockNumber / 10)+0x30);
++        BlockNumber=BlockNumber % 10;
++        S7_BI[35]=(byte) ((BlockNumber / 1)+0x30);
++
++        SendPacket(S7_BI);
++        if (LastError==0)
++        {
++            Length=RecvIsoPacket();
++            if (Length > 32) // the minimum expected
++            {
++                if ((S7.GetWordAt(PDU,27)==0) && (PDU[29]==(byte)0xFF))
++                {
++                    Block.Update(PDU, 42);
++                }
++                else
++                    LastError = errS7FunctionError;
++            }
++            else
++                LastError = errS7InvalidPDU;
++        }
++
++        return LastError;
++    }
++    /**
++     *
++     * @param DBNumber DB Number
++     * @param Buffer   Destination buffer
++     * @param SizeRead How many bytes were read
++     * @return
++     */
++    public int DBGet(int DBNumber, byte[] Buffer, IntByRef SizeRead)
++    {
++        S7BlockInfo Block = new S7BlockInfo();
++        // Query the DB Length
++        LastError = GetAgBlockInfo(S7.Block_DB, DBNumber, Block);
++        if (LastError==0)
++        {
++            int SizeToRead = Block.MC7Size();
++            // Checks the room
++            if (SizeToRead<=Buffer.length)
++            {
++                LastError=ReadArea(S7.S7AreaDB, DBNumber, 0, SizeToRead, S7WLByte, Buffer);
++                if (LastError==0)
++                    SizeRead.Value=SizeToRead;
++            }
++            else
++                LastError=errS7BufferTooSmall;
++        }
++        return LastError;
++    }
++
++    public int ReadSZL(int ID, int Index, S7Szl SZL)
++    {
++        int Length;
++        int DataSZL;
++        int Offset = 0;
++        boolean Done = false;
++        boolean First = true;
++        byte Seq_in =0x00;
++        int Seq_out =0x0000;
++
++        LastError=0;
++        SZL.DataSize=0;
++        do
++        {
++            if (First)
++            {
++                S7.SetWordAt(S7_SZL_FIRST, 11, ++Seq_out);
++                S7.SetWordAt(S7_SZL_FIRST, 29, ID);
++                S7.SetWordAt(S7_SZL_FIRST, 31, Index);
++                SendPacket(S7_SZL_FIRST);
++            }
++            else
++            {
++                S7.SetWordAt(S7_SZL_NEXT, 11, ++Seq_out);
++                PDU[24] = (byte)Seq_in;
++                SendPacket(S7_SZL_NEXT);
++            }
++            if (LastError!=0)
++                return LastError;
++
++            Length=RecvIsoPacket();
++            if (LastError==0)
++            {
++                if (First)
++                {
++                    if (Length > 32) // the minimum expected
++                    {
++                        if ((S7.GetWordAt(PDU,27)==0) && (PDU[29]==(byte)0xFF))
++                        {
++                            // Gets Amount of this slice
++                            DataSZL=S7.GetWordAt(PDU,31)-8; // Skips extra params (ID, Index ...)
++                            Done=PDU[26]==0x00;
++                            Seq_in=(byte)PDU[24]; // Slice sequence
++
++                            SZL.LENTHDR=S7.GetWordAt(PDU, 37);
++                            SZL.N_DR=S7.GetWordAt(PDU, 39);
++                            SZL.Copy(PDU, 41, Offset, DataSZL);
++                            Offset+=DataSZL;
++                            SZL.DataSize+=DataSZL;
++                        }
++                        else
++                            LastError = errS7FunctionError;
++                    }
++                    else
++                        LastError = errS7InvalidPDU;
++                }
++                else
++                {
++                    if (Length > 32) // the minimum expected
++                    {
++                        if ((S7.GetWordAt(PDU,27)==0) && (PDU[29]==(byte)0xFF))
++                        {
++                            // Gets Amount of this slice
++                            DataSZL=S7.GetWordAt(PDU,31);
++                            Done=PDU[26]==0x00;
++                            Seq_in=(byte)PDU[24]; // Slice sequence
++                            SZL.Copy(PDU, 37, Offset, DataSZL);
++                            Offset+=DataSZL;
++                            SZL.DataSize+=DataSZL;
++                        }
++                        else
++                            LastError = errS7FunctionError;
++                    }
++                    else
++                        LastError = errS7InvalidPDU;
++                }
++            }
++            First=false;
++        }
++        while(!Done && (LastError==0));
++
++        return LastError;
++    }
++
++    public int GetCpuInfo(S7CpuInfo Info)
++    {
++        S7Szl SZL = new S7Szl(1024);
++
++        LastError = ReadSZL(0x001C, 0x0000, SZL);
++        if (LastError==0)
++        {
++            Info.Update(SZL.Data, 0);
++        }
++        return LastError;
++    }
++
++    public int GetCpInfo(S7CpInfo Info)
++    {
++        S7Szl SZL = new S7Szl(1024);
++
++        LastError = ReadSZL(0x0131, 0x0001, SZL);
++        if (LastError==0)
++        {
++            Info.Update(SZL.Data, 0);
++        }
++        return LastError;
++    }
++
++    public int GetOrderCode(S7OrderCode Code)
++    {
++        S7Szl SZL = new S7Szl(1024);
++
++        LastError = ReadSZL(0x0011, 0x0000, SZL);
++        if (LastError==0)
++        {
++            Code.Update(SZL.Data, 0, SZL.DataSize);
++        }
++        return LastError;
++    }
++
++    public int GetPlcDateTime(Date DateTime)
++    {
++        int Length;
++
++        LastError = 0;
++        SendPacket(S7_GET_DT);
++        if (LastError==0)
++        {
++            Length=RecvIsoPacket();
++            if (Length > 30) // the minimum expected
++            {
++                if ((S7.GetWordAt(PDU,27)==0) && (PDU[29]==(byte)0xFF))
++                {
++                    DateTime=S7.GetDateAt(PDU, 34);
++                }
++                else
++                    LastError = errS7FunctionError;
++            }
++            else
++                LastError = errS7InvalidPDU;
++        }
++
++        return LastError;
++    }
++
++    public int SetPlcDateTime(Date DateTime)
++    {
++        int Length;
++
++        LastError = 0;
++        S7.SetDateAt(S7_SET_DT, 31, DateTime);
++
++        SendPacket(S7_SET_DT);
++        if (LastError==0)
++        {
++            Length=RecvIsoPacket();
++            if (Length > 30) // the minimum expected
++            {
++                if (S7.GetWordAt(PDU,27)!=0)
++                    LastError = errS7FunctionError;
++            }
++            else
++                LastError = errS7InvalidPDU;
++        }
++
++        return LastError;
++    }
++
++    public int SetPlcSystemDateTime()
++    {
++        return SetPlcDateTime(new Date());
++    }
++
++    public int PlcStop()
++    {
++        int Length;
++
++        LastError = 0;
++        SendPacket(S7_STOP);
++        if (LastError==0)
++        {
++            Length=RecvIsoPacket();
++            if (Length > 18) // 18 is the minimum expected
++            {
++                if (S7.GetWordAt(PDU,17)!=0)
++                    LastError = errS7FunctionError;
++            }
++            else
++                LastError = errS7InvalidPDU;
++        }
++        return LastError;
++    }
++
++    public int PlcHotStart()
++    {
++        int Length;
++
++        LastError = 0;
++        SendPacket(S7_HOT_START);
++        if (LastError==0)
++        {
++            Length=RecvIsoPacket();
++            if (Length > 18) // the minimum expected
++            {
++                if (S7.GetWordAt(PDU,17)!=0)
++                    LastError = errS7FunctionError;
++            }
++            else
++                LastError = errS7InvalidPDU;
++        }
++        return LastError;
++    }
++
++    public int PlcColdStart()
++    {
++        int Length;
++
++        LastError = 0;
++        SendPacket(S7_COLD_START);
++        if (LastError==0)
++        {
++            Length=RecvIsoPacket();
++            if (Length > 18) // the minimum expected
++            {
++                if (S7.GetWordAt(PDU,17)!=0)
++                    LastError = errS7FunctionError;
++            }
++            else
++                LastError = errS7InvalidPDU;
++        }
++        return LastError;
++    }
++
++    public int GetPlcStatus(IntByRef Status)
++    {
++        int Length;
++
++        LastError = 0;
++        SendPacket(S7_GET_STAT);
++        if (LastError==0)
++        {
++            Length=RecvIsoPacket();
++            if (Length > 30) // the minimum expected
++            {
++                if (S7.GetWordAt(PDU,27)==0)
++                {
++                    switch (PDU[44])
++                    {
++                        case S7.S7CpuStatusUnknown :
++                        case S7.S7CpuStatusRun     :
++                        case S7.S7CpuStatusStop    : Status.Value=PDU[44];
++                        break;
++                        default :
++                        // Since RUN status is always 0x08 for all CPUs and CPs, STOP status
++                        // sometime can be coded as 0x03 (especially for old cpu...)
++                            Status.Value=S7.S7CpuStatusStop;
++                    }
++                }
++                else
++                    LastError = errS7FunctionError;
++            }
++            else
++                LastError = errS7InvalidPDU;
++        }
++        return LastError;
++    }
++
++    public int SetSessionPassword(String Password)
++    {
++        byte[] pwd = {0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20};
++        int Length;
++
++        LastError = 0;
++        // Adjusts the Password length to 8
++        if (Password.length()>8)
++            Password=Password.substring(0, 8);
++        else
++        {
++            while (Password.length()<8)
++                Password=Password+" ";
++        }
++
++        try {
++            pwd = Password.getBytes("UTF-8");
++        } catch (UnsupportedEncodingException ex) {
++            LastError = errS7InvalidParams;
++        }
++        if (LastError==0)
++        {
++            // Encodes the password
++            pwd[0]=(byte) (pwd[0] ^ 0x55);
++            pwd[1]=(byte) (pwd[1] ^ 0x55);
++            for (int c = 2; c < 8; c++)
++            {
++                pwd[c]=(byte) (pwd[c] ^ 0x55 ^ pwd[c-2]);
++            }
++            System.arraycopy(pwd, 0, S7_SET_PWD, 29, 8);
++            // Sends the telegrem
++            SendPacket(S7_SET_PWD);
++            if (LastError==0)
++            {
++                Length=RecvIsoPacket();
++                if (Length > 32) // the minimum expected
++                {
++                    if (S7.GetWordAt(PDU,27)!=0)
++                        LastError = errS7FunctionError;
++                }
++                else
++                    LastError = errS7InvalidPDU;
++            }
++        }
++        return LastError;
++    }
++
++    public int ClearSessionPassword()
++    {
++        int Length;
++
++        LastError = 0;
++        SendPacket(S7_CLR_PWD);
++        if (LastError==0)
++        {
++            Length=RecvIsoPacket();
++            if (Length > 30) // the minimum expected
++            {
++                if (S7.GetWordAt(PDU,27)!=0)
++                    LastError = errS7FunctionError;
++            }
++            else
++                LastError = errS7InvalidPDU;
++        }
++        return LastError;
++    }
++
++    public int GetProtection(S7Protection Protection)
++    {
++        S7Szl SZL = new S7Szl(256);
++
++        LastError = ReadSZL(0x0232, 0x0004, SZL);
++        if (LastError==0)
++        {
++            Protection.Update(SZL.Data);
++        }
++        return LastError;
++    }
++
++}
+diff U3 S7CpInfo.java S7CpInfo.java
+--- S7CpInfo.java      Thu Mar 23 15:34:52 2017
++++ S7CpInfo.java      Tue Aug 08 18:53:37 2017
+@@ -1,41 +1,41 @@
+-/*=============================================================================|
+-|  PROJECT Moka7                                                         1.0.2 |
+-|==============================================================================|
+-|  Copyright (C) 2013, 2016 Davide Nardella                                    |
+-|  All rights reserved.                                                        |
+-|==============================================================================|
+-|  SNAP7 is free software: you can redistribute it and/or modify               |
+-|  it under the terms of the Lesser GNU General Public License as published by |
+-|  the Free Software Foundation, either version 3 of the License, or under     |
+-|  EPL Eclipse Public License 1.0.                                             |
+-|                                                                              |
+-|  This means that you have to chose in advance which take before you import   |
+-|  the library into your project.                                              |
+-|                                                                              |
+-|  SNAP7 is distributed in the hope that it will be useful,                    |
+-|  but WITHOUT ANY WARRANTY; without even the implied warranty of              |
+-|  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you    |
+-|  decide to adopt.                                                            |
+-|                                                                              |
+-|=============================================================================*/
+-package Moka7;
+-
+-/**
+- *
+- * @author Davide
+- */
+-public class S7CpInfo {
+-
+-    public int MaxPduLength;
+-    public int MaxConnections;
+-    public int MaxMpiRate;
+-    public int MaxBusRate;
+-
+-    protected void Update(byte[] Src, int Pos)
+-    {
+-        MaxPduLength = S7.GetShortAt(Src, 2);
+-        MaxConnections = S7.GetShortAt(Src, 4);
+-        MaxMpiRate = S7.GetDIntAt(Src, 6);
+-        MaxBusRate = S7.GetDIntAt(Src, 10);                      
+-    }         
+-}
++/*=============================================================================|
++|  PROJECT Moka7                                                         1.0.2 |
++|==============================================================================|
++|  Copyright (C) 2013, 2016 Davide Nardella                                    |
++|  All rights reserved.                                                        |
++|==============================================================================|
++|  SNAP7 is free software: you can redistribute it and/or modify               |
++|  it under the terms of the Lesser GNU General Public License as published by |
++|  the Free Software Foundation, either version 3 of the License, or under     |
++|  EPL Eclipse Public License 1.0.                                             |
++|                                                                              |
++|  This means that you have to chose in advance which take before you import   |
++|  the library into your project.                                              |
++|                                                                              |
++|  SNAP7 is distributed in the hope that it will be useful,                    |
++|  but WITHOUT ANY WARRANTY; without even the implied warranty of              |
++|  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you    |
++|  decide to adopt.                                                            |
++|                                                                              |
++|=============================================================================*/
++package Moka7;
++
++/**
++ *
++ * @author Davide Nardella
++ */
++public class S7CpInfo {
++
++    public int MaxPduLength;
++    public int MaxConnections;
++    public int MaxMpiRate;
++    public int MaxBusRate;
++
++    protected void Update(byte[] Src, int Pos)
++    {
++        MaxPduLength = S7.GetShortAt(Src, 2);
++        MaxConnections = S7.GetShortAt(Src, 4);
++        MaxMpiRate = S7.GetDIntAt(Src, 6);
++        MaxBusRate = S7.GetDIntAt(Src, 10);
++    }
++}
+diff U3 S7CpuInfo.java S7CpuInfo.java
+--- S7CpuInfo.java     Thu Mar 23 15:34:52 2017
++++ S7CpuInfo.java     Tue Aug 08 18:53:37 2017
+@@ -1,57 +1,57 @@
+-/*=============================================================================|
+-|  PROJECT Moka7                                                         1.0.2 |
+-|==============================================================================|
+-|  Copyright (C) 2013, 2016 Davide Nardella                                    |
+-|  All rights reserved.                                                        |
+-|==============================================================================|
+-|  SNAP7 is free software: you can redistribute it and/or modify               |
+-|  it under the terms of the Lesser GNU General Public License as published by |
+-|  the Free Software Foundation, either version 3 of the License, or under     |
+-|  EPL Eclipse Public License 1.0.                                             |
+-|                                                                              |
+-|  This means that you have to chose in advance which take before you import   |
+-|  the library into your project.                                              |
+-|                                                                              |
+-|  SNAP7 is distributed in the hope that it will be useful,                    |
+-|  but WITHOUT ANY WARRANTY; without even the implied warranty of              |
+-|  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you    |
+-|  decide to adopt.                                                            |
+-|                                                                              |
+-|=============================================================================*/
+-package Moka7;
+-
+-/**
+- *
+- * @author Davide
+- */
+-public class S7CpuInfo {
+-    
+-    private final int BufSize = 256;
+-    protected byte[] Buffer = new byte[BufSize];       
+-
+-    protected void Update(byte[] Src, int Pos)
+-    {
+-        System.arraycopy(Src, Pos, Buffer, 0, BufSize);
+-    }   
+-    
+-    public String ModuleTypeName()
+-    {
+-        return S7.GetStringAt(Buffer,172,32);
+-    }
+-    public String SerialNumber()
+-    {
+-        return S7.GetStringAt(Buffer,138,24);
+-    }
+-    public String ASName()
+-    {
+-        return S7.GetStringAt(Buffer,2,24);
+-    }
+-    public String Copyright()
+-    {
+-        return S7.GetStringAt(Buffer,104,26);
+-    }
+-    public String ModuleName()
+-    {
+-        return S7.GetStringAt(Buffer,36,24);
+-    }
+-}
++/*=============================================================================|
++|  PROJECT Moka7                                                         1.0.2 |
++|==============================================================================|
++|  Copyright (C) 2013, 2016 Davide Nardella                                    |
++|  All rights reserved.                                                        |
++|==============================================================================|
++|  SNAP7 is free software: you can redistribute it and/or modify               |
++|  it under the terms of the Lesser GNU General Public License as published by |
++|  the Free Software Foundation, either version 3 of the License, or under     |
++|  EPL Eclipse Public License 1.0.                                             |
++|                                                                              |
++|  This means that you have to chose in advance which take before you import   |
++|  the library into your project.                                              |
++|                                                                              |
++|  SNAP7 is distributed in the hope that it will be useful,                    |
++|  but WITHOUT ANY WARRANTY; without even the implied warranty of              |
++|  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you    |
++|  decide to adopt.                                                            |
++|                                                                              |
++|=============================================================================*/
++package Moka7;
++
++/**
++ *
++ * @author Davide Nardella
++ */
++public class S7CpuInfo {
++
++    private final int BufSize = 256;
++    protected byte[] Buffer = new byte[BufSize];
++
++    protected void Update(byte[] Src, int Pos)
++    {
++        System.arraycopy(Src, Pos, Buffer, 0, BufSize);
++    }
++
++    public String ModuleTypeName()
++    {
++        return S7.GetStringAt(Buffer,172,32);
++    }
++    public String SerialNumber()
++    {
++        return S7.GetStringAt(Buffer,138,24);
++    }
++    public String ASName()
++    {
++        return S7.GetStringAt(Buffer,2,24);
++    }
++    public String Copyright()
++    {
++        return S7.GetStringAt(Buffer,104,26);
++    }
++    public String ModuleName()
++    {
++        return S7.GetStringAt(Buffer,36,24);
++    }
++}
+diff U3 S7OrderCode.java S7OrderCode.java
+--- S7OrderCode.java   Thu Mar 23 15:34:52 2017
++++ S7OrderCode.java   Tue Aug 08 18:53:37 2017
+@@ -1,46 +1,46 @@
+-/*=============================================================================|
+-|  PROJECT Moka7                                                         1.0.2 |
+-|==============================================================================|
+-|  Copyright (C) 2013, 2016 Davide Nardella                                    |
+-|  All rights reserved.                                                        |
+-|==============================================================================|
+-|  SNAP7 is free software: you can redistribute it and/or modify               |
+-|  it under the terms of the Lesser GNU General Public License as published by |
+-|  the Free Software Foundation, either version 3 of the License, or under     |
+-|  EPL Eclipse Public License 1.0.                                             |
+-|                                                                              |
+-|  This means that you have to chose in advance which take before you import   |
+-|  the library into your project.                                              |
+-|                                                                              |
+-|  SNAP7 is distributed in the hope that it will be useful,                    |
+-|  but WITHOUT ANY WARRANTY; without even the implied warranty of              |
+-|  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you    |
+-|  decide to adopt.                                                            |
+-|                                                                              |
+-|=============================================================================*/
+-package Moka7;
+-
+-/**
+- *
+- * @author Davide
+- */
+-public class S7OrderCode {
+-  
+-    public int V1;
+-    public int V2;
+-    public int V3;
+-    protected byte[] Buffer = new byte[1024];       
+-
+-    protected void Update(byte[] Src, int Pos, int Size)
+-    {
+-        System.arraycopy(Src, Pos, Buffer, 0, Size);
+-        V1 = (byte) Src[Size-3];
+-        V2 = (byte) Src[Size-2];
+-        V3 = (byte) Src[Size-1];
+-    }   
+-
+-    public String Code()
+-    {
+-        return S7.GetStringAt(Buffer, 2, 20);
+-    }
+-}
++/*=============================================================================|
++|  PROJECT Moka7                                                         1.0.2 |
++|==============================================================================|
++|  Copyright (C) 2013, 2016 Davide Nardella                                    |
++|  All rights reserved.                                                        |
++|==============================================================================|
++|  SNAP7 is free software: you can redistribute it and/or modify               |
++|  it under the terms of the Lesser GNU General Public License as published by |
++|  the Free Software Foundation, either version 3 of the License, or under     |
++|  EPL Eclipse Public License 1.0.                                             |
++|                                                                              |
++|  This means that you have to chose in advance which take before you import   |
++|  the library into your project.                                              |
++|                                                                              |
++|  SNAP7 is distributed in the hope that it will be useful,                    |
++|  but WITHOUT ANY WARRANTY; without even the implied warranty of              |
++|  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you    |
++|  decide to adopt.                                                            |
++|                                                                              |
++|=============================================================================*/
++package Moka7;
++
++/**
++ *
++ * @author Davide Nardella
++ */
++public class S7OrderCode {
++
++    public int V1;
++    public int V2;
++    public int V3;
++    protected byte[] Buffer = new byte[1024];
++
++    protected void Update(byte[] Src, int Pos, int Size)
++    {
++        System.arraycopy(Src, Pos, Buffer, 0, Size);
++        V1 = (byte) Src[Size-3];
++        V2 = (byte) Src[Size-2];
++        V3 = (byte) Src[Size-1];
++    }
++
++    public String Code()
++    {
++        return S7.GetStringAt(Buffer, 2, 20);
++    }
++}
+diff U3 S7Protection.java S7Protection.java
+--- S7Protection.java  Thu Mar 23 15:34:52 2017
++++ S7Protection.java  Tue Aug 08 18:53:37 2017
+@@ -1,38 +1,43 @@
+-/*=============================================================================|
+-|  PROJECT Moka7                                                         1.0.2 |
+-|==============================================================================|
+-|  Copyright (C) 2013, 2016 Davide Nardella                                    |
+-|  All rights reserved.                                                        |
+-|==============================================================================|
+-|  SNAP7 is free software: you can redistribute it and/or modify               |
+-|  it under the terms of the Lesser GNU General Public License as published by |
+-|  the Free Software Foundation, either version 3 of the License, or under     |
+-|  EPL Eclipse Public License 1.0.                                             |
+-|                                                                              |
+-|  This means that you have to chose in advance which take before you import   |
+-|  the library into your project.                                              |
+-|                                                                              |
+-|  SNAP7 is distributed in the hope that it will be useful,                    |
+-|  but WITHOUT ANY WARRANTY; without even the implied warranty of              |
+-|  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you    |
+-|  decide to adopt.                                                            |
+-|                                                                              |
+-|=============================================================================*/
+-package Moka7;
+-
+-// See §33.19 of "System Software for S7-300/400 System and Standard Functions"
+-public class S7Protection {
+-   public int sch_schal;
+-   public int sch_par;
+-   public int sch_rel;
+-   public int bart_sch;
+-   public int anl_sch;
+-   protected void Update(byte[] Src)
+-   {
+-       sch_schal = S7.GetWordAt(Src,2);
+-       sch_par   = S7.GetWordAt(Src,4);
+-       sch_rel   = S7.GetWordAt(Src,6);
+-       bart_sch  = S7.GetWordAt(Src,8);
+-       anl_sch   = S7.GetWordAt(Src,10);
+-   }
+-}
++/*=============================================================================|
++|  PROJECT Moka7                                                         1.0.2 |
++|==============================================================================|
++|  Copyright (C) 2013, 2016 Davide Nardella                                    |
++|  All rights reserved.                                                        |
++|==============================================================================|
++|  SNAP7 is free software: you can redistribute it and/or modify               |
++|  it under the terms of the Lesser GNU General Public License as published by |
++|  the Free Software Foundation, either version 3 of the License, or under     |
++|  EPL Eclipse Public License 1.0.                                             |
++|                                                                              |
++|  This means that you have to chose in advance which take before you import   |
++|  the library into your project.                                              |
++|                                                                              |
++|  SNAP7 is distributed in the hope that it will be useful,                    |
++|  but WITHOUT ANY WARRANTY; without even the implied warranty of              |
++|  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you    |
++|  decide to adopt.                                                            |
++|                                                                              |
++|=============================================================================*/
++package Moka7;
++
++/**
++ *
++ * @author Davide Nardella
++ */
++
++// See §33.19 of "System Software for S7-300/400 System and Standard Functions"
++public class S7Protection {
++   public int sch_schal;
++   public int sch_par;
++   public int sch_rel;
++   public int bart_sch;
++   public int anl_sch;
++   protected void Update(byte[] Src)
++   {
++       sch_schal = S7.GetWordAt(Src,2);
++       sch_par   = S7.GetWordAt(Src,4);
++       sch_rel   = S7.GetWordAt(Src,6);
++       bart_sch  = S7.GetWordAt(Src,8);
++       anl_sch   = S7.GetWordAt(Src,10);
++   }
++}
+diff U3 S7Szl.java S7Szl.java
+--- S7Szl.java Thu Mar 23 15:34:52 2017
++++ S7Szl.java Tue Aug 08 18:53:37 2017
+@@ -1,42 +1,42 @@
+-/*=============================================================================|
+-|  PROJECT Moka7                                                         1.0.2 |
+-|==============================================================================|
+-|  Copyright (C) 2013, 2016 Davide Nardella                                    |
+-|  All rights reserved.                                                        |
+-|==============================================================================|
+-|  SNAP7 is free software: you can redistribute it and/or modify               |
+-|  it under the terms of the Lesser GNU General Public License as published by |
+-|  the Free Software Foundation, either version 3 of the License, or under     |
+-|  EPL Eclipse Public License 1.0.                                             |
+-|                                                                              |
+-|  This means that you have to chose in advance which take before you import   |
+-|  the library into your project.                                              |
+-|                                                                              |
+-|  SNAP7 is distributed in the hope that it will be useful,                    |
+-|  but WITHOUT ANY WARRANTY; without even the implied warranty of              |
+-|  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you    |
+-|  decide to adopt.                                                            |
+-|                                                                              |
+-|=============================================================================*/
+-package Moka7;
+-
+-/**
+- *
+- * @author Davide
+- */
+-public class S7Szl {
+-    
+-    public int LENTHDR;
+-    public int N_DR;
+-    public int DataSize;
+-    public byte Data[];
+-    
+-    public S7Szl(int BufferSize)
+-    {
+-        Data = new byte[BufferSize];
+-    }
+-    protected void Copy(byte[] Src, int SrcPos, int DestPos, int Size)
+-    {
+-        System.arraycopy(Src, SrcPos, Data, DestPos, Size);
+-    }   
+-}
++/*=============================================================================|
++|  PROJECT Moka7                                                         1.0.2 |
++|==============================================================================|
++|  Copyright (C) 2013, 2016 Davide Nardella                                    |
++|  All rights reserved.                                                        |
++|==============================================================================|
++|  SNAP7 is free software: you can redistribute it and/or modify               |
++|  it under the terms of the Lesser GNU General Public License as published by |
++|  the Free Software Foundation, either version 3 of the License, or under     |
++|  EPL Eclipse Public License 1.0.                                             |
++|                                                                              |
++|  This means that you have to chose in advance which take before you import   |
++|  the library into your project.                                              |
++|                                                                              |
++|  SNAP7 is distributed in the hope that it will be useful,                    |
++|  but WITHOUT ANY WARRANTY; without even the implied warranty of              |
++|  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you    |
++|  decide to adopt.                                                            |
++|                                                                              |
++|=============================================================================*/
++package Moka7;
++
++/**
++ *
++ * @author Davide Nardella
++ */
++public class S7Szl {
++
++    public int LENTHDR;
++    public int N_DR;
++    public int DataSize;
++    public byte Data[];
++
++    public S7Szl(int BufferSize)
++    {
++        Data = new byte[BufferSize];
++    }
++    protected void Copy(byte[] Src, int SrcPos, int DestPos, int Size)
++    {
++        System.arraycopy(Src, SrcPos, Data, DestPos, Size);
++    }
++}
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 (file)
index 3c8ecc0..0000000
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 (file)
index 8b1a218..0000000
+++ /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 ((SizeAvail<Size) && (!Expired) && (LastError==0))
--            {
--                
--                cnt++;
--                try {
--                    Thread.sleep(1);
--                } 
--                catch (InterruptedException ex) {
--                    LastError=errTCPDataRecvTout;
--                }
--                SizeAvail=InStream.available();              
--                Expired=cnt>Timeout;
--                // If timeout we clean the buffer
--                if (Expired && (SizeAvail>0) && (LastError==0))
--                  InStream.read(PDU, 0, SizeAvail);
--            }
--        } 
--        catch (IOException ex) 
--        {
--            LastError=errTCPDataRecvTout;
--        }
--        if (cnt>=Timeout)
--        {
--            LastError=errTCPDataRecvTout;
--        }        
--        return LastError;
--    }
--    
--    private int RecvPacket(byte[] Buffer, int Start, int Size)
--    {
--      int BytesRead=0;
--        LastError=WaitForData(Size,RecvTimeout);
--      if (LastError==0)
--        {
--            try {
--                BytesRead = InStream.read(Buffer, Start, Size);
--            } catch (IOException ex) {
--                LastError=errTCPDataRecv;
--            }
--            if (BytesRead==0)
--                LastError=errTCPConnectionReset;        
--        }
--        return LastError;
--    }
--
--    private void SendPacket(byte[] Buffer, int Len)
--    {
--        LastError = 0;
--        try {
--            OutStream.write(Buffer,0,Len);
--            OutStream.flush();
--        } catch (IOException ex) {
--            LastError = errTCPDataSend; 
--        }
--    }   
--    private void SendPacket(byte[] Buffer)
--    {
--        SendPacket(Buffer,Buffer.length);
--    }   
--    
--    private int RecvIsoPacket()
--    {
--        Boolean Done = false;
--        int Size = 0;
--      while ((LastError==0) && !Done)
--      {
--            // Get TPKT (4 bytes)
--            RecvPacket(PDU, 0, 4); 
--            if (LastError==0)
--            {
--                Size=S7.GetWordAt(PDU,2);
--                // Check 0 bytes Data Packet (only TPKT+COTP = 7 bytes)
--                if (Size==IsoHSize)
--                    RecvPacket(PDU,4, 3); // Skip remaining 3 bytes and Done is still false
--                else
--                {
--                    if ((Size>MaxPduSize) || (Size<MinPduSize))
--                        LastError=errISOInvalidPDU;
--                    else
--                        Done = true; // a valid Length !=7 && >16 && <247
--                }
--            }               
--        }
--        if (LastError==0)
--        {
--            RecvPacket(PDU,4, 3); // Skip remaining 3 COTP bytes
--            LastPDUType=PDU[5];   // Stores PDU Type, we need it 
--            // Receives the S7 Payload          
--            RecvPacket(PDU, 7, Size-IsoHSize);          
--        }
--        if (LastError==0)
--            return Size;
--        else
--            return 0;
--    }
--    
--    private int ISOConnect() 
--    {
--      int Size;
--        ISO_CR[16]=LocalTSAP_HI;
--        ISO_CR[17]=LocalTSAP_LO;
--        ISO_CR[20]=RemoteTSAP_HI;
--        ISO_CR[21]=RemoteTSAP_LO;
--        
--        // Sends the connection request telegram      
--        SendPacket(ISO_CR);
--        if (LastError==0)
--        {            
--            // Gets the reply (if any)
--            Size=RecvIsoPacket();
--            if (LastError==0) 
--            {
--                if (Size==22) 
--                {
--                    if (LastPDUType!=(byte)0xD0) // 0xD0 = CC Connection confirm
--                        LastError=errISOConnectionFailed;
--                }
--                else
--                    LastError=errISOInvalidPDU;
--            }
--        }        
--        return LastError;
--    }        
--    
--    private int NegotiatePduLength()
--    {
--        int Length;
--        // Set PDU Size Requested
--        S7.SetWordAt(S7_PN,23,DefaultPduSizeRequested);            
--        // Sends the connection request telegram
--        SendPacket(S7_PN);
--        if (LastError==0)    
--        {
--            Length=RecvIsoPacket();
--            if (LastError==0)                 
--            {
--                // check S7 Error
--                if ((Length==27) && (PDU[17]==0) && (PDU[18]==0))  // 20 = size of Negotiate Answer
--                {
--                    // Get PDU Size Negotiated
--                    _PDULength = S7.GetWordAt(PDU,25);
--                    if (_PDULength>0)
--                        return 0;
--                    else
--                        LastError=errISONegotiatingPDU;
--                }
--                else 
--                    LastError=errISONegotiatingPDU;
--            }
--        }
--        return LastError;
--    }
--      
--    public void SetConnectionType(short ConnectionType)
--    {
--        ConnType=ConnectionType;
--    }
--      
--    public int Connect() 
--    {
--        LastError=0;
--        if (!Connected)
--        {
--            TCPConnect();
--            if (LastError==0) // First stage : TCP Connection
--            {
--                ISOConnect();
--                if (LastError==0) // Second stage : ISOTCP (ISO 8073) Connection
--                {
--                    LastError=NegotiatePduLength(); // Third stage : S7 PDU negotiation
--                }
--            }             
--        }
--        Connected=LastError==0;
--        
--        // In case the connection is not completely established (TCP connection + ISO connection + PDU negotiation)
--        // we close the socket and its IO streams to revert the object back to pre-Connect() state
--        if (!Connected)
--        {
--            if (TCPSocket != null) {
--                try {
--                    TCPSocket.close();
--                } catch (IOException ex) {
--                }
--            }
--            if (InStream != null) {
--                try {
--                    InStream.close();
--                } catch (IOException ex) {
--                }
--            }
--            if (OutStream != null) {
--                try {
--                    OutStream.close();
--                } catch (IOException ex) {
--                }
--            }
--            _PDULength = 0;
--        }                
--        
--      return LastError;
--    }
--    
--    public void Disconnect()
--    {
--        if (Connected)
--        {
--            try {
--                OutStream.close();
--                InStream.close();
--                TCPSocket.close();
--                _PDULength=0;
--            } catch (IOException ex) {            
--            }
--            Connected=false;
--        }
--    }
--    
--    public int ConnectTo(String Address, int Rack, int Slot) 
--    {       
--        int RemoteTSAP=(ConnType<<8)+ (Rack * 0x20) + Slot;
--        SetConnectionParams(Address, 0x0100, RemoteTSAP);
--        return Connect();
--    }
--    
--    public int PDULength()
--    {
--        return _PDULength;
--    }
--    
--    public void SetConnectionParams(String Address, int LocalTSAP, int RemoteTSAP)
--    {
--        int LocTSAP = LocalTSAP & 0x0000FFFF;
--        int RemTSAP = RemoteTSAP & 0x0000FFFF;        
--        IPAddress    =  Address;
--        LocalTSAP_HI = (byte) (LocTSAP>>8);
--        LocalTSAP_LO = (byte) (LocTSAP & 0x00FF);
--        RemoteTSAP_HI= (byte) (RemTSAP>>8);
--        RemoteTSAP_LO= (byte) (RemTSAP & 0x00FF);      
--    }
-- 
--    public int ReadArea(int Area, int DBNumber, int Start, int Amount, byte[] Data)
--    {
--      int Address;
--      int NumElements;
--      int MaxElements;
--      int TotElements;
--      int SizeRequested;
--      int Length;
--      int Offset = 0;
--      int WordSize = 1;
--           
--      LastError=0;
--              
--      // If we are addressing Timers or counters the element size is 2
--      if ((Area==S7.S7AreaCT) || (Area==S7.S7AreaTM))
--            WordSize = 2;
--      
--        MaxElements=(_PDULength-18) / WordSize; // 18 = Reply telegram header
--            TotElements=Amount;
--      
--        while ((TotElements>0) && (LastError==0))
--        {
--            NumElements=TotElements;
--            if (NumElements>MaxElements)
--               NumElements=MaxElements;
--
--            SizeRequested = NumElements * WordSize;
--
--            // Setup the telegram
--            System.arraycopy(S7_RW, 0, PDU, 0, Size_RD);
--            // Set DB Number
--            PDU[27] = (byte) Area;
--            // Set Area
--            if (Area==S7.S7AreaDB) 
--                S7.SetWordAt(PDU,25,DBNumber);
--
--            // Adjusts Start and word length
--            if ((Area==S7.S7AreaCT) || (Area==S7.S7AreaTM))
--            {
--                Address = Start;
--                if (Area==S7.S7AreaCT)
--                    PDU[22]=S7WLCounter;
--                else
--                    PDU[22]=S7WLTimer;
--            }
--            else
--                Address = Start<<3;
--
--            // Num elements
--            S7.SetWordAt(PDU,23,NumElements);
--
--            // Address into the PLC (only 3 bytes)           
--            PDU[30] = (byte) (Address & 0x0FF);
--            Address = Address >> 8;
--            PDU[29] = (byte) (Address & 0x0FF);
--            Address = Address >> 8;
--            PDU[28] = (byte) (Address & 0x0FF);         
--            
--            SendPacket(PDU, Size_RD);
--            if (LastError==0)
--            {
--                Length=RecvIsoPacket();
--                if (LastError==0)
--                {
--                    if (Length>=25)
--                    {
--                        if ((Length-25==SizeRequested) && (PDU[21]==(byte)0xFF))
--                        {
--                            System.arraycopy(PDU, 25, Data, Offset, SizeRequested);
--                            Offset+=SizeRequested;
--                        }
--                        else
--                            LastError = errS7DataRead;
--                    }
--                    else
--                        LastError = errS7InvalidPDU;
--                }
--            }
--
--            TotElements -= NumElements;
--            Start += NumElements*WordSize;
--        }
--        return LastError;
--    }
--
--    public int WriteArea(int Area, int DBNumber, int Start, int Amount, byte[] Data)
--    {
--      int Address;
--      int NumElements;
--      int MaxElements;
--      int TotElements;
--      int DataSize;
--      int IsoSize;
--      int Length;
--      int Offset = 0;
--      int WordSize = 1;
--     
--      LastError=0;
--      
--      // If we are addressing Timers or counters the element size is 2
--      if ((Area==S7.S7AreaCT) || (Area==S7.S7AreaTM))
--            WordSize = 2;
--
--        MaxElements=(_PDULength-35) / WordSize; // 18 = Reply telegram header
--      TotElements=Amount;
--      
--        while ((TotElements>0) && (LastError==0))
--        {
--            NumElements=TotElements;
--            if (NumElements>MaxElements)
--               NumElements=MaxElements;
--
--            DataSize = NumElements * WordSize;
--            IsoSize  = Size_WR + DataSize;
--
--            // Setup the telegram
--            System.arraycopy(S7_RW, 0, PDU, 0, Size_WR);
--            // Whole telegram Size
--            S7.SetWordAt(PDU,2,IsoSize);
--            // Data Length
--            Length=DataSize+4;
--            S7.SetWordAt(PDU,15,Length);
--            // Function
--            PDU[17]= (byte) 0x05;
--            // Set DB Number
--            PDU[27] = (byte) Area;
--            if (Area==S7.S7AreaDB) 
--                S7.SetWordAt(PDU,25,DBNumber);
--
--            // Adjusts Start and word length
--            if ((Area==S7.S7AreaCT) || (Area==S7.S7AreaTM))
--            {
--                Address = Start;
--                Length = DataSize;
--                if (Area==S7.S7AreaCT)
--                    PDU[22]=S7WLCounter;
--                else
--                    PDU[22]=S7WLTimer;
--            }
--            else
--            {
--                Address = Start<<3;
--                Length  = DataSize<<3;
--            }
--            // Num elements
--            S7.SetWordAt(PDU,23,NumElements);
--            // Address into the PLC
--            PDU[30] = (byte) (Address & 0x0FF);
--            Address = Address >> 8;
--            PDU[29] = (byte) (Address & 0x0FF);
--            Address = Address >> 8;
--            PDU[28] = (byte) (Address & 0x0FF);
--            // Length
--            S7.SetWordAt(PDU,33,Length);
--            
--            // Copies the Data
--            System.arraycopy(Data, Offset, PDU, 35, DataSize);
--                        
--            SendPacket(PDU, IsoSize);
--            if (LastError==0)
--            {
--                Length=RecvIsoPacket();
--                if (LastError==0)
--                {
--                    if (Length==22)
--                    {
--                        if ((S7.GetWordAt(PDU,17)!=0) || (PDU[21]!=(byte)0xFF))
--                            LastError = errS7DataWrite;
--                    }
--                    else
--                        LastError = errS7InvalidPDU;
--                }
--            }
--
--            Offset+=DataSize;
--            TotElements -= NumElements;
--            Start += NumElements*WordSize;
--        }
--        return LastError;
--    }
--   
--    public int GetAgBlockInfo(int BlockType, int BlockNumber, S7BlockInfo Block)
--    {
--      int Length;
--        LastError=0;
--        // Block Type
--        S7_BI[30] = (byte) BlockType;
--        // Block Number
--        S7_BI[31]=(byte) ((BlockNumber / 10000)+0x30);
--        BlockNumber=BlockNumber % 10000;
--        S7_BI[32]=(byte) ((BlockNumber / 1000)+0x30);
--        BlockNumber=BlockNumber % 1000;
--        S7_BI[33]=(byte) ((BlockNumber / 100)+0x30);
--        BlockNumber=BlockNumber % 100;
--        S7_BI[34]=(byte) ((BlockNumber / 10)+0x30);
--        BlockNumber=BlockNumber % 10;
--        S7_BI[35]=(byte) ((BlockNumber / 1)+0x30);
--        
--        SendPacket(S7_BI);
--        if (LastError==0)
--        {
--            Length=RecvIsoPacket();
--            if (Length > 32) // the minimum expected
--            {
--                if ((S7.GetWordAt(PDU,27)==0) && (PDU[29]==(byte)0xFF))
--                {
--                    Block.Update(PDU, 42);
--                }
--                else
--                    LastError = errS7FunctionError;
--            }
--            else
--                LastError = errS7InvalidPDU;
--        }
--        
--        return LastError;
--    }      
--    /**
--     * 
--     * @param DBNumber DB Number
--     * @param Buffer   Destination buffer
--     * @param SizeRead How many bytes were read
--     * @return 
--     */
--    public int DBGet(int DBNumber, byte[] Buffer, IntByRef SizeRead)
--    {
--        S7BlockInfo Block = new S7BlockInfo();
--        // Query the DB Length
--        LastError = GetAgBlockInfo(S7.Block_DB, DBNumber, Block);
--        if (LastError==0)
--        {
--            int SizeToRead = Block.MC7Size();
--            // Checks the room
--            if (SizeToRead<=Buffer.length)
--            {
--                LastError=ReadArea(S7.S7AreaDB, DBNumber, 0, SizeToRead, Buffer);
--                if (LastError==0)
--                    SizeRead.Value=SizeToRead;
--            }
--            else
--                LastError=errS7BufferTooSmall;
--        }
--        return LastError;
--    }  
--    
--    public int ReadSZL(int ID, int Index, S7Szl SZL)
--    {
--      int Length;
--        int DataSZL;
--        int Offset = 0;
--        boolean Done = false;
--        boolean First = true;
--        byte Seq_in =0x00;
--        int Seq_out =0x0000;
--        
--        LastError=0;
--        SZL.DataSize=0;
--        do
--        {
--            if (First)
--            {
--                S7.SetWordAt(S7_SZL_FIRST, 11, ++Seq_out);
--                S7.SetWordAt(S7_SZL_FIRST, 29, ID);
--                S7.SetWordAt(S7_SZL_FIRST, 31, Index);
--                SendPacket(S7_SZL_FIRST);                
--            }
--            else
--            {
--                S7.SetWordAt(S7_SZL_NEXT, 11, ++Seq_out);
--                PDU[24] = (byte)Seq_in;
--                SendPacket(S7_SZL_NEXT);                
--            }
--            if (LastError!=0)
--                return LastError;
--            
--            Length=RecvIsoPacket();
--            if (LastError==0)
--            {
--                if (First)
--                {
--                    if (Length > 32) // the minimum expected
--                    {
--                        if ((S7.GetWordAt(PDU,27)==0) && (PDU[29]==(byte)0xFF))
--                        {
--                            // Gets Amount of this slice
--                            DataSZL=S7.GetWordAt(PDU,31)-8; // Skips extra params (ID, Index ...)
--                            Done=PDU[26]==0x00;
--                            Seq_in=(byte)PDU[24]; // Slice sequence
--                            
--                            SZL.LENTHDR=S7.GetWordAt(PDU, 37);
--                            SZL.N_DR=S7.GetWordAt(PDU, 39);
--                            SZL.Copy(PDU, 41, Offset, DataSZL);                       
--                            Offset+=DataSZL;
--                            SZL.DataSize+=DataSZL;
--                        }
--                        else
--                            LastError = errS7FunctionError;
--                    }
--                    else
--                        LastError = errS7InvalidPDU;
--                }
--                else
--                {
--                    if (Length > 32) // the minimum expected
--                    {
--                        if ((S7.GetWordAt(PDU,27)==0) && (PDU[29]==(byte)0xFF))
--                        {
--                            // Gets Amount of this slice
--                            DataSZL=S7.GetWordAt(PDU,31); 
--                            Done=PDU[26]==0x00;
--                            Seq_in=(byte)PDU[24]; // Slice sequence
--                            SZL.Copy(PDU, 37, Offset, DataSZL);                       
--                            Offset+=DataSZL;
--                            SZL.DataSize+=DataSZL;
--                        }
--                        else
--                            LastError = errS7FunctionError;
--                    }
--                    else
--                        LastError = errS7InvalidPDU;
--                }
--            }            
--            First=false;
--        }            
--        while(!Done && (LastError==0));
--        
--        return LastError;
--    }
--    
--    
--    public int GetCpuInfo(S7CpuInfo Info)
--    {
--        S7Szl SZL = new S7Szl(1024);
--        
--        LastError = ReadSZL(0x001C, 0x0000, SZL);
--        if (LastError==0)
--        {
--            Info.Update(SZL.Data, 0);
--        }
--        return LastError;
--    }
--
--    public int GetCpInfo(S7CpInfo Info)
--    {
--        S7Szl SZL = new S7Szl(1024);
--        
--        LastError = ReadSZL(0x0131, 0x0001, SZL);
--        if (LastError==0)
--        {
--            Info.Update(SZL.Data, 0);
--        }
--        return LastError;
--    }
--    
--    public int GetOrderCode(S7OrderCode Code)
--    {
--        S7Szl SZL = new S7Szl(1024);
--        
--        LastError = ReadSZL(0x0011, 0x0000, SZL);
--        if (LastError==0)
--        {
--            Code.Update(SZL.Data, 0, SZL.DataSize);
--        }
--        return LastError;
--    }
--
--    public int GetPlcDateTime(Date DateTime)
--    {
--        int Length;
--
--        LastError = 0;
--        SendPacket(S7_GET_DT);
--        if (LastError==0)
--        {
--            Length=RecvIsoPacket();
--            if (Length > 30) // the minimum expected
--            {
--                if ((S7.GetWordAt(PDU,27)==0) && (PDU[29]==(byte)0xFF))
--                {
--                    DateTime=S7.GetDateAt(PDU, 34);
--                }
--                else
--                    LastError = errS7FunctionError;
--            }
--            else
--                LastError = errS7InvalidPDU;
--        }
--        
--        return LastError;
--    }
--
--    public int SetPlcDateTime(Date DateTime)
--    {
--        int Length;
--       
--        LastError = 0;
--        S7.SetDateAt(S7_SET_DT, 31, DateTime);
--        
--        SendPacket(S7_SET_DT);
--        if (LastError==0)
--        {
--            Length=RecvIsoPacket();
--            if (Length > 30) // the minimum expected
--            {
--                if (S7.GetWordAt(PDU,27)!=0) 
--                    LastError = errS7FunctionError;
--            }
--            else
--                LastError = errS7InvalidPDU;
--        }
--        
--        return LastError;
--    }
--
--    public int SetPlcSystemDateTime()
--    {
--        return SetPlcDateTime(new Date());
--    }
--    
--    public int PlcStop()
--    {
--        int Length;
--       
--        LastError = 0;
--        SendPacket(S7_STOP);
--        if (LastError==0)
--        {
--            Length=RecvIsoPacket();
--            if (Length > 18) // 18 is the minimum expected
--            {
--                if (S7.GetWordAt(PDU,17)!=0) 
--                    LastError = errS7FunctionError;
--            }
--            else
--                LastError = errS7InvalidPDU;
--        }
--        return LastError;
--    }
--
--    public int PlcHotStart()
--    {
--        int Length;
--       
--        LastError = 0;
--        SendPacket(S7_HOT_START);
--        if (LastError==0)
--        {
--            Length=RecvIsoPacket();
--            if (Length > 18) // the minimum expected
--            {
--                if (S7.GetWordAt(PDU,17)!=0) 
--                    LastError = errS7FunctionError;
--            }
--            else
--                LastError = errS7InvalidPDU;
--        }
--        return LastError;
--    }
--
--    public int PlcColdStart()
--    {
--        int Length;
--       
--        LastError = 0;
--        SendPacket(S7_COLD_START);
--        if (LastError==0)
--        {
--            Length=RecvIsoPacket();
--            if (Length > 18) // the minimum expected
--            {
--                if (S7.GetWordAt(PDU,17)!=0) 
--                    LastError = errS7FunctionError;
--            }
--            else
--                LastError = errS7InvalidPDU;
--        }
--        return LastError;
--    }
--
--    public int GetPlcStatus(IntByRef Status)
--    {
--        int Length;
--       
--        LastError = 0;
--        SendPacket(S7_GET_STAT);
--        if (LastError==0)
--        {
--            Length=RecvIsoPacket();
--            if (Length > 30) // the minimum expected
--            {
--                if (S7.GetWordAt(PDU,27)==0) 
--                {
--                    switch (PDU[44])
--                    {
--                        case S7.S7CpuStatusUnknown :
--                        case S7.S7CpuStatusRun     :
--                        case S7.S7CpuStatusStop    : Status.Value=PDU[44];
--                        break;
--                        default :
--                        // Since RUN status is always 0x08 for all CPUs and CPs, STOP status
--                        // sometime can be coded as 0x03 (especially for old cpu...)
--                            Status.Value=S7.S7CpuStatusStop;
--                    }                    
--                }
--                else
--                    LastError = errS7FunctionError;
--            }
--            else
--                LastError = errS7InvalidPDU;
--        }            
--        return LastError;
--    }
--
--    public int SetSessionPassword(String Password)
--    {
--        byte[] pwd = {0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20};
--        int Length;
--
--        LastError = 0;
--        // Adjusts the Password length to 8
--        if (Password.length()>8) 
--            Password=Password.substring(0, 8);
--        else
--        {
--            while (Password.length()<8)
--                Password=Password+" ";
--        }
--        
--        try {
--            pwd = Password.getBytes("UTF-8");
--        } catch (UnsupportedEncodingException ex) {
--            LastError = errS7InvalidParams;
--        }
--        if (LastError==0)
--        {            
--            // Encodes the password
--            pwd[0]=(byte) (pwd[0] ^ 0x55);
--            pwd[1]=(byte) (pwd[1] ^ 0x55);
--            for (int c = 2; c < 8; c++)
--            {
--                pwd[c]=(byte) (pwd[c] ^ 0x55 ^ pwd[c-2]);            
--            }
--            System.arraycopy(pwd, 0, S7_SET_PWD, 29, 8);
--            // Sends the telegrem
--            SendPacket(S7_SET_PWD);
--            if (LastError==0)
--            {
--                Length=RecvIsoPacket();
--                if (Length > 32) // the minimum expected
--                {
--                    if (S7.GetWordAt(PDU,27)!=0) 
--                        LastError = errS7FunctionError;                    
--                }                
--                else
--                    LastError = errS7InvalidPDU;                
--            }            
--        }        
--        return LastError;
--    }
--        
--    public int ClearSessionPassword()
--    {
--        int Length;
--       
--        LastError = 0;       
--        SendPacket(S7_CLR_PWD);
--        if (LastError==0)
--        {
--            Length=RecvIsoPacket();
--            if (Length > 30) // the minimum expected
--            {
--                if (S7.GetWordAt(PDU,27)!=0) 
--                    LastError = errS7FunctionError;
--            }
--            else
--                LastError = errS7InvalidPDU;
--        }        
--        return LastError;
--    }
--    
--    public int GetProtection(S7Protection Protection)
--    {
--        S7Szl SZL = new S7Szl(256);
--        
--        LastError = ReadSZL(0x0232, 0x0004, SZL);
--        if (LastError==0)
--        {
--            Protection.Update(SZL.Data);
--        }
--        return LastError;
--    }
--    
--}
-+/*=============================================================================|
-+|  PROJECT Moka7                                                         1.0.2 |
-+|==============================================================================|
-+|  Copyright (C) 2013, 2016 Davide Nardella                                    |
-+|  All rights reserved.                                                        |
-+|==============================================================================|
-+|  SNAP7 is free software: you can redistribute it and/or modify               |
-+|  it under the terms of the Lesser GNU General Public License as published by |
-+|  the Free Software Foundation, either version 3 of the License, or under     |
-+|  EPL Eclipse Public License 1.0.                                             |
-+|                                                                              |
-+|  This means that you have to chose in advance which take before you import   |
-+|  the library into your project.                                              |
-+|                                                                              |
-+|  SNAP7 is distributed in the hope that it will be useful,                    |
-+|  but WITHOUT ANY WARRANTY; without even the implied warranty of              |
-+|  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you    |
-+|  decide to adopt.                                                            |
-+|                                                                              |
-+|=============================================================================*/
-+package Moka7;
-+
-+import java.io.DataInputStream;
-+import java.io.DataOutputStream;
-+import java.io.IOException;
-+import java.io.UnsupportedEncodingException;
-+import java.net.InetSocketAddress;
-+import java.net.Socket;
-+import java.net.SocketAddress;
-+import java.util.Date;
-+
-+
-+/**
-+ *
-+ * @author Davide Nardella
-+ */
-+public class S7Client
-+{
-+    // WordLength
-+    public static final int S7WLBit     = 0x01;
-+    public static final int S7WLByte    = 0x02;
-+    public static final int S7WLCounter = 0x1C;
-+    public static final int S7WLTimer   = 0x1D;
-+
-+    // Error Codes
-+    public static final int errTCPConnectionFailed = 0x0001;
-+    public static final int errTCPDataSend         = 0x0002;
-+    public static final int errTCPDataRecv         = 0x0003;
-+    public static final int errTCPDataRecvTout     = 0x0004;
-+    public static final int errTCPConnectionReset  = 0x0005;
-+    public static final int errISOInvalidPDU       = 0x0006;
-+    public static final int errISOConnectionFailed = 0x0007;
-+    public static final int errISONegotiatingPDU   = 0x0008;
-+    public static final int errS7InvalidPDU        = 0x0009;
-+    public static final int errS7DataRead          = 0x000A;
-+    public static final int errS7DataWrite         = 0x000B;
-+    public static final int errS7BufferTooSmall    = 0x000C;
-+    public static final int errS7FunctionError     = 0x000D;
-+    public static final int errS7InvalidParams     = 0x000E;
-+
-+    // Public fields
-+    public boolean Connected = false;
-+    public int LastError = 0;
-+    public int RecvTimeout = 2000;
-+
-+    // Privates
-+    private static final int ISOTCP = 102; // ISOTCP Port
-+    private static final int MinPduSize = 16;
-+    private static final int DefaultPduSizeRequested = 480;
-+    private static final int IsoHSize = 7; // TPKT+COTP Header Size
-+    private static final int MaxPduSize = DefaultPduSizeRequested+IsoHSize;
-+
-+    private Socket TCPSocket;
-+    private final byte[] PDU = new byte[2048];
-+
-+    private DataInputStream InStream = null;
-+    private DataOutputStream OutStream = null;
-+
-+    private String IPAddress;
-+
-+    private byte LocalTSAP_HI;
-+    private byte LocalTSAP_LO;
-+    private byte RemoteTSAP_HI;
-+    private byte RemoteTSAP_LO;
-+    private byte LastPDUType;
-+
-+    private short ConnType = S7.PG;
-+    private int _PDULength = 0;
-+
-+    // Telegrams
-+    // ISO Connection Request telegram (contains also ISO Header and COTP Header)
-+    private static final byte ISO_CR[] = {
-+        // TPKT (RFC1006 Header)
-+        (byte)0x03, // RFC 1006 ID (3)
-+        (byte)0x00, // Reserved, always 0
-+        (byte)0x00, // High part of packet lenght (entire frame, payload and TPDU included)
-+        (byte)0x16, // Low part of packet lenght (entire frame, payload and TPDU included)
-+        // COTP (ISO 8073 Header)
-+        (byte)0x11, // PDU Size Length
-+        (byte)0xE0, // CR - Connection Request ID
-+        (byte)0x00, // Dst Reference HI
-+        (byte)0x00, // Dst Reference LO
-+        (byte)0x00, // Src Reference HI
-+        (byte)0x01, // Src Reference LO
-+        (byte)0x00, // Class + Options Flags
-+        (byte)0xC0, // PDU Max Length ID
-+        (byte)0x01, // PDU Max Length HI
-+        (byte)0x0A, // PDU Max Length LO
-+        (byte)0xC1, // Src TSAP Identifier
-+        (byte)0x02, // Src TSAP Length (2 bytes)
-+        (byte)0x01, // Src TSAP HI (will be overwritten)
-+        (byte)0x00, // Src TSAP LO (will be overwritten)
-+        (byte)0xC2, // Dst TSAP Identifier
-+        (byte)0x02, // Dst TSAP Length (2 bytes)
-+        (byte)0x01, // Dst TSAP HI (will be overwritten)
-+        (byte)0x02  // Dst TSAP LO (will be overwritten)
-+    };
-+
-+    // S7 PDU Negotiation Telegram (contains also ISO Header and COTP Header)
-+    private static final byte S7_PN[] = {
-+        (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x19,
-+        (byte)0x02, (byte)0xf0, (byte)0x80, // TPKT + COTP (see above for info)
-+        (byte)0x32, (byte)0x01, (byte)0x00, (byte)0x00,
-+        (byte)0x04, (byte)0x00, (byte)0x00, (byte)0x08,
-+        (byte)0x00, (byte)0x00, (byte)0xf0, (byte)0x00,
-+        (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x01,
-+        (byte)0x00, (byte)0x1e // PDU Length Requested = HI-LO 480 bytes
-+    };
-+
-+    // S7 Read/Write Request Header (contains also ISO Header and COTP Header)
-+    private static final byte S7_RW[] = { // 31-35 bytes
-+        (byte)0x03,(byte)0x00,
-+        (byte)0x00,(byte)0x1f,  // Telegram Length (Data Size + 31 or 35)
-+        (byte)0x02,(byte)0xf0, (byte)0x80, // COTP (see above for info)
-+        (byte)0x32,             // S7 Protocol ID
-+        (byte)0x01,             // Job Type
-+        (byte)0x00,(byte)0x00,  // Redundancy identification
-+        (byte)0x05,(byte)0x00,  // PDU Reference
-+        (byte)0x00,(byte)0x0e,  // Parameters Length
-+        (byte)0x00,(byte)0x00,  // Data Length = Size(bytes) + 4
-+        (byte)0x04,             // Function 4 Read Var, 5 Write Var
-+        (byte)0x01,             // Items count
-+        (byte)0x12,             // Var spec.
-+        (byte)0x0a,             // Length of remaining bytes
-+        (byte)0x10,             // Syntax ID
-+        S7WLByte,               // Transport Size
-+        (byte)0x00,(byte)0x00,  // Num Elements
-+        (byte)0x00,(byte)0x00,  // DB Number (if any, else 0)
-+        (byte)0x84,             // Area Type
-+        (byte)0x00,(byte)0x00,(byte)0x00, // Area Offset
-+        // WR area
-+        (byte)0x00,             // Reserved
-+        (byte)0x04,             // Transport size
-+        (byte)0x00,(byte)0x00,  // Data Length * 8 (if not timer or counter)
-+    };
-+    private static final int Size_RD = 31;
-+    private static final int Size_WR = 35;
-+
-+    // S7 Get Block Info Request Header (contains also ISO Header and COTP Header)
-+    private static final byte S7_BI[] = {
-+        (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x25,
-+        (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
-+        (byte)0x07, (byte)0x00, (byte)0x00, (byte)0x05,
-+        (byte)0x00, (byte)0x00, (byte)0x08, (byte)0x00,
-+        (byte)0x0c, (byte)0x00, (byte)0x01, (byte)0x12,
-+        (byte)0x04, (byte)0x11, (byte)0x43, (byte)0x03,
-+        (byte)0x00, (byte)0xff, (byte)0x09, (byte)0x00,
-+        (byte)0x08, (byte)0x30,
-+        (byte)0x41, // Block Type
-+        (byte)0x30, (byte)0x30, (byte)0x30, (byte)0x30, (byte)0x30, // ASCII Block Number
-+        (byte)0x41
-+    };
-+
-+    // SZL First telegram request
-+    private static final byte S7_SZL_FIRST[] = {
-+        (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x21,
-+        (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
-+        (byte)0x07, (byte)0x00, (byte)0x00,
-+        (byte)0x05, (byte)0x00, // Sequence out
-+        (byte)0x00, (byte)0x08, (byte)0x00,
-+        (byte)0x08, (byte)0x00, (byte)0x01, (byte)0x12,
-+        (byte)0x04, (byte)0x11, (byte)0x44, (byte)0x01,
-+        (byte)0x00, (byte)0xff, (byte)0x09, (byte)0x00,
-+        (byte)0x04,
-+        (byte)0x00, (byte)0x00, // ID (29)
-+        (byte)0x00, (byte)0x00  // Index (31)
-+    };
-+
-+    // SZL Next telegram request
-+    private static final byte S7_SZL_NEXT[] = {
-+        (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x21,
-+        (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
-+        (byte)0x07, (byte)0x00, (byte)0x00, (byte)0x06,
-+        (byte)0x00, (byte)0x00, (byte)0x0c, (byte)0x00,
-+        (byte)0x04, (byte)0x00, (byte)0x01, (byte)0x12,
-+        (byte)0x08, (byte)0x12, (byte)0x44, (byte)0x01,
-+        (byte)0x01, // Sequence
-+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-+        (byte)0x0a, (byte)0x00, (byte)0x00, (byte)0x00
-+    };
-+
-+    // Get Date/Time request
-+    private static final byte S7_GET_DT[] = {
-+        (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x1d,
-+        (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
-+        (byte)0x07, (byte)0x00, (byte)0x00, (byte)0x38,
-+        (byte)0x00, (byte)0x00, (byte)0x08, (byte)0x00,
-+        (byte)0x04, (byte)0x00, (byte)0x01, (byte)0x12,
-+        (byte)0x04, (byte)0x11, (byte)0x47, (byte)0x01,
-+        (byte)0x00, (byte)0x0a, (byte)0x00, (byte)0x00,
-+        (byte)0x00
-+    };
-+
-+    // Set Date/Time command
-+    private static final byte S7_SET_DT[] = {
-+        (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x27,
-+        (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
-+        (byte)0x07, (byte)0x00, (byte)0x00, (byte)0x89,
-+        (byte)0x03, (byte)0x00, (byte)0x08, (byte)0x00,
-+        (byte)0x0e, (byte)0x00, (byte)0x01, (byte)0x12,
-+        (byte)0x04, (byte)0x11, (byte)0x47, (byte)0x02,
-+        (byte)0x00, (byte)0xff, (byte)0x09, (byte)0x00,
-+        (byte)0x0a, (byte)0x00, (byte)0x19, // Hi part of Year
-+        (byte)0x13, // Lo part of Year
-+        (byte)0x12, // Month
-+        (byte)0x06, // Day
-+        (byte)0x17, // Hour
-+        (byte)0x37, // Min
-+        (byte)0x13, // Sec
-+        (byte)0x00, (byte)0x01 // ms + Day of week
-+    };
-+
-+    // S7 STOP request
-+    private static final byte S7_STOP[] = {
-+        (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x21,
-+        (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
-+        (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x0e,
-+        (byte)0x00, (byte)0x00, (byte)0x10, (byte)0x00,
-+        (byte)0x00, (byte)0x29, (byte)0x00, (byte)0x00,
-+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x09,
-+        (byte)0x50, (byte)0x5f, (byte)0x50, (byte)0x52,
-+        (byte)0x4f, (byte)0x47, (byte)0x52, (byte)0x41,
-+        (byte)0x4d
-+    };
-+
-+    // S7 HOT Start request
-+    private static final byte S7_HOT_START[] = {
-+        (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x25,
-+        (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
-+        (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x0c,
-+        (byte)0x00, (byte)0x00, (byte)0x14, (byte)0x00,
-+        (byte)0x00, (byte)0x28, (byte)0x00, (byte)0x00,
-+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-+        (byte)0xfd, (byte)0x00, (byte)0x00, (byte)0x09,
-+        (byte)0x50, (byte)0x5f, (byte)0x50, (byte)0x52,
-+        (byte)0x4f, (byte)0x47, (byte)0x52, (byte)0x41,
-+        (byte)0x4d
-+    };
-+
-+    // S7 COLD Start request
-+    private static final byte S7_COLD_START[] = {
-+        (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x27,
-+        (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
-+        (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x0f,
-+        (byte)0x00, (byte)0x00, (byte)0x16, (byte)0x00,
-+        (byte)0x00, (byte)0x28, (byte)0x00, (byte)0x00,
-+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-+        (byte)0xfd, (byte)0x00, (byte)0x02, (byte)0x43,
-+        (byte)0x20, (byte)0x09, (byte)0x50, (byte)0x5f,
-+        (byte)0x50, (byte)0x52, (byte)0x4f, (byte)0x47,
-+        (byte)0x52, (byte)0x41, (byte)0x4d
-+    };
-+
-+    // S7 Get PLC Status
-+    private static final byte S7_GET_STAT[] = {
-+        (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x21,
-+        (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
-+        (byte)0x07, (byte)0x00, (byte)0x00, (byte)0x2c,
-+        (byte)0x00, (byte)0x00, (byte)0x08, (byte)0x00,
-+        (byte)0x08, (byte)0x00, (byte)0x01, (byte)0x12,
-+        (byte)0x04, (byte)0x11, (byte)0x44, (byte)0x01,
-+        (byte)0x00, (byte)0xff, (byte)0x09, (byte)0x00,
-+        (byte)0x04, (byte)0x04, (byte)0x24, (byte)0x00,
-+        (byte)0x00
-+    };
-+
-+    // S7 Set Session Password
-+    private static final byte S7_SET_PWD[] = {
-+        (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x25,
-+        (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
-+        (byte)0x07, (byte)0x00, (byte)0x00, (byte)0x27,
-+        (byte)0x00, (byte)0x00, (byte)0x08, (byte)0x00,
-+        (byte)0x0c, (byte)0x00, (byte)0x01, (byte)0x12,
-+        (byte)0x04, (byte)0x11, (byte)0x45, (byte)0x01,
-+        (byte)0x00, (byte)0xff, (byte)0x09, (byte)0x00,
-+        (byte)0x08,
-+        // 8 Char Encoded Password
-+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
-+        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00
-+    };
-+
-+    // S7 Clear Session Password
-+    private static final byte S7_CLR_PWD[] = {
-+        (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x1d,
-+        (byte)0x02, (byte)0xf0, (byte)0x80, (byte)0x32,
-+        (byte)0x07, (byte)0x00, (byte)0x00, (byte)0x29,
-+        (byte)0x00, (byte)0x00, (byte)0x08, (byte)0x00,
-+        (byte)0x04, (byte)0x00, (byte)0x01, (byte)0x12,
-+        (byte)0x04, (byte)0x11, (byte)0x45, (byte)0x02,
-+        (byte)0x00, (byte)0x0a, (byte)0x00, (byte)0x00,
-+        (byte)0x00
-+    };
-+
-+    public S7Client()
-+    {
-+        // Placeholder for future implementations
-+    }
-+
-+    public static String ErrorText(int Error)
-+    {
-+        switch (Error)
-+        {
-+            case errTCPConnectionFailed :
-+                return "TCP Connection failed.";
-+            case errTCPDataSend :
-+                return "TCP Sending error.";
-+            case errTCPDataRecv :
-+                return "TCP Receiving error.";
-+            case errTCPDataRecvTout :
-+                return "Data Receiving timeout.";
-+            case errTCPConnectionReset :
-+                return "Connection reset by the peer.";
-+            case errISOInvalidPDU :
-+                return "Invalid ISO PDU received.";
-+            case errISOConnectionFailed :
-+                return "ISO connection refused by the CPU.";
-+            case errISONegotiatingPDU :
-+                return "ISO error negotiating the PDU length.";
-+            case errS7InvalidPDU :
-+                return "Invalid S7 PDU received.";
-+            case errS7DataRead :
-+                return "S7 Error reading data from the CPU.";
-+            case errS7DataWrite :
-+                return "S7 Error writing data to the CPU.";
-+            case errS7BufferTooSmall :
-+                return "The Buffer supplied to the function is too small.";
-+            case errS7FunctionError :
-+                return "S7 function refused by the CPU.";
-+            case errS7InvalidParams :
-+                return "Invalid parameters supplied to the function.";
-+            default :
-+                return "Unknown error : 0x"+Integer.toHexString(Error);
-+        }
-+    }
-+
-+    private int TCPConnect()
-+    {
-+        SocketAddress sockaddr = new InetSocketAddress(IPAddress, ISOTCP);
-+        LastError=0;
-+        try {
-+            TCPSocket = new Socket();
-+            TCPSocket.connect(sockaddr ,5000);
-+            TCPSocket.setTcpNoDelay(true);
-+            InStream = new DataInputStream(TCPSocket.getInputStream());
-+            OutStream = new DataOutputStream(TCPSocket.getOutputStream());
-+        }
-+        catch (IOException e) {
-+            LastError=errTCPConnectionFailed;
-+        }
-+        return LastError;
-+    }
-+
-+    private int WaitForData(int Size, int Timeout)
-+    {
-+        int cnt = 0;
-+        LastError=0;
-+        int SizeAvail;
-+        boolean Expired = false;
-+        try
-+        {
-+            SizeAvail=InStream.available();
-+            while ((SizeAvail<Size) && (!Expired) && (LastError==0))
-+            {
-+                cnt++;
-+                try {
-+                    Thread.sleep(1);
-+                }
-+                catch (InterruptedException ex) {
-+                    LastError=errTCPDataRecvTout;
-+                }
-+                SizeAvail=InStream.available();
-+                Expired=cnt>Timeout;
-+                // If timeout we clean the buffer
-+                if (Expired && (SizeAvail>0) && (LastError==0))
-+                  InStream.read(PDU, 0, SizeAvail);
-+            }
-+        }
-+        catch (IOException ex)
-+        {
-+            LastError=errTCPDataRecvTout;
-+        }
-+        if (cnt>=Timeout)
-+        {
-+            LastError=errTCPDataRecvTout;
-+        }
-+        return LastError;
-+    }
-+
-+    private int RecvPacket(byte[] Buffer, int Start, int Size)
-+    {
-+        int BytesRead=0;
-+        LastError=WaitForData(Size,RecvTimeout);
-+        if (LastError==0)
-+        {
-+            try {
-+                BytesRead = InStream.read(Buffer, Start, Size);
-+            } catch (IOException ex) {
-+                LastError=errTCPDataRecv;
-+            }
-+            if (BytesRead==0)
-+                LastError=errTCPConnectionReset;
-+        }
-+        return LastError;
-+    }
-+
-+    private void SendPacket(byte[] Buffer, int Len)
-+    {
-+        LastError = 0;
-+        try {
-+            OutStream.write(Buffer,0,Len);
-+            OutStream.flush();
-+        } catch (IOException ex) {
-+            LastError = errTCPDataSend;
-+        }
-+    }
-+    private void SendPacket(byte[] Buffer)
-+    {
-+        SendPacket(Buffer,Buffer.length);
-+    }
-+
-+    private int RecvIsoPacket()
-+    {
-+        Boolean Done = false;
-+        int Size = 0;
-+        while ((LastError==0) && !Done)
-+        {
-+            // Get TPKT (4 bytes)
-+            RecvPacket(PDU, 0, 4);
-+            if (LastError==0)
-+            {
-+                Size=S7.GetWordAt(PDU,2);
-+                // Check 0 bytes Data Packet (only TPKT+COTP = 7 bytes)
-+                if (Size==IsoHSize)
-+                    RecvPacket(PDU,4, 3); // Skip remaining 3 bytes and Done is still false
-+                else
-+                {
-+                    if ((Size>MaxPduSize) || (Size<MinPduSize))
-+                        LastError=errISOInvalidPDU;
-+                    else
-+                        Done = true; // a valid Length !=7 && >16 && <247
-+                }
-+            }
-+        }
-+        if (LastError==0)
-+        {
-+            RecvPacket(PDU,4, 3); // Skip remaining 3 COTP bytes
-+            LastPDUType=PDU[5];   // Stores PDU Type, we need it
-+            // Receives the S7 Payload
-+            RecvPacket(PDU, 7, Size-IsoHSize);
-+        }
-+        if (LastError==0)
-+            return Size;
-+        else
-+            return 0;
-+    }
-+
-+    private int ISOConnect()
-+    {
-+        int Size;
-+        ISO_CR[16]=LocalTSAP_HI;
-+        ISO_CR[17]=LocalTSAP_LO;
-+        ISO_CR[20]=RemoteTSAP_HI;
-+        ISO_CR[21]=RemoteTSAP_LO;
-+
-+        // Sends the connection request telegram
-+        SendPacket(ISO_CR);
-+        if (LastError==0)
-+        {
-+            // Gets the reply (if any)
-+            Size=RecvIsoPacket();
-+            if (LastError==0)
-+            {
-+                if (Size==22)
-+                {
-+                    if (LastPDUType!=(byte)0xD0) // 0xD0 = CC Connection confirm
-+                        LastError=errISOConnectionFailed;
-+                }
-+                else
-+                    LastError=errISOInvalidPDU;
-+            }
-+        }
-+        return LastError;
-+    }
-+
-+    private int NegotiatePduLength()
-+    {
-+        int Length;
-+        // Set PDU Size Requested
-+        S7.SetWordAt(S7_PN,23,DefaultPduSizeRequested);
-+        // Sends the connection request telegram
-+        SendPacket(S7_PN);
-+        if (LastError==0)
-+        {
-+            Length=RecvIsoPacket();
-+            if (LastError==0)
-+            {
-+                // check S7 Error
-+                if ((Length==27) && (PDU[17]==0) && (PDU[18]==0))  // 20 = size of Negotiate Answer
-+                {
-+                    // Get PDU Size Negotiated
-+                    _PDULength = S7.GetWordAt(PDU,25);
-+                    if (_PDULength>0)
-+                        return 0;
-+                    else
-+                        LastError=errISONegotiatingPDU;
-+                }
-+                else
-+                    LastError=errISONegotiatingPDU;
-+            }
-+        }
-+        return LastError;
-+    }
-+
-+    public void SetConnectionType(short ConnectionType)
-+    {
-+        ConnType=ConnectionType;
-+    }
-+
-+    public int Connect()
-+    {
-+        LastError=0;
-+        if (!Connected)
-+        {
-+            TCPConnect();
-+            if (LastError==0) // First stage : TCP Connection
-+            {
-+                ISOConnect();
-+                if (LastError==0) // Second stage : ISOTCP (ISO 8073) Connection
-+                {
-+                    LastError=NegotiatePduLength(); // Third stage : S7 PDU negotiation
-+                }
-+            }
-+        }
-+        Connected=LastError==0;
-+
-+        // In case the connection is not completely established (TCP connection + ISO connection + PDU negotiation)
-+        // we close the socket and its IO streams to revert the object back to pre-Connect() state
-+        if (!Connected)
-+        {
-+            if (TCPSocket != null) {
-+                try {
-+                    TCPSocket.close();
-+                } catch (IOException ex) {
-+                }
-+            }
-+            if (InStream != null) {
-+                try {
-+                    InStream.close();
-+                } catch (IOException ex) {
-+                }
-+            }
-+            if (OutStream != null) {
-+                try {
-+                    OutStream.close();
-+                } catch (IOException ex) {
-+                }
-+            }
-+            _PDULength = 0;
-+        }
-+
-+        return LastError;
-+    }
-+
-+    public void Disconnect()
-+    {
-+        if (Connected)
-+        {
-+            try {
-+                OutStream.close();
-+                InStream.close();
-+                TCPSocket.close();
-+                _PDULength=0;
-+            } catch (IOException ex) {
-+            }
-+            Connected=false;
-+        }
-+    }
-+
-+    public int ConnectTo(String Address, int Rack, int Slot)
-+    {
-+        int RemoteTSAP=(ConnType<<8)+ (Rack * 0x20) + Slot;
-+        SetConnectionParams(Address, 0x0100, RemoteTSAP);
-+        return Connect();
-+    }
-+
-+    public int PDULength()
-+    {
-+        return _PDULength;
-+    }
-+
-+    public void SetConnectionParams(String Address, int LocalTSAP, int RemoteTSAP)
-+    {
-+        int LocTSAP = LocalTSAP & 0x0000FFFF;
-+        int RemTSAP = RemoteTSAP & 0x0000FFFF;
-+        IPAddress    =  Address;
-+        LocalTSAP_HI = (byte) (LocTSAP>>8);
-+        LocalTSAP_LO = (byte) (LocTSAP & 0x00FF);
-+        RemoteTSAP_HI= (byte) (RemTSAP>>8);
-+        RemoteTSAP_LO= (byte) (RemTSAP & 0x00FF);
-+    }
-+
-+    public int ReadArea(int Area, int DBNumber, int Start, int Amount, int WordLength, byte[] Data)
-+    {
-+        int Address;
-+        int NumElements;
-+        int MaxElements;
-+        int TotElements;
-+        int SizeRequested;
-+        int Length;
-+        int Offset = 0;
-+        byte WordSize = 1;
-+
-+        LastError=0;
-+
-+        // If we are addressing Timers or counters the element size is 2
-+        if ((Area==S7.S7AreaCT) || (Area==S7.S7AreaTM))
-+            WordSize = 2;
-+
-+        MaxElements=(_PDULength-18) / WordSize; // 18 = Reply telegram header
-+            TotElements=Amount;
-+
-+        while ((TotElements>0) && (LastError==0))
-+        {
-+            NumElements=TotElements;
-+            if (NumElements>MaxElements)
-+               NumElements=MaxElements;
-+
-+            SizeRequested = NumElements * WordSize;
-+
-+            // Setup the telegram
-+            System.arraycopy(S7_RW, 0, PDU, 0, Size_RD);
-+            // Set DB Number
-+            PDU[27] = (byte) Area;
-+            // Set Area
-+            if (Area==S7.S7AreaDB)
-+                S7.SetWordAt(PDU,25,DBNumber);
-+
-+            PDU[22] = (byte) WordLength;
-+            // Adjusts Start and word length
-+            if ((WordLength==S7WLBit) || (WordLength==S7WLTimer) || (WordLength==S7WLCounter))
-+            {
-+                Address = Start;
-+            }
-+            else
-+            {
-+                Address = Start<<3;
-+            }
-+
-+            // Num elements
-+            S7.SetWordAt(PDU,23,NumElements);
-+
-+            // Address into the PLC (only 3 bytes)
-+            PDU[30] = (byte) (Address & 0x0FF);
-+            Address = Address >> 8;
-+            PDU[29] = (byte) (Address & 0x0FF);
-+            Address = Address >> 8;
-+            PDU[28] = (byte) (Address & 0x0FF);
-+
-+            // Transport Size
-+            PDU[32] = 0x04;
-+            if (WordLength==S7WLBit)
-+            {
-+                PDU[32] = 0x03;
-+            }
-+            else if ((WordLength==S7WLTimer) || (WordLength==S7WLCounter))
-+            {
-+                PDU[32] = 0x09;
-+            }
-+
-+            SendPacket(PDU, Size_RD);
-+            if (LastError==0)
-+            {
-+                Length=RecvIsoPacket();
-+                if (LastError==0)
-+                {
-+                    if (Length>=25)
-+                    {
-+                        if ((Length-25==SizeRequested) && (PDU[21]==(byte)0xFF))
-+                        {
-+                            System.arraycopy(PDU, 25, Data, Offset, SizeRequested);
-+                            Offset+=SizeRequested;
-+                        }
-+                        else
-+                            LastError = errS7DataRead;
-+                    }
-+                    else
-+                        LastError = errS7InvalidPDU;
-+                }
-+            }
-+
-+            TotElements -= NumElements;
-+            Start += NumElements*WordSize;
-+        }
-+        return LastError;
-+    }
-+
-+    public int WriteArea(int Area, int DBNumber, int Start, int Amount, int WordLength, byte[] Data)
-+    {
-+        int Address;
-+        int NumElements;
-+        int MaxElements;
-+        int TotElements;
-+        int DataSize;
-+        int IsoSize;
-+        int Length;
-+        int Offset = 0;
-+        byte WordSize = 1;
-+
-+        LastError=0;
-+
-+        // If we are addressing Timers or counters the element size is 2
-+        if ((Area==S7.S7AreaCT) || (Area==S7.S7AreaTM))
-+            WordSize = 2;
-+
-+        MaxElements=(_PDULength-35) / WordSize; // 35 = Reply telegram header
-+        TotElements=Amount;
-+
-+        while ((TotElements>0) && (LastError==0))
-+        {
-+            NumElements=TotElements;
-+            if (NumElements>MaxElements)
-+               NumElements=MaxElements;
-+
-+            DataSize = NumElements * WordSize;
-+            IsoSize  = Size_WR + DataSize;
-+
-+            // Setup the telegram
-+            System.arraycopy(S7_RW, 0, PDU, 0, Size_WR);
-+            // Whole telegram Size
-+            S7.SetWordAt(PDU,2,IsoSize);
-+            // Data Length
-+            Length=DataSize+4;
-+            S7.SetWordAt(PDU,15,Length);
-+            // Function
-+            PDU[17]= (byte) 0x05;
-+            // Set DB Number
-+            PDU[27] = (byte) Area;
-+            if (Area==S7.S7AreaDB)
-+                S7.SetWordAt(PDU,25,DBNumber);
-+
-+            PDU[22] = (byte) WordLength;
-+            // Adjusts Start and word length
-+            if ((WordLength==S7WLBit) || (WordLength==S7WLTimer) || (WordLength==S7WLCounter))
-+            {
-+                Address = Start;
-+                Length = DataSize;
-+            }
-+            else
-+            {
-+                Address = Start<<3;
-+                Length = DataSize<<3;
-+            }
-+
-+            // Num elements
-+            S7.SetWordAt(PDU,23,NumElements);
-+            // Address into the PLC
-+            PDU[30] = (byte) (Address & 0x0FF);
-+            Address = Address >> 8;
-+            PDU[29] = (byte) (Address & 0x0FF);
-+            Address = Address >> 8;
-+            PDU[28] = (byte) (Address & 0x0FF);
-+
-+            // Transport Size
-+            PDU[32] = 0x04;
-+            if (WordLength==S7WLBit)
-+            {
-+                PDU[32] = 0x03;
-+            }
-+            else if ((WordLength==S7WLTimer) || (WordLength==S7WLCounter))
-+            {
-+                PDU[32] = 0x09;
-+            }
-+
-+            // Length
-+            S7.SetWordAt(PDU,33,Length);
-+
-+            // Copies the Data
-+            System.arraycopy(Data, Offset, PDU, 35, DataSize);
-+
-+            SendPacket(PDU, IsoSize);
-+            if (LastError==0)
-+            {
-+                Length=RecvIsoPacket();
-+                if (LastError==0)
-+                {
-+                    if (Length==22)
-+                    {
-+                        if ((S7.GetWordAt(PDU,17)!=0) || (PDU[21]!=(byte)0xFF))
-+                            LastError = errS7DataWrite;
-+                    }
-+                    else
-+                        LastError = errS7InvalidPDU;
-+                }
-+            }
-+
-+            Offset+=DataSize;
-+            TotElements -= NumElements;
-+            Start += NumElements*WordSize;
-+        }
-+        return LastError;
-+    }
-+
-+    public int GetAgBlockInfo(int BlockType, int BlockNumber, S7BlockInfo Block)
-+    {
-+        int Length;
-+        LastError=0;
-+        // Block Type
-+        S7_BI[30] = (byte) BlockType;
-+        // Block Number
-+        S7_BI[31]=(byte) ((BlockNumber / 10000)+0x30);
-+        BlockNumber=BlockNumber % 10000;
-+        S7_BI[32]=(byte) ((BlockNumber / 1000)+0x30);
-+        BlockNumber=BlockNumber % 1000;
-+        S7_BI[33]=(byte) ((BlockNumber / 100)+0x30);
-+        BlockNumber=BlockNumber % 100;
-+        S7_BI[34]=(byte) ((BlockNumber / 10)+0x30);
-+        BlockNumber=BlockNumber % 10;
-+        S7_BI[35]=(byte) ((BlockNumber / 1)+0x30);
-+
-+        SendPacket(S7_BI);
-+        if (LastError==0)
-+        {
-+            Length=RecvIsoPacket();
-+            if (Length > 32) // the minimum expected
-+            {
-+                if ((S7.GetWordAt(PDU,27)==0) && (PDU[29]==(byte)0xFF))
-+                {
-+                    Block.Update(PDU, 42);
-+                }
-+                else
-+                    LastError = errS7FunctionError;
-+            }
-+            else
-+                LastError = errS7InvalidPDU;
-+        }
-+
-+        return LastError;
-+    }
-+    /**
-+     *
-+     * @param DBNumber DB Number
-+     * @param Buffer   Destination buffer
-+     * @param SizeRead How many bytes were read
-+     * @return
-+     */
-+    public int DBGet(int DBNumber, byte[] Buffer, IntByRef SizeRead)
-+    {
-+        S7BlockInfo Block = new S7BlockInfo();
-+        // Query the DB Length
-+        LastError = GetAgBlockInfo(S7.Block_DB, DBNumber, Block);
-+        if (LastError==0)
-+        {
-+            int SizeToRead = Block.MC7Size();
-+            // Checks the room
-+            if (SizeToRead<=Buffer.length)
-+            {
-+                LastError=ReadArea(S7.S7AreaDB, DBNumber, 0, SizeToRead, S7WLByte, Buffer);
-+                if (LastError==0)
-+                    SizeRead.Value=SizeToRead;
-+            }
-+            else
-+                LastError=errS7BufferTooSmall;
-+        }
-+        return LastError;
-+    }
-+
-+    public int ReadSZL(int ID, int Index, S7Szl SZL)
-+    {
-+        int Length;
-+        int DataSZL;
-+        int Offset = 0;
-+        boolean Done = false;
-+        boolean First = true;
-+        byte Seq_in =0x00;
-+        int Seq_out =0x0000;
-+
-+        LastError=0;
-+        SZL.DataSize=0;
-+        do
-+        {
-+            if (First)
-+            {
-+                S7.SetWordAt(S7_SZL_FIRST, 11, ++Seq_out);
-+                S7.SetWordAt(S7_SZL_FIRST, 29, ID);
-+                S7.SetWordAt(S7_SZL_FIRST, 31, Index);
-+                SendPacket(S7_SZL_FIRST);
-+            }
-+            else
-+            {
-+                S7.SetWordAt(S7_SZL_NEXT, 11, ++Seq_out);
-+                PDU[24] = (byte)Seq_in;
-+                SendPacket(S7_SZL_NEXT);
-+            }
-+            if (LastError!=0)
-+                return LastError;
-+
-+            Length=RecvIsoPacket();
-+            if (LastError==0)
-+            {
-+                if (First)
-+                {
-+                    if (Length > 32) // the minimum expected
-+                    {
-+                        if ((S7.GetWordAt(PDU,27)==0) && (PDU[29]==(byte)0xFF))
-+                        {
-+                            // Gets Amount of this slice
-+                            DataSZL=S7.GetWordAt(PDU,31)-8; // Skips extra params (ID, Index ...)
-+                            Done=PDU[26]==0x00;
-+                            Seq_in=(byte)PDU[24]; // Slice sequence
-+
-+                            SZL.LENTHDR=S7.GetWordAt(PDU, 37);
-+                            SZL.N_DR=S7.GetWordAt(PDU, 39);
-+                            SZL.Copy(PDU, 41, Offset, DataSZL);
-+                            Offset+=DataSZL;
-+                            SZL.DataSize+=DataSZL;
-+                        }
-+                        else
-+                            LastError = errS7FunctionError;
-+                    }
-+                    else
-+                        LastError = errS7InvalidPDU;
-+                }
-+                else
-+                {
-+                    if (Length > 32) // the minimum expected
-+                    {
-+                        if ((S7.GetWordAt(PDU,27)==0) && (PDU[29]==(byte)0xFF))
-+                        {
-+                            // Gets Amount of this slice
-+                            DataSZL=S7.GetWordAt(PDU,31);
-+                            Done=PDU[26]==0x00;
-+                            Seq_in=(byte)PDU[24]; // Slice sequence
-+                            SZL.Copy(PDU, 37, Offset, DataSZL);
-+                            Offset+=DataSZL;
-+                            SZL.DataSize+=DataSZL;
-+                        }
-+                        else
-+                            LastError = errS7FunctionError;
-+                    }
-+                    else
-+                        LastError = errS7InvalidPDU;
-+                }
-+            }
-+            First=false;
-+        }
-+        while(!Done && (LastError==0));
-+
-+        return LastError;
-+    }
-+
-+    public int GetCpuInfo(S7CpuInfo Info)
-+    {
-+        S7Szl SZL = new S7Szl(1024);
-+
-+        LastError = ReadSZL(0x001C, 0x0000, SZL);
-+        if (LastError==0)
-+        {
-+            Info.Update(SZL.Data, 0);
-+        }
-+        return LastError;
-+    }
-+
-+    public int GetCpInfo(S7CpInfo Info)
-+    {
-+        S7Szl SZL = new S7Szl(1024);
-+
-+        LastError = ReadSZL(0x0131, 0x0001, SZL);
-+        if (LastError==0)
-+        {
-+            Info.Update(SZL.Data, 0);
-+        }
-+        return LastError;
-+    }
-+
-+    public int GetOrderCode(S7OrderCode Code)
-+    {
-+        S7Szl SZL = new S7Szl(1024);
-+
-+        LastError = ReadSZL(0x0011, 0x0000, SZL);
-+        if (LastError==0)
-+        {
-+            Code.Update(SZL.Data, 0, SZL.DataSize);
-+        }
-+        return LastError;
-+    }
-+
-+    public int GetPlcDateTime(Date DateTime)
-+    {
-+        int Length;
-+
-+        LastError = 0;
-+        SendPacket(S7_GET_DT);
-+        if (LastError==0)
-+        {
-+            Length=RecvIsoPacket();
-+            if (Length > 30) // the minimum expected
-+            {
-+                if ((S7.GetWordAt(PDU,27)==0) && (PDU[29]==(byte)0xFF))
-+                {
-+                    DateTime=S7.GetDateAt(PDU, 34);
-+                }
-+                else
-+                    LastError = errS7FunctionError;
-+            }
-+            else
-+                LastError = errS7InvalidPDU;
-+        }
-+
-+        return LastError;
-+    }
-+
-+    public int SetPlcDateTime(Date DateTime)
-+    {
-+        int Length;
-+
-+        LastError = 0;
-+        S7.SetDateAt(S7_SET_DT, 31, DateTime);
-+
-+        SendPacket(S7_SET_DT);
-+        if (LastError==0)
-+        {
-+            Length=RecvIsoPacket();
-+            if (Length > 30) // the minimum expected
-+            {
-+                if (S7.GetWordAt(PDU,27)!=0)
-+                    LastError = errS7FunctionError;
-+            }
-+            else
-+                LastError = errS7InvalidPDU;
-+        }
-+
-+        return LastError;
-+    }
-+
-+    public int SetPlcSystemDateTime()
-+    {
-+        return SetPlcDateTime(new Date());
-+    }
-+
-+    public int PlcStop()
-+    {
-+        int Length;
-+
-+        LastError = 0;
-+        SendPacket(S7_STOP);
-+        if (LastError==0)
-+        {
-+            Length=RecvIsoPacket();
-+            if (Length > 18) // 18 is the minimum expected
-+            {
-+                if (S7.GetWordAt(PDU,17)!=0)
-+                    LastError = errS7FunctionError;
-+            }
-+            else
-+                LastError = errS7InvalidPDU;
-+        }
-+        return LastError;
-+    }
-+
-+    public int PlcHotStart()
-+    {
-+        int Length;
-+
-+        LastError = 0;
-+        SendPacket(S7_HOT_START);
-+        if (LastError==0)
-+        {
-+            Length=RecvIsoPacket();
-+            if (Length > 18) // the minimum expected
-+            {
-+                if (S7.GetWordAt(PDU,17)!=0)
-+                    LastError = errS7FunctionError;
-+            }
-+            else
-+                LastError = errS7InvalidPDU;
-+        }
-+        return LastError;
-+    }
-+
-+    public int PlcColdStart()
-+    {
-+        int Length;
-+
-+        LastError = 0;
-+        SendPacket(S7_COLD_START);
-+        if (LastError==0)
-+        {
-+            Length=RecvIsoPacket();
-+            if (Length > 18) // the minimum expected
-+            {
-+                if (S7.GetWordAt(PDU,17)!=0)
-+                    LastError = errS7FunctionError;
-+            }
-+            else
-+                LastError = errS7InvalidPDU;
-+        }
-+        return LastError;
-+    }
-+
-+    public int GetPlcStatus(IntByRef Status)
-+    {
-+        int Length;
-+
-+        LastError = 0;
-+        SendPacket(S7_GET_STAT);
-+        if (LastError==0)
-+        {
-+            Length=RecvIsoPacket();
-+            if (Length > 30) // the minimum expected
-+            {
-+                if (S7.GetWordAt(PDU,27)==0)
-+                {
-+                    switch (PDU[44])
-+                    {
-+                        case S7.S7CpuStatusUnknown :
-+                        case S7.S7CpuStatusRun     :
-+                        case S7.S7CpuStatusStop    : Status.Value=PDU[44];
-+                        break;
-+                        default :
-+                        // Since RUN status is always 0x08 for all CPUs and CPs, STOP status
-+                        // sometime can be coded as 0x03 (especially for old cpu...)
-+                            Status.Value=S7.S7CpuStatusStop;
-+                    }
-+                }
-+                else
-+                    LastError = errS7FunctionError;
-+            }
-+            else
-+                LastError = errS7InvalidPDU;
-+        }
-+        return LastError;
-+    }
-+
-+    public int SetSessionPassword(String Password)
-+    {
-+        byte[] pwd = {0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20};
-+        int Length;
-+
-+        LastError = 0;
-+        // Adjusts the Password length to 8
-+        if (Password.length()>8)
-+            Password=Password.substring(0, 8);
-+        else
-+        {
-+            while (Password.length()<8)
-+                Password=Password+" ";
-+        }
-+
-+        try {
-+            pwd = Password.getBytes("UTF-8");
-+        } catch (UnsupportedEncodingException ex) {
-+            LastError = errS7InvalidParams;
-+        }
-+        if (LastError==0)
-+        {
-+            // Encodes the password
-+            pwd[0]=(byte) (pwd[0] ^ 0x55);
-+            pwd[1]=(byte) (pwd[1] ^ 0x55);
-+            for (int c = 2; c < 8; c++)
-+            {
-+                pwd[c]=(byte) (pwd[c] ^ 0x55 ^ pwd[c-2]);
-+            }
-+            System.arraycopy(pwd, 0, S7_SET_PWD, 29, 8);
-+            // Sends the telegrem
-+            SendPacket(S7_SET_PWD);
-+            if (LastError==0)
-+            {
-+                Length=RecvIsoPacket();
-+                if (Length > 32) // the minimum expected
-+                {
-+                    if (S7.GetWordAt(PDU,27)!=0)
-+                        LastError = errS7FunctionError;
-+                }
-+                else
-+                    LastError = errS7InvalidPDU;
-+            }
-+        }
-+        return LastError;
-+    }
-+
-+    public int ClearSessionPassword()
-+    {
-+        int Length;
-+
-+        LastError = 0;
-+        SendPacket(S7_CLR_PWD);
-+        if (LastError==0)
-+        {
-+            Length=RecvIsoPacket();
-+            if (Length > 30) // the minimum expected
-+            {
-+                if (S7.GetWordAt(PDU,27)!=0)
-+                    LastError = errS7FunctionError;
-+            }
-+            else
-+                LastError = errS7InvalidPDU;
-+        }
-+        return LastError;
-+    }
-+
-+    public int GetProtection(S7Protection Protection)
-+    {
-+        S7Szl SZL = new S7Szl(256);
-+
-+        LastError = ReadSZL(0x0232, 0x0004, SZL);
-+        if (LastError==0)
-+        {
-+            Protection.Update(SZL.Data);
-+        }
-+        return LastError;
-+    }
-+
-+}
-diff U3 S7CpInfo.java S7CpInfo.java
---- S7CpInfo.java      Thu Mar 23 15:34:52 2017
-+++ S7CpInfo.java      Tue Aug 08 18:53:37 2017
-@@ -1,41 +1,41 @@
--/*=============================================================================|
--|  PROJECT Moka7                                                         1.0.2 |
--|==============================================================================|
--|  Copyright (C) 2013, 2016 Davide Nardella                                    |
--|  All rights reserved.                                                        |
--|==============================================================================|
--|  SNAP7 is free software: you can redistribute it and/or modify               |
--|  it under the terms of the Lesser GNU General Public License as published by |
--|  the Free Software Foundation, either version 3 of the License, or under     |
--|  EPL Eclipse Public License 1.0.                                             |
--|                                                                              |
--|  This means that you have to chose in advance which take before you import   |
--|  the library into your project.                                              |
--|                                                                              |
--|  SNAP7 is distributed in the hope that it will be useful,                    |
--|  but WITHOUT ANY WARRANTY; without even the implied warranty of              |
--|  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you    |
--|  decide to adopt.                                                            |
--|                                                                              |
--|=============================================================================*/
--package Moka7;
--
--/**
-- *
-- * @author Davide
-- */
--public class S7CpInfo {
--
--    public int MaxPduLength;
--    public int MaxConnections;
--    public int MaxMpiRate;
--    public int MaxBusRate;
--
--    protected void Update(byte[] Src, int Pos)
--    {
--        MaxPduLength = S7.GetShortAt(Src, 2);
--        MaxConnections = S7.GetShortAt(Src, 4);
--        MaxMpiRate = S7.GetDIntAt(Src, 6);
--        MaxBusRate = S7.GetDIntAt(Src, 10);                      
--    }         
--}
-+/*=============================================================================|
-+|  PROJECT Moka7                                                         1.0.2 |
-+|==============================================================================|
-+|  Copyright (C) 2013, 2016 Davide Nardella                                    |
-+|  All rights reserved.                                                        |
-+|==============================================================================|
-+|  SNAP7 is free software: you can redistribute it and/or modify               |
-+|  it under the terms of the Lesser GNU General Public License as published by |
-+|  the Free Software Foundation, either version 3 of the License, or under     |
-+|  EPL Eclipse Public License 1.0.                                             |
-+|                                                                              |
-+|  This means that you have to chose in advance which take before you import   |
-+|  the library into your project.                                              |
-+|                                                                              |
-+|  SNAP7 is distributed in the hope that it will be useful,                    |
-+|  but WITHOUT ANY WARRANTY; without even the implied warranty of              |
-+|  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you    |
-+|  decide to adopt.                                                            |
-+|                                                                              |
-+|=============================================================================*/
-+package Moka7;
-+
-+/**
-+ *
-+ * @author Davide Nardella
-+ */
-+public class S7CpInfo {
-+
-+    public int MaxPduLength;
-+    public int MaxConnections;
-+    public int MaxMpiRate;
-+    public int MaxBusRate;
-+
-+    protected void Update(byte[] Src, int Pos)
-+    {
-+        MaxPduLength = S7.GetShortAt(Src, 2);
-+        MaxConnections = S7.GetShortAt(Src, 4);
-+        MaxMpiRate = S7.GetDIntAt(Src, 6);
-+        MaxBusRate = S7.GetDIntAt(Src, 10);
-+    }
-+}
-diff U3 S7CpuInfo.java S7CpuInfo.java
---- S7CpuInfo.java     Thu Mar 23 15:34:52 2017
-+++ S7CpuInfo.java     Tue Aug 08 18:53:37 2017
-@@ -1,57 +1,57 @@
--/*=============================================================================|
--|  PROJECT Moka7                                                         1.0.2 |
--|==============================================================================|
--|  Copyright (C) 2013, 2016 Davide Nardella                                    |
--|  All rights reserved.                                                        |
--|==============================================================================|
--|  SNAP7 is free software: you can redistribute it and/or modify               |
--|  it under the terms of the Lesser GNU General Public License as published by |
--|  the Free Software Foundation, either version 3 of the License, or under     |
--|  EPL Eclipse Public License 1.0.                                             |
--|                                                                              |
--|  This means that you have to chose in advance which take before you import   |
--|  the library into your project.                                              |
--|                                                                              |
--|  SNAP7 is distributed in the hope that it will be useful,                    |
--|  but WITHOUT ANY WARRANTY; without even the implied warranty of              |
--|  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you    |
--|  decide to adopt.                                                            |
--|                                                                              |
--|=============================================================================*/
--package Moka7;
--
--/**
-- *
-- * @author Davide
-- */
--public class S7CpuInfo {
--    
--    private final int BufSize = 256;
--    protected byte[] Buffer = new byte[BufSize];       
--
--    protected void Update(byte[] Src, int Pos)
--    {
--        System.arraycopy(Src, Pos, Buffer, 0, BufSize);
--    }   
--    
--    public String ModuleTypeName()
--    {
--        return S7.GetStringAt(Buffer,172,32);
--    }
--    public String SerialNumber()
--    {
--        return S7.GetStringAt(Buffer,138,24);
--    }
--    public String ASName()
--    {
--        return S7.GetStringAt(Buffer,2,24);
--    }
--    public String Copyright()
--    {
--        return S7.GetStringAt(Buffer,104,26);
--    }
--    public String ModuleName()
--    {
--        return S7.GetStringAt(Buffer,36,24);
--    }
--}
-+/*=============================================================================|
-+|  PROJECT Moka7                                                         1.0.2 |
-+|==============================================================================|
-+|  Copyright (C) 2013, 2016 Davide Nardella                                    |
-+|  All rights reserved.                                                        |
-+|==============================================================================|
-+|  SNAP7 is free software: you can redistribute it and/or modify               |
-+|  it under the terms of the Lesser GNU General Public License as published by |
-+|  the Free Software Foundation, either version 3 of the License, or under     |
-+|  EPL Eclipse Public License 1.0.                                             |
-+|                                                                              |
-+|  This means that you have to chose in advance which take before you import   |
-+|  the library into your project.                                              |
-+|                                                                              |
-+|  SNAP7 is distributed in the hope that it will be useful,                    |
-+|  but WITHOUT ANY WARRANTY; without even the implied warranty of              |
-+|  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you    |
-+|  decide to adopt.                                                            |
-+|                                                                              |
-+|=============================================================================*/
-+package Moka7;
-+
-+/**
-+ *
-+ * @author Davide Nardella
-+ */
-+public class S7CpuInfo {
-+
-+    private final int BufSize = 256;
-+    protected byte[] Buffer = new byte[BufSize];
-+
-+    protected void Update(byte[] Src, int Pos)
-+    {
-+        System.arraycopy(Src, Pos, Buffer, 0, BufSize);
-+    }
-+
-+    public String ModuleTypeName()
-+    {
-+        return S7.GetStringAt(Buffer,172,32);
-+    }
-+    public String SerialNumber()
-+    {
-+        return S7.GetStringAt(Buffer,138,24);
-+    }
-+    public String ASName()
-+    {
-+        return S7.GetStringAt(Buffer,2,24);
-+    }
-+    public String Copyright()
-+    {
-+        return S7.GetStringAt(Buffer,104,26);
-+    }
-+    public String ModuleName()
-+    {
-+        return S7.GetStringAt(Buffer,36,24);
-+    }
-+}
-diff U3 S7OrderCode.java S7OrderCode.java
---- S7OrderCode.java   Thu Mar 23 15:34:52 2017
-+++ S7OrderCode.java   Tue Aug 08 18:53:37 2017
-@@ -1,46 +1,46 @@
--/*=============================================================================|
--|  PROJECT Moka7                                                         1.0.2 |
--|==============================================================================|
--|  Copyright (C) 2013, 2016 Davide Nardella                                    |
--|  All rights reserved.                                                        |
--|==============================================================================|
--|  SNAP7 is free software: you can redistribute it and/or modify               |
--|  it under the terms of the Lesser GNU General Public License as published by |
--|  the Free Software Foundation, either version 3 of the License, or under     |
--|  EPL Eclipse Public License 1.0.                                             |
--|                                                                              |
--|  This means that you have to chose in advance which take before you import   |
--|  the library into your project.                                              |
--|                                                                              |
--|  SNAP7 is distributed in the hope that it will be useful,                    |
--|  but WITHOUT ANY WARRANTY; without even the implied warranty of              |
--|  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you    |
--|  decide to adopt.                                                            |
--|                                                                              |
--|=============================================================================*/
--package Moka7;
--
--/**
-- *
-- * @author Davide
-- */
--public class S7OrderCode {
--  
--    public int V1;
--    public int V2;
--    public int V3;
--    protected byte[] Buffer = new byte[1024];       
--
--    protected void Update(byte[] Src, int Pos, int Size)
--    {
--        System.arraycopy(Src, Pos, Buffer, 0, Size);
--        V1 = (byte) Src[Size-3];
--        V2 = (byte) Src[Size-2];
--        V3 = (byte) Src[Size-1];
--    }   
--
--    public String Code()
--    {
--        return S7.GetStringAt(Buffer, 2, 20);
--    }
--}
-+/*=============================================================================|
-+|  PROJECT Moka7                                                         1.0.2 |
-+|==============================================================================|
-+|  Copyright (C) 2013, 2016 Davide Nardella                                    |
-+|  All rights reserved.                                                        |
-+|==============================================================================|
-+|  SNAP7 is free software: you can redistribute it and/or modify               |
-+|  it under the terms of the Lesser GNU General Public License as published by |
-+|  the Free Software Foundation, either version 3 of the License, or under     |
-+|  EPL Eclipse Public License 1.0.                                             |
-+|                                                                              |
-+|  This means that you have to chose in advance which take before you import   |
-+|  the library into your project.                                              |
-+|                                                                              |
-+|  SNAP7 is distributed in the hope that it will be useful,                    |
-+|  but WITHOUT ANY WARRANTY; without even the implied warranty of              |
-+|  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you    |
-+|  decide to adopt.                                                            |
-+|                                                                              |
-+|=============================================================================*/
-+package Moka7;
-+
-+/**
-+ *
-+ * @author Davide Nardella
-+ */
-+public class S7OrderCode {
-+
-+    public int V1;
-+    public int V2;
-+    public int V3;
-+    protected byte[] Buffer = new byte[1024];
-+
-+    protected void Update(byte[] Src, int Pos, int Size)
-+    {
-+        System.arraycopy(Src, Pos, Buffer, 0, Size);
-+        V1 = (byte) Src[Size-3];
-+        V2 = (byte) Src[Size-2];
-+        V3 = (byte) Src[Size-1];
-+    }
-+
-+    public String Code()
-+    {
-+        return S7.GetStringAt(Buffer, 2, 20);
-+    }
-+}
-diff U3 S7Protection.java S7Protection.java
---- S7Protection.java  Thu Mar 23 15:34:52 2017
-+++ S7Protection.java  Tue Aug 08 18:53:37 2017
-@@ -1,38 +1,43 @@
--/*=============================================================================|
--|  PROJECT Moka7                                                         1.0.2 |
--|==============================================================================|
--|  Copyright (C) 2013, 2016 Davide Nardella                                    |
--|  All rights reserved.                                                        |
--|==============================================================================|
--|  SNAP7 is free software: you can redistribute it and/or modify               |
--|  it under the terms of the Lesser GNU General Public License as published by |
--|  the Free Software Foundation, either version 3 of the License, or under     |
--|  EPL Eclipse Public License 1.0.                                             |
--|                                                                              |
--|  This means that you have to chose in advance which take before you import   |
--|  the library into your project.                                              |
--|                                                                              |
--|  SNAP7 is distributed in the hope that it will be useful,                    |
--|  but WITHOUT ANY WARRANTY; without even the implied warranty of              |
--|  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you    |
--|  decide to adopt.                                                            |
--|                                                                              |
--|=============================================================================*/
--package Moka7;
--
--// See §33.19 of "System Software for S7-300/400 System and Standard Functions"
--public class S7Protection {
--   public int sch_schal;
--   public int sch_par;
--   public int sch_rel;
--   public int bart_sch;
--   public int anl_sch;
--   protected void Update(byte[] Src)
--   {
--       sch_schal = S7.GetWordAt(Src,2);
--       sch_par   = S7.GetWordAt(Src,4);
--       sch_rel   = S7.GetWordAt(Src,6);
--       bart_sch  = S7.GetWordAt(Src,8);
--       anl_sch   = S7.GetWordAt(Src,10);
--   }
--}
-+/*=============================================================================|
-+|  PROJECT Moka7                                                         1.0.2 |
-+|==============================================================================|
-+|  Copyright (C) 2013, 2016 Davide Nardella                                    |
-+|  All rights reserved.                                                        |
-+|==============================================================================|
-+|  SNAP7 is free software: you can redistribute it and/or modify               |
-+|  it under the terms of the Lesser GNU General Public License as published by |
-+|  the Free Software Foundation, either version 3 of the License, or under     |
-+|  EPL Eclipse Public License 1.0.                                             |
-+|                                                                              |
-+|  This means that you have to chose in advance which take before you import   |
-+|  the library into your project.                                              |
-+|                                                                              |
-+|  SNAP7 is distributed in the hope that it will be useful,                    |
-+|  but WITHOUT ANY WARRANTY; without even the implied warranty of              |
-+|  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you    |
-+|  decide to adopt.                                                            |
-+|                                                                              |
-+|=============================================================================*/
-+package Moka7;
-+
-+/**
-+ *
-+ * @author Davide Nardella
-+ */
-+
-+// See §33.19 of "System Software for S7-300/400 System and Standard Functions"
-+public class S7Protection {
-+   public int sch_schal;
-+   public int sch_par;
-+   public int sch_rel;
-+   public int bart_sch;
-+   public int anl_sch;
-+   protected void Update(byte[] Src)
-+   {
-+       sch_schal = S7.GetWordAt(Src,2);
-+       sch_par   = S7.GetWordAt(Src,4);
-+       sch_rel   = S7.GetWordAt(Src,6);
-+       bart_sch  = S7.GetWordAt(Src,8);
-+       anl_sch   = S7.GetWordAt(Src,10);
-+   }
-+}
-diff U3 S7Szl.java S7Szl.java
---- S7Szl.java Thu Mar 23 15:34:52 2017
-+++ S7Szl.java Tue Aug 08 18:53:37 2017
-@@ -1,42 +1,42 @@
--/*=============================================================================|
--|  PROJECT Moka7                                                         1.0.2 |
--|==============================================================================|
--|  Copyright (C) 2013, 2016 Davide Nardella                                    |
--|  All rights reserved.                                                        |
--|==============================================================================|
--|  SNAP7 is free software: you can redistribute it and/or modify               |
--|  it under the terms of the Lesser GNU General Public License as published by |
--|  the Free Software Foundation, either version 3 of the License, or under     |
--|  EPL Eclipse Public License 1.0.                                             |
--|                                                                              |
--|  This means that you have to chose in advance which take before you import   |
--|  the library into your project.                                              |
--|                                                                              |
--|  SNAP7 is distributed in the hope that it will be useful,                    |
--|  but WITHOUT ANY WARRANTY; without even the implied warranty of              |
--|  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you    |
--|  decide to adopt.                                                            |
--|                                                                              |
--|=============================================================================*/
--package Moka7;
--
--/**
-- *
-- * @author Davide
-- */
--public class S7Szl {
--    
--    public int LENTHDR;
--    public int N_DR;
--    public int DataSize;
--    public byte Data[];
--    
--    public S7Szl(int BufferSize)
--    {
--        Data = new byte[BufferSize];
--    }
--    protected void Copy(byte[] Src, int SrcPos, int DestPos, int Size)
--    {
--        System.arraycopy(Src, SrcPos, Data, DestPos, Size);
--    }   
--}
-+/*=============================================================================|
-+|  PROJECT Moka7                                                         1.0.2 |
-+|==============================================================================|
-+|  Copyright (C) 2013, 2016 Davide Nardella                                    |
-+|  All rights reserved.                                                        |
-+|==============================================================================|
-+|  SNAP7 is free software: you can redistribute it and/or modify               |
-+|  it under the terms of the Lesser GNU General Public License as published by |
-+|  the Free Software Foundation, either version 3 of the License, or under     |
-+|  EPL Eclipse Public License 1.0.                                             |
-+|                                                                              |
-+|  This means that you have to chose in advance which take before you import   |
-+|  the library into your project.                                              |
-+|                                                                              |
-+|  SNAP7 is distributed in the hope that it will be useful,                    |
-+|  but WITHOUT ANY WARRANTY; without even the implied warranty of              |
-+|  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE whatever license you    |
-+|  decide to adopt.                                                            |
-+|                                                                              |
-+|=============================================================================*/
-+package Moka7;
-+
-+/**
-+ *
-+ * @author Davide Nardella
-+ */
-+public class S7Szl {
-+
-+    public int LENTHDR;
-+    public int N_DR;
-+    public int DataSize;
-+    public byte Data[];
-+
-+    public S7Szl(int BufferSize)
-+    {
-+        Data = new byte[BufferSize];
-+    }
-+    protected void Copy(byte[] Src, int SrcPos, int DestPos, int Size)
-+    {
-+        System.arraycopy(Src, SrcPos, Data, DestPos, Size);
-+    }
-+}
index d36322c7b777971e0872b90b15826a44b15eb490..9dc84172b4a184094ab976f660b0895e0313b559 100644 (file)
 
   <name>openHAB Add-ons :: Bundles :: PLCLogo Binding</name>
 
+  <dependencies>
+    <dependency>
+      <groupId>org.openhab.binding.plclogo</groupId>
+      <artifactId>Moka7</artifactId>
+      <version>1.0.2-iopatch</version>
+    </dependency>
+  </dependencies>
+
 </project>