From de22f218134aefd7a554667fd16d90871992a81e Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 4 Oct 2016 09:36:28 -0400 Subject: [PATCH 01/13] for soap 1.2 only probe for NetworkVideoTransmitter --- onvif/scripts/zmonvif-probe.pl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/onvif/scripts/zmonvif-probe.pl b/onvif/scripts/zmonvif-probe.pl index 10aa26a08..60f66146c 100755 --- a/onvif/scripts/zmonvif-probe.pl +++ b/onvif/scripts/zmonvif-probe.pl @@ -210,11 +210,11 @@ sub discover # This is not a copy. So we generate a new uuid. $uuid = $uuid_gen->create_str(); + # Everyone else, like the nodejs onvif code and odm only ask for NetworkVideoTransmitter $result = $svc_discover->ProbeOp( { # WSDiscovery::Types::ProbeType - xmlattr => { 'xmlns:dn' => 'http://www.onvif.org/ver10/network/wsdl', - 'xmlns:tds' => 'http://www.onvif.org/ver10/device/wsdl', }, - Types => 'dn:NetworkVideoTransmitter tds:Device', # QNameListType + xmlattr => { 'xmlns:dn' => 'http://www.onvif.org/ver10/network/wsdl', }, + Types => 'dn:NetworkVideoTransmitter', # QNameListType Scopes => { value => '' }, }, WSDiscovery10::Elements::Header->new({ From e6626cef69f51a530a52573eef1f43ae534324ab Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 4 Oct 2016 09:51:20 -0400 Subject: [PATCH 02/13] if soap version is specified for probe, don't do both versions --- onvif/scripts/zmonvif-probe.pl | 95 ++++++++++++++++++---------------- 1 file changed, 51 insertions(+), 44 deletions(-) diff --git a/onvif/scripts/zmonvif-probe.pl b/onvif/scripts/zmonvif-probe.pl index 60f66146c..50259b8e8 100755 --- a/onvif/scripts/zmonvif-probe.pl +++ b/onvif/scripts/zmonvif-probe.pl @@ -41,6 +41,7 @@ require WSDiscovery::TransportUDP; # Globals my $verbose = 0; +my $soap_version = undef; my $client; # ========================================================================= @@ -171,59 +172,64 @@ sub discover my %services; my $uuid_gen = Data::UUID->new(); + + if ( ( ! $soap_version ) or ( $soap_version eq '1.1' ) ) { - if($verbose) { - print "Probing for SOAP 1.1\n" - } - my $svc_discover = WSDiscovery10::Interfaces::WSDiscovery::WSDiscoveryPort->new({ + 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'); + }); + $svc_discover->set_soap_version('1.1'); - my $uuid = $uuid_gen->create_str(); + 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 => '' }, - }, - WSDiscovery10::Elements::Header->new({ - Action => { value => 'http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe' }, - MessageID => { value => "urn:uuid:$uuid" }, - To => { value => 'urn:schemas-xmlsoap-org:ws:2005:04:discovery' }, - }) - ); + 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 => '' }, + }, + WSDiscovery10::Elements::Header->new({ + Action => { value => 'http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe' }, + MessageID => { value => "urn:uuid:$uuid" }, + To => { value => 'urn:schemas-xmlsoap-org:ws:2005:04:discovery' }, + }) + ); # print $result . "\n"; - interpret_messages($svc_discover, \%services, @responses); - @responses = (); + interpret_messages($svc_discover, \%services, @responses); + @responses = (); + } # end if doing soap 1.1 - if($verbose) { - print "Probing for SOAP 1.2\n" - } - $svc_discover = WSDiscovery10::Interfaces::WSDiscovery::WSDiscoveryPort->new({ + if ( ( ! $soap_version ) or ( $soap_version eq '1.2' ) ) { + if($verbose) { + print "Probing for SOAP 1.2\n" + } + $svc_discover = WSDiscovery10::Interfaces::WSDiscovery::WSDiscoveryPort->new({ # no_dispatch => '1', - }); - $svc_discover->set_soap_version('1.2'); + }); + $svc_discover->set_soap_version('1.2'); - # copies of the same Probe message must have the same MessageID. - # This is not a copy. So we generate a new uuid. - $uuid = $uuid_gen->create_str(); +# copies of the same Probe message must have the same MessageID. +# This is not a copy. So we generate a new uuid. + $uuid = $uuid_gen->create_str(); - # Everyone else, like the nodejs onvif code and odm only ask for NetworkVideoTransmitter - $result = $svc_discover->ProbeOp( - { # WSDiscovery::Types::ProbeType - xmlattr => { 'xmlns:dn' => 'http://www.onvif.org/ver10/network/wsdl', }, - Types => 'dn:NetworkVideoTransmitter', # QNameListType - Scopes => { value => '' }, - }, - WSDiscovery10::Elements::Header->new({ - Action => { value => 'http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe' }, - MessageID => { value => "urn:uuid:$uuid" }, - To => { value => 'urn:schemas-xmlsoap-org:ws:2005:04:discovery' }, - }) - ); +# Everyone else, like the nodejs onvif code and odm only ask for NetworkVideoTransmitter + $result = $svc_discover->ProbeOp( + { # WSDiscovery::Types::ProbeType + xmlattr => { 'xmlns:dn' => 'http://www.onvif.org/ver10/network/wsdl', }, + Types => 'dn:NetworkVideoTransmitter', # QNameListType + Scopes => { value => '' }, + }, + WSDiscovery10::Elements::Header->new({ + Action => { value => 'http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe' }, + MessageID => { value => "urn:uuid:$uuid" }, + To => { value => 'urn:schemas-xmlsoap-org:ws:2005:04:discovery' }, + }) + ); # print $result . "\n"; + } # end if doing soap 1.2 interpret_messages($svc_discover, \%services, @responses); } @@ -321,7 +327,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 < Date: Tue, 4 Oct 2016 10:15:16 -0400 Subject: [PATCH 03/13] apply use strict and fix issues --- onvif/scripts/zmonvif-probe.pl | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/onvif/scripts/zmonvif-probe.pl b/onvif/scripts/zmonvif-probe.pl index 50259b8e8..37ca56834 100755 --- a/onvif/scripts/zmonvif-probe.pl +++ b/onvif/scripts/zmonvif-probe.pl @@ -1,4 +1,5 @@ #!/usr/bin/perl -w +use strict; # # ========================================================================== # @@ -196,7 +197,7 @@ sub discover To => { value => 'urn:schemas-xmlsoap-org:ws:2005:04:discovery' }, }) ); -# print $result . "\n"; + print $result . "\n" if $verbose; interpret_messages($svc_discover, \%services, @responses); @responses = (); @@ -206,17 +207,17 @@ sub discover if($verbose) { print "Probing for SOAP 1.2\n" } - $svc_discover = WSDiscovery10::Interfaces::WSDiscovery::WSDiscoveryPort->new({ + my $svc_discover = WSDiscovery10::Interfaces::WSDiscovery::WSDiscoveryPort->new({ # no_dispatch => '1', }); $svc_discover->set_soap_version('1.2'); # copies of the same Probe message must have the same MessageID. # This is not a copy. So we generate a new uuid. - $uuid = $uuid_gen->create_str(); + my $uuid = $uuid_gen->create_str(); # Everyone else, like the nodejs onvif code and odm only ask for NetworkVideoTransmitter - $result = $svc_discover->ProbeOp( + my $result = $svc_discover->ProbeOp( { # WSDiscovery::Types::ProbeType xmlattr => { 'xmlns:dn' => 'http://www.onvif.org/ver10/network/wsdl', }, Types => 'dn:NetworkVideoTransmitter', # QNameListType @@ -228,10 +229,10 @@ sub discover To => { value => 'urn:schemas-xmlsoap-org:ws:2005:04:discovery' }, }) ); -# print $result . "\n"; + print $result . "\n" if $verbose; + interpret_messages($svc_discover, \%services, @responses); } # end if doing soap 1.2 - interpret_messages($svc_discover, \%services, @responses); } From c1f9c0aff5ccb883e2895bfae22c74a5d196596d Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 4 Oct 2016 10:16:01 -0400 Subject: [PATCH 04/13] also need ProbeMatchesType to inherit get_ProbeMatch --- onvif/proxy/lib/WSDiscovery10/Elements/Probe.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/onvif/proxy/lib/WSDiscovery10/Elements/Probe.pm b/onvif/proxy/lib/WSDiscovery10/Elements/Probe.pm index e07ec2510..33e3c5f96 100644 --- a/onvif/proxy/lib/WSDiscovery10/Elements/Probe.pm +++ b/onvif/proxy/lib/WSDiscovery10/Elements/Probe.pm @@ -15,6 +15,7 @@ __PACKAGE__->__set_ref(); use base qw( SOAP::WSDL::XSD::Typelib::Element WSDiscovery10::Types::ProbeType + WSDiscovery10::Types::ProbeMatchesType ); } From 21a94a62004f10e0a850c9a9b7317225774e218d Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 4 Oct 2016 10:29:37 -0400 Subject: [PATCH 05/13] better error message --- web/skins/classic/views/onvifprobe.php | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/web/skins/classic/views/onvifprobe.php b/web/skins/classic/views/onvifprobe.php index 700246936..c183d010c 100644 --- a/web/skins/classic/views/onvifprobe.php +++ b/web/skins/classic/views/onvifprobe.php @@ -28,12 +28,18 @@ $cameras = array(); $cameras[0] = translate('ChooseDetectedCamera'); -function execONVIF( $cmd ) -{ - exec( escapeshellcmd(ZM_PATH_BIN . "/zmonvif-probe.pl $cmd"), $output, $status ); - - if ( $status ) - Fatal( "Unable to probe network cameras, status is '$status'" ); +function execONVIF( $cmd ) { + $shell_command = escapeshellcmd(ZM_PATH_BIN . "/zmonvif-probe.pl $cmd"); + + exec( $shell_command, $output, $status ); + + if ( $status ) { + $html_output = implode( '
', $output ); + Fatal( "Unable to probe network cameras, status is '$status'. Output was:

+ $html_output

+ Please the following command from a command line for more information:

$shell_command" + ); + } return $output; } From 866b6fea8c9ae1a688ab9c7e60db8fb6c1354ab9 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 4 Oct 2016 14:06:23 -0400 Subject: [PATCH 06/13] Fall back to getCapabilities if getServices is not supported. --- onvif/modules/lib/ONVIF/Client.pm | 58 ++++++++++++++++++++++++------- 1 file changed, 46 insertions(+), 12 deletions(-) diff --git a/onvif/modules/lib/ONVIF/Client.pm b/onvif/modules/lib/ONVIF/Client.pm index eaf78747d..c835caca9 100644 --- a/onvif/modules/lib/ONVIF/Client.pm +++ b/onvif/modules/lib/ONVIF/Client.pm @@ -77,6 +77,8 @@ my %soap_version_of :ATTR(:default<('1.1')>); sub service { my ($self, $serviceName, $attr) = @_; +#print "service: " . $services_of{${$self}}{$serviceName}{$attr} . "\n"; +# Please note that the Std::Class::Fast docs say not to use ident. $services_of{ident $self}{$serviceName}{$attr}; } @@ -113,27 +115,59 @@ sub set_soap_version delete $serializer_of{ ident $self }; } -sub get_service_urls -{ +sub get_service_urls { my ($self) = @_; my $result = $self->service('device', 'ep')->GetServices( { IncludeCapability => 'true', # boolean },, ); - - die $result if not $result; -# print $result . "\n"; - - foreach my $svc ( @{ $result->get_Service() } ) { - my $short_name = $namespace_map{$svc->get_Namespace()}; - my $url_svc = $svc->get_XAddr()->get_value(); - if(defined $short_name && defined $url_svc) { + if ( $result ) { + foreach my $svc ( @{ $result->get_Service() } ) { + my $short_name = $namespace_map{$svc->get_Namespace()}; + my $url_svc = $svc->get_XAddr()->get_value(); + if(defined $short_name && defined $url_svc) { # print "Got $short_name service\n"; - $self->set_service($short_name, 'url', $url_svc); + $self->set_service($short_name, 'url', $url_svc); + } } + # } else { + #print "No results from GetServices: $result\n"; } -} + + # Some devices do not support getServices, so we have to try getCapabilities + + $result = $self->service('device', 'ep')->GetCapabilities( {}, , ); + if ( ! $result ) { + print "No results from GetCapabilities: $result\n"; + return; + } + # Result is a GetCapabilitiesResponse + foreach my $capabilities ( @{ $result->get_Capabilities() } ) { + foreach my $capability ( 'PTZ', 'Media', 'Imaging', 'Events', 'Device' ) { + if ( my $function = $capabilities->can( "get_$capability" ) ) { + my $Services = $function->( $capabilities ); + if ( ! $Services ) { + print "Nothing returned ffrom get_$capability\n"; + } else { + foreach my $svc ( @{ $Services } ) { + # The capability versions don't have a namespace, so just lowercase them. + my $short_name = lc $capability; + my $url_svc = $svc->get_XAddr()->get_value(); + if( defined $url_svc) { +# print "Got $short_name service\n"; + $self->set_service($short_name, 'url', $url_svc); + } + } # end foreach svr + } + } else { + print "No $capability function\n"; + + } # end if has a get_ function + } # end foreach capability + } # end foreach capabilities + +} # end sub get_service_urls sub http_digest { my ($service, $username, $password) = @_; From df255d3d5d174190db36087c1514865773474996 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 4 Oct 2016 14:07:11 -0400 Subject: [PATCH 07/13] check for existence of attribute before calling it to break gently --- onvif/modules/lib/ONVIF/Deserializer/MessageParser.pm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/onvif/modules/lib/ONVIF/Deserializer/MessageParser.pm b/onvif/modules/lib/ONVIF/Deserializer/MessageParser.pm index b0ce6f0fd..0e4b6dcfb 100644 --- a/onvif/modules/lib/ONVIF/Deserializer/MessageParser.pm +++ b/onvif/modules/lib/ONVIF/Deserializer/MessageParser.pm @@ -272,7 +272,11 @@ sub _initialize { # $_method =~s{\.}{__}xg; $_method =~s{\-}{_}xg; - $list->[-1]->$_method( $current ); + if ( $list->[-1]->can( $_method ) ) { + $list->[-1]->$_method( $current ); + } else { + print ( "ERror " . $list->[-1] . " cannot $_method\n" ); + } $current = pop @$list; # step up in object hierarchy From 09c5e3012a36dff5b505fe58630d6da5564fdff2 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 4 Oct 2016 14:09:32 -0400 Subject: [PATCH 08/13] username and password don't actually have to be specified --- web/skins/classic/views/onvifprobe.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/web/skins/classic/views/onvifprobe.php b/web/skins/classic/views/onvifprobe.php index c183d010c..7f8d6ed7f 100644 --- a/web/skins/classic/views/onvifprobe.php +++ b/web/skins/classic/views/onvifprobe.php @@ -222,9 +222,10 @@ if( !isset($_REQUEST['step']) || ($_REQUEST['step'] == "1")) { } else if($_REQUEST['step'] == "2") { - if ( empty($_REQUEST['probe']) || empty($_REQUEST['username']) || - empty($_REQUEST['password']) ) - Fatal("Internal error. Please re-open this page."); + if ( empty($_REQUEST['probe']) ) + Fatal("No probe passed in request. Please go back and try again."); +#|| empty($_REQUEST['username']) || + #empty($_REQUEST['password']) ) $probe = unserialize(base64_decode($_REQUEST['probe'])); foreach ( $probe as $name=>$value ) From 84a18926d878923e5f31b4f5154f38856b97212e Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 4 Oct 2016 14:28:03 -0400 Subject: [PATCH 09/13] password is not required, set it to '' to quiet warnings --- onvif/scripts/zmonvif-probe.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onvif/scripts/zmonvif-probe.pl b/onvif/scripts/zmonvif-probe.pl index 37ca56834..94b5fdd19 100755 --- a/onvif/scripts/zmonvif-probe.pl +++ b/onvif/scripts/zmonvif-probe.pl @@ -374,7 +374,7 @@ else { my $url_svc_device = shift; $soap_version = shift; my $username = shift; - my $password = shift; + my $password = @_ ? shift : ''; $client = ONVIF::Client->new( { 'url_svc_device' => $url_svc_device, From e7eab488c971decff0857590a312c0d4137aa99d Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 4 Oct 2016 14:28:30 -0400 Subject: [PATCH 10/13] password is not required, set it to '' to quiet warnings --- onvif/scripts/zmonvif-probe.pl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/onvif/scripts/zmonvif-probe.pl b/onvif/scripts/zmonvif-probe.pl index 94b5fdd19..c1f39c020 100755 --- a/onvif/scripts/zmonvif-probe.pl +++ b/onvif/scripts/zmonvif-probe.pl @@ -373,8 +373,9 @@ else { # all other actions need URI and credentials my $url_svc_device = shift; $soap_version = shift; - my $username = shift; + my $username = @_ ? shift : ''; my $password = @_ ? shift : ''; +print "Username: $username"; $client = ONVIF::Client->new( { 'url_svc_device' => $url_svc_device, From 7561dc00eab13939d719f65cc5252aacc7c389d4 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 4 Oct 2016 14:33:13 -0400 Subject: [PATCH 11/13] be explici about which unnamed array we are access for getopts. Default username and password to '' --- onvif/scripts/zmonvif-probe.pl | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/onvif/scripts/zmonvif-probe.pl b/onvif/scripts/zmonvif-probe.pl index c1f39c020..a5aee9574 100755 --- a/onvif/scripts/zmonvif-probe.pl +++ b/onvif/scripts/zmonvif-probe.pl @@ -371,11 +371,10 @@ if($action eq "probe") { } else { # all other actions need URI and credentials - my $url_svc_device = shift; - $soap_version = shift; - my $username = @_ ? shift : ''; - my $password = @_ ? shift : ''; -print "Username: $username"; + my $url_svc_device = shift @ARGV; + $soap_version = shift @ARGV; + my $username = @ARGV ? shift @ARGV : ''; + my $password = @ARGV ? shift @ARGV: ''; $client = ONVIF::Client->new( { 'url_svc_device' => $url_svc_device, From 6814bcc7917c3a7b7ef6f6f19cbe3d51784be345 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 4 Oct 2016 14:33:38 -0400 Subject: [PATCH 12/13] add NoDetectProfiles instead of reusing NoDetectedCameras --- web/lang/en_gb.php | 1 + 1 file changed, 1 insertion(+) diff --git a/web/lang/en_gb.php b/web/lang/en_gb.php index 3d07ad733..dc4398dae 100644 --- a/web/lang/en_gb.php +++ b/web/lang/en_gb.php @@ -519,6 +519,7 @@ $SLANG = array( 'NewUser' => 'New User', 'Next' => 'Next', 'NoDetectedCameras' => 'No Detected Cameras', + 'NoDetectedProfiles' => 'No Detected Profiles', 'NoFramesRecorded' => 'There are no frames recorded for this event', 'NoGroup' => 'No Group', 'NoneAvailable' => 'None available', From ac2486564771837291a66fe706029bc04fd0d226 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 4 Oct 2016 14:33:51 -0400 Subject: [PATCH 13/13] add NoDetectProfiles instead of reusing NoDetectedCameras --- web/skins/classic/views/onvifprobe.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/web/skins/classic/views/onvifprobe.php b/web/skins/classic/views/onvifprobe.php index 7f8d6ed7f..01e52ee38 100644 --- a/web/skins/classic/views/onvifprobe.php +++ b/web/skins/classic/views/onvifprobe.php @@ -27,6 +27,8 @@ if ( !canEdit( 'Monitors' ) ) $cameras = array(); $cameras[0] = translate('ChooseDetectedCamera'); +$profiles = array(); +$profiles[0] = translate('ChooseDetectedProfile'); function execONVIF( $cmd ) { $shell_command = escapeshellcmd(ZM_PATH_BIN . "/zmonvif-probe.pl $cmd"); @@ -255,11 +257,11 @@ else if($_REQUEST['step'] == "2") $monitor['Path'] = $profile['Path']; // $sourceDesc = htmlspecialchars(serialize($monitor)); $sourceDesc = base64_encode(serialize($monitor)); - $cameras[$sourceDesc] = $sourceString; + $profiles[$sourceDesc] = $sourceString; } - if ( count($cameras) <= 0 ) - $cameras[0] = translate('NoDetectedCameras'); + if ( count($profiles) <= 0 ) + $profiles[0] = translate('NoDetectedProfiles'); ?> @@ -276,7 +278,7 @@ else if($_REQUEST['step'] == "2")

- +