Browse Source

完善文档

tags/v1.3.0
SmallChi 6 years ago
parent
commit
1bf540ff3b
2 changed files with 193 additions and 13 deletions
  1. +192
    -12
      README.md
  2. +1
    -1
      src/JT809.Protocol/JT809Header.cs

+ 192
- 12
README.md View File

@@ -1,17 +1,192 @@
# JT809协议开发
# JT809协议

## 瞎逼逼:

  现在有了[JT808](https://github.com/SmallChi/GPSPlatform/blob/master/JT808.md)的基础,对JT809就只剩搬砖了
> 该JT809协议是参考[MessagePack-CSharp](https://github.com/neuecc/MessagePack-CSharp)一款二进制序列化器,借鉴其思想,不得不说站在巨人的肩膀上搬砖就是爽歪歪

> 该JT809协议是参考[MessagePack-CSharp](https://github.com/neuecc/MessagePack-CSharp)一款二进制序列化器,站在巨人的肩膀上搬砖就是爽歪歪
> 在github上面搜索竟然没有针对.NET开源的809协议库,难度做GPS行业的.NET很少人吗?可能是藏着,掖着<( ̄3 ̄)> <( ̄3 ̄)> <( ̄3 ̄)>

> 这GB的文档不得不说,太坑了。。。
> 不得不说这GB的文档,太坑了。。。

> 现在有了[JT808](https://github.com/SmallChi/GPSPlatform/blob/master/JT808.md)的基础,对JT809就只剩搬砖了。

## 前提条件

1. 掌握进制转换:二进制转十六进制;
2. 掌握什么叫BCD编码、Hex编码;
3. 掌握各种位移、异或;
4. 掌握常用反射;
5. 掌握快速ctrl+c、ctrl+v;
6. 掌握以上装逼技能,就可以开始搬砖了。

## JT809数据结构解析

### 数据包[JT809Package]
|头标识|数据头|数据体|CRC校验码|尾标识
|:------:|:------:|:------:|:------:|:------:|
| BeginFlag | JT809Header | JT809Bodies | CRCCode | EndFlag |
| 5B | - | - | - | 5D |

### 数据头[JT809Header]

|数据长度|报文序列号|业务数据类型|下级平台接入码|协议版本号标识|报文加密标识位|数据加密的密匙|
|:------:|:------:|:------:|:------:|:------:|:------:|:------:|
| MsgLength | MsgSN | MsgID | MsgGNSSCENTERID | Version | EndFlag |EncryptFlag | EncryptKey |

### 数据体[JT809Bodies]

> 根据对应业务数据类型:MsgID

|车牌号|车辆颜色|子业务类型标识|后续数据长度|子业务数据体
|:------:|:------:|:------:|:------:|:------:|
| VehicleNo | VehicleColor | SubBusinessType | DataLength | JT809SubBodies |

### 子数据体[JT809SubBodies]

> 根据对应子业务数据类型 SubBusinessType 处理子业务数据体(JT809SubBodies)。

***注意:数据内容(除去头和尾标识)进行转义判断***

转义规则如下:
1. 若数据内容中有出现字符 0x5b 的,需替换为字符 0x5a 紧跟字符 0x01;
2. 若数据内容中有出现字符 0x5a 的,需替换为字符 0x5a 紧跟字符 0x02;
3. 若数据内容中有出现字符 0x5d 的,需替换为字符 0x5e 紧跟字符 0x01;
4. 若数据内容中有出现字符 0x5e 的,需替换为字符 0x5e 紧跟字符 0x02.

反转义的原因:确认JT809协议的TCP消息边界。

### 举个栗子

1. 组包:
> 业务数据类型 MsgID:从链路报警信息交互消息
> 子业务类型标识 SubBusinessType:报警督办请求消息

```
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;

byte[] data = JT809Serializer.Serialize(jT809Package);

string hex = data.ToHexString();

// 输出结果Hex:
// 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
```

2. 手动解包:
```
1.原包:
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

2.进行反转义
5A 01 ->5B
5A 02 ->5A
5E 01 ->5D
5E 02 ->5E
反转义后
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 5B AC 3F 40 12 3F FA A1 00 00 00 00 5B 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

3.拆解
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 5B AC 3F 40 --子数据体->报警时间UTCDateTime
12 3F FA A1 --子数据体->报警督办ID
00 00 00 00 5B 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 --CRC校验码
5D --尾标识
```

3. 程序解包:
```
//1.转成byte数组
var 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();

//2.将数组反序列化
JT809Package jT809Package = JT809Serializer.Deserialize(bytes);

//3.数据包头
Assert.Equal((uint)146, jT809Package.Header.MsgLength);
Assert.Equal((uint)1666, jT809Package.Header.MsgSN);
Assert.Equal((uint)9999, jT809Package.Header.EncryptKey);
Assert.Equal(JT809Header_Encrypt.None, jT809Package.Header.EncryptFlag);
Assert.Equal((uint)20180920, jT809Package.Header.MsgGNSSCENTERID);
Assert.Equal(JT809Enums.JT809BusinessType.DOWN_WARN_MSG, jT809Package.Header.MsgID);
Assert.Equal(new JT809Header_Version(1, 0, 0).ToString(), jT809Package.Header.Version.ToString());

//4.数据包体
JT809_0x9400 jT809_0X400 = (JT809_0x9400)jT809Package.Bodies;
Assert.Equal("粤A12345", jT809_0X400.VehicleNo);
Assert.Equal(JT809Enums.JT809VehicleColorType.黄色, jT809_0X400.VehicleColor);
Assert.Equal(JT809Enums.JT809SubBusinessType.DOWN_WARN_MSG_URGE_TODO_REQ, jT809_0X400.SubBusinessType);
Assert.Equal((uint)92, jT809_0X400.DataLength);

//5.子数据包体
JT809_0x9400_0x9401 jT809_0x9400_0x9401 = (JT809_0x9400_0x9401)jT809_0X400.JT809SubBodies;
Assert.Equal(JT809WarnSrc.车载终端, jT809_0x9400_0x9401.WarnSrc);
Assert.Equal(JT809WarnType.疲劳驾驶报警, jT809_0x9400_0x9401.WarnType);
Assert.Equal(DateTime.Parse("2018-09-27 10:24:00"), jT809_0x9400_0x9401.WarnTime);
Assert.Equal("123FFAA1", jT809_0x9400_0x9401.SupervisionID);
Assert.Equal(DateTime.Parse("2018-09-27 11:24:00"), jT809_0x9400_0x9401.SupervisionEndTime);
Assert.Equal(3, jT809_0x9400_0x9401.SupervisionLevel);
Assert.Equal("smallchi", jT809_0x9400_0x9401.Supervisor);
Assert.Equal("12345678901", jT809_0x9400_0x9401.SupervisorTel);
Assert.Equal("123456@qq.com", jT809_0x9400_0x9401.SupervisorEmail);

```

## JT809协议消息对照表

### 链路管理类

#### 主链路

|序号|消息ID|完成情况|消息体名称|
|:------:|:------:|:------:|:------:|
| 1 | 0x1001 | √ | 主链路登录请求消息 |
@@ -22,14 +197,19 @@
| 6 | 0x1006 | √ | 主链路连接保持应答消息 |
| 7 | 0x1007 | √ | 主链路断开通知消息 |
| 8 | 0x1008 | √ | 下级平台主动关闭链路通知消息 |
| 9 | 0x9001 | √ | 从链路连接请求消息 |
| 10 | 0x9002 | √ | 从链路连接应答消息 |
| 11 | 0x9003 | √ | 从链路注销请求消息 |
| 12 | 0x9004 | √ | 从链路注销应答消息 |
| 13 | 0x9005 | √ | 从链路连接保持请求消息 |
| 14 | 0x9006 | √ | 从链路连接保持应答消息 |
| 15 | 0x9007 | √ | 从链路断开通知消息 |
| 16 | 0x9008 | √ | 上级平台主动关闭链路通知消息 |

#### 从链路

|序号|消息ID|完成情况|消息体名称|
|:------:|:------:|:------:|:------:|
| 1 | 0x9001 | √ | 从链路连接请求消息 |
| 2 | 0x9002 | √ | 从链路连接应答消息 |
| 3 | 0x9003 | √ | 从链路注销请求消息 |
| 4 | 0x9004 | √ | 从链路注销应答消息 |
| 5 | 0x9005 | √ | 从链路连接保持请求消息 |
| 6 | 0x9006 | √ | 从链路连接保持应答消息 |
| 7 | 0x9007 | √ | 从链路断开通知消息 |
| 8 | 0x9008 | √ | 上级平台主动关闭链路通知消息 |

### 信息统计类



+ 1
- 1
src/JT809.Protocol/JT809Header.cs View File

@@ -35,7 +35,7 @@ namespace JT809.Protocol
/// </summary>
public uint MsgGNSSCENTERID { get; set; }
/// <summary>
/// 协议版本标识,上下级平台之间采用的标准协议版
/// 协议版本标识,上下级平台之间采用的标准协议版
/// 编号;长度为 3 个字节来表示,0x01 0x02 0x0F 标识
/// 的版本号是 v1.2.15,以此类推。
/// </summary>


Loading…
Cancel
Save