diff --git a/onvif/modules/lib/WSDiscovery/TransportUDP.pm b/onvif/modules/lib/WSDiscovery/TransportUDP.pm index 33308db13..5125ac9f0 100644 --- a/onvif/modules/lib/WSDiscovery/TransportUDP.pm +++ b/onvif/modules/lib/WSDiscovery/TransportUDP.pm @@ -43,7 +43,7 @@ my %message_of :ATTR(:name :default<()>); my %is_success_of :ATTR(:name :default<()>); my %local_addr_of :ATTR(:name :init_arg :default<()>); - +my $net_interface; # create methods normally inherited from SOAP::Client SUBFACTORY: { @@ -60,14 +60,22 @@ sub _notify_response } +sub set_net_interface { + my $self = shift; + $net_interface = shift; +} + sub send_multi() { my ($self, $address, $port, $utf8_string) = @_; my $destination = $address . ':' . $port; - my $socket = IO::Socket::Multicast->new(PROTO => 'udp', - LocalPort=>$port, PeerAddr=>$destination, ReuseAddr=>1) - - or die 'Cannot open multicast socket to ' . ${address} . ':' . ${port}; + my $socket = IO::Socket::Multicast->new( + PROTO => 'udp', + LocalPort=>$port, + PeerAddr=>$destination, + ReuseAddr=>1 + ) or die 'Cannot open multicast socket to ' . ${address} . ':' . ${port}; + $_ = $socket->mcast_if($net_interface) if $net_interface; my $bytes = $utf8_string; utf8::encode($bytes); @@ -80,14 +88,16 @@ sub receive_multi() { my ($self, $address, $port) = @_; my $data = undef; - my $socket = IO::Socket::Multicast->new(PROTO => 'udp', - LocalPort=>$port, ReuseAddr=>1); - $socket->mcast_add($address); + my $socket = IO::Socket::Multicast->new( + PROTO => 'udp', + LocalPort=>$port, + ReuseAddr=>1); + $socket->mcast_add($address, $net_interface); my $readbits = ''; vec($readbits, $socket->fileno, 1) = 1; - if(select($readbits, undef, undef, WAIT_TIME/1000)) { + if ( select($readbits, undef, undef, WAIT_TIME/1000) ) { $socket->recv($data, 9999); return $data; } @@ -98,15 +108,19 @@ sub receive_uni() { my ($self, $address, $port, $localaddr) = @_; my $data = undef; - my $socket = IO::Socket::Multicast->new(PROTO => 'udp', - LocalAddr => $localaddr, LocalPort=>$port, ReuseAddr=>1); + my $socket = IO::Socket::Multicast->new( + PROTO => 'udp', + LocalAddr => $localaddr, + LocalPort=>$port, + ReuseAddr=>1 + ); - $socket->mcast_add($address); + $socket->mcast_add($address, $net_interface); my $readbits = ''; vec($readbits, $socket->fileno, 1) = 1; - if(select($readbits, undef, undef, WAIT_TIME/1000)) { + if ( select($readbits, undef, undef, WAIT_TIME/1000) ) { $socket->recv($data, 9999); return $data; } @@ -114,50 +128,51 @@ sub receive_uni() { } sub send_receive { - my ($self, %parameters) = @_; - my ($envelope, $soap_action, $endpoint, $encoding, $content_type) = - @parameters{qw(envelope action endpoint encoding content_type)}; + my ($self, %parameters) = @_; + my ($envelope, $soap_action, $endpoint, $encoding, $content_type) = + @parameters{qw(envelope action endpoint encoding content_type)}; - my ($address,$port) = ($endpoint =~ /([^:\/]+):([0-9]+)/); + my ($address,$port) = ($endpoint =~ /([^:\/]+):([0-9]+)/); - #warn "address = ${address}"; - #warn "port = ${port}"; +#warn "address = ${address}"; +#warn "port = ${port}"; - $self->send_multi($address, $port, $envelope); + $self->send_multi($address, $port, $envelope); - my $localaddr = $self->get_local_addr(); + my $localaddr = $self->get_local_addr(); +#warn "localddr $localaddr"; - my ($response, $last_response); - my $wait = WAIT_COUNT; - while ( $wait >= 0 ) { - if($localaddr) { - if($response = $self->receive_uni($address, $port, $localaddr)) { - $last_response = $response; - $self->_notify_response($response); - } - $wait --; - } - if($response = $self->receive_multi($address, $port)) { - $last_response = $response; - $self->_notify_response($response); - } - $wait --; - } - - if($last_response) { - $self->set_code(); - $self->set_message(""); - $self->set_is_success(1); - $self->set_status('OK'); - } - else{ - $self->set_code(); - $self->set_message("Timed out waiting for response"); - $self->set_is_success(0); - $self->set_status('TIMEOUT'); - } + my ($response, $last_response); + my $wait = WAIT_COUNT; + while ( $wait >= 0 ) { + if ( $localaddr ) { + if ( $response = $self->receive_uni($address, $port, $localaddr) ) { + $last_response = $response; + $self->_notify_response($response); + } + $wait --; + } + if ( $response = $self->receive_multi($address, $port) ) { + $last_response = $response; + $self->_notify_response($response); + } + $wait --; + } - return $last_response; + if ( $last_response ) { + $self->set_code(); + $self->set_message(''); + $self->set_is_success(1); + $self->set_status('OK'); + } else { + $self->set_code(); + $self->set_message('Timed out waiting for response'); + $self->set_is_success(0); + $self->set_status('TIMEOUT'); + } + + return $last_response; } 1; +__END__ diff --git a/scripts/ZoneMinder/lib/ZoneMinder/ONVIF.pm.in b/scripts/ZoneMinder/lib/ZoneMinder/ONVIF.pm.in index f4dedb3b9..9b9c6c794 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/ONVIF.pm.in +++ b/scripts/ZoneMinder/lib/ZoneMinder/ONVIF.pm.in @@ -172,7 +172,7 @@ sub interpret_messages { # functions sub discover { - my ( $soap_version ) = @_; + my ( $soap_version, $net_interface ) = @_; my @results; ## collect all responses @@ -190,22 +190,27 @@ sub discover { my $uuid_gen = Data::UUID->new(); if ( ( ! $soap_version ) or ( $soap_version eq '1.1' ) ) { - my %services; + my %services; - if($verbose) { - print "Probing for SOAP 1.1\n" + if ( $verbose ) { + print "Probing for SOAP 1.1\n"; } my $svc_discover = WSDiscovery10::Interfaces::WSDiscovery::WSDiscoveryPort->new({ # no_dispatch => '1', }); $svc_discover->set_soap_version('1.1'); + if ( $net_interface ) { + my $transport = $svc_discover->get_transport(); + print "Setting net interface for $transport to $net_interface\n"; + $transport->set_net_interface($net_interface); + } my $uuid = $uuid_gen->create_str(); my $result = $svc_discover->ProbeOp( - { # WSDiscovery::Types::ProbeType - Types => 'http://www.onvif.org/ver10/network/wsdl:NetworkVideoTransmitter http://www.onvif.org/ver10/device/wsdl:Device', # QNameListType - Scopes => { value => '' }, + { # WSDiscovery::Types::ProbeType + Types => 'http://www.onvif.org/ver10/network/wsdl:NetworkVideoTransmitter http://www.onvif.org/ver10/device/wsdl:Device', # QNameListType + Scopes => { value => '' }, }, WSDiscovery10::Elements::Header->new({ Action => { value => 'http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe' }, @@ -220,14 +225,19 @@ sub discover { } # end if doing soap 1.1 if ( ( ! $soap_version ) or ( $soap_version eq '1.2' ) ) { - my %services; - if($verbose) { - print "Probing for SOAP 1.2\n" + my %services; + if ( $verbose ) { + print "Probing for SOAP 1.2\n"; } my $svc_discover = WSDiscovery10::Interfaces::WSDiscovery::WSDiscoveryPort->new({ # no_dispatch => '1', }); $svc_discover->set_soap_version('1.2'); + if ( $net_interface ) { + my $transport = $svc_discover->get_transport(); + print "Setting net interface for $transport to $net_interface\n"; + $transport->set_net_interface($net_interface); + } # copies of the same Probe message must have the same MessageID. # This is not a copy. So we generate a new uuid. @@ -250,7 +260,7 @@ sub discover { push @results, interpret_messages($svc_discover, \%services, @responses); } # end if doing soap 1.2 return @results; -} +} # end sub discover sub profiles { my ( $client ) = @_; diff --git a/scripts/zmcamtool.pl.in b/scripts/zmcamtool.pl.in index 7e345b79d..3d68b1408 100644 --- a/scripts/zmcamtool.pl.in +++ b/scripts/zmcamtool.pl.in @@ -352,9 +352,13 @@ sub exportsql { } my $name = $ARGV[0]; - if ($name && $name =~ /^([A-Za-z0-9 ,.&()\/\-]+)$/) { # Allow alphanumeric and " ,.&()/-" - $name = $1; - $command .= qq( --where="Name = '$name'"); + if ( $name ) { + if ( $name =~ /^([A-Za-z0-9 ,.&()\/\-]+)$/ ) { # Allow alphanumeric and " ,.&()/-" + $name = $1; + $command .= qq( --where="Name = '$name'"); + } else { + print "Invalid characters in Name\n"; + } } $command .= " zm Controls MonitorPresets"; diff --git a/scripts/zmonvif-probe.pl.in b/scripts/zmonvif-probe.pl.in index 6b4c5c1a6..c825f8447 100755 --- a/scripts/zmonvif-probe.pl.in +++ b/scripts/zmonvif-probe.pl.in @@ -41,7 +41,7 @@ my $OPTIONS = 'v'; sub HELP_MESSAGE { my ($fh, $pkg, $ver, $opts) = @_; - print $fh "Usage: " . __FILE__ . " [-v] probe \n"; + print $fh "Usage: " . __FILE__ . " [-v] probe \n"; print $fh " " . __FILE__ . " [-v] \n"; print $fh <