You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

137 lines
4.6 KiB

  1. using JT808.Protocol.Enums;
  2. using JT808.Protocol.Exceptions;
  3. using JT808.Protocol.MessagePack;
  4. namespace JT808.Protocol
  5. {
  6. /// <summary>
  7. /// JT808头部数据包
  8. /// </summary>
  9. public record JT808HeaderPackage
  10. {
  11. /// <summary>
  12. /// 起始符
  13. /// </summary>
  14. public byte Begin { get; set; }
  15. /// <summary>
  16. /// 头数据
  17. /// </summary>
  18. public JT808Header Header { get; set; }
  19. /// <summary>
  20. /// 数据体
  21. /// </summary>
  22. public byte[] Bodies { get; set; }
  23. /// <summary>
  24. /// 校验码
  25. /// 从消息头开始,同后一字节异或,直到校验码前一个字节,占用一个字节。
  26. /// </summary>
  27. public byte CheckCode { get; set; }
  28. /// <summary>
  29. /// 终止符
  30. /// </summary>
  31. public byte End { get; set; }
  32. /// <summary>
  33. /// 808版本号
  34. /// </summary>
  35. public JT808Version Version
  36. {
  37. get {
  38. if (Header != null)
  39. {
  40. try
  41. {
  42. if (Header.MessageBodyProperty.VersionFlag)
  43. {
  44. return JT808Version.JTT2019;
  45. }
  46. else
  47. {
  48. return JT808Version.JTT2013;
  49. }
  50. }
  51. catch
  52. {
  53. return JT808Version.JTT2013;
  54. }
  55. }
  56. else
  57. {
  58. return JT808Version.JTT2013;
  59. }
  60. }
  61. }
  62. /// <summary>
  63. /// 原数据
  64. /// </summary>
  65. public byte[] OriginalData { get; set; }
  66. /// <summary>
  67. ///
  68. /// </summary>
  69. /// <param name="reader"></param>
  70. /// <param name="config"></param>
  71. public JT808HeaderPackage(ref JT808MessagePackReader reader, IJT808Config config)
  72. {
  73. // 1. 验证校验和
  74. if (!config.SkipCRCCode)
  75. {
  76. if (!reader.CheckXorCodeVali)
  77. {
  78. throw new JT808Exception(JT808ErrorCode.CheckCodeNotEqual, $"{reader.RealCheckXorCode}!={reader.CalculateCheckXorCode}");
  79. }
  80. }
  81. // ---------------开始解包--------------
  82. // 2.读取起始位置
  83. this.Begin = reader.ReadStart();
  84. // 3.读取头部信息
  85. this.Header = new JT808Header();
  86. // 3.1.读取消息Id
  87. this.Header.MsgId = reader.ReadUInt16();
  88. // 3.2.读取消息体属性
  89. ushort messageBodyPropertyValue = reader.ReadUInt16();
  90. // 3.2.1.解包消息体属性
  91. this.Header.MessageBodyProperty = new JT808HeaderMessageBodyProperty(messageBodyPropertyValue);
  92. if (this.Header.MessageBodyProperty.VersionFlag)
  93. {
  94. //2019版本
  95. // 3.3.读取协议版本号
  96. this.Header.ProtocolVersion = reader.ReadByte();
  97. // 3.4.读取终端手机号
  98. this.Header.TerminalPhoneNo = reader.ReadBCD(20, config.Trim);
  99. reader.Version = JT808Version.JTT2019;
  100. }
  101. else
  102. {
  103. //2013版本
  104. // 3.3.读取终端手机号
  105. this.Header.TerminalPhoneNo = reader.ReadBCD(config.TerminalPhoneNoLength, config.Trim);
  106. }
  107. // 3.4.读取消息流水号
  108. this.Header.MsgNum = reader.ReadUInt16();
  109. // 3.5.判断有无分包
  110. if (this.Header.MessageBodyProperty.IsPackage)
  111. {
  112. //3.5.1.读取消息包总数
  113. this.Header.PackgeCount = reader.ReadUInt16();
  114. //3.5.2.读取消息包序号
  115. this.Header.PackageIndex = reader.ReadUInt16();
  116. }
  117. // 4.处理数据体
  118. // 4.1.判断有无数据体
  119. if (this.Header.MessageBodyProperty.DataLength > 0)
  120. {
  121. this.Bodies = reader.ReadContent().ToArray();
  122. }
  123. else
  124. {
  125. this.Bodies = default;
  126. }
  127. // 5.读取校验码
  128. this.CheckCode = reader.ReadByte();
  129. // 6.读取终止位置
  130. this.End = reader.ReadEnd();
  131. // ---------------解包完成--------------
  132. this.OriginalData = reader.SrcBuffer.ToArray();
  133. }
  134. }
  135. }