Example #1
0
        void IMODBUSResponseMessage.Initialize(byte[] frame, bool isExtendedUnitId, IMODBUSRequestMessage requestMessage)
        {
            base.Initialize(frame, isExtendedUnitId);

            var dataLength = isExtendedUnitId ? frame[3] : frame[2];

            var readCoilRegistersRequest = requestMessage as ReadCoilRegistersRequest;

            if (readCoilRegistersRequest != null)
            {
                this.CoilRegisters = readCoilRegistersRequest.CoilRegisters;

                data = new byte[dataLength + 1];

                if (isExtendedUnitId)
                {
                    Buffer.BlockCopy(frame, 3, data, 0, dataLength + 1);
                }
                else
                {
                    Buffer.BlockCopy(frame, 2, data, 0, dataLength + 1);
                }

                var coilValues = new BitArray(data);

                for (int i = 0; i < this.CoilRegisters.Count; i++)
                {
                    ((IMODBUSRegisterData)this.CoilRegisters[i]).Data = BitConverter.GetBytes(coilValues[i + 8]);
                }
            }
            else
            {
                throw new FormatException("Unable to create response message (request message null).");
            }
        }
Example #2
0
        void IMODBUSResponseMessage.Initialize(byte[] frame, bool isExtendedUnitId, IMODBUSRequestMessage requestMessage)
        {
            base.Initialize(frame, isExtendedUnitId);

            var dataLength = isExtendedUnitId ? 5 : 4;

            var writeBooleanRequest = requestMessage as WriteBooleanRequest;

            if (writeBooleanRequest != null)
            {
                data = new byte[dataLength];

                if (isExtendedUnitId)
                {
                    Buffer.BlockCopy(frame, 3, data, 0, dataLength);
                }
                else
                {
                    Buffer.BlockCopy(frame, 2, data, 0, dataLength);
                }
            }
            else
            {
                throw new FormatException("Unable to create response message (request message null).");
            }
        }
Example #3
0
        void IMODBUSResponseMessage.Initialize(byte[] frame, bool isExtendedUnitId, IMODBUSRequestMessage requestMessage)
        {
            base.Initialize(frame, isExtendedUnitId);

            var dataLength = isExtendedUnitId ? frame[3] : frame[2];

            var readEventArchiveRequest = requestMessage as ReadEventArchiveRequest;

            if (readEventArchiveRequest != null)
            {
                data = new byte[dataLength + 1];

                if (isExtendedUnitId)
                {
                    Buffer.BlockCopy(frame, 3, data, 0, dataLength + 1);
                }
                else
                {
                    Buffer.BlockCopy(frame, 2, data, 0, dataLength + 1);
                }

                this.EventArchiveRecords = new List <EventArchiveRecord>();

                for (int i = 1; i < dataLength; i += 20)
                {
                    var eventData = new byte[20];
                    Buffer.BlockCopy(data, i, eventData, 0, 20);
                    this.EventArchiveRecords.Add(new EventArchiveRecord(readEventArchiveRequest.Index, eventData));
                }
            }
            else
            {
                throw new FormatException("Unable to create response message (request message null).");
            }
        }
Example #4
0
        void IMODBUSResponseMessage.Initialize(byte[] frame, bool isExtendedUnitId, IMODBUSRequestMessage requestMessage)
        {
            base.Initialize(frame, isExtendedUnitId);

            var dataLength = isExtendedUnitId ? frame[3] : frame[2];

            var readHistoryArchiveRequest = requestMessage as ReadHistoryArchiveRequest;

            if (readHistoryArchiveRequest != null)
            {
                data = new byte[dataLength + 1];

                if (isExtendedUnitId)
                {
                    Buffer.BlockCopy(frame, 3, data, 0, dataLength + 1);
                }
                else
                {
                    Buffer.BlockCopy(frame, 2, data, 0, dataLength + 1);
                }

                var historyData = new byte[dataLength];

                Buffer.BlockCopy(data, 1, historyData, 0, dataLength);

                this.HistoryArchiveRecord = new HistoryArchiveRecord(readHistoryArchiveRequest.Index, historyData);
            }
            else
            {
                throw new FormatException("Unable to create response message (request message null).");
            }
        }
Example #5
0
        void IMODBUSResponseMessage.Initialize(byte[] frame, bool isExtendedUnitId, IMODBUSRequestMessage requestMessage)
        {
            base.Initialize(frame, isExtendedUnitId);

            var writeFloatsRequest = requestMessage as WriteFloatsRequest;

            if (writeFloatsRequest != null)
            {
                data = new byte[4];

                if (isExtendedUnitId)
                {
                    Buffer.BlockCopy(frame, 3, data, 0, 4);
                }
                else
                {
                    Buffer.BlockCopy(frame, 2, data, 0, 4);
                }

                this.isZeroBased = writeFloatsRequest.FloatRegisters[0].Address.IsZeroBased;
            }
            else
            {
                throw new FormatException("Unable to create response message (request message null).");
            }
        }
        void IMODBUSResponseMessage.Initialize(byte[] frame, bool isExtendedUnitId, IMODBUSRequestMessage requestMessage)
        {
            base.Initialize(frame, isExtendedUnitId);

            var dataLength = isExtendedUnitId ? frame[3] : frame[2];

            var readStringRequest = requestMessage as ReadStringRequest;

            if (readStringRequest != null)
            {
                data = new byte[dataLength + 1];

                if (isExtendedUnitId)
                {
                    Buffer.BlockCopy(frame, 3, data, 0, dataLength + 1);
                }
                else
                {
                    Buffer.BlockCopy(frame, 2, data, 0, dataLength + 1);
                }

                this.StringRegister = readStringRequest.StringRegister;

                var stringData = new byte[StringRegister.Length];

                Buffer.BlockCopy(data, 1, stringData, 0, dataLength);

                this.StringRegister.Data = stringData;
            }
            else
            {
                throw new FormatException("Unable to create response message (request message null).");
            }
        }
Example #7
0
        void IMODBUSResponseMessage.Initialize(byte[] frame, bool isExtendedUnitId, IMODBUSRequestMessage requestMessage)
        {
            base.Initialize(frame, isExtendedUnitId);

            if (frame.Length < (IsExtendedUnitId ? Device.MinimumFrameSizeWithExtendedUnitId : Device.MinimumFrameSize))
            {
                throw new FormatException("Message frame does not contain enough bytes.");
            }

            ErrorCode = IsExtendedUnitId ? frame[3] : frame[2];
        }
Example #8
0
        internal IMODBUSResponseMessage ReadResponse <TResponseMessage>(IMODBUSRequestMessage requestMessage)
            where TResponseMessage : IMODBUSResponseMessage, new()
        {
            var sequence = 0;
            var referenceHeader = requestMessage.IsExtendedUnitId ? BitConverter.GetBytes(requestMessage.UnitId).Concat(new byte[] { requestMessage.FunctionCode }) : new byte[] { Convert.ToByte(requestMessage.UnitId) }.Concat(new byte[] { requestMessage.FunctionCode });
            var errorHeader = requestMessage.IsExtendedUnitId ? BitConverter.GetBytes(requestMessage.UnitId).Concat(new byte[] { Convert.ToByte(requestMessage.FunctionCode + 128) }) : new byte[] { Convert.ToByte(requestMessage.UnitId) }.Concat(new byte[] { Convert.ToByte(requestMessage.FunctionCode + 128) });
            var header = Read(requestMessage.IsExtendedUnitId ? RESPONSE_HEADER_LENGTH_WITH_EXTENDED_UNIT_ID : RESPONSE_HEADER_LENGTH, sequence);

            while ((!header.SequenceEqual(referenceHeader)) && (!header.SequenceEqual(errorHeader)))
            {
                sequence++;
                var streamByte = Read(1, sequence)[0];
                if (requestMessage.IsExtendedUnitId)
                {
                    header = new byte[] { header[1], header[2], streamByte };
                }
                else
                {
                    header = new byte[] { header[1], streamByte };
                }
            }

            var frameStart = header.Concat(Read(RESPONSE_DATA_START_LENGTH, sequence)).ToArray();

            sequence++;
            var numberOfBytesToRead = ResponseBytesToRead(frameStart, requestMessage.IsExtendedUnitId);
            var frameEnd            = Read(numberOfBytesToRead, sequence);

            sequence++;
            var frameBytes = frameStart.Concat(frameEnd).ToArray();

            sequence++;

            var numberOfBytesAvailable = Channel.NumberOfBytesAvailable;

            while (numberOfBytesAvailable > 0)
            {
                sequence++;
                Read(numberOfBytesAvailable, (-1 * sequence));
                Thread.Sleep(0);
                numberOfBytesAvailable = Channel.NumberOfBytesAvailable;
            }

            var responseMessage = CreateResponse <TResponseMessage>(frameBytes, requestMessage);

            if (!ChecksumsMatch(responseMessage, frameBytes))
            {
                throw new IOException("Checksum Error");
            }

            return(responseMessage);
        }
Example #9
0
        internal void ValidateResponse(IMODBUSRequestMessage request, IMODBUSResponseMessage response)
        {
            if (request.FunctionCode != response.FunctionCode)
            {
                throw new IOException(String.Format(CultureInfo.InvariantCulture, "Received response with unexpected function code. Expected {0}, received {1}.", request.FunctionCode, response.FunctionCode));
            }

            if (request.UnitId != response.UnitId)
            {
                throw new IOException(String.Format(CultureInfo.InvariantCulture, "Response source unit does not match request. Expected {0}, received {1}.", response.UnitId, request.UnitId));
            }

            request.ValidateResponse(response);
        }
Example #10
0
        void IMODBUSResponseMessage.Initialize(byte[] frame, bool isExtendedUnitId, IMODBUSRequestMessage requestMessage)
        {
            base.Initialize(frame, isExtendedUnitId);

            var dataLength = isExtendedUnitId ? frame[3] : frame[2];

            var readShortsRequest = requestMessage as ReadShortsRequest;

            if (readShortsRequest != null)
            {
                this.ShortRegisters = readShortsRequest.ShortRegisters;

                data = new byte[dataLength + 1];

                if (isExtendedUnitId)
                {
                    Buffer.BlockCopy(frame, 3, data, 0, dataLength + 1);
                }
                else
                {
                    Buffer.BlockCopy(frame, 2, data, 0, dataLength + 1);
                }

                var shortRegisters = new List <ShortRegister>();

                for (int i = 1; i < data.Length; i += 2)
                {
                    var shortData = new byte[] { data[i], data[i + 1] };
                    ((IMODBUSRegisterData)this.ShortRegisters[((i - 1) / 2)]).Data = shortData;
                }
            }
            else
            {
                throw new FormatException("Unable to create response message (request message null).");
            }
        }
        public static IMODBUSResponseMessage CreateMODBUSResponseMessage <TResponseMessage>(byte[] frame, bool isExtendedUnitId, IMODBUSRequestMessage requestMessage)
            where TResponseMessage : IMODBUSResponseMessage, new()
        {
            TResponseMessage responseMessage = new TResponseMessage();

            responseMessage.Initialize(frame, isExtendedUnitId, requestMessage);
            return(responseMessage);
        }
Example #12
0
        internal virtual TResponseMessage UnicastMessage <TResponseMessage>(IMODBUSRequestMessage requestMessage)
            where TResponseMessage : IMODBUSResponseMessage, new()
        {
            if (TracingEnabled)
            {
                Trace.WriteLine(string.Format("Function {0} Request Started At: {1}", requestMessage.FunctionCode.ToString(), DateTime.Now.ToString("O"), "Transport"));
            }
            var lastException               = (Exception)null;
            var transactionStopWatch        = Stopwatch.StartNew();
            IMODBUSResponseMessage response = default(TResponseMessage);
            int  attempt = 0;
            bool success = false;

            lock (channelLock)
            {
                do
                {
                    try
                    {
                        attempt++;
                        if (RequestWriteDelayMilliseconds > 0)
                        {
                            if (TracingEnabled)
                            {
                                Trace.WriteLine(string.Format("Function {0} Request Write Delay: {1}ms", requestMessage.FunctionCode.ToString(), RequestWriteDelayMilliseconds.ToString("0.0")), "Transport");
                            }
                            TimedThreadBlocker.Wait(RequestWriteDelayMilliseconds);
                        }
                        Write(requestMessage);
                        if (ResponseReadDelayMilliseconds > 0)
                        {
                            if (TracingEnabled)
                            {
                                Trace.WriteLine(string.Format("Function {0} Request Read Delay: {1}", requestMessage.FunctionCode.ToString(), ResponseReadDelayMilliseconds.ToString("0.0")), "Transport");
                            }
                            TimedThreadBlocker.Wait(RequestWriteDelayMilliseconds);
                        }
                        response = ReadResponse <TResponseMessage>(requestMessage);
                        if (response is MODBUSErrorResponse)
                        {
                            throw new MODBUSSlaveException(response as MODBUSErrorResponse);
                        }
                        else
                        {
                            ValidateResponse(requestMessage, response);
                            transactionStopWatch.Stop();
                            if (TracingEnabled)
                            {
                                Trace.WriteLine(string.Format("Function {0} Request Completed in: {1}ms", requestMessage.FunctionCode.ToString(), transactionStopWatch.Elapsed.TotalMilliseconds.ToString()), "Transport");
                            }

                            return((TResponseMessage)response);
                        }
                    }
                    catch (Exception e)
                    {
                        lastException = e;
                        Trace.WriteLine(string.Format("Function {0} Request Error: {1}", requestMessage.FunctionCode.ToString(), e.Message), "Transport");
                        if (e is FormatException ||
                            e is NotImplementedException ||
                            e is TimeoutException ||
                            e is IOException)
                        {
                            if (attempt > NumberOfRetries)
                            {
                                goto Finish;
                            }
                            else
                            {
                                TimedThreadBlocker.Wait(WaitToRetryMilliseconds);
                            }
                        }
                        else
                        {
                            throw;
                        }
                    }
                    if (TracingEnabled)
                    {
                        Trace.WriteLine(string.Format("Function {0} Request Retry Number {1}", requestMessage.FunctionCode.ToString(), attempt.ToString()), "Transport");
                    }
                } while (!success && NumberOfRetries > attempt);
            }
Finish:
            throw new TimeoutException("Device not responding to requests", lastException);
        }
