Merge branch 'master' of github.com:zoneminder/ZoneMinder

This commit is contained in:
Isaac Connor 2020-06-05 13:04:22 -04:00
commit 30f90dbae4
26 changed files with 508 additions and 391 deletions

View File

@ -445,6 +445,10 @@ CREATE TABLE `Monitors` (
`Enabled` tinyint(3) unsigned NOT NULL default '1', `Enabled` tinyint(3) unsigned NOT NULL default '1',
`LinkedMonitors` varchar(255), `LinkedMonitors` varchar(255),
`Triggers` set('X10') NOT NULL default '', `Triggers` set('X10') NOT NULL default '',
`ONVIF_URL` VARCHAR(255) NOT NULL DEFAULT '',
`ONVIF_Username` VARCHAR(64) NOT NULL DEFAULT '',
`ONVIF_Password` VARCHAR(64) NOT NULL DEFAULT '',
`ONVIF_Options` VARCHAR(64) NOT NULL DEFAULT '',
`Device` tinytext NOT NULL default '', `Device` tinytext NOT NULL default '',
`Channel` tinyint(3) unsigned NOT NULL default '0', `Channel` tinyint(3) unsigned NOT NULL default '0',
`Format` int(10) unsigned NOT NULL default '0', `Format` int(10) unsigned NOT NULL default '0',

View File

@ -116,7 +116,7 @@ sub getParam {
} elsif ( defined($default) ) { } elsif ( defined($default) ) {
return $default; return $default;
} }
Fatal("Missing mandatory parameter '$name'"); Error("Missing mandatory parameter '$name'");
} }
sub executeCommand { sub executeCommand {

View File

@ -210,7 +210,7 @@ sub initialise( @ ) {
if ( my $logFile = $this->getTargettedEnv('LOG_FILE') ) { if ( my $logFile = $this->getTargettedEnv('LOG_FILE') ) {
$tempLogFile = $logFile; $tempLogFile = $logFile;
} }
($tempLogFile) = $tempLogFile =~ /^([\w\.\/]+)$/; ($tempLogFile) = $tempLogFile =~ /^([_\-\w\.\/]+)$/;
my $tempLevel = INFO; my $tempLevel = INFO;
my $tempTermLevel = $this->{termLevel}; my $tempTermLevel = $this->{termLevel};
@ -456,9 +456,9 @@ sub fileLevel {
if ( defined($fileLevel) ) { if ( defined($fileLevel) ) {
$fileLevel = $this->limit($fileLevel); $fileLevel = $this->limit($fileLevel);
# The filename might have changed, so always close and re-open # The filename might have changed, so always close and re-open
$this->closeFile() if ( $this->{fileLevel} > NOLOG ); $this->closeFile() if $this->{fileLevel} > NOLOG;
$this->{fileLevel} = $fileLevel; $this->{fileLevel} = $fileLevel;
$this->openFile() if ( $this->{fileLevel} > NOLOG ); $this->openFile() if $this->{fileLevel} > NOLOG;
} }
return $this->{fileLevel}; return $this->{fileLevel};
} }
@ -499,6 +499,7 @@ sub logFile {
sub openFile { sub openFile {
my $this = shift; my $this = shift;
if ( open($LOGFILE, '>>', $this->{logFile}) ) { if ( open($LOGFILE, '>>', $this->{logFile}) ) {
$LOGFILE->autoflush() if $this->{autoFlush}; $LOGFILE->autoflush() if $this->{autoFlush};
@ -519,7 +520,6 @@ sub openFile {
} }
sub closeFile { sub closeFile {
#my $this = shift;
close($LOGFILE) if fileno($LOGFILE); close($LOGFILE) if fileno($LOGFILE);
} }

View File

@ -39,12 +39,10 @@ our %EXPORT_TAGS = (
); );
push( @{$EXPORT_TAGS{all}}, @{$EXPORT_TAGS{$_}} ) foreach keys %EXPORT_TAGS; push( @{$EXPORT_TAGS{all}}, @{$EXPORT_TAGS{$_}} ) foreach keys %EXPORT_TAGS;
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); our @EXPORT_OK = ( @{ $EXPORT_TAGS{all} } );
our @EXPORT = qw(); our @EXPORT = qw();
our $VERSION = $ZoneMinder::Base::VERSION;
use Data::UUID; use Data::UUID;
use vars qw( $verbose $soap_version ); use vars qw( $verbose $soap_version );
@ -60,6 +58,9 @@ require WSDiscovery::TransportUDP;
sub deserialize_message { sub deserialize_message {
my ($wsdl_client, $response) = @_; my ($wsdl_client, $response) = @_;
if ( ! $response ) {
return;
}
# copied and adapted from SOAP::WSDL::Client # copied and adapted from SOAP::WSDL::Client
@ -74,20 +75,16 @@ sub deserialize_message {
} }
# set class resolver if serializer supports it # set class resolver if serializer supports it
$deserializer->set_class_resolver( $wsdl_client->get_class_resolver() ) $deserializer->set_class_resolver( $wsdl_client->get_class_resolver() )
if ( $deserializer->can('set_class_resolver') ); if $deserializer->can('set_class_resolver');
# Try deserializing response - there may be some, # Try deserializing response - there may be some,
# even if transport did not succeed (got a 500 response) # even if transport did not succeed (got a 500 response)
if ( ! $response ) {
return;
}
# as our faults are false, returning a success marker is the only # as our faults are false, returning a success marker is the only
# reliable way of determining whether the deserializer succeeded. # reliable way of determining whether the deserializer succeeded.
# Custom deserializers may return an empty list, or undef, # Custom deserializers may return an empty list, or undef,
# and $@ is not guaranteed to be undefined. # and $@ is not guaranteed to be undefined.
my ($success, $result_body, $result_header) = eval { my ($success, $result_body, $result_header) = eval {
(1, $deserializer->deserialize( $response )); (1, $deserializer->deserialize($response));
}; };
if ( defined $success ) { if ( defined $success ) {
return wantarray return wantarray
@ -110,10 +107,7 @@ sub interpret_messages {
my @results; my @results;
foreach my $response ( @responses ) { foreach my $response ( @responses ) {
print "Received message:\n" . $response . "\n" if $verbose;
if ( $verbose ) {
print "Received message:\n" . $response . "\n";
}
my $result = deserialize_message($svc_discover, $response); my $result = deserialize_message($svc_discover, $response);
if ( not $result ) { if ( not $result ) {
@ -151,17 +145,16 @@ sub interpret_messages {
foreach my $scope (split ' ', $scopes) { foreach my $scope (split ' ', $scopes) {
if ( $scope =~ m|onvif://www\.onvif\.org/(.+)/(.*)| ) { if ( $scope =~ m|onvif://www\.onvif\.org/(.+)/(.*)| ) {
my ($attr, $value) = ($1,$2); my ($attr, $value) = ($1,$2);
if ( 0 < $count ++) { print ', ' if 0 < $count ++;
print ', ';
}
print $attr . '=\'' . $value . '\''; print $attr . '=\'' . $value . '\'';
$scopes{$attr} = $value; $scopes{$attr} = $value;
} }
} }
print ")\n"; print ")\n";
push @results, { xaddr=>$xaddr, push @results, {
xaddr => $xaddr,
soap_version => $svc_discover->get_soap_version(), soap_version => $svc_discover->get_soap_version(),
scopes => \%scopes, scopes => \%scopes,
}; };
} }
return @results; return @results;
@ -170,7 +163,7 @@ sub interpret_messages {
# functions # functions
sub discover { sub discover {
my ( $soap_version, $net_interface ) = @_; my ($soap_versions, $net_interface) = @_;
my @results; my @results;
## collect all responses ## collect all responses
@ -185,7 +178,7 @@ sub discover {
my $uuid_gen = Data::UUID->new(); my $uuid_gen = Data::UUID->new();
foreach my $version ( $soap_version ? ( $soap_version ) : ( '1.1', '1.2') ) { foreach my $version ( $soap_versions ? ( split(',',$soap_versions) ) : ( '1.1', '1.2') ) {
my %services; my %services;
print "Probing for SOAP $version\n" if $verbose; print "Probing for SOAP $version\n" if $verbose;
@ -195,7 +188,7 @@ sub discover {
$svc_discover->set_soap_version($version); $svc_discover->set_soap_version($version);
if ( $net_interface ) { if ( $net_interface ) {
my $transport = $svc_discover->get_transport(); my $transport = $svc_discover->get_transport();
print "Setting net interface for $transport to $net_interface\n"; print "Setting net interface for $transport to $net_interface\n" if $verbose;
$transport->set_net_interface($net_interface); $transport->set_net_interface($net_interface);
} }
@ -203,7 +196,15 @@ sub discover {
my $result = $svc_discover->ProbeOp( my $result = $svc_discover->ProbeOp(
{ # WSDiscovery::Types::ProbeType { # WSDiscovery::Types::ProbeType
Types => 'http://www.onvif.org/ver10/network/wsdl:NetworkVideoTransmitter http://www.onvif.org/ver10/device/wsdl:Device', # QNameListType (
($version eq '1.1') ?
(
Types => 'http://www.onvif.org/ver10/network/wsdl:NetworkVideoTransmitter http://www.onvif.org/ver10/device/wsdl:Device', # QNameListType
) : (
xmlattr => { 'xmlns:dn' => 'http://www.onvif.org/ver10/network/wsdl', },
)
),
Types => 'dn:NetworkVideoTransmitter', # QNameListType
Scopes => { value => '' }, Scopes => { value => '' },
}, },
WSDiscovery10::Elements::Header->new({ WSDiscovery10::Elements::Header->new({
@ -215,22 +216,23 @@ sub discover {
print $result."\n" if $verbose; print $result."\n" if $verbose;
push @results, interpret_messages($svc_discover, \%services, @responses); push @results, interpret_messages($svc_discover, \%services, @responses);
@responses = ();
} # end foreach version } # end foreach version
return @results; return @results;
} # end sub discover } # end sub discover
sub profiles { sub profiles {
my ( $client ) = @_; my ($client) = @_;
my $media = $client->get_endpoint('media'); my $media = $client->get_endpoint('media');
if ( ! $media ) { if ( !$media ) {
print "No media endpoint for client.\n"; print "No media endpoint for client.\n";
return; return;
} }
my $result = $media->GetProfiles( { } ,, ); my $result = $media->GetProfiles( { } ,, );
if ( ! $result ) { if ( !$result ) {
print "No result from GetProfiles.\n"; print "No result from GetProfiles.\n";
return; return;
} }
@ -244,7 +246,7 @@ sub profiles {
print "No profiles returned from get_Profiles\n"; print "No profiles returned from get_Profiles\n";
return; return;
} }
print "Number of profiles found: " .(scalar @Profiles)."\n" if $verbose; print 'Number of profiles found: ' .(scalar @Profiles)."\n" if $verbose;
my @profiles; my @profiles;
foreach my $profile ( @Profiles ) { foreach my $profile ( @Profiles ) {
@ -339,12 +341,12 @@ sub move {
} # end sub move } # end sub move
sub metadata { sub metadata {
my ( $client ) = @_; my ($client) = @_;
my $media = $client->get_endpoint('media'); my $media = $client->get_endpoint('media');
die 'No media endpoint.' if !$media; die 'No media endpoint.' if !$media;
my $result = $media->GetMetadataConfigurations( { } ,, ); my $result = $media->GetMetadataConfigurations( { } ,, );
if ( ! $result ) { if ( !$result ) {
print "No MetaDataConfigurations\n" if $verbose; print "No MetaDataConfigurations\n" if $verbose;
} else { } else {
print $result . "\n"; print $result . "\n";
@ -363,8 +365,6 @@ sub metadata {
} }
1; 1;
__END__ __END__

View File

@ -41,7 +41,7 @@ my $OPTIONS = 'v';
sub HELP_MESSAGE { sub HELP_MESSAGE {
my ($fh, $pkg, $ver, $opts) = @_; my ($fh, $pkg, $ver, $opts) = @_;
print $fh "Usage: " . __FILE__ . " [-v] probe <soap version> <network interface>\n"; print $fh "Usage: " . __FILE__ . " [-v] probe <soap versions> <network interface>\n";
print $fh " " . __FILE__ . " [-v] <command> <device URI> <soap version> <user> <password>\n"; print $fh " " . __FILE__ . " [-v] <command> <device URI> <soap version> <user> <password>\n";
print $fh <<EOF print $fh <<EOF
Commands are: Commands are:
@ -53,7 +53,7 @@ sub HELP_MESSAGE {
-v - increase verbosity -v - increase verbosity
Device access parameters (for all commands but 'probe'): Device access parameters (for all commands but 'probe'):
device URL - the ONVIF Device service URL device URL - the ONVIF Device service URL
soap version - SOAP version (1.1 or 1.2) soap versions - SOAP versions (1.1 or 1.2 or 1.1,1.2)
user - username of a user with access to the device user - username of a user with access to the device
password - password for the user password - password for the user
EOF EOF
@ -69,7 +69,7 @@ if ( !getopts($OPTIONS) ) {
my $action = shift; my $action = shift;
if ( ! defined $action ) { if ( !defined $action ) {
HELP_MESSAGE(\*STDOUT); HELP_MESSAGE(\*STDOUT);
exit(1); exit(1);
} }

View File

@ -121,6 +121,8 @@ GetOptions(
my $dbh = zmDbConnect(undef, { mysql_multi_statements=>1 } ); my $dbh = zmDbConnect(undef, { mysql_multi_statements=>1 } );
$Config{ZM_DB_USER} = $dbUser; $Config{ZM_DB_USER} = $dbUser;
$Config{ZM_DB_PASS} = $dbPass; $Config{ZM_DB_PASS} = $dbPass;
# we escape dbpass with single quotes so that $ in the password has no effect, but dbpass could have a ' in it.
$dbPass =~ s/'/\\'/g;
if ( ! ($check || $freshen || $rename || $zoneFix || $migrateEvents || $version) ) { if ( ! ($check || $freshen || $rename || $zoneFix || $migrateEvents || $version) ) {
if ( $Config{ZM_DYN_DB_VERSION} ) { if ( $Config{ZM_DYN_DB_VERSION} ) {
@ -384,21 +386,22 @@ if ( $version ) {
my $command = 'mysqldump'; my $command = 'mysqldump';
if ( defined($portOrSocket) ) { if ( defined($portOrSocket) ) {
if ( $portOrSocket =~ /^\// ) { if ( $portOrSocket =~ /^\// ) {
$command .= " -S".$portOrSocket; $command .= ' -S'.$portOrSocket;
} else { } else {
$command .= " -h".$host." -P".$portOrSocket; $command .= ' -h'.$host.' -P'.$portOrSocket;
} }
} else { } else {
$command .= " -h".$host; $command .= ' -h'.$host;
} }
if ( $dbUser ) { if ( $dbUser ) {
$command .= ' -u'.$dbUser; $command .= ' -u'.$dbUser;
$command .= ' -p"'.$dbPass.'"' if $dbPass; $command .= ' -p\''.$dbPass.'\'' if $dbPass;
} }
my $backup = "@ZM_TMPDIR@/".$Config{ZM_DB_NAME}."-".$version.".dump"; my $backup = '@ZM_TMPDIR@/'.$Config{ZM_DB_NAME}.'-'.$version.'.dump';
$command .= " --add-drop-table --databases ".$Config{ZM_DB_NAME}." > ".$backup; $command .= ' --add-drop-table --databases '.$Config{ZM_DB_NAME}.' > '.$backup;
print( "Creating backup to $backup. This may take several minutes.\n" ); print("Creating backup to $backup. This may take several minutes.\n");
print( "Executing '$command'\n" ) if ( logDebugging() ); print("Executing '$command'\n") if logDebugging();
($command) = $command =~ /(.*)/; # detaint
my $output = qx($command); my $output = qx($command);
my $status = $? >> 8; my $status = $? >> 8;
if ( $status || logDebugging() ) { if ( $status || logDebugging() ) {
@ -982,7 +985,7 @@ sub patchDB {
} }
if ( $dbUser ) { if ( $dbUser ) {
$command .= ' -u'.$dbUser; $command .= ' -u'.$dbUser;
$command .= ' -p"'.$dbPass.'"' if $dbPass; $command .= ' -p\''.$dbPass.'\'' if $dbPass;
} }
$command .= ' '.$Config{ZM_DB_NAME}.' < '; $command .= ' '.$Config{ZM_DB_NAME}.' < ';
if ( $updateDir ) { if ( $updateDir ) {
@ -993,6 +996,7 @@ sub patchDB {
$command .= '/zm_update-'.$version.'.sql'; $command .= '/zm_update-'.$version.'.sql';
print("Executing '$command'\n") if logDebugging(); print("Executing '$command'\n") if logDebugging();
($command) = $command =~ /(.*)/; # detaint
my $output = qx($command); my $output = qx($command);
my $status = $? >> 8; my $status = $? >> 8;
if ( $status || logDebugging() ) { if ( $status || logDebugging() ) {

View File

@ -81,10 +81,11 @@ bool zmDbConnect() {
void zmDbClose() { void zmDbClose() {
if ( zmDbConnected ) { if ( zmDbConnected ) {
db_mutex.lock(); db_mutex.lock();
mysql_close( &dbconn ); mysql_close(&dbconn);
// mysql_init() call implicitly mysql_library_init() but // mysql_init() call implicitly mysql_library_init() but
// mysql_close() does not call mysql_library_end() // mysql_close() does not call mysql_library_end()
mysql_library_end(); // We get segfaults and a hang when we call this. So just don't.
//mysql_library_end();
zmDbConnected = false; zmDbConnected = false;
db_mutex.unlock(); db_mutex.unlock();
} }
@ -96,6 +97,12 @@ MYSQL_RES * zmDbFetch(const char * query) {
return NULL; return NULL;
} }
db_mutex.lock(); db_mutex.lock();
// Might have been disconnected while we waited for the lock
if ( !zmDbConnected ) {
db_mutex.unlock();
Error("Not connected.");
return NULL;
}
if ( mysql_query(&dbconn, query) ) { if ( mysql_query(&dbconn, query) ) {
db_mutex.unlock(); db_mutex.unlock();

View File

@ -714,11 +714,9 @@ bool EventStream::sendFrame(int delta_us) {
Image *image = NULL; Image *image = NULL;
if ( filepath[0] ) { if ( filepath[0] ) {
Debug(1, "Loading image");
image = new Image(filepath); image = new Image(filepath);
} else if ( ffmpeg_input ) { } else if ( ffmpeg_input ) {
// Get the frame from the mp4 input // Get the frame from the mp4 input
Debug(1,"Getting frame from ffmpeg");
FrameData *frame_data = &event_data->frames[curr_frame_id-1]; FrameData *frame_data = &event_data->frames[curr_frame_id-1];
AVFrame *frame = ffmpeg_input->get_frame( AVFrame *frame = ffmpeg_input->get_frame(
ffmpeg_input->get_video_stream_id(), ffmpeg_input->get_video_stream_id(),
@ -767,7 +765,11 @@ Debug(1, "Loading image");
switch ( type ) { switch ( type ) {
case STREAM_JPEG : case STREAM_JPEG :
send_image->EncodeJpeg(img_buffer, &img_buffer_size); if ( send_image->EncodeJpeg(img_buffer, &img_buffer_size) ) {
Debug(1, "encoded JPEG");
} else {
// Failed
}
break; break;
case STREAM_ZIP : case STREAM_ZIP :
#if HAVE_ZLIB_H #if HAVE_ZLIB_H
@ -787,10 +789,6 @@ Debug(1, "Loading image");
Fatal("Unexpected frame type %d", type); Fatal("Unexpected frame type %d", type);
break; break;
} }
if ( send_image != image ) {
delete send_image;
send_image = NULL;
}
delete image; delete image;
image = NULL; image = NULL;
} // end if send_raw or not } // end if send_raw or not
@ -815,7 +813,7 @@ Debug(1, "Loading image");
fprintf(stdout, "Content-Length: %d\r\n\r\n", (int)filestat.st_size); fprintf(stdout, "Content-Length: %d\r\n\r\n", (int)filestat.st_size);
if ( zm_sendfile(fileno(stdout), fileno(fdj), 0, (int)filestat.st_size) != (int)filestat.st_size ) { if ( zm_sendfile(fileno(stdout), fileno(fdj), 0, (int)filestat.st_size) != (int)filestat.st_size ) {
/* sendfile() failed, use standard way instead */ /* sendfile() failed, use standard way instead */
img_buffer_size = fread( img_buffer, 1, sizeof(temp_img_buffer), fdj ); img_buffer_size = fread(img_buffer, 1, sizeof(temp_img_buffer), fdj);
if ( fwrite(img_buffer, img_buffer_size, 1, stdout) != 1 ) { if ( fwrite(img_buffer, img_buffer_size, 1, stdout) != 1 ) {
fclose(fdj); /* Close the file handle */ fclose(fdj); /* Close the file handle */
Error("Unable to send raw frame %u: %s", curr_frame_id, strerror(errno)); Error("Unable to send raw frame %u: %s", curr_frame_id, strerror(errno));

View File

@ -975,10 +975,12 @@ int FfmpegCamera::CaptureAndRecord(
Error("Error count over 100, going to close and re-open stream"); Error("Error count over 100, going to close and re-open stream");
return -1; return -1;
} }
#if HAVE_LIBAVUTIL_HWCONTEXT_H
if ( (ret == AVERROR_INVALIDDATA ) && (hw_pix_fmt != AV_PIX_FMT_NONE) ) { if ( (ret == AVERROR_INVALIDDATA ) && (hw_pix_fmt != AV_PIX_FMT_NONE) ) {
use_hwaccel = false; use_hwaccel = false;
return -1; return -1;
} }
#endif
} }
zm_av_packet_unref(&packet); zm_av_packet_unref(&packet);
continue; continue;

View File

@ -1905,11 +1905,11 @@ void Image::MaskPrivacy( const unsigned char *p_bitmask, const Rgb pixel_colour
/* RGB32 compatible: complete */ /* RGB32 compatible: complete */
void Image::Annotate( const char *p_text, const Coord &coord, const unsigned int size, const Rgb fg_colour, const Rgb bg_colour ) void Image::Annotate( const char *p_text, const Coord &coord, const unsigned int size, const Rgb fg_colour, const Rgb bg_colour )
{ {
strncpy( text, p_text, sizeof(text)-1 ); strncpy(text, p_text, sizeof(text)-1);
unsigned int index = 0; unsigned int index = 0;
unsigned int line_no = 0; unsigned int line_no = 0;
unsigned int text_len = strlen( text ); unsigned int text_len = strlen(text);
unsigned int line_len = 0; unsigned int line_len = 0;
const char *line = text; const char *line = text;
@ -1928,10 +1928,10 @@ void Image::Annotate( const char *p_text, const Coord &coord, const unsigned int
const bool bg_trans = (bg_colour == RGB_TRANSPARENT); const bool bg_trans = (bg_colour == RGB_TRANSPARENT);
int zm_text_bitmask = 0x80; int zm_text_bitmask = 0x80;
if (size == 2) if ( size == 2 )
zm_text_bitmask = 0x8000; zm_text_bitmask = 0x8000;
while ( (index < text_len) && (line_len = strcspn( line, "\n" )) ) { while ( (index < text_len) && (line_len = strcspn(line, "\n")) ) {
unsigned int line_width = line_len * ZM_CHAR_WIDTH * size; unsigned int line_width = line_len * ZM_CHAR_WIDTH * size;
@ -1967,10 +1967,19 @@ void Image::Annotate( const char *p_text, const Coord &coord, const unsigned int
unsigned char *temp_ptr = ptr; unsigned char *temp_ptr = ptr;
for ( unsigned int x = lo_line_x, c = 0; x < hi_line_x && c < line_len; c++ ) { for ( unsigned int x = lo_line_x, c = 0; x < hi_line_x && c < line_len; c++ ) {
int f; int f;
if (size == 2) if ( size == 2 ) {
if ( (line[c] * ZM_CHAR_HEIGHT * size) + r > sizeof(bigfontdata) ) {
Warning("Unsupported character %c in %s", line[c], line);
continue;
}
f = bigfontdata[(line[c] * ZM_CHAR_HEIGHT * size) + r]; f = bigfontdata[(line[c] * ZM_CHAR_HEIGHT * size) + r];
else } else {
if ( (line[c] * ZM_CHAR_HEIGHT) + r > sizeof(fontdata) ) {
Warning("Unsupported character %c in %s", line[c], line);
continue;
}
f = fontdata[(line[c] * ZM_CHAR_HEIGHT) + r]; f = fontdata[(line[c] * ZM_CHAR_HEIGHT) + r];
}
for ( unsigned int i = 0; i < (ZM_CHAR_WIDTH * size) && x < hi_line_x; i++, x++, temp_ptr++ ) { for ( unsigned int i = 0; i < (ZM_CHAR_WIDTH * size) && x < hi_line_x; i++, x++, temp_ptr++ ) {
if ( f & (zm_text_bitmask >> i) ) { if ( f & (zm_text_bitmask >> i) ) {
if ( !fg_trans ) if ( !fg_trans )
@ -1989,10 +1998,19 @@ void Image::Annotate( const char *p_text, const Coord &coord, const unsigned int
unsigned char *temp_ptr = ptr; unsigned char *temp_ptr = ptr;
for ( unsigned int x = lo_line_x, c = 0; x < hi_line_x && c < line_len; c++ ) { for ( unsigned int x = lo_line_x, c = 0; x < hi_line_x && c < line_len; c++ ) {
int f; int f;
if (size == 2) if ( size == 2 ) {
if ( (line[c] * ZM_CHAR_HEIGHT * size) + r > sizeof(bigfontdata) ) {
Warning("Unsupported character %c in %s", line[c], line);
continue;
}
f = bigfontdata[(line[c] * ZM_CHAR_HEIGHT * size) + r]; f = bigfontdata[(line[c] * ZM_CHAR_HEIGHT * size) + r];
else } else {
if ( (line[c] * ZM_CHAR_HEIGHT) + r > sizeof(fontdata) ) {
Warning("Unsupported character %c in %s", line[c], line);
continue;
}
f = fontdata[(line[c] * ZM_CHAR_HEIGHT) + r]; f = fontdata[(line[c] * ZM_CHAR_HEIGHT) + r];
}
for ( unsigned int i = 0; i < (ZM_CHAR_WIDTH * size) && x < hi_line_x; i++, x++, temp_ptr += colours ) { for ( unsigned int i = 0; i < (ZM_CHAR_WIDTH * size) && x < hi_line_x; i++, x++, temp_ptr += colours ) {
if ( f & (zm_text_bitmask >> i) ) { if ( f & (zm_text_bitmask >> i) ) {
if ( !fg_trans ) { if ( !fg_trans ) {
@ -2016,10 +2034,19 @@ void Image::Annotate( const char *p_text, const Coord &coord, const unsigned int
Rgb* temp_ptr = (Rgb*)ptr; Rgb* temp_ptr = (Rgb*)ptr;
for ( unsigned int x = lo_line_x, c = 0; x < hi_line_x && c < line_len; c++ ) { for ( unsigned int x = lo_line_x, c = 0; x < hi_line_x && c < line_len; c++ ) {
int f; int f;
if (size == 2) if ( size == 2 ) {
if ( (line[c] * ZM_CHAR_HEIGHT * size) + r > sizeof(bigfontdata) ) {
Warning("Unsupported character %c in %s", line[c], line);
continue;
}
f = bigfontdata[(line[c] * ZM_CHAR_HEIGHT * size) + r]; f = bigfontdata[(line[c] * ZM_CHAR_HEIGHT * size) + r];
else } else {
if ( (line[c] * ZM_CHAR_HEIGHT) + r > sizeof(fontdata) ) {
Warning("Unsupported character %c in %s", line[c], line);
continue;
}
f = fontdata[(line[c] * ZM_CHAR_HEIGHT) + r]; f = fontdata[(line[c] * ZM_CHAR_HEIGHT) + r];
}
for ( unsigned int i = 0; i < (ZM_CHAR_WIDTH * size) && x < hi_line_x; i++, x++, temp_ptr++ ) { for ( unsigned int i = 0; i < (ZM_CHAR_WIDTH * size) && x < hi_line_x; i++, x++, temp_ptr++ ) {
if ( f & (zm_text_bitmask >> i) ) { if ( f & (zm_text_bitmask >> i) ) {
if ( !fg_trans ) { if ( !fg_trans ) {

View File

@ -552,14 +552,18 @@ bool Monitor::connect() {
snprintf(mem_file, sizeof(mem_file), "%s/zm.mmap.%d", staticConfig.PATH_MAP.c_str(), id); snprintf(mem_file, sizeof(mem_file), "%s/zm.mmap.%d", staticConfig.PATH_MAP.c_str(), id);
map_fd = open(mem_file, O_RDWR|O_CREAT, (mode_t)0600); map_fd = open(mem_file, O_RDWR|O_CREAT, (mode_t)0600);
if ( map_fd < 0 ) { if ( map_fd < 0 ) {
Fatal("Can't open memory map file %s, probably not enough space free: %s", mem_file, strerror(errno)); Error("Can't open memory map file %s, probably not enough space free: %s", mem_file, strerror(errno));
return false;
} else { } else {
Debug(3, "Success opening mmap file at (%s)", mem_file); Debug(3, "Success opening mmap file at (%s)", mem_file);
} }
struct stat map_stat; struct stat map_stat;
if ( fstat(map_fd, &map_stat) < 0 ) if ( fstat(map_fd, &map_stat) < 0 ) {
Fatal("Can't stat memory map file %s: %s, is the zmc process for this monitor running?", mem_file, strerror(errno)); Error("Can't stat memory map file %s: %s, is the zmc process for this monitor running?", mem_file, strerror(errno));
close(map_fd);
return false;
}
if ( map_stat.st_size != mem_size ) { if ( map_stat.st_size != mem_size ) {
if ( purpose == CAPTURE ) { if ( purpose == CAPTURE ) {

View File

@ -196,12 +196,11 @@ bool ValidateAccess(User *user, int mon_id, int function) {
return allowed; return allowed;
} }
int exit_zmu(int exit_code) { void exit_zmu(int exit_code) {
logTerm(); logTerm();
zmDbClose(); zmDbClose();
exit(exit_code); exit(exit_code);
return exit_code;
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
@ -477,228 +476,233 @@ int main(int argc, char *argv[]) {
if ( mon_id > 0 ) { if ( mon_id > 0 ) {
Monitor *monitor = Monitor::Load(mon_id, function&(ZMU_QUERY|ZMU_ZONES), Monitor::QUERY); Monitor *monitor = Monitor::Load(mon_id, function&(ZMU_QUERY|ZMU_ZONES), Monitor::QUERY);
if ( monitor ) { if ( !monitor ) {
if ( verbose ) { Error("Unable to load monitor %d", mon_id);
printf("Monitor %d(%s)\n", monitor->Id(), monitor->Name()); exit_zmu(-1);
} } // end if ! MONITOR
if ( !monitor->connect() ) {
Error("Can't connect to capture daemon: %d %s", monitor->Id(), monitor->Name());
exit_zmu(-1);
}
char separator = ' '; if ( verbose ) {
bool have_output = false; printf("Monitor %d(%s)\n", monitor->Id(), monitor->Name());
if ( function & ZMU_STATE ) { }
Monitor::State state = monitor->GetState(); if ( !monitor->connect() ) {
if ( verbose ) { Error("Can't connect to capture daemon: %d %s", monitor->Id(), monitor->Name());
printf("Current state: %s\n", state==Monitor::ALARM?"Alarm":(state==Monitor::ALERT?"Alert":"Idle"));
} else {
if ( have_output ) fputc(separator, stdout);
printf("%d", state);
have_output = true;
}
}
if ( function & ZMU_TIME ) {
struct timeval timestamp = monitor->GetTimestamp(image_idx);
if ( verbose ) {
char timestamp_str[64] = "None";
if ( timestamp.tv_sec )
strftime(timestamp_str, sizeof(timestamp_str), "%Y-%m-%d %H:%M:%S", localtime(&timestamp.tv_sec));
if ( image_idx == -1 )
printf("Time of last image capture: %s.%02ld\n", timestamp_str, timestamp.tv_usec/10000);
else
printf("Time of image %d capture: %s.%02ld\n", image_idx, timestamp_str, timestamp.tv_usec/10000);
} else {
if ( have_output ) fputc(separator, stdout);
printf("%ld.%02ld", timestamp.tv_sec, timestamp.tv_usec/10000);
have_output = true;
}
}
if ( function & ZMU_READ_IDX ) {
if ( verbose )
printf("Last read index: %d\n", monitor->GetLastReadIndex());
else {
if ( have_output ) fputc(separator, stdout);
printf("%d", monitor->GetLastReadIndex());
have_output = true;
}
}
if ( function & ZMU_WRITE_IDX ) {
if ( verbose ) {
printf("Last write index: %d\n", monitor->GetLastWriteIndex());
} else {
if ( have_output ) fputc(separator, stdout);
printf("%d", monitor->GetLastWriteIndex());
have_output = true;
}
}
if ( function & ZMU_EVENT ) {
if ( verbose ) {
printf("Last event id: %" PRIu64 "\n", monitor->GetLastEventId());
} else {
if ( have_output ) fputc(separator, stdout);
printf("%" PRIu64, monitor->GetLastEventId());
have_output = true;
}
}
if ( function & ZMU_FPS ) {
if ( verbose ) {
printf("Current capture rate: %.2f frames per second\n", monitor->GetFPS());
} else {
if ( have_output ) fputc(separator, stdout);
printf("%.2f", monitor->GetFPS());
have_output = true;
}
}
if ( function & ZMU_IMAGE ) {
if ( verbose ) {
if ( image_idx == -1 )
printf("Dumping last image captured to Monitor%d.jpg", monitor->Id());
else
printf("Dumping buffer image %d to Monitor%d.jpg", image_idx, monitor->Id());
if ( scale != -1 )
printf(", scaling by %d%%", scale);
printf("\n");
}
monitor->GetImage(image_idx, scale>0?scale:100);
}
if ( function & ZMU_ZONES ) {
if ( verbose )
printf("Dumping zone image to Zones%d.jpg\n", monitor->Id());
monitor->DumpZoneImage(zoneString);
}
if ( function & ZMU_ALARM ) {
if ( monitor->GetFunction() == Monitor::Function::MONITOR ) {
printf("A Monitor in monitor mode cannot handle alarms. Please use NoDect\n");
} else {
Monitor::State state = monitor->GetState();
if ( verbose ) {
printf("Forcing alarm on current state: %s, event %" PRIu64 "\n",
state==Monitor::ALARM?"Alarm":(state==Monitor::ALERT?"Alert":"Idle"),
monitor->GetLastEventId()
);
}
monitor->ForceAlarmOn(config.forced_alarm_score, "Forced Web");
while ( ((state = monitor->GetState()) != Monitor::ALARM) && !zm_terminate ) {
// Wait for monitor to notice.
usleep(1000);
}
printf("Alarmed event id: %" PRIu64 "\n", monitor->GetLastEventId());
} // end if ! MONITOR
}
if ( function & ZMU_NOALARM ) {
if ( verbose )
printf("Forcing alarm off\n");
monitor->ForceAlarmOff();
}
if ( function & ZMU_CANCEL ) {
if ( verbose )
printf("Cancelling forced alarm on/off\n");
monitor->CancelForced();
}
if ( function & ZMU_RELOAD ) {
if ( verbose )
printf("Reloading monitor settings\n");
monitor->actionReload();
}
if ( function & ZMU_ENABLE ) {
if ( verbose )
printf("Enabling event generation\n");
monitor->actionEnable();
}
if ( function & ZMU_DISABLE ) {
if ( verbose )
printf("Disabling event generation\n");
monitor->actionDisable();
}
if ( function & ZMU_SUSPEND ) {
if ( verbose )
printf("Suspending event generation\n");
monitor->actionSuspend();
}
if ( function & ZMU_RESUME ) {
if ( verbose )
printf("Resuming event generation\n");
monitor->actionResume();
}
if ( function & ZMU_QUERY ) {
char monString[16382] = "";
monitor->DumpSettings(monString, verbose);
printf("%s\n", monString);
}
if ( function & ZMU_BRIGHTNESS ) {
if ( verbose ) {
if ( brightness >= 0 )
printf("New brightness: %d\n", monitor->actionBrightness(brightness));
else
printf("Current brightness: %d\n", monitor->actionBrightness());
} else {
if ( have_output ) fputc(separator, stdout);
if ( brightness >= 0 )
printf("%d", monitor->actionBrightness(brightness));
else
printf("%d", monitor->actionBrightness());
have_output = true;
}
}
if ( function & ZMU_CONTRAST ) {
if ( verbose ) {
if ( contrast >= 0 )
printf("New brightness: %d\n", monitor->actionContrast(contrast));
else
printf("Current contrast: %d\n", monitor->actionContrast());
} else {
if ( have_output ) fputc(separator, stdout);
if ( contrast >= 0 )
printf("%d", monitor->actionContrast(contrast));
else
printf("%d", monitor->actionContrast());
have_output = true;
}
}
if ( function & ZMU_HUE ) {
if ( verbose ) {
if ( hue >= 0 )
printf("New hue: %d\n", monitor->actionHue(hue));
else
printf("Current hue: %d\n", monitor->actionHue());
} else {
if ( have_output ) fputc(separator, stdout);
if ( hue >= 0 )
printf("%d", monitor->actionHue(hue));
else
printf("%d", monitor->actionHue());
have_output = true;
}
}
if ( function & ZMU_COLOUR ) {
if ( verbose ) {
if ( colour >= 0 )
printf("New colour: %d\n", monitor->actionColour(colour));
else
printf("Current colour: %d\n", monitor->actionColour());
} else {
if ( have_output ) fputc(separator, stdout);
if ( colour >= 0 )
printf("%d", monitor->actionColour(colour));
else
printf("%d", monitor->actionColour());
have_output = true;
}
}
if ( have_output ) {
printf("\n");
}
if ( !function ) {
Usage();
}
delete monitor; delete monitor;
} else { monitor = NULL;
Error("Invalid monitor id %d", mon_id);
exit_zmu(-1); exit_zmu(-1);
} }
} else {
char separator = ' ';
bool have_output = false;
if ( function & ZMU_STATE ) {
Monitor::State state = monitor->GetState();
if ( verbose ) {
printf("Current state: %s\n", state==Monitor::ALARM?"Alarm":(state==Monitor::ALERT?"Alert":"Idle"));
} else {
if ( have_output ) fputc(separator, stdout);
printf("%d", state);
have_output = true;
}
}
if ( function & ZMU_TIME ) {
struct timeval timestamp = monitor->GetTimestamp(image_idx);
if ( verbose ) {
char timestamp_str[64] = "None";
if ( timestamp.tv_sec )
strftime(timestamp_str, sizeof(timestamp_str), "%Y-%m-%d %H:%M:%S", localtime(&timestamp.tv_sec));
if ( image_idx == -1 )
printf("Time of last image capture: %s.%02ld\n", timestamp_str, timestamp.tv_usec/10000);
else
printf("Time of image %d capture: %s.%02ld\n", image_idx, timestamp_str, timestamp.tv_usec/10000);
} else {
if ( have_output ) fputc(separator, stdout);
printf("%ld.%02ld", timestamp.tv_sec, timestamp.tv_usec/10000);
have_output = true;
}
}
if ( function & ZMU_READ_IDX ) {
if ( verbose )
printf("Last read index: %d\n", monitor->GetLastReadIndex());
else {
if ( have_output ) fputc(separator, stdout);
printf("%d", monitor->GetLastReadIndex());
have_output = true;
}
}
if ( function & ZMU_WRITE_IDX ) {
if ( verbose ) {
printf("Last write index: %d\n", monitor->GetLastWriteIndex());
} else {
if ( have_output ) fputc(separator, stdout);
printf("%d", monitor->GetLastWriteIndex());
have_output = true;
}
}
if ( function & ZMU_EVENT ) {
if ( verbose ) {
printf("Last event id: %" PRIu64 "\n", monitor->GetLastEventId());
} else {
if ( have_output ) fputc(separator, stdout);
printf("%" PRIu64, monitor->GetLastEventId());
have_output = true;
}
}
if ( function & ZMU_FPS ) {
if ( verbose ) {
printf("Current capture rate: %.2f frames per second\n", monitor->GetFPS());
} else {
if ( have_output ) fputc(separator, stdout);
printf("%.2f", monitor->GetFPS());
have_output = true;
}
}
if ( function & ZMU_IMAGE ) {
if ( verbose ) {
if ( image_idx == -1 )
printf("Dumping last image captured to Monitor%d.jpg", monitor->Id());
else
printf("Dumping buffer image %d to Monitor%d.jpg", image_idx, monitor->Id());
if ( scale != -1 )
printf(", scaling by %d%%", scale);
printf("\n");
}
monitor->GetImage(image_idx, scale>0?scale:100);
}
if ( function & ZMU_ZONES ) {
if ( verbose )
printf("Dumping zone image to Zones%d.jpg\n", monitor->Id());
monitor->DumpZoneImage(zoneString);
}
if ( function & ZMU_ALARM ) {
if ( monitor->GetFunction() == Monitor::Function::MONITOR ) {
printf("A Monitor in monitor mode cannot handle alarms. Please use NoDect\n");
} else {
Monitor::State state = monitor->GetState();
if ( verbose ) {
printf("Forcing alarm on current state: %s, event %" PRIu64 "\n",
state==Monitor::ALARM?"Alarm":(state==Monitor::ALERT?"Alert":"Idle"),
monitor->GetLastEventId()
);
}
monitor->ForceAlarmOn(config.forced_alarm_score, "Forced Web");
while ( ((state = monitor->GetState()) != Monitor::ALARM) && !zm_terminate ) {
// Wait for monitor to notice.
usleep(1000);
}
printf("Alarmed event id: %" PRIu64 "\n", monitor->GetLastEventId());
}
} // end if ZMU_ALARM
if ( function & ZMU_NOALARM ) {
if ( verbose )
printf("Forcing alarm off\n");
monitor->ForceAlarmOff();
}
if ( function & ZMU_CANCEL ) {
if ( verbose )
printf("Cancelling forced alarm on/off\n");
monitor->CancelForced();
}
if ( function & ZMU_RELOAD ) {
if ( verbose )
printf("Reloading monitor settings\n");
monitor->actionReload();
}
if ( function & ZMU_ENABLE ) {
if ( verbose )
printf("Enabling event generation\n");
monitor->actionEnable();
}
if ( function & ZMU_DISABLE ) {
if ( verbose )
printf("Disabling event generation\n");
monitor->actionDisable();
}
if ( function & ZMU_SUSPEND ) {
if ( verbose )
printf("Suspending event generation\n");
monitor->actionSuspend();
}
if ( function & ZMU_RESUME ) {
if ( verbose )
printf("Resuming event generation\n");
monitor->actionResume();
}
if ( function & ZMU_QUERY ) {
char monString[16382] = "";
monitor->DumpSettings(monString, verbose);
printf("%s\n", monString);
}
if ( function & ZMU_BRIGHTNESS ) {
if ( verbose ) {
if ( brightness >= 0 )
printf("New brightness: %d\n", monitor->actionBrightness(brightness));
else
printf("Current brightness: %d\n", monitor->actionBrightness());
} else {
if ( have_output ) fputc(separator, stdout);
if ( brightness >= 0 )
printf("%d", monitor->actionBrightness(brightness));
else
printf("%d", monitor->actionBrightness());
have_output = true;
}
}
if ( function & ZMU_CONTRAST ) {
if ( verbose ) {
if ( contrast >= 0 )
printf("New brightness: %d\n", monitor->actionContrast(contrast));
else
printf("Current contrast: %d\n", monitor->actionContrast());
} else {
if ( have_output ) fputc(separator, stdout);
if ( contrast >= 0 )
printf("%d", monitor->actionContrast(contrast));
else
printf("%d", monitor->actionContrast());
have_output = true;
}
}
if ( function & ZMU_HUE ) {
if ( verbose ) {
if ( hue >= 0 )
printf("New hue: %d\n", monitor->actionHue(hue));
else
printf("Current hue: %d\n", monitor->actionHue());
} else {
if ( have_output ) fputc(separator, stdout);
if ( hue >= 0 )
printf("%d", monitor->actionHue(hue));
else
printf("%d", monitor->actionHue());
have_output = true;
}
}
if ( function & ZMU_COLOUR ) {
if ( verbose ) {
if ( colour >= 0 )
printf("New colour: %d\n", monitor->actionColour(colour));
else
printf("Current colour: %d\n", monitor->actionColour());
} else {
if ( have_output ) fputc(separator, stdout);
if ( colour >= 0 )
printf("%d", monitor->actionColour(colour));
else
printf("%d", monitor->actionColour());
have_output = true;
}
}
if ( have_output ) {
printf("\n");
}
if ( !function ) {
Usage();
}
delete monitor;
monitor = NULL;
} else { // non monitor functions
if ( function & ZMU_QUERY ) { if ( function & ZMU_QUERY ) {
#if ZM_HAS_V4L #if ZM_HAS_V4L
char vidString[0x10000] = ""; char vidString[0x10000] = "";
@ -770,8 +774,9 @@ int main(int argc, char *argv[]) {
} // end foreach row } // end foreach row
mysql_free_result(result); mysql_free_result(result);
} // end if function && ZMU_LIST } // end if function && ZMU_LIST
} } // end if monitor id or not
delete user; delete user;
return exit_zmu(0); exit_zmu(0);
} return 0;
} // end int main()

View File

@ -1,5 +1,5 @@
<?php <?php
ini_set('display_errors','0'); ini_set('display_errors', '0');
if ( empty($_REQUEST['id']) && empty($_REQUEST['eids']) ) { if ( empty($_REQUEST['id']) && empty($_REQUEST['eids']) ) {
ajaxError('No event id(s) supplied'); ajaxError('No event id(s) supplied');
@ -28,8 +28,8 @@ if ( canView('Events') ) {
$ok = true; $ok = true;
break; break;
case 'deleteVideo' : case 'deleteVideo' :
unlink( $videoFiles[$_REQUEST['id']] ); unlink($videoFiles[$_REQUEST['id']]);
unset( $videoFiles[$_REQUEST['id']] ); unset($videoFiles[$_REQUEST['id']]);
ajaxResponse(); ajaxResponse();
break; break;
case 'export' : case 'export' :
@ -110,7 +110,11 @@ if ( canView('Events') ) {
false#,#Compress false#,#Compress
#$exportStructure #$exportStructure
) ) { ) ) {
ajaxResponse(array('exportFile'=>$exportFile,'exportFormat'=>$exportFormat, 'connkey'=>(isset($_REQUEST['connkey'])?$_REQUEST['connkey']:''))); ajaxResponse(array(
'exportFile'=>$exportFile,
'exportFormat'=>$exportFormat,
'connkey'=>(isset($_REQUEST['connkey'])?$_REQUEST['connkey']:'')
));
} else { } else {
ajaxError('Export Failed'); ajaxError('Export Failed');
} }
@ -145,7 +149,7 @@ if ( canEdit('Events') ) {
break; break;
case 'delete' : case 'delete' :
$Event = new ZM\Event($_REQUEST['id']); $Event = new ZM\Event($_REQUEST['id']);
if ( ! $Event->Id() ) { if ( !$Event->Id() ) {
ajaxResponse(array('refreshEvent'=>false, 'refreshParent'=>true, 'message'=> 'Event not found.')); ajaxResponse(array('refreshEvent'=>false, 'refreshParent'=>true, 'message'=> 'Event not found.'));
} else { } else {
$Event->delete(); $Event->delete();

View File

@ -1499,15 +1499,15 @@ function getLoad() {
function getDiskPercent($path = ZM_DIR_EVENTS) { function getDiskPercent($path = ZM_DIR_EVENTS) {
$total = disk_total_space($path); $total = disk_total_space($path);
if ( $total === false ) { if ( $total === false ) {
Error('disk_total_space returned false. Verify the web account user has access to ' . $path); ZM\Error('disk_total_space returned false. Verify the web account user has access to ' . $path);
return 0; return 0;
} elseif ( $total == 0 ) { } elseif ( $total == 0 ) {
Error('disk_total_space indicates the following path has a filesystem size of zero bytes ' . $path); ZM\Error('disk_total_space indicates the following path has a filesystem size of zero bytes ' . $path);
return 100; return 100;
} }
$free = disk_free_space($path); $free = disk_free_space($path);
if ( $free === false ) { if ( $free === false ) {
Error('disk_free_space returned false. Verify the web account user has access to ' . $path); ZM\Error('disk_free_space returned false. Verify the web account user has access to ' . $path);
} }
$space = round((($total - $free) / $total) * 100); $space = round((($total - $free) / $total) * 100);
return $space; return $space;
@ -2063,7 +2063,7 @@ function logState() {
if ( $count['Level'] <= ZM\Logger::PANIC ) if ( $count['Level'] <= ZM\Logger::PANIC )
$count['Level'] = ZM\Logger::FATAL; $count['Level'] = ZM\Logger::FATAL;
if ( !($levelCount = $levelCounts[$count['Level']]) ) { if ( !($levelCount = $levelCounts[$count['Level']]) ) {
Error('Unexpected Log level '.$count['Level']); ZM\Error('Unexpected Log level '.$count['Level']);
next; next;
} }
if ( $levelCount[1] && $count['LevelCount'] >= $levelCount[1] ) { if ( $levelCount[1] && $count['LevelCount'] >= $levelCount[1] ) {

View File

@ -423,13 +423,16 @@ if ( (!ZM_OPT_USE_AUTH) or $user ) {
if ( count($storage_areas) <= 4 ) if ( count($storage_areas) <= 4 )
echo implode(', ', array_map($func, $storage_areas)); echo implode(', ', array_map($func, $storage_areas));
$shm_percent = getDiskPercent(ZM_PATH_MAP); $shm_percent = getDiskPercent(ZM_PATH_MAP);
$shm_total_space = disk_total_space(ZM_PATH_MAP);
$shm_used = $shm_total_space - disk_free_space(ZM_PATH_MAP);
$class = ''; $class = '';
if ( $shm_percent > 98 ) { if ( $shm_percent > 98 ) {
$class = 'error'; $class = 'error';
} else if ( $shm_percent > 90 ) { } else if ( $shm_percent > 90 ) {
$class = 'warning'; $class = 'warning';
} }
echo ' <span class="'.$class.'">'.ZM_PATH_MAP.': '.$shm_percent.'%</span>'; echo ' <span class="'.$class.'" title="' . human_filesize($shm_used).' of '.human_filesize($shm_total_space).'">'.ZM_PATH_MAP.': '.$shm_percent.'%</span>';
?></li> ?></li>
</ul> </ul>
<?php if ( defined('ZM_WEB_CONSOLE_BANNER') and ZM_WEB_CONSOLE_BANNER != '' ) { ?> <?php if ( defined('ZM_WEB_CONSOLE_BANNER') and ZM_WEB_CONSOLE_BANNER != '' ) { ?>

View File

@ -205,6 +205,7 @@ getBodyTopHTML();
<?php <?php
ob_start(); ob_start();
?> ?>
<div class="table-responsive">
<table class="table table-striped table-hover table-condensed consoleTable"> <table class="table table-striped table-hover table-condensed consoleTable">
<thead class="thead-highlight"> <thead class="thead-highlight">
<tr> <tr>
@ -390,9 +391,10 @@ for( $monitor_i = 0; $monitor_i < count($displayMonitors); $monitor_i += 1 ) {
<?php if ( canEdit('Monitors') ) { ?> <?php if ( canEdit('Monitors') ) { ?>
<td class="colMark"></td> <td class="colMark"></td>
<?php } ?> <?php } ?>
</tr> </tr>
</tfoot> </tfoot>
</table> </table>
</div>
</div> </div>
</form> </form>
<?php xhtmlFooter() ?> <?php xhtmlFooter() ?>

View File

@ -285,7 +285,7 @@ function getCmdResponse( respObj, respText ) {
} }
} // end if haev a new auth hash } // end if haev a new auth hash
streamCmdTimer = streamQuery.delay( streamTimeout ); //Timeout is refresh rate for progressBox and time display streamCmdTimer = streamQuery.delay(streamTimeout); //Timeout is refresh rate for progressBox and time display
} }
var streamReq = new Request.JSON( { var streamReq = new Request.JSON( {

View File

@ -212,7 +212,8 @@ function Monitor(monitorData) {
* @param {*} element - the event data passed by onchange callback * @param {*} element - the event data passed by onchange callback
*/ */
function selectLayout(element) { function selectLayout(element) {
layout = $j(element).val(); var ddm = $j('#zmMontageLayout');
layout = ddm.val();
if ( layout_id = parseInt(layout) ) { if ( layout_id = parseInt(layout) ) {
layout = layouts[layout]; layout = layouts[layout];
@ -231,6 +232,7 @@ function selectLayout(element) {
if ( layout.Positions['default'] ) { if ( layout.Positions['default'] ) {
styles = layout.Positions['default']; styles = layout.Positions['default'];
for ( style in styles ) { for ( style in styles ) {
console.log("Applying " + style + ' ' + styles[style]);
monitor_frame.css(style, styles[style]); monitor_frame.css(style, styles[style]);
} }
} else { } else {
@ -241,7 +243,6 @@ function selectLayout(element) {
styles = layout.Positions['mId'+monitor.id]; styles = layout.Positions['mId'+monitor.id];
for ( style in styles ) { for ( style in styles ) {
monitor_frame.css(style, styles[style]); monitor_frame.css(style, styles[style]);
console.log("Applying " + style + ' : ' + styles[style]);
} }
} else { } else {
console.log("No Monitor styles to apply"); console.log("No Monitor styles to apply");

View File

@ -33,3 +33,7 @@ function configureButtons(element) {
form.saveBtn.disabled = (form.probe.selectedIndex==0); form.saveBtn.disabled = (form.probe.selectedIndex==0);
} }
} }
function changeInterface(element) {
gotoStep1(element);
}

View File

@ -36,14 +36,14 @@ function createEventHtml(zm_event, frame) {
return eventHtml; return eventHtml;
} }
function showEventDetail( eventHtml ) { function showEventDetail(eventHtml) {
$('instruction').addClass( 'hidden' ); $('instruction').addClass('hidden');
$('eventData').empty(); $('eventData').empty();
$('eventData').adopt( eventHtml ); $('eventData').adopt(eventHtml);
$('eventData').removeClass( 'hidden' ); $('eventData').removeClass('hidden');
} }
function eventDataResponse( respObj, respText ) { function eventDataResponse(respObj, respText) {
var zm_event = respObj.event; var zm_event = respObj.event;
if ( !zm_event ) { if ( !zm_event ) {
console.log('Null event'); console.log('Null event');
@ -179,7 +179,10 @@ function loadEventImage( imagePath, eid, fid, width, height, fps, videoName, dur
eventData.addEvent('click', showEvent.pass()); eventData.addEvent('click', showEvent.pass());
} }
function tlZoomBounds( minTime, maxTime ) { function tlZoomBounds(event) {
var target = event.target;
var minTime = target.getAttribute('data-zoom-min-time');
var maxTime = target.getAttribute('data-zoom-max-time');
location.replace('?view='+currentView+filterQuery+'&minTime='+minTime+'&maxTime='+maxTime); location.replace('?view='+currentView+filterQuery+'&minTime='+minTime+'&maxTime='+maxTime);
} }
@ -194,14 +197,20 @@ function tlPanRight() {
location.replace('?view='+currentView+filterQuery+'&midTime='+maxTime+'&range='+range); location.replace('?view='+currentView+filterQuery+'&midTime='+maxTime+'&range='+range);
} }
window.addEventListener("DOMContentLoaded", function() { window.addEventListener('DOMContentLoaded', function() {
document.querySelectorAll("div.event").forEach(function(el) { // These look like the code in skin.js, but that code doesn't select for divs.
document.querySelectorAll('div.event').forEach(function(el) {
el.onclick = window[el.getAttribute('data-on-click-this')].bind(el, el); el.onclick = window[el.getAttribute('data-on-click-this')].bind(el, el);
el.onmouseover = window[el.getAttribute('data-on-mouseover-this')].bind(el, el); el.onmouseover = window[el.getAttribute('data-on-mouseover-this')].bind(el, el);
}); });
document.querySelectorAll("div.activity").forEach(function(el) { document.querySelectorAll('div.activity').forEach(function(el) {
el.onclick = window[el.getAttribute('data-on-click-this')].bind(el, el); el.onclick = window[el.getAttribute('data-on-click-this')].bind(el, el);
el.onmouseover = window[el.getAttribute('data-on-mouseover-this')].bind(el, el); el.onmouseover = window[el.getAttribute('data-on-mouseover-this')].bind(el, el);
}); });
document.querySelectorAll('div.zoom').forEach(function(el) {
el.onclick = function(ev) {
window[el.getAttribute('data-on-click')](ev);
};
});
}); });

View File

@ -695,12 +695,11 @@ function getControlResponse(respObj, respText) {
function controlCmd(event) { function controlCmd(event) {
button = event.target; button = event.target;
control = button.getAttribute('value'); control = button.getAttribute('value');
xtell = button.getAttribute('xtell'); xtell = button.getAttribute('data-xtell');
ytell = button.getAttribute('ytell'); ytell = button.getAttribute('data-ytell');
var locParms = ''; var locParms = '';
if ( event && (xtell || ytell) ) { if ( event && (xtell || ytell) ) {
console.log(event);
var target = event.target; var target = event.target;
var coords = $(target).getCoordinates(); var coords = $(target).getCoordinates();
@ -849,7 +848,7 @@ function initPage() {
if ( refreshApplet && appletRefreshTime ) { if ( refreshApplet && appletRefreshTime ) {
appletRefresh.delay(appletRefreshTime*1000); appletRefresh.delay(appletRefreshTime*1000);
} }
if ( scale == 'auto' ) changeScale(); if ( scale == '0' || scale == 'auto' ) changeScale();
if ( window.history.length == 1 ) { if ( window.history.length == 1 ) {
$j('#closeControl').html(''); $j('#closeControl').html('');
} }

View File

@ -169,12 +169,6 @@ if ( !ZM_PCRE )
// Currently unsupported // Currently unsupported
unset($httpMethods['jpegTags']); unset($httpMethods['jpegTags']);
$configTypes = array(
'None' => translate('None'),
'ONVIF' => 'ONVIF',
'PSIA' => 'PSIA',
);
if ( ZM_HAS_V4L1 ) { if ( ZM_HAS_V4L1 ) {
$v4l1DeviceFormats = array( $v4l1DeviceFormats = array(
'PAL' => 0, 'PAL' => 0,
@ -327,31 +321,31 @@ $orientations = array(
); );
$deinterlaceopts = array( $deinterlaceopts = array(
'Disabled' => 0x00000000, 0x00000000 => 'Disabled',
'Four field motion adaptive - Soft' => 0x00001E04, /* 30 change */ 0x00001E04 => 'Four field motion adaptive - Soft', /* 30 change */
'Four field motion adaptive - Medium' => 0x00001404, /* 20 change */ 0x00001404 => 'Four field motion adaptive - Medium', /* 20 change */
'Four field motion adaptive - Hard' => 0x00000A04, /* 10 change */ 0x00000A04 => 'Four field motion adaptive - Hard', /* 10 change */
'Discard' => 0x00000001, 0x00000001 => 'Discard',
'Linear' => 0x00000002, 0x00000002 => 'Linear',
'Blend' => 0x00000003, 0x00000003 => 'Blend',
'Blend (25%)' => 0x00000205 0x00000205 => 'Blend (25%)',
); );
$deinterlaceopts_v4l2 = array( $deinterlaceopts_v4l2 = array(
'Disabled' => 0x00000000, 0x00000000 => 'Disabled',
'Four field motion adaptive - Soft' => 0x00001E04, /* 30 change */ 0x00001E04 => 'Four field motion adaptive - Soft', /* 30 change */
'Four field motion adaptive - Medium' => 0x00001404, /* 20 change */ 0x00001404 => 'Four field motion adaptive - Medium', /* 20 change */
'Four field motion adaptive - Hard' => 0x00000A04, /* 10 change */ 0x00000A04 => 'Four field motion adaptive - Hard', /* 10 change */
'Discard' => 0x00000001, 0x00000001 => 'Discard',
'Linear' => 0x00000002, 0x00000002 => 'Linear',
'Blend' => 0x00000003, 0x00000003 => 'Blend',
'Blend (25%)' => 0x00000205, 0x00000205 => 'Blend (25%)',
'V4L2: Capture top field only' => 0x02000000, 0x02000000 => 'V4L2: Capture top field only',
'V4L2: Capture bottom field only' => 0x03000000, 0x03000000 => 'V4L2: Capture bottom field only',
'V4L2: Alternate fields (Bob)' => 0x07000000, 0x07000000 => 'V4L2: Alternate fields (Bob)',
'V4L2: Progressive' => 0x01000000, 0x01000000 => 'V4L2: Progressive',
'V4L2: Interlaced' => 0x04000000 0x04000000 => 'V4L2: Interlaced',
); );
$fastblendopts = array( $fastblendopts = array(
'No blending' => 0, 'No blending' => 0,
@ -419,7 +413,7 @@ if ( canEdit('Monitors') ) {
$tabs = array(); $tabs = array();
$tabs['general'] = translate('General'); $tabs['general'] = translate('General');
$tabs['source'] = translate('Source'); $tabs['source'] = translate('Source');
$tabs["config"] = translate('MetaConfig'); $tabs['onvif'] = translate('ONVIF');
if ( $monitor->Type() != 'WebSite' ) { if ( $monitor->Type() != 'WebSite' ) {
$tabs['storage'] = translate('Storage'); $tabs['storage'] = translate('Storage');
$tabs['timestamp'] = translate('Timestamp'); $tabs['timestamp'] = translate('Timestamp');
@ -498,7 +492,7 @@ if ( ZM_HAS_V4L && ($tab != 'source' || $monitor->Type() != 'Local') ) {
if ( $tab != 'onvif' ) { if ( $tab != 'onvif' ) {
?> ?>
<input type="hidden" name="newMonitor[ONVIF_URL]" value="<?php echo validHtmlStr($monitor->ONVIF_URL()) ?>"/> <input type="hidden" name="newMonitor[ONVIF_URL]" value="<?php echo validHtmlStr($monitor->ONVIF_URL()) ?>"/>
<input type="hidden" name="newMonitor[ONVIF_Username]" value="<?php echo validHtmlStr($monitor->ONVIF_User()) ?>"/> <input type="hidden" name="newMonitor[ONVIF_Username]" value="<?php echo validHtmlStr($monitor->ONVIF_Username()) ?>"/>
<input type="hidden" name="newMonitor[ONVIF_Password]" value="<?php echo validHtmlStr($monitor->ONVIF_Password()) ?>"/> <input type="hidden" name="newMonitor[ONVIF_Password]" value="<?php echo validHtmlStr($monitor->ONVIF_Password()) ?>"/>
<input type="hidden" name="newMonitor[ONVIF_Options]" value="<?php echo validHtmlStr($monitor->ONVIF_Options()) ?>"/> <input type="hidden" name="newMonitor[ONVIF_Options]" value="<?php echo validHtmlStr($monitor->ONVIF_Options()) ?>"/>
<?php <?php

View File

@ -39,16 +39,18 @@ function probeV4L() {
} }
$monitors = array(); $monitors = array();
foreach ( dbFetchAll("SELECT Id, Name, Device,Channel FROM Monitors WHERE Type = 'Local' ORDER BY Device, Channel" ) as $monitor ) foreach ( dbFetchAll("SELECT Id, Name, Device, Channel FROM Monitors WHERE Type = 'Local' ORDER BY Device, Channel" ) as $monitor )
$monitors[$monitor['Device'].':'.$monitor['Channel']] = $monitor; $monitors[$monitor['Device'].':'.$monitor['Channel']] = $monitor;
$devices = array(); $devices = array();
$preferredStandards = array('PAL', 'NTSC'); $preferredStandards = array('PAL', 'NTSC');
$preferredFormats = array('BGR3', 'RGB3', 'YUYV', 'UYVY', 'JPEG', 'MJPG', '422P', 'YU12', 'GREY'); $preferredFormats = array('BGR3', 'RGB3', 'YUYV', 'UYVY', 'JPEG', 'MJPG', '422P', 'YU12', 'GREY');
foreach ( $output as $line ) { foreach ( $output as $line ) {
if ( !preg_match('/^d:([^|]+).*S:([^|]*).*F:([^|]+).*I:(\d+)\|(.+)$/', $line, $deviceMatches) ) if ( !preg_match('/^d:([^|]+).*S:([^|]*).*F:([^|]+).*I:(\d+)\|(.+)$/', $line, $deviceMatches) ) {
ZM\Fatal("Can't parse command output '$line'"); ZM\Error("Can't parse command output '$line'");
$standards = explode('/',$deviceMatches[2]); continue;
}
$standards = explode('/', $deviceMatches[2]);
$preferredStandard = false; $preferredStandard = false;
foreach ( $preferredStandards as $standard ) { foreach ( $preferredStandards as $standard ) {
if ( in_array( $standard, $standards ) ) { if ( in_array( $standard, $standards ) ) {
@ -56,7 +58,7 @@ function probeV4L() {
break; break;
} }
} }
$formats = explode('/',$deviceMatches[3]); $formats = explode('/', $deviceMatches[3]);
$preferredFormat = false; $preferredFormat = false;
foreach ( $preferredFormats as $format ) { foreach ( $preferredFormats as $format ) {
if ( in_array($format, $formats) ) { if ( in_array($format, $formats) ) {
@ -73,8 +75,10 @@ function probeV4L() {
); );
$inputs = array(); $inputs = array();
for ( $i = 0; $i < $deviceMatches[4]; $i++ ) { for ( $i = 0; $i < $deviceMatches[4]; $i++ ) {
if ( !preg_match('/i'.$i.':([^|]+)\|i'.$i.'T:([^|]+)\|/', $deviceMatches[5], $inputMatches) ) if ( !preg_match('/i'.$i.':([^|]+)\|i'.$i.'T:([^|]+)\|/', $deviceMatches[5], $inputMatches) ) {
ZM\Fatal("Can't parse input '".$deviceMatches[5]."'"); ZM\Error("Can't parse input '".$deviceMatches[5]."'");
continue;
}
if ( $inputMatches[2] == 'Camera' ) { if ( $inputMatches[2] == 'Camera' ) {
$input = array( $input = array(
'index' => $i, 'index' => $i,
@ -101,7 +105,7 @@ function probeV4L() {
$inputMonitor['Colours'] = 1; $inputMonitor['Colours'] = 1;
$inputMonitor['SignalCheckColour'] = '#000023'; $inputMonitor['SignalCheckColour'] = '#000023';
} }
$inputDesc = base64_encode(serialize($inputMonitor)); $inputDesc = base64_encode(json_encode($inputMonitor));
$inputString = $deviceMatches[1].', chan '.$i.($input['free']?(' - '.translate('Available')):(' ('.$monitors[$input['id']]['Name'].')')); $inputString = $deviceMatches[1].', chan '.$i.($input['free']?(' - '.translate('Available')):(' ('.$monitors[$input['id']]['Name'].')'));
$inputs[] = $input; $inputs[] = $input;
$cameras[$inputDesc] = $inputString; $cameras[$inputDesc] = $inputString;
@ -288,7 +292,7 @@ function probeNetwork() {
if ( isset($macBases[$macRoot]) ) { if ( isset($macBases[$macRoot]) ) {
$macBase = $macBases[$macRoot]; $macBase = $macBases[$macRoot];
$camera = call_user_func($macBase['probeFunc'], $ip); $camera = call_user_func($macBase['probeFunc'], $ip);
$sourceDesc = base64_encode(serialize($camera['monitor'])); $sourceDesc = base64_encode(json_encode($camera['monitor']));
$sourceString = $camera['model'].' @ '.$host; $sourceString = $camera['model'].' @ '.$host;
if ( isset($monitors[$ip]) ) { if ( isset($monitors[$ip]) ) {
$monitor = $monitors[$ip]; $monitor = $monitors[$ip];
@ -330,7 +334,7 @@ xhtmlHeaders(__FILE__, translate('MonitorProbe') );
</p> </p>
<p> <p>
<label for="probe"><?php echo translate('DetectedCameras') ?></label> <label for="probe"><?php echo translate('DetectedCameras') ?></label>
<?php echo buildSelect('probe', $cameras, 'configureButtons(this)'); ?> <?php echo htmlSelect('probe', $cameras, null, array('data-on-change-this'=>'configureButtons(this)')); ?>
</p> </p>
<div id="contentButtons"> <div id="contentButtons">
<button type="button" name="saveBtn" value="Save" data-on-click-this="submitCamera" disabled="disabled"> <button type="button" name="saveBtn" value="Save" data-on-click-this="submitCamera" disabled="disabled">

View File

@ -75,10 +75,8 @@ zm_session_start();
$layout_id = ''; $layout_id = '';
if ( isset($_COOKIE['zmMontageLayout']) ) { if ( isset($_COOKIE['zmMontageLayout']) ) {
$layout_id = $_SESSION['zmMontageLayout'] = $_COOKIE['zmMontageLayout']; $layout_id = $_SESSION['zmMontageLayout'] = $_COOKIE['zmMontageLayout'];
ZM\Logger::Debug("Using layout $layout_id");
} elseif ( isset($_SESSION['zmMontageLayout']) ) { } elseif ( isset($_SESSION['zmMontageLayout']) ) {
$layout_id = $_SESSION['zmMontageLayout']; $layout_id = $_SESSION['zmMontageLayout'];
ZM\Logger::Debug("Using layout $layout_id from session");
} }
$options = array(); $options = array();
@ -88,7 +86,7 @@ if ( $layout_id and is_numeric($layout_id) and isset($layoutsById[$layout_id]) )
$Layout = $layoutsById[$layout_id]; $Layout = $layoutsById[$layout_id];
$Positions = json_decode($Layout->Positions(), true); $Positions = json_decode($Layout->Positions(), true);
} else { } else {
ZM\Logger::Debug("Layout not found"); ZM\Logger::Debug('Layout not found');
} }
if ( $Layout and ( $Layout->Name() != 'Freeform' ) ) { if ( $Layout and ( $Layout->Name() != 'Freeform' ) ) {
// Use layout instead of other options // Use layout instead of other options
@ -185,7 +183,7 @@ if ( $showZones ) {
</span> </span>
<span id="layoutControl"> <span id="layoutControl">
<label for="layout"><?php echo translate('Layout') ?></label> <label for="layout"><?php echo translate('Layout') ?></label>
<?php echo htmlSelect('zmMontageLayout', $layoutsById, $layout_id, array('data-on-change-this'=>'selectLayout')); ?> <?php echo htmlSelect('zmMontageLayout', $layoutsById, $layout_id, array('data-on-change'=>'selectLayout')); ?>
</span> </span>
<input type="hidden" name="Positions"/> <input type="hidden" name="Positions"/>
<button type="button" id="EditLayout" data-on-click-this="edit_layout"><?php echo translate('EditLayout') ?></button> <button type="button" id="EditLayout" data-on-click-this="edit_layout"><?php echo translate('EditLayout') ?></button>

View File

@ -29,16 +29,17 @@ $cameras[0] = translate('ChooseDetectedCamera');
$profiles = array(); $profiles = array();
$profiles[0] = translate('ChooseDetectedProfile'); $profiles[0] = translate('ChooseDetectedProfile');
function execONVIF( $cmd ) { function execONVIF($cmd) {
$shell_command = escapeshellcmd(ZM_PATH_BIN . "/zmonvif-probe.pl $cmd"); $shell_command = escapeshellcmd(ZM_PATH_BIN . "/zmonvif-probe.pl $cmd");
exec( $shell_command, $output, $status ); exec($shell_command, $output, $status);
if ( $status ) { if ( $status ) {
$html_output = implode( '<br/>', $output ); $html_output = implode('<br/>', $output);
ZM\Fatal( "Unable to probe network cameras, status is '$status'. Output was:<br/><br/> ZM\Error("Unable to probe network cameras, status is '$status'. Output was:
$html_output<br/><br/> $html_output
Please the following command from a command line for more information:<br/><br/>$shell_command" Please run the following command from a command line for more information:
$shell_command"
); );
} else { } else {
ZM\Logger::Debug('Results from probe: '.implode('<br/>', $output)); ZM\Logger::Debug('Results from probe: '.implode('<br/>', $output));
@ -49,7 +50,8 @@ function execONVIF( $cmd ) {
function probeCameras($localIp) { function probeCameras($localIp) {
$cameras = array(); $cameras = array();
if ( $lines = @execONVIF('probe') ) { $lines = @execONVIF('probe 1.1,1.2'.(isset($_REQUEST['interface']) ? ' '.isset($_REQUEST['interface']) : '' ));
if ( $lines ) {
foreach ( $lines as $line ) { foreach ( $lines as $line ) {
$line = rtrim($line); $line = rtrim($line);
if ( preg_match('|^(.+),(.+),\s\((.*)\)$|', $line, $matches) ) { if ( preg_match('|^(.+),(.+),\s\((.*)\)$|', $line, $matches) ) {
@ -62,20 +64,23 @@ function probeCameras($localIp) {
'Type' => 'Ffmpeg', 'Type' => 'Ffmpeg',
'Host' => $device_ep, 'Host' => $device_ep,
'SOAP' => $soapversion, 'SOAP' => $soapversion,
'ConfigURL' => $device_ep, 'ConfigURL' => $device_ep,
'ConfigOptions' => 'SOAP' . $soapversion, 'ConfigOptions' => 'SOAP' . $soapversion,
'Notes' => '',
), ),
); );
foreach ( preg_split('|,\s*|', $matches[3]) as $attr_val ) { foreach ( preg_split('|,\s*|', $matches[3]) as $attr_val ) {
if ( preg_match('|(.+)=\'(.*)\'|', $attr_val, $tokens) ) { if ( preg_match('|(.+)=\'(.*)\'|', $attr_val, $tokens) ) {
if ( $tokens[1] == 'hardware' ) { if ( $tokens[1] == 'hardware' ) {
$camera['model'] = $tokens[2]; $camera['model'] = $tokens[2];
} elseif ( $tokens[1] == 'name' ) { } else if ( $tokens[1] == 'name' ) {
$camera['monitor']['Name'] = $tokens[2]; $camera['monitor']['Name'] = $tokens[2];
} elseif ( $tokens[1] == 'location' ) { } else if ( $tokens[1] == 'type' ) {
// $camera['location'] = $tokens[2]; } else if ( $tokens[1] == 'location' or $tokens[1] == 'location/city' or $tokens[1] == 'location/country' ) {
$camera['monitor']['Notes'] .= $tokens[1].'='.$tokens[2]."\n";
// $camera['location'] = $tokens[2];
} else { } else {
ZM\Logger::Debug('Unknown token ' . $tokens[1]); ZM\Logger::Debug('Unknown token '.$tokens[1].' = '.$tokens[2]);
} }
} }
} // end foreach token } // end foreach token
@ -165,6 +170,48 @@ if ( !isset($_REQUEST['step']) || ($_REQUEST['step'] == '1') ) {
<p> <p>
<?php echo translate('OnvifProbeIntro') ?> <?php echo translate('OnvifProbeIntro') ?>
</p> </p>
<p><label for="interface"><?php echo translate('Interface') ?></label>
<?php
$interfaces = array();
$default_interface = null;
exec('ip link', $output, $status);
if ( $status ) {
$html_output = implode('<br/>', $output);
ZM\Error("Unable to list network interfaces, status is '$status'. Output was:<br/><br/>$html_output");
} else {
foreach ( $output as $line ) {
if ( preg_match('/^\d+: ([[:alnum:]]+):/', $line, $matches ) ) {
if ( $matches[1] != 'lo' ) {
$interfaces[$matches[1]] = $matches[1];
} else {
ZM\Logger::Debug("No match for $line");
}
}
}
}
$routes = array();
exec('ip route', $output, $status);
if ( $status ) {
$html_output = implode('<br/>', $output);
ZM\Error("Unable to list network interfaces, status is '$status'. Output was:<br/><br/>$html_output");
} else {
foreach ( $output as $line ) {
if ( preg_match('/^default via [.[:digit:]]+ dev ([[:alnum:]]+)/', $line, $matches) ) {
$default_interface = $matches[1];
} else if ( preg_match('/^([.\/[:digit:]]+) dev ([[:alnum:]]+)/', $line, $matches) ) {
$interfaces[$matches[2]] .= ' ' . $matches[1];
}
} # end foreach line of output
}
echo htmlSelect('interface', $interfaces,
(isset($_REQUEST['interface']) ? $_REQUEST['interface'] : $default_interface),
array('data-on-change-this'=>'changeInterface') );
?>
</p>
<div id="DetectedCameras">
<p> <p>
<label for="probe"><?php echo translate('DetectedCameras') ?></label> <label for="probe"><?php echo translate('DetectedCameras') ?></label>
<?php echo htmlSelect('probe', $cameras, null, array('data-on-change-this'=>'configureButtons')); ?> <?php echo htmlSelect('probe', $cameras, null, array('data-on-change-this'=>'configureButtons')); ?>
@ -180,6 +227,7 @@ if ( !isset($_REQUEST['step']) || ($_REQUEST['step'] == '1') ) {
<label for="Password"><?php echo translate('Password') ?></label> <label for="Password"><?php echo translate('Password') ?></label>
<input type="password" name="Password" data-on-change-this="configureButtons"/> <input type="password" name="Password" data-on-change-this="configureButtons"/>
</p> </p>
</div>
<div id="contentButtons"> <div id="contentButtons">
<button type="button" data-on-click="closeWindow"><?php echo translate('Cancel') ?></button> <button type="button" data-on-click="closeWindow"><?php echo translate('Cancel') ?></button>
<button type="button" name="nextBtn" data-on-click-this="gotoStep2" disabled="disabled"><?php echo translate('Next') ?></button> <button type="button" name="nextBtn" data-on-click-this="gotoStep2" disabled="disabled"><?php echo translate('Next') ?></button>

View File

@ -154,7 +154,7 @@ if ( isset($_REQUEST['midTime']) )
if ( isset($_REQUEST['maxTime']) ) if ( isset($_REQUEST['maxTime']) )
$maxTime = validHtmlStr($_REQUEST['maxTime']); $maxTime = validHtmlStr($_REQUEST['maxTime']);
if ( isset($range) ) { if ( isset($range) and validInt($range) ) {
$halfRange = (int)($range/2); $halfRange = (int)($range/2);
if ( isset($midTime) ) { if ( isset($midTime) ) {
$midTimeT = strtotime($midTime); $midTimeT = strtotime($midTime);
@ -616,7 +616,7 @@ function drawXGrid( $chart, $scale, $labelClass, $tickClass, $gridClass, $zoomCl
$zoomMinTime = strftime( STRF_FMT_DATETIME_DB, (int)($chart['data']['x']['lo'] + ($lastTick * $chart['data']['x']['density'])) ); $zoomMinTime = strftime( STRF_FMT_DATETIME_DB, (int)($chart['data']['x']['lo'] + ($lastTick * $chart['data']['x']['density'])) );
$zoomMaxTime = strftime( STRF_FMT_DATETIME_DB, (int)($chart['data']['x']['lo'] + ($i * $chart['data']['x']['density'])) ); $zoomMaxTime = strftime( STRF_FMT_DATETIME_DB, (int)($chart['data']['x']['lo'] + ($i * $chart['data']['x']['density'])) );
?> ?>
<div class="<?php echo $zoomClass ?>" style="left: <?php echo 100*($lastTick-1)/$chart['graph']['width'] ?>%; width: <?php echo round(100*($i-$lastTick)/$chart['graph']['width'],1) ?>%;" title="<?php echo translate('ZoomIn') ?>" onclick="tlZoomBounds( '<?php echo $zoomMinTime ?>', '<?php echo $zoomMaxTime ?>' )"></div> <div class="<?php echo $zoomClass ?>" style="left: <?php echo 100*($lastTick-1)/$chart['graph']['width'] ?>%; width: <?php echo round(100*($i-$lastTick)/$chart['graph']['width'],1) ?>%;" title="<?php echo translate('ZoomIn') ?>" data-on-click="tlZoomBounds" data-zoom-min-time="<?php echo $zoomMinTime ?>" data-zoom-max-time="<?php echo $zoomMaxTime ?>"></div>
<?php <?php
} }
$lastTick = $i; $lastTick = $i;
@ -629,7 +629,7 @@ function drawXGrid( $chart, $scale, $labelClass, $tickClass, $gridClass, $zoomCl
$zoomMinTime = strftime( STRF_FMT_DATETIME_DB, (int)($chart['data']['x']['lo'] + ($lastTick * $chart['data']['x']['density'])) ); $zoomMinTime = strftime( STRF_FMT_DATETIME_DB, (int)($chart['data']['x']['lo'] + ($lastTick * $chart['data']['x']['density'])) );
$zoomMaxTime = strftime( STRF_FMT_DATETIME_DB, (int)($chart['data']['x']['lo'] + ($i * $chart['data']['x']['density'])) ); $zoomMaxTime = strftime( STRF_FMT_DATETIME_DB, (int)($chart['data']['x']['lo'] + ($i * $chart['data']['x']['density'])) );
?> ?>
<div class="<?php echo $zoomClass ?>" style="left: <?php echo $lastTick-1 ?>px; width: <?php echo $i-$lastTick ?>px;" title="<?php echo translate('ZoomIn') ?>" onclick="tlZoomBounds( '<?php echo $zoomMinTime ?>', '<?php echo $zoomMaxTime ?>' )"></div> <div class="<?php echo $zoomClass ?>" style="left: <?php echo $lastTick-1 ?>px; width: <?php echo $i-$lastTick ?>px;" title="<?php echo translate('ZoomIn') ?>" data-on-click="tlZoomBounds" data-zoom-min-time="<?php echo $zoomMinTime ?>" data-zoom-max-time="<?php echo $zoomMaxTime ?>"></div>
<?php <?php
} }
?> ?>