diff --git a/README.md b/README.md
index 05bb4f0..b561727 100644
--- a/README.md
+++ b/README.md
@@ -23,15 +23,15 @@
### 数据头[JT808Header]
-| 消息ID | 消息体属性 | 终端手机号 | 消息流水号 | 消息总包数(依赖是否分包) | 包序号(依赖是否分包) |
-| :----: | :----------------------------: | :-------------: | :--------: |:---------: | :-------:|
-| MsgId | JT808HeaderMessageBodyProperty | TerminalPhoneNo | MsgNum |PackgeCount | PackageIndex |
+| 消息ID | 消息体属性 | 协议版本号(2019版本)|终端手机号 | 消息流水号 | 消息总包数(依赖是否分包) | 包序号(依赖是否分包) |
+| :----: | :----------------------------: | :-------------: |:-------------: | :--------: |:---------: | :-------:|
+| MsgId | JT808HeaderMessageBodyProperty | ProtocolVersion|TerminalPhoneNo | MsgNum |PackgeCount | PackageIndex |
#### 数据头-消息体属性[JT808HeaderMessageBodyProperty]
-| 是否分包 | 加密标识 | 消息体长度 |
-| :------: | :------: | :--------: |
-| IsPackge | Encrypt | DataLength |
+|版本标识(2019版本)| 是否分包 | 加密标识 | 消息体长度 |
+|:------:| :------: | :------: | :--------: |
+|VersionFlag| IsPackge | Encrypt | DataLength |
#### 消息体属性[JT808Bodies]
@@ -306,17 +306,17 @@ Platform=AnyCpu Server=False Toolchain=.NET Core 3.0
## JT808终端通讯协议消息对照表
-| 序号 | 消息ID | 完成情况 | 测试情况 | 消息体名称 |
-| :---: | :-----------: | :------: | :------: | :----------------------------: |
+| 序号 | 消息ID | 完成情况 | 测试情况 | 消息体名称 |2019版本|
+| :---: | :-----------: | :------: | :------: | :----------------------------: |:----------------------------:|
| 1 | 0x0001 | √ | √ | 终端通用应答 |
| 2 | 0x8001 | √ | √ | 平台通用应答 |
| 3 | 0x0002 | √ | √ | 终端心跳 |
| 4 | 0x8003 | √ | √ | 补传分包请求 |
-| 5 | 0x0100 | √ | √ | 终端注册 |
+| 5 | 0x0100 | √ | √ | 终端注册 |修改|
| 6 | 0x8100 | √ | √ | 终端注册应答 |
| 7 | 0x0003 | √ | √ | 终端注销 |
-| 8 | 0x0102 | √ | √ | 终端鉴权 |
-| 9 | 0x8103 | √ | √ | 设置终端参数 |
+| 8 | 0x0102 | √ | √ | 终端鉴权 |修改|
+| 9 | 0x8103 | √ | x | 设置终端参数 |修改且增加|
| 10 | 0x8104 | √ | √ | 查询终端参数 |
| 11 | 0x0104 | √ | √ | 查询终端参数应答 |
| 12 | 0x8105 | √ | √ | 终端控制 |
@@ -350,9 +350,9 @@ Platform=AnyCpu Server=False Toolchain=.NET Core 3.0
| 40 | 0x8605 | √ | √ | 删除多边形区域 |
| 41 | 0x8606 | √ | √ | 设置路线 |
| 42 | 0x8607 | √ | √ | 删除路线 |
-| 43 | 0x8700 | x | 下个版本 | 行驶记录仪数据采集命令 |
-| 44 | 0x0700 | x | 下个版本 | 行驶记录仪数据上传 |
-| 45 | 0x8701 | x | 下个版本 | 行驶记录仪参数下传命令 |
+| 43 | 0x8700 | x | 不开发 | 行驶记录仪数据采集命令 |
+| 44 | 0x0700 | x | 不开发 | 行驶记录仪数据上传 |
+| 45 | 0x8701 | x | 不开发 | 行驶记录仪参数下传命令 |
| 46 | 0x0701 | √ | √ | 电子运单上报 |
| 47 | 0x0702 | √ | √ | 驾驶员身份信息采集上报 |
| 48 | 0x8702 | √ | 消息体为空| 上报驾驶员身份信息请求 |
@@ -375,3 +375,6 @@ Platform=AnyCpu Server=False Toolchain=.NET Core 3.0
| 65 | 0x0A00 | √ | √ | 终端 RSA 公钥 |
| 66 | 0x8F00~0x8FFF | 保留 | 保留 | 平台下行消息保留 |
| 67 | 0x0F00~0x0FFF | 保留 | 保留 | 终端上行消息保留 |
+| 68 | 0x0004 | √ | √ | 查询服务器时间请求 |新增|
+| 69 | 0x8004 | √ | √ | 查询服务器时间应答 |新增|
+| 70 | 0x0005 | √ | √ | 终端补传分包请求 |新增|
diff --git a/doc/JTT.808-2019.PDF b/doc/JTT.808-2019.PDF
index dd195e2..7ea6824 100644
Binary files a/doc/JTT.808-2019.PDF and b/doc/JTT.808-2019.PDF differ
diff --git a/src/JT808.Protocol.Test/JT808.Protocol.Test.csproj b/src/JT808.Protocol.Test/JT808.Protocol.Test.csproj
index b4166dc..bd982a9 100644
--- a/src/JT808.Protocol.Test/JT808.Protocol.Test.csproj
+++ b/src/JT808.Protocol.Test/JT808.Protocol.Test.csproj
@@ -56,6 +56,8 @@
+
+
@@ -94,6 +96,10 @@
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/src/JT808.Protocol.Test/JT808HeaderMessageBodyPropertyTest.cs b/src/JT808.Protocol.Test/JT808HeaderMessageBodyPropertyTest.cs
index c84fae4..0f6b4f4 100644
--- a/src/JT808.Protocol.Test/JT808HeaderMessageBodyPropertyTest.cs
+++ b/src/JT808.Protocol.Test/JT808HeaderMessageBodyPropertyTest.cs
@@ -27,5 +27,49 @@ namespace JT808.Protocol.Test
Assert.True(jT808HeaderMessageBodyProperty.IsPackage);
Assert.Equal(JT808EncryptMethod.RSA, jT808HeaderMessageBodyProperty.Encrypt);
}
+
+ [Fact]
+ public void Test2019_1()
+ {
+ //01 1 001 0011111111
+ JT808HeaderMessageBodyProperty jT808HeaderMessageBodyProperty = new JT808HeaderMessageBodyProperty();
+ jT808HeaderMessageBodyProperty.DataLength = 255;
+ jT808HeaderMessageBodyProperty.IsPackage = true;
+ jT808HeaderMessageBodyProperty.Encrypt = JT808EncryptMethod.RSA;
+ jT808HeaderMessageBodyProperty.VersionFlag = true;
+ var result = jT808HeaderMessageBodyProperty.Wrap();
+ Assert.Equal(25855, result);
+ }
+
+ [Fact]
+ public void Test2019_2()
+ {
+ JT808HeaderMessageBodyProperty jT808HeaderMessageBodyProperty = new JT808HeaderMessageBodyProperty(25855);
+ Assert.Equal(255, jT808HeaderMessageBodyProperty.DataLength);
+ Assert.True(jT808HeaderMessageBodyProperty.IsPackage);
+ Assert.True(jT808HeaderMessageBodyProperty.VersionFlag);
+ Assert.Equal(JT808EncryptMethod.RSA, jT808HeaderMessageBodyProperty.Encrypt);
+ }
+
+ [Fact]
+ public void Test2019_3()
+ {
+ JT808HeaderMessageBodyProperty jT808HeaderMessageBodyProperty = new JT808HeaderMessageBodyProperty();
+ jT808HeaderMessageBodyProperty.DataLength = 255;
+ jT808HeaderMessageBodyProperty.IsPackage = false;
+ jT808HeaderMessageBodyProperty.Encrypt = JT808EncryptMethod.RSA;
+ jT808HeaderMessageBodyProperty.VersionFlag = true;
+ ushort result = jT808HeaderMessageBodyProperty.Wrap();
+ Assert.Equal(17663, result);
+ }
+ [Fact]
+ public void Test2019_4()
+ {
+ JT808HeaderMessageBodyProperty jT808HeaderMessageBodyProperty = new JT808HeaderMessageBodyProperty(17663);
+ Assert.Equal(255, jT808HeaderMessageBodyProperty.DataLength);
+ Assert.False(jT808HeaderMessageBodyProperty.IsPackage);
+ Assert.True(jT808HeaderMessageBodyProperty.VersionFlag);
+ Assert.Equal(JT808EncryptMethod.RSA, jT808HeaderMessageBodyProperty.Encrypt);
+ }
}
}
diff --git a/src/JT808.Protocol.Test/JT808HeaderTest.cs b/src/JT808.Protocol.Test/JT808HeaderTest.cs
index 97f11f1..7bc0cbe 100644
--- a/src/JT808.Protocol.Test/JT808HeaderTest.cs
+++ b/src/JT808.Protocol.Test/JT808HeaderTest.cs
@@ -8,6 +8,7 @@ namespace JT808.Protocol.Test
public class JT808HeaderTest
{
JT808Serializer JT808Serializer = new JT808Serializer();
+
[Fact]
public void Test3()
{
@@ -34,7 +35,7 @@ namespace JT808.Protocol.Test
jT808HeaderProperty.MsgId = JT808MsgId.终端鉴权.ToUInt16Value();
var hex = JT808Serializer.Serialize(jT808HeaderProperty).ToHexString();
- Assert.Equal("01 02 00 05 01 38 12 34 56 78 00 87".Replace(" ",""), hex);
+ Assert.Equal("01 02 00 05 01 38 12 34 56 78 00 87".Replace(" ", ""), hex);
}
[Fact]
@@ -75,5 +76,39 @@ namespace JT808.Protocol.Test
Assert.Equal(JT808MsgId.终端鉴权.ToValue(), jT808Header.MsgId);
Assert.Equal(5, jT808Header.MessageBodyProperty.DataLength);
}
+
+ [Fact]
+ public void JT808Header_2019Test1()
+ {
+ JT808Header jT808HeaderProperty = new JT808Header
+ {
+ TerminalPhoneNo = "13812345678"
+ };
+ JT808HeaderMessageBodyProperty jT808HeaderMessageBodyProperty = new JT808HeaderMessageBodyProperty();
+ jT808HeaderMessageBodyProperty.DataLength = 255;
+ jT808HeaderMessageBodyProperty.IsPackage = true;
+ jT808HeaderMessageBodyProperty.Encrypt = JT808EncryptMethod.RSA;
+ jT808HeaderMessageBodyProperty.VersionFlag = true;
+ jT808HeaderProperty.MessageBodyProperty = jT808HeaderMessageBodyProperty;
+ jT808HeaderProperty.MsgNum = 135;
+ jT808HeaderProperty.MsgId = JT808MsgId.终端鉴权.ToUInt16Value();
+ jT808HeaderProperty.ProtocolVersion = 2;
+ var hex = JT808Serializer.Serialize(jT808HeaderProperty).ToHexString();
+ Assert.Equal("010264FF0200000000013812345678008700000000", hex);
+ }
+
+ [Fact]
+ public void JT808Header_2019Test2()
+ {
+ byte[] headerBytes = "010264FF0200000000013812345678008700000000".ToHexBytes();
+ JT808Header jT808Header = JT808Serializer.Deserialize(headerBytes);
+ Assert.Equal(135, jT808Header.MsgNum);
+ Assert.Equal(2, jT808Header.ProtocolVersion);
+ Assert.Equal("13812345678", jT808Header.TerminalPhoneNo);
+ Assert.True(jT808Header.MessageBodyProperty.IsPackage);
+ Assert.True(jT808Header.MessageBodyProperty.VersionFlag);
+ Assert.Equal(JT808MsgId.终端鉴权.ToValue(), jT808Header.MsgId);
+ Assert.Equal(255, jT808Header.MessageBodyProperty.DataLength);
+ }
}
}
diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x0005Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x0005Test.cs
new file mode 100644
index 0000000..daa4ff1
--- /dev/null
+++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x0005Test.cs
@@ -0,0 +1,33 @@
+using System.Text;
+using Xunit;
+using JT808.Protocol.Extensions;
+using JT808.Protocol.MessageBody;
+
+namespace JT808.Protocol.Test.MessageBody
+{
+ public class JT808_0x0005Test
+ {
+ JT808Serializer JT808Serializer = new JT808Serializer();
+ [Fact]
+ public void Test1()
+ {
+ JT808_0x0005 jT808_0X8005 = new JT808_0x0005
+ {
+ OriginalMsgNum = 1234,
+ AgainPackageData = new byte[] { 0x01, 0x02, 0x02, 0x03 }
+ };
+ var hex = JT808Serializer.Serialize(jT808_0X8005).ToHexString();
+ Assert.Equal("04D20201020203", hex);
+ }
+
+ [Fact]
+ public void Test2()
+ {
+ var bytes = "04D20201020203".ToHexBytes();
+ JT808_0x0005 jT808_0X8005 = JT808Serializer.Deserialize(bytes);
+ Assert.Equal(1234, jT808_0X8005.OriginalMsgNum);
+ Assert.Equal(new byte[] { 0x01, 0x02, 0x02, 0x03 }, jT808_0X8005.AgainPackageData);
+ Assert.Equal(2, jT808_0X8005.AgainPackageCount);
+ }
+ }
+}
diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x0100Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x0100Test.cs
index 961e665..4f03465 100644
--- a/src/JT808.Protocol.Test/MessageBody/JT808_0x0100Test.cs
+++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x0100Test.cs
@@ -1,6 +1,7 @@
using Xunit;
using JT808.Protocol.MessageBody;
using JT808.Protocol.Extensions;
+using JT808.Protocol.Enums;
namespace JT808.Protocol.Test.MessageBody
{
@@ -52,5 +53,56 @@ namespace JT808.Protocol.Test.MessageBody
Assert.Equal("CHI1230", JT808Bodies.TerminalId);
Assert.Equal("smallchi123000000000", JT808Bodies.TerminalModel);
}
+
+ [Fact]
+ public void Test2019_1()
+ {
+ JT808Package jT808_0X0100 = new JT808Package
+ {
+ Header = new JT808Header
+ {
+ MsgId = Enums.JT808MsgId.终端注册.ToUInt16Value(),
+ MsgNum = 10,
+ TerminalPhoneNo = "123456789",
+ ProtocolVersion=1,
+ },
+ Bodies = new JT808_0x0100
+ {
+ AreaID = 40,
+ CityOrCountyId = 50,
+ MakerId = "1234",
+ PlateColor = 1,
+ PlateNo = "粤A12345",
+ TerminalId = "CHI123",
+ TerminalModel = "smallchi123"
+ }
+ };
+ JT808HeaderMessageBodyProperty jT808HeaderMessageBodyProperty = new JT808HeaderMessageBodyProperty(true);
+ jT808_0X0100.Header.MessageBodyProperty = jT808HeaderMessageBodyProperty;
+ var hex = JT808Serializer.Serialize(jT808_0X0100).ToHexString();
+ Assert.Equal("7E010040540100000000000123456789000A00280032303030303030303132333430303030303030303030303030303030303030736D616C6C63686931323330303030303030303030303030303030303030303030303043484931323301D4C1413132333435B27E", hex);
+ }
+
+ [Fact]
+ public void Test2019_2()
+ {
+ byte[] bytes = "7E010040540100000000000123456789000A00280032303030303030303132333430303030303030303030303030303030303030736D616C6C63686931323330303030303030303030303030303030303030303030303043484931323301D4C1413132333435B27E".ToHexBytes();
+ JT808Package jT808_0X0100 = JT808Serializer.Deserialize(bytes);
+ Assert.Equal(JT808MsgId.终端注册.ToUInt16Value(), jT808_0X0100.Header.MsgId);
+ Assert.Equal(1, jT808_0X0100.Header.ProtocolVersion);
+ Assert.Equal(JT808Version.JTT2019, jT808_0X0100.Version);
+ Assert.True(jT808_0X0100.Header.MessageBodyProperty.VersionFlag);
+ Assert.Equal(10, jT808_0X0100.Header.MsgNum);
+ Assert.Equal("123456789", jT808_0X0100.Header.TerminalPhoneNo);
+
+ JT808_0x0100 JT808Bodies = (JT808_0x0100)jT808_0X0100.Bodies;
+ Assert.Equal(40, JT808Bodies.AreaID);
+ Assert.Equal(50, JT808Bodies.CityOrCountyId);
+ Assert.Equal("1234".PadLeft(11,'0'), JT808Bodies.MakerId);
+ Assert.Equal(1, JT808Bodies.PlateColor);
+ Assert.Equal("粤A12345", JT808Bodies.PlateNo);
+ Assert.Equal("CHI123".PadLeft(30, '0'), JT808Bodies.TerminalId);
+ Assert.Equal("smallchi123".PadLeft(30, '0'), JT808Bodies.TerminalModel);
+ }
}
}
diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x0102Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x0102Test.cs
index 1b02e62..bbf625e 100644
--- a/src/JT808.Protocol.Test/MessageBody/JT808_0x0102Test.cs
+++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x0102Test.cs
@@ -1,6 +1,7 @@
using Xunit;
using JT808.Protocol.MessageBody;
using JT808.Protocol.Extensions;
+using JT808.Protocol.Enums;
namespace JT808.Protocol.Test.MessageBody
{
@@ -26,6 +27,30 @@ namespace JT808.Protocol.Test.MessageBody
Assert.Equal("45612", jT808LoginRequest.Code);
}
+ [Fact]
+ public void Test2019_1()
+ {
+ JT808_0x0102 jT808LoginRequestProperty = new JT808_0x0102
+ {
+ Code = "45612",
+ IMEI="1234567890abcde",
+ SoftwareVersion="v2.0.0"
+ };
+ string hex = JT808Serializer.Serialize(jT808LoginRequestProperty,JT808Version.JTT2019).ToHexString();
+ Assert.Equal("05343536313231323334353637383930616263646576322E302E303030303030303030303030303030", hex);
+ }
+
+ [Fact]
+ public void Test2019_2()
+ {
+ byte[] bodys = "05343536313231323334353637383930616263646576322E302E303030303030303030303030303030".ToHexBytes();
+ JT808_0x0102 jT808LoginRequest = JT808Serializer.Deserialize(bodys, JT808Version.JTT2019);
+ Assert.Equal("45612", jT808LoginRequest.Code);
+ Assert.Equal(5, jT808LoginRequest.CodeLength);
+ Assert.Equal("1234567890abcde", jT808LoginRequest.IMEI);
+ Assert.Equal("v2.0.0".PadRight(20,'0'), jT808LoginRequest.SoftwareVersion);
+ }
+
[Fact]
public void Test3()
{
diff --git a/src/JT808.Protocol.Test/MessageBody/JT808_0x8004Test.cs b/src/JT808.Protocol.Test/MessageBody/JT808_0x8004Test.cs
new file mode 100644
index 0000000..d244654
--- /dev/null
+++ b/src/JT808.Protocol.Test/MessageBody/JT808_0x8004Test.cs
@@ -0,0 +1,31 @@
+using System.Text;
+using Xunit;
+using JT808.Protocol.Extensions;
+using JT808.Protocol.MessageBody;
+using System;
+
+namespace JT808.Protocol.Test.MessageBody
+{
+ public class JT808_0x8004Test
+ {
+ JT808Serializer JT808Serializer = new JT808Serializer();
+ [Fact]
+ public void Test1()
+ {
+ JT808_0x8004 jT808_0X8004 = new JT808_0x8004
+ {
+ Time = DateTime.Parse("2019-11-26 15:58:50")
+ };
+ var hex = JT808Serializer.Serialize(jT808_0X8004).ToHexString();
+ Assert.Equal("191126155850", hex);
+ }
+
+ [Fact]
+ public void Test2()
+ {
+ var bytes = "191126155850".ToHexBytes();
+ JT808_0x8004 jT808_0X8004 = JT808Serializer.Deserialize(bytes);
+ Assert.Equal(DateTime.Parse("2019-11-26 15:58:50"), jT808_0X8004.Time);
+ }
+ }
+}
diff --git a/src/JT808.Protocol.Test/MessagePack/JT808MessagePackReaderTest.cs b/src/JT808.Protocol.Test/MessagePack/JT808MessagePackReaderTest.cs
index 8a745cd..be981c4 100644
--- a/src/JT808.Protocol.Test/MessagePack/JT808MessagePackReaderTest.cs
+++ b/src/JT808.Protocol.Test/MessagePack/JT808MessagePackReaderTest.cs
@@ -8,6 +8,7 @@ using System.Buffers;
using JT808.Protocol.Formatters;
using JT808.Protocol.Interfaces;
using JT808.Protocol.Internal;
+using JT808.Protocol.Enums;
namespace JT808.Protocol.Test.MessagePack
{
@@ -228,5 +229,15 @@ namespace JT808.Protocol.Test.MessagePack
}
}
}
+
+ [Fact]
+ public void VersionTest1()
+ {
+ byte[] array = new byte[4096];
+ var reader = new JT808MessagePackReader(array);
+ Assert.Equal(JT808Version.JTT2013, reader.Version);
+ reader.Version = JT808Version.JTT2019;
+ Assert.Equal(JT808Version.JTT2019, reader.Version);
+ }
}
}
diff --git a/src/JT808.Protocol.Test/MessagePack/JT808MessagePackWriterTest.cs b/src/JT808.Protocol.Test/MessagePack/JT808MessagePackWriterTest.cs
index bd65a07..b7722e5 100644
--- a/src/JT808.Protocol.Test/MessagePack/JT808MessagePackWriterTest.cs
+++ b/src/JT808.Protocol.Test/MessagePack/JT808MessagePackWriterTest.cs
@@ -5,6 +5,7 @@ using System.Collections.Generic;
using System.Text;
using Xunit;
using System.Buffers;
+using JT808.Protocol.Enums;
namespace JT808.Protocol.Test.MessagePack
{
@@ -457,5 +458,15 @@ namespace JT808.Protocol.Test.MessagePack
var realBytes = msgpackWriter.FlushAndGetRealArray().ToHexString();
Assert.Equal("7E 01 7E 00 7D 01 23 45 67 89 00 00 00 00 00 7E 7E 01 7D 02 00 7D 01 01 23 45 67 89 00 00 00 00 00 7E".Replace(" ", ""), realBytes);
}
+
+ [Fact]
+ public void VersionTest1()
+ {
+ byte[] array = new byte[4096];
+ var msgpackWriter = new JT808MessagePackWriter(array);
+ Assert.Equal(JT808Version.JTT2013, msgpackWriter.Version);
+ msgpackWriter.Version = JT808Version.JTT2019;
+ Assert.Equal(JT808Version.JTT2019, msgpackWriter.Version);
+ }
}
}
diff --git a/src/JT808.Protocol/Attributes/JT808FormatterAttribute.cs b/src/JT808.Protocol/Attributes/JT808FormatterAttribute.cs
deleted file mode 100644
index 18cf8cc..0000000
--- a/src/JT808.Protocol/Attributes/JT808FormatterAttribute.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace JT808.Protocol.Attributes
-{
- [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, AllowMultiple = false, Inherited = true)]
- public sealed class JT808FormatterAttribute : Attribute
- {
- public Type FormatterType { get; private set; }
-
- public JT808FormatterAttribute(Type formatterType)
- {
- this.FormatterType = formatterType;
- }
- }
-}
diff --git a/src/JT808.Protocol/Enums/JT808ErrorCode.cs b/src/JT808.Protocol/Enums/JT808ErrorCode.cs
index 92e9837..ca0916d 100644
--- a/src/JT808.Protocol/Enums/JT808ErrorCode.cs
+++ b/src/JT808.Protocol/Enums/JT808ErrorCode.cs
@@ -7,11 +7,6 @@
///
CheckCodeNotEqual = 1001,
///
- /// 没有标记
- ///
- ///
- GetFormatterAttributeError = 1002,
- ///
/// 消息头解析错误
///
HeaderParseError = 1003,
diff --git a/src/JT808.Protocol/Interfaces/IJT808Config.cs b/src/JT808.Protocol/Interfaces/IJT808Config.cs
index f27ad7c..e80d3a4 100644
--- a/src/JT808.Protocol/Interfaces/IJT808Config.cs
+++ b/src/JT808.Protocol/Interfaces/IJT808Config.cs
@@ -10,6 +10,7 @@ namespace JT808.Protocol
{
public interface IJT808Config
{
+ [Obsolete("目前没用")]
JT808Version Version { get;}
string ConfigId { get; }
///
diff --git a/src/JT808.Protocol/JT808.Protocol.csproj b/src/JT808.Protocol/JT808.Protocol.csproj
index 6d7b056..983c0a7 100644
--- a/src/JT808.Protocol/JT808.Protocol.csproj
+++ b/src/JT808.Protocol/JT808.Protocol.csproj
@@ -14,7 +14,7 @@
https://github.com/SmallChi/JT808/blob/master/LICENSE
https://github.com/SmallChi/JT808/blob/master/LICENSE
false
- 2.2.0-preview1
+ 2.2.0-preview3
LICENSE
@@ -65,6 +65,10 @@
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/src/JT808.Protocol/JT808.Protocol.xml b/src/JT808.Protocol/JT808.Protocol.xml
index 00528c6..5ec4efd 100644
--- a/src/JT808.Protocol/JT808.Protocol.xml
+++ b/src/JT808.Protocol/JT808.Protocol.xml
@@ -213,12 +213,6 @@
校验和不相等
-
-
- 没有标记
-
-
-
消息头解析错误
@@ -2197,10 +2191,21 @@
+
+
+ 消息体属性
+
+
+
+
+ 协议版本号(2019版本)
+
+
终端手机号
根据安装后终端自身的手机号转换。手机号不足 12 位,则在前补充数字,大陆手机号补充数字 0,港澳台则根据其区号进行位数补充
+ (2019版本)手机号不足 20 位,则在前补充数字 0
@@ -2221,6 +2226,11 @@
报序号 从1开始
+
+
+ 版本标识(默认为1=true)
+
+
是否分包
@@ -2292,9 +2302,14 @@
起始符
-
+
- 终止符
+ 头数据
+
+
+
+
+ 数据体
@@ -2303,17 +2318,17 @@
从消息头开始,同后一字节异或,直到校验码前一个字节,占用一个字节。
-
+
- 头数据
+ 终止符
-
+
- 数据体
+ 808版本号
-
+
用于负载或者分布式的时候,在网关只需要解到头部。
根据头部的消息Id进行分发处理,可以防止小部分性能损耗。
@@ -2365,6 +2380,42 @@
跳过数据体序列化
+
+
+ 查询服务器时间请求
+ 2019版本
+
+
+
+
+ 跳过数据体序列化
+
+
+
+
+ 终端补传分包请求
+ 2019版本
+
+
+
+
+ 原始消息流水号
+ 对应要求补传的原始消息第一包的消息流水号
+
+
+
+
+ 重传包总数
+ n
+
+
+
+
+ 重传包 ID 列表
+ BYTE[2*n]
+ 重传包序号顺序排列,如“包 ID1 包 ID2......包 IDn”。
+
+
终端注册
@@ -2389,21 +2440,22 @@
制造商 ID
- 5 个字节,终端制造商编码
+ 2013版本 5 个字节,终端制造商编码
+ 2019版本 11 个字节,终端制造商编码
终端型号
- 20 个字节,此终端型号由制造商自行定义,位数不
- 足时,后补“0X00”。
+ 2013版本 20 个字节,此终端型号由制造商自行定义,位数不足时,后补“0X00”。
+ 2019版本 30 个字节,此终端型号由制造商自行定义,位数不足时,后补“0X00”。
终端 ID
- 7 个字节,由大写字母和数字组成,此终端 ID 由制
- 造商自行定义,位数不足时,后补“0X00”。
+ 2013版本 7个字节,由大写字母和数字组成,此终端 ID 由制造商自行定义,位数不足时,后补“0X00”。
+ 2019版本 30个字节,由大写字母和数字组成,此终端 ID 由制造商自行定义,位数不足时,后补“0X00”。
@@ -2428,6 +2480,22 @@
鉴权码
+ 鉴权码内容 2019版本
+
+
+
+
+ 鉴权码长度 2019版本
+
+
+
+
+ 终端IMEI 长度15 2019版本
+
+
+
+
+ 软件版本号 长度20 后补 "0x00" 2019版本
@@ -3216,6 +3284,12 @@
重传包序号顺序排列,如“包 ID1 包 ID2......包 IDn”。
+
+
+ 查询服务器时间应答
+ 2019版本
+
+
终端注册应答
@@ -5420,7 +5494,7 @@
主要用来一次性读取所有数据体内容操作
-
+
解码(转义还原),计算校验和
diff --git a/src/JT808.Protocol/JT808Header.cs b/src/JT808.Protocol/JT808Header.cs
index b560c00..c5eb137 100644
--- a/src/JT808.Protocol/JT808Header.cs
+++ b/src/JT808.Protocol/JT808Header.cs
@@ -13,10 +13,18 @@ namespace JT808.Protocol
///
///
public ushort MsgId { get; set; }
+ ///
+ /// 消息体属性
+ ///
public JT808HeaderMessageBodyProperty MessageBodyProperty { get; set; }
///
+ /// 协议版本号(2019版本)
+ ///
+ public byte ProtocolVersion { get; set; } = 1;
+ ///
/// 终端手机号
/// 根据安装后终端自身的手机号转换。手机号不足 12 位,则在前补充数字,大陆手机号补充数字 0,港澳台则根据其区号进行位数补充
+ /// (2019版本)手机号不足 20 位,则在前补充数字 0
///
public string TerminalPhoneNo { get; set; }
///
@@ -42,8 +50,20 @@ namespace JT808.Protocol
jT808Header.MsgId = reader.ReadUInt16();
// 2.消息体属性
jT808Header.MessageBodyProperty = new JT808HeaderMessageBodyProperty(reader.ReadUInt16());
- // 3.终端手机号
- jT808Header.TerminalPhoneNo = reader.ReadBCD(config.TerminalPhoneNoLength, config.Trim);
+ if (jT808Header.MessageBodyProperty.VersionFlag)
+ {
+ // 2019 版本
+ // 3.协议版本号
+ jT808Header.ProtocolVersion = reader.ReadByte();
+ // 4.终端手机号
+ jT808Header.TerminalPhoneNo = reader.ReadBCD(20, config.Trim);
+ }
+ else
+ {
+ // 2013 版本
+ // 3.终端手机号
+ jT808Header.TerminalPhoneNo = reader.ReadBCD(config.TerminalPhoneNoLength, config.Trim);
+ }
jT808Header.MsgNum = reader.ReadUInt16();
// 4.判断有无分包
if (jT808Header.MessageBodyProperty.IsPackage)
@@ -62,8 +82,20 @@ namespace JT808.Protocol
writer.WriteUInt16(value.MsgId);
// 2.消息体属性
writer.WriteUInt16(value.MessageBodyProperty.Wrap());
- // 3.终端手机号
- writer.WriteBCD(value.TerminalPhoneNo, config.TerminalPhoneNoLength);
+ if (value.MessageBodyProperty.VersionFlag)
+ {
+ // 2019 版本
+ // 3.协议版本号
+ writer.WriteByte(value.ProtocolVersion);
+ // 4.终端手机号
+ writer.WriteBCD(value.TerminalPhoneNo, 20);
+ }
+ else
+ {
+ // 2013 版本
+ // 3.终端手机号
+ writer.WriteBCD(value.TerminalPhoneNo, config.TerminalPhoneNoLength);
+ }
// 4.消息流水号
writer.WriteUInt16(value.MsgNum);
// 5.判断是否分包
diff --git a/src/JT808.Protocol/JT808HeaderMessageBodyProperty.cs b/src/JT808.Protocol/JT808HeaderMessageBodyProperty.cs
index e093529..c90dd55 100644
--- a/src/JT808.Protocol/JT808HeaderMessageBodyProperty.cs
+++ b/src/JT808.Protocol/JT808HeaderMessageBodyProperty.cs
@@ -7,15 +7,34 @@ namespace JT808.Protocol
{
public struct JT808HeaderMessageBodyProperty
{
- public JT808HeaderMessageBodyProperty(int dataLength,bool isPackage, JT808EncryptMethod jT808EncryptMethod= JT808EncryptMethod.None)
+ public JT808HeaderMessageBodyProperty(int dataLength,bool isPackage, bool versionFlag= false, JT808EncryptMethod jT808EncryptMethod= JT808EncryptMethod.None)
{
IsPackage = isPackage;
Encrypt = jT808EncryptMethod;
DataLength = dataLength;
+ VersionFlag = versionFlag;
}
+
+ public JT808HeaderMessageBodyProperty(bool isPackage, bool versionFlag, JT808EncryptMethod jT808EncryptMethod = JT808EncryptMethod.None)
+ {
+ IsPackage = isPackage;
+ Encrypt = jT808EncryptMethod;
+ DataLength = 0;
+ VersionFlag = versionFlag;
+ }
+
+ public JT808HeaderMessageBodyProperty(bool versionFlag, JT808EncryptMethod jT808EncryptMethod = JT808EncryptMethod.None)
+ {
+ IsPackage = false;
+ Encrypt = jT808EncryptMethod;
+ DataLength = 0;
+ VersionFlag = versionFlag;
+ }
+
public JT808HeaderMessageBodyProperty(ushort value)
{
- IsPackage = (value >> 13) == 1;
+ VersionFlag = (value >> 14 & 0x01) == 1;
+ IsPackage = ((value >> 13) & 0x001) == 1;
switch ((value & 0x400) >> 10)
{
case 0:
@@ -31,6 +50,10 @@ namespace JT808.Protocol
DataLength = value & 0x3FF;
}
///
+ /// 版本标识(默认为1=true)
+ ///
+ public bool VersionFlag { get; set; }
+ ///
/// 是否分包
/// true-1 表示消息体为长消息,进行分包发送处理
/// false-0 消息头中无消息包封装项字段。
@@ -49,6 +72,7 @@ namespace JT808.Protocol
public int DataLength { get; set; }
public ushort Wrap()
{
+
// 1.是否分包
int tmpIsPacke = 0;
if (IsPackage)
@@ -75,8 +99,53 @@ namespace JT808.Protocol
{
// 判断有无数据体长度
DataLength = 0;
- }
- return (ushort)(tmpIsPacke | tmpEncrypt | DataLength);
+ }
+ // 3.是否分包
+ int versionFlag = 0;
+ if (VersionFlag)
+ {
+ versionFlag = 1 << 14;
+ }
+ return (ushort)(versionFlag|tmpIsPacke | tmpEncrypt | DataLength);
+ }
+
+ public ushort Wrap(int dataLength)
+ {
+ // 1.是否分包
+ int tmpIsPacke = 0;
+ if (IsPackage)
+ {
+ tmpIsPacke = 1 << 13;
+ }
+ // 2.是否加密
+ int tmpEncrypt;
+ // 2.3.数据加密方式
+ switch (Encrypt)
+ {
+ case JT808EncryptMethod.None:
+ tmpEncrypt = 0;
+ break;
+ case JT808EncryptMethod.RSA:
+ tmpEncrypt = 1 << 10;
+ break;
+ default:
+ tmpEncrypt = 0;
+ break;
+ }
+ // 2.4.数据长度
+ DataLength = dataLength;
+ if (dataLength <= 0)
+ {
+ // 判断有无数据体长度
+ dataLength = 0;
+ }
+ // 3.是否分包
+ int versionFlag = 0;
+ if (VersionFlag)
+ {
+ versionFlag = 1 << 14;
+ }
+ return (ushort)(versionFlag | tmpIsPacke | tmpEncrypt | dataLength);
}
}
}
diff --git a/src/JT808.Protocol/JT808HeaderPackage.cs b/src/JT808.Protocol/JT808HeaderPackage.cs
index ec47319..f644e97 100644
--- a/src/JT808.Protocol/JT808HeaderPackage.cs
+++ b/src/JT808.Protocol/JT808HeaderPackage.cs
@@ -34,6 +34,34 @@ namespace JT808.Protocol
///
public byte End { get; set; }
+ public JT808Version Version
+ {
+ get {
+ if (Header != null)
+ {
+ try
+ {
+ if (Header.MessageBodyProperty.VersionFlag)
+ {
+ return JT808Version.JTT2019;
+ }
+ else
+ {
+ return JT808Version.JTT2013;
+ }
+ }
+ catch
+ {
+ return JT808Version.JTT2013;
+ }
+ }
+ else
+ {
+ return JT808Version.JTT2013;
+ }
+ }
+ }
+
public JT808HeaderPackage Deserialize(ref JT808MessagePackReader reader, IJT808Config config)
{
// 1. 验证校验和
@@ -56,8 +84,21 @@ namespace JT808.Protocol
ushort messageBodyPropertyValue = reader.ReadUInt16();
// 3.2.1.解包消息体属性
jT808Package.Header.MessageBodyProperty = new JT808HeaderMessageBodyProperty(messageBodyPropertyValue);
- // 3.3.读取终端手机号
- jT808Package.Header.TerminalPhoneNo = reader.ReadBCD(config.TerminalPhoneNoLength, config.Trim);
+ if (jT808Package.Header.MessageBodyProperty.VersionFlag)
+ {
+ //2019版本
+ // 3.3.读取协议版本号
+ jT808Package.Header.ProtocolVersion = reader.ReadByte();
+ // 3.4.读取终端手机号
+ jT808Package.Header.TerminalPhoneNo = reader.ReadBCD(20, config.Trim);
+ reader.Version = JT808Version.JTT2019;
+ }
+ else
+ {
+ //2013版本
+ // 3.3.读取终端手机号
+ jT808Package.Header.TerminalPhoneNo = reader.ReadBCD(config.TerminalPhoneNoLength, config.Trim);
+ }
// 3.4.读取消息流水号
jT808Package.Header.MsgNum = reader.ReadUInt16();
// 3.5.判断有无分包
diff --git a/src/JT808.Protocol/JT808Package.cs b/src/JT808.Protocol/JT808Package.cs
index d109a83..7c7485a 100644
--- a/src/JT808.Protocol/JT808Package.cs
+++ b/src/JT808.Protocol/JT808Package.cs
@@ -25,27 +25,54 @@ namespace JT808.Protocol
/// 起始符
///
public byte Begin { get; set; } = BeginFlag;
-
///
- /// 终止符
+ /// 头数据
///
- public byte End { get; set; } = EndFlag;
-
+ public JT808Header Header { get; set; }
+ ///
+ /// 数据体
+ ///
+ public JT808Bodies Bodies { get; set; }
///
/// 校验码
/// 从消息头开始,同后一字节异或,直到校验码前一个字节,占用一个字节。
///
public byte CheckCode { get; set; }
-
///
- /// 头数据
+ /// 终止符
///
- public JT808Header Header { get; set; }
-
+ public byte End { get; set; } = EndFlag;
///
- /// 数据体
+ /// 808版本号
///
- public JT808Bodies Bodies { get; set; }
+ public JT808Version Version
+ {
+ get
+ {
+ if (Header != null)
+ {
+ try
+ {
+ if (Header.MessageBodyProperty.VersionFlag)
+ {
+ return JT808Version.JTT2019;
+ }
+ else
+ {
+ return JT808Version.JTT2013;
+ }
+ }
+ catch
+ {
+ return JT808Version.JTT2013;
+ }
+ }
+ else
+ {
+ return JT808Version.JTT2013;
+ }
+ }
+ }
public JT808Package Deserialize(ref JT808MessagePackReader reader, IJT808Config config)
{
@@ -67,11 +94,23 @@ namespace JT808.Protocol
jT808Package.Header.MsgId = reader.ReadUInt16();
// 3.2.读取消息体属性
jT808Package.Header.MessageBodyProperty = new JT808HeaderMessageBodyProperty(reader.ReadUInt16());
- // 3.3.读取终端手机号
- jT808Package.Header.TerminalPhoneNo = reader.ReadBCD(config.TerminalPhoneNoLength, config.Trim);
- // 3.4.读取消息流水号
+ if (jT808Package.Header.MessageBodyProperty.VersionFlag)
+ {
+ //2019版本
+ jT808Package.Header.ProtocolVersion = reader.ReadByte();
+ // 3.4.读取终端手机号
+ jT808Package.Header.TerminalPhoneNo = reader.ReadBCD(20, config.Trim);
+ reader.Version = JT808Version.JTT2019;
+ }
+ else
+ {
+ //2013版本
+ // 3.3.读取终端手机号
+ jT808Package.Header.TerminalPhoneNo = reader.ReadBCD(config.TerminalPhoneNoLength, config.Trim);
+ }
+ // 3.4.读取消息流水号
jT808Package.Header.MsgNum = reader.ReadUInt16();
- // 3.5.判断有无分包
+ // 3.5.判断有无分包
if (jT808Package.Header.MessageBodyProperty.IsPackage)
{
//3.5.1.读取消息包总数
@@ -131,9 +170,7 @@ namespace JT808.Protocol
}
}
}
-
-
-
+
// 5.读取校验码
jT808Package.CheckCode = reader.ReadByte();
// 6.读取终止位置
@@ -152,8 +189,21 @@ namespace JT808.Protocol
writer.WriteUInt16(value.Header.MsgId);
// 2.2.消息体属性(包含消息体长度所以先跳过)
writer.Skip(2, out int msgBodiesPropertyPosition);
- // 2.3.终端手机号 (写死大陆手机号码)
- writer.WriteBCD(value.Header.TerminalPhoneNo, config.TerminalPhoneNoLength);
+ if (value.Header.MessageBodyProperty.VersionFlag)
+ {
+ //2019版本
+ // 2.3.协议版本号
+ writer.WriteByte(value.Header.ProtocolVersion);
+ // 2.4.终端手机号
+ writer.WriteBCD(value.Header.TerminalPhoneNo, 20);
+ writer.Version = JT808Version.JTT2019;
+ }
+ else
+ {
+ //2013版本
+ // 2.3.终端手机号 (写死大陆手机号码)
+ writer.WriteBCD(value.Header.TerminalPhoneNo, config.TerminalPhoneNoLength);
+ }
value.Header.MsgNum = value.Header.MsgNum > 0 ? value.Header.MsgNum : config.MsgSNDistributed.Increment();
// 2.4.消息流水号
writer.WriteUInt16(value.Header.MsgNum);
@@ -177,9 +227,8 @@ namespace JT808.Protocol
}
}
// 3.1.处理数据体长度
- value.Header.MessageBodyProperty = new JT808HeaderMessageBodyProperty((ushort)(writer.GetCurrentPosition() - headerLength));
// 2.2.回写消息体属性
- writer.WriteUInt16Return(value.Header.MessageBodyProperty.Wrap(), msgBodiesPropertyPosition);
+ writer.WriteUInt16Return(value.Header.MessageBodyProperty.Wrap((writer.GetCurrentPosition() - headerLength)), msgBodiesPropertyPosition);
// 4.校验码
writer.WriteXor();
// 5.终止符
diff --git a/src/JT808.Protocol/JT808Serializer.cs b/src/JT808.Protocol/JT808Serializer.cs
index 8a69c2b..8f606be 100644
--- a/src/JT808.Protocol/JT808Serializer.cs
+++ b/src/JT808.Protocol/JT808Serializer.cs
@@ -1,4 +1,5 @@
-using JT808.Protocol.Extensions;
+using JT808.Protocol.Enums;
+using JT808.Protocol.Extensions;
using JT808.Protocol.Formatters;
using JT808.Protocol.Interfaces;
using JT808.Protocol.Internal;
@@ -27,13 +28,13 @@ namespace JT808.Protocol
private readonly IJT808Config jT808Config;
- public byte[] Serialize(JT808Package jT808Package, int minBufferSize = 4096)
+ public byte[] Serialize(JT808Package package, JT808Version version = JT808Version.JTT2013, int minBufferSize = 4096)
{
byte[] buffer = JT808ArrayPool.Rent(minBufferSize);
try
{
- JT808MessagePackWriter jT808MessagePackWriter = new JT808MessagePackWriter(buffer);
- jT808Package.Serialize(ref jT808MessagePackWriter, jT808Package, jT808Config);
+ JT808MessagePackWriter jT808MessagePackWriter = new JT808MessagePackWriter(buffer, version);
+ jT808Package.Serialize(ref jT808MessagePackWriter, package, jT808Config);
return jT808MessagePackWriter.FlushAndGetEncodingArray();
}
finally
@@ -42,13 +43,13 @@ namespace JT808.Protocol
}
}
- public ReadOnlySpan SerializeReadOnlySpan(JT808Package jT808Package, int minBufferSize = 4096)
+ public ReadOnlySpan SerializeReadOnlySpan(JT808Package package, JT808Version version = JT808Version.JTT2013, int minBufferSize = 4096)
{
byte[] buffer = JT808ArrayPool.Rent(minBufferSize);
try
{
- JT808MessagePackWriter jT808MessagePackWriter = new JT808MessagePackWriter(buffer);
- jT808Package.Serialize(ref jT808MessagePackWriter, jT808Package, jT808Config);
+ JT808MessagePackWriter jT808MessagePackWriter = new JT808MessagePackWriter(buffer, version);
+ jT808Package.Serialize(ref jT808MessagePackWriter, package, jT808Config);
return jT808MessagePackWriter.FlushAndGetEncodingReadOnlySpan();
}
finally
@@ -57,12 +58,12 @@ namespace JT808.Protocol
}
}
- public JT808Package Deserialize(ReadOnlySpan bytes, int minBufferSize = 4096)
+ public JT808Package Deserialize(ReadOnlySpan bytes, JT808Version version = JT808Version.JTT2013, int minBufferSize = 4096)
{
byte[] buffer = JT808ArrayPool.Rent(minBufferSize);
try
{
- JT808MessagePackReader jT808MessagePackReader = new JT808MessagePackReader(bytes);
+ JT808MessagePackReader jT808MessagePackReader = new JT808MessagePackReader(bytes, version);
jT808MessagePackReader.Decode(buffer);
return jT808Package.Deserialize(ref jT808MessagePackReader, jT808Config);
}
@@ -72,13 +73,13 @@ namespace JT808.Protocol
}
}
- public byte [] Serialize(T obj, int minBufferSize = 4096)
+ public byte [] Serialize(T obj, JT808Version version = JT808Version.JTT2013, int minBufferSize = 4096)
{
byte[] buffer = JT808ArrayPool.Rent(minBufferSize);
try
{
var formatter = jT808Config.GetMessagePackFormatter();
- JT808MessagePackWriter jT808MessagePackWriter = new JT808MessagePackWriter(buffer);
+ JT808MessagePackWriter jT808MessagePackWriter = new JT808MessagePackWriter(buffer, version);
formatter.Serialize(ref jT808MessagePackWriter, obj, jT808Config);
return jT808MessagePackWriter.FlushAndGetEncodingArray();
}
@@ -88,13 +89,13 @@ namespace JT808.Protocol
}
}
- public ReadOnlySpan SerializeReadOnlySpan(T obj, int minBufferSize = 4096)
+ public ReadOnlySpan SerializeReadOnlySpan(T obj, JT808Version version = JT808Version.JTT2013, int minBufferSize = 4096)
{
byte[] buffer = JT808ArrayPool.Rent(minBufferSize);
try
{
var formatter = jT808Config.GetMessagePackFormatter();
- JT808MessagePackWriter jT808MessagePackWriter = new JT808MessagePackWriter(buffer);
+ JT808MessagePackWriter jT808MessagePackWriter = new JT808MessagePackWriter(buffer, version);
formatter.Serialize(ref jT808MessagePackWriter, obj, jT808Config);
return jT808MessagePackWriter.FlushAndGetEncodingReadOnlySpan();
}
@@ -104,12 +105,12 @@ namespace JT808.Protocol
}
}
- public T Deserialize(ReadOnlySpan bytes, int minBufferSize = 4096)
+ public T Deserialize(ReadOnlySpan bytes, JT808Version version = JT808Version.JTT2013, int minBufferSize = 4096)
{
byte[] buffer = JT808ArrayPool.Rent(minBufferSize);
try
{
- JT808MessagePackReader jT808MessagePackReader = new JT808MessagePackReader(bytes);
+ JT808MessagePackReader jT808MessagePackReader = new JT808MessagePackReader(bytes, version);
if(CheckPackageType(typeof(T)))
jT808MessagePackReader.Decode(buffer);
var formatter = jT808Config.GetMessagePackFormatter();
@@ -132,12 +133,12 @@ namespace JT808.Protocol
///
///
///
- public JT808HeaderPackage HeaderDeserialize(ReadOnlySpan bytes, int minBufferSize = 4096)
+ public JT808HeaderPackage HeaderDeserialize(ReadOnlySpan bytes, JT808Version version = JT808Version.JTT2013, int minBufferSize = 4096)
{
byte[] buffer = JT808ArrayPool.Rent(minBufferSize);
try
{
- JT808MessagePackReader jT808MessagePackReader = new JT808MessagePackReader(bytes);
+ JT808MessagePackReader jT808MessagePackReader = new JT808MessagePackReader(bytes, version);
jT808MessagePackReader.Decode(buffer);
return jT808HeaderPackage.Deserialize(ref jT808MessagePackReader,jT808Config);
}
@@ -146,13 +147,13 @@ namespace JT808.Protocol
JT808ArrayPool.Return(buffer);
}
}
- public dynamic Deserialize(ReadOnlySpan bytes, Type type, int minBufferSize = 4096)
+ public dynamic Deserialize(ReadOnlySpan bytes, Type type, JT808Version version = JT808Version.JTT2013, int minBufferSize = 4096)
{
byte[] buffer = JT808ArrayPool.Rent(minBufferSize);
try
{
var formatter = jT808Config.GetMessagePackFormatterByType(type);
- JT808MessagePackReader jT808MessagePackReader = new JT808MessagePackReader(bytes);
+ JT808MessagePackReader jT808MessagePackReader = new JT808MessagePackReader(bytes, version);
if (CheckPackageType(type))
jT808MessagePackReader.Decode(buffer);
return JT808MessagePackFormatterResolverExtensions.JT808DynamicDeserialize(formatter,ref jT808MessagePackReader, jT808Config);
diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0004.cs b/src/JT808.Protocol/MessageBody/JT808_0x0004.cs
new file mode 100644
index 0000000..2bd9e48
--- /dev/null
+++ b/src/JT808.Protocol/MessageBody/JT808_0x0004.cs
@@ -0,0 +1,16 @@
+namespace JT808.Protocol.MessageBody
+{
+ ///
+ /// 查询服务器时间请求
+ /// 2019版本
+ ///
+ public class JT808_0x0004 : JT808Bodies
+ {
+ ///
+ /// 跳过数据体序列化
+ ///
+ public override bool SkipSerialization { get; set; } = true;
+
+ public override ushort MsgId { get; } = 0x0004;
+ }
+}
diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0005.cs b/src/JT808.Protocol/MessageBody/JT808_0x0005.cs
new file mode 100644
index 0000000..c5a9867
--- /dev/null
+++ b/src/JT808.Protocol/MessageBody/JT808_0x0005.cs
@@ -0,0 +1,44 @@
+using JT808.Protocol.Formatters;
+using JT808.Protocol.MessagePack;
+
+namespace JT808.Protocol.MessageBody
+{
+ ///
+ /// 终端补传分包请求
+ /// 2019版本
+ ///
+ public class JT808_0x0005 : JT808Bodies, IJT808MessagePackFormatter
+ {
+ public override ushort MsgId { get; } = 0x0005;
+ ///
+ /// 原始消息流水号
+ /// 对应要求补传的原始消息第一包的消息流水号
+ ///
+ public ushort OriginalMsgNum { get; set; }
+ ///
+ /// 重传包总数
+ /// n
+ ///
+ public byte AgainPackageCount { get; set; }
+ ///
+ /// 重传包 ID 列表
+ /// BYTE[2*n]
+ /// 重传包序号顺序排列,如“包 ID1 包 ID2......包 IDn”。
+ ///
+ public byte[] AgainPackageData { get; set; }
+ public JT808_0x0005 Deserialize(ref JT808MessagePackReader reader, IJT808Config config)
+ {
+ JT808_0x0005 value = new JT808_0x0005();
+ value.OriginalMsgNum = reader.ReadUInt16();
+ value.AgainPackageCount = reader.ReadByte();
+ value.AgainPackageData = reader.ReadArray(value.AgainPackageCount * 2).ToArray();
+ return value;
+ }
+ public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0005 value, IJT808Config config)
+ {
+ writer.WriteUInt16(value.OriginalMsgNum);
+ writer.WriteByte((byte)(value.AgainPackageData.Length / 2));
+ writer.WriteArray(value.AgainPackageData);
+ }
+ }
+}
diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0100.cs b/src/JT808.Protocol/MessageBody/JT808_0x0100.cs
index 6e8320b..94b83d0 100644
--- a/src/JT808.Protocol/MessageBody/JT808_0x0100.cs
+++ b/src/JT808.Protocol/MessageBody/JT808_0x0100.cs
@@ -1,4 +1,5 @@
-using JT808.Protocol.Formatters;
+using JT808.Protocol.Enums;
+using JT808.Protocol.Formatters;
using JT808.Protocol.MessagePack;
namespace JT808.Protocol.MessageBody
@@ -27,21 +28,22 @@ namespace JT808.Protocol.MessageBody
///
/// 制造商 ID
- /// 5 个字节,终端制造商编码
+ /// 2013版本 5 个字节,终端制造商编码
+ /// 2019版本 11 个字节,终端制造商编码
///
public string MakerId { get; set; }
///
/// 终端型号
- /// 20 个字节,此终端型号由制造商自行定义,位数不
- /// 足时,后补“0X00”。
+ /// 2013版本 20 个字节,此终端型号由制造商自行定义,位数不足时,后补“0X00”。
+ /// 2019版本 30 个字节,此终端型号由制造商自行定义,位数不足时,后补“0X00”。
///
public string TerminalModel { get; set; }
///
/// 终端 ID
- /// 7 个字节,由大写字母和数字组成,此终端 ID 由制
- /// 造商自行定义,位数不足时,后补“0X00”。
+ /// 2013版本 7个字节,由大写字母和数字组成,此终端 ID 由制造商自行定义,位数不足时,后补“0X00”。
+ /// 2019版本 30个字节,由大写字母和数字组成,此终端 ID 由制造商自行定义,位数不足时,后补“0X00”。
///
public string TerminalId { get; set; }
@@ -64,9 +66,18 @@ namespace JT808.Protocol.MessageBody
JT808_0x0100 jT808_0X0100 = new JT808_0x0100();
jT808_0X0100.AreaID = reader.ReadUInt16();
jT808_0X0100.CityOrCountyId = reader.ReadUInt16();
- jT808_0X0100.MakerId = reader.ReadString(5);
- jT808_0X0100.TerminalModel = reader.ReadString(20);
- jT808_0X0100.TerminalId = reader.ReadString(7);
+ if(reader.Version== JT808Version.JTT2019)
+ {
+ jT808_0X0100.MakerId = reader.ReadString(11);
+ jT808_0X0100.TerminalModel = reader.ReadString(30);
+ jT808_0X0100.TerminalId = reader.ReadString(30);
+ }
+ else
+ {
+ jT808_0X0100.MakerId = reader.ReadString(5);
+ jT808_0X0100.TerminalModel = reader.ReadString(20);
+ jT808_0X0100.TerminalId = reader.ReadString(7);
+ }
jT808_0X0100.PlateColor = reader.ReadByte();
jT808_0X0100.PlateNo = reader.ReadRemainStringContent();
return jT808_0X0100;
@@ -76,9 +87,18 @@ namespace JT808.Protocol.MessageBody
{
writer.WriteUInt16(value.AreaID);
writer.WriteUInt16(value.CityOrCountyId);
- writer.WriteString(value.MakerId.PadRight(5, '0'));
- writer.WriteString(value.TerminalModel.PadRight(20, '0'));
- writer.WriteString(value.TerminalId.PadRight(7, '0'));
+ if (writer.Version == JT808Version.JTT2019)
+ {
+ writer.WriteString(value.MakerId.PadLeft(11, '0'));
+ writer.WriteString(value.TerminalModel.PadLeft(30, '0'));
+ writer.WriteString(value.TerminalId.PadLeft(30, '0'));
+ }
+ else
+ {
+ writer.WriteString(value.MakerId.PadRight(5, '0'));
+ writer.WriteString(value.TerminalModel.PadRight(20, '0'));
+ writer.WriteString(value.TerminalId.PadRight(7, '0'));
+ }
writer.WriteByte(value.PlateColor);
writer.WriteString(value.PlateNo);
}
diff --git a/src/JT808.Protocol/MessageBody/JT808_0x0102.cs b/src/JT808.Protocol/MessageBody/JT808_0x0102.cs
index 189829e..97570ce 100644
--- a/src/JT808.Protocol/MessageBody/JT808_0x0102.cs
+++ b/src/JT808.Protocol/MessageBody/JT808_0x0102.cs
@@ -1,4 +1,5 @@
-using JT808.Protocol.Formatters;
+using JT808.Protocol.Enums;
+using JT808.Protocol.Formatters;
using JT808.Protocol.MessagePack;
namespace JT808.Protocol.MessageBody
@@ -11,19 +12,54 @@ namespace JT808.Protocol.MessageBody
public override ushort MsgId { get; } = 0x0102;
///
/// 鉴权码
+ /// 鉴权码内容 2019版本
///
public string Code { get; set; }
+ ///
+ /// 鉴权码长度 2019版本
+ ///
+ public byte CodeLength { get; set; }
+ ///
+ /// 终端IMEI 长度15 2019版本
+ ///
+ public string IMEI { get; set; }
+ ///
+ /// 软件版本号 长度20 后补 "0x00" 2019版本
+ ///
+ public string SoftwareVersion { get; set; }
public JT808_0x0102 Deserialize(ref JT808MessagePackReader reader, IJT808Config config)
{
JT808_0x0102 jT808_0X0102 = new JT808_0x0102();
- jT808_0X0102.Code = reader.ReadRemainStringContent();
+ if(reader.Version== JT808Version.JTT2019)
+ {
+ jT808_0X0102.CodeLength = reader.ReadByte();
+ jT808_0X0102.Code = reader.ReadString(jT808_0X0102.CodeLength);
+ jT808_0X0102.IMEI = reader.ReadString(15);
+ jT808_0X0102.SoftwareVersion = reader.ReadString(20);
+ }
+ else
+ {
+ jT808_0X0102.Code = reader.ReadRemainStringContent();
+ }
+
return jT808_0X0102;
}
public void Serialize(ref JT808MessagePackWriter writer, JT808_0x0102 value, IJT808Config config)
{
- writer.WriteString(value.Code);
+ if (writer.Version == JT808Version.JTT2019)
+ {
+ writer.Skip(1, out int CodeLengthPosition);
+ writer.WriteString(value.Code);
+ writer.WriteByteReturn((byte)(writer.GetCurrentPosition() - CodeLengthPosition - 1), CodeLengthPosition);
+ writer.WriteString(value.IMEI);
+ writer.WriteString(value.SoftwareVersion.PadRight(20,'0'));
+ }
+ else
+ {
+ writer.WriteString(value.Code);
+ }
}
}
}
diff --git a/src/JT808.Protocol/MessageBody/JT808_0x8004.cs b/src/JT808.Protocol/MessageBody/JT808_0x8004.cs
new file mode 100644
index 0000000..b15fe7c
--- /dev/null
+++ b/src/JT808.Protocol/MessageBody/JT808_0x8004.cs
@@ -0,0 +1,29 @@
+using JT808.Protocol.Formatters;
+using JT808.Protocol.MessagePack;
+using System;
+
+namespace JT808.Protocol.MessageBody
+{
+ ///
+ /// 查询服务器时间应答
+ /// 2019版本
+ ///
+ public class JT808_0x8004 : JT808Bodies, IJT808MessagePackFormatter
+ {
+ public override ushort MsgId { get; } = 0x8004;
+
+ public DateTime Time { get; set; } = DateTime.Now;
+
+ public JT808_0x8004 Deserialize(ref JT808MessagePackReader reader, IJT808Config config)
+ {
+ JT808_0x8004 value = new JT808_0x8004();
+ value.Time = reader.ReadDateTime6();
+ return value;
+ }
+
+ public void Serialize(ref JT808MessagePackWriter writer, JT808_0x8004 value, IJT808Config config)
+ {
+ writer.WriteDateTime6(value.Time);
+ }
+ }
+}
diff --git a/src/JT808.Protocol/MessagePack/JT808MessagePackReader.cs b/src/JT808.Protocol/MessagePack/JT808MessagePackReader.cs
index 7bfe262..f90012d 100644
--- a/src/JT808.Protocol/MessagePack/JT808MessagePackReader.cs
+++ b/src/JT808.Protocol/MessagePack/JT808MessagePackReader.cs
@@ -1,5 +1,7 @@
using JT808.Protocol.Buffers;
+using JT808.Protocol.Enums;
using JT808.Protocol.Extensions;
+using JT808.Protocol.Interfaces;
using System;
using System.Buffers;
using System.Buffers.Binary;
@@ -15,6 +17,7 @@ namespace JT808.Protocol.MessagePack
public ReadOnlySpan Reader { get; private set; }
public ReadOnlySpan SrcBuffer { get; }
public int ReaderCount { get; private set; }
+ public JT808Version Version { get; set; }
private byte _calculateCheckXorCode;
private byte _realCheckXorCode;
private bool _checkXorCodeVali;
@@ -31,7 +34,7 @@ namespace JT808.Protocol.MessagePack
/// 解码(转义还原),计算校验和
///
///
- public JT808MessagePackReader(ReadOnlySpan srcBuffer)
+ public JT808MessagePackReader(ReadOnlySpan srcBuffer, JT808Version version = JT808Version.JTT2013)
{
SrcBuffer = srcBuffer;
ReaderCount = 0;
@@ -39,6 +42,7 @@ namespace JT808.Protocol.MessagePack
_calculateCheckXorCode = 0x00;
_checkXorCodeVali = false;
_decoded = false;
+ Version = version;
Reader = srcBuffer;
}
///
diff --git a/src/JT808.Protocol/MessagePack/JT808MessagePackWriter.cs b/src/JT808.Protocol/MessagePack/JT808MessagePackWriter.cs
index d8d5558..490e7d1 100644
--- a/src/JT808.Protocol/MessagePack/JT808MessagePackWriter.cs
+++ b/src/JT808.Protocol/MessagePack/JT808MessagePackWriter.cs
@@ -1,4 +1,5 @@
using JT808.Protocol.Buffers;
+using JT808.Protocol.Enums;
using System;
using System.Buffers;
using System.Buffers.Binary;
@@ -9,9 +10,11 @@ namespace JT808.Protocol.MessagePack
public ref struct JT808MessagePackWriter
{
private JT808BufferWriter writer;
- public JT808MessagePackWriter(Span buffer)
+ public JT808Version Version { get; set; }
+ public JT808MessagePackWriter(Span buffer, JT808Version version= JT808Version.JTT2013)
{
this.writer = new JT808BufferWriter(buffer);
+ Version = version;
}
public byte[] FlushAndGetEncodingArray()
{