123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258 |
- <?php
- namespace App\Servers\Weikemu;
- use App\Handlers\ExceptionTrait;
- use App\Handlers\ToolsHandler;
- use App\Servers\Weikemu\Transforms\BaseStationLocationTransform;
- use App\Servers\Weikemu\Transforms\ConfigTransform;
- use App\Servers\Weikemu\Transforms\ControlTransform;
- use App\Servers\Weikemu\Transforms\HeartTransform;
- use App\Servers\Weikemu\Transforms\LocationTransform;
- use App\Servers\Weikemu\Transforms\LoginTransform;
- use App\Servers\Weikemu\Transforms\ResponseTransform;
- use App\Servers\Weikemu\Transforms\SatelliteLocationTransform;
- use App\Servers\Weikemu\Transforms\StatusTransform;
- use App\Servers\Weikemu\Transforms\UrlConfigTransform;
- use App\Servers\Weikemu\Transforms\VoiceTransform;
- use App\Servers\Weikemu\Transforms\WarningTransform;
- use GatewayWorker\Lib\Gateway;
- class WeiKeMuServer
- {
- use ExceptionTrait, ToolsHandler;
- protected static $db;
- protected static $redis;
- protected static $mongo;
- public static function initDatabases($param)
- {
- self::$db = $param['db'];
- self::$redis = $param['redis'];
- self::$mongo = $param['mongo'];
- }
- public static function main($client_id, $message, $data, $param)
- {
- //序号
- $number = $data[3] . $data[4];
- $param['msg_id'] = $number;
- //校检值
- $verification = implode('', array_slice($data, -2, 2));
- //消息长度
- $length = hexdec($data[6] . $data[7]);
- //消息内容
- $body = array_slice($data, 8, -2);
- if ($length !== count($body)) {
- self::log('length is error', "error", self::$LOG_MAJOR);
- return false;
- }
- if (!self::is_verification(array_slice($data, 2, -2), $verification)) {
- //校检失败
- self::log('verification is error', "error", self::$LOG_MAJOR);
- return false;
- }
- $cmd = $data[2];
- if ($cmd === '5e') {
- $imei = substr(self::stitching($body, 4, 8), 0, -1);
- } elseif ($cmd === '08') {
- $imei = substr(self::stitching($body, 19, 8), 0, -1);
- } else {
- $imei = substr(self::stitching($body, 18, 8), 0, -1);
- }
- self::initDatabases($param);
- $box_no = $imei;
- self::log($client_id . '==>' . $box_no, "log", self::$LOG_DEV);
- $_SESSION['box_no'] = $imei;
- if (!Gateway::getUidByClientId($client_id)) {
- Gateway::bindUid($client_id, $imei);
- }
- if (!isset($_SESSION['bike_no'])) {
- $_SESSION['bike_no'] = self::byBoxNoGetBikeNoStatic($box_no);
- }
- if (!Gateway::isUidOnline($imei)) {
- //离线检查
- if (self::$redis->exists('bike:offline:' . $box_no)) {
- self::log($box_no, 'EVENT_ONLINE', self::$LOG_MAJOR);
- $cols['is_link'] = \App\Maps\BikeMap::LINK_ONLINE;
- self::$db->update('bikes')->where('box_no = ' . $box_no)->cols($cols)->query();
- self::$redis->del('bike:offline:' . $box_no);
- }
- }
- $response_body = '';
- switch ($cmd) {
- case '5a':
- //状态
- self::log('CMD==>状态', "log", self::$LOG_DEV);
- $response_body = (new StatusTransform($param))->main($body);
- break;
- case '5b':
- //登录
- // self::log('CMD==>登录', "log", self::$LOG_DEV);
- $response_body = (new LoginTransform($param))->main($body);
- break;
- case '5c':
- self::log('CMD==>控制', "log", self::$LOG_DEV);
- $response_body = (new ControlTransform($param))->main($body);
- break;
- case '5d':
- self::log('CMD==>声音', "log", self::$LOG_DEV);
- $response_body = (new VoiceTransform($param))->main($body);
- break;
- case '5e':
- self::log('CMD==>心跳', "log", self::$LOG_DEV);
- $response_body = (new HeartTransform($param))->main($body);
- break;
- case '51':
- //告警消息
- self::log('CMD==>告警消息', "log", self::$LOG_DEV);
- $response_body = (new WarningTransform($param))->main($body);
- break;
- case '52':
- //卫星位置消息
- self::log('CMD==>卫星位置消息', "log", self::$LOG_DEV);
- $response_body = (new SatelliteLocationTransform($param))->main($body);
- break;
- case '53':
- //基站位置消息
- self::log('CMD==>基站位置消息', "log", self::$LOG_DEV);
- $response_body = (new BaseStationLocationTransform($param))->main($body);
- break;
- case '54': // 实时追踪
- case '55': // 位置查询
- //基站位置消息
- self::log('CMD==>基站位置消息(实时)', "log", self::$LOG_DEV);
- $response_body = (new LocationTransform($param))->main($body);
- break;
- case '56':
- //配置消息
- self::log('CMD==>配置消息', "log", self::$LOG_DEV);
- $response_body = (new ConfigTransform($param))->main($body);
- break;
- case '5f':
- self::log('CMD==>域名配置', "log", self::$LOG_DEV);
- $response_body = (new UrlConfigTransform($param))->main($body);
- break;
- case '08':
- self::log('CMD==>响应', "log", self::$LOG_DEV);
- $response_body = (new ResponseTransform($param))->main($body);
- break;
- }
- if ($response_body === false) {
- self::log('==>', 'RESPONSE_LOG', self::$LOG_DEV);
- return false;
- }
- $response_body[0] = $cmd;
- if (is_array($response_body)) {
- $response = self::response($response_body, $number);
- self::log($response, 'RESPONSE_LOG', self::$LOG_DEV);
- Gateway::sendToCurrentClient('+NNMI,' . hex2bin(str_replace(' ', '', $response)));
- }
- self::log('<===========================================>', 'RESPONSE_LOG', self::$LOG_DEV);
- }
- public static function outLine($client_id)
- {
- }
- /**
- * 校检
- * @param $data
- * @param $verification
- * @return bool
- * Author: Mead
- */
- protected static function verification($data)
- {
- $a = $b = 0;
- for ($i = 0; $i < count($data); $i++) {
- $a = $a + hexdec($data[$i]);
- $b = $a + $b;
- }
- return str_pad(substr(dechex($a), -2), 2, 0, STR_PAD_LEFT) . str_pad(substr(dechex($b), -2), 2, 0, STR_PAD_LEFT);
- }
- /**
- * 验证数据
- * @param $data
- * @param $verification
- * @return bool
- * Author: Mead
- */
- private static function is_verification($data, $verification)
- {
- $n_verification = self::verification($data);
- return (bool)((string)$n_verification === (string)$verification);
- }
- /**
- * 处理响应包
- * @param $body
- * @param $number
- * @return string
- * Author: Mead
- */
- private static function response($body, $number)
- {
- $header = [
- '28',
- "{$number}",
- '00',
- '0003',
- ];
- $data = self::arr2str($header, $body);
- $data .= self::verification(explode(' ', $data));
- return self::format('4244' . $data . '0D0A');
- }
- private static function format($str)
- {
- return strtoupper(implode(' ', str_split(str_replace(' ', '', $str), 2)));
- }
- private static function arr2str()
- {
- $args = func_get_args();
- $arr = '';
- foreach ($args as $arg) {
- if (is_array($arg)) {
- $arr .= implode('', $arg);
- } else {
- $arr .= str_replace(' ', '', $arg);
- }
- }
- return implode(' ', str_split($arr, 2));
- }
- /**
- * 根据box_no获取车的no
- * @param $box_no
- * @return mixed
- * User: Mead
- */
- private static $redis_bike_no_tags = 'box_no_and_bike_no';
- public static function byBoxNoGetBikeNoStatic($box_no)
- {
- return self::$redis->hget(self::$redis_bike_no_tags, $box_no);
- }
- }
|