Не секрет, что есть условно бесплатные (3000 минут) SIM-карты и если превысить их лимит, оператор может узнать, что используется gsm-шлюз. Представленный скрипт распределяет нагрузку и не звонит при превышении лимита по транку. Список разрешенных кодов задается в файле в /usr/share/asterisk/agi-bin/cods.txt
#!/usr/bin/perl
# load module use Asterisk::AGI; use DBI; #use date::Format;
# connect my $dbh = DBI->connect("DBI:Pg:dbname=asterisk;host=127.0.0.1", "asterisk_user", "passwd", {'RaiseError' => 1});
my %trunks=("name1" => "SIP/994", "name2" => "SIP/993", "name3" => "SIP/992", "name4" => "SIP/991"); #89839
my %trunks_id=("name1" => "994", "name2" => "993", "name3" => "992", "name4" => "991");
my $Default_trunk="SIP/63762xx"; my $Default_trunk_id="63762xx";
my %calls=(); my @calls_order=();
my $LIMIT=2000*60; my $min=$LIMIT; my $min_trunk="name1";
foreach $trunk (keys(%trunks)){ my $sth = $dbh->prepare("SELECT sum(billsec) AS calltime FROM cdr WHERE date_trunc('month',calldate) = date_trunc('month',now()) AND dstchannel LIKE '$trunks{$trunk}-%' ;"); $sth->execute();
while(my $ref = $sth->fetchrow_hashref()) { if($ref->{'calltime'} < $LIMIT){ $calls{$trunk}=$ref->{'calltime'}; if ($min > $ref->{'calltime'} ){ $min=$ref->{'calltime'}; $min_trunk=$trunk; } } if(not $ref){ $calls{$trunk}=0; } }#end while }
$dbh->disconnect();
#@calls_order = sort { $calls{$b} cmp $calls{$a} } keys %calls; @calls_order = sort { $calls{$a} <=> $calls{$b} } keys %calls;
#foreach $trunk (@calls_order){ # print "$trunk = $calls{$trunk}\n"; # $AGI->verbose("$trunk = $calls{$trunk}\n",3); #} #print "min $min_trunk\n"; #$AGI->verbose("min $min_trunk\n",3);
$|=1; my $AGI = new Asterisk::AGI; $AGI->setcallback(\&mycallback); my %input = $AGI->ReadParse(); sleep(1); my $num = $input{'extension'}; my $caller_id = $input{'callerid'}; if (!$num) { exit; } my $num1 = substr($num,1,6); my $syscmd1=`perl -ne "print if m/$num1/" /usr/share/asterisk/agi-bin/cods.txt`; chomp($syscmd1); if($syscmd1==0){ $AGI->exec('Playback', "/var/lib/asterisk/sounds/record/blocked_call"); exit; } my $use_default=1; #$AGI->stream_file("/var/lib/asterisk/sounds/record/limit_call","*"); $AGI->exec('Playback', "/var/lib/asterisk/sounds/record/limit_call");
$AGI->verbose("Executing Dial $num $num1 $caller_id $syscmd1 \n",3); foreach $trunk (@calls_order){ $AGI->set_callerid($trunks_id{$trunk}); my $syscmd=`asterisk -r -x "core show channels" | grep "$trunks{$trunk}"| wc -l`; chomp($syscmd); if($syscmd==0){ #$AGI->verbose("????? Status $trunks{$trunk} '$ret' '$status'\n",3); # my $ret=$AGI->exec('Dial', "$trunks{$trunk}/$num");
my $ret=$AGI->exec('Dial', "$trunks{$trunk}/$num|120|L(191664)"); my $status=$AGI->channel_status(); if( ($status==0 || $status==1) && $ret!=1 ){ $AGI->verbose("????? OK! $caller_id $num ret=$ret status=$status syscmd=$syscmd\n",3); $use_default=0; last; }else{ $AGI->verbose("????????? error $caller_id $num $trunks{$trunk}/$num '$ret' status=$status syscmd=$syscmd \n",3); } } }
if($use_default==1){ $AGI->set_callerid($Default_trunk_id); my $ret=$AGI->exec('Dial', "$Default_trunk/$num"); $AGI->verbose("????????? error_Default_trunk $caller_id $num $Default_trunk/$num ret=$ret \n",3); }
sleep(1); exit;
sub mycallback { my ($returncode) = @_; &log("CALLBACK"); &cleanup; #print STDERR "User Disconnected ($returncode)\n"; $AGI->verbose("!!!!!!!!!! ($returncode)\n"); exit($returncode); }
|