IsoControlPdu.cs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. using Core.Communication.Transport;
  2. using PLC.Siemens.Protocol.Common;
  3. using PLC.Siemens.Protocol.Header;
  4. using PLC.Siemens.O;
  5. namespace PLC.Siemens.Protocol.Iso
  6. {
  7. public class IsoControlPdu :IBuildRequest,IBuildResponse
  8. {
  9. public TpktHeader Tpkt { get; set; } // TPKT Header
  10. public CotpHeader Cotp { get; set; } // COPT Header for CONNECTION stuffs
  11. public int IsoPduSize { get; set; }
  12. public ushort SrcRef { get; set; }
  13. public ushort DstRef { get; set; }
  14. public ushort SrcTSap { get; set; }
  15. public ushort DstTSap { get; set; }
  16. /// <summary>
  17. /// 该报发送长度和接受长度都应该为22
  18. /// </summary>
  19. public IsoControlPdu()
  20. {
  21. Tpkt = new TpktHeader();
  22. Cotp = new CotpHeader();
  23. }
  24. public void Build()
  25. {
  26. Cotp.Params.PduSizeCode = 0xC0;
  27. Cotp.Params.PduSizeLen = 0x01;
  28. switch (IsoPduSize)
  29. {
  30. case 128:
  31. Cotp.Params.PduSizeVal = 0x07;
  32. break;
  33. case 256:
  34. Cotp.Params.PduSizeVal = 0x08;
  35. break;
  36. case 512:
  37. Cotp.Params.PduSizeVal = 0x09;
  38. break;
  39. case 1024:
  40. Cotp.Params.PduSizeVal = 0x0A;
  41. break;
  42. case 2048:
  43. Cotp.Params.PduSizeVal = 0x0B;
  44. break;
  45. case 4096:
  46. Cotp.Params.PduSizeVal = 0x0C;
  47. break;
  48. case 8192:
  49. Cotp.Params.PduSizeVal = 0x0D;
  50. break;
  51. default:
  52. Cotp.Params.PduSizeVal = 0x0B; // Our Default
  53. break;
  54. }
  55. // Build TSAPs
  56. Cotp.Params.Tsap[0] = 0xC1; // code that identifies source TSAP
  57. Cotp.Params.Tsap[1] = 2; // source TSAP Len
  58. Cotp.Params.Tsap[2] = (byte)((SrcTSap >> 8) & 0xFF); // HI part
  59. Cotp.Params.Tsap[3] = (byte)(SrcTSap & 0xFF); // LO part
  60. Cotp.Params.Tsap[4] = 0xC2; // code that identifies dest TSAP
  61. Cotp.Params.Tsap[5] = 2; // dest TSAP Len
  62. Cotp.Params.Tsap[6] = (byte)((DstTSap >> 8) & 0xFF); // HI part
  63. Cotp.Params.Tsap[7] = (byte)(DstTSap & 0xFF); // LO part
  64. Cotp.Params.TsapLenth = 8;
  65. // Params length
  66. var parLen = 11; // 2 Src TSAP (Code+field Len) +
  67. // 2 Src TSAP len +
  68. // 2 Dst TSAP (Code+field Len) +
  69. // 2 Src TSAP len +
  70. // 3 PDU size (Code+field Len+Val) = 11
  71. // Telegram length
  72. var isoLen = 4 + // TPKT Header
  73. 7 + // COTP Header Size without params
  74. parLen; // COTP params
  75. Tpkt.Version = StaticConst.IsoTcpVersion;
  76. Tpkt.Reserved = 0;
  77. Tpkt.Length = (ushort)isoLen;
  78. Cotp.Length = (byte)(parLen + 6); // <-- 6 = 7 - 1 (COTP Header size - 1)
  79. Cotp.PduType = (byte)PduType.ConnRequest; // Connection Request
  80. Cotp.DstRef = DstRef; // Destination reference
  81. Cotp.SrcRef = SrcRef; // Source reference
  82. Cotp.CoR = 0x00; // Class + Option : RFC0983 states that it must be always 0x40
  83. // but for some equipment (S7) must be 0 in disaccord of specifications !!!
  84. }
  85. public void Build(byte[] resBytes)
  86. {
  87. ByteBuffer buffer=ByteBuffer.Allocate();
  88. buffer.Push(resBytes);
  89. Tpkt.InitByBuffer(buffer);
  90. Cotp.InitByBuffer(buffer);
  91. }
  92. public ByteBuffer GetBuffer()
  93. {
  94. ByteBuffer buffer=ByteBuffer.Allocate();
  95. Tpkt.GetByteBuffer(buffer);
  96. Cotp.GetByteBuffer(buffer);
  97. return buffer;
  98. }
  99. public void Build(ByteBuffer buffer)
  100. {
  101. Tpkt.InitByBuffer(buffer);
  102. Cotp.InitByBuffer(buffer);
  103. }
  104. }
  105. }