Wednesday 20 January 2016

Asterisk AMI Events using Perl POE


POE is a Perl framework for reactive systems, cooperative multitasking, and network applications. Read more about POE.

I'll explain, how we can use POE event loop to process the AMI Event in a asynchronous way. We can build any application in Perl that is based on AMI Events. Like Realtime Asterisk based billing, custom application to push events for web application, or any other application. With this POE Application we have all states of the calls, include some states which we don't have in the Asterisk Dialplan.


#!/usr/bin/perl -w

use strict;
use threads;
use threads::shared;
use warnings;
use Data::Dumper;
use Config::Abstract::Ini;
use POE qw(Component::Client::Asterisk::Manager);


#AMI-POE
my $host = '10.11.22.33';
my $port = '5038';
my $user = 'user';
my $pass = 'password';

my $debug = 1;
my @threadz;

POE::Component::Client::Asterisk::Manager->new(
        Alias => 'monitor',
        RemoteHost      => $host,
        RemotePort      => $port,
        Username        => $user,
        Password        => $pass,
        CallBacks       => {
                #cb_on_event => ':all', # catchall for all manager events
                cb_on_new_channel      => { 'Event' => 'Newchannel', },
                cb_on_rename =>{'Event' => 'Rename'},
                cb_on_dial             => {'Event' => 'Dial'},
                cb_on_newexten => {'Event' => 'Newexten'},
                on_Bridge      => {'Event' => 'Bridge','Bridgestate' => 'Link'},
                on_peer_status => { 'Event' => 'PeerStatus', },
                on_new_callerid        => { 'Event' => 'Newcallerid', },
                on_ring => { 'Event' => 'Newchannel', 'State' => 'Ring', },
                on_hangup      => { 'Event' => 'Hangup','Cause-txt' => 'Normal Clearing', },
                on_cdr => { 'Event' => 'Cdr', },
                on_rtcp_received => { 'Event' => 'RTCPReceived' },


        },
        inline_states => {
                #cb_on_event    => \&on_event,
                cb_on_new_channel      => \&on_new_channel,
                cb_on_rename => \&on_rename,
                cb_on_dial             => \&on_dial,
                cb_on_newexten => \&on_newexten,
                 on_Bridge      => \&on_Bridge,
                on_answer      => \&on_answer,
                on_peer_status => \&on_peer_status,
                on_new_callerid        => \&on_new_callerid,
                on_ring => \&on_ring,
                on_hangup      => \&on_hangup,
                on_cdr => \&on_cdr,
                on_rtcp_received => \&on_rtcp_received,
        },
); POE::Kernel->run();


sub on_rtcp_received(){
        my $input = $_[ARG0];
        #print Data::Dumper->Dump([$input]);
        my $packet_loss = $input->{'PacketsLost'};
        if($packet_loss >200){
                print Data::Dumper->Dump([$input]);
                # This call has lot of packet loss
        }
}


sub on_answer{
    #print "We are in ON-Answer STATE \n";
    my $input = $_[ARG0];
    print Data::Dumper->Dump([$input]);

}

sub on_rename{
    print "----------------> on_rename() \n";
        my $input = $_[ARG0];
        print Data::Dumper->Dump([$input]);

}



sub on_Bridge{
        my $input = $_[ARG0];
        #print "on Bridge CALLER ID\n";
        print Data::Dumper->Dump([$input]);
}

sub on_dial{
        my $input = $_[ARG0];
        print "on_dial\n";
        print Data::Dumper->Dump([$input]);

}

sub on_event{
        # Print all AMI Events
        my $input = $_[ARG0];
        print Data::Dumper->Dump([$input]);
        #print "on_event\n";
}

sub on_newexten{
         my $input = $_[ARG0];
         print Data::Dumper->Dump([$input]);

        my $fu_callerid = $input->{'CallerIDNum'};
        my $ext_status = $input->{'Application'};
        if($ext_status eq 'Answer'){
               print Data::Dumper->Dump([$input]);
               my $channel = $input->{'Channel'};
               my $context = $input->{'Context'};
               my $local_ext = $input->{'Extension'};
               my $priority = $input->{'Priority'};
               print "in Answer state, $channel, $context, $local_ext, $priority \n";
        }
       #print "on_newexten\n";

}


sub on_new_channel{
    my $input = $_[ARG0];
    print "on_new_channel()\n";
    print Data::Dumper->Dump([$input]);

}

sub on_peer_status{
}

sub on_new_callerid{
    print "on_new_callerid\n";
    my $input = $_[ARG0];
    my @Dial_Event=Data::Dumper->Dump([$input]);
    my $callerid = $input->{'CallerIDNum'};
    print "on_new_callerid: $callerid \n";
}


sub on_ring{

}



sub on_hangup{
         my $input = $_[ARG0];
        print Data::Dumper->Dump([$input]);
        my $fu_callerid = $input->{'ConnectedLineNum'};
        my $cause_text = $input->{'Cause-txt'};
        my $channel  = $input->{'Channel'};

        my $tmp0 = substr($channel,0,3);
        print "leg detection...$tmp0\n";
}


sub on_cdr{

}


No comments:

Post a Comment