瀏覽代碼

1.增加0x1200|0x1201消息

2.增加0x1200|0x1201消息测试
3.增加及修复扩展方法的使用
tags/v1.3.0
SmallChi 6 年之前
父節點
當前提交
01ca4947a8
共有 29 個文件被更改,包括 451 次插入786 次删除
  1. +32
    -20
      README.md
  2. 二進制
      doc/JT-T809.pdf
  3. 二進制
      doc/JTT415-2006.pdf
  4. +54
    -0
      src/JT809.Protocol.Test/JT809MessageBody/JT809_0x1200Test.cs
  5. +42
    -0
      src/JT809.Protocol.Test/JT809SubMessageBody/JT809_0x1200_0x1201Test.cs
  6. +1
    -0
      src/JT809.Protocol/JT809.Protocol.csproj
  7. +0
    -40
      src/JT809.Protocol/JT809Configs/JT809Config.cs
  8. +1
    -0
      src/JT809.Protocol/JT809Enums/JT809BusinessType.cs
  9. +3
    -1
      src/JT809.Protocol/JT809Enums/JT809ErrorCode.cs
  10. +4
    -1
      src/JT809.Protocol/JT809Enums/JT809SubBusinessType.cs
  11. +18
    -0
      src/JT809.Protocol/JT809Enums/JT809VehicleColorType.cs
  12. +94
    -57
      src/JT809.Protocol/JT809Extensions/JT809BinaryExtensions.cs
  13. +64
    -0
      src/JT809.Protocol/JT809Formatters/JT809MessageBodyFormatters/JT809_0x1200Formatter.cs
  14. +37
    -0
      src/JT809.Protocol/JT809Formatters/JT809SubMessageBodyFormatters/JT809_0x1200_0x1201Formatter.cs
  15. +45
    -0
      src/JT809.Protocol/JT809MessageBody/JT809_0x1200.cs
  16. +1
    -1
      src/JT809.Protocol/JT809Serializer.cs
  17. +15
    -0
      src/JT809.Protocol/JT809SubBodies.cs
  18. +40
    -0
      src/JT809.Protocol/JT809SubMessageBody/JT809_0x1200_0x1201.cs
  19. +0
    -47
      src/JT809.Protocol/ProtocolPacket/Bodies/Master/Body_UP_CONNECT_REQ.cs
  20. +0
    -65
      src/JT809.Protocol/ProtocolPacket/BufferedEntityBase.cs
  21. +0
    -99
      src/JT809.Protocol/ProtocolPacket/Extensions/BinaryExtensions.cs
  22. +0
    -141
      src/JT809.Protocol/ProtocolPacket/Extensions/PackageExtensions.cs
  23. +0
    -101
      src/JT809.Protocol/ProtocolPacket/Header.cs
  24. +0
    -11
      src/JT809.Protocol/ProtocolPacket/IBuffer.cs
  25. +0
    -11
      src/JT809.Protocol/ProtocolPacket/IBuffered.cs
  26. +0
    -46
      src/JT809.Protocol/ProtocolPacket/JT809Version.cs
  27. +0
    -14
      src/JT809.Protocol/ProtocolPacket/Message/MainLink/MainLink_Login.cs
  28. +0
    -15
      src/JT809.Protocol/ProtocolPacket/MessageBody.cs
  29. +0
    -116
      src/JT809.Protocol/ProtocolPacket/Package.cs

+ 32
- 20
README.md 查看文件

@@ -1,35 +1,47 @@
# JT809协议开发

### 瞎逼逼:
## 瞎逼逼:

  现在有了[JT808](https://github.com/SmallChi/GPSPlatform/blob/master/JT808.md)的基础,对JT809就只剩搬砖了。

> 该JT809协议是参考[MessagePack-CSharp](https://github.com/neuecc/MessagePack-CSharp)一款二进制序列化器,站在巨人的肩膀上搬砖就是爽歪歪。

> 这GB的文档不得不说,太坑了。。。

## JT809协议消息对照表

### 链路管理类

|序号|消息ID|完成情况|消息体名称|
|:------:|:------:|:------:|:------:|
| 1 | 0x1001 | √ | 主链路登录请求消息 |
| 2 | 0x1002 | √ | 主链路登录应答消息 |
| 3 | 0x1003 | √ | 主链路注销请求消息 |
| 4 | 0x1004 | √ | 主链路注销应答消息 |
| 5 | 0x1005 | √ | 主链路连接保持请求消息 |
| 6 | 0x1006 | √ | 主链路连接保持应答消息 |
| 7 | 0x1007 | √ | 主链路断开通知消息 |
| 8 | 0x1008 | √ | 下级平台主动关闭链路通知消息 |
| 9 | 0x9001 | √ | 从链路连接请求消息 |
| 10 | 0x9002 | √ | 从链路连接应答消息 |
| 11 | 0x9003 | √ | 从链路注销请求消息 |
| 12 | 0x9004 | √ | 从链路注销应答消息 |
| 13 | 0x9005 | √ | 从链路连接保持请求消息 |
| 14 | 0x9006 | √ | 从链路连接保持应答消息 |
| 15 | 0x9007 | √ | 从链路断开通知消息 |
| 16 | 0x9008 | √ | 上级平台主动关闭链路通知消息 |
| 17 | 0x9101 | √ | 接收定位信息数量通知消息 |


| 1 | 0x1001 | √ | 主链路登录请求消息 |
| 2 | 0x1002 | √ | 主链路登录应答消息 |
| 3 | 0x1003 | √ | 主链路注销请求消息 |
| 4 | 0x1004 | √ | 主链路注销应答消息 |
| 5 | 0x1005 | √ | 主链路连接保持请求消息 |
| 6 | 0x1006 | √ | 主链路连接保持应答消息 |
| 7 | 0x1007 | √ | 主链路断开通知消息 |
| 8 | 0x1008 | √ | 下级平台主动关闭链路通知消息 |
| 9 | 0x9001 | √ | 从链路连接请求消息 |
| 10 | 0x9002 | √ | 从链路连接应答消息 |
| 11 | 0x9003 | √ | 从链路注销请求消息 |
| 12 | 0x9004 | √ | 从链路注销应答消息 |
| 13 | 0x9005 | √ | 从链路连接保持请求消息 |
| 14 | 0x9006 | √ | 从链路连接保持应答消息 |
| 15 | 0x9007 | √ | 从链路断开通知消息 |
| 16 | 0x9008 | √ | 上级平台主动关闭链路通知消息 |

### 信息统计类

|序号|消息ID|完成情况|消息体名称|
|:------:|:------:|:------:|:------:|
| 1 | 0x9101 | √ |接收定位信息数量通知消息 |

### 车辆动态信息交换

#### 主链路动态信息交换消息

|序号|消息ID|完成情况|消息体名称|
|:------:|:------:|:------:|:------:|
| 1 | 0x1200 | √ | 主链路动态信息交换消息 |
| 2 | 0x1201 | √ | 上传车辆注册信息 |

二進制
doc/JT-T809.pdf 查看文件


二進制
doc/JTT415-2006.pdf 查看文件


+ 54
- 0
src/JT809.Protocol.Test/JT809MessageBody/JT809_0x1200Test.cs 查看文件

@@ -0,0 +1,54 @@
using JT809.Protocol;
using JT809.Protocol.JT809Extensions;
using JT809.Protocol.JT809MessageBody;
using JT809.Protocol.JT809SubMessageBody;
using JT809.Protocol.JT809Exceptions;
using System;
using System.Collections.Generic;
using System.Text;
using Xunit;

namespace JT809.Protocol.Test.JT809MessageBody
{
public class JT809_0x1200Test
{
[Fact]
public void Test1()
{
JT809_0x1200 jT809_0X1200 = new JT809_0x1200();
jT809_0X1200.VehicleNo= "粤A12345";
jT809_0X1200.VehicleColor = JT809Enums.JT809VehicleColorType.蓝色;
jT809_0X1200.SubBusinessType = JT809Enums.JT809SubBusinessType.UP_EXG_MSG_REGISTER;
jT809_0X1200.DataLength = 61;
JT809_0x1200_0x1201 jT809_0X1200_0X1201 = new JT809_0x1200_0x1201
{
PlateformId = "1111111111",
ProducerId = "1111111111",
TerminalId = "11111AA",
TerminalModelType = "11111111",
TerminalSimCode = "222222222222"
};
jT809_0X1200.JT809SubBodies = jT809_0X1200_0X1201;
var hex = JT809Serializer.Serialize(jT809_0X1200).ToHexString();
//"D4 C1 41 31 32 33 34 35 00 00 00 00 00 00 00 00 00 00 00 00 00 01 12 01 00 00 00 3D 00 00 00 00 00 00 00 42 3A 35 C7 00 00 00 00 00 00 00 42 3A 35 C7 31 31 31 31 31 31 31 31 00 00 00 00 00 00 00 00 00 00 00 00 31 31 31 31 31 41 41 32 32 32 32 32 32 32 32 32 32 32 32"
//"D4 C1 41 31 32 33 34 35 00 00 00 00 00 00 00 00 00 00 00 00 00 01 12 01 00 00 00 3D 00 00 00 00 00 00 00 42 3A 35 C7 00 00 00 00 00 00 00 42 3A 35 C7 31 31 31 31 31 31 31 31 00 00 00 00 00 00 00 00 00 00 00 00 31 31 31 31 31 61 61 32 32 32 32 32 32 32 32 32 32 32 32"
}

[Fact]
public void Test2()
{
var bytes = "D4 C1 41 31 32 33 34 35 00 00 00 00 00 00 00 00 00 00 00 00 00 01 12 01 00 00 00 3D 00 00 00 00 00 00 00 42 3A 35 C7 00 00 00 00 00 00 00 42 3A 35 C7 31 31 31 31 31 31 31 31 00 00 00 00 00 00 00 00 00 00 00 00 31 31 31 31 31 41 41 32 32 32 32 32 32 32 32 32 32 32 32".ToHexBytes();
JT809_0x1200 jT809_0X9001 = JT809Serializer.Deserialize<JT809_0x1200>(bytes);
Assert.Equal("粤A12345", jT809_0X9001.VehicleNo);
Assert.Equal(JT809Enums.JT809VehicleColorType.蓝色, jT809_0X9001.VehicleColor);
Assert.Equal(JT809Enums.JT809SubBusinessType.UP_EXG_MSG_REGISTER, jT809_0X9001.SubBusinessType);
Assert.Equal((ushort)61, jT809_0X9001.DataLength);
JT809_0x1200_0x1201 jT809_0X1200_0X1201 = jT809_0X9001.JT809SubBodies as JT809_0x1200_0x1201;
Assert.Equal("1111111111", jT809_0X1200_0X1201.PlateformId);
Assert.Equal("1111111111", jT809_0X1200_0X1201.ProducerId);
Assert.Equal("11111AA", jT809_0X1200_0X1201.TerminalId);
Assert.Equal("11111111", jT809_0X1200_0X1201.TerminalModelType);
Assert.Equal("222222222222", jT809_0X1200_0X1201.TerminalSimCode);
}
}
}

+ 42
- 0
src/JT809.Protocol.Test/JT809SubMessageBody/JT809_0x1200_0x1201Test.cs 查看文件

@@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Text;
using Xunit;
using JT809.Protocol;
using JT809.Protocol.JT809Extensions;
using JT809.Protocol.JT809MessageBody;
using JT809.Protocol.JT809Exceptions;
using JT809.Protocol.JT809SubMessageBody;

namespace JT809.Protocol.Test.JT809SubMessageBody
{
public class JT809_0x1200_0x1201Test
{
[Fact]
public void Test1()
{
JT809_0x1200_0x1201 jT809_0X1200_0X1201 = new JT809_0x1200_0x1201
{
PlateformId= "1111111111",
ProducerId= "1111111111",
TerminalId= "11111AA",
TerminalModelType= "11111111",
TerminalSimCode= "222222222222"
};
var hex = JT809Serializer.Serialize(jT809_0X1200_0X1201).ToHexString();
//"00 00 00 00 00 00 00 42 3A 35 C7 00 00 00 00 00 00 00 42 3A 35 C7 31 31 31 31 31 31 31 31 00 00 00 00 00 00 00 00 00 00 00 00 31 31 31 31 31 41 41 32 32 32 32 32 32 32 32 32 32 32 32"
}

[Fact]
public void Test2()
{
var bytes = "00 00 00 00 00 00 00 42 3A 35 C7 00 00 00 00 00 00 00 42 3A 35 C7 31 31 31 31 31 31 31 31 00 00 00 00 00 00 00 00 00 00 00 00 31 31 31 31 31 41 41 32 32 32 32 32 32 32 32 32 32 32 32".ToHexBytes();
JT809_0x1200_0x1201 jT809_0X1200_0X1201 = JT809Serializer.Deserialize<JT809_0x1200_0x1201>(bytes);
Assert.Equal("1111111111", jT809_0X1200_0X1201.PlateformId);
Assert.Equal("1111111111", jT809_0X1200_0X1201.ProducerId);
Assert.Equal("11111AA", jT809_0X1200_0X1201.TerminalId);
Assert.Equal("11111111", jT809_0X1200_0X1201.TerminalModelType);
Assert.Equal("222222222222", jT809_0X1200_0X1201.TerminalSimCode);
}
}
}

+ 1
- 0
src/JT809.Protocol/JT809.Protocol.csproj 查看文件

@@ -37,6 +37,7 @@
<Compile Include="JT809Enums\JT809ErrorCode.cs" />
<Compile Include="JT809Enums\JT809BusinessType.cs" />
<Compile Include="JT809Enums\JT809SubBusinessType.cs" />
<Compile Include="JT809Enums\JT809VehicleColorType.cs" />
<Compile Include="JT809Enums\JT809_0x1002_Result.cs" />
<Compile Include="JT809Enums\JT809_0x1007_ErrorCode.cs" />
<Compile Include="JT809Enums\JT809_0x9007_ReasonCode.cs" />


+ 0
- 40
src/JT809.Protocol/JT809Configs/JT809Config.cs 查看文件

@@ -1,40 +0,0 @@
using JT809.Protocol.ProtocolPacket;
using System;
using System.Collections.Generic;
using System.Text;

namespace JT809.Protocol.Configs
{
public class JT809Config
{
public JT809Config() { }

public JT809Config(uint sessionId, JT809Version jt809Version)
{
SessionId = sessionId;
JT809Version = jt809Version;
}

public JT809Config(uint sessionId, JT809Version jt809Version, JT809EncryptConfig encryptConfig)
{
SessionId = sessionId;
JT809Version = jt809Version;
JT809EncryptConfig = encryptConfig;
}

/// <summary>
/// 下级平台接入码,上级平台给下级平台分配唯一标识码。
/// </summary>
public uint SessionId { get; set; }

/// <summary>
/// 加密配置
/// </summary>
public JT809EncryptConfig JT809EncryptConfig { get; set; }

/// <summary>
/// 版本号
/// </summary>
public JT809Version JT809Version { get; set; } = new JT809Version();
}
}

+ 1
- 0
src/JT809.Protocol/JT809Enums/JT809BusinessType.cs 查看文件

@@ -123,6 +123,7 @@ namespace JT809.Protocol.JT809Enums
///主链路动态信息交换消息
///</summary>
[Description("主链路动态信息交换消息")]
[JT809BodiesType(typeof(JT809_0x1200))]
UP_EXG_MSG = 0x1200,
///<summary>
///从链路动态信息交换消息


+ 3
- 1
src/JT809.Protocol/JT809Enums/JT809ErrorCode.cs 查看文件

@@ -12,6 +12,8 @@ namespace JT809.Protocol.JT809Enums
SerializeError=1004,
DeserializeError=1005,
HeaderParseError=1006,
BodiesParseError=1007
BodiesParseError=1007,
SubBodiesParseError = 1008,
GetAttributeError=1009
}
}

+ 4
- 1
src/JT809.Protocol/JT809Enums/JT809SubBusinessType.cs 查看文件

@@ -1,4 +1,6 @@
using System.ComponentModel;
using JT809.Protocol.JT809Attributes;
using JT809.Protocol.JT809SubMessageBody;
using System.ComponentModel;

namespace JT809.Protocol.JT809Enums
{
@@ -12,6 +14,7 @@ namespace JT809.Protocol.JT809Enums
/// 上传车辆注册信息
/// </summary>
[Description("上传车辆注册信息")]
[JT809BodiesType(typeof(JT809_0x1200_0x1201))]
UP_EXG_MSG_REGISTER = 0x1201,
///<summary>
///实时上传车辆定位信息


+ 18
- 0
src/JT809.Protocol/JT809Enums/JT809VehicleColorType.cs 查看文件

@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace JT809.Protocol.JT809Enums
{
/// <summary>
/// 车辆颜色,按照 JT/T415-2006 中5.4.12 的规定
/// </summary>
public enum JT809VehicleColorType:byte
{
蓝色=0x01,
黄色=0x02,
黑色 = 0x03,
白色 = 0x04,
其他 =0x09,
}
}

+ 94
- 57
src/JT809.Protocol/JT809Extensions/JT809BinaryExtensions.cs 查看文件

@@ -58,7 +58,7 @@ namespace JT809.Protocol.JT809Extensions
public static string ReadStringLittle(ReadOnlySpan<byte> read, ref int offset, int len)
{
string value = encoding.GetString(read.Slice(offset, len).ToArray());
offset += value.Length;
offset += len;
return value.Trim('\0');
}

@@ -69,11 +69,6 @@ namespace JT809.Protocol.JT809Extensions
return value.Trim('\0');
}

//public static void WriteLatLng(byte[] write, int offset,double latlng)
//{
// WriteLittle(write, (int)(Math.Pow(10, 6) * latlng), offset, 4);
//}

public static long ReadBCD(ReadOnlySpan<byte> buf, ref int offset, int len)
{
long result = 0;
@@ -164,15 +159,42 @@ namespace JT809.Protocol.JT809Extensions
return temp.ToArray();
}

public static int WriteLittle(ref byte[] write, int offset, DateTime date)
/// <summary>
/// 数字编码 大端模式、高位在前
/// </summary>
/// <param name="read"></param>
/// <param name="offset"></param>
/// <param name="len"></param>
/// <returns></returns>
public static string ReadBigNumberLittle(ReadOnlySpan<byte> read, ref int offset, int len)
{
write[offset] = ((byte)(date.Year - DateLimitYear)).ToBcdByte();
write[offset + 1] = ((byte)(date.Month)).ToBcdByte();
write[offset + 2] = ((byte)(date.Day)).ToBcdByte();
write[offset + 3] = ((byte)(date.Hour)).ToBcdByte();
write[offset + 4] = ((byte)(date.Minute)).ToBcdByte();
write[offset + 5] = ((byte)(date.Second)).ToBcdByte();
return 6;
ulong result = 0;
for (int i = 0; i < len; i++)
{
ulong currentData = (ulong)read[offset+i] << (8 * (len - i - 1));
result += currentData;
}
offset += len;
return result.ToString();
}

/// <summary>
/// 数字编码 小端模式、低位在前
/// </summary>
/// <param name="read"></param>
/// <param name="offset"></param>
/// <param name="len"></param>
/// <returns></returns>
public static string ReadLowNumberLittle(ReadOnlySpan<byte> read, ref int offset, int len)
{
ulong result = 0;
for (int i = 0; i < len; i++)
{
ulong currentData = (ulong)read[offset+i] << (8 * i);
result += currentData;
}
offset += len;
return result.ToString();
}

public static int WriteDateTime6Little(IMemoryOwner<byte> memoryOwner, int offset, DateTime date)
@@ -186,15 +208,6 @@ namespace JT809.Protocol.JT809Extensions
return 6;
}

public static int WriteDateLittle(ref byte[] write, int offset, DateTime date)
{
write[offset] = (byte)(date.Year >> 8);
write[offset + 1] = (byte)date.Year;
write[offset + 2] = ((byte)(date.Month)).ToBcdByte();
write[offset + 3] = ((byte)(date.Day)).ToBcdByte();
return 4;
}

public static int WriteDateTime4Little(IMemoryOwner<byte> memoryOwner, int offset, DateTime date)
{
memoryOwner.Memory.Span[offset] = (byte)(date.Year >> 8);
@@ -204,15 +217,6 @@ namespace JT809.Protocol.JT809Extensions
return 4;
}

public static int WriteLittle(ref byte[] write, int offset, int data)
{
write[offset] = (byte)(data >> 24);
write[offset + 1] = (byte)(data >> 16);
write[offset + 2] = (byte)(data >> 8);
write[offset + 3] = (byte)data;
return 4;
}

public static int WriteInt32Little(IMemoryOwner<byte> memoryOwner, int offset, int data)
{
memoryOwner.Memory.Span[offset] = (byte)(data >> 24);
@@ -244,13 +248,6 @@ namespace JT809.Protocol.JT809Extensions
return 8;
}

public static int WriteUInt16Little(ref byte[] write, int offset, ushort data)
{
write[offset] = (byte)(data >> 8);
write[offset + 1] = (byte)data;
return 2;
}

public static int WriteUInt16Little(IMemoryOwner<byte> memoryOwner, int offset, ushort data)
{
memoryOwner.Memory.Span[offset] = (byte)(data >> 8);
@@ -258,12 +255,6 @@ namespace JT809.Protocol.JT809Extensions
return 2;
}

public static int WriteLittle(ref byte[] write, int offset, byte data)
{
write[offset] = data;
return 1;
}

public static int WriteByteLittle(IMemoryOwner<byte> memoryOwner, int offset, byte data)
{
memoryOwner.Memory.Span[offset] = data;
@@ -276,24 +267,32 @@ namespace JT809.Protocol.JT809Extensions
return data.Length;
}

public static int WriteLittle(ref byte[] write, int offset, byte[] data)
{
Buffer.BlockCopy(data, 0, write, offset, data.Length);
return data.Length;
}

public static int WriteLittle(ref byte[] write, int offset, string data)
public static int WriteStringLittle(IMemoryOwner<byte> memoryOwner, int offset, string data)
{
byte[] codeBytes = encoding.GetBytes(data);
Buffer.BlockCopy(codeBytes, 0, write, offset, codeBytes.Length);
CopyTo(codeBytes, memoryOwner.Memory.Span, offset);
return codeBytes.Length;
}

public static int WriteStringLittle(IMemoryOwner<byte> memoryOwner, int offset, string data)
public static int WriteStringLittle(IMemoryOwner<byte> memoryOwner, int offset, string data, int len)
{
byte[] codeBytes = encoding.GetBytes(data);
CopyTo(codeBytes, memoryOwner.Memory.Span, offset);
return codeBytes.Length;
byte[] bytes = null;
if (string.IsNullOrEmpty(data))
{
bytes = new byte[0];
}
else
{
bytes = encoding.GetBytes(data);
}
byte[] rBytes = new byte[len];
for (int i = 0; i < bytes.Length; i++)
{
if (i >= len) break;
rBytes[i] = bytes[i];
}
CopyTo(rBytes, memoryOwner.Memory.Span, offset);
return rBytes.Length;
}

public static int WriteStringPadLeftLittle(IMemoryOwner<byte> memoryOwner, int offset, string data, int len)
@@ -332,6 +331,44 @@ namespace JT809.Protocol.JT809Extensions
return digit;
}

/// <summary>
/// 数字编码 大端模式、高位在前
/// </summary>
/// <param name="memoryOwner"></param>
/// <param name="offset"></param>
/// <param name="data"></param>
/// <param name="len"></param>
/// <returns></returns>
public static int WriteBigNumberLittle(IMemoryOwner<byte> memoryOwner, int offset, string data, int len)
{
ulong number = string.IsNullOrEmpty(data) ? 0 : (ulong)double.Parse(data);
for (int i = len - 1; i >= 0; i--)
{
memoryOwner.Memory.Span[offset+i] = (byte)(number & 0xFF); //取低8位
number = number >> 8;
}
return len;
}

/// <summary>
/// 数字编码 小端模式、低位在前
/// </summary>
/// <param name="memoryOwner"></param>
/// <param name="offset"></param>
/// <param name="data"></param>
/// <param name="len"></param>
/// <returns></returns>
public static int WriteLowNumberLittle(IMemoryOwner<byte> memoryOwner, int offset, string data, int len)
{
ulong number = string.IsNullOrEmpty(data) ? 0 : (ulong)double.Parse(data);
for (int i = 0; i < len; i++)
{
memoryOwner.Memory.Span[offset + i] = (byte)(number & 0xFF); //取低8位
number = number >> 8;
}
return len;
}

public static IEnumerable<byte> ToBytes(this string data, Encoding coding)
{
return coding.GetBytes(data);


+ 64
- 0
src/JT809.Protocol/JT809Formatters/JT809MessageBodyFormatters/JT809_0x1200Formatter.cs 查看文件

@@ -0,0 +1,64 @@
using JT809.Protocol.JT809Attributes;
using JT809.Protocol.JT809Enums;
using JT809.Protocol.JT809Exceptions;
using JT809.Protocol.JT809Extensions;
using JT809.Protocol.JT809MessageBody;
using System;
using System.Buffers;
using System.Collections.Generic;
using System.Text;

namespace JT809.Protocol.JT809Formatters.JT809MessageBodyFormatters
{
public class JT809_0x1200Formatter : IJT809Formatter<JT809_0x1200>
{
public JT809_0x1200 Deserialize(ReadOnlySpan<byte> bytes, out int readSize)
{
int offset = 0;
JT809_0x1200 jT809_0X1200 = new JT809_0x1200();
jT809_0X1200.VehicleNo =JT809BinaryExtensions.ReadStringLittle(bytes, ref offset,21);
jT809_0X1200.VehicleColor = (JT809VehicleColorType)JT809BinaryExtensions.ReadByteLittle(bytes, ref offset);
jT809_0X1200.SubBusinessType = (JT809SubBusinessType)JT809BinaryExtensions.ReadUInt16Little(bytes, ref offset);
jT809_0X1200.DataLength = JT809BinaryExtensions.ReadUInt32Little(bytes, ref offset);
//JT809.Protocol.JT809Enums.JT809BusinessType 映射对应消息特性
JT809BodiesTypeAttribute jT809SubBodiesTypeAttribute = jT809_0X1200.SubBusinessType.GetAttribute<JT809BodiesTypeAttribute>();
if (jT809SubBodiesTypeAttribute == null)
{
throw new JT809Exception(JT809ErrorCode.GetAttributeError, $"JT809BodiesTypeAttribute Not Found>{jT809_0X1200.SubBusinessType.ToString()}");
}
try
{
jT809_0X1200.JT809SubBodies = JT809FormatterResolverExtensions.JT809DynamicDeserialize(JT809FormatterExtensions.GetFormatter(jT809SubBodiesTypeAttribute.JT809BodiesType), bytes.Slice(offset, (int)jT809_0X1200.DataLength), out readSize);
}
catch
{
throw new JT809Exception(JT809ErrorCode.SubBodiesParseError, $"SubBusinessType>{jT809_0X1200.SubBusinessType.ToString()}");
}
readSize = offset;
return jT809_0X1200;
}

public int Serialize(IMemoryOwner<byte> memoryOwner, int offset, JT809_0x1200 value)
{
offset += JT809BinaryExtensions.WriteStringLittle(memoryOwner, offset, value.VehicleNo, 21);
offset += JT809BinaryExtensions.WriteByteLittle(memoryOwner, offset, (byte)value.VehicleColor);
offset += JT809BinaryExtensions.WriteUInt16Little(memoryOwner, offset, (ushort)value.SubBusinessType);
offset += JT809BinaryExtensions.WriteUInt32Little(memoryOwner, offset, value.DataLength);
//JT809.Protocol.JT809Enums.JT809BusinessType 映射对应消息特性
JT809BodiesTypeAttribute jT809SubBodiesTypeAttribute = value.SubBusinessType.GetAttribute<JT809BodiesTypeAttribute>();
if (jT809SubBodiesTypeAttribute == null)
{
throw new JT809Exception(JT809ErrorCode.GetAttributeError, $"JT809BodiesTypeAttribute Not Found>{value.SubBusinessType.ToString()}");
}
try
{
offset = JT809FormatterResolverExtensions.JT809DynamicSerialize(JT809FormatterExtensions.GetFormatter(jT809SubBodiesTypeAttribute.JT809BodiesType), memoryOwner, offset, value.JT809SubBodies);
}
catch
{
throw new JT809Exception(JT809ErrorCode.SubBodiesParseError, $"SubBusinessType>{value.SubBusinessType.ToString()}");
}
return offset;
}
}
}

+ 37
- 0
src/JT809.Protocol/JT809Formatters/JT809SubMessageBodyFormatters/JT809_0x1200_0x1201Formatter.cs 查看文件

@@ -0,0 +1,37 @@
using JT809.Protocol.JT809Extensions;
using JT809.Protocol.JT809SubMessageBody;
using JT809.Protocol.JT809Enums;
using System;
using System.Buffers;
using System.Collections.Generic;
using System.Text;

namespace JT809.Protocol.JT809Formatters.JT809SubMessageBodyFormatters
{
public class JT809_0x1200_0x1201Formatter : IJT809Formatter<JT809_0x1200_0x1201>
{
public JT809_0x1200_0x1201 Deserialize(ReadOnlySpan<byte> bytes, out int readSize)
{
int offset = 0;
JT809_0x1200_0x1201 jT809_0X1200_0X1201 = new JT809_0x1200_0x1201();
jT809_0X1200_0X1201.PlateformId= JT809BinaryExtensions.ReadBigNumberLittle(bytes, ref offset, 11);
jT809_0X1200_0X1201.ProducerId = JT809BinaryExtensions.ReadBigNumberLittle(bytes, ref offset, 11);
jT809_0X1200_0X1201.TerminalModelType = JT809BinaryExtensions.ReadStringLittle(bytes, ref offset, 20);
jT809_0X1200_0X1201.TerminalId = JT809BinaryExtensions.ReadStringLittle(bytes, ref offset, 7);
jT809_0X1200_0X1201.TerminalId = jT809_0X1200_0X1201.TerminalId.ToUpper();
jT809_0X1200_0X1201.TerminalSimCode = JT809BinaryExtensions.ReadStringLittle(bytes, ref offset, 12);
readSize = offset;
return jT809_0X1200_0X1201;
}

public int Serialize(IMemoryOwner<byte> memoryOwner, int offset, JT809_0x1200_0x1201 value)
{
offset += JT809BinaryExtensions.WriteBigNumberLittle(memoryOwner, offset, value.PlateformId,11);
offset += JT809BinaryExtensions.WriteBigNumberLittle(memoryOwner, offset, value.ProducerId, 11);
offset += JT809BinaryExtensions.WriteStringPadRightLittle(memoryOwner, offset, value.TerminalModelType, 20);
offset += JT809BinaryExtensions.WriteStringPadRightLittle(memoryOwner, offset, value.TerminalId.ToUpper(), 7);
offset += JT809BinaryExtensions.WriteStringPadRightLittle(memoryOwner, offset, value.TerminalSimCode, 12);
return offset;
}
}
}

+ 45
- 0
src/JT809.Protocol/JT809MessageBody/JT809_0x1200.cs 查看文件

@@ -0,0 +1,45 @@
using JT809.Protocol.JT809Attributes;
using JT809.Protocol.JT809Enums;
using JT809.Protocol.JT809Formatters.JT809MessageBodyFormatters;
using System;
using System.Collections.Generic;
using System.Text;

namespace JT809.Protocol.JT809MessageBody
{
/// <summary>
/// 主链路车辆动态信息交换业务
/// <para>链路类型:主链路</para>
/// <para>消息方向:下级平台往上级平台</para>
/// <para>业务数据类型标识:UP_EXG_MSG</para>
/// <para>描述:下级平台向上级平台发送车辆动态信息交换业务数据包</para>
/// </summary>
[JT809Formatter(typeof(JT809_0x1200Formatter))]
public class JT809_0x1200:JT809Bodies
{
/// <summary>
/// 车牌号
/// </summary>
public string VehicleNo { get; set; }
/// <summary>
/// 车辆颜色
/// </summary>
public JT809VehicleColorType VehicleColor { get; set; }
/// <summary>
/// 子业务类型标识
/// </summary>
public JT809SubBusinessType SubBusinessType { get; set; }
/// <summary>
/// 后续数据长度
/// </summary>
public uint DataLength { get; set; }
/// <summary>
/// 数据部分
/// </summary>
public byte[] Data { get; set; }
/// <summary>
/// 子业务数据体
/// </summary>
public JT809SubBodies JT809SubBodies { get; set; }
}
}

+ 1
- 1
src/JT809.Protocol/JT809Serializer.cs 查看文件

@@ -39,7 +39,7 @@ namespace JT809.Protocol
{
var formatter = JT809FormatterExtensions.GetFormatter<T>();
var pool = MemoryPool<byte>.Shared;
IMemoryOwner<byte> buffer = pool.Rent(10240);
IMemoryOwner<byte> buffer = pool.Rent(4096);
try
{
var len = formatter.Serialize(buffer, 0, obj);


+ 15
- 0
src/JT809.Protocol/JT809SubBodies.cs 查看文件

@@ -0,0 +1,15 @@
using JT809.Protocol.JT809Enums;
using System;
using System.Collections.Generic;
using System.Text;

namespace JT809.Protocol
{
/// <summary>
/// 子业务数据体
/// </summary>
public abstract class JT809SubBodies
{

}
}

+ 40
- 0
src/JT809.Protocol/JT809SubMessageBody/JT809_0x1200_0x1201.cs 查看文件

@@ -0,0 +1,40 @@
using JT809.Protocol.JT809Attributes;
using JT809.Protocol.JT809Enums;
using JT809.Protocol.JT809Formatters.JT809SubMessageBodyFormatters;
using System;
using System.Collections.Generic;
using System.Text;

namespace JT809.Protocol.JT809SubMessageBody
{
/// <summary>
/// 上传车辆注册信息消息
/// <para>子业务类型标识:UP_ EXG_ MSG_ REGISTER</para>
/// <para>描述:监控平台收到车载终端鉴权信息后,启动本命令向上级监管平台上传该车辆注册信息.各级监管平台再逐级向上级平台上传该信息</para>
/// <para>本条消息服务端无需应答</para>
/// </summary>
[JT809Formatter(typeof(JT809_0x1200_0x1201Formatter))]
public class JT809_0x1200_0x1201:JT809SubBodies
{
/// <summary>
/// 平台唯一编码
/// </summary>
public string PlateformId { get; set; }
/// <summary>
/// 车载终端厂商唯一编码
/// </summary>
public string ProducerId { get; set; }
/// <summary>
/// 车载终端型号,不是 8 位时以“\0”终结
/// </summary>
public string TerminalModelType { get; set; }
/// <summary>
/// 车载终端编号,大写字母和数字组成
/// </summary>
public string TerminalId { get; set; }
/// <summary>
/// 车载终端 SIM 卡电话号码。号码不是12 位,则在前补充数字 0.
/// </summary>
public string TerminalSimCode { get; set; }
}
}

+ 0
- 47
src/JT809.Protocol/ProtocolPacket/Bodies/Master/Body_UP_CONNECT_REQ.cs 查看文件

@@ -1,47 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace JT809.Protocol.ProtocolPacket.Bodies.Master
{
public sealed class Body_UP_CONNECT_REQ : MessageBody
{
public uint UserId { get; private set; }

public byte[] Password { get; private set; }

public byte[] DownLinkIp { get; private set; }

public ushort DownLinkPort { get; private set; }

public Body_UP_CONNECT_REQ(byte[] buffer) : base(buffer) { }

public Body_UP_CONNECT_REQ(uint userId, byte[] password, byte[] downLinkIp, ushort downLinkPort)
: base(userId, password, downLinkIp, downLinkPort) { }

protected override void InitializeProperties(object[] properties, int startIndex)
{
UserId = (uint)properties[startIndex++];
Password = SetMatchBytes((byte[])properties[startIndex++], 8);
DownLinkIp = SetMatchBytes((byte[])properties[startIndex++], 32);
DownLinkPort = (ushort)properties[startIndex++];
}

protected override void OnInitializePropertiesFromReadBuffer(BinaryReader reader)
{
UserId = reader.ReadUInt32Little();
Password = reader.ReadBytes(8);
DownLinkIp = reader.ReadBytes(32);
DownLinkPort = reader.ReadUInt16Little();
}

protected override void OnWriteToBuffer(BinaryWriter writer)
{
writer.WriteLittle(UserId);
writer.WriteLittle(Password);
writer.WriteLittle(DownLinkIp);
writer.WriteLittle(DownLinkPort);
}
}
}

+ 0
- 65
src/JT809.Protocol/ProtocolPacket/BufferedEntityBase.cs 查看文件

@@ -1,65 +0,0 @@
using System;
using System.IO;

namespace JT809.Protocol.ProtocolPacket
{
public abstract class BufferedEntityBase : IBuffered, IBuffer
{
public byte[] Buffer { get; protected set; }

public virtual byte[] ToBuffer()
{
using (var stream = new MemoryStream())
{
var writer = new BinaryWriter(stream);
OnWriteToBuffer(writer);
var reader = new BinaryReader(stream);
stream.Seek(0, SeekOrigin.Begin);
Buffer = reader.ReadBytes((int)stream.Length);//stream.GetBuffer();
stream.Close();
}
return Buffer;
}

protected BufferedEntityBase(params object[] properties)
{
InitializeProperties(properties, 0);
ToBuffer();
}

protected BufferedEntityBase(byte[] buffer)
{
Buffer = buffer;
InitializePropertiesFromBuffer();
}

public static byte[] SetMatchBytes(byte[] bufferIn, int lengthMatch, byte mask = 0X00)
{
if (bufferIn.Length != lengthMatch)
{
var tempBuffer = new byte[lengthMatch];
Array.ForEach(tempBuffer, b => b = mask);//TODO : Maybe mask error
var copyLength = bufferIn.Length > lengthMatch ? lengthMatch : bufferIn.Length;
Array.Copy(bufferIn, 0, tempBuffer, 0, copyLength);
return tempBuffer;
}
return bufferIn;
}

protected abstract void InitializeProperties(object[] properties, int startIndex);

protected abstract void OnInitializePropertiesFromReadBuffer(BinaryReader reader);

protected virtual void InitializePropertiesFromBuffer()
{
using (var stream = new MemoryStream(Buffer))
{
var reader = new BinaryReader(stream);
OnInitializePropertiesFromReadBuffer(reader);
stream.Close();
}
}

protected abstract void OnWriteToBuffer(BinaryWriter writer);
}
}

+ 0
- 99
src/JT809.Protocol/ProtocolPacket/Extensions/BinaryExtensions.cs 查看文件

@@ -1,99 +0,0 @@
using System;
using System.IO;
using System.Linq;

namespace JT809.Protocol.ProtocolPacket
{
public static class BinaryExtensions
{
public static void WriteLittle(this BinaryWriter writer, ulong value)
{
writer.Write((byte)(value >> 56));
writer.Write((byte)(value >> 48));
writer.Write((byte)(value >> 40));
writer.Write((byte)(value >> 32));
writer.Write((byte)(value >> 24));
writer.Write((byte)(value >> 16));
writer.Write((byte)(value >> 8));
writer.Write((byte)(value));
}

public static void WriteLittle(this BinaryWriter writer, uint value)
{
writer.Write((byte)(value >> 24));
writer.Write((byte)(value >> 16));
writer.Write((byte)(value >> 8));
writer.Write((byte)(value));
}

public static void WriteLittle(this BinaryWriter writer, int value)
{
writer.Write((byte)(value >> 24));
writer.Write((byte)(value >> 16));
writer.Write((byte)(value >> 8));
writer.Write((byte)(value));
}

public static void WriteLittle(this BinaryWriter writer, short value)
{
writer.Write((byte)(value >> 8));
writer.Write((byte)(value));
}

public static void WriteLittle(this BinaryWriter writer, ushort value)
{
writer.Write((byte)(value >> 8));
writer.Write((byte)(value));
}

public static void WriteLittle(this BinaryWriter writer, byte value)
{
writer.Write(value);
}

public static void WriteLittle(this BinaryWriter writer, byte[] value)
{
writer.Write(value);
}

public static ulong ReadUInt64Little(this BinaryReader read)
{
var buffer = read.ReadBytes(8);
return (ulong)(buffer[7] | buffer[6] << 8 | buffer[5] << 16 | buffer[4] << 24| buffer[3] << 32 | buffer[2] << 40 | buffer[1] << 48 | buffer[0] << 56);
}

public static uint ReadUInt32Little(this BinaryReader read)
{
var buffer = read.ReadBytes(4);
return (uint)(buffer[3] | buffer[2] << 8 | buffer[1] << 16 | buffer[0] << 24);
}

public static ushort ReadUInt16Little(this BinaryReader read)
{
var buffer = read.ReadBytes(2);
return (ushort)(buffer[1] | buffer[0] << 8);
}

/// <summary>
/// 字节数组转16进制字符串
/// </summary>
/// <param name="bytes"></param>
/// <param name="separator">默认 " "</param>
/// <returns></returns>
public static string ToHexString(this byte[] bytes,string separator=" ")
{
return string.Join(separator, bytes.Select(s => s.ToString("X2")));
}

/// <summary>
/// 16进制字符串转16进制数组
/// </summary>
/// <param name="hexString"></param>
/// <param name="separator"></param>
/// <returns></returns>
public static byte[] ToHexBytes(this string hexString, string separator = " ")
{
return hexString.Split(new string[] { separator }, StringSplitOptions.RemoveEmptyEntries).Select(s => Convert.ToByte(s, 16)).ToArray();
}
}
}

+ 0
- 141
src/JT809.Protocol/ProtocolPacket/Extensions/PackageExtensions.cs 查看文件

@@ -1,141 +0,0 @@
using JT809.Protocol.Configs;
using System.Collections.Generic;


namespace JT809.Protocol.ProtocolPacket.Extensions
{
/// <summary>
/// 包扩展方法
/// </summary>
public static class PackageExtensions
{
const ushort cnCRC_CCITT = 0x1021; //CRC校验多项式
static ulong[] CRC = new ulong[256]; //建立CRC16表
static PackageExtensions()
{
ushort i, j;
ushort nData;
ushort nAccum;
for (i = 0; i < 256; i++)
{
nData = (ushort)(i << 8);
nAccum = 0;
for (j = 0; j < 8; j++)
{
if (((nData ^ nAccum) & 0x8000) > 0)
nAccum = (ushort)((nAccum << 1) ^ cnCRC_CCITT);
else
nAccum <<= 1;
nData <<= 1;
}
CRC[i] = (ulong)nAccum;
}
}
internal static byte[] Escape(this Package packege, byte[] bytes)
{
List<byte> dataList = new List<byte>();
dataList.Add(bytes[0]);
for (int i = 1; i < bytes.Length - 1; i++)
{
var item = bytes[i];
switch (item)
{
case 0x5b:
dataList.Add(0x5a);
dataList.Add(0x01);
break;
case 0x5a:
dataList.Add(0x5a);
dataList.Add(0x02);
break;
case 0x5d:
dataList.Add(0x5e);
dataList.Add(0x01);
break;
case 0x5e:
dataList.Add(0x5e);
dataList.Add(0x02);
break;
default:
dataList.Add(item);
break;
}
}
dataList.Add(bytes[bytes.Length - 1]);
var tempBuffe = dataList.ToArray();
return tempBuffe;
}
internal static byte[] UnEscape(this Package packege, byte[] bytes)
{
List<byte> dataList = new List<byte>();
dataList.Add(bytes[0]);
for (int i = 1; i < bytes.Length - 1; i++)
{
byte first = bytes[i];
byte second = bytes[i + 1];
if (first == 0x5a && second == 0x01)
{
dataList.Add(0x5b);
i++;
}
else if (first == 0x5a && second == 0x02)
{
dataList.Add(0x5a);
i++;
}
else if (first == 0x5e && second == 0x01)
{
dataList.Add(0x5d);
i++;
}
else if (first == 0x5e && second == 0x02)
{
dataList.Add(0x5e);
i++;
}
else
{
dataList.Add(first);
}
}
dataList.Add(bytes[bytes.Length - 1]);
var tempBuffe = dataList.ToArray();
return tempBuffe;
}
/// <summary>
/// 从数据头到校验码前的 CRC 1 G-CCITT 的校验值,遵循人端排序方式的规定。
/// </summary>
/// <param name="packege"></param>
/// <param name="ucbuf"></param>
/// <param name="offset"></param>
/// <param name="iLen"></param>
/// <returns></returns>
internal static ushort CRC16_CCITT(this Package packege, byte[] ucbuf, int offset, int iLen)
{
ushort checkCode = 0xFFFF;
for (int j = offset; j < iLen; ++j)
{
checkCode = (ushort)((checkCode << 8) ^ (ushort)CRC[(checkCode >> 8) ^ ucbuf[j]]);
}
return checkCode;
}
internal static byte[] Encrypt(this Package packege, byte[] buffer, int size, JT809EncryptConfig Config)
{
if (0 == Config.Key)
{
Config.Key = 1;
}
uint mkey = Config.M1;
if (0 == mkey)
{
mkey = 1;
}
for (int idx = 0; idx < size; idx++)
{
Config.Key = Config.IA1 * (Config.Key % mkey) + Config.IC1;
buffer[idx] ^= (byte)((Config.Key >> 20) & 0xFF);
}
return buffer;
}
}
}

+ 0
- 101
src/JT809.Protocol/ProtocolPacket/Header.cs 查看文件

@@ -1,101 +0,0 @@
using JT809.Protocol.Configs;
using JT809.Protocol.Enums;
using System;
using System.IO;
namespace JT809.Protocol.ProtocolPacket
{
/// <summary>
/// Message Header 数据头
/// </summary>
public class Header: BufferedEntityBase
{
/// <summary>
/// 固定为22个字节长度
/// </summary>
public const int HeaderFixedByteLength = 22;
/// <summary>
/// 发送计数器
/// 占用四个字节,为发送信息的序列号,用于接收方检测是否有信息的丢失,上级平台和下级平台接自己发送数据包的个数计数,互不影响。
/// 程序开始运行时等于零,发送第一帧数据时开始计数,到最大数后自动归零
/// </summary>
public static uint CounterOnSendGenerater { get; private set; }
/// <summary>
/// 接收计数器
/// 占用四个字节,为发送信息的序列号,用于接收方检测是否有信息的丢失,上级平台和下级平台接自己发送数据包的个数计数,互不影响。
/// 程序开始运行时等于零,发送第一帧数据时开始计数,到最大数后自动归零
/// </summary>
public static uint CounterOnRecieveGenerater { get; private set; }
/// <summary>
/// 数据长度(包括头标识、数据头、数据体和尾标识)
/// </summary>
public uint Length { get; private set; }
/// <summary>
/// 报文序列号
/// </summary>
public uint SN { get; private set; }
/// <summary>
/// 业务数据类型
/// </summary>
public BusinessType BusinessID { get; private set; }
/// <summary>
/// 下级平台接入码,上级平台给下级平台分配唯一标识码。
/// </summary>
public uint SessionId { get; set; }
public JT809Version JT809Version { get; private set; }
public EncryptOpitions EncryptOpition { get; private set; }
/// <summary>
/// 数据加密的密匙,长度为 4 个字节。
/// </summary>
public uint EncryptKey { get; private set; } = 0X00;
public Header(byte[] buffer) : base(buffer) { CounterOnRecieveGenerater++; }
internal Header(uint length, uint number, BusinessType businessID, JT809Config jt809Config) : base(length, number, businessID, jt809Config)
{ CounterOnSendGenerater++; }
public Header(uint length, BusinessType businessID, JT809Config jt809Config) : this(length, CounterOnSendGenerater, businessID, jt809Config) { }
protected override void InitializeProperties(object[] properties, int startIndex)
{
Length = (uint)properties[0] + Package.NotDataLength;
SN = (uint)properties[1];
BusinessID = (BusinessType)properties[2];
JT809Config jt809Config=(JT809Config)properties[3];
SessionId = jt809Config.SessionId;
JT809Version = jt809Config.JT809Version;
EncryptOpition = jt809Config.JT809EncryptConfig==null? EncryptOpitions.None: EncryptOpitions.Common;
if(jt809Config.JT809EncryptConfig == null)
{
EncryptOpition = EncryptOpitions.None;
}
else
{
EncryptOpition = EncryptOpitions.Common;
EncryptKey = jt809Config.JT809EncryptConfig.Key;
}
}
protected override void OnInitializePropertiesFromReadBuffer(BinaryReader reader)
{
Length = reader.ReadUInt32Little();
SN = reader.ReadUInt32Little();
BusinessID = (BusinessType)reader.ReadUInt16Little();
SessionId = reader.ReadUInt32Little();
JT809Version = new JT809Version(reader.ReadByte(), reader.ReadByte(), reader.ReadByte());
EncryptOpition = (EncryptOpitions)reader.ReadByte();
EncryptKey = reader.ReadUInt32Little();
}
protected override void OnWriteToBuffer(BinaryWriter writer)
{
writer.WriteLittle(Length);
writer.WriteLittle(SN);
writer.WriteLittle((ushort)BusinessID);
writer.WriteLittle(SessionId);
writer.WriteLittle(JT809Version.Buffer);
writer.WriteLittle((byte)EncryptOpition);
writer.WriteLittle(EncryptKey);
}
}
}

+ 0
- 11
src/JT809.Protocol/ProtocolPacket/IBuffer.cs 查看文件

@@ -1,11 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace JT809.Protocol.ProtocolPacket
{
public interface IBuffer
{
byte[] Buffer { get; }
}
}

+ 0
- 11
src/JT809.Protocol/ProtocolPacket/IBuffered.cs 查看文件

@@ -1,11 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace JT809.Protocol.ProtocolPacket
{
public interface IBuffered
{
byte[] ToBuffer();
}
}

+ 0
- 46
src/JT809.Protocol/ProtocolPacket/JT809Version.cs 查看文件

@@ -1,46 +0,0 @@
namespace JT809.Protocol.ProtocolPacket
{
/// <summary>
/// 协议版本好标识,上下级平台之间采用的标准协议版编号;
/// 长度为 3 个字节来表示,
/// 0x01 0x02 0x0F 标识的版本号是 v1.2.15,以此类推。
/// </summary>
public class JT809Version
{
public byte[] Buffer { get; } = new byte[3];
private const int MajorIndex = 0;
private const int MinorIndex = 1;
private const int BuildIndex = 2;
public byte Major
{
get { return Buffer[MajorIndex]; }
private set { Buffer[MajorIndex] = value; }
}
public byte Minor
{
get { return Buffer[MinorIndex]; }
private set { Buffer[MinorIndex] = value; }
}
public byte Build
{
get { return Buffer[BuildIndex]; }
private set { Buffer[BuildIndex] = value; }
}
public JT809Version()
{
Major = 1;
Minor = 0;
Build = 0;
}
public JT809Version(byte major, byte minor, byte buid)
{
Major = major;
Minor = minor;
Build = buid;
}
public override string ToString()
{
return $"{Major}.{Minor}.{Build}";
}
}
}

+ 0
- 14
src/JT809.Protocol/ProtocolPacket/Message/MainLink/MainLink_Login.cs 查看文件

@@ -1,14 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace JT809.Protocol.ProtocolPacket.Message.MainLink
{
/// <summary>
/// 主链路登录请求消息
/// </summary>
public sealed class MainLink_Login: MessageBody
{

}
}

+ 0
- 15
src/JT809.Protocol/ProtocolPacket/MessageBody.cs 查看文件

@@ -1,15 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace JT809.Protocol.ProtocolPacket
{
/// <summary>
/// 抽象消息体
/// </summary>
public abstract class MessageBody: BufferedEntityBase
{
protected MessageBody(params object[] properties) : base(properties){}
protected MessageBody(byte[] buffer):base(buffer){}
}
}

+ 0
- 116
src/JT809.Protocol/ProtocolPacket/Package.cs 查看文件

@@ -1,116 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using JT809.Protocol.Configs;
using JT809.Protocol.Enums;
using JT809.Protocol.Exceptions;
using JT809.Protocol.ProtocolPacket.Extensions;
namespace JT809.Protocol.ProtocolPacket
{
/// <summary>
/// 数据包
/// </summary>
public class Package: BufferedEntityBase
{
public const int NotDataLength = 26;
public const int Crc16ByteLength = 2;
public const byte BeginFlag = 0X5B;
public const byte EndFlag = 0X5D;
public const int BeginFixedByteLength = 1;
public const int EndFixedByteLength = 1;
public JT809Config JT809Config;
public Header Header { get; private set; }
public MessageBody Body { get; private set; }
private ushort CRC16 { get; set; }
public Package(byte[] buffer) : base(buffer){}
public Package(Header header, MessageBody body, JT809Config jt809Config) : base(header, body)
{
JT809Config = jt809Config;
}
protected override void InitializeProperties(object[] properties, int startIndex)
{
Header = properties[0] as Header;
Body = properties[1] as MessageBody;
if (Header == null) throw new NullReferenceException($"{new StackFrame().GetMethod().Name }:Header can't be null.");
if (Body == null) throw new NullReferenceException($"{new StackFrame().GetMethod().Name }:Body can't be null.");
}
protected override void OnInitializePropertiesFromReadBuffer(BinaryReader reader)
{
var content00 = new byte[Buffer.Length- BeginFixedByteLength-EndFixedByteLength];
Array.Copy(Buffer, BeginFixedByteLength, content00, 0, Buffer.Length- BeginFixedByteLength-EndFixedByteLength);
var content01 = this.UnEscape(content00);
var crc16 = this.CRC16_CCITT(content01, 0, content01.Length - Crc16ByteLength);
CRC16 = BitConverter.ToUInt16(new[] { content01[content01.Length - 1], content01[content01.Length - 2] }, 0);
if (CRC16 != crc16) throw new JT809Exception(ErrorCode.CRC16CheckInvalid,$"{CRC16}-{crc16},{content01.ToHexString()}");
Header = new Header(content01);
var bodyBuffer00 = new byte[content01.Length - Header.HeaderFixedByteLength - Crc16ByteLength];
Array.Copy(content01, Header.HeaderFixedByteLength, bodyBuffer00, 0, bodyBuffer00.Length);
//Default
byte[] bodyBuffer01 = bodyBuffer00;
switch (Header.EncryptOpition)
{
case EncryptOpitions.None:
break;
case EncryptOpitions.Common:
bodyBuffer01 = this.Encrypt(bodyBuffer01, bodyBuffer01.Length, JT809Config.JT809EncryptConfig);
break;
}
if (Header.Length != (bodyBuffer01.Length + NotDataLength)) throw new JT809Exception(ErrorCode.HeaderLengthNotEqualBodyLength);
Body = GenerateBody(Header.BusinessID, bodyBuffer01);
}
protected override void OnWriteToBuffer(BinaryWriter writer)
{
writer.WriteLittle(BeginFlag);
//Dealling Code On Header
var headerBuffer00 = Header.Buffer;
//Dealling Code On Body
byte[] bodyBuffer00 = Body.Buffer;
switch (Header.EncryptOpition)
{
case EncryptOpitions.None:
bodyBuffer00 = Body.Buffer;
break;
case EncryptOpitions.Common:
bodyBuffer00 = this.Encrypt(Body.Buffer, Body.Buffer.Length, JT809Config.JT809EncryptConfig);
break;
}
//Content:Except BeginFlag & EndFlag
var content = new byte[headerBuffer00.Length + bodyBuffer00.Length + Crc16ByteLength];
Array.Copy(headerBuffer00, 0, content, 0, headerBuffer00.Length);
Array.Copy(bodyBuffer00, 0, content, headerBuffer00.Length, bodyBuffer00.Length);
//Dealling Code On CRC16
CRC16 = this.CRC16_CCITT(content, 0, content.Length - Crc16ByteLength);
var crc1600 = BitConverter.GetBytes(CRC16).Reverse().ToArray();
Array.Copy(crc1600, 0, content, headerBuffer00.Length + bodyBuffer00.Length, Crc16ByteLength);
//Last Content
var content00 = this.Escape(content);
//ToBuffer Core.
writer.WriteLittle(content00);
writer.WriteLittle(EndFlag);
}
public static Package GeneratePackage(BusinessType businessType, MessageBody messageBody, JT809Config jt809Config)
{
var header = new Header((uint)messageBody.Buffer.Length, businessType, jt809Config);
return new Package(header, messageBody, jt809Config);
}
public static MessageBody GenerateBody(BusinessType businessID, byte[] bodyBuffer)
{
return Activator.CreateInstance(typeof(object), bodyBuffer) as MessageBody;
}
}
}

Loading…
取消
儲存