[Pkg-voip-commits] r2441 - / libasterisk-perl libasterisk-perl/branches libasterisk-perl/branches/upstream libasterisk-perl/branches/upstream/current libasterisk-perl/branches/upstream/current/lib libasterisk-perl/branches/upstream/current/lib/Asterisk

Tzafrir Cohen tzafrir-guest at costa.debian.org
Wed Sep 27 22:08:54 UTC 2006


Author: tzafrir-guest
Date: 2006-09-27 22:08:50 +0000 (Wed, 27 Sep 2006)
New Revision: 2441

Added:
   libasterisk-perl/
   libasterisk-perl/branches/
   libasterisk-perl/branches/upstream/
   libasterisk-perl/branches/upstream/current/
   libasterisk-perl/branches/upstream/current/lib/
   libasterisk-perl/branches/upstream/current/lib/Asterisk/
   libasterisk-perl/branches/upstream/current/lib/Asterisk/Manager.pm
   libasterisk-perl/tags/
Log:
[svn-inject] Installing original source of libasterisk-perl

Added: libasterisk-perl/branches/upstream/current/lib/Asterisk/Manager.pm
===================================================================
--- libasterisk-perl/branches/upstream/current/lib/Asterisk/Manager.pm	                        (rev 0)
+++ libasterisk-perl/branches/upstream/current/lib/Asterisk/Manager.pm	2006-09-27 22:08:50 UTC (rev 2441)
@@ -0,0 +1,392 @@
+package Asterisk::Manager;
+
+require 5.004;
+
+use Asterisk;
+use IO::Socket;
+use Digest::MD5;
+
+use strict;
+use warnings;
+
+=head1 NAME
+
+Asterisk::Manager - Asterisk Manager Interface
+
+=head1 SYNOPSIS
+
+use Asterisk::Manager;
+
+my $astman = new Asterisk::Manager;
+
+$astman->user('username');
+
+$astman->secret('test');
+
+$astman->host('localhost');
+
+$astman->connect || die "Could not connect to " . $astman->host . "!\n";
+
+$astman->disconnect;
+
+=head1 DESCRIPTION
+
+This module provides a simple interface to the asterisk manager interface.
+
+=cut
+
+my $EOL = "\r\n";
+my $BLANK = $EOL x 2;
+
+my $VERSION = '0.01';
+
+sub version { $VERSION; }
+
+sub new {
+	my ($class, %args) = @_;
+
+	my $self = {};
+	$self->{_CONNFD} = undef;
+	$self->{_PROTOVERS} = undef;
+	$self->{_ERRORSTR} = undef;
+	$self->{_HOST} = 'localhost';
+	$self->{_PORT} = 5038;
+	$self->{_USER} = undef;
+	$self->{_SECRET} = undef;
+	$self->{_EVENTCB} = {};
+	$self->{_DEBUG} = 0;
+	$self->{_CONNECTED} = 0;
+	bless $self, ref $class || $class;
+	return $self;
+}
+
+sub DESTROY { }
+
+sub user {
+	my ($self, $user) = @_;
+
+	if ($user) {
+		$self->{_USER} = $user;
+	}
+
+	return $self->{_USER};
+}
+
+sub secret {
+	my ($self, $secret) = @_;
+
+	if ($secret) {
+		$self->{_SECRET} = $secret;
+	}
+
+	return $self->{_SECRET};
+}
+
+sub host {
+	my ($self, $host) = @_;
+
+	if ($host) {
+		$self->{_HOST} = $host;
+	}
+
+	return $self->{_HOST};
+}
+
+sub port {
+	my ($self, $port) = @_;
+
+	if ($port) {
+		$self->{_PORT} = $port;
+	}
+
+	return $self->{_PORT};
+}
+
+sub connected {
+	my ($self, $connected) = @_;
+
+	if (defined($connected)) {
+		$self->{_CONNECTED} = $connected;
+	}
+
+	return $self->{_CONNECTED};
+}
+
+sub error {
+	my ($self, $error) = @_;
+
+	if ($error) {
+		$self->{_ERRORSTR} = $error;
+	}
+
+	return $self->{_ERRORSTR};
+}
+
+sub debug {
+	my ($self, $debug) = @_;
+
+	if ($debug) {
+		$self->{_DEBUG} = $debug;
+	}
+
+	return $self->{_DEBUG};
+}
+
+sub connfd {
+	my ($self, $connfd) = @_;
+
+	if ($connfd) {
+		$self->{_CONNFD} = $connfd;
+	}
+
+	return $self->{_CONNFD};
+}
+
+sub read_response {
+	my ($self, $connfd) = @_;
+
+	my @response;
+
+	if (!$connfd) {
+		$connfd = $self->connfd;
+	}
+
+	while (my $line = <$connfd>) {
+		last if ($line eq $EOL);
+
+		if (wantarray) {
+			$line =~ s/$EOL//g;
+			push(@response, $line) if $line;
+		} else {
+			$response[0] .= $line;
+		}
+
+	}
+
+	return wantarray ? @response : $response[0];
+}
+
+sub connect {
+	my ($self) = @_;
+
+	my $host = $self->host;
+	my $port = $self->port;
+	my $user = $self->user;
+	my $secret = $self->secret;
+	my %resp;
+
+	my $conn = new IO::Socket::INET( Proto => 'tcp',
+					 PeerAddr => $host,
+					 PeerPort => $port
+					);
+	if (!$conn) {
+		$self->error("Connection refused ($host:$port)\n");
+		return undef;
+	}
+
+	$conn->autoflush(1);
+
+	my $input = <$conn>;
+	$input =~ s/$EOL//g;
+
+	my ($manager, $version) = split('/', $input);
+
+	if ($manager !~ /Asterisk Call Manager/) {
+		return $self->error("Unknown Protocol\n");
+	}
+
+	$self->{_PROTOVERS} = $version;
+	$self->connfd($conn);
+
+	# check if the remote host supports MD5 Challenge authentication
+	my %authresp = $self->sendcommand( Action => 'Challenge',
+					   AuthType => 'MD5'
+					 );
+
+	if (($authresp{Response} eq 'Success')) {
+		# do md5 login
+		my $md5 = new Digest::MD5;
+		$md5->add($authresp{Challenge});
+		$md5->add($secret);
+		my $digest = $md5->hexdigest;
+		%resp = $self->sendcommand(  Action => 'Login',
+					     AuthType => 'MD5',
+					     Username => $user,
+					     Key => $digest
+					  );
+	} else {
+		# do plain text login
+		%resp = $self->sendcommand(  Action => 'Login',
+					     Username => $user,
+					     Secret => $secret
+					  );
+
+	}
+
+	if ( ($resp{Response} ne 'Success') && ($resp{Message} ne 'Authentication accepted') ) {
+		$self->error("Authentication failed for user $user\n");
+		return undef;
+	}
+
+	$self->connected(1);
+
+	return $conn;
+}
+
+sub astman_h2s {
+	my ($self, %thash) = @_;
+
+	my $tstring = '';
+
+	foreach my $key (keys %thash) {
+		$tstring .= $key . ': ' . $thash{$key} . ${EOL};
+	}
+
+	return $tstring;
+}
+
+sub astman_s2h {
+	my ($self, $tstring) = @_;
+
+	my %thash;
+
+	foreach my $line (split(/$EOL/, $tstring)) {
+		if ($line =~ /(\w*):\s*(\w*)/) {
+			$thash{$1} = $2;
+		}
+	}
+
+	return %thash;
+}
+
+#$want is how you want the data returned
+#$want = 0 (default) returns the results in a hash
+#$want = 1 returns the results in a large string
+#$want = 2 returns the results in an array
+sub sendcommand {
+	my ($self, %command, $want) = @_;
+
+	if (!defined($want)) {
+		$want = 0;
+	}
+	
+	my $conn = $self->connfd || return;
+	my $cstring = $self->astman_h2s(%command);
+
+	$conn->send("$cstring$EOL");
+
+	if ($want == 1) {
+		my $response = $self->read_response($conn);
+		return $response;
+	}
+
+	my @resp = $self->read_response($conn);
+
+	if ($want == 2) {
+		return @resp;
+	} else {
+		return map { splitresult($_) } @resp;
+	}
+}
+
+sub setcallback {
+	my ($self, $event, $function) = @_;
+
+	if (defined($function) && ref($function) eq 'CODE') {
+		$self->{_EVENTCB}{$event} = $function;
+	}
+}
+
+sub eventcallback {
+	my ($self, %resp) = @_;
+
+	my $callback;
+	my $event = $resp{Event};
+
+	return if (!$event);
+
+	if (defined($self->{_EVENTCB}{$event})) {
+		$callback = $self->{_EVENTCB}{$event};
+	} elsif (defined($self->{_EVENTCB}{DEFAULT})) {
+		$callback = $self->{_EVENTCB}{DEFAULT};
+	} else {
+		return;
+	}
+
+	return &{$callback}(%resp);
+}
+
+sub eventloop {
+	my ($self) = @_;
+
+	while (1) {
+		$self->handleevent;
+	}
+}
+
+sub handleevent {
+	my ($self) = @_;
+
+	my %resp = map { splitresult($_); } $self->read_response;
+	$self->eventcallback(%resp);
+
+	return %resp;
+}
+
+sub action {
+	my ($self, $command, $wanthash) = @_;
+
+	return if (!$command);
+
+	my $conn = $self->connfd || return;
+
+	print $conn "Action: $command" . $BLANK;
+	my @resp = $self->read_response($conn);
+
+	if ($wanthash) {
+		return map { splitresult($_) } @resp;
+	} elsif (wantarray) {
+		return @resp;
+	} else {
+		return $resp[0];
+	}
+}
+
+sub command {
+	my ($self, $command) = @_;
+
+	return if (!$command);
+
+	return $self->sendcommand('Action' => 'Command',
+				  'Command' => $command, 1 );
+}
+
+sub disconnect {
+	my ($self) = @_;
+
+	my $conn = $self->connfd;
+
+	my %resp = $self->sendcommand('Action' => 'Logoff');
+
+
+	if ($resp{Response} eq 'Goodbye') {
+		$self->{_CONNFD} = undef;
+		$self->connected(0);
+		return 1;
+	}
+
+	return 0;
+}
+
+sub splitresult {
+	my ($res) = @_;
+	my ($key, $val) = ('', '');
+
+	$res =~ /^([^:]+):\ {0,1}([^\ ].*)$/;
+	$key = $1 if ($1);
+	$val = $2 if ($2);
+
+	return ($key, $val);
+}
+
+1;




More information about the Pkg-voip-commits mailing list