123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- <?php
- namespace Workerman\Protocols;
- class Lhtlv {
-
-
- public static function input( $buffer, $connection ){
- if (strlen($buffer) < 4) {
- return 0;
- }
- $unpack_data = unpack('C1magic/C1method/n1length', $buffer);
- return $unpack_data['length'] + 6;
- }
-
-
- private static function bin2str( $hex, $space ){
- $data = unpack("C*chars",$hex);
- $bin = '';
- foreach($data as $key=>$value){
- $bin .= sprintf('%02X',$value);
- if($space)
- $bin .= ' ';
- }
- return trim($bin);
- }
-
-
- private static function packValue( $value ){
- if($value['cmd'] == 0x02){
- return pack('C1',$value['result']);
- }
- elseif($value['cmd'] == 0x04){
- return pack('C1',$value['result']);
- }
- elseif($value['cmd'] == 0x09){
- return pack('C1n1',$value['type'],$value['data']);
- }
- elseif($value['cmd'] == 0x01 || $value['cmd'] == 0xBC){
- return pack('H*', $value['data']);
- }
- else{
- return false;
- }
- }
-
-
- private static function unpackValue( $cmd, $value, $length ){
- if($cmd == 0x01){ //设备注册
- if($length == 6)
- return array('uid' => self::bin2str($value,false) );
- else
- return null;
- }
- elseif($cmd == 0x05){ //设备心跳
- return null;
- }
- elseif($cmd == 0x07){ //上报IMSI
- if($length == 21){
- return array(
- 'uid' => self::bin2str(substr($value,0,6),false) ,
- 'imsi' => substr($value,6,15)
- );
- }
- else
- return null;
- }
- elseif($cmd == 0x08){ //设备响应
- if($length == 2){
- return array(
- 'type' => Ord(substr($value,0,1)) ,
- 'result' => Ord(substr($value,1,1))
- );
- }
- else
- return null;
- }
- elseif($cmd == 0xbc){ //上报标签
- if($length >= 14){
- //解析设置的时间间隔,设置的设备数量
- $setting = unpack('n1maxtime/n1maxlabels', substr($value,10,4));
- //解析车辆信息
- $count = ($length - 14)/14;
- $labels = array();
- for($i=0;$i<$count;$i++){
- //解析RFID
- $j = 14+$i*14;
- $rfid = self::bin2str(substr($value,$j,6),false);
- $j += 6;
- //解析SSD信号强度
- $ssd = Ord(substr($value,$j,1));
- //解析时间
- $year1 = Ord(substr($value,$j+1,1));
- $year2 = Ord(substr($value,$j+2,1));
- $month = Ord(substr($value,$j+3,1));
- $day = Ord(substr($value,$j+4,1));
- $hour = Ord(substr($value,$j+5,1));
- $minute = Ord(substr($value,$j+6,1));
- $second = Ord(substr($value,$j+7,1));
- $hour = sprintf('%02d',$hour);
- $minute = sprintf('%02d',$minute);
- $second = sprintf('%02d',$second);
- $time = date('Y-m-d').' '.$hour.':'.$minute.':'.$second;
- if(strtotime($time) > time()){
- $time = date('Y-m-d H:i:s',strtotime('-1 day',strtotime($time)));
- }
- $info = array(
- 'rfid' => $rfid,
- 'ssd' => $ssd,
- 'time' => $time
- );
- array_push($labels,$info);
- }
- return array(
- 'maxtime' => $setting['maxtime'],
- 'maxlabels' => $setting['maxlabels'],
- 'labels' => $labels
- );
- }
- else
- return null;
- }
- elseif($cmd == 0xbd){ //上报报警
- if($length == 1)
- return array('v' => self::bin2str($value) );
- else
- return null;
- }
- return $value;
- }
-
-
- public static function decode( $buffer ){
- //解码头部数据
- $unpack_head = unpack('C1magic/C1cmd/n1length', $buffer);
- $unpack_head['method'] = sprintf("method%'04x",$unpack_head['cmd']);
- //判断头部引导符
- if( $unpack_head['magic'] != 0xEC )
- return null;
- //判断最后结尾符
- if( Ord(substr($buffer,-1)) != 0x68 )
- return null;
- //判断签名是否正确
-
- //如果长度等于0则没有值数据
- if($unpack_head['length'] == 0)
- return $unpack_head;
-
- //解码值数据
- $value = substr($buffer,4,$unpack_head['length']);
- $unpack_value = self::unpackValue($unpack_head['cmd'],$value,$unpack_head['length']);
- if(!$unpack_value)
- return null;
-
- //头部+值一起返回
- return array_merge($unpack_head,$unpack_value);
- }
-
-
- public static function encode( $value ){
- $pack_value = self::packValue($value);
- $length = strlen($pack_value);
- $sign = $value['cmd'] + $length;
- for($i=0;$i<strlen($pack_value);$i++){
- $sign += Ord($pack_value[$i]);
- }
- $buf = pack('C1C1n1', 0xEC,$value['cmd'],$length) . $pack_value .pack('C1', $sign). pack('C1', 0x68);
- return $buf;
- }
-
-
- private static function str2bin( $text ){
- if (!is_string($text))
- return null;
- $arr = explode(' ',$text);
- $bin = '';
- foreach($arr as $hex){
- if(strlen($hex) == 2){
- $bin .= chr( hexdec($hex) );
- }
- }
- return $bin;
- }
-
- }
|