終端是指obd設備,既車載obd設備。php
平臺是指上文中說到的經過短信設置的上報IP指向的機器所提供的網關服務。this
這兩種消息一是終端設備發出的,一是平臺發出的,都是通用應答的格式,所謂通用既是能夠用於應答其餘消息的一種消息格式。code
起始字節 | 字段 | 數據類型 | 描述及要求 |
---|---|---|---|
0 | 應答流水號 | WORD | 對應的平臺消息的流水號 |
2 | 應答 ID | WORD | 對應的平臺消息的 ID |
4 | 結果 | BYTE | 0:成功/確認;1:失敗;2:消息有誤;3:不支持 |
ps.上表省略消息頭部分,默認全部的應答和發送都帶有消息頭字符串
在平臺下發指令或者設置終端參數(0x8103)時設備將應答此消息。it
0000
設備發送的消息,除註冊應答(0x8100)、校時應答(0x8f01)外其餘數據數據發送均可使用此消息id應答。io
如消息:7E80010005013183700516000005D2020000817Etable
拆分編號 | 消息 | 說明 |
---|---|---|
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
上篇大概說了一下計算的方法,這裏詳細寫下計算校驗碼和驗證校驗碼的細節。class
將接收到的消息還原轉義後除去消息標識和校驗位,按位異或獲得的結果就是這條消息的校驗碼,和校驗位比對驗證其的一致性。
將要發出的消息封裝好後出去標示位外,按位異或,獲得的校驗碼放在消息尾部,而後轉義。終端
#按位僞代碼 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; }