<?php
namespace Workerman\Protocols;

class Lhtcp {
			


 
	public static function input( $buffer, $connection ){
		if (strlen($buffer) < 6) {
			return 0;
		}
		if(Ord($buffer[0]) == 0xF5){
			$unpack_data = unpack('C4magic/C1length', $buffer);
			return $unpack_data['length'];
		}else if(Ord($buffer[0]) == 0xF6){
			$unpack_data = unpack('C4magic/S1length', $buffer);
			return $unpack_data['length'];
		}else if(Ord($buffer[0]) == 0xEC){
			$unpack_data = unpack('C1magic/C1method/n1length', $buffer);
			return $unpack_data['length'] + 6;
		}else{
			return strlen($buffer);
		}
		
		
	}
	
 
	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'] == 0x01){
			return '';
		}
		elseif($value['cmd'] == 0x0F){
			return '';
		}
		else{
			return false;
		}
	}
	
 
	private static function unpackValue( $cmd, $value, $length ){
		if($cmd == 0x0F){ //设备心跳
			return array();
		}
		elseif($cmd == 0x01){ //上报标签
				//解析车辆信息
				$count = $length/6;
				$labels = array();
				for($i=0;$i<$count;$i++){
					$rfid = self::bin2strr(substr($value,$j,6),false);
					$j += 6;
					$info = array(
						'rfid' => $rfid,
						'time' => date('Y-m-d H:i:s') 
					);
					array_push($labels,$info);
				}
				return array(
					'labels' => $labels
				);
		}
		return $value;
	}
	
 
	public static function decode( $buffer ){
		//判断最后结尾符
		if( Ord(substr($buffer,-2,1)) != 0x0D || Ord(substr($buffer,-1)) != 0x0A ){
			return null;
		}
		//解码头部数据
		$unpack_magic = unpack('C4magic', $buffer);
		//判断头部引导符
		if( $unpack_magic['magic1'] == 0xF6 && $unpack_magic['magic2'] == 0xF6 && 
		   $unpack_magic['magic3'] == 0xF6 && $unpack_magic['magic4'] == 0xF6){
		   $unpack_head = unpack('S1length/C1project/C1type/', substr($buffer,4,4));
			$unpack_head['version'] = 0xF6;
			$unpack_head['cmd'] = Ord(substr($buffer,14,1));
			$unpack_head['method'] = sprintf("method%'04x",$unpack_head['cmd']);
			$unpack_head['uid'] = self::bin2strr(substr($buffer,8,6),false);
			$unpack_head['uid_raw'] = substr($buffer,8,6);
			//解码值数据
			$value = substr($buffer,15,$unpack_head['length']-17);
			$unpack_value = self::unpackValue($unpack_head['cmd'],$value,$unpack_head['length']-17);
		}
		//判断头部引导符
		else if( $unpack_magic['magic1'] == 0xF5 && $unpack_magic['magic2'] == 0xF5 && 
		   $unpack_magic['magic3'] == 0xF5 && $unpack_magic['magic4'] == 0xF5){
			$unpack_head = unpack('C1length/C1project/C1type/', substr($buffer,4,3));
			$unpack_head['uid'] = self::bin2strr(substr($buffer,7,6),false);
			$unpack_head['uid_raw'] = substr($buffer,7,6);
			//解码值数据
			$unpack_head['version'] = 0xF5;
			$unpack_head['cmd'] = Ord(substr($buffer,13,1));
			$unpack_head['method'] = sprintf("method%'04x",$unpack_head['cmd']);
			$value = substr($buffer,14,$unpack_head['length']-16);
			$unpack_value = self::unpackValue($unpack_head['cmd'],$value,$unpack_head['length']-16);
		}
		else if( $unpack_magic['magic1'] == 0xEC ){
					$unpack = \Jiaruan\Lhtlv::decode($buffer);
					$unpack['version'] = 0xEC;
					return $unpack;
		}
		else{
			return null;
		}
		//头部+值一起返回
		return array_merge($unpack_head,$unpack_value);
	}
	
 
	public static function encode( $value ){
		if($value['version'] == 0xF6){
			$buf = pack('C1C1C1C1S1C1C1',0xF6,0xF6,0xF6,0xF6,17,0x65,0x00).$value['uid_raw'].pack('C1',$value['cmd']).pack('C1C1',0x0D,0x0A);
		}else if($value['version'] == 0xF5){
			$buf = pack('C1C1C1C1C1C1C1',0xF5,0xF5,0xF5,0xF5,16,0x65,0x00).$value['uid_raw'].pack('C1',$value['cmd']).pack('C1C1',0x0D,0x0A);
		}else if($value['version'] == 0xEC){
			$buf = \Jiaruan\Lhtlv::encode($value);
		}else{
			echo 'version error'.PHP_EOL;
			return '';
		}
		if(APP_DEBUG){
			echo self::bin2str($buf,true).PHP_EOL;
		}
		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;
	}
	
 
	private static function bin2strr( $hex, $space ){
		$data = unpack("C*chars",$hex);
		$bin = '';
		foreach($data as $key=>$value){
			$bin = sprintf('%02X',$value).$bin;
			if($space)
				$bin .= ' ';
		}
		return trim($bin);
	}
	

}