说明

本代码仅适用以下协议。
协议中,由Packet_Length表示序号7-11的长度。也就是Packet_Length=N+2+2+1+1。
但是在设计时,会将序号1-10,视为固定包头。序号11-13为Body。

版权

该代码所有版权归若汝棋茗所有,使用时请务必注明。

协议类型

数据协议.png

代码

  1. using RRQMCore.ByteManager;
  2. using RRQMSocket;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Text;
  6. namespace AdapterConsoleApp
  7. {
  8. /// <summary>
  9. /// 国网输电i1标准版
  10. /// </summary>
  11. internal class SGCCCustomDataHandlingAdapter : CustomFixedHeaderDataHandlingAdapter<SGCCRequestInfo>
  12. {
  13. public override int HeaderLength => 30;
  14. protected override SGCCRequestInfo GetInstance()
  15. {
  16. return new SGCCRequestInfo();
  17. }
  18. }
  19. public class SGCCRequestInfo : IFixedHeaderRequestInfo
  20. {
  21. private byte[] m_sync;
  22. private int m_bodyLength;
  23. private byte[] m_cMDID;
  24. private byte[] m_sample;
  25. private byte[] m_cRC16;
  26. public int BodyLength { get => m_bodyLength; }
  27. /// <summary>
  28. /// 报文头:5AA5
  29. /// </summary>
  30. public byte[] Sync { get => m_sync; set => m_sync = value; }
  31. /// <summary>
  32. /// 报文长度
  33. /// </summary>
  34. public ushort PacketLength { get => (ushort)(this.m_bodyLength - 3); }
  35. /// <summary>
  36. /// 状态监测装置ID(17位编码)
  37. /// </summary>
  38. public byte[] CMDID { get => m_cMDID; set => m_cMDID = value; }
  39. /// <summary>
  40. /// 帧类型—参考附表C8-1相关含义
  41. /// </summary>
  42. public byte FrameType { get; set; }
  43. /// <summary>
  44. /// 报文类型—参考附表C8-2相关含义
  45. /// </summary>
  46. public byte PacketType { get; set; }
  47. /// <summary>
  48. /// 帧序列号(无符号整数)
  49. /// </summary>
  50. public byte FrameNo { get; set; }
  51. /// <summary>
  52. /// 通道号—表示采集装置上的摄像机编号。如:一个装连接⒉部摄像机,则分别标号为1、2
  53. /// </summary>
  54. public byte ChannelNo { get; set; }
  55. /// <summary>
  56. /// 预置位号—即云台摄像所设置的预置位号,不带云台摄像机,预置位号为255
  57. /// </summary>
  58. public byte PresettingNo { get; set; }
  59. /// <summary>
  60. /// 总包数(无符号整数,取值范围:大于等于0)
  61. /// </summary>
  62. public ushort PacketNo { get; set; }
  63. /// <summary>
  64. /// 子包包号(无符号整数,取值范围:大于等于0>
  65. /// </summary>
  66. public ushort SubpacketNo { get; set; }
  67. /// <summary>
  68. /// 数据区
  69. /// </summary>
  70. public byte[] Sample { get => m_sample; set => m_sample = value; }
  71. /// <summary>
  72. /// 校验位
  73. /// </summary>
  74. public byte[] CRC16 { get => m_cRC16;}
  75. /// <summary>
  76. /// 报文尾:0x96
  77. /// </summary>
  78. public byte End { get; set; }
  79. public bool OnParsingHeader(byte[] header)
  80. {
  81. if (header.Length == 30)
  82. {
  83. using (ByteBlock byteBlock = new ByteBlock(header))
  84. {
  85. byteBlock.Pos = 0;
  86. byteBlock.Read(out m_sync, 2);
  87. this.m_bodyLength = byteBlock.ReadInt16() + 3 - 6;//先把crc校验和end都获取。
  88. byteBlock.Read(out m_cMDID, 17);
  89. this.FrameType = (byte)byteBlock.ReadByte();
  90. this.PacketType = (byte)byteBlock.ReadByte();
  91. this.FrameNo = (byte)byteBlock.ReadByte();
  92. this.ChannelNo = (byte)byteBlock.ReadByte();
  93. this.PresettingNo = (byte)byteBlock.ReadByte();
  94. this.PacketNo = byteBlock.ReadUInt16();
  95. this.SubpacketNo = byteBlock.ReadUInt16();
  96. return true;
  97. }
  98. }
  99. return false;
  100. }
  101. public bool OnParsingBody(byte[] body)
  102. {
  103. if (body.Length == this.BodyLength && body[^1] == 150)
  104. {
  105. using (ByteBlock byteBlock = new ByteBlock(body))
  106. {
  107. byteBlock.Read(out this.m_sample, this.m_bodyLength-3);
  108. byteBlock.Read(out this.m_cRC16, 2);
  109. this.End = (byte)byteBlock.ReadByte();
  110. }
  111. return true;
  112. }
  113. return false;
  114. }
  115. }
  116. }