Esempio n. 1
0
 /// <summary>
 /// 发送指定数量的字节数据
 /// </summary>
 /// <param name="buf"></param>
 /// <param name="offset"></param>
 /// <param name="count"></param>
 private void Write(byte[] buf, int offset, int count)
 {
     // 清接收缓冲区
     commProxy.DiscardInBuffer();
     // 发送数据
     commProxy.Write(buf, offset, count);
 }
Esempio n. 2
0
        public void Write(HJ212Message message)
        {
            _streamResource.DiscardInBuffer();

            byte[] frame = BuildMessageFrame(message);
            _streamResource.Write(frame, 0, frame.Length);
        }
Esempio n. 3
0
        public void Listen()
        {
            while (true)
            {
                try
                {
                    try
                    {
                        //Get a single byte
                        byte sample = _streamResource.ReadSingleByte();

                        //Raise the event
                        RaiseSampleEvent(sample);
                    }

                    catch (IOException)
                    {
                        if (_streamResource != null)
                        {
                            //_streamResource.DiscardInBuffer();
                        }
                    }
                    catch (TimeoutException)
                    {
                        _streamResource?.DiscardInBuffer();
                    }
                }
                catch (InvalidOperationException)
                {
                    // when the underlying transport is disposed
                    break;
                }
            }
        }
Esempio n. 4
0
        public void UnicastMessage_PurgeReceiveBuffer()
        {
            var             mock           = new Mock <IStreamResource>(MockBehavior.Strict);
            IStreamResource serialResource = mock.Object;
            var             factory        = new ModbusFactory();
            var             transport      = new ModbusRtuTransport(serialResource, factory, NullModbusLogger.Instance);

            mock.Setup(s => s.DiscardInBuffer());
            mock.Setup(s => s.Write(It.IsAny <byte[]>(), 0, 0));

            serialResource.DiscardInBuffer();
            serialResource.Write(null, 0, 0);

            // mangled response
            mock.Setup(s => s.Read(It.Is <byte[]>(x => x.Length == 4), 0, 4)).Returns(4);

            serialResource.DiscardInBuffer();
            serialResource.Write(null, 0, 0);

            // normal response
            var response = new ReadCoilsInputsResponse(ModbusFunctionCodes.ReadCoils, 2, 1, new DiscreteCollection(true, false, true, false, false, false, false, false));

            // write request
            mock.Setup(s => s.Write(It.Is <byte[]>(x => x.Length == 8), 0, 8));

            // read header
            mock.Setup(s => s.Read(It.Is <byte[]>(x => x.Length == 4), 0, 4))
            .Returns((byte[] buf, int offset, int count) =>
            {
                Array.Copy(response.MessageFrame, 0, buf, 0, 4);
                return(4);
            });

            // read remainder
            mock.Setup(s => s.Read(It.Is <byte[]>(x => x.Length == 2), 0, 2))
            .Returns((byte[] buf, int offset, int count) =>
            {
                Array.Copy(ModbusUtility.CalculateCrc(response.MessageFrame), 0, buf, 0, 2);
                return(2);
            });

            var request = new ReadCoilsInputsRequest(ModbusFunctionCodes.ReadCoils, 2, 3, 4);
            ReadCoilsInputsResponse actualResponse = transport.UnicastMessage <ReadCoilsInputsResponse>(request);

            ModbusMessageFixture.AssertModbusMessagePropertiesAreEqual(response, actualResponse);
            mock.VerifyAll();
        }
        public void UnicastMessage_PurgeReceiveBuffer()
        {
            MockRepository        mocks          = new MockRepository();
            IStreamResource       serialResource = mocks.StrictMock <IStreamResource>();
            ModbusSerialTransport transport      = new ModbusRtuTransport(serialResource);

            serialResource.DiscardInBuffer();
            serialResource.Write(null, 0, 0);
            LastCall.IgnoreArguments();

            // mangled response
            Expect.Call(serialResource.Read(new byte[] { 0, 0, 0, 0 }, 0, 4)).Return(4);

            serialResource.DiscardInBuffer();
            serialResource.Write(null, 0, 0);
            LastCall.IgnoreArguments();

            // normal response
            ReadCoilsInputsResponse response = new ReadCoilsInputsResponse(Modbus.ReadCoils, 2, 1,
                                                                           new DiscreteCollection(true, false, true, false, false, false, false, false));

            // read header
            Expect.Call(serialResource.Read(new byte[] { 0, 0, 0, 0 }, 0, 4))
            .Do(((Func <byte[], int, int, int>) delegate(byte[] buf, int offset, int count)
            {
                Array.Copy(response.MessageFrame, 0, buf, 0, 4);
                return(4);
            }));

            // read remainder
            Expect.Call(serialResource.Read(new byte[] { 0, 0 }, 0, 2))
            .Do(((Func <byte[], int, int, int>) delegate(byte[] buf, int offset, int count)
            {
                Array.Copy(ModbusUtility.CalculateCrc(response.MessageFrame), 0, buf, 0, 2);
                return(2);
            }));

            mocks.ReplayAll();

            ReadCoilsInputsRequest request = new ReadCoilsInputsRequest(Modbus.ReadCoils, 2, 3, 4);

            transport.UnicastMessage <ReadCoilsInputsResponse>(request);

            mocks.VerifyAll();
        }
Esempio n. 6
0
        internal virtual T UnicastMessage <T>(IModbusMessage message) where T : IModbusMessage, new()
        {
            IModbusMessage response = null;
            int            attempt  = 1;
            bool           success  = false;

            do
            {
                try
                {
                    lock (_syncLock)
                    {
                        // Discard read buffer just before writing a request
                        // Garbage in receive buffer can cause transaction ID off-by-one errors!
                        _streamResource.DiscardInBuffer();

                        Write(message);

                        bool readAgain;
                        do
                        {
                            readAgain = false;
                            response  = ReadResponse <T>();

                            var exceptionResponse = response as SlaveExceptionResponse;
                            if (exceptionResponse != null)
                            {
                                // if SlaveExceptionCode == ACKNOWLEDGE we retry reading the response without resubmitting request
                                readAgain = exceptionResponse.SlaveExceptionCode == Modbus.Acknowledge;
                                if (readAgain)
                                {
                                    Trace.WriteLine(string.Format(
                                                        "Received ACKNOWLEDGE slave exception response, waiting {0} milliseconds and retrying to read response.",
                                                        _waitToRetryMilliseconds));
                                    Sleep(WaitToRetryMilliseconds);
                                }
                                else
                                {
                                    throw new SlaveException(exceptionResponse);
                                }
                            }
                            else if (ShouldRetryResponse(message, response))
                            {
                                readAgain = true;
                            }
                        } while (readAgain);
                    }

                    ValidateResponse(message, response);
                    success = true;
                }
                catch (SlaveException se)
                {
                    if (se.SlaveExceptionCode != Modbus.SlaveDeviceBusy)
                    {
                        throw;
                    }

                    if (SlaveBusyUsesRetryCount && attempt++ > _retries)
                    {
                        throw;
                    }

                    Trace.WriteLine(string.Format(
                                        "Received SLAVE_DEVICE_BUSY exception response, waiting {0} milliseconds and resubmitting request.",
                                        _waitToRetryMilliseconds));
                    Sleep(WaitToRetryMilliseconds);
                }
                catch (Exception e)
                {
                    if (e is FormatException ||
                        e is NotImplementedException ||
                        e is TimeoutException ||
                        e is IOException)
                    {
                        Trace.WriteLine(string.Format("{0}, {1} retries remaining - {2}", e.GetType().Name, _retries - attempt + 1, e));

                        if (attempt++ > _retries)
                        {
                            throw;
                        }
                    }
                    else
                    {
                        throw;
                    }
                }
            } while (!success);

            return((T)response);
        }