[asterisk-users] Asterisk 1.4.30 is slow sending STDIN to AGI script
Danny Nicholas
danny at debsinc.com
Wed Apr 28 10:14:57 CDT 2010
Darn, that should have worked. The "improvement" from 1.4.22 to 1.4.23+
basically requires that every "print STDOUT" line be followed by a <STDIN>
to make util.c not choke when doing commands/setting variables. I wonder
how this "rewrite" would work?
sub set_variable
{
my ($self, %vars) = @_;
while (my($var,$val) = each %vars)
{
if (!defined($val))
{ warn "AGI->set_variable: not setting '$var' because value
was undef\n"; next; }
print STDOUT "SET VARIABLE $var \"$val\" \r\n";
<STDIN>;
}
}
-----Original Message-----
From: asterisk-users-bounces at lists.digium.com
[mailto:asterisk-users-bounces at lists.digium.com] On Behalf Of Gareth Blades
Sent: Wednesday, April 28, 2010 10:05 AM
To: Asterisk Users Mailing List - Non-Commercial Discussion
Subject: Re: [asterisk-users] Asterisk 1.4.30 is slow sending STDIN to AGI
script
You mean as in :- ?
sub set_variable
{
my ($self, %vars) = @_;
while (my($var,$val) = each %vars)
{
if (!defined($val))
{ warn "AGI->set_variable: not setting '$var' because value
was undef\n"; next; }
#warn "AGI->set_variable('$var','$val')\n";
$self->SUPER::set_variable($var, $val);
<STDIN>;
}
}
It didnt work. The AGI script hung the dialplan before attempting to dial
Thanks
Danny Nicholas wrote:
> Just a hunch - add <STDIN>; after line 15 and give it a whirl.
>
> -----Original Message-----
> From: asterisk-users-bounces at lists.digium.com
> [mailto:asterisk-users-bounces at lists.digium.com] On Behalf Of Gareth
Blades
> Sent: Wednesday, April 28, 2010 9:47 AM
> To: Asterisk Users Mailing List - Non-Commercial Discussion
> Subject: Re: [asterisk-users] Asterisk 1.4.30 is slow sending STDIN to AGI
> script
>
> Danny Nicholas wrote:
>> Can you post the script?
>>
>
> Yes private stuff is in a separate file. $mode=start works fine but
> answered and completed cause the problem.
> I dont know if it is a problem with teh AGI script or just the newer
> asterisk reporting it as an error. It doesnt effect functionality but
> just gives a lot of console output and logging which is undesireable.
>
> Thanks
> Gareth
>
>
>
> #!/usr/bin/perl -I /var/lib/asterisk/agi-bin/includes
>
> package Asterisk::AGIwrap;
> use strict;
> use base 'Asterisk::AGI';
>
> sub set_variable
> {
> my ($self, %vars) = @_;
> while (my($var,$val) = each %vars)
> {
> if (!defined($val))
> { warn "AGI->set_variable: not setting '$var' because value
> was undef\n"; next; }
> #warn "AGI->set_variable('$var','$val')\n";
> $self->SUPER::set_variable($var, $val);
> }
> }
>
> package main;
> use strict;
>
> our $application = "service_nts_nextgen";
> our $subagent = "AGI - $application";
> open(OLD_STDERR,">&STDERR") or die "Failed to save STDERR";
> open(STDERR,">>/var/log/agi_$application.err") or die "Failed to
> redirect STDERR";
>
> my $settings = require '/var/lib/asterisk/agi-bin/skycom_gw_settings.pl';
> our $gatewayID = $settings->{'gatewayID'};
> my ($dbname, $dbhost, $dbport, $dbuser, $dbpass) =
> @{%{$settings->{'db'}}}{'name','host','port','user','pass'};
>
> my $db;
>
> eval
> {
> use DBI;
> $db = DBI->connect("DBI:mysql:$dbname:$dbhost:$dbport", $dbuser,
> $dbpass, $settings->{'dbopt'}) || die "Cannot connect to database:
> $DBI::errstr";
>
> our $AGI = new Asterisk::AGIwrap;
>
> print STDERR scalar localtime, " RUNNING:$0 ", (map {"\"$_\" "}
> @ARGV), "\n";
> our $mode = $ARGV[0];
> my %ARG = ();
> if ($mode =~ /mode=(.*)/)
> {
> $ARG{'mode'} = $mode = $1;
> foreach my $arg (@ARGV)
> {
> $arg =~ /^(\w+)=(.*)$/ || next;
> $ARG{$1} = $arg = $2;
> }
> }
>
> our $not_recognised = 0;
> my $func;
>
> if ($mode eq "start")
> {
> $func = require
> '/var/lib/asterisk/agi-bin/service_nts_nextgen-start.pl';
> &$func('db'=>$db, 'AGI'=>$AGI, 'settings'=>$settings);
> }
>
> elsif ($mode eq "answered")
> {
> my $uniqueID = $ARGV[1];
> my $uniqueIDB = $ARGV[2];
> my $destination = $ARGV[3];
> my $destination_type = $ARGV[4];
> my $destination_args = $ARGV[5];
> my $destination_carrier = $ARGV[6];
> $destination =~ s/^00//; # International
> $destination =~ s/^0([1-9]+)/44$1/; # UK
> my $args = {
> #'destination_type_id' => '"'.$destination_type.'"',
> 'answer_time' => 'NOW()',
> 'answer_epoch' => 'UNIX_TIMESTAMP()',
> 'uniqueIDB' => '"'.$uniqueIDB.'"',
> 'ddi' => '"'.$destination.'"',
> 'carriernameID' => carriernameID($destination_carrier)
> };
> if ($destination_type)
> { $args->{'destination_type_id'} = '"'.$destination_type.'"'; }
> if ($destination_args ne '') { $args->{'destination_args'} =
> '"'.$destination_args.'"'; }
> if (defined($ARG{'params'}))
> { $args->{'extra_params'} =
> $db->quote(urlstr_to_miniserial($ARG{'params'})); }
> &updateCDR($uniqueID,$args,$db);
> }
>
> elsif ($mode eq "completed")
> {
> my $uniqueID = $ARGV[1];
> my $status = $ARGV[2];
> my $failedpredial = $ARGV[4];
> if ($uniqueID eq "") { $uniqueID = $ARGV[3]; }
> if ($status eq "" && $failedpredial ne "1") { $status = "FAILED";
}
> my $destination_type = ($ARGV[6] =~ /^\d+$/ ? $ARGV[6] : 0);
> my $dest_arg = $ARGV[7];
> my $connect_epoch = $ARGV[8] || 0;
>
> my $args = {
> 'end_time' => 'NOW()',
> 'end_epoch' => 'UNIX_TIMESTAMP()',
> 'duration' => '(UNIX_TIMESTAMP(NOW()) -
> UNIX_TIMESTAMP(start_time))',
> 'carriernameID' => carriernameID($ARGV[5]),
> 'connect_epoch'=>$connect_epoch,
> ($destination_type ?
> ('destination_type_id'=>$destination_type) : ()),
> };
> if (defined($ARG{'params'}))
> { $args->{'extra_params'} =
> $db->quote(urlstr_to_miniserial($ARG{'params'})); }
> if ($status eq "VOICEMAIL")
> {
> $args->{'destination_type_id'} = 3;
> $status = "ANSWER";
> }
> if ($status eq "ANNOUNCEMENT")
> {
> $args->{'destination_type_id'} = 6;
> $status = "ANSWER";
> }
> if ($destination_type == 1)
> {
> if ($dest_arg =~ /^\d+$/)
> {
> if ($dest_arg =~ /^00/)
> { $dest_arg =~ s/^00//; }
> elsif ($dest_arg =~ /^0[1-9]/)
> { $dest_arg =~ s/^0/44/; }
> $args->{'ddi'} = $db->quote($dest_arg);
> }
> }
> elsif ($destination_type > 1)
> { $args->{'destination_args'} = $db->quote($dest_arg); }
> if (!$failedpredial) { $args->{'disposition'} = '"'.$status.'"';
}
> if ($status eq "ANSWER")
> {
> my @existing_updates = keys(%$args);
> $args->{'answer_epoch'} =
> "COALESCE(answer_epoch,UNIX_TIMESTAMP())";
> $args->{'start_epoch'} = "LEAST(start_epoch,answer_epoch)";
> # } if date puts time back a few seconds, this would cause us to record
> an answer
> $args->{'start_time'} = "FROM_UNIXTIME(start_epoch)";
> # } time/epoch earlier than the start time, so fix the start time/epoch
> $args->{'answer_time'} = "FROM_UNIXTIME(answer_epoch)";
> $args->{'end_time'} = "NOW()";
> $args->{'end_epoch'} = "UNIX_TIMESTAMP()";
> $args->{'disposition'} = "'ANSWER'";
> $args->{'duration'} = "end_epoch-start_epoch";
> $args->{'duration_billable'} = "end_epoch-answer_epoch";
> $args->{'.order'} =
>
['answer_epoch','answer_time','start_epoch','start_time','end_time','end_epo
> ch','disposition','duration','duration_billable', at existing_updates];
> #$args->{'duration_billable'} = '(UNIX_TIMESTAMP(NOW()) -
> UNIX_TIMESTAMP(answer_time))';
> }
> print STDERR scalar localtime, " *** CALL COMPLETED:
> ".join(',', at ARGV)." ***\n";
> &updateCDR($uniqueID, $args,$db);
> }
>
> elsif ($mode eq "ida_ddi")
> {
> my ($ddi, $uniqueID) = @ARG{'ddi','uniqueID'};
> $ddi =~ /^\d+$/ || die "Bad ddi '$ddi'\n";
> $func = require
> '/var/lib/asterisk/agi-bin/service_nts_nextgen-start.pl';
> &$func('db'=>$db, 'AGI'=>$AGI, 'settings'=>$settings,
> 'selector'=>{'mode'=>'ida_ddi', 'args'=>{'ddi'=>$ddi}});
> ($ddi =~ s/^00//) || ($ddi =~ s/^0([1-9])/44$1/);
> &updateCDR($uniqueID, {'ddi'=>$ddi}, $db);
> }
>
> elsif ($mode eq "getivr")
> {
> my ($ivrID) = @ARGV[1];
> $ivrID =~ /^\d+$/ || die "Bad ivrID '$ivrID'\n";
> $func = require
> '/var/lib/asterisk/agi-bin/service_nts_nextgen-start.pl';
> &$func('db'=>$db, 'AGI'=>$AGI, 'settings'=>$settings,
> 'selector'=>{'mode'=>'ivrmenu', 'args'=>{'ivrID'=>$ivrID}});
> }
>
> elsif ($mode eq "getivrchoice")
> {
> my ($ivrID, $userchoice) = @ARGV[1,2];
> $ivrID =~ /^\d+$/ || die "Bad ivrID '$ivrID'\n";
> $userchoice =~ /^\d+$/ || die "Bad userchoice '$ivrID'\n";
> $func = require
> '/var/lib/asterisk/agi-bin/service_nts_nextgen-start.pl';
> &$func('db'=>$db, 'AGI'=>$AGI, 'settings'=>$settings,
> 'selector'=>{'mode'=>'ivrchoice', 'args'=>{'ivrID'=>$ivrID,
> 'userchoice'=>$userchoice}});
> }
>
> };
>
> print STDERR scalar localtime, " Gateway $gatewayID app
> error(app=$application, file=$0): $@\n" if $@;
>
> open(STDERR,">&OLD_STDERR") or die "Failed to restore STDERR";
>
> # the end
>
>
> sub updateCDR
> {
> my ($uniqueid, $args, $db) = @_;
>
> my @required = ();
> foreach my $field (@required)
> {
> if (!defined($args->{$field}))
> {
> logMessage(10, $subagent, "updateCDR: required field
> missing: ".$field);
> return 0;
> }
> }
>
> my @updates = ();
> my @update_order = (exists($args->{'.order'}) ?
> @{$args->{'.order'}} : keys %$args);
> delete ($args->{'.order'});
> foreach my $field (@update_order)
> {
> next if !exists($args->{$field});
> push (@updates, "$field=".$args->{$field});
> delete ($args->{$field});
> }
> die "no CDR data" if !@updates;
>
> my $query = "UPDATE call_detail_log SET ".join(",", at updates)."
> WHERE uniqueID='$uniqueid'";
> print STDERR scalar localtime, " $query\n";
> $db->do($query);
> return 1;
> }
>
>
> sub carriernameID
> {
> my $name = shift(@_) || return 0;
> return $db->selectcol_arrayref("SELECT ID FROM
> call_detail_log_enum_carriername WHERE name=?",{},$name)->[0] || eval
> {
> my $rows = $db->do("INSERT INTO
> call_detail_log_enum_carriername SET name=?",{},$name);
> return ($rows > 0 ? $db->{'mysql_insertid'} : 0);
> };
> }
>
>
> sub urlstr_to_miniserial
> {
> my $urldec = sub { my ($url) = @_; $url =~ s/(\+|%([A-Z0-9]{2}))/$1
> eq '+'?' ':chr(hex($2))/eg; return $url; };
> my $dec_hash = sub { return map { $_ =~ /^(.+?)(=(.*))?$/ &&
> (&$urldec($1),&$urldec($3)) } split(/&/,shift(@_)); };
> return join('',map { length($_).':'.$_ } &$dec_hash(@_));
> }
>
>
>
--
_____________________________________________________________________
-- Bandwidth and Colocation Provided by http://www.api-digital.com --
New to Asterisk? Join us for a live introductory webinar every Thurs:
http://www.asterisk.org/hello
asterisk-users mailing list
To UNSUBSCRIBE or update options visit:
http://lists.digium.com/mailman/listinfo/asterisk-users
More information about the asterisk-users
mailing list