Przeglądaj źródła

添加2019新版808协议的兼容

tags/v2.2.0
SmallChi(Koike) 5 lat temu
rodzic
commit
69ce328cda
28 zmienionych plików z 776 dodań i 124 usunięć
  1. +17
    -14
      README.md
  2. BIN
      doc/JTT.808-2019.PDF
  3. +6
    -0
      src/JT808.Protocol.Test/JT808.Protocol.Test.csproj
  4. +44
    -0
      src/JT808.Protocol.Test/JT808HeaderMessageBodyPropertyTest.cs
  5. +36
    -1
      src/JT808.Protocol.Test/JT808HeaderTest.cs
  6. +33
    -0
      src/JT808.Protocol.Test/MessageBody/JT808_0x0005Test.cs
  7. +52
    -0
      src/JT808.Protocol.Test/MessageBody/JT808_0x0100Test.cs
  8. +25
    -0
      src/JT808.Protocol.Test/MessageBody/JT808_0x0102Test.cs
  9. +31
    -0
      src/JT808.Protocol.Test/MessageBody/JT808_0x8004Test.cs
  10. +11
    -0
      src/JT808.Protocol.Test/MessagePack/JT808MessagePackReaderTest.cs
  11. +11
    -0
      src/JT808.Protocol.Test/MessagePack/JT808MessagePackWriterTest.cs
  12. +0
    -17
      src/JT808.Protocol/Attributes/JT808FormatterAttribute.cs
  13. +0
    -5
      src/JT808.Protocol/Enums/JT808ErrorCode.cs
  14. +1
    -0
      src/JT808.Protocol/Interfaces/IJT808Config.cs
  15. +5
    -1
      src/JT808.Protocol/JT808.Protocol.csproj
  16. +93
    -19
      src/JT808.Protocol/JT808.Protocol.xml
  17. +36
    -4
      src/JT808.Protocol/JT808Header.cs
  18. +73
    -4
      src/JT808.Protocol/JT808HeaderMessageBodyProperty.cs
  19. +43
    -2
      src/JT808.Protocol/JT808HeaderPackage.cs
  20. +70
    -21
      src/JT808.Protocol/JT808Package.cs
  21. +20
    -19
      src/JT808.Protocol/JT808Serializer.cs
  22. +16
    -0
      src/JT808.Protocol/MessageBody/JT808_0x0004.cs
  23. +44
    -0
      src/JT808.Protocol/MessageBody/JT808_0x0005.cs
  24. +32
    -12
      src/JT808.Protocol/MessageBody/JT808_0x0100.cs
  25. +39
    -3
      src/JT808.Protocol/MessageBody/JT808_0x0102.cs
  26. +29
    -0
      src/JT808.Protocol/MessageBody/JT808_0x8004.cs
  27. +5
    -1
      src/JT808.Protocol/MessagePack/JT808MessagePackReader.cs
  28. +4
    -1
      src/JT808.Protocol/MessagePack/JT808MessagePackWriter.cs

+ 17
- 14
README.md Wyświetl plik

@@ -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 | √ | √ | 终端补传分包请求 |新增|

BIN
doc/JTT.808-2019.PDF Wyświetl plik


+ 6
- 0
src/JT808.Protocol.Test/JT808.Protocol.Test.csproj Wyświetl plik

@@ -56,6 +56,8 @@
<Compile Include="MessageBody\JT808_0x0901Test.cs" />
<Compile Include="MessageBody\JT808_0x0A00Test.cs" />
<Compile Include="MessageBody\JT808_0x8001Test.cs" />
<Compile Include="MessageBody\JT808_0x0005Test.cs" />
<Compile Include="MessageBody\JT808_0x8004Test.cs" />
<Compile Include="MessageBody\JT808_0x8003Test.cs" />
<Compile Include="MessageBody\JT808_0x8100Test.cs" />
<Compile Include="MessageBody\JT808_0x8103CustomIdExtensions\JT808_0x8103_0x0075.cs" />
@@ -94,6 +96,10 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.8">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.3.0" />
<PackageReference Include="NETStandard.Library" Version="2.0.3" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />


+ 44
- 0
src/JT808.Protocol.Test/JT808HeaderMessageBodyPropertyTest.cs Wyświetl plik

@@ -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);
}
}
}

+ 36
- 1
src/JT808.Protocol.Test/JT808HeaderTest.cs Wyświetl plik

@@ -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<JT808Header>(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);
}
}
}

+ 33
- 0
src/JT808.Protocol.Test/MessageBody/JT808_0x0005Test.cs Wyświetl plik

@@ -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<JT808_0x0005>(bytes);
Assert.Equal(1234, jT808_0X8005.OriginalMsgNum);
Assert.Equal(new byte[] { 0x01, 0x02, 0x02, 0x03 }, jT808_0X8005.AgainPackageData);
Assert.Equal(2, jT808_0X8005.AgainPackageCount);
}
}
}

+ 52
- 0
src/JT808.Protocol.Test/MessageBody/JT808_0x0100Test.cs Wyświetl plik

@@ -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<JT808Package>(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);
}
}
}

+ 25
- 0
src/JT808.Protocol.Test/MessageBody/JT808_0x0102Test.cs Wyświetl plik

@@ -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<JT808_0x0102>(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()
{


+ 31
- 0
src/JT808.Protocol.Test/MessageBody/JT808_0x8004Test.cs Wyświetl plik

@@ -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<JT808_0x8004>(bytes);
Assert.Equal(DateTime.Parse("2019-11-26 15:58:50"), jT808_0X8004.Time);
}
}
}

+ 11
- 0
src/JT808.Protocol.Test/MessagePack/JT808MessagePackReaderTest.cs Wyświetl plik

@@ -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);
}
}
}

+ 11
- 0
src/JT808.Protocol.Test/MessagePack/JT808MessagePackWriterTest.cs Wyświetl plik

@@ -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);
}
}
}

+ 0
- 17
src/JT808.Protocol/Attributes/JT808FormatterAttribute.cs Wyświetl plik

@@ -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;
}
}
}

+ 0
- 5
src/JT808.Protocol/Enums/JT808ErrorCode.cs Wyświetl plik

@@ -7,11 +7,6 @@
/// </summary>
CheckCodeNotEqual = 1001,
/// <summary>
/// 没有标记
/// <see cref="JT808.Protocol.Attributes.JT808FormatterAttribute"/>
/// </summary>
GetFormatterAttributeError = 1002,
/// <summary>
/// 消息头解析错误
/// </summary>
HeaderParseError = 1003,


+ 1
- 0
src/JT808.Protocol/Interfaces/IJT808Config.cs Wyświetl plik

