The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  вход/выход  слежка  RSS
"Помогите подправить скрипт, вставив перекодирование"
Вариант для распечатки  
Пред. тема | След. тема 
Форум Программирование под UNIX (Perl)
Изначальное сообщение [ Отслеживать ]

"Помогите подправить скрипт, вставив перекодирование"  +/
Сообщение от Alting email(ok) on 27-Апр-11, 14:02 
Коллеги, выручайте!
В перле ни ганджубас :(
Отсюда:
http://ipo.wikidot.com/sniff

Вот скрипт:

#!/usr/bin/perl -w

use Config::Tiny;
use Net::TFTP;
use IO::Socket::INET;
use POSIX;

## Avaya Fn Description

%TAIL = (             ## this is tail exceptions (normal is 0x44)
    0x0526 => 0x4e,
    0x0705 => 0x48,
    0x071d => 0x43,
    0x0726 => 0x4e,
    0x0426 => 0x4e
);

@KNOWN = (            ## Functions known (and loved)
    0x0200,
    0x0405, 0x0408, 0x0409, 0x040a, 0x040d, 0x040e, 0x041f, 0x0425, 0x0426,
    0x0505, 0x0506, 0x0507, 0x0508, 0x050a, 0x050b, 0x050c, 0x050e, 0x0526, 0x052b,
    0x0705, 0x0706, 0x0707, 0x0708, 0x070a, 0x070b, 0x070c, 0x070e, 0x071c, 0x071d, 0x071e, 0x071f, 0x0722, 0x0726, 0x072b, 0x072c,
    0x0800
);

foreach (@KNOWN)    {
    $known{$_} = 1;
}

# Reading config
$Config = Config::Tiny->read( 'phoneavay.ini' );

$user = $Config->{_}->{User};
$pass = $Config->{_}->{Password};
$pbx  = $Config->{_}->{IPOffice};
$pref = $Config->{_}->{Prefer0x07};

$TIMEOUT=5;        ## UDP Timeout

$reqstr = "";        ## request string with name and password
$counter = 0;        ## Counter for the packets

# Making password encoded
$s = $pass;
for($i=0; length($s) != 0; $s = substr($s,1))    {
    $c = unpack("C", $s);
    $nc = $c + 0x10 - $i;
    $ps .= pack("C", $nc);
    $i++;
}
print tftp_get_str("nasystem/who_is")."\n";
tftp_get_str("nasystem/user_list2");
tftp_get_str("nasystem/licence_list");
tftp_get_str("nasystem/user_list4");
tftp_get_str("nasystem/extn_list");
$reqstr = sprintf("%c%s%c%s", length($user), $user, length($ps), $ps);

# Preparing UDP
$ipo = new IO::Socket::INET->new(PeerPort=>50796,Proto=>'udp',PeerAddr=>$pbx) || die;

## Running listening thread

login_to_pbx();

$| = 1;

while(1)    {
    next    if(! ($s = read_reply()));
    $counter = unpack("C", substr($s,1,1));
    send_ok();
    process_reply($s)    if(defined($s));
    last     if(substr($s,0,1) eq "\x02");
}

print "Well done";

logout_from_pbx();

exit;

sub read_reply {
    my $packet = undef;
    eval {
        local $SIG{ALRM} = sub { die "alarm time out" };
        alarm $TIMEOUT;
        $ipo->recv($packet, 1024)      or die "recv: $!";
        alarm 0;
    };
    return $packet;
}

# *************
# decode_passtr(buff) - decode pascal string (len)str
# returns array (str,rest_part)
#    str - resulting string
#    rest_part - rest part of data just after string

sub decode_passtr    {
    my $b = shift;
    my $s = "";
    my $len = unpack("C", $b);
    $b = substr($b,1);
    while($len--)    {
        $s .= substr($b,0,1);
        $b = substr($b,1);
    };
    return ($s, $b);
}

sub process_reply    {
    my $packet = shift;
    $fn = unpack("C", $packet);
    $counter = unpack("C", substr($packet,1));
    if($fn == 0x02)    {
        print "Logout\n";
    } elsif($fn == 0x08)    {
#        print "OK\n";
    } else    {            # getting subfn
        $fn = avaya_fn($packet);
        if(defined($known{$fn}))    {
            return    if(length($packet) < 0x1a);    # ignore short packets
        # decoding payload
            $dddd = unpack("N", substr($packet, 0x1a, 4));
            $vc = unpack("N", substr($packet, 0x11, 4));
            ($s1, $s2, $s3, $s4, $packet) = decode_dddd(substr($packet, 0x1a));
            $off = 0x44;        # standard offset
            $off = $TAIL{$fn}    if(defined($TAIL{$fn}));
            ($sp, $packet) = decode_passtr(substr($packet, $off));
        # analyze it
            return    if($fn == 0x071f || $fn == 0x041f);    # skip "i'm alive"
            if($fn == 0x0405)    {
                print strftime("%H:%M", localtime(time)), " handset lifted, ";
            } elsif($fn == 0x071d)    {
                $sp =~ s/[\r\n]+//g;
                print "($sp)";
            } elsif($fn == 0x0409)    {
                print "$s1";
            } elsif($fn == 0x071c)    {
                print "connected $s3->$s1";
            } elsif($fn == 0x070e)    {
                print " hang up\n";
            } elsif($fn == 0x0506 || $fn == 0x0706)    {
                return if(ignored($fn));
                print "[$s1 ($sp) dialed]"    if($s1 ne "");
                # skip
            } elsif($fn == 0x0507 || $fn == 0x0707)    {
                # skip
            } elsif($fn == 0x052b || $fn == 0x072b)    {
                # skip
            } elsif($fn == 0x050e || $fn == 0x040e)    {
                # skip
            } elsif($fn == 0x050a || $fn == 0x070a)    {
                # skip
            } elsif($fn == 0x070b || $fn == 0x050b)    {
                # skip
            } elsif($fn == 0x0425)    {
                print "(second call)";
            } elsif($fn == 0x0423)    {
                print "(call retrieved)";
            } elsif($fn == 0x040d)    {
                # skip
            } elsif($fn == 0x0722)    {
                # skip
            } elsif($fn == 0x051c)    {
                # skip
            } elsif($fn == 0x0408)    {
                # skip
            } elsif($fn == 0x0508 || $fn == 0x0708)    {
                return if(ignored($fn));
                print " waiting ";
            } elsif($fn == 0x040a)    {
                # skip
            } elsif($fn == 0x0505 || $fn == 0x0705)    {
                return if(ignored($fn));
                print strftime("%H:%M", localtime(time)), " incoming $sp($s3)";
            } elsif($fn == 0x0526 || $fn == 0x0726)    {
                return if(ignored($fn));
                print "  VM: $s1: $s2 $s3\n";
            } else {    # print function
                $sp = printable_str($sp);
                printf "S: 0x%04x", $fn;
                printf " VC=%d", $vc;
                printf " %08x:($s1)($s2)($s3)($s4)", $dddd;
                print "+($sp)\n";
            }
        } else {
            printf " unknown %04x", $fn;
            dump_hex($packet);
        }
    }
}

# returns string from PBX
sub tftp_get_str    {
    my $rrq = shift;

    my $tftp = Net::TFTP->new("$pbx", Mode => "octet");
    $fh = $tftp->get("$rrq");
    $s = <$fh>;
    chomp $s;
    return $s;
}

# Send a request to pbx
#   send_to_pbx ( function, payload);
#
sub send_to_pbx    {
    my ($fn, $req) = (shift, shift);
    my $s = sprintf("%c%c$reqstr$req", $fn, $counter);
    $ipo -> send($s);
#    print "\nSent:";
#    dump_hex($s);
}

sub send_ok    {
    send_to_pbx(0x08, "");
}

# Try to login to PBX
sub login_to_pbx {
    send_to_pbx(0x03, "\x01\x01\x00\x01\x00\x01\x00\x00\x00\x00");
    my $reply = read_reply();
    if(substr($reply,0,1) eq "\x0a")    {    ## name/pass error
        ($s1, $reply) = decode_passtr(substr($reply, 2));
        ($s2, $reply) = decode_passtr($reply);
        return "$s1: $s2";
    } else {
        return "Ok";
    }
}

sub logout_from_pbx    {
    send_to_pbx(0x02, "");
    read_reply();
}

# dumps the string out in hex
sub dump_hex    {
    my $data = shift;
    my $i;
    my $ascii = "";
    for($i=0;$i != length($data); $i++)      {
        if(($i & 0x1f) == 0)    {
            print "$ascii\n";
            $ascii = "    ";
        }
        $rc = substr($data, $i, 1);
        $c = unpack("C", $rc);
        printf " %02x", $c;
        $rc =~ s/[\x00-\x1f\x80-\xff]/./;
        $ascii .= $rc;
    }
    print "   " x (34-length($ascii))."      $ascii\n";
}

# decode dddd reply
# Returns:
# (s1,s2,s3,s4,rest)
# s1/s2 - first 2 strings
# s3/s4 - second strings
# rest  - rest part
sub decode_dddd {
    my $data = shift;
    my ($s1, $s2, $s3, $s4);
    ($s1, $data) = decode_passtr(substr($data,4));
    ($s2, $data) = decode_passtr($data);
    ($s3, $data) = decode_passtr(substr($data,4));
    ($s4, $data) = decode_passtr($data);
    return ($s1, $s2, $s3, $s4, substr($data,4));
}

sub avaya_fn    {
    my $data = shift;
    return unpack("v", substr($data,4,1).substr($data,0,1));
}

sub printable_str    {
    $_ = shift;
    s/[\x00-\x1f\x80-\xff]/sprintf("\\x%02x", unpack("C", $&))/ge;
    return $_;
}

sub ignored    {
    my $a = shift;
    return ($pref == 1 && ($a >> 8) == 5) || ($pref == 0 && ($a >> 8) == 7);
}

Берет с тел. станции информацию в Windows-1251.
А вывод требуется в UTF-8
Как туда декодирование добавить?

Ответить | Правка | Cообщить модератору

Оглавление

Сообщения по теме [Сортировка по времени | RSS]


1. "Помогите подправить скрипт, вставив перекодирование"  +/
Сообщение от NuINu (??) on 27-Апр-11, 21:39 
> Коллеги, выручайте!
> В перле ни ганджубас :(
> Отсюда:
> http://ipo.wikidot.com/sniff
> Берет с тел. станции информацию в Windows-1251.
> А вывод требуется в UTF-8
> Как туда декодирование добавить?

Поинтересуюсь :-), а что делает эта программа?

по теме ), если надо весь вывод программы переконвертировать из одной кодировки в другую, ничего в программе менять не надо, надо весь вывод программы пусть в пайп на iconv, он сделает перекодировку.

Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

