예제 #1
0
        public ErrorCode WriteBytes(DataType dataType, int db, int startByteAdr, byte[] value)
        {
            //TODO: implement support for dynamic PDU Size (208+32 / 448+32 / 928+32
            byte[] bReceive = new byte[512];
            int    varCount = 0;

            try
            {
                varCount = value.Length;
                // first create the header
                int             packageSize = 35 + value.Length;
                Types.ByteArray package     = new Types.ByteArray(packageSize);

                //TODO: dirty mixed dez/hex
                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);

                //TODO: ugly way to ensure addresses like : DB999.8192 are writable
                if (startByteAdr > 8191)
                {
                    package.Add((byte)1);
                }
                else
                {
                    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, SocketFlags.None);

                int numReceived = _mSocket.Receive(bReceive, 512, SocketFlags.None);
                if (bReceive[21] != 0xff)
                {
                    throw new Exception(ErrorCode.WrongNumberReceivedBytes.ToString());
                }

                return(ErrorCode.NoError);
            }
            catch
            {
                LastErrorCode   = ErrorCode.WriteData;
                LastErrorString = "";
                return(LastErrorCode);
            }
        }
예제 #2
0
        private async Task <ErrorCode> WriteBitWithASingleRequestAsync(DataType dataType, int db, int startByteAdr, int bitAdr, bool bitValue)
        {
            byte[] bReceive = new byte[513];
            int    varCount = 0;

            try
            {
                var value = new[] { bitValue ? (byte)1 : (byte)0 };
                varCount = value.Length;
                // first create the header
                int       packageSize = 35 + value.Length;
                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(Word.ToByteArray((ushort)(varCount - 1)));
                package.Add(new byte[] { 0, 0x0e });
                package.Add(Word.ToByteArray((ushort)(varCount + 4)));
                package.Add(new byte[] { 0x05, 0x01, 0x12, 0x0a, 0x10, 0x01 }); //ending 0x01 is used for writing a sinlge bit
                package.Add(Word.ToByteArray((ushort)varCount));
                package.Add(Word.ToByteArray((ushort)(db)));
                package.Add((byte)dataType);
                int overflow = (int)(startByteAdr * 8 / 0xffffU); // handles words with address bigger than 8191
                package.Add((byte)overflow);
                package.Add(Word.ToByteArray((ushort)(startByteAdr * 8 + bitAdr)));
                package.Add(new byte[] { 0, 0x03 }); //ending 0x03 is used for writing a sinlge bit
                package.Add(Word.ToByteArray((ushort)(varCount)));

                // now join the header and the data
                package.Add(value);

                await stream.WriteAsync(package.Array, 0, package.Array.Length);

                var s7data = await COTP.TSDU.ReadAsync(stream);

                if (s7data == null || s7data[14] != 0xff)
                {
                    throw new Exception(ErrorCode.WrongNumberReceivedBytes.ToString());
                }

                return(ErrorCode.NoError);
            }
            catch (Exception exc)
            {
                LastErrorCode   = ErrorCode.WriteData;
                LastErrorString = exc.Message;
                return(LastErrorCode);
            }
        }
예제 #3
0
파일: PLC.cs 프로젝트: suribes/s7netplus
        /// <summary>
        /// Writes up to 200 bytes to the plc and returns NoError if successful. You must specify the memory area type, memory are address, byte start address and bytes count.
        /// If the write was not successful, check LastErrorCode or LastErrorString.
        /// </summary>
        /// <param name="dataType">Data type of the memory area, can be DB, Timer, Counter, Merker(Memory), Input, Output.</param>
        /// <param name="db">Address of the memory area (if you want to read DB1, this is set to 1). This must be set also for other memory area types: counters, timers,etc.</param>
        /// <param name="startByteAdr">Start byte address. If you want to read DB1.DBW200, this is 200.</param>
        /// <param name="value">Bytes to write. The lenght of this parameter can't be higher than 200. If you need more, use recursion.</param>
        /// <returns>NoError if it was successful, or the error is specified</returns>
        private ErrorCode WriteBytesWithASingleRequest(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);
                var overflow = (int)(startByteAdr * 8 / 0xffffU); // handles words with address bigger than 8191
                package.Add((byte)overflow);
                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, SocketFlags.None);

                int numReceived = _mSocket.Receive(bReceive, 512, SocketFlags.None);
                if (bReceive[21] != 0xff)
                {
                    throw new Exception(ErrorCode.WrongNumberReceivedBytes.ToString());
                }

                return(ErrorCode.NoError);
            }
            catch (Exception exc)
            {
                LastErrorCode   = ErrorCode.WriteData;
                LastErrorString = exc.Message;
                return(LastErrorCode);
            }
        }
예제 #4
0
        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, SocketFlags.None);

                int numReceived = _mSocket.Receive(bReceive, 512, SocketFlags.None);
                if (bReceive[21] != 0xff)
                {
                    throw new Exception(ErrorCode.WrongNumberReceivedBytes.ToString());
                }

                return(ErrorCode.NoError);
            }
            catch
            {
                LastErrorCode   = ErrorCode.WriteData;
                LastErrorString = "";
                return(LastErrorCode);
            }
        }
예제 #5
0
파일: PLC.cs 프로젝트: suribes/s7netplus
        /// <summary>
        /// Creates the header to read bytes from the plc
        /// </summary>
        /// <param name="amount"></param>
        /// <returns></returns>
        private Types.ByteArray ReadHeaderPackage(int amount = 1)
        {
            //header size = 19 bytes
            var package = new Types.ByteArray(19);

            package.Add(new byte[] { 0x03, 0x00, 0x00 });
            //complete package size
            package.Add((byte)(19 + (12 * amount)));
            package.Add(new byte[] { 0x02, 0xf0, 0x80, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00 });
            //data part size
            package.Add(Types.Word.ToByteArray((ushort)(2 + (amount * 12))));
            package.Add(new byte[] { 0x00, 0x00, 0x04 });
            //amount of requests
            package.Add((byte)amount);

            return(package);
        }
예제 #6
0
        /// <summary>
        /// Convert S7 Byte Array to x86 Byte Array
        /// </summary>
        /// <param name="value">byte array</param>
        /// <param name="dimension">array length</param>
        /// <returns></returns>
        public static byte[] SwapByte(this byte[] value, int dimension)
        {
            Types.ByteArray swapByte = new Types.ByteArray();

            if (dimension > 1)
            {
                swapByte.Add(value[1]);
                swapByte.Add(value[0]);
            }

            if (dimension > 3)
            {
                swapByte.Add(value[3]);
                swapByte.Add(value[2]);
            }

            return(swapByte.array);
        }
예제 #7
0
파일: PLC.cs 프로젝트: suribes/s7netplus
        /// <summary>
        /// Create the bytes-package to request data from the plc. You have to specify the memory type (dataType),
        /// the address of the memory, the address of the byte and the bytes count.
        /// </summary>
        /// <param name="dataType">MemoryType (DB, Timer, Counter, etc.)</param>
        /// <param name="db">Address of the memory to be read</param>
        /// <param name="startByteAdr">Start address of the byte</param>
        /// <param name="count">Number of bytes to be read</param>
        /// <returns></returns>
        private Types.ByteArray CreateReadDataRequestPackage(DataType dataType, int db, int startByteAdr, int count = 1)
        {
            //single data req = 12
            var package = new Types.ByteArray(12);

            package.Add(new byte[] { 0x12, 0x0a, 0x10 });
            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);
            var overflow = (int)(startByteAdr * 8 / 0xffffU); // handles words with address bigger than 8191

            package.Add((byte)overflow);
            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;
            }

            return(package);
        }
예제 #8
0
파일: PLC.cs 프로젝트: Katsarakis/s7netplus
        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, SocketFlags.None);

                int numReceived = _mSocket.Receive(bReceive, 512, SocketFlags.None);
                if (bReceive[21] != 0xff)
                {
                    throw new Exception(ErrorCode.WrongNumberReceivedBytes.ToString());
                }

                return ErrorCode.NoError;
            }
            catch
            {
                LastErrorCode = ErrorCode.WriteData;
                LastErrorString = "";
                return LastErrorCode;
            }
        }
예제 #9
0
파일: PLC.cs 프로젝트: Katsarakis/s7netplus
        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, SocketFlags.None);

                byte[] bReceive = new byte[512];
                int numReceived = _mSocket.Receive(bReceive, 512, SocketFlags.None);
                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)
            {
                IsConnected = false;
                LastErrorCode = ErrorCode.WriteData;
                LastErrorString = socketException.Message;
                return null;
            }
            catch(Exception exc)
            {
                LastErrorCode = ErrorCode.WriteData;
                LastErrorString = exc.Message;
                return null;
            }
        }
예제 #10
0
파일: PLC.cs 프로젝트: killnine/s7netplus
        /// <summary>
        /// Create the bytes-package to request data from the plc. You have to specify the memory type (dataType), 
        /// the address of the memory, the address of the byte and the bytes count. 
        /// </summary>
        /// <param name="dataType">MemoryType (DB, Timer, Counter, etc.)</param>
        /// <param name="db">Address of the memory to be read</param>
        /// <param name="startByteAdr">Start address of the byte</param>
        /// <param name="count">Number of bytes to be read</param>
        /// <returns></returns>
        private Types.ByteArray CreateReadDataRequestPackage(DataType dataType, int db, int startByteAdr, int count = 1)
        {
            //single data req = 12
            var package = new Types.ByteArray(12);
            package.Add(new byte[] { 0x12, 0x0a, 0x10 });
            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);
            var overflow = (int)(startByteAdr * 8 / 0xffffU); // handles words with address bigger than 8191
            package.Add((byte)overflow);
            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;
            }

            return package;
        }
예제 #11
0
파일: PLC.cs 프로젝트: killnine/s7netplus
        /// <summary>
        /// Writes up to 200 bytes to the plc and returns NoError if successful. You must specify the memory area type, memory are address, byte start address and bytes count.
        /// If the write was not successful, check LastErrorCode or LastErrorString.
        /// </summary>
        /// <param name="dataType">Data type of the memory area, can be DB, Timer, Counter, Merker(Memory), Input, Output.</param>
        /// <param name="db">Address of the memory area (if you want to read DB1, this is set to 1). This must be set also for other memory area types: counters, timers,etc.</param>
        /// <param name="startByteAdr">Start byte address. If you want to read DB1.DBW200, this is 200.</param>
        /// <param name="value">Bytes to write. The lenght of this parameter can't be higher than 200. If you need more, use recursion.</param>
        /// <returns>NoError if it was successful, or the error is specified</returns>
        private ErrorCode WriteBytesWithASingleRequest(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);
                var overflow = (int)(startByteAdr * 8 / 0xffffU); // handles words with address bigger than 8191
                package.Add((byte)overflow);
                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, SocketFlags.None);

                int numReceived = _mSocket.Receive(bReceive, 512, SocketFlags.None);
                if (bReceive[21] != 0xff)
                {
                    throw new Exception(ErrorCode.WrongNumberReceivedBytes.ToString());
                }

                return ErrorCode.NoError;
            }
            catch (Exception exc)
            {
                LastErrorCode = ErrorCode.WriteData;
                LastErrorString = exc.Message;
                return LastErrorCode;
            }
        }
예제 #12
0
파일: PLC.cs 프로젝트: killnine/s7netplus
        /// <summary>
        /// Creates the header to read bytes from the plc
        /// </summary>
        /// <param name="amount"></param>
        /// <returns></returns>
        private Types.ByteArray ReadHeaderPackage(int amount = 1)
        {
            //header size = 19 bytes
            var package = new Types.ByteArray(19);
            package.Add(new byte[] { 0x03, 0x00, 0x00 });
            //complete package size
            package.Add((byte)(19 + (12 * amount)));
            package.Add(new byte[] { 0x02, 0xf0, 0x80, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00 });
            //data part size
            package.Add(Types.Word.ToByteArray((ushort)(2 + (amount * 12))));
            package.Add(new byte[] { 0x00, 0x00, 0x04 });
            //amount of requests
            package.Add((byte)amount);

            return package;
        }
