1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 |
- using System;
- using System.IO;
- using System.Threading;
- using System.Threading.Tasks;
- using NModbus.Logging;
- using NModbus.Message;
- namespace NModbus.Device
- {
- using Extensions;
- internal class ModbusSerialSlaveNetwork : ModbusSlaveNetwork
- {
- private readonly IModbusSerialTransport _serialTransport;
- private readonly IModbusFactory _modbusFactory;
- public ModbusSerialSlaveNetwork(IModbusSerialTransport transport, IModbusFactory modbusFactory, IModbusLogger logger)
- : base(transport, modbusFactory, logger)
- {
- _serialTransport = transport ?? throw new ArgumentNullException(nameof(transport));
- _modbusFactory = modbusFactory;
- }
- private IModbusSerialTransport SerialTransport => _serialTransport;
- public override Task ListenAsync(CancellationToken cancellationToken = new CancellationToken())
- {
- while (!cancellationToken.IsCancellationRequested)
- {
- try
- {
- // read request and build message
- byte[] frame = SerialTransport.ReadRequest();
- //Create the request
- IModbusMessage request = _modbusFactory.CreateModbusRequest(frame);
- //Check the message
- if (SerialTransport.CheckFrame && !SerialTransport.ChecksumsMatch(request, frame))
- {
- string msg = $"Checksums failed to match {string.Join(", ", request.MessageFrame)} != {string.Join(", ", frame)}.";
- Logger.Warning(msg);
- throw new IOException(msg);
- }
- //Apply the request
- IModbusMessage response = ApplyRequest(request);
- if (response == null)
- {
- _serialTransport.IgnoreResponse();
- }
- else
- {
- Transport.Write(response);
- }
- }
- catch (IOException ioe)
- {
- Logger.Warning($"IO Exception encountered while listening for requests - {ioe.Message}");
- SerialTransport.DiscardInBuffer();
- }
- catch (TimeoutException te)
- {
- Logger.Trace($"Timeout Exception encountered while listening for requests - {te.Message}");
- SerialTransport.DiscardInBuffer();
- }
- catch(InvalidOperationException)
- {
- // when the underlying transport is disposed
- break;
- }
- catch (Exception ex)
- {
- Logger.Error($"{GetType()}: {ex.Message}");
- SerialTransport.DiscardInBuffer();
- }
- }
- return Task.FromResult(0);
- }
- }
- }
|