Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

158 rindas
7.2 KiB

  1. using JT809.Protocol.Attributes;
  2. using JT809.Protocol.Enums;
  3. using JT809.Protocol.Exceptions;
  4. using JT809.Protocol.Extensions;
  5. using JT809.Protocol.Interfaces;
  6. using JT809.Protocol.Internal;
  7. using JT809.Protocol.MessagePack;
  8. using System;
  9. using System.Buffers;
  10. using System.Collections.Generic;
  11. using System.Text;
  12. namespace JT809.Protocol.Formatters
  13. {
  14. public class JT809PackageFormatter : IJT809MessagePackFormatter<JT809Package>
  15. {
  16. public readonly static JT809PackageFormatter Instance = new JT809PackageFormatter();
  17. public JT809Package Deserialize(ref JT809MessagePackReader reader, IJT809Config config)
  18. {
  19. // 1. 验证校验码
  20. if (!config.SkipCRCCode)
  21. {
  22. // 1.2. 验证校验码
  23. if (!reader.CheckXorCodeVali)
  24. {
  25. throw new JT809Exception(JT809ErrorCode.CRC16CheckInvalid, $"{reader.CalculateCheckXorCode.ToString()}!={reader.RealCheckXorCode.ToString()}");
  26. }
  27. }
  28. JT809Package jT809Package = new JT809Package();
  29. // 2.读取起始头
  30. jT809Package.BeginFlag = reader.ReadStart();
  31. // 3.初始化消息头
  32. try
  33. {
  34. jT809Package.Header = JT809HeaderFormatter.Instance.Deserialize(ref reader, config);
  35. }
  36. catch (Exception ex)
  37. {
  38. throw new JT809Exception(JT809ErrorCode.HeaderParseError, $"offset>{reader.ReadCurrentRemainContentLength().ToString()}", ex);
  39. }
  40. // 5.数据体处理
  41. // 5.1 判断是否有数据体(总长度-固定长度)> 0
  42. if ((jT809Package.Header.MsgLength - JT809Package.FixedByteLength) > 0)
  43. {
  44. try
  45. {
  46. Type jT809BodiesImplType = config.BusinessTypeFactory.GetBodiesImplTypeByBusinessType(jT809Package.Header.BusinessType, jT809Package.Header.MsgGNSSCENTERID);
  47. if (jT809BodiesImplType != null)
  48. {
  49. // 5.2 是否加密
  50. switch (jT809Package.Header.EncryptFlag)
  51. {
  52. case JT809Header_Encrypt.None:
  53. // 5.3 处理消息体
  54. jT809Package.Bodies = JT809MessagePackFormatterResolverExtensions.JT809DynamicDeserialize(
  55. config.GetMessagePackFormatterByType(jT809BodiesImplType),
  56. ref reader, config);
  57. break;
  58. case JT809Header_Encrypt.Common:
  59. // 5.4. 处理加密消息体
  60. byte[] bodiesData = config.Encrypt.Decrypt(reader.ReadContent(), config.EncryptOptions, jT809Package.Header.EncryptKey);
  61. JT809MessagePackReader bodiesReader = new JT809MessagePackReader(bodiesData);
  62. jT809Package.Bodies = JT809MessagePackFormatterResolverExtensions.JT809DynamicDeserialize(
  63. config.GetMessagePackFormatterByType(jT809BodiesImplType),
  64. ref bodiesReader, config);
  65. break;
  66. }
  67. }
  68. }
  69. catch (Exception ex)
  70. {
  71. throw new JT809Exception(JT809ErrorCode.BodiesParseError, $"offset>{reader.ReadCurrentRemainContentLength().ToString()}", ex);
  72. }
  73. }
  74. jT809Package.CRCCode = reader.CalculateCheckXorCode;
  75. jT809Package.EndFlag = reader.ReadEnd();
  76. return jT809Package;
  77. }
  78. public void Serialize(ref JT809MessagePackWriter writer, JT809Package value, IJT809Config config)
  79. {
  80. // -----------开始组包----------
  81. // 1.起始符
  82. writer.WriteByte(value.BeginFlag);
  83. // 2.写入头部数据
  84. // 2.1.跳过数据长度的写入
  85. writer.Skip(4, out int lengthPosition);
  86. // 2.2.报文序列号
  87. value.Header.MsgSN = value.Header.MsgSN > 0 ? value.Header.MsgSN : config.MsgSNDistributed.Increment();
  88. writer.WriteUInt32(value.Header.MsgSN);
  89. // 2.3.业务数据类型
  90. writer.WriteUInt16(value.Header.BusinessType);
  91. // 2.4.下级平台接入码
  92. writer.WriteUInt32(value.Header.MsgGNSSCENTERID);
  93. // 2.5.版本号
  94. writer.WriteArray(value.Header.Version.Buffer);
  95. // 2.6.报文加密
  96. writer.WriteByte((byte)value.Header.EncryptFlag);
  97. // 2.7.数据加密密钥
  98. writer.WriteUInt32(value.Header.EncryptKey);
  99. // 3.写入数据体
  100. // 3.1.记录当前开始位置
  101. int startIndex = writer.GetCurrentPosition();
  102. // 3.2.写入数据对应数据体
  103. if (value.Bodies != null)
  104. {
  105. JT809MessagePackFormatterResolverExtensions.JT809DynamicSerialize(
  106. config.GetMessagePackFormatterByType(value.Bodies.GetType()),
  107. ref writer, value.Bodies,
  108. config);
  109. }
  110. // 3.3.记录当前结束位置
  111. int endIndex = writer.GetCurrentPosition();
  112. int contentLength = endIndex - startIndex;
  113. if (contentLength > 0)
  114. {
  115. // 3.4. 数据加密
  116. switch (value.Header.EncryptFlag)
  117. {
  118. case JT809Header_Encrypt.None:
  119. break;
  120. case JT809Header_Encrypt.Common:
  121. // 3.5. 提取数据体并进行加密处理
  122. byte[] messageBodyDatEncrypted = config.Encrypt.Encrypt(writer.Extract(startIndex), config.EncryptOptions, value.Header.EncryptKey);
  123. int flagLength = messageBodyDatEncrypted.Length - contentLength;
  124. if (flagLength == 0)
  125. {
  126. // 相等复制
  127. writer.CopyTo(messageBodyDatEncrypted, startIndex);
  128. }
  129. else if (flagLength > 0)
  130. {
  131. // 扩容
  132. writer.Skip(flagLength, out _);
  133. writer.CopyTo(messageBodyDatEncrypted, startIndex);
  134. }
  135. else
  136. {
  137. // 缩减
  138. writer.CopyTo(messageBodyDatEncrypted, startIndex);
  139. writer.Shrink(-flagLength);
  140. }
  141. break;
  142. }
  143. }
  144. // 4.计算内容的总长度(校验码2+终止符1=3)
  145. writer.WriteInt32Return(writer.GetCurrentPosition() + 3, lengthPosition);
  146. // 5.校验码
  147. writer.WriteCRC16();
  148. // 6.终止符
  149. writer.WriteByte(value.EndFlag);
  150. // 7.转义
  151. writer.WriteEncode();
  152. // -----------组包完成----------
  153. }
  154. }
  155. }