ModbusSlave.cs 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.Linq;
  5. using NModbus.Extensions;
  6. using NModbus.Message;
  7. namespace NModbus.Device
  8. {
  9. public class ModbusSlave : IModbusSlave
  10. {
  11. private readonly byte _unitId;
  12. private readonly ISlaveDataStore _dataStore;
  13. private readonly IDictionary<byte, IModbusFunctionService> _handlers;
  14. public ModbusSlave(byte unitId, ISlaveDataStore dataStore, IEnumerable<IModbusFunctionService> handlers)
  15. {
  16. if (dataStore == null) throw new ArgumentNullException(nameof(dataStore));
  17. if (handlers == null) throw new ArgumentNullException(nameof(handlers));
  18. _unitId = unitId;
  19. _dataStore = dataStore;
  20. _handlers = handlers.ToDictionary(h => h.FunctionCode, h => h);
  21. }
  22. public byte UnitId => _unitId;
  23. public ISlaveDataStore DataStore => _dataStore;
  24. public IModbusMessage ApplyRequest(IModbusMessage request)
  25. {
  26. IModbusMessage response;
  27. try
  28. {
  29. //Try to get a handler for this function.
  30. IModbusFunctionService handler = _handlers.GetValueOrDefault(request.FunctionCode);
  31. //Check to see if we found a handler for this function code.
  32. if (handler == null)
  33. {
  34. throw new InvalidModbusRequestException(SlaveExceptionCodes.IllegalFunction);
  35. }
  36. //Process the request
  37. response = handler.HandleSlaveRequest(request, DataStore);
  38. }
  39. catch (InvalidModbusRequestException ex)
  40. {
  41. // Catches the exception for an illegal function or a custom exception from the ModbusSlaveRequestReceived event.
  42. response = new SlaveExceptionResponse(
  43. request.SlaveAddress,
  44. (byte) (Modbus.ExceptionOffset + request.FunctionCode),
  45. ex.ExceptionCode);
  46. }
  47. #if NET45 || NET46
  48. catch (Exception ex)
  49. {
  50. //Okay - this is no beuno.
  51. response = new SlaveExceptionResponse(request.SlaveAddress,
  52. (byte) (Modbus.ExceptionOffset + request.FunctionCode),
  53. SlaveExceptionCodes.SlaveDeviceFailure);
  54. //Give the consumer a chance at seeing what the *(&& happened.
  55. Trace.WriteLine(ex.ToString());
  56. }
  57. #else
  58. catch (Exception)
  59. {
  60. //Okay - this is no beuno.
  61. response = new SlaveExceptionResponse(request.SlaveAddress,
  62. (byte)(Modbus.ExceptionOffset + request.FunctionCode),
  63. SlaveExceptionCodes.SlaveDeviceFailure);
  64. }
  65. #endif
  66. return response;
  67. }
  68. }
  69. }