Example #13
0
        internal virtual IMODBUSResponseMessage CreateResponse <TResponseMessage>(byte[] frame, IMODBUSRequestMessage requestMessage)
            where TResponseMessage : IMODBUSResponseMessage, new()
        {
            byte functionCode = (requestMessage.IsExtendedUnitId ? frame[2] : frame[1]);

            IMODBUSResponseMessage response;

            switch (functionCode)
            {
            case Device.ReadCoils:
                response = MODBUSMessageFactory.CreateMODBUSResponseMessage <ReadCoilRegistersResponse>(frame, requestMessage.IsExtendedUnitId, requestMessage);
                break;

            case Device.ReadDiscreteInputs:
                response = MODBUSMessageFactory.CreateMODBUSResponseMessage <ReadDiscreteInputRegistersResponse>(frame, requestMessage.IsExtendedUnitId, requestMessage);
                break;

            case Device.WriteSingleCoil:
                response = MODBUSMessageFactory.CreateMODBUSResponseMessage <WriteBooleanResponse>(frame, requestMessage.IsExtendedUnitId, requestMessage);
                break;

            case Device.ReadInputRegisters:
                response = MODBUSMessageFactory.CreateMODBUSResponseMessage <ReadInputRegistersResponse>(frame, requestMessage.IsExtendedUnitId, requestMessage);
                break;

            case Device.ReadHoldingRegisters:
                switch (requestMessage.DataType)
                {
                case Device.DataType.EventArchive:
                    response = MODBUSMessageFactory.CreateMODBUSResponseMessage <ReadEventArchiveResponse>(frame, requestMessage.IsExtendedUnitId, requestMessage);
                    break;

                case Device.DataType.HistoryArchive:
                    response = MODBUSMessageFactory.CreateMODBUSResponseMessage <ReadHistoryArchiveResponse>(frame, requestMessage.IsExtendedUnitId, requestMessage);
                    break;

                case Device.DataType.Short:
                    response = MODBUSMessageFactory.CreateMODBUSResponseMessage <ReadShortsResponse>(frame, requestMessage.IsExtendedUnitId, requestMessage);
                    break;

                case Device.DataType.Long:
                    response = MODBUSMessageFactory.CreateMODBUSResponseMessage <ReadLongsResponse>(frame, requestMessage.IsExtendedUnitId, requestMessage);
                    break;

                case Device.DataType.String:
                    response = MODBUSMessageFactory.CreateMODBUSResponseMessage <ReadStringResponse>(frame, requestMessage.IsExtendedUnitId, requestMessage);
                    break;

                case Device.DataType.Float:
                    response = MODBUSMessageFactory.CreateMODBUSResponseMessage <ReadFloatsResponse>(frame, requestMessage.IsExtendedUnitId, requestMessage);
                    break;

                default:
                    response = MODBUSMessageFactory.CreateMODBUSResponseMessage <ReadHoldingRegistersResponse>(frame, requestMessage.IsExtendedUnitId, requestMessage);
                    break;
                }
                break;

            case Device.WriteMultipleRegisters:
                response = MODBUSMessageFactory.CreateMODBUSResponseMessage <WriteFloatsResponse>(frame, requestMessage.IsExtendedUnitId, requestMessage);
                break;

            default:
                if (functionCode > Device.ExceptionOffset)
                {
                    response = MODBUSMessageFactory.CreateMODBUSResponseMessage <MODBUSErrorResponse>(frame, requestMessage.IsExtendedUnitId);
                    break;
                }
                else
                {
                    throw new FormatException(string.Format("Unknown Function Code ({0}).", functionCode.ToString()));
                }
            }

            return(response);
        }