File Coverage

blib/lib/Net/SIP/ReceiveChain.pm
Criterion Covered Total %
statement 26 33 78.7
branch 5 10 50.0
condition n/a
subroutine 6 7 85.7
pod 2 2 100.0
total 39 52 75.0


line stmt bran cond sub pod time code
1             ###########################################################################
2             # package Net::SIP::ReceiveChain
3             # used to put Authorize, Registrar, StatelessProxy etc together so that
4             # the object first in chain will try to handle the packets first and
5             # pass them only to the next object if it was not fully handled by the
6             # previous object
7             # each object in chain returns TRUE from method receive if it handled
8             # the packet fully
9             ###########################################################################
10              
11 43     43   263 use strict;
  43         91  
  43         1094  
12 43     43   183 use warnings;
  43         75  
  43         1334  
13              
14             package Net::SIP::ReceiveChain;
15 43     43   194 use fields qw( objects filter );
  43         69  
  43         187  
16 43     43   2805 use Net::SIP::Util 'invoke_callback';
  43         79  
  43         12241  
17              
18             ###########################################################################
19             # creates new ReceiveChain object
20             # Args: ($class,$objects,%args)
21             # $objects: \@list of objects which it should put in the chain
22             # %args:
23             # filter: callback invoked on each packet to find out if it should
24             # be processed by this chain
25             # methods: \@list of methods, used if no filter is given
26             # Returns: $self
27             ###########################################################################
28             sub new {
29 2     2 1 38 my ($class,$objects,%args) = @_;
30 2         11 my $self = fields::new( $class );
31 2 50       148 if ( ! ( $self->{filter} = $args{filter} )) {
32 2 50       11 if ( my $m = $args{methods} ) {
33             # predefined filter to filter based on method
34 0         0 my %m = map { $_ => 1 } @$m;
  0         0  
35             my $method_filter = sub {
36 0     0   0 my ($hm,$packet) = @_;
37 0         0 return $hm->{ $packet->method }
38 0         0 };
39 0         0 $self->{filter} = [ $method_filter, \%m ];
40             }
41             }
42 2         4 $self->{objects} = $objects;
43 2         7 return $self;
44             }
45              
46             ###########################################################################
47             # handle packet, called from Net::SIP::Dispatcher on incoming requests
48             # Args: ($self,$packet,$leg,$addr)
49             # $packet: Net::SIP::Packet
50             # $leg: Net::SIP::Leg where request came in (and response gets send out)
51             # $addr: ip:port where request came from and response will be send
52             # Returns: TRUE if it handled the packet
53             ###########################################################################
54             sub receive {
55 12     12 1 21 my Net::SIP::ReceiveChain $self = shift;
56 12         24 my ($packet,$leg,$addr) = @_;
57              
58 12 50       63 if ( my $f = $self->{filter} ) {
59             # check if packet should be handled by filter
60 0 0       0 return if ! invoke_callback($f,$packet,$leg,$addr);
61             }
62 12         21 foreach my $object (@{ $self->{objects} }) {
  12         39  
63 17         107 my $handled = $object->receive($packet,$leg,$addr);
64 17 100       61 return $handled if $handled;
65             }
66 3         14 return; # not handled
67             }
68              
69             1;