From f9de94d6234a3b5848af593310c343bc4c643519 Mon Sep 17 00:00:00 2001 From: yedajiang44 <602830483@qq.com> Date: Wed, 19 Apr 2023 22:34:04 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=87=AA=E5=8A=A8=E5=90=88?= =?UTF-8?q?=E5=B9=B6=E5=88=86=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 581 +++++++++--------- .../JT808SerializerTest.cs | 35 +- .../Interfaces/GlobalConfigBase.cs | 11 +- src/JT808.Protocol/Interfaces/IJT808Config.cs | 16 +- src/JT808.Protocol/Interfaces/IMerger.cs | 18 + src/JT808.Protocol/Internal/DefaultMerger.cs | 62 ++ src/JT808.Protocol/JT808.Protocol.xml | 149 +++-- src/JT808.Protocol/JT808Package.cs | 23 +- src/JT808.Protocol/JT808Serializer.cs | 9 +- 9 files changed, 533 insertions(+), 371 deletions(-) create mode 100644 src/JT808.Protocol/Interfaces/IMerger.cs create mode 100644 src/JT808.Protocol/Internal/DefaultMerger.cs diff --git a/README.md b/README.md index 57d8167..c1fee64 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# JT/T808协议 +# JT/T808 协议 [![MIT Licence](https://img.shields.io/github/license/mashape/apistatus.svg)](https://github.com/SmallChi/JT808/blob/master/LICENSE)![.NET Core](https://github.com/SmallChi/JT808/workflows/.NET%20Core/badge.svg?branch=master) @@ -10,55 +10,55 @@ ## 前提条件 1. 掌握进制转换:二进制转十六进制; -2. 掌握BCD编码、Hex编码; +2. 掌握 BCD 编码、Hex 编码; 3. 掌握各种位移、异或; 4. 掌握常用反射; -5. 掌握JObject的用法; -6. 掌握快速ctrl+c、ctrl+v; -7. 掌握Span\的基本用法 +5. 掌握 JObject 的用法; +6. 掌握快速 ctrl+c、ctrl+v; +7. 掌握 Span\的基本用法 8. 掌握以上装逼技能,就可以开始搬砖了。 -## JT808数据结构解析 +## JT808 数据结构解析 ### 数据包[JT808Package] -| 头标识 | 数据头 | 数据体/分包数据体 | 校验码 | 尾标识 | -| :----: | :---------: | :---------: | :----------: | :----: | -| Begin | JT808Header | JT808Bodies/JT808SubDataBodies |CheckCode | End | -| 7E | - | - | - | 7E | +| 头标识 | 数据头 | 数据体/分包数据体 | 校验码 | 尾标识 | +| :----: | :---------: | :----------------------------: | :-------: | :----: | +| Begin | JT808Header | JT808Bodies/JT808SubDataBodies | CheckCode | End | +| 7E | - | - | - | 7E | ### 数据头[JT808Header] -| 消息ID | 消息体属性 | 协议版本号(2019版本)|终端手机号 | 消息流水号 | 消息总包数(依赖是否分包) | 包序号(依赖是否分包) | -| :----: | :----------------------------: | :-------------: |:-------------: | :--------: |:---------: | :-------:| -| MsgId | JT808HeaderMessageBodyProperty | ProtocolVersion|TerminalPhoneNo | MsgNum |PackgeCount | PackageIndex | +| 消息 ID | 消息体属性 | 协议版本号(2019 版本) | 终端手机号 | 消息流水号 | 消息总包数(依赖是否分包) | 包序号(依赖是否分包) | +| :-----: | :----------------------------: | :-------------------: | :-------------: | :--------: | :----------------------: | :------------------: | +| MsgId | JT808HeaderMessageBodyProperty | ProtocolVersion | TerminalPhoneNo | MsgNum | PackgeCount | PackageIndex | #### 数据头-消息体属性[JT808HeaderMessageBodyProperty] -|版本标识(2019版本)| 是否分包 | 加密标识 | 消息体长度 | -|:------:| :------: | :------: | :--------: | -|VersionFlag| IsPackge | Encrypt | DataLength | +| 版本标识(2019 版本) | 是否分包 | 加密标识 | 消息体长度 | +| :-----------------: | :------: | :------: | :--------: | +| VersionFlag | IsPackge | Encrypt | DataLength | #### 消息体属性[JT808Bodies] -> 根据对应消息ID:MsgId +> 根据对应消息 ID:MsgId -***注意:数据内容(除去头和尾标识)进行转义判断*** +**_注意:数据内容(除去头和尾标识)进行转义判断_** 转义规则如下: 1. 若数据内容中有出现字符 0x7e 的,需替换为字符 0x7d 紧跟字符 0x02; 2. 若数据内容中有出现字符 0x7d 的,需替换为字符 0x7d 紧跟字符 0x01; -反转义的原因:确认JT808协议的TCP消息边界。 +反转义的原因:确认 JT808 协议的 TCP 消息边界。 -### 举个栗子1 +### 举个栗子 1 #### 1.组包: > MsgId 0x0200:位置信息汇报 -``` csharp +```csharp JT808Package jT808Package = new JT808Package(); @@ -102,7 +102,7 @@ var hex = data.ToHexString(); #### 2.手动解包: -``` text +```text 1.原包: 7E 02 00 00 26 12 34 56 78 90 12 00 (7D 02) 00 00 00 01 00 00 00 02 00 BA 7F 0E 07 E4 F1 1C 00 28 00 3C 00 00 18 10 15 10 10 10 01 04 00 00 00 64 02 02 00 (7D 01) 13 7E @@ -138,7 +138,7 @@ var hex = data.ToHexString(); #### 3.程序解包: -``` csharp +```csharp //1.转成byte数组 byte[] bytes = "7E 02 00 00 26 12 34 56 78 90 12 00 7D 02 00 00 00 01 00 00 00 02 00 BA 7F 0E 07 E4 F1 1C 00 28 00 3C 00 00 18 10 15 10 10 10 01 04 00 00 00 64 02 02 00 7D 01 13 7E".ToHexBytes(); @@ -171,9 +171,9 @@ Assert.Equal(100, ((JT808_0x0200_0x01)jT808_0x0200.BasicLocationAttachData[JT808 Assert.Equal(125, ((JT808_0x0200_0x02)jT808_0x0200.BasicLocationAttachData[JT808Constants.JT808_0x0200_0x02]).Oil); ``` -### 举个栗子2 +### 举个栗子 2 -``` csharp +```csharp // 使用消息Id的扩展方法创建JT808Package包 JT808Package jT808Package = Enums.JT808MsgId._0x0200.Create("123456789012", new JT808_0x0200 { @@ -199,9 +199,9 @@ var hex = data.ToHexString(); //7E 02 00 00 26 12 34 56 78 90 12 00 01 00 00 00 01 00 00 00 02 00 BA 7F 0E 07 E4 F1 1C 00 28 00 3C 00 00 18 10 15 10 10 10 01 04 00 00 00 64 02 02 00 7D 01 6C 7E ``` -### 举个栗子3 +### 举个栗子 3 -``` csharp +```csharp // 初始化配置 IJT808Config DT1JT808Config = new DT1Config(); IJT808Config DT2JT808Config = new DT2Config(); @@ -219,174 +219,181 @@ JT808Serializer DT1JT808Serializer = new JT808Serializer(DT1JT808Config); JT808Serializer DT2JT808Serializer = new JT808Serializer(DT2JT808Config); ``` -[可以参考Simples的Demo6](https://github.com/SmallChi/JT808/blob/master/src/JT808.Protocol.Test/Simples/Demo6.cs) +[可以参考 Simples 的 Demo6](https://github.com/SmallChi/JT808/blob/master/src/JT808.Protocol.Test/Simples/Demo6.cs) -### 举个栗子4 +### 举个栗子 4 #### 遇到的问题-多设备多协议的自定义位置附加信息 场景: -一个设备厂商对应多个设备类型,不同设备类型可能存在相同的自定义位置附加信息Id,导致自定义附加信息Id冲突,无法解析。 +一个设备厂商对应多个设备类型,不同设备类型可能存在相同的自定义位置附加信息 Id,导致自定义附加信息 Id 冲突,无法解析。 -***解决方式:*** +**_解决方式:_** 1.可以根据设备类型做个工厂,解耦对公共序列化器的依赖。 -2.可以根据设备类型去实现(GlobalConfigBase)对应的配置,根据不同的GlobalConfigBase实例去绑定对应协议解析器。 +2.可以根据设备类型去实现(GlobalConfigBase)对应的配置,根据不同的 GlobalConfigBase 实例去绑定对应协议解析器。 -[可以参考Simples的Demo4](https://github.com/SmallChi/JT808/blob/master/src/JT808.Protocol.Test/Simples/Demo4.cs) +[可以参考 Simples 的 Demo4](https://github.com/SmallChi/JT808/blob/master/src/JT808.Protocol.Test/Simples/Demo4.cs) -[可以参考Simples的Demo6](https://github.com/SmallChi/JT808/blob/master/src/JT808.Protocol.Test/Simples/Demo6.cs) +[可以参考 Simples 的 Demo6](https://github.com/SmallChi/JT808/blob/master/src/JT808.Protocol.Test/Simples/Demo6.cs) > 要是哪位大佬还有其他的解决方式,请您告知我下,谢谢您了。 -### 举个栗子5 +### 举个栗子 5 #### 遇到的问题-多媒体数据上传进行分包处理 场景: 设备在上传多媒体数据的时候,由于数据比较多,一次上传不了,所以采用分包方式处理。 -***解决方式:*** +**_解决方式:_** 1. 第一包数据上来采用平常的方式去解析数据; 2. 当第二包上来跟第一包的分包数据体(SubDataBodies)进行合并 -3. 当N包数据上来,延续步骤2的方式。 +3. 当 N 包数据上来,延续步骤 2 的方式。 -> 普及知识点1:由于消息体长度最大为10bit也就是1023的字节,所以这边就有个硬性条件不能超过最大长度。 +> 普及知识点 1:由于消息体长度最大为 10bit 也就是 1023 的字节,所以这边就有个硬性条件不能超过最大长度。 -> 普及知识点2:一般行业分包是按256的整数倍,太多不行,太少也不行,必须刚刚好。 +> 普及知识点 2:一般行业分包是按 256 的整数倍,太多不行,太少也不行,必须刚刚好。 -[可以参考Simples的Demo5](https://github.com/SmallChi/JT808/blob/master/src/JT808.Protocol.Test/Simples/Demo5.cs) +[可以参考 Simples 的 Demo5](https://github.com/SmallChi/JT808/blob/master/src/JT808.Protocol.Test/Simples/Demo5.cs) -### 举个栗子6 +### 举个栗子 6 -#### 遇到的问题-多设备多协议的消息ID冲突 +#### 遇到的问题-多设备多协议的消息 ID 冲突 场景: -由于每个设备厂商不同,导致设备的私有协议可能使用相同的消息ID作为指令,导致平台解析不了。 +由于每个设备厂商不同,导致设备的私有协议可能使用相同的消息 ID 作为指令,导致平台解析不了。 -***解决方式:*** +**_解决方式:_** -可以根据设备类型去实现(GlobalConfigBase)对应的配置,根据不同的GlobalConfigBase实例去绑定对应协议解析器。 +可以根据设备类型去实现(GlobalConfigBase)对应的配置,根据不同的 GlobalConfigBase 实例去绑定对应协议解析器。 -[可以参考Simples的Demo6](https://github.com/SmallChi/JT808/blob/master/src/JT808.Protocol.Test/Simples/Demo6.cs) +[可以参考 Simples 的 Demo6](https://github.com/SmallChi/JT808/blob/master/src/JT808.Protocol.Test/Simples/Demo6.cs) -### 举个栗子7 +### 举个栗子 7 -如何兼容2019版本 +如何兼容 2019 版本 -> 最新协议文档已经写好了如何做兼容,就是在消息体属性中第14位为版本标识。 +> 最新协议文档已经写好了如何做兼容,就是在消息体属性中第 14 位为版本标识。 -1. 当第14位为0时,标识协议为2011年的版本; +1. 当第 14 位为 0 时,标识协议为 2011 年的版本; -2. 当第14位为1时,标识协议为2019年的版本。 +2. 当第 14 位为 1 时,标识协议为 2019 年的版本。 -[可以参考Simples的Demo7](https://github.com/SmallChi/JT808/blob/master/src/JT808.Protocol.Test/Simples/Demo7.cs) +[可以参考 Simples 的 Demo7](https://github.com/SmallChi/JT808/blob/master/src/JT808.Protocol.Test/Simples/Demo7.cs) -### 举个栗子8 +### 举个栗子 8 -协议分析器在数据出现异常和纠错的时候也是挺有用的,总不能凭借24K氪金眼去观察数据,那么可以在开发协议的同时就把协议分析器给写好,这样方便技术或者技术支持排查问题,提高效率。 +协议分析器在数据出现异常和纠错的时候也是挺有用的,总不能凭借 24K 氪金眼去观察数据,那么可以在开发协议的同时就把协议分析器给写好,这样方便技术或者技术支持排查问题,提高效率。 -[可以参考Simples的Demo8](https://github.com/SmallChi/JT808/blob/master/src/JT808.Protocol.Test/Simples/Demo8.cs) +[可以参考 Simples 的 Demo8](https://github.com/SmallChi/JT808/blob/master/src/JT808.Protocol.Test/Simples/Demo8.cs) -### 举个栗子9 +### 举个栗子 9 -增加行车记录仪序列化器,既可以单独的存在,也可以组装在808的数据包当中。 +增加行车记录仪序列化器,既可以单独的存在,也可以组装在 808 的数据包当中。 -[可以参考Simples的Demo9](https://github.com/SmallChi/JT808/blob/master/src/JT808.Protocol.Test/Simples/Demo9.cs) +[可以参考 Simples 的 Demo9](https://github.com/SmallChi/JT808/blob/master/src/JT808.Protocol.Test/Simples/Demo9.cs) -### 举个栗子10 +### 举个栗子 10 -场景1: -有些设备,不会按照国标的附加信息Id来搞,把附加信息Id搞为两个字节,这样在上报上来的数据就会存在重复的附加Id,导致平台解析出错。 +场景 1: +有些设备,不会按照国标的附加信息 Id 来搞,把附加信息 Id 搞为两个字节,这样在上报上来的数据就会存在重复的附加 Id,导致平台解析出错。 -场景2: -由于粤标的设备厂家自定义的附加信息长度可以为四4个字节的,所以需要兼容。 +场景 2: +由于粤标的设备厂家自定义的附加信息长度可以为四 4 个字节的,所以需要兼容。 -场景3: -有些设备上报会出现两个相同的附加信息Id,那么只能解析一个,另一个只能丢在异常附加信息里面去处理。 +场景 3: +有些设备上报会出现两个相同的附加信息 Id,那么只能解析一个,另一个只能丢在异常附加信息里面去处理。 -|附加信息类说明| 附加ID字节数 | 附加长度字节数 | 备注 | -| :--- | :---: | :---: | :---:| -| JT808_0x0200_CustomBodyBase | 1 BYTE | 1 BYTE | 标准| -| JT808_0x0200_CustomBodyBase2 | 2 BYTE | 1 BYTE | 自定义| -| JT808_0x0200_CustomBodyBase3 | 2 BYTE | 2 BYTE | 自定义| -| JT808_0x0200_CustomBodyBase4 | 1 BYTE | 4 BYTE | 自定义| +| 附加信息类说明 | 附加 ID 字节数 | 附加长度字节数 | 备注 | +| :--------------------------- | :------------: | :------------: | :----: | +| JT808_0x0200_CustomBodyBase | 1 BYTE | 1 BYTE | 标准 | +| JT808_0x0200_CustomBodyBase2 | 2 BYTE | 1 BYTE | 自定义 | +| JT808_0x0200_CustomBodyBase3 | 2 BYTE | 2 BYTE | 自定义 | +| JT808_0x0200_CustomBodyBase4 | 1 BYTE | 4 BYTE | 自定义 | -[可以参考Simples的Demo10](https://github.com/SmallChi/JT808/blob/master/src/JT808.Protocol.Test/Simples/Demo10.cs) +[可以参考 Simples 的 Demo10](https://github.com/SmallChi/JT808/blob/master/src/JT808.Protocol.Test/Simples/Demo10.cs) ->注意:默认都是以**标准**的去解析,要是出现未知的附加,不一定解析就是正确,最好还是需要依照协议文档去开发然后自行注册解析器去解析。 +> 注意:默认都是以**标准**的去解析,要是出现未知的附加,不一定解析就是正确,最好还是需要依照协议文档去开发然后自行注册解析器去解析。 -### 举个栗子11 +### 举个栗子 11 场景: 有些设备,补报的定位数据有异常数据包内容长度跟原始的内容长度不一致导致整包的数据的解析出错,再设备不升级,改不了的情况下,尽量能解析多少补报的数据量,就解析多少。 -[可以参考Simples的Demo11](https://github.com/SmallChi/JT808/blob/master/src/JT808.Protocol.Test/Simples/Demo11.cs) +[可以参考 Simples 的 Demo11](https://github.com/SmallChi/JT808/blob/master/src/JT808.Protocol.Test/Simples/Demo11.cs) -### 举个栗子12 +### 举个栗子 12 场景: -由于粤标的设备把2019版本的0x8105终端控制消息命令参数做了扩展,所以需要兼容。 +由于粤标的设备把 2019 版本的 0x8105 终端控制消息命令参数做了扩展,所以需要兼容。 -[可以参考Simples的Demo12](https://github.com/SmallChi/JT808/blob/master/src/JT808.Protocol.Test/Simples/Demo12.cs) +[可以参考 Simples 的 Demo12](https://github.com/SmallChi/JT808/blob/master/src/JT808.Protocol.Test/Simples/Demo12.cs) -### 举个栗子13 +### 举个栗子 13 场景: -由于协议库本身可能存在消息解析出错的情况,要么就提PR上来,但是不一定会及时发布,这时候就需要自己把原有的消息解析复制出来,改造好,然后重新注册。 +由于协议库本身可能存在消息解析出错的情况,要么就提 PR 上来,但是不一定会及时发布,这时候就需要自己把原有的消息解析复制出来,改造好,然后重新注册。 -[可以参考Simples的Demo13](https://github.com/SmallChi/JT808/blob/master/src/JT808.Protocol.Test/Simples/Demo13.cs) +[可以参考 Simples 的 Demo13](https://github.com/SmallChi/JT808/blob/master/src/JT808.Protocol.Test/Simples/Demo13.cs) -### 举个栗子14 +### 举个栗子 14 场景: -由于某些厂商不按要求去做,明明使用的2013的协议但是在消息头部的版本标识位置为1,导致程序认为是2019协议。从而解析报错。此时可以强制解析成2013后,然后修正版本标识,重新序列化消息,以供下游服务使用 +由于某些厂商不按要求去做,明明使用的 2013 的协议但是在消息头部的版本标识位置为 1,导致程序认为是 2019 协议。从而解析报错。此时可以强制解析成 2013 后,然后修正版本标识,重新序列化消息,以供下游服务使用 -[可以参考Simples的Demo14](https://github.com/SmallChi/JT808/blob/master/src/JT808.Protocol.Test/Simples/Demo14.cs) +[可以参考 Simples 的 Demo14](https://github.com/SmallChi/JT808/blob/master/src/JT808.Protocol.Test/Simples/Demo14.cs) -### 举个栗子15 +### 举个栗子 15 场景: -兼容2011协议的注册消息 +兼容 2011 协议的注册消息 -[可以参考Simples的Demo15](https://github.com/SmallChi/JT808/blob/master/src/JT808.Protocol.Test/Simples/Demo15.cs) +[可以参考 Simples 的 Demo15](https://github.com/SmallChi/JT808/blob/master/src/JT808.Protocol.Test/Simples/Demo15.cs) -### 举个栗子16 +### 举个栗子 16 场景: 平台下发分包数据到设备 -可以参考【举个栗子5】中,设备上来的分包数据结构,然后举一反三的去实现。 +可以参考【举个栗子 5】中,设备上来的分包数据结构,然后举一反三的去实现。 -### 举个栗子17 +### 举个栗子 17 场景: -由于808的0x0200标准协议的附加数据是有明确的表示对部分附加信息Id进行保留的,所以按照标准,有些设备厂商把标准的附加信息Id占用,所以需要解析这部分的数据,可以参考外部自定义附加信息注册的方式来解决解析问题。 +由于 808 的 0x0200 标准协议的附加数据是有明确的表示对部分附加信息 Id 进行保留的,所以按照标准,有些设备厂商把标准的附加信息 Id 占用,所以需要解析这部分的数据,可以参考外部自定义附加信息注册的方式来解决解析问题。 -可以参考[举个栗子10](https://github.com/SmallChi/JT808/blob/master/src/JT808.Protocol.Test/Simples/Demo10.cs)中的程序。 +可以参考[举个栗子 10](https://github.com/SmallChi/JT808/blob/master/src/JT808.Protocol.Test/Simples/Demo10.cs)中的程序。 -### 举个栗子18 +### 举个栗子 18 场景: -由于接入很多不同设备厂商的协议,但是每个协议对接又比较少,想同时放在一个类库下面进行统一管理,那么在各个厂家不冲突的情况下使用程序集方式的注册是没有问题的,一旦有冲突,那么使用程序集的方式进行注册会报Id冲突,本身库不支持这种方式进行隔离的,所以遇到这种情况自己使用SetMap的方式进行管理。 +由于接入很多不同设备厂商的协议,但是每个协议对接又比较少,想同时放在一个类库下面进行统一管理,那么在各个厂家不冲突的情况下使用程序集方式的注册是没有问题的,一旦有冲突,那么使用程序集的方式进行注册会报 Id 冲突,本身库不支持这种方式进行隔离的,所以遇到这种情况自己使用 SetMap 的方式进行管理。 -## NuGet安装 +### 自动合并分包 -| Package Name| Version| Preview Version |Downloads|Remark| -| --- | --- | --- | ---| --- | -| Install-Package JT808 | ![JT808](https://img.shields.io/nuget/v/JT808.svg) | ![JT808](https://img.shields.io/nuget/vpre/JT808.svg)|![JT808](https://img.shields.io/nuget/dt/JT808.svg) |JT808| -| Install-Package JT808.Protocol.Extensions.JT1078 | ![JT808.Protocol.Extensions.JT1078](https://img.shields.io/nuget/v/JT808.Protocol.Extensions.JT1078.svg) | ![JT808.Protocol.Extensions.JT1078](https://img.shields.io/nuget/vpre/JT808.Protocol.Extensions.JT1078.svg)|![JT808](https://img.shields.io/nuget/dt/JT808.Protocol.Extensions.JT1078.svg) |JT1078扩展JT808| -| Install-Package JT808.Protocol.Extensions.SuBiao| ![JT808.Protocol.Extensions.SuBiao](https://img.shields.io/nuget/v/JT808.Protocol.Extensions.SuBiao.svg) | ![JT808.Protocol.Extensions.SuBiao](https://img.shields.io/nuget/vpre/JT808.Protocol.Extensions.SuBiao.svg)|![JT808](https://img.shields.io/nuget/dt/JT808.Protocol.Extensions.SuBiao.svg) |主动安全(苏标)扩展JT808| -| Install-Package JT808.Protocol.Extensions.YueBiao| ![JT808.Protocol.Extensions.YueBiao](https://img.shields.io/nuget/v/JT808.Protocol.Extensions.YueBiao.svg) | ![JT808.Protocol.Extensions.YueBiao](https://img.shields.io/nuget/vpre/JT808.Protocol.Extensions.YueBiao.svg)|![JT808](https://img.shields.io/nuget/dt/JT808.Protocol.Extensions.YueBiao.svg) |主动安全(粤标)扩展JT808| -| Install-Package JT808.Protocol.DependencyInjection| ![JT808.Protocol.DependencyInjection](https://img.shields.io/nuget/v/JT808.Protocol.DependencyInjection.svg) | ![JT808.Protocol.DependencyInjection](https://img.shields.io/nuget/vpre/JT808.Protocol.DependencyInjection.svg)|![JT808.Protocol.DependencyInjection](https://img.shields.io/nuget/dt/JT808.Protocol.DependencyInjection.svg) |JT808依赖注入扩展| +场景: +当数据体超过协议规定的 1023 个字节时,设备将会以分包的形式发送给服务,此时服务需要进行合并后才能正常解析 -## 使用BenchmarkDotNet性能测试报告(只是玩玩,不能当真) +可以参考单元测试的[JT808SerializerTest.MergerTest](src/JT808.Protocol.Test/JT808SerializerTest.cs#L52) -``` ini +## NuGet 安装 + +| Package Name | Version | Preview Version | Downloads | Remark | +| -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | -------------------------- | +| Install-Package JT808 | ![JT808](https://img.shields.io/nuget/v/JT808.svg) | ![JT808](https://img.shields.io/nuget/vpre/JT808.svg) | ![JT808](https://img.shields.io/nuget/dt/JT808.svg) | JT808 | +| Install-Package JT808.Protocol.Extensions.JT1078 | ![JT808.Protocol.Extensions.JT1078](https://img.shields.io/nuget/v/JT808.Protocol.Extensions.JT1078.svg) | ![JT808.Protocol.Extensions.JT1078](https://img.shields.io/nuget/vpre/JT808.Protocol.Extensions.JT1078.svg) | ![JT808](https://img.shields.io/nuget/dt/JT808.Protocol.Extensions.JT1078.svg) | JT1078 扩展 JT808 | +| Install-Package JT808.Protocol.Extensions.SuBiao | ![JT808.Protocol.Extensions.SuBiao](https://img.shields.io/nuget/v/JT808.Protocol.Extensions.SuBiao.svg) | ![JT808.Protocol.Extensions.SuBiao](https://img.shields.io/nuget/vpre/JT808.Protocol.Extensions.SuBiao.svg) | ![JT808](https://img.shields.io/nuget/dt/JT808.Protocol.Extensions.SuBiao.svg) | 主动安全(苏标)扩展 JT808 | +| Install-Package JT808.Protocol.Extensions.YueBiao | ![JT808.Protocol.Extensions.YueBiao](https://img.shields.io/nuget/v/JT808.Protocol.Extensions.YueBiao.svg) | ![JT808.Protocol.Extensions.YueBiao](https://img.shields.io/nuget/vpre/JT808.Protocol.Extensions.YueBiao.svg) | ![JT808](https://img.shields.io/nuget/dt/JT808.Protocol.Extensions.YueBiao.svg) | 主动安全(粤标)扩展 JT808 | +| Install-Package JT808.Protocol.DependencyInjection | ![JT808.Protocol.DependencyInjection](https://img.shields.io/nuget/v/JT808.Protocol.DependencyInjection.svg) | ![JT808.Protocol.DependencyInjection](https://img.shields.io/nuget/vpre/JT808.Protocol.DependencyInjection.svg) | ![JT808.Protocol.DependencyInjection](https://img.shields.io/nuget/dt/JT808.Protocol.DependencyInjection.svg) | JT808 依赖注入扩展 | + +## 使用 BenchmarkDotNet 性能测试报告(只是玩玩,不能当真) + +```ini BenchmarkDotNet=v0.13.2, OS=Windows 11 (10.0.22621.1105) Intel Core i7-8700K CPU 3.70GHz (Coffee Lake), 1 CPU, 12 logical and 6 physical cores @@ -394,141 +401,141 @@ Intel Core i7-8700K CPU 3.70GHz (Coffee Lake), 1 CPU, 12 logical and 6 physical [Host] : .NET 7.0.2 (7.0.222.60605), X64 RyuJIT AVX2 Job-OIKLWD : .NET 7.0.2 (7.0.222.60605), X64 RyuJIT AVX2 -Platform=AnyCpu Server=False Toolchain=.NET 7.0 +Platform=AnyCpu Server=False Toolchain=.NET 7.0 ``` -| Method | Categories | N | Mean | Error | StdDev | Gen0 | Gen1 | Allocated | -|-------------------------------- |----------------- |------- |--------------:|-------------:|-------------:|-----------:|---------:|-------------:| -| **0x0100Serialize** | **0x0100Serializer** | **100** | **75.25 μs** | **0.519 μs** | **0.433 μs** | **10.7422** | **-** | **66.41 KB** | -| 0x0100Deserialize | 0x0100Serializer | 100 | 66.56 μs | 0.412 μs | 0.385 μs | 15.7471 | - | 96.88 KB | -| **0x0100Serialize** | **0x0100Serializer** | **10000** | **7,581.60 μs** | **108.729 μs** | **101.705 μs** | **1078.1250** | **-** | **6640.63 KB** | -| 0x0100Deserialize | 0x0100Serializer | 10000 | 6,609.91 μs | 58.293 μs | 51.675 μs | 1578.1250 | - | 9687.5 KB | -| **0x0100Serialize** | **0x0100Serializer** | **100000** | **74,221.22 μs** | **514.498 μs** | **456.089 μs** | **10714.2857** | **-** | **66406.32 KB** | -| 0x0100Deserialize | 0x0100Serializer | 100000 | 65,918.35 μs | 173.702 μs | 162.481 μs | 15750.0000 | - | 96875.06 KB | -| | | | | | | | | | -| **0x0200_All_AttachId_Serialize** | **0x0200Serializer** | **100** | **133.71 μs** | **1.003 μs** | **0.889 μs** | **29.2969** | **-** | **180.47 KB** | -| 0x0200_All_AttachId_Deserialize | 0x0200Serializer | 100 | 137.71 μs | 1.125 μs | 0.997 μs | 38.0859 | 0.2441 | 234.38 KB | -| **0x0200_All_AttachId_Serialize** | **0x0200Serializer** | **10000** | **13,317.92 μs** | **82.257 μs** | **68.688 μs** | **2937.5000** | **-** | **18046.88 KB** | -| 0x0200_All_AttachId_Deserialize | 0x0200Serializer | 10000 | 14,040.86 μs | 242.740 μs | 227.060 μs | 3812.5000 | 15.6250 | 23437.51 KB | -| **0x0200_All_AttachId_Serialize** | **0x0200Serializer** | **100000** | **131,292.10 μs** | **871.653 μs** | **815.344 μs** | **29250.0000** | **-** | **180468.87 KB** | -| 0x0200_All_AttachId_Deserialize | 0x0200Serializer | 100000 | 137,063.75 μs | 1,301.430 μs | 1,086.753 μs | 38250.0000 | 250.0000 | 234375.12 KB | - - -## JT808终端通讯协议消息对照表 - -| 序号 | 消息ID | 完成情况 | 测试情况 | 消息体名称 |2019版本 | 2011版本 -| :---: | :-----------: | :------: | :------: | :---------------------------- |:----------------------------:|:----------------------------:| -| 1 | 0x0001 | √ | √ | 终端通用应答 | -| 2 | 0x8001 | √ | √ | 平台通用应答 | -| 3 | 0x0002 | √ | √ | 终端心跳 | -| 4 | 0x8003 | √ | √ | 补传分包请求 | |被新增| -| 5 | 0x0100 | √ | √ | 终端注册 |修改 |被修改 -| 6 | 0x8100 | √ | √ | 终端注册应答 | -| 7 | 0x0003 | √ | √ | 终端注销 | -| 8 | 0x0102 | √ | √ | 终端鉴权 |修改| -| 9 | 0x8103 | √ | √ | 设置终端参数 |修改且增加 |被修改 -| 10 | 0x8104 | √ | √ | 查询终端参数 | -| 11 | 0x0104 | √ | √ | 查询终端参数应答 | -| 12 | 0x8105 | √ | √ | 终端控制 | -| 13 | 0x8106 | √ | √ | 查询指定终端参数 | |被新增 -| 14 | 0x8107 | √ | 消息体为空| 查询终端属性 | |被新增 -| 15 | 0x0107 | √ | √ | 查询终端属性应答 | |被新增 -| 16 | 0x8108 | √ | √ | 下发终端升级包 | |被新增 -| 17 | 0x0108 | √ | √ | 终端升级结果通知 | |被新增 -| 18 | 0x0200 | √ | √ | 位置信息汇报 |增加附加信息 |被修改 -| 19 | 0x8201 | √ | √ | 位置信息查询 | -| 20 | 0x0201 | √ | √ | 位置信息查询应答 | -| 21 | 0x8202 | √ | √ | 临时位置跟踪控制 | -| 22 | 0x8203 | √ | √ | 人工确认报警消息 | |被新增 -| 23 | 0x8300 | √ | √ | 文本信息下发 |修改 |被修改 -| 24 | 0x8301 | √ | √ | 事件设置 |删除| -| 25 | 0x0301 | √ | √ | 事件报告 |删除| -| 26 | 0x8302 | √ | √ | 提问下发 |删除| -| 27 | 0x0302 | √ | √ | 提问应答 |删除| -| 28 | 0x8303 | √ | √ | 信息点播菜单设置 |删除| -| 29 | 0x0303 | √ | √ | 信息点播/取消 |删除| -| 30 | 0x8304 | √ | √ | 信息服务 |删除| -| 31 | 0x8400 | √ | √ | 电话回拨 | -| 32 | 0x8401 | √ | √ | 设置电话本 | -| 33 | 0x8500 | √ | √ | 车辆控制 |修改| -| 34 | 0x0500 | √ | √ | 车辆控制应答 | -| 35 | 0x8600 | √ | √ | 设置圆形区域 |修改 |被修改 -| 36 | 0x8601 | √ | √ | 删除圆形区域 | -| 37 | 0x8602 | √ | √ | 设置矩形区域 |修改| -| 38 | 0x8603 | √ | √ | 删除矩形区域 | -| 39 | 0x8604 | √ | √ | 设置多边形区域 |修改| -| 40 | 0x8605 | √ | √ | 删除多边形区域 | -| 41 | 0x8606 | √ | √ | 设置路线 |修改| -| 42 | 0x8607 | √ | √ | 删除路线 | -| 43 | 0x8700 | √ | √ | 行驶记录仪数据采集命令 | |被修改 -| 44 | 0x0700 | √ | √ | 行驶记录仪数据上传 | -| 45 | 0x8701 | √ | √ | 行驶记录仪参数下传命令 | |被修改 -| 46 | 0x0701 | √ | √ | 电子运单上报 | -| 47 | 0x0702 | √ | √ | 驾驶员身份信息采集上报 |修改 |被修改 -| 48 | 0x8702 | √ | 消息体为空| 上报驾驶员身份信息请求 | |被新增 -| 49 | 0x0704 | √ | √ | 定位数据批量上传 |修改| |被新增 -| 50 | 0x0705 | √ | √ | CAN 总线数据上传 |修改| |被新增 -| 51 | 0x0800 | √ | √ | 多媒体事件信息上传 | |被修改 -| 52 | 0x0801 | √ | √ | 多媒体数据上传 |修改 |被修改 -| 53 | 0x8800 | √ | √ | 多媒体数据上传应答 | |被修改 -| 54 | 0x8801 | √ | √ | 摄像头立即拍摄命令 |修改| -| 55 | 0x0805 | √ | √ | 摄像头立即拍摄命令应答 |修改| |被新增 -| 56 | 0x8802 | √ | √ | 存储多媒体数据检索 | -| 57 | 0x0802 | √ | √ | 存储多媒体数据检索应答 | |被修改 -| 58 | 0x8803 | √ | √ | 存储多媒体数据上传 | -| 59 | 0x8804 | √ | √ | 录音开始命令 | -| 60 | 0x8805 | √ | √ | 单条存储多媒体数据检索上传命令 |修改| |被新增 -| 61 | 0x8900 | √ | √ | 数据下行透传 |修改 |被修改 -| 62 | 0x0900 | √ | √ | 数据上行透传 |修改 |被修改 -| 63 | 0x0901 | √ | √ | 数据压缩上报 | -| 64 | 0x8A00 | √ | √ | 平台 RSA 公钥 | -| 65 | 0x0A00 | √ | √ | 终端 RSA 公钥 | -| 66 | 0x8F00~0x8FFF | 保留 | 保留 | 平台下行消息保留 | -| 67 | 0x0F00~0x0FFF | 保留 | 保留 | 终端上行消息保留 | -| 68 | 0x0004 | √ | √ | 查询服务器时间请求 |新增| -| 69 | 0x8004 | √ | √ | 查询服务器时间应答 |新增| -| 70 | 0x0005 | √ | √ | 终端补传分包请求 |新增| -| 71 | 0x8204 | √ | √ | 链路检测 |新增| -| 72 | 0x8608 | √ | √ | 查询区域或线路数据 |新增| -| 73 | 0x0608 | √ | √ | 查询区域或线路数据应答 |新增| -| 74 | 0xE000~0xEFFF | 保留 | 保留 | 厂商自定义上行消息 |新增| -| 75 | 0xF000~0xFFFF | 保留 | 保留 | 厂商自定义下行消息 |新增| - -## JT1078扩展JT808议消息对照表 - -| 序号 | 消息ID | 完成情况 | 测试情况 | 消息体名称 | -| :---: | :-----------: | :------: | :------: | :---------------------------- | -| 1 | 0x0200_0x14 | √ | √ | 视频相关报警 | -| 2 | 0x0200_0x15 | √ | √ | 视频信号丢失报警状态 | -| 3 | 0x0200_0x16 | √ | √ | 视频信号遮挡报警状态 | -| 4 | 0x0200_0x17 | √ | √ | 存储器故障报警状态 | -| 5 | 0x0200_0x18 | √ | √ | 异常驾驶行为报警详细描述 | -| 6 | 0x8103_0x0075 | √ | √ | 音视频参数设置 | -| 7 | 0x8103_0x0076 | √ | √ | 音视频通道列表设置 | -| 8 | 0x8103_0x0077 | √ | √ | 单独视频通道参数设置 | -| 9 | 0x8103_0x0079 | √ | √ | 特殊报警录像参数设置 | -| 10 | 0x8103_0x007A | √ | √ | 视频相关报警屏蔽字 | -| 11 | 0x8103_0x007B | √ | √ | 图像分析报警参数设置 | -| 12 | 0x8103_0x007C | √ | √ | 终端休眠模式唤醒设置 | -| 13 | 0x1003 | √ | √ | 终端上传音视频属性 | -| 14 | 0x1005 | √ | √ | 终端上传乘客流量 | -| 15 | 0x1205 | √ | √ | 终端上传音视频资源列表 | -| 16 | 0x1206 | √ | √ | 文件上传完成通知 | -| 17 | 0x9003 | √ | √ | 查询终端音视频属性 | -| 18 | 0x9101 | √ | √ | 实时音视频传输请求 | -| 19 | 0x9102 | √ | √ | 音视频实时传输控制 | -| 20 | 0x9105 | √ | √ | 实时音视频传输状态通知 | -| 21 | 0x9201 | √ | √ | 平台下发远程录像回放请求 | -| 22 | 0x9202 | √ | √ | 平台下发远程录像回放控制 | -| 23 | 0x9205 | √ | √ | 查询资源列表 | -| 24 | 0x9206 | √ | √ | 文件上传指令 | -| 25 | 0x9207 | √ | √ | 文件上传控制 | -| 26 | 0x9301 | √ | √ | 云台旋转 | -| 27 | 0x9302 | √ | √ | 云台调整焦距控制 | -| 28 | 0x9303 | √ | √ | 云台调整光圈控制 | -| 29 | 0x9304 | √ | √ | 云台雨刷控制 | -| 30 | 0x9305 | √ | √ | 红外补光控制 | -| 31 | 0x9306 | √ | √ | 云台变倍控制 | + +| Method | Categories | N | Mean | Error | StdDev | Gen0 | Gen1 | Allocated | +| --------------------------------- | -------------------- | ---------- | ----------------: | -------------: | -------------: | -------------: | -------: | ---------------: | +| **0x0100Serialize** | **0x0100Serializer** | **100** | **75.25 μs** | **0.519 μs** | **0.433 μs** | **10.7422** | **-** | **66.41 KB** | +| 0x0100Deserialize | 0x0100Serializer | 100 | 66.56 μs | 0.412 μs | 0.385 μs | 15.7471 | - | 96.88 KB | +| **0x0100Serialize** | **0x0100Serializer** | **10000** | **7,581.60 μs** | **108.729 μs** | **101.705 μs** | **1078.1250** | **-** | **6640.63 KB** | +| 0x0100Deserialize | 0x0100Serializer | 10000 | 6,609.91 μs | 58.293 μs | 51.675 μs | 1578.1250 | - | 9687.5 KB | +| **0x0100Serialize** | **0x0100Serializer** | **100000** | **74,221.22 μs** | **514.498 μs** | **456.089 μs** | **10714.2857** | **-** | **66406.32 KB** | +| 0x0100Deserialize | 0x0100Serializer | 100000 | 65,918.35 μs | 173.702 μs | 162.481 μs | 15750.0000 | - | 96875.06 KB | +| | | | | | | | | | +| **0x0200_All_AttachId_Serialize** | **0x0200Serializer** | **100** | **133.71 μs** | **1.003 μs** | **0.889 μs** | **29.2969** | **-** | **180.47 KB** | +| 0x0200_All_AttachId_Deserialize | 0x0200Serializer | 100 | 137.71 μs | 1.125 μs | 0.997 μs | 38.0859 | 0.2441 | 234.38 KB | +| **0x0200_All_AttachId_Serialize** | **0x0200Serializer** | **10000** | **13,317.92 μs** | **82.257 μs** | **68.688 μs** | **2937.5000** | **-** | **18046.88 KB** | +| 0x0200_All_AttachId_Deserialize | 0x0200Serializer | 10000 | 14,040.86 μs | 242.740 μs | 227.060 μs | 3812.5000 | 15.6250 | 23437.51 KB | +| **0x0200_All_AttachId_Serialize** | **0x0200Serializer** | **100000** | **131,292.10 μs** | **871.653 μs** | **815.344 μs** | **29250.0000** | **-** | **180468.87 KB** | +| 0x0200_All_AttachId_Deserialize | 0x0200Serializer | 100000 | 137,063.75 μs | 1,301.430 μs | 1,086.753 μs | 38250.0000 | 250.0000 | 234375.12 KB | + +## JT808 终端通讯协议消息对照表 + +| 序号 | 消息 ID | 完成情况 | 测试情况 | 消息体名称 | 2019 版本 | 2011 版本 | +| :--: | :-----------: | :------: | :--------: | :----------------------------- | :----------: | :-------: | ------ | +| 1 | 0x0001 | √ | √ | 终端通用应答 | +| 2 | 0x8001 | √ | √ | 平台通用应答 | +| 3 | 0x0002 | √ | √ | 终端心跳 | +| 4 | 0x8003 | √ | √ | 补传分包请求 | | 被新增 | +| 5 | 0x0100 | √ | √ | 终端注册 | 修改 | 被修改 | +| 6 | 0x8100 | √ | √ | 终端注册应答 | +| 7 | 0x0003 | √ | √ | 终端注销 | +| 8 | 0x0102 | √ | √ | 终端鉴权 | 修改 | +| 9 | 0x8103 | √ | √ | 设置终端参数 | 修改且增加 | 被修改 | +| 10 | 0x8104 | √ | √ | 查询终端参数 | +| 11 | 0x0104 | √ | √ | 查询终端参数应答 | +| 12 | 0x8105 | √ | √ | 终端控制 | +| 13 | 0x8106 | √ | √ | 查询指定终端参数 | | 被新增 | +| 14 | 0x8107 | √ | 消息体为空 | 查询终端属性 | | 被新增 | +| 15 | 0x0107 | √ | √ | 查询终端属性应答 | | 被新增 | +| 16 | 0x8108 | √ | √ | 下发终端升级包 | | 被新增 | +| 17 | 0x0108 | √ | √ | 终端升级结果通知 | | 被新增 | +| 18 | 0x0200 | √ | √ | 位置信息汇报 | 增加附加信息 | 被修改 | +| 19 | 0x8201 | √ | √ | 位置信息查询 | +| 20 | 0x0201 | √ | √ | 位置信息查询应答 | +| 21 | 0x8202 | √ | √ | 临时位置跟踪控制 | +| 22 | 0x8203 | √ | √ | 人工确认报警消息 | | 被新增 | +| 23 | 0x8300 | √ | √ | 文本信息下发 | 修改 | 被修改 | +| 24 | 0x8301 | √ | √ | 事件设置 | 删除 | +| 25 | 0x0301 | √ | √ | 事件报告 | 删除 | +| 26 | 0x8302 | √ | √ | 提问下发 | 删除 | +| 27 | 0x0302 | √ | √ | 提问应答 | 删除 | +| 28 | 0x8303 | √ | √ | 信息点播菜单设置 | 删除 | +| 29 | 0x0303 | √ | √ | 信息点播/取消 | 删除 | +| 30 | 0x8304 | √ | √ | 信息服务 | 删除 | +| 31 | 0x8400 | √ | √ | 电话回拨 | +| 32 | 0x8401 | √ | √ | 设置电话本 | +| 33 | 0x8500 | √ | √ | 车辆控制 | 修改 | +| 34 | 0x0500 | √ | √ | 车辆控制应答 | +| 35 | 0x8600 | √ | √ | 设置圆形区域 | 修改 | 被修改 | +| 36 | 0x8601 | √ | √ | 删除圆形区域 | +| 37 | 0x8602 | √ | √ | 设置矩形区域 | 修改 | +| 38 | 0x8603 | √ | √ | 删除矩形区域 | +| 39 | 0x8604 | √ | √ | 设置多边形区域 | 修改 | +| 40 | 0x8605 | √ | √ | 删除多边形区域 | +| 41 | 0x8606 | √ | √ | 设置路线 | 修改 | +| 42 | 0x8607 | √ | √ | 删除路线 | +| 43 | 0x8700 | √ | √ | 行驶记录仪数据采集命令 | | 被修改 | +| 44 | 0x0700 | √ | √ | 行驶记录仪数据上传 | +| 45 | 0x8701 | √ | √ | 行驶记录仪参数下传命令 | | 被修改 | +| 46 | 0x0701 | √ | √ | 电子运单上报 | +| 47 | 0x0702 | √ | √ | 驾驶员身份信息采集上报 | 修改 | 被修改 | +| 48 | 0x8702 | √ | 消息体为空 | 上报驾驶员身份信息请求 | | 被新增 | +| 49 | 0x0704 | √ | √ | 定位数据批量上传 | 修改 | | 被新增 | +| 50 | 0x0705 | √ | √ | CAN 总线数据上传 | 修改 | | 被新增 | +| 51 | 0x0800 | √ | √ | 多媒体事件信息上传 | | 被修改 | +| 52 | 0x0801 | √ | √ | 多媒体数据上传 | 修改 | 被修改 | +| 53 | 0x8800 | √ | √ | 多媒体数据上传应答 | | 被修改 | +| 54 | 0x8801 | √ | √ | 摄像头立即拍摄命令 | 修改 | +| 55 | 0x0805 | √ | √ | 摄像头立即拍摄命令应答 | 修改 | | 被新增 | +| 56 | 0x8802 | √ | √ | 存储多媒体数据检索 | +| 57 | 0x0802 | √ | √ | 存储多媒体数据检索应答 | | 被修改 | +| 58 | 0x8803 | √ | √ | 存储多媒体数据上传 | +| 59 | 0x8804 | √ | √ | 录音开始命令 | +| 60 | 0x8805 | √ | √ | 单条存储多媒体数据检索上传命令 | 修改 | | 被新增 | +| 61 | 0x8900 | √ | √ | 数据下行透传 | 修改 | 被修改 | +| 62 | 0x0900 | √ | √ | 数据上行透传 | 修改 | 被修改 | +| 63 | 0x0901 | √ | √ | 数据压缩上报 | +| 64 | 0x8A00 | √ | √ | 平台 RSA 公钥 | +| 65 | 0x0A00 | √ | √ | 终端 RSA 公钥 | +| 66 | 0x8F00~0x8FFF | 保留 | 保留 | 平台下行消息保留 | +| 67 | 0x0F00~0x0FFF | 保留 | 保留 | 终端上行消息保留 | +| 68 | 0x0004 | √ | √ | 查询服务器时间请求 | 新增 | +| 69 | 0x8004 | √ | √ | 查询服务器时间应答 | 新增 | +| 70 | 0x0005 | √ | √ | 终端补传分包请求 | 新增 | +| 71 | 0x8204 | √ | √ | 链路检测 | 新增 | +| 72 | 0x8608 | √ | √ | 查询区域或线路数据 | 新增 | +| 73 | 0x0608 | √ | √ | 查询区域或线路数据应答 | 新增 | +| 74 | 0xE000~0xEFFF | 保留 | 保留 | 厂商自定义上行消息 | 新增 | +| 75 | 0xF000~0xFFFF | 保留 | 保留 | 厂商自定义下行消息 | 新增 | + +## JT1078 扩展 JT808 议消息对照表 + +| 序号 | 消息 ID | 完成情况 | 测试情况 | 消息体名称 | +| :--: | :-----------: | :------: | :------: | :----------------------- | +| 1 | 0x0200_0x14 | √ | √ | 视频相关报警 | +| 2 | 0x0200_0x15 | √ | √ | 视频信号丢失报警状态 | +| 3 | 0x0200_0x16 | √ | √ | 视频信号遮挡报警状态 | +| 4 | 0x0200_0x17 | √ | √ | 存储器故障报警状态 | +| 5 | 0x0200_0x18 | √ | √ | 异常驾驶行为报警详细描述 | +| 6 | 0x8103_0x0075 | √ | √ | 音视频参数设置 | +| 7 | 0x8103_0x0076 | √ | √ | 音视频通道列表设置 | +| 8 | 0x8103_0x0077 | √ | √ | 单独视频通道参数设置 | +| 9 | 0x8103_0x0079 | √ | √ | 特殊报警录像参数设置 | +| 10 | 0x8103_0x007A | √ | √ | 视频相关报警屏蔽字 | +| 11 | 0x8103_0x007B | √ | √ | 图像分析报警参数设置 | +| 12 | 0x8103_0x007C | √ | √ | 终端休眠模式唤醒设置 | +| 13 | 0x1003 | √ | √ | 终端上传音视频属性 | +| 14 | 0x1005 | √ | √ | 终端上传乘客流量 | +| 15 | 0x1205 | √ | √ | 终端上传音视频资源列表 | +| 16 | 0x1206 | √ | √ | 文件上传完成通知 | +| 17 | 0x9003 | √ | √ | 查询终端音视频属性 | +| 18 | 0x9101 | √ | √ | 实时音视频传输请求 | +| 19 | 0x9102 | √ | √ | 音视频实时传输控制 | +| 20 | 0x9105 | √ | √ | 实时音视频传输状态通知 | +| 21 | 0x9201 | √ | √ | 平台下发远程录像回放请求 | +| 22 | 0x9202 | √ | √ | 平台下发远程录像回放控制 | +| 23 | 0x9205 | √ | √ | 查询资源列表 | +| 24 | 0x9206 | √ | √ | 文件上传指令 | +| 25 | 0x9207 | √ | √ | 文件上传控制 | +| 26 | 0x9301 | √ | √ | 云台旋转 | +| 27 | 0x9302 | √ | √ | 云台调整焦距控制 | +| 28 | 0x9303 | √ | √ | 云台调整光圈控制 | +| 29 | 0x9304 | √ | √ | 云台雨刷控制 | +| 30 | 0x9305 | √ | √ | 红外补光控制 | +| 31 | 0x9306 | √ | √ | 云台变倍控制 | ## 使用方法 @@ -541,29 +548,29 @@ serviceDescriptors1.AddJT808Configure() JT808Serializer.Instance.Register(JT808_JT1078_Constants.GetCurrentAssembly()); ``` -## 主动安全(苏标)扩展JT808协议消息对照表 - -| 序号 | 消息ID | 完成情况 | 测试情况 | 消息体名称 | -| :---: | :---: | :---: | :---: | :---| -| 1 | 0x1210 | √ | √ | 报警附件信息消息 | -| 2 | 0x1211 | √ | √ | 文件信息上传 | -| 3 | 0x1212 | √ | √ | 文件上传完成消息 | -| 4 | 0x9208 | √ | √ | 报警附件上传指令 | -| 5 | 0x9212 | √ | √ | 文件上传完成消息应答 | -| 6 | 0x0200_0x64 | √ | √ | 高级驾驶辅助系统报警信息 | -| 7 | 0x0200_0x65 | √ | √ | 驾驶员状态监测系统报警信息 | -| 8 | 0x0200_0x66 | √ | √ | 胎压监测系统报警信息 | -| 9 | 0x0200_0x67 | √ | √ | 盲区监测系统报警信息 | -| 10 | 0x8103_0xF364 | √ | √ | 高级驾驶辅助系统参数 | -| 11 | 0x8103_0xF365 | √ | √ | 驾驶员状态监测系统参数 | -| 12 | 0x8103_0xF366 | √ | √ | 胎压监测系统参数 | -| 13 | 0x8103_0xF367 | √ | √ | 盲区监测系统参数 | -| 14 | 0x0900 | √ | √ | 上传基本信息 | -| 15 | 0x0900_0xF7 | √ | √ | 外设工作状态 | -| 16 | 0x0900_0xF8 | √ | √ | 外设系统信息 | -| 17 | 0x8900 | √ | √ | 查询基本信息 | -| 18 | 0x8900_0xF7 | √ | √ | 外设工作状态 | -| 19 | 0x8900_0xF8 | √ | √ | 外设系统信息 | +## 主动安全(苏标)扩展 JT808 协议消息对照表 + +| 序号 | 消息 ID | 完成情况 | 测试情况 | 消息体名称 | +| :--: | :-----------: | :------: | :------: | :------------------------- | +| 1 | 0x1210 | √ | √ | 报警附件信息消息 | +| 2 | 0x1211 | √ | √ | 文件信息上传 | +| 3 | 0x1212 | √ | √ | 文件上传完成消息 | +| 4 | 0x9208 | √ | √ | 报警附件上传指令 | +| 5 | 0x9212 | √ | √ | 文件上传完成消息应答 | +| 6 | 0x0200_0x64 | √ | √ | 高级驾驶辅助系统报警信息 | +| 7 | 0x0200_0x65 | √ | √ | 驾驶员状态监测系统报警信息 | +| 8 | 0x0200_0x66 | √ | √ | 胎压监测系统报警信息 | +| 9 | 0x0200_0x67 | √ | √ | 盲区监测系统报警信息 | +| 10 | 0x8103_0xF364 | √ | √ | 高级驾驶辅助系统参数 | +| 11 | 0x8103_0xF365 | √ | √ | 驾驶员状态监测系统参数 | +| 12 | 0x8103_0xF366 | √ | √ | 胎压监测系统参数 | +| 13 | 0x8103_0xF367 | √ | √ | 盲区监测系统参数 | +| 14 | 0x0900 | √ | √ | 上传基本信息 | +| 15 | 0x0900_0xF7 | √ | √ | 外设工作状态 | +| 16 | 0x0900_0xF8 | √ | √ | 外设系统信息 | +| 17 | 0x8900 | √ | √ | 查询基本信息 | +| 18 | 0x8900_0xF7 | √ | √ | 外设工作状态 | +| 19 | 0x8900_0xF8 | √ | √ | 外设系统信息 | ## 使用方法 @@ -577,33 +584,33 @@ serviceDescriptors1.AddJT808Configure() JT808Serializer.Instance.Register(JT808_SuBiao_Constants.GetCurrentAssembly()); ``` -## 主动安全(粤标)扩展JT808协议消息对照表 - -> 注意:基于JT/T808 2019版本 - -| 序号 | 消息ID | 完成情况 | 测试情况 | 消息体名称 | -| :---: | :---: | :---: | :---: | :---| -| 1 | 0x1210 | √ | √ | 报警附件信息消息 | -| 2 | 0x1211 | √ | √ | 文件信息上传 | -| 3 | 0x1212 | √ | √ | 文件上传完成消息 | -| 4 | 0x9208 | √ | √ | 报警附件上传指令 | -| 5 | 0x9212 | √ | √ | 文件上传完成消息应答 | -| 6 | 0x1FC4 | √ | √ | 终端升级进度上报 | -| 7 | 0x0200_0x64 | √ | √ | 高级驾驶辅助系统报警信息 | -| 8 | 0x0200_0x65 | √ | √ | 驾驶员状态监测系统报警信息 | -| 9 | 0x0200_0x66 | √ | √ | 胎压监测系统报警信息 | -| 10 | 0x0200_0x67 | √ | √ | 盲区监测系统报警信息 | -| 11 | 0x8103_0xF364 | √ | √ | 高级驾驶辅助系统参数 | -| 12 | 0x8103_0xF365 | √ | √ | 驾驶员状态监测系统参数 | -| 13 | 0x8103_0xF366 | √ | √ | 胎压监测系统参数 | -| 14 | 0x8103_0xF367 | √ | √ | 盲区监测系统参数 | -| 15 | 0x8103_0xF370 | √ | √ | 智能视频协议版本信息 | -| 16 | 0x0900 | √ | √ | 上传基本信息 | -| 17 | 0x0900_0xF7 | √ | √ | 外设工作状态 | -| 18 | 0x0900_0xF8 | √ | √ | 外设系统信息 | -| 19 | 0x8900 | √ | √ | 查询基本信息 | -| 20 | 0x8900_0xF7 | √ | √ | 外设工作状态 | -| 21 | 0x8900_0xF8 | √ | √ | 外设系统信息 | +## 主动安全(粤标)扩展 JT808 协议消息对照表 + +> 注意:基于 JT/T808 2019 版本 + +| 序号 | 消息 ID | 完成情况 | 测试情况 | 消息体名称 | +| :--: | :-----------: | :------: | :------: | :------------------------- | +| 1 | 0x1210 | √ | √ | 报警附件信息消息 | +| 2 | 0x1211 | √ | √ | 文件信息上传 | +| 3 | 0x1212 | √ | √ | 文件上传完成消息 | +| 4 | 0x9208 | √ | √ | 报警附件上传指令 | +| 5 | 0x9212 | √ | √ | 文件上传完成消息应答 | +| 6 | 0x1FC4 | √ | √ | 终端升级进度上报 | +| 7 | 0x0200_0x64 | √ | √ | 高级驾驶辅助系统报警信息 | +| 8 | 0x0200_0x65 | √ | √ | 驾驶员状态监测系统报警信息 | +| 9 | 0x0200_0x66 | √ | √ | 胎压监测系统报警信息 | +| 10 | 0x0200_0x67 | √ | √ | 盲区监测系统报警信息 | +| 11 | 0x8103_0xF364 | √ | √ | 高级驾驶辅助系统参数 | +| 12 | 0x8103_0xF365 | √ | √ | 驾驶员状态监测系统参数 | +| 13 | 0x8103_0xF366 | √ | √ | 胎压监测系统参数 | +| 14 | 0x8103_0xF367 | √ | √ | 盲区监测系统参数 | +| 15 | 0x8103_0xF370 | √ | √ | 智能视频协议版本信息 | +| 16 | 0x0900 | √ | √ | 上传基本信息 | +| 17 | 0x0900_0xF7 | √ | √ | 外设工作状态 | +| 18 | 0x0900_0xF8 | √ | √ | 外设系统信息 | +| 19 | 0x8900 | √ | √ | 查询基本信息 | +| 20 | 0x8900_0xF7 | √ | √ | 外设工作状态 | +| 21 | 0x8900_0xF8 | √ | √ | 外设系统信息 | ## 使用方法 diff --git a/src/JT808.Protocol.Test/JT808SerializerTest.cs b/src/JT808.Protocol.Test/JT808SerializerTest.cs index ed574bb..634334d 100644 --- a/src/JT808.Protocol.Test/JT808SerializerTest.cs +++ b/src/JT808.Protocol.Test/JT808SerializerTest.cs @@ -1,14 +1,14 @@ -using JT808.Protocol.Enums; -using JT808.Protocol.Extensions; -using JT808.Protocol.Interfaces; -using JT808.Protocol.Internal; -using JT808.Protocol.MessageBody; -using System; +using System; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Text; using System.Threading.Tasks; +using JT808.Protocol.Enums; +using JT808.Protocol.Extensions; +using JT808.Protocol.Interfaces; +using JT808.Protocol.Internal; +using JT808.Protocol.MessageBody; using Xunit; namespace JT808.Protocol.Test @@ -18,7 +18,7 @@ namespace JT808.Protocol.Test [Fact] public void ParallelTest1() { - var result = Parallel.For(0, 100, new ParallelOptions { MaxDegreeOfParallelism = 2 }, (i) => + var result = Parallel.For(0, 100, new ParallelOptions { MaxDegreeOfParallelism = 2 }, (i) => { IJT808Config jT808Config = new DefaultGlobalConfig(); JT808Serializer jT808Serializer = new JT808Serializer(jT808Config); @@ -33,7 +33,7 @@ namespace JT808.Protocol.Test public unsafe void DefaultGlobalConfigTest1() { List defaultGlobalConfigs = new List(); - for(var i = 0; i < 100; i++) + for (var i = 0; i < 100; i++) { if (i % 2 == 0) { @@ -45,5 +45,24 @@ namespace JT808.Protocol.Test } } } + + [Theory] + [InlineData("7E010423F001127540038104D10002000100006B00000001040000025800000002040000000A00000003040000000500000004040000000A0000000504000000050000000604000000000000000704000000000000001005434D4E455400000011000000001200000000130D3232322E3138342E32362E323200000014000000001500000000160000000017000000001804000007E50000001904000007E50000002304000000000000002404000000000000002504000000000000002604000000000000003204000005000000001A000000001B04000000000000001C04000000000000001D0000000020040000000000000021040000000000000022040000012C000000270400001C2000000028040000001E00000029040000001E0000002C04000001F40000002D04000001F40000002E04000001F40000002F04000000C800000030040000001E000000310201F4000000400000000041000000004200000000430000000044000000004504000000010000004604FFFFFFFF0000004704FFFFFFFF0000004800000000490000000050040363160800000051040000000000000052040000000100000053040000000000000054040000000000000055040000000000000056040000001E0000005704000038400000005804000070800000005904000004B00000005A0400000E100000005B0200000000005C0207080000005D0224000000005E02001E00000064040000010100000065040000000000000070040000000500000071040000007F00000072040000004000000073040000004000000074040000007F00000080040004B9930000008102000000000082020000000000830CB2E2CAD4CAD3C6B5B3B5C1BE00000084010000000090010300000091010100000092010000000093040000000100000094010000000095040000000000000100040000000000000101020000000001020400000000000001030200000000C11204000000050000C11304000000050000C11404000000030000C11504000000000000C1160200000000C1170200000000C118033200030000C119030000000000CB00040000000200000075150103001E0F00000100000300191900000400002B00000000761B05000101010000020200000303000004040000050500000606020000000077A908010103001E0F00000100000300191900000400002B020103001E0F00000100000300191900000400002B030103001E0F00000100000300191900000400002B040103001E0F00000100000300191900000400002B050103001E0F00000100000300191900000400002B060103001E0F00000100000300191900000400002B070103001E0F00000100000300191900000400002B080103001E0F00000100000300191900000400002B0000007903140501C17E")] + [InlineData("7E010420D301127540038104E2000200020000007A04000000000000007B0200000000007C1400000000000000000000000000000000000000000000F364381E06000E1007D003020101FFFFFFFFFFFFFFFFFF0000000302000000060302320503021B320503021E320503020A320503020302FFFFFFFF0000F365311E06000E1007D003020101FFFFFFFF00000007012C0078FFFFFF320503023205030232050302320503023205030200FFFF0000FF010537303231380000FF02144B352D50000000000000000000000000000000000000F373040BB80BB80000FF0006FEEA4C0510BD1F7E")] + public void MergerTest(string data) + { + var config = new DefaultGlobalConfig(); + config.EnableAutoMerge = true; + var package = config.GetSerializer().Deserialize(data.ToHexBytes()); + if (package.Header.PackageIndex == package.Header.PackgeCount) + { + Assert.NotNull(package.Bodies); + } + else + { + Assert.Null(package.Bodies); + Assert.NotEmpty(package.SubDataBodies); + } + } } } diff --git a/src/JT808.Protocol/Interfaces/GlobalConfigBase.cs b/src/JT808.Protocol/Interfaces/GlobalConfigBase.cs index af01d76..84c8210 100644 --- a/src/JT808.Protocol/Interfaces/GlobalConfigBase.cs +++ b/src/JT808.Protocol/Interfaces/GlobalConfigBase.cs @@ -1,11 +1,7 @@ -using JT808.Protocol.Enums; +using System.Reflection; +using System.Text; using JT808.Protocol.Formatters; using JT808.Protocol.Internal; -using JT808.Protocol.MessageBody; -using System; -using System.Reflection; -using System.Text; -using static JT808.Protocol.MessageBody.JT808_0x8105; namespace JT808.Protocol.Interfaces { @@ -126,6 +122,9 @@ namespace JT808.Protocol.Interfaces /// 终端控制自定义参数命令工厂 /// public virtual IJT808_0x8105_Cusotm_Factory JT808_0x8105_Cusotm_Factory { get; set; } + /// + public virtual bool EnableAutoMerge { get; set; } + /// /// 外部扩展程序集注册 /// diff --git a/src/JT808.Protocol/Interfaces/IJT808Config.cs b/src/JT808.Protocol/Interfaces/IJT808Config.cs index 858151c..7ede120 100644 --- a/src/JT808.Protocol/Interfaces/IJT808Config.cs +++ b/src/JT808.Protocol/Interfaces/IJT808Config.cs @@ -1,10 +1,10 @@ -using JT808.Protocol.Enums; -using JT808.Protocol.Formatters; -using JT808.Protocol.Interfaces; -using System; +using System; using System.Collections.Generic; using System.Reflection; using System.Text; +using JT808.Protocol.Enums; +using JT808.Protocol.Formatters; +using JT808.Protocol.Interfaces; using static JT808.Protocol.MessageBody.JT808_0x8105; namespace JT808.Protocol @@ -106,6 +106,12 @@ namespace JT808.Protocol /// int TerminalPhoneNoLength { get; set; } /// + /// 是否启用自动组包,默认不启用。 + /// 当反序列化时遇到分包消息时,将分包数据缓存至内存,直到收到最后一包数据,将其取出进行反序列化,并清除相应缓存 + /// + /// 启用该选项存在一定风险,请谨慎使用。 + bool EnableAutoMerge { get; set; } + /// /// 全局注册外部程序集 /// /// @@ -116,7 +122,7 @@ namespace JT808.Protocol /// void ReplaceMsgId() where TSourceJT808Bodies : JT808Bodies - where TTargetJT808Bodies : JT808Bodies,new(); + where TTargetJT808Bodies : JT808Bodies, new(); } } diff --git a/src/JT808.Protocol/Interfaces/IMerger.cs b/src/JT808.Protocol/Interfaces/IMerger.cs new file mode 100644 index 0000000..500f613 --- /dev/null +++ b/src/JT808.Protocol/Interfaces/IMerger.cs @@ -0,0 +1,18 @@ +namespace JT808.Protocol.Interfaces +{ + /// + /// 合并分包数据接口 + /// + public interface IMerger + { + /// + /// 合并元数据并反序列化数据包 + /// + /// 消息头 + /// 分包数据包中的消息体部分元数据 + /// 配置项 + /// 反序列化得出的数据包 + /// 是否反序列化成功 + bool TryMerge(JT808Header header, byte[] data, IJT808Config config, out JT808Bodies body); + } +} \ No newline at end of file diff --git a/src/JT808.Protocol/Internal/DefaultMerger.cs b/src/JT808.Protocol/Internal/DefaultMerger.cs new file mode 100644 index 0000000..62f44ab --- /dev/null +++ b/src/JT808.Protocol/Internal/DefaultMerger.cs @@ -0,0 +1,62 @@ +using System.Collections.Concurrent; +using JT808.Protocol.Interfaces; +using JT808.Protocol.MessagePack; + +namespace JT808.Protocol.Internal +{ + /// + /// 默认分包合并实现 + /// + public class DefaultMerger : IMerger + { + /// + /// 分包数据缓存 + /// key为sim卡号,value为字典,key为消息id,value为元组,结构为:(分包索引,分包元数据) + /// + private readonly ConcurrentDictionary>> SplitPackages = new(); + + /// + public bool TryMerge(JT808Header header, byte[] data, IJT808Config config, out JT808Bodies body) + { + body = null; + if (header.PackageIndex == header.PackgeCount) + { + if (SplitPackages.TryGetValue(header.TerminalPhoneNo, out var item) && item.TryRemove(header.MsgId, out var packages)) + { + SplitPackages.TryRemove(header.TerminalPhoneNo, out _); + + var mateData = packages.OrderBy(x => x.index).SelectMany(x => x.data).Concat(data).ToArray(); + + byte[] buffer = JT808ArrayPool.Rent(mateData.Length); + try + { + var reader = new JT808MessagePackReader(mateData, (Enums.JT808Version)header.ProtocolVersion); + if (config.MsgIdFactory.TryGetValue(header.MsgId, out var value) && value is JT808Bodies instance) + { + body = instance.DeserializeExt(ref reader, config); + return true; + } + } + finally + { + JT808ArrayPool.Return(buffer); + } + } + return default; + } + else + { + SplitPackages.AddOrUpdate(header.TerminalPhoneNo, new ConcurrentDictionary>() { [header.MsgId] = new List<(ushort, byte[])> { (header.PackageIndex, data) } }, (_, value) => + { + value.AddOrUpdate(header.MsgId, new List<(ushort, byte[])> { (header.PackageIndex, data) }, (_, item) => + { + item.Add((header.PackageIndex, data)); + return item; + }); + return value; + }); + } + return false; + } + } +} \ No newline at end of file diff --git a/src/JT808.Protocol/JT808.Protocol.xml b/src/JT808.Protocol/JT808.Protocol.xml index ac88296..4bd4c81 100644 --- a/src/JT808.Protocol/JT808.Protocol.xml +++ b/src/JT808.Protocol/JT808.Protocol.xml @@ -4351,6 +4351,9 @@ 终端控制自定义参数命令工厂 + + + 外部扩展程序集注册 @@ -4689,6 +4692,21 @@ + + + 合并分包数据接口 + + + + + 合并元数据并反序列化数据包 + + 消息头 + 分包数据包中的消息体部分元数据 + 配置项 + 反序列化得出的数据包 + 是否反序列化成功 + 记录仪工厂 @@ -4862,6 +4880,13 @@ 设备终端号(默认12位) + + + 是否启用自动组包,默认不启用。 + 当反序列化时遇到分包消息时,将分包数据缓存至内存,直到收到最后一包数据,将其取出进行反序列化,并清除相应缓存 + + 启用该选项存在一定风险,请谨慎使用。 + 全局注册外部程序集 @@ -4906,6 +4931,20 @@ + + + 默认分包合并实现 + + + + + 分包数据缓存 + key为sim卡号,value为字典,key为消息id,value为元组,结构为:(分包索引,分包元数据) + + + + + 内存池 @@ -6103,104 +6142,104 @@ - + ctor - + ctor - + 标识 - + 序列化数据包 - - - - + 数据包 + 协议版本 + 最低所需缓冲区大小 + 元数据 - + 反序列化 - - - - + 元数据 + 协议版本 + 最低所需缓冲区大小 + 数据包 - + 序列化 - - - - + 数据包 + 协议版本 + 最低所需缓冲区大小 + 元数据 - + 根据泛型反序列化元数据 - - - - + 元素书 + 协议版本 + 最低所需缓冲区大小 + 数据包 - + 验证类型是否为或者 - + 需要验证的类型 - 用于负载或者分布式的时候,在网关只需要解到头部。 - 根据头部的消息Id进行分发处理,可以防止小部分性能损耗。 + 反序列化消息头 + 用于负载或者分布式的时候,在网关只需要解到头部,根据头部的消息Id进行分发处理,可以防止小部分性能损耗。 - - - + 元数据 + 协议版本 + 最低所需缓冲区大小 - + 根据类型反序列化 - - - - + 元数据 + 类型 + 协议版本 + 最低所需缓冲区大小 - + 分析元数据至json - - - - + 元数据 + 协议版本 + json选项 + 最低所需缓冲区大小 - + 分析元数据至json - - - - + 元数据 + 协议版本 + json序列化选项 + 最低所需缓冲区大小 @@ -6227,23 +6266,23 @@ - + 分析元数据至json - - - - + 元数据 + 协议版本 + json选项 + 最低所需缓冲区大小 - + 分析元数据至json - - - - + 元数据 + 协议版本 + json选项 + 最低所需缓冲区大小 diff --git a/src/JT808.Protocol/JT808Package.cs b/src/JT808.Protocol/JT808Package.cs index cfdab5d..07b5ef5 100644 --- a/src/JT808.Protocol/JT808Package.cs +++ b/src/JT808.Protocol/JT808Package.cs @@ -1,11 +1,11 @@ -using JT808.Protocol.Enums; +using System; +using System.Text.Json; +using JT808.Protocol.Enums; using JT808.Protocol.Exceptions; using JT808.Protocol.Extensions; using JT808.Protocol.Formatters; using JT808.Protocol.Interfaces; using JT808.Protocol.MessagePack; -using System; -using System.Text.Json; namespace JT808.Protocol { @@ -82,7 +82,8 @@ namespace JT808.Protocol jT808Package.Header.TerminalPhoneNo = reader.ReadBCD(config.TerminalPhoneNoLength, config.Trim); reader.Version = JT808Version.JTT2013; } - else { + else + { if (reader.Version == JT808Version.JTT2019 || jT808Package.Header.MessageBodyProperty.VersionFlag) { //2019版本 @@ -120,7 +121,16 @@ namespace JT808.Protocol //读取分包的数据体 try { - jT808Package.SubDataBodies = reader.ReadArray(jT808Package.Header.MessageBodyProperty.DataLength).ToArray(); + var data = reader.ReadArray(jT808Package.Header.MessageBodyProperty.DataLength).ToArray(); + + if (config.EnableAutoMerge && config.GetSerializer().merger.TryMerge(jT808Package.Header, data, config, out var body)) + { + jT808Package.Bodies = body; + } + else + { + jT808Package.SubDataBodies = data; + } } catch (Exception ex) { @@ -273,7 +283,8 @@ namespace JT808.Protocol //消息体属性对象 结束 writer.WriteString($"[{terminalPhoneNo.PadLeft(config.TerminalPhoneNoLength, '0')}]终端手机号", terminalPhoneNo); } - else { + else + { if (reader.Version == JT808Version.JTT2019 || headerMessageBodyProperty.VersionFlag) { reader.Version = JT808Version.JTT2019; diff --git a/src/JT808.Protocol/JT808Serializer.cs b/src/JT808.Protocol/JT808Serializer.cs index 14478ff..2312b9e 100644 --- a/src/JT808.Protocol/JT808Serializer.cs +++ b/src/JT808.Protocol/JT808Serializer.cs @@ -5,6 +5,7 @@ using System.Text.Json; using JT808.Protocol.Enums; using JT808.Protocol.Extensions; using JT808.Protocol.Formatters; +using JT808.Protocol.Interfaces; using JT808.Protocol.Internal; using JT808.Protocol.MessagePack; @@ -16,6 +17,7 @@ namespace JT808.Protocol /// public class JT808Serializer { + internal readonly IMerger merger; private readonly static JT808Package jT808Package = new JT808Package(); private readonly static Type JT808_Header_Package_Type = typeof(JT808HeaderPackage); @@ -39,16 +41,15 @@ namespace JT808.Protocol /// public JT808Serializer(IJT808Config jT808Config) { + if (jT808Config.EnableAutoMerge) + merger = new DefaultMerger(); this.jT808Config = jT808Config; } /// /// ctor /// - public JT808Serializer() : this(new DefaultGlobalConfig()) - { - - } + public JT808Serializer() : this(new DefaultGlobalConfig()) { } /// /// 标识