ModbusMessageImpl.cs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Net;
  5. using NModbus.Data;
  6. namespace NModbus.Message
  7. {
  8. /// <summary>
  9. /// Class holding all implementation shared between two or more message types.
  10. /// Interfaces expose subsets of type specific implementations.
  11. /// </summary>
  12. internal class ModbusMessageImpl
  13. {
  14. // smallest supported message frame size (sans checksum)
  15. private const int MinimumFrameSize = 2;
  16. public ModbusMessageImpl()
  17. {
  18. }
  19. public ModbusMessageImpl(byte slaveAddress, byte functionCode)
  20. {
  21. SlaveAddress = slaveAddress;
  22. FunctionCode = functionCode;
  23. }
  24. public byte? ByteCount { get; set; }
  25. public byte? ExceptionCode { get; set; }
  26. public ushort TransactionId { get; set; }
  27. public byte FunctionCode { get; set; }
  28. public ushort? NumberOfPoints { get; set; }
  29. public byte SlaveAddress { get; set; }
  30. public ushort? StartAddress { get; set; }
  31. public ushort? SubFunctionCode { get; set; }
  32. public IModbusMessageDataCollection Data { get; set; }
  33. public byte[] MessageFrame
  34. {
  35. get
  36. {
  37. var pdu = ProtocolDataUnit;
  38. var frame = new MemoryStream(1 + pdu.Length);
  39. frame.WriteByte(SlaveAddress);
  40. frame.Write(pdu, 0, pdu.Length);
  41. return frame.ToArray();
  42. }
  43. }
  44. public byte[] ProtocolDataUnit
  45. {
  46. get
  47. {
  48. List<byte> pdu = new List<byte>();
  49. pdu.Add(FunctionCode);
  50. if (ExceptionCode.HasValue)
  51. {
  52. pdu.Add(ExceptionCode.Value);
  53. }
  54. if (SubFunctionCode.HasValue)
  55. {
  56. pdu.AddRange(BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)SubFunctionCode.Value)));
  57. }
  58. if (StartAddress.HasValue)
  59. {
  60. pdu.AddRange(BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)StartAddress.Value)));
  61. }
  62. if (NumberOfPoints.HasValue)
  63. {
  64. pdu.AddRange(BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)NumberOfPoints.Value)));
  65. }
  66. if (ByteCount.HasValue)
  67. {
  68. pdu.Add(ByteCount.Value);
  69. }
  70. if (Data != null)
  71. {
  72. pdu.AddRange(Data.NetworkBytes);
  73. }
  74. return pdu.ToArray();
  75. }
  76. }
  77. public void Initialize(byte[] frame)
  78. {
  79. if (frame == null)
  80. {
  81. throw new ArgumentNullException(nameof(frame), "Argument frame cannot be null.");
  82. }
  83. if (frame.Length < MinimumFrameSize)
  84. {
  85. string msg = $"Message frame must contain at least {MinimumFrameSize} bytes of data.";
  86. throw new FormatException(msg);
  87. }
  88. SlaveAddress = frame[0];
  89. FunctionCode = frame[1];
  90. }
  91. }
  92. }