예제 #13
0
파일: PLC.cs 프로젝트: jobmeij/s7netplus
        public byte[] ReadBytes(DataType dataType, int DB, int startByteAdr, int count)
        {
            //TODO: implement check count <= PDU Size - 32 and throw exception
            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 });
                //switch datatype dynamicly
                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);

                //TODO: ugly way to ensure addresses like : DB999.8192 are readable
                if (startByteAdr > 8191)
                {
                    package.Add((byte)1);
                }
                else
                {
                    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, SocketFlags.None);

                //TODO: implement support for dynamic PDU Size (208+32 / 448+32 / 928+32)
                byte[] bReceive = new byte[512];
                int numReceived = _mSocket.Receive(bReceive, 512, SocketFlags.None);
                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;
            }
        }
예제 #14
0
파일: PLC.cs 프로젝트: jobmeij/s7netplus
        public ErrorCode WriteBytes(DataType dataType, int db, int startByteAdr, byte[] value)
        {
            //TODO: implement support for dynamic PDU Size (208+32 / 448+32 / 928+32
            byte[] bReceive = new byte[512];
            int varCount = 0;

            try
            {
                varCount = value.Length;
                // first create the header
                int packageSize = 35 + value.Length;
                Types.ByteArray package = new Types.ByteArray(packageSize);

                //TODO: dirty mixed dez/hex
                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);

                //TODO: ugly way to ensure addresses like : DB999.8192 are writable
                if (startByteAdr > 8191)
                {
                    package.Add((byte)1);
                }
                else
                {
                    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, SocketFlags.None);

                int numReceived = _mSocket.Receive(bReceive, 512, SocketFlags.None);
                if (bReceive[21] != 0xff)
                {
                    throw new Exception(ErrorCode.WrongNumberReceivedBytes.ToString());
                }

                return ErrorCode.NoError;
            }
            catch
            {
                LastErrorCode = ErrorCode.WriteData;
                LastErrorString = "";
                return LastErrorCode;
            }
        }
예제 #15
0
        public byte[] ReadBytes(DataType dataType, int DB, int startByteAdr, int count)
        {
            //TODO: implement check count <= PDU Size - 32 and throw exception
            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 });
                //switch datatype dynamicly
                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);

                //TODO: ugly way to ensure addresses like : DB999.8192 are readable
                if (startByteAdr > 8191)
                {
                    package.Add((byte)1);
                }
                else
                {
                    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, SocketFlags.None);

                //TODO: implement support for dynamic PDU Size (208+32 / 448+32 / 928+32)
                byte[] bReceive    = new byte[512];
                int    numReceived = _mSocket.Receive(bReceive, 512, SocketFlags.None);
                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);
            }
        }
예제 #16
0
        /// <summary>
        /// Convert S7 Byte Array to x86 Byte Array
        /// </summary>
        /// <param name="value">byte array</param>
        /// <param name="dimension">array length</param>
        /// <returns></returns>
        public static byte[] SwapByte(this byte[] value, int dimension)
        {
            Types.ByteArray swapByte = new Types.ByteArray();

            if (dimension > 1)
            {
                swapByte.Add(value[1]);
                swapByte.Add(value[0]);
            }

            if (dimension > 3)
            {
                swapByte.Add(value[3]);
                swapByte.Add(value[2]);
            }

            return swapByte.array;
        }
예제 #17
0
        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);
                var overflow = (int)(startByteAdr * 8 / 0xffffU); // handles words with address bigger than 8191
                package.Add((byte)overflow);
                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);
            }
        }
예제 #18
0
 public void Add(ByteArray byteArray)
 {
     list.AddRange(byteArray.array);
 }