主流项目还是得用java
Java版的演示地址:
http://gps.lingx.com
账号:admin
密码:123456
以下JT808解析的部分代码:
package jt808
import (
"bytes"
"encoding/binary"
"fmt"
"log"
"net"
"lingx.com/jt808-server/tools"
)
var Obj *Jt808
//初始化函数
func init() {
Obj = new(Jt808)
Obj.sessions = make(map[string]net.Conn)
Obj.fbCache = make(map[string][]byte)
Obj.msgHandleMap = make(map[uint16]func(data []byte, tid string, sn uint16, conn net.Conn))
Obj.lastPosition = make(map[string]map[string]interface{})
}
func GetJT808Object() *Jt808 {
return Obj
}
type Jt808 struct {
//会话缓存
sessions map[string]net.Conn
//消息处理函数缓存
msgHandleMap map[uint16]func(data []byte, tid string, sn uint16, conn net.Conn)
//分包缓存
fbCache map[string][]byte
//最新数据缓存
lastPosition map[string]map[string]interface{}
}
//注册消息处理函数
func (jt808 *Jt808) RegisterFun(msgId uint16, f func(data []byte, tid string, sn uint16, conn net.Conn)) {
jt808.msgHandleMap[msgId] = f
}
//协议解析
func (jt808 *Jt808) Analyze(data []byte, conn net.Conn) {
if !jt808.CheckJt808Packet(data) {
log.Fatal("JT808校验码不通过,丢掉该包")
return
}
data = jt808.Decode(data) //解码
var byteBuf = new(tools.ByteBuf)
byteBuf.WriteBytes(data)
byteBuf.ReadByte() //0x7E
var msgId = byteBuf.ReadUInt16()
var length = byteBuf.ReadUInt16()
var content []byte //正文
isFB := (length & 0b0010000000000000) > 0 //是否分包
isVersion := (length & 0b0100000000000000) > 0 //是否版本标识
var tid string
if isVersion {
byteBuf.ReadByte() // version
tid = byteBuf.ReadBCD(10)
} else {
tid = byteBuf.ReadBCD(6)
}
jt808.sessions[tid] = conn //创建Session
var sn = (byteBuf.ReadUInt16()) //流水号
if isFB {
//分包处理
fbbytes := make([]byte, 4)
byteBuf.ReadBytes(fbbytes)
var maxPack, currPack uint16
bytesBuffer := bytes.NewBuffer(fbbytes[0:2])
binary.Read(bytesBuffer, binary.BigEndian, &maxPack)
bytesBuffer = bytes.NewBuffer(fbbytes[2:4])
binary.Read(bytesBuffer, binary.BigEndian, &currPack)
log.Println("分包max,curr", maxPack, currPack)
var key = tid + fmt.Sprintf("%04X", msgId)
content = make([]byte, length&0x3ff)
byteBuf.ReadBytes(content)
if maxPack == currPack {
//合并分包
jt808.fbCache[key] = append(jt808.fbCache[key], content...)
content = jt808.fbCache[key]
if content == nil {
return
}
} else {
if currPack == 1 {
tempArr := make([]byte, 0)
tempArr = append(tempArr, content...)
jt808.fbCache[key] = tempArr
} else {
jt808.fbCache[key] = append(jt808.fbCache[key], content...)
}
return //等待传包结束
}
} else {
content = make([]byte, length&0x3ff)
byteBuf.ReadBytes(content)
}
byteBuf.ReadByte() //check
byteBuf.ReadByte() //0x7E
//fmt.Println(msgId, tid)
handleFun := jt808.msgHandleMap[msgId]
if handleFun != nil {
handleFun(content, tid, sn, conn)
} else {
log.Fatalln("JT808未实现处理消息:", fmt.Sprintf("%04X", msgId))
}
}
//检查校验码
func (jt808 *Jt808) CheckJt808Packet(bytes []byte) bool {
var xor byte = 0
check := (bytes)[len(bytes)-2]
for _, b := range (bytes)[1 : len(bytes)-2] {
xor ^= b
}
return check == xor
}
//根据J808规则转码
func (jt808 *Jt808) Encode(bytes []byte) []byte {
array := make([]byte, 0)
for i, b := range bytes {
if i == 0 || i == len(bytes)-1 {
array = append(array, b)
} else if b == 0x7D {
array = append(array, 0x7D)
array = append(array, 0x01)
} else if b == 0x7E {
array = append(array, 0x7D)
array = append(array, 0x02)
} else {
array = append(array, b)
}
}
_ = bytes //释放原数组
return array
}
//根据JT808规则解码
func (jt808 *Jt808) Decode(bytes []byte) []byte {
array := make([]byte, 0)
length := len(bytes)
array = append(array, 0x7E)
for i := 1; i < length-1; i++ {
if (bytes)[i] == 0x7D {
if (bytes)[i+1] == 0x01 {
array = append(array, 0x7D)
i++
} else if (bytes)[i+1] == 0x02 {
array = append(array, 0x7E)
i++
} else {
array = append(array, (bytes)[i])
}
} else {
array = append(array, (bytes)[i])
}
}
array = append(array, 0x7E)
_ = bytes //释放原数组
return array
}