2. "Помогите подправить скрипт, вставив перекодирование"  +/
Сообщение от Alting email(ok) on 28-Апр-11, 07:32 
>[оверквотинг удален]
>> В перле ни ганджубас :(
>> Отсюда:
>> http://ipo.wikidot.com/sniff
>> Берет с тел. станции информацию в Windows-1251.
>> А вывод требуется в UTF-8
>> Как туда декодирование добавить?
> Поинтересуюсь :-), а что делает эта программа?
> по теме ), если надо весь вывод программы переконвертировать из одной кодировки
> в другую, ничего в программе менять не надо, надо весь вывод
> программы пусть в пайп на iconv, он сделает перекодировку.

Этот скрипт подключается к тел. станции с логином и паролем пользователя и считывает информацию по звонкам, идет звонок - скрипт сыпет информацию (кто, кому, куда, состоялся ли разговор и .т.п.).
В дальнейшем собирался таким образом парсить информацию и слать смс-ку о пропущенном вызове (сейчас мой внутренний стоит в твиннинге с сотовым, но сколько не долби "уверенным пользователям ПК", чтобы подольше вызов держали - воз и ныне там. А я не вижу вызывающего на сотовом - только АОН наш, который подставляет провайдер и не знаю, кто именно мне звонил).
К сожалению, скрипт, мягко говоря, сыроват - подглючивает сильно и отваливается.
Прописал в начале use encoding 'cp1251', STDOUT => 'utf8';
Вроде теперь по-русски пишет, но как-то очень выборочно, но думаю, дело в не совсем верном парсинге ответов станции (скрипт старый и писался, судя по всему, под более старую версию ПО станции).


