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.

117 lines
5.2 KiB

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Text;
  7. using JT809.Protocol.Configs;
  8. using JT809.Protocol.Enums;
  9. using JT809.Protocol.Exceptions;
  10. using JT809.Protocol.ProtocolPacket.Extensions;
  11. namespace JT809.Protocol.ProtocolPacket
  12. {
  13. /// <summary>
  14. /// 数据包
  15. /// </summary>
  16. public class Package: BufferedEntityBase
  17. {
  18. public const int NotDataLength = 26;
  19. public const int Crc16ByteLength = 2;
  20. public const byte BeginFlag = 0X5B;
  21. public const byte EndFlag = 0X5D;
  22. public const int BeginFixedByteLength = 1;
  23. public const int EndFixedByteLength = 1;
  24. public JT809Config JT809Config;
  25. public Header Header { get; private set; }
  26. public MessageBody Body { get; private set; }
  27. private ushort CRC16 { get; set; }
  28. public Package(byte[] buffer) : base(buffer){}
  29. public Package(Header header, MessageBody body, JT809Config jt809Config) : base(header, body)
  30. {
  31. JT809Config = jt809Config;
  32. }
  33. protected override void InitializeProperties(object[] properties, int startIndex)
  34. {
  35. Header = properties[0] as Header;
  36. Body = properties[1] as MessageBody;
  37. if (Header == null) throw new NullReferenceException($"{new StackFrame().GetMethod().Name }:Header can't be null.");
  38. if (Body == null) throw new NullReferenceException($"{new StackFrame().GetMethod().Name }:Body can't be null.");
  39. }
  40. protected override void OnInitializePropertiesFromReadBuffer(BinaryReader reader)
  41. {
  42. var content00 = new byte[Buffer.Length- BeginFixedByteLength-EndFixedByteLength];
  43. Array.Copy(Buffer, BeginFixedByteLength, content00, 0, Buffer.Length- BeginFixedByteLength-EndFixedByteLength);
  44. var content01 = this.UnEscape(content00);
  45. var crc16 = this.CRC16_CCITT(content01, 0, content01.Length - Crc16ByteLength);
  46. CRC16 = BitConverter.ToUInt16(new[] { content01[content01.Length - 1], content01[content01.Length - 2] }, 0);
  47. if (CRC16 != crc16) throw new JT809Exception(ErrorCode.CRC16CheckInvalid,$"{CRC16}-{crc16},{content01.ToHexString()}");
  48. Header = new Header(content01);
  49. var bodyBuffer00 = new byte[content01.Length - Header.HeaderFixedByteLength - Crc16ByteLength];
  50. Array.Copy(content01, Header.HeaderFixedByteLength, bodyBuffer00, 0, bodyBuffer00.Length);
  51. //Default
  52. byte[] bodyBuffer01 = bodyBuffer00;
  53. switch (Header.EncryptOpition)
  54. {
  55. case EncryptOpitions.None:
  56. break;
  57. case EncryptOpitions.Common:
  58. bodyBuffer01 = this.Encrypt(bodyBuffer01, bodyBuffer01.Length, JT809Config.JT809EncryptConfig);
  59. break;
  60. }
  61. if (Header.Length != (bodyBuffer01.Length + NotDataLength)) throw new JT809Exception(ErrorCode.HeaderLengthNotEqualBodyLength);
  62. Body = GenerateBody(Header.BusinessID, bodyBuffer01);
  63. }
  64. protected override void OnWriteToBuffer(BinaryWriter writer)
  65. {
  66. writer.WriteLittle(BeginFlag);
  67. //Dealling Code On Header
  68. var headerBuffer00 = Header.Buffer;
  69. //Dealling Code On Body
  70. byte[] bodyBuffer00 = Body.Buffer;
  71. switch (Header.EncryptOpition)
  72. {
  73. case EncryptOpitions.None:
  74. bodyBuffer00 = Body.Buffer;
  75. break;
  76. case EncryptOpitions.Common:
  77. bodyBuffer00 = this.Encrypt(Body.Buffer, Body.Buffer.Length, JT809Config.JT809EncryptConfig);
  78. break;
  79. }
  80. //Content:Except BeginFlag & EndFlag
  81. var content = new byte[headerBuffer00.Length + bodyBuffer00.Length + Crc16ByteLength];
  82. Array.Copy(headerBuffer00, 0, content, 0, headerBuffer00.Length);
  83. Array.Copy(bodyBuffer00, 0, content, headerBuffer00.Length, bodyBuffer00.Length);
  84. //Dealling Code On CRC16
  85. CRC16 = this.CRC16_CCITT(content, 0, content.Length - Crc16ByteLength);
  86. var crc1600 = BitConverter.GetBytes(CRC16).Reverse().ToArray();
  87. Array.Copy(crc1600, 0, content, headerBuffer00.Length + bodyBuffer00.Length, Crc16ByteLength);
  88. //Last Content
  89. var content00 = this.Escape(content);
  90. //ToBuffer Core.
  91. writer.WriteLittle(content00);
  92. writer.WriteLittle(EndFlag);
  93. }
  94. public static Package GeneratePackage(BusinessType businessType, MessageBody messageBody, JT809Config jt809Config)
  95. {
  96. var header = new Header((uint)messageBody.Buffer.Length, businessType, jt809Config);
  97. return new Package(header, messageBody, jt809Config);
  98. }
  99. public static MessageBody GenerateBody(BusinessType businessID, byte[] bodyBuffer)
  100. {
  101. return Activator.CreateInstance(typeof(object), bodyBuffer) as MessageBody;
  102. }
  103. }
  104. }