#!/usr/bin/perl
# http://userside.ua/wiki/index.php/Us_gps - Module info
$zrevision = "19";
$zver = "us_gps v.1.4." . $zrevision; #Module version
# =============================================================================
use DBI;
use Time::Local;
use FindBin;
use IO::Socket;
use CGI qw/:standard/; # Загружаем стандартные процедуры CGI

no warnings 'once';

$zpath = $FindBin::RealBin . '/';
$zsilence = '';
$zucp = '';
$zip = '';
$ps_dev_id = '';

require($zpath . 'us_config.tmp');

$ps_full_debug = 0;

$pb_is_test = 0;

$zmodule_param = 'M_GPS';

if ($zport < 1) {
    $zport = 5005;
}
if ($zinterval < 1) {
    $zinterval = 1;
}

#Загружаем параметры
load_first_light();

#Загружаем настройки конфига
$query = "SELECT PARAM, VALUEINT, VALUESTR FROM tbl_conf";
printlog_sql_u($query);
    while (@ln = $rs->fetchrow_array()) {
        #Выясняем - нужно ли запускать модуль
        if ($ln[0] eq 'US_GPS') {
            $ps_module_allow = $ln[1];
        }
        if ($ln[0] eq $zmodule_param) {
            $ps_needversion = $ln[2];
        }
    };
$rs->finish();

#Проверяем версию и включен ли модуль
version_verify_light();

#Начальные системные операции
load_second_light();

#Фиксируем в логе специфические параметры
printlog("zip        = " . $zip);
printlog("zport      = " . $zport);
printlog("zinterval  = " . $zinterval);
printlog("confIsWest = " . $confIsWest);

bufer_clear();

#Начинаем работу

#Закрываем соединение
$rs->finish();
$conn1->disconnect();

$pidfile = $ps_logpath . "pid.txt";
open ($tempFile, ">" . $pidfile) || die;
    print $tempFile $$ . "\n";
close $tempFile;

my $server = IO::Socket::INET->new (
    LocalPort    => $zport,
    Type         => SOCK_STREAM,
    Reuse        => 1,
    Proto        => 'tcp',
    Listen       => SOMAXCONN
    ) or die "Could not open port " . $zip . ":" . $zport . "\n";

#print "server ready waiting for connections.....  \n";

my $client;

# Array of children
my @children = ();

sub signal_handler{
	print "Interrupted Module\n";
	foreach (@children){
		print "Destroy Children: " . $_ . "\n";
    	kill 'TERM', $_;
  	}
  	close($server);
  	exit;
}

# Обработчик сигналов
$SIG{INT} = $SIG{TERM} = $SIG{ALRM} = \&signal_handler;

sub REAPER {
    my $child;
    while (($child = waitpid(-1,WNOHANG)) > 0) {
        $Kid_Status{$child} = $?;
    }
    $SIG{CHLD} = \&REAPER;
}
$SIG{CHLD} = \&REAPER;

$buf_size = 256;    #Размер буфера чтения из сокета
$currentProtokol = '';

