Asterisk-CoroManager

 view release on metacpan or  search on metacpan

lib/Asterisk/CoroManager.pm  view on Meta::CPAN

	no strict qw(refs);
	foreach my $level (qw(trace debug error fatal)) {
	    *{__PACKAGE__."::$level"} =
	      sub {
		  $Log::Log4perl::caller_depth++;
		  my( $astman, $message ) = @_;
		  my $log = Log::Log4perl->get_logger();
		  $log->$level($astman->host .': '. $message);
		  $Log::Log4perl::caller_depth--;
		  return;
	      };
	}
    }
}


my $EOL = "\015\012";
my $BLANK = $EOL x 2;

use vars qw($VERSION); $VERSION = '0.11'; sub version { return $VERSION }

my $ACTIONID_SEQ = 1;
my $RESULT_SEQ = 1;



##############################################################################
##############################################################################

=head1 Constructor

=head2 new

  my $astman = new Asterisk::CoroManager({
                                          host   => 'localhost',
                                          user   => 'username',
                                          secret => 'test',
                                         });

Supported args are:

  host       Asterisk host.  Defaults to 'localhost'.
  port       Manager port.  Defaults to 5038,
  user       Manager user.
  secret     Manager secret.

=cut

sub new
{
    my( $class, $args ) = @_;

    my $astman;
    $astman =  bless {
		      host        => $args->{host} || 'localhost',
		      port        => $args->{port} || 5038,
		      user        => $args->{user},
		      secret      => $args->{secret},
		      watcher     => undef,
		      finished    => undef, # Will hold AnyEvent->condvar
		      action_cb   => {},    # Action response callbacks
		      event_cb    => {},    # event callbacks
		      event_dcb   => undef, # event default callback
		      uevent_cb   => {},    # userevent callbacks
		      uevent_dcb  => undef, # userevent default callback
		      ami_version => undef,
		      read_buffer => [],
		     }, __PACKAGE__;

    $astman->add_event_callback('UserEvent',
                                sub{ $astman->handle_uevent(@_) }
                               );

    return $astman;
}


##############################################################################
##############################################################################

=head1 Actions

=cut

##############################################################################

=head2 connect

  $astman->connect or croak "Could not connect to ". $astman->host ."!\n";

Connects the manager to asterisk.  User, secret and host should be set
before calling this.

Returns Asterisk Manager Interface version on success; otherwise undef.

=cut

sub connect
{
    my( $astman ) = @_;

    my $host = $astman->{host};
    my $port = $astman->{port};
    my $user = $astman->{user};
    my $secret = $astman->{secret};

    my $fh = new IO::Socket::INET( Proto => 'tcp',
				   PeerAddr => $host,
				   PeerPort => $port,
				   Blocking => 0,
				 );

    if (!$fh) {
	$astman->error("Can't bind ($host:$port): $@\n");
	return;
    }

    $astman->{fh} = $fh;
    $fh->autoflush(1);

    # Recieve greeting from asterisk server
    my $greeting = AnyEvent->condvar;
    my $greeting_watcher
      = AnyEvent->io( fh   => $fh,

lib/Asterisk/CoroManager.pm  view on Meta::CPAN

	    };
	    $astman->{read_buffer} = [];
	}
	else {
	    push @{$astman->{read_buffer}}, $line;
	}
    }

    return;
}


##############################################################################

=head2 handle_packet

handle_packet is called when incoming on fh has gotten a full packet.

=cut

sub handle_packet {
    my( $astman, $packet ) = @_;
    my $pack = parse_packet( $packet );
    my $event = $pack->{Event};
    my $callback;

    if( $pack->{Ping} and
	not $pack->{ActionID}
      ) {
	$pack->{ActionID} = 'Ping';
    }

    if( $event ) {
	$astman->handle_event( $pack );
    }
    elsif( my $actionid = $pack->{ActionID} ) {
	$astman->debug("Returning response for Action $actionid");
	$astman->handle_actionresponse( $pack );
    }
    else {
	$astman->trace("Unhandled packet from Asterisk.");
    }

    return;
}


##############################################################################

=head2 handle_event

handle_event is called if an incoming packet is an event.  Falls back
to default event handler.

=cut

sub handle_event {
    my( $astman, $pack ) = @_;
    my $event = $pack->{Event};

    if ( my $callbacks =
	 $astman->{event_cb}{$event} ||
	 $astman->{event_dcb}
       ) {
	$astman->debug("Handling event: $event");
	foreach my $cb (@$callbacks) {
	    &{$cb}($pack);
	}
    }
    else {
	$astman->trace("Unhandled event: $event");
    }
    return;
}


##############################################################################

=head2 handle_uevent

handle_uevent is called if an incoming packet is a user event.  Falls
back to default user event handler and ultimately to default event
handler.

=cut

sub handle_uevent {
    my( $astman, $pack ) = @_;
    my $uevent = $pack->{UserEvent};

    if ( my $callbacks =
	 $astman->{uevent_cb}{$uevent} ||
	 $astman->{uevent_dcb} ||
	 $astman->{event_dcb}
       ) {
	$astman->debug("Handling uevent: $uevent");

	foreach my $cb (@$callbacks) {
	    &{$cb}($pack);
	}
    }
    else {
	$astman->trace("Unhandled uevent: $uevent");
    }
    return;
}


##############################################################################

=head2 handle_actionresponse

handle_actionresponse is called if an incoming packet is a response
with an ActionID.

=cut

sub handle_actionresponse {
    my( $astman, $resp ) = @_;
    my $actionid = $resp->{'ActionID'};

    if( my $callback = $astman->{action_cb}{$actionid} ) {
	&{$callback}($resp);
	delete $astman->{action_cb}{$actionid};
    }
    else {
	$astman->debug("Unhandled ActionID: $actionid");
	$astman->trace("Actions: ". Dumper( $astman->{action_cb} ));
    }
    return;
}


##############################################################################

=head2 parse_packet

Parses a packet as array-ref and returns it as hash-ref.

Puts unmatched lines in an array in $pack->{RestResult}.

=cut

sub parse_packet {
    my( $packet ) = @_;
    my @rest;
    my %pack;

    while (my $line = shift @{$packet}) {
	if( $line =~ /^([^:]+):\ {0,1}([^\ ].*)$/ ) {
	    $pack{$1} = $2;
	}
	else {
	    push @rest, $line;
	}
    }

    if( @rest ) {



( run in 1.584 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )