JT/T808协议之:0x0001终端通用应答和0x8001平台通用应答

similarJ · · 12 次点击 · · 开始浏览    

终端是指obd设备,既车载obd设备。

平台是指上文中说到的通过短信设置的上报IP指向的机器所提供的网关服务。

这两种消息一是终端设备发出的,一是平台发出的,都是通用应答的格式,所谓通用既是可以用于应答其他消息的一种消息格式。

0x0001终端通用应答

起始字节 字段 数据类型 描述及要求
0 应答流水号 WORD 对应的平台消息的流水号
2 应答 ID WORD 对应的平台消息的 ID
4 结果 BYTE 0:成功/确认;1:失败;2:消息有误;3:不支持

ps.上表省略消息头部分,默认所有的应答和发送都带有消息头

在平台下发指令或者设置终端参数(0x8103)时设备将应答此消息。

  • 应答流水号:一个四位字符的16进制字符串,是平台消息的流水号,可以为 0000
  • 应答ID: 四位字符16进制的消息id,如(8103,0001等)
  • 应答结果:两位字符的16进制字符,如表中的结果应答为,00:成功,01:失败,02:消息有误等

0x8001平台通用应答

设备发送的消息,除注册应答(0x8100)、校时应答(0x8f01)外其他数据数据发送都可使用此消息id应答。

如消息:7E80010005013183700516000005D2020000817E

  • 解析如下:
拆分编号 消息 说明
1 7e 消息标示
2 8100 消息ID
3 000F 消息体属性
4 013183700516 设备号
5 0000 消息流水号
6 05D2 对应的终端消息的流水号,既终端消息的流水号
7 0200 对应的终端消息的 ID
8 00 0:成功/确认;1:失败;2:消息有误;3:不支持;4:报警确认处理
9 81 校验码
10 7e 消息标示

消息头就不说了,这里需要注意的是 编号7 行的 0200是设备位置信息汇报的消息id,这说明这条信息是应答设备发出的位置信息汇报(0x0200)的结果, 回复不同的消息,这里的数据是不同的。

校验码的计算

上篇大概说了一下计算的方法,这里详细写下计算校验码和验证校验码的细节。

将接收到的消息还原转义后除去消息标识和校验位,按位异或得到的结果就是这条消息的校验码,和校验位比对验证其的一致性。
将要发出的消息封装好后出去标示位外,按位异或,得到的校验码放在消息尾部,然后转义。

#按位伪代码
function bcc(array data) {
    xor = data[0];

    for(i=1; i< data.length; i++) {
        xor ^= data[i]
    }
    return xor
}

熟悉上面的过程且看下如下代码:

  • 转义和还原转义代码举例
/**
 * Jt808协议解析
 */
class Jt808 implements Protocol {

    public $hex;

    /**
     * 消息体内容
     * @var |body
     */
    public $body;

    /**
     * 转义与转义还原时使用
     * @var array
     */
    public $search = ['7d01', '7d02'];
    public $replace = ['7d', '7e'];

    ...

    ...

    /**
     * 转义消息内容
     * 7d -> 7d01
     * 7e -> 7d02
     * @return mixed
     */
    public function escape($msg = '') {
        if ($msg) {
            return '7e' . str_replace($this->replace, $this->search, $msg) . '7e';
        } else {
            $this->hex = '7e' . str_replace($this->replace, $this->search, substr($this->hex, 2, -2)) . '7e';
        }
    }

    /**
     * 还原转义
     * 7d01 -> 7d
     * 7d02 -> 7e
     * @return mixed
     */
    public function descape($msg = '') {
        if ($msg) {
            return str_replace($this->search, $this->replace, $msg);
        } else {
            $this->hex = '7e' . str_replace($this->search, $this->replace, substr($this->hex, 2, -2)) . '7e';
        }
    }
}
  • 计算&验证校验码举例
#@param check_code|校验码 为空是计算校验码,不为空为验证校验码
function bcc($msg, $check_code = '') {
    //按两位字符切割字符串
    $check_str_array = str_split($msg, 2);
    $str_len = count($check_str_array);

    $xor = hexdec($check_str_array[0]);

    for ($i = 1; $i < $str_len; $i++) {
        $xor ^= hexdec($check_str_array[$i]);
    }
    $xor = dechex($xor);
    $xor = str_pad($xor, 2, 0, STR_PAD_LEFT); #不足两位前面填充0
    if (!$check_code) {
        return $xor;
    }
    return $xor == $check_code;
}

本文来自:Segmentfault

感谢作者:similarJ

查看原文:JT/T808协议之:0x0001终端通用应答和0x8001平台通用应答

12 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet