Lhtcp.php 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. <?php
  2. namespace Workerman\Protocols;
  3. class Lhtcp {
  4. public static function input( $buffer, $connection ){
  5. if (strlen($buffer) < 6) {
  6. return 0;
  7. }
  8. if(Ord($buffer[0]) == 0xF5){
  9. $unpack_data = unpack('C4magic/C1length', $buffer);
  10. return $unpack_data['length'];
  11. }else if(Ord($buffer[0]) == 0xF6){
  12. $unpack_data = unpack('C4magic/S1length', $buffer);
  13. return $unpack_data['length'];
  14. }else if(Ord($buffer[0]) == 0xEC){
  15. $unpack_data = unpack('C1magic/C1method/n1length', $buffer);
  16. return $unpack_data['length'] + 6;
  17. }else{
  18. return strlen($buffer);
  19. }
  20. }
  21. private static function bin2str( $hex, $space ){
  22. $data = unpack("C*chars",$hex);
  23. $bin = '';
  24. foreach($data as $key=>$value){
  25. $bin .= sprintf('%02X',$value);
  26. if($space)
  27. $bin .= ' ';
  28. }
  29. return trim($bin);
  30. }
  31. private static function packValue( $value ){
  32. if($value['cmd'] == 0x01){
  33. return '';
  34. }
  35. elseif($value['cmd'] == 0x0F){
  36. return '';
  37. }
  38. else{
  39. return false;
  40. }
  41. }
  42. private static function unpackValue( $cmd, $value, $length ){
  43. if($cmd == 0x0F){ //设备心跳
  44. return array();
  45. }
  46. elseif($cmd == 0x01){ //上报标签
  47. //解析车辆信息
  48. $count = $length/6;
  49. $labels = array();
  50. for($i=0;$i<$count;$i++){
  51. $rfid = self::bin2strr(substr($value,$j,6),false);
  52. $j += 6;
  53. $info = array(
  54. 'rfid' => $rfid,
  55. 'time' => date('Y-m-d H:i:s')
  56. );
  57. array_push($labels,$info);
  58. }
  59. return array(
  60. 'labels' => $labels
  61. );
  62. }
  63. return $value;
  64. }
  65. public static function decode( $buffer ){
  66. //判断最后结尾符
  67. if( Ord(substr($buffer,-2,1)) != 0x0D || Ord(substr($buffer,-1)) != 0x0A ){
  68. return null;
  69. }
  70. //解码头部数据
  71. $unpack_magic = unpack('C4magic', $buffer);
  72. //判断头部引导符
  73. if( $unpack_magic['magic1'] == 0xF6 && $unpack_magic['magic2'] == 0xF6 &&
  74. $unpack_magic['magic3'] == 0xF6 && $unpack_magic['magic4'] == 0xF6){
  75. $unpack_head = unpack('S1length/C1project/C1type/', substr($buffer,4,4));
  76. $unpack_head['version'] = 0xF6;
  77. $unpack_head['cmd'] = Ord(substr($buffer,14,1));
  78. $unpack_head['method'] = sprintf("method%'04x",$unpack_head['cmd']);
  79. $unpack_head['uid'] = self::bin2strr(substr($buffer,8,6),false);
  80. $unpack_head['uid_raw'] = substr($buffer,8,6);
  81. //解码值数据
  82. $value = substr($buffer,15,$unpack_head['length']-17);
  83. $unpack_value = self::unpackValue($unpack_head['cmd'],$value,$unpack_head['length']-17);
  84. }
  85. //判断头部引导符
  86. else if( $unpack_magic['magic1'] == 0xF5 && $unpack_magic['magic2'] == 0xF5 &&
  87. $unpack_magic['magic3'] == 0xF5 && $unpack_magic['magic4'] == 0xF5){
  88. $unpack_head = unpack('C1length/C1project/C1type/', substr($buffer,4,3));
  89. $unpack_head['uid'] = self::bin2strr(substr($buffer,7,6),false);
  90. $unpack_head['uid_raw'] = substr($buffer,7,6);
  91. //解码值数据
  92. $unpack_head['version'] = 0xF5;
  93. $unpack_head['cmd'] = Ord(substr($buffer,13,1));
  94. $unpack_head['method'] = sprintf("method%'04x",$unpack_head['cmd']);
  95. $value = substr($buffer,14,$unpack_head['length']-16);
  96. $unpack_value = self::unpackValue($unpack_head['cmd'],$value,$unpack_head['length']-16);
  97. }
  98. else if( $unpack_magic['magic1'] == 0xEC ){
  99. $unpack = \Jiaruan\Lhtlv::decode($buffer);
  100. $unpack['version'] = 0xEC;
  101. return $unpack;
  102. }
  103. else{
  104. return null;
  105. }
  106. //头部+值一起返回
  107. return array_merge($unpack_head,$unpack_value);
  108. }
  109. public static function encode( $value ){
  110. if($value['version'] == 0xF6){
  111. $buf = pack('C1C1C1C1S1C1C1',0xF6,0xF6,0xF6,0xF6,17,0x65,0x00).$value['uid_raw'].pack('C1',$value['cmd']).pack('C1C1',0x0D,0x0A);
  112. }else if($value['version'] == 0xF5){
  113. $buf = pack('C1C1C1C1C1C1C1',0xF5,0xF5,0xF5,0xF5,16,0x65,0x00).$value['uid_raw'].pack('C1',$value['cmd']).pack('C1C1',0x0D,0x0A);
  114. }else if($value['version'] == 0xEC){
  115. $buf = \Jiaruan\Lhtlv::encode($value);
  116. }else{
  117. echo 'version error'.PHP_EOL;
  118. return '';
  119. }
  120. if(APP_DEBUG){
  121. echo self::bin2str($buf,true).PHP_EOL;
  122. }
  123. return $buf;
  124. }
  125. private static function str2bin( $text ){
  126. if (!is_string($text))
  127. return null;
  128. $arr = explode(' ',$text);
  129. $bin = '';
  130. foreach($arr as $hex){
  131. if(strlen($hex) == 2){
  132. $bin .= chr( hexdec($hex) );
  133. }
  134. }
  135. return $bin;
  136. }
  137. private static function bin2strr( $hex, $space ){
  138. $data = unpack("C*chars",$hex);
  139. $bin = '';
  140. foreach($data as $key=>$value){
  141. $bin = sprintf('%02X',$value).$bin;
  142. if($space)
  143. $bin .= ' ';
  144. }
  145. return trim($bin);
  146. }
  147. }