根据上面的分析,进行代码编写。
数据解析正常。
在这有个插曲,”JT-T 808-2013道路运输车辆卫星定位系统北斗兼容车载终端通讯协议技术规范.pdf”这个文件里表77位置汇报数据体的说明中让参考8.12,实际上应该参考8.18,需要特别注意。。
希望帮到一些人。
```go
package main
import (
"fmt"
"strconv"
"strings"
)
func main() {
str := "7e0704018401357924681013a5000501004b00000000000c00030212a58c06c64dfe004800000149220523123843010400001127030200002504000000002a0200002b040000000030011d310119910101920400000000140400000000004b00000000000c00030212a58c06c64dfe004800000149220523123853010400001127030200002504000000002a0200002b040000000030011f310119910101920400000040140400000000004b00000000000c00030212a58c06c64dfe004900000149220523123903010400001127030200002504000000002a0200002b040000000030011f310119910101920400000040140400000000004b00000000000c00030212a58c06c64dfe004a00000149220523123913010400001127030200002504000000002a0200002b040000000030011f310119910101920400000040140400000000004b00000000000c00030212a58c06c64dfe004a00000149220523123923010400001127030200002504000000002a0200002b040000000030011f310119910101920400000040140400000000dd7e"
str = removeIdentity(str)
rawMsg := restoreIdentity(str)
//消息类型
msgType := rawMsg[0:4]
//消息体属性
//15、14保留|13分包|12、11、10数据加密方式|9-0消息体长度
msgAttr := rawMsg[4:8]
b := hexStrToByteString(msgAttr)
fmt.Printf("msgAttr byte:%s len:%d \n", b, len(b))
multiPackage := false
if b[2] == '1' {
//表示消息体为长消息,进行分包发送处理
multiPackage = true
}
//手机号:BCD[6] 8421 码,n 字节
phoneNumber := rawMsg[9:20]
//消息流水号:WORD
msgOrderNum := rawMsg[20:24]
msgBodyIndex := 24
fmt.Println("msgType:", msgType, " msgAttr:", msgAttr, " phoneNumber:", phoneNumber, " msgOrderNum:", msgOrderNum)
if multiPackage {
//消息包总数
packageNum := rawMsg[msgBodyIndex : msgBodyIndex+4]
msgBodyIndex += 4
//包序号
packageSerialNum := rawMsg[msgBodyIndex : msgBodyIndex+4]
msgBodyIndex += 4
fmt.Println("packageNum:", packageNum, " packageSerialNum:", packageSerialNum)
}
if msgType == "0704" {
//
dataNumStr := rawMsg[msgBodyIndex : msgBodyIndex+4]
msgBodyIndex += 4
dataTypeStr := rawMsg[msgBodyIndex : msgBodyIndex+2]
msgBodyIndex += 2
fmt.Println("msgType:", msgType, " msgAttr:", msgAttr, " phoneNumber:", phoneNumber, " msgOrder:", msgOrderNum, " dataNum:", dataNumStr, " dataType:", dataTypeStr)
dataNum, err := strconv.ParseInt(dataNumStr, 16, 32)
if err != nil {
panic(err)
}
dataType, err := strconv.ParseInt(dataTypeStr, 16, 32)
if err != nil {
panic(err)
}
fmt.Println("dataNum:", dataNum, " dataType:", dataType)
if dataType == 1 {
fmt.Println("盲区补报")
}
msgBody := rawMsg[msgBodyIndex:]
for i := 0; i < int(dataNum); i++ {
singleMsgLenStr := msgBody[0:4]
singleMsgLen, err := strconv.ParseInt(singleMsgLenStr, 16, 32)
if err != nil {
panic(err)
}
fmt.Println("singleMsgLen2:", singleMsgLen)
singleMsgContent := msgBody[4 : 4+singleMsgLen*2] //每个位置上报数据的内容
//8.18位置信息汇报
//报警标志:DWORD 32位 表24报警标志位定义
index := 0
alarmIdentity := singleMsgContent[index : index+8]
index += 8
fmt.Println("alarmIdentity:", hexStrToByteString(alarmIdentity))
//状态:DWORD 32位
status := singleMsgContent[index : index+8]
index += 8
statusBinaryStr := hexStrToByteString(status)
//statusBinaryStr[31:32]等于1表示acc处于开启状态;0表示acc关闭状态
fmt.Println("status:", statusBinaryStr, " acc:", statusBinaryStr[31:32] == "1")
//纬度:DWORD 32位
lat := singleMsgContent[index : index+8]
index += 8
latI, err := strconv.ParseInt(lat, 16, 32)
if err != nil {
panic(err)
}
fmt.Println("lat string:", lat, " latI:", latI)
if latI != 0 {
latS := strconv.FormatInt(latI, 10)
latS2 := strconv.FormatInt(latI/1000000, 10)
fmt.Println("latS:", latS, " latS2:", latS2)
latFinalStr := latS2 + "." + latS[len(latS)-6:]
fmt.Println("latFinalStr:", latFinalStr)
}
//经度:DWORD 32位
lng := singleMsgContent[index : index+8]
index += 8
lngI, err := strconv.ParseInt(lng, 16, 32)
if err != nil {
panic(err)
}
fmt.Println("lng string:", lng, " lngI:", lngI)
if lngI != 0 {
lngS := strconv.FormatInt(lngI, 10)
lngS2 := strconv.FormatInt(lngI/1000000, 10)
fmt.Println("lngS:", lngS, " lngS2:", lngS2)
lngFinalStr := lngS2 + "." + lngS[len(lngS)-6:]
fmt.Println("lngFinalStr:", lngFinalStr)
}
//高程:WORD 16位 单位:米
height := singleMsgContent[index : index+4]
index += 4
iHeight, err := strconv.ParseInt(height, 16, 32)
if err != nil {
panic(err)
}
fmt.Println("height:", iHeight)
//速度:WORD 16位 单位:1/10km/h
speed := singleMsgContent[index : index+4]
index += 4
iSpeed, err := strconv.ParseInt(speed, 16, 32)
if err != nil {
panic(err)
}
fmt.Println("speed:", iSpeed)
//方向:WORD 16位 0-359,正北为0,顺时针
direction := singleMsgContent[index : index+4]
index += 4
iDirection, err := strconv.ParseInt(direction, 16, 32)
if err != nil {
panic(err)
}
fmt.Println("direction:", iDirection)
//时间:BCD[6] YY-MM-DD-hh-mm-ss格式
msgTime := singleMsgContent[index : index+12]
index += 12
fmt.Println("msgTime:", "20"+msgTime)
msgBody = msgBody[4+singleMsgLen*2:]
fmt.Println("")
}
}
}
func removeIdentity(str string) string {
str = str[2:]
str = str[:len(str)-2]
return str
}
func restoreIdentity(str string) string {
if strings.Contains(str, "7d02") {
str = strings.ReplaceAll(str, "7d02", "7e")
}
if strings.Contains(str, "7d01") {
str = strings.ReplaceAll(str, "7d01", "7d")
}
return str
}
//将16进制的字符串转为2进制的字符串
func hexStrToByteString(str string) string {
var ret string
if str == "" || len(str)%2 != 0 {
return ""
}
for _, ch := range str {
ch_hex, err := strconv.ParseInt(string(ch), 16, 8)
if err != nil {
panic(err)
}
ch_bin := ""
for ; ch_hex > 0; ch_hex /= 2 {
b := ch_hex % 2
ch_bin = strconv.Itoa(int(b)) + ch_bin
}
fill := 4 - len(ch_bin)
for fill > 0 {
ch_bin = "0" + ch_bin
fill -= 1
}
ret += ch_bin
}
return ret
}