Ответить | Правка | ^ к родителю #1 | Наверх | Cообщить модератору

3. "Помогите подправить скрипт, вставив перекодирование"  +/
Сообщение от NuINu (??) on 28-Апр-11, 18:35 
>[оверквотинг удален]
> вызове (сейчас мой внутренний стоит в твиннинге с сотовым, но сколько
> не долби "уверенным пользователям ПК", чтобы подольше вызов держали - воз
> и ныне там. А я не вижу вызывающего на сотовом -
> только АОН наш, который подставляет провайдер и не знаю, кто именно
> мне звонил).
> К сожалению, скрипт, мягко говоря, сыроват - подглючивает сильно и отваливается.
> Прописал в начале use encoding 'cp1251', STDOUT => 'utf8';
> Вроде теперь по-русски пишет, но как-то очень выборочно, но думаю, дело в
> не совсем верном парсинге ответов станции (скрипт старый и писался, судя
> по всему, под более старую версию ПО станции).

спасибо за подробное объяснение. скрипт написан в худших традициях перла, чтобы его понять надо сломать мозг изучая каждую запятую во всем тексте программы.

там у вас есть куча обращений по тфтп, к станции, для ваших целей они лишние, к тому же большая их часть вообще не распечатывается, т.е пропадает в пустую.

Ответить | Правка | ^ к родителю #2 | Наверх | Cообщить модератору

4. "Помогите подправить скрипт, вставив перекодирование"  +/
Сообщение от eugene pazhitnov email on 07-Май-11, 00:10 
> К сожалению, скрипт, мягко говоря, сыроват - подглючивает сильно и отваливается.
> Прописал в начале use encoding 'cp1251', STDOUT => 'utf8';
> Вроде теперь по-русски пишет, но как-то очень выборочно, но думаю, дело в
> не совсем верном парсинге ответов станции (скрипт старый и писался, судя
> по всему, под более старую версию ПО станции).

О, неужели кому-то понадобилось?!

Да, писалось под 3-ю версию прошивки и, как правильно заметил коллега ниже, "в худших традициях перла". Тем не менее, если у Вас получится что-то интересное, прошу поделиться с общественностью, готов дать права на ipo.wikidot.com.

Ответить | Правка | ^ к родителю #2 | Наверх | Cообщить модератору

5. "Помогите подправить скрипт, вставив перекодирование"  +/
Сообщение от Alting email(ok) on 10-Май-11, 13:52 
> О, неужели кому-то понадобилось?!
> Да, писалось под 3-ю версию прошивки и, как правильно заметил коллега ниже,
> "в худших традициях перла". Тем не менее, если у Вас получится
> что-то интересное, прошу поделиться с общественностью, готов дать права на ipo.wikidot.com.

да, Евгений, здравствуйте!
Понадобилось мне, но я перла не знаю совершенно :(
А задумка прекрасная!

Ответить | Правка | ^ к родителю #4 | Наверх | Cообщить модератору

Архив | Удалить

Рекомендовать для помещения в FAQ | Индекс форумов | Темы | Пред. тема | След. тема




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру