-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
67 changed files
with
3,914 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,61 @@ | ||
# protocol-jt808 | ||
# protocol-jt808 | ||
|
||
`protocol-jt808` 是一个实现了对《JT/T808 2019道路运输车辆卫星定位系统终端通讯协议及数据格式》数据进行解析与拼接的工具库。 | ||
|
||
* 基于`JDK8`,`Netty` | ||
|
||
# 1 使用准备 | ||
|
||
## 1.1 引入依赖 | ||
|
||
`Maven` | ||
|
||
```xml | ||
|
||
<dependency> | ||
<groupId>com.shisx.protocol</groupId> | ||
<artifactId>protocol-jt808</artifactId> | ||
<version>1.0.0</version> | ||
</dependency> | ||
``` | ||
|
||
## 1.2 数据解析 | ||
|
||
> 将字节数组解析成`JT808Message`对象 | ||
```java | ||
class Example { | ||
public static void main(String[] args) { | ||
byte[] bytes = ...; | ||
JT808Message jt808Message = JT808Message.parse(bytes); | ||
} | ||
} | ||
``` | ||
|
||
## 1.2 数据拼装 | ||
|
||
> 将`JT808Message`对象转换字节数组 | ||
示例:为手机号为`123456789123456789`的终端构建一个`0x8100`消息 | ||
|
||
```java | ||
class Example { | ||
public static void main(String[] args) { | ||
Msg8100 body = new Msg8100(); | ||
body.setAckSn((short) 1); | ||
body.setResult((byte) 0); | ||
body.setAuthCode("success"); | ||
|
||
JT808Message.build("123456789123456789", body); | ||
} | ||
} | ||
``` | ||
|
||
## 1.2 作为服务 | ||
|
||
### 1.2.1 TCP服务 | ||
|
||
启动一个TCP服务,监听客户端发送的消息,并将消息解析成[JT808Message](/src/main/java/com/shisx/protocol/jt808/message/JT808Message.java) | ||
对象,并进行业务处理 | ||
|
||
[TcpListener](/src/main/java/com/shisx/protocol/jt808/network/TcpListener.java) |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<groupId>com.shisx.protocol</groupId> | ||
<artifactId>protocol-jt808</artifactId> | ||
<version>1.0.0</version> | ||
<name>Protocol Of JTT808</name> | ||
|
||
<properties> | ||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
</properties> | ||
|
||
<developers> | ||
<developer> | ||
<id>shisx</id> | ||
<name>ShiShouXing</name> | ||
<email>[email protected]</email> | ||
</developer> | ||
</developers> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>org.projectlombok</groupId> | ||
<artifactId>lombok</artifactId> | ||
<version>1.18.32</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>io.netty</groupId> | ||
<artifactId>netty-all</artifactId> | ||
<version>4.1.107.Final</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.apache.commons</groupId> | ||
<artifactId>commons-lang3</artifactId> | ||
<version>3.5</version> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>org.slf4j</groupId> | ||
<artifactId>slf4j-api</artifactId> | ||
<version>1.5.6</version> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>junit</groupId> | ||
<artifactId>junit</artifactId> | ||
<version>4.13.2</version> | ||
<scope>test</scope> | ||
</dependency> | ||
</dependencies> | ||
|
||
<build> | ||
<resources> | ||
<resource> | ||
<directory>src/main/resources</directory> | ||
<filtering>true</filtering> | ||
</resource> | ||
</resources> | ||
|
||
<plugins> | ||
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-compiler-plugin</artifactId> | ||
<version>3.3</version> | ||
<configuration> | ||
<source>1.8</source> | ||
<target>1.8</target> | ||
</configuration> | ||
</plugin> | ||
</plugins> | ||
</build> | ||
</project> |
51 changes: 51 additions & 0 deletions
51
src/main/java/com/shisx/protocol/jt808/message/IBuilder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package com.shisx.protocol.jt808.message; | ||
|
||
import io.netty.buffer.ByteBuf; | ||
|
||
public interface IBuilder { | ||
|
||
byte[] build(); | ||
|
||
default ByteBuf allowBuffer(int initialCapacity) { | ||
return io.netty.buffer.Unpooled.buffer(initialCapacity, 10240); | ||
} | ||
|
||
default ByteBuf allowBuffer(int initialCapacity, int maxCapacity) { | ||
return io.netty.buffer.Unpooled.buffer(initialCapacity, maxCapacity); | ||
} | ||
|
||
default ByteBuf fixBuffer(int capacity) { | ||
return io.netty.buffer.Unpooled.buffer(capacity, capacity); | ||
} | ||
|
||
default byte[] readReadableBytes(ByteBuf byteBuf) { | ||
byte[] bytes = new byte[byteBuf.readableBytes()]; | ||
byteBuf.readBytes(bytes); | ||
return bytes; | ||
} | ||
|
||
default void writeFixLengthBytes(ByteBuf byteBuf, byte[] bytes, int length, int mode) { | ||
int zeros = bytes == null ? length : length - bytes.length; | ||
|
||
// 前补0x00 | ||
if (mode == 0) { | ||
if (zeros > 0) { | ||
byteBuf.writeZero(zeros); | ||
} | ||
if (bytes != null && bytes.length > 0) { | ||
byteBuf.writeBytes(bytes); | ||
} | ||
} | ||
|
||
// 后补0x00 | ||
if (mode == 1) { | ||
if (bytes != null && bytes.length > 0) { | ||
byteBuf.writeBytes(bytes); | ||
} | ||
if (zeros > 0) { | ||
byteBuf.writeZero(zeros); | ||
} | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package com.shisx.protocol.jt808.message; | ||
|
||
import io.netty.buffer.ByteBuf; | ||
|
||
public interface IParser { | ||
|
||
void parse(ByteBuf message); | ||
|
||
} |
106 changes: 106 additions & 0 deletions
106
src/main/java/com/shisx/protocol/jt808/message/JT808Message.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
package com.shisx.protocol.jt808.message; | ||
|
||
import com.shisx.protocol.jt808.util.JT808Utils; | ||
import com.shisx.protocol.jt808.util.ProtocolUtil; | ||
import io.netty.buffer.ByteBuf; | ||
import io.netty.buffer.Unpooled; | ||
import lombok.Data; | ||
|
||
/** | ||
* Desc | ||
* | ||
* @author Brook | ||
*/ | ||
@Data | ||
public class JT808Message implements IParser, IBuilder { | ||
|
||
// 消息头 | ||
private MessageHead messageHead; | ||
// 消息体 | ||
private MessageBody messageBody; | ||
|
||
@Override | ||
public void parse(ByteBuf message) { | ||
messageHead = new MessageHead(); | ||
messageHead.parse(message); | ||
|
||
try { | ||
messageBody = MessageBody.buildByMsgId(messageHead.getMsgId()); | ||
if (messageBody == null) { | ||
throw new RuntimeException("Can't parse the message: " + ProtocolUtil.short2Hex(messageHead.getMsgId())); | ||
} | ||
|
||
messageBody.parse(message); | ||
} catch (RuntimeException e) { | ||
throw e; | ||
} catch (Exception e) { | ||
throw new RuntimeException("The message body parsing failed.", e); | ||
} | ||
} | ||
|
||
@Override | ||
public byte[] build() { | ||
byte[] bodyBytes = messageBody.build(); | ||
messageHead.setBodyLength((short) bodyBytes.length); | ||
return _build(messageHead.build(), bodyBytes); | ||
} | ||
|
||
public static JT808Message parse(byte[] bytes) { | ||
// 转义还原 | ||
byte[] finalData = JT808Utils.flagRestore(bytes); | ||
|
||
// 验证校验和 | ||
if (!JT808Utils.verifyCRC(finalData)) { | ||
throw new RuntimeException("校验和不通过"); | ||
} | ||
|
||
// 解析 | ||
JT808Message jt808Message = new JT808Message(); | ||
jt808Message.parse(Unpooled.wrappedBuffer(finalData)); | ||
return jt808Message; | ||
} | ||
|
||
public static byte[] build(String terminalNumber, MessageBody messageBody) { | ||
JT808Message jt808Message = new JT808Message(); | ||
|
||
byte[] bodyBytes = messageBody.build(); | ||
|
||
MessageHead head = new MessageHead(); | ||
head.setMsgId(MessageBody.getMsgIdByClass(messageBody.getClass())); | ||
head.setMsgSn(JT808Utils.genMsgSn()); | ||
head.setProtocolVersion((byte) 0x01); | ||
head.setTerminalNumber(terminalNumber); | ||
head.setBodyLength(bodyBytes == null ? 0 : (short) bodyBytes.length); | ||
|
||
return jt808Message._build(head.build(), bodyBytes); | ||
} | ||
|
||
private byte[] _build(byte[] headBytes, byte[] bodyBytes) { | ||
ByteBuf byteBuf = allowBuffer(1024); | ||
|
||
// 标识位-头 | ||
byteBuf.writeByte((byte) 0x7E); | ||
|
||
// 消息头 | ||
byteBuf.writeBytes(headBytes); | ||
|
||
// 消息体 | ||
if (bodyBytes != null && bodyBytes.length > 0) { | ||
byteBuf.writeBytes(bodyBytes); | ||
} | ||
|
||
// 校验码 | ||
byte[] currBytes = new byte[byteBuf.readerIndex(1).readableBytes()]; | ||
byteBuf.readBytes(currBytes); | ||
byteBuf.writeByte(ProtocolUtil.xor(currBytes)); | ||
|
||
// 标识位-尾 | ||
byteBuf.writeByte((byte) 0x7E); | ||
|
||
// 转义,并返回数据 | ||
byte[] allBytes = new byte[byteBuf.readerIndex(0).readableBytes()]; | ||
byteBuf.readBytes(allBytes); | ||
return JT808Utils.flagTransference(allBytes); | ||
} | ||
|
||
} |
52 changes: 52 additions & 0 deletions
52
src/main/java/com/shisx/protocol/jt808/message/MessageBody.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package com.shisx.protocol.jt808.message; | ||
|
||
import java.util.HashMap; | ||
import java.util.Map; | ||
|
||
public abstract class MessageBody implements IParser, IBuilder { | ||
|
||
public static MessageBody buildByMsgId(short msgId) throws IllegalAccessException, InstantiationException { | ||
Class<? extends MessageBody> clazz = BODY_MAP.get(msgId); | ||
return clazz == null ? null : clazz.newInstance(); | ||
} | ||
|
||
public static short getMsgIdByClass(Class<? extends MessageBody> clazz) { | ||
return BODY_MAP2.get(clazz); | ||
} | ||
|
||
private static final Map<Short, Class<? extends MessageBody>> BODY_MAP = new HashMap<>(); | ||
private static final Map<Class<? extends MessageBody>, Short> BODY_MAP2 = new HashMap<>(); | ||
|
||
static { | ||
register((short) 0x0001, Msg0001.class); | ||
register((short) 0x0002, Msg0002.class); | ||
register((short) 0x0003, Msg0003.class); | ||
register((short) 0x0004, Msg0004.class); | ||
register((short) 0x0100, Msg0100.class); | ||
register((short) 0x0102, Msg0102.class); | ||
register((short) 0x0104, Msg0104.class); | ||
register((short) 0x0107, Msg0107.class); | ||
register((short) 0x0108, Msg0108.class); | ||
register((short) 0x0200, Msg0200.class); | ||
register((short) 0x0201, Msg0201.class); | ||
register((short) 0x8001, Msg8001.class); | ||
register((short) 0x8004, Msg8004.class); | ||
register((short) 0x8100, Msg8100.class); | ||
register((short) 0x8103, Msg8103.class); | ||
register((short) 0x8104, Msg8104.class); | ||
register((short) 0x8105, Msg8105.class); | ||
register((short) 0x8106, Msg8106.class); | ||
register((short) 0x8107, Msg8107.class); | ||
register((short) 0x8108, Msg8108.class); | ||
register((short) 0x8201, Msg8201.class); | ||
register((short) 0x8202, Msg8202.class); | ||
register((short) 0x8203, Msg8203.class); | ||
register((short) 0x8204, Msg8204.class); | ||
register((short) 0x8300, Msg8300.class); | ||
} | ||
|
||
private static void register(short msgId, Class<? extends MessageBody> clazz) { | ||
BODY_MAP.put(msgId, clazz); | ||
BODY_MAP2.put(clazz, msgId); | ||
} | ||
} |
Oops, something went wrong.