Сбор звонков с Avaya IP Office 500 (smdr/cdr)

Попалась под руки Avaya IPO500, весьма кстати распространенная в наших широтах. Стало интересно - как бы с нее детализацию звонков (smdr в аваевской терминологии) получить. Настройка станции весьма проста - там указывается ип-адрес сервера назначения, коллектора, и порт)

Wintarrif со сбором звонков справился на ура, но он триальный, на две недели, неинтересно, разумеется хотелось чего-нить бесплатного. Попробовали посмотреть netcat'ом, а что там собственно приходит-то, со станции, может как-нить получится формат понят и пропарсить - так вот, вы не представляете - там обычный текст идет! Один звонок - одна запись, поля разделены запятыми. Ну сами понимаете - сам торвалдс велел взять в руки напильничек, в результате чего родился вот такой вот нижеприведенный перловый скрипт-демон, который висит себе (в нашем случае на 60100-м порту) пишет звонки в логфайл, и заодно еще и в базу пишет. Ну а уж с этими данными все что душа пожелает можно сделать - например всякие отчеты по направлениям, дозвоном/недозвоном, длительностью ожидания, тарификацию ту же. Скриптом делюсь (названия полей кстати взял из документашки - почти все названия вполне понятны и говорят сами за себя)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#!/usr/bin/perl
 
use strict;
use warnings;
use DBI;
 
package SimpleServer;
 
use base qw(Net::Server);
 
my $dbhost = 'localhost';
my $dbname.= 'smdr';
my $dbuser = 'smdr';
my $dbpass = 'smdr';
 
my $DEBUG = 0;
 
if((defined($ARGV[0]))&&(($ARGV[0] eq '-x')||($ARGV[0] eq '-X')))
{
  $DEBUG = 1;
}
 
sub process_request
{
    while () {
        s/\r?\n$//;
        print STDERR "Received [$_]\n" if $DEBUG;
        open FH, ">>/var/log/smdr-ip500.dump";
        print FH "$_\n";
        close FH;
        my ($CallStart, $ConnectedTime, $RingTime, $Caller, $Direction, $CalledNumber,
         $DialledNumber, $Account, $IsInternal, $CallID, $Continuation, $Party1Device,
         $Party1Name, $Party2Device, $Party2Name, $HoldTime, $ParkTime, $AuthValid,
         $AuthCode, $UserCharged, $CallCharge, $Currency, $AmountatLastUserChange,
         $CallUnits, $UnitsatLastUserChange, $CostperUnit, $MarkUp, $ExternalTargetingCause,
         $ExternalTargeterId, $ExternalTargetedNumber) = split /\,/;
 
        $CallStart =~ s/\//-/g;
        my ($h,$m,$s) = split /\:/, $ConnectedTime;
        $ConnectedTime = $h*3600+$m*60+$s;
 
        $RingTime = 0 if $RingTime eq '';
        $IsInternal = 0 if $IsInternal eq '';
        $CallID = 0 if $CallID eq '';
        $Continuation = 0 if $Continuation eq '';
        $HoldTime = 0 if $HoldTime eq '';
        $ParkTime = 0 if $ParkTime eq '';
        $AuthValid = 0 if $AuthValid eq '';
 
        my $dbh = DBI->connect('DBI:mysql:'.$dbname.':'.$dbhost,$dbuser,$dbpass,{RaiseError => 1}) or print STDERR "connecting: $DBI::errstr\n";
        $dbh->do("SET NAMES UTF8");
        my $cmd = "insert into smdr set ".
                  "CallStart = '$CallStart',".
                  "ConnectedTime = $ConnectedTime,".
                  "RingTime = $RingTime,".
                  "Caller = '$Caller',".
                  "Direction = '$Direction',".
                  "CalledNumber = '$CalledNumber',".
                  "DialledNumber = '$DialledNumber',".
                  "Account = '$Account',".
                  "IsInternal = $IsInternal,".
                  "CallID = $CallID,".
                  "Continuation = $Continuation,".
                  "Party1Device = '$Party1Device',".
                  "Party1Name = '$Party1Name',".
                  "Party2Device = '$Party2Device',".
                  "Party2Name = '$Party2Name',".
                  "HoldTime = $HoldTime,".
                  "ParkTime = $ParkTime,".
                  "AuthValid = $AuthValid,".
                  "AuthCode = '$AuthCode',".
                  "UserCharged = '$UserCharged',".
                  "CallCharge = '$CallCharge',".
                  "Currency = '$Currency',".
                  "AmountatLastUserChange = '$AmountatLastUserChange',".
                  "CallUnits = '$CallUnits',".
                  "UnitsatLastUserChange = '$UnitsatLastUserChange',".
                  "CostperUnit = '$CostperUnit',".
                  "MarkUp = '$MarkUp',".
                  "ExternalTargetingCause = '$ExternalTargetingCause',".
                  "ExternalTargeterId = '$ExternalTargeterId',".
                  "ExternalTargetedNumber = '$ExternalTargetedNumber'";
        print STDERR "SQL: $cmd\n" if $DEBUG;
        my $sth = $dbh->do($cmd);
        last if /quit/i;
    }
}
 
if($DEBUG)
{
  SimpleServer->run(port => 60010);
}
else
{
  SimpleServer->run(port => 60010, background => 1, setsid => 1);
}
tags: