808通讯协议技术规范消息ID:0x0704数据分析,后附go代码

3 篇文章 0 订阅
1 篇文章 0 订阅

在这里插入图片描述
根据上面的分析,进行代码编写。
数据解析正常。

在这有个插曲,”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
}


  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

codears

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值