Asterisk-AMI
view release on metacpan or search on metacpan
lib/Asterisk/AMI.pm view on Meta::CPAN
#Register warnings
use warnings::register;
use strict;
use warnings;
use AnyEvent;
use AnyEvent::Handle;
use AnyEvent::Socket;
use Digest::MD5;
use Scalar::Util qw/weaken/;
use Carp qw/carp/;
#Duh
use version 0.77; our $VERSION = version->declare("v0.2.8");
#Used for storing events while reading command responses Events are stored as hashes in the array Example
#$self->{EVETNBUFFER}->{'Event'} = Something
#Buffer for holding action responses and data
# Structure: $self->{RESPONSEBUFFER}->{'ActionID'}->{'Response'} = (Success|Failure|Follows|Goodbye|Pong|Etc..)
lib/Asterisk/AMI.pm view on Meta::CPAN
#and don't mess with the handlers
} elsif (lc($self->{CONFIG}->{EVENTS}) !~ /on|call/x) {
$self->{CONFIG}->{EVENTS} .= ',call';
}
}
#Initialize the seq number
$self->{idseq} = 1;
#Weaken reference for use in anonsub
weaken($self);
#Set keepalive
$self->{CONFIG}->{KEEPALIVE} = AE::timer($self->{CONFIG}->{KEEPALIVE}, $self->{CONFIG}->{KEEPALIVE}, sub { $self->_send_keepalive }) if ($self->{CONFIG}->{KEEPALIVE});
return 1;
}
#Handles connection failures (includes login failure);
sub _on_connect_err {
lib/Asterisk/AMI.pm view on Meta::CPAN
my ($self, $fh, $line) = @_;
if ($line =~ /^Asterisk\ Call\ Manager\/([0-9]\.[0-9])$/ox) {
$self->{AMIVER} = $1;
} else {
warnings::warnif('Asterisk::AMI', "Unknown Protocol/AMI Version from $self->{CONFIG}->{PEERADDR}:$self->{CONFIG}->{PEERPORT}");
}
#Weak reference for us in anonysub
weaken($self);
$self->{handle}->push_read( 'Asterisk::AMI' => sub { $self->_handle_packet(@_); } );
return 1;
}
#Connects to the AMI Returns 1 on success, 0 on failure
sub _connect {
my ($self) = @_;
#Weaken ref for use in anonysub
weaken($self);
#Build a hash of our anyevent::handle options
my %hdl = ( connect => [$self->{CONFIG}->{PEERADDR} => $self->{CONFIG}->{PEERPORT}],
on_connect_err => sub { $self->_on_connect_err($_[1]); },
on_error => sub { $self->_on_error($_[2]) },
on_eof => sub { $self->_on_disconnect; },
on_connect => sub { $self->{handle}->push_read( line => sub { $self->_on_connect(@_); } ); });
#TLS stuff
$hdl{'tls'} = 'connect' if ($self->{CONFIG}->{USESSL});
lib/Asterisk/AMI.pm view on Meta::CPAN
delete $self->{EXPECTED}->{$id};
return $resp;
}
#Don't Have it, wait for it Install some handlers and use a CV to simulate blocking
my $process = AE::cv;
$self->{CALLBACKS}->{$id}->{'cb'} = sub { $process->send($_[1]) };
$timeout = $self->{CONFIG}->{TIMEOUT} unless (defined $timeout);
#Should not need to weaken here because this is a blocking call Only outcomes can be error, timeout, or
#complete, all of which will finish the cb and clear the reference weaken($self)
if ($timeout) {
$self->{CALLBACKS}->{$id}->{'timeout'} = sub {
my $response = $self->{'RESPONSEBUFFER'}->{$id};
delete $self->{RESPONSEBUFFER}->{$id};
delete $self->{CALLBACKS}->{$id};
delete $self->{EXPECTED}->{$id};
$process->send($response);
};
lib/Asterisk/AMI.pm view on Meta::CPAN
$self->{handle}->push_write($action);
} else {
$self->{PRELOGIN}->{$id} = $action;
}
$self->{RESPONSEBUFFER}->{$id}->{'COMPLETED'} = 0;
$self->{RESPONSEBUFFER}->{$id}->{'GOOD'} = 0;
$self->{EXPECTED}->{$id} = 1;
#Weaken ref of use in anonsub
weaken($self);
#Set default timeout if needed
$timeout = $self->{CONFIG}->{TIMEOUT} unless (defined $timeout);
#Setup callback
if (defined $callback) {
#Set callback if defined
$self->{CALLBACKS}->{$id}->{'cb'} = $callback;
#Variable to return with Callback
$self->{CALLBACKS}->{$id}->{'store'} = $store;
lib/Asterisk/AMI.pm view on Meta::CPAN
}
return $self->_logged_in($resp);
}
#Non-blocking login
sub _login_noblock {
my ($self, $action, $challenge, $timeout) = @_;
#Weaken ref for use in anonsub
weaken($self);
#Callback for login action
my $login_cb = sub { $self->_logged_in($_[1]) };
#Do a md5 challenge
if (%{$challenge}) {
#Create callbacks for the challenge
my $challenge_cb = sub {
if ($_[1]->{'GOOD'}) {
my $md5 = Digest::MD5->new();
lib/Asterisk/AMI.pm view on Meta::CPAN
#Check whether there was an error on the socket
sub error {
my ($self) = @_;
return $self->{SOCKERR};
}
#Sends a keep alive
sub _send_keepalive {
my ($self) = @_;
#Weaken ref for use in anonysub
weaken($self);
my $cb = sub {
unless ($_[1]->{'GOOD'}) {
$self->_on_timeout("Asterisk failed to respond to keepalive - $self->{CONFIG}->{PEERADDR}:$self->{CONFIG}->{PEERPORT}");
};
};
my $timeout = $self->{CONFIG}->{TIMEOUT} || 5;
return $self->send_action({ Action => 'Ping' }, $cb, $timeout);
}
( run in 0.345 second using v1.01-cache-2.11-cpan-65fba6d93b7 )