掌握 进制转换:二进制转十六进制;掌握 BCD 编码、Hex 编码;掌握 各 种位移 、异或;掌握 常用 反射 ;掌握 JObject的 用法 ;掌握 快速 ctrl+c、ctrl+v;掌握 Span<T>的 基本 用法 掌握 以上 装 逼技能 ,就可以开始 搬砖了 。
头标识 | ||||
---|---|---|---|---|
Begin | JT808Header | JT808Bodies/JT808SubDataBodies | CheckCode | End |
7E | - | - | - | 7E |
协议 |
终端 |
|||||
---|---|---|---|---|---|---|
MsgId | JT808HeaderMessageBodyProperty | ProtocolVersion | TerminalPhoneNo | MsgNum | PackgeCount | PackageIndex |
VersionFlag | IsPackge | Encrypt | DataLength |
根 据 对应消息 ID:MsgId
转义规则如下:
若 数 据 内容 中有 出 现字符 0x7e的 ,需替换为字 符 0x7d 紧跟字 符 0x02;若 数 据 内容 中有 出 现字符 0x7d的 ,需替换为字 符 0x7d 紧跟字 符 0x01;
MsgId 0x0200:
位置 信 息 汇报
JT808Package jT808Package = new JT808Package();
jT808Package.Header = new JT808Header
{
MsgId = (ushort)JT808.Protocol.Enums.JT808MsgId._0x0200,
ManualMsgNum = 126,
TerminalPhoneNo = "123456789012"
};
JT808_0x0200 jT808_0x0200 = new JT808_0x0200();
jT808_0x0200.AlarmFlag = 1;
jT808_0x0200.Altitude = 40;
jT808_0x0200.GPSTime = DateTime.Parse("2018-10-15 10:10:10");
jT808_0x0200.Lat = 12222222;
jT808_0x0200.Lng = 132444444;
jT808_0x0200.Speed = 60;
jT808_0x0200.Direction = 0;
jT808_0x0200.StatusFlag = 2;
jT808_0x0200.BasicLocationAttachData = new Dictionary<byte, JT808_0x0200_BodyBase>();
jT808_0x0200.BasicLocationAttachData.Add(JT808Constants.JT808_0x0200_0x01, new JT808_0x0200_0x01
{
Mileage = 100
});
jT808_0x0200.BasicLocationAttachData.Add(JT808Constants.JT808_0x0200_0x02, new JT808_0x0200_0x02
{
Oil = 125
});
jT808Package.Bodies = jT808_0x0200;
byte[] data = JT808Serializer.Serialize(jT808Package);
var hex = data.ToHexString();
// 输出结果Hex:
// 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
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
2.进行反 转义
7D 02 ->7E
7D 01 ->7D
反 转义后
7E 02 00 00 26 12 34 56 78 90 12 00 7E 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 13 7E
3.拆解
7E --头标识
02 00 --数 据 头->消息 ID
00 26 --数 据 头->消息 体 属性
12 34 56 78 90 12 --数 据 头->终端手 机 号
00 7E --数 据 头->消息 流水 号
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 --消息 体 ->GPS时间
01 --消息 体 ->附加 信 息 ->里程
04 --消息 体 ->附加 信 息 ->长度
00 00 00 64 --消息 体 ->附加 信 息 ->数 据
02 --消息 体 ->附加 信 息 ->油 量
02 --消息 体 ->附加 信 息 ->长度
00 7D --消息 体 ->附加 信 息 ->数 据
13 --检验码
7E --尾 标识
//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();
//2.将 数 组反序列 化
var jT808Package = JT808Serializer.Deserialize(bytes);
//3.数 据 包 头
Assert.Equal(Enums.JT808MsgId._0x0200, jT808Package.Header.MsgId);
Assert.Equal(38, jT808Package.Header.MessageBodyProperty.DataLength);
Assert.Equal(126, jT808Package.Header.MsgNum);
Assert.Equal("123456789012", jT808Package.Header.TerminalPhoneNo);
Assert.False(jT808Package.Header.MessageBodyProperty.IsPackge);
Assert.Equal(0, jT808Package.Header.PackageIndex);
Assert.Equal(0, jT808Package.Header.PackgeCount);
Assert.Equal(JT808EncryptMethod.None, jT808Package.Header.MessageBodyProperty.Encrypt);
//4.数 据 包 体
JT808_0x0200 jT808_0x0200 = (JT808_0x0200)jT808Package.Bodies;
Assert.Equal((uint)1, jT808_0x0200.AlarmFlag);
Assert.Equal((uint)40, jT808_0x0200.Altitude);
Assert.Equal(DateTime.Parse("2018-10-15 10:10:10"), jT808_0x0200.GPSTime);
Assert.Equal(12222222, jT808_0x0200.Lat);
Assert.Equal(132444444, jT808_0x0200.Lng);
Assert.Equal(60, jT808_0x0200.Speed);
Assert.Equal(0, jT808_0x0200.Direction);
Assert.Equal((uint)2, jT808_0x0200.StatusFlag);
//4.1.附加 信 息 1
Assert.Equal(100, ((JT808_0x0200_0x01)jT808_0x0200.BasicLocationAttachData[JT808Constants.JT808_0x0200_0x01]).Mileage);
//4.2.附加 信 息 2
Assert.Equal(125, ((JT808_0x0200_0x02)jT808_0x0200.BasicLocationAttachData[JT808Constants.JT808_0x0200_0x02]).Oil);
// 使用 消息 Id的 扩展方法 创建JT808Package包
JT808Package jT808Package = Enums.JT808MsgId._0x0200.Create("123456789012",
new JT808_0x0200 {
AlarmFlag = 1,
Altitude = 40,
GPSTime = DateTime.Parse("2018-10-15 10:10:10"),
Lat = 12222222,
Lng = 132444444,
Speed = 60,
Direction = 0,
StatusFlag = 2,
BasicLocationAttachData = new Dictionary<byte, JT808LocationAttachBase>
{
{ JT808Constants.JT808_0x0200_0x01,new JT808_0x0200_0x01{Mileage = 100}},
{ JT808Constants.JT808_0x0200_0x02,new JT808_0x0200_0x02{Oil = 125}}
}
});
byte[] data = JT808Serializer.Serialize(jT808Package);
var hex = data.ToHexString();
//输出结果Hex:
//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
// 初 始 化 配置
IJT808Config DT1JT808Config = new DT1Config();
IJT808Config DT2JT808Config = new DT2Config();
// 注 册 自 定 义消息 外部 程 序 集
DT1JT808Config.Register(Assembly.GetExecutingAssembly());
// 跳 过校验和验证
DT1JT808Config.SkipCRCCode = true;
// 根 据 不同 的 设备终端号 ,添加 自 定 义消息 Id
DT1JT808Config.MsgIdFactory.SetMap<DT1Demo6>();
DT1JT808Config.FormatterFactory.SetMap<DT1Demo6>();
DT2JT808Config.MsgIdFactory.SetMap<DT2Demo6>();
DT2JT808Config.FormatterFactory.SetMap<DT2Demo6>();
// 初 始 化 序列 化 实例
JT808Serializer DT1JT808Serializer = new JT808Serializer(DT1JT808Config);
JT808Serializer DT2JT808Serializer = new JT808Serializer(DT2JT808Config);
场景:
一个设备厂商对应多个设备类型,
1.
2.
要 是 哪位大 佬还有 其他的 解 决方式 ,请您告知 我 下 ,谢谢您了。
场景:
设备
-
第 一包数据上来采用平常的方式去解析数据; -
当 第 二包上来跟第一包的分包数据体(SubDataBodies)进行合 并 -
当 N包 数 据 上 来 ,延 续步骤 2的 方式 。
普及 知 识点 1:由 于消息 体 长度最大 为 10bit 也就是 1023的 字 节,所以 这边就有个硬性 条件 不能 超 过最大 长度。
普及 知 识点 2:一般行业分包是按 256的 整数 倍 ,太 多 不 行 ,太 少 也不行 ,必须刚刚好 。
场景:
最新 协议文 档已经写好 了 如何 做兼容 ,就是在 消息 体 属性 中 第 14位 为版本 标识。
-
当 第 14位 为 0 时,标识协议为 2011年 的 版本 ; -
当 第 14位 为 1 时,标识协议为 2019年 的 版本 。
协议
场景 1:
场景 2:
场景 3:
备注 | |||
---|---|---|---|
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 |
注意 :默 认都是 以标准的 去 解析 ,要 是 出 现未知的 附加 ,不 一定解析就是正确,最 好 还是需要 依 照 协议文 档去开发然 后 自 行 注 册 解析 器 去 解析 。
场景:
场景:
场景:
场景:
场景:
场景:
场景:
场景:
场景:
默 认缓存 超 时时间为5分 钟- 如果
合 并且反 序列 化 成功 则JT808Package的 Bodies
不 为空,反 之 亦 然 超 时计时为收 到 指定 终端的 指定 消息 id第 一 包 开始,期 间如果 收 到 所有 分包 数 据 ,在 收 到 最 后 一个分包时自动反序列化,如果期 间未收 到 所有 分包 数 据 ,则后续将无法合 并出完 整 的 数 据 并反序列 化 - 如有
特殊 需求请重写 默 认实现或 自 行 实现接 口 并手动设置 全局 配置 的 Jt808PackageMerger
属性
BenchmarkDotNet v0.13.10, Windows 11 (10.0.22621.2428/22H2/2022Update/SunValley2)
Intel Core i7-8700K CPU 3.70GHz (Coffee Lake), 1 CPU, 12 logical and 6 physical cores
.NET SDK 8.0.100
[Host] : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2
Job-EBMZTG : .NET 8.0.0 (8.0.23.53103), X64 RyuJIT AVX2
Platform=AnyCpu Server=False Toolchain=.NET 8.0
Method | Categories | N | Mean | Error | StdDev | Gen0 | Gen1 | Allocated |
---|---|---|---|---|---|---|---|---|
0x0100Serialize | 0x0100Serializer | 100 | 56.79 |
0.448 |
0.397 |
10.8032 | - | 66.41 KB |
0x0100Deserialize | 0x0100Serializer | 100 | 51.04 |
0.538 |
0.477 |
15.8081 | - | 96.88 KB |
0x0100Serialize | 0x0100Serializer | 10000 | 5,316.12 |
40.148 |
37.554 |
1078.1250 | - | 6640.63 KB |
0x0100Deserialize | 0x0100Serializer | 10000 | 5,170.64 |
47.209 |
44.160 |
1578.1250 | - | 9687.5 KB |
0x0100Serialize | 0x0100Serializer | 100000 | 53,662.59 |
349.274 |
326.711 |
10800.0000 | - | 66406.32 KB |
0x0100Deserialize | 0x0100Serializer | 100000 | 50,744.93 |
560.585 |
524.372 |
15800.0000 | - | 96875.07 KB |
0x0200_All_AttachId_Serialize | 0x0200Serializer | 100 | 99.29 |
0.615 |
0.545 |
29.4189 | 0.1221 | 180.47 KB |
0x0200_All_AttachId_Deserialize | 0x0200Serializer | 100 | 112.93 |
0.536 |
0.502 |
38.2080 | 0.2441 | 234.38 KB |
0x0200_All_AttachId_Serialize | 0x0200Serializer | 10000 | 10,000.00 |
57.313 |
50.806 |
2937.5000 | - | 18046.89 KB |
0x0200_All_AttachId_Deserialize | 0x0200Serializer | 10000 | 11,079.90 |
74.979 |
66.467 |
3812.5000 | 15.6250 | 23437.51 KB |
0x0200_All_AttachId_Serialize | 0x0200Serializer | 100000 | 100,822.02 |
1,061.507 |
992.935 |
29400.0000 | - | 180468.88 KB |
0x0200_All_AttachId_Deserialize | 0x0200Serializer | 100000 | 113,578.52 |
801.568 |
669.345 |
38200.0000 | 200.0000 | 234375.13 KB |
测试 |
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 | √ | √ | |||
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 | 厂商 |
测试 |
||||
---|---|---|---|---|
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 | √ | √ |
DI:
IServiceCollection serviceDescriptors1 = new ServiceCollection();
serviceDescriptors1.AddJT808Configure()
.AddJT1078Configure();
全局 注 册 :
JT808Serializer.Instance.Register(JT808_JT1078_Constants.GetCurrentAssembly());
测试 |
||||
---|---|---|---|---|
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 | √ | √ |
DI:
IServiceCollection serviceDescriptors1 = new ServiceCollection();
serviceDescriptors1.AddJT808Configure()
.AddSuBiaoConfigure();
全局 注 册 :
JT808Serializer.Instance.Register(JT808_SuBiao_Constants.GetCurrentAssembly());
注意 :基 于 JT/T808 2019版本
测试 |
||||
---|---|---|---|---|
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 | √ | √ |
DI:
IServiceCollection serviceDescriptors1 = new ServiceCollection();
serviceDescriptors1.AddJT808Configure()
.AddYueBiaoConfigure();
全局 注 册 :
JT808Serializer.Instance.Register(JT808_YueBiao_Constants.GetCurrentAssembly());