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.

143 regels
5.5 KiB

  1. using GBNewEnergy.Protocol.Enums;
  2. using GBNewEnergy.Protocol.Exceptions;
  3. using GBNewEnergy.Protocol.Extensions;
  4. using GBNewEnergy.Protocol.NEProperties;
  5. using System;
  6. using System.IO;
  7. namespace GBNewEnergy.Protocol
  8. {
  9. /// <summary>
  10. /// 新能源包
  11. /// </summary>
  12. public class NEPackage : NEBufferedEntityBase
  13. {
  14. public NEPackage(byte[] header, byte[] body, NEGlobalConfigs nEConfigs) : base(header, body, nEConfigs)
  15. {
  16. }
  17. public NEPackage(byte[] buf, NEGlobalConfigs nEConfigs) : base(buf, nEConfigs)
  18. {
  19. }
  20. public NEPackage(INEProperties nEProperties, NEGlobalConfigs nEConfigs)
  21. : base(nEProperties, nEConfigs)
  22. { }
  23. /// <summary>
  24. /// 固定为24个字节长度
  25. /// </summary>
  26. public const int HeaderFixedByteLength = 24;
  27. /// <summary>
  28. /// 起始符
  29. /// </summary>
  30. public const byte BeginFlag = 0x23;
  31. /// <summary>
  32. /// 校验位1字节
  33. /// </summary>
  34. private const int CheckBit = 1;
  35. /// <summary>
  36. /// 命令标识
  37. /// </summary>
  38. public NEMsgId MsgId { get; private set; }
  39. /// <summary>
  40. /// 应答标志
  41. /// </summary>
  42. public NEAskId AskId { get; private set; }
  43. /// <summary>
  44. /// 车辆识别码
  45. /// </summary>
  46. public string VIN { get; private set; }
  47. /// <summary>
  48. /// 数据加密方式
  49. /// 0x01:数据不加密;0x02:数据经过 RSA 算法加密;0x03:数据经过 AES128 位算法加密;“0xFE”表示异常,“0xFF”表示无效
  50. /// </summary>
  51. public NEEncryptMethod EncryptMethod { get; private set; }
  52. /// <summary>
  53. /// 数据单元长度是数据单元的总字节数,有效值范围:0-65531
  54. /// </summary>
  55. public int DataUnitLength { get; private set; }
  56. /// <summary>
  57. /// 采用BCC(异或检验)法,校验范围从命令单元的第一个字节开始,同后一个字节异或,直到校验码前一个字节为止,
  58. /// 校验码占用一个字节,当数据单元存在加密时,应先加密后检验,先校验后解密
  59. /// </summary>
  60. public byte BCCCode { get; private set; }
  61. /// <summary>
  62. /// 头数据
  63. /// </summary>
  64. public byte[] Header { get; private set; }
  65. /// <summary>
  66. /// 数据体
  67. /// </summary>
  68. public NEBodies Bodies { get; protected set; }
  69. protected override void ToBuffer()
  70. {
  71. // 固定单元长度
  72. DataUnitLength = Bodies.Buffer.Length;
  73. Buffer = new byte[HeaderFixedByteLength + DataUnitLength + CheckBit];
  74. Buffer[0] = BeginFlag;
  75. Buffer[1] = BeginFlag;
  76. Buffer[2] = (byte)MsgId;
  77. Buffer[3] = (byte)AskId;
  78. Buffer.WriteLittle(VIN, 4);
  79. Buffer[21] = (byte)EncryptMethod;
  80. Buffer.WriteLittle(DataUnitLength, 22, 2);
  81. if (NEConfigs.Encrypt != null)
  82. {
  83. Buffer.WriteLittle(NEConfigs.Encrypt.Encrypt(Bodies.Buffer), 24, DataUnitLength);
  84. }
  85. else
  86. {
  87. Buffer.WriteLittle(Bodies.Buffer, 24, DataUnitLength);
  88. }
  89. BCCCode = Buffer.ToXor(2, (HeaderFixedByteLength + DataUnitLength - 1));
  90. Buffer[HeaderFixedByteLength + DataUnitLength] = BCCCode;
  91. Header = new byte[HeaderFixedByteLength];
  92. Array.Copy(Buffer, 0, Header, 0, HeaderFixedByteLength);
  93. }
  94. protected override void InitializeProperties(INEProperties nEProperties)
  95. {
  96. NEPackageProperty nEPackageProperty = (NEPackageProperty)nEProperties;
  97. VIN = nEPackageProperty.VIN;
  98. MsgId = nEPackageProperty.MsgId;
  99. AskId = nEPackageProperty.AskId;
  100. Bodies = nEPackageProperty.Bodies;
  101. EncryptMethod = NEConfigs.EncryptMethod;
  102. }
  103. protected override void InitializePropertiesFromBuffer()
  104. {
  105. if (Buffer[0] != BeginFlag && Buffer[1] == BeginFlag) throw new NEException(NEErrorCode.BeginFlagError, $"{Buffer[0]},{Buffer[1]}");
  106. MsgId = (NEMsgId)Buffer[2];
  107. AskId = (NEAskId)Buffer[3];
  108. VIN = Buffer.ReadStringLittle(4, 17);
  109. EncryptMethod = (NEEncryptMethod)Buffer[21];
  110. DataUnitLength = Buffer.ReadUShortH2LLittle(22, 2);
  111. // 进行BCC校验码
  112. // 校验位 = 报文长度 - 最后一位(校验位) - 偏移量(2)
  113. int checkBit = Buffer.Length - CheckBit - 2;
  114. byte bCCCode = Buffer.ToXor(2, checkBit);
  115. byte bCCCode2 = Buffer[Buffer.Length - CheckBit];
  116. if (bCCCode != bCCCode2)
  117. {
  118. throw new NEException(NEErrorCode.BCCCodeError, $"request:{bCCCode2}!=calculate:{bCCCode}");
  119. }
  120. BCCCode = bCCCode2;
  121. byte[] bodiesBytes = new byte[DataUnitLength + CheckBit];
  122. Array.Copy(Buffer, HeaderFixedByteLength, bodiesBytes, 0, bodiesBytes.Length);
  123. if (NEConfigs.Encrypt != null)
  124. {
  125. Bodies = NEBodiesFactory.GetNEBodiesByMsgId(MsgId, NEConfigs.Encrypt.Decrypt(bodiesBytes),NEConfigs);
  126. }
  127. else
  128. {
  129. Bodies = NEBodiesFactory.GetNEBodiesByMsgId(MsgId, bodiesBytes, NEConfigs);
  130. }
  131. Header = new byte[HeaderFixedByteLength];
  132. Array.Copy(Buffer, 0, Header, 0, HeaderFixedByteLength);
  133. }
  134. }
  135. }