很多人问题JT808的指令怎么构造,在这在给大家介绍下哈。
首先要掌握JT808的报文格式、转义处理、校验码。
标识位 7E
消息头 功能号,如0200,消息上报
消息体 需要转义处理
检验码 异或校验码
标识位 7E
如:7E80010004013600000003AE5C00010200407E
先来段简单代码,异或校验,作用是保证数据的一致性
public static String yh(String temp){
byte xor=0;
byte array[]=Utils.hexToBytes(temp);
for(byte b :array)xor=xor ^= b;
return Utils.bytesToHex(new byte[]{xor}, 1);
}
转义处理麻烦些,核心思想是不要出现7E,有的话转义
public String decode(String str) {
StringBuilder sb = new StringBuilder();
sb.append("7E");
for (int i = 2; i < str.length() - 2; i += 2) {
switch (Integer.parseInt(str.substring(i, i + 4), 16)) {
case 0x7D01:
sb.append("7D");
i += 2;
break;
case 0x7D02:
sb.append("7E");
i += 2;
break;
default:
sb.append(str.substring(i, i + 2));
}
}
sb.append(str.substring(str.length() - 2));
return sb.toString();
}
public String encode(String str) {
StringBuilder sb = new StringBuilder();
sb.append("7E");
for (int i = 2; i < str.length() - 2; i += 2) {
switch (Integer.parseInt(str.substring(i, i + 2), 16)) {
case 0x7D:
sb.append("7D01");
break;
case 0x7E:
sb.append("7D02");
break;
default:
sb.append(new String(str.substring(i, i + 2)));
}
}
sb.append("7E");
return sb.toString();
}
有这两个做为基础接入来会好很多,可以先写个基类把公共部分写到一起再继承。接下来写子信令时就写简单了
基类如下:
package com.mall1024.jt808.cmd;
import java.util.Random;
/**
7E
8100指令
0005 数据长度
088888888888
0000 包序
0001 收到注册的包序
00 成功
3131 鉴权码11
05 校验
7E
* @author lingx
*
*/
public class CmdBubiao {
static Random random=new Random();
private String cmd,body,tid;
public CmdBubiao(String cmd,String body,String tid){
this.cmd=cmd;
this.body=body;
this.tid=tid;
}
public String toCommand(){
StringBuilder sb=new StringBuilder();sb.append("7E");
sb.append(this.cmd).append(Utils.leftAdd0(Integer.toHexString(this.body.length()/2), 4)).append(this.tid).append(getXh());
sb.append(body).append(Utils.yh(sb.toString().substring(2)));sb.append("7E");
String temp=encode(sb.toString());
return temp.toUpperCase();
}
/**
* 取序号
* @return
*/
public String getXh(){
return Utils.leftAdd0(Integer.toHexString(random.nextInt(65535)),4).toUpperCase();
}
public String decode(String str) {
StringBuilder sb = new StringBuilder();
sb.append("7E");
for (int i = 2; i < str.length() - 2; i += 2) {
switch (Integer.parseInt(str.substring(i, i + 4), 16)) {
case 0x7D01:
sb.append("7D");
i += 2;
break;
case 0x7D02:
sb.append("7E");
i += 2;
break;
default:
sb.append(str.substring(i, i + 2));
}
}
sb.append(str.substring(str.length() - 2));
return sb.toString();
}
public String encode(String str) {
StringBuilder sb = new StringBuilder();
sb.append("7E");
for (int i = 2; i < str.length() - 2; i += 2) {
switch (Integer.parseInt(str.substring(i, i + 2), 16)) {
case 0x7D:
sb.append("7D01");
break;
case 0x7E:
sb.append("7D02");
break;
default:
sb.append(new String(str.substring(i, i + 2)));
}
}
sb.append("7E");
return sb.toString();
}
public String getTid(){
return this.tid;
}
}
有了基类写具体的功能就很快,比如通用指令8001
package com.mall1024.jt808.cmd;
public class Cmd8001 extends CmdBubiao {
public Cmd8001(String tid,String mainCmd,String subCmd){
super("8001",subCmd+mainCmd+"00",tid);
}
public Cmd8001(String tid,String mainCmd,String subCmd,int code){
super("8001",subCmd+mainCmd+Utils.leftAdd0(Integer.toHexString(code), 2),tid);
}
public static void main(String args[]){
Cmd8001 cmd=new Cmd8001("013600000003","0102","00");//7E80010004013600000003AE5C00010200407E
System.out.println(cmd.toCommand());
}
}
演示地址
http://gps.lingx.com/
账号:admin
密码:123456
GPS设备入口
IP:47.100.112.218
端口:8808