while ($client = $server->accept()) {

    my $pid;
    while (not defined ($pid = fork())) {
        sleep 5;
    }
    if ($pid) {
        push @children, $pid;
        close $client;        # Only meaningful in the client
    } else {
        $client->autoflush(1);    # Always a good idea
        close $server;

        $SIG{CHLD} = \&REAPER;
        $SIG{INT} = $SIG{TERM} = $SIG{ALRM} = sub{ 
        	close($client); 
        	print "Close Client. Exit\n";
        	exit; 
        };

        if ($zsilence ne 1) {
            print "Client connected to pid $$\n";
            printlog("Client connected to pid $$");
        }

        open ($tempFile, ">>" . $pidfile) || die;
            print $tempFile $$ . "\n";
        close $tempFile;

        $pb_work2 = 1;
        while ($pb_work2 eq 1) {

            #Безконечный цикл ожидания ввода команд от пользователя
            $pi_s_c = 0;
            $pb_work = 1;
            $ps_data = '';
            while ($pb_work eq 1) {
                $pi_s_c++;
                if (defined ($client->recv($ps_symbol, $buf_size, 0)) || die "Can not read from socket: $!" ) {

                    $ps_data .= $ps_symbol;
                    $ps_hex = unpack "H2", $ps_symbol;

                    $ps_data_hex = '';
                    @arr = split(//, $ps_data);
                    foreach $byte (@arr) {
                        $hex = unpack "H2", $byte;
                        $ps_data_hex .= $hex;
                    }

                    if ($ps_data_hex ne '') {
                        $ps_str = 'proto: ' . $currentProtokol . '| dev: ' . $ps_dev_id . '| symbol=' . $ps_symbol . ' (HEX: ' . $ps_hex . ")| bufer= " . $ps_data . " | LENGTH: " . length($ps_data) . " (DATA_HEX: " . $ps_data_hex . " | LENGTH_HEX: " . length($ps_data_hex) . ")|";
                        printlog($ps_str);

                        if ($pb_is_test eq 1) {
                            print $ps_str . "\n";
                        }
                        
                        #print $ps_str . "\n";

                        #print $client "respcrc=";

                    }

                    bufer_clear();

                    #Выясняем - возможно требуется досрочно прервать обработку и мы уже получили всё что нужно

                    #====================================================================================================
                    if (length($ps_data_hex) eq 'test') {
                        $currentProtokol = 'test';
                        $pb_work = 0;
                    }
                    #====================================================================================================

                    #GALILEOSKY
                    #====================================================================================================
                    if (substr($ps_data_hex, 1, 4) eq '0117' && length($ps_data_hex) eq 224) {
                        $currentProtokol = 'gsky';
                        $pb_work = 0;
                    }
                    #====================================================================================================

                    #H02 tracker protocol
                    #====================================================================================================
                    if (substr($ps_data, 0, 4) eq '*HQ,') {
                        # *HQ,353505220872211,XT,V,0,0#
                        $currentProtokol = 'h02';
                        $pb_work = 0;
                    }
                    #====================================================================================================

                    #KHD
                    #====================================================================================================
                    if (substr($ps_data_hex, 0, 4) eq '2929' && substr($ps_data_hex, -2) eq '0d') {
                        # 2929b10007258677280c460d
                        $currentProtokol = 'khd';
                        $pb_work = 0;
                    }
                    #====================================================================================================

                    #ОКО-NAVI
                    #====================================================================================================
                    #printlog ("arrived|" . substr($ps_data_hex, 0, 2) . "|" . substr($ps_data_hex, -2) . "|");
                    if (substr($ps_data_hex, 0, 2) eq '7b' && substr($ps_data_hex, -2) eq '7d') {
                        # 7b3836313030313030323736323837362c3135313432362e3030302c412c343634352e3231383230312c4e2c30333634372e3237393635392c452c302e3030302c36372e372c3036303331352c372c302e30302c46392c31322e342c312c30307d
                        # 7b3135313532372e3030302c412c343634352e3231383230312c4e2c30333634372e3237393635392c452c302e3030302c36372e372c3036303331352c392c302e30302c46392c31322e342c312c30307d
                        $currentProtokol = 'oko';
                        $pb_work = 0;
                        #print "proto: " . $currentProtokol . "|\n";
                    }
                    #====================================================================================================

                    #Автофон
                    #====================================================================================================
                    printlog ("arrived|" . substr($ps_data_hex, 0, 2) . "|" . length($ps_data_hex) . "|");
                    if (
                            (substr($ps_data_hex, 0, 2) eq '10' && length($ps_data_hex) eq 24)
                        ||
                            (substr($ps_data_hex, 0, 2) eq '11' && length($ps_data_hex) eq 156)
                        ||
                            (substr($ps_data_hex, 0, 2) eq '12' && length($ps_data_hex) eq 514)
                        ||
                            (substr($ps_data_hex, 0, 2) eq '41' && length($ps_data_hex) eq 38)
                        ||
                            (substr($ps_data_hex, 0, 2) eq '02' && length($ps_data_hex) eq 68)
                        ) {
                        # 10626b08630710111896901a
                        # 10 62 6b 0863071011189690 1a
                        # 11149225603445045000010000651c0a0c0f14181d0a0c0c0005a046ffffffff1d0a0c0c00276047ffffffff076100fa000102bd1be94c04030f150817034aef77022bfad200bc00060009ffffca
                        # 120601034da053023c6d5e01070851002dffff84414b04030f011e1f0d4b00fa0001023e27204304030f
                        # 41035509404568372341138096421558572153
                        $currentProtokol = 'autofon';
                        $pb_work = 0;
                        #print "work: 1|\n";
                    }
                    #====================================================================================================

                    #GT02
                    #====================================================================================================
                    if (substr($ps_data, 0, 2) eq 'hh' && substr($ps_data_hex, -4) eq '0d0a') {
                        $currentProtokol = 'gt02';
                        $pb_work = 0;
                        #print "work: 1|\n";
                    }
                    #====================================================================================================

                    #GT06
                    #====================================================================================================
                    if (substr($ps_data, 0, 2) eq 'xx' && substr($ps_data_hex, -4) eq '0d0a') {
                        $currentProtokol = 'gt06';
                        $pb_work = 0;
                        #print "work: 1|\n";
                    }
                    #====================================================================================================

                    #Wialon
                    #====================================================================================================
                    if (substr($ps_data, 0, 3) eq '#D#' || substr($ps_data, 0, 3) eq '#L#') {
                        $currentProtokol = 'wialon';
                        $pb_work = 0;
                        #print "work: 1|\n";
                    }
                    #====================================================================================================

                    #Traccar
                    #====================================================================================================
                    if ($pb_is_test eq 1) {
                        #printlog("6=" . substr($ps_data, 0, 6) . "|"); #***
                    }
                    if (substr($ps_data, 0, 6) eq '$PGID,' || substr($ps_data, 0, 7) eq '$GPRMC,' || substr($ps_data, 0, 7) eq '$TRCCR,') {
                        # $PGID,352372052807200*0e
                        # $GPRMC,152347.000,A,4747.1585,N,03513.9105,E,0.00,0.00,070215,,*04
                        # $TRCCR,20150617123106.000,A,55.79049666666666,37.936236666666666,0.0,116.39,180.2,57,*01
                        $currentProtokol = 'traccar';
                        $pb_work = 0;
                        if ($pb_is_test eq 1) {
                            printlog("We find Traccar"); #***
                        }
                    }
                    #====================================================================================================

                    #Traccar - 55 (OsmAnd)
                    #====================================================================================================
                    if ($ps_data ne '') {
                        #print "|10=" . substr($ps_data, 2, 10) . "|" . $ps_data . "|\n";
                    }
                    if ($pb_is_test eq 1) {
                        #print "|" . substr($ps_data, 5, 144) . "|\n";
                        #printlog("7=" . substr($ps_data, 0, 100) . "|"); #***
                    }
                    # 07
                    # Connection: Keep-Alive
                    # Accept-Encoding: gzip
                    if (
                            substr($ps_data, 5, 4) eq '?id='
                        ||
                            (substr($ps_data, 0, 2) eq '07' && substr($ps_data, 4, 10) eq 'Connection')
                        ||
                            (substr($ps_data, 2, 10) eq 'Connection')
                        ) {
                        # ?id=352372052807200&timestamp=1440418474&lat=47.78615908447165&lon=35.23193219149758&speed=0.0&bearing=0.0&altitude=107.84642666000549&batt=90.0
                        $currentProtokol = 'traccar55';
                        $pb_work = 0;
                        if ($pb_is_test eq 1) {
                            printlog("We find Traccar 55"); #***
                        }
                        #print "We find Traccar 55\n";
                    }
                    #====================================================================================================

                    #GPS102
                    #====================================================================================================
                    if (substr($ps_data, 0, 8) eq '##,imei:' && substr($ps_data, -3) eq ',A;') {
                        # ##,imei:359710043917690,A;
                        $currentProtokol = '102';
                        $pb_work = 0;
                    }
                    if ($currentProtokol eq 102) {
                        if (substr($ps_data, -1) eq ';') {
                            $pb_work = 0;
                        }
                    }
                    #====================================================================================================

                    #TK102
                    #====================================================================================================
                    if (substr($ps_data, 0, 2) eq '(0' && substr($ps_data, -9) eq '00000000)') {
                        # (027043576388BR00150919A4949.6147N02402.0461E000.60650290.000000000000L00000000)
                        $currentProtokol = 'tk102';
                        $pb_work = 0;
                    }
                    #====================================================================================================

                }

                #Досрочно прерываем работу, если длина буфера превысила 1024 байт
                if ($pi_s_c > 1024 || length($ps_data_hex) > 2048) {
                	$currentProtokol = '';
                    $pb_work = 0;
                    $pi_s_c = 0;
                    $ps_data_hex = '';
                    sleep 5;
                    #$pb_work2 = 0;
                    #if ($pb_is_test eq 1) {
                        #print "Emergency Exit: (" . $pi_s_c . "|" . length($ps_data_hex) . ")\n";
                        #print "Emergency Exit\n";
                    #}
                }
            }

            #print "Try to work data|\n";

            &do_your_stuff();

        }
    }
}

print "Exit " . $$ . "\n";

close Client;
close Server;
exit(0);

sub do_your_stuff {
    if ($ps_data ne '') {

        @arr = split(//, $ps_data);
        $ps_data_hex = '';
        @pmas_symbol = ();
        $pi_c1 = 0;
        foreach $byte (@arr) {
            $hex = unpack "H2", $byte;
            $ps_data_hex .= $hex . " ";
            $pi_c1++;
            $pmas_symbol[$pi_c1] = $hex;
        }

        printlog("Data arrived - DEV_ID: " . $ps_dev_id . " DATA: " . $ps_data . " DATA_HEX: " . $ps_data_hex);
        printlog("Proto: " . $currentProtokol);

        bufer_clear();

        if (1 eq 0) {
            print formatdatetime("hh:mm:ss", time) . " Data arrived - DEV_ID: " . $ps_dev_id;
            print " DATA: " . $ps_data;
            print " DATA_HEX: " . $ps_data_hex;
            print "\n";
        }

        $isKnownProtocol = 0;

        #Wialon
        #====================================================================================================
        if ($currentProtokol eq 'wialon') {
            $isKnownProtocol = 1;

            $ps_data .= "\r\n";

            @arr = split(/\n/, $ps_data);
            foreach $ps_data (@arr) {

                #print $ps_data . "\n";

                if (substr($ps_data, 0, 3) eq '#L#') {
                    #Авторизация
                    $ps_dev_id = substr($ps_data, 3, 15);
                    if ($zsilence ne 1) {
                        print formatdatetime("hh:mm:ss", time) . " | " . $ps_dev_id . " | CONNECT |\n";
                    }
                    $ps_answer = "#AL#1\r\n";
                    print $client $ps_answer;
                    printlog ("DEV_ID: " . $ps_dev_id);
                    printlog ("Answer> " . $ps_answer);
                }


                if (substr($ps_data, 0, 3) eq '#D#') {
                    #Данные
                    #D#240316;200213;4747.8387;N;03511.4496;E;0;0;49.000000;14;NA;0;NA;0.008000;NA;param179:1:0,param180:1:0,param240:1:0,gsm:1:3,pwr_ext:2:11.999000,param199:1:0,param241:1:25503,battery_charge:1:0

                    $ps_year = '20' . substr($ps_data, 7, 2);
                    $ps_month = substr($ps_data, 5, 2);
                    $ps_day = substr($ps_data, 3, 2);
                    $ps_hour = substr($ps_data, 10, 2);
                    $ps_minute = substr($ps_data, 12, 2);
                    $ps_second = substr($ps_data, 14, 2);

                    $ps_utc_date = $ps_year . '-' . $ps_month . '-' . $ps_day . ' ' . $ps_hour . ':' . $ps_minute . ':' . $ps_second;
                    $ps_local_date = UTC2LocalString($ps_utc_date);

                    $ps_lat = substr($ps_data, 17, 2);
                    $ps_lat2 = substr($ps_data, 19, 2) . substr($ps_data, 22, 4);
                    $ps_lat2 = sprintf("%.0f", $ps_lat2 / 6 * 10);
                    $ps_lat .= '.' . $ps_lat2;

                    $ps_lng = substr($ps_data, 29, 3);
                    $ps_lng2 = substr($ps_data, 32, 2) . substr($ps_data, 35, 4);
                    $ps_lng2 = sprintf("%.0f", $ps_lng2 / 6 * 10);
                    $ps_lng .= '.' . $ps_lng2;

                    $ps_speed = int(substr($ps_data, 42, 3));

                    $ps_answer = "#AD#1\r\n";
                    print $client $ps_answer;
                    printlog ("Answer> " . $ps_answer);

                    $ps_str = "|date: " . $ps_local_date . "|lat (x): " . $ps_lat . "|lng (y): " . $ps_lng . "|speed: " . $ps_speed . "|";
                    #print "Data: " . $ps_str;
                    printlog($ps_str);

                    write_result($ps_dev_id, $ps_local_date, $ps_lat, $ps_lng, $ps_speed, $ps_data);
                }


            }

        }

        #ОКО-NAVI
        #====================================================================================================
        if ($currentProtokol eq 'oko') {
            $isKnownProtocol = 1;
            # 7b3836313030313030323736323837362c3135313432362e3030302c412c343634352e3231383230312c4e2c30333634372e3237393635392c452c302e3030302c36372e372c3036303331352c372c302e30302c46392c31322e342c312c30307d
            # 7b 38 36 31 30 30 31 30 30 32 37 36 32 38 37 36 2c 3135313432362e3030302c412c343634352e3231383230312c4e2c30333634372e3237393635392c452c302e3030302c36372e372c3036303331352c372c302e30302c46392c31322e342c312c30307d
            # {861001002762876,154241.000,A,4645.224114,N,03647.265595,E,0.000,205.8,060315,9,0.00,F9,12.4,1,00}
            # 0 - 861001002762876,
            # 1 - 154241.000,
            # 2 - A,
            # 3 - 4645.224114,
            # 4 - N,
            # 5 - 03647.265595,
            # 6 - E,
            # 7 - 0.000,
            # 8 - 205.8,
            # 9 - 060315,
            # 10 - 9,
            # 11 - 0.00,
            # 12 - F9,
            # 13 - 12.4,
            # 14 - 1,
            # 15 - 00
            $ps_data =~s/{//;
            $ps_data =~s/}//;
            @pmas_data = split(/,/, $ps_data);

            $pi_add = 0;

            if ($ps_dev_id eq '') {
                $ps_dev_id = $pmas_data[0];
                if ($zsilence ne 1) {
                    print formatdatetime("hh:mm:ss", time) . " | " . $ps_dev_id . " | CONNECT |\n";
                }
                $pi_add = 1;
            }

            if (length($ps_dev_id) > 10) {
                if ($pmas_data[(1 + $pi_add)] eq 'A') {
                    #060315 160051.000
                    $ps_date = $pmas_data[(8 + $pi_add)] . ' ' . $pmas_data[(0 + $pi_add)];
                    $ps_year = '20' . substr($ps_date, 4, 2);
                    $ps_month = substr($ps_date, 2, 2);
                    $ps_day = substr($ps_date, 0, 2);
                    $ps_hour = substr($ps_date, 7, 2);
                    $ps_minute = substr($ps_date, 9, 2);
                    $ps_second = substr($ps_date, 11, 2);

                    $ps_utc_date = $ps_year . '-' . $ps_month . '-' . $ps_day . ' ' . $ps_hour . ':' . $ps_minute . ':' . $ps_second;
                    $ps_local_date = UTC2LocalString($ps_utc_date);

                    $ps_lat = $pmas_data[(2 + $pi_add)];
                    $ps_lat = sprintf("%.6f", $ps_lat / 100);
                    $ps_lat2 = sprintf("%.0f", $ps_lat);
                    $ps_lat3 = ($ps_lat - $ps_lat2) / 6 * 10;
                    $ps_lat = sprintf("%.6f", ($ps_lat2 + $ps_lat3));

                    $ps_lng = $pmas_data[(4 + $pi_add)];
                    $ps_lng = sprintf("%.6f", $ps_lng / 100);
                    $ps_lng2 = sprintf("%.0f", $ps_lng);
                    $ps_lng3 = ($ps_lng - $ps_lng2) / 6 * 10;
                    $ps_lng = sprintf("%.6f", ($ps_lng2 + $ps_lng3));

                    $ps_speed = $pmas_data[(6 + $pi_add)] * 1.852; #Скорость в узлах (морских миль в час)

                    printlog ("DEV_ID: " . $ps_dev_id);

                    $ps_str = "|date: " . $ps_local_date . "|lat (x): " . $ps_lat . "|lng (y): " . $ps_lng . "|speed: " . $ps_speed . "|";
                    printlog($ps_str);

                    write_result($ps_dev_id, $ps_local_date, $ps_lat, $ps_lng, $ps_speed, $ps_data_hex);

                }
            }

            printlog ($ps_data);

        }

        #Автофон
        #====================================================================================================
        if ($currentProtokol eq 'autofon') {
            $isKnownProtocol = 1;
            #Автофон

            # 10626b08630710111896901a
            # 10 62 6b 0863071011189690 1a
            # 41035509404568372341138096421558572153

            if ($pmas_symbol[1] eq 10 && length($ps_data_hex) eq 36) { #36 - потому-что с пробелами
                #Авторизация
                $ps_in_crc = substr($ps_data, -1);
                $ps_answer = "resp_crc=" . $ps_in_crc;

                $ps_dev_id = int($pmas_symbol[4]) . $pmas_symbol[5] . $pmas_symbol[6] . $pmas_symbol[7] . $pmas_symbol[8] . $pmas_symbol[9] . $pmas_symbol[10] . $pmas_symbol[11];

                if ($zsilence ne 1) {
                    print formatdatetime("hh:mm:ss", time) . " | " . $ps_dev_id . " | CONNECT |\n";
                }

                print $client $ps_answer;
                printlog ("DEV_ID: " . $ps_dev_id);
                printlog ("Answer> " . $ps_answer);
            }

            #print "1: " . $pmas_symbol[1] . "|" . length($ps_data_hex) . "|\n";

            if ($pmas_symbol[1] eq 41 && length($ps_data_hex) eq 57) { #36 - потому-что с пробелами
                #Авторизация
                #41035509404568372341138096421558572153
                # 41 03 55 09 40 45 68 37 23 41 13 80 96 42 15 58 57 21 53

                # 0x41 0x03 0x21 0x25 0x65 0x69 0x85 0x54 0x75 0x43 0x61 0x91 0x73 0x48 0x40 0x02 0x12 0x34 0x81
                # 0x41: символ «А» (пакет авторизации).
                # 0x03 0x21 0x25 0x65 0x69 0x85 0x54 0x75: IMEI (321256569855475).
                # 0x43: 4-тип системы (маяк), 3-версия «железа».
                # 0x61: символ «а» (версия ПО)
                # 0x91 0x73 0x48 0x40 0x02: сейчас передаются нули (зарезервированно)
                # 0x12 0x34: сейчас передаются нули (зарезервированно)
                # 0x81: CRC

                $ps_in_crc = substr($ps_data, -1);

                #print "2: " . $ps_data . "|" . $ps_in_crc . "|\n";

                $ps_answer = "resp_crc=" . $ps_in_crc;

                $ps_dev_id = int($pmas_symbol[2]) . $pmas_symbol[3] . $pmas_symbol[4] . $pmas_symbol[5] . $pmas_symbol[6] . $pmas_symbol[7] . $pmas_symbol[8] . $pmas_symbol[9];

                if ($zsilence ne 1) {
                    print formatdatetime("hh:mm:ss", time) . " | " . $ps_dev_id . " | CONNECT |\n";
                }

                print $client $ps_answer;
                printlog ("DEV_ID: " . $ps_dev_id);
                printlog ("Answer> " . $ps_answer);
            }

            if ($pmas_symbol[1] eq '02' && length($ps_data_hex) eq 102) {
                #0218ffff26a8484703ff03e679262b860144c6035d632f743161231fc3f10f008206
                #0298ffff26a8484703ff03e679262b860144c9035d632f743411231fcf8112006c74
                #0218ffff26a8484703ff03e679262b860144cc035d632f743be1231fdbb11600307c
                # 02 18 ff ff 26 a8 48 47 03 ff 03 e6 79 26 2b 86 01 44 cc 03 5d 63 2f 74 3b e1 23 1f db b1 16 00 30 7c

                # Расшифровка:
                # 02: 2 -(рабочий пакет).
                # 18: 7-й бит сброшен – вход неактивный, 0x3E=62 (уровень батареи).
                # FF FF: оставшееся время работы канала (выключен).
                # 26: температура (+30C).
                # a8: интервал пробуждения (0 – без режима сна).
                # 48: минуты или часы для  интервала пробуждения (символ «М» - минуты).
                # 47: режим работы  («А»).
                # 03: интервал передачи GPRS-пакетов, в секундах (30 секунд).
                # FF: MCC (250).
                # 03: MNC (01).
                # E6 79: LAC (0x772F).
                # 26 2B: CID (0x1852)
                # 86: статус GPS-данных  (6-й и 7-й биты = 0b10 = 2 -  действительные координаты),  количество спутников (0-й – 5-й биты – 0b000101 = 5).
                # 01 44 cc: время по Гринвичу, шестизначное число в формате чч:мм:сс, при необходимости «добивается» нулями (40008 -> 04:00:08).
                # 03 5d 63: дата, шестизначное число в формате дд:мм:гг, при необходимости «добивается» нулями (27:01:10).
                # 2f: широта, градусы (54). 0x36
                # 74 3b e1: 4-й – 27-й биты - широта (минуты, доли минут), шестизначное число, при необходимости «добивается» нулями (0x6C 0x29 0x6 = 44.3030). 0-й бит установлен (север).
                # 23: долгота, градусы (056). 0x38
                # 1f db b1: 4-й – 27-й биты - долгота (минуты, доли минут), шестизначное число, при необходимости «добивается» нулями (0x0F 0x26 0xB = 06.2059). 0-й бит установлен (восток).
                # 16: скорость в узлах (11).
                # 00 30: курс в градусах (145).
                # 7c: CRC.

                #023E00001E004D411EFA01772F185285009C48041F1E366C2961380F26B10B00911C
                # 0x02 0x3E 0x00 0x00 0x1E 0x00 0x4D 0x41 0x1E 0xFA 0x01 0x77 0x2F 0x18 0x52 0x85 0x00 0x9C 0x48 0x04 0x1F 0x1E 0x36 0x6C 0x29 0x61 0x38 0x0F 0x26 0xB1 0x0B 0x00 0x91 0x1C

                $ps_in_crc = substr($ps_data, -1);
                $ps_answer = "resp_crc=" . $ps_in_crc;

                $ps_date = $pmas_symbol[20] . $pmas_symbol[21] . $pmas_symbol[22];
                $ps_date = hex($ps_date);
                $ps_date = substr("0" . $ps_date, -6);
                $ps_day = substr($ps_date, 0, 2);
                $ps_month = substr($ps_date, 2, 2);
                $ps_year = substr($ps_date, 4, 2);
                $ps_time = $pmas_symbol[17] . $pmas_symbol[18] . $pmas_symbol[19];
                $ps_time = hex($ps_time);
                $ps_time = substr("0" . $ps_time, -6);
                $ps_hour = substr($ps_time, 0, 2);
                $ps_minute = substr($ps_time, 2, 2);
                $ps_second = substr($ps_time, 4, 2);
                $ps_utc_date = $ps_year . '-' . $ps_month . '-' . $ps_day . ' ' . $ps_hour . ':' . $ps_minute . ':' . $ps_second;
                $ps_local_date = UTC2LocalString($ps_utc_date);

                $ps_lat = hex($pmas_symbol[23]);
                $ps_lat2 = substr('0' . hex($pmas_symbol[24] . $pmas_symbol[25] . substr($pmas_symbol[26], 0, 1)), -6);
                $ps_lat2 = $ps_lat2 / 6 * 10;
                $ps_lat = $ps_lat . "." . $ps_lat2;
                $ps_lat = sprintf("%.6f", $ps_lat);

                $ps_lng = hex($pmas_symbol[27]);
                $ps_lng2 = substr('0' . hex($pmas_symbol[28] . $pmas_symbol[29] . substr($pmas_symbol[30], 0, 1)), -6);
                $ps_lng2 = $ps_lng2 / 6 * 10;
                $ps_lng = $ps_lng . "." . $ps_lng2;
                $ps_lng = sprintf("%.6f", $ps_lng);

                $ps_speed = $pmas_symbol[31] * 1.852; #Скорость в узлах (морских миль в час)

                $ps_str = "|date: " . $ps_local_date . "|lat (x): " . $ps_lat . "|lng (y): " . $ps_lng . "|1 speed: " . $ps_speed . "|";
                printlog($ps_str);
                #print $ps_str . "\n";

                write_result($ps_dev_id, $ps_local_date, $ps_lat, $ps_lng, $ps_speed, $ps_data_hex);

                print $client $ps_answer;
                printlog ("Answer> " . $ps_answer);
            }


            if ($pmas_symbol[1] eq '11' && length($ps_data_hex) eq 234) { #234 - потому-что с пробелами
                # Рабочий пакет

                #DATA_HEX: 11 3c d2 20 60 34 45 38 7c 00 81 00 00 64 0e 02 10 0f 1d 2e 05 03 10 13 1a a8 c0 47 53 41 ff ff 13 02 10 0c 00 27 60 47 ff ff ff ff 12 3a 00 fa 00 01 27 62 01 a3 8b 0e 02 10 0d 03 35 02 b6 7d d9 02 63 77 fc 00 64 00 a0 00 08 00 ff 7e

                $ps_in_crc = substr($ps_data, -1);
                $ps_answer = "resp_crc=" . $ps_in_crc;

                $ps_year = $pmas_symbol[58]; #0f
                $ps_year = "20" . hex($ps_year);
                $ps_month = $pmas_symbol[57]; #03
                $ps_month = substr("0" . hex($ps_month), -2);
                $ps_day = $pmas_symbol[56]; #04
                $ps_day = substr("0" . hex($ps_day), -2);
                $ps_hour = $pmas_symbol[59];
                $ps_hour = substr("0" . hex($ps_hour), -2);
                $ps_minute = $pmas_symbol[60];
                $ps_minute = substr("0" . hex($ps_minute), -2);
                $ps_second = $pmas_symbol[61];
                $ps_second = substr("0" . hex($ps_second), -2);

                $ps_utc_date = $ps_year . '-' . $ps_month . '-' . $ps_day . ' ' . $ps_hour . ':' . $ps_minute . ':' . $ps_second;
                $ps_local_date = UTC2LocalString($ps_utc_date);

                #0d 4b 00 fa
                $ps_lat = $pmas_symbol[62] . $pmas_symbol[63] . $pmas_symbol[64] . $pmas_symbol[65];
                $ps_lat = hex($ps_lat);
                $ps_lat = sprintf("%.6f", $ps_lat / 1000000);
                $ps_lat2 = int($ps_lat);
                $ps_lat3 = ($ps_lat - $ps_lat2) / 6 * 10;
                $ps_lat = sprintf("%.6f", ($ps_lat2 + $ps_lat3));

                #00 01 02 3e
                $ps_lng = $pmas_symbol[66] . $pmas_symbol[67] . $pmas_symbol[68] . $pmas_symbol[69];
                $ps_lng = hex($ps_lng);
                $ps_lng = sprintf("%.6f", $ps_lng / 1000000);
                $ps_lng2 = int($ps_lng);
                $ps_lng3 = ($ps_lng - $ps_lng2) / 6 * 10;
                $ps_lng = sprintf("%.6f", ($ps_lng2 + $ps_lng3));

                $ps_speed = $pmas_symbol[72] * 1.852; #Скорость в узлах (морских миль в час)

                $ps_str = "|date: " . $ps_local_date . "|lat (x): " . $ps_lat . "|lng (y): " . $ps_lng . "|2 speed: " . $ps_speed . "|";
                printlog($ps_str);

                write_result($ps_dev_id, $ps_local_date, $ps_lat, $ps_lng, $ps_speed, $ps_data_hex);

                print $client $ps_answer;
                printlog ("Answer> " . $ps_answer);
            }


            if ($pmas_symbol[1] eq '12' && length($ps_data_hex) eq 771) { #771 - потому-что с пробелами
                #Пакеты из черного ящика
                # 120601034da053023c6d5e01070851002dffff84414b04030f011e1f0d4b00fa0001023e27204304030f
                # 12 06 01 03
                # 4d a0 53 02 3c 6d 5e 01 07 08 51 00 2d ff ff 84 41 4b 04 03 0f 01 1e 1f 0d 4b 00 fa 00 01 02 3e 27 20 43 04 03 0f
                #

                # DATA_HEX: 12 04 00 00 81 77 11 02 10 05 30 35 1b 40 00 fa 00 01 27 62 01 a3 8c 11 02 10 07 17 1f 02 b6 7d ed 02 63 77 e7 00 4c 00 46 00 07 00 ff b6 81 78 11 02 10 05 31 35 1d 40 00 fa 00 01 27 62 01 a3 8a 11 02 10 07 18 1f 02 b6 7d ed 02 63 77 e7 00 4c 00 46 00 09 00 ff c0 81 78 11 02 10 05 32 35 1d 40 00 fa 00 01 27 62 01 a3 8c 11 02 10 07 19 1f 02 b6 7d ed 02 63 77 e7 00 4c 00 46 00 08 00 ff c8 81 78 11 02 10 05 33 35 1d 4a 00 fa 00 01 27 62 01 a3 8b 11 02 10 07 1a 1f 02 b6 7d ed 02 63 77 e7 00 4c 00 46 00 08 00 ff 34 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f9

                $ps_in_crc = substr($ps_data, -1);
                $ps_answer = "resp_crc=" . $ps_in_crc;

                $ps_year = $pmas_symbol[26]; #0f
                $ps_year = "20" . hex($ps_year);
                $ps_month = $pmas_symbol[25]; #03
                $ps_month = substr("0" . hex($ps_month), -2);
                $ps_day = $pmas_symbol[24]; #04
                $ps_day = substr("0" . hex($ps_day), -2);
                $ps_hour = $pmas_symbol[27];
                $ps_hour = substr("0" . hex($ps_hour), -2);
                $ps_minute = $pmas_symbol[28];
                $ps_minute = substr("0" . hex($ps_minute), -2);
                $ps_second = $pmas_symbol[29];
                $ps_second = substr("0" . hex($ps_second), -2);

                $ps_utc_date = $ps_year . '-' . $ps_month . '-' . $ps_day . ' ' . $ps_hour . ':' . $ps_minute . ':' . $ps_second;
                $ps_local_date = UTC2LocalString($ps_utc_date);

                #0d 4b 00 fa
                $ps_lat = $pmas_symbol[30] . $pmas_symbol[31] . $pmas_symbol[32] . $pmas_symbol[33];
                $ps_lat = hex($ps_lat);
                $ps_lat = sprintf("%.6f", $ps_lat / 1000000);
                $ps_lat2 = int($ps_lat);
                $ps_lat3 = ($ps_lat - $ps_lat2) / 6 * 10;
                $ps_lat = sprintf("%.6f", ($ps_lat2 + $ps_lat3));

                #00 01 02 3e
                $ps_lng = $pmas_symbol[34] . $pmas_symbol[35] . $pmas_symbol[36] . $pmas_symbol[37];
                $ps_lng = hex($ps_lng);
                $ps_lng = sprintf("%.6f", $ps_lng / 1000000);
                $ps_lng2 = int($ps_lng);
                $ps_lng3 = ($ps_lng - $ps_lng2) / 6 * 10;
                $ps_lng = sprintf("%.6f", ($ps_lng2 + $ps_lng3));

                $ps_speed = $pmas_symbol[40] * 1.852; #Скорость в узлах (морских миль в час)

                $ps_str = "|date: " . $ps_local_date . "|lat (x): " . $ps_lat . "|lng (y): " . $ps_lng . "|3 speed: " . $ps_speed . "|";
                printlog($ps_str);

                write_result($ps_dev_id, $ps_local_date, $ps_lat, $ps_lng, $ps_speed, $ps_data_hex);

                print $client $ps_answer;
                printlog ("Answer> " . $ps_answer);
            }

        }
        #====================================================================================================

        #KHD
        #====================================================================================================
        if ($currentProtokol eq 'khd') {
            $isKnownProtocol = 1;

            # 29 29 b1 00 07 25 86 77 28 0c 46 0d
            # IMEI: 867965025867728
            # s/n: 25 86 77 28
            
            #print "1: " . substr($ps_data_hex,0,9) . "\n";
            print "Input : " . $ps_data_hex . "\n";
            
            if (substr($ps_data_hex,0,9) eq '29 29 b1 ') {
                #Авторизация
                $ps_dev_id = $pmas_symbol[6] . $pmas_symbol[7] . $pmas_symbol[8] . $pmas_symbol[9];
                $crc = $pmas_symbol[($hexArraySize - 1)];

                #print "|crc_old: " . $crc . "|\n";
                #print "|crc_new: " . crcKhd($ps_data) . "|\n";
                
                $ps_answer_beforeCrc = "29 29 21 00 05 " . $crc . " B1 00";
                $ps_answer_before = "2929210005" . $crc . "B100" . crcKhd($ps_answer_beforeCrc) . "0D";
                $answer = pack("H*", $ps_answer_before);
                printlog ("DEV_ID: " . $ps_dev_id);
                printlog ("Answer Before> " . $ps_answer_before);
                printlog ("Answer> " . $answer);
                print "Answer: " . $ps_answer_before . "\n";
                print $client $answer;
                
                #Запрашиваем версию
                #$ps_answer_beforeCrc = "29 29 3D 00 06 " . $pmas_symbol[6] . " " . $pmas_symbol[7] . " " . $pmas_symbol[8] . " " . $pmas_symbol[9];
                #$ps_answer_before = "29293D0006" . $ps_dev_id . crcKhd($ps_answer_beforeCrc) . "0D";
                #$answer = pack("H*", $ps_answer_before);
                #printlog ("Request Answer Before> " . $ps_answer_before);
                #printlog ("Request Answer> " . $answer);
                #print "Request Answer Before> " . $ps_answer_before . "\n";
                #print $client $answer;


                #$ps_answer_before = "29293D00060A" . $crc . "b106110d";
                #$answer = pack("H*", $ps_answer_before);
                #printlog ("DEV_ID: " . $ps_dev_id);
                #printlog ("Answer Before> " . $ps_answer_before);
                #printlog ("Answer> " . $answer);
                #print $client $answer;
            }
            
        }
        #====================================================================================================

        #GPS102
        #====================================================================================================
        if ($currentProtokol eq 102) {
            $isKnownProtocol = 1;
            #GPS102

            # ##,imei:359710043917690,A;
            # imei:359710043917690,tracker,1502072219,,F,141944.000,A,4211.2306,N,02420.0362,E,0.00,0;

            my @pmas_temp = split(/:/,$ps_data);

            if ($pmas_temp[0] eq ($ps_dev_id . ';')) {
                print $client "ON";
                printlog ("Answer> ON");

                if ($zsilence ne 1) {
                    #print formatdatetime("hh:mm:ss", time) . " | " . $ps_dev_id . " | LIVE |\n";
                }
            }

            if ($pmas_temp[0] eq '##,imei') {
                print $client "LOAD";
                printlog ("Answer> LOAD");

                my @pmas_temp2 = split(/,/,$pmas_temp[1]);
                $ps_dev_id = $pmas_temp2[0];

                if ($zsilence ne 1) {
                    print formatdatetime("hh:mm:ss", time) . " | " . $ps_dev_id . " | CONNECT |\n";
                }
            }

            if ($pmas_temp[0] eq 'imei') {
                my @pmas_temp2 = split(/,/,$pmas_temp[1]);
                $ps_dev_id = $pmas_temp2[0];

                $ps_x = int($pmas_temp2[7] * 10000);
                $ps_x_1 = int($ps_x * 0.000001);
                $ps_x_2 = int(($ps_x - $ps_x_1 * 1000000) / 6 * 10);
                $ps_x = $ps_x_1 . '.' . substr("00" . $ps_x_2, -6);

                $ps_y = int($pmas_temp2[9] * 10000);
                $ps_y_1 = int($ps_y * 0.000001);
                $ps_y_2 = int(($ps_y - $ps_y_1 * 1000000) / 6 * 10);
                $ps_y = $ps_y_1 . '.' . substr("00" . $ps_y_2, -6);

                $ps_speed = $pmas_temp2[11];
                #$ps_speed = 0;

                $ps_local_date = formatdatetime("YYYY-MM-DD hh:mm:ss", time());

                #$ps_local_date = formatdatetime("YYYY-MM-DD hh:mm:ss", $pmas_temp2[2]);
                #print "\n";
                #print "Date: " . $ps_local_date . " |" . $pmas_temp2[2] . "|\n";
                #print "x=" . $ps_x . "|\ny=" . $ps_y . "|\n\n";

                write_result($ps_dev_id, $ps_local_date, $ps_x, $ps_y, $ps_speed, $ps_data_hex);
            }

        }
        #====================================================================================================

        #TK102
        #====================================================================================================
        if ($currentProtokol eq 'tk102') {
            $isKnownProtocol = 1;

            #(027043576388BR00150919A4949.6147N02402.0461E000.60650290.000000000000L00000000)

            # (0
            # 27043576388
            # BR00
            # 150919
            # A
            # 4949.6147N
            # 02402.0461E
            # 000.6
            # 065029
            # 0.000000000000L00000000)

            $ps_dev_id = substr($ps_data, 2, 11);

            if ($zsilence ne 1) {
                print formatdatetime("hh:mm:ss", time) . " | " . $ps_dev_id . " | CONNECT |\n";
            }

            $subProtocol = substr($ps_data, 13, 4);

            printlog("Device: " . $ps_dev_id . " SubProtocol: " . $subProtocol);

            if ($subProtocol eq 'BR00') {

                $x = substr($ps_data, 24, 9);
                $y = substr($ps_data, 34, 10);


                $utcDate = '20' . substr($ps_data, 17, 2) . '-' . substr($ps_data, 19, 2) . '-' . substr($ps_data, 21, 2) . ' ' . substr($ps_data, 50, 2) . ':' . substr($ps_data, 52, 2) . ':' . substr($ps_data, 54, 2);
                $ps_local_date = UTC2LocalString($utcDate);

                $ps_x = int($x * 10000);
                $ps_x_1 = int($ps_x * 0.000001);
                $ps_x_2 = int(($ps_x - $ps_x_1 * 1000000) / 6 * 10);
                $ps_x = $ps_x_1 . '.' . substr("00" . $ps_x_2, -6);

                $ps_y = int($y * 10000);
                $ps_y_1 = int($ps_y * 0.000001);
                $ps_y_2 = int(($ps_y - $ps_y_1 * 1000000) / 6 * 10);
                $ps_y = $ps_y_1 . '.' . substr("00" . $ps_y_2, -6);

                $ps_speed = substr($ps_data, 45, 3);

                printlog("Device: " . $ps_dev_id . " Date: " . $ps_local_date . " X: " . $x . " Y: " . $y . " ps_x: " . $ps_x . " ps_y: " . $ps_y);

                #$ps_local_date = formatdatetime("YYYY-MM-DD hh:mm:ss", $pmas_temp2[2]);
                #print "\n";
                #print "Date: " . $ps_local_date . " |" . $pmas_temp2[2] . "|\n";
                #print "x=" . $ps_x . "|\ny=" . $ps_y . "|\n\n";

                write_result($ps_dev_id, $ps_local_date, $ps_x, $ps_y, $ps_speed, $ps_data);
            }
        }
        #====================================================================================================

        #Traccar
        #====================================================================================================
        if ($currentProtokol eq 'traccar') {
            $isKnownProtocol = 1;

            # $PGID,355070056790821*04
            # $GPRMC,225446,A,4916.45,N,12311.12,W,000.5,054.7,191194,020.3,E*68\r\n
            # $TRCCR,20150617123106.000,A,55.79049666666666,37.936236666666666,0.0,116.39,180.2,57,*01

            my @pmas_temp = split(/,/,$ps_data);

            if ($pb_is_test eq 1) {
                printlog("Traccar 0: " . $pmas_temp[0]); #***
            }

            if ($pmas_temp[0] eq '$PGID') {
                $ps_dev_id = $pmas_temp[1];
                my @pmas_temp2 = split(/\*/,$ps_dev_id);
                $ps_dev_id = $pmas_temp2[0];

                if ($zsilence ne 1) {
                    print formatdatetime("hh:mm:ss", time) . " | " . $ps_dev_id . " | CONNECT |\n";
                }

            }

            if ($pmas_temp[0] eq '$GPRMC') {

                #$GPRMC,122008.999,A,4747.1738,N,03513.9099,E,0.00,0.00,230515,,*03
                #$GPRMC,174354.889,A,3629.8600,N,00459.7093,W,0.00,0.00,211215,,*19


                $ps_utc_date = '20' . substr($pmas_temp[9], 4, 2) . '-' . substr($pmas_temp[9], 2, 2) . '-' . substr($pmas_temp[9], 0, 2) . ' ' . substr($pmas_temp[1], 0, 2) . ':' . substr($pmas_temp[1], 2, 2) . ':' . substr($pmas_temp[1], 4, 2);
                $ps_local_date = UTC2LocalString($ps_utc_date);

                $ps_x = int($pmas_temp[3] * 10000);
                $ps_x_1 = int($ps_x * 0.000001);
                $ps_x_2 = int(($ps_x - $ps_x_1 * 1000000) / 6 * 10);
                $ps_lat = $ps_x_1 . '.' . substr("00" . $ps_x_2, -6);

                $ps_y = int($pmas_temp[5] * 10000);
                $ps_y_1 = int($ps_y * 0.000001);
                $ps_y_2 = int(($ps_y - $ps_y_1 * 1000000) / 6 * 10);
                $ps_lng = $ps_y_1 . '.' . substr("00" . $ps_y_2, -6);

                $ew = $pmas_temp[6];
                if ($ew eq 'W') {
                    $ps_lng = $ps_lng * -1;
                }

                $ps_speed = $pmas_temp[7] * 1.852;

                $ps_str = "|date: " . $ps_local_date . "|lat (x): " . $ps_lat . "|lng (y): " . $ps_y . "| speed: " . $ps_speed . "\n";

                if ($pb_is_test eq 1) {
                    printlog($ps_str); #***
                }

                #print $ps_str;

                write_result($ps_dev_id, $ps_local_date, $ps_lat, $ps_lng, $ps_speed, $ps_data);

            }

            if ($pmas_temp[0] eq '$TRCCR') {
                # $TRCCR,20150617123106.000,A,55.79049666666666,37.936236666666666,0.0,116.39,180.2,57,*01

                $ps_utc_date = substr($pmas_temp[1], 0, 4) . '-' . substr($pmas_temp[1], 4, 2) . '-' . substr($pmas_temp[1], 6, 2) . ' ' . substr($pmas_temp[1], 8, 2) . ':' . substr($pmas_temp[1], 10, 2) . ':' . substr($pmas_temp[1], 12, 2);
                $ps_local_date = UTC2LocalString($ps_utc_date);

                $ps_lat = $pmas_temp[3];
                $ps_lng = $pmas_temp[4];

                $ps_speed = $pmas_temp[5] * 1.852;

                $ps_str = "|date: " . $ps_local_date . "|lat (x): " . $ps_lat . "|lng (y): " . $ps_y . "| speed: " . $ps_speed . "\n";
                #print $ps_str;

                write_result($ps_dev_id, $ps_local_date, $ps_lat, $ps_lng, $ps_speed, $ps_data);

            }
        }
        #====================================================================================================

        #H02
        #====================================================================================================
        if ($currentProtokol eq 'h02') {
            $isKnownProtocol = 1;

            # *HQ,353505220872211,V1,,V,3629.86245,N,00459.70816,W,0.00,0,,FBFFFFFF,d6,1e, c23,240f# 
            # *HQ,353505220872211,V1,175626,A,3629.84910,N,00459.68332,W,0.45,0,200116,FFFFFFFF,d6,1e, c23,240f# 
            
            my @pmas_temp = split(/,/,$ps_data);
            
            if ($pmas_temp[2] eq 'V1') {
                $ps_dev_id = $pmas_temp[1];

                if ($zsilence ne 1) {
                    print formatdatetime("hh:mm:ss", time) . " | " . $ps_dev_id . " | CONNECT |\n";
                }

                $ps_x = int($pmas_temp[5] * 10000);
                $ps_x_1 = int($ps_x * 0.000001);
                $ps_x_2 = int(($ps_x - $ps_x_1 * 1000000) / 6 * 10);
                $ps_lat = $ps_x_1 . '.' . substr("00" . $ps_x_2, -6);

                $ps_y = int($pmas_temp[7] * 10000);
                $ps_y_1 = int($ps_y * 0.000001);
                $ps_y_2 = int(($ps_y - $ps_y_1 * 1000000) / 6 * 10);
                $ps_lng = $ps_y_1 . '.' . substr("00" . $ps_y_2, -6);
                
                $ew = $pmas_temp[8];
                if ($ew eq 'W') {
                    $ps_lng = $ps_lng * -1;
                }

                $ps_utc_date = '20' . substr($pmas_temp[11], 4, 2) . '-' . substr($pmas_temp[11], 2, 2) . '-' . substr($pmas_temp[11], 0, 2) . ' ' . substr($pmas_temp[3], 0, 2) . ':' . substr($pmas_temp[3], 2, 2) . ':' . substr($pmas_temp[3], 4, 2);
                $ps_local_date = UTC2LocalString($ps_utc_date);

                $ps_speed = $pmas_temp[9] * 1.852;

                $ps_str = "|date: " . $ps_local_date . "|lat (x): " . $ps_lat . "|lng (y): " . $ps_y . "| speed: " . $ps_speed . "\n";

                if ($pb_is_test eq 1) {
                    printlog($ps_str); #***
                }
                
                #print $ps_str;
                
                write_result($ps_dev_id, $ps_local_date, $ps_lat, $ps_lng, $ps_speed, $ps_data);

            }
        }
        #====================================================================================================

        #Traccar 55
        #====================================================================================================
        if ($currentProtokol eq 'traccar55') {
            $isKnownProtocol = 1;

            # ?id=352372052807200&timestamp=1440418474&lat=47.78615908447165&lon=35.23193219149758&speed=0.0&bearing=0.0&altitude=107.84642666000549&batt=90.0

            $ps_data2 = "&" . substr($ps_data, 9, 140);
            my @pmas_temp = split(/&/,$ps_data2);

            #print "1|" . $pmas_temp[1] . "\n";
            #print "2|" . $pmas_temp[2] . "\n";
            #print "3|" . $pmas_temp[3] . "\n";
            #print "4|" . $pmas_temp[4] . "\n";
            #print "5|" . $pmas_temp[5] . "\n";
            #print "6|" . $pmas_temp[6] . "\n";
            #print "7|" . $pmas_temp[7] . "\n";
            #print "8|" . $pmas_temp[8] . "|\n";

            if ($pmas_temp[8] ne '') {
                $ps_dev_id = $pmas_temp[1];
                if ($zsilence ne 1) {
                    print formatdatetime("hh:mm:ss", time) . " | " . $ps_dev_id . " | CONNECT |\n";
                }
                $pmas_temp[2] = substr($pmas_temp[2], 10, 20);
                $ps_utc_date = formatdatetime("YYYY-MM-DD hh:mm:ss", $pmas_temp[2]);
                #print "Date: " . $ps_utc_date . "\n";
                #$ps_local_date = UTC2LocalString($ps_utc_date);
                $ps_local_date = $ps_utc_date;
                $ps_lat = substr($pmas_temp[3], 4, 20);
                $ps_lng = substr($pmas_temp[4], 4, 20);
                $ps_speed = substr($pmas_temp[5], 6, 20) * 1.852;

                $ps_str = "|date: " . $ps_local_date . "|lat (x): " . $ps_lat . "|lng (y): " . $ps_lng . "| speed: " . $ps_speed . "\n";
                write_result($ps_dev_id, $ps_local_date, $ps_lat, $ps_lng, $ps_speed, $ps_data);
                #Отвечаем
                $answer =  "HTTP/1.1 200 OK\r\n\r\n";
                $answer =  "HTTP/1.1 200\r\nContent-Type: text/plain\r\n\r\n";
                #print $client $answer;
 #print $client qq{HTTP/1.1 200 OK
 # };

 #print $client "hello22";

                #printlog ("Answer> " . $answer);
                #print $answer . "\n";

            }

            if (substr($ps_data, 4, 10) eq 'Connection' || substr($ps_data, 2, 10) eq 'Connection') {
                $answer =  "HTTP/1.1 200 OK\r\n\r\n";
                #$answer =  "HTTP/1.1 200\r\nContent-Type: text/plain\r\n\r\n";
                #print $client header(-type  =>  'text/html');
 #print $client qq{HTTP/1.1 200 OK
 #
 # };

                print $client $answer;
                printlog ("Answer> " . $answer);
                print $answer . "\n";
            }
        }
        #====================================================================================================

        #GT02
        #====================================================================================================
        if ($currentProtokol eq 'gt02') {
            $isKnownProtocol = 1;

            # 686825e67908647170034527070001100f020e0d140e05207b6503c7ab110000530326cb000000070d0a68680f0504086471700345270700ea1a04d00d0a
            # 6868 25 e679 0864717003452707 0001 10 0f020e0d140e05207b6503c7ab110000530326cb00000007 0d0a
            # 6868 0f 0504 0864717003452707 00ea 1a 04d0 0d0a

            #print "|" . $ps_data . "|";

            @arr = split(//, $ps_data);
            @pmas_symbol = ();
            $pi_c1 = 0;
            foreach $byte (@arr) {
                $hex = unpack "H2", $byte;
                $pi_c1++;
                $pmas_symbol[$pi_c1] = $hex;
            }

            if ($pmas_symbol[1] eq 68 && $pmas_symbol[2] eq 68) {
                $ps_proto = $pmas_symbol[16];
                $ps_dev_id = int($pmas_symbol[6]) . $pmas_symbol[7] . $pmas_symbol[8] . $pmas_symbol[9] . $pmas_symbol[10] . $pmas_symbol[11] . $pmas_symbol[12] . $pmas_symbol[13];

                if ($pb_is_test eq 1) {
                    print "|1: " . $pmas_symbol[1] . "|2: " . $pmas_symbol[2] . "| (proto): " . $ps_proto . "| (dev_id): " . $ps_dev_id . "|\n";
                }

                if ($ps_proto eq "10") {
                    #Координаты
                    #0f020e0d140e - дата и время - 15-2-14-13-14-14
                    $ps_year = $pmas_symbol[17]; #0A
                    $ps_year = "20" . hex($ps_year);
                    $ps_month = $pmas_symbol[18]; #03
                    $ps_month = substr("0" . hex($ps_month), -2);
                    $ps_day = $pmas_symbol[19]; #17
                    $ps_day = substr("0" . hex($ps_day), -2);
                    $ps_hour = $pmas_symbol[20];
                    $ps_hour = substr("0" . hex($ps_hour), -2);
                    $ps_minute = $pmas_symbol[21];
                    $ps_minute = substr("0" . hex($ps_minute), -2);
                    $ps_second = $pmas_symbol[22];
                    $ps_second = substr("0" . hex($ps_second), -2);

                    $ps_utc_date = $ps_year . '-' . $ps_month . '-' . $ps_day . ' ' . $ps_hour . ':' . $ps_minute . ':' . $ps_second;
                    $ps_local_date = UTC2LocalString($ps_utc_date);

                    #05207b65
                    $ps_lat = $pmas_symbol[23] . $pmas_symbol[24] . $pmas_symbol[25] . $pmas_symbol[26];
                    $ps_lat = hex($ps_lat);
                    $ps_lat = sprintf("%.6f", $ps_lat / 1800000);

                    #03c7ab11
                    $ps_lng = $pmas_symbol[27] . $pmas_symbol[28] . $pmas_symbol[29] . $pmas_symbol[30];
                    $ps_lng = hex($ps_lng);
                    $ps_lng = sprintf("%.6f", $ps_lng / 1800000);

                    #print "|local_data: " . $ps_local_date . "|lat: " . $ps_lat . "|lng: " . $ps_lng . "\n";

                    $ps_str = "|date: " . $ps_local_date . "|lat (x): " . $ps_lat . "|lng (y): " . $ps_lng . "|";
                    printlog($ps_str);
                }
                if ($ps_proto eq "10" || $ps_proto eq "1a") {

                    #Отвечаем на сообщение

                    $ps_answer_before = "54681A0D0A";
                    $ps_answer_text = pack("H*", $ps_answer_before);
                    printlog("Answer> " . $ps_answer_text);
                    #print "Answer> " . $ps_answer_text;
                    print $client $ps_answer_text;

                    $speed = hex($pmas_symbol[31]);

                    write_result($ps_dev_id, $ps_local_date, $ps_lat, $ps_lng, $speed, $ps_data_hex);
                }

            }
        }

        #GT06
        #====================================================================================================
        if ($currentProtokol eq 'gt06') {
            $isKnownProtocol = 1;

            @arr = split(//, $ps_data);
            @pmas_symbol = ();
            $pi_c1 = 0;
            foreach $byte (@arr) {
                $hex = unpack "H2", $byte;
                $pi_c1++;
                $pmas_symbol[$pi_c1] = $hex;
            }

            if ($pmas_symbol[1] eq 78 && $pmas_symbol[2] eq 78) {

                $ps_proto = $pmas_symbol[4];
                $ps_crc_in = $pmas_symbol[($pi_c1 - 3)] . $pmas_symbol[($pi_c1 - 2)];

                #print "|1: " . $pmas_symbol[1] . "|2: " . $pmas_symbol[2] . "| (proto): " . $ps_proto . "| (crc): " . $ps_crc_in . "|\n";

                if ($ps_proto eq "01" || $ps_proto eq "12") {
                    #Контролируем CRC
                    $ps_str_to_crc = '';
                    for ($pi1=3; $pi1<=@pmas_symbol-5; $pi1++) {
                        $ps_str_to_crc .= $pmas_symbol[$pi1];
                    }
                    $ps_crc = lc(CRC2($ps_str_to_crc));
                    #print "|str_to_crc: " . $ps_str_to_crc . "|CRC: " . $ps_crc . "|\n\n\n";

                    if ($ps_crc ne $ps_crc_in) {

                        #print "CRC_BAD\n\n\n";

                        printlog ("CRC_BAD -  In: " . $ps_crc_in . " StrToCRC: " . $ps_str_to_crc . " CRC: " . $ps_crc);

                    } else {

                        if ($ps_proto eq "01") {
                            #Отвечаем на приветственное сообщение

                            $ps_dev_id = int($pmas_symbol[5]) . $pmas_symbol[6] . $pmas_symbol[7] . $pmas_symbol[8] . $pmas_symbol[9] . $pmas_symbol[10] . $pmas_symbol[11] . $pmas_symbol[12];

                            if ($zsilence ne 1) {
                                print formatdatetime("hh:mm:ss", time) . " | " . $ps_dev_id . " | CONNECT |\n";
                            }

                            $ps_answer_before = "0501" . $pmas_symbol[13] . $pmas_symbol[14];
                            $ps_answer_crc = uc(CRC2($ps_answer_before));
                            $ps_answer_text = "78 78 05 01 " . $pmas_symbol[13] . " " . $pmas_symbol[14] . " " . substr($ps_answer_crc, 0, 2) . " " . substr($ps_answer_crc, 2, 2) . " 0d 0a";
                            $ps_answer_text3 = "78780501" . $pmas_symbol[13] . $pmas_symbol[14] . substr($ps_answer_crc, 0, 2) . substr($ps_answer_crc, 2, 2) . "0D0A";

                            #print "|answer=" . $ps_answer_text . "|\n\n\n";
                            printlog("Answer> " . $ps_answer_text);

                            $ps_answer_text = answer($pmas_symbol[13] . $pmas_symbol[14], "01");

                            print $client $ps_answer_text;
                        }

                        if ($ps_proto eq "12") {
                            #Координаты

                            #78 78 1f 12 0f 05 17 0a 00 28 c7 05 20 90 4a 03 c7 b1 9b 00 14 d6 00 ff 06 7e 30 00 00 1f 02 91 bb 06 0d 0a

                            $ps_year = $pmas_symbol[5]; #0A
                            $ps_year = "20" . hex($ps_year);
                            $ps_month = $pmas_symbol[6]; #03
                            $ps_month = substr("0" . hex($ps_month), -2);
                            $ps_day = $pmas_symbol[7]; #17
                            $ps_day = substr("0" . hex($ps_day), -2);
                            $ps_hour = $pmas_symbol[8];
                            $ps_hour = substr("0" . hex($ps_hour), -2);
                            $ps_minute = $pmas_symbol[9];
                            $ps_minute = substr("0" . hex($ps_minute), -2);
                            $ps_second = $pmas_symbol[10];
                            $ps_second = substr("0" . hex($ps_second), -2);

                            $ps_utc_date = $ps_year . '-' . $ps_month . '-' . $ps_day . ' ' . $ps_hour . ':' . $ps_minute . ':' . $ps_second;
                            $ps_local_date = UTC2LocalString($ps_utc_date);

                            $ps_lat = $pmas_symbol[12] . $pmas_symbol[13] . $pmas_symbol[14] . $pmas_symbol[15];
                            $ps_lat = hex($ps_lat);
                            $ps_lat = sprintf("%.6f", $ps_lat / 1800000);

                            $ps_lng = $pmas_symbol[16] . $pmas_symbol[17] . $pmas_symbol[18] . $pmas_symbol[19];
                            $ps_lng = hex($ps_lng);
                            $ps_lng = sprintf("%.6f", $ps_lng / 1800000);

                            $ps_sputnik_count = $pmas_symbol[11];
                            $ps_sputnik_count2 = substr($ps_sputnik_count, -1);

                            $ps_str = "|date: " . $ps_local_date . "|lat (x): " . $ps_lat . "|lng (y): " . $ps_lng . "|sputnik_count: " . $ps_sputnik_count . "=" . $ps_sputnik_count2;
                            printlog($ps_str);
                            #print $ps_str . "\n\n\n";

                            #open ($tempFile, ">>" . $ps_repalllog) || die;
                            #    print $tempFile $ps_str . "\n";
                            #close $tempFile;

                            $ps_speed = hex($pmas_symbol[20]);

                            write_result($ps_dev_id, $ps_local_date, $ps_lat, $ps_lng, $ps_speed, $ps_data_hex);
                        }
                    }
                }
            }
        }

        #Неизвестное подключение
        if ($isKnownProtocol ne 1) {
            print $client "\r\n";
            print $client "Who you are?\r\n";
            print $client "Receive: " . $ps_data;
        }

        #print "client info> ", $ps_data;
        #print $client "Receive: " . $ps_data;
    }
}

sub write_result{
    my $ps_dev_id = $_[0];
    my $ps_local_date = $_[1];
    my $ps_x = $_[2];
    my $ps_y = $_[3];
    my $ps_speed = $_[4];
    my $ps_raw = $_[5];

	if ($ps_y > 0 && $confIsWest eq 1) {
    	$ps_y = $ps_y * -1; # ***
	}

    $ps_raw =~s/\s//g;

    if ($pb_is_test eq 1) {
        print "dev_id=" . $ps_dev_id . " | ps_x=" . $ps_x . " |  ps_y=" . $ps_y . " |  ps_speed=" . $ps_speed . " |  ps_local_date=" . $ps_local_date . "|\n";
        printlog("dev_id=" . $ps_dev_id . " | ps_x=" . $ps_x . " |  ps_y=" . $ps_y . " |  ps_speed=" . $ps_speed . " |  ps_local_date=" . $ps_local_date . "|\n"); #***
    }

    if ($ps_dev_id ne '' && ($ps_x > 10 || $ps_y > 10) && $ps_x < 200 && $ps_y < 200) {
        #Открываем базу
        $conn1 = DBI->connect("DBI:mysql:database=" . $zubase . ";host=" . $zuserver, $zuuser, $zupass) || die $DBI::errstr;
        $ps_objtyper = 0;
        $ps_objcode = 0;
        $query = qq{
            SELECT
                1 AS OBJTYPER,
                p.CODE AS OBJCODE
            FROM
                tbl_pers AS p
            WHERE
                p.GPS_ID LIKE '%$ps_dev_id'
            UNION SELECT
                2 AS OBJTYPER,
                a.CODE AS OBJCODE
            FROM
                tbl_avto AS a
            WHERE
                a.GPS_ID LIKE '%$ps_dev_id'};
        printlog_sql_u($query);
            @ln = $rs->fetchrow_array();
            $ps_objtyper = $ln[0];
            $ps_objcode = $ln[1];
        $rs->finish();

        $ps_local_date_unix = mysqldatetounix($ps_local_date);

        $query = "UPDATE tbl_conf SET VALUEDATE = NOW() WHERE PARAM = '" . $zmodule_param . "'";
        sql_do($query);
        $pb_fixed = 0;
        if ($ps_speed < 1) {
            $ps_speed = 0;
        }
        if ($ps_objtyper > 0) {
            $ps_raw = substr($ps_raw, 0, 255);
            $query = "INSERT INTO tbl_gps SET OBJTYPER = " . $ps_objtyper . ", OBJCODE = " . $ps_objcode . ", DATEDO = '" . $ps_local_date . "', GEO_X = '" . $ps_x . "', GEO_Y = '" . $ps_y . "', SPEED = '" . $ps_speed . "', RAW = '" . $ps_raw . "'";
            sql_do($query);
            $pb_fixed = 1;
            #print "fixed\n";
        }
        $rs->finish();
        $conn1->disconnect();

        if ($zsilence ne 1) {
            print formatdatetime("hh:mm:ss", time) . " | " . $ps_dev_id . " (" . $ps_objtyper . "/" . $ps_objcode . ") | ";
            if ($pb_fixed ne 1) {
                print " ";
            }
            print $ps_local_date . " | " . $ps_x . "," . $ps_y . " |";
            if ($pb_fixed eq 1) {
                print "+";
            }
            print "\n";
        }
    }
    return;
}

sub answer {
    my $serialno = $_[0];
    my $protocol = $_[1];
    my $answer = "05" . $protocol . $serialno;
    $answer = "7878" . $answer . CRC2($answer) . "0d0a";
    $answer = pack("H*", $answer);
    return $answer;
}
sub CRC2 {
     my $bytes = shift;
     $bytes = pack("H*", $bytes);
     my @table =(0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF,
      0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7,
      0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E,
      0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876,
      0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD,
      0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5,
      0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C,
      0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974,
      0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB,
      0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3,
      0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A,
      0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72,
      0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9,
      0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1,
      0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738,
      0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70,
      0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7,
      0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF,
      0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036,
      0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E,
      0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5,
      0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD,
      0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134,
      0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C,
      0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3,
      0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB,
      0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232,
      0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A,
      0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1,
      0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9,
      0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330,
      0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78);

     my $crc = 0xffff;
     foreach my $x (unpack ('C*', $bytes)) { $crc = (($crc >> 8) & 0xffff) ^ $table[ ($crc ^ $x) & 0xff ]; }
     $crc = $crc ^ 0xffff;
     return sprintf("%0004x",$crc);
}

### ================================================================================================================
#Standart Module Light function v.2 - 05.01.2015
#================================================================================================================
sub trim {
    my($string) = @_;
    for ($string) {
        s/^\s+//;
        s/\s+$//;
    }
    return $string;
}

#========================================================
sub formatdatetime {
    my $format = shift @_ || "YYYY-MM-DD hh:mm:ss";
    my $datetime = shift @_ || time;
    my %strings = (
        '500'=>"AM", '501'=>"PM",
        '400'=>"January", '401'=>"February", '402'=>"March", '403'=>"April", '404'=>"May", '405'=>"June", '406'=>"July", '407'=>"August", '408'=>"September", '409'=>"October", '410'=>"November", '411'=>"December",
        '300'=>"Jan", '301'=>"Feb", '302'=>"Mar", '303'=>"Apr", '304'=>"May", '305'=>"Jun", '306'=>"Jul", '307'=>"Aug", '308'=>"Sep", '309'=>"Oct", '310'=>"Nov", '311'=>"Dec",
        '200'=>"Sunday", '201'=>"Monday", '202'=>"Tuesday", '203'=>"Wednesday", '204'=>"Thursday", '205'=>"Friday", '206'=>"Saturday",
        '100'=>"Sun", '101'=>"Mon", '102'=>"Tue", '103'=>"Wed", '104'=>"Thu", '105'=>"Fri", '106'=>"Sat"
    );
    ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime($datetime);
    $year += 1900;
    if ($format=~m/AM/) {
        my $ampmhour=($hour % 12) || 12;
        $format=~s/hh/sprintf("%02u",$ampmhour)/eg;
        $format=~s/h/$ampmhour/eg;
        $format=~s/AM/($hour>11?"^501":"^500")/eg;
    } else {
        $format=~s/hh/sprintf("%02u",$hour)/eg;
        $format=~s/h/$hour/eg;
    };
    $format=~s/mm/sprintf("%02u",$min)/eg;
    $format=~s/m/$min/eg;
    $format=~s/ss/sprintf("%02u",$sec)/eg;
    $format=~s/s/$sec/eg;

    $format=~s/YYYY/$year/eg;
    $format=~s/YY/sprintf("%02u",$year % 100)/eg;
    $format=~s/MMMM/sprintf("^4%02u",$mon)/eg;
    $format=~s/MMM/sprintf("^3%02u",$mon)/eg;
    $format=~s/MM/sprintf("%02u",$mon+1)/eg;
    $format=~s/M/($mon+1)/eg;
    $format=~s/DDDD/sprintf("^2%02u",$wday)/eg;
    $format=~s/DDD/sprintf("^1%02u",$wday)/eg;
    $format=~s/DD/sprintf("%02u",$mday)/eg;
    $format=~s/D/$mday/eg;
    $format=~s/\^(\d\d\d)/$strings{$1}/g;
    return $format;
}

#========================================================
sub printlog{
    my($string) = @_;
    print $fileLog formatdatetime("DD.MM.YYYY hh:mm:ss", time) . " - (" . $$ . ") " . $string . "\n";
    return $string;
}

#========================================================
sub printlog2{
    my($string) = @_;
    open ($fileTemp, ">>" . $ps_rep_logupd) || die;
    print $fileTemp formatdatetime("DD.MM.YYYY hh:mm:ss", time) . " - (" . $$ . ") " . $string . " - 2\n";
    close $fileLog;
}

#========================================================
sub sql_do{
    my($string) = @_;
    $zl_sqlc_u++;
    #print 'U: '.$zl_sqlc_u."\n";
    print $ps_file102 "U:" . $zl_sqlc_u . "| " . $string . ";\n";
    $conn1->do($string);
    return $string;
}

#========================================================
sub printlog_sql_u{
    my($string) =@_;
    $zl_sqlc_u++ ;
    print $ps_file102 "U:" . $zl_sqlc_u . '| ' . $string . ";\n";
    $rs = $conn1->prepare($string);
    $rs->execute();
    return $string;
}

#========================================================
sub load_first_light {
    $ps_repalllog = $ps_logpath . 'rep_alllog.txt';
    $ps_rep_logupd = $ps_logpath . 'rep_logupd.txt';
    $ps_rep_sql = $ps_logpath . 'rep_mysql.txt';

	if(!defined $ARGV[0]){
		$ARGV[0] = '';
	}
	if(!defined $ARGV[1]){
		$ARGV[1] = '';
	}
	if(!defined $ARGV[2]){
		$ARGV[2] = '';
	}
	
    if ($ARGV[0] eq 'debug' || $ARGV[1] eq 'debug' || $ARGV[2] eq 'debug') {
        $ps_full_debug = 1;
    }

    open ($fileLog, ">" . $ps_rep_logupd) || die;
    print $fileLog "===========================================\n";

    #Удаляем громоздкий файл
    $ps_fn_size  = -s $ps_repalllog;
    if ($ps_fn_size > 100000) {
        unlink($ps_repalllog);
    }

    open ($tempFile, ">>" . $ps_repalllog) || die;
        print $tempFile $zver . ' Module START at ' . formatdatetime("DD.MM.YYYY hh:mm:ss", time) . "\n";
    close $tempFile;

    $pidfile = $ps_logpath . "pid.txt";
    if (-e $pidfile) {
        unless (open(PIDFILE, $pidfile)) {
            #Если найден - то выходим
            open ($tempFile, ">>".$ps_repalllog) || die;
                print $tempFile $zver . " Find previous PID: " . $oldpid . " - exit\n";
                print $tempFile $zver . " FINISH at " . formatdatetime("DD.MM.YYYY hh:mm:ss", time) . "\n";
                print $tempFile "==============================================================\n";
            close $tempFile;
            exit(1);
        }
        close PIDFILE;

		open ($tempFile, "<" . $pidfile) || die;
		    while ($ps1=readline $tempFile) {
		        my @ps_mas = split(/\n/, $ps1);
		        $ps_pid = $ps_mas[0];
		        if ($ps_pid > 0 || $ps_pid < 0) {
	                kill(0, $ps_pid);
	                $a = `kill -9 $ps_pid`;
	                printlog("Kill Process: " . $ps_pid);
	                print "Kill Process: " . $ps_pid . "\n";
		        }
		    }
		close $tempFile;
    }
    open(PID, ">$pidfile") or die;
        print PID $$;
    close(PID);

    # Выведем заголовок типа данных
    if ($zsilence ne 1) {
        print $zver . "\n";
        print "===================================\n";
        print 'start module at ' . formatdatetime("DD.MM.YYYY hh:mm:ss", time) . "\n";
    }
    printlog($zver." - start module");
    printlog($zpath);
    open ($ps_file102, ">" . $ps_rep_sql) || die;
    print $ps_file102 formatdatetime("DD.MM.YYYY hh:mm:ss", time) . "\n";
    $zl_sqlc_u = 0;
    #Открываем базу
    $conn1 = DBI->connect("DBI:mysql:database=" . $zubase . ";host=" . $zuserver, $zuuser, $zupass) || die $DBI::errstr;
    if ($zucp eq '') {
        $zucp = 'cp1251';
    }
    $conn1->do('set character set ' . $zucp);
    $conn1->do('set names ' . $zucp);
    return;
}

#========================================================
sub version_verify_light {
    if ($ps_module_allow ne 1) {
        open ($tempFile, ">>" . $ps_repalllog) || die;
            print $tempFile $zver . " Module disabled in system - exit\n";
            print $tempFile $zver . " Module FINISH at " . formatdatetime("DD.MM.YYYY hh:mm:ss", time) . "\n";
            print $tempFile "==============================================================\n";
        close $tempFile;
        close $ps_file102;
        print "Module disabled in system - exit\n";
        print "=================================== \n";
        $rs->finish();
        $conn1->disconnect();
        exit(1);
    }
    if (($zrevision < $ps_needversion) || ($ps_needversion < 1)) {
        open ($tempFile, ">>" . $ps_repalllog) || die;
            print $tempFile $zver . ' Version failure. Need version: ' . $ps_needversion . " - exit\n";
            print $tempFile $zver . ' Module FINISH at ' . formatdatetime("DD.MM.YYYY hh:mm:ss", time) . "\n";
            print $tempFile "==============================================================\n";
        close $tempFile;
        close $ps_file102;
        print 'Version failure. Need version: ' . $ps_needversion . " - exit\n";
        print "===================================\n";
        $rs->finish();
        $conn1->disconnect();
        exit(1);
    }
    return;
}

#========================================================
sub load_second_light {
    #Фиксируем время по базам
    $query = 'SELECT NOW()';
    printlog_sql_u($query);
    @ln = $rs->fetchrow_array();
    $ps_time_us = $ln[0];
    printlog('Time in DB UserSide: ' . $ps_time_us);
    printlog("zsilence      = " . $zsilence);

    #Прописываемся в базу
    $ps_info = $zver . '|' . $zpath . '|' . $ps_time_us . '|';
    $query = "UPDATE tbl_conf SET VALUEMEMO = '" . $ps_info . "' WHERE PARAM = '" . $zmodule_param . "'";
    sql_do($query);

    return;
}

#========================================================
sub bufer_clear{
    #Сброс буферов в файлы
    close $fileLog;
    open ($fileLog, ">>" . $ps_rep_logupd) || die;
    close $ps_file102;
    open ($ps_file102, ">>" . $ps_rep_sql) || die;
    return;
}

#========================================================
sub ip2long {
    return unpack("N",inet_aton(shift));
}

#========================================================

sub mysqldatetounix {
    my($string)=@_;
    if (length($string) eq 10) {
        $string .= " 00:00:01";
    }
    $ps_year = substr($string, -length($string), 4);
    $ps_month = substr($string, -length($string) + 5, 2);
    $ps_day = substr($string, -length($string) + 8, 2);
    $ps_hour = substr($string, -length($string) + 11, 2);
    $ps_minute = substr($string, -length($string) + 14, 2);
    $ps_second = substr($string, -length($string) + 17, 2);
    if ($ps_month < 1) {
        $ps_month = '1';
    }
    if (!$ps_day) {
        $ps_day = '1';
    }
    $string = timelocal($ps_second, $ps_minute, $ps_hour, $ps_day, $ps_month-1, $ps_year);
    return $string;
}

#========================================================
sub UTC2LocalString {
  my $t = shift;
  my ($datehour, $rest) = split(/:/,$t,2);
  my ($year, $month, $day, $hour) =
      $datehour =~ /(\d+)-(\d\d)-(\d\d)\s+(\d\d)/;

  #  proto: $time = timegm($sec,$min,$hour,$mday,$mon,$year);
  $month = $month - 1;
  if ($month eq -1) {
  	  return ('1970-01-01 00:00:00');
  }
  my $epoch = timegm (0,0,$hour,$day,$month,$year);

  #  proto: ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
  #          localtime(time);
  my ($lyear,$lmonth,$lday,$lhour,$isdst) =
            (localtime($epoch))[5,4,3,2,-1];

  $lyear += 1900;  # year is 1900 based
  $lmonth++;       # month number is zero based
  #print "isdst: $isdst\n"; #debug flag day-light-savings time
  return ( sprintf("%04d-%02d-%02d %02d:%s",
           $lyear,$lmonth,$lday,$lhour,$rest) );
}

#========================================================