Gps.php 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. <?php
  2. namespace Workerman\Protocols;
  3. class Gps {
  4. public static function input( $buffer, $connection ){
  5. if (strlen($buffer) < 4) {
  6. return 0;
  7. }
  8. $unpack_data = unpack('C1magic/C1method/n1length', $buffer);
  9. return $unpack_data['length'] + 6;
  10. }
  11. private static function bin2str( $hex, $space ){
  12. $data = unpack("C*chars",$hex);
  13. $bin = '';
  14. foreach($data as $key=>$value){
  15. $bin .= sprintf('%02X',$value);
  16. if($space)
  17. $bin .= ' ';
  18. }
  19. return trim($bin);
  20. }
  21. private static function packValue( $value ){
  22. if($value['cmd'] == 0x02){
  23. return pack('C1',$value['result']);
  24. }
  25. elseif($value['cmd'] == 0x04){
  26. return pack('C1',$value['result']);
  27. }
  28. elseif($value['cmd'] == 0x03){
  29. return pack('n1',$value['data']);
  30. }
  31. elseif($value['cmd'] == 0x01 || $value['cmd'] == 0xBE){
  32. return pack('H*', $value['data']);
  33. }
  34. else{
  35. return false;
  36. }
  37. }
  38. private static function unpackValue( $cmd, $value, $length ){
  39. if($cmd == 0x01){ //设备注册
  40. if($length == 6)
  41. return array('uid' => self::bin2str($value,false) );
  42. else
  43. return null;
  44. }
  45. elseif($cmd == 0x05){ //设备心跳
  46. return null;
  47. }
  48. elseif($cmd == 0x07){ //上报IMSI
  49. if($length == 21){
  50. return array(
  51. 'uid' => self::bin2str(substr($value,0,6),false) ,
  52. 'imsi' => substr($value,6,15)
  53. );
  54. }
  55. else
  56. return null;
  57. }
  58. elseif($cmd == 0x08){ //设备响应
  59. if($length == 2){
  60. return array(
  61. 'type' => Ord(substr($value,0,1)) ,
  62. 'result' => Ord(substr($value,1,1))
  63. );
  64. }
  65. else
  66. return null;
  67. }
  68. elseif($cmd == 0xbe){ //上报地理位置
  69. if($length == 20){
  70. //解析设置的时间间隔,设置的设备数量
  71. //$info = unpack('C1status/C1nbsphere/C1dxsphere/C1speed1/C1speed2/n1longitude/n1latitude/', substr($value,10,4));
  72. $info = array();
  73. //定位状态
  74. $info['state'] = Ord(substr($value,0,1));
  75. //南北半球
  76. $info['nbsphere'] = Ord(substr($value,1,1));
  77. //东西半球
  78. $info['dxsphere'] = Ord(substr($value,2,1));
  79. //速度
  80. $speed1 = Ord(substr($value,3,1));
  81. $speed2 = Ord(substr($value,4,1));
  82. $info['speed'] = $speed1 .'.'.$speed2;
  83. //经度
  84. $longitude1 = Ord(substr($value,5,1));
  85. $longitude2 = Ord(substr($value,6,1))*256*256+Ord(substr($value,7,1))*256+Ord(substr($value,8,1));
  86. $info['longitude'] = $longitude1 .'.'.sprintf("%05d", $longitude2);
  87. //纬度
  88. $latitude1 = Ord(substr($value,9,1));
  89. $latitude2 = Ord(substr($value,10,1))*256*256+Ord(substr($value,11,1))*256+Ord(substr($value,12,1));
  90. $info['latitude'] = $latitude1 .'.'. sprintf("%05d", $latitude2);
  91. //解析时间
  92. $year1 = Ord(substr($value,13,1));
  93. $year2 = Ord(substr($value,14,1));
  94. $month = Ord(substr($value,15,1));
  95. $day = Ord(substr($value,16,1));
  96. $hour = Ord(substr($value,17,1));
  97. $minute = Ord(substr($value,18,1));
  98. $second = Ord(substr($value,19,1));
  99. $info['time'] = sprintf("%02d%02d-%02d-%02d %02d:%02d:%02d",$year1 ,$year2 ,$month, $day, $hour, $minute, $second);
  100. return $info;
  101. }
  102. else
  103. return null;
  104. }
  105. elseif($cmd == 0xbd){ //上报报警
  106. if($length == 1)
  107. return array('v' => self::bin2str($value) );
  108. else
  109. return null;
  110. }
  111. return $value;
  112. }
  113. public static function decode( $buffer ){
  114. //解码头部数据
  115. $unpack_head = unpack('C1magic/C1cmd/n1length', $buffer);
  116. $unpack_head['method'] = sprintf("method%'04x",$unpack_head['cmd']);
  117. //判断头部引导符
  118. if( $unpack_head['magic'] != 0xEC )
  119. return null;
  120. //判断最后结尾符
  121. if( Ord(substr($buffer,-1)) != 0x68 )
  122. return null;
  123. //判断签名是否正确
  124. //如果长度等于0则没有值数据
  125. if($unpack_head['length'] == 0)
  126. return $unpack_head;
  127. //解码值数据
  128. $value = substr($buffer,4,$unpack_head['length']);
  129. $unpack_value = self::unpackValue($unpack_head['cmd'],$value,$unpack_head['length']);
  130. if(!$unpack_value)
  131. return null;
  132. //头部+值一起返回
  133. return array_merge($unpack_head,$unpack_value);
  134. }
  135. public static function encode( $value ){
  136. $pack_value = self::packValue($value);
  137. $length = strlen($pack_value);
  138. $sign = $value['cmd'] + $length;
  139. for($i=0;$i<strlen($pack_value);$i++){
  140. $sign += Ord($pack_value[$i]);
  141. }
  142. $buf = pack('C1C1n1', 0xEC,$value['cmd'],$length) . $pack_value .pack('C1', $sign). pack('C1', 0x68);
  143. return $buf;
  144. }
  145. private static function str2bin( $text ){
  146. if (!is_string($text))
  147. return null;
  148. $arr = explode(' ',$text);
  149. $bin = '';
  150. foreach($arr as $hex){
  151. if(strlen($hex) == 2){
  152. $bin .= chr( hexdec($hex) );
  153. }
  154. }
  155. return $bin;
  156. }
  157. }