IsoControlPdu.cs 4.2 KB

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