###########################################################################
# package Net::SIP::Redirect
# uses Registrar to redirect incoming calls based on the information
# provided by the registrar
###########################################################################
use strict;
use warnings;
package Net::SIP::Redirect;
use fields qw(dispatcher registrar);
use Net::SIP::Debug;
use Net::SIP::Util ':all';
sub new {
my ($class,%args) = @_;
my $self = fields::new($class);
%$self = %args;
$self->{dispatcher} or croak( "no dispatcher given" );
$self->{registrar} or croak( "no registrar given" );
return $self;
}
sub receive {
my Net::SIP::Redirect $self = shift;
my ($packet,$leg,$addr) = @_;
$packet->is_request or return; # don't handle responses
my $method = $packet->method;
my $resp;
if ( $method eq 'ACK' ) {
# if I got an ACK cancel delivery of response to INVITE
$self->{dispatcher}->cancel_delivery( $packet->tid );
return -1; # don't process in next part of chain
} elsif ( $method eq 'CANCEL' ) {
$resp = $packet->create_response(200);
} elsif ( $method eq 'REGISTER' ) {
return; # don't process myself
} else {
my $key = sip_parts2uri((sip_uri2parts($packet->uri))[0,1,2]);
if ( my @contacts = $self->{registrar}->query($key)) {
$resp = $packet->create_response('302','Moved Temporarily');
$resp->add_header( contact => $_ ) for(@contacts);
} else {
$resp = $packet->create_response('404','Not found');
}
}
$self->{dispatcher}->deliver($resp,leg => $leg,dst_addr => $addr);
return $resp->code;
}
1;