Как я обновлял Asterisk
Проблемы переход с 1.2 на 1.4
Сообщений: 1573
|
Re: Как я обновлял Asterisk
димас, вы очень разговорчивый. Если хочется поговорить на отвлеченные темы, для этого сделана отдельная ветка ...
dimas: Что вы имели в виду каку-то другую ситуацию
Я то, как раз, имел ввиду ситуацию, которая описана в первом посте ... ))
В этом топике есть четко поставленный вопрос ... Поэтому и отвечайте на него, или хотя бы учитывайте то, что там сказано, если уж "тема уходит" ...
А вам просто хочется показать свое - "я"
Поэтому еще раз - вам сюда
|
Откуда: SPB
Сообщений: 61
|
Re: Как я обновлял Asterisk
один вопрос с AGI решил, за что всем спасибо. может с такой проблемкой подскажете, коллеги.
в случае успешного выполнения скрипта происходит
$AGI->exec('NoOp', "OK $call_type:$call_num");
exec заменяет данные в полях lastapp и lastdata на указанные в параметрах,.
$AGI->exec($app, $options)
Executes AGI Command "EXEC $app "$options""
The most powerful AGI command. Executes the given application passing the given options.
Example: $AGI->exec('Dial', 'Zap/g2/8005551212');
Returns: -2 on failure to find application, or whatever the given application returns
в старой версии работало все четко, после обновления данные вносятся в базу через раз.
при это если передавать просто текст, типа $AGI->exec('blabla', 'blabla');
то все пишется стабильно.
подозреваю, что затык либо в двойных кавычках, либо в том, что параметрами передаются переменные.
в debug agi, все ок, exec отрабатывается. при этом в базе и в cdr заменя значений не происходит.
уже все перерыл, обновил asterisk-perl, нифига.
есть идеи?
|
Сообщений: 866
|
Re: Как я обновлял Asterisk
exec заменяет данные в полях lastapp и lastdata на указанные в параметрах,.
Утверждение некорректно. exec просто принимает два строковых параметра. А подстановку переменных (замену $var на ее значение) в строке делает интерпретатор Perl перед вызовом exec.
И каким образом вы хотите чтобы Exec Noop'в привел к замене каих-то полей CDR? Покажите тот exec который вы делаете на самом деле...
ну и конечно же, использование символов | и , в подставляемых переменных - чревато.
а в зависимости от операции - может быть чреват и символ = и $ и т.п....
|
Сообщений: 1573
|
Re: Как я обновлял Asterisk
All of the pre-defined CDR variables are read-only with the exception of the following:
Asterisk 1.4
accountcode
amaflags
userfield
Asterisk 1.2
accountcode
userfield
Это учитываете?
|
Сообщений: 866
|
Re: Как я обновлял Asterisk
Утверждение некорректно. exec просто принимает два строковых параметра. А подстановку переменных (замену $var на ее значение) в строке делает интерпретатор Perl перед вызовом exec.
ой, это я прогнал жестко. Прочитал не то что написано.
теперь понял что имелось в виду. Да, астериск сам должен в lastapp и lastdata сложить имя последней команды (noop) м ее параметры (то есть вашу строчку).
А что именно пишется в CDR вместо noop'а когда вы говорите что оно "не пишется через раз"?
|
Сообщений: 1573
|
Re: Как я обновлял Asterisk
Не сразу понял, что вы хотите ...
А что в записи попадает при сбое (и что должно было попасть)? (дубль 2)
Как вариант - используйте app. Exec в диалплане:
exten => h,1,Exec(Noop(OK $call_type:$call_num))
...
|
Откуда: SPB
Сообщений: 61
|
Re: Как я обновлял Asterisk
Итак, стандартно * пишет в эти поля, например, следующее:
lastapp = Dial
lastdata = Zap/g2/5609070|40
Скрипт в зависимости от результатов выполнения заменяет их на следующее:
lastapp = NoOp
lastdata = OK fix:5609070
В случае неуспешного завершения могут быть другие варианты результатов скрипта:
$AGI->exec('NoOp', "ERR No route to num: $call_num");
или
$AGI->exec('NoOp', "ERR Clid not found: $clid");
или
$AGI->exec('NoOp', "ERR different user ids: $user_id, $customer_id");
Так вот при обновлении до последней версии ветки 1.2 результат работы exec, т.е. новые значения в lastapp и lastdata, появляется через раз, т.е. иногда данные заменяются на новые, иногда остаются прежними(или после работы скрипта снова переписываются * ??).
В 1.4 не заменяются вообще.
ЗЫ: если это поможет могу выложить скрипт целиком
|
Сообщений: 866
|
Re: Как я обновлял Asterisk
выкладывайте. И кусок диалплана которые его вызывает - тоже.
т.е. иногда данные заменяются на новые, иногда остаются прежними(или после работы скрипта снова переписываются * ??).
что значит "прежними"? Что конкретно там лежит?? "AGI","..." ?
Я правильно понимаю что вы эти данные потом в пост-процессинге/биллинге где-то используете? То есть берете из базы CDR и для чего-то там используете?
Если это ради этого все делается то имхо это крайне неправильный способ - не нужно бороться с астериском пытаясь положить какие-то свои особые значения в служебные по большому счету поля. Что вам мешает custom-поля в CDR использовать?
|
Откуда: SPB
Сообщений: 61
|
Re: Как я обновлял Asterisk
да. эти данные потом используются для построения отчетов. к сожалению вся логика и аги писались до меня и переделывать ВСЕ из-за этого невозможно))
вызывается скрипт в конце выполнения макроса тупо exten => h,1,DeadAGI(aline_bill.agi)
Его сожержание:
#!/usr/bin/perl
use strict;
use Asterisk::AGI;
use DBI;
sub Debug (@);
$SIG{HUP} = "IGNORE";
my $gate = 1; # gateways.id
my $loc_rate = "0.00";
my $fix_rate = "0.00";
my $mob_rate = "2.00";
# данные для соединения с базой
my $host_name = "192.168.100.11";
my $db_name = "aster";
my $login = "blabla";
my $passw = "blabla";
my $AGI = new Asterisk::AGI;
my %var = $AGI->ReadParse();
# читаем нужные переменные
my $clid = $var{callerid};
my $user_id = $AGI->get_variable("user_id");
my $call_id = $AGI->get_variable("CDR(uniqueid)");
my $billsec = $AGI->get_variable("ANSWEREDTIME");
my $call_type = $AGI->get_variable("call_type");
my $call_num = $AGI->get_variable("call_num");
my $dial_status = $AGI->get_variable("DIALSTATUS");
my $hangup_cause = $AGI->get_variable("HANGUPCAUSE");
Debug "Line hang up, clid: $clid, user_id: $user_id, billsec: $billsec, call_id: $call_id";
Debug "DIALSTATUS: $dial_status, HANGUPCAUSE: $hangup_cause";
if ( $dial_status eq "CANCEL" ) {
Debug "Call was canceled by caller";
exit;
}
# смотрим DIALSTATUS
unless ( $dial_status =~ /^answer/i ) {
Debug "Unsuccessful call, exiting";
$AGI->exec('NoOp', "ERR Dial status: $dial_status, $hangup_cause");
exit;
}
# парсим clid
unless ( $clid =~ /^(\d+)(\d)(\d{4})$/ ) {
Debug "Clid $clid has wrong format";
$AGI->exec('NoOp', "ERR clid wrong format: $clid");
exit;
}
my $customer_id = $1;
my $group = $2;
my $short = $3;
# сверяем customer_id и user_id
unless ( $customer_id == $user_id ) {
Debug "User_id $user_id is not equal customer_id $customer_id";
$AGI->exec('NoOp', "ERR different user ids: $user_id, $customer_id");
exit;
}
my $dbh = db_connect();
# проверка существования номера
my $clid_exists = $dbh->selectrow_array(qq/SELECT COUNT(*) FROM al_clids
WHERE clid = ? AND customer_id = ?/, undef, $group.$short, $customer_id);
unless ($clid_exists) {
Debug "Clid $clid is not found at al_clids";
$AGI->exec('NoOp', "ERR Clid not found: $clid");
exit;
}
my $fee;
if ($call_type eq 'local') { #звонок внутри сети
$fee = sprintf "%.4f", $billsec * $loc_rate / 60;
Debug "Local call, rate: $loc_rate, fee: $fee";
}
elsif ($call_type eq 'fix') { # городской
$fee = sprintf "%.4f", $billsec * $fix_rate / 60;
Debug "Fix call, rate: $fix_rate, fee: $fee";
}
elsif ($call_type eq 'mob') { # мобильный
$fee = sprintf "%.4f", $billsec * $mob_rate / 60;
Debug "Mobile call, rate: $mob_rate, fee: $fee";
}
elsif ($call_type eq 'native' or 'foreign') { # МГМН
my $cnum = $call_num; $cnum =~ s/^810// or $cnum =~ s/^8/7/;
my($pref, $desc, $rate) = search_route($dbh, $cnum, $gate);
if (defined $pref) {
$fee = sprintf "%.4f", $billsec * $rate / 60;
Debug "Longdist call, rate: $rate, fee: $fee, gate: $gate, prefix: $pref";
} else {
Debug "Cant find route for num $call_num";
$AGI->exec('NoOp', "ERR No route to num: $call_num");
exit;
}
}
else { # неизвестный звонок
Debug "Unknown or undefined call type $call_type";
$AGI->exec('NoOp', "ERR Unknown call type: $call_type");
exit;
}
$dbh->do(qq/UPDATE customers SET balance = balance - $fee
WHERE id = ?/, undef, $user_id) if $fee > 0;
$dbh->disconnect;
# прописываем в CDR
$AGI->set_variable('CDR(userfield)' => $fee);
$AGI->exec('NoOp', "OK $call_type:$call_num");
sub search_route {
my($dbh, $num, $gate) = @_;
my $sth = $dbh->prepare(qq/SELECT prefix, description, rate2 FROM routs
WHERE prefix = ? AND gateway_id = ?/);
do {
my $rc = $sth->execute($num, $gate);
return $sth->fetchrow_array if $rc + 0;
chop $num;
}
while (length $num);
return;
}
sub Debug(@) {
my $string = shift;
my $level = shift || 3;
$AGI->verbose(">>>> $string\n", $level);
}
sub db_connect {
my $dsn = "DBI:mysql:host=$host_name;database=$db_name";
return DBI->connect($dsn, $login, $passw,
{PrintError => 0, RaiseError => 1});
}
|
Сообщений: 866
|
Re: Как я обновлял Asterisk
аааа... так это ваш AGI который в экстеншене h обрабатывается?
я только что проверил в своем 1.4 - операции выполненные из 'h' в lastapp/lastdata не попадают вообще...
Пишите все что хотите в CDR переменные и поправьте скрипт отчетов чтобы брал данные оттуда.
Я смотрю, CDR(userfield) вы уже заняли подо что-то. Но у вас есть еще accountcode и amaflags. Ну и самое главное - вы можете вообще свои поля новые придумать. Нужно только что-то настроить будет чтобы они в лог/базу пошли. Я этого ниогда не делал.
Тогда
$AGI->exec('NoOp', "OK $call_type:$call_num");
превратится например в
$AGI->set_variable('CDR(accountcode)' => "OK $call_type:$call_num");
И потребуется несложная модификация рипортов...
(повторюсь что "правильно" делать - это не accountcode юзать а свое поле добавить)
|
|