@@ -10,6 +10,7 @@ namespace JT808.Protocol
{
public interface IJT808Config
{
[Obsolete("目前没用")]
JT808Version Version { get;}
string ConfigId { get; }
/// <summary>


+ 5
- 1
src/JT808.Protocol/JT808.Protocol.csproj Wyświetl plik

@@ -14,7 +14,7 @@
<licenseUrl>https://github.com/SmallChi/JT808/blob/master/LICENSE</licenseUrl>
<license>https://github.com/SmallChi/JT808/blob/master/LICENSE</license>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>2.2.0-preview1</Version>
<Version>2.2.0-preview3</Version>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
@@ -65,6 +65,10 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.7">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.CSharp" Version="4.6.0" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.6.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.0.0" />


+ 93
- 19
src/JT808.Protocol/JT808.Protocol.xml Wyświetl plik

@@ -213,12 +213,6 @@
校验和不相等
</summary>
</member>
<member name="F:JT808.Protocol.Enums.JT808ErrorCode.GetFormatterAttributeError">
<summary>
没有标记
<see cref="T:JT808.Protocol.Attributes.JT808FormatterAttribute"/>
</summary>
</member>
<member name="F:JT808.Protocol.Enums.JT808ErrorCode.HeaderParseError">
<summary>
消息头解析错误
@@ -2197,10 +2191,21 @@
<see cref="T:JT808.Protocol.Enums.JT808MsgId"/>
</summary>
</member>
<member name="P:JT808.Protocol.JT808Header.MessageBodyProperty">
<summary>
消息体属性
</summary>
</member>
<member name="P:JT808.Protocol.JT808Header.ProtocolVersion">
<summary>
协议版本号(2019版本)
</summary>
</member>
<member name="P:JT808.Protocol.JT808Header.TerminalPhoneNo">
<summary>
终端手机号
根据安装后终端自身的手机号转换。手机号不足 12 位,则在前补充数字,大陆手机号补充数字 0,港澳台则根据其区号进行位数补充
(2019版本)手机号不足 20 位,则在前补充数字 0
</summary>
</member>
<member name="P:JT808.Protocol.JT808Header.MsgNum">
@@ -2221,6 +2226,11 @@
报序号 从1开始
</summary>
</member>
<member name="P:JT808.Protocol.JT808HeaderMessageBodyProperty.VersionFlag">
<summary>
版本标识(默认为1=true)
</summary>
</member>
<member name="P:JT808.Protocol.JT808HeaderMessageBodyProperty.IsPackage">
<summary>
是否分包
@@ -2292,9 +2302,14 @@
起始符
</summary>
</member>
<member name="P:JT808.Protocol.JT808Package.End">
<member name="P:JT808.Protocol.JT808Package.Header">
<summary>
终止符
头数据
</summary>
</member>
<member name="P:JT808.Protocol.JT808Package.Bodies">
<summary>
数据体
</summary>
</member>
<member name="P:JT808.Protocol.JT808Package.CheckCode">
@@ -2303,17 +2318,17 @@
从消息头开始,同后一字节异或,直到校验码前一个字节,占用一个字节。
</summary>
</member>
<member name="P:JT808.Protocol.JT808Package.Header">
<member name="P:JT808.Protocol.JT808Package.End">
<summary>
头数据
终止符
</summary>
</member>
<member name="P:JT808.Protocol.JT808Package.Bodies">
<member name="P:JT808.Protocol.JT808Package.Version">
<summary>
数据体
808版本号
</summary>
</member>
<member name="M:JT808.Protocol.JT808Serializer.HeaderDeserialize(System.ReadOnlySpan{System.Byte},System.Int32)">
<member name="M:JT808.Protocol.JT808Serializer.HeaderDeserialize(System.ReadOnlySpan{System.Byte},JT808.Protocol.Enums.JT808Version,System.Int32)">
<summary>
用于负载或者分布式的时候,在网关只需要解到头部。
根据头部的消息Id进行分发处理,可以防止小部分性能损耗。
@@ -2365,6 +2380,42 @@
跳过数据体序列化
</summary>
</member>
<member name="T:JT808.Protocol.MessageBody.JT808_0x0004">
<summary>
查询服务器时间请求
2019版本
</summary>
</member>
<member name="P:JT808.Protocol.MessageBody.JT808_0x0004.SkipSerialization">
<summary>
跳过数据体序列化
</summary>
</member>
<member name="T:JT808.Protocol.MessageBody.JT808_0x0005">
<summary>
终端补传分包请求
2019版本
</summary>
</member>
<member name="P:JT808.Protocol.MessageBody.JT808_0x0005.OriginalMsgNum">
<summary>
原始消息流水号
对应要求补传的原始消息第一包的消息流水号
</summary>
</member>
<member name="P:JT808.Protocol.MessageBody.JT808_0x0005.AgainPackageCount">
<summary>
重传包总数
n
</summary>
</member>
<member name="P:JT808.Protocol.MessageBody.JT808_0x0005.AgainPackageData">
<summary>
重传包 ID 列表
BYTE[2*n]
重传包序号顺序排列,如“包 ID1 包 ID2......包 IDn”。
</summary>
</member>
<member name="T:JT808.Protocol.MessageBody.JT808_0x0100">
<summary>
终端注册
@@ -2389,21 +2440,22 @@
<member name="P:JT808.Protocol.MessageBody.JT808_0x0100.MakerId">
<summary>
制造商 ID
5 个字节,终端制造商编码
2013版本 5 个字节,终端制造商编码
2019版本 11 个字节,终端制造商编码
</summary>
</member>
<member name="P:JT808.Protocol.MessageBody.JT808_0x0100.TerminalModel">
<summary>
终端型号
20 个字节,此终端型号由制造商自行定义,位数不
足时,后补“0X00”。
2013版本 20 个字节,此终端型号由制造商自行定义,位数不足时,后补“0X00”。
2019版本 30 个字节,此终端型号由制造商自行定义,位数不足时,后补“0X00”。
</summary>
</member>
<member name="P:JT808.Protocol.MessageBody.JT808_0x0100.TerminalId">
<summary>
终端 ID
7 个字节,由大写字母和数字组成,此终端 ID 由制
造商自行定义,位数不足时,后补“0X00”。
2013版本 7个字节,由大写字母和数字组成,此终端 ID 由制造商自行定义,位数不足时,后补“0X00”。
2019版本 30个字节,由大写字母和数字组成,此终端 ID 由制造商自行定义,位数不足时,后补“0X00”。
</summary>
</member>
<member name="P:JT808.Protocol.MessageBody.JT808_0x0100.PlateColor">
@@ -2428,6 +2480,22 @@
<member name="P:JT808.Protocol.MessageBody.JT808_0x0102.Code">
<summary>
鉴权码
鉴权码内容 2019版本
</summary>
</member>
<member name="P:JT808.Protocol.MessageBody.JT808_0x0102.CodeLength">
<summary>
鉴权码长度 2019版本
</summary>
</member>
<member name="P:JT808.Protocol.MessageBody.JT808_0x0102.IMEI">
<summary>
终端IMEI 长度15 2019版本
</summary>
</member>
<member name="P:JT808.Protocol.MessageBody.JT808_0x0102.SoftwareVersion">
<summary>
软件版本号 长度20 后补 "0x00" 2019版本
</summary>
</member>
<member name="T:JT808.Protocol.MessageBody.JT808_0x0104">
@@ -3216,6 +3284,12 @@
重传包序号顺序排列,如“包 ID1 包 ID2......包 IDn”。
</summary>
</member>
<member name="T:JT808.Protocol.MessageBody.JT808_0x8004">
<summary>
查询服务器时间应答
2019版本
</summary>
</member>
<member name="T:JT808.Protocol.MessageBody.JT808_0x8100">
<summary>
终端注册应答
@@ -5420,7 +5494,7 @@
主要用来一次性读取所有数据体内容操作
</summary>
</member>
<member name="M:JT808.Protocol.MessagePack.JT808MessagePackReader.#ctor(System.ReadOnlySpan{System.Byte})">
<member name="M:JT808.Protocol.MessagePack.JT808MessagePackReader.#ctor(System.ReadOnlySpan{System.Byte},JT808.Protocol.Enums.JT808Version)">
<summary>
解码(转义还原),计算校验和
</summary>


+ 36
- 4
src/JT808.Protocol/JT808Header.cs Wyświetl plik

@@ -13,10 +13,18 @@ namespace JT808.Protocol
/// <see cref="JT808.Protocol.Enums.JT808MsgId"/>
/// </summary>
public ushort MsgId { get; set; }
/// <summary>
/// 消息体属性
/// </summary>
public JT808HeaderMessageBodyProperty MessageBodyProperty { get; set; }
/// <summary>
/// 协议版本号(2019版本)
/// </summary>
public byte ProtocolVersion { get; set; } = 1;
/// <summary>
/// 终端手机号
/// 根据安装后终端自身的手机号转换。手机号不足 12 位,则在前补充数字,大陆手机号补充数字 0,港澳台则根据其区号进行位数补充
/// (2019版本)手机号不足 20 位,则在前补充数字 0
/// </summary>
public string TerminalPhoneNo { get; set; }
/// <summary>
@@ -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.判断是否分包


+ 73
- 4
src/JT808.Protocol/JT808HeaderMessageBodyProperty.cs Wyświetl plik

@@ -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;
}
/// <summary>
/// 版本标识(默认为1=true)
/// </summary>
public bool VersionFlag { get; set; }
/// <summary>
/// 是否分包
/// 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);
}
}
}

+ 43
- 2
src/JT808.Protocol/JT808HeaderPackage.cs Wyświetl plik

@@ -34,6 +34,34 @@ namespace JT808.Protocol
/// </summary>
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.判断有无分包


+ 70
- 21
src/JT808.Protocol/JT808Package.cs Wyświetl plik

@@ -25,27 +25,54 @@ namespace JT808.Protocol
/// 起始符
/// </summary>
public byte Begin { get; set; } = BeginFlag;

/// <summary>
/// 终止符
/// 头数据
/// </summary>
public byte End { get; set; } = EndFlag;

public JT808Header Header { get; set; }
/// <summary>
/// 数据体
/// </summary>
public JT808Bodies Bodies { get; set; }
/// <summary>
/// 校验码
/// 从消息头开始,同后一字节异或,直到校验码前一个字节,占用一个字节。
/// </summary>
public byte CheckCode { get; set; }

/// <summary>
/// 头数据
/// 终止符
/// </summary>
public JT808Header Header { get; set; }

public byte End { get; set; } = EndFlag;
/// <summary>
/// 数据体
/// 808版本号
/// </summary>
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.终止符


+ 20
- 19
src/JT808.Protocol/JT808Serializer.cs Wyświetl plik

@@ -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<byte> SerializeReadOnlySpan(JT808Package jT808Package, int minBufferSize = 4096)
public ReadOnlySpan<byte> 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<byte> bytes, int minBufferSize = 4096)
public JT808Package Deserialize(ReadOnlySpan<byte> 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>(T obj, int minBufferSize = 4096)
public byte [] Serialize<T>(T obj, JT808Version version = JT808Version.JTT2013, int minBufferSize = 4096)
{
byte[] buffer = JT808ArrayPool.Rent(minBufferSize);
try
{
var formatter = jT808Config.GetMessagePackFormatter<T>();
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<byte> SerializeReadOnlySpan<T>(T obj, int minBufferSize = 4096)
public ReadOnlySpan<byte> SerializeReadOnlySpan<T>(T obj, JT808Version version = JT808Version.JTT2013, int minBufferSize = 4096)
{
byte[] buffer = JT808ArrayPool.Rent(minBufferSize);
try
{
var formatter = jT808Config.GetMessagePackFormatter<T>();
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<T>(ReadOnlySpan<byte> bytes, int minBufferSize = 4096)
public T Deserialize<T>(ReadOnlySpan<byte> 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<T>();
@@ -132,12 +133,12 @@ namespace JT808.Protocol
/// </summary>
/// <param name="bytes"></param>
/// <returns></returns>
public JT808HeaderPackage HeaderDeserialize(ReadOnlySpan<byte> bytes, int minBufferSize = 4096)
public JT808HeaderPackage HeaderDeserialize(ReadOnlySpan<byte> 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<byte> bytes, Type type, int minBufferSize = 4096)
public dynamic Deserialize(ReadOnlySpan<byte> 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);


+ 16
- 0
src/JT808.Protocol/MessageBody/JT808_0x0004.cs Wyświetl plik

@@ -0,0 +1,16 @@
namespace JT808.Protocol.MessageBody
{
/// <summary>
/// 查询服务器时间请求
/// 2019版本
/// </summary>
public class JT808_0x0004 : JT808Bodies
{
/// <summary>
/// 跳过数据体序列化
/// </summary>
public override bool SkipSerialization { get; set; } = true;

public override ushort MsgId { get; } = 0x0004;
}
}

+ 44
- 0
src/JT808.Protocol/MessageBody/JT808_0x0005.cs Wyświetl plik

@@ -0,0 +1,44 @@
using JT808.Protocol.Formatters;
using JT808.Protocol.MessagePack;

namespace JT808.Protocol.MessageBody
{
/// <summary>
/// 终端补传分包请求
/// 2019版本
/// </summary>
public class JT808_0x0005 : JT808Bodies, IJT808MessagePackFormatter<JT808_0x0005>
{
public override ushort MsgId { get; } = 0x0005;
/// <summary>
/// 原始消息流水号
/// 对应要求补传的原始消息第一包的消息流水号
/// </summary>
public ushort OriginalMsgNum { get; set; }
/// <summary>
/// 重传包总数
/// n
/// </summary>
public byte AgainPackageCount { get; set; }
/// <summary>
/// 重传包 ID 列表
/// BYTE[2*n]
/// 重传包序号顺序排列,如“包 ID1 包 ID2......包 IDn”。
/// </summary>
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);
}
}
}

+ 32
- 12
src/JT808.Protocol/MessageBody/JT808_0x0100.cs Wyświetl plik

@@ -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

/// <summary>
/// 制造商 ID
/// 5 个字节,终端制造商编码
/// 2013版本 5 个字节,终端制造商编码
/// 2019版本 11 个字节,终端制造商编码
/// </summary>
public string MakerId { get; set; }

/// <summary>
/// 终端型号
/// 20 个字节,此终端型号由制造商自行定义,位数不
/// 足时,后补“0X00”。
/// 2013版本 20 个字节,此终端型号由制造商自行定义,位数不足时,后补“0X00”。
/// 2019版本 30 个字节,此终端型号由制造商自行定义,位数不足时,后补“0X00”。
/// </summary>
public string TerminalModel { get; set; }

/// <summary>
/// 终端 ID
/// 7 个字节,由大写字母和数字组成,此终端 ID 由制
/// 造商自行定义,位数不足时,后补“0X00”。
/// 2013版本 7个字节,由大写字母和数字组成,此终端 ID 由制造商自行定义,位数不足时,后补“0X00”。
/// 2019版本 30个字节,由大写字母和数字组成,此终端 ID 由制造商自行定义,位数不足时,后补“0X00”。
/// </summary>
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);
}


+ 39
- 3
src/JT808.Protocol/MessageBody/JT808_0x0102.cs Wyświetl plik

@@ -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;
/// <summary>
/// 鉴权码
/// 鉴权码内容 2019版本
/// </summary>
public string Code { get; set; }
/// <summary>
/// 鉴权码长度 2019版本
/// </summary>
public byte CodeLength { get; set; }
/// <summary>
/// 终端IMEI 长度15 2019版本
/// </summary>
public string IMEI { get; set; }
/// <summary>
/// 软件版本号 长度20 后补 "0x00" 2019版本
/// </summary>
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);
}
}
}
}

+ 29
- 0
src/JT808.Protocol/MessageBody/JT808_0x8004.cs Wyświetl plik

@@ -0,0 +1,29 @@
using JT808.Protocol.Formatters;
using JT808.Protocol.MessagePack;
using System;

namespace JT808.Protocol.MessageBody
{
/// <summary>
/// 查询服务器时间应答
/// 2019版本
/// </summary>
public class JT808_0x8004 : JT808Bodies, IJT808MessagePackFormatter<JT808_0x8004>
{
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);
}
}
}

+ 5
- 1
src/JT808.Protocol/MessagePack/JT808MessagePackReader.cs Wyświetl plik

@@ -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<byte> Reader { get; private set; }
public ReadOnlySpan<byte> 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
/// 解码(转义还原),计算校验和
/// </summary>
/// <param name="buffer"></param>
public JT808MessagePackReader(ReadOnlySpan<byte> srcBuffer)
public JT808MessagePackReader(ReadOnlySpan<byte> 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;
}
/// <summary>


+ 4
- 1
src/JT808.Protocol/MessagePack/JT808MessagePackWriter.cs Wyświetl plik

@@ -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<byte> buffer)
public JT808Version Version { get; set; }
public JT808MessagePackWriter(Span<byte> buffer, JT808Version version= JT808Version.JTT2013)
{
this.writer = new JT808BufferWriter(buffer);
Version = version;
}
public byte[] FlushAndGetEncodingArray()
{


Ładowanie…
Anuluj
Zapisz