public void UnicastMessage_ReReadsIfValidateResponseIsFalse()
        {
            MockRepository  mocks     = new MockRepository();
            ModbusTransport transport = mocks.PartialMock <ModbusTransport>();

            transport.WaitToRetryMilliseconds = 5;

            transport.Write(null);
            LastCall.IgnoreArguments();

            Expect.Call(transport.ReadResponse <ReadHoldingInputRegistersResponse>())
            .Return(new ReadHoldingInputRegistersResponse(Modbus.ReadHoldingRegisters, 1, new RegisterCollection(1)))
            .Repeat.Times(2)
            .Message("ReadResponse should be called twice, one for the retry");

            Expect.Call(transport.OnValidateResponse(null, null))
            .IgnoreArguments()
            .Return(false)
            .Repeat.Times(1);
            Expect.Call(transport.OnValidateResponse(null, null))
            .IgnoreArguments()
            .Return(true)
            .Repeat.Times(1);

            mocks.ReplayAll();
            ReadHoldingInputRegistersRequest  request  = new ReadHoldingInputRegistersRequest(Modbus.ReadHoldingRegisters, 1, 1, 1);
            ReadHoldingInputRegistersResponse response = transport.UnicastMessage <ReadHoldingInputRegistersResponse>(request);

            mocks.VerifyAll();
        }
Esempio n. 2
0
        public void UnicastMessage_ReReads_IfShouldRetryReturnTrue()
        {
            var mock = new Mock <ModbusTransport>(new ModbusFactory(), NullModbusLogger.Instance)
            {
                CallBase = true
            };
            ModbusTransport transport                       = mock.Object;
            var             expectedResponse                = new ReadHoldingInputRegistersResponse(ModbusFunctionCodes.ReadHoldingRegisters, 1, new RegisterCollection(1));
            int             readResponseCallsCount          = 0;
            int             onShouldRetryResponseCallsCount = 0;

            bool[] expectedReturn = { true, false };

            transport.RetryOnOldResponseThreshold = 3;

            mock.Setup(t => t.Write(It.IsNotNull <IModbusMessage>()));
            ////transport.Stub(x => x.Write(null)).IgnoreArguments();

            mock.Setup(t => t.OnValidateResponse(It.IsNotNull <IModbusMessage>(), It.IsNotNull <IModbusMessage>()));

            mock.Setup(t => t.OnShouldRetryResponse(It.IsNotNull <IModbusMessage>(), It.IsNotNull <IModbusMessage>()))
            .Returns(() => expectedReturn[onShouldRetryResponseCallsCount++]);

            mock.Setup(t => t.ReadResponse <ReadHoldingInputRegistersResponse>())
            .Returns(expectedResponse)
            .Callback(() => ++ readResponseCallsCount);

            var request = new ReadHoldingInputRegistersRequest(ModbusFunctionCodes.ReadHoldingRegisters, 1, 1, 1);
            ReadHoldingInputRegistersResponse response = transport.UnicastMessage <ReadHoldingInputRegistersResponse>(request);

            Assert.Equal(2, readResponseCallsCount);
            Assert.Equal(2, onShouldRetryResponseCallsCount);
            Assert.Equal(expectedResponse.MessageFrame, response.MessageFrame);
            mock.VerifyAll();
        }
Esempio n. 3
0
        public void UnicastMessage()
        {
            MockRepository  mocks     = new MockRepository();
            ModbusTransport transport = mocks.PartialMock <ModbusTransport>();

            transport.Write(null);
            LastCall.IgnoreArguments();
            // read 4 coils from slave id 2
            Expect.Call(transport.ReadResponse <ReadCoilsInputsResponse>())
            .Return(new ReadCoilsInputsResponse(Modbus.ReadCoils, 2, 1,
                                                new DiscreteCollection(true, false, true, false, false, false, false, false)));
            transport.OnValidateResponse(null, null);
            LastCall.IgnoreArguments();

            mocks.ReplayAll();

            ReadCoilsInputsRequest  request          = new ReadCoilsInputsRequest(Modbus.ReadCoils, 2, 3, 4);
            ReadCoilsInputsResponse expectedResponse = new ReadCoilsInputsResponse(Modbus.ReadCoils, 2, 1,
                                                                                   new DiscreteCollection(true, false, true, false, false, false, false, false));
            ReadCoilsInputsResponse response = transport.UnicastMessage <ReadCoilsInputsResponse>(request);

            Assert.Equal(expectedResponse.MessageFrame, response.MessageFrame);

            mocks.VerifyAll();
        }
        public void UnicastMessage_AcknowlegeSlaveException()
        {
            MockRepository  mocks     = new MockRepository();
            ModbusTransport transport = mocks.PartialMock <ModbusTransport>();

            // set the wait to retry property to a small value so the test completes quickly
            transport.WaitToRetryMilliseconds = 5;

            transport.Write(null);
            LastCall.IgnoreArguments();

            // return a slave exception a greater number of times than number of retries to make sure we aren't just retrying
            Expect.Call(transport.ReadResponse <ReadHoldingInputRegistersResponse>())
            .Return(new SlaveExceptionResponse(1, Modbus.ReadHoldingRegisters + Modbus.ExceptionOffset, Modbus.Acknowledge))
            .Repeat.Times(transport.Retries + 1);

            Expect.Call(transport.ReadResponse <ReadHoldingInputRegistersResponse>())
            .Return(new ReadHoldingInputRegistersResponse(Modbus.ReadHoldingRegisters, 1, new RegisterCollection(1)));

            transport.Stub(x => x.OnValidateResponse(null, null))
            .IgnoreArguments()
            .Return(true);

            mocks.ReplayAll();

            ReadHoldingInputRegistersRequest  request          = new ReadHoldingInputRegistersRequest(Modbus.ReadHoldingRegisters, 1, 1, 1);
            ReadHoldingInputRegistersResponse expectedResponse = new ReadHoldingInputRegistersResponse(Modbus.ReadHoldingRegisters, 1, new RegisterCollection(1));
            ReadHoldingInputRegistersResponse response         = transport.UnicastMessage <ReadHoldingInputRegistersResponse>(request);

            Assert.AreEqual(expectedResponse.MessageFrame, response.MessageFrame);

            mocks.VerifyAll();
        }
Esempio n. 5
0
        public void UnicastMessage_ReReads_IfShouldRetryReturnTrue()
        {
            MockRepository  mocks     = new MockRepository();
            ModbusTransport transport = mocks.PartialMock <ModbusTransport>();

            transport.RetryOnOldResponseThreshold = 3;
            transport.Stub(x => x.Write(null)).IgnoreArguments();

            Expect.Call(transport.ReadResponse <ReadHoldingInputRegistersResponse>())
            .Return(new ReadHoldingInputRegistersResponse(Modbus.ReadHoldingRegisters, 1, new RegisterCollection(1)))
            .Repeat.Times(2)
            .Message("ReadResponse should be called twice, one for the retry");

            transport.Expect(x => x.OnValidateResponse(null, null)).IgnoreArguments();

            Expect.Call(transport.OnShouldRetryResponse(null, null))
            .IgnoreArguments()
            .Return(true)
            .Repeat.Times(1);
            Expect.Call(transport.OnShouldRetryResponse(null, null))
            .IgnoreArguments()
            .Return(false)
            .Repeat.Times(1);

            mocks.ReplayAll();
            ReadHoldingInputRegistersRequest  request  = new ReadHoldingInputRegistersRequest(Modbus.ReadHoldingRegisters, 1, 1, 1);
            ReadHoldingInputRegistersResponse response = transport.UnicastMessage <ReadHoldingInputRegistersResponse>(request);

            mocks.VerifyAll();
        }
Esempio n. 6
0
        public void UnicastMessage_SingleFailingException(Type exceptionType)
        {
            MockRepository  mocks     = new MockRepository();
            ModbusTransport transport = mocks.PartialMock <ModbusTransport>();

            transport.Retries = 1;
            transport.Write(null);
            LastCall.IgnoreArguments().Repeat.Times(2);
            Expect.Call(transport.ReadResponse <ReadCoilsInputsResponse>())
            .Do((ThrowExceptionDelegate) delegate { throw (Exception)Activator.CreateInstance(exceptionType); });

            Expect.Call(transport.ReadResponse <ReadCoilsInputsResponse>())
            .Return(new ReadCoilsInputsResponse(Modbus.ReadCoils, 2, 1,
                                                new DiscreteCollection(true, false, true, false, false, false, false, false)));

            transport.OnValidateResponse(null, null);
            LastCall.IgnoreArguments();

            mocks.ReplayAll();

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

            transport.UnicastMessage <ReadCoilsInputsResponse>(request);

            mocks.VerifyAll();
        }
Esempio n. 7
0
        public void UnicastMessage_Retries()
        {
            var mock = new Mock <ModbusTransport>(new ModbusFactory(), NullModbusLogger.Instance)
            {
                CallBase = true
            };
            ModbusTransport transport              = mock.Object;
            int             writeCallsCount        = 0;
            int             readResponseCallsCount = 0;

            mock.Setup(t => t.Write(It.IsNotNull <IModbusMessage>()))
            .Callback(() => ++ writeCallsCount);

            transport.Retries = 5;
            mock.Setup(t => t.ReadResponse <ReadCoilsInputsResponse>())
            .Callback(() => ++ readResponseCallsCount)
            .Throws <TimeoutException>();

            var request = new ReadCoilsInputsRequest(ModbusFunctionCodes.ReadInputs, 2, 3, 4);

            Assert.Throws <TimeoutException>(() => transport.UnicastMessage <ReadCoilsInputsResponse>(request));
            Assert.Equal(transport.Retries + 1, writeCallsCount);
            Assert.Equal(transport.Retries + 1, readResponseCallsCount);
            mock.VerifyAll();
        }
Esempio n. 8
0
 public ModbusClient(
     ModbusTransport modbusTransport,
     IPacketLogger?packetLogger = null)
 {
     ModbusTransport = modbusTransport;
     PacketLogger    = packetLogger;
 }
Esempio n. 9
0
 public ModbusServer(
     ModbusTransport modbusTransport,
     IPacketLogger?packetLogger = null)
 {
     ModbusTransport = modbusTransport;
     PacketLogger    = packetLogger;
 }
Esempio n. 10
0
        private async Task ReadAsync(ModbusDevice device, ModbusFunctionCode functionCode, int zeroBasedOffset, int count, Action <MessageBufferSpan> actionWithReturnedBuffer, CancellationToken cancellationToken)
        {
            var requestContext = new ModbusTransportContext()
            {
                TransactionIdentifier = GetTransactionIdentifier()
            };

            await ModbusTransport.SendMessageAsync(requestContext,
                                                   (writer) =>
            {
                writer.Push(device.Address);
                writer.Push((byte)functionCode);
                writer.Push((byte)((zeroBasedOffset >> 8) & 0xFF));
                writer.Push((byte)((zeroBasedOffset >> 0) & 0xFF));
                writer.Push((byte)((count >> 8) & 0xFF));
                writer.Push((byte)((count >> 0) & 0xFF));
            }, cancellationToken);

            MessageBufferSpan?receivedBuffer = null;

            var responseContext = await ModbusTransport.ReceiveMessageAsync(
                async (reader) =>
            {
                if (await reader.PushByteFromStreamAsync(cancellationToken) != device.Address)
                {
                    throw new InvalidOperationException();
                }

                byte receivedFunctionCode = await reader.PushByteFromStreamAsync(cancellationToken);

                if (receivedFunctionCode == ((byte)functionCode | 0x80))
                {
                    var exceptionCode = (ModbusExceptionCode)await reader.PushByteFromStreamAsync(cancellationToken);
                    throw new ModbusException(exceptionCode);
                }

                if (receivedFunctionCode != (byte)functionCode)
                {
                    throw new InvalidOperationException();
                }

                var byteCount = await reader.PushByteFromStreamAsync(cancellationToken);

                await reader.PushFromStreamAsync(byteCount, cancellationToken);

                receivedBuffer = new MessageBufferSpan(reader.Buffer, (ushort)(reader.Buffer.Length - byteCount), byteCount);
            }, cancellationToken);

            if (responseContext.TransactionIdentifier != requestContext.TransactionIdentifier)
            {
                throw new InvalidOperationException();
            }

            actionWithReturnedBuffer(receivedBuffer !);
        }
Esempio n. 11
0
        private async Task <T> WriteAsync <T>(ModbusDevice device, ModbusFunctionCode functionCode, int zeroBasedOffset, Action <IMessageBufferWriter> writeAction, Func <IMessageBufferReader, Task <T> > readValueFunc, CancellationToken cancellationToken)
        {
            var requestContext = new ModbusTransportContext()
            {
                TransactionIdentifier = GetTransactionIdentifier()
            };

            await ModbusTransport.SendMessageAsync(requestContext,
                                                   (writer) =>
            {
                writer.Push(device.Address);
                writer.Push((byte)functionCode);
                writer.Push((byte)((zeroBasedOffset >> 8) & 0xFF));
                writer.Push((byte)((zeroBasedOffset >> 0) & 0xFF));
                writeAction(writer);
            }, cancellationToken);

            T returnedValue = default;

            var responseContext = await ModbusTransport.ReceiveMessageAsync(
                async (reader) =>
            {
                if (await reader.PushByteFromStreamAsync(cancellationToken) != device.Address)
                {
                    throw new InvalidOperationException();
                }

                byte receivedFunctionCode = await reader.PushByteFromStreamAsync(cancellationToken);

                if (receivedFunctionCode == ((byte)functionCode | 0x80))
                {
                    var exceptionCode = (ModbusExceptionCode)await reader.PushByteFromStreamAsync(cancellationToken);
                    throw new ModbusException(exceptionCode);
                }

                if (receivedFunctionCode != (byte)functionCode)
                {
                    throw new InvalidOperationException();
                }

                if (await reader.PushByteFromStreamAsync(cancellationToken) != zeroBasedOffset)
                {
                    throw new InvalidOperationException();
                }

                returnedValue = await readValueFunc(reader);
            }, cancellationToken);

            if (requestContext.TransactionIdentifier != responseContext.TransactionIdentifier)
            {
                throw new InvalidOperationException();
            }

            return(returnedValue !);
        }
Esempio n. 12
0
        private T Write <T>(ModbusDevice device, ModbusFunctionCode functionCode, int zeroBasedOffset, Action <IMessageBufferWriter> writeAction, Func <IMessageBufferReader, T> readValueFunc)
        {
            var requestContext = new ModbusTransportContext()
            {
                TransactionIdentifier = GetTransactionIdentifier()
            };

            ModbusTransport.SendMessage(requestContext,
                                        (writer) =>
            {
                writer.Push(device.Address);
                writer.Push((byte)functionCode);
                writer.Push((byte)((zeroBasedOffset >> 8) & 0xFF));
                writer.Push((byte)((zeroBasedOffset >> 0) & 0xFF));
                writeAction(writer);
            });

            T returnedValue = default;

            var responseContext = ModbusTransport.ReceiveMessage(
                (reader) =>
            {
                if (reader.PushByteFromStream() != device.Address)
                {
                    throw new InvalidOperationException();
                }

                byte receivedFunctionCode = reader.PushByteFromStream();

                if (receivedFunctionCode == ((byte)functionCode | 0x80))
                {
                    var exceptionCode = (ModbusExceptionCode)reader.PushByteFromStream();
                    throw new ModbusException(exceptionCode);
                }

                if (receivedFunctionCode != (byte)functionCode)
                {
                    throw new InvalidOperationException();
                }

                if ((ushort)((reader.PushByteFromStream() << 8) + (reader.PushByteFromStream() << 0)) != zeroBasedOffset)
                {
                    throw new InvalidOperationException();
                }

                returnedValue = readValueFunc(reader);
            });

            if (requestContext.TransactionIdentifier != responseContext.TransactionIdentifier)
            {
                throw new InvalidOperationException();
            }

            return(returnedValue !);
        }
 /// <summary>
 /// Releases unmanaged and - optionally - managed resources
 /// </summary>
 /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
 protected virtual void Dispose(bool disposing)
 {
     if (disposing)
     {
         if (_transport != null)
         {
             _transport.Dispose();
             _transport = null;
         }
     }
 }
Esempio n. 14
0
        public static IStreamResource GetStreamResource(this ModbusTransport modbusTransport)
        {
            var property = modbusTransport.GetType().GetProperty("StreamResource", BindingFlags.Instance | BindingFlags.NonPublic);

            if (property == null)
            {
                throw new InvalidOperationException("Unable to find StreamResource");
            }

            return(property.GetValue(modbusTransport) as IStreamResource);
        }
        public void ValidateResponse_MismatchingFunctionCodes()
        {
            MockRepository  mocks     = new MockRepository();
            ModbusTransport transport = mocks.PartialMock <ModbusTransport>();

            IModbusMessage request  = new ReadCoilsInputsRequest(Modbus.ReadCoils, 1, 1, 1);
            IModbusMessage response = new ReadHoldingInputRegistersResponse(Modbus.ReadHoldingRegisters, 1, new RegisterCollection());

            mocks.ReplayAll();
            Assert.Throws <IOException>(() => transport.ValidateResponse(request, response));
        }
Esempio n. 16
0
        public void HandleRequest(params ModbusDevice[] devices)
        {
            if (devices is null)
            {
                throw new ArgumentNullException(nameof(devices));
            }

            if (devices.Length == 0)
            {
                throw new ArgumentException();
            }

            MessageHandler?messageHandler = null;
            ModbusDevice?  device         = null;

            var requestContext = ModbusTransport.ReceiveMessage(reader =>
            {
                var deviceAddress = reader.PushByteFromStream();

                device = devices.FirstOrDefault(_ => _.Address == deviceAddress);

                if (device == null)
                {
                    throw new InvalidOperationException($"Received request for device with unknown address {deviceAddress}");
                }

                var functionCode = (ModbusFunctionCode)reader.PushByteFromStream();
                messageHandler   = functionCode switch
                {
                    ModbusFunctionCode.ReadDiscreteInputs => ReadDiscreteInputsHandler.Create(reader),
                    ModbusFunctionCode.ReadCoils => ReadCoilsHandler.Create(reader),
                    ModbusFunctionCode.ReadInputRegisters => ReadInputRegistersHandler.Create(reader),
                    ModbusFunctionCode.ReadHoldingRegisters => ReadHoldingRegistersHandler.Create(reader),

                    ModbusFunctionCode.WriteSingleCoil => WriteSingleCoilHandler.Create(reader),
                    ModbusFunctionCode.WriteSingleRegister => WriteSingleRegisterHandler.Create(reader),
                    ModbusFunctionCode.WriteMultipleCoils => WriteMultipleCoilsHandler.Create(reader),
                    ModbusFunctionCode.WriteMultipleRegisters => WriteMultipleRegistersHandler.Create(reader),

                    ModbusFunctionCode.ReadWriteMultipleRegisters => ReadWriteMultipleRegistersHandler.Create(reader),
                    _ => throw new NotSupportedException($"Function {functionCode} not supported"),
                };
            });

            if (messageHandler is WriteHandler writeHandler)
            {
                writeHandler.UpdateMemory(device !);
            }

            ModbusTransport.SendMessage(requestContext, writer =>
            {
                messageHandler !.WriteResponse(device !, writer);
            });
Esempio n. 17
0
        public void ValidateResponse_MismatchingSlaveAddress()
        {
            var mock = new Mock <ModbusTransport>(MockBehavior.Strict, new ModbusFactory(), NullModbusLogger.Instance)
            {
                CallBase = true
            };
            ModbusTransport transport = mock.Object;

            IModbusMessage request  = new ReadCoilsInputsRequest(ModbusFunctionCodes.ReadCoils, 42, 1, 1);
            IModbusMessage response = new ReadHoldingInputRegistersResponse(ModbusFunctionCodes.ReadCoils, 33, new RegisterCollection());

            Assert.Throws <IOException>(() => transport.ValidateResponse(request, response));
        }
Esempio n. 18
0
        public void ShouldRetryResponse_ReturnsFalse_IfDifferentMessage()
        {
            var mock = new Mock <ModbusTransport>(MockBehavior.Strict, new ModbusFactory(), NullModbusLogger.Instance)
            {
                CallBase = true
            };
            ModbusTransport transport = mock.Object;

            IModbusMessage request  = new ReadCoilsInputsRequest(ModbusFunctionCodes.ReadCoils, 2, 1, 1);
            IModbusMessage response = new ReadCoilsInputsResponse(ModbusFunctionCodes.ReadCoils, 1, 1, null);

            Assert.False(transport.ShouldRetryResponse(request, response));
        }
Esempio n. 19
0
        public void CreateResponse_SlaveException()
        {
            var mock = new Mock <ModbusTransport>(new ModbusFactory(), NullModbusLogger.Instance)
            {
                CallBase = true
            };
            ModbusTransport transport = mock.Object;

            byte[]         frame   = { 2, 129, 2 };
            byte           lrc     = ModbusUtility.CalculateLrc(frame);
            IModbusMessage message = transport.CreateResponse <ReadCoilsInputsResponse>(Enumerable.Concat(frame, new byte[] { lrc }).ToArray());

            Assert.IsType <SlaveExceptionResponse>(message);
        }
Esempio n. 20
0
        public void ValidateResponse_CallsOnValidateResponse()
        {
            MockRepository  mocks     = new MockRepository();
            ModbusTransport transport = mocks.PartialMock <ModbusTransport>();

            IModbusMessage request  = new ReadCoilsInputsRequest(Modbus.ReadCoils, 1, 1, 1);
            IModbusMessage response = new ReadCoilsInputsResponse(Modbus.ReadCoils, 1, 1, null);

            transport.OnValidateResponse(null, null);
            LastCall.IgnoreArguments();

            mocks.ReplayAll();
            transport.ValidateResponse(request, response);
            mocks.VerifyAll();
        }
        public void ValidateResponse_CallsOnValidateResponse()
        {
            MockRepository  mocks     = new MockRepository();
            ModbusTransport transport = mocks.PartialMock <ModbusTransport>();

            IModbusMessage request  = new ReadCoilsInputsRequest(Modbus.ReadCoils, 1, 1, 1);
            IModbusMessage response = new ReadCoilsInputsResponse(Modbus.ReadCoils, 1, 1, null);

            Expect.Call(transport.OnValidateResponse(request, response))
            .Return(true);

            mocks.ReplayAll();
            transport.ValidateResponse(request, response);
            mocks.VerifyAll();
        }
Esempio n. 22
0
        public void ValidateResponse_CallsOnValidateResponse()
        {
            var mock = new Mock <ModbusTransport>(MockBehavior.Strict, new ModbusFactory(), NullModbusLogger.Instance)
            {
                CallBase = true
            };
            ModbusTransport transport = mock.Object;

            mock.Setup(t => t.OnValidateResponse(It.IsNotNull <IModbusMessage>(), It.IsNotNull <IModbusMessage>()));

            IModbusMessage request  = new ReadCoilsInputsRequest(ModbusFunctionCodes.ReadCoils, 1, 1, 1);
            IModbusMessage response = new ReadCoilsInputsResponse(ModbusFunctionCodes.ReadCoils, 1, 1, new DiscreteCollection());

            transport.ValidateResponse(request, response);
            mock.VerifyAll();
        }
Esempio n. 23
0
        public void UnicastMessage_ErrorSlaveException()
        {
            var mock = new Mock <ModbusTransport>(new ModbusFactory(), NullModbusLogger.Instance)
            {
                CallBase = true
            };
            var             request   = new ReadCoilsInputsRequest(ModbusFunctionCodes.ReadInputs, 2, 3, 4);
            ModbusTransport transport = mock.Object;

            mock.Setup(t => t.Write(It.IsNotNull <IModbusMessage>()));
            mock.Setup(t => t.ReadResponse <ReadCoilsInputsResponse>()).Throws <SlaveException>();

            Assert.Throws <SlaveException>(() => transport.UnicastMessage <ReadCoilsInputsResponse>(request));

            mock.VerifyAll();
        }
Esempio n. 24
0
        public void WaitToRetryMilliseconds()
        {
            var mock = new Mock <ModbusTransport>(MockBehavior.Strict, new ModbusFactory(), NullModbusLogger.Instance)
            {
                CallBase = true
            };
            ModbusTransport transport = mock.Object;

            Assert.Equal(Modbus.DefaultWaitToRetryMilliseconds, transport.WaitToRetryMilliseconds);

            Assert.Throws <ArgumentException>(() => transport.WaitToRetryMilliseconds = -1);

            const int expectedWaitToRetryMilliseconds = 42;

            transport.WaitToRetryMilliseconds = expectedWaitToRetryMilliseconds;
            Assert.Equal(expectedWaitToRetryMilliseconds, transport.WaitToRetryMilliseconds);
        }
Esempio n. 25
0
        public void Dispose_MultipleTimes_ShouldNotThrow()
        {
            var streamMock = new Mock <IStreamResource>(MockBehavior.Strict);

            streamMock.Setup(s => s.Dispose());

            var mock = new Mock <ModbusTransport>(streamMock.Object, new ModbusFactory(), NullModbusLogger.Instance)
            {
                CallBase = true
            };

            using (ModbusTransport transport = mock.Object)
            {
                Assert.NotNull(transport.StreamResource);
                transport.Dispose();
                Assert.Null(transport.StreamResource);
            }
        }
Esempio n. 26
0
        public void UnicastMessage_ErrorSlaveException()
        {
            MockRepository  mocks     = new MockRepository();
            ModbusTransport transport = mocks.PartialMock <ModbusTransport>();

            transport.Write(null);
            LastCall.IgnoreArguments();
            Expect.Call(transport.ReadResponse <ReadCoilsInputsResponse>())
            .Do((ThrowExceptionDelegate) delegate { throw new SlaveException(); });

            mocks.ReplayAll();

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

            Assert.Throws <SlaveException>(() => transport.UnicastMessage <ReadCoilsInputsResponse>(request));

            mocks.VerifyAll();
        }
        public void UnicastMessage_TimeoutException()
        {
            MockRepository  mocks     = new MockRepository();
            ModbusTransport transport = mocks.PartialMock <ModbusTransport>();

            transport.Write(null);
            LastCall.IgnoreArguments().Repeat.Times(Modbus.DefaultRetries + 1);
            Expect.Call(transport.ReadResponse <ReadCoilsInputsResponse>())
            .Do((ThrowExceptionDelegate) delegate { throw new TimeoutException(); })
            .Repeat.Times(Modbus.DefaultRetries + 1);

            mocks.ReplayAll();

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

            transport.UnicastMessage <ReadCoilsInputsResponse>(request);

            mocks.VerifyAll();
        }
Esempio n. 28
0
        public void UnicastMessage_SlaveDeviceBusySlaveException()
        {
            var mock = new Mock <ModbusTransport>(new ModbusFactory(), NullModbusLogger.Instance)
            {
                CallBase = true
            };
            ModbusTransport transport              = mock.Object;
            int             writeCallsCount        = 0;
            int             readResponseCallsCount = 0;

            // set the wait to retry property to a small value so the test completes quickly
            transport.WaitToRetryMilliseconds = 5;

            mock.Setup(t => t.Write(It.IsNotNull <IModbusMessage>()))
            .Callback(() => ++ writeCallsCount);

            // return a slave exception a greater number of times than number of retries to make sure we aren't just retrying
            mock.Setup(t => t.ReadResponse <ReadHoldingInputRegistersResponse>())
            .Returns(() =>
            {
                if (readResponseCallsCount == 0)
                {
                    return(new SlaveExceptionResponse(1, ModbusFunctionCodes.ReadHoldingRegisters + Modbus.ExceptionOffset, SlaveExceptionCodes.SlaveDeviceBusy));
                }
                else
                {
                    return(new ReadHoldingInputRegistersResponse(ModbusFunctionCodes.ReadHoldingRegisters, 1, new RegisterCollection(1)));
                }
            })
            .Callback(() => ++ readResponseCallsCount);

            mock.Setup(t => t.OnValidateResponse(It.IsNotNull <IModbusMessage>(), It.IsNotNull <IModbusMessage>()));

            var request          = new ReadHoldingInputRegistersRequest(ModbusFunctionCodes.ReadHoldingRegisters, 1, 1, 1);
            var expectedResponse = new ReadHoldingInputRegistersResponse(ModbusFunctionCodes.ReadHoldingRegisters, 1, new RegisterCollection(1));
            ReadHoldingInputRegistersResponse response = transport.UnicastMessage <ReadHoldingInputRegistersResponse>(request);

            Assert.Equal(2, writeCallsCount);
            Assert.Equal(2, readResponseCallsCount);
            Assert.Equal(expectedResponse.MessageFrame, response.MessageFrame);

            mock.VerifyAll();
        }
Esempio n. 29
0
        public void UnicastMessage_TooManyFailingExceptions(Type exceptionType)
        {
            MockRepository  mocks     = new MockRepository();
            ModbusTransport transport = mocks.PartialMock <ModbusTransport>();

            transport.Write(null);
            LastCall.IgnoreArguments().Repeat.Times(transport.Retries + 1);

            Expect.Call(transport.ReadResponse <ReadCoilsInputsResponse>())
            .Do((ThrowExceptionDelegate) delegate { throw (Exception)Activator.CreateInstance(exceptionType); })
            .Repeat.Times(transport.Retries + 1);

            mocks.ReplayAll();

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

            Assert.Throws(exceptionType, () => transport.UnicastMessage <ReadCoilsInputsResponse>(request));

            mocks.VerifyAll();
        }
Esempio n. 30
0
        public void UnicastMessage_WrongResponseFunctionCode()
        {
            MockRepository  mocks     = new MockRepository();
            ModbusTransport transport = mocks.PartialMock <ModbusTransport>();

            transport.Write(null);
            LastCall.IgnoreArguments().Repeat.Times(Modbus.DefaultRetries + 1);
            // read 4 coils from slave id 2
            Expect.Call(transport.ReadResponse <ReadCoilsInputsResponse>())
            .Return(new ReadCoilsInputsResponse(Modbus.ReadCoils, 2, 0, new DiscreteCollection()))
            .Repeat.Times(Modbus.DefaultRetries + 1);

            mocks.ReplayAll();

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

            Assert.Throws <IOException>(() => transport.UnicastMessage <ReadCoilsInputsResponse>(request));

            mocks.VerifyAll();
        }
Esempio n. 31
0
        public void UnicastMessage()
        {
            var data = new DiscreteCollection(true, false, true, false, false, false, false, false);
            var mock = new Mock <ModbusTransport>(new ModbusFactory(), NullModbusLogger.Instance)
            {
                CallBase = true
            };
            ModbusTransport transport = mock.Object;

            mock.Setup(t => t.Write(It.IsNotNull <IModbusMessage>()));
            mock.Setup(t => t.ReadResponse <ReadCoilsInputsResponse>())
            .Returns(new ReadCoilsInputsResponse(ModbusFunctionCodes.ReadCoils, 2, 1, data));
            mock.Setup(t => t.OnValidateResponse(It.IsNotNull <IModbusMessage>(), It.IsNotNull <IModbusMessage>()));

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

            Assert.Equal(expectedResponse.MessageFrame, response.MessageFrame);
            mock.VerifyAll();
        }
Esempio n. 32
0
 private ModbusIpMaster(ModbusTransport transport)
     : base(transport)
 {
 }
Esempio n. 33
0
		private ModbusSerialMaster(ModbusTransport transport)
			: base(transport)
		{
		}
 internal ModbusSlave(byte unitId, ModbusTransport transport)
     : base(transport)
 {
     DataStore = DataStoreFactory.CreateDefaultDataStore();
     UnitId = unitId;
 }
 private ModbusPromiscuousSerialSlave(ModbusTransport transport)
     : base(transport)
 {
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="ModbusSlave"/> class.
 /// </summary>
 public ModbusSlave(byte unitID, ModbusTransport transport)
     : base(transport)
 {
     _dataStore = DataStoreFactory.CreateDefaultDataStore();
     _unitID = unitID;
 }
 internal ModbusPromiscuousSlave(ModbusTransport transport)
     : base(transport)
 {
 }
Esempio n. 38
0
 internal ModbusDevice(ModbusTransport transport)
 {
     _transport = transport;
 }
Esempio n. 39
0
 private ModbusSerialSlave(byte unitId, ModbusTransport transport)
     : base(unitId, transport)
 {
 }