From 4fd09e7db13eb74fc0ce9abf68650b8a8769caa3 Mon Sep 17 00:00:00 2001 From: Marcos Date: Mon, 8 Feb 2016 22:09:18 +0000 Subject: [PATCH] VS2015 .Net Core compatible solution added. --- {S7.Net => S7.Net.Common}/Conversion.cs | 436 ++++----- {S7.Net => S7.Net.Common}/Enums.cs | 0 {S7.Net => S7.Net.Common}/Interfaces/IPLC.cs | 58 +- {S7.Net => S7.Net.Common}/Types/Boolean.cs | 52 +- {S7.Net => S7.Net.Common}/Types/Byte.cs | 40 +- {S7.Net => S7.Net.Common}/Types/ByteArray.cs | 78 +- {S7.Net => S7.Net.Common}/Types/Class.cs | 31 +- {S7.Net => S7.Net.Common}/Types/Counter.cs | 122 +-- {S7.Net => S7.Net.Common}/Types/DInt.cs | 142 +-- {S7.Net => S7.Net.Common}/Types/DWord.cs | 118 +-- {S7.Net => S7.Net.Common}/Types/Double.cs | 332 +++---- {S7.Net => S7.Net.Common}/Types/Int.cs | 148 ++-- {S7.Net => S7.Net.Common}/Types/String.cs | 68 +- {S7.Net => S7.Net.Common}/Types/Struct.cs | 451 +++++----- {S7.Net => S7.Net.Common}/Types/Timer.cs | 148 ++-- {S7.Net => S7.Net.Common}/Types/Word.cs | 122 +-- S7.Net.Core/PLC.cs | 885 +++++++++++++++++++ S7.Net.Core/Properties/AssemblyInfo.cs | 29 + S7.Net.Core/Properties/S7.Net.Core.rd.xml | 33 + S7.Net.Core/S7.Net.Core.csproj | 131 +++ S7.Net.Core/SocketClient.cs | 154 ++++ S7.Net.Core/project.json | 16 + S7.Net/S7.Net.csproj | 21 +- S7.sln | 52 +- 24 files changed, 2478 insertions(+), 1189 deletions(-) rename {S7.Net => S7.Net.Common}/Conversion.cs (97%) rename {S7.Net => S7.Net.Common}/Enums.cs (100%) rename {S7.Net => S7.Net.Common}/Interfaces/IPLC.cs (97%) rename {S7.Net => S7.Net.Common}/Types/Boolean.cs (95%) rename {S7.Net => S7.Net.Common}/Types/Byte.cs (95%) rename {S7.Net => S7.Net.Common}/Types/ByteArray.cs (94%) rename {S7.Net => S7.Net.Common}/Types/Class.cs (99%) rename {S7.Net => S7.Net.Common}/Types/Counter.cs (96%) rename {S7.Net => S7.Net.Common}/Types/DInt.cs (96%) rename {S7.Net => S7.Net.Common}/Types/DWord.cs (96%) rename {S7.Net => S7.Net.Common}/Types/Double.cs (96%) rename {S7.Net => S7.Net.Common}/Types/Int.cs (96%) rename {S7.Net => S7.Net.Common}/Types/String.cs (96%) rename {S7.Net => S7.Net.Common}/Types/Struct.cs (97%) rename {S7.Net => S7.Net.Common}/Types/Timer.cs (96%) rename {S7.Net => S7.Net.Common}/Types/Word.cs (96%) create mode 100644 S7.Net.Core/PLC.cs create mode 100644 S7.Net.Core/Properties/AssemblyInfo.cs create mode 100644 S7.Net.Core/Properties/S7.Net.Core.rd.xml create mode 100644 S7.Net.Core/S7.Net.Core.csproj create mode 100644 S7.Net.Core/SocketClient.cs create mode 100644 S7.Net.Core/project.json diff --git a/S7.Net/Conversion.cs b/S7.Net.Common/Conversion.cs similarity index 97% rename from S7.Net/Conversion.cs rename to S7.Net.Common/Conversion.cs index 3f58d1e..0b8b00d 100644 --- a/S7.Net/Conversion.cs +++ b/S7.Net.Common/Conversion.cs @@ -1,218 +1,218 @@ -using System; -using System.Globalization; - -namespace S7.Net -{ - public static class Conversion - { - public static int BinStringToInt32(this string txt) - { - int cnt = 0; - int ret = 0; - - for (cnt = txt.Length - 1; cnt >= 0; cnt += -1) - { - if (int.Parse(txt.Substring(cnt, 1)) == 1) - { - ret += (int)(Math.Pow(2, (txt.Length - 1 - cnt))); - } - } - return ret; - } - - public static byte? BinStringToByte(this string txt) - { - int cnt = 0; - int ret = 0; - - if (txt.Length == 8) - { - for (cnt = 7; cnt >= 0; cnt += -1) - { - if (int.Parse(txt.Substring(cnt, 1)) == 1) - { - ret += (int)(Math.Pow(2, (txt.Length - 1 - cnt))); - } - } - return (byte)ret; - } - return null; - } - - public static string ValToBinString(this object value) - { - int cnt = 0; - int cnt2 = 0; - int x = 0; - string txt = ""; - long longValue = 0; - - try - { - if (value.GetType().Name.IndexOf("[]") < 0) - { - // ist nur ein Wert - switch (value.GetType().Name) - { - case "Byte": - x = 7; - longValue = (long)((byte)value); - break; - case "Int16": - x = 15; - longValue = (long)((Int16)value); - break; - case "Int32": - x = 31; - longValue = (long)((Int32)value); - break; - case "Int64": - x = 63; - longValue = (long)((Int64)value); - break; - default: - throw new Exception(); - } - - for (cnt = x; cnt >= 0; cnt += -1) - { - if (((Int64)longValue & (Int64)Math.Pow(2, cnt)) > 0) - txt += "1"; - else - txt += "0"; - } - } - else - { - // ist ein Array - switch (value.GetType().Name) - { - case "Byte[]": - x = 7; - byte[] ByteArr = (byte[])value; - for (cnt2 = 0; cnt2 <= ByteArr.Length - 1; cnt2++) - { - for (cnt = x; cnt >= 0; cnt += -1) - if ((ByteArr[cnt2] & (byte)Math.Pow(2, cnt)) > 0) txt += "1"; else txt += "0"; - } - break; - case "Int16[]": - x = 15; - Int16[] Int16Arr = (Int16[])value; - for (cnt2 = 0; cnt2 <= Int16Arr.Length - 1; cnt2++) - { - for (cnt = x; cnt >= 0; cnt += -1) - if ((Int16Arr[cnt2] & (byte)Math.Pow(2, cnt)) > 0) txt += "1"; else txt += "0"; - } - break; - case "Int32[]": - x = 31; - Int32[] Int32Arr = (Int32[])value; - for (cnt2 = 0; cnt2 <= Int32Arr.Length - 1; cnt2++) - { - for (cnt = x; cnt >= 0; cnt += -1) - if ((Int32Arr[cnt2] & (byte)Math.Pow(2, cnt)) > 0) txt += "1"; else txt += "0"; - } - break; - case "Int64[]": - x = 63; - byte[] Int64Arr = (byte[])value; - for (cnt2 = 0; cnt2 <= Int64Arr.Length - 1; cnt2++) - { - for (cnt = x; cnt >= 0; cnt += -1) - if ((Int64Arr[cnt2] & (byte)Math.Pow(2, cnt)) > 0) txt += "1"; else txt += "0"; - } - break; - default: - throw new Exception(); - } - } - return txt; - } - catch - { - return ""; - } - } - - public static bool SelectBit(this byte data, int bitPosition) - { - int mask = 1 << bitPosition; - int result = data & mask; - - return (result != 0); - } - - /// - /// Converts from ushort value to short value; it's used to retrieve negative values from words - /// - /// - /// - public static short ConvertToShort(this ushort input) - { - short output; - output = short.Parse(input.ToString("X"), NumberStyles.HexNumber); - return output; - } - - /// - /// Converts from short value to ushort value; it's used to pass negative values to DWs - /// - /// - /// - public static ushort ConvertToUshort(this short input) - { - ushort output; - output = ushort.Parse(input.ToString("X"), NumberStyles.HexNumber); - return output; - } - - /// - /// Converts from UInt32 value to Int32 value; it's used to retrieve negative values from DBDs - /// - /// - /// - public static Int32 ConvertToInt(this uint input) - { - int output; - output = int.Parse(input.ToString("X"), NumberStyles.HexNumber); - return output; - } - - /// - /// Converts from Int32 value to UInt32 value; it's used to pass negative values to DBDs - /// - /// - /// - public static UInt32 ConvertToUInt(this int input) - { - uint output; - output = uint.Parse(input.ToString("X"), NumberStyles.HexNumber); - return output; - } - - /// - /// Converts from double to DWord (DBD) - /// - /// - /// - public static UInt32 ConvertToUInt(this double input) - { - uint output; - output = S7.Net.Types.DWord.FromByteArray(S7.Net.Types.Double.ToByteArray(input)); - return output; - } - - /// - /// Converts from DWord (DBD) to double - /// - /// - /// - public static double ConvertToDouble(this uint input) - { - double output; - output = S7.Net.Types.Double.FromByteArray(S7.Net.Types.DWord.ToByteArray(input)); - return output; - } - } -} +using System; +using System.Globalization; + +namespace S7.Net +{ + public static class Conversion + { + public static int BinStringToInt32(this string txt) + { + int cnt = 0; + int ret = 0; + + for (cnt = txt.Length - 1; cnt >= 0; cnt += -1) + { + if (int.Parse(txt.Substring(cnt, 1)) == 1) + { + ret += (int)(Math.Pow(2, (txt.Length - 1 - cnt))); + } + } + return ret; + } + + public static byte? BinStringToByte(this string txt) + { + int cnt = 0; + int ret = 0; + + if (txt.Length == 8) + { + for (cnt = 7; cnt >= 0; cnt += -1) + { + if (int.Parse(txt.Substring(cnt, 1)) == 1) + { + ret += (int)(Math.Pow(2, (txt.Length - 1 - cnt))); + } + } + return (byte)ret; + } + return null; + } + + public static string ValToBinString(this object value) + { + int cnt = 0; + int cnt2 = 0; + int x = 0; + string txt = ""; + long longValue = 0; + + try + { + if (value.GetType().Name.IndexOf("[]") < 0) + { + // ist nur ein Wert + switch (value.GetType().Name) + { + case "Byte": + x = 7; + longValue = (long)((byte)value); + break; + case "Int16": + x = 15; + longValue = (long)((Int16)value); + break; + case "Int32": + x = 31; + longValue = (long)((Int32)value); + break; + case "Int64": + x = 63; + longValue = (long)((Int64)value); + break; + default: + throw new Exception(); + } + + for (cnt = x; cnt >= 0; cnt += -1) + { + if (((Int64)longValue & (Int64)Math.Pow(2, cnt)) > 0) + txt += "1"; + else + txt += "0"; + } + } + else + { + // ist ein Array + switch (value.GetType().Name) + { + case "Byte[]": + x = 7; + byte[] ByteArr = (byte[])value; + for (cnt2 = 0; cnt2 <= ByteArr.Length - 1; cnt2++) + { + for (cnt = x; cnt >= 0; cnt += -1) + if ((ByteArr[cnt2] & (byte)Math.Pow(2, cnt)) > 0) txt += "1"; else txt += "0"; + } + break; + case "Int16[]": + x = 15; + Int16[] Int16Arr = (Int16[])value; + for (cnt2 = 0; cnt2 <= Int16Arr.Length - 1; cnt2++) + { + for (cnt = x; cnt >= 0; cnt += -1) + if ((Int16Arr[cnt2] & (byte)Math.Pow(2, cnt)) > 0) txt += "1"; else txt += "0"; + } + break; + case "Int32[]": + x = 31; + Int32[] Int32Arr = (Int32[])value; + for (cnt2 = 0; cnt2 <= Int32Arr.Length - 1; cnt2++) + { + for (cnt = x; cnt >= 0; cnt += -1) + if ((Int32Arr[cnt2] & (byte)Math.Pow(2, cnt)) > 0) txt += "1"; else txt += "0"; + } + break; + case "Int64[]": + x = 63; + byte[] Int64Arr = (byte[])value; + for (cnt2 = 0; cnt2 <= Int64Arr.Length - 1; cnt2++) + { + for (cnt = x; cnt >= 0; cnt += -1) + if ((Int64Arr[cnt2] & (byte)Math.Pow(2, cnt)) > 0) txt += "1"; else txt += "0"; + } + break; + default: + throw new Exception(); + } + } + return txt; + } + catch + { + return ""; + } + } + + public static bool SelectBit(this byte data, int bitPosition) + { + int mask = 1 << bitPosition; + int result = data & mask; + + return (result != 0); + } + + /// + /// Converts from ushort value to short value; it's used to retrieve negative values from words + /// + /// + /// + public static short ConvertToShort(this ushort input) + { + short output; + output = short.Parse(input.ToString("X"), NumberStyles.HexNumber); + return output; + } + + /// + /// Converts from short value to ushort value; it's used to pass negative values to DWs + /// + /// + /// + public static ushort ConvertToUshort(this short input) + { + ushort output; + output = ushort.Parse(input.ToString("X"), NumberStyles.HexNumber); + return output; + } + + /// + /// Converts from UInt32 value to Int32 value; it's used to retrieve negative values from DBDs + /// + /// + /// + public static Int32 ConvertToInt(this uint input) + { + int output; + output = int.Parse(input.ToString("X"), NumberStyles.HexNumber); + return output; + } + + /// + /// Converts from Int32 value to UInt32 value; it's used to pass negative values to DBDs + /// + /// + /// + public static UInt32 ConvertToUInt(this int input) + { + uint output; + output = uint.Parse(input.ToString("X"), NumberStyles.HexNumber); + return output; + } + + /// + /// Converts from double to DWord (DBD) + /// + /// + /// + public static UInt32 ConvertToUInt(this double input) + { + uint output; + output = S7.Net.Types.DWord.FromByteArray(S7.Net.Types.Double.ToByteArray(input)); + return output; + } + + /// + /// Converts from DWord (DBD) to double + /// + /// + /// + public static double ConvertToDouble(this uint input) + { + double output; + output = S7.Net.Types.Double.FromByteArray(S7.Net.Types.DWord.ToByteArray(input)); + return output; + } + } +} diff --git a/S7.Net/Enums.cs b/S7.Net.Common/Enums.cs similarity index 100% rename from S7.Net/Enums.cs rename to S7.Net.Common/Enums.cs diff --git a/S7.Net/Interfaces/IPLC.cs b/S7.Net.Common/Interfaces/IPLC.cs similarity index 97% rename from S7.Net/Interfaces/IPLC.cs rename to S7.Net.Common/Interfaces/IPLC.cs index 35c876f..20efc32 100644 --- a/S7.Net/Interfaces/IPLC.cs +++ b/S7.Net.Common/Interfaces/IPLC.cs @@ -1,30 +1,30 @@ -using System; - -namespace S7.Net.Interfaces -{ - public interface IPlc : IDisposable - { - string IP { get; set; } - bool IsConnected { get; } - CpuType CPU { get; set; } - Int16 Rack { get; set; } - Int16 Slot { get; set; } - string Name { get; set; } - object Tag { get; set; } - bool IsAvailable { get; } - ErrorCode Open(); - void Close(); - byte[] ReadBytes(DataType dataType, int DB, int startByteAdr, int count); - object Read(DataType dataType, int db, int startByteAdr, VarType varType, int varCount); - object Read(string variable); - object ReadStruct(Type structType, int db); - void ReadClass(object sourceClass, int db); - ErrorCode WriteBytes(DataType dataType, int db, int startByteAdr, byte[] value); - object Write(DataType dataType, int db, int startByteAdr, object value); - object Write(string variable, object value); - ErrorCode WriteStruct(object structValue, int db); - ErrorCode WriteClass(object classValue, int db); - string LastErrorString { get; } - ErrorCode LastErrorCode { get; } - } +using System; + +namespace S7.Net.Interfaces +{ + public interface IPlc : IDisposable + { + string IP { get; set; } + bool IsConnected { get; } + CpuType CPU { get; set; } + Int16 Rack { get; set; } + Int16 Slot { get; set; } + string Name { get; set; } + object Tag { get; set; } + bool IsAvailable { get; } + ErrorCode Open(); + void Close(); + byte[] ReadBytes(DataType dataType, int DB, int startByteAdr, int count); + object Read(DataType dataType, int db, int startByteAdr, VarType varType, int varCount); + object Read(string variable); + object ReadStruct(Type structType, int db); + void ReadClass(object sourceClass, int db); + ErrorCode WriteBytes(DataType dataType, int db, int startByteAdr, byte[] value); + object Write(DataType dataType, int db, int startByteAdr, object value); + object Write(string variable, object value); + ErrorCode WriteStruct(object structValue, int db); + ErrorCode WriteClass(object classValue, int db); + string LastErrorString { get; } + ErrorCode LastErrorCode { get; } + } } \ No newline at end of file diff --git a/S7.Net/Types/Boolean.cs b/S7.Net.Common/Types/Boolean.cs similarity index 95% rename from S7.Net/Types/Boolean.cs rename to S7.Net.Common/Types/Boolean.cs index 32c96c3..bcbdefd 100644 --- a/S7.Net/Types/Boolean.cs +++ b/S7.Net.Common/Types/Boolean.cs @@ -1,26 +1,26 @@ -using System; - -namespace S7.Net.Types -{ - public static class Boolean - { - public static bool GetValue(byte value, int bit) - { - if ((value & (int)Math.Pow(2, bit)) != 0) - return true; - else - return false; - } - - public static byte SetBit(byte value, int bit) - { - return (byte)(value | (byte)Math.Pow(2, bit)); - } - - public static byte ClearBit(byte value, int bit) - { - return (byte)(value & (byte)(~(byte)Math.Pow(2, bit))); - } - - } -} +using System; + +namespace S7.Net.Types +{ + public static class Boolean + { + public static bool GetValue(byte value, int bit) + { + if ((value & (int)Math.Pow(2, bit)) != 0) + return true; + else + return false; + } + + public static byte SetBit(byte value, int bit) + { + return (byte)(value | (byte)Math.Pow(2, bit)); + } + + public static byte ClearBit(byte value, int bit) + { + return (byte)(value & (byte)(~(byte)Math.Pow(2, bit))); + } + + } +} diff --git a/S7.Net/Types/Byte.cs b/S7.Net.Common/Types/Byte.cs similarity index 95% rename from S7.Net/Types/Byte.cs rename to S7.Net.Common/Types/Byte.cs index 62a0d61..5cdd445 100644 --- a/S7.Net/Types/Byte.cs +++ b/S7.Net.Common/Types/Byte.cs @@ -1,20 +1,20 @@ -namespace S7.Net.Types -{ - public static class Byte - { - // publics - #region ToByteArray - public static byte[] ToByteArray(byte value) - { - byte[] bytes = new byte[] { value}; - return bytes; - } - #endregion - #region FromByteArray - public static byte FromByteArray(byte[] bytes) - { - return bytes[0]; - } - #endregion - } -} +namespace S7.Net.Types +{ + public static class Byte + { + // publics + #region ToByteArray + public static byte[] ToByteArray(byte value) + { + byte[] bytes = new byte[] { value}; + return bytes; + } + #endregion + #region FromByteArray + public static byte FromByteArray(byte[] bytes) + { + return bytes[0]; + } + #endregion + } +} diff --git a/S7.Net/Types/ByteArray.cs b/S7.Net.Common/Types/ByteArray.cs similarity index 94% rename from S7.Net/Types/ByteArray.cs rename to S7.Net.Common/Types/ByteArray.cs index 63c2701..d364a98 100644 --- a/S7.Net/Types/ByteArray.cs +++ b/S7.Net.Common/Types/ByteArray.cs @@ -1,39 +1,39 @@ -using System.Collections.Generic; - -namespace S7.Net.Types -{ - class ByteArray - { - List list = new List(); - - public byte[] array - { - get { return list.ToArray(); } - } - - public ByteArray() - { - list = new List(); - } - - public ByteArray(int size) - { - list = new List(size); - } - - public void Clear() - { - list = new List(); - } - - public void Add(byte item) - { - list.Add(item); - } - - public void Add(byte[] items) - { - list.AddRange(items); - } - } -} +using System.Collections.Generic; + +namespace S7.Net.Types +{ + class ByteArray + { + List list = new List(); + + public byte[] array + { + get { return list.ToArray(); } + } + + public ByteArray() + { + list = new List(); + } + + public ByteArray(int size) + { + list = new List(size); + } + + public void Clear() + { + list = new List(); + } + + public void Add(byte item) + { + list.Add(item); + } + + public void Add(byte[] items) + { + list.AddRange(items); + } + } +} diff --git a/S7.Net/Types/Class.cs b/S7.Net.Common/Types/Class.cs similarity index 99% rename from S7.Net/Types/Class.cs rename to S7.Net.Common/Types/Class.cs index 9489afb..e64a7cf 100644 --- a/S7.Net/Types/Class.cs +++ b/S7.Net.Common/Types/Class.cs @@ -1,4 +1,5 @@ using System; +using System.Reflection; namespace S7.Net.Types { @@ -6,7 +7,7 @@ namespace S7.Net.Types { /// /// Gets the size of the struct in bytes. - /// + /// /// the type of the class /// the number of bytes public static int GetClassSize(Type classType) @@ -22,7 +23,7 @@ namespace S7.Net.Types /// /// Given a property name, it returns the number of bytes that is composed - /// + /// /// type of the property /// static double CalculateBytes(string propertyType) @@ -94,12 +95,12 @@ namespace S7.Net.Types bitPos = (int)((numBytes - (double)bytePos) / 0.125); if ((bytes[bytePos] & (int)Math.Pow(2, bitPos)) != 0) property.SetValue(sourceClass, true, null); - else + else property.SetValue(sourceClass, false, null); numBytes += 0.125; break; case "Byte": - numBytes = Math.Ceiling(numBytes); + numBytes = Math.Ceiling(numBytes); property.SetValue(sourceClass, (byte)(bytes[(int)numBytes]), null); numBytes++; break; @@ -108,7 +109,7 @@ namespace S7.Net.Types if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0) numBytes++; // hier auswerten - ushort source = Word.FromBytes(bytes[(int)numBytes + 1], bytes[(int)numBytes]); + ushort source = Word.FromBytes(bytes[(int)numBytes + 1], bytes[(int)numBytes]); property.SetValue(sourceClass, source.ConvertToShort(), null); numBytes += 2; break; @@ -116,7 +117,7 @@ namespace S7.Net.Types numBytes = Math.Ceiling(numBytes); if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0) numBytes++; - // hier auswerten + // hier auswerten property.SetValue(sourceClass, Word.FromBytes(bytes[(int)numBytes + 1], bytes[(int)numBytes]), null); numBytes += 2; break; @@ -128,7 +129,7 @@ namespace S7.Net.Types uint sourceUInt = DWord.FromBytes(bytes[(int)numBytes + 3], bytes[(int)numBytes + 2], bytes[(int)numBytes + 1], - bytes[(int)numBytes + 0]); + bytes[(int)numBytes + 0]); property.SetValue(sourceClass, sourceUInt.ConvertToInt(), null); numBytes += 4; break; @@ -139,7 +140,7 @@ namespace S7.Net.Types // hier auswerten property.SetValue(sourceClass, DWord.FromBytes(bytes[(int)numBytes], bytes[(int)numBytes + 1], - bytes[(int)numBytes + 2], + bytes[(int)numBytes + 2], bytes[(int)numBytes + 3]), null); numBytes += 4; break; @@ -183,7 +184,7 @@ namespace S7.Net.Types case "Boolean": // get the value bytePos = (int)Math.Floor(numBytes); - bitPos = (int)((numBytes - (double)bytePos) / 0.125); + bitPos = (int)((numBytes - (double)bytePos) / 0.125); if ((bool)property.GetValue(sourceClass, null)) bytes[bytePos] |= (byte)Math.Pow(2, bitPos); // is true else @@ -192,23 +193,23 @@ namespace S7.Net.Types break; case "Byte": numBytes = (int)Math.Ceiling(numBytes); - bytePos = (int)numBytes; + bytePos = (int)numBytes; bytes[bytePos] = (byte)property.GetValue(sourceClass, null); numBytes++; break; - case "Int16": + case "Int16": bytes2 = Int.ToByteArray((Int16)property.GetValue(sourceClass, null)); break; - case "UInt16": + case "UInt16": bytes2 = Word.ToByteArray((UInt16)property.GetValue(sourceClass, null)); break; - case "Int32": + case "Int32": bytes2 = DInt.ToByteArray((Int32)property.GetValue(sourceClass, null)); break; - case "UInt32": + case "UInt32": bytes2 = DWord.ToByteArray((UInt32)property.GetValue(sourceClass, null)); break; - case "Double": + case "Double": bytes2 = Double.ToByteArray((double)property.GetValue(sourceClass, null)); break; } diff --git a/S7.Net/Types/Counter.cs b/S7.Net.Common/Types/Counter.cs similarity index 96% rename from S7.Net/Types/Counter.cs rename to S7.Net.Common/Types/Counter.cs index b5174d6..1602693 100644 --- a/S7.Net/Types/Counter.cs +++ b/S7.Net.Common/Types/Counter.cs @@ -1,61 +1,61 @@ -using System; - -namespace S7.Net.Types -{ - public static class Counter - { - // publics - #region FromByteArray - public static UInt16 FromByteArray(byte[] bytes) - { - // bytes[0] -> HighByte - // bytes[1] -> LowByte - return FromBytes(bytes[1], bytes[0]); - } - #endregion - #region FromBytes - public static UInt16 FromBytes(byte LoVal, byte HiVal) - { - return (UInt16)(HiVal * 256 + LoVal); - } - #endregion - - #region ToByteArray - public static byte[] ToByteArray(UInt16 value) - { - byte[] bytes = new byte[2]; - int x = 2; - long valLong = (long)((UInt16)value); - for (int cnt = 0; cnt < x; cnt++) - { - Int64 x1 = (Int64)Math.Pow(256, (cnt)); - - Int64 x3 = (Int64)(valLong / x1); - bytes[x - cnt - 1] = (byte)(x3 & 255); - valLong -= bytes[x - cnt - 1] * x1; - } - return bytes; - } - - public static byte[] ToByteArray(UInt16[] value) - { - ByteArray arr = new ByteArray(); - foreach (UInt16 val in value) - arr.Add(ToByteArray(val)); - return arr.array; - } - #endregion - #region ToArray - public static UInt16[] ToArray(byte[] bytes) - { - UInt16[] values = new UInt16[bytes.Length / 2]; - - int counter = 0; - for (int cnt = 0; cnt < bytes.Length / 2; cnt++) - values[cnt] = FromByteArray(new byte[] { bytes[counter++], bytes[counter++] }); - - return values; - } - #endregion - } -} +using System; + +namespace S7.Net.Types +{ + public static class Counter + { + // publics + #region FromByteArray + public static UInt16 FromByteArray(byte[] bytes) + { + // bytes[0] -> HighByte + // bytes[1] -> LowByte + return FromBytes(bytes[1], bytes[0]); + } + #endregion + #region FromBytes + public static UInt16 FromBytes(byte LoVal, byte HiVal) + { + return (UInt16)(HiVal * 256 + LoVal); + } + #endregion + + #region ToByteArray + public static byte[] ToByteArray(UInt16 value) + { + byte[] bytes = new byte[2]; + int x = 2; + long valLong = (long)((UInt16)value); + for (int cnt = 0; cnt < x; cnt++) + { + Int64 x1 = (Int64)Math.Pow(256, (cnt)); + + Int64 x3 = (Int64)(valLong / x1); + bytes[x - cnt - 1] = (byte)(x3 & 255); + valLong -= bytes[x - cnt - 1] * x1; + } + return bytes; + } + + public static byte[] ToByteArray(UInt16[] value) + { + ByteArray arr = new ByteArray(); + foreach (UInt16 val in value) + arr.Add(ToByteArray(val)); + return arr.array; + } + #endregion + #region ToArray + public static UInt16[] ToArray(byte[] bytes) + { + UInt16[] values = new UInt16[bytes.Length / 2]; + + int counter = 0; + for (int cnt = 0; cnt < bytes.Length / 2; cnt++) + values[cnt] = FromByteArray(new byte[] { bytes[counter++], bytes[counter++] }); + + return values; + } + #endregion + } +} diff --git a/S7.Net/Types/DInt.cs b/S7.Net.Common/Types/DInt.cs similarity index 96% rename from S7.Net/Types/DInt.cs rename to S7.Net.Common/Types/DInt.cs index 8f92575..c610efc 100644 --- a/S7.Net/Types/DInt.cs +++ b/S7.Net.Common/Types/DInt.cs @@ -1,71 +1,71 @@ -using System; - -namespace S7.Net.Types -{ - public static class DInt - { - // publics - #region FromByteArray - public static Int32 FromByteArray(byte[] bytes) - { - return FromBytes(bytes[3], bytes[2], bytes[1], bytes[0]); - } - #endregion - #region FromBytes - public static Int32 FromBytes(byte v1, byte v2, byte v3, byte v4) - { - return (Int32)(v1 + v2 * Math.Pow(2, 8) + v3 * Math.Pow(2, 16) + v4 * Math.Pow(2, 24)); - } - #endregion - - #region ToByteArray - public static byte[] ToByteArray(Int32 value) - { - byte[] bytes = new byte[4]; - int x = 4; - long valLong = (long)((Int32)value); - for (int cnt = 0; cnt < x; cnt++) - { - Int64 x1 = (Int64)Math.Pow(256, (cnt)); - - Int64 x3 = (Int64)(valLong / x1); - bytes[x - cnt - 1] = (byte)(x3 & 255); - valLong -= bytes[x - cnt - 1] * x1; - } - return bytes; - } - - public static byte[] ToByteArray(Int32[] value) - { - ByteArray arr = new ByteArray(); - foreach (Int32 val in value) - arr.Add(ToByteArray(val)); - return arr.array; - } - #endregion - #region ToArray - public static Int32[] ToArray(byte[] bytes) - { - Int32[] values = new Int32[bytes.Length / 4]; - - int counter = 0; - for (int cnt = 0; cnt < bytes.Length / 4; cnt++) - values[cnt] = FromByteArray(new byte[] { bytes[counter++], bytes[counter++], bytes[counter++], bytes[counter++] }); - - return values; - } - #endregion - - // conversion - public static Int32 CDWord(Int64 value) - { - if (value > Int32.MaxValue) - { - value -= (long)Int32.MaxValue + 1; - value = (long)Int32.MaxValue + 1 - value; - value *= -1; - } - return (int)value; - } - } -} +using System; + +namespace S7.Net.Types +{ + public static class DInt + { + // publics + #region FromByteArray + public static Int32 FromByteArray(byte[] bytes) + { + return FromBytes(bytes[3], bytes[2], bytes[1], bytes[0]); + } + #endregion + #region FromBytes + public static Int32 FromBytes(byte v1, byte v2, byte v3, byte v4) + { + return (Int32)(v1 + v2 * Math.Pow(2, 8) + v3 * Math.Pow(2, 16) + v4 * Math.Pow(2, 24)); + } + #endregion + + #region ToByteArray + public static byte[] ToByteArray(Int32 value) + { + byte[] bytes = new byte[4]; + int x = 4; + long valLong = (long)((Int32)value); + for (int cnt = 0; cnt < x; cnt++) + { + Int64 x1 = (Int64)Math.Pow(256, (cnt)); + + Int64 x3 = (Int64)(valLong / x1); + bytes[x - cnt - 1] = (byte)(x3 & 255); + valLong -= bytes[x - cnt - 1] * x1; + } + return bytes; + } + + public static byte[] ToByteArray(Int32[] value) + { + ByteArray arr = new ByteArray(); + foreach (Int32 val in value) + arr.Add(ToByteArray(val)); + return arr.array; + } + #endregion + #region ToArray + public static Int32[] ToArray(byte[] bytes) + { + Int32[] values = new Int32[bytes.Length / 4]; + + int counter = 0; + for (int cnt = 0; cnt < bytes.Length / 4; cnt++) + values[cnt] = FromByteArray(new byte[] { bytes[counter++], bytes[counter++], bytes[counter++], bytes[counter++] }); + + return values; + } + #endregion + + // conversion + public static Int32 CDWord(Int64 value) + { + if (value > Int32.MaxValue) + { + value -= (long)Int32.MaxValue + 1; + value = (long)Int32.MaxValue + 1 - value; + value *= -1; + } + return (int)value; + } + } +} diff --git a/S7.Net/Types/DWord.cs b/S7.Net.Common/Types/DWord.cs similarity index 96% rename from S7.Net/Types/DWord.cs rename to S7.Net.Common/Types/DWord.cs index bded772..20a2e67 100644 --- a/S7.Net/Types/DWord.cs +++ b/S7.Net.Common/Types/DWord.cs @@ -1,59 +1,59 @@ -using System; - -namespace S7.Net.Types -{ - public static class DWord - { - // publics - #region FromByteArray - public static UInt32 FromByteArray(byte[] bytes) - { - return FromBytes(bytes[3], bytes[2], bytes[1], bytes[0]); - } - #endregion - #region FromBytes - public static UInt32 FromBytes(byte v1, byte v2, byte v3, byte v4) - { - return (UInt32)(v1 + v2 * Math.Pow(2, 8) + v3 * Math.Pow(2, 16) + v4 * Math.Pow(2, 24)); - } - #endregion - - #region ToByteArray - public static byte[] ToByteArray(UInt32 value) - { - byte[] bytes = new byte[4]; - int x = 4; - long valLong = (long)((UInt32)value); - for (int cnt = 0; cnt < x; cnt++) - { - Int64 x1 = (Int64)Math.Pow(256, (cnt)); - - Int64 x3 = (Int64)(valLong / x1); - bytes[x - cnt - 1] = (byte)(x3 & 255); - valLong -= bytes[x - cnt - 1] * x1; - } - return bytes; - } - - public static byte[] ToByteArray(UInt32[] value) - { - ByteArray arr = new ByteArray(); - foreach (UInt32 val in value) - arr.Add(ToByteArray(val)); - return arr.array; - } - #endregion - #region ToArray - public static UInt32[] ToArray(byte[] bytes) - { - UInt32[] values = new UInt32[bytes.Length / 4]; - - int counter = 0; - for (int cnt = 0; cnt < bytes.Length / 4; cnt++) - values[cnt] = FromByteArray(new byte[] { bytes[counter++], bytes[counter++], bytes[counter++], bytes[counter++] }); - - return values; - } - #endregion - } -} +using System; + +namespace S7.Net.Types +{ + public static class DWord + { + // publics + #region FromByteArray + public static UInt32 FromByteArray(byte[] bytes) + { + return FromBytes(bytes[3], bytes[2], bytes[1], bytes[0]); + } + #endregion + #region FromBytes + public static UInt32 FromBytes(byte v1, byte v2, byte v3, byte v4) + { + return (UInt32)(v1 + v2 * Math.Pow(2, 8) + v3 * Math.Pow(2, 16) + v4 * Math.Pow(2, 24)); + } + #endregion + + #region ToByteArray + public static byte[] ToByteArray(UInt32 value) + { + byte[] bytes = new byte[4]; + int x = 4; + long valLong = (long)((UInt32)value); + for (int cnt = 0; cnt < x; cnt++) + { + Int64 x1 = (Int64)Math.Pow(256, (cnt)); + + Int64 x3 = (Int64)(valLong / x1); + bytes[x - cnt - 1] = (byte)(x3 & 255); + valLong -= bytes[x - cnt - 1] * x1; + } + return bytes; + } + + public static byte[] ToByteArray(UInt32[] value) + { + ByteArray arr = new ByteArray(); + foreach (UInt32 val in value) + arr.Add(ToByteArray(val)); + return arr.array; + } + #endregion + #region ToArray + public static UInt32[] ToArray(byte[] bytes) + { + UInt32[] values = new UInt32[bytes.Length / 4]; + + int counter = 0; + for (int cnt = 0; cnt < bytes.Length / 4; cnt++) + values[cnt] = FromByteArray(new byte[] { bytes[counter++], bytes[counter++], bytes[counter++], bytes[counter++] }); + + return values; + } + #endregion + } +} diff --git a/S7.Net/Types/Double.cs b/S7.Net.Common/Types/Double.cs similarity index 96% rename from S7.Net/Types/Double.cs rename to S7.Net.Common/Types/Double.cs index 1e18fc4..2223edd 100644 --- a/S7.Net/Types/Double.cs +++ b/S7.Net.Common/Types/Double.cs @@ -1,166 +1,166 @@ -using System; - -namespace S7.Net.Types -{ - public static class Double - { - // publics - #region FromByteArray - public static double FromByteArray(byte[] bytes) - { - byte v1 = bytes[0]; - byte v2 = bytes[1]; - byte v3 = bytes[2]; - byte v4 = bytes[3]; - - if ((int)v1 + v2 + v3 + v4 == 0) - { - return 0.0; - } - else - { - // nun String bilden - string txt = ValToBinString(v1) + ValToBinString(v2) + ValToBinString(v3) + ValToBinString(v4); - // erstmal das Vorzeichen - int vz = int.Parse(txt.Substring(0, 1)); - int exd = Conversion.BinStringToInt32(txt.Substring(1, 8)); - string ma = txt.Substring(9, 23); - double mantisse = 1; - double faktor = 1.0; - - //das ist die Anzahl der restlichen bit's - for (int cnt = 0; cnt <= 22; cnt++) - { - faktor = faktor / 2.0; - //entspricht 2^-y - if (ma.Substring(cnt, 1) == "1") - { - mantisse = mantisse + faktor; - } - } - return Math.Pow((-1), vz) * Math.Pow(2, (exd - 127)) * mantisse; - } - } - #endregion - #region FromDWord - public static double FromDWord(Int32 value) - { - byte[] b = DInt.ToByteArray(value); - double d = FromByteArray(b); - return d; - } - - public static double FromDWord(UInt32 value) - { - byte[] b = DWord.ToByteArray(value); - double d = FromByteArray(b); - return d; - } - #endregion - - #region ToByteArray - public static byte[] ToByteArray(double value) - { - double wert = (double)value; - string binString = ""; - byte[] bytes = new byte[4]; - if (wert != 0f) - { - if (wert < 0) - { - wert *= -1; - binString = "1"; - } - else - { - binString = "0"; - } - int exponent = (int)Math.Floor((double)Math.Log(wert) / Math.Log(2.0)); - wert = wert / (Math.Pow(2, exponent)) - 1; - - binString += ValToBinString((byte)(exponent + 127)); - for (int cnt = 1; cnt <= 23; cnt++) - { - if (!(wert - System.Math.Pow(2, -cnt) < 0)) - { - wert = wert - System.Math.Pow(2, -cnt); - binString += "1"; - } - else - binString += "0"; - } - bytes[0] = (byte)BinStringToByte(binString.Substring(0, 8)); - bytes[1] = (byte)BinStringToByte(binString.Substring(8, 8)); - bytes[2] = (byte)BinStringToByte(binString.Substring(16, 8)); - bytes[3] = (byte)BinStringToByte(binString.Substring(24, 8)); - - } - else - { - bytes[0] = 0; - bytes[1] = 0; - bytes[2] = 0; - bytes[3] = 0; - } - return bytes; - } - - public static byte[] ToByteArray(double[] value) - { - ByteArray arr = new ByteArray(); - foreach (double val in value) - arr.Add(ToByteArray(val)); - return arr.array; - } - #endregion - #region ToArray - public static double[] ToArray(byte[] bytes) - { - double[] values = new double[bytes.Length / 4]; - - int counter = 0; - for (int cnt = 0; cnt < bytes.Length / 4; cnt++) - values[cnt] = FromByteArray(new byte[] { bytes[counter++], bytes[counter++], bytes[counter++], bytes[counter++] }); - - return values; - } - #endregion - - // privates - #region ValToBinString - private static string ValToBinString(byte value) - { - string txt = ""; - - for (int cnt = 7; cnt >= 0; cnt += -1) - { - if ((value & (byte)Math.Pow(2, cnt)) > 0) - txt += "1"; - else - txt += "0"; - } - return txt; - } - #endregion - #region BinStringToByte - private static byte? BinStringToByte(string txt) - { - int cnt = 0; - int ret = 0; - - if (txt.Length == 8) - { - for (cnt = 7; cnt >= 0; cnt += -1) - { - if (int.Parse(txt.Substring(cnt, 1)) == 1) - { - ret += (int)(Math.Pow(2, (txt.Length - 1 - cnt))); - } - } - return (byte)ret; - } - return null; - } - #endregion - } -} +using System; + +namespace S7.Net.Types +{ + public static class Double + { + // publics + #region FromByteArray + public static double FromByteArray(byte[] bytes) + { + byte v1 = bytes[0]; + byte v2 = bytes[1]; + byte v3 = bytes[2]; + byte v4 = bytes[3]; + + if ((int)v1 + v2 + v3 + v4 == 0) + { + return 0.0; + } + else + { + // nun String bilden + string txt = ValToBinString(v1) + ValToBinString(v2) + ValToBinString(v3) + ValToBinString(v4); + // erstmal das Vorzeichen + int vz = int.Parse(txt.Substring(0, 1)); + int exd = Conversion.BinStringToInt32(txt.Substring(1, 8)); + string ma = txt.Substring(9, 23); + double mantisse = 1; + double faktor = 1.0; + + //das ist die Anzahl der restlichen bit's + for (int cnt = 0; cnt <= 22; cnt++) + { + faktor = faktor / 2.0; + //entspricht 2^-y + if (ma.Substring(cnt, 1) == "1") + { + mantisse = mantisse + faktor; + } + } + return Math.Pow((-1), vz) * Math.Pow(2, (exd - 127)) * mantisse; + } + } + #endregion + #region FromDWord + public static double FromDWord(Int32 value) + { + byte[] b = DInt.ToByteArray(value); + double d = FromByteArray(b); + return d; + } + + public static double FromDWord(UInt32 value) + { + byte[] b = DWord.ToByteArray(value); + double d = FromByteArray(b); + return d; + } + #endregion + + #region ToByteArray + public static byte[] ToByteArray(double value) + { + double wert = (double)value; + string binString = ""; + byte[] bytes = new byte[4]; + if (wert != 0f) + { + if (wert < 0) + { + wert *= -1; + binString = "1"; + } + else + { + binString = "0"; + } + int exponent = (int)Math.Floor((double)Math.Log(wert) / Math.Log(2.0)); + wert = wert / (Math.Pow(2, exponent)) - 1; + + binString += ValToBinString((byte)(exponent + 127)); + for (int cnt = 1; cnt <= 23; cnt++) + { + if (!(wert - System.Math.Pow(2, -cnt) < 0)) + { + wert = wert - System.Math.Pow(2, -cnt); + binString += "1"; + } + else + binString += "0"; + } + bytes[0] = (byte)BinStringToByte(binString.Substring(0, 8)); + bytes[1] = (byte)BinStringToByte(binString.Substring(8, 8)); + bytes[2] = (byte)BinStringToByte(binString.Substring(16, 8)); + bytes[3] = (byte)BinStringToByte(binString.Substring(24, 8)); + + } + else + { + bytes[0] = 0; + bytes[1] = 0; + bytes[2] = 0; + bytes[3] = 0; + } + return bytes; + } + + public static byte[] ToByteArray(double[] value) + { + ByteArray arr = new ByteArray(); + foreach (double val in value) + arr.Add(ToByteArray(val)); + return arr.array; + } + #endregion + #region ToArray + public static double[] ToArray(byte[] bytes) + { + double[] values = new double[bytes.Length / 4]; + + int counter = 0; + for (int cnt = 0; cnt < bytes.Length / 4; cnt++) + values[cnt] = FromByteArray(new byte[] { bytes[counter++], bytes[counter++], bytes[counter++], bytes[counter++] }); + + return values; + } + #endregion + + // privates + #region ValToBinString + private static string ValToBinString(byte value) + { + string txt = ""; + + for (int cnt = 7; cnt >= 0; cnt += -1) + { + if ((value & (byte)Math.Pow(2, cnt)) > 0) + txt += "1"; + else + txt += "0"; + } + return txt; + } + #endregion + #region BinStringToByte + private static byte? BinStringToByte(string txt) + { + int cnt = 0; + int ret = 0; + + if (txt.Length == 8) + { + for (cnt = 7; cnt >= 0; cnt += -1) + { + if (int.Parse(txt.Substring(cnt, 1)) == 1) + { + ret += (int)(Math.Pow(2, (txt.Length - 1 - cnt))); + } + } + return (byte)ret; + } + return null; + } + #endregion + } +} diff --git a/S7.Net/Types/Int.cs b/S7.Net.Common/Types/Int.cs similarity index 96% rename from S7.Net/Types/Int.cs rename to S7.Net.Common/Types/Int.cs index 1215ecb..c53f7ac 100644 --- a/S7.Net/Types/Int.cs +++ b/S7.Net.Common/Types/Int.cs @@ -1,74 +1,74 @@ -using System; - -namespace S7.Net.Types -{ - public static class Int - { - // publics - #region FromByteArray - public static Int16 FromByteArray(byte[] bytes) - { - // bytes[0] -> HighByte - // bytes[1] -> LowByte - return FromBytes(bytes[1], bytes[0]); - } - #endregion - #region FromBytes - public static Int16 FromBytes(byte LoVal, byte HiVal) - { - return (Int16)(HiVal * 256 + LoVal); - } - #endregion - - #region ToByteArray - public static byte[] ToByteArray(Int16 value) - { - byte[] bytes = new byte[2]; - int x = 2; - long valLong = (long)((Int16)value); - for (int cnt = 0; cnt < x; cnt++) - { - Int64 x1 = (Int64)Math.Pow(256, (cnt)); - - Int64 x3 = (Int64)(valLong / x1); - bytes[x - cnt - 1] = (byte)(x3 & 255); - valLong -= bytes[x - cnt - 1] * x1; - } - return bytes; - } - - public static byte[] ToByteArray(Int16[] value) - { - ByteArray arr = new ByteArray(); - foreach (Int16 val in value) - arr.Add(ToByteArray(val)); - return arr.array; - } - #endregion - #region ToArray - public static Int16[] ToArray(byte[] bytes) - { - Int16[] values = new Int16[bytes.Length / 2]; - - int counter = 0; - for (int cnt = 0; cnt < bytes.Length / 2; cnt++) - values[cnt] = FromByteArray(new byte[] { bytes[counter++], bytes[counter++] }); - - return values; - } - #endregion - - // conversion - public static Int16 CWord(int value) - { - if (value > 32767) - { - value -= 32768; - value = 32768 - value; - value *= -1; - } - return (short)value; - } - - } -} +using System; + +namespace S7.Net.Types +{ + public static class Int + { + // publics + #region FromByteArray + public static Int16 FromByteArray(byte[] bytes) + { + // bytes[0] -> HighByte + // bytes[1] -> LowByte + return FromBytes(bytes[1], bytes[0]); + } + #endregion + #region FromBytes + public static Int16 FromBytes(byte LoVal, byte HiVal) + { + return (Int16)(HiVal * 256 + LoVal); + } + #endregion + + #region ToByteArray + public static byte[] ToByteArray(Int16 value) + { + byte[] bytes = new byte[2]; + int x = 2; + long valLong = (long)((Int16)value); + for (int cnt = 0; cnt < x; cnt++) + { + Int64 x1 = (Int64)Math.Pow(256, (cnt)); + + Int64 x3 = (Int64)(valLong / x1); + bytes[x - cnt - 1] = (byte)(x3 & 255); + valLong -= bytes[x - cnt - 1] * x1; + } + return bytes; + } + + public static byte[] ToByteArray(Int16[] value) + { + ByteArray arr = new ByteArray(); + foreach (Int16 val in value) + arr.Add(ToByteArray(val)); + return arr.array; + } + #endregion + #region ToArray + public static Int16[] ToArray(byte[] bytes) + { + Int16[] values = new Int16[bytes.Length / 2]; + + int counter = 0; + for (int cnt = 0; cnt < bytes.Length / 2; cnt++) + values[cnt] = FromByteArray(new byte[] { bytes[counter++], bytes[counter++] }); + + return values; + } + #endregion + + // conversion + public static Int16 CWord(int value) + { + if (value > 32767) + { + value -= 32768; + value = 32768 - value; + value *= -1; + } + return (short)value; + } + + } +} diff --git a/S7.Net/Types/String.cs b/S7.Net.Common/Types/String.cs similarity index 96% rename from S7.Net/Types/String.cs rename to S7.Net.Common/Types/String.cs index a0a8230..d5f9651 100644 --- a/S7.Net/Types/String.cs +++ b/S7.Net.Common/Types/String.cs @@ -1,34 +1,34 @@ -namespace S7.Net.Types -{ - public static class String - { - // publics - #region ToByteArray - public static byte[] ToByteArray(string value) - { - string txt = (string)value; - char[] ca = txt.ToCharArray(); - byte[] bytes = new byte[txt.Length]; - for (int cnt = 0; cnt <= ca.Length - 1; cnt++) - bytes[cnt] = (byte)Asc(ca[cnt].ToString()); - return bytes; - } - #endregion - - #region FromByteArray - public static string FromByteArray(byte[] bytes) - { - return System.Text.Encoding.ASCII.GetString(bytes); - } - #endregion - - // privates - private static int Asc(string s) - { - byte[] b = System.Text.Encoding.ASCII.GetBytes(s); - if (b.Length > 0) - return b[0]; - return 0; - } - } -} +namespace S7.Net.Types +{ + public static class String + { + // publics + #region ToByteArray + public static byte[] ToByteArray(string value) + { + string txt = (string)value; + char[] ca = txt.ToCharArray(); + byte[] bytes = new byte[txt.Length]; + for (int cnt = 0; cnt <= ca.Length - 1; cnt++) + bytes[cnt] = (byte)Asc(ca[cnt].ToString()); + return bytes; + } + #endregion + + #region FromByteArray + public static string FromByteArray(byte[] bytes) + { + return System.Text.Encoding.ASCII.GetString(bytes); + } + #endregion + + // privates + private static int Asc(string s) + { + byte[] b = System.Text.Encoding.ASCII.GetBytes(s); + if (b.Length > 0) + return b[0]; + return 0; + } + } +} diff --git a/S7.Net/Types/Struct.cs b/S7.Net.Common/Types/Struct.cs similarity index 97% rename from S7.Net/Types/Struct.cs rename to S7.Net.Common/Types/Struct.cs index b636c6d..9ecf2bf 100644 --- a/S7.Net/Types/Struct.cs +++ b/S7.Net.Common/Types/Struct.cs @@ -1,225 +1,226 @@ -using System; -using System.Linq; -using System.Globalization; - -namespace S7.Net.Types -{ - public static class Struct - { - /// - /// Gets the size of the struct in bytes. - /// - /// the type of the struct - /// the number of bytes - public static int GetStructSize(Type structType) - { - double numBytes = 0.0; - - System.Reflection.FieldInfo[] infos = structType.GetFields(); - foreach (System.Reflection.FieldInfo info in infos) - { - switch (info.FieldType.Name) - { - case "Boolean": - numBytes += 0.125; - break; - case "Byte": - numBytes = Math.Ceiling(numBytes); - numBytes++; - break; - case "Int16": - case "UInt16": - numBytes = Math.Ceiling(numBytes); - if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0) - numBytes++; - numBytes += 2; - break; - case "Int32": - case "UInt32": - numBytes = Math.Ceiling(numBytes); - if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0) - numBytes++; - numBytes += 4; - break; - case "Float": - case "Double": - numBytes = Math.Ceiling(numBytes); - if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0) - numBytes++; - numBytes += 4; - break; - } - } - return (int)numBytes; - } - - /// - /// Creates a struct of a specified type by an array of bytes. - /// - /// The struct type - /// The array of bytes - /// The object depending on the struct type or null if fails(array-length != struct-length - public static object FromBytes(Type structType, byte[] bytes) - { - if (bytes == null) - return null; - - if (bytes.Length != GetStructSize(structType)) - return null; - - // and decode it - int bytePos = 0; - int bitPos = 0; - double numBytes = 0.0; - object structValue = Activator.CreateInstance(structType); - - System.Reflection.FieldInfo[] infos = structValue.GetType().GetFields(); - foreach (System.Reflection.FieldInfo info in infos) - { - switch (info.FieldType.Name) - { - case "Boolean": - // get the value - bytePos = (int)Math.Floor(numBytes); - bitPos = (int)((numBytes - (double)bytePos) / 0.125); - if ((bytes[bytePos] & (int)Math.Pow(2, bitPos)) != 0) - info.SetValue(structValue, true); - else - info.SetValue(structValue, false); - numBytes += 0.125; - break; - case "Byte": - numBytes = Math.Ceiling(numBytes); - info.SetValue(structValue, (byte)(bytes[(int)numBytes])); - numBytes++; - break; - case "Int16": - numBytes = Math.Ceiling(numBytes); - if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0) - numBytes++; - // hier auswerten - ushort source = Word.FromBytes(bytes[(int)numBytes + 1], bytes[(int)numBytes]); - info.SetValue(structValue, source.ConvertToShort()); - numBytes += 2; - break; - case "UInt16": - numBytes = Math.Ceiling(numBytes); - if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0) - numBytes++; - // hier auswerten - info.SetValue(structValue, Word.FromBytes(bytes[(int)numBytes + 1], - bytes[(int)numBytes])); - numBytes += 2; - break; - case "Int32": - numBytes = Math.Ceiling(numBytes); - if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0) - numBytes++; - // hier auswerten - uint sourceUInt = DWord.FromBytes(bytes[(int)numBytes + 3], - bytes[(int)numBytes + 2], - bytes[(int)numBytes + 1], - bytes[(int)numBytes + 0]); - info.SetValue(structValue, sourceUInt.ConvertToInt()); - numBytes += 4; - break; - case "UInt32": - numBytes = Math.Ceiling(numBytes); - if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0) - numBytes++; - // hier auswerten - info.SetValue(structValue, DWord.FromBytes(bytes[(int)numBytes], - bytes[(int)numBytes + 1], - bytes[(int)numBytes + 2], - bytes[(int)numBytes + 3])); - numBytes += 4; - break; - case "Double": - numBytes = Math.Ceiling(numBytes); - if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0) - numBytes++; - // hier auswerten - info.SetValue(structValue, Double.FromByteArray(new byte[] { bytes[(int)numBytes], - bytes[(int)numBytes + 1], - bytes[(int)numBytes + 2], - bytes[(int)numBytes + 3] })); - numBytes += 4; - break; - } - } - return structValue; - } - - /// - /// Creates a byte array depending on the struct type. - /// - /// The struct object - /// A byte array or null if fails. - public static byte[] ToBytes(object structValue) - { - Type type = structValue.GetType(); - - int size = Struct.GetStructSize(type); - byte[] bytes = new byte[size]; - byte[] bytes2 = null; - - int bytePos = 0; - int bitPos = 0; - double numBytes = 0.0; - - System.Reflection.FieldInfo[] infos = type.GetFields(); - foreach (System.Reflection.FieldInfo info in infos) - { - bytes2 = null; - switch (info.FieldType.Name) - { - case "Boolean": - // get the value - bytePos = (int)Math.Floor(numBytes); - bitPos = (int)((numBytes - (double)bytePos) / 0.125); - if ((bool)info.GetValue(structValue)) - bytes[bytePos] |= (byte)Math.Pow(2, bitPos); // is true - else - bytes[bytePos] &= (byte)(~(byte)Math.Pow(2, bitPos)); // is false - numBytes += 0.125; - break; - case "Byte": - numBytes = (int)Math.Ceiling(numBytes); - bytePos = (int)numBytes; - bytes[bytePos] = (byte)info.GetValue(structValue); - numBytes++; - break; - case "Int16": - bytes2 = Int.ToByteArray((Int16)info.GetValue(structValue)); - break; - case "UInt16": - bytes2 = Word.ToByteArray((UInt16)info.GetValue(structValue)); - break; - case "Int32": - bytes2 = DInt.ToByteArray((Int32)info.GetValue(structValue)); - break; - case "UInt32": - bytes2 = DWord.ToByteArray((UInt32)info.GetValue(structValue)); - break; - case "Double": - bytes2 = Double.ToByteArray((double)info.GetValue(structValue)); - break; - } - if (bytes2 != null) - { - // add them - numBytes = Math.Ceiling(numBytes); - if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0) - numBytes++; - bytePos = (int)numBytes; - for (int bCnt=0; bCnt + /// Gets the size of the struct in bytes. + /// + /// the type of the struct + /// the number of bytes + public static int GetStructSize(Type structType) + { + double numBytes = 0.0; + + System.Reflection.FieldInfo[] infos = structType.GetFields(); + foreach (System.Reflection.FieldInfo info in infos) + { + switch (info.FieldType.Name) + { + case "Boolean": + numBytes += 0.125; + break; + case "Byte": + numBytes = Math.Ceiling(numBytes); + numBytes++; + break; + case "Int16": + case "UInt16": + numBytes = Math.Ceiling(numBytes); + if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0) + numBytes++; + numBytes += 2; + break; + case "Int32": + case "UInt32": + numBytes = Math.Ceiling(numBytes); + if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0) + numBytes++; + numBytes += 4; + break; + case "Float": + case "Double": + numBytes = Math.Ceiling(numBytes); + if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0) + numBytes++; + numBytes += 4; + break; + } + } + return (int)numBytes; + } + + /// + /// Creates a struct of a specified type by an array of bytes. + /// + /// The struct type + /// The array of bytes + /// The object depending on the struct type or null if fails(array-length != struct-length + public static object FromBytes(Type structType, byte[] bytes) + { + if (bytes == null) + return null; + + if (bytes.Length != GetStructSize(structType)) + return null; + + // and decode it + int bytePos = 0; + int bitPos = 0; + double numBytes = 0.0; + object structValue = Activator.CreateInstance(structType); + + System.Reflection.FieldInfo[] infos = structValue.GetType().GetFields(); + foreach (System.Reflection.FieldInfo info in infos) + { + switch (info.FieldType.Name) + { + case "Boolean": + // get the value + bytePos = (int)Math.Floor(numBytes); + bitPos = (int)((numBytes - (double)bytePos) / 0.125); + if ((bytes[bytePos] & (int)Math.Pow(2, bitPos)) != 0) + info.SetValue(structValue, true); + else + info.SetValue(structValue, false); + numBytes += 0.125; + break; + case "Byte": + numBytes = Math.Ceiling(numBytes); + info.SetValue(structValue, (byte)(bytes[(int)numBytes])); + numBytes++; + break; + case "Int16": + numBytes = Math.Ceiling(numBytes); + if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0) + numBytes++; + // hier auswerten + ushort source = Word.FromBytes(bytes[(int)numBytes + 1], bytes[(int)numBytes]); + info.SetValue(structValue, source.ConvertToShort()); + numBytes += 2; + break; + case "UInt16": + numBytes = Math.Ceiling(numBytes); + if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0) + numBytes++; + // hier auswerten + info.SetValue(structValue, Word.FromBytes(bytes[(int)numBytes + 1], + bytes[(int)numBytes])); + numBytes += 2; + break; + case "Int32": + numBytes = Math.Ceiling(numBytes); + if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0) + numBytes++; + // hier auswerten + uint sourceUInt = DWord.FromBytes(bytes[(int)numBytes + 3], + bytes[(int)numBytes + 2], + bytes[(int)numBytes + 1], + bytes[(int)numBytes + 0]); + info.SetValue(structValue, sourceUInt.ConvertToInt()); + numBytes += 4; + break; + case "UInt32": + numBytes = Math.Ceiling(numBytes); + if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0) + numBytes++; + // hier auswerten + info.SetValue(structValue, DWord.FromBytes(bytes[(int)numBytes], + bytes[(int)numBytes + 1], + bytes[(int)numBytes + 2], + bytes[(int)numBytes + 3])); + numBytes += 4; + break; + case "Double": + numBytes = Math.Ceiling(numBytes); + if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0) + numBytes++; + // hier auswerten + info.SetValue(structValue, Double.FromByteArray(new byte[] { bytes[(int)numBytes], + bytes[(int)numBytes + 1], + bytes[(int)numBytes + 2], + bytes[(int)numBytes + 3] })); + numBytes += 4; + break; + } + } + return structValue; + } + + /// + /// Creates a byte array depending on the struct type. + /// + /// The struct object + /// A byte array or null if fails. + public static byte[] ToBytes(object structValue) + { + Type type = structValue.GetType(); + + int size = Struct.GetStructSize(type); + byte[] bytes = new byte[size]; + byte[] bytes2 = null; + + int bytePos = 0; + int bitPos = 0; + double numBytes = 0.0; + + System.Reflection.FieldInfo[] infos = type.GetFields(); + foreach (System.Reflection.FieldInfo info in infos) + { + bytes2 = null; + switch (info.FieldType.Name) + { + case "Boolean": + // get the value + bytePos = (int)Math.Floor(numBytes); + bitPos = (int)((numBytes - (double)bytePos) / 0.125); + if ((bool)info.GetValue(structValue)) + bytes[bytePos] |= (byte)Math.Pow(2, bitPos); // is true + else + bytes[bytePos] &= (byte)(~(byte)Math.Pow(2, bitPos)); // is false + numBytes += 0.125; + break; + case "Byte": + numBytes = (int)Math.Ceiling(numBytes); + bytePos = (int)numBytes; + bytes[bytePos] = (byte)info.GetValue(structValue); + numBytes++; + break; + case "Int16": + bytes2 = Int.ToByteArray((Int16)info.GetValue(structValue)); + break; + case "UInt16": + bytes2 = Word.ToByteArray((UInt16)info.GetValue(structValue)); + break; + case "Int32": + bytes2 = DInt.ToByteArray((Int32)info.GetValue(structValue)); + break; + case "UInt32": + bytes2 = DWord.ToByteArray((UInt32)info.GetValue(structValue)); + break; + case "Double": + bytes2 = Double.ToByteArray((double)info.GetValue(structValue)); + break; + } + if (bytes2 != null) + { + // add them + numBytes = Math.Ceiling(numBytes); + if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0) + numBytes++; + bytePos = (int)numBytes; + for (int bCnt=0; bCnt HighByte - // bytes[1] -> LowByte - return FromBytes(bytes[1], bytes[0]); - } - #endregion - #region FromBytes - public static UInt16 FromBytes(byte LoVal, byte HiVal) - { - return (UInt16)(HiVal * 256 + LoVal); - } - #endregion - - #region ToByteArray - public static byte[] ToByteArray(UInt16 value) - { - byte[] bytes = new byte[2]; - int x = 2; - long valLong = (long)((UInt16)value); - for (int cnt = 0; cnt < x; cnt++) - { - Int64 x1 = (Int64)Math.Pow(256, (cnt)); - - Int64 x3 = (Int64)(valLong / x1); - bytes[x - cnt - 1] = (byte)(x3 & 255); - valLong -= bytes[x - cnt - 1] * x1; - } - return bytes; - } - - public static byte[] ToByteArray(UInt16[] value) - { - ByteArray arr = new ByteArray(); - foreach (UInt16 val in value) - arr.Add(ToByteArray(val)); - return arr.array; - } - #endregion - #region ToArray - public static UInt16[] ToArray(byte[] bytes) - { - UInt16[] values = new UInt16[bytes.Length / 2]; - - int counter = 0; - for (int cnt = 0; cnt < bytes.Length / 2; cnt++) - values[cnt] = FromByteArray(new byte[] { bytes[counter++], bytes[counter++] }); - - return values; - } - #endregion - } -} +using System; + +namespace S7.Net.Types +{ + public static class Word + { + // publics + #region FromByteArray + public static UInt16 FromByteArray(byte[] bytes) + { + // bytes[0] -> HighByte + // bytes[1] -> LowByte + return FromBytes(bytes[1], bytes[0]); + } + #endregion + #region FromBytes + public static UInt16 FromBytes(byte LoVal, byte HiVal) + { + return (UInt16)(HiVal * 256 + LoVal); + } + #endregion + + #region ToByteArray + public static byte[] ToByteArray(UInt16 value) + { + byte[] bytes = new byte[2]; + int x = 2; + long valLong = (long)((UInt16)value); + for (int cnt = 0; cnt < x; cnt++) + { + Int64 x1 = (Int64)Math.Pow(256, (cnt)); + + Int64 x3 = (Int64)(valLong / x1); + bytes[x - cnt - 1] = (byte)(x3 & 255); + valLong -= bytes[x - cnt - 1] * x1; + } + return bytes; + } + + public static byte[] ToByteArray(UInt16[] value) + { + ByteArray arr = new ByteArray(); + foreach (UInt16 val in value) + arr.Add(ToByteArray(val)); + return arr.array; + } + #endregion + #region ToArray + public static UInt16[] ToArray(byte[] bytes) + { + UInt16[] values = new UInt16[bytes.Length / 2]; + + int counter = 0; + for (int cnt = 0; cnt < bytes.Length / 2; cnt++) + values[cnt] = FromByteArray(new byte[] { bytes[counter++], bytes[counter++] }); + + return values; + } + #endregion + } +} diff --git a/S7.Net.Core/PLC.cs b/S7.Net.Core/PLC.cs new file mode 100644 index 0000000..78c8ebf --- /dev/null +++ b/S7.Net.Core/PLC.cs @@ -0,0 +1,885 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Net.NetworkInformation; +using System.Net.Sockets; +using S7.Net.Interfaces; +using Double = System.Double; + +namespace S7.Net +{ + public class Plc : IPlc + { + private SocketClient _mSocket; //TCP connection to device + + public string IP { get; set; } + public CpuType CPU { get; set; } + public Int16 Rack { get; set; } + public Int16 Slot { get; set; } + public string Name { get; set; } + public object Tag { get; set; } + + /// + /// Pings the IP address and returns true if the result of the ping is Success. + /// + public bool IsAvailable + { + get + { + //using (Ping ping = new Ping()) + //{ + //PingReply result; + //try + //{ + // result = ping.Send(IP); + //} + //catch (PingException) + //{ + // result = null; + //} + return (!string.IsNullOrEmpty(IP)); // result != null && result.Status == IPStatus.Success; + //} + } + } + + /// + /// Checks if the socket is connected and polls the other peer (the plc) to see if it's connected. + /// This is the variable that you should continously check to see if the communication is working + /// See also: http://stackoverflow.com/questions/2661764/how-to-check-if-a-socket-is-connected-disconnected-in-c + /// + public bool IsConnected + { + get + { + try + { + if (_mSocket == null) + return false; + return _mSocket.Connected; //!((_mSocket.Poll(1000, SelectMode.SelectRead) && (_mSocket.Available == 0)) || !_mSocket.Connected); + } + catch { return false; } + } + } + public string LastErrorString { get; private set; } + public ErrorCode LastErrorCode { get; private set; } + + public Plc() : this(CpuType.S7400, "localhost", 0, 2) { } + + /// + /// Creates a PLC object with all the parameters needed for connections. + /// For S7-1200 and S7-1500, the default is rack = 0 and slot = 0. + /// You need slot > 0 if you are connecting to external ethernet card (CP). + /// For S7-300 and S7-400 the default is rack = 0 and slot = 2. + /// + /// + /// + /// + /// + /// + /// + public Plc(CpuType cpu, string ip, Int16 rack, Int16 slot, string name = "", object tag = null) + { + IP = ip; + CPU = cpu; + Rack = rack; + Slot = slot; + Name = name; + Tag = tag; + } + + public ErrorCode Open() + { + byte[] bReceive = new byte[256]; + + try + { + // check if available + if (!IsAvailable) + { + throw new Exception(); + } + } + catch + { + LastErrorCode = ErrorCode.IPAddressNotAvailable; + LastErrorString = string.Format("Destination IP-Address '{0}' is not available!", IP); + return LastErrorCode; + } + + try { + // open the channel + _mSocket = new SocketClient(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + + _mSocket.SetReceiveTimeout(1000); + _mSocket.SetSendTimeout(1000); + + IPEndPoint server = new IPEndPoint(IPAddress.Parse(IP), 102); + _mSocket.Connect(server); + } + catch (Exception ex) { + LastErrorCode = ErrorCode.ConnectionError; + LastErrorString = ex.Message; + return ErrorCode.ConnectionError; + } + + try + { + byte[] bSend1 = { 3, 0, 0, 22, 17, 224, 0, 0, 0, 46, 0, 193, 2, 1, 0, 194, 2, 3, 0, 192, 1, 9 }; + + switch (CPU) { + case CpuType.S7200: + //S7200: Chr(193) & Chr(2) & Chr(16) & Chr(0) 'Eigener Tsap + bSend1[11] = 193; + bSend1[12] = 2; + bSend1[13] = 16; + bSend1[14] = 0; + //S7200: Chr(194) & Chr(2) & Chr(16) & Chr(0) 'Fremder Tsap + bSend1[15] = 194; + bSend1[16] = 2; + bSend1[17] = 16; + bSend1[18] = 0; + break; + case CpuType.S71200: + case CpuType.S7300: + //S7300: Chr(193) & Chr(2) & Chr(1) & Chr(0) 'Eigener Tsap + bSend1[11] = 193; + bSend1[12] = 2; + bSend1[13] = 1; + bSend1[14] = 0; + //S7300: Chr(194) & Chr(2) & Chr(3) & Chr(2) 'Fremder Tsap + bSend1[15] = 194; + bSend1[16] = 2; + bSend1[17] = 3; + bSend1[18] = (byte)(Rack * 2 * 16 + Slot); + break; + case CpuType.S7400: + //S7400: Chr(193) & Chr(2) & Chr(1) & Chr(0) 'Eigener Tsap + bSend1[11] = 193; + bSend1[12] = 2; + bSend1[13] = 1; + bSend1[14] = 0; + //S7400: Chr(194) & Chr(2) & Chr(3) & Chr(3) 'Fremder Tsap + bSend1[15] = 194; + bSend1[16] = 2; + bSend1[17] = 3; + bSend1[18] = (byte)(Rack * 2 * 16 + Slot); + break; + case CpuType.S71500: + // Eigener Tsap + bSend1[11] = 193; + bSend1[12] = 2; + bSend1[13] = 0x10; + bSend1[14] = 0x2; + // Fredmer Tsap + bSend1[15] = 194; + bSend1[16] = 2; + bSend1[17] = 0x3; + bSend1[18] = (byte)(Rack * 2 * 16 + Slot); + break; + default: + return ErrorCode.WrongCPU_Type; + } + + _mSocket.Send(bSend1, 22); + if (_mSocket.Receive(bReceive, 22) != 22) + { + throw new Exception(ErrorCode.WrongNumberReceivedBytes.ToString()); + } + + byte[] bsend2 = { 3, 0, 0, 25, 2, 240, 128, 50, 1, 0, 0, 255, 255, 0, 8, 0, 0, 240, 0, 0, 3, 0, 3, 1, 0 }; + _mSocket.Send(bsend2, 25); + + if (_mSocket.Receive(bReceive, 27) != 27) + { + throw new Exception(ErrorCode.WrongNumberReceivedBytes.ToString()); + } + } + catch + { + LastErrorCode = ErrorCode.ConnectionError; + LastErrorString = string.Format("Couldn't establish the connection to {0}!", IP); + return ErrorCode.ConnectionError; + } + + return ErrorCode.NoError; + } + + public void Close() + { + if (_mSocket != null && _mSocket.Connected) + { + _mSocket.Close(); + } + } + + public byte[] ReadBytes(DataType dataType, int DB, int startByteAdr, int count) + { + byte[] bytes = new byte[count]; + + try + { + // first create the header + int packageSize = 31; + Types.ByteArray package = new Types.ByteArray(packageSize); + + package.Add(new byte[] {0x03, 0x00, 0x00}); + package.Add((byte) packageSize); + package.Add(new byte[] + {0x02, 0xf0, 0x80, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x04, 0x01, 0x12, 0x0a, 0x10}); + // package.Add(0x02); // datenart + switch (dataType) + { + case DataType.Timer: + case DataType.Counter: + package.Add((byte) dataType); + break; + default: + package.Add(0x02); + break; + } + + package.Add(Types.Word.ToByteArray((ushort) (count))); + package.Add(Types.Word.ToByteArray((ushort) (DB))); + package.Add((byte) dataType); + package.Add((byte) 0); + switch (dataType) + { + case DataType.Timer: + case DataType.Counter: + package.Add(Types.Word.ToByteArray((ushort) (startByteAdr))); + break; + default: + package.Add(Types.Word.ToByteArray((ushort) ((startByteAdr)*8))); + break; + } + + _mSocket.Send(package.array, package.array.Length); + + byte[] bReceive = new byte[512]; + int numReceived = _mSocket.Receive(bReceive, 512); + if (bReceive[21] != 0xff) throw new Exception(ErrorCode.WrongNumberReceivedBytes.ToString()); + + for (int cnt = 0; cnt < count; cnt++) + bytes[cnt] = bReceive[cnt + 25]; + + return bytes; + } + catch (SocketException socketException) + { + LastErrorCode = ErrorCode.WriteData; + LastErrorString = socketException.Message; + return null; + } + catch(Exception exc) + { + LastErrorCode = ErrorCode.WriteData; + LastErrorString = exc.Message; + return null; + } + } + + public object Read(DataType dataType, int db, int startByteAdr, VarType varType, int varCount) + { + byte[] bytes = null; + int cntBytes = 0; + + switch (varType) + { + case VarType.Byte: + cntBytes = varCount; + if (cntBytes < 1) cntBytes = 1; + bytes = ReadBytes(dataType, db, startByteAdr, cntBytes); + if (bytes == null) return null; + if (varCount == 1) + return bytes[0]; + else + return bytes; + case VarType.Word: + cntBytes = varCount * 2; + bytes = ReadBytes(dataType, db, startByteAdr, cntBytes); + if (bytes == null) return null; + + if (varCount == 1) + return Types.Word.FromByteArray(bytes); + else + return Types.Word.ToArray(bytes); + case VarType.Int: + cntBytes = varCount * 2; + bytes = ReadBytes(dataType, db, startByteAdr, cntBytes); + if (bytes == null) return null; + + if (varCount == 1) + return Types.Int.FromByteArray(bytes); + else + return Types.Int.ToArray(bytes); + case VarType.DWord: + cntBytes = varCount * 4; + bytes = ReadBytes(dataType, db, startByteAdr, cntBytes); + if (bytes == null) return null; + + if (varCount == 1) + return Types.DWord.FromByteArray(bytes); + else + return Types.DWord.ToArray(bytes); + case VarType.DInt: + cntBytes = varCount * 4; + bytes = ReadBytes(dataType, db, startByteAdr, cntBytes); + if (bytes == null) return null; + + if (varCount == 1) + return Types.DInt.FromByteArray(bytes); + else + return Types.DInt.ToArray(bytes); + case VarType.Real: + cntBytes = varCount * 4; + bytes = ReadBytes(dataType, db, startByteAdr, cntBytes); + if (bytes == null) return null; + + if (varCount == 1) + return Types.Double.FromByteArray(bytes); + else + return Types.Double.ToArray(bytes); + case VarType.String: + cntBytes = varCount; + bytes = ReadBytes(dataType, db, startByteAdr, cntBytes); + if (bytes == null) return null; + + return Types.String.FromByteArray(bytes); + case VarType.Timer: + cntBytes = varCount * 2; + bytes = ReadBytes(dataType, db, startByteAdr, cntBytes); + if (bytes == null) return null; + + if (varCount == 1) + return Types.Timer.FromByteArray(bytes); + else + return Types.Timer.ToArray(bytes); + case VarType.Counter: + cntBytes = varCount * 2; + bytes = ReadBytes(dataType, db, startByteAdr, cntBytes); + if (bytes == null) return null; + + if (varCount == 1) + return Types.Counter.FromByteArray(bytes); + else + return Types.Counter.ToArray(bytes); + default: + return null; + } + } + + public object Read(string variable) + { + DataType mDataType; + int mDB; + int mByte; + int mBit; + + byte objByte; + UInt16 objUInt16; + UInt32 objUInt32; + double objDouble; + BitArray objBoolArray; + + string txt = variable.ToUpper(); + txt = txt.Replace(" ", ""); // remove spaces + + try + { + switch (txt.Substring(0, 2)) + { + case "DB": + string[] strings = txt.Split(new char[] { '.' }); + if (strings.Length < 2) + throw new Exception(); + + mDB = int.Parse(strings[0].Substring(2)); + string dbType = strings[1].Substring(0, 3); + int dbIndex = int.Parse(strings[1].Substring(3)); + + switch (dbType) + { + case "DBB": + byte obj = (byte)Read(DataType.DataBlock, mDB, dbIndex, VarType.Byte, 1); + return obj; + case "DBW": + UInt16 objI = (UInt16)Read(DataType.DataBlock, mDB, dbIndex, VarType.Word, 1); + return objI; + case "DBD": + UInt32 objU = (UInt32)Read(DataType.DataBlock, mDB, dbIndex, VarType.DWord, 1); + return objU; + case "DBX": + mByte = dbIndex; + mBit = int.Parse(strings[2]); + if (mBit > 7) throw new Exception(); + byte obj2 = (byte)Read(DataType.DataBlock, mDB, mByte, VarType.Byte, 1); + objBoolArray = new BitArray(new byte[] { obj2 }); + return objBoolArray[mBit]; + default: + throw new Exception(); + } + case "EB": + // Input byte + objByte = (byte)Read(DataType.Input, 0, int.Parse(txt.Substring(2)), VarType.Byte, 1); + return objByte; + case "EW": + // Input word + objUInt16 = (UInt16)Read(DataType.Input, 0, int.Parse(txt.Substring(2)), VarType.Word, 1); + return objUInt16; + case "ED": + // Input double-word + objUInt32 = (UInt32)Read(DataType.Input, 0, int.Parse(txt.Substring(2)), VarType.DWord, 1); + return objUInt32; + case "AB": + // Output byte + objByte = (byte)Read(DataType.Output, 0, int.Parse(txt.Substring(2)), VarType.Byte, 1); + return objByte; + case "AW": + // Output word + objUInt16 = (UInt16)Read(DataType.Output, 0, int.Parse(txt.Substring(2)), VarType.Word, 1); + return objUInt16; + case "AD": + // Output double-word + objUInt32 = (UInt32)Read(DataType.Output, 0, int.Parse(txt.Substring(2)), VarType.DWord, 1); + return objUInt32; + case "MB": + // Memory byte + objByte = (byte)Read(DataType.Memory, 0, int.Parse(txt.Substring(2)), VarType.Byte, 1); + return objByte; + case "MW": + // Memory word + objUInt16 = (UInt16)Read(DataType.Memory, 0, int.Parse(txt.Substring(2)), VarType.Word, 1); + return objUInt16; + case "MD": + // Memory double-word + objUInt32 = (UInt32)Read(DataType.Memory, 0, int.Parse(txt.Substring(2)), VarType.DWord, 1); + return objUInt32; + default: + switch (txt.Substring(0, 1)) + { + case "E": + case "I": + // Input + mDataType = DataType.Input; + break; + case "A": + case "O": + // Output + mDataType = DataType.Output; + break; + case "M": + // Memory + mDataType = DataType.Memory; + break; + case "T": + // Timer + objDouble = (double)Read(DataType.Timer, 0, int.Parse(txt.Substring(1)), VarType.Timer, 1); + return objDouble; + case "Z": + case "C": + // Counter + objUInt16 = (UInt16)Read(DataType.Counter, 0, int.Parse(txt.Substring(1)), VarType.Counter, 1); + return objUInt16; + default: + throw new Exception(); + } + + string txt2 = txt.Substring(1); + if (txt2.IndexOf(".") == -1) throw new Exception(); + + mByte = int.Parse(txt2.Substring(0, txt2.IndexOf("."))); + mBit = int.Parse(txt2.Substring(txt2.IndexOf(".") + 1)); + if (mBit > 7) throw new Exception(); + var obj3 = (byte)Read(mDataType, 0, mByte, VarType.Byte, 1); + objBoolArray = new BitArray(new byte[]{obj3}); + return objBoolArray[mBit]; + } + } + catch + { + LastErrorCode = ErrorCode.WrongVarFormat; + LastErrorString = "The variable'" + variable + "' could not be read. Please check the syntax and try again."; + return LastErrorCode; + } + } + + public object ReadStruct(Type structType, int db) + { + int numBytes = Types.Struct.GetStructSize(structType); + // now read the package + List resultBytes = ReadMultipleBytes(numBytes, db); + + // and decode it + return Types.Struct.FromBytes(structType, resultBytes.ToArray()); + } + + /// + /// Read a class from plc. Only properties are readed + /// + /// Instance of the class that will store the values + /// Index of the DB; es.: 1 is for DB1 + public void ReadClass(object sourceClass, int db) + { + Type classType = sourceClass.GetType(); + int numBytes = Types.Class.GetClassSize(classType); + // now read the package + List resultBytes = ReadMultipleBytes(numBytes, db); + // and decode it + Types.Class.FromBytes(sourceClass, classType, resultBytes.ToArray()); + } + + public ErrorCode WriteBytes(DataType dataType, int db, int startByteAdr, byte[] value) + { + byte[] bReceive = new byte[513]; + int varCount = 0; + + try + { + varCount = value.Length; + // first create the header + int packageSize = 35 + value.Length; + Types.ByteArray package = new Types.ByteArray(packageSize); + + package.Add(new byte[] { 3, 0, 0 }); + package.Add((byte)packageSize); + package.Add(new byte[] { 2, 0xf0, 0x80, 0x32, 1, 0, 0 }); + package.Add(Types.Word.ToByteArray((ushort)(varCount - 1))); + package.Add(new byte[] { 0, 0x0e }); + package.Add(Types.Word.ToByteArray((ushort)(varCount + 4))); + package.Add(new byte[] { 0x05, 0x01, 0x12, 0x0a, 0x10, 0x02 }); + package.Add(Types.Word.ToByteArray((ushort)varCount)); + package.Add(Types.Word.ToByteArray((ushort)(db))); + package.Add((byte)dataType); + package.Add((byte)0); + package.Add(Types.Word.ToByteArray((ushort)(startByteAdr * 8))); + package.Add(new byte[] { 0, 4 }); + package.Add(Types.Word.ToByteArray((ushort)(varCount * 8))); + + // now join the header and the data + package.Add(value); + + _mSocket.Send(package.array, package.array.Length); + + int numReceived = _mSocket.Receive(bReceive, 512); + if (bReceive[21] != 0xff) + { + throw new Exception(ErrorCode.WrongNumberReceivedBytes.ToString()); + } + + return ErrorCode.NoError; + } + catch + { + LastErrorCode = ErrorCode.WriteData; + LastErrorString = ""; + return LastErrorCode; + } + } + + public object Write(DataType dataType, int db, int startByteAdr, object value) + { + byte[] package = null; + + switch (value.GetType().Name) + { + case "Byte": + package = Types.Byte.ToByteArray((byte)value); + break; + case "Int16": + package = Types.Int.ToByteArray((Int16)value); + break; + case "UInt16": + package = Types.Word.ToByteArray((UInt16)value); + break; + case "Int32": + package = Types.DInt.ToByteArray((Int32)value); + break; + case "UInt32": + package = Types.DWord.ToByteArray((UInt32)value); + break; + case "Double": + package = Types.Double.ToByteArray((Double)value); + break; + case "Byte[]": + package = (byte[])value; + break; + case "Int16[]": + package = Types.Int.ToByteArray((Int16[])value); + break; + case "UInt16[]": + package = Types.Word.ToByteArray((UInt16[])value); + break; + case "Int32[]": + package = Types.DInt.ToByteArray((Int32[])value); + break; + case "UInt32[]": + package = Types.DWord.ToByteArray((UInt32[])value); + break; + case "Double[]": + package = Types.Double.ToByteArray((double[])value); + break; + case "String": + package = Types.String.ToByteArray(value as string); + break; + default: + return ErrorCode.WrongVarFormat; + } + return WriteBytes(dataType, db, startByteAdr, package); + } + + public object Write(string variable, object value) + { + DataType mDataType; + int mDB; + int mByte; + int mBit; + + string addressLocation; + byte _byte; + object objValue; + + string txt = variable.ToUpper(); + txt = txt.Replace(" ", ""); // Remove spaces + + try + { + switch (txt.Substring(0, 2)) + { + case "DB": + string[] strings = txt.Split(new char[]{'.'}); + if (strings.Length < 2) + throw new Exception(); + + mDB = int.Parse(strings[0].Substring(2)); + string dbType = strings[1].Substring(0, 3); + int dbIndex = int.Parse(strings[1].Substring(3)); + + switch (dbType) + { + case "DBB": + objValue = Convert.ChangeType(value, typeof(byte)); + return Write(DataType.DataBlock, mDB, dbIndex, (byte)objValue); + case "DBW": + if (value is short) + { + objValue = ((short)value).ConvertToUshort(); + } + else + { + objValue = Convert.ChangeType(value, typeof(UInt16)); + } + return Write(DataType.DataBlock, mDB, dbIndex, (UInt16)objValue); + case "DBD": + if (value is int) + { + return Write(DataType.DataBlock, mDB, dbIndex, (Int32)value); + } + else + { + objValue = Convert.ChangeType(value, typeof(UInt32)); + } + return Write(DataType.DataBlock, mDB, dbIndex, (UInt32)objValue); + case "DBX": + mByte = dbIndex; + mBit = int.Parse(strings[2]); + if (mBit > 7) + { + throw new Exception(string.Format("Addressing Error: You can only reference bitwise locations 0-7. Address {0} is invalid", mBit)); + } + byte b = (byte)Read(DataType.DataBlock, mDB, mByte, VarType.Byte, 1); + if ((int)value == 1) + b = (byte)(b | (byte)Math.Pow(2, mBit)); // Bit setzen + else + b = (byte)(b & (b ^ (byte)Math.Pow(2, mBit))); // Bit rücksetzen + + return Write(DataType.DataBlock, mDB, mByte, (byte)b); + case "DBS": + // DB-String + return Write(DataType.DataBlock, mDB, dbIndex, (string)value); + default: + throw new Exception(string.Format("Addressing Error: Unable to parse address {0}. Supported formats include DBB (byte), DBW (word), DBD (dword), DBX (bitwise), DBS (string).", dbType)); + } + case "EB": + // Input Byte + objValue = Convert.ChangeType(value, typeof(byte)); + return Write(DataType.Input, 0, int.Parse(txt.Substring(2)), (byte)objValue); + case "EW": + // Input Word + objValue = Convert.ChangeType(value, typeof(UInt16)); + return Write(DataType.Input, 0, int.Parse(txt.Substring(2)), (UInt16)objValue); + case "ED": + // Input Double-Word + objValue = Convert.ChangeType(value, typeof(UInt32)); + return Write(DataType.Input, 0, int.Parse(txt.Substring(2)), (UInt32)objValue); + case "AB": + // Output Byte + objValue = Convert.ChangeType(value, typeof(byte)); + return Write(DataType.Output, 0, int.Parse(txt.Substring(2)), (byte)objValue); + case "AW": + // Output Word + objValue = Convert.ChangeType(value, typeof(UInt16)); + return Write(DataType.Output, 0, int.Parse(txt.Substring(2)), (UInt16)objValue); + case "AD": + // Output Double-Word + objValue = Convert.ChangeType(value, typeof(UInt32)); + return Write(DataType.Output, 0, int.Parse(txt.Substring(2)), (UInt32)objValue); + case "MB": + // Memory Byte + objValue = Convert.ChangeType(value, typeof(byte)); + return Write(DataType.Memory, 0, int.Parse(txt.Substring(2)), (byte)objValue); + case "MW": + // Memory Word + objValue = Convert.ChangeType(value, typeof(UInt16)); + return Write(DataType.Memory, 0, int.Parse(txt.Substring(2)), (UInt16)objValue); + case "MD": + // Memory Double-Word + return Write(DataType.Memory, 0, int.Parse(txt.Substring(2)), value); + default: + switch (txt.Substring(0, 1)) + { + case "E": + case "I": + // Input + mDataType = DataType.Input; + break; + case "A": + case "O": + // Output + mDataType = DataType.Output; + break; + case "M": + // Memory + mDataType = DataType.Memory; + break; + case "T": + // Timer + return Write(DataType.Timer, 0, int.Parse(txt.Substring(1)), (double)value); + case "Z": + case "C": + // Counter + return Write(DataType.Counter, 0, int.Parse(txt.Substring(1)), (short)value); + default: + throw new Exception(string.Format("Unknown variable type {0}.",txt.Substring(0,1))); + } + + addressLocation = txt.Substring(1); + int decimalPointIndex = addressLocation.IndexOf("."); + if (decimalPointIndex == -1) + { + throw new Exception(string.Format("Cannot parse variable {0}. Input, Output, Memory Address, Timer, and Counter types require bit-level addressing (e.g. I0.1).",addressLocation)); + } + + mByte = int.Parse(addressLocation.Substring(0, decimalPointIndex)); + mBit = int.Parse(addressLocation.Substring(decimalPointIndex + 1)); + if (mBit > 7) + { + throw new Exception(string.Format("Addressing Error: You can only reference bitwise locations 0-7. Address {0} is invalid", mBit)); + } + + _byte = (byte)Read(mDataType, 0, mByte, VarType.Byte, 1); + if ((int)value == 1) + _byte = (byte)(_byte | (byte)Math.Pow(2, mBit)); // Set bit + else + _byte = (byte)(_byte & (_byte ^ (byte)Math.Pow(2, mBit))); // Reset bit + + return Write(mDataType, 0, mByte, (byte)_byte); + } + } + catch + { + LastErrorCode = ErrorCode.WrongVarFormat; + LastErrorString = "The variable'" + variable + "' could not be parsed. Please check the syntax and try again."; + return LastErrorCode; + } + } + + public ErrorCode WriteStruct(object structValue, int db) + { + var bytes = Types.Struct.ToBytes(structValue).ToList(); + var errCode = WriteMultipleBytes(bytes, db); + return errCode; + } + + public ErrorCode WriteClass(object classValue, int db) + { + var bytes = Types.Class.ToBytes(classValue).ToList(); + var errCode = WriteMultipleBytes(bytes, db); + return errCode; + } + + /// + /// Writes multiple bytes in a DB starting from index 0. This handles more than 200 bytes with multiple requests. + /// + /// The bytes to be written + /// The DB number + /// ErrorCode when writing (NoError if everything was ok) + private ErrorCode WriteMultipleBytes(List bytes, int db) + { + ErrorCode errCode = ErrorCode.NoError; + int index = 0; + try + { + while (bytes.Count > 0) + { + var maxToWrite = Math.Min(bytes.Count, 200); + var part = bytes.ToList().GetRange(0, maxToWrite); + errCode = WriteBytes(DataType.DataBlock, db, index, part.ToArray()); + bytes.RemoveRange(0, maxToWrite); + index += maxToWrite; + if (errCode != ErrorCode.NoError) + { + break; + } + } + } + catch + { + LastErrorCode = ErrorCode.WriteData; + LastErrorString = "An error occurred while writing data."; + } + return errCode; + } + + /// + /// Reads a number of bytes from a DB starting from index 0. This handles more than 200 bytes with multiple requests. + /// + /// + /// + /// + private List ReadMultipleBytes(int numBytes, int db) + { + List resultBytes = new List(); + int index = 0; + while (numBytes > 0) + { + var maxToRead = (int)Math.Min(numBytes, 200); + byte[] bytes = (byte[])Read(DataType.DataBlock, db, index, VarType.Byte, (int)maxToRead); + resultBytes.AddRange(bytes); + numBytes -= maxToRead; + index += maxToRead; + } + return resultBytes; + } + + + + #region IDisposable members + + public void Dispose() + { + if (_mSocket != null) + { + if (_mSocket.Connected) + { + //Close() performs a Dispose on the socket. + _mSocket.Close(); + } + //((IDisposable)_mSocket).Dispose(); + } + } + + #endregion + } +} diff --git a/S7.Net.Core/Properties/AssemblyInfo.cs b/S7.Net.Core/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..bc10b55 --- /dev/null +++ b/S7.Net.Core/Properties/AssemblyInfo.cs @@ -0,0 +1,29 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("S7.Net.Core")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("S7.Net.Core")] +[assembly: AssemblyCopyright("Copyright © Microsoft 2016")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: ComVisible(false)] \ No newline at end of file diff --git a/S7.Net.Core/Properties/S7.Net.Core.rd.xml b/S7.Net.Core/Properties/S7.Net.Core.rd.xml new file mode 100644 index 0000000..6cda541 --- /dev/null +++ b/S7.Net.Core/Properties/S7.Net.Core.rd.xml @@ -0,0 +1,33 @@ + + + + + + + + + diff --git a/S7.Net.Core/S7.Net.Core.csproj b/S7.Net.Core/S7.Net.Core.csproj new file mode 100644 index 0000000..1f87265 --- /dev/null +++ b/S7.Net.Core/S7.Net.Core.csproj @@ -0,0 +1,131 @@ + + + + + Debug + AnyCPU + {CBFF80E8-3D3D-4656-A27C-A65EA5774536} + Library + Properties + S7.Net.Core + S7.Net.Core + en-US + UAP + 10.0.10586.0 + 10.0.10240.0 + 14 + 512 + {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + + + ARM + true + full + false + bin\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + prompt + 4 + + + ARM + pdbonly + true + bin\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + prompt + 4 + + + x86 + true + bin\x86\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + x86 + false + prompt + + + x86 + bin\x86\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + x86 + false + prompt + + + ARM + true + bin\ARM\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + ARM + false + prompt + + + ARM + bin\ARM\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + ARM + false + prompt + + + x64 + true + bin\x64\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + x64 + false + prompt + + + x64 + bin\x64\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + x64 + false + prompt + + + + + + + + + + + + + + %(RecursiveDir)%(FileName) + + + + 14.0 + + + + \ No newline at end of file diff --git a/S7.Net.Core/SocketClient.cs b/S7.Net.Core/SocketClient.cs new file mode 100644 index 0000000..2535449 --- /dev/null +++ b/S7.Net.Core/SocketClient.cs @@ -0,0 +1,154 @@ +using System; +using System.Net.Sockets; +using System.Threading; +using System.Net; + +namespace S7.Net +{ + internal class SocketClient + { + + public bool Connected { get; private set; } + + public SocketClient(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType) + { + _socket = new Socket(addressFamily, socketType, protocolType); + } + + public void Connect(IPEndPoint server) + { + SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs(); + + socketEventArg.RemoteEndPoint = server; + + socketEventArg.Completed += new EventHandler(delegate (object s, SocketAsyncEventArgs e) + { + if (e.SocketError == SocketError.Success) + { + Connected = true; + } + else + { + throw new SocketException((int)e.SocketError); + } + + _clientDone.Set(); + }); + + _clientDone.Reset(); + + _socket.ConnectAsync(socketEventArg); + + _clientDone.WaitOne(TIMEOUT_MILLISECONDS); + } + + public void SetReceiveTimeout(int milis) + { + _receiveTimeout = milis; + } + + public void SetSendTimeout(int milis) + { + _sendTimeout = milis; + } + + public int Send(byte[] buffer, int size) + { + var response = 0; + + if (_socket != null) + { + SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs(); + + socketEventArg.RemoteEndPoint = _socket.RemoteEndPoint; + socketEventArg.UserToken = null; + + socketEventArg.Completed += new EventHandler(delegate (object s, SocketAsyncEventArgs e) + { + if (e.SocketError == SocketError.Success) + { + response = e.BytesTransferred; + } + else + { + throw new SocketException((int)e.SocketError); + } + + _clientDone.Set(); + }); + + socketEventArg.SetBuffer(buffer, 0, size); + + _clientDone.Reset(); + + _socket.SendAsync(socketEventArg); + + _clientDone.WaitOne(_sendTimeout); + } + else + { + throw new SocketException((int)SocketError.NotInitialized); + } + + return response; + } + + public int Receive(byte[] buffer, int size) + { + var response = 0; + + if (_socket != null) + { + SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs(); + + socketEventArg.RemoteEndPoint = _socket.RemoteEndPoint; + socketEventArg.SetBuffer(buffer, 0, size); + + socketEventArg.Completed += new EventHandler(delegate (object s, SocketAsyncEventArgs e) + { + if (e.SocketError == SocketError.Success) + { + response = e.BytesTransferred; + } + else + { + throw new SocketException((int)e.SocketError); + } + + _clientDone.Set(); + }); + + _clientDone.Reset(); + + _socket.ReceiveAsync(socketEventArg); + + _clientDone.WaitOne(_receiveTimeout); + } + else + { + throw new SocketException((int)SocketError.NotInitialized); + } + + return response; + } + + public void Close() + { + Connected = false; + + if (_socket != null) + { + _socket.Shutdown(SocketShutdown.Both); + } + } + + private Socket _socket = null; + private int _receiveTimeout = TIMEOUT_MILLISECONDS; + private int _sendTimeout = TIMEOUT_MILLISECONDS; + + private static ManualResetEvent _clientDone = new ManualResetEvent(false); + + private const int TIMEOUT_MILLISECONDS = 5000; + + } +} \ No newline at end of file diff --git a/S7.Net.Core/project.json b/S7.Net.Core/project.json new file mode 100644 index 0000000..c594939 --- /dev/null +++ b/S7.Net.Core/project.json @@ -0,0 +1,16 @@ +{ + "dependencies": { + "Microsoft.NETCore.UniversalWindowsPlatform": "5.0.0" + }, + "frameworks": { + "uap10.0": {} + }, + "runtimes": { + "win10-arm": {}, + "win10-arm-aot": {}, + "win10-x86": {}, + "win10-x86-aot": {}, + "win10-x64": {}, + "win10-x64-aot": {} + } +} \ No newline at end of file diff --git a/S7.Net/S7.Net.csproj b/S7.Net/S7.Net.csproj index 9632066..1dfda6f 100644 --- a/S7.Net/S7.Net.csproj +++ b/S7.Net/S7.Net.csproj @@ -68,24 +68,13 @@ - - - - - - - - - - - - - - - - + + + + %(RecursiveDir)%(FileName) + diff --git a/S7.sln b/S7.sln index d1dc768..4629c70 100644 --- a/S7.sln +++ b/S7.sln @@ -1,6 +1,8 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2012 +# Visual Studio 14 +VisualStudioVersion = 14.0.24720.0 +MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "S7.Net", "S7.Net\S7.Net.csproj", "{BFD484F9-3F04-42A2-BF2A-60A189A25DCF}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{7A8252C3-E6AE-435A-809D-4413C06E0711}" @@ -10,20 +12,68 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "S7.Net.UnitTest", "S7.Net.UnitTest\S7.Net.UnitTest.csproj", "{303CCED6-9ABC-4899-A509-743341AAA804}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "S7.Net.Core", "S7.Net.Core\S7.Net.Core.csproj", "{CBFF80E8-3D3D-4656-A27C-A65EA5774536}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU + Debug|ARM = Debug|ARM + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU + Release|ARM = Release|ARM + Release|x64 = Release|x64 + Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {BFD484F9-3F04-42A2-BF2A-60A189A25DCF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {BFD484F9-3F04-42A2-BF2A-60A189A25DCF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BFD484F9-3F04-42A2-BF2A-60A189A25DCF}.Debug|ARM.ActiveCfg = Debug|Any CPU + {BFD484F9-3F04-42A2-BF2A-60A189A25DCF}.Debug|ARM.Build.0 = Debug|Any CPU + {BFD484F9-3F04-42A2-BF2A-60A189A25DCF}.Debug|x64.ActiveCfg = Debug|Any CPU + {BFD484F9-3F04-42A2-BF2A-60A189A25DCF}.Debug|x64.Build.0 = Debug|Any CPU + {BFD484F9-3F04-42A2-BF2A-60A189A25DCF}.Debug|x86.ActiveCfg = Debug|Any CPU + {BFD484F9-3F04-42A2-BF2A-60A189A25DCF}.Debug|x86.Build.0 = Debug|Any CPU {BFD484F9-3F04-42A2-BF2A-60A189A25DCF}.Release|Any CPU.ActiveCfg = Release|Any CPU {BFD484F9-3F04-42A2-BF2A-60A189A25DCF}.Release|Any CPU.Build.0 = Release|Any CPU + {BFD484F9-3F04-42A2-BF2A-60A189A25DCF}.Release|ARM.ActiveCfg = Release|Any CPU + {BFD484F9-3F04-42A2-BF2A-60A189A25DCF}.Release|ARM.Build.0 = Release|Any CPU + {BFD484F9-3F04-42A2-BF2A-60A189A25DCF}.Release|x64.ActiveCfg = Release|Any CPU + {BFD484F9-3F04-42A2-BF2A-60A189A25DCF}.Release|x64.Build.0 = Release|Any CPU + {BFD484F9-3F04-42A2-BF2A-60A189A25DCF}.Release|x86.ActiveCfg = Release|Any CPU + {BFD484F9-3F04-42A2-BF2A-60A189A25DCF}.Release|x86.Build.0 = Release|Any CPU {303CCED6-9ABC-4899-A509-743341AAA804}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {303CCED6-9ABC-4899-A509-743341AAA804}.Debug|Any CPU.Build.0 = Debug|Any CPU + {303CCED6-9ABC-4899-A509-743341AAA804}.Debug|ARM.ActiveCfg = Debug|Any CPU + {303CCED6-9ABC-4899-A509-743341AAA804}.Debug|ARM.Build.0 = Debug|Any CPU + {303CCED6-9ABC-4899-A509-743341AAA804}.Debug|x64.ActiveCfg = Debug|Any CPU + {303CCED6-9ABC-4899-A509-743341AAA804}.Debug|x64.Build.0 = Debug|Any CPU + {303CCED6-9ABC-4899-A509-743341AAA804}.Debug|x86.ActiveCfg = Debug|Any CPU + {303CCED6-9ABC-4899-A509-743341AAA804}.Debug|x86.Build.0 = Debug|Any CPU {303CCED6-9ABC-4899-A509-743341AAA804}.Release|Any CPU.ActiveCfg = Release|Any CPU {303CCED6-9ABC-4899-A509-743341AAA804}.Release|Any CPU.Build.0 = Release|Any CPU + {303CCED6-9ABC-4899-A509-743341AAA804}.Release|ARM.ActiveCfg = Release|Any CPU + {303CCED6-9ABC-4899-A509-743341AAA804}.Release|ARM.Build.0 = Release|Any CPU + {303CCED6-9ABC-4899-A509-743341AAA804}.Release|x64.ActiveCfg = Release|Any CPU + {303CCED6-9ABC-4899-A509-743341AAA804}.Release|x64.Build.0 = Release|Any CPU + {303CCED6-9ABC-4899-A509-743341AAA804}.Release|x86.ActiveCfg = Release|Any CPU + {303CCED6-9ABC-4899-A509-743341AAA804}.Release|x86.Build.0 = Release|Any CPU + {CBFF80E8-3D3D-4656-A27C-A65EA5774536}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CBFF80E8-3D3D-4656-A27C-A65EA5774536}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CBFF80E8-3D3D-4656-A27C-A65EA5774536}.Debug|ARM.ActiveCfg = Debug|ARM + {CBFF80E8-3D3D-4656-A27C-A65EA5774536}.Debug|ARM.Build.0 = Debug|ARM + {CBFF80E8-3D3D-4656-A27C-A65EA5774536}.Debug|x64.ActiveCfg = Debug|x64 + {CBFF80E8-3D3D-4656-A27C-A65EA5774536}.Debug|x64.Build.0 = Debug|x64 + {CBFF80E8-3D3D-4656-A27C-A65EA5774536}.Debug|x86.ActiveCfg = Debug|x86 + {CBFF80E8-3D3D-4656-A27C-A65EA5774536}.Debug|x86.Build.0 = Debug|x86 + {CBFF80E8-3D3D-4656-A27C-A65EA5774536}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CBFF80E8-3D3D-4656-A27C-A65EA5774536}.Release|Any CPU.Build.0 = Release|Any CPU + {CBFF80E8-3D3D-4656-A27C-A65EA5774536}.Release|ARM.ActiveCfg = Release|ARM + {CBFF80E8-3D3D-4656-A27C-A65EA5774536}.Release|ARM.Build.0 = Release|ARM + {CBFF80E8-3D3D-4656-A27C-A65EA5774536}.Release|x64.ActiveCfg = Release|x64 + {CBFF80E8-3D3D-4656-A27C-A65EA5774536}.Release|x64.Build.0 = Release|x64 + {CBFF80E8-3D3D-4656-A27C-A65EA5774536}.Release|x86.ActiveCfg = Release|x86 + {CBFF80E8-3D3D-4656-A27C-A65EA5774536}.Release|x86.Build.0 = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE