ModbusSerialSlaveNetwork.cs 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. using System;
  2. using System.IO;
  3. using System.Threading;
  4. using System.Threading.Tasks;
  5. using NModbus.Logging;
  6. using NModbus.Message;
  7. namespace NModbus.Device
  8. {
  9. using Extensions;
  10. internal class ModbusSerialSlaveNetwork : ModbusSlaveNetwork
  11. {
  12. private readonly IModbusSerialTransport _serialTransport;
  13. private readonly IModbusFactory _modbusFactory;
  14. public ModbusSerialSlaveNetwork(IModbusSerialTransport transport, IModbusFactory modbusFactory, IModbusLogger logger)
  15. : base(transport, modbusFactory, logger)
  16. {
  17. _serialTransport = transport ?? throw new ArgumentNullException(nameof(transport));
  18. _modbusFactory = modbusFactory;
  19. }
  20. private IModbusSerialTransport SerialTransport => _serialTransport;
  21. public override Task ListenAsync(CancellationToken cancellationToken = new CancellationToken())
  22. {
  23. while (!cancellationToken.IsCancellationRequested)
  24. {
  25. try
  26. {
  27. // read request and build message
  28. byte[] frame = SerialTransport.ReadRequest();
  29. //Create the request
  30. IModbusMessage request = _modbusFactory.CreateModbusRequest(frame);
  31. //Check the message
  32. if (SerialTransport.CheckFrame && !SerialTransport.ChecksumsMatch(request, frame))
  33. {
  34. string msg = $"Checksums failed to match {string.Join(", ", request.MessageFrame)} != {string.Join(", ", frame)}.";
  35. Logger.Warning(msg);
  36. throw new IOException(msg);
  37. }
  38. //Apply the request
  39. IModbusMessage response = ApplyRequest(request);
  40. if (response == null)
  41. {
  42. _serialTransport.IgnoreResponse();
  43. }
  44. else
  45. {
  46. Transport.Write(response);
  47. }
  48. }
  49. catch (IOException ioe)
  50. {
  51. Logger.Warning($"IO Exception encountered while listening for requests - {ioe.Message}");
  52. SerialTransport.DiscardInBuffer();
  53. }
  54. catch (TimeoutException te)
  55. {
  56. Logger.Trace($"Timeout Exception encountered while listening for requests - {te.Message}");
  57. SerialTransport.DiscardInBuffer();
  58. }
  59. catch(InvalidOperationException)
  60. {
  61. // when the underlying transport is disposed
  62. break;
  63. }
  64. catch (Exception ex)
  65. {
  66. Logger.Error($"{GetType()}: {ex.Message}");
  67. SerialTransport.DiscardInBuffer();
  68. }
  69. }
  70. return Task.FromResult(0);
  71. }
  72. }
  73. }