@@ -1,10 +1,10 @@ | |||
# JT809协议 | |||
# JT809协议 | |||
## 瞎逼逼: | |||
> 该JT809协议是参考[MessagePack-CSharp](https://github.com/neuecc/MessagePack-CSharp)一款二进制序列化器,借鉴其思想,不得不说站在巨人的肩膀上搬砖就是爽歪歪。 | |||
> 在github上面搜索竟然没有针对.NET开源的809协议库,难度做GPS行业的.NET很少人吗?可能是藏着,掖着<( ̄3 ̄)> <( ̄3 ̄)> <( ̄3 ̄)> 。 | |||
> 在github上面搜索竟然没有针对.NET开源的809协议库,难道做GPS行业的.NET很少人吗?可能是藏着,掖着<( ̄3 ̄)> <( ̄3 ̄)> <( ̄3 ̄)> 。 | |||
> 不得不说这GB的文档,太坑了。。。 | |||
@@ -13,7 +13,7 @@ | |||
## 前提条件 | |||
1. 掌握进制转换:二进制转十六进制; | |||
2. 掌握什么叫BCD编码、Hex编码; | |||
2. 掌握BCD编码、Hex编码; | |||
3. 掌握各种位移、异或; | |||
4. 掌握常用反射; | |||
5. 掌握快速ctrl+c、ctrl+v; | |||
@@ -31,7 +31,7 @@ | |||
|数据长度|报文序列号|业务数据类型|下级平台接入码|协议版本号标识|报文加密标识位|数据加密的密匙| | |||
|:------:|:------:|:------:|:------:|:------:|:------:|:------:| | |||
| MsgLength | MsgSN | MsgID | MsgGNSSCENTERID | Version | EndFlag |EncryptFlag | EncryptKey | | |||
| MsgLength | MsgSN | MsgID | MsgGNSSCENTERID | Version |EncryptFlag | EncryptKey | | |||
### 数据体[JT809Bodies] | |||
@@ -181,6 +181,36 @@ Assert.Equal("123456@qq.com", jT809_0x9400_0x9401.SupervisorEmail); | |||
``` | |||
## 使用BenchmarkDotNet性能测试报告(只是玩玩,不能当真) | |||
``` ini | |||
BenchmarkDotNet=v0.11.1, OS=Windows 7 SP1 (6.1.7601.0) | |||
Intel Core i5-5200U CPU 2.20GHz (Max: 2.18GHz) (Broadwell), 1 CPU, 4 logical and 2 physical cores | |||
Frequency=2143505 Hz, Resolution=466.5256 ns, Timer=TSC | |||
.NET Core SDK=2.1.401 | |||
[Host] : .NET Core 2.1.2 (CoreCLR 4.6.26628.05, CoreFX 4.6.26629.01), 64bit RyuJIT | |||
Job-VCXLHD : .NET Framework 4.7.2 (CLR 4.0.30319.42000), 64bit RyuJIT-v4.7.3133.0 | |||
Job-WATJMQ : .NET Core 2.1.2 (CoreCLR 4.6.26628.05, CoreFX 4.6.26629.01), 64bit RyuJIT | |||
Platform=AnyCpu Server=True | |||
``` | |||
| Method | Runtime | Toolchain | N | Mean | Error | StdDev | Median | Gen 0 | Allocated | | |||
|---------------------------------------- |-------- |-------------- |------- |-------------:|------------:|------------:|-------------:|------------:|-------------:| | |||
| **JT809_0x9400_0x9401_Package_Deserialize** | **Clr** | **Default** | **100** | **6.023 ms** | **0.1358 ms** | **0.3939 ms** | **5.890 ms** | **-** | **520 KB** | | |||
| JT809_0x9400_0x9401_Package_Serialize | Clr | Default | 100 | 7.548 ms | 0.1737 ms | 0.5067 ms | 7.479 ms | - | 536 KB | | |||
| JT809_0x9400_0x9401_Package_Deserialize | Core | .NET Core 2.1 | 100 | 4.405 ms | 0.0874 ms | 0.2332 ms | 4.372 ms | 23.4375 | 465.18 KB | | |||
| JT809_0x9400_0x9401_Package_Serialize | Core | .NET Core 2.1 | 100 | 5.178 ms | 0.1031 ms | 0.2107 ms | 5.131 ms | 23.4375 | 466.74 KB | | |||
| **JT809_0x9400_0x9401_Package_Deserialize** | **Clr** | **Default** | **10000** | **569.689 ms** | **11.3421 ms** | **28.0348 ms** | **560.844 ms** | **33000.0000** | **50755.41 KB** | | |||
| JT809_0x9400_0x9401_Package_Serialize | Clr | Default | 10000 | 709.679 ms | 14.0759 ms | 32.0580 ms | 705.015 ms | 34000.0000 | 52365.04 KB | | |||
| JT809_0x9400_0x9401_Package_Deserialize | Core | .NET Core 2.1 | 10000 | 435.974 ms | 8.6721 ms | 23.2971 ms | 432.058 ms | 2000.0000 | 46516.3 KB | | |||
| JT809_0x9400_0x9401_Package_Serialize | Core | .NET Core 2.1 | 10000 | 559.733 ms | 16.1688 ms | 46.3913 ms | 552.344 ms | 2000.0000 | 46672.55 KB | | |||
| **JT809_0x9400_0x9401_Package_Deserialize** | **Clr** | **Default** | **100000** | **6,167.859 ms** | **182.6382 ms** | **512.1372 ms** | **6,133.157 ms** | **330000.0000** | **507097.91 KB** | | |||
| JT809_0x9400_0x9401_Package_Serialize | Clr | Default | 100000 | 7,558.213 ms | 179.7646 ms | 518.6620 ms | 7,478.251 ms | 340000.0000 | 523420.85 KB | | |||
| JT809_0x9400_0x9401_Package_Deserialize | Core | .NET Core 2.1 | 100000 | 5,064.515 ms | 179.1875 ms | 511.2320 ms | 4,932.761 ms | 27000.0000 | 465045.28 KB | | |||
| JT809_0x9400_0x9401_Package_Serialize | Core | .NET Core 2.1 | 100000 | 5,108.023 ms | 99.7554 ms | 126.1587 ms | 5,071.244 ms | 26000.0000 | 466693.55 KB | | |||
## JT809协议消息对照表 | |||
### 链路管理类 | |||
@@ -329,4 +359,5 @@ Assert.Equal("123456@qq.com", jT809_0x9400_0x9401.SupervisorEmail); | |||
|序号|消息ID|完成情况|消息体名称| | |||
|:------:|:------:|:------:|:------:| | |||
| 1 | 0x9600 | √ | 从链路静态信息交换消息 | | |||
| 2 | 0x9601 | √ | 补报车辆静态信息应答 | | |||
| 2 | 0x9601 | √ | 补报车辆静态信息应答 | | |||
@@ -0,0 +1,16 @@ | |||
<Project Sdk="Microsoft.NET.Sdk"> | |||
<PropertyGroup> | |||
<OutputType>Exe</OutputType> | |||
<TargetFrameworks>netcoreapp2.1;net472;</TargetFrameworks> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<PackageReference Include="BenchmarkDotNet" Version="0.11.1" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<ProjectReference Include="..\JT809.Protocol\JT809.Protocol.csproj" /> | |||
</ItemGroup> | |||
</Project> |
@@ -0,0 +1,93 @@ | |||
using BenchmarkDotNet.Attributes; | |||
using BenchmarkDotNet.Configs; | |||
using BenchmarkDotNet.Environments; | |||
using BenchmarkDotNet.Jobs; | |||
using BenchmarkDotNet.Toolchains.CsProj; | |||
using JT809.Protocol.JT809Enums; | |||
using JT809.Protocol.JT809MessageBody; | |||
using JT809.Protocol.JT809SubMessageBody; | |||
using JT809.Protocol.JT809Extensions; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Text; | |||
namespace JT809.Protocol.Benchmark | |||
{ | |||
[Config(typeof(JT809SerializerContextConfig))] | |||
[MarkdownExporter] | |||
[MemoryDiagnoser] | |||
public class JT809SerializerContext | |||
{ | |||
private byte[] bytes; | |||
[Params(100, 10000,100000)] | |||
public int N; | |||
[GlobalSetup] | |||
public void Setup() | |||
{ | |||
bytes = "5B 00 00 00 92 00 00 06 82 94 00 01 33 EF B8 01 00 00 00 00 00 27 0F D4 C1 41 31 32 33 34 35 00 00 00 00 00 00 00 00 00 00 00 00 00 02 94 01 00 00 00 5C 01 00 02 00 00 00 00 5A 01 AC 3F 40 12 3F FA A1 00 00 00 00 5A 01 AC 4D 50 03 73 6D 61 6C 6C 63 68 69 00 00 00 00 00 00 00 00 31 32 33 34 35 36 37 38 39 30 31 00 00 00 00 00 00 00 00 00 31 32 33 34 35 36 40 71 71 2E 63 6F 6D 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 BA D8 5D".ToHexBytes(); | |||
} | |||
[Benchmark(Description = "JT809_0x9400_0x9401_Package_Deserialize")] | |||
public void JT809_0x9400_0x9401_Package_Deserialize_Test() | |||
{ | |||
for (int i = 0; i < N; i++) | |||
{ | |||
var result = JT809Serializer.Deserialize(bytes); | |||
} | |||
} | |||
[Benchmark(Description = "JT809_0x9400_0x9401_Package_Serialize")] | |||
public void JT809_0x9400_0x9401_Package_Serialize_Test() | |||
{ | |||
for (int i = 0; i < N; i++) | |||
{ | |||
JT809Package jT809Package = new JT809Package(); | |||
jT809Package.Header = new JT809Header | |||
{ | |||
MsgSN = 1666, | |||
EncryptKey = 9999, | |||
EncryptFlag = JT809Header_Encrypt.None, | |||
Version = new JT809Header_Version(1, 0, 0), | |||
MsgID = JT809Enums.JT809BusinessType.DOWN_WARN_MSG, | |||
MsgGNSSCENTERID = 20180920, | |||
}; | |||
jT809Package.Bodies = new JT809_0x9400 | |||
{ | |||
VehicleNo = "粤A12345", | |||
VehicleColor = JT809Enums.JT809VehicleColorType.黄色, | |||
SubBusinessType = JT809Enums.JT809SubBusinessType.DOWN_WARN_MSG_URGE_TODO_REQ, | |||
}; | |||
JT809_0x9400_0x9401 jT809_0x9400_0x9401 = new JT809_0x9400_0x9401 | |||
{ | |||
WarnSrc = JT809WarnSrc.车载终端, | |||
WarnType = JT809WarnType.疲劳驾驶报警, | |||
WarnTime = DateTime.Parse("2018-09-27 10:24:00"), | |||
SupervisionID = "123FFAA1", | |||
SupervisionEndTime = DateTime.Parse("2018-09-27 11:24:00"), | |||
SupervisionLevel = 3, | |||
Supervisor = "smallchi", | |||
SupervisorTel = "12345678901", | |||
SupervisorEmail = "123456@qq.com" | |||
}; | |||
jT809Package.Bodies.JT809SubBodies = jT809_0x9400_0x9401; | |||
var hex = JT809Serializer.Serialize(jT809Package); | |||
} | |||
} | |||
} | |||
public class JT809SerializerContextConfig : ManualConfig | |||
{ | |||
public JT809SerializerContextConfig() | |||
{ | |||
Add(Job.Default.WithGcServer(true).With(Runtime.Clr).With(Platform.AnyCpu)); | |||
Add(Job.Default.WithGcServer(true).With(CsProjCoreToolchain.NetCoreApp21).With(Platform.AnyCpu)); | |||
} | |||
} | |||
} |
@@ -0,0 +1,20 @@ | |||
using BenchmarkDotNet.Attributes; | |||
using BenchmarkDotNet.Configs; | |||
using BenchmarkDotNet.Environments; | |||
using BenchmarkDotNet.Exporters; | |||
using BenchmarkDotNet.Jobs; | |||
using BenchmarkDotNet.Reports; | |||
using BenchmarkDotNet.Running; | |||
using BenchmarkDotNet.Toolchains.CsProj; | |||
using System; | |||
namespace JT809.Protocol.Benchmark | |||
{ | |||
class Program | |||
{ | |||
static void Main(string[] args) | |||
{ | |||
Summary summary = BenchmarkRunner.Run<JT809SerializerContext>(); | |||
} | |||
} | |||
} |
@@ -7,6 +7,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT809.Protocol", "JT809.Pro | |||
EndProject | |||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT809.Protocol.Test", "JT809.Protocol.Test\JT809.Protocol.Test.csproj", "{59D2D876-8D81-4CCE-839A-B153912C0C27}" | |||
EndProject | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JT809.Protocol.Benchmark", "JT809.Protocol.Benchmark\JT809.Protocol.Benchmark.csproj", "{47CE50B3-A0D6-4F5F-907B-01BD7B8AB87F}" | |||
EndProject | |||
Global | |||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | |||
Debug|Any CPU = Debug|Any CPU | |||
@@ -21,6 +23,10 @@ Global | |||
{59D2D876-8D81-4CCE-839A-B153912C0C27}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||
{59D2D876-8D81-4CCE-839A-B153912C0C27}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||
{59D2D876-8D81-4CCE-839A-B153912C0C27}.Release|Any CPU.Build.0 = Release|Any CPU | |||
{47CE50B3-A0D6-4F5F-907B-01BD7B8AB87F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||
{47CE50B3-A0D6-4F5F-907B-01BD7B8AB87F}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||
{47CE50B3-A0D6-4F5F-907B-01BD7B8AB87F}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||
{47CE50B3-A0D6-4F5F-907B-01BD7B8AB87F}.Release|Any CPU.Build.0 = Release|Any CPU | |||
EndGlobalSection | |||
GlobalSection(SolutionProperties) = preSolution | |||
HideSolutionNode = FALSE | |||
@@ -3,21 +3,29 @@ | |||
<PropertyGroup> | |||
<TargetFramework>netstandard2.0</TargetFramework> | |||
<LangVersion>latest</LangVersion> | |||
<Copyright>Copyright 2016-2018.</Copyright> | |||
<Copyright>Copyright 2018.</Copyright> | |||
<Authors>SmallChi</Authors> | |||
<PackageId>JT809</PackageId> | |||
<Product>JT809</Product> | |||
<Description>JT809</Description> | |||
<PackageReleaseNotes>JT809</PackageReleaseNotes> | |||
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance> | |||
<Description>JT809协议、GB809协议、道路运输车辆卫星定位系统平台数据交换</Description> | |||
<PackageReleaseNotes>JT809协议、GB809协议、道路运输车辆卫星定位系统平台数据交换</PackageReleaseNotes> | |||
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance> | |||
<RepositoryUrl>https://github.com/SmallChi/JT809</RepositoryUrl> | |||
<PackageProjectUrl>https://github.com/SmallChi/JT809</PackageProjectUrl> | |||
<PackageLicenseUrl>https://github.com/SmallChi/JT809/blob/master/LICENSE</PackageLicenseUrl> | |||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild> | |||
</PropertyGroup> | |||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'"> | |||
<DocumentationFile>bin\Release\netstandard2.0\JT809.Protocol.xml</DocumentationFile> | |||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> | |||
<NoWarn>1701;1702;1591</NoWarn> | |||
</PropertyGroup> | |||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> | |||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> | |||
<DocumentationFile>E:\koike\My Project\JT809\src\JT809.Protocol\JT809.Protocol.xml</DocumentationFile> | |||
<NoWarn>1701;1702;1591</NoWarn> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
@@ -9,7 +9,6 @@ namespace JT809.Protocol.JT809Extensions | |||
/// <summary> | |||
/// 从数据头到校验码前的 CRC 1 G-CCITT 的校验值,遵循人端排序方式的规定。 | |||
/// </summary> | |||
/// <param name="packege"></param> | |||
/// <param name="ucbuf"></param> | |||
/// <param name="offset"></param> | |||
/// <param name="iLen"></param> | |||
@@ -27,7 +26,6 @@ namespace JT809.Protocol.JT809Extensions | |||
/// <summary> | |||
/// 从数据头到校验码前的 CRC 1 G-CCITT 的校验值,遵循人端排序方式的规定。 | |||
/// </summary> | |||
/// <param name="packege"></param> | |||
/// <param name="ucbuf"></param> | |||
/// <param name="offset"></param> | |||
/// <param name="iLen"></param> | |||
@@ -89,7 +89,7 @@ namespace JT809.Protocol.JT809Extensions | |||
/// <summary> | |||
/// 获取DescriptionAttribute特性枚举及描述 | |||
/// </summary> | |||
/// <param name="type"></param> | |||
/// <param name="value"></param> | |||
/// <returns></returns> | |||
public static Dictionary<string, string> GetDescriptionAttributeDictionary(this Enum value) | |||
{ | |||
@@ -106,7 +106,7 @@ namespace JT809.Protocol.JT809Extensions | |||
/// <summary> | |||
/// 获取DisplayNameAttribute特性枚举值的描述 | |||
/// </summary> | |||
/// <param name="obj">枚举值</param> | |||
/// <param name="value">枚举值</param> | |||
/// <returns></returns> | |||
public static string GetDisplayName(this Enum value) | |||
{ | |||
@@ -117,7 +117,7 @@ namespace JT809.Protocol.JT809Extensions | |||
/// <summary> | |||
/// 获取DisplayNameAttribute特性枚举及描述 | |||
/// </summary> | |||
/// <param name="type"></param> | |||
/// <param name="value"></param> | |||
/// <returns></returns> | |||
public static Dictionary<string, string> GetDisplayNameAttributeDictionary(this Enum value) | |||
{ | |||
@@ -7,7 +7,8 @@ using System.Text; | |||
namespace JT809.Protocol.JT809Extensions | |||
{ | |||
/// <summary> | |||
/// <see cref="https://www.codeproject.com/tips/447938/high-performance-csharp-byte-array-to-hex-string-t"/> | |||
/// | |||
/// ref:"www.codeproject.com/tips/447938/high-performance-csharp-byte-array-to-hex-string-t" | |||
/// </summary> | |||
public static partial class JT809BinaryExtensions | |||
{ | |||
@@ -20,7 +20,7 @@ namespace JT809.Protocol.JT809SubMessageBody | |||
public class JT809_0x1200_0x1203 : JT809SubBodies | |||
{ | |||
/// <summary> | |||
/// 卫星定位数据个数 1<=GNSS_CNT<=5。 | |||
/// 卫星定位数据个数 1大于GNSS_CNT小于5 | |||
/// </summary> | |||
public byte GNSSCount { get; set; } | |||
/// <summary> | |||
@@ -15,7 +15,7 @@ namespace JT809.Protocol.JT809SubMessageBody | |||
public class JT809_0x9200_0x9203:JT809SubBodies | |||
{ | |||
/// <summary> | |||
/// 卫星定位数据个数 1<=GNSS_CNT<=5。 | |||
/// 卫星定位数据个数 1大于GNSS_CNT小于5 | |||
/// </summary> | |||
public byte GNSSCount { get; set; } | |||
/// <summary> | |||