The OpenNET Project / Index page

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

Равномерное использование транков в Asterisk
Не секрет, что есть условно бесплатные (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);
 } 
 
28.07.2010 , Автор: ink08 , Источник: http://ink-08.blogspot.com/2010/07/...
Ключи: asterisk, gsm, voip
Раздел:    Корень / Маршрутизаторы Cisco, VoIP / Ограничение и учет трафика на Cisco

Обсуждение [ RSS ]
  • 1, kaka (?), 14:29, 29/07/2010 [ответить]  
  • +/
    полезно, спасибо
     
  • 2, Filosof (ok), 16:20, 04/08/2010 [ответить]  
  • +/
    обычно при привышении лимита просто оплата появляется(в Украине). Но скрипт действительно полезен. спасибо.
     
  • 3, забыл_пароль_sadm (?), 16:27, 09/08/2010 [ответить]  
  • +/
    Может кому пригодится мое простенькое решение для asterisk+freepbx, которое выключает транк при превышении заданного порога минут и включает его в новом месяце:

    1. делаем скрипт /usr/local/bin/watch-trunk.sh (не забываем заменить ИМЯ_ТРАНКА, ИД_ТРАНКА и КОЛ-ВО_МИНУТ):

    #!/bin/bash

    USER='cat /etc/asterisk/cdr_mysql.conf | grep -Pi "^user *=" | cut -d = -f 2 | sed 's# ##g''
    PASSWD='cat /etc/asterisk/cdr_mysql.conf | grep -Pi "^password *=" | cut -d = -f 2 | sed 's# ##g''
    HOST='cat /etc/asterisk/cdr_mysql.conf | grep -Pi "^hostname *=" | cut -d = -f 2 | sed 's# ##g''
    DB='cat /etc/asterisk/cdr_mysql.conf | grep -Pi "^dbname *=" | cut -d = -f 2 | sed 's# ##g''

    COUNT='mysql -h${HOST} -u${USER} -p${PASSWD} ${DB} -N -B -e \
        "select round(sum(duration/60)) from cdr where dstchannel like '%ИМЯ_ТРАНКА%' and calldate > date_format(now(),'%Y-%m')"'

    if [ "${COUNT}" = 'NULL' ] ; then COUNT=0 ; fi

    if [ "${COUNT}" -gt КОЛ-ВО_МИНУТ ] ; then
        /usr/sbin/rasterisk -x "database put TRUNK ИМЯ_ТРАНКА 0" >/dev/null
    else
        /usr/sbin/rasterisk -x "database put TRUNK ИМЯ_ТРАНКА 1" >/dev/null
    fi

    2. добавляем в /etc/asterisk/extensions_override_freepbx.conf следующий блок:

    [macro-dialout-trunk-predial-hook]                                                                                                                                                
    exten => s,1,ExecIf($[$["${DB(TRUNK/ИМЯ_ТРАНКА)}" = "0"] & $["${DIAL_TRUNK}" = "ИД_ТРАНКА"]]?Set(PREDIAL_HOOK_RET="BYPASS"))                                                                  
    exten => s,n,MacroExit()

    3. Добавляем запись в кронтаб:

    */10 * * * * /usr/local/bin/watch-trunk.sh

     
  • 4, Nixon (?), 06:42, 12/11/2010 [ответить]  
  • +/
    Могу поделиться своим расширением на эту тему под a2billing
    http://www.asterisk2billing.org/cgi-bin/trac.cgi/ticket/869
    Абсолютно индивидуально настраивается каждый транк вплоть до количества посекунд тарификации, времени действия, смены и периодичности тарифа, а так же переход к следующему транку по условию. Пожелания приветствуются на e-mail.
     
     
  • 5, Nixon (?), 23:42, 05/06/2012 [^] [^^] [^^^] [ответить]  
  • +/
    Новая ссылка https://github.com/nixonch/a2billing/downloads
     

     Добавить комментарий
    Имя:
    E-Mail:
    Заголовок:
    Текст:




    Спонсоры:
    Слёрм
    Inferno Solutions
    Hosting by Ihor
    Хостинг:

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