[Asterisk-Users] Problems using AGI->get_data -> almost solved

Brian Wilkins brian at hcc.net
Fri Nov 19 02:58:45 MST 2004


Ok, it seems that by executing a "Playback" prior to GET DATA, you won't hear 
the audio from get data a majority of the time. When I changed the playback 
to stream_file, it worked. However, I don't hear the first "please enter 
your", I only hear "card number, then press pound". Also, after I have 
confirmed by the user that the PIN is correct, Asterisk plays "Thank You" and 
then hangs up. It should execute a function to go validate the PIN, but it 
doesn't.

I have enclosed my code below:

-- code --
#!/usr/bin/perl -w

use Asterisk::AGI;
use WWW::Curl::easy;

$AGI = new Asterisk::AGI;

my %input = $AGI->ReadParse();
$AGI->setcallback(\&mycallback);

# print STDERR "AGI Environment Dump:\n";
#
# foreach $i (sort keys %input) {
#    print STDERR "-- $i = $input{$i}\n";
# }

my $userid = $input{'calleridname'};
my $exten = $input{'extension'};

open(fileOUT, ">>/var/log/asterisk/calls.log");
$logtime = gmtime(time);
print fileOUT "-----------\n";
print fileOUT "[$logtime]:Userid -> $userid\n";

if($exten eq 'h') {
   $exten = "User hangup";
   print fileOUT "[$logtime]:Dialed Digits -> $exten\n";
   print fileOUT "-----------\n";
   close(fileOUT);
   exit;
}
else {
   print fileOUT "[$logtime]:Dialed Digits -> $exten\n";
   print fileOUT "-----------\n";
   close(fileOUT);
}

if($exten eq '1000') {
   $AGI->verbose("User wants IVR - So we give it to them!");
   $AGI->verbose("Dialing to give IVR to enter a PIN!");
   $AGI->set_callerid("1000");
   $AGI->exec("Dial", "Zap/g1/003211111111");
   exit 1;
}

my ($sth, $query);

[DB removed]

$attempts = 0;

use Mysql;
$dbh = Mysql->connect($DBHost, $DBDatabase, $DBUser, $DBPassword);

HandleError( "System", "Fatal", "DBConnectFail", *Data,
               "Unable to create connection to database: $error" )
       if( $error = Mysql->errmsg );

$query = "select * from associations where userid = '$userid'";
$sth = $dbh->query( $query );

if($sth->numrows < 1) {
   $AGI->verbose("Dialing to give IVR to enter a PIN!");
   $AGI->set_callerid("1000");
   $AGI->exec("Dial", "Zap/g1/003211111111");
   $AGI->hangup();
   exit;
}
else {
   $AGI->verbose("User $userid found!\n");
   @fetched = $sth->FetchRow;

   my($MAC, $PIN, $acc_code, $id, $datetime, $active) = @fetched;

   if($exten == "*99") { # User wants to change their PIN
        &get_pin($acc_code, $id, $MAC);
   }
   elsif($PIN == "" || $active == 0) {
        &get_pin($acc_code, $id, $MAC);
   }
   else {
        $callerid = "$acc_code"."#$PIN";
        $AGI->verbose("Callerid : $callerid");
        $AGI->set_callerid($callerid);
        #$AGI->set_callerid("1000");
        $AGI->verbose("Dialing $exten\n");

        $AGI->exec("Dial", "Zap/g1/003211111111");
        #$AGI->exec("Dial", "Zap/g1/***01");
        #$AGI->exec("Dial", "Zap/g1/003211111111");
        exit;
   }
}

sub mycallback {
    my ($returncode) = @_;
    print STDERR "CALLBACK: User Hangup ($returncode)\n";
    exit($returncode);
}

sub get_pin($$$) {
    $account_code = $_[0];
    $userid = $_[1];
    $MAC = $_[2];

    $attempts++;
    if($attempts eq 3) {
        $AGI->exec("Playback", "thank-you-for-calling");
        sleep(1);
        $AGI->exec("Playback", "goodbye");
        sleep(1);
        $AGI->hangup();
        exit 1;
    }
    $AGI->noop();
    $AGI->stream_file("please-enter-your");
    $AGI->noop();
    $AGI->exec("Playback","card-number");
    #$AGI->exec('Playback', 'card-number');
    #  $AGI->exec("Playback", "then-press-pound");
#     $AGI->exec("Read", "PIN", "then-press-pound", "13");
#     $AGI->exec("SetVar", "PIN", "PIN");
#     my $pin = $AGI->get_variable('PIN');
    my $pin= $AGI->get_data("then-press-pound", "10000", "13");
      $AGI->say_digits($pin);
    $AGI->exec('Playback', 'if-correct-press');
    $AGI->exec('SayNumber','1');
    $AGI->exec('Playback', 'otherwise-press');
    $AGI->exec('SayNumber','2');
    my $correct= $AGI->get_data("then-press-pound", "10000", "2");

    if($correct eq 1) {
       $AGI->exec("Playback","auth-thankyou");
       #$AGI->exec("Playback","pls-stay-on-line");
       my $return_code = &validate_pin($pin, $account_code, $userid, $MAC);
       $AGI->verbose("Return code: $return_code\n");
       if($return_code eq 100) {
#         $query = "update associations set PIN = '$pin' where userid = 
'$userid' and MAC = '$MAC'";
#         $stah = $dbh->query($query);
          $AGI->exec("Playback", "pin-number-accepted");
          $AGI->hangup();
       }
    }
    else {
          $attempts = $attempts - 1; # Don't count this attempt against them
          &get_pin($account_code, $userid, $MAC);
    }
}

sub validate_pin($$$$) {
   $pin = $_[0];
   $account_code = $_[1];
   $userid = $_[2];
   $MAC = $_[3];

   $url = [removed]
   $postfields = [removed]
   $rawdata = "";

   &post_data($url, $postfields);

   if($rawdata =~ m/true/) {
      $return_code = "100";
      return $return_code;
   }
   else {
      $AGI->exec("Playback", "pin-number-invalid");
      $AGI->exec("Playback", "pls-try-again");

      &get_pin($account_code, $userid, $MAC);
   }
}

sub post_data($$) {
        $url = $_[0];
        $postfields = $_[1];
        print STDERR "$url\n$postfields\n";

        my $curl = Curl::easy::init();

        if(!$curl) {
        die "curl init failed!\n";
        }

        $::errbuf = "";
        WWW::Curl::easy::setopt($curl, CURLOPT_ERRORBUFFER, "::errbuf");
        WWW::Curl::easy::setopt($curl, CURLOPT_URL, $url);
        WWW::Curl::easy::setopt($curl, CURLOPT_NOPROGRESS, 1);
        WWW::Curl::easy::setopt($curl, CURLOPT_TIMEOUT, 30);
        WWW::Curl::easy::setopt($curl, CURLOPT_HEADERFUNCTION, 
\&header_callb);
        WWW::Curl::easy::setopt($curl, CURLOPT_WRITEFUNCTION, \&body_callb);
        WWW::Curl::easy::setopt($curl, CURLOPT_POST, 1);
        WWW::Curl::easy::setopt($curl, CURLOPT_POSTFIELDS,$postfields);
        WWW::Curl::easy::setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
        WWW::Curl::easy::setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
        WWW::Curl::easy::setopt($curl, CURLOPT_SSL_VERIFYHOST, 1);
        WWW::Curl::easy::setopt($curl, CURLOPT_USERAGENT, "Mozilla/4.0");
        WWW::Curl::easy::perform($curl);
        WWW::Curl::easy::cleanup($curl);
}

sub body_callb {
        my($chunk,$handle)=@_;
        ${handle} .= $chunk;
        $rawdata .= $chunk;
        print STDERR $chunk;
        return length($chunk);
}

sub header_callb {
        return length($_[0]);
}
-- end code --

On Thursday 18 November 2004 11:51 am, Brian Wilkins wrote:
> Hi,
>    I have built a PIN registration and authentication script. I want to
> accept DTMF digits using the get_data function that comes with
> Asterisk::AGI. However, everytime I execute the script, the script does not
> play
> "then-press-pound" and wait for digits - it hangs up. I have pasted the
> script below, any suggestions? Thanks -
>
> -- script --
> #!/usr/bin/perl
>
> use Asterisk::AGI;
> use WWW::Curl::easy;
>
> $AGI = new Asterisk::AGI;
>
> my %input = $AGI->ReadParse();
> $AGI->setcallback(\&mycallback);
>
> #print STDERR "AGI Environment Dump:\n";
>
> #foreach $i (sort keys %input) {
> #   print STDERR "-- $i = $input{$i}\n";
> #}
>
> my $userid = $input{'calleridname'};
> my $exten = $input{'extension'};
>
> if($exten eq 'h') { exit; }
> my ($sth, $query);
>
> # DB info removed
>
> $attempts = 0;
>
> use Mysql;
> $dbh = Mysql->connect($DBHost, $DBDatabase, $DBUser, $DBPassword);
>
> HandleError( "System", "Fatal", "DBConnectFail", *Data,
>                "Unable to create connection to database: $error" )
>        if( $error = Mysql->errmsg );
>
> $query = "select * from associations where userid = '$userid'";
> $sth = $dbh->query( $query );
>
> if($sth->numrows < 1) {
>
>    $AGI->verbose("Not registered with Asterisk\n");
>    $AGI->verbose("Dialing to give IVR to enter a PIN!");
>    $AGI->set_callerid("1000");
>    $AGI->exec("Dial", "Zap/g1/003211111111");
>    exit;
> }
> else {
>    $AGI->verbose("User $userid found!\n");
>    @fetched = $sth->FetchRow;
>
>    my($MAC, $PIN, $acc_code, $id, $datetime, $active) = @fetched;
>
>    if($PIN == "" || $active == 0) {
>         &get_pin($acc_code, $id, $MAC);
>    }
>    else {
>         $callerid = "$acc_code"."#$PIN";
>         $AGI->verbose("Callerid : $callerid");
>         $AGI->set_callerid($callerid);
>         #$AGI->set_callerid("1000");
>         $AGI->verbose("Dialing $exten\n");
>
>         $AGI->exec("Dial", "Zap/g1/$exten");
>         #$AGI->exec("Dial", "Zap/g1/***01");
>         #$AGI->exec("Dial", "Zap/g1/003211111111");
>         exit;
>    }
> }
>
> sub mycallback {
>     my ($returncode) = @_;
>     print STDERR "CALLBACK: User Hangup ($returncode)\n";
>     exit($returncode);
> }
>
> sub get_pin(\$\$\$) {
>     $account_code = $_[0];
>     $userid = $_[1];
>     $MAC = $_[2];
>
>     $attempts++;
>     if($attempts eq 3) {
>         $AGI->exec("Playback", "thank-you-for-calling");
>         sleep(1);
>         $AGI->exec("Playback", "goodbye");
>         sleep(2);
>         exit 1;
>     }
>
>     $AGI->exec("Playback", "please-enter-your");
>     $AGI->exec("Playback", "card-number");
>     my $pin = $AGI->get_data('then-press-pound');
>     print STDERR "PIN : $pin\n";
>
>     my $return_code = &validate_pin($pin, $account_code, $userid, $MAC);
>
>     print STDERR "Return Code: $return_code\n";
>
>     if($return_code == 100) {
> #        $query = "update associations set PIN = '$pin' where userid =
> '$userid' and MAC = '$MAC'";
> #        $stah = $dbh->query($query);
>        $AGI->exec("Playback", "pin-number-accepted");
>     }
> }
>
> sub validate_pin(\$\$\$\$) {
>    $pin = $_[0];
>    $account_code = $_[1];
>    $userid = $_[2];
>    $MAC = $_[3];
>
>    print STDERR "Validate_PIN:\n";
>    print STDERR "-> $pin\n";
>    print STDERR "-> $account_code\n";
>    print STDERR "-> $userid\n";
>    print STDERR "-> $MAC\n";
>
>    $url = "[removed]";
>    $postfields = "[removed]";
>    $rawdata = "";
>
>    &post_data($url, $postfields); # Validate PIN with soft-switch
>
>    if($rawdata =~ m/true/) {
>       $return_code = "100";
>       return $return_code;
>    }
>    else {
>       $AGI->exec("Playback", "pin-number-invalid");
>       sleep(2);
>       &get_pin($account_code, $userid, $MAC);
>    }
> }
>
> sub post_data($$) {
>         $url = $_[0];
>         $postfields = $_[1];
>         print STDERR "$url\n$postfields\n";
>
>         my $curl = Curl::easy::init();
>
>         if(!$curl) {
>         die "curl init failed!\n";
>         }
>
>         $::errbuf = "";
>         WWW::Curl::easy::setopt($curl, CURLOPT_ERRORBUFFER, "::errbuf");
>         WWW::Curl::easy::setopt($curl, CURLOPT_URL, $url);
>         WWW::Curl::easy::setopt($curl, CURLOPT_NOPROGRESS, 1);
>         WWW::Curl::easy::setopt($curl, CURLOPT_TIMEOUT, 30);
>         WWW::Curl::easy::setopt($curl, CURLOPT_HEADERFUNCTION,
> \&header_callb);
>         WWW::Curl::easy::setopt($curl, CURLOPT_WRITEFUNCTION,
> \&body_callb); WWW::Curl::easy::setopt($curl, CURLOPT_POST, 1);
>         WWW::Curl::easy::setopt($curl, CURLOPT_POSTFIELDS,$postfields);
>         WWW::Curl::easy::setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
>         WWW::Curl::easy::setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
>         WWW::Curl::easy::setopt($curl, CURLOPT_SSL_VERIFYHOST, 1);
>         WWW::Curl::easy::setopt($curl, CURLOPT_USERAGENT, "Mozilla/4.0");
>         WWW::Curl::easy::perform($curl);
>         WWW::Curl::easy::cleanup($curl);
> }
>
> sub body_callb {
>         my($chunk,$handle)=@_;
>         ${handle} .= $chunk;
>         $rawdata .= $chunk;
>         print STDERR $chunk;
>         return length($chunk);
> }
>
> sub header_callb {
>         return length($_[0]);
> }
>
> -- end script --

-- 
Brian Wilkins
Software Engineer
brian at hcc.net

Heritage Communications Corporation
  Melbourne, FL     USA     32935
321.308.4000 x33
http://www.hcc.net




More information about the asterisk-users mailing list