Example #1
0
            private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
            {
                var startTime  = DateTime.Now;
                var lockObject = SourceChannel.LockObject;

                lock (lockObject)
                {
                    var masterStopWatch = new Stopwatch();
                    var requestBytes    = new byte[] { };

                    TimedThreadBlocker.Wait(requestDelay);

                    requestBytes = new byte[SerialPort.BytesToRead];

                    if (requestBytes.Length > 0)
                    {
                        Read(ref requestBytes, 0, requestBytes.Length, 0);
                        SourceChannel.Write(ref requestBytes, 0, requestBytes.Length);
                        TimedThreadBlocker.Wait(responseDelay);
                        masterStopWatch.Start();

                        var sequence = 0;
                        while (SourceChannel.NumberOfBytesAvailable > 0 && responseTimeout > masterStopWatch.ElapsedMilliseconds)
                        {
                            var responseBytes = new byte[SourceChannel.NumberOfBytesAvailable];

                            SourceChannel.Read(ref responseBytes, 0, responseBytes.Length, sequence++);
                            Write(ref responseBytes, 0, responseBytes.Length);
                        }

                        masterStopWatch.Stop();
                    }
                }
            }
Example #2
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 #3
0
        internal virtual TResponseMessage UnicastMessage <TResponseMessage>(IROCRequestMessage requestMessage)
            where TResponseMessage : IROCResponseMessage, new()
        {
            if (TracingEnabled)
            {
                Trace.WriteLine(string.Format("ROCMaster.Transport,WriteDelay,{0},{1}", requestMessage.OpCode.ToString(), DateTime.Now.ToString("O"), "Transport"));
            }
            var lastException                   = (Exception)null;
            var transactionStopWatch            = Stopwatch.StartNew();
            IROCResponseMessage responseMessage = default(TResponseMessage);
            int    attempt     = 0;
            bool   success     = false;
            object channelLock = Channel.LockObject;

            lock (channelLock)
            {
                do
                {
                    try
                    {
                        attempt++;
                        if (RequestWriteDelayMilliseconds > 0)
                        {
                            if (TracingEnabled)
                            {
                                Trace.WriteLine(string.Format("ROCMaster.Transport,WriteDelay,{0},{1}", requestMessage.OpCode.ToString(), RequestWriteDelayMilliseconds.ToString("0.0")));
                            }
                            TimedThreadBlocker.Wait(RequestWriteDelayMilliseconds);
                        }
                        Write(requestMessage);
                        if (ResponseReadDelayMilliseconds > 0)
                        {
                            if (TracingEnabled)
                            {
                                Trace.WriteLine(string.Format("ROCMaster.Transport,ReadDelay,{0},{1}", requestMessage.OpCode.ToString(), ResponseReadDelayMilliseconds.ToString("0.0")));
                            }
                            TimedThreadBlocker.Wait(RequestWriteDelayMilliseconds);
                        }
                        responseMessage = ReadResponse <TResponseMessage>(requestMessage);
                        if (responseMessage.OpCode == 255)
                        {
                            var opCode255Response = responseMessage as OpCode255Response;
                            if (opCode255Response != null)
                            {
                                throw new OpCode255Exception(opCode255Response);
                            }
                        }
                        else
                        {
                            ValidateResponse(requestMessage, responseMessage);
                            transactionStopWatch.Stop();
                            if (TracingEnabled)
                            {
                                Trace.WriteLine(string.Format("ROCMaster.Transport,Read,{0},{1},{3},{4}", requestMessage.OpCode.ToString(), transactionStopWatch.Elapsed.TotalMilliseconds.ToString(), HexConverter.ToHexString(requestMessage.ProtocolDataUnit), HexConverter.ToHexString(responseMessage.ProtocolDataUnit), ""));
                            }
                            return((TResponseMessage)responseMessage);
                        }
                    }
                    catch (Exception e)
                    {
                        lastException = e;
                        Trace.WriteLine(string.Format("ROCMaster.Transport.Error,{0},{1}", requestMessage.OpCode.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("ROCMaster.Transport.Warning,Retry,{0},{1}", requestMessage.OpCode.ToString(), attempt.ToString()));
                    }
                } while (!success && NumberOfRetries > attempt);
            }
Finish:
            throw new TimeoutException("Device not responding to requests", lastException);
        }